Looking4Group / L4G_Core

Looking4Group Core
http://looking4group.eu
GNU General Public License v2.0
37 stars 73 forks source link

Stealth Detection Calculation #3245

Open AnonXS opened 7 years ago

AnonXS commented 7 years ago

Stealth and Stealth Detection is not calculated right.

It might be that stealth is not the main problem but https://github.com/Looking4Group/L4G_Core/issues/470.


Xadras Initial Answer (Sorry for German will translate it at some point):

Test on Level 70 NPC:

Test on Level 62 NPC:


Wobei es sehr darauf ankommt, dass man wirklich exakt von vorne/hinten heranschleicht, da jede Abweichung auch Änderungen in der Entdeckungsreichweite hat.

Wenn man sich dazu nun den Code für die Stealth Detection anschaut, sieht man dass die testergebnise ziemlich stimmig sind: (ich hab versucht das so zu kommentieren, dass es einigermaßen verständlich wird)

bool Unit::canDetectStealthOf(Unit const* target, WorldObject const* viewPoint, float distance) const
{
    if (hasUnitState(UNIT_STAT_STUNNED)) //Ein gestunnter NPC kann kein Stealth entdecken
        return false;

    if (distance < 0.24f) //collision - Immer wenn jmd. näher ist als 0,24yards wird er entdeckt, sofern der Mob nicht im Stun ist
        return true;

    if (!viewPoint->HasInArc(M_PI, target)) //behind - Wenn man sich hinter monstern befindet und nicht näher als 0,24yards ist wird man nicht entdeckt
        return false;

    if (HasAuraType(SPELL_AURA_DETECT_STEALTH)) //Sofern der NPC eine Aura zum aufspüren von stealth hat wird man entdeckt
        return true;

    AuraList const& auras = target->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
    for (AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
        if ((*iter)->GetCasterGUID() == GetGUID()) //Sofern das ziel des NPCs von dem Mal des Jägers betroffen ist, wird es entdeckt
            return true;

    //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5)
    float visibleDistance = 7.5f; //vgl. wowwiki link siehe unten
    //Visible distance is modified by -Level Diff (every level diff = 1.0f in visible distance)
    visibleDistance += float(getLevelForTarget(target)) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/5.0f;
    //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
    //based on wowwiki every 5 mod we have 1 more level diff in calculation
    visibleDistance += (float)(GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DETECT, 0) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL)) / 5.0f;
    visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance;

    return distance < visibleDistance; //wenn also der Spieler nun näher (distance) an dem mob ist, als es die visibleDistance erlaubt wird er entdeckt
}

http://www.wowwiki.com/Stealth_%28mechanic%29?oldid=1512438

Entsprechend meiner Tests und dessen würde ich derzeit von keinem Bug ausgehen.

Mir ist jedoch aufgefallen, dass es bei "kleinere" NPCs so aussieht, als wäre man noch viel weiter weg als man in Wirklichkeit ist. Beispielsweise waren bei einem fetten Stork die Distance Werte auch mit dem visuellen sehr übereinstimmend. Bei einem normalen Ork sah es allerdings so aus, als wäre ich noch recht weit entfernt, als ich entdeckt wurde, jedoch hat die ausgegebene distance (.distance) vollkommen gepasst.

Sämtliche Tests wurden ohne Skillung gemacht, damit es nicht zu verfälschungen kommen kann.

AnonXS commented 7 years ago

AnonXS Initial Answer (Sorry for German will translate it at some point):

wiki: Detection is an innate skill that all players and mobs have, and this increases by 5 points per level. Question? Level 1: 5 Detection Value(MOD), Level 60: 300MOD and Level 70: 350MOD.


What a Stealth Detect Update should do:


// https://github.com/Looking4Group/L4G_Core/blob/89d91e3f4028924be699c1f7c44e629da84275f9/src/game/Player.cpp#L1396

    //Handle detect stealth players
    if (m_DetectInvTimer > 0)
    {
        if (update_diff >= m_DetectInvTimer)
        {
            HandleStealthedUnitsDetection();
            m_DetectInvTimer = InArena() ? 500 : 1500;
        }
        else
            m_DetectInvTimer -= update_diff;
}

bool Unit::canDetectStealthOf(Unit const* target, WorldObject const* viewPoint, float distance) const
{
    if (hasUnitState(UNIT_STAT_STUNNED) || hasUnitState(UNIT_STAT_CONFUSED)) // A stunned/confused npc cant detect stealth. -> This is not enough as some playerskills blind/charm are no stuns. add UNIT_STAT_CONFUSED+UNIT_STAT_POSSESSED (not needed as the npc is friendly then)
        return false;

    if (distance < 0.24f) // If a unit has less then 0.24yards distance it will be discovered if npc is not stunned/confused
        return true;

    if (!HasInArc(float(M_PI), target)) // If a unit is behind the target it will not be discovered unless it moves into above distance
        return false;

    if (HasAuraType(SPELL_AURA_DETECT_STEALTH)) // If a npc has an aura like 18950 it will discover the unit distance < aggro range
        return true;

    AuraList const& auras = target->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
    for (AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
        if ((*iter)->GetCasterGUID() == GetGUID()) // If the unit has Hunter's Mark it will be discovered
            return true;

    //Visible distance based on stealth value (stealth rank 4 300MOD)
    float visibleDistance = 9.25f;  // statt 7.5f ~ +1-2yard player hitbox added to range
    //Visible distance is modified by -Level Diff (every level diff = 1.0f in visible distance)
    visibleDistance += float(getLevelForTarget(target)) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/5.0f;
    //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
    //based on wowwiki every 5 mod we have 1 more level diff in calculation
    visibleDistance += (float)(GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DETECT, 0) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL)) / 5.0f;
    visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance;

    return distance < visibleDistance; // if the unit's distance towards npc is less then calculated visibleDistance it is discovered
}

Sources:

http://www.wowwiki.com/Stealth, http://wow.gamepedia.com/Stealth

http://www.wowhead.com/spell=1784/stealth#comments

http://db.hellfire-tbc.com/?spell=13973 15 MOD, http://db.hellfire-tbc.com/?spell=1787 300 MOD

http://wowwiki.wikia.com/wiki/Stealth_(mechanic)?oldid=1512438


https://github.com/mangosfour/server/blob/master/src/game/Unit.cpp#L8694

https://www.youtube.com/watch?v=eJWNMCD8SMU&feature=youtu.be&t=6m

https://github.com/TrinityCore/TrinityCore/issues/1768

https://github.com/TrinityCore/TrinityCore/issues/452

https://github.com/TrinityCore/TrinityCore/pull/14974

https://bitbucket.org/Xadras/tbcpvp/commits/05983469d8d04682df3975fb5f77373e619783f7

https://bitbucket.org/Caboon/playcore-official/commits/f0713717d1421e46996accba71b786e91fe58d1e

https://github.com/TrinityCore/TrinityCore/commit/43910434c5eb2240dc4b4585ccbb5f95fa399d53

INTERACTION_DISTANCE https://github.com/Looking4Group/L4G_Core/blob/57fa1ba630e7a6c2fb45b25183b542bb0f1cf41b/src/game/SharedDefines.h#L2550

https://github.com/netherspite/cc-buglist/issues/1165 - research


https://code.google.com/p/trinitycore/issues/detail?id=2384


Wrath but logic:

if (!HasInArc(M_PI, target)) //behind
    visibleDistance /= 4; 

the reason i've divided by 4 and not 3 the behind detection it's because a stealthed rogue will not be able to use pick pocket on targets of it's level unless it has improved stealth. [pick pocket distance = 2 yards] and 6.5/3 = 2.16.. so 6.5/4=1.625

Remember that stealth worked corectly up to 2.4.3. The only thing changed since is that Stealth went from Rank 1(100MOD),Rank 2(200MOD),Rank 3(300MOD) to a no-rank constant 400MOD [this made almost all rogues/druids imposible to spot with no stealth updates]. An that's what we are doing here..

6.5 yards is the maximum distance two untalented rogues can see each other. [Wrath] (7.5y in TBC maybe)

Also the detection range is not a constant 2π radius as you might think, but π for 100% range and -π for a 25% [here you might need more different values for π,π/3 and π/6 angles though. I've attached the second pict with a basic concept]

The main problem is that we are talking about two completly different things. If you want to make a patch about a 'chance' of looking at a stealthed rogue, turning around and than looking again in the same spot to see the rogue is gone even though he hasn't moved.. than be my guest.

But you must accept the fact that at the moment the basic Stealth formulas are broken, which is the thing i'm trying to discuss over here.