aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/Northrend
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-01-03 20:04:19 +0100
committerGitHub <noreply@github.com>2018-01-03 20:04:19 +0100
commit532ab1c7f8653d1a2e48aa1f1f8a9ba1041d4bb7 (patch)
tree81e2f7eb89b3144c14dd488ea6304f6d44d19848 /src/server/scripts/Northrend
parent425b181544a21d2246fdf0261ba76a37e2510883 (diff)
Core: Combat/threat system rewrite (PR #19930)
- PvE combat is now always mutual. UNIT_FLAG_IN_COMBAT is backed by actual references to the units we're in combat with. - PvP combat is now also tracked, and almost always mutual; spells like Vanish and Feign Death can break this rule. That means we can easily determine a list of players we're fighting. - By extension, IsInCombatWith now has sensible behavior when invoked on nonplayers. - Threat and combat systems are no longer the same. - They still have an enforced relationship (threat implies combat - clearing combat clears threat)... - ...but we can have combat without threat. A creature (with threat list) isn't considered to be engaged until it has an entry on its threat list... - ...which means we can now faithfully replicate retail engage behavior. Combat on projectile launch - engagement start on projectile impact. Yay for progress! - AI method refactor, as already ported in 6113b9d - `JustEngagedWith`, `JustEnteredCombat` and `JustExitedCombat`. - Vehicle threat is now properly pooled on the main vehicle body (fixes #16542). - Various edge case bug fixes for threat redirects (Misdirection "cancelling" Vigilance and similar). - Target re-selection is now significantly faster. - Fixed a ton of other smaller edge case bugs, probably. Closes #7951 and #19998.
Diffstat (limited to 'src/server/scripts/Northrend')
-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
10 files changed, 61 insertions, 79 deletions
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 c6cae404478..1d6eed64946 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 9ba7cce3130..8ce416a5eba 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 1c4f444234b..6f77a251f31 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -822,7 +822,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 7ea01046763..6bc1bdc9e10 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
@@ -673,14 +673,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 e87248ddff0..1a78118b7c1 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 02afc219aa3..4ac7f99e2c2 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 90c9224669f..f940d67f8c7 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -560,25 +560,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 777b9a8cf1a..3bbb13258f1 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
@@ -487,12 +487,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 53850b38f54..c67c88a397d 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->RemoveFlag(UNIT_FIELD_FLAGS, 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 eba719e957e..bcc0f7c0c51 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);