Core/AI: Finally move the "is creature engaged" flag to be a property of the creature AI, where it honestly always belonged.

Port From (https://github.com/TrinityCore/TrinityCore/commit/c13d83796f7b2111c5dcf8546bdd84eccd232ae3)
This commit is contained in:
hondacrx
2022-01-01 17:05:29 -05:00
parent 9b3fe829d6
commit 2842cc9c91
13 changed files with 142 additions and 71 deletions
+55 -5
View File
@@ -29,6 +29,7 @@ namespace Game.AI
{
public class CreatureAI : UnitAI
{
bool _isEngaged;
bool _moveInLOSLocked;
List<AreaBoundary> _boundary = new();
bool _negateBoundary;
@@ -201,6 +202,12 @@ namespace Game.AI
}
}
public override void JustEnteredCombat(Unit who)
{
if (!IsEngaged() && !me.CanHaveThreatList())
EngagementStart(who);
}
// Called for reaction at stopping attack at no attackers or targets
public virtual void EnterEvadeMode(EvadeReason why = EvadeReason.Other)
{
@@ -231,7 +238,7 @@ namespace Game.AI
public bool UpdateVictim()
{
if (!me.IsEngaged())
if (!IsEngaged())
return false;
if (!me.HasReactState(ReactStates.Passive))
@@ -254,23 +261,53 @@ namespace Game.AI
return true;
}
public void EngagementStart(Unit who)
{
if (_isEngaged)
{
//Log.outError(LogFilter.ScriptsAi, $"CreatureAI::EngagementStart called even though creature is already engaged. Creature debug info:\n{me.GetDebugInfo()}");
return;
}
_isEngaged = true;
me.AtEngage(who);
}
public void EngagementOver()
{
if (!_isEngaged)
{
//Log.outError(LogFilter.ScriptsAi, $"CreatureAI::EngagementOver called even though creature is not currently engaged. Creature debug info:\n{me.GetDebugInfo()}");
return;
}
_isEngaged = false;
me.AtDisengage();
}
public bool _EnterEvadeMode(EvadeReason why = EvadeReason.Other)
{
if (!me.IsAlive())
if (me.IsInEvadeMode())
return false;
if (!me.IsAlive())
{
EngagementOver();
return false;
}
me.RemoveAurasOnEvade();
// sometimes bosses stuck in combat?
me.CombatStop(true);
me.GetThreatManager().NotifyDisengaged();
me.SetLootRecipient(null);
me.ResetPlayerDamageReq();
me.SetLastDamagedTime(0);
me.SetCannotReachTarget(false);
me.DoNotReacquireTarget();
EngagementOver();
return !me.IsInEvadeMode();
return true;
}
public CypherStrings VisualizeBoundary(int duration, Unit owner = null, bool fill = false)
@@ -404,11 +441,22 @@ namespace Game.AI
me.DoImmediateBoundaryCheck();
}
// Called for reaction whenever a new non-offline unit is added to the threat list
public virtual void JustStartedThreateningMe(Unit who)
{
if (!IsEngaged())
EngagementStart(who);
}
// Called for reaction when initially engaged - this will always happen _after_ JustEnteredCombat
public virtual void JustEngagedWith(Unit who) { }
// Called when the creature is killed
public virtual void JustDied(Unit killer) { }
public virtual void JustDied(Unit killer)
{
if (IsEngaged())
EngagementOver();
}
// Called when the creature kills a unit
public virtual void KilledUnit(Unit victim) { }
@@ -521,6 +569,8 @@ namespace Game.AI
public virtual bool IsEscortNPC(bool onlyIfActive) { return false; }
public List<AreaBoundary> GetBoundary() { return _boundary; }
public bool IsEngaged() { return _isEngaged; }
}
public class AISpellInfoType
+2 -2
View File
@@ -48,7 +48,7 @@ namespace Game.AI
{
me.GetMotionMaster().MoveIdle();
me.CombatStop(true);
me.GetThreatManager().NotifyDisengaged();
EngagementOver();
return;
}
@@ -56,7 +56,7 @@ namespace Game.AI
me.RemoveAllAuras();
me.CombatStop(true);
me.GetThreatManager().NotifyDisengaged();
EngagementOver();
me.GetMotionMaster().MoveTargetedHome();
}
+17
View File
@@ -77,6 +77,21 @@ namespace Game.AI
public override void MoveInLineOfSight(Unit who) { }
public override void JustEnteredCombat(Unit who)
{
EngagementStart(who);
}
public override void JustExitedCombat()
{
EngagementOver();
}
public override void JustStartedThreateningMe(Unit who)
{
}
public override void EnterEvadeMode(EvadeReason why) { }
}
@@ -89,6 +104,8 @@ namespace Game.AI
public override void MoveInLineOfSight(Unit unit) { }
public override void AttackStart(Unit unit) { }
public override void JustStartedThreateningMe(Unit unit) { }
public override void JustEnteredCombat(Unit who) { }
public override void UpdateAI(uint diff) { }
public override void JustAppeared() { }
public override void EnterEvadeMode(EvadeReason why) { }
+1 -10
View File
@@ -21,7 +21,7 @@ using Game.Maps;
namespace Game.AI
{
public class TotemAI : CreatureAI
public class TotemAI : NullCreatureAI
{
ObjectGuid _victimGuid;
@@ -30,15 +30,6 @@ namespace Game.AI
_victimGuid = ObjectGuid.Empty;
}
public override void MoveInLineOfSight(Unit who) { }
public override void JustAppeared() { }
public override void EnterEvadeMode(EvadeReason why)
{
me.CombatStop(true);
}
public override void UpdateAI(uint diff)
{
if (me.ToTotem().GetTotemType() != TotemType.Active)
+1 -1
View File
@@ -536,7 +536,7 @@ namespace Game.AI
_me = unit;
_dist = dist;
_playerOnly = playerOnly;
_exception = !withTank ? _me.GetThreatManager().GetCurrentVictim() : null;
_exception = !withTank ? unit.GetThreatManager().GetLastVictim() : null;
_aura = aura;
}
@@ -135,9 +135,10 @@ namespace Game.AI
{
me.RemoveAllAuras();
me.CombatStop(true);
me.GetThreatManager().NotifyDisengaged();
me.SetLootRecipient(null);
EngagementOver();
if (HasEscortState(EscortState.Escorting))
{
AddEscortState(EscortState.Returning);
@@ -123,15 +123,19 @@ namespace Game.AI
public override void EnterEvadeMode(EvadeReason why)
{
if (!me.IsAlive())
{
EngagementOver();
return;
}
me.RemoveAllAuras();
me.CombatStop(true);
me.GetThreatManager().NotifyDisengaged();
me.SetLootRecipient(null);
me.SetCannotReachTarget(false);
me.DoNotReacquireTarget();
EngagementOver();
if (HasFollowState(FollowState.Inprogress))
{
Log.outDebug(LogFilter.Scripts, "FollowerAI left combat, returning to CombatStartPosition.");