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));
    }
Ejemplo n.º 2
0
    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);
    }
Ejemplo n.º 3
0
    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);
    }
Ejemplo n.º 4
0
    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);
    }