diff options
| author | Ovah <dreadkiller@gmx.de> | 2017-11-15 21:56:15 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2017-11-15 21:56:15 +0100 |
| commit | ea99801cd6ff687462df4fdbb69c06071dedfcf0 (patch) | |
| tree | d1f16496883338acd7849d5c8878498aa11b2cdd /src/server/game/Entities | |
| parent | 434380c9accc0b3885ac6a5b3d67576b2d35153b (diff) | |
Core/Creature: Reworked creature aggro radius calculation (#20615)
* Core/Creatures: rewrote creature aggro radius calculation
* Formulas are taken from WoW Wiki
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 2686c22d0a0..eccbd596dd1 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1646,40 +1646,44 @@ bool Creature::CheckNoGrayAggroConfig(uint32 playerLevel, uint32 creatureLevel) float Creature::GetAttackDistance(Unit const* player) const { + // WoW Wiki: the minimum radius seems to be 5 yards, while the maximum range is 45 yards + float maxRadius = (45.0f * sWorld->getRate(RATE_CREATURE_AGGRO)); + float minRadius = (5.0f * sWorld->getRate(RATE_CREATURE_AGGRO)); float aggroRate = sWorld->getRate(RATE_CREATURE_AGGRO); - if (aggroRate == 0) - return 0.0f; + uint8 expansionMaxLevel = uint8(GetMaxLevelForExpansion(GetCreatureTemplate()->RequiredExpansion)); + int32 levelDifference = getLevel() - player->getLevel(); - uint32 playerlevel = player->GetLevelForTarget(this); - uint32 creaturelevel = GetLevelForTarget(player); + if (aggroRate == 0.0f) + return 0.0; - int32 leveldif = int32(playerlevel) - int32(creaturelevel); + // The aggro radius for creatures with equal level as the player is 20 yards. + // The combatreach should not get taken into account for the distance so we drop it from the range (see Supremus as expample) + float baseAggroDistance = 20.0f - GetFloatValue(UNIT_FIELD_COMBATREACH); - // "The maximum Aggro Radius has a cap of 25 levels under. Example: A level 30 char has the same Aggro Radius of a level 5 char on a level 60 mob." - if (leveldif < - 25) - leveldif = -25; + // + - 1 yard for each level difference between player and creature + float aggroRadius = baseAggroDistance + float(levelDifference); - // "The aggro radius of a mob having the same level as the player is roughly 20 yards" - float RetDistance = 20; - - // "Aggro Radius varies with level difference at a rate of roughly 1 yard/level" - // radius grow if playlevel < creaturelevel - RetDistance -= (float)leveldif; - - if (creaturelevel+5 <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) + // detect range auras + if (float(getLevel() + 5) <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { - // detect range auras - RetDistance += GetTotalAuraModifier(SPELL_AURA_MOD_DETECT_RANGE); + aggroRadius += GetTotalAuraModifier(SPELL_AURA_MOD_DETECT_RANGE); - // detected range auras - RetDistance += player->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE); + aggroRadius += GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE); } - // "Minimum Aggro Radius for a mob seems to be combat range (5 yards)" - if (RetDistance < 5) - RetDistance = 5; + // The aggro range of creatures with higher levels than the total player level for the expansion should get the maxlevel treatment + // This makes sure that creatures such as bosses wont have a bigger aggro range than the rest of the npc's + // The following code is used for blizzlike behaivior such as skipable bosses (e.g. Commander Springvale at level 85) + if (getLevel() > expansionMaxLevel) + aggroRadius = baseAggroDistance + float(expansionMaxLevel - player->getLevel()); + + // Make sure that we wont go over the total range limits + if (aggroRadius > maxRadius) + aggroRadius = maxRadius; + else if (aggroRadius < minRadius) + aggroRadius = minRadius; - return (RetDistance*aggroRate); + return (aggroRadius * aggroRate); } void Creature::setDeathState(DeathState s) |
