Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.14.4] items not getting deleted


andGarrett
 Share

Recommended Posts

I'm trying to delete items from an inventory, but no matter what I do, they keep coming back in a weird way. the inventory looks empty, but if I click on one of the seemingly empty slots, they all reappear. I've tried all kind of things like getSlot(i).putStack(ItemStack.EMPTY);, setting the stack count to zero, decreasing the stack size to zero etc. it always ends the same way.

 

The items are "deleted" in the "sellItems" method near the bottom.

package com.garrett.backtobasics.blocks;

import com.garrett.backtobasics.capabilities.BankAccount.BankAccountProvider;
import com.garrett.backtobasics.capabilities.itemvalues.ItemValuesProvider;
import com.garrett.backtobasics.capabilities.itemvalues.TradeItem;
import com.garrett.backtobasics.capabilities.saleitemlist.SaleItemListProvider;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.IContainerListener;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.util.IntReferenceHolder;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import static com.garrett.backtobasics.blocks.ModBlocks.STORE_CONTAINER;

import javax.annotation.Nonnull;
import java.util.ArrayList;

public class StoreContainer extends Container {

    private int sellSlots = 16;
    private IInventory storeInventory;
    private TileEntity tileEntity;
    private PlayerEntity playerEntity;
    private IItemHandler playerInventory;
    private ArrayList<TradeItem> itemValueList;
    // itemList is a list of items taken from itemValueList for use with .contains()
    private ArrayList<String> itemList;
    // valueList is a list of values taken from itemValueList for use with .contains()
    private ArrayList<Double> valueList;
    private double inventoryValue;
    private static final Logger LOGGER = LogManager.getLogger();

    public StoreContainer(int windowId, World world, BlockPos pos, PlayerInventory PlayerInventory, PlayerEntity player) {

        super(STORE_CONTAINER, windowId);
        tileEntity = world.getTileEntity(pos);
        this.playerEntity = player;
        this.playerInventory = new InvWrapper(PlayerInventory);

        world.getCapability(ItemValuesProvider.ITEM_VALUES_CAPABILITY).ifPresent(h -> {
            itemValueList = h.getItemValueList();
            itemList = h.getItemList();
            valueList = h.getValueList();
        });

        tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(h -> {
            createSlotGrid(h, 4, 4, 0, 20, 23);

            addListener(new IContainerListener() {
                @Override
                public void sendAllContents(Container containerToSend, NonNullList<ItemStack> itemsList) {

                }

                @Override
                public void sendSlotContents(Container containerToSend, int slotInd, ItemStack stack) {
                    inventoryValue = calculateInventoryValue();
                }

                @Override
                public void sendWindowProperty(Container containerIn, int varToUpdate, int newValue) {
                }
            });
        });
        layoutPlayerInventorySlots(20, 138);

        /*
         * communicates inventory value between server and client
         * this allows the gui screen to update real time
         */
        trackInt(new IntReferenceHolder() {
            @Override
            public int get() {
                return (int) inventoryValue;
            }

            @Override
            public void set(int value) {
                inventoryValue = value;
            }
        });
    }

    @Override
    public boolean canInteractWith(PlayerEntity playerIn) {
        return isWithinUsableDistance(IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos()), playerEntity, ModBlocks.STORE);
    }

    private int addSlotRange(IItemHandler handler, int index, int x, int y, int amount, int dx) {
        for (int i = 0 ; i < amount ; i++) {
            addSlot(new SlotItemHandler(handler, index, x, y));
            x += dx;
            index++;
        }
        return index;
    }

    private int addSlotBox(IItemHandler handler, int index, int x, int y, int horAmount, int dx, int verAmount, int dy) {
        for (int j = 0 ; j < verAmount ; j++) {
            index = addSlotRange(handler, index, x, y, horAmount, dx);
            y += dy;
        }
        return index;
    }


    private void layoutPlayerInventorySlots(int leftCol, int topRow) {
        // Player inventory
        addSlotBox(playerInventory, 9, leftCol, topRow, 9, 18, 3, 18);

        // Hotbar
        topRow += 58;
        addSlotRange(playerInventory, 0, leftCol, topRow, 9, 18);
    }

    /*
     * Handles when the stack in slot is shift-clicked. Normally this moves the stack between the player
     * inventory and the other inventory(s).
     * copied from ChestContainer#transferStackInSlot
     */
    @Nonnull
    @Override
    public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {

        /*
        playerIn.getCapability(SaleItemListProvider.SALE_ITEM_LIST_CAPABILITY).ifPresent(h -> {
            //LOGGER.info("SaleItemList");
        });
         */
        ItemStack itemstack = ItemStack.EMPTY;
        Slot slot = this.inventorySlots.get(index);
        if (slot != null && slot.getHasStack()) {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();
            if (index < 16) {
                if (!this.mergeItemStack(itemstack1, 16, this.inventorySlots.size(), true)) {
                    return ItemStack.EMPTY;
                }
            } else if (!this.mergeItemStack(itemstack1, 0, 16, false)) {
                return ItemStack.EMPTY;
            }

            if (itemstack1.isEmpty()) {
                slot.putStack(ItemStack.EMPTY);
            } else {
                slot.onSlotChanged();
            }
        }
        return itemstack;
    }

    private void createSlotGrid(IItemHandler h, int columns, int rows, int startIndex, int startX, int startY) {

        int index = 0;

        for (int j = 0; j < rows; j++) {
            for (int i = 0; i < columns; i++) {
                addSlot(new SlotItemHandler(h, index + startIndex, startX + (i * 18), startY + (j * 18)));
                index++;
            }
        }
    }
    private double calculateInventoryValue() {
        NonNullList<ItemStack> inventory = this.getInventory();
        double totalValue = 0;
        for (int i = 0; i < sellSlots; i++) {
            // check if stack item is in ItemValues
            if (itemList.contains(inventory.get(i).getItem().toString())) {
                totalValue += valueList.get(itemList.indexOf((inventory.get(i).getItem().toString()))) * inventory.get(i).getCount();
            }

        }
        return totalValue;
    }

    public double getInventoryValue() {
        return inventoryValue;
    }

    public void sellItems() {

        inventoryValue = calculateInventoryValue();
        playerEntity.getCapability(BankAccountProvider.BANK_ACCOUNT_CAPABILITY).ifPresent(h -> {
            h.setBalance(h.getBalance() + inventoryValue);
        });
        NonNullList<ItemStack> inventory = this.getInventory();
        for (int i = 0; i < sellSlots; i++) {
            // check if stack item is in itemValueList and has a value greater than zero
            if (itemList.contains(inventory.get(i).getItem().toString()) && (valueList.get(itemList.indexOf((inventory.get(i).getItem().toString()))) > 0)) {
                getSlot(i).putStack(ItemStack.EMPTY);
            }
        }
        inventoryValue = calculateInventoryValue();
    }
}

 

 

the "sellItems" method is called on line 30 in this class.

package com.garrett.backtobasics.blocks;

import com.garrett.backtobasics.BackToBasics;
import com.garrett.backtobasics.capabilities.BankAccount.BankAccountProvider;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.client.gui.widget.button.Button;

public class StoreScreen extends ContainerScreen<StoreContainer> {

    private ResourceLocation GUI = new ResourceLocation(BackToBasics.MODID, "textures/gui/store_inventory02.png");
    private double playerBankBalance = 0;

    public StoreScreen(StoreContainer container, PlayerInventory inv, ITextComponent name) {
        super(container, inv, name);
        xSize = 200;
        ySize = 220;
    }

    @Override
    protected void init() {
        super.init();

        //buttons.clear();
        addButton(new Button(guiLeft + 31, guiTop + 110, 48, 20, "Sell", (button) -> {
            //do stuff
            container.sellItems();
        }));

    }

    @Override
    public void render(int mouseX, int mouseY, float partialTicks) {
        this.renderBackground();
        super.render(mouseX, mouseY, partialTicks);
        this.renderHoveredToolTip(mouseX, mouseY);
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        //drawString(Minecraft.getInstance().fontRenderer, "Auto-Miner", 10, 10, 434343);
        this.font.drawString("Store", (float) ((xSize / 2.0) - 15), 10,4210752);
        this.font.drawString(Integer.toString((int) container.getInventoryValue()), alignDigitsRight(container.getInventoryValue(), 9, 25), 100,4210752);
        playerInventory.player.getCapability(BankAccountProvider.BANK_ACCOUNT_CAPABILITY).ifPresent(h ->{
            this.playerBankBalance = h.getBalance();
        });
        this.font.drawString("$" + ((int) this.playerBankBalance), alignDigitsRight(((int) this.playerBankBalance), 8, 25), 10,-16746496);
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
        GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.minecraft.getTextureManager().bindTexture(GUI);
        int relX = (this.width - this.xSize) / 2;
        int relY = (this.height - this.ySize) / 2;
        this.blit(relX, relY, 0, 0, this.xSize, this.ySize);
    }

    // generates x location that aligns text on the decimal point of a Double
    private int alignDigitsRight(double number, int maxLeadingDigits, int x) {
        int numDigits = Integer.toString((int) number).length();
        int addedSpaces = 0;
        if (numDigits < maxLeadingDigits) {
            addedSpaces = maxLeadingDigits - numDigits;
        }
        return (addedSpaces * 6) + x;
    }
}

 

Link to comment
Share on other sites

You can't modify inventories on the client like this (GUIs are client side!). You must send a packet to the server saying "hey, the user pressed the sell button!". Then the server must check if the Container is still open (send Container#windowId with the packet, check if EntityPlayer#openContainer still has the same windowId on the server), if it's even the correct Container (instanceof MyContainerClass). Then validate that selling is actually appropriate currently and then and only then the server can do the selling process.

  • Thanks 1
Link to comment
Share on other sites

7 hours ago, diesieben07 said:

You can't modify inventories on the client like this (GUIs are client side!). You must send a packet to the server saying "hey, the user pressed the sell button!". Then the server must check if the Container is still open (send Container#windowId with the packet, check if EntityPlayer#openContainer still has the same windowId on the server), if it's even the correct Container (instanceof MyContainerClass). Then validate that selling is actually appropriate currently and then and only then the server can do the selling process.

This would require setting up my own custom packet and packet handler?

Link to comment
Share on other sites

38 minutes ago, andGarrett said:

This would require setting up my own custom packet and packet handler?

Well it requires you to register methods for a packet. Yes. Check out here.

  • Like 1

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
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.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.