예제 #1
0
        public async Task CheckTimesCommand()
        {
            MarbleBotUser user = MarbleBotUser.Find(Context);
            TimeSpan      timeUntilNextDaily    = user.LastDaily - DateTime.UtcNow.AddHours(-24);
            TimeSpan      timeUntilNextRace     = user.LastRaceWin - DateTime.UtcNow.AddHours(-6);
            TimeSpan      timeUntilNextScavenge = user.LastScavenge - DateTime.UtcNow.AddHours(-6);
            TimeSpan      timeUntilNextSiege    = user.LastSiegeWin - DateTime.UtcNow.AddHours(-6);
            TimeSpan      timeUntilNextWar      = user.LastWarWin - DateTime.UtcNow.AddHours(-6);

            await ReplyAsync(embed : new EmbedBuilder()
                             .AddField("Daily",
                                       timeUntilNextDaily.TotalHours < 0 ? "**Ready!**" : timeUntilNextDaily.ToString(@"hh\:mm\:ss"),
                                       true)
                             .AddField("Race",
                                       timeUntilNextRace.TotalHours < 0 ? "**Ready!**" : timeUntilNextRace.ToString(@"hh\:mm\:ss"),
                                       true)
                             .AddField("Scavenge",
                                       timeUntilNextScavenge.TotalHours < 0 ? "**Ready!**" : timeUntilNextScavenge.ToString(@"hh\:mm\:ss"),
                                       true)
                             .AddField("Siege",
                                       timeUntilNextSiege.TotalHours < 0 ? "**Ready!**" : timeUntilNextSiege.ToString(@"hh\:mm\:ss"),
                                       true)
                             .AddField("War",
                                       timeUntilNextWar.TotalHours < 0 ? "**Ready!**" : timeUntilNextWar.ToString(@"hh\:mm\:ss"),
                                       true)
                             .WithAuthor(Context.User)
                             .WithColor(GetColor(Context))
                             .Build());
        }
예제 #2
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task RecipesCommand(string rawPage = "1")
        {
            EmbedBuilder embed = new EmbedBuilder()
                                 .WithColor(GetColor(Context));
            IDictionary <int, Item> items = Item.GetItems();

            if (!int.TryParse(rawPage, out int page) && page > 0)
            {
                await ReplyAsync("Invalid number! Use `mb/help recipes` for more info.");

                return;
            }

            int minValue = page * 20 - 20;
            KeyValuePair <int, Item> lastItem = items.Last();

            if (minValue > lastItem.Key)
            {
                await ReplyAsync($"The last item has ID `{lastItem}`!");

                return;
            }

            int maxValue = page * 20 - 1;

            embed.WithTitle($"Recipes in IDs `{minValue:000}`-`{maxValue:000}` :notepad_spiral:");
            foreach ((int itemId, Item item) in items)
            {
                if (item.CraftingRecipe != null)
                {
                    if (itemId >= minValue && itemId <= maxValue)
                    {
                        if (item.Stage > ((await MarbleBotUser.Find(Context)) !).Stage)
                        {
                            embed.AddField($"`[{itemId:000}]` {Item.Find<Item>(itemId).Name}",
                                           $"{StageTooHighString()}\n\nYou are unable to view information about this item!");
                        }
                        else
                        {
                            var output = new StringBuilder();
                            foreach ((int ingredientId, int noRequired) in item.CraftingRecipe)
                            {
                                output.AppendLine($"`[{ingredientId:000}]` {Item.Find<Item>(ingredientId).Name}: {noRequired}");
                            }

                            embed.AddField($"`[{itemId:000}]` {item.Name} (produces **{item.CraftingProduced}**)",
                                           output.ToString());
                        }
                    }

                    if (itemId > maxValue)
                    {
                        break;
                    }
                }
            }

            await ReplyAsync(embed : embed.Build());
        }
예제 #3
0
 public async Task ScavengeLocationDestroyerCommand()
 {
     if (((await MarbleBotUser.Find(Context)) !).Stage < 2)
     {
         await ReplyAsync(embed : new EmbedBuilder()
                          .WithColor(GetColor(Context))
                          .WithDescription($"{StageTooHighString()}\n\nYou cannot scavenge in this location!")
                          .WithTitle("Scavenge Location Info: Destroyer's Remains")
                          .Build());
     }
예제 #4
0
        public async Task ScavengeDrillCommand()
        {
            if (!_gamesService.Scavenges.ContainsKey(Context.User.Id) ||
                _gamesService.Scavenges[Context.User.Id] == null)
            {
                await SendErrorAsync($"**{Context.User.Username}**, you are not scavenging!");

                return;
            }

            if (_gamesService.Scavenges[Context.User.Id].Ores.Count == 0)
            {
                await SendErrorAsync($"**{Context.User.Username}**, there is nothing to drill!");

                return;
            }

            var user = MarbleBotUser.Find(Context);

            if (!(user.Items.ContainsKey(81) || user.Items.ContainsKey(82)))
            {
                await SendErrorAsync($"**{Context.User.Username}**, you need a drill to mine ore!");

                return;
            }

            var item = _gamesService.Scavenges[Context.User.Id].Ores.Dequeue();

            _gamesService.Scavenges[Context.User.Id].UsedOres.Enqueue(item);
            if (user.Items.ContainsKey(item.Id))
            {
                user.Items[item.Id]++;
            }
            else
            {
                user.Items.Add(item.Id, 1);
            }

            user.NetWorth += item.Price;
            MarbleBotUser.UpdateUser(user);
            await _gamesService.Scavenges[Context.User.Id].UpdateEmbed();
            var confirmationMessage =
                await ReplyAsync($"**{Context.User.Username}**, you have successfully added **{item.Name}** x**1** to your inventory!");

            // Clean up the messages created if the bot can delete messages
            if (!Context.IsPrivate && Context.Guild.CurrentUser.GuildPermissions.ManageMessages)
            {
                await Task.Delay(4000);

                await Context.Message.DeleteAsync();

                await confirmationMessage.DeleteAsync();
            }
        }
예제 #5
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task InventoryCommand(int page = 1)
        {
            if (page < 1)
            {
                await SendErrorAsync($"**{Context.User.Username}**, the inventory page must be at least one!");

                return;
            }

            await ShowUserInventory(Context.User, (await MarbleBotUser.Find(Context)) !, page);
        }
예제 #6
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task BalanceCommand([Remainder] MarbleBotUser?user = null)
        {
            user ??= (await MarbleBotUser.Find(Context)) !;
            EmbedBuilder?builder = new EmbedBuilder()
                                   .WithColor(GetColor(Context))
                                   .AddField("Balance", $"{UnitOfMoney}{user.Balance:n2}", true)
                                   .AddField("Net Worth", $"{UnitOfMoney}{user.NetWorth:n2}", true);

            AddAuthor(Context, user, builder);

            await ReplyAsync(embed : builder.Build());
        }
예제 #7
0
        public async Task ScavengeLocationCommand()
        {
            var stageTwoLocations = MarbleBotUser.Find(Context).Stage > 1
                ? "Destroyer's Remains\nViolet Volcanoes"
                : ":lock: LOCKED\n:lock: LOCKED";

            await ReplyAsync(embed : new EmbedBuilder()
                             .WithColor(GetColor(Context))
                             .WithDescription($"Canary Beach\nTree Wurld\n{stageTwoLocations}\n\nUse `mb/scavenge info <location name>` to see which items you can get!")
                             .WithTitle("Scavenge Locations")
                             .Build());
        }
예제 #8
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task DailyCommand()
        {
            var user = (await MarbleBotUser.Find(Context)) !;

            if ((DateTime.UtcNow - user.LastDaily).TotalHours < 24)
            {
                DateTime aDayAgo = DateTime.UtcNow.AddDays(-1);
                await ReplyAsync($"You need to wait for {GetTimeSpanSentence(user.LastDaily - aDayAgo)} until you can get your daily gift again!");

                return;
            }

            if ((DateTime.UtcNow - user.LastDaily).TotalHours > _dailyTimeoutService.DailyTimeout)
            {
                user.DailyStreak = 0;
            }

            int     power = user.DailyStreak > 100 ? 100 : user.DailyStreak;
            decimal gift  = (decimal)MathF.Round(MathF.Pow(200f, 1f + power / 100f), 2);
            bool    giveCraftingStation = user.DailyStreak > 2 && !user.Items.ContainsKey(17);

            user.Balance  += gift;
            user.NetWorth += gift;
            user.DailyStreak++;
            user.LastDaily = DateTime.UtcNow;

            if (giveCraftingStation)
            {
                user.Items.Add(17, 1);
            }

            bool giveQefpedunCharm = false;

            if (!user.Items.ContainsKey(10) && DateTime.UtcNow.DayOfYear < 51 && DateTime.UtcNow.DayOfYear > 42)
            {
                giveQefpedunCharm = true;
                user.Items.Add(10, 1);
            }

            MarbleBotUser.UpdateUser(user);
            await ReplyAsync($"**{Context.User.Username}**, you have received {UnitOfMoney}**{gift:n2}**!\n(Streak: **{user.DailyStreak}**)");

            if (giveCraftingStation)
            {
                await ReplyAsync("You have been given a **Crafting Station Mk.I**!");
            }

            if (giveQefpedunCharm)
            {
                await ReplyAsync("You have been given a **Qefpedun Charm**!");
            }
        }
예제 #9
0
 public async Task ScavengeVolcanoCommand()
 {
     if (MarbleBotUser.Find(Context).Stage < 2)
     {
         await ReplyAsync(embed : new EmbedBuilder()
                          .WithColor(GetColor(Context))
                          .WithDescription($"{StageTooHighString()}\n\nYou cannot scavenge in this location!")
                          .WithTitle("Scavenge: Violet Volcanoes")
                          .Build());
     }
     else
     {
         await ScavengeStartAsync(MarbleBotUser.Find(Context), ScavengeLocation.VioletVolcanoes);
     }
 }
예제 #10
0
        public async Task ScavengeDestroyerCommand()
        {
            var user = (await MarbleBotUser.Find(Context)) !;

            if (user.Stage < 2)
            {
                await ReplyAsync(embed : new EmbedBuilder()
                                 .WithColor(GetColor(Context))
                                 .WithDescription($"{StageTooHighString()}\n\nYou cannot scavenge in this location!")
                                 .WithTitle("Scavenge: Destroyer's Remains")
                                 .Build());
            }
            else
            {
                await ScavengeStartAsync(user, ScavengeLocation.DestroyersRemains);
            }
        }
예제 #11
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task BuyCommand(Item item, int noOfItems = 1)
        {
            if (noOfItems < 1)
            {
                await SendErrorAsync($"**{Context.User.Username}**, invalid number of items! Use `mb/help buy` to see how the command works.");

                return;
            }

            if (item.Price == -1)
            {
                await SendErrorAsync($"**{Context.User.Username}**, this item cannot be sold!");

                return;
            }

            if (!item.OnSale)
            {
                await SendErrorAsync($"**{Context.User.Username}**, this item is not on sale!");

                return;
            }

            var user = (await MarbleBotUser.Find(Context)) !;

            if (user.Balance >= item.Price * noOfItems)
            {
                if (user.Items.ContainsKey(item.Id))
                {
                    user.Items[item.Id] += noOfItems;
                }
                else
                {
                    user.Items.Add(item.Id, noOfItems);
                }

                user.Balance -= item.Price * noOfItems;
                MarbleBotUser.UpdateUser(user);
                await ReplyAsync($"**{user.Name}** has successfully purchased **{item.Name}** x**{noOfItems}** for {UnitOfMoney}**{item.Price:n2}** each!\nTotal price: {UnitOfMoney}**{item.Price * noOfItems:n2}**\nNew balance: {UnitOfMoney}**{user.Balance:n2}**.");
            }
            else
            {
                await SendErrorAsync("You can't afford this!");
            }
        }
예제 #12
0
        public async Task ScavengeHelpCommand([Remainder] string _ = "")
        {
            bool         userCanDrill = MarbleBotUser.Find(Context).Stage > 1;
            const string helpP1       =
                "Use `mb/scavenge locations` to see where you can scavenge for items and use `mb/scavenge <location name>` to start a scavenge session!";
            const string helpP2 =
                "\n\nWhen you find an item, use `mb/scavenge sell` to sell immediately or `mb/scavenge grab` to put the item in your inventory!";
            const string helpP3 =
                "\n\nScavenge games last for 32 seconds - every 4 seconds there will be a 80% chance that you've found an item.";
            const string helpP4 =
                "\n\nIf you find an ore, you can use `mb/scavenge drill` to drill it. Drilling requires a drill in your inventory.";
            string helpP5 =
                $"\n\nAt the end of the scavenge, all {(userCanDrill ? "non-ore" : "")} items are automatically added to your inventory.";

            await ReplyAsync(embed : new EmbedBuilder()
                             .AddField("How to play", $"{helpP1}{helpP2}{helpP3}{(userCanDrill ? helpP4 : "")}{helpP5}")
                             .WithColor(GetColor(Context))
                             .WithTitle("Item Scavenge!")
                             .Build());
        }
예제 #13
0
        public async Task ScavengeSellCommand()
        {
            var user = MarbleBotUser.Find(Context);

            if (!_gamesService.Scavenges.ContainsKey(Context.User.Id) ||
                _gamesService.Scavenges[Context.User.Id] == null)
            {
                await SendErrorAsync($"**{Context.User.Username}**, you are not scavenging!");

                return;
            }

            if (_gamesService.Scavenges[Context.User.Id].Items.Count == 0)
            {
                await SendErrorAsync($"**{Context.User.Username}**, there is nothing to sell!");

                return;
            }

            var item = _gamesService.Scavenges[Context.User.Id].Items.Dequeue();

            _gamesService.Scavenges[Context.User.Id].UsedItems.Enqueue(item);
            user.Balance  += item.Price;
            user.NetWorth += item.Price;
            MarbleBotUser.UpdateUser(user);
            await _gamesService.Scavenges[Context.User.Id].UpdateEmbed();
            var confirmationMessage = await ReplyAsync($"**{Context.User.Username}**, you have successfully sold **{item.Name}** x**1** for {UnitOfMoney}**{item.Price:n2}**!");

            // Clean up the messages created if the bot can delete messages
            if (!Context.IsPrivate && Context.Guild.CurrentUser.GuildPermissions.ManageMessages)
            {
                await Task.Delay(4000);

                await Context.Message.DeleteAsync();

                await confirmationMessage.DeleteAsync();
            }
        }
예제 #14
0
        protected internal static async Task <string> GetUsernameDiscriminatorString(SocketCommandContext context, ulong id)
        {
            var    marbleBotUser = (await MarbleBotUser.Find(context, id)) !;
            string usernameString;

            if (marbleBotUser != null)
            {
                usernameString = $"{marbleBotUser.Name}#{marbleBotUser.Discriminator}";
            }
            else
            {
                var discordSocketUser = context.Client.GetUser(id);
                if (discordSocketUser != null)
                {
                    usernameString = $"{discordSocketUser.Username}#{discordSocketUser.Discriminator}";
                }
                else
                {
                    usernameString = "user not found";
                }
            }
            return(usernameString);
        }
        public override Task <TypeReaderResult> ReadAsync(ICommandContext context, string input,
                                                          IServiceProvider services)
        {
            if (ulong.TryParse(input.TrimStart('<').TrimEnd('>').TrimStart('@'), out ulong id))
            {
                return(Task.FromResult(TypeReaderResult.FromSuccess(MarbleBotUser.Find(context, id))));
            }

            var           usersDict   = MarbleBotUser.GetUsers();
            MarbleBotUser?closestUser = null;

            // If the input and the username are equal, return straght away
            // Otherwise, find the closest match
            foreach ((_, MarbleBotUser user) in usersDict)
            {
                if (string.Compare(input, user.Name, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    return(Task.FromResult(TypeReaderResult.FromSuccess(user)));
                }
                else if (input.Contains(user.Name, StringComparison.OrdinalIgnoreCase) ||
                         user.Name.Contains(input, StringComparison.OrdinalIgnoreCase))
                {
                    closestUser = user;
                }
            }

            if (closestUser == null)
            {
                return(Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed,
                                                                  "Input could not be parsed as a user.")));
            }
            else
            {
                return(Task.FromResult(TypeReaderResult.FromSuccess(closestUser)));
            }
        }
예제 #16
0
 public async Task ScavengeTreeCommand()
 {
     await ScavengeStartAsync(MarbleBotUser.Find(Context), ScavengeLocation.TreeWurld);
 }
예제 #17
0
 public async Task ScavengeCanaryCommand()
 {
     await ScavengeStartAsync(MarbleBotUser.Find(Context), ScavengeLocation.CanaryBeach);
 }
예제 #18
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task CraftableCommand()
        {
            int currentPart = 0;
            var embed       = new EmbedBuilder();
            var user        = (await MarbleBotUser.Find(Context)) !;
            var output      = new StringBuilder();
            IDictionary <int, Item> itemsDict = Item.GetItems();

            foreach ((int itemId, Item item) in itemsDict)
            {
                if (item.CraftingRecipe != null)
                {
                    bool craftable   = true;
                    int  noCraftable = 0;
                    foreach ((int ingredientId, int ingredientNoOwned) in item.CraftingRecipe)
                    {
                        if (!user.Items.ContainsKey(ingredientId) || user.Items[ingredientId] < ingredientNoOwned)
                        {
                            craftable = false;
                            break;
                        }

                        noCraftable = noCraftable == 0
                            ? user.Items[ingredientId] / ingredientNoOwned
                            : Math.Min(user.Items[ingredientId] / ingredientNoOwned, noCraftable);
                    }

                    if (craftable)
                    {
                        string itemInfo = $"`[{itemId:000}]` {item.Name}: {noCraftable}";
                        if (output.Length + itemInfo.Length > EmbedFieldBuilder.MaxFieldValueLength)
                        {
                            currentPart++;
                            embed.AddField($"Part {currentPart}", output.ToString());
                            output = new StringBuilder(itemInfo);
                        }
                        else
                        {
                            output.AppendLine(itemInfo);
                        }
                    }
                }
            }

            if (output.Length == 0)
            {
                output.Append("There are no items you can craft!");
            }

            if (embed.Fields.Count == 0)
            {
                embed.WithDescription(output.ToString());
            }
            else
            {
                currentPart++;
                embed.AddField($"Part {currentPart}", output.ToString());
            }

            await ReplyAsync(embed : embed
                             .WithAuthor(Context.User)
                             .WithColor(GetColor(Context))
                             .WithTitle("Craftable items")
                             .Build());
        }
예제 #19
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task DecraftCommand(Item requestedItem, int noOfItems = 1)
        {
            var user = (await MarbleBotUser.Find(Context)) !;

            if (!user.Items.ContainsKey(17) && !user.Items.ContainsKey(62))
            {
                await SendErrorAsync($"**{Context.User.Username}**, you need a Crafting Station to decraft items!");

                return;
            }

            if (requestedItem.CraftingProduced == 0)
            {
                await SendErrorAsync($"**{Context.User.Username}**, you cannot dismantle this item!");

                return;
            }

            if (requestedItem.CraftingStationRequired == 2 && !user.Items.ContainsKey(62))
            {
                await SendErrorAsync($"**{Context.User.Username}**, your Crafting Station is not advanced enough to dismantle this item!");

                return;
            }

            if (requestedItem.CraftingRecipe == null)
            {
                await SendErrorAsync($"**{Context.User.Username}**, the item **{requestedItem.Name}** cannot be decrafted!");

                return;
            }

            if (!user.Items.ContainsKey(requestedItem.Id) || user.Items[requestedItem.Id] < noOfItems)
            {
                await SendErrorAsync($"**{Context.User.Username}**, you do not have enough of this item!");

                return;
            }

            decimal currentNetWorth = user.NetWorth;
            int     noCrafted       = requestedItem.CraftingProduced * noOfItems;
            var     output          = new StringBuilder();

            foreach ((int itemId, int noRequired) in requestedItem.CraftingRecipe)
            {
                var item     = Item.Find <Item>(itemId);
                int noGained = noRequired * noOfItems;
                output.AppendLine($"`[{item.Id:000}]` {item.Name}: {noGained}");
                if (user.Items.ContainsKey(item.Id))
                {
                    user.Items[itemId] += noGained;
                }
                else
                {
                    user.Items.Add(item.Id, noGained);
                }

                user.NetWorth += item.Price * noOfItems;
            }

            user.Items[requestedItem.Id] -= noCrafted;
            user.NetWorth -= requestedItem.Price * noCrafted;
            MarbleBotUser.UpdateUser(user);
            await ReplyAsync(embed : new EmbedBuilder()
                             .WithColor(GetColor(Context))
                             .WithDescription($"**{Context.User.Username}** has successfully decrafted **{requestedItem.Name}** x**{noCrafted}**!")
                             .WithTitle($"Crafting: {requestedItem.Name}")
                             .AddField("Gained items", output.ToString())
                             .AddField("Net Worth",
                                       $"Old: {UnitOfMoney}**{currentNetWorth:n2}**\nNew: {UnitOfMoney}**{user.NetWorth:n2}**")
                             .Build());
        }
예제 #20
0
        public async Task HelpCommand([Remainder] string commandToFind = "")
        {
            var builder = new EmbedBuilder()
                          .WithColor(GetColor(Context));

            ModuleInfo?module = _commandService.Modules.FirstOrDefault(m =>
                                                                       string.Equals(m.Name, commandToFind, StringComparison.CurrentCultureIgnoreCase));

            if (module != null)
            {
                bool owner = _botCredentials.AdminIds.Any(id => id == Context.User.Id);

                if (!owner && module.Name == "Moderation" && !Context.IsPrivate &&
                    !(Context.User as SocketGuildUser) !.GuildPermissions.ManageMessages ||
                    module.Name == "Sneak")
                {
                    await SendErrorAsync("You cannot access this module!");

                    return;
                }

                IEnumerable <CommandInfo> commands = module.Commands
                                                     .Where(c => owner || !c.Preconditions.Any(p => p is RequireOwnerAttribute)).OrderBy(c => c.Name);

                if (Context.IsPrivate)
                {
                    if (!owner)
                    {
                        commands = commands.Where(c =>
                                                  c.Preconditions != null && !c.Preconditions.Any(p => p is RequireContextAttribute));
                    }
                }
                else if (Context.Guild.Id != CommunityMarble)
                {
                    commands = commands.Where(commandInfo => commandInfo.Remarks != "CM Only");
                }

                if (MarbleBotUser.Find(Context).Stage < 2)
                {
                    commands = commands.Where(commandInfo => commandInfo.Remarks != "Stage2");
                }

                var commandInfos = commands as CommandInfo[] ?? commands.ToArray();
                if (!commandInfos.Any())
                {
                    await SendErrorAsync("No applicable commands in this module could be found!");
                }

                await ReplyAsync(embed : builder
                                 .AddField($"{CultureInfo.CurrentCulture.TextInfo.ToTitleCase(commandToFind)} Commands",
                                           commandInfos.Aggregate(new StringBuilder(), (stringBuilder, commandInfo) =>
                {
                    stringBuilder.AppendLine($"**{commandInfo.Name}** - {commandInfo.Summary}");
                    return(stringBuilder);
                }).ToString())
                                 .WithTitle("MarbleBot Help")
                                 .Build());
            }
            else if (commandToFind.ToLower() == "games")
            {
                await ReplyAsync(embed : builder
                                 .AddField("Games commands", new StringBuilder()
                                           .AppendLine("**race** - Participate in a marble race!")
                                           .AppendLine("**scavenge** - Scavenge for items!")
                                           .AppendLine("**siege** - Participate in a Marble Siege!")
                                           .AppendLine("**war** - Participate in a Marble War!")
                                           .ToString())
                                 .WithDescription("*by Doc671#1965*")
                                 .WithTitle("MarbleBot Help")
                                 .Build());
            }
            else
            {
                // If a module could not be found, try searching for a command
                CommandInfo?command = _commandService.Commands.FirstOrDefault(commandInfo =>
                                                                              commandInfo.Name.ToLower() == commandToFind || commandInfo.Aliases.Any(alias => alias == commandToFind) &&
                                                                              !commandInfo.Preconditions.Any(precondition => precondition is RequireOwnerAttribute));

                // If neither a command nor a module could be found, show a list of modules
                if (command == null)
                {
                    if (!Context.IsPrivate && (Context.User as SocketGuildUser) !.GuildPermissions.ManageMessages)
                    {
                        builder.AddField("Modules", "Economy\nFun\nGames\nModeration\nRoles\nUtility\nYouTube");
                    }
                    else
                    {
                        builder.AddField("Modules", "Economy\nFun\nGames\nRoles\nUtility\nYouTube");
                    }

                    await ReplyAsync(embed : builder
                                     .WithDescription("*by Doc671#1965*\n\nUse `mb/help` followed by the name of a module or a command for more info.")
                                     .WithTitle("MarbleBot Help")
                                     .Build());

                    return;
                }

                string example = "";
                string usage   = $"mb/{command.Aliases[0]}{command.Parameters.Aggregate(new StringBuilder(), (stringBuilder, param) => { stringBuilder.Append($" <{param.Name}>"); return stringBuilder; })}";

                // Gets extra command info (e.g. an example of the command's usage) if present
                string json = await File.ReadAllTextAsync($"Resources{Path.DirectorySeparatorChar}ExtraCommandInfo.json");

                var commandDict = JsonSerializer.Deserialize <Dictionary <string, Dictionary <string, string> > >(json);
                if (commandDict !.ContainsKey(command.Name) ||
                    command.Aliases.Any(alias => commandDict.ContainsKey(alias)))
                {
                    example = commandDict[command.Name].ContainsKey("Example")
                        ? commandDict[command.Name]["Example"]
                        : "";
                    usage = commandDict[command.Name].ContainsKey("Usage") ? commandDict[command.Name]["Usage"] : "";
                }

                builder.WithDescription(command.Summary)
                .AddField("Usage", $"`{usage}`")
                .WithTitle($"MarbleBot Help: **{command.Name.CamelToTitleCase()}**");

                if (!string.IsNullOrEmpty(example))
                {
                    builder.AddField("Example", $"`{example}`", true);
                }

                builder.AddField("Module", $"{CultureInfo.CurrentCulture.TextInfo.ToTitleCase(command.Module.Name)}",
                                 true);

                if (command.Aliases.Count > 1)
                {
                    builder.AddField("Aliases", command.Aliases.Skip(1).Aggregate(new StringBuilder(),
                                                                                  (stringBuilder, alias) =>
                    {
                        stringBuilder.AppendLine($"`mb/{alias}`");
                        return(stringBuilder);
                    }).ToString(), true);
                }

                if (command.Parameters.Count != 0)
                {
                    builder.AddField("Parameters", command.Parameters.Aggregate(new StringBuilder(),
                                                                                (stringBuilder, param) =>
                    {
                        stringBuilder.AppendLine($"{param.Name.CamelToTitleCase()} ({(param.IsOptional ? "optional " : "")}{(param.IsRemainder ? "remainder " : "")}{param.Type.Name})");
                        return(stringBuilder);
                    }).ToString(), true);
                }

                if (command.Preconditions.Count != 0)
                {
                    builder.AddField("Preconditions", command.Preconditions.Aggregate(new StringBuilder(),
                                                                                      (stringBuilder, precondition) =>
                    {
                        stringBuilder.AppendLine((precondition.TypeId as Type) !.Name[7..^ 9].CamelToTitleCase());
                        return(stringBuilder);
                    }).ToString(), true);
예제 #21
0
        public async Task WarStartCommand()
        {
            ulong fileId = Context.IsPrivate ? Context.User.Id : Context.Guild.Id;

            if (_gamesService.Wars.ContainsKey(fileId))
            {
                await SendErrorAsync($"**{Context.User.Username}**, there is already a war going on!");

                return;
            }

            if (!File.Exists($"Data{Path.DirectorySeparatorChar}{fileId}.war"))
            {
                await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                return;
            }

            var marbles = new List <WarMarble>();

            using (var marbleList = new StreamReader($"Data{Path.DirectorySeparatorChar}{fileId}.war"))
            {
                if (marbleList.BaseStream.Length == 0)
                {
                    await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                    return;
                }

                var formatter  = new BinaryFormatter();
                var rawMarbles = (List <(ulong id, string name, int itemId)>)formatter.Deserialize(marbleList.BaseStream);
                if (rawMarbles.Count == 0)
                {
                    await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                    return;
                }

                foreach ((ulong id, string name, int itemId) in rawMarbles.OrderBy(marbleInfo => _randomService.Rand.Next()))
                {
                    var user = MarbleBotUser.Find(Context, id);
                    marbles.Add(new WarMarble(user, name, 35, Item.Find <Weapon>(itemId)));
                }
            }

            var team1    = new List <WarMarble>();
            var team2    = new List <WarMarble>();
            var mentions = new StringBuilder();

            for (int i = 0; i < marbles.Count; i++)
            {
                WarMarble marble = marbles[i];
                if (i < (int)Math.Ceiling(marbles.Count / 2d))
                {
                    team1.Add(marble);
                }
                else
                {
                    team2.Add(marble);
                }

                if (MarbleBotUser.Find(Context, marble.Id).SiegePing&& Context.Client.GetUser(marble.Id).Status != UserStatus.Offline)
                {
                    mentions.Append($"<@{marble.Id}> ");
                }
            }

            WarMarble?aiMarble = null;

            if ((team1.Count + team2.Count) % 2 > 0)
            {
                WarMarble[] allMarbles = team1.Union(team2).ToArray();
                if (allMarbles.Average(m => MarbleBotUser.Find(Context, m.Id).Stage) > 1.5)
                {
                    aiMarble = new WarMarble(Context.Client.CurrentUser.Id, "MarbleBot", 40, Item.Find <Weapon>(_randomService.Rand.Next(0, 9) switch
                    {
                        0 => "086",
                        1 => "087",
                        2 => "088",
                        3 => "089",
                        4 => "093",
                        5 => "094",
                        6 => "095",
                        7 => "096",
                        _ => "097"
                    }), Item.Find <Shield>("063"), Item.Find <Spikes>(_randomService.Rand.Next(0, 4) switch
예제 #22
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task ProfileCommand([Remainder] MarbleBotUser?user = null)
        {
            user ??= (await MarbleBotUser.Find(Context)) !;

            string lastDaily = user.LastDaily.ToString("yyyy-MM-dd HH:mm:ss");

            if (user.LastDaily.Year == 1)
            {
                lastDaily = "N/A";
            }

            string lastRaceWin = user.LastRaceWin.ToString("yyyy-MM-dd HH:mm:ss");

            if (user.LastRaceWin.Year == 1)
            {
                lastRaceWin = "N/A";
            }

            string lastScavenge = user.LastScavenge.ToString("yyyy-MM-dd HH:mm:ss");

            if (user.LastScavenge.Year == 1)
            {
                lastScavenge = "N/A";
            }

            string lastSiegeWin = user.LastSiegeWin.ToString("yyyy-MM-dd HH:mm:ss");

            if (user.LastSiegeWin.Year == 1)
            {
                lastSiegeWin = "N/A";
            }

            string lastWarWin = user.LastWarWin.ToString("yyyy-MM-dd HH:mm:ss");

            if (user.LastWarWin.Year == 1)
            {
                lastWarWin = "N/A";
            }

            EmbedBuilder?builder = new EmbedBuilder()
                                   .WithColor(GetColor(Context))
                                   .WithFooter("All times in UTC, all dates YYYY-MM-DD.")
                                   .AddField("Balance", $"{UnitOfMoney}{user.Balance:n2}", true)
                                   .AddField("Net Worth", $"{UnitOfMoney}{user.NetWorth:n2}", true)
                                   .AddField("Daily Streak", user.DailyStreak, true)
                                   .AddField("Siege Mentions", user.SiegePing, true)
                                   .AddField("War Mentions", user.WarPing, true)
                                   .AddField("Race Wins", user.RaceWins, true)
                                   .AddField("Siege Wins", user.SiegeWins, true)
                                   .AddField("War Wins", user.WarWins, true)
                                   .AddField("Last Daily", lastDaily, true)
                                   .AddField("Last Race Win", lastRaceWin, true)
                                   .AddField("Last Scavenge", lastScavenge, true)
                                   .AddField("Last Siege Win", lastSiegeWin, true)
                                   .AddField("Last War Win", lastWarWin, true);

            AddAuthor(Context, user, builder);

            if (user.Stage == 2)
            {
                builder.AddField("Stage", user.Stage, true)
                .AddField("Shield", user.GetShield()?.Name ?? "None", true)
                .AddField("Spikes", user.GetSpikes()?.Name ?? "None", true);
            }

            var weaponOutput = new StringBuilder();

            foreach (Item item in user.Items.Select(item => Item.Find <Item>(item.Key)))
            {
                if (item is Weapon weapon)
                {
                    weaponOutput.AppendLine(weapon.ToString());
                }
            }

            if (weaponOutput.Length != 0)
            {
                builder.AddField("Weapons", weaponOutput.ToString());
            }

            await ReplyAsync(embed : builder.Build());
        }
예제 #23
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task ItemCommand([Remainder] Item item)
        {
            var user = (await MarbleBotUser.Find(Context)) !;

            if (item.Stage > user.Stage)
            {
                await ReplyAsync(embed : new EmbedBuilder()
                                 .WithColor(GetColor(Context))
                                 .WithDescription($"{StageTooHighString()}\n\nYou are unable to view information about this item!")
                                 .WithTitle(item.Name)
                                 .Build());

                return;
            }

            string       price   = item.Price == -1 ? "N/A" : $"{UnitOfMoney}{item.Price:n2}";
            EmbedBuilder?builder = new EmbedBuilder()
                                   .WithColor(GetColor(Context))
                                   .WithDescription(item.Description)
                                   .WithTitle(item.Name)
                                   .AddField("ID", $"{item.Id:000}", true)
                                   .AddField("Price", price, true)
                                   .AddField("For Sale", item.OnSale ? "Yes" : "No", true)
                                   .AddField("Scavenge Location", item.ScavengeLocation, true);

            if (user.Stage > 1)
            {
                builder.AddField("Stage", item.Stage, true);
            }

            switch (item)
            {
            case Weapon weapon:
            {
                builder.AddField("Weapon Info", new StringBuilder()
                                 .AppendLine($"Class: **{weapon.WeaponClass}**")
                                 .AppendLine($"Accuracy: **{weapon.Accuracy}**%")
                                 .AppendLine($"Damage: **{weapon.Damage}**")
                                 .AppendLine($"Uses: **{weapon.Hits}**"), true);

                if (weapon.Ammo.Length != 0)
                {
                    var output = new StringBuilder();
                    foreach (int ammoId in weapon.Ammo)
                    {
                        output.AppendLine($"`[{ammoId:000}]` {Item.Find<Ammo>(ammoId.ToString("000")).Name}");
                    }

                    builder.AddField("Ammo", output.ToString(), true);
                }

                break;
            }

            case Ammo ammo:
                builder.AddField("Ammo Damage", ammo.Damage, true);
                break;

            case Spikes spikes:
                builder.AddField("Spikes Damage Boost", $"x{spikes.OutgoingDamageMultiplier}", true);
                break;

            case Shield shield:
                builder.AddField("Shield Damage Absorption", $"x{shield.IncomingDamageMultiplier}");
                break;
            }

            if (item.CraftingRecipe != null)
            {
                var output = new StringBuilder();
                foreach ((int ingredientId, int noRequired) in item.CraftingRecipe)
                {
                    output.AppendLine($"`[{ingredientId:000}]` {Item.Find<Item>(ingredientId).Name}: {noRequired}");
                }

                builder.AddField($"Crafting Recipe (produces **{item.CraftingProduced}**)", output.ToString());
            }

            await ReplyAsync(embed : builder.Build());
        }
예제 #24
0
파일: Economy.cs 프로젝트: Doc671/MarbleBot
        public async Task CraftCommand(Item requestedItem, int noOfItems = 1)
        {
            var user = (await MarbleBotUser.Find(Context)) !;

            if (!user.Items.ContainsKey(17) && !user.Items.ContainsKey(62))
            {
                await SendErrorAsync($"**{Context.User.Username}**, you need a Crafting Station to craft items!");

                return;
            }

            if (requestedItem.CraftingStationRequired == 2 && !user.Items.ContainsKey(62))
            {
                await SendErrorAsync($"**{Context.User.Username}**, your current Crafting Station cannot craft this item!");

                return;
            }

            if (requestedItem.CraftingRecipe == null)
            {
                await SendErrorAsync($"**{Context.User.Username}**, the item **{requestedItem.Name}** cannot be crafted!");

                return;
            }

            bool sufficientMaterials = requestedItem.CraftingRecipe
                                       .All(itemPair => user.Items.ContainsKey(itemPair.Key) &&
                                            itemPair.Value * noOfItems <= user.Items[itemPair.Key]);

            if (!sufficientMaterials)
            {
                await SendErrorAsync($"**{Context.User.Username}**, you do not have enough items to craft this!");

                return;
            }

            int     noCrafted       = requestedItem.CraftingProduced * noOfItems;
            var     output          = new StringBuilder();
            decimal currentNetWorth = user.NetWorth;

            foreach ((int itemId, int noRequired) in requestedItem.CraftingRecipe)
            {
                var item   = Item.Find <Item>(itemId);
                int noLost = noRequired * noOfItems;
                output.AppendLine($"`[{item.Id:000}]` {item.Name}: {noLost}");
                user.Items[itemId] -= noLost;
                user.NetWorth      -= item.Price * noOfItems;
            }

            if (!user.Items.ContainsKey(requestedItem.Id))
            {
                user.Items.Add(requestedItem.Id, noCrafted);
            }
            else
            {
                user.Items[requestedItem.Id] += noCrafted;
            }

            user.NetWorth += requestedItem.Price * noCrafted;
            MarbleBotUser.UpdateUser(user);
            await ReplyAsync(embed : new EmbedBuilder()
                             .WithColor(GetColor(Context))
                             .WithDescription($"**{Context.User.Username}** has successfully crafted **{requestedItem.Name}** x**{noCrafted}**!")
                             .WithTitle("Crafting: " + requestedItem.Name)
                             .AddField("Lost items", output.ToString())
                             .AddField("Net Worth",
                                       $"Old: {UnitOfMoney}**{currentNetWorth:n2}**\nNew: {UnitOfMoney}**{user.NetWorth:n2}**")
                             .Build());
        }
예제 #25
0
        public async Task SiegeStartCommand([Remainder] string overrideString = "")
        {
            ulong fileId = Context.IsPrivate ? Context.User.Id : Context.Guild.Id;

            if (_gamesService.Sieges.ContainsKey(fileId) && _gamesService.Sieges[fileId].Active)
            {
                await SendErrorAsync("A battle is currently ongoing!");

                return;
            }

            if (!File.Exists($"Data{Path.DirectorySeparatorChar}{fileId}.siege"))
            {
                await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                return;
            }

            // Get marbles
            List <(ulong id, string name)> rawMarbleData;

            using (var marbleList = new StreamReader($"Data{Path.DirectorySeparatorChar}{fileId}.siege"))
            {
                var formatter = new BinaryFormatter();
                if (marbleList.BaseStream.Length == 0)
                {
                    await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                    return;
                }

                rawMarbleData = (List <(ulong id, string name)>)formatter.Deserialize(marbleList.BaseStream);
            }

            if (rawMarbleData.Count == 0)
            {
                await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                return;
            }

            var marbles       = new List <SiegeMarble>();
            var marbleOutput  = new StringBuilder();
            var mentionOutput = new StringBuilder();
            int stageTotal    = 0;

            foreach ((ulong id, string name) in rawMarbleData)
            {
                MarbleBotUser user = MarbleBotUser.Find(Context, id);
                stageTotal += user.Stage;
                marbles.Add(new SiegeMarble(id, name, 0)
                {
                    Shield = user.GetShield(),
                    Spikes = user.GetSpikes()
                });

                marbleOutput.AppendLine($"**{name}** [{user.Name}#{user.Discriminator}]");
                if (user.SiegePing && Context.Client.GetUser(id).Status != UserStatus.Offline)
                {
                    mentionOutput.Append($"<@{user.Id}> ");
                }
            }

            Boss boss;

            if (!_gamesService.Sieges.TryGetValue(fileId, out Siege? currentSiege))
            {
                // Pick boss & set battle stats based on boss
                if (overrideString.Contains("override") &&
                    (_botCredentials.AdminIds.Any(id => id == Context.User.Id) || Context.IsPrivate))
                {
                    boss = Boss.GetBoss(overrideString.Split(' ')[1].RemoveChar(' '));
                }
                else
                {
                    // Choose a stage 1 or stage 2 boss depending on the stage of each participant
                    float stage = stageTotal / (float)marbles.Count;
                    if (Math.Abs(stage - 1f) < float.Epsilon)
                    {
                        boss = ChooseStageOneBoss(marbles);
                    }
                    else if (Math.Abs(stage - 2f) < float.Epsilon)
                    {
                        boss = ChooseStageTwoBoss(marbles);
                    }
                    else
                    {
                        stage--;
                        boss = _randomService.Rand.NextDouble() < stage
                            ? ChooseStageTwoBoss(marbles)
                            : ChooseStageOneBoss(marbles);
                    }
                }

                _gamesService.Sieges.TryAdd(fileId,
                                            currentSiege = new Siege(Context, _gamesService, _randomService, boss, marbles));
            }
            else
            {
                boss = currentSiege.Boss;
                currentSiege.Marbles = marbles;
            }

            int marbleHealth = ((int)boss.Difficulty + 2) * 5;

            foreach (SiegeMarble marble in marbles)
            {
                marble.MaxHealth = marbleHealth;
            }

            var builder = new EmbedBuilder()
                          .WithColor(GetColor(Context))
                          .WithDescription("Get ready! Use `mb/siege attack` to attack and `mb/siege grab` to grab power-ups when they appear!")
                          .WithTitle("The Siege has begun! :crossed_swords:")
                          .WithThumbnailUrl(boss.ImageUrl)
                          .AddField($"Marbles: **{marbles.Count}**", marbleOutput.ToString())
                          .AddField($"Boss: **{boss.Name}**", new StringBuilder()
                                    .AppendLine($"Health: **{boss.Health}**")
                                    .AppendLine($"Attacks: **{boss.Attacks.Length}**")
                                    .AppendLine($"Difficulty: **{boss.Difficulty} {(int)boss.Difficulty}**/10")
                                    .ToString());

            // Siege Start
            IUserMessage countdownMessage = await ReplyAsync("**3**");

            await Task.Delay(1000);

            await countdownMessage.ModifyAsync(m => m.Content = "**2**");

            await Task.Delay(1000);

            await countdownMessage.ModifyAsync(m => m.Content = "**1**");

            await Task.Delay(1000);

            await countdownMessage.ModifyAsync(m => m.Content = "**BEGIN THE SIEGE!**");

            await ReplyAsync(embed : builder.Build());

            currentSiege.Start();

            if (mentionOutput.Length != 0 && _botCredentials.AdminIds.Any(id => id == Context.User.Id) &&
                !overrideString.Contains("noping"))
            {
                await ReplyAsync(mentionOutput.ToString());
            }
        }
예제 #26
0
        public async Task RaceStartCommand()
        {
            ulong fileId = Context.IsPrivate ? Context.User.Id : Context.Guild.Id;

            if (!File.Exists($"Data{Path.DirectorySeparatorChar}{fileId}.race"))
            {
                await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                return;
            }

            var builder = new EmbedBuilder()
                          .WithColor(GetColor(Context));
            int marbleCount = 0;
            var marbles     = new List <(ulong id, string name)>();

            using (var marbleList = new StreamReader($"Data{Path.DirectorySeparatorChar}{fileId}.race"))
            {
                if (marbleList.BaseStream.Length == 0)
                {
                    await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                    return;
                }

                var formatter = new BinaryFormatter();
                marbles     = (List <(ulong, string)>)formatter.Deserialize(marbleList.BaseStream);
                marbleCount = marbles.Count;
            }

            ulong[] marbleIds = marbles.Select(marbleInfo => marbleInfo.id).ToArray();

            if (marbleCount == 0)
            {
                await SendErrorAsync($"**{Context.User.Username}**, no-one is signed up!");

                return;
            }

            // Get the death messages
            var messages = new List <string>();

            using (var messageFile = new StreamReader($"Resources{Path.DirectorySeparatorChar}RaceDeathMessages.txt"))
            {
                while (!messageFile.EndOfStream)
                {
                    messages.Add((await messageFile.ReadLineAsync()) !);
                }
            }

            // Race start
            builder.WithTitle("The race has started!");
            var message = await ReplyAsync(embed : builder.Build());

            await Task.Delay(1500);

            for (int alive = marbleCount; alive > 1; alive--)
            {
                int eliminatedIndex = _randomService.Rand.Next(0, marbles.Count);

                string deathMessage = messages[_randomService.Rand.Next(0, messages.Count - 1)];

                builder.AddField($"{Bold(marbles[eliminatedIndex].name)} is eliminated!",
                                 $"{marbles[eliminatedIndex].name} {deathMessage} and is now out of the competition!");

                // A special message may be displayed depending on the name of last place
                if (alive == marbleCount)
                {
                    string json = await File.ReadAllTextAsync($"Resources{Path.DirectorySeparatorChar}RaceSpecialMessages.json");

                    var messageDict = JsonSerializer.Deserialize <Dictionary <string, string> >(json) !;
                    var marbleName  = marbles[eliminatedIndex].name.ToLower().RemoveChar(' ');
                    if (messageDict.ContainsKey(marbleName))
                    {
                        builder.WithDescription($"*{messageDict[marbleName]}*");
                    }
                }

                marbles.RemoveAt(eliminatedIndex);
                await message.ModifyAsync(msg => msg.Embed = builder.Build());

                await Task.Delay(1500);
            }

            // Race finish
            (ulong winningMarbleId, string winningMarbleName) = marbles[0];

            string boldedWinningMarbleName = Bold(winningMarbleName);

            builder.AddField($"{boldedWinningMarbleName} wins!", $"{winningMarbleName} is the winner!");

            if (marbleCount > 1)
            {
                await using var racers = new StreamWriter($"Data{Path.DirectorySeparatorChar}RaceWinners.txt", true);
                await racers.WriteLineAsync(winningMarbleName);
            }

            await message.ModifyAsync(msg => msg.Embed = builder.Build());

            await ReplyAsync($":trophy: | {boldedWinningMarbleName} won the race!");

            // Reward winner
            var user = MarbleBotUser.Find(winningMarbleId);

            if ((DateTime.UtcNow - user.LastRaceWin).TotalHours > 6)
            {
                int noOfSameUser = marbleIds.Count(marbleId => marbleId == winningMarbleId);

                decimal gift = (decimal)MathF.Round(((float)marbleCount / noOfSameUser - 1) * 100, 2);
                if (gift > 0)
                {
                    if (user.Items.ContainsKey(83))
                    {
                        gift *= 3;
                    }

                    user.Balance    += gift;
                    user.NetWorth   += gift;
                    user.LastRaceWin = DateTime.UtcNow;
                    user.RaceWins++;
                    MarbleBotUser.UpdateUser(user);
                    await ReplyAsync($"**{user.Name}** won {UnitOfMoney}**{gift:n2}** for winning the race!");
                }
            }

            await using (var marbleList = new StreamWriter($"Data{Path.DirectorySeparatorChar}{fileId}.race", false))
            {
                await marbleList.WriteAsync("");
            }
        }
예제 #27
0
        public async Task AdviceCommand()
        {
            MarbleBotUser user = MarbleBotUser.Find(Context);
            string        msg;

            if (user.Items.ContainsKey(78))
            {
                msg = new StringBuilder().Append("Combine the terror-inducing essence of the bosses you have just ")
                      .AppendLine("defeated with another similar, yet different liquid. Be careful with the product.")
                      .Append("\n**TO ADVANCE:** Craft the **Essence of Corruption** (ID `079`).")
                      .ToString();
            }
            else if (user.Items.ContainsKey(66) || user.Items.ContainsKey(71) || user.Items.ContainsKey(74) ||
                     user.Items.ContainsKey(80))
            {
                msg = new StringBuilder().Append("Your equipment will prove very useful in the upcoming battles.")
                      .AppendLine("Seek the Chest of sentience and the Scary Face to test your newfound power.")
                      .Append("\n**TO ADVANCE:** Obtain the **Raw Essence of Horror** (ID `078`) from Chest or Scary Face.")
                      .ToString();
            }
            else if (user.Items.ContainsKey(81))
            {
                msg = new StringBuilder().Append("There is a way to increase the offensive capabilities of a marble.")
                      .AppendLine("Form a covering of spikes, made of iron, steel or even infernite.")
                      .Append("\n**TO ADVANCE:** Craft **Iron Spikes** (ID `066`), **Steel Spikes** (ID `071`) or **Infernite Spikes** (ID `074`).")
                      .ToString();
            }
            else if (user.Items.ContainsKey(63))
            {
                msg = new StringBuilder().Append("The world now contains a plethora of treasures for you to gather.")
                      .AppendLine("Craft the drill of chromium to allow you to extract the ore of the Violet Volcanoes.")
                      .Append("\n**TO ADVANCE:** Craft the **Chromium Drill** (ID `081`).")
                      .ToString();
            }
            else if (user.Items.ContainsKey(62))
            {
                msg = new StringBuilder()
                      .Append("Before you can successfully take on the new terrors roaming the land, ")
                      .AppendLine("you must first improve your equipment. Use Destroyer's plating to craft your own shield.")
                      .Append("\n**TO ADVANCE:** Craft the **Coating of Destruction** (ID `063`).")
                      .ToString();
            }
            else if (user.Stage == 2)
            {
                msg = new StringBuilder()
                      .Append("The cyborg's defeat has both given you new options and caught the attention of ")
                      .AppendLine("even more powerful foes. Head to its remains and gather the resources to upgrade your workstation.")
                      .Append("\n**TO ADVANCE:** Craft the **Crafting Station Mk.II** (ID `062`).")
                      .ToString();
            }
            else if (user.Items.ContainsKey(53) && user.Items.ContainsKey(57))
            {
                msg = new StringBuilder()
                      .Append("You have done very well, and have forged the best with the resources available ")
                      .AppendLine("to you. There is more to this world, however. Gather your allies and seek the cyborg Destroyer.")
                      .Append("\n**TO ADVANCE:** Defeat Destroyer. Item `091` may provide assistance.")
                      .ToString();
            }
            else if (user.Items.ContainsKey(53))
            {
                msg = new StringBuilder()
                      .Append("The Trebuchet Array is a potent weapon, albeit rather inaccurate. To assist ")
                      .AppendLine("in your battles, create the Rocket Boots, which shall help you evade their menacing attacks.")
                      .Append("\n**TO ADVANCE:** Craft the **Rocket Boots** (ID `057`).")
                      .ToString();
            }
            else if (user.Items.ContainsKey(17))
            {
                msg = new StringBuilder()
                      .Append("With your workstation, forge the Trebuchet Array from the different woods found ")
                      .AppendLine("in the forest. You will have to create three separate trebuchets first, then combine them.")
                      .Append("\n**TO ADVANCE:** Craft the **Trebuchet Array** (ID `053`).")
                      .ToString();
            }
            else if (user.LastScavenge.DayOfYear != 1 || user.LastScavenge.Year != 2019)
            {
                msg = new StringBuilder()
                      .Append("The items you have gathered are likely unable to be used in their current form. ")
                      .AppendLine("You must find a way to obtain a Crafting Station.")
                      .Append("\n**TO ADVANCE:** Obtain the **Crafting Station Mk.I** (ID `017`) via dailies.")
                      .ToString();
            }
            else if (user.NetWorth > 1000)
            {
                msg = new StringBuilder()
                      .Append("Well done. Your next goal is to gather for items at Canary Beach and Tree Wurld. ")
                      .AppendLine("Use `mb/scavenge help` if you are unsure of how to proceed.")
                      .Append("\n**TO ADVANCE:** Successfully complete a Scavenge.")
                      .ToString();
            }
            else
            {
                msg = new StringBuilder()
                      .Append($"Welcome! Your first task is to gain {UnitOfMoney}1000! If you need help ")
                      .AppendLine("earning money, try using `mb/daily`, `mb/race` or `mb/siege`.")
                      .Append($"\n**TO ADVANCE:** Obtain {UnitOfMoney}1000.")
                      .ToString();
            }

            await ReplyAsync(embed : new EmbedBuilder()
                             .WithColor(GetColor(Context))
                             .WithDescription(msg)
                             .WithTitle($"Advice: {Context.User.Username}")
                             .Build());
        }