feat(Core/Creatures): extend mob leash mechanic assist in-combat creatures (#4897)
This commit is contained in:
@@ -128,19 +128,24 @@ void CreatureTemplate::InitializeQueryData()
|
|||||||
|
|
||||||
bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||||
{
|
{
|
||||||
if (Unit* victim = ObjectAccessor::GetUnit(m_owner, m_victim))
|
if (Unit* victim = ObjectAccessor::GetUnit(*m_owner, m_victim))
|
||||||
{
|
{
|
||||||
|
// Initialize last damage timer if it doesn't exist
|
||||||
|
m_owner->SetLastDamagedTime(sWorld->GetGameTime() + MAX_AGGRO_RESET_TIME);
|
||||||
|
|
||||||
while (!m_assistants.empty())
|
while (!m_assistants.empty())
|
||||||
{
|
{
|
||||||
Creature* assistant = ObjectAccessor::GetCreature(m_owner, *m_assistants.begin());
|
Creature* assistant = ObjectAccessor::GetCreature(*m_owner, *m_assistants.begin());
|
||||||
m_assistants.pop_front();
|
m_assistants.pop_front();
|
||||||
|
|
||||||
if (assistant && assistant->CanAssistTo(&m_owner, victim))
|
if (assistant && assistant->CanAssistTo(m_owner, victim))
|
||||||
{
|
{
|
||||||
assistant->SetNoCallAssistance(true);
|
assistant->SetNoCallAssistance(true);
|
||||||
assistant->CombatStart(victim);
|
assistant->CombatStart(victim);
|
||||||
if (assistant->IsAIEnabled)
|
if (assistant->IsAIEnabled)
|
||||||
assistant->AI()->AttackStart(victim);
|
assistant->AI()->AttackStart(victim);
|
||||||
|
|
||||||
|
assistant->SetLastDamagedTimePtr(m_owner->GetLastDamagedTimePtr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,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_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
|
||||||
m_DBTableGuid(0), m_equipmentId(0), m_originalEquipmentId(0), m_originalAnimTier(UNIT_BYTE1_FLAG_GROUND), m_AlreadyCallAssistance(false),
|
m_DBTableGuid(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_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(0), m_cannotReachTarget(false), m_cannotReachTimer(0),
|
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),
|
||||||
_isMissingSwimmingFlagOutOfCombat(false)
|
_isMissingSwimmingFlagOutOfCombat(false)
|
||||||
{
|
{
|
||||||
m_regenTimer = CREATURE_REGEN_INTERVAL;
|
m_regenTimer = CREATURE_REGEN_INTERVAL;
|
||||||
@@ -1666,6 +1671,8 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
|||||||
|
|
||||||
if (s == JUST_DIED)
|
if (s == JUST_DIED)
|
||||||
{
|
{
|
||||||
|
_lastDamagedTime.reset();
|
||||||
|
|
||||||
m_corpseRemoveTime = time(nullptr) + m_corpseDelay;
|
m_corpseRemoveTime = time(nullptr) + m_corpseDelay;
|
||||||
m_respawnTime = time(nullptr) + m_respawnDelay + m_corpseDelay;
|
m_respawnTime = time(nullptr) + m_respawnDelay + m_corpseDelay;
|
||||||
|
|
||||||
@@ -2098,7 +2105,7 @@ void Creature::CallAssistance()
|
|||||||
|
|
||||||
if (!assistList.empty())
|
if (!assistList.empty())
|
||||||
{
|
{
|
||||||
AssistDelayEvent* e = new AssistDelayEvent(GetVictim()->GetGUID(), *this);
|
AssistDelayEvent* e = new AssistDelayEvent(GetVictim()->GetGUID(), this);
|
||||||
while (!assistList.empty())
|
while (!assistList.empty())
|
||||||
{
|
{
|
||||||
// Pushing guids because in delay can happen some creature gets despawned => invalid pointer
|
// Pushing guids because in delay can happen some creature gets despawned => invalid pointer
|
||||||
@@ -3152,3 +3159,34 @@ void Creature::SetCannotReachTarget(bool cannotReach)
|
|||||||
if (cannotReach)
|
if (cannotReach)
|
||||||
sLog->outDebug(LOG_FILTER_UNITS, "Creature::SetCannotReachTarget() called with true. Details: %s", GetDebugInfo().c_str());
|
sLog->outDebug(LOG_FILTER_UNITS, "Creature::SetCannotReachTarget() called with true. Details: %s", GetDebugInfo().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t Creature::GetLastDamagedTime() const
|
||||||
|
{
|
||||||
|
if (!_lastDamagedTime)
|
||||||
|
return time_t(0);
|
||||||
|
|
||||||
|
return *_lastDamagedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<time_t> const& Creature::GetLastDamagedTimePtr() const
|
||||||
|
{
|
||||||
|
return _lastDamagedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Creature::SetLastDamagedTime(time_t val)
|
||||||
|
{
|
||||||
|
if (val > 0)
|
||||||
|
{
|
||||||
|
if (_lastDamagedTime)
|
||||||
|
*_lastDamagedTime = val;
|
||||||
|
else
|
||||||
|
_lastDamagedTime = std::make_shared<time_t>(val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_lastDamagedTime.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Creature::SetLastDamagedTimePtr(std::shared_ptr<time_t> const& val)
|
||||||
|
{
|
||||||
|
_lastDamagedTime = val;
|
||||||
|
}
|
||||||
|
|||||||
@@ -739,8 +739,10 @@ public:
|
|||||||
bool IsMovementPreventedByCasting() const;
|
bool IsMovementPreventedByCasting() const;
|
||||||
|
|
||||||
// Part of Evade mechanics
|
// Part of Evade mechanics
|
||||||
[[nodiscard]] time_t GetLastDamagedTime() const { return _lastDamagedTime; }
|
[[nodiscard]] time_t GetLastDamagedTime() const;
|
||||||
void SetLastDamagedTime(time_t val) { _lastDamagedTime = val; }
|
[[nodiscard]] std::shared_ptr<time_t> const& GetLastDamagedTimePtr() const;
|
||||||
|
void SetLastDamagedTime(time_t val);
|
||||||
|
void SetLastDamagedTimePtr(std::shared_ptr<time_t> const& val);
|
||||||
|
|
||||||
bool IsFreeToMove();
|
bool IsFreeToMove();
|
||||||
static constexpr uint32 MOVE_CIRCLE_CHECK_INTERVAL = 3000;
|
static constexpr uint32 MOVE_CIRCLE_CHECK_INTERVAL = 3000;
|
||||||
@@ -821,7 +823,7 @@ private:
|
|||||||
CreatureGroup* m_formation;
|
CreatureGroup* m_formation;
|
||||||
bool TriggerJustRespawned;
|
bool TriggerJustRespawned;
|
||||||
|
|
||||||
time_t _lastDamagedTime; // Part of Evade mechanics
|
mutable std::shared_ptr<time_t> _lastDamagedTime; // Part of Evade mechanics
|
||||||
|
|
||||||
bool m_cannotReachTarget;
|
bool m_cannotReachTarget;
|
||||||
uint32 m_cannotReachTimer;
|
uint32 m_cannotReachTimer;
|
||||||
@@ -836,7 +838,7 @@ private:
|
|||||||
class AssistDelayEvent : public BasicEvent
|
class AssistDelayEvent : public BasicEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AssistDelayEvent(uint64 victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { }
|
AssistDelayEvent(uint64 victim, Creature* owner) : BasicEvent(), m_victim(victim), m_owner(owner) { }
|
||||||
|
|
||||||
bool Execute(uint64 e_time, uint32 p_time) override;
|
bool Execute(uint64 e_time, uint32 p_time) override;
|
||||||
void AddAssistant(uint64 guid) { m_assistants.push_back(guid); }
|
void AddAssistant(uint64 guid) { m_assistants.push_back(guid); }
|
||||||
@@ -845,7 +847,7 @@ private:
|
|||||||
|
|
||||||
uint64 m_victim;
|
uint64 m_victim;
|
||||||
std::list<uint64> m_assistants;
|
std::list<uint64> m_assistants;
|
||||||
Unit& m_owner;
|
Creature* m_owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ForcedDespawnDelayEvent : public BasicEvent
|
class ForcedDespawnDelayEvent : public BasicEvent
|
||||||
|
|||||||
Reference in New Issue
Block a user