EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Support::General Support (https://www.eqemulator.org/forums/forumdisplay.php?f=598)
-   -   Taunt (https://www.eqemulator.org/forums/showthread.php?t=25205)

jenco420 05-10-2008 05:26 PM

Taunt
 
Alright been looking at taunt recently b/c i never get a failed message when a taunt so i peeked in special_attacks.cpp to see how taunt worked on eqemu.

Looking at the code i see that it can fail but it seems when ever i loose aggro and taunt it switches right back to me everytime?

Am i just crazy or has anyone else noticed this ? :P

Code:

float tauntchance;
                if(always_succeed) {
                        tauntchance = 101;
                } else {
                       
                        // no idea how taunt success is actually calculated
                        // TODO: chance for level 50+ mobs should be lower
                        int level_difference = level - target->GetLevel();
                        if (level_difference <= 5) {
                                tauntchance = 25.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 65.0)
                                        tauntchance = 65.0;
                        }
                        else if (level_difference <= 10) {
                                tauntchance = 30.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 85.0)
                                        tauntchance = 85.0;
                        }
                        else if (level_difference <= 15) {
                                tauntchance = 40.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 90.0)
                                        tauntchance = 90.0;
                        }
                        else {
                                tauntchance = 50.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 95.0)
                                        tauntchance = 95.0;
                        }
                }

i noticed if(always_succeed) {tauntchance = 101; how does the server know when to use this? sorry i'm new to programming in general reading the code is pretty easy for the most part but i get confused easy sometimes ~.~

moydock 05-10-2008 06:00 PM

That's saying if always_succeed (probably for a discipline) then it's 100% chance.
Then 'else' (for all other cases), then it breaks it up into what level the person is using it and has a formula for each group. In the last group there should be a maximum of 95% chance that you are successful. The problem could be in the function that's calling tauntchance. It may just not properly be giving the fail message. But who knows.
This is the code for above lvl 15:
Code:

else {
                                tauntchance = 50.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 95.0)
                                        tauntchance = 95.0;

or
tauntchance = 50 + (50 * (tauntskill / 200))
which isn't the best formula because at 200 taunt skill you'll have 100% chance, which will be 95% since there's a cap.

jenco420 05-10-2008 08:33 PM

and if you look further down the page you'll see

Code:

if (tauntchance > MakeRandomFloat(0, 100)) {
                        // this is the max additional hate added per succesfull taunt
                        tauntvalue = (MakeRandomInt(5, 10) * level);
                        //tauntvalue = (sint32) ((float)level * 10.0 * (float)rand()/(float)RAND_MAX + 1);
                        // new hate: find diff of player's hate and whoever's at top of list, add that plus tauntvalue to players hate
                        newhate = who->GetNPCHate(hate_top) - who->GetNPCHate(this) + tauntvalue;
                        // add the hate
                        who->CastToNPC()->AddToHateList(this, newhate);
                }
                else{
                        //generate at least some hate reguardless of the outcome.
                        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));
                }
        }
       
        //generate at least some hate reguardless of the outcome.
        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));
}

so it's adding hate even it taunt fails? Wierd from what i remember if it failed you got no hate whatsoever (at least did'nt ever take aggo) so if i changed
Code:

else{
                        //generate at least some hate reguardless of the outcome.
                        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));
                }
        }
       
        //generate at least some hate reguardless of the outcome.
        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));

to
Code:

else{
                        //generate at least some hate reguardless of the outcome.
                        who->CastToNPC()->AddToHateList(this, (0));
                }
        }
       
        //generate at least some hate reguardless of the outcome.
        who->CastToNPC()->AddToHateList(this, (0));

would that mean that if your taunt failed you get no added hate what so ever?

moydock 05-10-2008 08:40 PM

Yeah. Could break it though. I'm guessing they are sending 1 agro instead of 0 for a reason.

Scorpious2k 05-10-2008 09:12 PM

It actually looks like the hate is being generated twice at times.

I would think the second instance of
Code:

        //generate at least some hate reguardless of the outcome.
        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));

at the end of the function probably should be removed. It ends up adding hate even if player at the top of the hate list already, the taunted one is lower level than the taunter, or taunted is at 20% health or less.

It is also added after either the taunt succeeds and hate is added for that, or taunt fails and some hate is added for that.

I don't think that should be happening. I could be wrong.

As for getting it to add no hate when taunt fails, take out the above AND take out the following:
Code:

                else{
                        //generate at least some hate reguardless of the outcome.
                        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));
                }

I haven't tested it, but I think it should work.

jenco420 05-10-2008 09:27 PM

cool i'll get this into my source and let ya know how it goes.

jenco420 05-15-2008 08:02 PM

Well after a few days tweking and rewriting some code Mouya and i came up with a good system for taunt (well based on my players feedback)

Replace

Code:

void Mob::Taunt(NPC* who, bool always_succeed) {
        if (who == NULL)
                return;
       
        if(DivineAura())
                return;
       
        if (!always_succeed && IsClient())
                CastToClient()->CheckIncreaseSkill(TAUNT);
       
        int level = GetLevel();
       
        Mob *hate_top = who->GetHateMost();
       
        // Check to see if we're already at the top of the target's hate list
        // a mob will not be taunted if its target's health is below 20%
        if ((hate_top != this)
        && (who->GetLevel() < level)
        && (hate_top == NULL || hate_top->GetHPRatio() >= 20) ) {
                sint32 newhate, tauntvalue;

                float tauntchance;
                if(always_succeed) {
                        tauntchance = 101;
                } else {
                       
                        // no idea how taunt success is actually calculated
                        // TODO: chance for level 50+ mobs should be lower
                        int level_difference = level - target->GetLevel();
                        if (level_difference <= 5) {
                                tauntchance = 25.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 65.0)
                                        tauntchance = 65.0;
                        }
                        else if (level_difference <= 10) {
                                tauntchance = 30.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 85.0)
                                        tauntchance = 85.0;
                        }
                        else if (level_difference <= 15) {
                                tauntchance = 40.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 90.0)
                                        tauntchance = 90.0;
                        }
                        else {
                                tauntchance = 50.0;        // minimum
                                tauntchance += tauntchance * (float)GetSkill(TAUNT) / 200.0;        // skill modifier
                                if (tauntchance > 95.0)
                                        tauntchance = 95.0;
                        }
                }
                if (tauntchance > MakeRandomFloat(0, 100)) {
                        // this is the max additional hate added per succesfull taunt
                        tauntvalue = (MakeRandomInt(5, 10) * level);
                        //tauntvalue = (sint32) ((float)level * 10.0 * (float)rand()/(float)RAND_MAX + 1);
                        // new hate: find diff of player's hate and whoever's at top of list, add that plus tauntvalue to players hate
                        newhate = who->GetNPCHate(hate_top) - who->GetNPCHate(this) + tauntvalue;
                        // add the hate
                        who->CastToNPC()->AddToHateList(this, newhate);
                }
                else{
                        //generate at least some hate reguardless of the outcome.
                        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));
                }
        }
       
        //generate at least some hate reguardless of the outcome.
        who->CastToNPC()->AddToHateList(this, (MakeRandomInt(5, 10)*level));
}

With

Code:

void Mob::Taunt(NPC* who, bool always_succeed) {
  if (who == NULL) // Make sure we have a target
      return;
 
  if(DivineAura())
      return;
 
  if (!always_succeed && IsClient()) // If the user is a Player and it's possible to fail, check to see if skill increases.
      CastToClient()->CheckIncreaseSkill(TAUNT);
 
  int level = GetLevel();
 
  Mob *hate_top = who->GetHateMost();
 
  // Check to see if we're already at the top of the target's hate list
  // a mob will not be taunted if its target's health is below 20%
  if ((hate_top != this)
  && (who->GetLevel() < level)
  && (hate_top == NULL || hate_top->GetHPRatio() >= 20) ) {
      sint32 newhate, tauntvalue;
      float tauntchance;

      int level_difference = level - target->GetLevel();
      tauntchance = 20.0 + (float)level_difference;
      tauntchance += tauntchance * ( (float)GetSkill(TAUNT) / 400.0);  // skill modifier
     
      if (tauntchance > 66.6) // TODO: Change this to whatever you want the maximum chance to taunt to be -- I picked a max of 66.6% success.
        tauntchance = 66.6;
      if (tauntchance < 0.0)
        tauntchance = 0.0; // TODO: Change this to whatever you want the minimum chance to taunt regardless of skill and level
     
      if ((tauntchance > MakeRandomFloat(0, 100)) || always_succeed) {
              // this is the max additional hate added per succesfull taunt, on live it always gave a set amount of hate change it to what you think it should add.
              tauntvalue = (10);
        // new hate: find diff of player's hate and whoever's at top of list, add that plus tauntvalue to players hate
        newhate = who->GetNPCHate(hate_top) - who->GetNPCHate(this) + tauntvalue;
        // add the hate
        who->CastToNPC()->AddToHateList(this, newhate);
        return;
      }
      //do nothing and give failed message
      Message(13, "You have failed to taunt your target.");
      return;
  }
}



All times are GMT -4. The time now is 12:46 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.