TShock icon indicating copy to clipboard operation
TShock copied to clipboard

[Bouncer] RFC+Issue: Brain of Confusion Bouncer code

Open bartico6 opened this issue 4 years ago • 4 comments

Applies to TShock 4.3.2.6, API 2.1.

As mentioned in #1686, the Brain of Confusion time & range scale up with the damage taken. As I mentioned in a Discord conversation shown below, however, it doesn't have a maximum.

BoC discussion

This means that the buff's application cannot simply be bounded by Bouncer using a constant value, or it'll cause false positives at some point.

How should this be solved? A max value for "the most damage you can reasonably take"? A dynamic value based on most recent damage? Uncap the de-buff?

I don't have any idea how to approach this yet & upon investigation it seems the previous PR did not fix the problem entirely so I'm opening this issue for discussion.

bartico6 avatar Mar 21 '20 22:03 bartico6

Thanks quake. Seems like brain of confusion was made by confused brains.

Something possibly of importance: does the player attempt to apply the buff to themselves if the damage they take would kill them? Eg, from the screenshot, if 500 damage were to result in death, does the bouncer kick still occur? If not, this could potentially allow us to set a maximum length cap based on 500 calculated (after defence etc) damage. Tracking most recent damage application could also be used to bound the timing further

QuiCM avatar Mar 21 '20 22:03 QuiCM

@moisterrific should have the details. I think he got kicked a few times before sending his PR so yeah, it must be an issue with high incoming damage.

As for whether it takes raw damage or post-reduction damage, I'll have a look.

EDIT: It uses post-mitigation damage, not capped by health. Death does not prevent it.

Also, it applies the buff to NPCs only:

        if (this.brainOfConfusion && Main.myPlayer == this.whoAmI)
        {
          for (int index = 0; index < 200; ++index)
          {
            if (Main.npc[index].active && !Main.npc[index].friendly)
            {
              int num1 = 300 + (int) dmg * 2;
              if (Main.rand.Next(500) < num1)
              {
                Vector2 vector2 = Vector2.op_Subtraction(Main.npc[index].Center, this.Center);
                // ISSUE: explicit reference operation
                double num2 = (double) ((Vector2) @vector2).Length();
                float num3 = (float) Main.rand.Next(200 + (int) dmg / 2, 301 + (int) dmg * 2);
                if ((double) num3 > 500.0)
                  num3 = (float) (500.0 + ((double) num3 - 500.0) * 0.75);
                if ((double) num3 > 700.0)
                  num3 = (float) (700.0 + ((double) num3 - 700.0) * 0.5);
                if ((double) num3 > 900.0)
                  num3 = (float) (900.0 + ((double) num3 - 900.0) * 0.25);
                double num4 = (double) num3;
                if (num2 < num4)
                {
                  float num5 = (float) Main.rand.Next(90 + (int) dmg / 3, 300 + (int) dmg / 2);
                  Main.npc[index].AddBuff(31, (int) num5, false);
                }
              }
            }
          }
          Projectile.NewProjectile((float) this.Center.X + (float) Main.rand.Next(-40, 40), (float) this.Center.Y - (float) Main.rand.Next(20, 60), (float) (this.velocity.X * 0.300000011920929), (float) (this.velocity.Y * 0.300000011920929), 565, 0, 0.0f, this.whoAmI, 0.0f, 0.0f);
        }

bartico6 avatar Mar 21 '20 22:03 bartico6

Thanks for the research. I suppose we can try tracking the last damage received and bound based on that - assuming damage received comes in before NPC buff.

QuiCM avatar Mar 21 '20 23:03 QuiCM

Damage received comes before applying the buff since it’s needed to calculate the duration, if I’m not mistaken. If it’s possible to check last received damage and if the buff duration is less than or equal to the maximum possible time it should not be detected as cheat.

moisterrific avatar Apr 25 '20 03:04 moisterrific