Core/Entities: Kick engagement logic upstairs to Unit (from ThreatManager), since all Units with AI need it (not just those with threat list).
Port From (https://github.com/TrinityCore/TrinityCore/commit/35e55f10899712435102764671241b94a2026599)
This commit is contained in:
@@ -934,7 +934,7 @@ namespace Game.Chat
|
|||||||
{
|
{
|
||||||
if (!mgr.IsThreatListEmpty(true))
|
if (!mgr.IsThreatListEmpty(true))
|
||||||
{
|
{
|
||||||
if (mgr.IsEngaged())
|
if (target.IsEngaged())
|
||||||
handler.SendSysMessage($"Threat list of {target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}):");
|
handler.SendSysMessage($"Threat list of {target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}):");
|
||||||
else
|
else
|
||||||
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}) is not engaged, but still has a threat list? Well, here it is:");
|
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}) is not engaged, but still has a threat list? Well, here it is:");
|
||||||
@@ -948,13 +948,15 @@ namespace Game.Chat
|
|||||||
}
|
}
|
||||||
handler.SendSysMessage("End of threat list.");
|
handler.SendSysMessage("End of threat list.");
|
||||||
}
|
}
|
||||||
else if (!mgr.IsEngaged())
|
else if (!target.IsEngaged())
|
||||||
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}) is not currently engaged.");
|
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}) is not currently engaged.");
|
||||||
else
|
else
|
||||||
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}) seems to be engaged, but does not have a threat list??");
|
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}, SpawnID {(target.IsCreature() ? target.ToCreature().GetSpawnId() : 0)}) seems to be engaged, but does not have a threat list??");
|
||||||
}
|
}
|
||||||
|
else if (target.IsEngaged())
|
||||||
|
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}) is currently engaged. (This unit cannot have a threat list.)");
|
||||||
else
|
else
|
||||||
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}) cannot have a threat list.");
|
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}) is not currently engaged. (This unit cannot have a threat list.)");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,11 +277,15 @@ namespace Game.Combat
|
|||||||
{
|
{
|
||||||
_owner.AddUnitFlag(UnitFlags.InCombat);
|
_owner.AddUnitFlag(UnitFlags.InCombat);
|
||||||
_owner.AtEnterCombat();
|
_owner.AtEnterCombat();
|
||||||
|
if (!_owner.CanHaveThreatList() && !_owner.IsEngaged())
|
||||||
|
_owner.AtEngage(GetAnyTarget());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_owner.RemoveUnitFlag(UnitFlags.InCombat);
|
_owner.RemoveUnitFlag(UnitFlags.InCombat);
|
||||||
_owner.AtExitCombat();
|
_owner.AtExitCombat();
|
||||||
|
if (_owner.IsEngaged() && !(_owner.IsCreature() && _owner.ToCreature().IsAIEnabled()))
|
||||||
|
_owner.AtDisengage();
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit master = _owner.GetCharmerOrOwner();
|
Unit master = _owner.GetCharmerOrOwner();
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ namespace Game.Combat
|
|||||||
|
|
||||||
public Unit _owner;
|
public Unit _owner;
|
||||||
bool _ownerCanHaveThreatList;
|
bool _ownerCanHaveThreatList;
|
||||||
bool _ownerEngaged;
|
|
||||||
|
|
||||||
public bool NeedClientUpdate;
|
public bool NeedClientUpdate;
|
||||||
uint _updateTimer;
|
uint _updateTimer;
|
||||||
@@ -82,7 +81,7 @@ namespace Game.Combat
|
|||||||
|
|
||||||
public void Update(uint tdiff)
|
public void Update(uint tdiff)
|
||||||
{
|
{
|
||||||
if (!CanHaveThreatList() || !IsEngaged())
|
if (!CanHaveThreatList() || IsThreatListEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_updateTimer <= tdiff)
|
if (_updateTimer <= tdiff)
|
||||||
@@ -192,13 +191,6 @@ namespace Game.Combat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SaveCreatureHomePositionIfNeed(Creature c)
|
|
||||||
{
|
|
||||||
MovementGeneratorType movetype = c.GetMotionMaster().GetCurrentMovementGeneratorType();
|
|
||||||
if (movetype == MovementGeneratorType.Waypoint || movetype == MovementGeneratorType.Point || (c.IsAIEnabled() && c.GetAI().IsEscorted()))
|
|
||||||
c.SetHomePosition(c.GetPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddThreat(Unit target, float amount, SpellInfo spell = null, bool ignoreModifiers = false, bool ignoreRedirects = false)
|
public void AddThreat(Unit target, float amount, SpellInfo spell = null, bool ignoreModifiers = false, bool ignoreRedirects = false)
|
||||||
{
|
{
|
||||||
// step 1: we can shortcut if the spell has one of the NO_THREAT attrs set - nothing will happen
|
// step 1: we can shortcut if the spell has one of the NO_THREAT attrs set - nothing will happen
|
||||||
@@ -317,20 +309,10 @@ namespace Game.Combat
|
|||||||
if (newRefe.IsOnline()) // ...and if the ref is online it also gets the threat it should have
|
if (newRefe.IsOnline()) // ...and if the ref is online it also gets the threat it should have
|
||||||
newRefe.AddThreat(amount);
|
newRefe.AddThreat(amount);
|
||||||
|
|
||||||
if (!_ownerEngaged)
|
if (!_owner.IsEngaged())
|
||||||
{
|
{
|
||||||
Creature cOwner = _owner.ToCreature(); // if we got here the owner can have a threat list, and must be a creature!
|
_owner.AtEngage(target);
|
||||||
_ownerEngaged = true;
|
|
||||||
|
|
||||||
UpdateVictim();
|
UpdateVictim();
|
||||||
SaveCreatureHomePositionIfNeed(cOwner);
|
|
||||||
CreatureAI ownerAI = cOwner.GetAI();
|
|
||||||
if (ownerAI != null)
|
|
||||||
ownerAI.JustEngagedWith(target);
|
|
||||||
|
|
||||||
CreatureGroup formation = cOwner.GetFormation();
|
|
||||||
if (formation != null)
|
|
||||||
formation.MemberEngagingTarget(cOwner, target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,14 +389,17 @@ namespace Game.Combat
|
|||||||
|
|
||||||
public void ClearAllThreat()
|
public void ClearAllThreat()
|
||||||
{
|
{
|
||||||
_ownerEngaged = false;
|
if (!_myThreatListEntries.Empty())
|
||||||
if (_myThreatListEntries.Empty())
|
{
|
||||||
return;
|
SendClearAllThreatToClients();
|
||||||
|
do
|
||||||
SendClearAllThreatToClients();
|
_myThreatListEntries.FirstOrDefault().Value.UnregisterAndFree();
|
||||||
do
|
while (!_myThreatListEntries.Empty());
|
||||||
_myThreatListEntries.First().Value.UnregisterAndFree();
|
}
|
||||||
while (!_myThreatListEntries.Empty());
|
// note: i don't really like having this here
|
||||||
|
// (maybe engage flag should be in creature ai? it's inherently an AI property...)
|
||||||
|
if (_owner.IsEngaged())
|
||||||
|
_owner.AtDisengage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FixateTarget(Unit target)
|
public void FixateTarget(Unit target)
|
||||||
@@ -783,8 +768,6 @@ namespace Game.Combat
|
|||||||
// identical to ThreatManager::CanHaveThreatList(GetOwner())
|
// identical to ThreatManager::CanHaveThreatList(GetOwner())
|
||||||
public bool CanHaveThreatList() { return _ownerCanHaveThreatList; }
|
public bool CanHaveThreatList() { return _ownerCanHaveThreatList; }
|
||||||
|
|
||||||
public bool IsEngaged() { return _ownerEngaged; }
|
|
||||||
|
|
||||||
public int GetThreatListSize() { return _sortedThreatList.Count; }
|
public int GetThreatListSize() { return _sortedThreatList.Count; }
|
||||||
|
|
||||||
// fastest of the three threat list getters - gets the threat list in "arbitrary" order
|
// fastest of the three threat list getters - gets the threat list in "arbitrary" order
|
||||||
|
|||||||
@@ -1042,9 +1042,9 @@ namespace Game.Entities
|
|||||||
&& !GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoXpAtKill);
|
&& !GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoXpAtKill);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AtEnterCombat()
|
public override void AtEngage(Unit target)
|
||||||
{
|
{
|
||||||
base.AtEnterCombat();
|
base.AtEngage(target);
|
||||||
|
|
||||||
if (!GetCreatureTemplate().TypeFlags.HasAnyFlag(CreatureTypeFlags.MountedCombatAllowed))
|
if (!GetCreatureTemplate().TypeFlags.HasAnyFlag(CreatureTypeFlags.MountedCombatAllowed))
|
||||||
Dismount();
|
Dismount();
|
||||||
@@ -1055,11 +1055,23 @@ namespace Game.Entities
|
|||||||
UpdateSpeed(UnitMoveType.Swim);
|
UpdateSpeed(UnitMoveType.Swim);
|
||||||
UpdateSpeed(UnitMoveType.Flight);
|
UpdateSpeed(UnitMoveType.Flight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MovementGeneratorType movetype = GetMotionMaster().GetCurrentMovementGeneratorType();
|
||||||
|
if (movetype == MovementGeneratorType.Waypoint || movetype == MovementGeneratorType.Point || (IsAIEnabled() && GetAI().IsEscorted()))
|
||||||
|
SetHomePosition(GetPosition());
|
||||||
|
|
||||||
|
CreatureAI ai = GetAI();
|
||||||
|
if (ai != null)
|
||||||
|
ai.JustEngagedWith(target);
|
||||||
|
|
||||||
|
CreatureGroup formation = GetFormation();
|
||||||
|
if (formation != null)
|
||||||
|
formation.MemberEngagingTarget(this, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AtExitCombat()
|
public override void AtDisengage()
|
||||||
{
|
{
|
||||||
base.AtExitCombat();
|
base.AtDisengage();
|
||||||
|
|
||||||
ClearUnitState(UnitState.AttackPlayer);
|
ClearUnitState(UnitState.AttackPlayer);
|
||||||
if (HasDynamicFlag(UnitDynFlags.Tapped))
|
if (HasDynamicFlag(UnitDynFlags.Tapped))
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ namespace Game.Entities
|
|||||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeavingCombat);
|
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeavingCombat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void AtEngage(Unit target) { m_isEngaged = true; }
|
||||||
|
public virtual void AtDisengage() { m_isEngaged = false; }
|
||||||
|
|
||||||
public void CombatStop(bool includingCast = false, bool mutualPvP = true)
|
public void CombatStop(bool includingCast = false, bool mutualPvP = true)
|
||||||
{
|
{
|
||||||
if (includingCast && IsNonMeleeSpellCast(false))
|
if (includingCast && IsNonMeleeSpellCast(false))
|
||||||
@@ -144,10 +147,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public bool CanHaveThreatList() { return m_threatManager.CanHaveThreatList(); }
|
public bool CanHaveThreatList() { return m_threatManager.CanHaveThreatList(); }
|
||||||
|
|
||||||
// For NPCs with threat list: Whether there are any enemies on our threat list
|
// This value can be different from IsInCombat:
|
||||||
// For other units: Whether we're in combat
|
// - when a projectile spell is midair against a creature (combat on launch - threat+aggro on impact)
|
||||||
// This value is different from IsInCombat when a projectile spell is midair (combat on launch - threat+aggro on impact)
|
// - when the creature has no targets left, but the AI has not yet ceased engaged logic
|
||||||
public bool IsEngaged() { return CanHaveThreatList() ? m_threatManager.IsEngaged() : IsInCombat(); }
|
public bool IsEngaged() { return m_isEngaged; }
|
||||||
|
|
||||||
public bool IsEngagedBy(Unit who) { return CanHaveThreatList() ? IsThreatenedBy(who) : IsInCombatWith(who); }
|
public bool IsEngagedBy(Unit who) { return CanHaveThreatList() ? IsThreatenedBy(who) : IsInCombatWith(who); }
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ namespace Game.Entities
|
|||||||
internal float[] m_modAttackSpeedPct = new float[(int)WeaponAttackType.Max];
|
internal float[] m_modAttackSpeedPct = new float[(int)WeaponAttackType.Max];
|
||||||
protected uint[] m_attackTimer = new uint[(int)WeaponAttackType.Max];
|
protected uint[] m_attackTimer = new uint[(int)WeaponAttackType.Max];
|
||||||
|
|
||||||
|
// Threat+combat management
|
||||||
|
bool m_isEngaged;
|
||||||
|
|
||||||
CombatManager m_combatManager;
|
CombatManager m_combatManager;
|
||||||
ThreatManager m_threatManager;
|
ThreatManager m_threatManager;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user