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:
hondacrx
2021-12-23 20:00:45 -05:00
parent ff48f2cab9
commit 8694a2ae24
6 changed files with 49 additions and 42 deletions
+5 -3
View File
@@ -934,7 +934,7 @@ namespace Game.Chat
{
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)}):");
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:");
@@ -948,13 +948,15 @@ namespace Game.Chat
}
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.");
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??");
}
else if (target.IsEngaged())
handler.SendSysMessage($"{target.GetName()} ({target.GetGUID()}) is currently engaged. (This unit cannot have a threat list.)");
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;
}
+4
View File
@@ -277,11 +277,15 @@ namespace Game.Combat
{
_owner.AddUnitFlag(UnitFlags.InCombat);
_owner.AtEnterCombat();
if (!_owner.CanHaveThreatList() && !_owner.IsEngaged())
_owner.AtEngage(GetAnyTarget());
}
else
{
_owner.RemoveUnitFlag(UnitFlags.InCombat);
_owner.AtExitCombat();
if (_owner.IsEngaged() && !(_owner.IsCreature() && _owner.ToCreature().IsAIEnabled()))
_owner.AtDisengage();
}
Unit master = _owner.GetCharmerOrOwner();
+14 -31
View File
@@ -32,7 +32,6 @@ namespace Game.Combat
public Unit _owner;
bool _ownerCanHaveThreatList;
bool _ownerEngaged;
public bool NeedClientUpdate;
uint _updateTimer;
@@ -82,7 +81,7 @@ namespace Game.Combat
public void Update(uint tdiff)
{
if (!CanHaveThreatList() || !IsEngaged())
if (!CanHaveThreatList() || IsThreatListEmpty())
return;
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)
{
// 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
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!
_ownerEngaged = true;
_owner.AtEngage(target);
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()
{
_ownerEngaged = false;
if (_myThreatListEntries.Empty())
return;
SendClearAllThreatToClients();
do
_myThreatListEntries.First().Value.UnregisterAndFree();
while (!_myThreatListEntries.Empty());
if (!_myThreatListEntries.Empty())
{
SendClearAllThreatToClients();
do
_myThreatListEntries.FirstOrDefault().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)
@@ -783,8 +768,6 @@ namespace Game.Combat
// identical to ThreatManager::CanHaveThreatList(GetOwner())
public bool CanHaveThreatList() { return _ownerCanHaveThreatList; }
public bool IsEngaged() { return _ownerEngaged; }
public int GetThreatListSize() { return _sortedThreatList.Count; }
// fastest of the three threat list getters - gets the threat list in "arbitrary" order
+16 -4
View File
@@ -1042,9 +1042,9 @@ namespace Game.Entities
&& !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))
Dismount();
@@ -1055,11 +1055,23 @@ namespace Game.Entities
UpdateSpeed(UnitMoveType.Swim);
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);
if (HasDynamicFlag(UnitDynFlags.Tapped))
+7 -4
View File
@@ -57,6 +57,9 @@ namespace Game.Entities
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)
{
if (includingCast && IsNonMeleeSpellCast(false))
@@ -144,10 +147,10 @@ namespace Game.Entities
public bool CanHaveThreatList() { return m_threatManager.CanHaveThreatList(); }
// For NPCs with threat list: Whether there are any enemies on our threat list
// For other units: Whether we're in combat
// This value is different from IsInCombat when a projectile spell is midair (combat on launch - threat+aggro on impact)
public bool IsEngaged() { return CanHaveThreatList() ? m_threatManager.IsEngaged() : IsInCombat(); }
// This value can be different from IsInCombat:
// - when a projectile spell is midair against a creature (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 m_isEngaged; }
public bool IsEngagedBy(Unit who) { return CanHaveThreatList() ? IsThreatenedBy(who) : IsInCombatWith(who); }
+3
View File
@@ -54,6 +54,9 @@ namespace Game.Entities
internal float[] m_modAttackSpeedPct = new float[(int)WeaponAttackType.Max];
protected uint[] m_attackTimer = new uint[(int)WeaponAttackType.Max];
// Threat+combat management
bool m_isEngaged;
CombatManager m_combatManager;
ThreatManager m_threatManager;