Core/Spells:

* fixed releasing spell focus when a creature enters evade mode while focusing a target
* allow the focus handling to accept self cast spells
* fixed an issue that was prevent channeled spells without a cast time being rejected for focusing
* channeled spells will now always have a focus target
* target less casts will now trigger focusing as well
This commit is contained in:
Ovahlord
2019-08-11 13:57:55 +02:00
parent 148291729f
commit 4ba820d5dc
4 changed files with 23 additions and 13 deletions

View File

@@ -279,6 +279,7 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
me->SetLastDamagedTime(0);
me->SetCannotReachTarget(false);
me->DoNotReacquireSpellFocusTarget();
me->SetTarget(ObjectGuid::Empty);
if (me->IsInEvadeMode())
return false;

View File

@@ -2951,11 +2951,11 @@ void Creature::SetTarget(ObjectGuid guid)
void Creature::SetSpellFocus(Spell const* focusSpell, WorldObject const* target)
{
// already focused
if (_spellFocusInfo.spell)
// Pointer validation and checking for a already existing focus
if (_spellFocusInfo.spell || !focusSpell)
return;
// Prevent dead/feigning death creatures from setting a focus target, so they won't turn
// Prevent dead / feign death creatures from setting a focus target
if (!IsAlive() || HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH) || HasAuraType(SPELL_AURA_FEIGN_DEATH))
return;
@@ -2973,7 +2973,8 @@ void Creature::SetSpellFocus(Spell const* focusSpell, WorldObject const* target)
if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
return;
if ((!target || target == this) && !focusSpell->GetCastTime()) // instant cast, untargeted (or self-targeted) spell doesn't need any facing updates
// instant non-channeled casts and non-target spells don't need facing updates
if (!target && (!focusSpell->GetCastTime() && !spellInfo->IsChanneled()))
return;
// store pre-cast values for target and orientation (used to later restore)
@@ -3072,12 +3073,11 @@ void Creature::ReleaseSpellFocus(Spell const* focusSpell, bool withDelay)
void Creature::ReacquireSpellFocusTarget()
{
if (!HasSpellFocus())
return;
ASSERT(HasSpellFocus());
SetTarget(_spellFocusInfo.target);
SetGuidValue(UNIT_FIELD_TARGET, _spellFocusInfo.target);
if (!HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISABLE_TURN) && !IsMovementPreventedByCasting())
if (!HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISABLE_TURN))
{
if (_spellFocusInfo.target)
{
@@ -3090,6 +3090,12 @@ void Creature::ReacquireSpellFocusTarget()
_spellFocusInfo.delay = 0;
}
void Creature::DoNotReacquireSpellFocusTarget()
{
_spellFocusInfo.delay = 0;
_spellFocusInfo.spell = nullptr;
}
bool Creature::IsMovementPreventedByCasting() const
{
// first check if currently a movement allowed channel is active and we're not casting

View File

@@ -328,7 +328,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
// Handling caster facing during spellcast
void SetTarget(ObjectGuid guid) override;
void ReacquireSpellFocusTarget();
void DoNotReacquireSpellFocusTarget() { _spellFocusInfo.delay = 0; }
void DoNotReacquireSpellFocusTarget();
void SetSpellFocus(Spell const* focusSpell, WorldObject const* target);
bool HasSpellFocus(Spell const* focusSpell = nullptr) const override;
void ReleaseSpellFocus(Spell const* focusSpell = nullptr, bool withDelay = true);

View File

@@ -4679,6 +4679,10 @@ void Spell::SendChannelStart(uint32 duration)
}
}
// There must always be a caster
if (!channelTarget)
channelTarget = m_caster->GetGUID();
uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
uint32 schoolImmunityMask = m_caster->GetSchoolImmunityMask();
uint32 mechanicImmunityMask = m_caster->GetMechanicImmunityMask();
@@ -4733,10 +4737,9 @@ void Spell::SendChannelStart(uint32 duration)
{
m_caster->SetChannelObjectGuid(channelTarget);
if (channelTarget != m_caster->GetGUID())
if (Creature* creatureCaster = m_caster->ToCreature())
if (!creatureCaster->HasSpellFocus(this))
creatureCaster->SetSpellFocus(this, ObjectAccessor::GetWorldObject(*creatureCaster, channelTarget));
if (Creature* creatureCaster = m_caster->ToCreature())
if (!creatureCaster->HasSpellFocus(this))
creatureCaster->SetSpellFocus(this, ObjectAccessor::GetWorldObject(*creatureCaster, channelTarget));
}
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellInfo->Id);