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 | |
parent | 434380c9accc0b3885ac6a5b3d67576b2d35153b (diff) |
Core/Creature: Reworked creature aggro radius calculation (#20615)
* Core/Creatures: rewrote creature aggro radius calculation
* Formulas are taken from WoW Wiki
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 52 | ||||
-rw-r--r-- | src/server/game/Handlers/ReferAFriendHandler.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 24 |
3 files changed, 52 insertions, 48 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) diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index 5c12bd4d550..707504e1a5e 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -22,30 +22,6 @@ #include "ReferAFriendPackets.h" #include "World.h" -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; - case EXPANSION_CATACLYSM: - return 85; - case EXPANSION_MISTS_OF_PANDARIA: - return 90; - case EXPANSION_WARLORDS_OF_DRAENOR: - return 100; - case EXPANSION_LEGION: - return 110; - default: - break; - } - return 0; -} - void WorldSession::HandleGrantLevel(WorldPackets::RaF::GrantLevel& grantLevel) { Player* target = ObjectAccessor::GetPlayer(*_player, grantLevel.Target); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 4f239fa6e61..105735b1ffd 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -90,6 +90,30 @@ enum Expansions #define CURRENT_EXPANSION EXPANSION_LEGION +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; + case EXPANSION_CATACLYSM: + return 85; + case EXPANSION_MISTS_OF_PANDARIA: + return 90; + case EXPANSION_WARLORDS_OF_DRAENOR: + return 100; + case EXPANSION_LEGION: + return 110; + default: + break; + } + return 0; +} + enum Gender { GENDER_UNKNOWN = -1, |