bibouche_ Posted July 15, 2021 Posted July 15, 2021 Hi, I don't really know if my title is correct or appropriate but I don't know how to describe it. I created a TileEntity which you can fill only with one item, and which has an inventory size of 1, so it takes only one item in the inventory. My problem is that when I want to set the item in the slot, with items.set(0, ItemStack) (items is a NonNullList of ItemStacks), it is not setting it, and I don't know why because I did exactly the same thing with my other TileEntities (with more slots) and it works perfectly, so I don't know if it's a problem with NonNullList of size 1 or f I need a container (because I think I don't need a container if I won't add a gui but I may be wrong), or anything else. So please someone help me ? My TileEntity class: public class CelestialPowerPedestalTileEntity extends LockableLootTileEntity implements ISidedInventory { public static final int slots = 1; public NonNullList <ItemStack> items = NonNullList.withSize(slots, ItemStack.EMPTY); public CelestialPowerPedestalTileEntity() { super(ModTileEntities.CELESTIAL_POWER_PEDESTAL_TILE_ENTITY.get()); } @Override protected ITextComponent getDefaultName() { return new TranslationTextComponent("container." + Alcamod.ModID + ".celestial_power_pedestal"); } @Override public ITextComponent getDisplayName() { return new TranslationTextComponent("Celestial Power Pedestal"); } @Override protected Container createMenu( int id, PlayerInventory player) { return null; } @Override protected NonNullList <ItemStack> getItems() { return this.items; } public Item getItem() { return this.items.get(0).getItem(); } public ItemStack getStack() { return this.items.get(0); } @Override protected void setItems( @Nonnull NonNullList <ItemStack> itemsIn) { this.items = itemsIn; } public void setStack(ItemStack stack) { this.items.set(0, stack); } @Override public int getSizeInventory() { return 1; } public void read( BlockState state, CompoundNBT nbt) { super.read( state, nbt); this.items = NonNullList.withSize(getSizeInventory(), ItemStack.EMPTY); if (!this.checkLootAndRead(nbt)) { ItemStackHelper.loadAllItems(nbt, this.items); } } @Nonnull @Override public CompoundNBT write( CompoundNBT compound) { super.write(compound); if (!checkLootAndWrite(compound)) { ItemStackHelper.saveAllItems(compound, this.items); } return compound; } @Nonnull @Override public <T> LazyOptional <T> getCapability( Capability <T> cap, Direction side) { return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, LazyOptional.of(() -> (IItemHandler) this.items)); } @Nonnull @Override public int[] getSlotsForFace( Direction side) { return new int[] {0}; } @Override public boolean canInsertItem( int index, ItemStack stack, @Nullable Direction direction) { return stack.getItem() == ModItems.CELESTIAL_POWER_EYE.get(); } @Override public boolean canExtractItem( int index, ItemStack stack, Direction direction) { return true; } public boolean isFillable() { return getItem() != ModItems.CELESTIAL_POWER_EYE.get(); } } My Block class: public class CelestialPowerPedestal extends Block { public CelestialPowerPedestal() { super(Properties.create(Material.IRON) .hardnessAndResistance(40, 80) .sound(SoundType.BASALT) .harvestLevel(3) .harvestTool(ToolType.PICKAXE)); } public VoxelShape getShape( BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { return CelestialPowerPedestalVoxelShapes.SHAPE; } @Override public boolean hasTileEntity(BlockState state) { return true; } @Nullable @Override public TileEntity createTileEntity( BlockState state, IBlockReader world) { return ModTileEntities.CELESTIAL_POWER_PEDESTAL_TILE_ENTITY.get().create(); } @Override public ActionResultType onBlockActivated( BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (worldIn != null && !worldIn.isRemote()) { TileEntity te = worldIn.getTileEntity(pos); Item playerItem = player.getHeldItemMainhand() .getItem(); if (te instanceof CelestialPowerPedestalTileEntity) { if (((CelestialPowerPedestalTileEntity) te).isFillable() && playerItem == ModItems.CELESTIAL_POWER_EYE.get()) { ItemStack stack = player.getHeldItemMainhand(); ((CelestialPowerPedestalTileEntity) te).setStack(stack); player.getHeldItemMainhand().shrink(1); return ActionResultType.SUCCESS; } if (!((CelestialPowerPedestalTileEntity) te).isFillable()) { player.addItemStackToInventory(((CelestialPowerPedestalTileEntity) te).getStack()); ((CelestialPowerPedestalTileEntity) te).setStack(ItemStack.EMPTY); return ActionResultType.SUCCESS; } } } return ActionResultType.CONSUME; } @Override public void onReplaced( BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { TileEntity tile = worldIn.getTileEntity(pos); if (tile instanceof CelestialPowerPedestalTileEntity && state.getBlock() != newState.getBlock()) { InventoryHelper.dropInventoryItems(worldIn, pos, (IInventory) tile); worldIn.updateComparatorOutputLevel(pos, this); } if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { worldIn.removeTileEntity(pos); } } } The targeted code block where I put the action when the player right click the block: @Override public ActionResultType onBlockActivated( BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (worldIn != null && !worldIn.isRemote()) { TileEntity te = worldIn.getTileEntity(pos); Item playerItem = player.getHeldItemMainhand() .getItem(); if (te instanceof CelestialPowerPedestalTileEntity) { if (((CelestialPowerPedestalTileEntity) te).isFillable() && playerItem == ModItems.CELESTIAL_POWER_EYE.get()) { ItemStack stack = player.getHeldItemMainhand(); ((CelestialPowerPedestalTileEntity) te).setStack(stack); player.getHeldItemMainhand().shrink(1); return ActionResultType.SUCCESS; } if (!((CelestialPowerPedestalTileEntity) te).isFillable()) { player.addItemStackToInventory(((CelestialPowerPedestalTileEntity) te).getStack()); ((CelestialPowerPedestalTileEntity) te).setStack(ItemStack.EMPTY); return ActionResultType.SUCCESS; } } } return ActionResultType.CONSUME; } Quote
InspectorCaracal Posted July 16, 2021 Posted July 16, 2021 (I don't have a Forge solution so general debugging advice here) Did you manage to track down where exactly it's not working, or is the "not setting it" just a description of the effects? If you aren't sure where exactly it's not working the way it's supposed to, what I like to do to narrow down the issue is put in debug log lines that echo the status of the variables or code at all the steps of the process that's not working. Echoing your input/output for your set and get methods to console, for example, or checking the status of your items list at each step to see where it changes, or doesn't change, and so on. Then you can track down exactly which function call(s) aren't working right and try alternatives for them. Quote
bibouche_ Posted July 16, 2021 Author Posted July 16, 2021 38 minutes ago, diesieben07 said: Show updated code. @Override public ActionResultType onBlockActivated( BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (worldIn != null && !worldIn.isRemote()) { TileEntity te = worldIn.getTileEntity(pos); Item playerItem = player.getHeldItemMainhand() .getItem(); if (te instanceof CelestialPowerPedestalTileEntity) { if (((CelestialPowerPedestalTileEntity) te).isFillable() && playerItem == ModItems.CELESTIAL_POWER_EYE.get()) { ItemStack stack = player.getHeldItemMainhand(); ((CelestialPowerPedestalTileEntity) te).insertItem(0, stack, false); player.getHeldItemMainhand().shrink(1); Alcamod.LOGGER.info(((CelestialPowerPedestalTileEntity) te).getStackInSlot(0)); return ActionResultType.SUCCESS; } if (!((CelestialPowerPedestalTileEntity) te).isFillable()) { player.addItemStackToInventory(((CelestialPowerPedestalTileEntity) te).getStackInSlot(0)); ((CelestialPowerPedestalTileEntity) te).extractItem(0, 1, false); return ActionResultType.SUCCESS; } } } return ActionResultType.CONSUME; } In the tile entity: public Item getItem() { return getStackInSlot(0).getItem(); } @Override public ItemStack getStackInSlot( int index) { return this.items.get(index); } @Nonnull @Override public ItemStack insertItem( int slot, @Nonnull ItemStack stack, boolean simulate) { if (!this.isFillable()) return stack; return ItemStack.EMPTY; } @Nonnull @Override public ItemStack extractItem( int slot, int amount, boolean simulate) { if (this.isFillable()) return ItemStack.EMPTY; else return getStackInSlot(0); } @Override public int getSlotLimit( int slot) { return getStackInSlot(0).getMaxStackSize(); } @Override public boolean isItemValid( int slot, @Nonnull ItemStack stack) { return true; } Quote
loordgek Posted July 16, 2021 Posted July 16, 2021 https://mcforge.readthedocs.io/en/1.13.x/datastorage/capabilities/ Quote
bibouche_ Posted July 18, 2021 Author Posted July 18, 2021 I implemented IItemHandler as a capability, but i don't know why it is still not working, the setting part still seems to cause issues. here is the updated code: private static Capability <IItemHandler> capability = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY; public IItemHandler inv = capability.getDefaultInstance(); private final LazyOptional <IItemHandler> capabilityLazyOptional = LazyOptional.of(() -> inv); @Override protected NonNullList <ItemStack> getItems() { NonNullList<ItemStack> items = NonNullList.withSize(slots, ItemStack.EMPTY); for (int i = 0; i < inv.getSlots(); i++) { items.set(i, inv.getStackInSlot(i)); } return items; } @Override protected void setItems( NonNullList <ItemStack> itemsIn) { for (int i = 0; i < itemsIn.size(); i++) { inv.insertItem(i, itemsIn.get(i), false); } } public Item getItem() { return this.inv.getStackInSlot(0) .getItem(); } @Override public int getSizeInventory() { return slots; } public boolean isFillable() { return inv.getStackInSlot(0).getItem() != ModItems.CELESTIAL_POWER_EYE.get(); } @Nonnull @Override public <T> LazyOptional <T> getCapability( Capability <T> cap, Direction side) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return capabilityLazyOptional.cast(); } return super.getCapability(cap, side); } @Override protected void invalidateCaps() { super.invalidateCaps(); capabilityLazyOptional.invalidate(); } @Override public ActionResultType onBlockActivated( BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (worldIn != null && !worldIn.isRemote()) { TileEntity te = worldIn.getTileEntity(pos); Item playerItem = player.getHeldItemMainhand() .getItem(); if (te instanceof CelestialPowerPedestalTileEntity) { if (((CelestialPowerPedestalTileEntity) te).isFillable() && playerItem == ModItems.CELESTIAL_POWER_EYE.get()) { ItemStack stack = player.getHeldItemMainhand(); ((CelestialPowerPedestalTileEntity) te).inv.insertItem(0, stack, false); player.getHeldItemMainhand().shrink(1); return ActionResultType.SUCCESS; } if (!((CelestialPowerPedestalTileEntity) te).isFillable()) { player.addItemStackToInventory(((CelestialPowerPedestalTileEntity) te).inv.getStackInSlot(0)); ((CelestialPowerPedestalTileEntity) te).inv.extractItem(0, 1, false); return ActionResultType.SUCCESS; } } } return ActionResultType.CONSUME; } On 7/16/2021 at 7:07 PM, InspectorCaracal said: (I don't have a Forge solution so general debugging advice here) Did you manage to track down where exactly it's not working, or is the "not setting it" just a description of the effects? If you aren't sure where exactly it's not working the way it's supposed to, what I like to do to narrow down the issue is put in debug log lines that echo the status of the variables or code at all the steps of the process that's not working. Echoing your input/output for your set and get methods to console, for example, or checking the status of your items list at each step to see where it changes, or doesn't change, and so on. Then you can track down exactly which function call(s) aren't working right and try alternatives for them. I didn't do that but I saw that the problem was coming from the setting part, since everything works perfectly but this. Quote
bibouche_ Posted July 18, 2021 Author Posted July 18, 2021 Ok so I found that LockableLootTileEntity extends LockableTileEntity which implements IInventory, and my TileEntity was extending LockableLootTileEntity. However, even after changing the extends to TileEntity, which does not implements IInventory it is not working, god it will never end XD :(( Quote
bibouche_ Posted July 18, 2021 Author Posted July 18, 2021 I just changes in my TileEntity class the "extends LockableLootTileEntity" with "extends TileEntity", and removed the functionds that were implemented with it I changed some : protected NonNullList <ItemStack> getItems() { NonNullList<ItemStack> items = NonNullList.withSize(slots, ItemStack.EMPTY); for (int i = 0; i < inv.getSlots(); i++) { items.set(i, inv.getStackInSlot(i)); } return items; } protected void setItems( NonNullList <ItemStack> itemsIn) { for (int i = 0; i < itemsIn.size(); i++) { inv.insertItem(i, itemsIn.get(i), false); } } public Item getItem() { return this.inv.getStackInSlot(0) .getItem(); } public boolean isFillable() { return inv.getStackInSlot(0).getItem() != ModItems.CELESTIAL_POWER_EYE.get(); } public void read( BlockState state, CompoundNBT nbt) { super.read( state, nbt); NonNullList <ItemStack> inv = NonNullList.withSize(this.inv.getSlots(), ItemStack.EMPTY); ItemStackHelper.loadAllItems(nbt, inv); setItems(inv); } @Nonnull @Override public CompoundNBT write( CompoundNBT compound) { super.write(compound); ItemStackHelper.saveAllItems(compound, this.getItems()); return compound; } I did not changed the capability and ItemHandler related things: public static final int slots = 1; private static Capability <IItemHandler> capability = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY; public IItemHandler inv = capability.getDefaultInstance(); private final LazyOptional <IItemHandler> capabilityLazyOptional = LazyOptional.of(() -> inv); @Nonnull @Override public <T> LazyOptional <T> getCapability( Capability <T> cap, Direction side) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return capabilityLazyOptional.cast(); } return super.getCapability(cap, side); } @Override protected void invalidateCaps() { super.invalidateCaps(); capabilityLazyOptional.invalidate(); } And retouched the onBlockActivated function: @Override public ActionResultType onBlockActivated( BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if (worldIn != null && !worldIn.isRemote()) { TileEntity te = worldIn.getTileEntity(pos); Item playerItem = player.getHeldItemMainhand() .getItem(); if (te instanceof CelestialPowerPedestalTileEntity) { if (((CelestialPowerPedestalTileEntity) te).isFillable() && playerItem == ModItems.CELESTIAL_POWER_EYE.get()) { ItemStack stack = player.getHeldItemMainhand(); ((CelestialPowerPedestalTileEntity) te).inv.insertItem(0, stack, false); player.getHeldItemMainhand().shrink(1); return ActionResultType.SUCCESS; } if (!((CelestialPowerPedestalTileEntity) te).isFillable()) { player.addItemStackToInventory(((CelestialPowerPedestalTileEntity) te).inv.getStackInSlot(0)); ((CelestialPowerPedestalTileEntity) te).inv.extractItem(0, 1, false); return ActionResultType.SUCCESS; } } } return ActionResultType.CONSUME; } Quote
bibouche_ Posted July 18, 2021 Author Posted July 18, 2021 10 minutes ago, diesieben07 said: You cannot modify an ItemStack once you give it to the IItemHandler via insertItem. Here you shrink it afterwards, which will cause undocumented behavior. Ok, indeed I did not realize this, but putting a copy of the item stack in the tile entity and then shrinking the original seems to work. Was such a stupid thing, thank you ! Quote
Draco18s Posted July 18, 2021 Posted July 18, 2021 https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/industry/entity/WoodenHopperTileEntity.java#L21 https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/hardlib/api/internal/inventory/MaxSizeItemStackHandler.java#L5 Quote 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.
Recommended Posts
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.