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.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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user