aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Creature
diff options
context:
space:
mode:
authorModoX <moardox@gmail.com>2024-12-29 09:04:40 +0100
committerGitHub <noreply@github.com>2024-12-29 09:04:40 +0100
commit26d1337461114506ca57e2265d3dc5e96fd08f82 (patch)
tree4f0d9a7fe7ad793d25c58dff188df8750ddafc0c /src/server/game/Entities/Creature
parentd913e38cbab9521c80d826417093d22b2c4a1c1a (diff)
Core/Creature: Implement aggro grace period (#30362)
Ref: #26528 #30273 #23258
Diffstat (limited to 'src/server/game/Entities/Creature')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp15
-rw-r--r--src/server/game/Entities/Creature/Creature.h4
2 files changed, 18 insertions, 1 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 0a5c0c88612..466ddec3800 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -315,7 +315,7 @@ Creature::Creature(bool isWorldObject) : Unit(isWorldObject), MapObject(), m_Pla
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_cannotReachTarget(false), m_cannotReachTimer(0),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(),
m_creatureInfo(nullptr), m_creatureData(nullptr), m_creatureDifficulty(nullptr), m_stringIds(), _waypointPathId(0), _currentWaypointNodeInfo(0, 0),
- m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _lastDamagedTime(0),
+ m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _aggroGracePeriodExpired(false), _lastDamagedTime(0),
_regenerateHealth(true), _creatureImmunitiesId(0), _gossipMenuId(0), _sparringHealthPct(0)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
@@ -929,6 +929,16 @@ void Creature::Heartbeat()
// Creatures with CREATURE_STATIC_FLAG_2_FORCE_PARTY_MEMBERS_INTO_COMBAT periodically force party members into combat
ForcePartyMembersIntoCombat();
+
+ // creatures should only attack surroundings initially after heartbeat has passed or until attacked
+ if (!_aggroGracePeriodExpired)
+ {
+ _aggroGracePeriodExpired = true;
+
+ // trigger MoveInLineOfSight
+ Trinity::CreatureAggroGracePeriodExpiredNotifier notifier(*this);
+ Cell::VisitAllObjects(this, notifier, GetVisibilityRange());
+ }
}
void Creature::Regenerate(Powers power)
@@ -2335,6 +2345,7 @@ void Creature::Respawn(bool force)
ai->Reset();
m_triggerJustAppeared = true;
+ _aggroGracePeriodExpired = false;
uint32 poolid = GetCreatureData() ? GetCreatureData()->poolId : 0;
if (poolid)
@@ -3672,6 +3683,8 @@ void Creature::AtEngage(Unit* target)
{
Unit::AtEngage(target);
+ _aggroGracePeriodExpired = true;
+
GetThreatManager().ResetUpdateTimer();
if (!HasFlag(CREATURE_STATIC_FLAG_2_ALLOW_MOUNTED_COMBAT))
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index a7f6113aab6..7bf4560e4e4 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -455,6 +455,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void SetNoThreatFeedback(bool noThreatFeedback) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_3_NO_THREAT_FEEDBACK, noThreatFeedback); }
void ForcePartyMembersIntoCombat();
+ bool IsAggroGracePeriodExpired() { return _aggroGracePeriodExpired; }
+
void OverrideSparringHealthPct(float healthPct) { _sparringHealthPct = healthPct; }
void OverrideSparringHealthPct(std::vector<float> const& healthPct);
float GetSparringHealthPct() const { return _sparringHealthPct; }
@@ -579,6 +581,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
bool m_triggerJustAppeared;
bool m_respawnCompatibilityMode;
+ bool _aggroGracePeriodExpired;
+
/* Spell focus system */
void ReacquireSpellFocusTarget();
struct