// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.inventory;

import com.hypixel.hytale.server.core.inventory.container.filter.FilterActionType;
import java.util.Objects;
import java.util.function.Function;
import com.hypixel.hytale.protocol.BlockMaterial;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.protocol.PickupLocation;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.fastutil.shorts.Short2ObjectConcurrentHashMap;
import java.util.Collection;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import com.hypixel.hytale.server.core.inventory.transaction.ListTransaction;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemArmor;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.inventory.transaction.MoveTransaction;
import java.util.Iterator;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction;
import com.hypixel.hytale.server.core.entity.entities.player.windows.ItemContainerWindow;
import com.hypixel.hytale.server.core.entity.entities.player.windows.Window;
import javax.annotation.Nonnull;
import com.hypixel.hytale.protocol.SmartMoveType;
import com.hypixel.hytale.server.core.entity.InteractionChain;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
import com.hypixel.hytale.protocol.BlockPosition;
import com.hypixel.hytale.protocol.Vector3f;
import com.hypixel.hytale.protocol.InteractionChainData;
import com.hypixel.hytale.server.core.util.UUIDUtil;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.none.ChangeActiveSlotInteraction;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;
import com.hypixel.hytale.server.core.entity.InteractionManager;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemUtility;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemWeapon;
import com.hypixel.hytale.server.core.entity.StatModifiersManager;
import com.hypixel.hytale.server.core.inventory.transaction.Transaction;
import com.hypixel.hytale.event.IEventDispatcher;
import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction;
import com.hypixel.hytale.event.IEvent;
import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.inventory.container.ItemContainerUtil;
import com.hypixel.hytale.server.core.inventory.container.SimpleItemContainer;
import com.hypixel.hytale.server.core.inventory.container.EmptyItemContainer;
import com.hypixel.hytale.event.EventRegistration;
import com.hypixel.hytale.server.core.inventory.container.SortType;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.inventory.container.CombinedItemContainer;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import java.util.concurrent.atomic.AtomicBoolean;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.protocol.packets.inventory.UpdatePlayerInventory;
import com.hypixel.hytale.server.core.io.NetworkSerializable;

public class Inventory implements NetworkSerializable<UpdatePlayerInventory>
{
    public static final short DEFAULT_HOTBAR_CAPACITY = 9;
    public static final short DEFAULT_UTILITY_CAPACITY = 4;
    public static final short DEFAULT_TOOLS_CAPACITY = 23;
    public static final short DEFAULT_ARMOR_CAPACITY;
    public static final short DEFAULT_STORAGE_ROWS = 4;
    public static final short DEFAULT_STORAGE_COLUMNS = 9;
    public static final short DEFAULT_STORAGE_CAPACITY = 36;
    public static final int HOTBAR_SECTION_ID = -1;
    public static final int STORAGE_SECTION_ID = -2;
    public static final int ARMOR_SECTION_ID = -3;
    public static final int UTILITY_SECTION_ID = -5;
    public static final int TOOLS_SECTION_ID = -8;
    public static final int BACKPACK_SECTION_ID = -9;
    public static final byte INACTIVE_SLOT_INDEX = -1;
    public static final int VERSION = 4;
    public static final BuilderCodec<Inventory> CODEC;
    private final AtomicBoolean isDirty;
    private final AtomicBoolean needsSaving;
    private ItemContainer storage;
    private ItemContainer armor;
    private ItemContainer hotbar;
    private ItemContainer utility;
    @Deprecated
    private ItemContainer tools;
    private ItemContainer backpack;
    private CombinedItemContainer combinedHotbarFirst;
    private CombinedItemContainer combinedStorageFirst;
    private CombinedItemContainer combinedBackpackStorageHotbar;
    private CombinedItemContainer combinedStorageHotbarBackpack;
    private CombinedItemContainer combinedArmorHotbarStorage;
    private CombinedItemContainer combinedArmorHotbarUtilityStorage;
    private CombinedItemContainer combinedHotbarUtilityConsumableStorage;
    private CombinedItemContainer combinedEverything;
    private byte activeHotbarSlot;
    private byte activeUtilitySlot;
    private byte activeToolsSlot;
    @Nullable
    private LivingEntity entity;
    @Deprecated
    private SortType sortType;
    @Nullable
    private EventRegistration armorChange;
    @Nullable
    private EventRegistration storageChange;
    @Nullable
    private EventRegistration hotbarChange;
    @Nullable
    private EventRegistration utilityChange;
    @Nullable
    private EventRegistration toolChange;
    @Nullable
    private EventRegistration backpackChange;
    private boolean _usingToolsItem;
    
    private Inventory(final Void dummy) {
        this.isDirty = new AtomicBoolean();
        this.needsSaving = new AtomicBoolean();
        this.storage = EmptyItemContainer.INSTANCE;
        this.armor = EmptyItemContainer.INSTANCE;
        this.hotbar = EmptyItemContainer.INSTANCE;
        this.utility = EmptyItemContainer.INSTANCE;
        this.tools = EmptyItemContainer.INSTANCE;
        this.backpack = EmptyItemContainer.INSTANCE;
        this.activeUtilitySlot = -1;
        this.activeToolsSlot = -1;
        this.sortType = SortType.NAME;
        this._usingToolsItem = false;
    }
    
    public Inventory() {
        this((short)36, Inventory.DEFAULT_ARMOR_CAPACITY, (short)9, (short)4, (short)23);
    }
    
    public Inventory(final short storageCapacity, final short armorCapacity, final short hotbarCapacity, final short utilityCapacity, final short toolCapacity) {
        this((storageCapacity == 0) ? EmptyItemContainer.INSTANCE : new SimpleItemContainer(storageCapacity), (armorCapacity == 0) ? EmptyItemContainer.INSTANCE : new SimpleItemContainer(armorCapacity), (hotbarCapacity == 0) ? EmptyItemContainer.INSTANCE : new SimpleItemContainer(hotbarCapacity), (utilityCapacity == 0) ? EmptyItemContainer.INSTANCE : new SimpleItemContainer(utilityCapacity), (toolCapacity == 0) ? EmptyItemContainer.INSTANCE : new SimpleItemContainer(toolCapacity), EmptyItemContainer.INSTANCE);
    }
    
    public Inventory(final ItemContainer storage, final ItemContainer armor, final ItemContainer hotbar, final ItemContainer utility, final ItemContainer tools, final ItemContainer backpack) {
        this.isDirty = new AtomicBoolean();
        this.needsSaving = new AtomicBoolean();
        this.storage = EmptyItemContainer.INSTANCE;
        this.armor = EmptyItemContainer.INSTANCE;
        this.hotbar = EmptyItemContainer.INSTANCE;
        this.utility = EmptyItemContainer.INSTANCE;
        this.tools = EmptyItemContainer.INSTANCE;
        this.backpack = EmptyItemContainer.INSTANCE;
        this.activeUtilitySlot = -1;
        this.activeToolsSlot = -1;
        this.sortType = SortType.NAME;
        this._usingToolsItem = false;
        this.storage = storage;
        this.armor = ItemContainerUtil.trySetArmorFilters(armor);
        this.hotbar = hotbar;
        this.utility = ItemContainerUtil.trySetSlotFilters(utility, (type, container, slot, itemStack) -> itemStack == null || itemStack.getItem().getUtility().isUsable());
        this.tools = tools;
        this.backpack = backpack;
        this.buildCombinedContains();
        this.registerChangeEvents();
    }
    
    protected void registerChangeEvents() {
        this.storageChange = this.storage.registerChangeEvent(e -> {
            this.markChanged();
            final IEventDispatcher<IEvent, IEvent> dispatcher = (IEventDispatcher<IEvent, IEvent>)HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<String>>)LivingEntityInventoryChangeEvent.class, this.entity.getWorld().getName());
            if (dispatcher.hasListener()) {
                dispatcher.dispatch(new LivingEntityInventoryChangeEvent(this.entity, e.container(), e.transaction()));
            }
            return;
        });
        this.armorChange = this.armor.registerChangeEvent(e -> {
            this.markChanged();
            final IEventDispatcher<IEvent, IEvent> dispatcher2 = (IEventDispatcher<IEvent, IEvent>)HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<String>>)LivingEntityInventoryChangeEvent.class, this.entity.getWorld().getName());
            if (dispatcher2.hasListener()) {
                dispatcher2.dispatch(new LivingEntityInventoryChangeEvent(this.entity, e.container(), e.transaction()));
            }
            this.entity.invalidateEquipmentNetwork();
            return;
        });
        this.hotbarChange = this.hotbar.registerChangeEvent(e -> {
            this.markChanged();
            final IEventDispatcher<IEvent, IEvent> dispatcher3 = (IEventDispatcher<IEvent, IEvent>)HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<String>>)LivingEntityInventoryChangeEvent.class, this.entity.getWorld().getName());
            if (dispatcher3.hasListener()) {
                dispatcher3.dispatch(new LivingEntityInventoryChangeEvent(this.entity, e.container(), e.transaction()));
            }
            if (this.activeHotbarSlot != -1 && this.entity != null && e.transaction().wasSlotModified(this.activeHotbarSlot)) {
                final Transaction patt0$temp = e.transaction();
                if (patt0$temp instanceof final SlotTransaction slot) {
                    if (ItemStack.isEquivalentType(slot.getSlotBefore(), slot.getSlotAfter())) {
                        return;
                    }
                }
                final StatModifiersManager statModifiersManager = this.entity.getStatModifiersManager();
                this.entity.invalidateEquipmentNetwork();
                statModifiersManager.setRecalculate(true);
                final ItemStack itemStack = this.getItemInHand();
                if (itemStack != null) {
                    final ItemWeapon itemWeapon = itemStack.getItem().getWeapon();
                    if (itemWeapon != null) {
                        final int[] entityStatsToClear = itemWeapon.getEntityStatsToClear();
                        if (entityStatsToClear != null) {
                            statModifiersManager.queueEntityStatsToClear(entityStatsToClear);
                        }
                    }
                }
            }
            return;
        });
        this.utilityChange = this.utility.registerChangeEvent(e -> {
            this.markChanged();
            final IEventDispatcher<IEvent, IEvent> dispatcher4 = (IEventDispatcher<IEvent, IEvent>)HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<String>>)LivingEntityInventoryChangeEvent.class, this.entity.getWorld().getName());
            if (dispatcher4.hasListener()) {
                dispatcher4.dispatch(new LivingEntityInventoryChangeEvent(this.entity, e.container(), e.transaction()));
            }
            if (this.activeUtilitySlot != -1 && this.entity != null && e.transaction().wasSlotModified(this.activeUtilitySlot)) {
                final Transaction patt0$temp2 = e.transaction();
                if (patt0$temp2 instanceof final SlotTransaction slot2) {
                    if (ItemStack.isEquivalentType(slot2.getSlotBefore(), slot2.getSlotAfter())) {
                        return;
                    }
                }
                final StatModifiersManager statModifiersManager2 = this.entity.getStatModifiersManager();
                this.entity.invalidateEquipmentNetwork();
                statModifiersManager2.setRecalculate(true);
                final ItemStack itemStack2 = this.getUtilityItem();
                if (itemStack2 != null) {
                    final ItemUtility itemUtility = itemStack2.getItem().getUtility();
                    if (itemUtility != null) {
                        final int[] entityStatsToClear2 = itemUtility.getEntityStatsToClear();
                        if (entityStatsToClear2 != null) {
                            statModifiersManager2.queueEntityStatsToClear(entityStatsToClear2);
                        }
                    }
                }
            }
            return;
        });
        this.toolChange = this.tools.registerChangeEvent(e -> {
            this.markChanged();
            final IEventDispatcher<IEvent, IEvent> dispatcher5 = (IEventDispatcher<IEvent, IEvent>)HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<String>>)LivingEntityInventoryChangeEvent.class, this.entity.getWorld().getName());
            if (dispatcher5.hasListener()) {
                dispatcher5.dispatch(new LivingEntityInventoryChangeEvent(this.entity, e.container(), e.transaction()));
            }
            return;
        });
        this.registerBackpackListener();
    }
    
    private void registerBackpackListener() {
        this.unregisterBackpackChange();
        this.backpackChange = this.backpack.registerChangeEvent(e -> {
            this.markChanged();
            final IEventDispatcher<IEvent, IEvent> dispatcher = (IEventDispatcher<IEvent, IEvent>)HytaleServer.get().getEventBus().dispatchFor((Class<? super IEvent<String>>)LivingEntityInventoryChangeEvent.class, this.entity.getWorld().getName());
            if (dispatcher.hasListener()) {
                dispatcher.dispatch(new LivingEntityInventoryChangeEvent(this.entity, e.container(), e.transaction()));
            }
        });
    }
    
    public void unregister() {
        this.entity = null;
        if (this.storageChange != null) {
            this.storageChange.unregister();
            this.storageChange = null;
        }
        if (this.armorChange != null) {
            this.armorChange.unregister();
            this.armorChange = null;
        }
        if (this.hotbarChange != null) {
            this.hotbarChange.unregister();
            this.hotbarChange = null;
        }
        if (this.utilityChange != null) {
            this.utilityChange.unregister();
            this.utilityChange = null;
        }
        if (this.toolChange != null) {
            this.toolChange.unregister();
            this.toolChange = null;
        }
        this.unregisterBackpackChange();
    }
    
    private void unregisterBackpackChange() {
        if (this.backpackChange != null) {
            this.backpackChange.unregister();
            this.backpackChange = null;
        }
    }
    
    public void markChanged() {
        this.isDirty.set(true);
        this.needsSaving.set(true);
    }
    
    public void moveItem(final int fromSectionId, final int fromSlotId, final int quantity, final int toSectionId, final int toSlotId) {
        final ItemContainer fromContainer = this.getSectionById(fromSectionId);
        if (fromContainer == null) {
            return;
        }
        final ItemContainer toContainer = this.getSectionById(toSectionId);
        if (toContainer == null) {
            return;
        }
        if (this.entity instanceof Player && ((toSectionId == -1 && this.activeHotbarSlot == toSlotId) || (fromSectionId == -1 && this.activeHotbarSlot == fromSlotId))) {
            final ItemStack fromItem = fromContainer.getItemStack((short)fromSlotId);
            final ItemStack currentItem = toContainer.getItemStack((short)toSlotId);
            if (ItemStack.isStackableWith(fromItem, currentItem) || ItemStack.isSameItemType(fromItem, currentItem)) {
                fromContainer.moveItemStackFromSlotToSlot((short)fromSlotId, quantity, toContainer, (short)toSlotId);
                return;
            }
            final int interactionSlot = (toSectionId == -1 && this.activeHotbarSlot == toSlotId) ? toSlotId : this.activeHotbarSlot;
            final Ref<EntityStore> ref = this.entity.getReference();
            final Store<EntityStore> store = ref.getStore();
            final InteractionManager interactionManagerComponent = store.getComponent(ref, InteractionModule.get().getInteractionManagerComponent());
            if (interactionManagerComponent != null) {
                final PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
                assert playerRefComponent != null;
                final InteractionContext context = InteractionContext.forInteraction(interactionManagerComponent, ref, InteractionType.SwapFrom, store);
                context.getMetaStore().putMetaObject(Interaction.TARGET_SLOT, interactionSlot);
                context.getMetaStore().putMetaObject(ChangeActiveSlotInteraction.PLACE_MOVED_ITEM, () -> {
                    fromContainer.moveItemStackFromSlotToSlot((short)fromSlotId, quantity, toContainer, (short)toSlotId);
                    playerRefComponent.getPacketHandler().write(this.toPacket());
                    return;
                });
                final String interactions = context.getRootInteractionId(InteractionType.SwapFrom);
                final InteractionChainData data = new InteractionChainData(-1, UUIDUtil.EMPTY_UUID, null, null, null, -interactionSlot - 1, null);
                final InteractionChain chain = interactionManagerComponent.initChain(data, InteractionType.SwapFrom, context, RootInteraction.getRootInteractionOrUnknown(interactions), null, false);
                interactionManagerComponent.queueExecuteChain(chain);
                return;
            }
        }
        fromContainer.moveItemStackFromSlotToSlot((short)fromSlotId, quantity, toContainer, (short)toSlotId);
    }
    
    public void smartMoveItem(final int fromSectionId, final int fromSlotId, final int quantity, @Nonnull final SmartMoveType moveType) {
        final ItemContainer targetContainer = this.getSectionById(fromSectionId);
        if (targetContainer == null) {
            return;
        }
        Label_0419: {
            switch (moveType) {
                case EquipOrMergeStack: {
                    if (this.tryEquipArmorPart(fromSectionId, (short)fromSlotId, quantity, targetContainer, true)) {
                        return;
                    }
                    if (this.entity instanceof final Player player) {
                        for (final Window window : player.getWindowManager().getWindows()) {
                            if (window instanceof final ItemContainerWindow itemContainerWindow) {
                                itemContainerWindow.getItemContainer().combineItemStacksIntoSlot(targetContainer, (short)fromSlotId);
                            }
                        }
                    }
                    this.combinedHotbarFirst.combineItemStacksIntoSlot(targetContainer, (short)fromSlotId);
                    break;
                }
                case PutInHotbarOrWindow: {
                    if (fromSectionId >= 0) {
                        targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, this.combinedHotbarFirst);
                        return;
                    }
                    if (this.entity instanceof final Player player2) {
                        for (final Window window : player2.getWindowManager().getWindows()) {
                            if (window instanceof final ItemContainerWindow itemContainerWindow2) {
                                final ItemContainer itemContainer = itemContainerWindow2.getItemContainer();
                                final MoveTransaction<ItemStackTransaction> transaction = targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, itemContainer);
                                final ItemStack remainder = transaction.getAddTransaction().getRemainder();
                                if (ItemStack.isEmpty(remainder) || remainder.getQuantity() != quantity) {
                                    return;
                                }
                                continue;
                            }
                        }
                    }
                    if (this.tryEquipArmorPart(fromSectionId, (short)fromSlotId, quantity, targetContainer, false)) {
                        return;
                    }
                    switch (fromSectionId) {
                        case -1: {
                            targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, this.storage);
                            break Label_0419;
                        }
                        case -2: {
                            targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, this.hotbar);
                            break Label_0419;
                        }
                        default: {
                            targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, this.combinedHotbarFirst);
                            break Label_0419;
                        }
                    }
                    break;
                }
                case PutInHotbarOrBackpack: {
                    if (fromSectionId == -9) {
                        targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, this.combinedHotbarFirst);
                        break;
                    }
                    targetContainer.moveItemStackFromSlot((short)fromSlotId, quantity, this.combinedBackpackStorageHotbar);
                    break;
                }
            }
        }
    }
    
    private boolean tryEquipArmorPart(final int fromSectionId, final short fromSlotId, final int quantity, final ItemContainer targetContainer, final boolean forceEquip) {
        final ItemStack itemStack = targetContainer.getItemStack(fromSlotId);
        final Item item = itemStack.getItem();
        final ItemArmor itemArmor = item.getArmor();
        if (itemArmor != null && fromSectionId != -3 && (forceEquip || this.armor.getItemStack((short)itemArmor.getArmorSlot().ordinal()) == null)) {
            targetContainer.moveItemStackFromSlotToSlot(fromSlotId, quantity, this.armor, (short)itemArmor.getArmorSlot().ordinal());
            return true;
        }
        return false;
    }
    
    @Nullable
    public ListTransaction<MoveTransaction<ItemStackTransaction>> takeAll(final int inventorySectionId) {
        final ItemContainer sectionById = this.getSectionById(inventorySectionId);
        if (sectionById != null) {
            return sectionById.moveAllItemStacksTo(this.combinedHotbarFirst);
        }
        return null;
    }
    
    @Nullable
    public ListTransaction<MoveTransaction<ItemStackTransaction>> putAll(final int inventorySectionId) {
        final ItemContainer sectionById = this.getSectionById(inventorySectionId);
        if (sectionById != null) {
            return this.storage.moveAllItemStacksTo(sectionById);
        }
        return null;
    }
    
    @Nullable
    public ListTransaction<MoveTransaction<ItemStackTransaction>> quickStack(final int inventorySectionId) {
        final ItemContainer sectionById = this.getSectionById(inventorySectionId);
        if (sectionById != null) {
            return this.combinedHotbarFirst.quickStackTo(sectionById);
        }
        return null;
    }
    
    @Nonnull
    public List<ItemStack> dropAllItemStacks() {
        final List<ItemStack> items = new ObjectArrayList<ItemStack>();
        items.addAll(this.storage.dropAllItemStacks());
        items.addAll(this.armor.dropAllItemStacks());
        items.addAll(this.hotbar.dropAllItemStacks());
        items.addAll(this.utility.dropAllItemStacks());
        items.addAll(this.backpack.dropAllItemStacks());
        return items;
    }
    
    public void clear() {
        this.storage.clear();
        this.armor.clear();
        this.hotbar.clear();
        this.utility.clear();
        this.backpack.clear();
    }
    
    public ItemContainer getStorage() {
        return this.storage;
    }
    
    public ItemContainer getArmor() {
        return this.armor;
    }
    
    public ItemContainer getHotbar() {
        return this.hotbar;
    }
    
    public ItemContainer getUtility() {
        return this.utility;
    }
    
    public ItemContainer getTools() {
        return this.tools;
    }
    
    public ItemContainer getBackpack() {
        return this.backpack;
    }
    
    public void resizeBackpack(final short capacity, final List<ItemStack> remainder) {
        if (capacity > 0) {
            this.backpack = ItemContainer.ensureContainerCapacity(this.backpack, capacity, (Short2ObjectConcurrentHashMap.ShortFunction<ItemContainer>)SimpleItemContainer::new, remainder);
        }
        else {
            this.backpack = ItemContainer.copy(this.backpack, EmptyItemContainer.INSTANCE, remainder);
        }
        this.buildCombinedContains();
        if (this.entity != null) {
            this.registerBackpackListener();
        }
        this.markChanged();
    }
    
    public CombinedItemContainer getCombinedHotbarFirst() {
        return this.combinedHotbarFirst;
    }
    
    public CombinedItemContainer getCombinedStorageFirst() {
        return this.combinedStorageFirst;
    }
    
    public CombinedItemContainer getCombinedBackpackStorageHotbar() {
        return this.combinedBackpackStorageHotbar;
    }
    
    public CombinedItemContainer getCombinedArmorHotbarStorage() {
        return this.combinedArmorHotbarStorage;
    }
    
    public CombinedItemContainer getCombinedArmorHotbarUtilityStorage() {
        return this.combinedArmorHotbarUtilityStorage;
    }
    
    public CombinedItemContainer getCombinedHotbarUtilityConsumableStorage() {
        return this.combinedHotbarUtilityConsumableStorage;
    }
    
    public CombinedItemContainer getCombinedEverything() {
        return this.combinedEverything;
    }
    
    @Nonnull
    public ItemContainer getContainerForItemPickup(@Nonnull final Item item, final PlayerSettings playerSettings) {
        if (item.getArmor() != null) {
            return (playerSettings.armorItemsPreferredPickupLocation() == PickupLocation.Hotbar) ? this.getCombinedHotbarFirst() : this.getCombinedStorageFirst();
        }
        if (item.getWeapon() != null || item.getTool() != null) {
            return (playerSettings.weaponAndToolItemsPreferredPickupLocation() == PickupLocation.Hotbar) ? this.getCombinedHotbarFirst() : this.getCombinedStorageFirst();
        }
        if (item.getUtility().isUsable()) {
            return (playerSettings.usableItemsItemsPreferredPickupLocation() == PickupLocation.Hotbar) ? this.getCombinedHotbarFirst() : this.getCombinedStorageFirst();
        }
        BlockType blockType = item.hasBlockType() ? BlockType.getAssetMap().getAsset(item.getBlockId()) : BlockType.EMPTY;
        if (blockType == null) {
            blockType = BlockType.EMPTY;
        }
        if (blockType.getMaterial() == BlockMaterial.Solid) {
            return (playerSettings.solidBlockItemsPreferredPickupLocation() == PickupLocation.Hotbar) ? this.getCombinedHotbarFirst() : this.getCombinedStorageFirst();
        }
        return (playerSettings.miscItemsPreferredPickupLocation() == PickupLocation.Hotbar) ? this.getCombinedHotbarFirst() : this.getCombinedStorageFirst();
    }
    
    public void setActiveSlot(final int inventorySectionId, final byte slot) {
        int[] entityStatsToClear = null;
        switch (inventorySectionId) {
            case -1: {
                this.activeHotbarSlot = slot;
                final ItemStack itemStack = this.getItemInHand();
                if (itemStack == null) {
                    break;
                }
                final ItemWeapon weapon = itemStack.getItem().getWeapon();
                if (weapon == null) {
                    break;
                }
                entityStatsToClear = weapon.getEntityStatsToClear();
                break;
            }
            case -5: {
                this.activeUtilitySlot = slot;
                final ItemStack itemStack = this.getUtilityItem();
                if (itemStack == null) {
                    break;
                }
                final ItemUtility utility = itemStack.getItem().getUtility();
                entityStatsToClear = utility.getEntityStatsToClear();
                break;
            }
            case -8: {
                this.activeToolsSlot = slot;
                break;
            }
            default: {
                throw new IllegalArgumentException("Inventory section with id " + inventorySectionId + " cannot select an active slot");
            }
        }
        final StatModifiersManager statModifiersManager = this.entity.getStatModifiersManager();
        this.entity.invalidateEquipmentNetwork();
        statModifiersManager.setRecalculate(true);
        if (entityStatsToClear != null) {
            statModifiersManager.queueEntityStatsToClear(entityStatsToClear);
        }
    }
    
    public byte getActiveSlot(final int inventorySectionId) {
        return switch (inventorySectionId) {
            case -1 -> this.activeHotbarSlot;
            case -5 -> this.activeUtilitySlot;
            case -8 -> this.activeToolsSlot;
            default -> throw new IllegalArgumentException("Inventory section with id " + inventorySectionId + " cannot select an active slot");
        };
    }
    
    public byte getActiveHotbarSlot() {
        return this.activeHotbarSlot;
    }
    
    public void setActiveHotbarSlot(final byte slot) {
        this.setUsingToolsItem(false);
        this.setActiveSlot(-1, slot);
    }
    
    @Nullable
    public ItemStack getActiveHotbarItem() {
        return (this.activeHotbarSlot == -1) ? null : this.hotbar.getItemStack(this.activeHotbarSlot);
    }
    
    @Nullable
    public ItemStack getActiveToolItem() {
        return (this.activeToolsSlot == -1) ? null : this.tools.getItemStack(this.activeToolsSlot);
    }
    
    @Nullable
    public ItemStack getItemInHand() {
        return this._usingToolsItem ? this.getActiveToolItem() : this.getActiveHotbarItem();
    }
    
    public byte getActiveUtilitySlot() {
        return this.activeUtilitySlot;
    }
    
    public void setActiveUtilitySlot(final byte slot) {
        this.setActiveSlot(-5, slot);
    }
    
    @Nullable
    public ItemStack getUtilityItem() {
        return (this.activeUtilitySlot == -1) ? null : this.utility.getItemStack(this.activeUtilitySlot);
    }
    
    public byte getActiveToolsSlot() {
        return this.activeToolsSlot;
    }
    
    public void setActiveToolsSlot(final byte slot) {
        this.setUsingToolsItem(true);
        this.setActiveSlot(-8, slot);
    }
    
    @Nullable
    public ItemStack getToolsItem() {
        return (this.activeToolsSlot == -1) ? null : this.tools.getItemStack(this.activeToolsSlot);
    }
    
    @Nullable
    public ItemContainer getSectionById(final int id) {
        if (id >= 0) {
            if (this.entity instanceof final Player player) {
                final Window window = player.getWindowManager().getWindow(id);
                if (window instanceof final ItemContainerWindow itemContainerWindow) {
                    return itemContainerWindow.getItemContainer();
                }
            }
            return null;
        }
        return switch (id) {
            case -1 -> this.hotbar;
            case -2 -> this.storage;
            case -3 -> this.armor;
            case -5 -> this.utility;
            case -8 -> this.tools;
            case -9 -> this.backpack;
            default -> null;
        };
    }
    
    public boolean consumeIsDirty() {
        return this.isDirty.getAndSet(false);
    }
    
    public boolean consumeNeedsSaving() {
        return this.needsSaving.getAndSet(false);
    }
    
    public void setEntity(final LivingEntity entity) {
        this.entity = entity;
    }
    
    public void sortStorage(@Nonnull final SortType type) {
        this.sortType = type;
        this.storage.sortItems(type);
        this.markChanged();
    }
    
    public void setSortType(final SortType type) {
        this.sortType = type;
        this.markChanged();
    }
    
    public boolean containsBrokenItem() {
        boolean hasBrokenItem = false;
        for (short i = 0; i < this.combinedEverything.getCapacity(); ++i) {
            final ItemStack itemStack = this.combinedEverything.getItemStack(i);
            if (!ItemStack.isEmpty(itemStack)) {
                if (itemStack.isBroken()) {
                    hasBrokenItem = true;
                }
            }
        }
        return hasBrokenItem;
    }
    
    @Nonnull
    @Override
    public UpdatePlayerInventory toPacket() {
        final UpdatePlayerInventory packet = new UpdatePlayerInventory();
        packet.storage = this.storage.toPacket();
        packet.armor = this.armor.toPacket();
        packet.hotbar = this.hotbar.toPacket();
        packet.utility = this.utility.toPacket();
        packet.tools = this.tools.toPacket();
        packet.backpack = this.backpack.toPacket();
        packet.sortType = this.sortType.toPacket();
        return packet;
    }
    
    public void doMigration(final Function<String, String> blockMigration) {
        Objects.requireNonNull(blockMigration);
        this.hotbar.doMigration(blockMigration);
        this.storage.doMigration(blockMigration);
        this.armor.doMigration(blockMigration);
        this.utility.doMigration(blockMigration);
        this.tools.doMigration(blockMigration);
        this.backpack.doMigration(blockMigration);
    }
    
    private void postDecode() {
        this.armor = ItemContainerUtil.trySetArmorFilters(this.armor);
        this.utility = ItemContainerUtil.trySetSlotFilters(this.utility, (type, container, slot, itemStack) -> itemStack == null || itemStack.getItem().getUtility().isUsable());
        this.activeHotbarSlot = (byte)((this.activeHotbarSlot < this.hotbar.getCapacity()) ? this.activeHotbarSlot : ((this.hotbar.getCapacity() > 0) ? 0 : -1));
        this.activeUtilitySlot = (byte)((this.activeUtilitySlot < this.utility.getCapacity()) ? this.activeUtilitySlot : -1);
        this.activeToolsSlot = (byte)((this.activeToolsSlot < this.tools.getCapacity()) ? this.activeToolsSlot : -1);
        this.buildCombinedContains();
        this.registerChangeEvents();
    }
    
    private void buildCombinedContains() {
        this.combinedHotbarFirst = new CombinedItemContainer(new ItemContainer[] { this.hotbar, this.storage });
        this.combinedStorageFirst = new CombinedItemContainer(new ItemContainer[] { this.storage, this.hotbar });
        this.combinedBackpackStorageHotbar = new CombinedItemContainer(new ItemContainer[] { this.backpack, this.storage, this.hotbar });
        this.combinedStorageHotbarBackpack = new CombinedItemContainer(new ItemContainer[] { this.storage, this.hotbar, this.backpack });
        this.combinedArmorHotbarStorage = new CombinedItemContainer(new ItemContainer[] { this.armor, this.hotbar, this.storage });
        this.combinedArmorHotbarUtilityStorage = new CombinedItemContainer(new ItemContainer[] { this.armor, this.hotbar, this.utility, this.storage });
        this.combinedHotbarUtilityConsumableStorage = new CombinedItemContainer(new ItemContainer[] { this.hotbar, this.utility, this.storage });
        this.combinedEverything = new CombinedItemContainer(new ItemContainer[] { this.armor, this.hotbar, this.utility, this.storage, this.backpack });
    }
    
    @Override
    public boolean equals(@Nullable final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        final Inventory inventory = (Inventory)o;
        return this.activeHotbarSlot == inventory.activeHotbarSlot && this.activeUtilitySlot == inventory.activeUtilitySlot && this.isDirty == inventory.isDirty && this.needsSaving == inventory.needsSaving && Objects.equals(this.storage, inventory.storage) && Objects.equals(this.armor, inventory.armor) && Objects.equals(this.utility, inventory.utility) && Objects.equals(this.tools, inventory.tools) && Objects.equals(this.backpack, inventory.backpack) && Objects.equals(this.hotbar, inventory.hotbar);
    }
    
    @Override
    public int hashCode() {
        int result = (this.storage != null) ? this.storage.hashCode() : 0;
        result = 31 * result + ((this.armor != null) ? this.armor.hashCode() : 0);
        result = 31 * result + ((this.hotbar != null) ? this.hotbar.hashCode() : 0);
        result = 31 * result + ((this.utility != null) ? this.utility.hashCode() : 0);
        result = 31 * result + ((this.tools != null) ? this.tools.hashCode() : 0);
        result = 31 * result + ((this.backpack != null) ? this.backpack.hashCode() : 0);
        result = 31 * result + this.activeHotbarSlot;
        result = 31 * result + this.activeUtilitySlot;
        result = 31 * result + this.activeToolsSlot;
        result = 31 * result + this.isDirty.hashCode();
        result = 31 * result + this.needsSaving.hashCode();
        return result;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "Inventory{, storage=" + String.valueOf(this.storage) + ", armor=" + String.valueOf(this.armor) + ", hotbar=" + String.valueOf(this.hotbar) + ", utility=" + String.valueOf(this.utility) + ", activeHotbarSlot=" + this.activeHotbarSlot + ", activeUtilitySlot=" + this.activeUtilitySlot + ", activeToolsSlot=" + this.activeToolsSlot + ", isDirty=" + String.valueOf(this.isDirty) + ", needsSaving=" + String.valueOf(this.needsSaving);
    }
    
    @Nonnull
    public static Inventory ensureCapacity(@Nonnull final Inventory inventory, final List<ItemStack> remainder) {
        final ItemContainer storage = inventory.getStorage();
        final ItemContainer armor = inventory.getArmor();
        final ItemContainer hotbar = inventory.getHotbar();
        final ItemContainer utility = inventory.getUtility();
        final ItemContainer tool = inventory.getTools();
        if (storage.getCapacity() == 36 && armor.getCapacity() == Inventory.DEFAULT_ARMOR_CAPACITY && hotbar.getCapacity() == 9 && utility.getCapacity() == 4 && tool.getCapacity() == 23) {
            return inventory;
        }
        final ItemContainer newStorage = ItemContainer.ensureContainerCapacity(storage, (short)36, (Short2ObjectConcurrentHashMap.ShortFunction<ItemContainer>)SimpleItemContainer::new, remainder);
        final ItemContainer newArmor = ItemContainer.ensureContainerCapacity(armor, Inventory.DEFAULT_ARMOR_CAPACITY, (Short2ObjectConcurrentHashMap.ShortFunction<ItemContainer>)SimpleItemContainer::new, remainder);
        final ItemContainer newHotbar = ItemContainer.ensureContainerCapacity(hotbar, (short)9, (Short2ObjectConcurrentHashMap.ShortFunction<ItemContainer>)SimpleItemContainer::new, remainder);
        final ItemContainer newUtility = ItemContainer.ensureContainerCapacity(utility, (short)4, (Short2ObjectConcurrentHashMap.ShortFunction<ItemContainer>)SimpleItemContainer::new, remainder);
        final ItemContainer newTool = ItemContainer.ensureContainerCapacity(tool, (short)23, (Short2ObjectConcurrentHashMap.ShortFunction<ItemContainer>)SimpleItemContainer::new, remainder);
        byte activeHotbarSlot = inventory.getActiveHotbarSlot();
        if (activeHotbarSlot > newHotbar.getCapacity()) {
            activeHotbarSlot = (byte)((hotbar.getCapacity() > 0) ? 0 : -1);
        }
        byte activeUtilitySlot = inventory.getActiveUtilitySlot();
        if (activeUtilitySlot > newUtility.getCapacity()) {
            activeUtilitySlot = -1;
        }
        byte activeToolsSlot = inventory.getActiveToolsSlot();
        if (activeToolsSlot > newTool.getCapacity()) {
            activeToolsSlot = -1;
        }
        inventory.unregister();
        final Inventory newInventory = new Inventory(newStorage, newArmor, newHotbar, newUtility, newTool, EmptyItemContainer.INSTANCE);
        newInventory.activeHotbarSlot = activeHotbarSlot;
        newInventory.activeUtilitySlot = activeUtilitySlot;
        newInventory.activeToolsSlot = activeToolsSlot;
        newInventory.setSortType(inventory.sortType);
        return newInventory;
    }
    
    public void setUsingToolsItem(final boolean value) {
        this._usingToolsItem = value;
    }
    
    public boolean usingToolsItem() {
        return this._usingToolsItem;
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokevirtual   java/lang/Class.desiredAssertionStatus:()Z
        //     5: ifne            12
        //     8: iconst_1       
        //     9: goto            13
        //    12: iconst_0       
        //    13: putstatic       com/hypixel/hytale/server/core/inventory/Inventory.$assertionsDisabled:Z
        //    16: getstatic       com/hypixel/hytale/protocol/ItemArmorSlot.VALUES:[Lcom/hypixel/hytale/protocol/ItemArmorSlot;
        //    19: arraylength    
        //    20: i2s            
        //    21: putstatic       com/hypixel/hytale/server/core/inventory/Inventory.DEFAULT_ARMOR_CAPACITY:S
        //    24: ldc             Lcom/hypixel/hytale/server/core/inventory/Inventory;.class
        //    26: invokedynamic   BootstrapMethod #12, get:()Ljava/util/function/Supplier;
        //    31: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    34: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.versioned:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    37: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    40: iconst_4       
        //    41: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.codecVersion:(I)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    44: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    47: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    50: dup            
        //    51: ldc_w           "Storage"
        //    54: getstatic       com/hypixel/hytale/server/core/inventory/container/ItemContainer.CODEC:Lcom/hypixel/hytale/codec/lookup/CodecMapCodec;
        //    57: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    60: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
        //    65: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
        //    70: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    73: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    76: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    79: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    82: dup            
        //    83: ldc_w           "Armor"
        //    86: getstatic       com/hypixel/hytale/server/core/inventory/container/ItemContainer.CODEC:Lcom/hypixel/hytale/codec/lookup/CodecMapCodec;
        //    89: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    92: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
        //    97: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
        //   102: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   105: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   108: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   111: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   114: dup            
        //   115: ldc_w           "HotBar"
        //   118: getstatic       com/hypixel/hytale/server/core/inventory/container/ItemContainer.CODEC:Lcom/hypixel/hytale/codec/lookup/CodecMapCodec;
        //   121: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   124: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
        //   129: invokedynamic   BootstrapMethod #18, apply:()Ljava/util/function/Function;
        //   134: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   137: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   140: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   143: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   146: dup            
        //   147: ldc_w           "Utility"
        //   150: getstatic       com/hypixel/hytale/server/core/inventory/container/ItemContainer.CODEC:Lcom/hypixel/hytale/codec/lookup/CodecMapCodec;
        //   153: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   156: invokedynamic   BootstrapMethod #19, accept:()Ljava/util/function/BiConsumer;
        //   161: invokedynamic   BootstrapMethod #20, apply:()Ljava/util/function/Function;
        //   166: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   169: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   172: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   175: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   178: dup            
        //   179: ldc_w           "Backpack"
        //   182: getstatic       com/hypixel/hytale/server/core/inventory/container/ItemContainer.CODEC:Lcom/hypixel/hytale/codec/lookup/CodecMapCodec;
        //   185: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   188: invokedynamic   BootstrapMethod #21, accept:()Ljava/util/function/BiConsumer;
        //   193: invokedynamic   BootstrapMethod #22, apply:()Ljava/util/function/Function;
        //   198: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   201: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   204: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   207: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   210: dup            
        //   211: ldc_w           "ActiveHotbarSlot"
        //   214: getstatic       com/hypixel/hytale/codec/Codec.BYTE:Lcom/hypixel/hytale/codec/codecs/simple/ByteCodec;
        //   217: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   220: invokedynamic   BootstrapMethod #23, accept:()Ljava/util/function/BiConsumer;
        //   225: invokedynamic   BootstrapMethod #24, apply:()Ljava/util/function/Function;
        //   230: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   233: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   236: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   239: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   242: dup            
        //   243: ldc_w           "Tool"
        //   246: getstatic       com/hypixel/hytale/server/core/inventory/container/ItemContainer.CODEC:Lcom/hypixel/hytale/codec/lookup/CodecMapCodec;
        //   249: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   252: invokedynamic   BootstrapMethod #25, accept:()Ljava/util/function/BiConsumer;
        //   257: invokedynamic   BootstrapMethod #26, apply:()Ljava/util/function/Function;
        //   262: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   265: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   268: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   271: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   274: dup            
        //   275: ldc_w           "ActiveToolsSlot"
        //   278: getstatic       com/hypixel/hytale/codec/Codec.BYTE:Lcom/hypixel/hytale/codec/codecs/simple/ByteCodec;
        //   281: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   284: invokedynamic   BootstrapMethod #27, accept:()Ljava/util/function/BiConsumer;
        //   289: invokedynamic   BootstrapMethod #28, apply:()Ljava/util/function/Function;
        //   294: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   297: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   300: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   303: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   306: dup            
        //   307: ldc_w           "ActiveUtilitySlot"
        //   310: getstatic       com/hypixel/hytale/codec/Codec.BYTE:Lcom/hypixel/hytale/codec/codecs/simple/ByteCodec;
        //   313: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   316: invokedynamic   BootstrapMethod #29, accept:()Ljava/util/function/BiConsumer;
        //   321: invokedynamic   BootstrapMethod #30, apply:()Ljava/util/function/Function;
        //   326: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   329: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   332: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   335: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   338: dup            
        //   339: ldc_w           "SortType"
        //   342: new             Lcom/hypixel/hytale/codec/codecs/EnumCodec;
        //   345: dup            
        //   346: ldc             Lcom/hypixel/hytale/server/core/inventory/container/SortType;.class
        //   348: getstatic       com/hypixel/hytale/codec/codecs/EnumCodec$EnumStyle.LEGACY:Lcom/hypixel/hytale/codec/codecs/EnumCodec$EnumStyle;
        //   351: invokespecial   com/hypixel/hytale/codec/codecs/EnumCodec.<init>:(Ljava/lang/Class;Lcom/hypixel/hytale/codec/codecs/EnumCodec$EnumStyle;)V
        //   354: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   357: invokedynamic   BootstrapMethod #31, accept:()Ljava/util/function/BiConsumer;
        //   362: invokedynamic   BootstrapMethod #32, apply:()Ljava/util/function/Function;
        //   367: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   370: iconst_0       
        //   371: iconst_3       
        //   372: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.setVersionRange:(II)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   375: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   378: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   381: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   384: dup            
        //   385: ldc_w           "SortType"
        //   388: new             Lcom/hypixel/hytale/codec/codecs/EnumCodec;
        //   391: dup            
        //   392: ldc             Lcom/hypixel/hytale/server/core/inventory/container/SortType;.class
        //   394: invokespecial   com/hypixel/hytale/codec/codecs/EnumCodec.<init>:(Ljava/lang/Class;)V
        //   397: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   400: invokedynamic   BootstrapMethod #33, accept:()Ljava/util/function/BiConsumer;
        //   405: invokedynamic   BootstrapMethod #34, apply:()Ljava/util/function/Function;
        //   410: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   413: iconst_4       
        //   414: iconst_4       
        //   415: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.setVersionRange:(II)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   418: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   421: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   424: invokedynamic   BootstrapMethod #35, accept:()Ljava/util/function/Consumer;
        //   429: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.afterDecode:(Ljava/util/function/Consumer;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   432: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   435: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   438: putstatic       com/hypixel/hytale/server/core/inventory/Inventory.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   441: return         
        //    StackMapTable: 00 02 0C 40 01
        // 
        // The error that occurred was:
        // 
        // java.lang.UnsupportedOperationException: The requested operation is not supported.
        //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
        //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:225)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:211)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:314)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2611)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypesForVariables(TypeAnalysis.java:593)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:405)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:109)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
        //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
        //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    public enum ItemPickupType
    {
        PASSIVE, 
        INTERACTION;
    }
}
