SOLVED Taille d'un ItemStack vaut 0 à la sortie d'un slot

  • Moddeurs confirmés Rédacteurs

    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

  • Moddeurs confirmés Rédacteurs

    Ok, merci, c'était bien cette fonction, j'ai utilisé ItemStackHelper mais ça marche, merci beacoup