feat(Core/Creatures): extend mob leash mechanic assist in-combat creatures (#4897)

This commit is contained in:
UltraNix
2021-04-05 15:35:29 +02:00
committed by GitHub
parent f9d708b450
commit fdc29c7a02
2 changed files with 50 additions and 10 deletions

View File

@@ -128,19 +128,24 @@ void CreatureTemplate::InitializeQueryData()
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())
{
Creature* assistant = ObjectAccessor::GetCreature(m_owner, *m_assistants.begin());
Creature* assistant = ObjectAccessor::GetCreature(*m_owner, *m_assistants.begin());
m_assistants.pop_front();
if (assistant && assistant->CanAssistTo(&m_owner, victim))
if (assistant && assistant->CanAssistTo(m_owner, victim))
{
assistant->SetNoCallAssistance(true);
assistant->CombatStart(victim);
if (assistant->IsAIEnabled)
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_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_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)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
@@ -1666,6 +1671,8 @@ void Creature::setDeathState(DeathState s, bool despawn)
if (s == JUST_DIED)
{
_lastDamagedTime.reset();
m_corpseRemoveTime = time(nullptr) + m_corpseDelay;
m_respawnTime = time(nullptr) + m_respawnDelay + m_corpseDelay;
@@ -2098,7 +2105,7 @@ void Creature::CallAssistance()
if (!assistList.empty())
{
AssistDelayEvent* e = new AssistDelayEvent(GetVictim()->GetGUID(), *this);
AssistDelayEvent* e = new AssistDelayEvent(GetVictim()->GetGUID(), this);
while (!assistList.empty())
{
// Pushing guids because in delay can happen some creature gets despawned => invalid pointer
@@ -3152,3 +3159,34 @@ void Creature::SetCannotReachTarget(bool cannotReach)
if (cannotReach)
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;
}

View File

@@ -739,8 +739,10 @@ public:
bool IsMovementPreventedByCasting() const;
// Part of Evade mechanics
[[nodiscard]] time_t GetLastDamagedTime() const { return _lastDamagedTime; }
void SetLastDamagedTime(time_t val) { _lastDamagedTime = val; }
[[nodiscard]] time_t GetLastDamagedTime() const;
[[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();
static constexpr uint32 MOVE_CIRCLE_CHECK_INTERVAL = 3000;
@@ -821,7 +823,7 @@ private:
CreatureGroup* m_formation;
bool TriggerJustRespawned;
time_t _lastDamagedTime; // Part of Evade mechanics
mutable std::shared_ptr<time_t> _lastDamagedTime; // Part of Evade mechanics
bool m_cannotReachTarget;
uint32 m_cannotReachTimer;
@@ -836,7 +838,7 @@ private:
class AssistDelayEvent : public BasicEvent
{
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;
void AddAssistant(uint64 guid) { m_assistants.push_back(guid); }
@@ -845,7 +847,7 @@ private:
uint64 m_victim;
std::list<uint64> m_assistants;
Unit& m_owner;
Creature* m_owner;
};
class ForcedDespawnDelayEvent : public BasicEvent