diff options
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 48 | ||||
-rw-r--r-- | src/server/shared/SharedDefines.h | 16 |
2 files changed, 42 insertions, 22 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index dce1df66980..891c451133b 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1853,36 +1853,40 @@ float Creature::GetAttackDistance(Unit const* player) const if (aggroRate == 0) return 0.0f; - uint32 playerlevel = player->GetLevelForTarget(this); - uint32 creaturelevel = GetLevelForTarget(player); + // 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)); - int32 leveldif = int32(playerlevel) - int32(creaturelevel); + uint8 expansionMaxLevel = uint8(GetMaxLevelForExpansion(GetCreatureTemplate()->expansion)); + int32 levelDifference = GetLevel() - player->GetLevel(); - // "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; + // 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 aggro radius of a mob having the same level as the player is roughly 20 yards" - float RetDistance = 20; + // + - 1 yard for each level difference between player and creature + float aggroRadius = baseAggroDistance + float(levelDifference); - // "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); - - // detected range auras - RetDistance += player->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE); + aggroRadius += GetTotalAuraModifier(SPELL_AURA_MOD_DETECT_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 skippable bosses + 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) diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 19e01ba1865..2f58a29e08f 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -55,6 +55,22 @@ enum Expansions MAX_EXPANSIONS = 3 }; +inline uint32 GetMaxLevelForExpansion(uint32 expansion) +{ + switch (expansion) + { + case EXPANSION_CLASSIC: + return 60; + case EXPANSION_THE_BURNING_CRUSADE: + return 70; + case EXPANSION_WRATH_OF_THE_LICH_KING: + return 80; + default: + break; + } + return 0; +} + enum Gender { GENDER_MALE = 0, |