Jump to content

[Bug] Threat Calculation


Guest Janu

Recommended Posts

Hey guys,

there seems to be a problem with the threat calcultion:

aggro.jpg

This are screenshots of the Addon "Omen" after the raid has done ~200k damage on the bosses.

Left side is on retail servers and right side is in mangos. I think you can see the differences in BPS and threat amount quite clearly :) Besides it is much more difficult for tanks to keep holding their threat high enough in raids than on retail.

Maybe someone has a solution for that?

Thanks and Regards,

Janu

Link to comment
Share on other sites

Tank skill, gear, talent build, and fight mechanics are big variables in the threat/second equation. You may be comparing apples to oranges.

How do you mean this? The players are the same, so he can play his char :) The great difference is the gear yep, cause on Offi it is ICC and on my server it is TOC equip.. But I think this threat difference is quite too much on the whole. On retail the last player in the threat list has more threat than the tank on mangos and this can definitely not be correct even with this equip difference :)

Could it be that all the values in DB are incorrect or is this problem more on the core side, like in sending packages to the client or threat calculation on the whole?

Link to comment
Share on other sites

what i see in the "BPS" column is a difference or 2 orders of magnitude.. multiple value by 100?

Usually 1 damage does 1 threat so for dps classes TPS matches the DPS like we see on offy's screenshots (from 2k to 6k sounds realistic) while mangos, as you noted, gives just 1/100th of DPS as TPS.

I think the problem is how threath is sent on SMSG_THREATUPDATES messages:

threat is calculated usually as 1:1 from damage or 2:1 for IsDamageToThreatSpell (what's that?) and it's stored as float since it can be modified by some aura coefficients.

When treath is sent to client with Unit::SendThreathUpdate the value is converted with uint32((*itr)->getThreat()) and the decimal fraction is lost due to truncate while, IMHO, it should be sent as uint32((*itr)->getThreat()*100) so 2 decimal fraction is preserved and thus it will explain the 2 orders of magnitude.

For the DK treath, for example, DnD should give 1.9*damage as threat but actualy it can't be done since table SPELL_THREAT only allows a fixed valued per spell and, I'm not sure, only as immediate effect.

Link to comment
Share on other sites

there are a little bug from any skills what are generating a LOL agro,for example: http://www.wowhead.com/spell=586 IF you have boss agro,and you use this,are working,but when effect is finished,when debuff expires,you win all agro,for example:

tank are tanking a boss and boss Summon a add,you have Agro 0 with boss,and you attack to add,andyouuse this,when effect is finalized,you have agro 100% from boss, and add,if you're un world and are 6 people fighting withmobs,and you're fighting with a mob,you win all agro from all players fighting in a zone :S if you use http://es.wowhead.com/spell=58984 the same,you win agro from battles what you're not involved :S

P.D too are skills what doesen't generate agro,but they generate a gran cuantity of agro,for example spell=48078 or any talents for example this talent 33202

Link to comment
Share on other sites

Hey guys,

there seems to be a problem with the threat calcultion:

aggro.jpg

This are screenshots of the Addon "Omen" after the raid has done ~200k damage on the bosses.

Left side is on retail servers and right side is in mangos. I think you can see the differences in BPS and threat amount quite clearly :) Besides it is much more difficult for tanks to keep holding their threat high enough in raids than on retail.

Maybe someone has a solution for that?

Thanks and Regards,

Janu

tnx god another player that post same bug that i post time ago. all the threat system seems to be wrong. as i said in my topic. i test with my paladin on retail and easily can get 60 100k on aggro, and in mangos with same talent build with more gear got 3k 6k.

also i test with a warrior is the same result the threat generated is wrong, dps can easily get the aggro on mobs when its aoe.

Link to comment
Share on other sites

When treath is sent to client with Unit::SendThreathUpdate the value is converted with uint32((*itr)->getThreat()) and the decimal fraction is lost due to truncate while, IMHO, it should be sent as uint32((*itr)->getThreat()*100) so 2 decimal fraction is preserved and thus it will explain the 2 orders of magnitude.

I didn't get it.

Imagine (*itr)->getThreat() returns 12345.678

conversion to uint32 would give : 12346

You would do (*itr)->getThreat()*100, which is : 1234567.8

conversion to uint32 : 1234568...

Problem is not from threat sending I think...

Link to comment
Share on other sites

For the DK treath, for example, DnD should give 1.9*damage as threat but actualy it can't be done since table SPELL_THREAT only allows a fixed valued per spell and, I'm not sure, only as immediate effect.

I think it wouldn't be a big problem to add something like a multiplicator to database and calculation. I'm not sure, but I guess this is not only a problem when handeling Death and Decay . So it might be useful...

When treath is sent to client with Unit::SendThreathUpdate the value is converted with uint32((*itr)->getThreat()) and the decimal fraction is lost due to truncate while, IMHO, it should be sent as uint32((*itr)->getThreat()*100) so 2 decimal fraction is preserved and thus it will explain the 2 orders of magnitude.

I agree with Tonian67. I haven't taken a look on calculation yet, but I think that isn't the point.

Link to comment
Share on other sites

Mine was a replay to Darkstalker's post about why on mangos we got a lower 2 order magnitute not why tanks compared to DPS do less threat...

In other words using Tonian67 example:

Imagine player A with 12345.678 threat and player B with 12345.000 so for the server A > B, now they are both sent as 12346 so for the client A = B which is wrong due to the loss of precision by the uint32 conversion.

Also, as the screenshot suggests, on offy OMEN should show 1234568 and not 12346.

Alternatively it's possible to calculate threat as damage*100 rather then damage*1, in the end it will give the same results, the only problem could be how this ratio works with some aura/effect that add/remove an hardcode flat value

For DnD, I simple gave an example of a spell, but surely there are others, where threat value is wrong and with actual revision it can not be fixed by simply updating values on DB.

For Searing Pain, Mind Blast, Earth Shock, threat is calculated using an hardcoded 2x by Unit::IsDamageToThreatSpell, I think we agree that maybe a more general approch using vaules from DB would be better.

About Fade and Shadowmeld spells both add a big flat negative value, I didn't test yet but I suspect there could be some signed to unsigned conversion that gives problems

Link to comment
Share on other sites

if you just multiply by 100 you don't fix the bug, but move it out of sight.

our main line of calls is:

in Unit::DealDamage : pVictim->AddThreat(this, float(damage), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
m_ThreatManager.addThreat(pVictim, threat, crit, schoolMask, threatSpell);
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell);
where
Unit::ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask)
{
   if (schoolMask == SPELL_SCHOOL_MASK_NONE)
       return threat;

   SpellSchools school = GetFirstSchoolInMask(schoolMask);
   return threat * m_threatModifier[school];
}

So, _if_ 1 threat for 1 damage is correct, then our system should be correct at all ;)

Exceptions should be carefully examined (ie whitedmg without any special talents) - and as far as I see the only place for problems could be m_threatModifier[school]

Link to comment
Share on other sites

In other words using Tonian67 example:

Imagine player A with 12345.678 threat and player B with 12345.000 so for the server A > B, now they are both sent as 12346 so for the client A = B which is wrong due to the loss of precision by the uint32 conversion.

Also, as the screenshot suggests, on offy OMEN should show 1234568 and not 12346.

Why does Omen should show 1234568 ? Omen shoud show the real threat, not a real_threat*100 .

Anyway, it's not a 0.1 conversion problem : retail threat is 130 000, whereas private threat is 3 800. The ratio is something like.. 34, and you can see it on others threats :

-51% on retail : 67 200 / 51% on private : 2 000 -> ratio of ~= 34

-20% on retail : 26 200 / 19% on private: 733 -> ratio of ~= 34

Link to comment
Share on other sites

With the release of v3.0, WoW now provides the players with threat values on your target. These values are normalized differently: they are 100x damage done instead of 1-to-1. This is most likely done to optimize for integer calculations, rather than slower floating-point math.
Usually 1 damage does 1 threat so for dps classes TPS matches the DPS like we see on offy's screenshots (from 2k to 6k sounds realistic) while mangos, as you noted, gives just 1/100th of DPS as TPS.

I think the problem is how threath is sent on SMSG_THREATUPDATES messages:

When treath is sent to client with Unit::SendThreathUpdate the value is converted with uint32((*itr)->getThreat()) and the decimal fraction is lost due to truncate while, IMHO, it should be sent as uint32((*itr)->getThreat()*100) so 2 decimal fraction is preserved and thus it will explain the 2 orders of magnitude.

Imagine player A with 12345.678 threat ... on offy OMEN should show 1234568 and not 12346.

Alternatively it's possible to calculate threat as damage*100 rather then damage*1

so also wowwiki confirms what I wrote

Link to comment
Share on other sites

So...should we make a config option like ThreatMultiplier ? Default value 100?

Or a hardcoded define THREAT_MULTIPLIER like


diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h
index 98ff67a..35156b5 100644
--- a/src/game/ThreatManager.h
+++ b/src/game/ThreatManager.h
@@ -34,6 +34,7 @@ class ThreatManager;
struct SpellEntry;

#define THREAT_UPDATE_INTERVAL 1 * IN_MILLISECONDS    // Server should send threat update to client periodically each second
+#define THREAT_MULTIPLIER      100                    // Since 3.0, threat is multiplied by 100 to optimize calculations

//==============================================================
// Class to calculate the real threat based
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 2754e72..12d9f4a 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -922,9 +922,9 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
        if (pVictim->GetTypeId() != TYPEID_PLAYER)
        {
            if(spellProto && IsDamageToThreatSpell(spellProto))
-                pVictim->AddThreat(this, float(damage*2), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
+                pVictim->AddThreat(this, float(damage*2*THREAT_MULTIPLIER), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
            else
-                pVictim->AddThreat(this, float(damage), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
+                pVictim->AddThreat(this, float(damage*THREAT_MULTIPLIER), (cleanDamage && cleanDamage->hitOutCome == MELEE_HIT_CRIT), damageSchoolMask, spellProto);
        }
        else                                                // victim is a player
        {

Link to comment
Share on other sites

Just to make one thing clear, scaling everything with the same factor has no influence on threat mechanics at all.

And since we are calculating with float, multiplying the internal values won't really do anything useful, so as mentioned SendThreatUpdate() would be the more logical place...

Side note: I'm not sure whether the choice of patrick star as avatar influences the way i perceive your posts...

Link to comment
Share on other sites

Yes, I know it has no influence, it's just a proposal. I just thought doing it completely blizzlike would be best : retail multiplies the real threat by 100.

Sending a *100 value would be enough, for sure

My avatar is self-deprecating, just to make people know my posts can be completely wrong (as the last one was wrong obviously). And I like patrick.

I hope I don't totally look like an idiot.

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use