Search in sources :

Example 11 with IInventorySlot

use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.

the class TileEntityFormulaicAssemblicator method organizeStock.

private void organizeStock() {
    if (formula == null) {
        return;
    }
    // build map of what items we have to organize
    Object2IntMap<HashedItem> storedMap = new Object2IntOpenHashMap<>();
    for (IInventorySlot inputSlot : inputSlots) {
        ItemStack stack = inputSlot.getStack();
        if (!stack.isEmpty()) {
            HashedItem hashed = HashedItem.create(stack);
            storedMap.put(hashed, storedMap.getOrDefault(hashed, 0) + stack.getCount());
        }
    }
    // place items into respective controlled slots
    IntSet unused = new IntOpenHashSet();
    for (int i = 0; i < inputSlots.size(); i++) {
        HashedItem hashedItem = stockControlMap[i];
        if (hashedItem == null) {
            unused.add(i);
        } else if (storedMap.containsKey(hashedItem)) {
            int stored = storedMap.getInt(hashedItem);
            int count = Math.min(hashedItem.getStack().getMaxStackSize(), stored);
            if (count == stored) {
                storedMap.removeInt(hashedItem);
            } else {
                storedMap.put(hashedItem, stored - count);
            }
            setSlotIfChanged(inputSlots.get(i), hashedItem, count);
        } else {
            // If we don't have the item stored anymore (already filled all previous slots with it),
            // then we need to empty the slot as the items in it has been moved to a more "optimal" slot
            // Note: We only set them to empty if they are not already empty to avoid onContentsChanged being called
            // Technically our default implementation doesn't fire onContentsChanged if the stack was already empty
            // but this is not an API contract
            IInventorySlot slot = inputSlots.get(i);
            if (!slot.isEmpty()) {
                slot.setEmpty();
            }
        }
    }
    // if we still have items, first try to add remaining items to known unused (non-controlled) slots
    boolean empty = storedMap.isEmpty();
    for (int i : unused) {
        IInventorySlot slot = inputSlots.get(i);
        if (empty) {
            // but this is not an API contract
            if (!slot.isEmpty()) {
                slot.setEmpty();
            }
        } else {
            empty = setSlotIfChanged(storedMap, slot);
        }
    }
    if (empty) {
        // If we are empty exit
        return;
    }
    // if we still have items, just add them to any slots that are still empty
    for (IInventorySlot inputSlot : inputSlots) {
        if (inputSlot.isEmpty()) {
            if (setSlotIfChanged(storedMap, inputSlot)) {
                // Exit all items accounted for
                return;
            }
        }
    }
    if (!storedMap.isEmpty()) {
        Mekanism.logger.error("Critical error: Formulaic Assemblicator had items left over after organizing stock. Impossible!");
    }
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) IntOpenHashSet(it.unimi.dsi.fastutil.ints.IntOpenHashSet) HashedItem(mekanism.common.lib.inventory.HashedItem) IntSet(it.unimi.dsi.fastutil.ints.IntSet) Object2IntOpenHashMap(it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap) ItemStack(net.minecraft.item.ItemStack) SyncableItemStack(mekanism.common.inventory.container.sync.SyncableItemStack)

Example 12 with IInventorySlot

use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.

the class TileEntityFormulaicAssemblicator method moveItemsToInput.

private void moveItemsToInput(boolean forcePush) {
    for (int i = 0; i < craftingGridSlots.size(); i++) {
        IInventorySlot recipeSlot = craftingGridSlots.get(i);
        ItemStack recipeStack = recipeSlot.getStack();
        if (!recipeStack.isEmpty() && (forcePush || (formula != null && !formula.isIngredientInPos(getLevel(), recipeStack, i)))) {
            recipeSlot.setStack(tryMoveToInput(recipeStack));
        }
    }
    markDirty(false);
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) ItemStack(net.minecraft.item.ItemStack) SyncableItemStack(mekanism.common.inventory.container.sync.SyncableItemStack)

Example 13 with IInventorySlot

use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.

the class TileEntityFormulaicAssemblicator method moveItemsToGrid.

private boolean moveItemsToGrid() {
    boolean ret = true;
    for (int i = 0; i < craftingGridSlots.size(); i++) {
        IInventorySlot recipeSlot = craftingGridSlots.get(i);
        ItemStack recipeStack = recipeSlot.getStack();
        if (formula.isIngredientInPos(level, recipeStack, i)) {
            continue;
        }
        if (recipeStack.isEmpty()) {
            boolean found = false;
            for (int j = inputSlots.size() - 1; j >= 0; j--) {
                // The stack stored in the stock inventory
                IInventorySlot stockSlot = inputSlots.get(j);
                if (!stockSlot.isEmpty()) {
                    ItemStack stockStack = stockSlot.getStack();
                    if (formula.isIngredientInPos(level, stockStack, i)) {
                        recipeSlot.setStack(StackUtils.size(stockStack, 1));
                        MekanismUtils.logMismatchedStackSize(stockSlot.shrinkStack(1, Action.EXECUTE), 1);
                        markDirty(false);
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                ret = false;
            }
        } else {
            // Update recipeStack as well, so we can check if it is empty without having to get it again
            recipeSlot.setStack(recipeStack = tryMoveToInput(recipeStack));
            markDirty(false);
            if (!recipeStack.isEmpty()) {
                ret = false;
            }
        }
    }
    return ret;
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) ItemStack(net.minecraft.item.ItemStack) SyncableItemStack(mekanism.common.inventory.container.sync.SyncableItemStack)

Example 14 with IInventorySlot

use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.

the class EntityRobit method collectItems.

private void collectItems() {
    List<ItemEntity> items = level.getEntitiesOfClass(ItemEntity.class, getBoundingBox().inflate(1.5, 1.5, 1.5));
    if (!items.isEmpty()) {
        for (ItemEntity item : items) {
            if (isItemValid(item)) {
                for (IInventorySlot slot : inventoryContainerSlots) {
                    if (slot.isEmpty()) {
                        slot.setStack(item.getItem());
                        take(item, item.getItem().getCount());
                        item.remove();
                        playSound(SoundEvents.ITEM_PICKUP, 1, ((random.nextFloat() - random.nextFloat()) * 0.7F + 1.0F) * 2.0F);
                        break;
                    }
                    ItemStack itemStack = slot.getStack();
                    int maxSize = slot.getLimit(itemStack);
                    if (ItemHandlerHelper.canItemStacksStack(itemStack, item.getItem()) && itemStack.getCount() < maxSize) {
                        int needed = maxSize - itemStack.getCount();
                        int toAdd = Math.min(needed, item.getItem().getCount());
                        MekanismUtils.logMismatchedStackSize(slot.growStack(toAdd, Action.EXECUTE), toAdd);
                        item.getItem().shrink(toAdd);
                        take(item, toAdd);
                        if (item.getItem().isEmpty()) {
                            item.remove();
                        }
                        playSound(SoundEvents.ITEM_PICKUP, 1, ((random.nextFloat() - random.nextFloat()) * 0.7F + 1.0F) * 2.0F);
                        break;
                    }
                }
            }
        }
    }
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) ItemEntity(net.minecraft.entity.item.ItemEntity) ItemStack(net.minecraft.item.ItemStack)

Example 15 with IInventorySlot

use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.

the class InventoryUtils method getEjectItemMap.

@Contract("_, _ -> param1")
public static <REQUEST extends TileTransitRequest> REQUEST getEjectItemMap(REQUEST request, List<IInventorySlot> slots) {
    // shuffle the order we look at our slots to avoid ejection patterns
    List<IInventorySlot> shuffled = new ArrayList<>(slots);
    Collections.shuffle(shuffled);
    for (IInventorySlot slot : shuffled) {
        // Note: We are using EXTERNAL as that is what we actually end up using when performing the extraction in the end
        ItemStack simulatedExtraction = slot.extractItem(slot.getCount(), Action.SIMULATE, AutomationType.EXTERNAL);
        if (!simulatedExtraction.isEmpty()) {
            request.addItem(simulatedExtraction, slots.indexOf(slot));
        }
    }
    return request;
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) ArrayList(java.util.ArrayList) ItemStack(net.minecraft.item.ItemStack) Contract(org.jetbrains.annotations.Contract)

Aggregations

IInventorySlot (mekanism.api.inventory.IInventorySlot)22 ItemStack (net.minecraft.item.ItemStack)12 ArrayList (java.util.ArrayList)7 Nonnull (javax.annotation.Nonnull)5 SyncableItemStack (mekanism.common.inventory.container.sync.SyncableItemStack)5 HashedItem (mekanism.common.lib.inventory.HashedItem)5 ConfigInfo (mekanism.common.tile.component.config.ConfigInfo)4 List (java.util.List)3 Nullable (javax.annotation.Nullable)3 IntList (it.unimi.dsi.fastutil.ints.IntList)2 IntOpenHashSet (it.unimi.dsi.fastutil.ints.IntOpenHashSet)2 IntSet (it.unimi.dsi.fastutil.ints.IntSet)2 Object2IntMap (it.unimi.dsi.fastutil.objects.Object2IntMap)2 Object2IntOpenHashMap (it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap)2 HashMap (java.util.HashMap)2 NBTConstants (mekanism.api.NBTConstants)2 IMekanismInventory (mekanism.api.inventory.IMekanismInventory)2 FloatingLong (mekanism.api.math.FloatingLong)2 ComputerMethod (mekanism.common.integration.computer.annotation.ComputerMethod)2 TileEntityMekanism (mekanism.common.tile.base.TileEntityMekanism)2