Jump to content

Bugs with drag and drop and containers


Raycoms

Recommended Posts

In the Block.

 

/**
* The class handling the fieldBlocks, placement and activation.
*/
public class BlockHutField extends BlockContainer
{
    /**
     * Hardness of the block.
     */
    private static final float HARDNESS = 10F;

    /**
     * Resistance of the block.
     */
    private static final float RESISTANCE = 10F;

    /**
     * The position it faces.
     */
    public static final PropertyDirection FACING = PropertyDirection.create("FACING", Plane.HORIZONTAL);

    /**
     * Start of the collision box at y.
     */
    private static final double BOTTOM_COLLISION = 0.0;

    /**
     * Start of the collision box at x and z.
     */
    private static final double START_COLLISION = 0.1;

    /**
     * End of the collision box.
     */
    private static final double END_COLLISION = 0.9;

    /**
     * Height of the collision box.
     */
    private static final double HEIGHT_COLLISION = 2.5;

    /**
     * Registry name for this block.
     */
    private static final String REGISTRY_NAME = "blockHutField";

    /**
     * Constructor called on block placement.
     */
    BlockHutField()
    {
        super(Material.wood);
        initBlock();
    }

    /**
     * Method called by constructor.
     * Sets basic details of the block.
     */
    private void initBlock()
    {
        setRegistryName(REGISTRY_NAME);
        setUnlocalizedName(Constants.MOD_ID.toLowerCase() + "." + "blockHutField");
        setCreativeTab(ModCreativeTabs.MINECOLONIES);
        //Blast resistance for creepers etc. makes them explosion proof.
        setResistance(RESISTANCE);
        //Hardness of 10 takes a long time to mine to not loose progress.
        setHardness(HARDNESS);
        this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, NORTH));
        GameRegistry.registerBlock(this);
        setBlockBounds((float) START_COLLISION, (float) BOTTOM_COLLISION, (float) START_COLLISION, (float) END_COLLISION, (float) HEIGHT_COLLISION, (float) END_COLLISION);
    }

    @Override
    public int getRenderType()
    {
        return -1;
    }

    @Override
    public IBlockState getStateFromMeta(int meta)
    {
        EnumFacing facing;
        switch (getFront(meta))
        {
            case WEST:
                facing = WEST;
                break;
            case EAST:
                facing = EAST;
                break;
            case NORTH:
                facing = NORTH;
                break;
            default:
                facing = SOUTH;
        }
        return this.getDefaultState().withProperty(FACING, facing);
    }

    @Override
    public int getMetaFromState(IBlockState state)
    {
        return state.getValue(FACING).getIndex();
    }

    @Override
    public boolean isFullCube()
    {
        return false;
    }

    @Override
    public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
    {
        return false;
    }

    @Override
    public boolean isOpaqueCube()
    {
        return false;
    }

    @Override
    @SideOnly(Side.CLIENT)
    public EnumWorldBlockLayer getBlockLayer()
    {
        return EnumWorldBlockLayer.SOLID;
    }

    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ)
    {
        //If the world is server, open the inventory of the field.
        if (!worldIn.isRemote)
        {
            final Colony colony = ColonyManager.getColony(worldIn, pos);
            if (colony != null)
            {
                playerIn.openGui(MineColonies.instance, 0, worldIn, pos.getX(), pos.getY(), pos.getZ());
                return true;
            }
        }
        return false;
    }

    // =======================================================================
    // ======================= Rendering & IBlockState =======================
    // =======================================================================
    @Override
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
    {
        final EnumFacing enumFacing = (placer == null) ? NORTH : fromAngle(placer.rotationYaw);
        return this.getDefaultState().withProperty(FACING, enumFacing);
    }

    @Override
    public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
    {
        //Only work on server side.
        if (worldIn.isRemote)
        {
            return;
        }

        if (placer instanceof EntityPlayer)
        {
            final Colony colony = ColonyManager.getColony(worldIn, pos);

            if (colony != null)
            {
                final InventoryField inventoryField = new InventoryField(LanguageHandler.getString("com.minecolonies.gui.inventory.scarecrow"), true);

                ((ScarecrowTileEntity) worldIn.getTileEntity(pos)).setInventoryField(inventoryField);
                colony.addNewField((ScarecrowTileEntity) worldIn.getTileEntity(pos), ((EntityPlayer) placer).inventory, pos, worldIn);
            }
        }
    }

    @Override
    protected BlockState createBlockState()
    {
        return new BlockState(this, FACING);
    }

    @Override
    public boolean hasTileEntity(final IBlockState state)
    {
        return true;
    }

    @Override
    public TileEntity createNewTileEntity(World worldIn, int meta)
    {
        return new ScarecrowTileEntity();
    }
    // =======================================================================
    // ===================== END of Rendering & Meta-Data ====================
    // =======================================================================
}

Link to comment
Share on other sites

I think the problem might be somewhere in the container class but I have no idea why, anyone has any suggestion?

Ok just a couple things you do not need to load the Colony from NBT if you already to in the TileEntity, you can just pass along the data by using the syncing strategy from ContainerFurnace. Do you really need all of those getters and setters in the container class? And third if the problem is in the Your Container class then it is probably the way you override transferStackInSlot(), but I do not see a way that would cause a problem.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

Yeah I have a pretty big AI accessing my Container class that's why I need these getters and setters for.

I also thought about the overriding of the transferStackInSlot() but dragging doesn't call this method(I debugged tested it)

Only the slotClicked methods are called on dragging but I have no idea how I could use that to enable dragging normally the original onSlotClicked should handle the drag event.

The transferStackInSlot() is only for shift click in and out. (That's why shift-clicking it works great)

Link to comment
Share on other sites

Yeah I have a pretty big AI accessing my Container class that's why I need these getters and setters for.

I also thought about the overriding of the transferStackInSlot() but dragging doesn't call this method(I debugged tested it)

Only the slotClicked methods are called on dragging but I have no idea how I could use that to enable dragging normally the original onSlotClicked should handle the drag event.

The transferStackInSlot() is only for shift click in and out. (That's why shift-clicking it works great)

I can't find anything wrong with the code try creating a new Container and just add the players inventory and see if you can drag it around or not.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

I can drag stuff around in the players inventory perfectly well I also can drag stuff from the players inventory to the custom inventory but not the other way around.

Post your TileEntity and InventoryField

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

Custom inventory field.

package com.minecolonies.inventory;
/**
* The custom chest of the field.
*/
public class InventoryField extends InventoryCitizen
{
    /**
     * NBTTag to store the slot.
     */
    private static final String TAG_SLOT = "slot";

    /**
     * NBTTag to store the items.
     */
    private static final String TAG_ITEMS = "items";

    /**
     * NBTTag to store the custom name.
     */
    private static final String TAG_CUSTOM_NAME = "name";

    /**
     * NBTTag to store the inventory.
     */
    private static final String TAG_INVENTORY = "inventory";

    /**
     * Returned slot if no slat has been found.
     */
    private static final int NO_SLOT = -1;

    /**
     * The inventory stack.
     */
    private ItemStack[] stackResult   = new ItemStack[1];

    /**
     * The custom name of the inventory.
     */
    private String customName         = "";

    /**
     * Creates the inventory of the citizen.
     *
     * @param title         Title of the inventory.
     * @param localeEnabled Boolean whether the inventory has a custom name.
     */
    public InventoryField(final String title, final boolean localeEnabled)
    {
        super(title, localeEnabled);
        customName = title;
    }




    @Override
    public int getSizeInventory()
    {
        return 1;
    }

    @Override
    public int getInventoryStackLimit()
    {
        return 1;
    }

    @Override
    public int getHotbarSize()
    {
        return 0;
    }

    /**
     * Getter for the stack in the inventory. Since there is only one slot return always that one.
     * @param index the slot.
     * @return the itemStack in it.
     */
    @Override
    public ItemStack getStackInSlot(int index)
    {
        return this.stackResult[0];
    }

    @Override
    public boolean hasCustomName()
    {
        return true;
    }

    /**
     * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
     * @param index the slot to set the itemStack.
     * @param stack the itemStack to set.
     */
    @Override
    public void setInventorySlotContents(int index, ItemStack stack)
    {
        this.stackResult[index] = stack;

        if (stack != null && stack.stackSize > this.getInventoryStackLimit())
        {
            stack.stackSize = this.getInventoryStackLimit();
        }

        this.markDirty();
    }

    /**
     *  Get the name of this object. For citizens this returns their name.
     * @return the name of the inventory.
     */
    @Override
    public String getName()
    {
        return this.hasCustomName() ? this.customName : "field.inventory";
    }

    /**
     * Used to retrieve variables.
     * @param compound with the give tag.
     */
    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        final NBTTagList nbttaglist = compound.getTagList(TAG_ITEMS, Constants.NBT.TAG_COMPOUND);
        this.stackResult = new ItemStack[this.getSizeInventory()];

        for (int i = 0; i < nbttaglist.tagCount(); ++i)
        {
            final NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
            final int            j              = nbttagcompound.getByte(TAG_SLOT) & Byte.MAX_VALUE;

            if (j != NO_SLOT && j < this.stackResult.length)
            {
                this.stackResult[j] = ItemStack.loadItemStackFromNBT(nbttagcompound);
            }
        }

        if (compound.hasKey(TAG_CUSTOM_NAME, Constants.NBT.TAG_STRING))
        {
            this.customName = compound.getString(TAG_CUSTOM_NAME);
        }
    }

    /**
     * Used to store variables.
     * @param compound with the given tag.
     */
    @Override
    public void writeToNBT(NBTTagCompound compound)
    {
        final NBTTagList nbttaglist = new NBTTagList();

        for (int i = 0; i < this.stackResult.length; ++i)
        {
            if (this.stackResult[i] != null)
            {
                final NBTTagCompound nbttagcompound = new NBTTagCompound();
                nbttagcompound.setByte(TAG_SLOT, (byte) i);
                this.stackResult[i].writeToNBT(nbttagcompound);
                nbttaglist.appendTag(nbttagcompound);
            }
        }

        compound.setTag(TAG_ITEMS, nbttaglist);

        if (this.hasCustomName())
        {
            compound.setString(TAG_CUSTOM_NAME, this.customName);
        }

        compound.setTag(TAG_INVENTORY, nbttaglist);
    }
}

 

Inherits from inventory citizen

 

package com.minecolonies.inventory;

import com.minecolonies.colony.materials.MaterialStore;
import com.minecolonies.colony.materials.MaterialSystem;
import com.minecolonies.colony.permissions.Permissions;
import com.minecolonies.entity.EntityCitizen;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.ReportedException;
import net.minecraftforge.common.util.Constants;

/**
* Basic inventory for the citizens.
*/
public class InventoryCitizen implements IInventory
{
    /**
     * Number of slots in the inventory.
     */
    private static final int INVENTORY_SIZE = 27;
    /**
     * Max size of the stacks.
     */
    private static final int MAX_STACK_SIZE = 64;
    /**
     * The inventory content.
     */
    private ItemStack[] stacks = new ItemStack[iNVENTORY_SIZE];
    /**
     * The inventories custom name. In our case the citizens name.
     */
    private String customName;
    /**
     * The held item.
     */
    private int heldItem;
    /**
     * The material store object.
     */
    private MaterialStore materialStore;
    /**
     * NBT tag to store and retrieve the inventory.
     */
    private static final String TAG_INVENTORY = "Inventory";
    /**
     * NBT tag to store and retrieve the custom name.
     */
    private static final String TAG_CUSTOM_NAME = "CustomName";
    /**
     * NBT tag to store and retrieve the custom name.
     */
    private static final String TAG_ITEMS = "Items";
    /**
     * NBT tag to store and retrieve the custom name.
     */
    private static final String TAG_SLOT= "Slot";
    /**
     * Updated after the inventory has been changed
     */
    private boolean inventoryChanged = false;
    /**
     * The returned slot if a slot hasn't been found.
     */
    private static final int NO_SLOT = -1;

    /**
     * The citizen which owns the inventory.
     */
    private EntityCitizen citizen;

    /**
     * Creates the inventory of the citizen.
     *
     * @param title         Title of the inventory.
     * @param localeEnabled Boolean whether the inventory has a custom name.
     * @param citizen       Citizen owner of the inventory.
     */
    public InventoryCitizen(String title, boolean localeEnabled, EntityCitizen citizen)
    {
        this.citizen = citizen;
        if(localeEnabled)
        {
            customName = title;
        }
    }

    /**
     * Creates the inventory of the citizen.
     *
     * @param title         Title of the inventory.
     * @param localeEnabled Boolean whether the inventory has a custom name.
     */
    public InventoryCitizen(String title, boolean localeEnabled)
    {
        if(localeEnabled)
        {
            customName = title;
        }
    }

    private int getInventorySlotContainItem(Item itemIn)
    {
        for (int i = 0; i < this.stacks.length; ++i)
        {
            if (this.stacks[i] != null && this.stacks[i].getItem() == itemIn)
            {
                return i;
            }
        }

        return NO_SLOT;
    }

    /**
     * stores an itemstack in the users inventory
     */
    private int storeItemStack(ItemStack itemStackIn)
    {
        for (int i = 0; i < this.stacks.length; ++i)
        {
            if (this.stacks[i] != null && this.stacks[i].getItem() == itemStackIn.getItem() && this.stacks[i].isStackable()
                && this.stacks[i].stackSize < this.stacks[i].getMaxStackSize() && this.stacks[i].stackSize < this.getInventoryStackLimit()
                && (!this.stacks[i].getHasSubtypes() || this.stacks[i].getMetadata() == itemStackIn.getMetadata())
                && ItemStack.areItemStackTagsEqual(this.stacks[i], itemStackIn))
            {
                return i;
            }
        }

        return NO_SLOT;
    }

    /**
     * Returns the first item stack that is empty.
     *
     * @return the id of the first empty slot.
     */
    public int getFirstEmptyStack()
    {
        for (int i = 0; i < this.stacks.length; ++i)
        {
            if (this.stacks[i] == null)
            {
                return i;
            }
        }

        return NO_SLOT;
    }

    /**
     * Get the size of the citizens hotbar inventory
     * @return the size.
     */
    public int getHotbarSize()
    {
        return 0;
    }

    /**
     * Contains the size of the inventory.
     * @return the size.
     */
    @Override
    public int getSizeInventory()
    {
        return INVENTORY_SIZE;
    }

    /**
     * Gets the stack of a certain slot.
     * @param index the slot.
     * @return the ItemStack.
     */
    @Override
    public ItemStack getStackInSlot(int index)
    {
        return this.stacks[index];
    }

    /**
     * Removes up to a specified number of items from an inventory slot and returns them in a new stack.
     * @param index the slot of the itemStack.
     * @param count the amount of items to reduce.
     * @return the resulting stack.
     */
    @Override
    public ItemStack decrStackSize(int index, int count)
    {
        if (this.stacks[index] != null)
        {
            if (this.stacks[index].stackSize <= count)
            {
                ItemStack itemstack1 = this.stacks[index];
                this.stacks[index] = null;
                this.markDirty();
                if(index == heldItem)
                {
                    if(citizen != null)
                    {
                        citizen.removeHeldItem();
                    }
                    heldItem = 0;
                }
                return itemstack1;
            }
            else
            {
                ItemStack itemstack = this.stacks[index].splitStack(count);

                if (this.stacks[index].stackSize == 0)
                {
                    this.stacks[index] = null;
                }

                this.markDirty();
                return itemstack;
            }

        }
        else
        {
            return null;
        }
    }

    /**
     * Removes a stack from the given slot and returns it.
     * @param index the slot of the stack.
     * @return the removed itemStack.
     */
    @Override
    public ItemStack removeStackFromSlot(int index)
    {
        if (this.stacks[index] != null)
        {
            ItemStack itemstack = this.stacks[index];
            this.stacks[index] = null;
            return itemstack;
        }
        else
        {
            return null;
        }
    }

    /**
     * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections).
     * @param index the slot to set the itemStack.
     * @param stack the itemStack to set.
     */
    @Override
    public void setInventorySlotContents(int index, ItemStack stack)
    {
        if(index == heldItem && stack == null)
        {
            if(citizen != null)
            {
                citizen.removeHeldItem();
            }
            heldItem = 0;
        }

        this.stacks[index] = stack;

        if (stack != null && stack.stackSize > this.getInventoryStackLimit())
        {
            stack.stackSize = this.getInventoryStackLimit();
        }

        this.markDirty();
    }

    /**
     *  Get the name of this object. For citizens this returns their name.
     * @return the name of the inventory.
     */
    @Override
    public String getName()
    {
        return this.hasCustomName() ? this.customName : "citizen.inventory";
    }

    /**
     * Sets the name of the inventory.
     * @param customName the string to use to set the name.
     */
    public void setCustomName(String customName)
    {
        this.customName = customName;
    }

    /**
     * Checks if the inventory is named.
     * @return true if the inventory has a custom name.
     */
    @Override
    public boolean hasCustomName()
    {
        return this.customName != null;
    }

    /**
     * Get the formatted ChatComponent that will be used for the sender's username in chat
     */
    @Override
    public IChatComponent getDisplayName()
    {
        return this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatComponentTranslation(this.getName());
    }

    /**
     * Contains the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended.
     * @return the stack size.
     */
    @Override
    public int getInventoryStackLimit()
    {
        return MAX_STACK_SIZE;
    }

    /**
     * For tile entities, ensures the chunk containing the tile entity is saved to disk later - the game won't think it
     * hasn't changed and skip it.
     */
    @Override
    public void markDirty()
    {
        this.inventoryChanged = true;
    }

    /**
     * Checks if the inventory has been changed and then resets the boolean.
     * @return true if it changed.
     */
    public boolean hasInventoryChanged()
    {
        if(inventoryChanged)
        {
            inventoryChanged = false;
            return true;
        }
        return false;
    }
    /**
     * Do not give this method the name canInteractWith because it clashes with Container
     * @param player the player acessing the inventory.
     * @return if the player is allowed to access.
     */
    @Override
    public boolean isUseableByPlayer(EntityPlayer player)
    {
        return this.citizen.getColony().getPermissions().hasPermission(player, Permissions.Action.ACCESS_HUTS);
    }

    /**
     *  Called when inventory is opened by a player.
      * @param player the player who opened the inventory.
     */
    @Override
    public void openInventory(EntityPlayer player)
    {
        /*
         * This may be filled in order to specify some custom handling.
         */
    }

    /**
     * Called after the inventory has been closed by a player.
      * @param player the player who opened the inventory.
     */
    @Override
    public void closeInventory(EntityPlayer player)
    {
        /*
         * This may be filled in order to specify some custom handling.
         */
    }

    /**
     * Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot.
     * @param index the accessing slot.
     * @param stack the stack trying to enter.
     * @return if the stack may be inserted.
     */
    @Override
    public boolean isItemValidForSlot(int index, ItemStack stack)
    {
        return true;
    }

    /**
     * This may be used in order to return values of different GUI areas like the ones in the beacon.
     * @param id the id of the field.
     * @return the value of the field.
     */
    @Override
    public int getField(int id)
    {
        return 0;
    }

    /**
     * This may be used to set GUI areas with a certain id and value.
     * @param id some id.
     * @param value some value.
     */
    @Override
    public void setField(int id, int value)
    {
        /*
         * We currently need no fields.
         */
    }

    /**
     * Returns the number of fields.
     * @return the amount.
     */
    @Override
    public int getFieldCount()
    {
        return 0;
    }

    /**
     * Completely clears the inventory.
     */
    @Override
    public void clear()
    {
        for (int i = 0; i < this.stacks.length; ++i)
        {
            this.stacks[i] = null;
        }
    }

    /**
     * Set item to be held by citizen
     *
     * @param slot Slot index with item to be held by citizen
     */
    public void setHeldItem(int slot)
    {
        this.heldItem = slot;
    }

    /**
     * Returns the item that is currently being held by citizen
     *
     * @return {@link ItemStack} currently being held by citizen
     */
    public ItemStack getHeldItem()
    {
        return getStackInSlot(heldItem);
    }

    /**
     * This function stores as many items of an ItemStack as possible in a matching slot and returns the quantity of
     * left over items.
     */
    private int storePartialItemStack(ItemStack itemStackIn)
    {
        int i = itemStackIn.stackSize;
        int j = this.storeItemStack(itemStackIn);

        if (j < 0)
        {
            j = this.getFirstEmptyStack();
        }

        if (j < 0)
        {
            return i;
        }
        else
        {
            if (this.stacks[j] == null)
            {
                // Forge: Replace Item clone above to preserve item capabilities when picking the item up.
                this.stacks[j] = itemStackIn.copy();
                this.stacks[j].stackSize = 0;
            }

            int k = i;

            if (i > this.stacks[j].getMaxStackSize() - this.stacks[j].stackSize)
            {
                k = this.stacks[j].getMaxStackSize() - this.stacks[j].stackSize;
            }

            if (k > this.getInventoryStackLimit() - this.stacks[j].stackSize)
            {
                k = this.getInventoryStackLimit() - this.stacks[j].stackSize;
            }

            if (k == 0)
            {
                return i;
            }
            else
            {
                i = i - k;
                this.stacks[j].stackSize += k;
                return i;
            }
        }
    }


    /**
     * Removes one item of specified Item from inventory (if it is in a stack, the stack size will reduce with 1)
     * @param itemIn the item to consume.
     * @return true if succeed.
     */
    public boolean consumeInventoryItem(Item itemIn)
    {
        int i = this.getInventorySlotContainItem(itemIn);

        if (i < 0)
        {
            return false;
        }
        else
        {
            --this.stacks[i].stackSize;
            if (this.stacks[i].stackSize <= 0)
            {
                this.stacks[i] = null;
            }

            return true;
        }
    }

    /**
     * Adds the item stack to the inventory, returns false if it is impossible.
     * @param itemStackIn the stack to add
     * @return true if succeeded.
     */
    public boolean addItemStackToInventory(final ItemStack itemStackIn)
    {
        if (itemStackIn != null && itemStackIn.stackSize != 0 && itemStackIn.getItem() != null)
        {
            try
            {
                if (itemStackIn.isItemDamaged())
                {
                    int j = this.getFirstEmptyStack();

                    if (j != NO_SLOT)
                    {
                        this.stacks[j] = ItemStack.copyItemStack(itemStackIn);
                        itemStackIn.stackSize = 0;
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    int i;

                    while (true)
                    {
                        i = itemStackIn.stackSize;
                        itemStackIn.stackSize = this.storePartialItemStack(itemStackIn);

                        if (itemStackIn.stackSize <= 0 || itemStackIn.stackSize >= i)
                        {
                            break;
                        }
                    }

                    return itemStackIn.stackSize < i;
                }
            }
            catch (RuntimeException exp)
            {
                CrashReport         crashreport         = CrashReport.makeCrashReport(exp, "Adding item to inventory");
                CrashReportCategory crashreportcategory = crashreport.makeCategory("Item being added");
                crashreportcategory.addCrashSection("Item ID", Item.getIdFromItem(itemStackIn.getItem()));
                crashreportcategory.addCrashSection("Item data", itemStackIn.getMetadata());
                crashreportcategory.addCrashSectionCallable("Item name", itemStackIn::getDisplayName);
                throw new ReportedException(crashreport);
            }
        }
        else
        {
            return false;
        }
    }

    /**
     * Checks if a specified Item is inside the inventory
     * @param itemIn the item to check for.
     * @return if itemIn in inventory.
     */
    public boolean hasItem(Item itemIn)
    {
        return getInventorySlotContainItem(itemIn) != NO_SLOT;
    }

    /**
     * Gets slot that hold item that is being held by citizen.
     * {@link #getHeldItem()}.
     *
     * @return Slot index of held item
     */
    public int getHeldItemSlot()
    {
        return heldItem;
    }

    /**
     * Checks if a certain slot is empty.
     * @param index the slot.
     * @return true if empty.
     */
    public boolean isSlotEmpty(int index)
    {
        return getStackInSlot(index) == null;
    }

    //-----------------------------Material Handling--------------------------------

    public void createMaterialStore(MaterialSystem system)
    {
        if (materialStore == null)
        {
            materialStore = new MaterialStore(MaterialStore.Type.INVENTORY, system);
        }
    }

    public MaterialStore getMaterialStore()
    {
        return materialStore;
    }

    //todo missing now
    /*
    @Override
    public ItemStack getStackInSlotOnClosing(int index)
    {
            ItemStack removed = super.getStackInSlotOnClosing(index);

                    removeStackFromMaterialStore(removed);

                    return removed;
    }*/

    private void addStackToMaterialStore(ItemStack stack)
    {
        if (stack == null)
        {
            return;
        }

        if (MaterialSystem.isEnabled)
        {
            materialStore.addMaterial(stack.getItem(), stack.stackSize);
        }
    }

    private void removeStackFromMaterialStore(ItemStack stack)
    {
        if (stack == null)
        {
            return;
        }

        if (MaterialSystem.isEnabled)
        {
            materialStore.removeMaterial(stack.getItem(), stack.stackSize);
        }
    }

    /**
     * Used to retrieve variables.
     * @param compound with the give tag.
     */
    public void readFromNBT(NBTTagCompound compound)
    {
        NBTTagList nbttaglist = compound.getTagList(TAG_ITEMS, Constants.NBT.TAG_COMPOUND);
        this.stacks = new ItemStack[this.getSizeInventory()];

        for (int i = 0; i < nbttaglist.tagCount(); ++i)
        {
            NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
            int            j              = nbttagcompound.getByte(TAG_SLOT) & Byte.MAX_VALUE;

            if (j != NO_SLOT && j < this.stacks.length)
            {
                this.stacks[j] = ItemStack.loadItemStackFromNBT(nbttagcompound);
            }
        }

        if (compound.hasKey(TAG_CUSTOM_NAME, Constants.NBT.TAG_STRING))
        {
            this.customName = compound.getString(TAG_CUSTOM_NAME);
        }
    }

    /**
     * Used to store variables.
     * @param compound with the given tag.
     */
    public void writeToNBT(NBTTagCompound compound)
    {
        NBTTagList nbttaglist = new NBTTagList();

        for (int i = 0; i < this.stacks.length; ++i)
        {
            if (this.stacks[i] != null)
            {
                NBTTagCompound nbttagcompound = new NBTTagCompound();
                nbttagcompound.setByte(TAG_SLOT, (byte) i);
                this.stacks[i].writeToNBT(nbttagcompound);
                nbttaglist.appendTag(nbttagcompound);
            }
        }

        compound.setTag(TAG_ITEMS, nbttaglist);

        if (this.hasCustomName())
        {
            compound.setString(TAG_CUSTOM_NAME, this.customName);
        }
        if (MaterialSystem.isEnabled)
        {
            materialStore.writeToNBT(compound);
        }

        compound.setTag(TAG_INVENTORY, nbttaglist);
    }
}

 

TileEntity

package com.minecolonies.tileentities;
/**
* The scarecrow tile entity to store extra data.
*/
public class ScarecrowTileEntity extends TileEntityChest
{
    /**
     * NBTTag to store the type.
     */
    private static final String TAG_TYPE = "type";
    /**
     * Random generator.
     */
    private final Random random = new Random();
    /**
     * The inventory connected with the scarecrow.
     */
    private InventoryField inventoryField;
    /**
     * The type of the scarecrow.
     */
    private ScareCrowType  type;

    /**
     * Creates an instance of the tileEntity.
     */
    public ScarecrowTileEntity()
    {
        super();
        this.inventoryField = new InventoryField(LanguageHandler.getString("com.minecolonies.gui.inventory.scarecrow"), true);
    }

    @Override
    public void onLoad()
    {
        super.onLoad();
        World world = getWorld();

        if(world != null)
        {
            Colony colony = ColonyManager.getColony(world, pos);

            if (colony != null && colony.getField(pos) == null)
            {
                Entity entity = EntityUtils.getEntityFromUUID(world, colony.getPermissions().getOwner());

                if (entity instanceof EntityPlayer)
                {
                    colony.addNewField(this, ((EntityPlayer) entity).inventory, pos, world);
                }
            }
        }
    }

    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        super.readFromNBT(compound);

        type = ScareCrowType.values()[compound.getInteger(TAG_TYPE)];
        getInventoryField().readFromNBT(compound);
    }

    @Override
    public void writeToNBT(NBTTagCompound compound)
    {
        super.writeToNBT(compound);

        compound.setInteger(TAG_TYPE, this.getType().ordinal());
        getInventoryField().writeToNBT(compound);
    }

    /**
     * Returns the type of the scarecrow (Important for the rendering).
     *
     * @return the enum type.
     */
    public ScareCrowType getType()
    {
        if (this.type == null)
        {
            this.type = ScareCrowType.values()[this.random.nextInt(2)];
        }
        return this.type;
    }
    /**
     * Set the inventory connected with the scarecrow.
     *
     * @param inventoryField the field to set it to
     */
    public final void setInventoryField(final InventoryField inventoryField)
    {
        this.inventoryField = inventoryField;
    }

    /**
     * Get the inventory connected with the scarecrow.
     *
     * @return the inventory field of this scarecrow
     */
    public InventoryField getInventoryField()
    {
        return inventoryField;
    }

    /**
     * Enum describing the different textures the scarecrow has.
     */
    public enum ScareCrowType
    {
        PUMPKINHEAD,
        NORMAL
    }
}

Link to comment
Share on other sites

Override removeStackFromSlot(int) in InventoryField also decrItemStack(int, int) and overall anything that doesn't use your ItemStack[] in InventoryField as that is your problem.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

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