I am designing a casino game mod and have a black jack table container with a GUI and 2 TileEntity inventory slots. I want it to duplicate the ItemStack in the first inventory slot and place the copy in the second slot. So far it creates the ItemStack and renders it in the slot but when the player attempts to click on this new ItemStack it disappears as if the new ItemStack was only an illusion. Below is my code, however it is highly commented as I have been testing many different methods I found online.
package com.j342256.casinonight.container;
import com.j342256.casinonight.tileentity.BlackJackTileEntity;
import com.j342256.casinonight.util.ModContainerTypes;
import com.j342256.casinonight.util.RegistryHandler;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.IContainerListener;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.util.NonNullList;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.Tags;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.items.*;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.GameData;
import org.apache.logging.log4j.core.pattern.AbstractStyleNameConverter;
import java.util.Objects;
public class BlackJackContainer extends Container implements IItemProvider {
public final BlackJackTileEntity tileEntity;
private final IWorldPosCallable canInteractWithCallable;
public Item item;
public BlackJackContainer(final int windowId, final PlayerInventory playerInventory,
final BlackJackTileEntity tileEntity) {
super(ModContainerTypes.BLACK_JACK.get(), windowId);
this.tileEntity = tileEntity;
this.canInteractWithCallable = IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos());
/*
LazyOptional<IItemHandler> inv = tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.DOWN);
addSlot(new SlotItemHandler(inv,0,80,35) {
@Override
public void onSlotChanged() {
tileEntity.markDirty();
}
});
*/
int startX = 70;
int startY = 225;
int deltaX = 18;
for (int i=0;i<9;++i){
this.addSlot(new Slot(playerInventory,i,startX + (i * deltaX),startY));
}
this.addSlot(new Slot(tileEntity, 0, 70, 195));
this.addSlot(new Slot(tileEntity, 1, 70, 175));
//ItemStack prize = new ItemStack(this.asItem(),2);
//this.tileEntity.setInventorySlotContents(0,prize);
}
private static BlackJackTileEntity getTileEntity(final PlayerInventory playerInventory,
final PacketBuffer data) {
Objects.requireNonNull(playerInventory, "playerInventory cannot be null");
Objects.requireNonNull(data, "data cannot be null");
final TileEntity tileAtPos = playerInventory.player.world.getTileEntity(data.readBlockPos());
if (tileAtPos instanceof BlackJackTileEntity) {
return (BlackJackTileEntity) tileAtPos;
}
throw new IllegalStateException("Tile entity is not correct! " + tileAtPos);
}
public BlackJackContainer(final int windowId, final PlayerInventory playerInventory, final PacketBuffer data) {
this(windowId, playerInventory, getTileEntity(playerInventory, data));
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return isWithinUsableDistance(canInteractWithCallable, playerIn, RegistryHandler.BLACK_JACK.get());
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (index < 36) {
if (!this.mergeItemStack(itemstack1, 36, this.inventorySlots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(itemstack1, 0, 36, false)) {
return ItemStack.EMPTY;
}
if (itemstack1.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
}
return itemstack;
}
public void generateItem(Item itg, int slotIndex){
//this.item = itg;
//int amt = this.tileEntity.getStackInSlot(0).getCount();
//this.tileEntity.setInventorySlotContents(slotIndex,new ItemStack(this.asItem(),amt));
this.tileEntity.generateItem();
}
@Override
public Item asItem() {
return this.item;
}
}
package com.j342256.casinonight.tileentity;
import com.j342256.casinonight.blocks.BlackJackBlock;
import com.j342256.casinonight.container.BlackJackContainer;
import com.j342256.casinonight.util.ModTileEntityTypes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.LockableLootTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import javax.annotation.Nonnull;
public class BlackJackTileEntity extends LockableLootTileEntity implements IItemProvider {
private NonNullList<ItemStack> chestContents = NonNullList.withSize(36, ItemStack.EMPTY);
protected int numPlayersUsing;
private IItemHandlerModifiable items = createHandler();
private LazyOptional<IItemHandlerModifiable> itemHandler = LazyOptional.of(() -> items);
public BlackJackTileEntity(TileEntityType<?> typeIn) {
super(typeIn);
}
public BlackJackTileEntity() {
this(ModTileEntityTypes.BLACK_JACK.get());
}
@Override
public int getSizeInventory() {
return 2;
}
@Override
public NonNullList<ItemStack> getItems() {
return this.chestContents;
}
@Override
public void setItems(NonNullList<ItemStack> itemsIn) {
this.chestContents = itemsIn;
}
@Override
protected ITextComponent getDefaultName() {
return new TranslationTextComponent("Black Jack Table");
}
@Override
protected Container createMenu(int id, PlayerInventory player) {
return new BlackJackContainer(id, player, this);
}
@Override
public CompoundNBT write(CompoundNBT compound) {
super.write(compound);
if (!this.checkLootAndWrite(compound)) {
ItemStackHelper.saveAllItems(compound, this.chestContents);
}
return compound;
}
@Override
public void read(CompoundNBT compound) {
super.read(compound);
this.chestContents = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (!this.checkLootAndRead(compound)) {
ItemStackHelper.loadAllItems(compound, this.chestContents);
}
}
private void playSound(SoundEvent sound) {
double dx = (double) this.pos.getX() + 0.5D;
double dy = (double) this.pos.getY() + 0.5D;
double dz = (double) this.pos.getZ() + 0.5D;
this.world.playSound((PlayerEntity) null, dx, dy, dz, sound, SoundCategory.BLOCKS, 0.5f,
this.world.rand.nextFloat() * 0.1f + 0.9f);
}
@Override
public boolean receiveClientEvent(int id, int type) {
if (id == 1) {
this.numPlayersUsing = type;
return true;
} else {
return super.receiveClientEvent(id, type);
}
}
@Override
public void openInventory(PlayerEntity player) {
if (!player.isSpectator()) {
if (this.numPlayersUsing < 0) {
this.numPlayersUsing = 0;
}
++this.numPlayersUsing;
this.onOpenOrClose();
}
}
@Override
public void closeInventory(PlayerEntity player) {
if (!player.isSpectator()) {
--this.numPlayersUsing;
this.onOpenOrClose();
}
}
protected void onOpenOrClose() {
Block block = this.getBlockState().getBlock();
if (block instanceof BlackJackBlock) {
this.world.addBlockEvent(this.pos, block, 1, this.numPlayersUsing);
this.world.notifyNeighborsOfStateChange(this.pos, block);
}
}
public static int getPlayersUsing(IBlockReader reader, BlockPos pos) {
BlockState blockstate = reader.getBlockState(pos);
if (blockstate.hasTileEntity()) {
TileEntity tileentity = reader.getTileEntity(pos);
if (tileentity instanceof BlackJackTileEntity) {
return ((BlackJackTileEntity) tileentity).numPlayersUsing;
}
}
return 0;
}
public static void swapContents(BlackJackTileEntity te, BlackJackTileEntity otherTe) {
NonNullList<ItemStack> list = te.getItems();
te.setItems(otherTe.getItems());
otherTe.setItems(list);
}
@Override
public void updateContainingBlockInfo() {
super.updateContainingBlockInfo();
if (this.itemHandler != null) {
this.itemHandler.invalidate();
this.itemHandler = null;
}
}
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nonnull Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return itemHandler.cast();
}
return super.getCapability(cap, side);
}
private IItemHandlerModifiable createHandler() {
return new InvWrapper(this);
}
public void generateItem(){
ItemStack a = new ItemStack(this.asItem(), 2);
ItemStack itemStack = this.items.insertItem(1, a, false);
}
@Override
public void remove() {
super.remove();
if(itemHandler != null) {
itemHandler.invalidate();
}
}
@Override
public Item asItem() {
return Items.DIAMOND;
}
}
I will note that when i use the method
this.tileEntity.setInventorySlotContents(slotIndex,new ItemStack(this.asItem(),amt));
inside the container class constructor the ItemStack is generated properly in the game.
What am i doing wrong here? I'm assuming it has to do with updating the server with the inventory changes but have no clue how to do it. markDirty() did not solve this issue...