Jump to content

[1.18.2] onContentsChanged


Squander

Recommended Posts

public class ItemStackHandlerMod extends ItemStackHandler {
    private Player player;

    public ItemStackHandlerMod(int size) {
        super(size);
    }

    public ItemStackHandlerMod(int size, Player player) {
        super(size);
        this.player = player;
    }

    @Override
    protected void onContentsChanged(int slot) {
        if(player != null){
            if(getStackInSlot(slot).getItem() instanceof BaseAmulet amulet){
                amulet.apply(player);
            }
        }
    }
}
public class HealthAmulet extends BaseAmulet {
    public static final UUID HEALTH = UUID.fromString("c2d8616a-c58a-4d99-aec9-faad03858302");

    public HealthAmulet(Properties pProperties) {
        super(pProperties);
    }

    @Override
    public void apply(Player player) {
        AttributeInstance instance = player.getAttribute(Attributes.MAX_HEALTH);
        instance.addPermanentModifier(new AttributeModifier(HEALTH, "Health Amulet", 5, AttributeModifier.Operation.ADDITION));
    }

    @Override
    public void remove(Player player) {
        AttributeInstance instance = player.getAttribute(Attributes.MAX_HEALTH);
        instance.removeModifier(HEALTH);
    }
}

 

6 hours ago, Luis_ST said:

Could you please provide a useful context? Which exact method are you talking about? Where is the method located?

Please post your code.

 

Link to comment
Share on other sites

ItemStackHandler#onContentsChanged is called whenever a Item is added (via #insertItem), a Item is removed (via #extractItem) or a Item is set (via #setStackInSlot).

You should be able to run code after the Item is removed, by checking in #onContentsChanged if the Slot is empty or if there is a other Item in it.

Link to comment
Share on other sites

42 minutes ago, Luis_ST said:

ItemStackHandler#onContentsChanged is called whenever a Item is added (via #insertItem), a Item is removed (via #extractItem) or a Item is set (via #setStackInSlot).

You should be able to run code after the Item is removed, by checking in #onContentsChanged if the Slot is empty or if there is a other Item in it.

I don't think it will work. I want to do it in a similar way to the inventory when I put my boots on, the attributes from it are added to the player when I take them off they are removed.

Link to comment
Share on other sites

Why doesn't something like this work?

WARNING: This code is not tested, it just shows the idea. And see the comment in the code.

    @Override
    public void setStackInSlot(int slot, @NotNull ItemStack stack) {
        ItemStack previous = getStackInSlot(slot);
        super.setStackInSlot(slot, stack);
        // Probably needs some check here to see if "previous" and "stack" are the same item? 
        // i.e. item swap of two different amulets
        onRemoved(previous);
    }

    @Override
    public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) {
        ItemStack extracted = super.extractItem(slot, amount, simulate);
        if (!simulate) {
            onRemoved(extracted);
        }
        return extracted;
    }

    protected void onRemoved(ItemStack itemStack) {
        // Your code here
    }

 

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

Note: That code above only works if the item stacks are always amount=1 like armor or tools.

It doesn't take into account removing part of stacked items.

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

1 hour ago, warjort said:

Note: That code above only works if the item stacks are always amount=1 like armor or tools.

It doesn't take into account removing part of stacked items.

Ok it works, but i don't know how i can prevent amulet of the same kind from being added to a container

Link to comment
Share on other sites

Quote

Ok it works, but i don't know how i can prevent amulet of the same kind from being added to a container

One way would be to check if the stacks are the same (same item). Then skip the onRemove() call.

You might want a different check if you have custom nbt or something that means just checking the item is not enough.

if (!previous.isSame(itemStack)) {
    onRemoved(previous);
}

 

Edited by warjort

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

50 minutes ago, warjort said:

One way would be to check if the stacks are the same (same item). Then skip the onRemove() call.

You might want a different check if you have custom nbt or something that means just checking the item is not enough.

if (!previous.isSame(itemStack)) {
    onRemoved(previous);
}

 

i did something like this and it works too.

@Override
    public boolean isItemValid(int slot, @NotNull ItemStack stack) {
        for (int i = 0; i < getSlots(); i++) {
            ItemStack stack1 = getStackInSlot(i);
            if(stack.getItem() == stack1.getItem()){
                return false;
            }
        }
        return super.isItemValid(slot, stack);
    }

 

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.