internal static List <TamedCreatureViewModel> BuildCreatureViewModelsForPlayerId(ArkServerContext context, ulong playerId) { var result = new List <TamedCreatureViewModel>(); if (context.TamedCreatures != null) { var playercreatures = context.NoRafts.Where(x => (ulong)x.TargetingTeam == playerId || (x.OwningPlayerId.HasValue && (ulong)x.OwningPlayerId == playerId)).ToArray(); var tribe = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains((int)playerId)); var tribecreatures = tribe != null?context.NoRafts.Where(x => x.TargetingTeam == tribe.Id && !playercreatures.Any(y => y.Id == x.Id)).ToArray() : new ArkTamedCreature[] { }; foreach (var item in playercreatures.Select(x => new { c = x, o = "player" }).Concat(tribecreatures.Select(x => new { c = x, o = "tribe" }))) { var currentFood = item.c.CurrentStatusValues?.Length > 4 ? item.c.CurrentStatusValues[4] : null; var maxFood = item.c.BaseStats?.Length > 4 && item.c.TamedStats?.Length > 4 ? ArkContext.CalculateMaxStat( ArkSpeciesStatsData.Stat.Food, item.c.ClassName, item.c.BaseStats[4], item.c.TamedStats[4], (decimal)(item.c.DinoImprintingQuality ?? 0f), (decimal)(item.c.TamedIneffectivenessModifier ?? 0f)) : null; //baby food formula: max * 0.1 + (max - (max * 0.1)) * age if (maxFood.HasValue && item.c.BabyAge.HasValue) { maxFood = maxFood.Value * 0.1 + (maxFood.Value - (maxFood.Value * 0.1)) * item.c.BabyAge.Value; } var foodStatus = currentFood.HasValue && maxFood.HasValue ? currentFood.Value / (float)maxFood.Value : (float?)null; if (foodStatus.HasValue && foodStatus > 1f) { foodStatus = 1f; } var aliases = ArkSpeciesAliases.Instance.GetAliases(item.c.ClassName); var vmc = new TamedCreatureViewModel { Name = item.c.Name, ClassName = item.c.ClassName, Species = aliases?.FirstOrDefault(), Aliases = aliases?.Skip(2).ToArray() ?? new string[] { }, //skip primary name and class name Gender = item.c.Gender.ToString(), BaseLevel = item.c.BaseLevel, Level = item.c.Level, BabyAge = item.c.IsBaby ? item.c.BabyAge : null, Imprint = item.c.DinoImprintingQuality, FoodStatus = foodStatus, Latitude = item.c.Location?.Latitude, Longitude = item.c.Location?.Longitude, TopoMapX = item.c.Location?.TopoMapX, TopoMapY = item.c.Location?.TopoMapY, NextMating = item.c.NextAllowedMatingTimeApprox, BabyNextCuddle = item.c.BabyNextCuddleTimeApprox, OwnerType = item.o }; result.Add(vmc); } } return(result); }
public async Task Run(CommandEventArgs e) { var args = CommandHelper.ParseArgs(e, new { ServerKey = "" }, x => x.For(y => y.ServerKey, noPrefix: true, isRequired: false)); var serverContext = _contextManager.GetServer(args.ServerKey ?? _config.ServerKey); if (serverContext == null) { await e.Channel.SendMessage($"**Specified server instance key is not valid.**"); return; } if (!serverContext.IsInitialized) { await e.Channel.SendMessage($"**The data is loading but is not ready yet...**"); return; } var player = await CommandHelper.GetCurrentPlayerOrSendErrorMessage(e, _databaseContextFactory, serverContext); if (player == null) { return; } var playercreatures = serverContext.NoRafts.Where(x => (ulong)x.TargetingTeam == player.Id || (x.OwningPlayerId.HasValue && (ulong)x.OwningPlayerId == player.Id)).ToArray(); var tribecreatures = player.TribeId.HasValue ? serverContext.NoRafts.Where(x => x.TargetingTeam == player.TribeId.Value && !playercreatures.Any(y => y.Id == x.Id)).ToArray() : new ArkTamedCreature[] { }; var mydinos = playercreatures.Select(x => new { c = x, o = "player" }).Concat(tribecreatures.Select(x => new { c = x, o = "tribe" })).Select(item => { var currentFood = item.c.CurrentStatusValues?.Length > 4 ? item.c.CurrentStatusValues[4] : null; var maxFood = item.c.BaseStats?.Length > 4 && item.c.TamedStats?.Length > 4 ? ArkContext.CalculateMaxStat( ArkSpeciesStatsData.Stat.Food, item.c.ClassName, item.c.BaseStats[4], item.c.TamedStats[4], (decimal)(item.c.DinoImprintingQuality ?? 0f), (decimal)(item.c.TamedIneffectivenessModifier ?? 0f)) : null; //baby food formula: max * 0.1 + (max - (max * 0.1)) * age if (maxFood.HasValue && item.c.BabyAge.HasValue) { maxFood = maxFood.Value * 0.1 + (maxFood.Value - (maxFood.Value * 0.1)) * item.c.BabyAge.Value; } var fs = currentFood.HasValue && maxFood.HasValue ? currentFood.Value / (float)maxFood.Value : (float?)null; if (fs.HasValue && fs > 1f) { fs = 1f; } var aliases = ArkSpeciesAliases.Instance.GetAliases(item.c.ClassName); return(new { c = item.c, o = item.o, food = fs }); }).ToArray(); //var mydinos = serverContext.NoRafts // .Where(x => ((x.OwningPlayerId.HasValue && x.OwningPlayerId.Value == player.Id) || (x.Team.Value == player.TribeId)) && !x.IsBaby) // .Select(x => // { // //!_context.ArkSpeciesStatsData.SpeciesStats.Any(y => y.Name.Equals(x.SpeciesName, StringComparison.OrdinalIgnoreCase)) ? _context.ArkSpeciesStatsData.SpeciesStats.Select(y => new { name = y.Name, similarity = StatisticsHelper.CompareToCharacterSequence(x.Name, x.SpeciesName.ToCharArray()) }).OrderByDescending(y => y.similarity).FirstOrDefault()?.name : null; // return new // { // creature = x, // maxFood = ArkContext.CalculateMaxStat(Data.ArkSpeciesStatsData.Stat.Food, x.SpeciesClass ?? x.SpeciesName, x.WildLevels?.Food, x.TamedLevels?.Food, x.ImprintingQuality, x.TamedIneffectivenessModifier) // }; // }) // .ToArray(); //var foodStatus = mydinos?.Where(x => x.creature.CurrentFood.HasValue && x.maxFood.HasValue).Select(x => (double)x.creature.CurrentFood.Value / x.maxFood.Value) // .Where(x => x <= 1d).OrderBy(x => x).ToArray(); //var starving = mydinos?.Where(x => x.creature.CurrentFood.HasValue && x.maxFood.HasValue).Select(x => new { creature = x.creature, p = (double)x.creature.CurrentFood.Value / x.maxFood.Value }) // .Where(x => x.p <= (1 / 2d)).OrderBy(x => x.p).ToArray(); //any dino below 1/2 food is considered to be starving var foodStatus = mydinos.Where(x => x.food.HasValue).Select(x => x.food.Value).OrderBy(x => x).ToArray(); var starving = mydinos.Where(x => !x.food.HasValue || x.food <= (1 / 2d)).OrderBy(x => x.food).ToArray(); //any dino below 1/2 food is considered to be starving if (foodStatus.Length <= 0) { await e.Channel.SendMessage($"<@{e.User.Id}>, we could not get the food status of your dinos! :("); return; } var min = foodStatus.Min(); var avg = foodStatus.Average(); var max = foodStatus.Max(); var stateFun = min <= 0.25 ? "starving... :(" : min <= 0.5 ? "hungry... :|" : min <= 0.75 ? "feeling satisfied :)" : "feeling happy! :D"; var sb = new StringBuilder(); sb.AppendLine($"**Your dinos are {stateFun}**"); sb.AppendLine($"{min:P0} ≤ {avg:P0} ≤ {max:P0}"); if (starving.Length > 0) { var tmp = starving.Select(x => { var aliases = ArkSpeciesAliases.Instance.GetAliases(x.c.ClassName); return($"{x.c.Name ?? aliases.FirstOrDefault() ?? x.c.ClassName}, lvl {x.c.Level}" + $" ({(x.food.HasValue ? x.food.Value.ToString("P0") : "Unknown")})"); }).ToArray().Join((n, l) => n == l ? " and " : ", "); sb.AppendLine(tmp); } await CommandHelper.SendPartitioned(e.Channel, sb.ToString()); var filepath = Path.Combine(_config.TempFileOutputDirPath, "chart.jpg"); if (CommandHelper.AreaPlotSaveAs(foodStatus.Select((x, i) => new DataPoint(i, x)).ToArray(), filepath)) { await e.Channel.SendFile(filepath); } if (File.Exists(filepath)) { File.Delete(filepath); } }