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
+5 -11
View File
@@ -234,15 +234,9 @@ namespace Game.Combat
public static void NotifyAICombat(Unit me, Unit other)
{
if (!me.IsAIEnabled())
return;
me.GetAI().JustEnteredCombat(other);
Creature cMe = me.ToCreature();
if (cMe != null)
if (!cMe.CanHaveThreatList())
cMe.GetAI().JustEngagedWith(other);
UnitAI ai = me.GetAI();
if (ai != null)
ai.JustEnteredCombat(other);
}
void PutReference(ObjectGuid guid, CombatReference refe)
@@ -277,14 +271,14 @@ namespace Game.Combat
{
_owner.AddUnitFlag(UnitFlags.InCombat);
_owner.AtEnterCombat();
if (!_owner.CanHaveThreatList() && !_owner.IsEngaged())
if (_owner.IsCreature())
_owner.AtEngage(GetAnyTarget());
}
else
{
_owner.RemoveUnitFlag(UnitFlags.InCombat);
_owner.AtExitCombat();
if (_owner.IsEngaged() && !(_owner.IsCreature() && _owner.CanHaveThreatList() && _owner.ToCreature().IsAIEnabled()))
if (!_owner.IsCreature())
_owner.AtDisengage();
}
+37 -29
View File
@@ -37,6 +37,7 @@ namespace Game.Combat
uint _updateTimer;
List<ThreatReference> _sortedThreatList = new();
Dictionary<ObjectGuid, ThreatReference> _myThreatListEntries = new();
List<ThreatReference> _needsAIUpdate = new();
ThreatReference _currentVictimRef;
ThreatReference _fixateRef;
@@ -98,6 +99,12 @@ namespace Game.Combat
if (_currentVictimRef == null || _currentVictimRef.ShouldBeOffline())
UpdateVictim();
Cypher.Assert(_currentVictimRef == null || _currentVictimRef.IsAvailable());
return _currentVictimRef?.GetVictim();
}
public Unit GetLastVictim()
{
if (_currentVictimRef != null && !_currentVictimRef.ShouldBeOffline())
return _currentVictimRef.GetVictim();
@@ -294,7 +301,7 @@ namespace Game.Combat
}
}
if (targetRefe.IsOnline())
if (targetRefe.IsOnline())
targetRefe.AddThreat(amount);
return;
}
@@ -306,14 +313,13 @@ namespace Game.Combat
// afterwards, we evaluate whether this is an online reference (it might not be an acceptable target, but we need to add it to our threat list before we check!)
newRefe.UpdateOffline();
if (newRefe.IsOnline()) // ...and if the ref is online it also gets the threat it should have
if (newRefe.IsOnline()) // we only add the threat if the ref is currently available
newRefe.AddThreat(amount);
if (!_owner.IsEngaged())
{
_owner.AtEngage(target);
if (_currentVictimRef == null)
UpdateVictim();
}
else
ProcessAIUpdates();
}
void ScaleThreat(Unit target, float factor)
@@ -398,18 +404,6 @@ namespace Game.Combat
}
}
/// <summary>
/// THIS SHOULD ONLY BE CALLED FROM A CREATURE'S AI (typically in EnterEvadeMode)
/// notify the unit that the AI has disengaged
/// </summary>
public void NotifyDisengaged()
{
// 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)
{
if (target)
@@ -446,6 +440,7 @@ namespace Game.Combat
NeedClientUpdate = false;
}
ProcessAIUpdates();
}
ThreatReference ReselectVictim()
@@ -454,7 +449,7 @@ namespace Game.Combat
return null;
foreach (var pair in _myThreatListEntries)
pair.Value.UpdateOffline();
pair.Value.UpdateOffline(); // AI notifies are processed in ::UpdateVictim caller
// fixated target is always preferred
if (_fixateRef != null && _fixateRef.IsAvailable())
@@ -509,6 +504,16 @@ namespace Game.Combat
return null;
}
void ProcessAIUpdates()
{
CreatureAI ai = _owner.ToCreature().GetAI();
List<ThreatReference> v = new(_needsAIUpdate); // _needClientUpdate is now empty in case this triggers a recursive call
if (ai == null)
return;
foreach (ThreatReference refe in v)
ai.JustStartedThreateningMe(refe.GetVictim());
}
// returns true if a is LOWER on the threat list than b
public static bool CompareReferencesLT(ThreatReference a, ThreatReference b, float aWeight)
{
@@ -563,17 +568,17 @@ namespace Game.Combat
threat *= victimMgr._singleSchoolModifiers[(int)SpellSchools.Arcane];
break;
default:
{
if (victimMgr._multiSchoolModifiers.TryGetValue(mask, out float value))
{
if (victimMgr._multiSchoolModifiers.TryGetValue(mask, out float value))
{
threat *= value;
break;
}
float mod = victim.GetTotalAuraMultiplierByMiscMask(AuraType.ModThreat, (uint)mask);
victimMgr._multiSchoolModifiers[mask] = mod;
threat *= mod;
threat *= value;
break;
}
float mod = victim.GetTotalAuraMultiplierByMiscMask(AuraType.ModThreat, (uint)mask);
victimMgr._multiSchoolModifiers[mask] = mod;
threat *= mod;
break;
}
}
return threat;
}
@@ -671,7 +676,7 @@ namespace Game.Combat
threatClear.UnitGUID = _owner.GetGUID();
_owner.SendMessageToSet(threatClear, false);
}
public void SendRemoveToClients(Unit victim)
{
ThreatRemove threatRemove = new();
@@ -797,6 +802,8 @@ namespace Game.Combat
// Resets the specified unit's threat to zero
public void ResetThreat(Unit target) { ScaleThreat(target, 0.0f); }
public void RegisterForAIUpdate(ThreatReference refe) { _needsAIUpdate.Add(refe); }
}
public enum TauntState
@@ -827,7 +834,7 @@ namespace Game.Combat
_owner = mgr._owner as Creature;
_mgr = mgr;
_victim = victim;
Online = ShouldBeSuppressed() ? OnlineState.Suppressed : OnlineState.Online;
Online = OnlineState.Offline;
}
public void AddThreat(float amount)
@@ -866,6 +873,7 @@ namespace Game.Combat
{
Online = ShouldBeSuppressed() ? OnlineState.Suppressed : OnlineState.Online;
ListNotifyChanged();
_mgr.RegisterForAIUpdate(this);
}
}