aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/scripts')
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp97
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp52
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp26
-rw-r--r--src/server/scripts/EasternKingdoms/TheStockade/boss_randolph_moloch.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp4
-rw-r--r--src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp2
-rw-r--r--src/server/scripts/Kalimdor/Firelands/firelands.cpp2
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp8
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp74
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp10
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp12
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp2
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp5
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp18
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp9
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp6
-rw-r--r--src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp2
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp11
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp119
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp8
-rw-r--r--src/server/scripts/World/npcs_special.cpp17
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: