mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 14:46:24 +00:00
feat(Core): port aggro distance from vMaNGOS (#6214)
Read detection_range values from creature_template
This commit is contained in:
@@ -168,7 +168,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(),
|
||||
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
|
||||
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_originalAnimTier(UNIT_BYTE1_FLAG_GROUND), m_AlreadyCallAssistance(false),
|
||||
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
|
||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTarget(false), m_cannotReachTimer(0),
|
||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTarget(false), m_cannotReachTimer(0),
|
||||
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0)
|
||||
{
|
||||
m_regenTimer = CREATURE_REGEN_INTERVAL;
|
||||
@@ -521,6 +521,8 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
|
||||
|
||||
UpdateEnvironmentIfNeeded(3);
|
||||
|
||||
SetDetectionDistance(cInfo->detection_range);
|
||||
|
||||
LoadSpellTemplateImmunity();
|
||||
return true;
|
||||
}
|
||||
@@ -617,7 +619,7 @@ void Creature::Update(uint32 diff)
|
||||
}
|
||||
|
||||
Unit* owner = GetCharmerOrOwner();
|
||||
if (IsCharmed() && !IsWithinDistInMap(owner, GetMap()->GetVisibilityRange()))
|
||||
if (IsCharmed() && !IsWithinDistInMap(owner, GetMap()->GetVisibilityRange(), true, false))
|
||||
{
|
||||
RemoveCharmAuras();
|
||||
}
|
||||
@@ -1710,7 +1712,7 @@ bool Creature::CanStartAttack(Unit const* who) const
|
||||
assist = true;
|
||||
|
||||
if (!assist)
|
||||
if (IsNeutralToAll() || !IsWithinDistInMap(who, GetAggroRange(who) + m_CombatDistance)) // pussywizard: +m_combatDistance for turrets and similar
|
||||
if (IsNeutralToAll() || !IsWithinDistInMap(who, GetAggroRange(who) + m_CombatDistance, true, false)) // pussywizard: +m_combatDistance for turrets and similar
|
||||
return false;
|
||||
|
||||
if (!CanCreatureAttack(who))
|
||||
@@ -2978,17 +2980,20 @@ float Creature::GetAggroRange(Unit const* target) const
|
||||
if (aggroRate == 0)
|
||||
return 0.0f;
|
||||
|
||||
uint32 targetLevel = target->getLevelForTarget(this);
|
||||
uint32 myLevel = getLevelForTarget(target);
|
||||
int32 levelDiff = int32(targetLevel) - int32(myLevel);
|
||||
auto creatureLevel = target->getLevelForTarget(this);
|
||||
auto playerLevel = getLevelForTarget(target);
|
||||
int32 levelDiff = int32(creatureLevel) - int32(playerLevel);
|
||||
|
||||
// The maximum Aggro Radius is capped at 45 yards (25 level difference)
|
||||
if (levelDiff < -25)
|
||||
levelDiff = -25;
|
||||
|
||||
// The base aggro radius for mob of same level
|
||||
float aggroRadius = 20.0f;
|
||||
|
||||
auto aggroRadius = GetDetectionRange();
|
||||
if (aggroRadius < 1)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
// Aggro Radius varies with level difference at a rate of roughly 1 yard/level
|
||||
aggroRadius -= (float)levelDiff;
|
||||
|
||||
|
||||
@@ -176,6 +176,7 @@ public:
|
||||
|
||||
[[nodiscard]] CreatureTemplate const* GetCreatureTemplate() const { return m_creatureInfo; }
|
||||
[[nodiscard]] CreatureData const* GetCreatureData() const { return m_creatureData; }
|
||||
void SetDetectionDistance(float dist){ m_detectionDistance = dist; }
|
||||
[[nodiscard]] CreatureAddon const* GetCreatureAddon() const;
|
||||
|
||||
[[nodiscard]] std::string GetAIName() const;
|
||||
@@ -224,6 +225,7 @@ public:
|
||||
bool CanStartAttack(Unit const* u) const;
|
||||
float GetAggroRange(Unit const* target) const;
|
||||
float GetAttackDistance(Unit const* player) const;
|
||||
[[nodiscard]] float GetDetectionRange() const { return m_detectionDistance; }
|
||||
|
||||
void SendAIReaction(AiReaction reactionType);
|
||||
|
||||
@@ -413,6 +415,7 @@ protected:
|
||||
CreatureTemplate const* m_creatureInfo; // in difficulty mode > 0 can different from sObjectMgr->GetCreatureTemplate(GetEntry())
|
||||
CreatureData const* m_creatureData;
|
||||
|
||||
float m_detectionDistance;
|
||||
uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable
|
||||
|
||||
[[nodiscard]] bool IsInvisibleDueToDespawn() const override;
|
||||
|
||||
@@ -92,6 +92,7 @@ struct CreatureTemplate
|
||||
uint32 npcflag;
|
||||
float speed_walk;
|
||||
float speed_run;
|
||||
float detection_range; // Detection Range for Line of Sight aggro
|
||||
float scale;
|
||||
uint32 rank;
|
||||
uint32 dmgschool;
|
||||
|
||||
@@ -993,7 +993,7 @@ private:
|
||||
void UpdatePackedRotation();
|
||||
|
||||
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
|
||||
bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const override
|
||||
bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/, bool /*useBoundingRadius = true*/) const override
|
||||
{
|
||||
//! Following check does check 3d distance
|
||||
dist2compare += obj->GetObjectSize();
|
||||
|
||||
@@ -1069,9 +1069,9 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const
|
||||
return (dist > 0 ? dist : 0);
|
||||
}
|
||||
|
||||
bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
|
||||
bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool useBoundingRadius) const
|
||||
{
|
||||
float sizefactor = GetObjectSize() + obj->GetObjectSize();
|
||||
float sizefactor = useBoundingRadius ? GetObjectSize() + obj->GetObjectSize() : 0.0f;
|
||||
float maxdist = dist2compare + sizefactor;
|
||||
|
||||
if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUID() == m_transport->GetGUID())
|
||||
|
||||
@@ -870,13 +870,13 @@ public:
|
||||
bool IsWithinDist2d(const Position* pos, float dist) const
|
||||
{ return IsInDist2d(pos, dist + GetObjectSize()); }
|
||||
// use only if you will sure about placing both object at same map
|
||||
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const
|
||||
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true, bool useBoundingRadius = true) const
|
||||
{
|
||||
return obj && _IsWithinDist(obj, dist2compare, is3D);
|
||||
return obj && _IsWithinDist(obj, dist2compare, is3D, useBoundingRadius);
|
||||
}
|
||||
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const
|
||||
bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool useBoundingRadius = true) const
|
||||
{
|
||||
return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D);
|
||||
return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D, useBoundingRadius);
|
||||
}
|
||||
[[nodiscard]] bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS) const;
|
||||
bool IsWithinLOSInMap(WorldObject const* obj, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS) const;
|
||||
@@ -1076,7 +1076,7 @@ private:
|
||||
uint16 m_notifyflags;
|
||||
uint16 m_executed_notifies;
|
||||
|
||||
virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
|
||||
virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool useBoundingRadius = true) const;
|
||||
|
||||
bool CanNeverSee(WorldObject const* obj) const;
|
||||
virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; }
|
||||
|
||||
Reference in New Issue
Block a user