diff options
Diffstat (limited to 'src/server/scripts')
24 files changed, 246 insertions, 244 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; } 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 } } diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp index 6c7f00f9b32..e0198304477 100644 --- a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp +++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp @@ -635,7 +635,7 @@ class spell_alysrazor_aggro_closest : public SpellScriptLoader void HandleEffect(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - float curThreat = GetCaster()->GetThreatManager().getThreat(GetHitUnit(), true); + float curThreat = GetCaster()->GetThreatManager().GetThreat(GetHitUnit(), true); GetCaster()->GetThreatManager().AddThreat(GetHitUnit(), -curThreat + 50000.0f / std::min(1.0f, GetCaster()->GetDistance(GetHitUnit()))); } diff --git a/src/server/scripts/Kalimdor/Firelands/firelands.cpp b/src/server/scripts/Kalimdor/Firelands/firelands.cpp index 572e9a02f9f..6367bc88611 100644 --- a/src/server/scripts/Kalimdor/Firelands/firelands.cpp +++ b/src/server/scripts/Kalimdor/Firelands/firelands.cpp @@ -233,7 +233,7 @@ struct npc_firelands_magmakin : public ScriptedAI return; AddThreat(target, 50000000.0f); - me->TauntApply(target); + // TODO: Fixate mechanic } void UpdateAI(uint32 /*diff*/) override diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp index a491b553763..6824bc68385 100644 --- a/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp +++ b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp @@ -267,13 +267,13 @@ class npc_rock_borer : public CreatureScript { me->SetDisableGravity(true); me->SetReactState(REACT_PASSIVE); - events.ScheduleEvent(EVENT_EMERGED, 1200); - events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer } - void IsSummonedBy(Unit* summoner) override + void IsSummonedBy(Unit* /*summoner*/) override { - me->SetInCombatState(false, summoner); + events.ScheduleEvent(EVENT_EMERGED, 1200); + events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer + DoZoneInCombat(); DoCast(me, SPELL_ROCK_BORER_EMERGE); } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index 86632ed7e99..31d5a9a3e26 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -41,6 +41,7 @@ enum Spells SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947, SPELL_EMBRACE_OF_THE_VAMPYR = 55959, SPELL_VANISH = 55964, + SPELL_SHADOWSTEP = 55966, NPC_FLAME_SPHERE_1 = 30106, NPC_FLAME_SPHERE_2 = 31686, @@ -77,9 +78,8 @@ enum Events EVENT_CONJURE_FLAME_SPHERES = 1, EVENT_BLOODTHIRST, EVENT_VANISH, - EVENT_JUST_VANISHED, - EVENT_VANISHED, - EVENT_FEEDING, + EVENT_START_FEEDING, + EVENT_DONE_FEEDING, // Flame Sphere EVENT_START_MOVE, @@ -97,6 +97,7 @@ class boss_prince_taldaram : public CreatureScript { me->SetDisableGravity(true); _embraceTakenDamage = 0; + _initialCheckTimer = 3000; } void Reset() override @@ -140,8 +141,30 @@ class boss_prince_taldaram : public CreatureScript void UpdateAI(uint32 diff) override { - if (!UpdateVictim()) - return; + if (_initialCheckTimer) + { + if (_initialCheckTimer <= diff) + { + CheckSpheres(); + _initialCheckTimer = 0; + } + else + _initialCheckTimer -= diff; + } + + if (me->HasAura(SPELL_VANISH)) + { + if (me->GetThreatManager().IsThreatListEmpty(true)) + { + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + return; + } + } + else + { + if (!UpdateVictim()) + return; + } events.Update(diff); @@ -167,47 +190,29 @@ class boss_prince_taldaram : public CreatureScript break; case EVENT_VANISH: { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - uint32 targets = 0; - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - { - Player* player = i->GetSource(); - if (player && player->IsAlive()) - ++targets; - } - - if (targets > 2) + if (me->GetThreatManager().GetThreatListSize() > 1) { + if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + _embraceTargetGUID = embraceTarget->GetGUID(); Talk(SAY_VANISH); DoCast(me, SPELL_VANISH); - me->SetInCombatState(true); // Prevents the boss from resetting events.DelayEvents(500); - events.ScheduleEvent(EVENT_JUST_VANISHED, 500); - if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) - _embraceTargetGUID = embraceTarget->GetGUID(); + events.ScheduleEvent(EVENT_START_FEEDING, 2000); } events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000)); break; } - case EVENT_JUST_VANISHED: + case EVENT_START_FEEDING: + me->RemoveAurasDueToSpell(SPELL_VANISH); if (Unit* embraceTarget = GetEmbraceTarget()) { - me->GetMotionMaster()->Clear(); - me->SetSpeedRate(MOVE_WALK, 2.0f); - me->GetMotionMaster()->MoveChase(embraceTarget); - } - events.ScheduleEvent(EVENT_VANISHED, 1300); - break; - case EVENT_VANISHED: - if (Unit* embraceTarget = GetEmbraceTarget()) + DoCast(embraceTarget, SPELL_SHADOWSTEP); DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR); - Talk(SAY_FEED); - me->GetMotionMaster()->Clear(); - me->SetSpeedRate(MOVE_WALK, 1.0f); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - events.ScheduleEvent(EVENT_FEEDING, 20000); + Talk(SAY_FEED); + events.ScheduleEvent(EVENT_DONE_FEEDING, 20000); + } break; - case EVENT_FEEDING: + case EVENT_DONE_FEEDING: _embraceTargetGUID.Clear(); break; default: @@ -289,6 +294,7 @@ class boss_prince_taldaram : public CreatureScript ObjectGuid _flameSphereTargetGUID; ObjectGuid _embraceTargetGUID; uint32 _embraceTakenDamage; + uint32 _initialCheckTimer; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp index 7b3946364bb..9f99e018345 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp @@ -163,13 +163,9 @@ public: bool IsInCombatWithPlayer() const { - std::list<HostileReference*> const& refs = me->GetThreatManager().getThreatList(); - for (HostileReference const* hostileRef : refs) - { - if (Unit const* target = hostileRef->getTarget()) - if (target->IsControlledByPlayer()) - return true; - } + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) + if (pair.second->GetOther(me)->IsControlledByPlayer()) + return true; return false; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index dea9b160e08..7ea2afc6e84 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -820,7 +820,7 @@ class npc_anubarak_spike : public CreatureScript DoCast(who, SPELL_MARK); me->SetSpeedRate(MOVE_RUN, 0.5f); // make sure the Spine will really follow the one he should - ResetThreatList(); + me->GetThreatManager().ResetAllThreat(); me->SetInCombatWithZone(); AddThreat(who, 1000000.0f); me->GetMotionMaster()->Clear(true); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 1adc7eb9abf..658d4bb80a6 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -672,14 +672,10 @@ struct boss_faction_championsAI : public BossAI Unit* SelectEnemyCaster(bool /*casting*/) { - std::list<HostileReference*> const& tList = me->GetThreatManager().getThreatList(); - std::list<HostileReference*>::const_iterator iter; - for (iter = tList.begin(); iter!=tList.end(); ++iter) - { - Unit* target = ObjectAccessor::GetUnit(*me, (*iter)->getUnitGuid()); - if (target && target->GetPowerType() == POWER_MANA) - return target; - } + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) + if (Player* player = pair.second->GetOther(me)->ToPlayer()) + if (player->GetPowerType() == POWER_MANA) + return player; return nullptr; } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 29cb72ebb40..93fe8951d72 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -1342,7 +1342,7 @@ class npc_the_lich_king_escape_hor : public CreatureScript AttackStart(victim); return me->GetVictim() != nullptr; } - else if (me->GetThreatManager().GetThreatListSize() < 2 && me->HasAura(SPELL_REMORSELESS_WINTER)) + else if (me->GetCombatManager().GetPvECombatRefs().size() < 2 && me->HasAura(SPELL_REMORSELESS_WINTER)) { EnterEvadeMode(EVADE_REASON_OTHER); return false; diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp index 938d3701368..b6cebf1c172 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp @@ -148,15 +148,12 @@ class boss_drakkari_colossus : public CreatureScript if (me->GetReactState() == REACT_AGGRESSIVE) return; - me->SetReactState(REACT_AGGRESSIVE); me->SetImmuneToPC(false); + me->SetReactState(REACT_AGGRESSIVE); me->RemoveAura(SPELL_FREEZE_ANIM); me->SetInCombatWithZone(); - if (me->GetVictim()) - me->GetMotionMaster()->MoveChase(me->GetVictim(), 0, 0); - break; } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index a80874a211e..01213a9009d 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -559,25 +559,15 @@ class npc_green_dragon_combat_trigger : public CreatureScript if (!me->IsInCombat()) return; - // @TODO check out of bounds on all encounter creatures, evade if matched - - std::list<HostileReference*> const& threatList = me->GetThreatManager().getThreatList(); - if (threatList.empty()) - { - EnterEvadeMode(); - return; - } - // check evade every second tick _evadeCheck ^= true; if (!_evadeCheck) return; - // check if there is any player on threatlist, if not - evade - for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) - if (Unit* target = (*itr)->getTarget()) - if (target->GetTypeId() == TYPEID_PLAYER) - return; // found any player, return + // check if there is any player engaged, if not - evade + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) + if (pair.second->GetOther(me)->GetTypeId() == TYPEID_PLAYER) + return; EnterEvadeMode(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index 8ddc4d1a7dc..8737e8a2425 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -489,12 +489,11 @@ class boss_hodir : public CreatureScript if (gettingColdInHereTimer <= diff && gettingColdInHere) { - std::list<HostileReference*> ThreatList = me->GetThreatManager().getThreatList(); - for (std::list<HostileReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr) - if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) + if (Player* target = pair.second->GetOther(me)->ToPlayer()) if (Aura* BitingColdAura = target->GetAura(SPELL_BITING_COLD_TRIGGERED)) - if ((target->GetTypeId() == TYPEID_PLAYER) && (BitingColdAura->GetStackAmount() > 2)) - SetData(DATA_GETTING_COLD_IN_HERE, 0); + if (BitingColdAura->GetStackAmount() > 2) + SetData(DATA_GETTING_COLD_IN_HERE, 0); gettingColdInHereTimer = 1000; } else diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index f3b6d1af83e..7dd7fe30571 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -198,7 +198,7 @@ class boss_ingvar_the_plunderer : public CreatureScript void UpdateAI(uint32 diff) override { - if (!events.IsInPhase(PHASE_EVENT) && !UpdateVictim()) + if (!UpdateVictim()) return; events.Update(diff); @@ -231,9 +231,7 @@ class boss_ingvar_the_plunderer : public CreatureScript ScheduleSecondPhase(); me->RemoveUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)); me->SetImmuneToPC(false); - if (Unit* target = me->GetThreatManager().SelectVictim()) - AttackStart(target); - else + if (!me->IsThreatened()) { EnterEvadeMode(EVADE_REASON_NO_HOSTILES); return; diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp index 748e04ba3d0..2ab98e53093 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp @@ -184,7 +184,7 @@ class spell_toravon_random_aggro : public SpellScript if (!caster->IsAIEnabled) return; - caster->GetThreatManager().resetAllAggro(); + caster->GetThreatManager().ResetAllThreat(); if (Unit* target = caster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1)) caster->GetThreatManager().AddThreat(target, 1000000); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 45a8e390b9c..ed8f1eb38d5 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -38,6 +38,7 @@ enum HunterSpells SPELL_HUNTER_EXHILARATION_R2 = 231546, SPELL_HUNTER_LONE_WOLF = 155228, SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305, + SPELL_HUNTER_MISDIRECTION = 34477, SPELL_HUNTER_MISDIRECTION_PROC = 35079, SPELL_HUNTER_MULTI_SHOT_FOCUS = 213363, SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479, @@ -297,12 +298,7 @@ class spell_hun_misdirection : public SpellScriptLoader return; if (!GetTarget()->HasAura(SPELL_HUNTER_MISDIRECTION_PROC)) - GetTarget()->ResetRedirectThreat(); - } - - bool CheckProc(ProcEventInfo& /*eventInfo*/) - { - return GetTarget()->GetRedirectThreatTarget() != nullptr; + GetTarget()->GetThreatManager().UnregisterRedirectThreat(SPELL_HUNTER_MISDIRECTION); } void HandleProc(AuraEffect* aurEff, ProcEventInfo& /*eventInfo*/) @@ -314,7 +310,6 @@ class spell_hun_misdirection : public SpellScriptLoader void Register() override { AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - DoCheckProc += AuraCheckProcFn(spell_hun_misdirection_AuraScript::CheckProc); OnEffectProc += AuraEffectProcFn(spell_hun_misdirection_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); } }; @@ -337,7 +332,7 @@ class spell_hun_misdirection_proc : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetTarget()->ResetRedirectThreat(); + GetTarget()->GetThreatManager().UnregisterRedirectThreat(SPELL_HUNTER_MISDIRECTION); } void Register() override diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 003b55c260e..25ba6f0006d 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -51,6 +51,7 @@ enum RogueSpells SPELL_ROGUE_STEALTH_STEALTH_AURA = 158185, SPELL_ROGUE_STEALTH_SHAPESHIFT_AURA = 158188, SPELL_ROGUE_VANISH_AURA = 11327, + SPELL_ROGUE_TRICKS_OF_THE_TRADE = 57934, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, SPELL_ROGUE_HONOR_AMONG_THIEVES_ENERGIZE = 51699, SPELL_ROGUE_T5_2P_SET_BONUS = 37169 @@ -507,82 +508,78 @@ class spell_rog_vanish_aura : public SpellScriptLoader }; // 57934 - Tricks of the Trade -class spell_rog_tricks_of_the_trade : public SpellScriptLoader +class spell_rog_tricks_of_the_trade_aura : public AuraScript { - public: - spell_rog_tricks_of_the_trade() : SpellScriptLoader("spell_rog_tricks_of_the_trade") { } + PrepareAuraScript(spell_rog_tricks_of_the_trade_aura); - class spell_rog_tricks_of_the_trade_AuraScript : public AuraScript - { - PrepareAuraScript(spell_rog_tricks_of_the_trade_AuraScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC }); - } + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT || !GetTarget()->HasAura(SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC)) + GetTarget()->GetThreatManager().UnregisterRedirectThreat(SPELL_ROGUE_TRICKS_OF_THE_TRADE); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) - GetTarget()->ResetRedirectThreat(); - } + void HandleProc(AuraEffect* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); - bool CheckProc(ProcEventInfo& /*eventInfo*/) - { - _redirectTarget = GetTarget()->GetRedirectThreatTarget(); - return _redirectTarget != nullptr; - } + Unit* rogue = GetTarget(); + if (ObjectAccessor::GetUnit(*rogue, _redirectTarget)) + rogue->CastSpell(rogue, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC, aurEff); + Remove(AURA_REMOVE_BY_DEFAULT); + } - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_aura::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectProc += AuraEffectProcFn(spell_rog_tricks_of_the_trade_aura::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + } - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC, true); - Remove(AURA_REMOVE_BY_DEFAULT); // maybe handle by proc charges - } + ObjectGuid _redirectTarget; +public: + void SetRedirectTarget(ObjectGuid guid) { _redirectTarget = guid; } +}; - void Register() override +class spell_rog_tricks_of_the_trade : public SpellScript +{ + PrepareSpellScript(spell_rog_tricks_of_the_trade); + + void DoAfterHit() + { + if (Aura* aura = GetHitAura()) + if (auto* script = aura->GetScript<spell_rog_tricks_of_the_trade_aura>("spell_rog_tricks_of_the_trade")) { - AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - DoCheckProc += AuraCheckProcFn(spell_rog_tricks_of_the_trade_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_rog_tricks_of_the_trade_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); + if (Unit* explTarget = GetExplTargetUnit()) + script->SetRedirectTarget(explTarget->GetGUID()); + else + script->SetRedirectTarget(ObjectGuid::Empty); } + } - Unit* _redirectTarget = nullptr; - }; - - AuraScript* GetAuraScript() const override - { - return new spell_rog_tricks_of_the_trade_AuraScript(); - } + void Register() override + { + AfterHit += SpellHitFn(spell_rog_tricks_of_the_trade::DoAfterHit); + } }; // 59628 - Tricks of the Trade (Proc) -class spell_rog_tricks_of_the_trade_proc : public SpellScriptLoader +class spell_rog_tricks_of_the_trade_proc : public AuraScript { - public: - spell_rog_tricks_of_the_trade_proc() : SpellScriptLoader("spell_rog_tricks_of_the_trade_proc") { } + PrepareAuraScript(spell_rog_tricks_of_the_trade_proc); - class spell_rog_tricks_of_the_trade_proc_AuraScript : public AuraScript - { - PrepareAuraScript(spell_rog_tricks_of_the_trade_proc_AuraScript); - - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->ResetRedirectThreat(); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_proc_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->GetThreatManager().UnregisterRedirectThreat(SPELL_ROGUE_TRICKS_OF_THE_TRADE); + } - AuraScript* GetAuraScript() const override - { - return new spell_rog_tricks_of_the_trade_proc_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_tricks_of_the_trade_proc::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 198031 - Honor Among Thieves @@ -704,8 +701,8 @@ void AddSC_rogue_spell_scripts() new spell_rog_stealth(); new spell_rog_vanish(); new spell_rog_vanish_aura(); - new spell_rog_tricks_of_the_trade(); - new spell_rog_tricks_of_the_trade_proc(); + RegisterSpellAndAuraScriptPair(spell_rog_tricks_of_the_trade, spell_rog_tricks_of_the_trade_aura); + RegisterAuraScript(spell_rog_tricks_of_the_trade_proc); new spell_rog_honor_among_thieves(); new spell_rog_eviscerate(); new spell_rog_envenom(); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 163c867d71d..1740f3291f9 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -51,7 +51,7 @@ enum WarlockSpells SPELL_WARLOCK_RAIN_OF_FIRE_DAMAGE = 42223, SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE = 27285, SPELL_WARLOCK_SEED_OF_CORRUPTION_GENERIC = 32865, - SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_SOULSHATTER_EFFECT = 32835, SPELL_WARLOCK_SOUL_SWAP_CD_MARKER = 94229, SPELL_WARLOCK_SOUL_SWAP_OVERRIDE = 86211, SPELL_WARLOCK_SOUL_SWAP_MOD_COST = 92794, @@ -815,15 +815,15 @@ class spell_warl_soulshatter : public SpellScriptLoader bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_WARLOCK_SOULSHATTER }); + return ValidateSpellInfo({ SPELL_WARLOCK_SOULSHATTER_EFFECT }); } void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) - if (target->CanHaveThreatList() && target->GetThreatManager().IsThreatenedBy(caster, true)) - caster->CastSpell(target, SPELL_WARLOCK_SOULSHATTER, true); + if (target->GetThreatManager().IsThreatenedBy(caster, true)) + caster->CastSpell(target, SPELL_WARLOCK_SOULSHATTER_EFFECT, true); } void Register() override diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 3c8dac9d8de..0591f7c4a76 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1806,21 +1806,28 @@ public: { case EVENT_TD_CHECK_COMBAT: { - time_t now = GameTime::GetGameTime(); - for (std::unordered_map<ObjectGuid, time_t>::iterator itr = _damageTimes.begin(); itr != _damageTimes.end();) + time_t const now = GameTime::GetGameTime(); + auto const& pveRefs = me->GetCombatManager().GetPvECombatRefs(); + for (auto itr = _damageTimes.begin(); itr != _damageTimes.end();) { // If unit has not dealt damage to training dummy for 5 seconds, remove him from combat if (itr->second < now - 5) { - if (Unit* unit = ObjectAccessor::GetUnit(*me, itr->first)) - unit->getHostileRefManager().deleteReference(me); + auto it = pveRefs.find(itr->first); + if (it != pveRefs.end()) + it->second->EndCombat(); itr = _damageTimes.erase(itr); } else ++itr; } - _events.ScheduleEvent(EVENT_TD_CHECK_COMBAT, 1000); + + for (auto const& pair : pveRefs) + if (_damageTimes.find(pair.first) == _damageTimes.end()) + _damageTimes[pair.first] = now; + + _events.Repeat(1s); break; } case EVENT_TD_DESPAWN: |
