Jump to content

Recommended Posts

Posted

Hello,

 

I'm very new to Minecraft modding...  (not to programming though), and i'm struggling to build a very basic furnace...

i've tried to extend the code from the Minecraft furnace (because i want to to the same thing... only with different items and custom recipes). (I know, most of the tutorials extend TileEntityLockable and implements ITickable, ISidedInventory... and then everyone paste the same code over and over again... )

 

Everything "works" but one things : shift clicking items, or manually putting items in the furnace don't really work. The item is there.. but it's not showing/updating.

Ex : I can put one item in the fuel (container seems to be empty), then one in the top slot, and the furnace start smelting... but the items are still in my inventory.

If i try to pick them, they instantly "teleport" to the proper slot..

 

I've tried to change all code in my Slots to return "true"

 @Override
    public boolean isItemValid(ItemStack stack) {
//        return stack.getItem() instanceof ItemXPFuel || stack.getItem() instanceof ItemBlockXPFuel;
        return true;
}

But I still have the same problem.

I tried to look at other methods such as TileEntity.isItemValidForSlot, TileEntity.setInventorySlotContents, etc... but it's still not working.

 

Do you know what could cause this kind of desynchronisation?

If you are willing to have a look, you can find everything here (container, tileentities, ..) : https://github.com/KyneSilverhide/XPEssence/tree/master/src/main/java/kyne/xpessence

 

Here is a video showing the problem :

 

And here are some snippets :

package kyne.xpessence.tileentities;

import kyne.xpessence.blocks.BlockXPFurnace;
import kyne.xpessence.containers.ContainerXPFurnace;
import kyne.xpessence.items.base.ItemBlockXPFuel;
import kyne.xpessence.items.base.ItemXPFuel;
import kyne.xpessence.recipes.ModSmeltingRecipes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntityFurnace;
import net.minecraft.util.MathHelper;

public class TileEntityXPFurnace extends TileEntityFurnace {

    public static final int SMELTING_ITEM_SLOT = 0;
    public static final int FUEL_ITEM_SLOT = 1;
    public static final int SMELTED_ITEM_SLOT = 2;

    private static final int BURN_TIME_FIELD = 0;
    private static final int CURRENT_ITEM_BURN_TIME_FIELD = 1;
    private static final int COOK_TIME_FIELD = 2;
    private static final int TOTAL_COOK_TIME_FIELD = 3;

    ...

    @Override
    public void update() {

        boolean wasBurning = this.isBurning();
        boolean dirty = false;

        if (this.isBurning()) {
            int burnTime = getField(BURN_TIME_FIELD);
            setField(BURN_TIME_FIELD, burnTime - 1);
        }

        if (!this.worldObj.isRemote) {

            ItemStack fuelItemStack = getStackInSlot(FUEL_ITEM_SLOT);
            ItemStack smeltingItem = getStackInSlot(SMELTING_ITEM_SLOT);
            int cookTime = getField(COOK_TIME_FIELD);
            int totalCookTime = getField(TOTAL_COOK_TIME_FIELD);
            if (this.isBurning() || fuelItemStack != null && smeltingItem != null) {
                if (!this.isBurning() && this.canSmelt()) {

                    int fuelAmount = getFuelAmount(fuelItemStack);
                    setField(BURN_TIME_FIELD, fuelAmount);
                    setField(CURRENT_ITEM_BURN_TIME_FIELD, fuelAmount);

                    if (this.isBurning()) {
                        dirty = true;

                        if (fuelItemStack != null) {
                            decrStackSize(FUEL_ITEM_SLOT, 1);
                            if (fuelItemStack.stackSize == 0) {
                                setInventorySlotContents(FUEL_ITEM_SLOT, fuelItemStack.getItem().getContainerItem(fuelItemStack));
                            }
                        }
                    }
                }

                if (this.isBurning() && this.canSmelt()) {
                    setField(COOK_TIME_FIELD, cookTime + 1);

                    if (cookTime == totalCookTime) {
                        setField(COOK_TIME_FIELD, 0);
                        setField(TOTAL_COOK_TIME_FIELD, this.getCookTime(smeltingItem));
                        this.smeltItem();
                        dirty = true;
                    }
                } else {
                    setField(COOK_TIME_FIELD, 0);
                }
            } else if (!this.isBurning() && cookTime > 0) {
                setField(COOK_TIME_FIELD, MathHelper.clamp_int(cookTime - 2, 0, totalCookTime));
            }

            if (wasBurning != this.isBurning()) {
                dirty = true;
                BlockXPFurnace.setState(this.isBurning(), this.worldObj, this.pos);
            }
        }

        if (dirty) {
            this.markDirty();
        }
    }

    public void setInventorySlotContents(int index, ItemStack stack) {
        System.out.println("index = [" + index + "], stack = [" + stack + "]");
        super.setInventorySlotContents(index, stack);
    }

    private int getFuelAmount(ItemStack fuelItemStack) {
        if(fuelItemStack.getItem() instanceof ItemXPFuel) {
            return ((ItemXPFuel)fuelItemStack.getItem()).getFuelAmount();
        } else if(fuelItemStack.getItem() instanceof  ItemBlockXPFuel) {
            return ((ItemBlockXPFuel) fuelItemStack.getItem()).getFuelAmount();
        }
        return 0;
    }

    private boolean canSmelt() {
        ItemStack smeltingItem = getStackInSlot(SMELTING_ITEM_SLOT);
        ItemStack smeltedItem = getStackInSlot(SMELTED_ITEM_SLOT);
        if (smeltingItem == null) {
            return false;
        } else {
            ItemStack itemstack = ModSmeltingRecipes.getSmeltingResult(smeltingItem);
            if (itemstack == null) {
                return false;
            }
            if (smeltedItem == null) {
                return true;
            }
            if (!smeltedItem.isItemEqual(itemstack)) {
                return false;
            }
            int result = smeltedItem.stackSize + itemstack.stackSize;
            return result <= getInventoryStackLimit() && result <= smeltedItem.getMaxStackSize();
        }
    }

    ...

    @Override
    public void smeltItem() {
        if (this.canSmelt()) {
            ItemStack smeltingItem = getStackInSlot(SMELTING_ITEM_SLOT);
            ItemStack itemstack = ModSmeltingRecipes.getSmeltingResult(smeltingItem);
            ItemStack smeltedItem = getStackInSlot(SMELTED_ITEM_SLOT);

            if (itemstack != null) {
                if (smeltedItem == null) {
                    setInventorySlotContents(SMELTED_ITEM_SLOT, itemstack.copy());
                } else if (smeltedItem.getItem() == itemstack.getItem()) {
                    smeltedItem.stackSize += itemstack.stackSize;
                }
                decrStackSize(SMELTING_ITEM_SLOT, 1);
            }
        }
    }

    @Override
    public boolean isItemValidForSlot(int slot, ItemStack stack) {
        System.out.println("slot = [" + slot + "], stack = [" + stack + "]");
        return canInsertInSlot(slot, stack);
    }

    public static boolean canInsertInSlot(int slot, ItemStack stack) {
        return true;
//        if (slot == FUEL_ITEM_SLOT) {
//            return stack.getItem() instanceof ItemXPFuel || stack.getItem() instanceof ItemBlockXPFuel;
//        } else if (slot == SMELTING_ITEM_SLOT) {
//            return ModSmeltingRecipes.getSmeltingResult(stack) != null;
//        }
//        return false;
    }

    public static boolean isSmeltableItem(ItemStack stack) {
        System.out.println("stack = [" + stack + "]");
        return canInsertInSlot(SMELTING_ITEM_SLOT, stack);
    }

    ...

    @Override
    public Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn) {
        return new ContainerXPFurnace(playerInventory, this);
    }
}

 

import kyne.xpessence.items.base.ItemBlockXPFuel;
import kyne.xpessence.items.base.ItemXPFuel;
import kyne.xpessence.recipes.ModSmeltingRecipes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class ContainerXPFurnace extends Container {

    private final IInventory tileFurnace;
    private int field_178152_f;
    private int field_178153_g;
    private int field_178154_h;
    private int field_178155_i;

    public ContainerXPFurnace(InventoryPlayer playerInventory, IInventory furnaceInventory) {
        this.tileFurnace = furnaceInventory;
        this.addSlotToContainer(new SlotXPSmeltable(furnaceInventory, 0, 56, 17));
        this.addSlotToContainer(new SlotXPFuel(furnaceInventory, 1, 56, 53));
        this.addSlotToContainer(new SlotXPOutput(furnaceInventory, 2, 116, 35));

        addPlayerInventory(playerInventory);
        addPlayerToolbar(playerInventory);
    }

    private void addPlayerToolbar(InventoryPlayer playerInventory) {
        for (int k = 0; k < 9; ++k) {
            this.addSlotToContainer(new Slot(playerInventory, k, 8 + k * 18, 142));
        }
    }

    private void addPlayerInventory(InventoryPlayer playerInventory) {
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 9; ++j) {
                this.addSlotToContainer(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
            }
        }
    }

    @Override
    public void onCraftGuiOpened(ICrafting listener) {
        super.onCraftGuiOpened(listener);
        listener.sendAllWindowProperties(this, this.tileFurnace);
    }

    /**
     * Looks for changes made in the container, sends them to every listener.
     */
    @Override
    public void detectAndSendChanges() {
        super.detectAndSendChanges();

        for (ICrafting icrafting : this.crafters) {
            if (this.field_178152_f != this.tileFurnace.getField(2)) {
                icrafting.sendProgressBarUpdate(this, 2, this.tileFurnace.getField(2));
            }

            if (this.field_178154_h != this.tileFurnace.getField(0)) {
                icrafting.sendProgressBarUpdate(this, 0, this.tileFurnace.getField(0));
            }

            if (this.field_178155_i != this.tileFurnace.getField(1)) {
                icrafting.sendProgressBarUpdate(this, 1, this.tileFurnace.getField(1));
            }

            if (this.field_178153_g != this.tileFurnace.getField(3)) {
                icrafting.sendProgressBarUpdate(this, 3, this.tileFurnace.getField(3));
            }
        }

        this.field_178152_f = this.tileFurnace.getField(2);
        this.field_178154_h = this.tileFurnace.getField(0);
        this.field_178155_i = this.tileFurnace.getField(1);
        this.field_178153_g = this.tileFurnace.getField(3);
    }

    @SideOnly(Side.CLIENT)
    @Override
    public void updateProgressBar(int id, int data) {
        this.tileFurnace.setField(id, data);
    }

    @Override
    public boolean canInteractWith(EntityPlayer playerIn) {
        return this.tileFurnace.isUseableByPlayer(playerIn);
    }

    @Override
    public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) {
        System.out.println("playerIn = [" + playerIn + "], index = [" + index + "]");
        ItemStack itemstack = null;
        Slot slot = this.inventorySlots.get(index);

        if (slot != null && slot.getHasStack()) {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (index == 2) {
                if (!this.mergeItemStack(itemstack1, 3, 39, true)) {
                    return null;
                }

                slot.onSlotChange(itemstack1, itemstack);
            } else if (index != 1 && index != 0) {
                if (ModSmeltingRecipes.getSmeltingResult(itemstack1) != null) {
                    if (!this.mergeItemStack(itemstack1, 0, 1, false)) {
                        return null;
                    }
                } else if (itemstack.getItem() instanceof ItemXPFuel || itemstack.getItem() instanceof ItemBlockXPFuel) {
                    if (!this.mergeItemStack(itemstack1, 1, 2, false)) {
                        return null;
                    }
                } else if (index >= 3 && index < 30) {
                    if (!this.mergeItemStack(itemstack1, 30, 39, false)) {
                        return null;
                    }
                } else if (index >= 30 && index < 39 && !this.mergeItemStack(itemstack1, 3, 30, false)) {
                    return null;
                }
            } else if (!this.mergeItemStack(itemstack1, 3, 39, false)) {
                return null;
            }

            if (itemstack1.stackSize == 0) {
                slot.putStack(null);
            } else {
                slot.onSlotChanged();
            }

            if (itemstack1.stackSize == itemstack.stackSize) {
                return null;
            }

            slot.onPickupFromSlot(playerIn, itemstack1);
        }

        return itemstack;
    }

}

 

Thank you for any hint or help you can provide :)

Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.