mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Creature: Reworked creature aggro radius calculation (#20615)
* Core/Creatures: rewrote creature aggro radius calculation * Formulas are taken from WoW Wiki
This commit is contained in:
@@ -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());
|
||||
|
||||
return (RetDistance*aggroRate);
|
||||
// Make sure that we wont go over the total range limits
|
||||
if (aggroRadius > maxRadius)
|
||||
aggroRadius = maxRadius;
|
||||
else if (aggroRadius < minRadius)
|
||||
aggroRadius = minRadius;
|
||||
|
||||
return (aggroRadius * aggroRate);
|
||||
}
|
||||
|
||||
void Creature::setDeathState(DeathState s)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user