Search in sources :

Example 1 with SingularHashedItemSource

use of mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource in project Mekanism by mekanism.

the class QIOCraftingTransferHandler method hasRoomToShuffle.

/**
 * Loosely based on how {@link mekanism.common.content.qio.QIOServerCraftingTransferHandler}'s hasRoomToShuffle method works.
 */
private static boolean hasRoomToShuffle(QIOCraftingTransferHelper qioTransferHelper, @Nullable QIOFrequency frequency, QIOCraftingWindow craftingWindow, List<HotBarSlot> hotBarSlots, List<MainInventorySlot> mainInventorySlots, Map<HashedItemSource, List<List<SingularHashedItemSource>>> shuffleLookup) {
    // Map used to keep track of inputs while also merging identical inputs, so we can cut down
    // on how many times we have to check if things can stack
    Object2IntMap<HashedItem> leftOverInput = new Object2IntArrayMap<>(9);
    for (byte slotIndex = 0; slotIndex < 9; slotIndex++) {
        IInventorySlot slot = craftingWindow.getInputSlot(slotIndex);
        if (!slot.isEmpty()) {
            // Note: We can use raw as we are not modifying the stack or persisting the reference
            HashedItem type = HashedItem.raw(slot.getStack());
            HashedItemSource source = qioTransferHelper.getSource(type);
            if (source == null) {
                // Something went wrong, this should never be null for the things in the crafting slots
                return false;
            }
            int remaining = source.getSlotRemaining(slotIndex);
            if (remaining > 0) {
                // Don't bother adding any that we fully used
                leftOverInput.mergeInt(type, remaining, Integer::sum);
            }
        }
    }
    if (!leftOverInput.isEmpty()) {
        // If we have any leftover inputs in the crafting inventory, then get a simulated view of what the player's inventory
        // will look like after things are changed
        BaseSimulatedInventory simulatedInventory = new BaseSimulatedInventory(hotBarSlots, mainInventorySlots) {

            @Override
            protected int getRemaining(int slot, ItemStack currentStored) {
                HashedItemSource source = qioTransferHelper.getSource(HashedItem.raw(currentStored));
                if (source == null) {
                    return currentStored.getCount();
                }
                return source.getSlotRemaining((byte) (slot + 9));
            }
        };
        Object2IntMap<HashedItem> stillLeftOver = simulatedInventory.shuffleInputs(leftOverInput, frequency != null);
        if (stillLeftOver == null) {
            // If we have remaining items and no frequency then we don't have room to shuffle
            return false;
        }
        if (!stillLeftOver.isEmpty() && frequency != null) {
            // If we still have left over things try adding them to the frequency. We only are able to do a rough check and estimate
            // on if the frequency has room or not as depending on how things are stored in the drives there is a chance that we
            // do not actually have as much item space or types available, but this is the best we can do on the client side
            // Note: We validate the frequency is not null, even though it shouldn't be null if we have anything still left over
            // Note: We calculate these numbers as a difference so that it is easier to make sure none of the numbers accidentally overflow
            int availableItemTypes = frequency.getTotalItemTypeCapacity() - frequency.getTotalItemTypes(true);
            long availableItemSpace = frequency.getTotalItemCountCapacity() - frequency.getTotalItemCount();
            Object2BooleanMap<HashedItemSource> usedQIOSource = new Object2BooleanArrayMap<>(shuffleLookup.size());
            for (Map.Entry<HashedItemSource, List<List<SingularHashedItemSource>>> entry : shuffleLookup.entrySet()) {
                HashedItemSource source = entry.getKey();
                boolean usedQIO = false;
                for (List<SingularHashedItemSource> usedSources : entry.getValue()) {
                    for (SingularHashedItemSource usedSource : usedSources) {
                        UUID qioSource = usedSource.getQioSource();
                        if (qioSource != null) {
                            // Free up however much space as we used of the item
                            availableItemSpace += usedSource.getUsed();
                            if (source.getQIORemaining(qioSource) == 0) {
                                // If we used all that is available, we need to also free up an item type
                                availableItemTypes++;
                                usedQIO = true;
                            }
                        }
                    }
                }
                usedQIOSource.put(source, usedQIO);
            }
            for (Object2IntMap.Entry<HashedItem> entry : stillLeftOver.object2IntEntrySet()) {
                availableItemSpace -= entry.getIntValue();
                if (availableItemSpace <= 0) {
                    // No room for all our items, fail
                    return false;
                }
                HashedItemSource source = qioTransferHelper.getSource(entry.getKey());
                if (source == null) {
                    // Something went wrong, this should never be null for the things in the crafting slots
                    return false;
                } else if (source.hasQIOSources()) {
                    // It is stored, check to make sure it isn't a type we are removing at least one of fully
                    if (usedQIOSource.containsKey(source) && usedQIOSource.getBoolean(source)) {
                        // if it is, then we need to reclaim the item type as being available
                        availableItemTypes--;
                        if (availableItemTypes <= 0) {
                            // Not enough room for types
                            return false;
                        }
                    }
                } else {
                    // The item is not stored in the QIO frequency, we need to use an item type up
                    // Note: This is not super accurate due to the fact that we don't know for
                    // certain if our used source actually matched or differed in server side only
                    // NBT, but it is the best we can do on the client side
                    availableItemTypes--;
                    if (availableItemTypes <= 0) {
                        // Not enough room for types
                        return false;
                    }
                }
            }
        }
    }
    return true;
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) HashedItem(mekanism.common.lib.inventory.HashedItem) HashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.HashedItemSource) SingularHashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource) SingularHashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource) Object2IntMap(it.unimi.dsi.fastutil.objects.Object2IntMap) Object2BooleanArrayMap(it.unimi.dsi.fastutil.objects.Object2BooleanArrayMap) Object2IntArrayMap(it.unimi.dsi.fastutil.objects.Object2IntArrayMap) BaseSimulatedInventory(mekanism.common.content.qio.QIOCraftingTransferHelper.BaseSimulatedInventory) List(java.util.List) ArrayList(java.util.ArrayList) ByteList(it.unimi.dsi.fastutil.bytes.ByteList) ByteArrayList(it.unimi.dsi.fastutil.bytes.ByteArrayList) ItemStack(net.minecraft.item.ItemStack) UUID(java.util.UUID) Object2BooleanMap(it.unimi.dsi.fastutil.objects.Object2BooleanMap) Object2IntArrayMap(it.unimi.dsi.fastutil.objects.Object2IntArrayMap) Object2BooleanArrayMap(it.unimi.dsi.fastutil.objects.Object2BooleanArrayMap) Map(java.util.Map) Byte2ObjectArrayMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap) HashMap(java.util.HashMap) Byte2ObjectMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectMap) Object2IntMap(it.unimi.dsi.fastutil.objects.Object2IntMap)

Example 2 with SingularHashedItemSource

use of mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource in project Mekanism by mekanism.

the class PacketQIOFillCraftingWindow method decode.

public static PacketQIOFillCraftingWindow decode(PacketBuffer buffer) {
    ResourceLocation recipeID = buffer.readResourceLocation();
    boolean maxTransfer = buffer.readBoolean();
    byte slotCount = buffer.readByte();
    Byte2ObjectMap<List<SingularHashedItemSource>> sources = new Byte2ObjectArrayMap<>(slotCount);
    for (byte slot = 0; slot < slotCount; slot++) {
        byte targetSlot = buffer.readByte();
        int subSourceCount = maxTransfer ? buffer.readVarInt() : 1;
        List<SingularHashedItemSource> slotSources = new ArrayList<>(subSourceCount);
        sources.put(targetSlot, slotSources);
        for (int i = 0; i < subSourceCount; i++) {
            byte sourceSlot = buffer.readByte();
            int count = maxTransfer ? buffer.readVarInt() : 1;
            if (sourceSlot == -1) {
                slotSources.add(new SingularHashedItemSource(buffer.readUUID(), count));
            } else {
                slotSources.add(new SingularHashedItemSource(sourceSlot, count));
            }
        }
    }
    return new PacketQIOFillCraftingWindow(recipeID, maxTransfer, sources);
}
Also used : SingularHashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource) ResourceLocation(net.minecraft.util.ResourceLocation) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) Byte2ObjectArrayMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap)

Example 3 with SingularHashedItemSource

use of mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource in project Mekanism by mekanism.

the class QIOServerCraftingTransferHandler method transferItems.

private void transferItems(Byte2ObjectMap<List<SingularHashedItemSource>> sources) {
    SelectedWindowData windowData = craftingWindow.getWindowData();
    // Extract items that will be put into the crafting window
    Byte2ObjectMap<ItemStack> targetContents = new Byte2ObjectArrayMap<>(sources.size());
    for (Byte2ObjectMap.Entry<List<SingularHashedItemSource>> entry : sources.byte2ObjectEntrySet()) {
        for (SingularHashedItemSource source : entry.getValue()) {
            byte slot = source.getSlot();
            ItemStack stack;
            if (slot == -1) {
                UUID qioSource = source.getQioSource();
                // Neither the source nor the frequency can be null here as we validated that during simulation
                HashedItem storedItem = frequency.getTypeByUUID(qioSource);
                if (storedItem == null) {
                    bail(targetContents, "Received transfer request from: {}, for: {}, could not find stored item with UUID: {}. " + "This likely means that more of it was requested than is stored.", player, recipeID, qioSource);
                    return;
                }
                stack = frequency.removeByType(storedItem, source.getUsed());
                if (stack.isEmpty()) {
                    bail(targetContents, "Received transfer request from: {}, for: {}, but could not extract item: {} with nbt: {} from the QIO.", player, recipeID, storedItem.getStack().getItem(), storedItem.getStack().getTag());
                    return;
                } else if (stack.getCount() < source.getUsed()) {
                    Mekanism.logger.warn("Received transfer request from: {}, for: {}, but was unable to extract the expected amount: {} of item: {} " + "with nbt: {} from the QIO. This should not be possible as it should have been caught during simulation. Attempting " + "to continue anyways with the actual extracted amount of {}.", player, recipeID, source.getUsed(), storedItem.getStack().getItem(), storedItem.getStack().getTag(), stack.getCount());
                }
            } else {
                int actualSlot;
                String slotType;
                if (slot < 9) {
                    // Crafting Window
                    actualSlot = slot;
                    slotType = "crafting window";
                    stack = craftingWindow.getInputSlot(slot).extractItem(source.getUsed(), Action.EXECUTE, AutomationType.MANUAL);
                } else if (slot < 9 + PlayerInventory.getSelectionSize()) {
                    // Hotbar
                    actualSlot = slot - 9;
                    slotType = "hotbar";
                    stack = hotBarSlots.get(actualSlot).remove(source.getUsed());
                } else {
                    // Main inventory
                    actualSlot = slot - 9 - PlayerInventory.getSelectionSize();
                    slotType = "main inventory";
                    stack = mainInventorySlots.get(actualSlot).remove(source.getUsed());
                }
                if (stack.isEmpty()) {
                    bail(targetContents, "Received transfer request from: {}, for: {}, could not extract item from {} slot: {}. " + "This likely means that more of it was requested than is stored.", player, recipeID, slotType, actualSlot);
                    return;
                } else if (stack.getCount() < source.getUsed()) {
                    Mekanism.logger.warn("Received transfer request from: {}, for: {}, but was unable to extract the expected amount: {} from {} slot: {}. " + "This should not be possible as it should have been caught during simulation. Attempting to continue anyways with the " + "actual extracted amount of {}.", player, recipeID, source.getUsed(), slotType, actualSlot, stack.getCount());
                }
            }
            byte targetSlot = entry.getByteKey();
            if (targetContents.containsKey(targetSlot)) {
                ItemStack existing = targetContents.get(targetSlot);
                if (ItemHandlerHelper.canItemStacksStack(existing, stack)) {
                    int needed = existing.getMaxStackSize() - existing.getCount();
                    if (stack.getCount() <= needed) {
                        existing.grow(stack.getCount());
                    } else {
                        existing.grow(needed);
                        // Note: We can safely modify the stack as all our ways of extracting return a new stack
                        stack.shrink(needed);
                        Mekanism.logger.warn("Received transfer request from: {}, for: {}, but contents could not fully fit into target slot: {}. " + "This should not be able to happen, returning excess stack, and attempting to continue.", player, recipeID, targetSlot);
                        returnItem(stack, windowData);
                    }
                } else {
                    Mekanism.logger.warn("Received transfer request from: {}, for: {}, but contents could not stack into target slot: {}. " + "This should not be able to happen, returning extra stack, and attempting to continue.", player, recipeID, targetSlot);
                    returnItem(stack, windowData);
                }
            } else {
                // Note: We can safely modify the stack as all our ways of extracting return a new stack
                targetContents.put(targetSlot, stack);
            }
        }
    }
    // Extract what items are still in the window
    Byte2ObjectMap<ItemStack> remainingCraftingGridContents = new Byte2ObjectArrayMap<>(9);
    for (byte slot = 0; slot < 9; slot++) {
        CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(slot);
        if (!inputSlot.isEmpty()) {
            ItemStack stack = inputSlot.extractItem(inputSlot.getCount(), Action.EXECUTE, AutomationType.MANUAL);
            if (!stack.isEmpty()) {
                remainingCraftingGridContents.put(slot, stack);
            } else {
                bail(targetContents, remainingCraftingGridContents, "Received transfer request from: {}, for: {}, but failed to remove items from crafting " + "input slot: {}. This should not be possible as it should have been caught by an earlier check.", player, recipeID, slot);
                return;
            }
        }
    }
    // Insert items for the crafting window into it
    for (ObjectIterator<Byte2ObjectMap.Entry<ItemStack>> iter = targetContents.byte2ObjectEntrySet().iterator(); iter.hasNext(); ) {
        Byte2ObjectMap.Entry<ItemStack> entry = iter.next();
        byte targetSlot = entry.getByteKey();
        CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(targetSlot);
        ItemStack remainder = inputSlot.insertItem(entry.getValue(), Action.EXECUTE, AutomationType.MANUAL);
        if (remainder.isEmpty()) {
            // If it was fully inserted, remove the entry from what we have left to deal with
            iter.remove();
        } else {
            // otherwise, update the stack for what is remaining and also print a warning as this should have been caught earlier,
            // as we then will handle any remaining contents at the end (though we shouldn't have any)
            // Note: We need to use put, as entry#setValue is not supported in fastutil maps
            targetContents.put(targetSlot, remainder);
            Mekanism.logger.warn("Received transfer request from: {}, for: {}, but was unable to fully insert it into the {} crafting input slot. " + "This should not be possible as it should have been caught during simulation. Attempting to continue anyways.", player, recipeID, targetSlot);
        }
    }
    // Put the items that were in the crafting window in the player's inventory
    for (Byte2ObjectMap.Entry<ItemStack> entry : remainingCraftingGridContents.byte2ObjectEntrySet()) {
        // Insert into player's inventory
        ItemStack stack = returnItemToInventory(entry.getValue(), windowData);
        if (!stack.isEmpty()) {
            // If we couldn't insert it all, try recombining with the slots they were in the crafting window
            // (only if the type matches though)
            CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(entry.getByteKey());
            if (ItemHandlerHelper.canItemStacksStack(inputSlot.getStack(), stack)) {
                stack = inputSlot.insertItem(stack, Action.EXECUTE, AutomationType.MANUAL);
            }
            if (!stack.isEmpty()) {
                // If we couldn't insert it, then try to put the remaining items in the frequency
                if (frequency != null) {
                    stack = frequency.addItem(stack);
                }
                if (!stack.isEmpty()) {
                    // If we couldn't insert it all, either because there was no frequency or it didn't have room for it all
                    // drop it as the player, and print a warning as ideally we should never have been able to get to this
                    // point as our simulation should have marked it as invalid
                    // Note: In theory we should never get to this point due to having accurate simulations ahead of time
                    player.drop(stack, false);
                    Mekanism.logger.warn("Received transfer request from: {}, for: {}, and was unable to fit all contents that were in the crafting window " + "into the player's inventory/QIO system; dropping items by player.", player, recipeID);
                }
            }
        }
    }
    if (!targetContents.isEmpty()) {
        // If we have any contents we wanted to move remaining try to return them, in theory
        // this should never happen but in case it does make sure we don't void any items
        bail(targetContents, "Received transfer request from: {}, for: {}, but ended up with {} items that could not be transferred into " + "the proper crafting grid slot. This should not be possible as it should have been caught during simulation.", player, recipeID, targetContents.size());
    }
}
Also used : HashedItem(mekanism.common.lib.inventory.HashedItem) SingularHashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource) Byte2ObjectMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectMap) ArrayList(java.util.ArrayList) NonNullList(net.minecraft.util.NonNullList) List(java.util.List) Byte2ObjectArrayMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap) ItemStack(net.minecraft.item.ItemStack) UUID(java.util.UUID) SelectedWindowData(mekanism.common.inventory.container.SelectedWindowData) CraftingWindowInventorySlot(mekanism.common.inventory.slot.CraftingWindowInventorySlot)

Example 4 with SingularHashedItemSource

use of mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource in project Mekanism by mekanism.

the class QIOServerCraftingTransferHandler method tryTransfer.

private void tryTransfer(ICraftingRecipe recipe, Byte2ObjectMap<List<SingularHashedItemSource>> sources) {
    // need to be able to extract the contents afterwards anyway
    for (byte slot = 0; slot < 9; slot++) {
        CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(slot);
        if (!inputSlot.isEmpty()) {
            ItemStack available = inputSlot.extractItem(inputSlot.getCount(), Action.SIMULATE, AutomationType.INTERNAL);
            if (available.getCount() < inputSlot.getCount()) {
                // TODO: Eventually it would be nice if we added in some support so that if an item is staying put in its crafting slot
                // we don't actually need to do any validation of if it can be extracted from when it will just end up in the same spot anyways
                // but for now this isn't that major of a concern as our slots don't actually have any restrictions on them in regards to extracting
                Mekanism.logger.warn("Received transfer request from: {}, for: {}, and was unable to extract all items from crafting input slot: {}.", player, recipeID, slot);
                return;
            }
            availableItems.put(slot, new SlotData(available));
        }
    }
    for (Byte2ObjectMap.Entry<List<SingularHashedItemSource>> entry : sources.byte2ObjectEntrySet()) {
        byte targetSlot = entry.getByteKey();
        if (targetSlot < 0 || targetSlot >= 9) {
            Mekanism.logger.warn("Received transfer request from: {}, for: {}, with an invalid target slot id: {}.", player, recipeID, targetSlot);
            return;
        }
        int stackSize = 0;
        List<SingularHashedItemSource> singleSources = entry.getValue();
        for (Iterator<SingularHashedItemSource> iter = singleSources.iterator(); iter.hasNext(); ) {
            SingularHashedItemSource source = iter.next();
            byte slot = source.getSlot();
            int used;
            if (slot == -1) {
                used = simulateQIOSource(targetSlot, source.getQioSource(), source.getUsed(), stackSize);
            } else {
                used = simulateSlotSource(targetSlot, slot, source.getUsed(), stackSize);
            }
            if (used == -1) {
                // Error occurred and was logged, exit
                return;
            } else if (used == 0) {
                // Unable to use any of this source due to it not stacking with an earlier one for example
                // remove this source
                iter.remove();
            } else {
                if (used < source.getUsed()) {
                    // If we used less than we were expected to (most likely due to stack sizes) then we need
                    // to decrease the amount of the source being used
                    source.setUsed(used);
                }
                stackSize += used;
            }
        }
        if (singleSources.isEmpty()) {
            // There should always be at least one (the first source) that didn't get removed, but in case something went wrong,
            // and it got removed anyway, then we catch it here and fail
            Mekanism.logger.warn("Received transfer request from: {}, for: {}, that had no valid sources, this should not be possible.", player, recipeID);
            return;
        }
        ItemStack resultItem = recipeToTest.get(targetSlot);
        if (!resultItem.isEmpty() && resultItem.getMaxStackSize() < stackSize) {
            // Note: This should never happen as if it would happen it should be caught in the above simulation and have the amount used reduced to not happen
            Mekanism.logger.warn("Received transfer request from: {}, for: {}, that tried to transfer more items into: {} than can stack ({}) in one slot.", player, recipeID, targetSlot, resultItem.getMaxStackSize());
            return;
        }
    }
    CraftingInventory dummy = MekanismUtils.getDummyCraftingInv();
    for (int slot = 0; slot < 9; slot++) {
        dummy.setItem(slot, StackUtils.size(recipeToTest.get(slot), 1));
    }
    if (!recipe.matches(dummy, player.level)) {
        Mekanism.logger.warn("Received transfer request from: {}, but source items aren't valid for the requested recipe: {}.", player, recipeID);
    } else if (!hasRoomToShuffle()) {
        // Note: Uses debug logging level as there are a couple cases this might not be 100% accurate on the client side
        Mekanism.logger.debug("Received transfer request from: {}, but there is not enough room to shuffle items around for the requested recipe: {}.", player, recipeID);
    } else {
        transferItems(sources);
    }
}
Also used : CraftingInventory(net.minecraft.inventory.CraftingInventory) SingularHashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource) Byte2ObjectMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectMap) ArrayList(java.util.ArrayList) NonNullList(net.minecraft.util.NonNullList) List(java.util.List) ItemStack(net.minecraft.item.ItemStack) CraftingWindowInventorySlot(mekanism.common.inventory.slot.CraftingWindowInventorySlot)

Example 5 with SingularHashedItemSource

use of mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource in project Mekanism by mekanism.

the class PacketQIOFillCraftingWindow method encode.

@Override
public void encode(PacketBuffer buffer) {
    buffer.writeResourceLocation(recipeID);
    buffer.writeBoolean(maxTransfer);
    // Cast to byte as this should always be at most 9
    buffer.writeByte((byte) sources.size());
    for (Byte2ObjectMap.Entry<List<SingularHashedItemSource>> entry : sources.byte2ObjectEntrySet()) {
        // Target Slot
        buffer.writeByte(entry.getByteKey());
        // Source slot
        List<SingularHashedItemSource> slotSources = entry.getValue();
        if (maxTransfer) {
            // We "cheat" by only writing the list size if we are transferring as many items as possible as
            // the list will always be of size one
            buffer.writeVarInt(slotSources.size());
        }
        for (SingularHashedItemSource source : slotSources) {
            byte sourceSlot = source.getSlot();
            // We "cheat" here by just writing the source slot regardless of if we are in the crafting window, main inventory, or QIO
            // as then we can use the not a valid value as indication that we have a UUID following for QIO source, and otherwise we
            // get away with not having to write some sort of identifier for which type of data we are transferring
            buffer.writeByte(sourceSlot);
            if (maxTransfer) {
                // We "cheat" by only writing the amount used if we are transferring as many items as possible as
                // this will always just be one
                buffer.writeVarInt(source.getUsed());
            }
            if (sourceSlot == -1) {
                // If we don't actually have a source slot, that means we need to write the UUID
                // as it is being transferred out of the QIO
                UUID qioSource = source.getQioSource();
                if (qioSource == null) {
                    throw new IllegalStateException("Invalid QIO crafting window transfer source.");
                }
                buffer.writeUUID(qioSource);
            }
        }
    }
}
Also used : SingularHashedItemSource(mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource) Byte2ObjectMap(it.unimi.dsi.fastutil.bytes.Byte2ObjectMap) ArrayList(java.util.ArrayList) List(java.util.List) UUID(java.util.UUID)

Aggregations

ArrayList (java.util.ArrayList)6 List (java.util.List)6 SingularHashedItemSource (mekanism.common.content.qio.QIOCraftingTransferHelper.SingularHashedItemSource)6 Byte2ObjectMap (it.unimi.dsi.fastutil.bytes.Byte2ObjectMap)5 Byte2ObjectArrayMap (it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap)4 UUID (java.util.UUID)4 ItemStack (net.minecraft.item.ItemStack)4 CraftingWindowInventorySlot (mekanism.common.inventory.slot.CraftingWindowInventorySlot)3 HashedItem (mekanism.common.lib.inventory.HashedItem)3 ByteArrayList (it.unimi.dsi.fastutil.bytes.ByteArrayList)2 ByteList (it.unimi.dsi.fastutil.bytes.ByteList)2 Object2BooleanArrayMap (it.unimi.dsi.fastutil.objects.Object2BooleanArrayMap)2 Object2BooleanMap (it.unimi.dsi.fastutil.objects.Object2BooleanMap)2 Object2IntArrayMap (it.unimi.dsi.fastutil.objects.Object2IntArrayMap)2 Object2IntMap (it.unimi.dsi.fastutil.objects.Object2IntMap)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 IInventorySlot (mekanism.api.inventory.IInventorySlot)2 BaseSimulatedInventory (mekanism.common.content.qio.QIOCraftingTransferHelper.BaseSimulatedInventory)2 HashedItemSource (mekanism.common.content.qio.QIOCraftingTransferHelper.HashedItemSource)2