public static void GiveItemFromSelectBox(GameSession session, Item sourceItem, int index)
    {
        SelectItemBox    box      = sourceItem.Function.SelectItemBox;
        ItemDropMetadata metadata = ItemDropMetadataStorage.GetItemDropMetadata(box.BoxId);

        if (metadata == null)
        {
            session.Send(NoticePacket.Notice("No items found", NoticeType.Chat));
            return;
        }

        Inventory inventory = session.Player.Inventory;

        inventory.ConsumeItem(session, sourceItem.Uid, 1);

        // 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];

        Random rng    = RandomProvider.Get();
        int    amount = rng.Next((int)dropContents.MinAmount, (int)dropContents.MaxAmount);

        foreach (int id in dropContents.ItemIds)
        {
            Item newItem = new(id)
            {
                Enchants = dropContents.EnchantLevel,
                Amount   = amount,
                Rarity   = dropContents.Rarity
            };
            inventory.AddItem(session, newItem, true);
        }
    }
Exemple #2
0
        private static void HandleSelectBox(GameSession session, Dictionary <long, Item> items, SelectItemBox box, int index, int amount)
        {
            ItemDropMetadata metadata = ItemDropMetadataStorage.GetItemDropMetadata(box.BoxId);
            int opened = 0;

            foreach (KeyValuePair <long, Item> kvp in items)
            {
                Item item = kvp.Value;

                for (int i = opened; i < amount; i++)
                {
                    if (item.Amount <= 0)
                    {
                        break;
                    }

                    opened++;
                    ItemBoxHelper.GiveItemFromSelectBox(session, item, index);
                }
            }

            session.Send(ItemUsePacket.Use(items.FirstOrDefault().Value.Id, amount));
        }
    private static void HandleInteract(GameSession session, PacketReader packet)
    {
        Player player = session.Player;

        string id = packet.ReadString();

        session.FieldManager.State.InteractObjects.TryGetValue(id, out IFieldObject <InteractObject> fieldInteractObject);
        if (fieldInteractObject is null)
        {
            return;
        }

        InteractObject interactObject = fieldInteractObject.Value;

        InteractObjectMetadata metadata = InteractObjectMetadataStorage.GetInteractObjectMetadata(interactObject.InteractId);

        QuestManager.OnInteractObject(player, interactObject.InteractId);

        switch (interactObject.Type)
        {
        case InteractObjectType.Binoculars:
            session.Send(InteractObjectPacket.Use(interactObject));
            break;

        case InteractObjectType.Ui:
            session.Send(InteractObjectPacket.Use(interactObject));
            break;

        case InteractObjectType.RankBoard:
            session.Send(WebOpenPacket.Open(metadata.Web.Url));
            break;

        case InteractObjectType.AdBalloon:
            session.Send(PlayerHostPacket.AdBalloonWindow((AdBalloon)interactObject));
            break;

        case InteractObjectType.Gathering:
            GatheringHelper.HandleGathering(session, metadata.Gathering.RecipeId, out int numDrop);
            session.Send(InteractObjectPacket.Use(interactObject, (short)(numDrop > 0 ? 0 : 1), numDrop));
            break;

        case InteractObjectType.Common:
            // Unsure if all interact objects need to be set as disabled.
            interactObject.State = InteractObjectState.Disable;

            session.Send(InteractObjectPacket.Update(interactObject));
            session.Send(InteractObjectPacket.Interact(interactObject));

            foreach ((int questId, QuestState state) in metadata.Quests)
            {
                if (!player.QuestData.TryGetValue(questId, out QuestStatus questStatus) || questStatus.State != state)
                {
                    continue;
                }

                interactObject.State = InteractObjectState.Activated;
                session.Send(InteractObjectPacket.Update(interactObject));
            }

            DropItems();

            TrophyManager.OnObjectInteract(player, interactObject.InteractId);

            if (interactObject is MapChest)
            {
                // Unsure if setting as activated is specific of map chests
                interactObject.State = InteractObjectState.Activated;

                // Delayed removal of the chest
                Task.Run(async() =>
                {
                    await Task.Delay(TimeSpan.FromSeconds(10));
                    session.FieldManager.State.RemoveInteractObject(interactObject.Id);

                    session.FieldManager.BroadcastPacket(InteractObjectPacket.Update(interactObject));
                    session.FieldManager.BroadcastPacket(InteractObjectPacket.Remove(interactObject));
                });
            }

            return;
        }

        session.Send(InteractObjectPacket.Interact(interactObject));

        void DropItems()
        {
            foreach (int boxId in metadata.Drop.IndividualDropBoxId)
            {
                ItemDropMetadata itemDropMetadataStorage = ItemDropMetadataStorage.GetItemDropMetadata(boxId);
                if (itemDropMetadataStorage is null)
                {
                    continue;
                }

                foreach (DropGroup dropGroup in itemDropMetadataStorage.DropGroups)
                {
                    foreach (DropGroupContent dropGroupContent in dropGroup.Contents)
                    {
                        foreach (int itemId in dropGroupContent.ItemIds)
                        {
                            int  amount = Random.Shared.Next((int)dropGroupContent.MinAmount, (int)dropGroupContent.MaxAmount);
                            Item item   = new(itemId, amount, dropGroupContent.Rarity);

                            session.FieldManager.AddItem(session.Player.FieldPlayer, item);
                        }
                    }
                }
            }

            foreach (int boxId in metadata.Drop.GlobalDropBoxId)
            {
                ItemDropMetadata itemDropMetadataStorage = ItemDropMetadataStorage.GetItemDropMetadata(boxId);
                if (itemDropMetadataStorage is null)
                {
                    continue;
                }

                foreach (DropGroup dropGroup in itemDropMetadataStorage.DropGroups)
                {
                    foreach (DropGroupContent dropGroupContent in dropGroup.Contents)
                    {
                        foreach (int itemId in dropGroupContent.ItemIds)
                        {
                            int  amount = Random.Shared.Next((int)dropGroupContent.MinAmount, (int)dropGroupContent.MaxAmount);
                            Item item   = new(itemId, amount, dropGroupContent.Rarity);

                            session.FieldManager.AddItem(session.Player.FieldPlayer, item);
                        }
                    }
                }
            }
        }
    }
    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);
    }
    public static void GiveItemFromOpenBox(GameSession session, Item item)
    {
        OpenItemBox      box      = item.Function.OpenItemBox;
        ItemDropMetadata metadata = ItemDropMetadataStorage.GetItemDropMetadata(box.BoxId);

        if (metadata == null)
        {
            session.Send(NoticePacket.Notice("No items found", NoticeType.Chat));
            return;
        }

        if (box.AmountRequired > item.Amount)
        {
            return;
        }

        Inventory inventory = session.Player.Inventory;

        if (box.RequiredItemId > 0)
        {
            Item requiredItem = inventory.Items[box.RequiredItemId];
            if (requiredItem == null)
            {
                return;
            }

            inventory.ConsumeItem(session, requiredItem.Uid, 1);
        }

        inventory.ConsumeItem(session, item.Uid, box.AmountRequired);

        Random rng = RandomProvider.Get();

        // Receive one item from each drop group
        if (box.ReceiveOneItem)
        {
            foreach (DropGroup group in metadata.DropGroups)
            {
                //randomize the contents
                List <DropGroupContent> contentList = group.Contents.OrderBy(x => rng.Next()).ToList();
                foreach (DropGroupContent dropContent in contentList)
                {
                    List <Item> items = GetItemsFromDropGroup(dropContent, session.Player.Gender, session.Player.Job);
                    foreach (Item newItem in items)
                    {
                        inventory.AddItem(session, newItem, true);
                    }
                }
            }
            return;
        }

        // 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.Gender, session.Player.Job);
                foreach (Item newItem in items)
                {
                    inventory.AddItem(session, newItem, true);
                }
            }
        }
    }