Example #1
0
        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);
            }
        }