public async Task <bool> Buy(ApplicationUser user, SocketMessage message, ShopBuyOption option) { var shop = GetForName(option.Name); if (shop == null) { var allShopsStr = GetNames(); await message.Channel.SendMessageAsync($"Cannot find shop. Available shops: {allShopsStr}"); return(false); } var isIntegerItem = int.TryParse(option.ItemNameOrId, out var itemId); ShopItem shopItem = null; if (isIntegerItem) { shopItem = shop.Items.FirstOrDefault(t => t.Item.ItemId == itemId); } else { shopItem = shop.Items.FirstOrDefault(t => ItemDefinition.GetItemName(t.Item.ItemId).Contains(option.ItemNameOrId, StringComparison.InvariantCultureIgnoreCase)); } if (shopItem == null) { await message.Channel.SendMessageAsync($"{option.ItemNameOrId} not found."); return(false); } var currencyAmount = user.Bank.GetAmount(shop.Currency); var currencyName = ItemDefinition.GetItemName(shop.Currency); var amount = ((ulong?)option.Amount) ?? shopItem.Item.Amount; amount = Math.Min(shopItem.Item.Amount, amount); var itemName = ItemDefinition.GetItemName(shopItem.Item.ItemId); var totalPrice = amount * (ulong)shopItem.Price; var maxAmountCanBuy = (ulong)Math.Floor(currencyAmount / (double)shopItem.Price); if (maxAmountCanBuy == 0) { await message.Channel.SendMessageAsync($"You do not have enough {currencyName} to buy {amount} x {itemName}. You need {(totalPrice - currencyAmount)} more {currencyName}."); return(false); } amount = Math.Min(maxAmountCanBuy, amount); if (option.Confirm.GetValueOrDefault()) { await message.Channel.SendMessageAsync($"{user.Mention} buys {amount} x {itemName} for {totalPrice} {currencyName}."); user.Bank.Remove(shop.Currency, totalPrice); user.Bank.Add(shopItem.Item.ItemId, amount); } else { var reply = _replyAwaiter.CreateReply(new CurrentTask { ChannelId = message.Channel.Id, MessageId = user.CurrentTask.MessageId, UserId = user.Id, User = user, Command = $"{Parser.Default.FormatCommandLine(option)} --confirm=true" }); await message.Channel.SendMessageAsync($"Press `+{reply.ConfirmChar}` to confirm buying {itemName} x {amount} for {totalPrice} {currencyName}."); await _replyAwaiter.Add(reply); } return(true); }
public async Task Process() { while (!_quit) { List <CurrentTask> tasks = null; using (var context = _contextFactory.Create()) { var now = DateTime.Now; tasks = context.CurrentTasks.AsQueryable() .Include(t => t.ExpGains) .Include(t => t.Items) .Where(t => !t.Notified && now > t.UnlockTime) .ToList(); if (tasks.Any()) { var userIds = tasks.Select(t => t.UserId).ToList(); var users = context.Users.AsQueryable() .Include(t => t.Items) .Include(t => t.Equipment) .Include(t => t.CurrentTask) .Include(t => t.SkillSet) .ThenInclude(t => t.Skills) .Where(t => userIds.Contains(t.Id)).ToList(); users.ForEach(user => { var bankUpdateRequired = tasks.Where(t => t.UserId == user.Id && t.Items != null && t.Items.Any()).Any(); if (bankUpdateRequired) { context.RemoveRange(user.Items); user.Bank = new Inventory(BankConstants.Size, Inventory.StackMode.STACK_ALWAYS); user.Bank.CopyTo(user.Items.Select(t => t.Item)); } }); await context.SaveChangesAsync(); foreach (var task in tasks) { var user = users.FirstOrDefault(t => t.Id == task.UserId); if (user != null) { if (task.Items != null && task.Items.Any()) { foreach (var item in task.Items) { user.Bank.Add(item.Item); } await BankSaver.SaveBank(context, user, false); } if (task.ExpGains.Any()) { foreach (var xpGain in task.ExpGains) { user.SkillSet.AddExperience(xpGain.Skill, xpGain.Amount); context.Update(user.SkillSet); } } } var repeatReply = _replyAwaiter.CreateReply(task); var channel = _discordBot.Client.GetChannel(task.ChannelId) as IMessageChannel; var xpStr = string.Join('\n', task.ExpGains.Select(xpGain => $"{_discordBot.GetEmote(Skill.GetName(xpGain.Skill))} +{xpGain.Amount} XP Gained, Level: {user.SkillSet.GetLevel(xpGain.Skill)}, Total XP: {user.SkillSet.GetExp(xpGain.Skill)}")); xpStr += $"\n Press `+{repeatReply.ConfirmChar}` to repeat"; await _replyAwaiter.Add(repeatReply); await channel.SendMessageAsync(string.Format(task.CompletionMessage, xpStr)); context.RemoveRange(task.Items); context.RemoveRange(task.ExpGains); task.Notified = true; } context.UpdateRange(tasks); await context.SaveChangesAsync(); } } await Task.Delay(TimeSpan.FromMinutes(1)); } }