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/EasternKingdoms | |
| 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/EasternKingdoms')
5 files changed, 29 insertions, 56 deletions
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp index 438230d622a..f2c8ef442ea 100644 --- a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp +++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp @@ -212,7 +212,7 @@ class FocusedFireTargetSelector : public std::unary_function<Unit *, bool> bool operator() (WorldObject* target) { - if (target == _victim && _me->GetThreatManager().getThreatList().size() > 1) + if (target == _victim && _me->GetThreatManager().GetThreatListSize() > 1) return true; if (target->GetTypeId() != TYPEID_PLAYER) diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 0338a3ad73f..6e0d047514e 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -198,30 +198,21 @@ public: if (!summonedUnit) return; - ThreatContainer::StorageType const& threatlist = me->GetThreatManager().getThreatList(); - ThreatContainer::StorageType::const_iterator i = threatlist.begin(); - for (i = threatlist.begin(); i != threatlist.end(); ++i) + for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) { - Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()); + Unit* unit = ref->GetVictim(); if (unit && unit->IsAlive()) - { - float threat = me->GetThreatManager().getThreat(unit); - AddThreat(unit, threat, summonedUnit); - } + AddThreat(unit, ref->GetThreat(), summonedUnit); } } void TeleportPlayersToSelf() { - float x = KaelLocations[0][0]; - float y = KaelLocations[0][1]; - me->UpdatePosition(x, y, LOCATION_Z, 0.0f); - ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList(); - ThreatContainer::StorageType::const_iterator i = threatlist.begin(); - for (i = threatlist.begin(); i != threatlist.end(); ++i) + me->UpdatePosition(KaelLocations[0][0], KaelLocations[0][1], LOCATION_Z, 0.0f); + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()); - if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = pair.second->GetOther(me); + if (unit->GetTypeId() == TYPEID_PLAYER) unit->CastSpell(unit, SPELL_TELEPORT_CENTER, true); } DoCast(me, SPELL_TELEPORT_CENTER, true); @@ -229,14 +220,11 @@ public: void CastGravityLapseKnockUp() { - ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList(); - ThreatContainer::StorageType::const_iterator i = threatlist.begin(); - for (i = threatlist.begin(); i != threatlist.end(); ++i) + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()); - if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = pair.second->GetOther(me); + if (unit->GetTypeId() == TYPEID_PLAYER) { - // Knockback into the air CastSpellExtraArgs args; args.TriggerFlags = TRIGGERED_FULL_MASK; args.OriginalCaster = me->GetGUID(); @@ -247,12 +235,10 @@ public: void CastGravityLapseFly() // Use Fly Packet hack for now as players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air... { - ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList(); - ThreatContainer::StorageType::const_iterator i = threatlist.begin(); - for (i = threatlist.begin(); i != threatlist.end(); ++i) + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()); - if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = pair.second->GetOther(me); + if (unit->GetTypeId() == TYPEID_PLAYER) { // Also needs an exception in spell system. CastSpellExtraArgs args; @@ -266,12 +252,10 @@ public: void RemoveGravityLapse() { - ThreatContainer::StorageType threatlist = me->GetThreatManager().getThreatList(); - ThreatContainer::StorageType::const_iterator i = threatlist.begin(); - for (i = threatlist.begin(); i != threatlist.end(); ++i) + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()); - if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = pair.second->GetOther(me); + if (unit->GetTypeId() == TYPEID_PLAYER) { unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY); unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT); @@ -684,8 +668,8 @@ public: { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { - AddThreat(target, 1.0f); - me->TauntApply(target); + ResetThreatList(); + AddThreat(target, 1000000.0f); AttackStart(target); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index e50740d8dac..21417362610 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -850,17 +850,12 @@ public: if (Blink_Timer <= diff) { bool InMeleeRange = false; - ThreatContainer::StorageType const& t_list = me->GetThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) + if (pair.second->GetOther(me)->IsWithinMeleeRange(me)) { - //if in melee range - if (target->IsWithinDistInMap(me, 5)) - { - InMeleeRange = true; - break; - } + InMeleeRange = true; + break; } } @@ -944,17 +939,12 @@ public: if (Intercept_Stun_Timer <= diff) { bool InMeleeRange = false; - ThreatContainer::StorageType const& t_list = me->GetThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) + if (pair.second->GetOther(me)->IsWithinMeleeRange(me)) { - //if in melee range - if (target->IsWithinDistInMap(me, ATTACK_DISTANCE)) - { - InMeleeRange = true; - break; - } + InMeleeRange = true; + break; } } diff --git a/src/server/scripts/EasternKingdoms/TheStockade/boss_randolph_moloch.cpp b/src/server/scripts/EasternKingdoms/TheStockade/boss_randolph_moloch.cpp index 901a1522223..573d3c6a4d5 100644 --- a/src/server/scripts/EasternKingdoms/TheStockade/boss_randolph_moloch.cpp +++ b/src/server/scripts/EasternKingdoms/TheStockade/boss_randolph_moloch.cpp @@ -115,7 +115,6 @@ struct boss_randolph_moloch : public BossAI me->RemoveAllAuras(); DoCastSelf(SPELL_VANISH); me->SetReactState(REACT_PASSIVE); - me->SetInCombatState(true); // Prevents the boss from resetting events.ScheduleEvent(EVENT_JUST_VANISHED, 2s); break; case EVENT_JUST_VANISHED: diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 5c63f224ff7..da7fff52dac 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -555,7 +555,7 @@ class DevastatingSlamTargetSelector : public std::unary_function<Unit *, bool> bool operator() (WorldObject* target) { - if (target == _victim && _me->GetThreatManager().getThreatList().size() > 1) + if (target == _victim && _me->GetThreatManager().GetThreatListSize() > 1) return true; if (target->GetTypeId() != TYPEID_PLAYER) @@ -684,7 +684,7 @@ class spell_mandokir_ohgan_orders_trigger : public SpellScriptLoader caster->GetMotionMaster()->Clear(); caster->GetThreatManager().ClearAllThreat(); caster->GetThreatManager().AddThreat(target, 50000000.0f); - caster->TauntApply(target); + // TODO: Fixate mechanic } } |
