mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Creature: Implement aggro grace period (#30362)
Ref: #26528 #30273 #23258
This commit is contained in:
@@ -124,7 +124,7 @@ void CreatureAI::MoveInLineOfSight(Unit* who)
|
||||
if (me->IsEngaged())
|
||||
return;
|
||||
|
||||
if (me->HasReactState(REACT_AGGRESSIVE) && me->CanStartAttack(who, false))
|
||||
if (me->HasReactState(REACT_AGGRESSIVE) && me->CanStartAttack(who, false) && (me->IsAggroGracePeriodExpired() || me->GetMap()->Instanceable()))
|
||||
me->EngageWithTarget(who);
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -242,6 +242,25 @@ void AIRelocationNotifier::Visit(CreatureMapType &m)
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureAggroGracePeriodExpiredNotifier::Visit(CreatureMapType& m)
|
||||
{
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Creature* c = iter->GetSource();
|
||||
CreatureUnitRelocationWorker(c, &i_creature);
|
||||
CreatureUnitRelocationWorker(&i_creature, c);
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureAggroGracePeriodExpiredNotifier::Visit(PlayerMapType& m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* player = iter->GetSource();
|
||||
CreatureUnitRelocationWorker(&i_creature, player);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
MessageDistDeliverer::VisitObject(Player* player)
|
||||
|
||||
@@ -108,6 +108,15 @@ namespace Trinity
|
||||
void Visit(CreatureMapType &);
|
||||
};
|
||||
|
||||
struct TC_GAME_API CreatureAggroGracePeriodExpiredNotifier
|
||||
{
|
||||
Creature& i_creature;
|
||||
CreatureAggroGracePeriodExpiredNotifier(Creature& c) : i_creature(c) { }
|
||||
template<class T> void Visit(GridRefManager<T>&) { }
|
||||
void Visit(CreatureMapType&);
|
||||
void Visit(PlayerMapType&);
|
||||
};
|
||||
|
||||
struct GridUpdater
|
||||
{
|
||||
GridType &i_grid;
|
||||
|
||||
Reference in New Issue
Block a user