aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/scripts')
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp1063
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp6
3 files changed, 451 insertions, 624 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index d1ed10dfb6c..d51c43b4255 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -28,6 +28,7 @@
#include "SpellInfo.h"
#include "SpellScript.h"
#include "TemporarySummon.h"
+#include "PassiveAI.h"
enum Texts
{
@@ -59,7 +60,7 @@ enum Texts
EMOTE_VALANAR_SHOCK_VORTEX = 3,
SAY_VALANAR_KILL = 4,
SAY_VALANAR_BERSERK = 5,
- SAY_VALANAR_DEATH = 6,
+ SAY_VALANAR_DEATH = 6
};
enum Spells
@@ -116,72 +117,104 @@ enum Spells
// Shock Vortex
SPELL_SHOCK_VORTEX_PERIODIC = 71945,
SPELL_SHOCK_VORTEX_DUMMY = 72633,
+
+ // Visual Spells
+ SPELL_INVOCATION_VISUAL_VALANAR = 71070,
+ SPELL_INVOCATION_VISUAL_TALDARAM = 71081,
+ SPELL_INVOCATION_VISUAL_KELESETH = 71080
};
enum Events
{
EVENT_INTRO_1 = 1,
- EVENT_INTRO_2 = 2,
+ EVENT_INTRO_2,
- EVENT_INVOCATION_OF_BLOOD = 3,
- EVENT_BERSERK = 4,
+ EVENT_INVOCATION_OF_BLOOD,
+ EVENT_BERSERK,
// Keleseth
- EVENT_SHADOW_RESONANCE = 5,
- EVENT_SHADOW_LANCE = 6,
+ EVENT_SHADOW_RESONANCE,
+ EVENT_SHADOW_LANCE,
// Taldaram
- EVENT_GLITTERING_SPARKS = 7,
- EVENT_CONJURE_FLAME = 8,
+ EVENT_GLITTERING_SPARKS,
+ EVENT_CONJURE_FLAME,
// Valanar
- EVENT_KINETIC_BOMB = 9,
- EVENT_SHOCK_VORTEX = 10,
- EVENT_BOMB_DESPAWN = 11,
- EVENT_CONTINUE_FALLING = 12,
+ EVENT_KINETIC_BOMB,
+ EVENT_SHOCK_VORTEX,
+ EVENT_BOMB_DESPAWN,
+ EVENT_CONTINUE_FALLING
};
enum Actions
{
ACTION_START_INTRO = 1,
- ACTION_STAND_UP = 2,
- ACTION_CAST_INVOCATION = 3,
- ACTION_REMOVE_INVOCATION = 4,
- ACTION_KINETIC_BOMB_JUMP = 5,
- ACTION_FLAME_BALL_CHASE = 6,
+ ACTION_INTRO_DONE,
+ ACTION_STAND_UP,
+ ACTION_CAST_INVOCATION,
+ ACTION_REMOVE_INVOCATION,
+ ACTION_KINETIC_BOMB_JUMP,
+ ACTION_FLAME_BALL_CHASE
};
enum Points
{
POINT_INTRO_DESPAWN = 380040,
- POINT_KINETIC_BOMB_IMPACT = 384540,
+ POINT_KINETIC_BOMB_IMPACT = 384540
};
-enum Displays
+enum Misc
{
DISPLAY_KINETIC_BOMB = 31095,
+ SUMMON_PRINCES_GROUP = 1,
+ DATA_INTRO = 2,
+ DATA_INTRO_DONE = 3,
+ DATA_PRINCE_EVADE = 4
};
class StandUpEvent : public BasicEvent
{
public:
- StandUpEvent(Creature& owner) : BasicEvent(), _owner(owner) { }
+ StandUpEvent(Creature* owner) : BasicEvent(), _owner(owner) { }
bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override
{
- _owner.HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
- _owner.SetReactState(REACT_AGGRESSIVE);
+ _owner->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+ _owner->SetReactState(REACT_AGGRESSIVE);
return true;
}
private:
- Creature& _owner;
+ Creature* _owner;
+};
+
+class VortexEvent : public BasicEvent
+{
+public:
+ VortexEvent(Creature* owner) : _owner(owner) { }
+
+ bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override
+ {
+ _owner->CastSpell(_owner, SPELL_SHOCK_VORTEX_PERIODIC, true);
+ return true;
+ }
+
+private:
+ Creature* _owner;
};
Position const introFinalPos = {4660.490f, 2769.200f, 430.0000f, 0.000000f};
Position const triggerPos = {4680.231f, 2769.134f, 379.9256f, 3.121708f};
Position const triggerEndPos = {4680.180f, 2769.150f, 365.5000f, 3.121708f};
+uint32 const PrincesData[] =
+{
+ DATA_PRINCE_KELESETH,
+ DATA_PRINCE_TALDARAM,
+ DATA_PRINCE_VALANAR
+};
+
class boss_blood_council_controller : public CreatureScript
{
public:
@@ -189,9 +222,10 @@ class boss_blood_council_controller : public CreatureScript
struct boss_blood_council_controllerAI : public BossAI
{
- boss_blood_council_controllerAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL)
+ boss_blood_council_controllerAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL), _intro(true)
{
Initialize();
+ SetCombatMovement(false);
}
void Initialize()
@@ -202,11 +236,32 @@ class boss_blood_council_controller : public CreatureScript
void Reset() override
{
- events.Reset();
- me->SetReactState(REACT_PASSIVE);
+ _Reset();
Initialize();
+ me->SummonCreatureGroup(SUMMON_PRINCES_GROUP);
+
+ if (!_intro)
+ for (uint32 bossData : PrincesData)
+ if (Creature* prince = ObjectAccessor::GetCreature(*me, instance->GetGuidData(bossData)))
+ {
+ prince->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ if (bossData == DATA_PRINCE_VALANAR)
+ prince->SetHealth(prince->GetMaxHealth());
+ }
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ // Avoid do set boss state to fail with hotswap
+ if (instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) == DONE)
+ return;
+
+ for (uint32 bossData : PrincesData)
+ if (Creature* prince = ObjectAccessor::GetCreature(*me, instance->GetGuidData(bossData)))
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, prince);
- instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, NOT_STARTED);
+ summons.DespawnAll();
+ _DespawnAtEvade();
}
void EnterCombat(Unit* who) override
@@ -216,45 +271,37 @@ class boss_blood_council_controller : public CreatureScript
if (!instance->CheckRequiredBosses(DATA_BLOOD_PRINCE_COUNCIL, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_SEQUENCE_BREAK);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
+ me->SetCombatPulseDelay(5);
+ me->setActive(true);
+ DoZoneInCombat();
instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, IN_PROGRESS);
- DoCast(me, SPELL_INVOCATION_OF_BLOOD_VALANAR);
-
- if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_KELESETH_GUID)))
- {
- instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, keleseth);
- DoZoneInCombat(keleseth);
- }
-
- if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID)))
- {
- instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, taldaram);
- DoZoneInCombat(taldaram);
- }
+ DoCastSelf(SPELL_INVOCATION_OF_BLOOD_VALANAR);
- if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_VALANAR_GUID)))
- {
- instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, valanar);
- DoZoneInCombat(valanar);
- }
+ for (uint32 bossData : PrincesData)
+ if (Creature* prince = ObjectAccessor::GetCreature(*me, instance->GetGuidData(bossData)))
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, prince);
+ DoZoneInCombat(prince);
+ }
- events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 46500);
+ events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, Seconds(46) + Milliseconds(500));
- _invocationOrder[0] = InvocationData(instance->GetGuidData(DATA_PRINCE_VALANAR_GUID), SPELL_INVOCATION_OF_BLOOD_VALANAR, EMOTE_VALANAR_INVOCATION, 71070);
- if (urand(0, 1))
+ _invocationOrder[0] = InvocationData(instance->GetGuidData(DATA_PRINCE_VALANAR), SPELL_INVOCATION_OF_BLOOD_VALANAR, EMOTE_VALANAR_INVOCATION, SPELL_INVOCATION_VISUAL_VALANAR);
+ if (roll_chance_i(50))
{
- _invocationOrder[1] = InvocationData(instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID), SPELL_INVOCATION_OF_BLOOD_TALDARAM, EMOTE_TALDARAM_INVOCATION, 71081);
- _invocationOrder[2] = InvocationData(instance->GetGuidData(DATA_PRINCE_KELESETH_GUID), SPELL_INVOCATION_OF_BLOOD_KELESETH, EMOTE_KELESETH_INVOCATION, 71080);
+ _invocationOrder[1] = InvocationData(instance->GetGuidData(DATA_PRINCE_TALDARAM), SPELL_INVOCATION_OF_BLOOD_TALDARAM, EMOTE_TALDARAM_INVOCATION, SPELL_INVOCATION_VISUAL_TALDARAM);
+ _invocationOrder[2] = InvocationData(instance->GetGuidData(DATA_PRINCE_KELESETH), SPELL_INVOCATION_OF_BLOOD_KELESETH, EMOTE_KELESETH_INVOCATION, SPELL_INVOCATION_VISUAL_KELESETH);
}
else
{
- _invocationOrder[1] = InvocationData(instance->GetGuidData(DATA_PRINCE_KELESETH_GUID), SPELL_INVOCATION_OF_BLOOD_KELESETH, EMOTE_KELESETH_INVOCATION, 71080);
- _invocationOrder[2] = InvocationData(instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID), SPELL_INVOCATION_OF_BLOOD_TALDARAM, EMOTE_TALDARAM_INVOCATION, 71081);
+ _invocationOrder[1] = InvocationData(instance->GetGuidData(DATA_PRINCE_KELESETH), SPELL_INVOCATION_OF_BLOOD_KELESETH, EMOTE_KELESETH_INVOCATION, SPELL_INVOCATION_VISUAL_KELESETH);
+ _invocationOrder[2] = InvocationData(instance->GetGuidData(DATA_PRINCE_TALDARAM), SPELL_INVOCATION_OF_BLOOD_TALDARAM, EMOTE_TALDARAM_INVOCATION, SPELL_INVOCATION_VISUAL_TALDARAM);
}
}
@@ -262,26 +309,21 @@ class boss_blood_council_controller : public CreatureScript
{
_resetCounter += uint8(data);
if (_resetCounter == 3)
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
}
- void JustReachedHome() override
+ uint32 GetData(uint32 data) const override
{
- _resetCounter = 0;
- if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_KELESETH_GUID)))
- keleseth->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
- if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID)))
- taldaram->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
- if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_VALANAR_GUID)))
- valanar->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (data == DATA_INTRO && !_intro)
+ return DATA_INTRO_DONE;
+ return 0;
}
void JustDied(Unit* killer) override
{
- _JustDied();
- // kill all prices
+ events.Reset();
+ instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, DONE);
+ // Kill all prices
for (uint8 i = 0; i < 3; ++i)
{
if (++_invocationStage == 3)
@@ -289,7 +331,7 @@ class boss_blood_council_controller : public CreatureScript
if (Creature* prince = ObjectAccessor::GetCreature(*me, _invocationOrder[_invocationStage].guid))
{
- // make sure looting is allowed
+ // Make sure looting is allowed
if (me->IsDamageEnoughForLootingAndReward())
prince->LowerPlayerDamageReq(prince->GetMaxHealth());
killer->Kill(prince);
@@ -297,6 +339,27 @@ class boss_blood_council_controller : public CreatureScript
}
}
+ void DoAction(int32 actionId) override
+ {
+ if (actionId == ACTION_START_INTRO && _intro && instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) != DONE)
+ {
+ _intro = false;
+ if (Creature* bloodQueen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL_COUNCIL)))
+ bloodQueen->AI()->DoAction(ACTION_START_INTRO);
+ }
+ else if (actionId == ACTION_INTRO_DONE)
+ {
+ // Remove feigh death from princes
+ for (uint32 bossData : PrincesData)
+ if (Creature* prince = ObjectAccessor::GetCreature(*me, instance->GetGuidData(bossData)))
+ {
+ prince->AI()->DoAction(ACTION_STAND_UP);
+ if (bossData == DATA_PRINCE_VALANAR)
+ prince->SetHealth(prince->GetMaxHealth());
+ }
+ }
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -331,8 +394,8 @@ class boss_blood_council_controller : public CreatureScript
newPrince->AI()->Talk(uint8(_invocationOrder[_invocationStage].textId));
}
- DoCast(me, _invocationOrder[_invocationStage].spellId);
- events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 46500);
+ DoCastSelf(_invocationOrder[_invocationStage].spellId);
+ events.Repeat(Seconds(46) + Milliseconds(500));
break;
}
default:
@@ -365,6 +428,7 @@ class boss_blood_council_controller : public CreatureScript
uint32 _invocationStage;
uint32 _resetCounter;
+ bool _intro;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -373,89 +437,214 @@ class boss_blood_council_controller : public CreatureScript
}
};
-class boss_prince_keleseth_icc : public CreatureScript
+struct BloodPrincesBossAI : public BossAI
{
- public:
- boss_prince_keleseth_icc() : CreatureScript("boss_prince_keleseth_icc") { }
-
- struct boss_prince_kelesethAI : public BossAI
+ BloodPrincesBossAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), _spawnHealth (creature->GetMaxHealth()), _isEmpowered(false)
+ {
+ SetBoundary(instance->GetBossBoundary(DATA_BLOOD_PRINCE_COUNCIL));
+ }
+
+ void InitializeAI() override
+ {
+ _spawnHealth = 1;
+ if (!me->isDead())
+ JustRespawned();
+ }
+
+ void Reset() override
+ {
+ events.Reset();
+ summons.DespawnAll();
+ me->SetCombatPulseDelay(0);
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ _isEmpowered = false;
+ me->SetHealth(_spawnHealth);
+ instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true));
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ me->SetCombatPulseDelay(5);
+ me->setActive(true);
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
+ DoZoneInCombat(controller);
+ ScheduleTasks();
+ }
+
+ virtual void ScheduleTasks() = 0;
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ events.Reset();
+ summons.DespawnAll();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+
+ switch (me->GetEntry())
{
- boss_prince_kelesethAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL)
- {
- _isEmpowered = false;
- _spawnHealth = creature->GetMaxHealth();
- }
+ case NPC_PRINCE_KELESETH:
+ Talk(SAY_KELESETH_DEATH);
+ break;
+ case NPC_PRINCE_TALDARAM:
+ Talk(EMOTE_TALDARAM_DEATH);
+ break;
+ case NPC_PRINCE_VALANAR:
+ Talk(SAY_VALANAR_DEATH);
+ break;
+ default:
+ break;
+ }
+ }
- void InitializeAI() override
- {
- if (CreatureData const* data = me->GetCreatureData())
- if (data->curhealth)
- _spawnHealth = data->curhealth;
+ void JustRespawned() override
+ {
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
+ if (controller->AI()->GetData(DATA_INTRO) != DATA_INTRO_DONE)
+ DoCastSelf(SPELL_FEIGN_DEATH);
- if (!me->isDead())
- JustRespawned();
- }
+ me->SetHealth(_spawnHealth);
+ }
- void Reset() override
- {
- events.Reset();
- summons.DespawnAll();
+ void DamageTaken(Unit* attacker, uint32& damage) override
+ {
+ if (!_isEmpowered)
+ {
+ me->AddThreat(attacker, float(damage));
+ damage = 0;
+ }
+ }
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- _isEmpowered = false;
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ switch (me->GetEntry())
+ {
+ case NPC_PRINCE_KELESETH:
+ Talk(SAY_KELESETH_KILL);
+ break;
+ case NPC_PRINCE_TALDARAM:
+ Talk(SAY_TALDARAM_KILL);
+ break;
+ case NPC_PRINCE_VALANAR:
+ Talk(SAY_VALANAR_KILL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void JustReachedHome() override
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ me->SetHealth(_spawnHealth);
+ _isEmpowered = false;
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ controller->AI()->SetData(DATA_PRINCE_EVADE, 1);
+ }
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
+ {
+ if (spell->Id == SelectInvocationSpell())
+ DoAction(ACTION_CAST_INVOCATION);
+ }
+
+ void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) override
+ {
+ if (damageType != SPELL_DIRECT_DAMAGE)
+ return;
+
+ if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
+ instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false));
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_STAND_UP:
+ me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ me->RemoveFlag(OBJECT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+ me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
+ me->m_Events.AddEvent(new StandUpEvent(me), me->m_Events.CalculateTime(1000));
+ break;
+ case ACTION_CAST_INVOCATION:
+ Talk(SelectInvocationSay());
+ DoCastSelf(SPELL_INVOCATION_VISUAL_ACTIVE, true);
+ _isEmpowered = true;
+ break;
+ case ACTION_REMOVE_INVOCATION:
me->SetHealth(_spawnHealth);
- instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true));
- }
+ me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
+ me->RemoveAurasDueToSpell(SelectInvocationSpell());
+ _isEmpowered = false;
+ break;
+ default:
+ break;
+ }
+ }
- void EnterCombat(Unit* /*who*/) override
- {
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
- DoZoneInCombat(controller);
+ uint32 SelectInvocationSay()
+ {
+ switch (me->GetEntry())
+ {
+ case NPC_PRINCE_KELESETH:
+ return SAY_KELESETH_INVOCATION;
+ case NPC_PRINCE_TALDARAM:
+ return SAY_TALDARAM_INVOCATION;
+ case NPC_PRINCE_VALANAR:
+ return SAY_KELESETH_INVOCATION;
+ default: // Should never happen
+ return 0;
+ }
+ }
- events.ScheduleEvent(EVENT_BERSERK, 600000);
- events.ScheduleEvent(EVENT_SHADOW_RESONANCE, urand(10000, 15000));
- events.ScheduleEvent(EVENT_SHADOW_LANCE, 2000);
+ uint32 SelectInvocationSpell()
+ {
+ switch (me->GetEntry())
+ {
+ case NPC_PRINCE_KELESETH:
+ return SPELL_INVOCATION_OF_BLOOD_KELESETH;
+ case NPC_PRINCE_TALDARAM:
+ return SPELL_INVOCATION_OF_BLOOD_TALDARAM;
+ case NPC_PRINCE_VALANAR:
+ return SPELL_INVOCATION_OF_BLOOD_VALANAR;
+ default: // Should never happen
+ return 0;
+ }
+ }
- if (IsHeroic())
- {
- me->AddAura(SPELL_SHADOW_PRISON, me);
- DoCast(me, SPELL_SHADOW_PRISON_DUMMY);
- }
- }
+protected:
+ uint32 _spawnHealth;
+ bool _isEmpowered;
+};
- void JustDied(Unit* /*killer*/) override
- {
- events.Reset();
- summons.DespawnAll();
+class boss_prince_keleseth_icc : public CreatureScript
+{
+ public:
+ boss_prince_keleseth_icc() : CreatureScript("boss_prince_keleseth_icc") { }
- Talk(SAY_KELESETH_DEATH);
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- }
+ struct boss_prince_kelesethAI : public BloodPrincesBossAI
+ {
+ boss_prince_kelesethAI(Creature* creature) : BloodPrincesBossAI(creature, DATA_PRINCE_KELESETH) { }
- void JustReachedHome() override
+ void ScheduleTasks() override
{
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- me->SetHealth(_spawnHealth);
- _isEmpowered = false;
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_SHADOW_RESONANCE, Seconds(10), Seconds(15));
+ events.ScheduleEvent(EVENT_SHADOW_LANCE, Seconds(2));
+
+ if (IsHeroic())
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- controller->AI()->SetData(0, 1);
+ DoCastSelf(SPELL_SHADOW_PRISON, true);
+ DoCastSelf(SPELL_SHADOW_PRISON_DUMMY);
}
}
- void JustRespawned() override
- {
- DoCast(me, SPELL_FEIGN_DEATH);
- me->SetHealth(_spawnHealth);
- }
-
- void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
- {
- if (spell->Id == SPELL_INVOCATION_OF_BLOOD_KELESETH)
- DoAction(ACTION_CAST_INVOCATION);
- }
-
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
@@ -467,78 +656,9 @@ class boss_prince_keleseth_icc : public CreatureScript
summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
}
- void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) override
- {
- if (damageType != SPELL_DIRECT_DAMAGE)
- return;
-
- if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
- instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false));
- }
-
- void DamageTaken(Unit* attacker, uint32& damage) override
- {
- if (!_isEmpowered)
- {
- me->AddThreat(attacker, float(damage));
- damage = 0;
- }
- }
-
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_KELESETH_KILL);
- }
-
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_STAND_UP:
- me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
- me->RemoveFlag(OBJECT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
- me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
- me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
- break;
- case ACTION_CAST_INVOCATION:
- Talk(SAY_KELESETH_INVOCATION);
- DoCast(me, SPELL_INVOCATION_VISUAL_ACTIVE, true);
- _isEmpowered = true;
- break;
- case ACTION_REMOVE_INVOCATION:
- me->SetHealth(_spawnHealth);
- me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
- me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_KELESETH);
- _isEmpowered = false;
- break;
- default:
- break;
- }
- }
-
- bool CheckInRoom() override
- {
- if (!CheckBoundary(me))
- {
- EnterEvadeMode();
- if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID)))
- taldaram->AI()->EnterEvadeMode();
-
- if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_VALANAR_GUID)))
- valanar->AI()->EnterEvadeMode();
-
- return false;
- }
-
- return true;
- }
-
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
@@ -551,20 +671,17 @@ class boss_prince_keleseth_icc : public CreatureScript
switch (eventId)
{
case EVENT_BERSERK:
- DoCast(me, SPELL_BERSERK);
+ DoCastSelf(SPELL_BERSERK);
Talk(EMOTE_KELESETH_BERSERK);
break;
case EVENT_SHADOW_RESONANCE:
Talk(SAY_KELESETH_SPECIAL);
- DoCast(me, SPELL_SHADOW_RESONANCE);
- events.ScheduleEvent(EVENT_SHADOW_RESONANCE, urand(10000, 15000));
+ DoCastSelf(SPELL_SHADOW_RESONANCE);
+ events.Repeat(Seconds(10), Seconds(15));
break;
case EVENT_SHADOW_LANCE:
- if (_isEmpowered)
- DoCastVictim(SPELL_EMPOWERED_SHADOW_LANCE);
- else
- DoCastVictim(SPELL_SHADOW_LANCE);
- events.ScheduleEvent(EVENT_SHADOW_LANCE, 2000);
+ _isEmpowered ? DoCastVictim(SPELL_EMPOWERED_SHADOW_LANCE) : DoCastVictim(SPELL_SHADOW_LANCE);
+ events.Repeat(Seconds(2));
break;
default:
break;
@@ -576,10 +693,6 @@ class boss_prince_keleseth_icc : public CreatureScript
// does not melee
}
-
- private:
- uint32 _spawnHealth;
- bool _isEmpowered;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -593,78 +706,17 @@ class boss_prince_taldaram_icc : public CreatureScript
public:
boss_prince_taldaram_icc() : CreatureScript("boss_prince_taldaram_icc") { }
- struct boss_prince_taldaramAI : public BossAI
+ struct boss_prince_taldaramAI : public BloodPrincesBossAI
{
- boss_prince_taldaramAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL)
- {
- _isEmpowered = false;
- _spawnHealth = creature->GetMaxHealth();
- }
+ boss_prince_taldaramAI(Creature* creature) : BloodPrincesBossAI(creature, DATA_PRINCE_TALDARAM) { }
- void InitializeAI() override
+ void ScheduleTasks() override
{
- if (CreatureData const* data = me->GetCreatureData())
- if (data->curhealth)
- _spawnHealth = data->curhealth;
-
- if (!me->isDead())
- JustRespawned();
- }
-
- void Reset() override
- {
- events.Reset();
- summons.DespawnAll();
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- _isEmpowered = false;
- me->SetHealth(_spawnHealth);
- instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true));
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
- DoZoneInCombat(controller);
-
- events.ScheduleEvent(EVENT_BERSERK, 600000);
- events.ScheduleEvent(EVENT_GLITTERING_SPARKS, urand(12000, 15000));
- events.ScheduleEvent(EVENT_CONJURE_FLAME, 20000);
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_GLITTERING_SPARKS, Seconds(12), Seconds(15));
+ events.ScheduleEvent(EVENT_CONJURE_FLAME, Seconds(20));
if (IsHeroic())
- me->AddAura(SPELL_SHADOW_PRISON, me);
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- events.Reset();
- summons.DespawnAll();
-
- Talk(EMOTE_TALDARAM_DEATH);
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- }
-
- void JustReachedHome() override
- {
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- me->SetHealth(_spawnHealth);
- _isEmpowered = false;
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- controller->AI()->SetData(0, 1);
- }
- }
-
- void JustRespawned() override
- {
- DoCast(me, SPELL_FEIGN_DEATH);
- me->SetHealth(_spawnHealth);
- }
-
- void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
- {
- if (spell->Id == SPELL_INVOCATION_OF_BLOOD_TALDARAM)
- DoAction(ACTION_CAST_INVOCATION);
+ DoCastSelf(SPELL_SHADOW_PRISON, true);
}
void JustSummoned(Creature* summon) override
@@ -681,78 +733,9 @@ class boss_prince_taldaram_icc : public CreatureScript
summon->AI()->SetGUID(target->GetGUID());
}
- void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) override
- {
- if (damageType != SPELL_DIRECT_DAMAGE)
- return;
-
- if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
- instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false));
- }
-
- void DamageTaken(Unit* attacker, uint32& damage) override
- {
- if (!_isEmpowered)
- {
- me->AddThreat(attacker, float(damage));
- damage = 0;
- }
- }
-
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_TALDARAM_KILL);
- }
-
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_STAND_UP:
- me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
- me->RemoveFlag(OBJECT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
- me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
- me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
- break;
- case ACTION_CAST_INVOCATION:
- Talk(SAY_TALDARAM_INVOCATION);
- DoCast(me, SPELL_INVOCATION_VISUAL_ACTIVE, true);
- _isEmpowered = true;
- break;
- case ACTION_REMOVE_INVOCATION:
- me->SetHealth(_spawnHealth);
- me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
- me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_TALDARAM);
- _isEmpowered = false;
- break;
- default:
- break;
- }
- }
-
- bool CheckInRoom() override
- {
- if (!CheckBoundary(me))
- {
- EnterEvadeMode();
- if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_KELESETH_GUID)))
- keleseth->AI()->EnterEvadeMode();
-
- if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_VALANAR_GUID)))
- valanar->AI()->EnterEvadeMode();
-
- return false;
- }
-
- return true;
- }
-
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
@@ -765,23 +748,23 @@ class boss_prince_taldaram_icc : public CreatureScript
switch (eventId)
{
case EVENT_BERSERK:
- DoCast(me, SPELL_BERSERK);
+ DoCastSelf(SPELL_BERSERK);
Talk(EMOTE_TALDARAM_BERSERK);
break;
case EVENT_GLITTERING_SPARKS:
DoCastVictim(SPELL_GLITTERING_SPARKS);
- events.ScheduleEvent(EVENT_GLITTERING_SPARKS, urand(15000, 50000));
+ events.Repeat(Seconds(15), Seconds(50));
break;
case EVENT_CONJURE_FLAME:
if (_isEmpowered)
{
- DoCast(me, SPELL_CONJURE_EMPOWERED_FLAME);
- events.ScheduleEvent(EVENT_CONJURE_FLAME, urand(15000, 25000));
+ DoCastSelf(SPELL_CONJURE_EMPOWERED_FLAME);
+ events.Repeat(Seconds(15), Seconds(25));
}
else
{
- DoCast(me, SPELL_CONJURE_FLAME);
- events.ScheduleEvent(EVENT_CONJURE_FLAME, urand(20000, 30000));
+ DoCastSelf(SPELL_CONJURE_FLAME);
+ events.Repeat(Seconds(20), Seconds(30));
}
Talk(SAY_TALDARAM_SPECIAL);
break;
@@ -795,10 +778,6 @@ class boss_prince_taldaram_icc : public CreatureScript
DoMeleeAttackIfReady();
}
-
- private:
- uint32 _spawnHealth;
- bool _isEmpowered;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -812,72 +791,17 @@ class boss_prince_valanar_icc : public CreatureScript
public:
boss_prince_valanar_icc() : CreatureScript("boss_prince_valanar_icc") { }
- struct boss_prince_valanarAI : public BossAI
+ struct boss_prince_valanarAI : public BloodPrincesBossAI
{
- boss_prince_valanarAI(Creature* creature) : BossAI(creature, DATA_BLOOD_PRINCE_COUNCIL)
- {
- _isEmpowered = false;
- _spawnHealth = creature->GetMaxHealth();
- }
-
- void InitializeAI() override
- {
- if (CreatureData const* data = me->GetCreatureData())
- if (data->curhealth)
- _spawnHealth = data->curhealth;
-
- if (!me->isDead())
- JustRespawned();
- }
+ boss_prince_valanarAI(Creature* creature) : BloodPrincesBossAI(creature, DATA_PRINCE_TALDARAM) { }
- void Reset() override
+ void ScheduleTasks() override
{
- events.Reset();
- summons.DespawnAll();
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- _isEmpowered = false;
- me->SetHealth(me->GetMaxHealth());
- instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true));
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
- DoZoneInCombat(controller);
-
- events.ScheduleEvent(EVENT_BERSERK, 600000);
- events.ScheduleEvent(EVENT_KINETIC_BOMB, urand(18000, 24000));
- events.ScheduleEvent(EVENT_SHOCK_VORTEX, urand(15000, 20000));
+ events.ScheduleEvent(EVENT_BERSERK, Minutes(10));
+ events.ScheduleEvent(EVENT_KINETIC_BOMB, Seconds(18), Seconds(24));
+ events.ScheduleEvent(EVENT_SHOCK_VORTEX, Seconds(15), Seconds(20));
if (IsHeroic())
- me->AddAura(SPELL_SHADOW_PRISON, me);
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- events.Reset();
- summons.DespawnAll();
-
- Talk(SAY_VALANAR_DEATH);
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- }
-
- void JustReachedHome() override
- {
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- me->SetHealth(me->GetMaxHealth());
- _isEmpowered = false;
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- controller->AI()->SetData(0, 1);
- }
- }
-
- void JustRespawned() override
- {
- DoCast(me, SPELL_FEIGN_DEATH);
- me->SetHealth(_spawnHealth);
+ DoCastSelf(SPELL_SHADOW_PRISON, true);
}
void JustSummoned(Creature* summon) override
@@ -886,7 +810,7 @@ class boss_prince_valanar_icc : public CreatureScript
{
case NPC_KINETIC_BOMB_TARGET:
summon->SetReactState(REACT_PASSIVE);
- summon->CastSpell(summon, SPELL_KINETIC_BOMB, true, NULL, NULL, me->GetGUID());
+ summon->CastSpell(summon, SPELL_KINETIC_BOMB, true, nullptr, nullptr, me->GetGUID());
break;
case NPC_KINETIC_BOMB:
{
@@ -899,7 +823,7 @@ class boss_prince_valanar_icc : public CreatureScript
}
case NPC_SHOCK_VORTEX:
summon->CastSpell(summon, SPELL_SHOCK_VORTEX_DUMMY, true);
- summon->CastSpell(summon, SPELL_SHOCK_VORTEX_PERIODIC, true);
+ summon->m_Events.AddEvent(new VortexEvent(summon), summon->m_Events.CalculateTime(5000));
break;
default:
break;
@@ -910,84 +834,9 @@ class boss_prince_valanar_icc : public CreatureScript
DoZoneInCombat(summon);
}
- void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
- {
- if (spell->Id == SPELL_INVOCATION_OF_BLOOD_VALANAR)
- DoAction(ACTION_CAST_INVOCATION);
- }
-
- void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) override
- {
- if (damageType != SPELL_DIRECT_DAMAGE)
- return;
-
- if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000))
- instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false));
- }
-
- void DamageTaken(Unit* attacker, uint32& damage) override
- {
- if (!_isEmpowered)
- {
- me->AddThreat(attacker, float(damage));
- damage = 0;
- }
- }
-
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_VALANAR_KILL);
- }
-
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_STAND_UP:
- me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
- me->RemoveFlag(OBJECT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
- me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
- me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
- break;
- case ACTION_CAST_INVOCATION:
- Talk(SAY_VALANAR_INVOCATION);
- DoCast(me, SPELL_INVOCATION_VISUAL_ACTIVE, true);
- _isEmpowered = true;
- break;
- case ACTION_REMOVE_INVOCATION:
- me->SetHealth(_spawnHealth);
- me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE);
- me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_VALANAR);
- _isEmpowered = false;
- break;
- default:
- break;
- }
- }
-
- bool CheckInRoom() override
- {
- if (!CheckBoundary(me))
- {
- EnterEvadeMode();
- if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_KELESETH_GUID)))
- keleseth->AI()->EnterEvadeMode();
-
- if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID)))
- taldaram->AI()->EnterEvadeMode();
-
- return false;
- }
-
- return true;
- }
-
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
@@ -1000,7 +849,7 @@ class boss_prince_valanar_icc : public CreatureScript
switch (eventId)
{
case EVENT_BERSERK:
- DoCast(me, SPELL_BERSERK);
+ DoCastSelf(SPELL_BERSERK);
Talk(SAY_VALANAR_BERSERK);
break;
case EVENT_KINETIC_BOMB:
@@ -1009,20 +858,20 @@ class boss_prince_valanar_icc : public CreatureScript
DoCast(target, SPELL_KINETIC_BOMB_TARGET);
Talk(SAY_VALANAR_SPECIAL);
}
- events.ScheduleEvent(EVENT_KINETIC_BOMB, urand(18000, 24000));
+ events.Repeat(Seconds(18), Seconds(24));
break;
case EVENT_SHOCK_VORTEX:
if (_isEmpowered)
{
- DoCast(me, SPELL_EMPOWERED_SHOCK_VORTEX);
+ DoCastSelf(SPELL_EMPOWERED_SHOCK_VORTEX);
Talk(EMOTE_VALANAR_SHOCK_VORTEX);
- events.ScheduleEvent(EVENT_SHOCK_VORTEX, 30000);
+ events.Repeat(Seconds(30));
}
else
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
DoCast(target, SPELL_SHOCK_VORTEX);
- events.ScheduleEvent(EVENT_SHOCK_VORTEX, urand(18000, 23000));
+ events.Repeat(Seconds(18), Seconds(23));
}
break;
default:
@@ -1035,10 +884,6 @@ class boss_prince_valanar_icc : public CreatureScript
DoMeleeAttackIfReady();
}
-
- private:
- uint32 _spawnHealth;
- bool _isEmpowered;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1052,25 +897,15 @@ class npc_blood_queen_lana_thel : public CreatureScript
public:
npc_blood_queen_lana_thel() : CreatureScript("npc_blood_queen_lana_thel") { }
- struct npc_blood_queen_lana_thelAI : public ScriptedAI
+ struct npc_blood_queen_lana_thelAI : public PassiveAI
{
- npc_blood_queen_lana_thelAI(Creature* creature) : ScriptedAI(creature)
- {
- _introDone = false;
- _instance = creature->GetInstanceScript();
- }
+ npc_blood_queen_lana_thelAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() override
{
_events.Reset();
me->SetDisableGravity(true);
- if (_instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) == DONE)
- {
- me->SetVisible(false);
- _introDone = true;
- }
- else
- me->SetVisible(true);
+ _instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) != DONE ? me->SetVisible(true) : me->SetVisible(false);
}
void DoAction(int32 action) override
@@ -1078,19 +913,15 @@ class npc_blood_queen_lana_thel : public CreatureScript
switch (action)
{
case ACTION_START_INTRO:
- if (!_introDone)
+ Talk(SAY_INTRO_1);
+ _events.SetPhase(1);
+ _events.ScheduleEvent(EVENT_INTRO_1, Seconds(14));
+ // summon a visual trigger
+ if (Creature* summon = DoSummon(NPC_FLOATING_TRIGGER, triggerPos, 15000, TEMPSUMMON_TIMED_DESPAWN))
{
- _introDone = true;
- Talk(SAY_INTRO_1);
- _events.SetPhase(1);
- _events.ScheduleEvent(EVENT_INTRO_1, 14000);
- // summon a visual trigger
- if (Creature* summon = DoSummon(NPC_FLOATING_TRIGGER, triggerPos, 15000, TEMPSUMMON_TIMED_DESPAWN))
- {
- summon->CastSpell(summon, SPELL_OOC_INVOCATION_VISUAL, true);
- summon->SetSpeedRate(MOVE_FLIGHT, 0.15f); // todo: creature is swimming, check if this is blizzlike or not.
- summon->GetMotionMaster()->MovePoint(0, triggerEndPos);
- }
+ summon->CastSpell(summon, SPELL_OOC_INVOCATION_VISUAL, true);
+ summon->SetSpeedRate(MOVE_RUN, 0.14f);
+ summon->GetMotionMaster()->MovePoint(0, triggerEndPos);
}
break;
default:
@@ -1117,25 +948,14 @@ class npc_blood_queen_lana_thel : public CreatureScript
me->GetMotionMaster()->MovePoint(POINT_INTRO_DESPAWN, introFinalPos);
_events.Reset();
- // remove Feign Death from princes
- if (Creature* keleseth = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_PRINCE_KELESETH_GUID)))
- keleseth->AI()->DoAction(ACTION_STAND_UP);
-
- if (Creature* taldaram = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID)))
- taldaram->AI()->DoAction(ACTION_STAND_UP);
-
- if (Creature* valanar = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_PRINCE_VALANAR_GUID)))
- {
- valanar->AI()->DoAction(ACTION_STAND_UP);
- valanar->SetHealth(valanar->GetMaxHealth());
- }
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
+ controller->AI()->DoAction(ACTION_INTRO_DONE);
}
}
private:
EventMap _events;
InstanceScript* _instance;
- bool _introDone;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1151,18 +971,15 @@ class npc_ball_of_flame : public CreatureScript
struct npc_ball_of_flameAI : public ScriptedAI
{
- npc_ball_of_flameAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
- {
- _despawnTimer = 0;
- }
+ npc_ball_of_flameAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() override
{
- me->CastSpell(me, SPELL_BALL_OF_FLAMES_VISUAL, true);
+ DoCastSelf(SPELL_BALL_OF_FLAMES_VISUAL, true);
if (me->GetEntry() == NPC_BALL_OF_INFERNO_FLAME)
{
- me->CastSpell(me, SPELL_BALL_OF_FLAMES_PROC, true);
- me->CastSpell(me, SPELL_BALL_OF_FLAMES_PERIODIC, true);
+ DoCastSelf(SPELL_BALL_OF_FLAMES_PROC, true);
+ DoCastSelf(SPELL_BALL_OF_FLAMES_PERIODIC, true);
}
}
@@ -1171,8 +988,11 @@ class npc_ball_of_flame : public CreatureScript
if (type == CHASE_MOTION_TYPE && id == _chaseGUID.GetCounter() && !_chaseGUID.IsEmpty())
{
me->RemoveAurasDueToSpell(SPELL_BALL_OF_FLAMES_PERIODIC);
- DoCast(me, SPELL_FLAMES);
- _despawnTimer = 1000;
+ DoCastSelf(SPELL_FLAMES);
+ _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/)
+ {
+ DoCastSelf(SPELL_FLAME_SPHERE_DEATH_EFFECT);
+ });
_chaseGUID.Clear();
}
}
@@ -1205,22 +1025,13 @@ class npc_ball_of_flame : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!_despawnTimer)
- return;
-
- if (_despawnTimer <= diff)
- {
- _despawnTimer = 0;
- DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT);
- }
- else
- _despawnTimer -= diff;
+ _scheduler.Update(diff);
}
private:
ObjectGuid _chaseGUID;
InstanceScript* _instance;
- uint32 _despawnTimer;
+ TaskScheduler _scheduler;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1236,19 +1047,14 @@ class npc_kinetic_bomb : public CreatureScript
struct npc_kinetic_bombAI : public ScriptedAI
{
- npc_kinetic_bombAI(Creature* creature) : ScriptedAI(creature)
- {
- _x = 0.f;
- _y = 0.f;
- _groundZ = 0.f;
- }
+ npc_kinetic_bombAI(Creature* creature) : ScriptedAI(creature), _x(0.f), _y(0.f), _groundZ(0.f) { }
void Reset() override
{
_events.Reset();
me->SetWalk(true);
- me->CastSpell(me, SPELL_UNSTABLE, true);
- me->CastSpell(me, SPELL_KINETIC_BOMB_VISUAL, true);
+ DoCastSelf(SPELL_UNSTABLE, true);
+ DoCastSelf(SPELL_KINETIC_BOMB_VISUAL, true);
me->SetReactState(REACT_PASSIVE);
me->GetPosition(_x, _y, _groundZ);
me->DespawnOrUnsummon(60000);
@@ -1258,12 +1064,16 @@ class npc_kinetic_bomb : public CreatureScript
void DoAction(int32 action) override
{
if (action == SPELL_KINETIC_BOMB_EXPLOSION)
- _events.ScheduleEvent(EVENT_BOMB_DESPAWN, 1000);
+ _events.ScheduleEvent(EVENT_BOMB_DESPAWN, Seconds(1));
+
else if (action == ACTION_KINETIC_BOMB_JUMP)
{
if (!me->HasAura(SPELL_KINETIC_BOMB_KNOCKBACK))
- me->GetMotionMaster()->MoveCharge(_x, _y, me->GetPositionZ() + 100.0f, me->GetSpeed(MOVE_RUN), 0);
- _events.RescheduleEvent(EVENT_CONTINUE_FALLING, 3000);
+ {
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveCharge(_x, _y, me->GetPositionZ() + 100.0f, me->GetSpeed(MOVE_RUN), POINT_KINETIC_BOMB_IMPACT);
+ }
+ _events.RescheduleEvent(EVENT_CONTINUE_FALLING, Seconds(3));
}
}
@@ -1280,7 +1090,8 @@ class npc_kinetic_bomb : public CreatureScript
me->DespawnOrUnsummon(5000);
break;
case EVENT_CONTINUE_FALLING:
- me->GetMotionMaster()->MoveCharge(_x, _y, _groundZ, me->GetSpeed(MOVE_WALK), POINT_KINETIC_BOMB_IMPACT);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveCharge(_x, _y, _groundZ, me->GetSpeed(MOVE_RUN), POINT_KINETIC_BOMB_IMPACT);
break;
default:
break;
@@ -1308,21 +1119,31 @@ class npc_dark_nucleus : public CreatureScript
struct npc_dark_nucleusAI : public ScriptedAI
{
- npc_dark_nucleusAI(Creature* creature) : ScriptedAI(creature)
- {
- _lockedTarget = false;
- _targetAuraCheck = 0;
- }
+ npc_dark_nucleusAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
me->SetReactState(REACT_DEFENSIVE);
- me->CastSpell(me, SPELL_SHADOW_RESONANCE_AURA, true);
+ DoCastSelf(SPELL_SHADOW_RESONANCE_AURA, true);
}
void EnterCombat(Unit* who) override
{
- _targetAuraCheck = 1000;
+ _scheduler.Schedule(Seconds(1), [this](TaskContext targetAuraCheck)
+ {
+ if (Unit* victim = me->GetVictim())
+ {
+ if (me->GetDistance(victim) < 15.0f && !victim->HasAura(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID()))
+ {
+ DoCast(victim, SPELL_SHADOW_RESONANCE_RESIST);
+ me->ClearUnitState(UNIT_STATE_CASTING);
+ }
+ else
+ MoveInLineOfSight(me->GetVictim());
+ }
+ targetAuraCheck.Repeat();
+ });
+
if (me->GetDistance(who) >= 15.0f)
{
DoStartMovement(who);
@@ -1333,11 +1154,6 @@ class npc_dark_nucleus : public CreatureScript
me->ClearUnitState(UNIT_STATE_CASTING);
}
- void MoveInLineOfSight(Unit* who) override
- {
- ScriptedAI::MoveInLineOfSight(who);
- }
-
void DamageTaken(Unit* attacker, uint32& /*damage*/) override
{
if (attacker == me)
@@ -1352,28 +1168,11 @@ class npc_dark_nucleus : public CreatureScript
if (!UpdateVictim())
return;
- if (_targetAuraCheck <= diff)
- {
- _targetAuraCheck = 1000;
- if (Unit* victim = me->GetVictim())
- {
- if (me->GetDistance(victim) < 15.0f &&
- !victim->HasAura(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID()))
- {
- DoCast(victim, SPELL_SHADOW_RESONANCE_RESIST);
- me->ClearUnitState(UNIT_STATE_CASTING);
- }
- else
- MoveInLineOfSight(me->GetVictim());
- }
- }
- else
- _targetAuraCheck -= diff;
+ _scheduler.Update(diff);
}
private:
- uint32 _targetAuraCheck;
- bool _lockedTarget;
+ TaskScheduler _scheduler;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -1382,6 +1181,7 @@ class npc_dark_nucleus : public CreatureScript
}
};
+// 71806 - Glittering Sparks
class spell_taldaram_glittering_sparks : public SpellScriptLoader
{
public:
@@ -1409,6 +1209,8 @@ class spell_taldaram_glittering_sparks : public SpellScriptLoader
}
};
+/* 71718 - Conjure Flame
+ 72040 - Conjure Empowered Flame */
class spell_taldaram_summon_flame_ball : public SpellScriptLoader
{
public:
@@ -1436,6 +1238,8 @@ class spell_taldaram_summon_flame_ball : public SpellScriptLoader
}
};
+/* 55891 - Flame Sphere Spawn Effect
+ 55947 - Flame Sphere Death Effect */
class spell_taldaram_flame_ball_visual : public SpellScriptLoader
{
public:
@@ -1452,6 +1256,11 @@ class spell_taldaram_flame_ball_visual : public SpellScriptLoader
return false;
}
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_BALL_OF_FLAMES });
+ }
+
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* target = GetTarget()->ToCreature();
@@ -1480,6 +1289,10 @@ class spell_taldaram_flame_ball_visual : public SpellScriptLoader
}
};
+/* 71756 - Ball of Flames Proc
+ 72782 - Ball of Flames Proc
+ 72783 - Ball of Flames Proc
+ 72784 - Ball of Flames Proc */
class spell_taldaram_ball_of_inferno_flame : public SpellScriptLoader
{
public:
@@ -1527,7 +1340,7 @@ class spell_taldaram_ball_of_inferno_flame : public SpellScriptLoader
}
};
-// 72080 - Kinetic Bomb (Valanar)
+// 72080 - Kinetic Bomb
class spell_valanar_kinetic_bomb : public SpellScriptLoader
{
public:
@@ -1553,6 +1366,11 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader
{
PrepareAuraScript(spell_valanar_kinetic_bomb_AuraScript);
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_KINETIC_BOMB_EXPLOSION, SPELL_KINETIC_BOMB_VISUAL });
+ }
+
void HandleDummyTick(AuraEffect const* /*aurEff*/)
{
Unit* target = GetTarget();
@@ -1585,6 +1403,7 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader
}
};
+// 72087 - Kinetic Bomb Knockback
class spell_valanar_kinetic_bomb_knockback : public SpellScriptLoader
{
public:
@@ -1615,6 +1434,7 @@ class spell_valanar_kinetic_bomb_knockback : public SpellScriptLoader
}
};
+// 72054 - Kinetic Bomb Visual
class spell_valanar_kinetic_bomb_absorb : public SpellScriptLoader
{
public:
@@ -1643,6 +1463,7 @@ class spell_valanar_kinetic_bomb_absorb : public SpellScriptLoader
}
};
+// 73001 - Shadow Prison
class spell_blood_council_shadow_prison : public SpellScriptLoader
{
public:
@@ -1652,10 +1473,15 @@ class spell_blood_council_shadow_prison : public SpellScriptLoader
{
PrepareAuraScript(spell_blood_council_shadow_prison_AuraScript);
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_SHADOW_PRISON_DAMAGE });
+ }
+
void HandleDummyTick(AuraEffect const* aurEff)
{
if (GetTarget()->isMoving())
- GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_PRISON_DAMAGE, true, NULL, aurEff);
+ GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_PRISON_DAMAGE, true, nullptr, aurEff);
}
void Register() override
@@ -1670,6 +1496,7 @@ class spell_blood_council_shadow_prison : public SpellScriptLoader
}
};
+// 72999 - Shadow Prison
class spell_blood_council_shadow_prison_damage : public SpellScriptLoader
{
public:
@@ -1706,8 +1533,8 @@ class at_blood_prince_council_start_intro : public AreaTriggerScript
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/, bool /*entered*/) override
{
if (InstanceScript* instance = player->GetInstanceScript())
- if (Creature* bloodQueen = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_BLOOD_QUEEN_LANA_THEL_COUNCIL)))
- bloodQueen->AI()->DoAction(ACTION_START_INTRO);
+ if (Creature* controller = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
+ controller->AI()->DoAction(ACTION_START_INTRO);
return true;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index c52e6ab1787..2f4dd00fea2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -97,9 +97,9 @@ enum ICDataTypes
DATA_PUTRICIDE_TABLE = 16,
DATA_NAUSEA_ACHIEVEMENT = 17,
DATA_ORB_WHISPERER_ACHIEVEMENT = 18,
- DATA_PRINCE_KELESETH_GUID = 19,
- DATA_PRINCE_TALDARAM_GUID = 20,
- DATA_PRINCE_VALANAR_GUID = 21,
+ DATA_PRINCE_KELESETH = 19,
+ DATA_PRINCE_TALDARAM = 20,
+ DATA_PRINCE_VALANAR = 21,
DATA_BLOOD_PRINCES_CONTROL = 22,
DATA_SINDRAGOSA_FROSTWYRMS = 23,
DATA_SPINESTALKER = 24,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index c70adae71e1..87dc5f0ee77 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -769,11 +769,11 @@ class instance_icecrown_citadel : public InstanceMapScript
return ProfessorPutricideGUID;
case DATA_PUTRICIDE_TABLE:
return PutricideTableGUID;
- case DATA_PRINCE_KELESETH_GUID:
+ case DATA_PRINCE_KELESETH:
return BloodCouncilGUIDs[0];
- case DATA_PRINCE_TALDARAM_GUID:
+ case DATA_PRINCE_TALDARAM:
return BloodCouncilGUIDs[1];
- case DATA_PRINCE_VALANAR_GUID:
+ case DATA_PRINCE_VALANAR:
return BloodCouncilGUIDs[2];
case DATA_BLOOD_PRINCES_CONTROL:
return BloodCouncilControllerGUID;