private static void HandleOpenBox(GameSession session, IReadOnlyCollection <Item> items, int amount) { int opened = 0; OpenBoxResult result = OpenBoxResult.Success; foreach (Item item in items) { for (int i = opened; i < amount; i++) { if (item.Amount <= 0) { break; } if (!ItemBoxHelper.GiveItemFromOpenBox(session, item, out result)) { break; } opened++; } } session.Send(ItemUsePacket.Use(items.First().Id, opened, result)); }
public static PacketWriter Use(int id, int amount, OpenBoxResult openBoxResult) { PacketWriter pWriter = PacketWriter.Of(SendOp.ItemUse); pWriter.WriteInt(id); pWriter.WriteInt(amount); pWriter.Write(openBoxResult); return(pWriter); }
public static bool GiveItemFromSelectBox(GameSession session, Item sourceItem, int index, out OpenBoxResult result) { result = OpenBoxResult.Success; SelectItemBox box = sourceItem.Function.SelectItemBox; ItemDropMetadata metadata = ItemDropMetadataStorage.GetItemDropMetadata(box.BoxId); if (metadata == null) { result = OpenBoxResult.UnableToOpen; return(false); } IInventory inventory = session.Player.Inventory; // Select boxes disregards group ID. Adding these all to a filtered list List <DropGroupContent> dropContentsList = new(); foreach (DropGroup group in metadata.DropGroups) { foreach (DropGroupContent dropGroupContent in group.Contents) { if (dropGroupContent.SmartDropRate == 100) { List <Job> recommendJobs = ItemMetadataStorage.GetRecommendJobs(dropGroupContent.ItemIds.First()); if (recommendJobs.Contains(session.Player.Job) || recommendJobs.Contains(Job.None)) { dropContentsList.Add(dropGroupContent); } continue; } dropContentsList.Add(dropGroupContent); } } DropGroupContent dropContents = dropContentsList[index]; int amount = Random.Shared.Next((int)dropContents.MinAmount, (int)dropContents.MaxAmount); foreach (int id in dropContents.ItemIds) { if (inventory.CanHold(id, amount)) { continue; } result = OpenBoxResult.InventoryFull; return(false); } inventory.ConsumeItem(session, sourceItem.Uid, 1); foreach (int id in dropContents.ItemIds) { Item newItem = new(id, amount, dropContents.Rarity) { EnchantLevel = dropContents.EnchantLevel }; newItem.Stats = new(newItem); if (inventory.CanHold(newItem)) { inventory.AddItem(session, newItem, true); continue; } result = OpenBoxResult.InventoryFull; MailHelper.InventoryWasFull(newItem, session.Player.CharacterId); } return(true); }
public static bool GiveItemFromOpenBox(GameSession session, Item item, out OpenBoxResult boxResult) { boxResult = OpenBoxResult.Success; OpenItemBox box = item.Function.OpenItemBox; ItemDropMetadata metadata = ItemDropMetadataStorage.GetItemDropMetadata(box.BoxId); if (metadata == null) { session.Send(NoticePacket.Notice("No items found", NoticeType.Chat)); boxResult = OpenBoxResult.UnableToOpen; return(false); } if (box.AmountRequired > item.Amount) { boxResult = OpenBoxResult.UnableToOpen; return(false); } IInventory inventory = session.Player.Inventory; List <Item> rewards = new(); // Receive one item from each drop group if (box.ReceiveOneItem) { foreach (DropGroup group in metadata.DropGroups) { bool receivedItem = false; // Randomize the contents IOrderedEnumerable <DropGroupContent> dropContent = group.Contents.OrderBy(_ => Random.Shared.Next()); foreach (DropGroupContent content in dropContent) { // If player has already received an item from this group, skip other contents if (box.ReceiveOneItem && receivedItem) { continue; } List <Item> items = GetItemsFromDropGroup(content, session.Player, item); foreach (Item newItem in items) { receivedItem = true; rewards.Add(newItem); } } } } else { // receive all items from each drop group foreach (DropGroup group in metadata.DropGroups) { foreach (DropGroupContent dropContent in group.Contents) { List <Item> items = GetItemsFromDropGroup(dropContent, session.Player, item); rewards.AddRange(items); } } } // Check if any inventory of the rewards is full if (rewards.Any(reward => inventory.GetFreeSlots(reward.InventoryTab) <= 0)) { boxResult = OpenBoxResult.InventoryFull; return(false); } // Remove the box and required items if (box.RequiredItemId > 0) { Item requiredItem = inventory.GetByUid(box.RequiredItemId); if (requiredItem is null) { boxResult = OpenBoxResult.UnableToOpen; return(false); } inventory.ConsumeItem(session, requiredItem.Uid, 1); } inventory.ConsumeItem(session, item.Uid, box.AmountRequired); // give the rewards foreach (Item reward in rewards) { reward.Uid = DatabaseManager.Items.Insert(reward); if (inventory.CanHold(reward)) { inventory.AddItem(session, reward, true); continue; } boxResult = OpenBoxResult.InventoryFull; MailHelper.InventoryWasFull(reward, session.Player.CharacterId); } return(true); }