mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 13:16:23 +00:00
fix(Core/Leash): Improve leashing behavior and timer handling (#22525)
This commit is contained in:
committed by
GitHub
parent
40c58123b1
commit
67aa022dbf
@@ -801,7 +801,7 @@ void Creature::Update(uint32 diff)
|
||||
// Periodically check if able to move, if not, extend leash timer
|
||||
if (diff >= m_extendLeashTime)
|
||||
{
|
||||
if (!CanFreeMove())
|
||||
if (HasUnitState(UNIT_STATE_LOST_CONTROL))
|
||||
UpdateLeashExtensionTime();
|
||||
m_extendLeashTime = EXTEND_LEASH_CHECK_INTERVAL;
|
||||
}
|
||||
@@ -2685,10 +2685,11 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const
|
||||
|
||||
float dist = sWorld->getFloatConfig(CONFIG_CREATURE_LEASH_RADIUS);
|
||||
|
||||
if (GetCharmerOrOwner())
|
||||
if (Unit* unit = GetCharmerOrOwner())
|
||||
{
|
||||
dist = std::min<float>(GetMap()->GetVisibilityRange() + GetObjectSize() * 2, 150.0f);
|
||||
return IsWithinDist(victim, dist);
|
||||
float visibilityDist = std::min<float>(GetMap()->GetVisibilityRange() + GetObjectSize() * 2, 150.0f);
|
||||
if (!victim->IsWithinDist(unit, visibilityDist))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dist)
|
||||
|
||||
@@ -4185,6 +4185,15 @@ void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id, bool withI
|
||||
InterruptSpell(CURRENT_CHANNELED_SPELL, true, true, bySelf);
|
||||
}
|
||||
|
||||
Spell* Unit::GetFirstCurrentCastingSpell() const
|
||||
{
|
||||
for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
|
||||
if (m_currentSpells[i] && m_currentSpells[i]->GetCastTimeRemaining() > 0)
|
||||
return m_currentSpells[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
|
||||
{
|
||||
for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
|
||||
@@ -10412,8 +10421,29 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
|
||||
if (meleeAttack)
|
||||
AddUnitState(UNIT_STATE_MELEE_ATTACKING);
|
||||
|
||||
Unit* owner = GetCharmerOrOwner();
|
||||
Creature* ownerCreature = owner ? owner->ToCreature() : nullptr;
|
||||
Creature* controlledCreatureWithSameVictim = nullptr;
|
||||
if (creature && !m_Controlled.empty())
|
||||
{
|
||||
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->ToCreature() && (*itr)->GetVictim() == victim)
|
||||
{
|
||||
controlledCreatureWithSameVictim = (*itr)->ToCreature();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Share leash timer with controlled unit
|
||||
if (controlledCreatureWithSameVictim)
|
||||
creature->SetLastLeashExtensionTimePtr(controlledCreatureWithSameVictim->GetLastLeashExtensionTimePtr());
|
||||
// Share leash timer with owner
|
||||
else if (creature && ownerCreature && ownerCreature->GetVictim() == victim)
|
||||
creature->SetLastLeashExtensionTimePtr(ownerCreature->GetLastLeashExtensionTimePtr());
|
||||
// Update leash timer when attacking creatures
|
||||
if (victim->IsCreature())
|
||||
else if (victim->IsCreature())
|
||||
victim->ToCreature()->UpdateLeashExtensionTime();
|
||||
|
||||
// set position before any AI calls/assistance
|
||||
|
||||
@@ -1494,6 +1494,7 @@ public:
|
||||
[[nodiscard]] Player* GetSpellModOwner() const;
|
||||
[[nodiscard]] Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
|
||||
[[nodiscard]] Spell* GetCurrentSpell(uint32 spellType) const { return m_currentSpells[spellType]; }
|
||||
[[nodiscard]] Spell* GetFirstCurrentCastingSpell() const;
|
||||
[[nodiscard]] Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
|
||||
[[nodiscard]] int32 GetCurrentSpellCastTime(uint32 spell_id) const;
|
||||
|
||||
|
||||
@@ -72,15 +72,27 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
||||
return false;
|
||||
|
||||
Creature* cOwner = owner->ToCreature();
|
||||
bool isStoppedBecauseOfCasting = cOwner && cOwner->IsMovementPreventedByCasting();
|
||||
|
||||
// the owner might be unable to move (rooted or casting), or we have lost the target, pause movement
|
||||
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || HasLostTarget(owner) || (cOwner && cOwner->IsMovementPreventedByCasting()))
|
||||
if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || HasLostTarget(owner) || isStoppedBecauseOfCasting)
|
||||
{
|
||||
owner->StopMoving();
|
||||
_lastTargetPosition.reset();
|
||||
if (cOwner)
|
||||
{
|
||||
cOwner->UpdateLeashExtensionTime();
|
||||
if (isStoppedBecauseOfCasting)
|
||||
{
|
||||
// Don't reset leash timer if it's a spell like Shoot with a short cast time.
|
||||
/// @todo: Research how it should actually work.
|
||||
Spell *spell = cOwner->GetFirstCurrentCastingSpell();
|
||||
bool spellHasLongCast = spell && spell->GetCastTime() > 1 * SECOND * IN_MILLISECONDS;
|
||||
if (spellHasLongCast)
|
||||
cOwner->UpdateLeashExtensionTime();
|
||||
}
|
||||
else
|
||||
cOwner->UpdateLeashExtensionTime();
|
||||
|
||||
cOwner->SetCannotReachTarget();
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user