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