Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Is there a hook somewhere that i am missing, or a way to implement it myself, because i was wondering how to tell when a piece of armour has been taken off or put on.

What is it you are trying to do?  There may be a way to acheive it without tracking this.

Long time Bukkit & Forge Programmer

Happy to try and help

  • Author

I am making upgrades for armour, these upgrades sometimes need to react when armour is taken off or put on.

So, you want to hurt the player when player puts it on themselves?  Or hurt them when they take it off?

 

You could track it as you said.

 

One other idea that comes to mind is using the onUpdate and onArmorUpdate.  One will be called when the item is in inventory, the other when it is in an armorslot.

 

You could write an NBT tag to the itemstack indicating where it is at.  Probably do not need to do this each tick, would be wastefull.  Before it is written, check to see if it changed from the previoius version and take your action.

 

The weakness is that if the player removed the item and throws it to the groudn instead of putting back in inventory, they could bypass the effort.

Long time Bukkit & Forge Programmer

Happy to try and help

  • Author

Yeah, i thought about that, not sure the best way to do this, mabye onArmourTick on first call calls the put on method, not sure how to do take off, thinking living entity update, checking every tick to see if they do not have the armour on any more. however not sure how to call it on that armour piece.

Minecraft actually tracks the change of armor and equipped items. Due to Armors being able to modify attributes, the method "getAttributeModifiers()" in ItemStack is called, which defers to "getAttributeModifiers(ItemStack stack)" in Item.

So by overwriting that method, you can track when the equipment changes. It will not allow you to check if it was equipping or unequipping, or what slot it refers to, and it also wont give you the player, so it's arguably not that useful.

However, it is called by "onUpdate()" in EntityLivingBase, and that is something you can emulate.

 

A quick example:

I set up a tick handler for player ticks. On tick start, it does the following:

if(!player.worldObj.isRemote)
{
ItemStack[] prevEquipment = getPreviousEquipment(player);
if(prevEquipment!=null)
	for (int j = 0; j < 5; ++j)
	{
		ItemStack itemstack = prevEquipment[j];
		ItemStack itemstack1 = player.getEquipmentInSlot(j);
		if (!ItemStack.areItemStacksEqual(itemstack1, itemstack))
			changeArmor(player, itemstack, itemstack1);
	}
}

 

the method "getPreviousEquipment(EntityPlayer)" accesses "previousEquipment" in EntityLivingBase via reflection, like this:

public static ItemStack[] getPreviousEquipment(EntityLivingBase entity)
{
int I_prevEquip = 5;
Field f = EntityLivingBase.class.getDeclaredFields()[i_prevEquip];
try {
	f.setAccessible(true);
	return (ItemStack[]) f.get(entity);
} catch (Exception e) {
	e.printStackTrace();
}
return null;
}

"I_prevEquip" is an integer that represents at which point in the array of declared fields you will find "previousEquipment". One can also find declared fields by name, but that is not obfuscation proof. With this, you'll just have to change the integer when Minecraft updates that class and moves the position of that field (which is generally unlikely)

the "setAccessible(true)" is necessary because it is a private and final field.

 

With that you can detect the change in equipment, the method "changeArmor(EntityPlayer, ItemStack, ItemStack)" in my case simply checks if it's my armor that's been moved around and then calls an equip or unequip method in the Item class.

 

lastly, keep in mind that this will detect changing armor but also the changing of the equipped item. Since that is probably something you don't car about, have the for loop start at j=1. That way, you only get the armor slots.

 

If any of that was horribly explained and you didn't understand a thing, I'm sorry =P

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

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.