diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index c6ffa1462..86a331eed 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -108,14 +108,14 @@ void UnitAI::DoSpellAttackToRandomTargetIfReady(uint32 spell, uint32 threatTable } } -Unit* UnitAI::SelectTarget(SelectTargetMethod targetType, uint32 position, float dist, bool playerOnly, int32 aura) +Unit* UnitAI::SelectTarget(SelectTargetMethod targetType, uint32 position, float dist, bool playerOnly, bool withTank, int32 aura) { - return SelectTarget(targetType, position, DefaultTargetSelector(me, dist, playerOnly, aura)); + return SelectTarget(targetType, position, DefaultTargetSelector(me, dist, playerOnly, withTank, aura)); } -void UnitAI::SelectTargetList(std::list& targetList, uint32 num, SelectTargetMethod targetType, float dist, bool playerOnly, int32 aura) +void UnitAI::SelectTargetList(std::list& targetList, uint32 num, SelectTargetMethod targetType, uint32 position, float dist, bool playerOnly, bool withTank, int32 aura) { - SelectTargetList(targetList, DefaultTargetSelector(me, dist, playerOnly, aura), num, targetType); + SelectTargetList(targetList, num, targetType, position, DefaultTargetSelector(me, dist, playerOnly, withTank, aura)); } float UnitAI::DoGetSpellMaxRange(uint32 spellId, bool positive) @@ -210,7 +210,7 @@ SpellCastResult UnitAI::DoCast(uint32 spellId) bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER); float range = spellInfo->GetMaxRange(false); - DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId); + DefaultTargetSelector targetSelector(me, range, playerOnly, true, -(int32)spellId); if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM) && targetSelector(me->GetVictim())) target = me->GetVictim(); @@ -317,6 +317,16 @@ void UnitAI::FillAISpellInfo() } } +ThreatMgr& UnitAI::GetThreatMgr() +{ + return me->GetThreatMgr(); +} + +void UnitAI::SortByDistance(std::list& list, bool ascending) +{ + list.sort(Acore::ObjectDistanceOrderPred(me, ascending)); +} + //Enable PlayerAI when charmed void PlayerAI::OnCharmed(bool apply) { @@ -397,5 +407,8 @@ bool NonTankTargetSelector::operator()(Unit const* target) const if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER) return false; + if (Unit* currentVictim = _source->GetThreatMgr().GetCurrentVictim()) + return target != currentVictim; + return target != _source->GetVictim(); } diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 1070a2ba5..d5288c4e4 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -43,14 +43,16 @@ struct DefaultTargetSelector : public Acore::unary_function { Unit const* me; float m_dist; + Unit const* except; bool m_playerOnly; int32 m_aura; // unit: the reference unit // dist: if 0: ignored, if > 0: maximum distance to the reference unit, if < 0: minimum distance to the reference unit // playerOnly: self explaining + // withMainTank: allow current tank to be selected // aura: if 0: ignored, if > 0: the target shall have the aura, if < 0, the target shall NOT have the aura - DefaultTargetSelector(Unit const* unit, float dist, bool playerOnly, int32 aura) : me(unit), m_dist(dist), m_playerOnly(playerOnly), m_aura(aura) {} + DefaultTargetSelector(Unit const* unit, float dist, bool playerOnly, bool withMainTank, int32 aura) : me(unit), m_dist(dist), except(withMainTank ? me->GetThreatMgr().GetCurrentVictim() : nullptr), m_playerOnly(playerOnly), m_aura(aura) {} bool operator()(Unit const* target) const { @@ -60,6 +62,9 @@ struct DefaultTargetSelector : public Acore::unary_function if (!target) return false; + if (target == except) + return false; + if (m_playerOnly && (target->GetTypeId() != TYPEID_PLAYER)) return false; @@ -208,7 +213,7 @@ public: // - Not the current tank (if withTank = false) // - Has aura with ID (if aura > 0) // - Does not have aura with ID - (if aura < 0) - Unit* SelectTarget(SelectTargetMethod targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, int32 aura = 0); + Unit* SelectTarget(SelectTargetMethod targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, bool withTank = true, int32 aura = 0); // Select the best target (in order) satisfying from the threat list. // If is nonzero, the first entries in order (or SelectTargetMethod::MaxThreat @@ -216,48 +221,30 @@ public: template Unit* SelectTarget(SelectTargetMethod targetType, uint32 position, PREDICATE const& predicate) { - ThreatContainer::StorageType const& threatlist = me->GetThreatMgr().GetThreatList(); - if (position >= threatlist.size()) + ThreatMgr& mgr = GetThreatMgr(); + // shortcut: if we ignore the first elements, and there are at most elements, then we ignore ALL elements + if (mgr.GetThreatListSize() <= position) return nullptr; std::list targetList; - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) - if (predicate((*itr)->getTarget())) - targetList.push_back((*itr)->getTarget()); + SelectTargetList(targetList, mgr.GetThreatListSize(), targetType, position, predicate); - if (position >= targetList.size()) + // maybe nothing fulfills the predicate + if (targetList.empty()) return nullptr; - if (targetType == SelectTargetMethod::MaxDistance || targetType == SelectTargetMethod::MinDistance) - targetList.sort(Acore::ObjectDistanceOrderPred(me)); - switch (targetType) { - case SelectTargetMethod::MaxDistance: - case SelectTargetMethod::MaxThreat: - { - std::list::iterator itr = targetList.begin(); - std::advance(itr, position); - return *itr; - } - case SelectTargetMethod::MinDistance: - case SelectTargetMethod::MinThreat: - { - std::list::reverse_iterator ritr = targetList.rbegin(); - std::advance(ritr, position); - return *ritr; - } - case SelectTargetMethod::Random: - { - std::list::iterator itr = targetList.begin(); - std::advance(itr, urand(position, targetList.size() - 1)); - return *itr; - } - default: - break; + case SelectTargetMethod::MaxThreat: + case SelectTargetMethod::MinThreat: + case SelectTargetMethod::MaxDistance: + case SelectTargetMethod::MinDistance: + return targetList.front(); + case SelectTargetMethod::Random: + return Acore::Containers::SelectRandomContainerElement(targetList); + default: + return nullptr; } - - return nullptr; } // Select the best (up to) targets (in order) from the threat list that fulfill the following: @@ -270,35 +257,79 @@ public: // - Has aura with ID (if aura > 0) // - Does not have aura with ID - (if aura < 0) // The resulting targets are stored in (which is cleared first). - void SelectTargetList(std::list& targetList, uint32 num, SelectTargetMethod targetType, float dist = 0.0f, bool playerOnly = false, int32 aura = 0); + void SelectTargetList(std::list& targetList, uint32 num, SelectTargetMethod targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, bool withTank = true, int32 aura = 0); // Select the best (up to) targets (in order) satisfying from the threat list and stores them in (which is cleared first). // If is nonzero, the first entries in order (or SelectTargetMethod::MaxThreat // order, if is SelectTargetMethod::Random) are skipped. template - void SelectTargetList(std::list& targetList, PREDICATE const& predicate, uint32 maxTargets, SelectTargetMethod targetType) + void SelectTargetList(std::list& targetList, uint32 num, SelectTargetMethod targetType, uint32 position, PREDICATE const& predicate) { - ThreatContainer::StorageType const& threatlist = me->GetThreatMgr().GetThreatList(); - if (threatlist.empty()) - return; - - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) - if (predicate((*itr)->getTarget())) - targetList.push_back((*itr)->getTarget()); - - if (targetList.size() < maxTargets) + targetList.clear(); + ThreatMgr& mgr = GetThreatMgr(); + // shortcut: we're gonna ignore the first elements, and there's at most elements, so we ignore them all - nothing to do here + if (mgr.GetThreatListSize() <= position) return; if (targetType == SelectTargetMethod::MaxDistance || targetType == SelectTargetMethod::MinDistance) - targetList.sort(Acore::ObjectDistanceOrderPred(me)); + { + for (ThreatReference const* ref : mgr.GetUnsortedThreatList()) + { + if (ref->IsOffline()) + continue; - if (targetType == SelectTargetMethod::MinDistance || targetType == SelectTargetMethod::MinThreat) + targetList.push_back(ref->GetVictim()); + } + } + else + { + Unit* currentVictim = mgr.GetCurrentVictim(); + if (currentVictim) + targetList.push_back(currentVictim); + + for (ThreatReference const* ref : mgr.GetSortedThreatList()) + { + if (ref->IsOffline()) + continue; + + Unit* thisTarget = ref->GetVictim(); + if (thisTarget != currentVictim) + targetList.push_back(thisTarget); + } + } + + // shortcut: the list isn't gonna get any larger + if (targetList.size() <= position) + { + targetList.clear(); + return; + } + + // right now, list is unsorted for DISTANCE types - re-sort by SelectTargetMethod::MaxDistance + if (targetType == SelectTargetMethod::MaxDistance || targetType == SelectTargetMethod::MinDistance) + SortByDistance(targetList, targetType == SelectTargetMethod::MinDistance); + + // now the list is MAX sorted, reverse for MIN types + if (targetType == SelectTargetMethod::MinThreat) targetList.reverse(); + // ignore the first elements + while (position) + { + targetList.pop_front(); + --position; + } + + // then finally filter by predicate + targetList.remove_if([&predicate](Unit* target) { return !predicate(target); }); + + if (targetList.size() <= num) + return; + if (targetType == SelectTargetMethod::Random) - Acore::Containers::RandomResize(targetList, maxTargets); + Acore::Containers::RandomResize(targetList, num); else - targetList.resize(maxTargets); + targetList.resize(num); } // Called at any Damage to any victim (before damage apply) @@ -348,6 +379,10 @@ public: virtual void sOnGameEvent(bool /*start*/, uint16 /*eventId*/) {} virtual std::string GetDebugInfo() const; + +private: + ThreatMgr& GetThreatMgr(); + void SortByDistance(std::list& list, bool ascending = true); }; class PlayerAI : public UnitAI diff --git a/src/server/game/Combat/ThreatMgr.h b/src/server/game/Combat/ThreatMgr.h index 7196e5638..846a1fd28 100644 --- a/src/server/game/Combat/ThreatMgr.h +++ b/src/server/game/Combat/ThreatMgr.h @@ -225,6 +225,9 @@ public: [[nodiscard]] bool isThreatListEmpty() const { return iThreatContainer.empty(); } [[nodiscard]] bool areThreatListsEmpty() const { return iThreatContainer.empty() && iThreatOfflineContainer.empty(); } + Acore::IteratorPair::const_iterator> GetSortedThreatList() const { auto& list = iThreatContainer.GetThreatList(); return { list.cbegin(), list.cend() }; } + Acore::IteratorPair::const_iterator> GetUnsortedThreatList() const { return GetSortedThreatList(); } + void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent); bool isNeedUpdateToClient(uint32 time); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp index 306d12a43..5e7440045 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp @@ -95,7 +95,7 @@ public: } case EVENT_IGNITE_MANA: { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, -SPELL_IGNITE_MANA)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_IGNITE_MANA)) { DoCast(target, SPELL_IGNITE_MANA); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_magmadar.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_magmadar.cpp index 951c86d49..786fef38f 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_magmadar.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_magmadar.cpp @@ -94,10 +94,10 @@ public: case EVENT_LAVA_BOMB_RANGED: { std::list targets; - SelectTargetList(targets, [this](Unit* target) + SelectTargetList(targets, 1, SelectTargetMethod::Random, 1, [this](Unit* target) { return target && target->IsPlayer() && target->GetDistance(me) > MELEE_TARGET_LOOKUP_DIST && target->GetDistance(me) < 100.0f; - }, 1, SelectTargetMethod::Random); + }); if (!targets.empty()) { diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp index e18944ee4..c079c9915 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp @@ -71,7 +71,7 @@ public: } case EVENT_SHAZZRAH_CURSE: { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, -SPELL_SHAZZRAH_CURSE)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_SHAZZRAH_CURSE)) { DoCast(target, SPELL_SHAZZRAH_CURSE); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_sulfuron_harbinger.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_sulfuron_harbinger.cpp index 516291820..f4f868736 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_sulfuron_harbinger.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_sulfuron_harbinger.cpp @@ -174,7 +174,7 @@ public: } case EVENT_SHADOW_WORD_PAIN: { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, -SPELL_SHADOW_WORD_PAIN)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_SHADOW_WORD_PAIN)) { DoCast(target, SPELL_SHADOW_WORD_PAIN); } @@ -183,7 +183,7 @@ public: } case EVENT_IMMOLATE: { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, -SPELL_IMMOLATE)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_IMMOLATE)) { DoCast(target, SPELL_IMMOLATE); } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp index bb78049f1..10e8898e9 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp @@ -140,7 +140,7 @@ public: events.ScheduleEvent(EVENT_SPELL_STOMP, 30000); break; case EVENT_SPELL_BURN: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, -SPELL_BURN_DAMAGE)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, true, -SPELL_BURN_DAMAGE)) me->CastSpell(target, SPELL_BURN, false); events.ScheduleEvent(EVENT_SPELL_BURN, 60000); break; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index f568b0411..d029d8329 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -215,7 +215,7 @@ public: break; case EVENT_MARK_OF_ARLOKK: { - Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, urand(1, 3), 0.0f, false, -SPELL_MARK_OF_ARLOKK); + Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, urand(1, 3), 0.0f, false, true, -SPELL_MARK_OF_ARLOKK); if (!target) target = me->GetVictim(); if (target) diff --git a/src/server/scripts/Events/brewfest.cpp b/src/server/scripts/Events/brewfest.cpp index 12ce02ee2..c4678dcc7 100644 --- a/src/server/scripts/Events/brewfest.cpp +++ b/src/server/scripts/Events/brewfest.cpp @@ -1768,7 +1768,7 @@ struct npc_coren_direbrew_sisters : public ScriptedAI }) .Schedule(Seconds(2), [this](TaskContext mugChuck) { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, false, -SPELL_HAS_DARK_BREWMAIDENS_BREW)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, false, true, -SPELL_HAS_DARK_BREWMAIDENS_BREW)) { DoCast(target, SPELL_CHUCK_MUG); } diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.cpp index 24a926615..868fa8374 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.cpp @@ -105,10 +105,10 @@ struct npc_obsidian_destroyer : public ScriptedAI _scheduler.Schedule(6s, [this](TaskContext context) { std::list targets; - SelectTargetList(targets, [&](Unit* target) + SelectTargetList(targets, 6, SelectTargetMethod::Random, 1, [&](Unit* target) { return target && target->IsPlayer() && target->GetPower(POWER_MANA) > 0; - }, 6, SelectTargetMethod::Random); + }); for (Unit* target : targets) { diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_amanitar.cpp b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_amanitar.cpp index a94d368fc..445c186db 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_amanitar.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_amanitar.cpp @@ -204,7 +204,7 @@ struct boss_amanitar : public BossAI } } - if (SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, -SPELL_MINI)) + if (SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_MINI)) { DoCastSelf(SPELL_REMOVE_MUSHROOM_POWER, true); DoCastAOE(SPELL_MINI); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp index 7b1ef38c7..07bf6f096 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp @@ -224,7 +224,7 @@ public: break; case EVENT_ENERVATING_BRAND: for (uint8 i = 0; i < RAID_MODE(2, 4, 2, 4); i++) - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true, -SPELL_ENERVATING_BRAND)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true, true, -SPELL_ENERVATING_BRAND)) me->CastSpell(target, SPELL_ENERVATING_BRAND, true); events.ScheduleEvent(EVENT_ENERVATING_BRAND, 26000); break; @@ -311,7 +311,7 @@ public: break; case EVENT_ENERVATING_BRAND: for (uint8 i = 0; i < RAID_MODE(4, 10, 4, 10); i++) - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true, -SPELL_ENERVATING_BRAND)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true, true, -SPELL_ENERVATING_BRAND)) me->CastSpell(target, SPELL_ENERVATING_BRAND, true); _events.ScheduleEvent(EVENT_ENERVATING_BRAND, 26000); break; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 55723e80e..2c89dca56 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -399,7 +399,7 @@ public: events.ScheduleEvent(EVENT_METEOR_STRIKE, 40000); break; case EVENT_FIERY_COMBUSTION: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, -SPELL_TWILIGHT_REALM)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, true, -SPELL_TWILIGHT_REALM)) me->CastSpell(target, SPELL_FIERY_COMBUSTION, false); events.ScheduleEvent(EVENT_FIERY_COMBUSTION, 25000); break; @@ -542,7 +542,7 @@ public: _events.ScheduleEvent(EVENT_BREATH, urand(10000, 12000)); break; case EVENT_SOUL_CONSUMPTION: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, SPELL_TWILIGHT_REALM)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, true, SPELL_TWILIGHT_REALM)) me->CastSpell(target, SPELL_SOUL_CONSUMPTION, false); _events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 20000); break; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index 24e77ff24..28ff389cc 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -211,12 +211,12 @@ public: events.RepeatEvent(urand(10000, 15000)); break; case EVENT_SPELL_FEL_LIGHTNING: - if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true) ) + if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true) ) me->CastSpell(target, SPELL_FEL_LIGHTNING, false); events.RepeatEvent(urand(10000, 15000)); break; case EVENT_SPELL_INCINERATE_FLESH: - if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true) ) + if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true) ) { Talk(EMOTE_INCINERATE, target); Talk(SAY_INCINERATE); @@ -230,7 +230,7 @@ public: events.RepeatEvent(urand(25000, 45000)); break; case EVENT_SPELL_LEGION_FLAME: - if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true) ) + if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true) ) { Talk(EMOTE_LEGION_FLAME, target); me->CastSpell(target, SPELL_LEGION_FLAME, false); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 2615b8957..032ca2ff9 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -465,7 +465,7 @@ public: switch (action) { case ACTION_MARK_OF_THE_FALLEN_CHAMPION: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, -SPELL_MARK_OF_THE_FALLEN_CHAMPION)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_MARK_OF_THE_FALLEN_CHAMPION)) { ++_fallenChampionCastCount; me->CastSpell(target, SPELL_MARK_OF_THE_FALLEN_CHAMPION, false); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index 97043531c..644a371d8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -235,7 +235,7 @@ public: { std::list targets; uint32 minTargets = RAID_MODE(3, 8, 3, 8); - SelectTargetList(targets, minTargets, SelectTargetMethod::Random, -5.0f, true); + SelectTargetList(targets, minTargets, SelectTargetMethod::Random, 0, -5.0f, true); float minDist = 0.0f; if (targets.size() >= minTargets) minDist = -5.0f; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 0ccd5fd16..f90b8eea6 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -445,7 +445,7 @@ public: count = 3; std::list targets; - SelectTargetList(targets, NonTankTargetSelector(me, true), count, SelectTargetMethod::Random); + SelectTargetList(targets, count, SelectTargetMethod::Random, 0, NonTankTargetSelector(me, true)); if (!targets.empty()) for (std::list::iterator itr = targets.begin(); itr != targets.end(); ++itr) me->CastSpell(*itr, SPELL_SUMMON_SHADE, true); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 99ce3c3b6..46c5015e0 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -479,7 +479,7 @@ public: void SelectTarget(std::list& targets) { targets.clear(); - Unit* target = GetCaster()->GetAI()->SelectTarget(SelectTargetMethod::Random, 1, -1.0f, true, -SPELL_IMPALED); // -1.0f as it takes into account object size + Unit* target = GetCaster()->GetAI()->SelectTarget(SelectTargetMethod::Random, 1, -1.0f, true,true, -SPELL_IMPALED); // -1.0f as it takes into account object size if (!target) target = GetCaster()->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true); // if only tank or noone outside of boss' model if (!target) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 7e31e8550..52ca27b44 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -548,7 +548,7 @@ public: case EVENT_SLIME_PUDDLE: { std::list targets; - SelectTargetList(targets, 2, SelectTargetMethod::Random, 0.0f, true); + SelectTargetList(targets, 2, SelectTargetMethod::Random, 0, 0.0f, true); if (!targets.empty()) for (std::list::iterator itr = targets.begin(); itr != targets.end(); ++itr) me->CastSpell(*itr, SPELL_SLIME_PUDDLE_TRIGGER, true); @@ -634,7 +634,7 @@ public: if (Is25ManRaid()) { std::list targets; - SelectTargetList(targets, MalleableGooSelector(me), (IsHeroic() ? 3 : 2), SelectTargetMethod::Random); + SelectTargetList(targets, (IsHeroic() ? 3 : 2), SelectTargetMethod::Random, 0, MalleableGooSelector(me)); if (!targets.empty()) { diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index dceec2f43..0bfe9055b 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -315,7 +315,7 @@ public: { std::list targets; uint32 minTargets = RAID_MODE(3, 8, 3, 8); - SelectTargetList(targets, minTargets, SelectTargetMethod::Random, -5.0f, true); + SelectTargetList(targets, minTargets, SelectTargetMethod::Random, 0, -5.0f, true); float minDist = 0.0f; if (targets.size() >= minTargets) minDist = -5.0f; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 88b8e27af..9f07f1b80 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -625,7 +625,7 @@ public: switch (eventId) { case EVENT_DEATH_PLAGUE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, -SPELL_RECENTLY_INFECTED)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_RECENTLY_INFECTED)) { Talk(EMOTE_DEATH_PLAGUE_WARNING, target); DoCast(target, SPELL_DEATH_PLAGUE); @@ -1175,7 +1175,7 @@ public: Talk(SAY_SVALNA_AGGRO); break; case EVENT_IMPALING_SPEAR: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, -SPELL_IMPALING_SPEAR)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_IMPALING_SPEAR)) { DoCast(me, SPELL_AETHER_SHIELD); me->AddAura(70203, me); @@ -1361,7 +1361,7 @@ public: Events.ScheduleEvent(EVENT_ARNATH_SMITE, urand(4000, 7000)); break; case EVENT_ARNATH_DOMINATE_MIND: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, -SPELL_DOMINATE_MIND)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_DOMINATE_MIND)) DoCast(target, SPELL_DOMINATE_MIND); Events.ScheduleEvent(EVENT_ARNATH_DOMINATE_MIND, urand(28000, 37000)); break; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp index 8a2a6b27e..00714018a 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp @@ -177,7 +177,7 @@ public: events.RepeatEvent(20000); break; case EVENT_MUTATING_INJECTION: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, -SPELL_MUTATING_INJECTION)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, true, -SPELL_MUTATING_INJECTION)) { me->CastSpell(target, SPELL_MUTATING_INJECTION, false); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 5617f54da..e362d1a43 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -427,7 +427,7 @@ public: case EVENT_CHAINS: for (uint8 i = 0; i < 3; ++i) { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 200, true, -SPELL_CHAINS_OF_KELTHUZAD)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 200, true, true, -SPELL_CHAINS_OF_KELTHUZAD)) { me->CastSpell(target, SPELL_CHAINS_OF_KELTHUZAD, true); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp index 3ea610a5a..37c79a7f3 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp @@ -201,7 +201,7 @@ public: Talk(EMOTE_WEB_WRAP); for (uint8 i = 0; i < RAID_MODE(1, 2); ++i) { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0, true, -SPELL_WEB_WRAP)) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0, true, true, -SPELL_WEB_WRAP)) { target->RemoveAura(RAID_MODE(SPELL_WEB_SPRAY_10, SPELL_WEB_SPRAY_25)); uint8 pos = urand(0, 2); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 32ace18ec..41977c51f 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -1505,7 +1505,7 @@ public: { uint8 i = 0; std::list drakes; - c->AI()->SelectTargetList(drakes, (c->GetMap()->GetSpawnMode() == 0 ? 1 : 3), SelectTargetMethod::Random, 0.0f, false, 57403 /*only drakes have this aura*/); + c->AI()->SelectTargetList(drakes, (c->GetMap()->GetSpawnMode() == 0 ? 1 : 3), SelectTargetMethod::Random, 0, 0.0f, false, true, 57403 /*only drakes have this aura*/); for (std::list::iterator itr = drakes.begin(); itr != drakes.end() && i < 3; ++itr) { DrakeGUID[i++] = (*itr)->GetGUID(); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp index 1c1aa9c63..aa21ce401 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp @@ -197,7 +197,7 @@ public: events.RepeatEvent(urand(4000, 5000)); break; case EVENT_FROST_TOMB: - if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true) ) + if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true) ) if( !target->HasAura(SPELL_FROST_TOMB_AURA) ) { Talk(SAY_FROST_TOMB_EMOTE, target);