Jump to content

How do I detect when a player no longer has an item?


AmethystAir

Recommended Posts

I'm working on a mod that adds rings that give you special abilities (with Baubles API) and I'm having an issue where certain rings that set player abilities are not being disabled when removed from the player's inventory by any method. I've tried to use onDroppedByPlayer but it has no effect; neither does creating an ItemTossEvent. I would like to have either perfect detection of when the item is removed from the inventory, or an update loop that runs once a second (or so) that will disable the player's abilities if there's no ring there. The problem is, I haven't had much luck looking for either. Do you have any suggestions on either solution? I will be more than happy to provide code snippets if needed. Thanks in advance for any help you can provide!

Link to comment
Share on other sites

Bro, do you even Bauble? In about 30sec i found this API and interface to do that.

 

public interface IBauble {
...
/**
* This method is called when the bauble is unequipped by a player
*/
public void onUnequipped(ItemStack itemstack, EntityLivingBase player);
...
}

 

If this documentation/API is working then this should do the trick (implement this interface in your Item.class).

 

If not, then you would have to track it yourself. Question is - Are you using your own inventory or vanilla one? (Because there are few ways of handling those.)

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

That's not exactly what I'm looking for, sorry, should have been more specific. The rings also function in the player's inventory (as intended), and that's where I'm having issues. I only mentioned the Baubles API in case it had some update function I could use. I'm using the vanilla inventory, nothing special about it other than having Baubles installed :P How would I go about tracking items in the vanilla inventory?

Link to comment
Share on other sites

Use a PlayerTickEvent and check with !event.player.inventory.hasItem()

 

I actually saw your post in another thread recommending that for something else so I gave it a try, but I'm not able to get it to run at all. Here's what I added, and nothing is being printed out to the console. I'm probably doing something wrong, but for the life of me I can't figure it out.

 

Entirety of UpdateEvent.java:

import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent;

public class UpdateEvent {
private static int tick = 0;
@EventHandler
public void eventHandler(PlayerTickEvent event) {
	tick++;
	System.out.println("Player ticked!");
	if (tick % 20 != 0)
		return;
	if (event.player.capabilities.allowFlying) {
		event.player.capabilities.allowFlying = false;
		event.player.capabilities.isFlying = false;
		event.player.fallDistance = 0;
		event.player.sendPlayerAbilities();
	}

}
}

 

Excerpt from CommonProxy.java where I register the new event:

	MinecraftForge.EVENT_BUS.register(new UpdateEvent());

Link to comment
Share on other sites

You just got me confused here:

"mod that adds rings" + "removed from the player's inventory" (You know, there are no rings in normal inventory, so I thought you are asking for Baubles one).

 

Believing the question is: How to know when item get's removed from player's inventory (4x9 one)?

 

Toss and onDropped are called when you actually toss item, so moving item to chest won't call it.

 

Answer:

Well, without custom inventory, you can never know when item is removed, you can only know when it exist inside of Inv (Item.onUpdate()).

Ofc. that is doable, but not simply.

1. You either hold 2 player inventories (that would also require new mapping, many check events, loading on startup, proably saving on unload) and compare using PlayerEvent.LivingUpdateEvent - invFromLastTick to invThisTick.

2. You extend player inventory and override normal one with yours where you ofc. only override choosen parts (to not break compatibility).

 

So in the end - there is no system that would allow you to: onItemAppearedInInventory -> addEffectToPlayer -> onItemRemovedFromInventory -> removeEffectFromPlayer

 

You can only track if it exist in this tick. And in this case using PlayerTickEvent is not wrong, but not best. you should use item.onUpdate(), it will save you one loop through eq.

 

Edit: As to this "1" i proposed - better way would be to add ExtendedProperty to player and go from there.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

I think you're registering the event handler to the wrong bus.  It is an FML event so needs to be registered on that event bus.

I tried registering it to the other bus using @SubscribeEvent and the event was still not being triggered, I'm at a loss for why it isn't working.

 

Also, I tried switching one of the rings to only function in the baubles inventory and it still did not deactivate when I removed it.

 

I believe the baubles onUnequipped() function not working may be related to something with whether it's running on the client or server and how I have the effects coded.

 

I'll keep looking into this more tomorrow, I'll post here if I have any updates.

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.