Core/Spells: cleaned up and improved spell focusing behavior
Port From (https://github.com/TrinityCore/TrinityCore/commit/c295cb9814f4c2a1878aa047cefe0cfbc7958f93)
This commit is contained in:
@@ -2975,39 +2975,15 @@ namespace Game.Entities
|
|||||||
_spellFocusInfo.Spell = focusSpell;
|
_spellFocusInfo.Spell = focusSpell;
|
||||||
|
|
||||||
bool noTurnDuringCast = spellInfo.HasAttribute(SpellAttr5.DontTurnDuringCast);
|
bool noTurnDuringCast = spellInfo.HasAttribute(SpellAttr5.DontTurnDuringCast);
|
||||||
|
bool turnDisabled = HasUnitFlag2(UnitFlags2.CannotTurn);
|
||||||
// set target, then force send update packet to players if it changed to provide appropriate facing
|
// set target, then force send update packet to players if it changed to provide appropriate facing
|
||||||
ObjectGuid newTarget = target ? target.GetGUID() : ObjectGuid.Empty;
|
ObjectGuid newTarget = (target != null && !noTurnDuringCast && !turnDisabled) ? target.GetGUID() : ObjectGuid.Empty;
|
||||||
if (GetTarget() != newTarget)
|
if (GetTarget() != newTarget)
|
||||||
{
|
|
||||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Target), newTarget);
|
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Target), newTarget);
|
||||||
|
|
||||||
// here we determine if the (relatively expensive) forced update is worth it, or whether we can afford to wait until the scheduled update tick
|
// If we are not allowed to turn during cast but have a focus target, face the target
|
||||||
// only require instant update for spells that actually have a visual
|
if (!turnDisabled && noTurnDuringCast && target)
|
||||||
if (spellInfo.GetSpellVisual() != 0 && (focusSpell.GetCastTime() == 0 || // if the spell is instant cast
|
SetFacingToObject(target, false);
|
||||||
noTurnDuringCast)) // client gets confused if we attempt to turn at the regularly scheduled update packet
|
|
||||||
{
|
|
||||||
List<Unit> playersNearby = GetPlayerListInGrid(GetVisibilityRange());
|
|
||||||
foreach (Player player in playersNearby)
|
|
||||||
{
|
|
||||||
// only update players that are known to the client (have already been created)
|
|
||||||
if (player.HaveAtClient(this))
|
|
||||||
SendUpdateToPlayer(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!HasUnitFlag2(UnitFlags2.CannotTurn))
|
|
||||||
{
|
|
||||||
// Face the target - we need to do this before the unit state is modified for no-turn spells
|
|
||||||
if (target)
|
|
||||||
SetFacingToObject(target, false);
|
|
||||||
else if (!noTurnDuringCast)
|
|
||||||
{
|
|
||||||
Unit victim = GetVictim();
|
|
||||||
if (victim)
|
|
||||||
SetFacingToObject(victim, false); // ensure server-side orientation is correct at beginning of cast
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!noTurnDuringCast)
|
if (!noTurnDuringCast)
|
||||||
AddUnitState(UnitState.Focusing);
|
AddUnitState(UnitState.Focusing);
|
||||||
|
|||||||
@@ -513,6 +513,18 @@ namespace Game.Spells
|
|||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
|
// Update serverside orientation of tracking channeled auras on periodic update ticks
|
||||||
|
if (caster != null && m_spellInfo.IsChanneled() && m_spellInfo.HasAttribute(SpellAttr1.ChannelTrackTarget) && !caster.m_unitData.ChannelObjects.Empty())
|
||||||
|
{
|
||||||
|
ObjectGuid channelGuid = caster.m_unitData.ChannelObjects[0];
|
||||||
|
if (channelGuid != caster.GetGUID())
|
||||||
|
{
|
||||||
|
WorldObject objectTarget = Global.ObjAccessor.GetWorldObject(caster, channelGuid);
|
||||||
|
if (objectTarget != null)
|
||||||
|
caster.SetInFront(objectTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (GetAuraType())
|
switch (GetAuraType())
|
||||||
{
|
{
|
||||||
case AuraType.PeriodicDummy:
|
case AuraType.PeriodicDummy:
|
||||||
|
|||||||
+13
-27
@@ -2462,16 +2462,15 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// focus if not controlled creature
|
// Creatures focus their target when possible
|
||||||
if (m_caster.GetTypeId() == TypeId.Unit && !m_caster.ToUnit().HasUnitFlag(UnitFlags.Possessed))
|
if (m_casttime != 0 && m_caster.IsCreature() && !m_spellInfo.IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_caster.ToUnit().HasUnitFlag(UnitFlags.Possessed))
|
||||||
{
|
{
|
||||||
if (!(m_spellInfo.IsNextMeleeSwingSpell() || IsAutoRepeat()))
|
// Channeled spells and some triggered spells do not focus a cast target. They face their target later on via channel object guid and via spell attribute or not at all
|
||||||
{
|
bool focusTarget = !m_spellInfo.IsChanneled() && !_triggeredCastFlags.HasFlag(TriggerCastFlags.IgnoreSetFacing);
|
||||||
if (m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
|
if (focusTarget && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
|
||||||
m_caster.ToCreature().SetSpellFocus(this, m_targets.GetObjectTarget());
|
m_caster.ToCreature().SetSpellFocus(this, m_targets.GetObjectTarget());
|
||||||
else if (m_spellInfo.HasAttribute(SpellAttr5.DontTurnDuringCast))
|
else
|
||||||
m_caster.ToCreature().SetSpellFocus(this, null);
|
m_caster.ToCreature().SetSpellFocus(this, null);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set timer base at cast time
|
// set timer base at cast time
|
||||||
@@ -2641,10 +2640,6 @@ namespace Game.Spells
|
|||||||
|
|
||||||
SetExecutedCurrently(true);
|
SetExecutedCurrently(true);
|
||||||
|
|
||||||
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreSetFacing))
|
|
||||||
if (m_caster.IsTypeId(TypeId.Unit) && m_targets.GetObjectTarget() != null && m_caster != m_targets.GetObjectTarget())
|
|
||||||
m_caster.ToCreature().SetInFront(m_targets.GetObjectTarget());
|
|
||||||
|
|
||||||
// Should this be done for original caster?
|
// Should this be done for original caster?
|
||||||
Player modOwner = m_caster.GetSpellModOwner();
|
Player modOwner = m_caster.GetSpellModOwner();
|
||||||
if (modOwner != null)
|
if (modOwner != null)
|
||||||
@@ -2730,17 +2725,11 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the spell allows the creature to turn while casting, then adjust server-side orientation to face the target now
|
// The spell focusing is making sure that we have a valid cast target guid when we need it so only check for a guid value here.
|
||||||
// client-side orientation is handled by the client itself, as the cast target is targeted due to Creature::FocusTarget
|
Creature creatureCaster = m_caster.ToCreature();
|
||||||
if (m_caster.IsTypeId(TypeId.Unit) && !m_caster.ToUnit().HasUnitFlag(UnitFlags.Possessed))
|
if (creatureCaster != null)
|
||||||
{
|
if (!creatureCaster.GetTarget().IsEmpty() && !creatureCaster.HasUnitFlag(UnitFlags.Possessed))
|
||||||
if (!m_spellInfo.HasAttribute(SpellAttr5.DontTurnDuringCast))
|
creatureCaster.SetInFront(Global.ObjAccessor.GetUnit(creatureCaster, creatureCaster.GetTarget()));
|
||||||
{
|
|
||||||
WorldObject objTarget = m_targets.GetObjectTarget();
|
|
||||||
if (objTarget != null)
|
|
||||||
m_caster.ToCreature().SetInFront(objTarget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectSpellTargets();
|
SelectSpellTargets();
|
||||||
|
|
||||||
@@ -2816,11 +2805,8 @@ namespace Game.Spells
|
|||||||
SendSpellGo();
|
SendSpellGo();
|
||||||
|
|
||||||
if (!m_spellInfo.IsChanneled())
|
if (!m_spellInfo.IsChanneled())
|
||||||
{
|
|
||||||
Creature creatureCaster = m_caster.ToCreature();
|
|
||||||
if (creatureCaster != null)
|
if (creatureCaster != null)
|
||||||
creatureCaster.ReleaseSpellFocus(this);
|
creatureCaster.ReleaseSpellFocus(this);
|
||||||
}
|
|
||||||
|
|
||||||
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
|
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
|
||||||
if ((m_spellInfo.HasHitDelay() && !m_spellInfo.IsChanneled()) || m_spellInfo.HasAttribute(SpellAttr4.Unk4))
|
if ((m_spellInfo.HasHitDelay() && !m_spellInfo.IsChanneled()) || m_spellInfo.HasAttribute(SpellAttr4.Unk4))
|
||||||
|
|||||||
Reference in New Issue
Block a user