Résolu Taille d'un ItemStack vaut 0 à la sortie d'un slot
-
Salut, voilà tout, j’ai fait un bloc qui possède un slot qui ne peut contenir que des items d’instance ItemTool. Quand je met une pioche dans le slot (par exemple) tout se passe bien, c’est lorsque je récupère la pioche en cliquant dessus que je récupère un stack de pioche d’une taille de 0, ce problème n’arrive pas lors d’un shift-clique.
Mon Container :
package brokenswing.mod.inventory; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import brokenswing.mod.BrokenSwingBlocks; import brokenswing.mod.tileentities.TileEntityToolForge; public class ContainerToolForge extends Container { private TileEntityToolForge tile; private SlotToolForge forgeSlot; public ContainerToolForge(TileEntityToolForge tile, InventoryPlayer playerInventory) { this.tile = tile; this.addSlotToContainer(forgeSlot = new SlotToolForge(this.tile, 0, 80, 35)); for (int k = 0; k < 3; ++k) { for (int i1 = 0; i1 < 9; ++i1) { this.addSlotToContainer(new Slot(playerInventory, i1 + k * 9 + 9, 8 + i1 * 18, 84 + k * 18)); } } for (int l = 0; l < 9; ++l) { this.addSlotToContainer(new Slot(playerInventory, l, 8 + l * 18, 142)); } } @Override public boolean canInteractWith(EntityPlayer playerIn) { return this.tile.getWorld().getBlockState(this.tile.getPos()).getBlock() != BrokenSwingBlocks.toolForge ? false : playerIn.getDistanceSq((double)this.tile.getPos().getX() + 0.5D, (double)this.tile.getPos().getY() + 0.5D, (double)this.tile.getPos().getZ() + 0.5D) <= 64.0D; } @Override public ItemStack transferStackInSlot(EntityPlayer playerIn, int slotNumber) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(slotNumber); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (slotNumber == 0) { if (!this.mergeItemStack(itemstack1, 1, 37, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } else if (!this.forgeSlot.getHasStack() && this.forgeSlot.isItemValid(itemstack1) && itemstack1.stackSize == 1) { if (!this.mergeItemStack(itemstack1, 0, 1, false)) { return null; } } else if (slotNumber >= 1 && slotNumber < 28) { if (!this.mergeItemStack(itemstack1, 28, 37, false)) { return null; } } else if (slotNumber >= 28 && slotNumber < 37) { if (!this.mergeItemStack(itemstack1, 1, 28, false)) { return null; } } else if (!this.mergeItemStack(itemstack1, 1, 37, false)) { return null; } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } if (itemstack1.stackSize == itemstack.stackSize) { return null; } slot.onPickupFromSlot(playerIn, itemstack1); } return itemstack; } }
Mon Slot :
package brokenswing.mod.inventory; import javax.annotation.Nullable; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; public class SlotToolForge extends Slot { public SlotToolForge(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } @Override public boolean isItemValid(@Nullable ItemStack stack) { return stack != null && stack.getItem() instanceof ItemTool; } @Override public int getItemStackLimit(ItemStack stack) { return 1; } }
Et le TE :
package brokenswing.mod.tileentities; import java.util.ArrayList; import java.util.List; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ITickable; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import brokenswing.mod.effects.EnumEffect; import brokenswing.mod.items.IEffectProvider; public class TileEntityToolForge extends TileEntity implements IInventory, ITickable { private ItemStack content; @Override public void update() { if(content != null) { List <entityitem>items = this.getWorld().getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(this.getPos())); List <entityitem>toDelete = new ArrayList<entityitem>(); for(int i = 0; i < items.size(); i++) { if(items.get(i).getEntityItem().getItem() instanceof IEffectProvider) { IEffectProvider item = (IEffectProvider)items.get(i).getEntityItem().getItem(); boolean flag = true; if(!content.hasTagCompound()) { content.setTagCompound(new NBTTagCompound()); } if(!content.getTagCompound().hasKey("bsmodEffects")) { content.getTagCompound().setTag("bsmodEffects", new NBTTagList()); } NBTTagList tagList = (NBTTagList)content.getTagCompound().getTag("bsmodEffects"); for(int k = 0; k < tagList.tagCount(); k++) { String tag = tagList.getStringTagAt(k); if(EnumEffect.valueOf(tag) == item.getEffect()) { flag = false; } } if(flag) { tagList.appendTag(new NBTTagString(item.getEffect().name())); toDelete.add(items.get(i)); content.getTagCompound().setTag("bsmodEffects", tagList); } } this.markDirty(); } for(int i = 0; i < toDelete.size(); i++) { this.getWorld().removeEntity(toDelete.get(i)); } } } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); if(content != null) { NBTTagCompound itemCompound = new NBTTagCompound(); content.writeToNBT(itemCompound); compound.setTag("theStack", itemCompound); } return compound; } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); if(compound.hasKey("theStack")) { content = ItemStack.loadItemStackFromNBT((NBTTagCompound)compound.getTag("theStack")); } } @Override public String getName() { return "container.toolforge"; } @Override public boolean hasCustomName() { return false; } @Override public ITextComponent getDisplayName() { return new TextComponentString(this.getName()); } @Override public int getSizeInventory() { return 1; } @Override public ItemStack getStackInSlot(int index) { return index == 0 ? content : null; } @Override public ItemStack decrStackSize(int index, int count) { if(index == 0 && content != null) { ItemStack s = content; content.stackSize -= count; if(content.stackSize <= 0) { content = null; } return s; } return null; } @Override public ItemStack removeStackFromSlot(int index) { if(index == 0) { ItemStack stack = content; content = null; return stack; } return null; } @Override public void setInventorySlotContents(int index, ItemStack stack) { if(index == 0) content = stack; } @Override public int getInventoryStackLimit() { return 1; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return true; } @Override public void openInventory(EntityPlayer player) { } @Override public void closeInventory(EntityPlayer player) { } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return (index == 0 && stack.getItem() instanceof ItemTool) ? true : false ; } @Override public int getField(int id) { return 0; } @Override public void setField(int id, int value) { } @Override public int getFieldCount() { return 0; } @Override public void clear() { content = null; } }
Bon, j’espère que vous allez trouver xD Pour expliquer la fonction update du TE, elle récupère les EntityItem qui se trouvent dans le bloc (il a une box de collision modifiée) et les parcoure, si l’item est d’instance IEffectProvider, elle regarde si elle peut ajouter l’effet à l’outil dans le stack, en parcourant les tags NBT, si elle peut ajouter l’effet, elle l’ajoute et supprime l’EntityItem, voilà tout</entityitem></entityitem></entityitem>
-
Il y a un problème dans ta fonction decrStackSize (et peut-être dans removeStackFromSlot, je suis pas sûr),
ItemStack s = content; content.stackSize -= count;
or quand tu met un = entre deux itemStack, tu ne fait pas que copier les information de l’itemStack mais tu copie l’instance de l’item : c’est-à-dire que si tu modifie l’un, l’autre vas aussi être modifier donc à ta ligne suivante, tu enlève un item au stack qui était dans le TileEntity et aussi au nouveau stack qui vas être dans ta main. Il faut donc faire quelque chose comme ItemStack s = content.copy(); ( ou peut-être ItemStack s = new ItemStack(content)) pour seulement copier le contenu de l’ItemStack
-
Ok, merci, c’était bien cette fonction, j’ai utilisé ItemStackHelper mais ça marche, merci beacoup