Jump to content

[1.7.10] How to tell when Armour has been taken off and put on.


chbachman

Recommended Posts

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

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



×
×
  • Create New...

Important Information

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