From aa5994f457b2178e9153a7020be0150900a9b9f6 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sun, 26 Sep 2021 14:23:30 -0400 Subject: [PATCH] Core/Threat: Re-add fixate system. I am being told Netherspite needs it. Port From (https://github.com/TrinityCore/TrinityCore/commit/16eb5032ad0e8fbc9cd9d3229be65a8f0190347b) --- Source/Game/Chat/Commands/DebugCommands.cs | 3 +- Source/Game/Combat/ThreatManager.cs | 33 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Source/Game/Chat/Commands/DebugCommands.cs b/Source/Game/Chat/Commands/DebugCommands.cs index 04d0fafd2..fdee92923 100644 --- a/Source/Game/Chat/Commands/DebugCommands.cs +++ b/Source/Game/Chat/Commands/DebugCommands.cs @@ -933,10 +933,11 @@ namespace Game.Chat 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:"); count = 0; + Unit fixateVictim = mgr.GetFixateTarget(); foreach (ThreatReference refe in mgr.GetSortedThreatList()) { Unit unit = refe.GetVictim(); - handler.SendSysMessage($" {++count}. {unit.GetName()} ({unit.GetGUID()}) - threat {refe.GetThreat()}[{refe.GetTauntState()}][{refe.GetOnlineState()}]"); + handler.SendSysMessage($" {++count}. {unit.GetName()} ({unit.GetGUID()}) - threat {refe.GetThreat()}[{(unit == fixateVictim ? "FIXATE" : refe.GetTauntState())}][{refe.GetOnlineState()}]"); } handler.SendSysMessage("End of threat list."); } diff --git a/Source/Game/Combat/ThreatManager.cs b/Source/Game/Combat/ThreatManager.cs index 7fb845902..964cf6226 100644 --- a/Source/Game/Combat/ThreatManager.cs +++ b/Source/Game/Combat/ThreatManager.cs @@ -37,6 +37,7 @@ namespace Game.Combat List _sortedThreatList = new(); Dictionary _myThreatListEntries = new(); ThreatReference _currentVictimRef; + ThreatReference _fixateRef; Dictionary _threatenedByMe = new(); // these refs are entries for myself on other units' threat lists public float[] _singleSchoolModifiers = new float[(int)SpellSchools.Max]; // most spells are single school - we pre-calculate these and store them @@ -387,10 +388,38 @@ namespace Game.Combat while (!_myThreatListEntries.Empty()); } + public void FixateTarget(Unit target) + { + if (target) + { + var it = _myThreatListEntries.LookupByKey(target.GetGUID()); + if (it != null) + { + _fixateRef = it; + return; + } + } + _fixateRef = null; + } + + public Unit GetFixateTarget() + { + if (_fixateRef != null) + return _fixateRef.GetVictim(); + else + return null; + } + + public void ClearFixate() { FixateTarget(null); } + ThreatReference ReselectVictim() { + // fixated target is always preferred + if (_fixateRef != null && _fixateRef.IsAvailable()) + return _fixateRef; + ThreatReference oldVictimRef = _currentVictimRef; - if (oldVictimRef != null && !oldVictimRef.IsAvailable()) + if (oldVictimRef != null && oldVictimRef.IsOffline()) oldVictimRef = null; // in 99% of cases - we won't need to actually look at anything beyond the first element @@ -640,6 +669,8 @@ namespace Game.Combat if (_currentVictimRef == refe) _currentVictimRef = null; + if (_fixateRef == refe) + _fixateRef = null; _sortedThreatList.Remove(refe); _sortedThreatList.Sort();