Jump to content

[1.12.2] Checking a Specific Container for Items


HalestormXV

Recommended Posts

So I made a custom backpack and it works nicely. No issues. What I am trying to do next is check a players inventory for items. However now that I have added my backpack I want to also check the backpack's inventory. Not sure how I would go reaching into the container to look for items though. Here is my simple function that checks for quantity in the player's inventory which I have been using for some time with no problems. How could I make this work on my backpack's inventory also?

public static int checkForReagentQuantity(ItemStack itemStack, EntityPlayer player)
{
    int count = 0;
    Item reagentItem = itemStack.getItem();
    boolean hasReagent = player.inventory.hasItemStack(itemStack);
    if (hasReagent)
    {
        for (int slot = 0; slot < player.inventory.getSizeInventory(); slot++)
        {
            ItemStack stack = player.inventory.getStackInSlot(slot);
            if (stack != null && stack.getItem().equals(reagentItem)) {
                int total = count += stack.getCount();
                //System.out.println("Player has: " + total);
                return total;
            }
        }
    } else {
        return 0;
    }
    return 0;
}

 

Ideally, I want to try and run that on my Backpack's as well. It sounds quite simple, but my gut is telling me it isn't that easy.

Edited by HalestormXV
Link to comment
Share on other sites

I've been using that code since forever, so I can imagine that it has been replaced. Do you have an example or pseudo code using IItemHandler for that above? I'm trying to migrate everything I can over to the better implementations. For starters like how I made the backpack with Capabilities. I'm imagining you are referring to the 

@Nonnull
ItemStack getStackInSlot(int slot);

 

/**
 * Returns the number of slots available
 *
 * @return The number of slots available
 **/
int getSlots();

 

in the IItemHandler and simply just replicating the above with those calls instead and obviously adjusting accordingly?

Edited by HalestormXV
Link to comment
Share on other sites

Pretty much. getSlots() tells you how many slots there are (0-indexed) and getStackInSlot(index) gets the stack in that slot.

  • Thanks 1

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

42 minutes ago, Draco18s said:

Pretty much. getSlots() tells you how many slots there are (0-indexed) and getStackInSlot(index) gets the stack in that slot.

So something like this?

public static int checkForReagentQuantityRuneBag(ItemStack itemStack, IItemHandler itemHandler)
{
    int count = 0;
    Item reagentItem = itemStack.getItem();
    for (int index = 0; index < itemHandler.getSlots(); index++)
    {
        ItemStack stack = itemHandler.getStackInSlot(index);
        if (!stack.isEmpty() && stack.getItem().equals(reagentItem)) 
        {
            int total = count += stack.getCount();
            System.out.println("There are "+total+" "+stack.getDisplayName()+" in the inventory.");
            return total;
        }
        else { return 0; }
    }
    return 0;
}

I am going to take a wild guess and say you can't actually pass the itemHandler in because you need to get the actual IItemHandler for your Backpack right? So do I have to call/check the capability somewhere?

 

Perhaps I am totally wrong which is certainly probable since I am so used to the IInventory that this is like throwing me off.

Link to comment
Share on other sites

First item in the backpack is a rock.

Not reagent item. Next!

Second item in the backpack is a reagent item.

int total = 0 + stack size.

Return total! All done!

 

(Hey...what about the 3rd, 4th, and 5th items?)

  • Like 1

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

2 hours ago, diesieben07 said:

First item in the backpack is a rock.

Not reagent item. Return 0! All done!

Ah, yes. You're correct. I saw the first return and missed that one ;)

  • Like 1

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Okay, I missed that myself. Let me try and explain better. You need particular items to cast something. Example, in order to apply a resistance you need both 4 Redstone Dust and 3 Glowstone Dust. This dust can be in the player inventory. But if not and the player has the BackPack item in their inventory we want to check that also. 

 

So I am thinking a check of the inventory first. --> Okay we have nothing in the players inventory but we see that the player has a backpack, --> lets check that also. I am going to have to use the Backpacks itemHandler to look inside it right? So I would have to first get the Capability of that Backpack? Then after returning it, call the ItemHandler functions and check through that backpack to see if we have both of the items and their quantities required. So I am also guessing, that these Items that are required will have to be stored in an Array, correct? Since I can't pass multiple items through? Instead, I'd have to pass the array through and iterate through the array right?

 

That is why this is tripping me up I think, because I am just trying to get the steps right and ordered correctly. The code above once fixed will work right? But won't work if there are multiple items required correct?

Link to comment
Share on other sites

You're tracking a total amount of dust found, but you're returning it before every slot has been checked (or if a slot is the wrong item, returning 0).

  • Thanks 1

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

What am I mucking up over here. I can't figure it out.

public static int checkForReagentQuantityRuneBag(ItemStack itemStack, EntityPlayer thePlayer)
{
    System.out.println("Good news is I am getting called at least.");
    Item reagentItem;
    IItemHandler itemHandler = new ItemStackHandler(thePlayer.inventory.getSizeInventory());
    for (int slot = 0; slot < thePlayer.inventory.getSizeInventory(); slot++)
    {
        ItemStack stack = itemHandler.getStackInSlot(slot);
        //if (stack.getItem() == ItemInit.ITEM_RUNE_BAG)
        if (stack.getItem() instanceof RuneBag)
        {
            System.out.println("I found the rune bag while going through all the slots!");
            IRuneBagProvider theRuneBag = thePlayer.getCapability(RuneBagProvider.RUNEBAG_CAP, null);
            theRuneBag.getBag(EnumDyeColor.RED);
            reagentItem = itemStack.getItem();
            IItemHandler bagHandler = new ItemStackHandler(theRuneBag.getBag(null).getSlots());
            for (int bagSlots = 0; bagSlots < bagHandler.getSlots(); bagSlots++)
            {
                ItemStack stackInBagSlot = bagHandler.getStackInSlot(bagSlots);
                if (!stackInBagSlot.isEmpty() && stackInBagSlot.getItem().equals(reagentItem))
                {
                    int total = stackInBagSlot.getCount();
                    System.out.println("Player has: " + total + stackInBagSlot.getDisplayName() + " in the Rune Bag.");
                    return total;
                }
            }
        } else {
            Logging.getLogger().debug("Sorry Kappa, you almost got it.");
            //return 0;
        }
    }
    Logging.getLogger().debug("Sorry Kappa, no Rune Bag here.");
    return 0;
}

 

System.out.println("Good news is I am getting called at least."); - The is where my code makes it and then stops. I am likely doing the whole checking the inventory of the RuneBag thing wrong, but I would at least want to try and get into that step before I start worrying about it. Thoughts on what I am doing wrong that I am getting stopped before even reaching any other of my debug messages? As you can see from the commented line I have tried both

 

if (stack.getItem() == ItemInit.ITEM_RUNE_BAG)

if (stack.getItem() instanceof RuneBag)

Edited by HalestormXV
Link to comment
Share on other sites

To be quite honest @diesieben07 I was hoping for either you or @Draco18s to reply and say exactly what you said which was somewhat like. "hey dope, why are you creating a new ItemStackHandler - stop being a dingus and remember the getCapability function to get the correct IItemHandler. Which is pretty much exactly what you said, in a more poignant way as I am the said dingus who forgot about the the IItemHandler capability entirely (even though it is in the actual bag but I was too focused on this single piece of code).  I knew that creating the new IItemHandler was going to cause me issues because my debug messages kept saying that "air" was present in the slots. 

 

That being said your four sentences managed to let me combine both my checks into one check that will first look at the inventory and if nothing is there, check if there is a bag in the inventory, and if yes then check that inventory and if nothing is in the bag then return a 0 lol. :P So I have to thank you as per usual lol. I am going to post the code once I finish fixing it up as I do have one other question relating to having different items as requirements as for example you require both 3 Redstone AND 4 Glowstone to successfully use this. I am not sure of the best way to do this.

 

EDIT: Here is the new code: https://pastebin.com/X22LRFaP

Still need the best method to take care of different item requirements though.

Edited by HalestormXV
Link to comment
Share on other sites

12 hours ago, diesieben07 said:

Simplest way: make two counters (for redstone and glowstone) and count them up as you loop through the inventory.

A more universal solution: Start with a list of requirements and remove from that list as you find things in the inventory. At the end check if the list is empty (all requirements found) or not.

I like that universal method as there are quite  a few abilities and creating a List for each ability seems like the best way especially if I store it in its own class (all the lists with the requirements). Then I am guessing I can do a call to initialize the list before the check runs, and then as the check runs remove the items from the list as you said when it finds the item and check if the list is empty and return true or not then it will just rinse and repeats itself when the item is used. Could that cause any problems though? Re-initializing the list over and over or is that probably the best way to do it. 

 

EDIT: I managed to get the universal method working. I'm open to criticism as I don't know quite how effective this is or how "hacky/sloppy" it is on efficency but I'm open to suggestions. But as it stands this piece of code looks into the ItemStack list that was passed to it and then calculates if the player has the items in the list and how many of those items should be removed.

 

I also have a backpack in my mod so it also will check the inventory of the player's backpack and compare. From testing it seems to respect the slots that the player has in inventory and if it can find an item in the inventory but is looking for another item as well and can't find it and the player has a backpack it will check that inventory as well. Overall I am pretty happy with it but I am open to comments or suggestions as well. Here is the link to the code segment: https://pastebin.com/Jrs7XD9Q

Edited by HalestormXV
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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
    • It is an issue with quark - update it to this build: https://www.curseforge.com/minecraft/mc-mods/quark/files/3642325
    • Remove Instant Massive Structures Mod from your server     Add new crash-reports with sites like https://paste.ee/  
  • Topics

×
×
  • Create New...

Important Information

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