Search in sources :

Example 1 with IMekanismInventory

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

the class ItemRecipeData method applyToStack.

@Override
public boolean applyToStack(ItemStack stack) {
    if (slots.isEmpty()) {
        return true;
    }
    Item item = stack.getItem();
    boolean isBin = item instanceof ItemBlockBin;
    Optional<IItemHandler> capability = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).resolve();
    List<IInventorySlot> slots = new ArrayList<>();
    if (capability.isPresent()) {
        IItemHandler itemHandler = capability.get();
        for (int i = 0; i < itemHandler.getSlots(); i++) {
            int slot = i;
            slots.add(new DummyInventorySlot(itemHandler.getSlotLimit(slot), itemStack -> itemHandler.isItemValid(slot, itemStack), isBin));
        }
    } else if (item instanceof BlockItem) {
        TileEntityMekanism tile = getTileFromBlock(((BlockItem) item).getBlock());
        if (tile == null || !tile.persistInventory()) {
            // Something went wrong
            return false;
        }
        for (int i = 0; i < tile.getSlots(); i++) {
            int slot = i;
            slots.add(new DummyInventorySlot(tile.getSlotLimit(slot), itemStack -> tile.isItemValid(slot, itemStack), isBin));
        }
    } else if (item instanceof ItemRobit) {
        // Inventory slots
        for (int slotY = 0; slotY < 3; slotY++) {
            for (int slotX = 0; slotX < 9; slotX++) {
                slots.add(new DummyInventorySlot(BasicInventorySlot.DEFAULT_LIMIT, BasicInventorySlot.alwaysTrue, false));
            }
        }
        // Energy slot
        slots.add(new DummyInventorySlot(BasicInventorySlot.DEFAULT_LIMIT, itemStack -> {
            if (EnergyCompatUtils.hasStrictEnergyHandler(itemStack)) {
                return true;
            }
            ItemStackToEnergyRecipe foundRecipe = MekanismRecipeType.ENERGY_CONVERSION.getInputCache().findTypeBasedRecipe(null, itemStack);
            return foundRecipe != null && !foundRecipe.getOutput(itemStack).isZero();
        }, false));
        // Smelting input slot
        slots.add(new DummyInventorySlot(BasicInventorySlot.DEFAULT_LIMIT, itemStack -> MekanismRecipeType.SMELTING.getInputCache().containsInput(null, itemStack), false));
        // Smelting output slot
        slots.add(new DummyInventorySlot(BasicInventorySlot.DEFAULT_LIMIT, BasicInventorySlot.alwaysTrue, false));
    } else if (item instanceof ISustainedInventory) {
        // Fallback just save it all
        for (IInventorySlot slot : this.slots) {
            if (!slot.isEmpty()) {
                // We have no information about what our item supports, but we have at least some stacks we want to transfer
                ((ISustainedInventory) stack.getItem()).setInventory(DataHandlerUtils.writeContainers(this.slots), stack);
                return true;
            }
        }
        return true;
    } else {
        return false;
    }
    if (slots.isEmpty()) {
        // We don't actually have any tanks in the output
        return true;
    }
    // TODO: Improve the logic so that it maybe tries multiple different slot combinations
    IMekanismInventory outputHandler = new IMekanismInventory() {

        @Nonnull
        @Override
        public List<IInventorySlot> getInventorySlots(@Nullable Direction side) {
            return slots;
        }

        @Override
        public void onContentsChanged() {
        }
    };
    boolean hasData = false;
    for (IInventorySlot slot : this.slots) {
        if (!slot.isEmpty()) {
            if (!ItemHandlerHelper.insertItemStacked(outputHandler, slot.getStack(), false).isEmpty()) {
                // If we have a remainder something failed so bail
                return false;
            }
            hasData = true;
        }
    }
    if (hasData) {
        // We managed to transfer it all into valid slots, so save it to the stack
        ((ISustainedInventory) stack.getItem()).setInventory(DataHandlerUtils.writeContainers(slots), stack);
    }
    return true;
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) IItemHandler(net.minecraftforge.items.IItemHandler) EnergyCompatUtils(mekanism.common.integration.energy.EnergyCompatUtils) IMekanismInventory(mekanism.api.inventory.IMekanismInventory) Item(net.minecraft.item.Item) BasicInventorySlot(mekanism.common.inventory.slot.BasicInventorySlot) Direction(net.minecraft.util.Direction) ParametersAreNonnullByDefault(javax.annotation.ParametersAreNonnullByDefault) ArrayList(java.util.ArrayList) ItemStack(net.minecraft.item.ItemStack) ItemHandlerHelper(net.minecraftforge.items.ItemHandlerHelper) Nonnull(javax.annotation.Nonnull) NonNull(mekanism.api.annotations.NonNull) ItemBlockBin(mekanism.common.item.block.ItemBlockBin) Nullable(javax.annotation.Nullable) TileEntityMekanism(mekanism.common.tile.base.TileEntityMekanism) ISustainedInventory(mekanism.common.tile.interfaces.ISustainedInventory) ListNBT(net.minecraft.nbt.ListNBT) MekanismRecipeType(mekanism.common.recipe.MekanismRecipeType) ItemRobit(mekanism.common.item.ItemRobit) Predicate(java.util.function.Predicate) DataHandlerUtils(mekanism.api.DataHandlerUtils) List(java.util.List) FieldsAreNonnullByDefault(mekanism.api.annotations.FieldsAreNonnullByDefault) IInventorySlot(mekanism.api.inventory.IInventorySlot) BlockItem(net.minecraft.item.BlockItem) NBTConstants(mekanism.api.NBTConstants) CapabilityItemHandler(net.minecraftforge.items.CapabilityItemHandler) ItemStackToEnergyRecipe(mekanism.api.recipes.ItemStackToEnergyRecipe) Optional(java.util.Optional) TileEntityMekanism(mekanism.common.tile.base.TileEntityMekanism) ISustainedInventory(mekanism.common.tile.interfaces.ISustainedInventory) IItemHandler(net.minecraftforge.items.IItemHandler) ItemRobit(mekanism.common.item.ItemRobit) ArrayList(java.util.ArrayList) BlockItem(net.minecraft.item.BlockItem) Direction(net.minecraft.util.Direction) ItemBlockBin(mekanism.common.item.block.ItemBlockBin) Item(net.minecraft.item.Item) BlockItem(net.minecraft.item.BlockItem) ItemStackToEnergyRecipe(mekanism.api.recipes.ItemStackToEnergyRecipe) IMekanismInventory(mekanism.api.inventory.IMekanismInventory) Nullable(javax.annotation.Nullable)

Example 2 with IMekanismInventory

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

the class ItemConfigurator method useOn.

@Nonnull
@Override
public ActionResultType useOn(ItemUseContext context) {
    PlayerEntity player = context.getPlayer();
    World world = context.getLevel();
    if (!world.isClientSide && player != null) {
        BlockPos pos = context.getClickedPos();
        Direction side = context.getClickedFace();
        ItemStack stack = context.getItemInHand();
        TileEntity tile = WorldUtils.getTileEntity(world, pos);
        ConfiguratorMode mode = getMode(stack);
        if (mode.isConfigurating()) {
            // Configurate
            TransmissionType transmissionType = Objects.requireNonNull(mode.getTransmission(), "Configurating state requires transmission type");
            if (tile instanceof ISideConfiguration && ((ISideConfiguration) tile).getConfig().supports(transmissionType)) {
                ISideConfiguration config = (ISideConfiguration) tile;
                ConfigInfo info = config.getConfig().getConfig(transmissionType);
                if (info != null) {
                    RelativeSide relativeSide = RelativeSide.fromDirections(config.getDirection(), side);
                    DataType dataType = info.getDataType(relativeSide);
                    if (!player.isShiftKeyDown()) {
                        player.sendMessage(MekanismUtils.logFormat(MekanismLang.CONFIGURATOR_VIEW_MODE.translate(transmissionType, dataType.getColor(), dataType, dataType.getColor().getColoredName())), Util.NIL_UUID);
                    } else if (SecurityUtils.canAccess(player, tile)) {
                        if (!player.isCreative()) {
                            IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
                            FloatingLong energyPerConfigure = MekanismConfig.gear.configuratorEnergyPerConfigure.get();
                            if (energyContainer == null || energyContainer.extract(energyPerConfigure, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyPerConfigure)) {
                                return ActionResultType.FAIL;
                            }
                            energyContainer.extract(energyPerConfigure, Action.EXECUTE, AutomationType.MANUAL);
                        }
                        DataType old = dataType;
                        dataType = info.incrementDataType(relativeSide);
                        if (dataType != old) {
                            player.sendMessage(MekanismUtils.logFormat(MekanismLang.CONFIGURATOR_TOGGLE_MODE.translate(transmissionType, dataType.getColor(), dataType, dataType.getColor().getColoredName())), Util.NIL_UUID);
                            config.getConfig().sideChanged(transmissionType, relativeSide);
                        }
                    } else {
                        SecurityUtils.displayNoAccess(player);
                    }
                }
                return ActionResultType.SUCCESS;
            }
            if (SecurityUtils.canAccess(player, tile)) {
                Optional<IConfigurable> capability = CapabilityUtils.getCapability(tile, Capabilities.CONFIGURABLE_CAPABILITY, side).resolve();
                if (capability.isPresent()) {
                    IConfigurable config = capability.get();
                    if (player.isShiftKeyDown()) {
                        return config.onSneakRightClick(player, side);
                    }
                    return config.onRightClick(player, side);
                }
            } else {
                SecurityUtils.displayNoAccess(player);
                return ActionResultType.SUCCESS;
            }
        } else if (mode == ConfiguratorMode.EMPTY) {
            // Empty
            if (tile instanceof IMekanismInventory) {
                IMekanismInventory inv = (IMekanismInventory) tile;
                if (inv.hasInventory()) {
                    if (SecurityUtils.canAccess(player, tile)) {
                        boolean creative = player.isCreative();
                        IEnergyContainer energyContainer = creative ? null : StorageUtils.getEnergyContainer(stack, 0);
                        if (!creative && energyContainer == null) {
                            return ActionResultType.FAIL;
                        }
                        // TODO: Switch this to items being handled by TileEntityMekanism, energy handled here (via lambdas?)
                        FloatingLong energyPerItemDump = MekanismConfig.gear.configuratorEnergyPerItem.get();
                        for (IInventorySlot inventorySlot : inv.getInventorySlots(null)) {
                            if (!inventorySlot.isEmpty()) {
                                if (!creative) {
                                    if (energyContainer.extract(energyPerItemDump, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyPerItemDump)) {
                                        break;
                                    }
                                    energyContainer.extract(energyPerItemDump, Action.EXECUTE, AutomationType.MANUAL);
                                }
                                Block.popResource(world, pos, inventorySlot.getStack().copy());
                                inventorySlot.setEmpty();
                            }
                        }
                        return ActionResultType.SUCCESS;
                    } else {
                        SecurityUtils.displayNoAccess(player);
                        return ActionResultType.FAIL;
                    }
                }
            }
        } else if (mode == ConfiguratorMode.ROTATE) {
            // Rotate
            if (tile instanceof TileEntityMekanism) {
                if (SecurityUtils.canAccess(player, tile)) {
                    TileEntityMekanism tileMekanism = (TileEntityMekanism) tile;
                    if (Attribute.get(tileMekanism.getBlockType(), AttributeStateFacing.class).canRotate()) {
                        if (!player.isShiftKeyDown()) {
                            tileMekanism.setFacing(side);
                        } else if (player.isShiftKeyDown()) {
                            tileMekanism.setFacing(side.getOpposite());
                        }
                    }
                } else {
                    SecurityUtils.displayNoAccess(player);
                }
            }
            return ActionResultType.SUCCESS;
        } else if (mode == ConfiguratorMode.WRENCH) {
            // Wrench
            return ActionResultType.PASS;
        }
    }
    return ActionResultType.PASS;
}
Also used : IInventorySlot(mekanism.api.inventory.IInventorySlot) TileEntityMekanism(mekanism.common.tile.base.TileEntityMekanism) World(net.minecraft.world.World) ConfigInfo(mekanism.common.tile.component.config.ConfigInfo) Direction(net.minecraft.util.Direction) IConfigurable(mekanism.api.IConfigurable) ConfiguratorMode(mekanism.common.item.ItemConfigurator.ConfiguratorMode) AttributeStateFacing(mekanism.common.block.attribute.AttributeStateFacing) PlayerEntity(net.minecraft.entity.player.PlayerEntity) TileEntity(net.minecraft.tileentity.TileEntity) FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) TransmissionType(mekanism.common.lib.transmitter.TransmissionType) RelativeSide(mekanism.api.RelativeSide) DataType(mekanism.common.tile.component.config.DataType) IMekanismInventory(mekanism.api.inventory.IMekanismInventory) BlockPos(net.minecraft.util.math.BlockPos) ItemStack(net.minecraft.item.ItemStack) ISideConfiguration(mekanism.common.tile.interfaces.ISideConfiguration) Nonnull(javax.annotation.Nonnull)

Aggregations

Nonnull (javax.annotation.Nonnull)2 IInventorySlot (mekanism.api.inventory.IInventorySlot)2 IMekanismInventory (mekanism.api.inventory.IMekanismInventory)2 TileEntityMekanism (mekanism.common.tile.base.TileEntityMekanism)2 ItemStack (net.minecraft.item.ItemStack)2 Direction (net.minecraft.util.Direction)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Optional (java.util.Optional)1 Predicate (java.util.function.Predicate)1 Nullable (javax.annotation.Nullable)1 ParametersAreNonnullByDefault (javax.annotation.ParametersAreNonnullByDefault)1 DataHandlerUtils (mekanism.api.DataHandlerUtils)1 IConfigurable (mekanism.api.IConfigurable)1 NBTConstants (mekanism.api.NBTConstants)1 RelativeSide (mekanism.api.RelativeSide)1 FieldsAreNonnullByDefault (mekanism.api.annotations.FieldsAreNonnullByDefault)1 NonNull (mekanism.api.annotations.NonNull)1 IEnergyContainer (mekanism.api.energy.IEnergyContainer)1 FloatingLong (mekanism.api.math.FloatingLong)1