Jump to content

[1.14.4] Can't use setStackInSlot anymore


Tieso2001

Recommended Posts

I'm making a machine which has a result slot (same idea as the output slot of the furnace). You only take items out of the slot and not put them in. The problem is that in 1.12.2 you could use setStackInSlot on the ItemHandler to put the resulting item of a recipe into the slot (like when an item in a furnace smelts and the result appears in the output slot). In 1.14.4 I can't use setStackInSlot anymore (it won't let me), so how do I do this in 1.14.4?

 

I'm using isItemValid so that you can't put any items in, which is also what I used in 1.12.2 (and what the furnace uses)

Spoiler

private IItemHandler outputInventory = new ItemStackHandler(1) {
        @Override
        protected void onContentsChanged(int slot) {
            markDirty();
        }

        @Override
        public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
            return false;
        }
    };

 

 

Link to comment
Share on other sites

Have two "versions" of your handler. One is just a regular ItemStackHandler, which is used internally by your machine, and a non-modifiable version that you expose via getCapability.

eg:

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/entity/SifterTileEntity.java#L43

For guis, you'd also need an extract-only Slot class:

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/inventory/SifterContainer.java#L29

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

1 hour ago, Draco18s said:

One is just a regular ItemStackHandler, which is used internally by your machine, and a non-modifiable version that you expose via getCapability.

If I understand correctly, in your case the non-modifiable version is the outputSlotWrapper, right?

Link to comment
Share on other sites

32 minutes ago, Tieso2001 said:

If I understand correctly, in your case the non-modifiable version is the outputSlotWrapper, right?

Yes. The wrapper is just a handler that accepts another handler as its constructor and forwards all interactions to the wrapped handler, except for insertion (which it denies).

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/hardlib/api/internal/inventory/OutputItemStackHandler.java

Note that setStackInSlot and getStackInSlot forwards to the hidden inventory (and in theory this could be used to insert items) because of external realities and using them in that way have Undefined Behavior.

 

18 minutes ago, Tieso2001 said:

Why do I need two versions? Can't I just create an outputslot as an IItemHandler, cast it as an IItemHandlerModifiable when I have to insert a stack internally, and then expose the non-casted version?

The problem I found with trying to do something like this was that I could not actually modify things internally. Because remember, extraction is modification. Also, any external access would be able to perform the same cast and modify anyway, your intended restriction be damned (remember, you're trying to make type safety--a compile time check--prevent a runtime situation).

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

I have created this and it seems to work how I want it to. I can't drag of shift click item into the output slot, hoppers only insert in the input slot and when a crafting operation is completed, the result gets inserted into the output slot. I have a question about this: If I have to guess the reason that this works is that hoppers can only insert from the top or sides, and not from the bottom. That would mean that a machine that can insert items from the bottom of my block will insert the items into the output slot. Am I right about this?

 

If that is indeed the case then I will try to do the two version method you described. If the only way you can insert items into the output slot is by some obscure way that can only be done intentionally, then I think it is fine how it is right now.

 

Anyway here is the code:

Spoiler

public class CaskTileEntity extends TileEntity implements ITickableTileEntity, INamedContainerProvider {

    public ItemStackHandler inputSlot;
    public ItemStackHandler outputSlot;
    private final LazyOptional<IItemHandler> inputSlotHolder = LazyOptional.of(() -> inputSlot);
    private final LazyOptional<IItemHandler> outputSlotHolder = LazyOptional.of(() -> outputSlot);
    private final LazyOptional<IItemHandler> combinedHolder = LazyOptional.of(() -> new CombinedInvWrapper(inputSlot, outputSlot));

    protected FluidTank inputTank;
    private final LazyOptional<IFluidHandler> inputFluidHolder = LazyOptional.of(() -> inputTank);

    private RecipeWrapper recipeWrapper;

    public CaskTileEntity() {
        super(ModTileEntityTypes.CASK);
        inputSlot = new ItemStackHandler();
        outputSlot = new ItemStackHandler();
        inputTank = new FluidTank(1000);
        recipeWrapper = new RecipeWrapper(inputSlot);
    }

    @Override
    public CompoundNBT write(CompoundNBT compound) {
        compound.put("inputSlot", inputSlot.serializeNBT());
        compound.put("outputSlot", outputSlot.serializeNBT());
        inputTank.writeToNBT(compound);
        return compound;
    }

    @Override
    public void read(CompoundNBT compound) {
        super.read(compound);
        inputSlot.deserializeNBT(compound.getCompound("inputSlot"));
        outputSlot.deserializeNBT(compound.getCompound("outputSlot"));
        inputTank.readFromNBT(compound);
    }

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
        if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
            if (side == Direction.DOWN) return outputSlotHolder.cast();
            return inputSlotHolder.cast();
        }
        if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) return inputFluidHolder.cast();
        return super.getCapability(cap, side);
    }

    @Override
    public void tick() {
        CaskRecipe recipe = world.getRecipeManager().getRecipe(CaskRecipe.cask, recipeWrapper, world).orElse(null);

        if (recipe != null && canProcess(recipe)) {
            inputSlot.extractItem(0,1, false);
            ItemStack stack = new ItemStack(recipe.getRecipeOutput().getItem(), outputSlot.getStackInSlot(0).getCount() + recipe.getRecipeOutput().getCount());
            outputSlot.setStackInSlot(0, stack);
            inputTank.drain(recipe.getIngredientFluid().getAmount(), IFluidHandler.FluidAction.EXECUTE);
            markDirty();
        }
    }

    private boolean canProcess(CaskRecipe recipe) {
        boolean itemInput = !inputSlot.extractItem(0,1, true).isEmpty() || recipe.getIngredients().isEmpty();
        boolean fluidInput = inputTank.getFluid().containsFluid(recipe.getIngredientFluid());
        boolean outputItemType = outputSlot.getStackInSlot(0).isEmpty() || outputSlot.getStackInSlot(0).isItemEqual(recipe.getRecipeOutput());
        boolean outputItemAmount = outputSlot.getStackInSlot(0).getCount() + recipe.getRecipeOutput().getCount() <= outputSlot.getSlotLimit(0);
        return itemInput && fluidInput && outputItemType && outputItemAmount;
    }

    @Override
    public ITextComponent getDisplayName() {
        return new StringTextComponent(getType().getRegistryName().getPath());
    }

    @Nullable
    @Override
    public Container createMenu(int i, PlayerInventory playerInventory, PlayerEntity playerEntity) {
        return new CaskContainer(i, world, pos, playerInventory, playerEntity);
    }
}

 

 

Link to comment
Share on other sites

5 hours ago, Tieso2001 said:

That would mean that a machine that can insert items from the bottom of my block will insert the items into the output slot. Am I right about this?

They would have the ability to access the slot but they would not be able to insert because the handler exposed simply returns the entire stack unmodified as the "overflow" from any attempted insertion. It would act as if the slot was full.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.