Posted January 13, 20205 yr 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; } };
January 13, 20205 yr 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.
January 13, 20205 yr Author 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?
January 13, 20205 yr Author 1 hour ago, Draco18s said: Have two "versions" of your handler 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?
January 13, 20205 yr 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 January 13, 20205 yr 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.
January 13, 20205 yr Author 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); } }
January 14, 20205 yr 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.
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.