Core/Spells: Delay combat flagging for spell targets until spell missile lands
Port From (https://github.com/TrinityCore/TrinityCore/commit/ff99952dfb7d2b532de2d1aedc825fb96038f4c2)
This commit is contained in:
@@ -113,7 +113,7 @@ namespace Game.Combat
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetInCombatWith(Unit who)
|
public bool SetInCombatWith(Unit who, bool suppressPvpSecond = false)
|
||||||
{
|
{
|
||||||
// Are we already in combat? If yes, refresh pvp combat
|
// Are we already in combat? If yes, refresh pvp combat
|
||||||
var pvpRefe = _pvpRefs.LookupByKey(who.GetGUID());
|
var pvpRefe = _pvpRefs.LookupByKey(who.GetGUID());
|
||||||
@@ -126,13 +126,18 @@ namespace Game.Combat
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise, check validity...
|
// Otherwise, check validity...
|
||||||
if (!CombatManager.CanBeginCombat(_owner, who))
|
if (!CanBeginCombat(_owner, who))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// ...then create new reference
|
// ...then create new reference
|
||||||
CombatReference refe;
|
CombatReference refe;
|
||||||
if (_owner.IsControlledByPlayer() && who.IsControlledByPlayer())
|
if (_owner.IsControlledByPlayer() && who.IsControlledByPlayer())
|
||||||
refe = new PvPCombatReference(_owner, who);
|
{
|
||||||
|
PvPCombatReference refPvp = new PvPCombatReference(_owner, who);
|
||||||
|
if (suppressPvpSecond)
|
||||||
|
refPvp.SuppressFor(who);
|
||||||
|
refe = refPvp;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
refe = new CombatReference(_owner, who);
|
refe = new CombatReference(_owner, who);
|
||||||
|
|
||||||
|
|||||||
@@ -95,10 +95,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public bool IsPetInCombat() { return HasUnitFlag(UnitFlags.PetInCombat); }
|
public bool IsPetInCombat() { return HasUnitFlag(UnitFlags.PetInCombat); }
|
||||||
|
|
||||||
public void SetInCombatWith(Unit enemy)
|
public void SetInCombatWith(Unit enemy, bool suppressPvpTargetCombat = false)
|
||||||
{
|
{
|
||||||
if (enemy != null)
|
if (enemy != null)
|
||||||
m_combatManager.SetInCombatWith(enemy);
|
m_combatManager.SetInCombatWith(enemy, suppressPvpTargetCombat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EngageWithTarget(Unit enemy)
|
public void EngageWithTarget(Unit enemy)
|
||||||
|
|||||||
@@ -1852,8 +1852,13 @@ namespace Game.Spells
|
|||||||
|
|
||||||
// Calculate hit result
|
// Calculate hit result
|
||||||
WorldObject caster = m_originalCaster ? m_originalCaster : m_caster;
|
WorldObject caster = m_originalCaster ? m_originalCaster : m_caster;
|
||||||
|
Unit unitCaster = m_caster.ToUnit();
|
||||||
targetInfo.MissCondition = caster.SpellHitResult(target, m_spellInfo, m_canReflect && !(IsPositive() && m_caster.IsFriendlyTo(target)));
|
targetInfo.MissCondition = caster.SpellHitResult(target, m_spellInfo, m_canReflect && !(IsPositive() && m_caster.IsFriendlyTo(target)));
|
||||||
|
|
||||||
|
// This will only cause combat - the target will engage once the projectile hits (in DoAllEffectOnTarget)
|
||||||
|
if (m_originalCaster != null && targetInfo.MissCondition != SpellMissInfo.Evade && !m_originalCaster.IsFriendlyTo(target) && (!m_spellInfo.IsPositive() || m_spellInfo.HasEffect(SpellEffectName.Dispel)) && (m_spellInfo.HasInitialAggro() || target.IsEngaged()))
|
||||||
|
m_originalCaster.SetInCombatWith(target, true);
|
||||||
|
|
||||||
// Spell have speed - need calculate incoming time
|
// Spell have speed - need calculate incoming time
|
||||||
// Incoming time is zero for self casts. At least I think so.
|
// Incoming time is zero for self casts. At least I think so.
|
||||||
if (m_caster != target)
|
if (m_caster != target)
|
||||||
@@ -1886,6 +1891,15 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
|
|
||||||
targetInfo.TimeDelay += (ulong)Math.Floor(hitDelay * 1000.0f);
|
targetInfo.TimeDelay += (ulong)Math.Floor(hitDelay * 1000.0f);
|
||||||
|
|
||||||
|
if (unitCaster != null && targetInfo.MissCondition != SpellMissInfo.Evade)
|
||||||
|
{
|
||||||
|
bool enterCombat = !caster.IsFriendlyTo(target) && (!m_spellInfo.IsPositive() || m_spellInfo.HasEffect(SpellEffectName.Dispel)) && (m_spellInfo.HasInitialAggro() || target.IsEngaged());
|
||||||
|
bool enablePVP = targetInfo.IsPVPEnabling();
|
||||||
|
|
||||||
|
if (enterCombat || enablePVP)
|
||||||
|
target.m_Events.AddEvent(new ProcImpactDelayed(target, m_originalCasterGUID, enterCombat, enablePVP), target.m_Events.CalculateTime(TimeSpan.FromMilliseconds(targetInfo.TimeDelay)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
targetInfo.TimeDelay = 0L;
|
targetInfo.TimeDelay = 0L;
|
||||||
@@ -1894,7 +1908,7 @@ namespace Game.Spells
|
|||||||
if (targetInfo.MissCondition == SpellMissInfo.Reflect)
|
if (targetInfo.MissCondition == SpellMissInfo.Reflect)
|
||||||
{
|
{
|
||||||
// Calculate reflected spell result on caster (shouldn't be able to reflect gameobject spells)
|
// Calculate reflected spell result on caster (shouldn't be able to reflect gameobject spells)
|
||||||
Unit unitCaster = m_caster.ToUnit();
|
Cypher.Assert(unitCaster != null);
|
||||||
targetInfo.ReflectResult = unitCaster.SpellHitResult(unitCaster, m_spellInfo, false); // can't reflect twice
|
targetInfo.ReflectResult = unitCaster.SpellHitResult(unitCaster, m_spellInfo, false); // can't reflect twice
|
||||||
|
|
||||||
// Proc spell reflect aura when missile hits the original target
|
// Proc spell reflect aura when missile hits the original target
|
||||||
@@ -7212,10 +7226,6 @@ namespace Game.Spells
|
|||||||
if (unit == null)
|
if (unit == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// This will only cause combat - the target will engage once the projectile hits (in DoAllEffectOnTarget)
|
|
||||||
if (m_originalCaster != null && targetInfo.MissCondition != SpellMissInfo.Evade && !m_originalCaster.IsFriendlyTo(unit) && (!m_spellInfo.IsPositive() || m_spellInfo.HasEffect(SpellEffectName.Dispel)) && (m_spellInfo.HasInitialAggro() || unit.IsEngaged()))
|
|
||||||
m_originalCaster.SetInCombatWith(unit);
|
|
||||||
|
|
||||||
m_damage = 0;
|
m_damage = 0;
|
||||||
m_healing = 0;
|
m_healing = 0;
|
||||||
|
|
||||||
@@ -8552,7 +8562,7 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spell.m_spellInfo.HasAttribute(SpellAttr3.DoNotTriggerTargetStand) && !unit.IsStandState())
|
if (!spell.m_spellInfo.HasAttribute(SpellAttr3.DoNotTriggerTargetStand) && !unit.IsStandState())
|
||||||
unit.SetStandState(UnitStandStateType.Stand);
|
unit.SetStandState(UnitStandStateType.Stand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8596,7 +8606,7 @@ namespace Game.Spells
|
|||||||
// Needs to be called after dealing damage/healing to not remove breaking on damage auras
|
// Needs to be called after dealing damage/healing to not remove breaking on damage auras
|
||||||
spell.DoTriggersOnSpellHit(_spellHitTarget);
|
spell.DoTriggersOnSpellHit(_spellHitTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_enablePVP)
|
if (_enablePVP)
|
||||||
spell.GetCaster().ToPlayer().UpdatePvP(true);
|
spell.GetCaster().ToPlayer().UpdatePvP(true);
|
||||||
|
|
||||||
@@ -8604,6 +8614,8 @@ namespace Game.Spells
|
|||||||
spell.CallScriptAfterHitHandlers();
|
spell.CallScriptAfterHitHandlers();
|
||||||
spell.spellAura = null;
|
spell.spellAura = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsPVPEnabling() { return _enablePVP; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GOTargetInfo : TargetInfoBase
|
public class GOTargetInfo : TargetInfoBase
|
||||||
@@ -9101,6 +9113,41 @@ namespace Game.Spells
|
|||||||
Spell m_Spell;
|
Spell m_Spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ProcImpactDelayed : BasicEvent
|
||||||
|
{
|
||||||
|
Unit _owner;
|
||||||
|
ObjectGuid _casterGUID;
|
||||||
|
bool _enterCombat;
|
||||||
|
bool _enablePVP;
|
||||||
|
|
||||||
|
public ProcImpactDelayed(Unit owner, ObjectGuid casterGUID, bool enterCombat, bool enablePVP)
|
||||||
|
{
|
||||||
|
_owner = owner;
|
||||||
|
_casterGUID = casterGUID;
|
||||||
|
_enterCombat = enterCombat;
|
||||||
|
_enablePVP = enablePVP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Execute(ulong e_time, uint p_time)
|
||||||
|
{
|
||||||
|
if (_owner == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Unit caster = Global.ObjAccessor.GetUnit(_owner, _casterGUID);
|
||||||
|
if (caster == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// This will only cause combat - the target will engage once the projectile hits (in DoAllEffectOnTarget)
|
||||||
|
if (_enterCombat)
|
||||||
|
_owner.SetInCombatWith(caster);
|
||||||
|
|
||||||
|
if (_enablePVP && caster.ToPlayer())
|
||||||
|
caster.ToPlayer().UpdatePvP(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ProcReflectDelayed : BasicEvent
|
class ProcReflectDelayed : BasicEvent
|
||||||
{
|
{
|
||||||
public ProcReflectDelayed(Unit owner, ObjectGuid casterGuid)
|
public ProcReflectDelayed(Unit owner, ObjectGuid casterGuid)
|
||||||
|
|||||||
Reference in New Issue
Block a user