Jump to content

[1.8] [SOLVED] addPotionEffect weirdness in onArmorTick


Recommended Posts

Posted

Hi,

 

Whenever I try to use addPotionEffect with the regeneration effect, I have a strange problem.

While I set the effectDuration to less than a 100 (5 seconds), I have the particles and the effect, but I don't actually regenerate.

While I set the effectDuration to 100+, the regeneration effect shows like it's in level 1, but it feels like it's in level 10 (insta-regen).

Not sure what's the problem.

Here's the code:

@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack)
{
	if (!world.isRemote)
	{

		if(player.getCurrentArmor(0) != null && player.getCurrentArmor(1) != null && player.getCurrentArmor(2) != null && player.getCurrentArmor(3) != null)
			{
				ItemStack boots = player.getCurrentArmor(0);
				ItemStack leggings = player.getCurrentArmor(1);
				ItemStack chestplate = player.getCurrentArmor(2);
				ItemStack helmet = player.getCurrentArmor(3);

			if(boots.getItem() == UselessItems.useless_boots && leggings.getItem() == UselessItems.useless_leggings && chestplate.getItem() == UselessItems.useless_chestplate && helmet.getItem() == UselessItems.useless_helmet)
				{
					player.addPotionEffect(new PotionEffect(Potion.regeneration.id, 200, 0));
				}

			}
	}
	else { 	super.onArmorTick(world, player, itemStack); }
}

 

Thanks for any reply,

Jon

Why are you reading this?

Posted

Part of the problem is you are adding the potion effect FOUR times per tick, once for each piece of armor (assuming they all belong to the same class, but even then you are adding it once every single tick). This means that the regen effect is constantly combining with itself, resetting the duration each time.

 

Regeneration level 1 heals 1/2 heart every 50 ticks, but since your duration is reset every single tick, it never gets a chance to do so, UNTIL you set the duration to a multiple of 50, in which case it regens you every single tick because (duration % 50) will always equal zero with a full duration.

 

In other words:

// with duration not a multiple of 50
tick effect
  1  add regen with duration 20
  1  check regen (duration % 50) == 0 ? no, it's 20
  2  decrement regen duration
  2  add regen with duration 20, again, resetting current duration to 20
  2  check regen (duration % 50) == 0 ? no, it's 20
  3  and so on

// with duration = 50, 100, 150, or any multiple of 50
tick effect
  1  add regen with duration 50
  1  check regen (duration % 50) == 0 ? yep! regen!!!
  2  decrement regen duration
  2  add regen with duration 50, again, resetting current duration to 50
  2  check regen (duration % 50) == 0 ? yep! regen!!!
  3  and so on

The order of the potion effect check and duration decrement may be off, but the idea is the same.

Posted

Part of the problem is you are adding the potion effect FOUR times per tick, once for each piece of armor (assuming they all belong to the same class, but even then you are adding it once every single tick). This means that the regen effect is constantly combining with itself, resetting the duration each time.

 

Regeneration level 1 heals 1/2 heart every 50 ticks, but since your duration is reset every single tick, it never gets a chance to do so, UNTIL you set the duration to a multiple of 50, in which case it regens you every single tick because (duration % 50) will always equal zero with a full duration.

 

In other words:

// with duration not a multiple of 50
tick effect
  1  add regen with duration 20
  1  check regen (duration % 50) == 0 ? no, it's 20
  2  decrement regen duration
  2  add regen with duration 20, again, resetting current duration to 20
  2  check regen (duration % 50) == 0 ? no, it's 20
  3  and so on

// with duration = 50, 100, 150, or any multiple of 50
tick effect
  1  add regen with duration 50
  1  check regen (duration % 50) == 0 ? yep! regen!!!
  2  decrement regen duration
  2  add regen with duration 50, again, resetting current duration to 50
  2  check regen (duration % 50) == 0 ? yep! regen!!!
  3  and so on

The order of the potion effect check and duration decrement may be off, but the idea is the same.

First of all thank you for replying, I believe this is indeed the issue.

I did understand the issue but I didn't understand the solution.

I tried to follow what you said but it didn't work out, I probably derped.

Here's the code:

	@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack)
{
	int effectDuration;

	if (!world.isRemote)
	{

		if(player.getCurrentArmor(0) != null && player.getCurrentArmor(1) != null && player.getCurrentArmor(2) != null && player.getCurrentArmor(3) != null)
			{
				ItemStack boots = player.getCurrentArmor(0);
				ItemStack leggings = player.getCurrentArmor(1);
				ItemStack chestplate = player.getCurrentArmor(2);
				ItemStack helmet = player.getCurrentArmor(3);

			if(boots.getItem() == UselessItems.useless_boots && leggings.getItem() == UselessItems.useless_leggings && chestplate.getItem() == UselessItems.useless_chestplate && helmet.getItem() == UselessItems.useless_helmet)
				{
					player.addPotionEffect(new PotionEffect(Potion.regeneration.id, effectDuration = 50, 0));
					if ((effectDuration % 50) == 0) //<- never been called
						{
							Log.debug("Test");
							player.addPotionEffect(new PotionEffect(Potion.regeneration.id, effectDuration, 0));
							effectDuration = 0;
						}
				}

			}
	}
	else { 	super.onArmorTick(world, player, itemStack); }
}

 

Why are you reading this?

Posted

I didn't actually offer a solution in the previous post - I only explained the problem.

// what's with the 'effectDuration = 50'  where is 'effectDuration' coming from?
player.addPotionEffect(new PotionEffect(Potion.regeneration.id, effectDuration = 50, 0));
  if ((effectDuration % 50) == 0) // what's this for???

No, the solution is 2-fold:

 

1. Only apply the potion effect for ONE of the armor pieces, e.g.

@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack) {
  if (this != UselessItems.useless_boots) { // only one piece needs to tick - why do the same thing 4 times?
     return;
  }
  // rest of onArmorTick code, except you already know the player is wearing the right boots 
}

 

2. Only perform the check once every so many ticks, probably 50 to match the regeneration potion's rate of application

@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack) {
  if (world.getWorldTime() % 50 > 0) {
     return; // it has not yet been 50 ticks since the last time your update tick code ran
  }
  // rest of onArmorTick code
}

Of course, #2 means you potentially have to wait 50 ticks before you receive regeneration upon donning the last piece of armor, so you may want to apply it immediately if the player does not already have the regen potion effect.

Posted

I didn't actually offer a solution in the previous post - I only explained the problem.

// what's with the 'effectDuration = 50'  where is 'effectDuration' coming from?
player.addPotionEffect(new PotionEffect(Potion.regeneration.id, effectDuration = 50, 0));
  if ((effectDuration % 50) == 0) // what's this for???

No, the solution is 2-fold:

 

1. Only apply the potion effect for ONE of the armor pieces, e.g.

@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack) {
  if (this != UselessItems.useless_boots) { // only one piece needs to tick - why do the same thing 4 times?
     return;
  }
  // rest of onArmorTick code, except you already know the player is wearing the right boots 
}

 

2. Only perform the check once every so many ticks, probably 50 to match the regeneration potion's rate of application

@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack) {
  if (world.getWorldTime() % 50 > 0) {
     return; // it has not yet been 50 ticks since the last time your update tick code ran
  }
  // rest of onArmorTick code
}

Of course, #2 means you potentially have to wait 50 ticks before you receive regeneration upon donning the last piece of armor, so you may want to apply it immediately if the player does not already have the regen potion effect.

Oh, I see.

I went on the second solution that looked more simple, and did this:

	@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack)
{

	if (!world.isRemote)
	{

		if(player.getCurrentArmor(0) != null && player.getCurrentArmor(1) != null && player.getCurrentArmor(2) != null && player.getCurrentArmor(3) != null)
			{
				ItemStack boots = player.getCurrentArmor(0);
				ItemStack leggings = player.getCurrentArmor(1);
				ItemStack chestplate = player.getCurrentArmor(2);
				ItemStack helmet = player.getCurrentArmor(3);

			if(boots.getItem() == UselessItems.useless_boots && leggings.getItem() == UselessItems.useless_leggings && chestplate.getItem() == UselessItems.useless_chestplate && helmet.getItem() == UselessItems.useless_helmet)
				{
					if (player.getActivePotionEffect(Potion.regeneration) == null)
					{
						player.addPotionEffect(new PotionEffect(Potion.regeneration.id, 50, 0));
					}
					if (world.getWorldTime() % 50 > 0)
					{
						return;
					}
					player.addPotionEffect(new PotionEffect(Potion.regeneration.id, 50, 0));
				}

			}
	}
	else { 	super.onArmorTick(world, player, itemStack); }
}

This seems to work!

Thank you guys :)

Why are you reading this?

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.