diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2018-01-03 20:04:19 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2021-05-16 21:56:01 +0200 |
| commit | 34c7810fe507eca1b8b9389630db5d5d26d92e77 (patch) | |
| tree | e05653a0adaf4c4f5c406649f1bfe6573cbb22ff /src/server/scripts/Commands | |
| parent | 5158136ee8a77046e37bafa192481b8b61d4a116 (diff) | |
Core: Combat/threat system rewrite (PR #19930)
- PvE combat is now always mutual. UNIT_FLAG_IN_COMBAT is backed by actual references to the units we're in combat with.
- PvP combat is now also tracked, and almost always mutual; spells like Vanish and Feign Death can break this rule. That means we can easily determine a list of players we're fighting.
- By extension, IsInCombatWith now has sensible behavior when invoked on nonplayers.
- Threat and combat systems are no longer the same.
- They still have an enforced relationship (threat implies combat - clearing combat clears threat)...
- ...but we can have combat without threat. A creature (with threat list) isn't considered to be engaged until it has an entry on its threat list...
- ...which means we can now faithfully replicate retail engage behavior. Combat on projectile launch - engagement start on projectile impact. Yay for progress!
- AI method refactor, as already ported in 6113b9d - `JustEngagedWith`, `JustEnteredCombat` and `JustExitedCombat`.
- Vehicle threat is now properly pooled on the main vehicle body (fixes #16542).
- Various edge case bug fixes for threat redirects (Misdirection "cancelling" Vigilance and similar).
- Target re-selection is now significantly faster.
- Fixed a ton of other smaller edge case bugs, probably.
Closes #7951 and #19998.
(cherry picked from commit 532ab1c7f8653d1a2e48aa1f1f8a9ba1041d4bb7)
Diffstat (limited to 'src/server/scripts/Commands')
| -rw-r--r-- | src/server/scripts/Commands/cs_debug.cpp | 97 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 1 |
2 files changed, 73 insertions, 25 deletions
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 15372bc0882..b46b8cfd978 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -846,23 +846,73 @@ public: static bool HandleDebugThreatListCommand(ChatHandler* handler, char const* /*args*/) { - Creature* target = handler->getSelectedCreature(); - if (!target || target->IsTotem() || target->IsPet()) - return false; + Unit* target = handler->getSelectedUnit(); + if (!target) + target = handler->GetSession()->GetPlayer(); + + ThreatManager& mgr = target->GetThreatManager(); + if (!target->IsAlive()) + { + handler->PSendSysMessage("%s (%s) is not alive.", target->GetName().c_str(), target->GetGUID().ToString().c_str()); + return true; + } + if (!target->CanHaveThreatList()) + handler->PSendSysMessage("%s (%s) cannot have a threat list.", target->GetName().c_str(), target->GetGUID().ToString().c_str()); - ThreatContainer::StorageType const& threatList = target->GetThreatManager().getThreatList(); - ThreatContainer::StorageType::const_iterator itr; uint32 count = 0; - handler->PSendSysMessage("Threat list of %s (%s)", target->GetName().c_str(), target->GetGUID().ToString().c_str()); - for (itr = threatList.begin(); itr != threatList.end(); ++itr) + auto const& threatenedByMe = target->GetThreatManager().GetThreatenedByMeList(); + if (threatenedByMe.empty()) + handler->PSendSysMessage("%s (%s) does not threaten any units.", target->GetName().c_str(), target->GetGUID().ToString().c_str()); + else { - Unit* unit = (*itr)->getTarget(); - if (!unit) - continue; - ++count; - handler->PSendSysMessage(" %u. %s (%s) - threat %f", count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), (*itr)->getThreat()); + handler->PSendSysMessage("List of units threatened by %s (%s)", target->GetName().c_str(), target->GetGUID().ToString().c_str()); + for (auto const& pair : threatenedByMe) + { + Unit* unit = pair.second->GetOwner(); + handler->PSendSysMessage(" %u. %s (%s, SpawnID %u) - threat %f", ++count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0, pair.second->GetThreat()); + } + handler->SendSysMessage("End of threatened-by-me list."); } - handler->SendSysMessage("End of threat list."); + + if (!mgr.CanHaveThreatList()) + return true; + if (mgr.IsEngaged()) + { + count = 0; + handler->PSendSysMessage("Threat list of %s (%s, SpawnID %u)", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0); + for (ThreatReference const* ref : mgr.GetSortedThreatList()) + { + Unit* unit = ref->GetVictim(); + char const* onlineStr; + switch (ref->GetOnlineState()) + { + case ThreatReference::ONLINE_STATE_SUPPRESSED: + onlineStr = " [SUPPRESSED]"; + break; + case ThreatReference::ONLINE_STATE_OFFLINE: + onlineStr = " [OFFLINE]"; + break; + default: + onlineStr = ""; + } + char const* tauntStr; + switch (ref->GetTauntState()) + { + case ThreatReference::TAUNT_STATE_TAUNT: + tauntStr = " [TAUNT]"; + break; + case ThreatReference::TAUNT_STATE_DETAUNT: + tauntStr = " [DETAUNT]"; + break; + default: + tauntStr = ""; + } + handler->PSendSysMessage(" %u. %s (%s) - threat %f%s%s", ++count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), ref->GetThreat(), tauntStr, onlineStr); + } + handler->SendSysMessage("End of threat list."); + } + else + handler->PSendSysMessage("%s (%s, SpawnID %u) is not currently engaged.", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0); return true; } @@ -871,19 +921,18 @@ public: Unit* target = handler->getSelectedUnit(); if (!target) target = handler->GetSession()->GetPlayer(); - HostileReference* ref = target->getHostileRefManager().getFirst(); - uint32 count = 0; - handler->PSendSysMessage("Hostil reference list of %s (%s)", target->GetName().c_str(), target->GetGUID().ToString().c_str()); - while (ref) + + handler->PSendSysMessage("Combat refs: (Combat state: %d | Manager state: %d)", target->IsInCombat(), target->GetCombatManager().HasCombat()); + for (auto const& ref : target->GetCombatManager().GetPvPCombatRefs()) { - if (Unit* unit = ref->GetSource()->GetOwner()) - { - ++count; - handler->PSendSysMessage(" %u. %s (%s, SpawnId: %s) - threat %f", count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), unit->GetTypeId() == TYPEID_UNIT ? std::to_string(unit->ToCreature()->GetSpawnId()).c_str() : "0", ref->getThreat()); - } - ref = ref->next(); + Unit* unit = ref.second->GetOther(target); + handler->PSendSysMessage("[PvP] %s (SpawnID %u)", unit->GetName().c_str(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0); + } + for (auto const& ref : target->GetCombatManager().GetPvECombatRefs()) + { + Unit* unit = ref.second->GetOther(target); + handler->PSendSysMessage("[PvE] %s (SpawnID %u)", unit->GetName().c_str(), unit->GetTypeId() == TYPEID_UNIT ? unit->ToCreature()->GetSpawnId() : 0); } - handler->SendSysMessage("End of hostil reference list."); return true; } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 0b3547670bc..c8fe798fcaf 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2491,7 +2491,6 @@ public: return false; target->CombatStop(); - target->getHostileRefManager().deleteReferences(); return true; } |
