aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp885
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp4
2 files changed, 382 insertions, 507 deletions
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
index 4d8171b2485..747546b9d12 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
@@ -51,32 +51,29 @@ enum Summons
enum BossSpells
{
- SPELL_LEGION_FLAME = 66197, // player should run away from raid because he triggers Legion Flame
- SPELL_LEGION_FLAME_EFFECT = 66201, // used by trigger npc
- SPELL_NETHER_POWER = 66228, // +20% of spell damage per stack, stackable up to 5/10 times, must be dispelled/stealed
- SPELL_FEL_LIGHTING = 66528, // jumps to nearby targets
- SPELL_FEL_FIREBALL = 66532, // does heavy damage to the tank, interruptable
- SPELL_INCINERATE_FLESH = 66237, // target must be healed or will trigger Burning Inferno
- SPELL_BURNING_INFERNO = 66242, // triggered by Incinerate Flesh
- SPELL_INFERNAL_ERUPTION = 66258, // summons Infernal Volcano
- SPELL_INFERNAL_ERUPTION_EFFECT = 66252, // summons Felflame Infernal (3 at Normal and inifinity at Heroic)
- SPELL_NETHER_PORTAL = 66269, // summons Nether Portal
- SPELL_NETHER_PORTAL_EFFECT = 66263, // summons Mistress of Pain (1 at Normal and infinity at Heroic)
+ SPELL_LEGION_FLAME = 66197,
+ SPELL_LEGION_FLAME_EFFECT = 66201,
+ SPELL_NETHER_POWER = 66228,
+ SPELL_FEL_LIGHTNING = 66528,
+ SPELL_FEL_FIREBALL = 66532,
+ SPELL_INCINERATE_FLESH = 66237,
+ SPELL_BURNING_INFERNO = 66242,
+ SPELL_INFERNAL_ERUPTION = 66258,
+ SPELL_INFERNAL_ERUPTION_EFFECT = 66252,
+ SPELL_NETHER_PORTAL = 66269,
+ SPELL_NETHER_PORTAL_EFFECT = 66263,
SPELL_LORD_JARAXXUS_HITTIN_YA = 66327,
- SPELL_FEL_LIGHTNING = 67888,
-
- SPELL_BERSERK = 64238, // unused
+ SPELL_FEL_LIGHTNING_INTRO = 67888,
+ SPELL_BERSERK = 64238,
// Mistress of Pain spells
- SPELL_SHIVAN_SLASH = 67098,
- SPELL_SPINNING_STRIKE = 66283,
+ SPELL_SHIVAN_SLASH = 66378,
+ SPELL_SPINNING_SPIKE = 66283,
SPELL_MISTRESS_KISS = 66336,
- SPELL_LORD_HITTIN = 66326, // special effect preventing more specific spells be cast on the same player within 10 seconds
SPELL_MISTRESS_KISS_DAMAGE_SILENCE = 66359,
// Felflame Infernal
- SPELL_FEL_STREAK_VISUAL = 66493,
- SPELL_FEL_STREAK = 66494,
+ SPELL_FEL_STREAK_VISUAL = 66493
};
enum Events
@@ -88,8 +85,9 @@ enum Events
EVENT_INCINERATE_FLESH,
EVENT_NETHER_POWER,
EVENT_LEGION_FLAME,
- EVENT_SUMMONO_NETHER_PORTAL,
+ EVENT_SUMMON_NETHER_PORTAL,
EVENT_SUMMON_INFERNAL_ERUPTION,
+ EVENT_ENRAGE,
EVENT_TAUNT_GNOME,
EVENT_KILL_GNOME,
EVENT_CHANGE_ORIENTATION,
@@ -97,7 +95,7 @@ enum Events
// Mistress of Pain
EVENT_SHIVAN_SLASH,
- EVENT_SPINNING_STRIKE,
+ EVENT_SPINNING_SPIKE,
EVENT_MISTRESS_KISS
};
@@ -109,588 +107,461 @@ enum Misc
POINT_SUMMONED = 1
};
-class boss_jaraxxus : public CreatureScript
+
+struct boss_jaraxxus : public BossAI
{
- public:
- boss_jaraxxus() : CreatureScript("boss_jaraxxus") { }
+ boss_jaraxxus(Creature* creature) : BossAI(creature, DATA_JARAXXUS) { }
- struct boss_jaraxxusAI : public BossAI
+ void Reset() override
+ {
+ me->SetCombatPulseDelay(0);
+ me->ResetLootMode();
+ events.Reset();
+ summons.DespawnAll();
+
+ if (instance->GetBossState(DATA_JARAXXUS) == NOT_STARTED)
+ DoAction(ACTION_JARAXXUS_INTRO);
+ else if (instance->GetBossState(DATA_JARAXXUS) == FAIL)
{
- boss_jaraxxusAI(Creature* creature) : BossAI(creature, DATA_JARAXXUS) { }
-
- void Reset() override
- {
- _Reset();
- if (instance->GetBossState(DATA_JARAXXUS) == NOT_STARTED)
- DoAction(ACTION_JARAXXUS_INTRO);
- }
+ DoCastSelf(SPELL_JARAXXUS_CHAINS);
+ me->SetImmuneToPC(true);
+ me->SetReactState(REACT_PASSIVE);
+ }
+ }
- void JustReachedHome() override
- {
- _JustReachedHome();
- instance->SetBossState(DATA_JARAXXUS, FAIL);
- DoCastSelf(SPELL_JARAXXUS_CHAINS);
- me->SetImmuneToPC(true);
- me->SetReactState(REACT_PASSIVE);
- }
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _JustEngagedWith();
+ Talk(SAY_AGGRO);
+ events.ScheduleEvent(EVENT_FEL_FIREBALL, 6s);
+ events.ScheduleEvent(EVENT_FEL_LIGHTNING, 17s);
+ events.ScheduleEvent(EVENT_INCINERATE_FLESH, 14s);
+ events.ScheduleEvent(EVENT_NETHER_POWER, 22s);
+ events.ScheduleEvent(EVENT_LEGION_FLAME, 20s);
+ events.ScheduleEvent(EVENT_SUMMON_NETHER_PORTAL, 20s);
+ events.ScheduleEvent(EVENT_SUMMON_INFERNAL_ERUPTION, 1min + 20s);
+ events.ScheduleEvent(EVENT_ENRAGE, 10min);
+ }
- void DoAction(int32 action) override
- {
- if (action == ACTION_JARAXXUS_INTRO)
- {
- me->SetReactState(REACT_PASSIVE);
- events.SetPhase(PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO, 1s);
- }
- else if (action == ACTION_JARAXXUS_ENGAGE)
- {
- me->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
- me->SetImmuneToPC(false);
- me->SetReactState(REACT_AGGRESSIVE);
- DoZoneInCombat();
- }
- }
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ _EnterEvadeMode();
+ instance->SetBossState(DATA_JARAXXUS, FAIL);
+ me->DespawnOrUnsummon();
+ }
- void MovementInform(uint32 type, uint32 pointId) override
- {
- if (type == SPLINE_CHAIN_MOTION_TYPE && pointId == POINT_SUMMONED)
- if (Creature* wilfred = instance->GetCreature(DATA_FIZZLEBANG))
- {
- me->SetFacingToObject(wilfred);
- events.ScheduleEvent(EVENT_TAUNT_GNOME, 9s);
- }
- }
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_JARAXXUS_INTRO)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ events.SetPhase(PHASE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO, 1s);
+ }
+ else if (action == ACTION_JARAXXUS_ENGAGE)
+ {
+ me->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
+ me->SetImmuneToPC(false);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat();
+ }
+ }
- void KilledUnit(Unit* who) override
+ void MovementInform(uint32 type, uint32 pointId) override
+ {
+ if (type == SPLINE_CHAIN_MOTION_TYPE && pointId == POINT_SUMMONED)
+ if (Creature* wilfred = instance->GetCreature(DATA_FIZZLEBANG))
{
- if (who->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_KILL_PLAYER);
+ me->SetFacingToObject(wilfred);
+ events.ScheduleEvent(EVENT_TAUNT_GNOME, 9s);
}
+ }
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
+ void KilledUnit(Unit* who) override
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_KILL_PLAYER);
+ }
- void JustEngagedWith(Unit* /*who*/) override
- {
- _JustEngagedWith();
- Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_FEL_FIREBALL, 5 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_FEL_LIGHTNING, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
- events.ScheduleEvent(EVENT_INCINERATE_FLESH, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
- events.ScheduleEvent(EVENT_NETHER_POWER, 40 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_LEGION_FLAME, 30 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_SUMMONO_NETHER_PORTAL, 20 * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_SUMMON_INFERNAL_ERUPTION, 80 * IN_MILLISECONDS);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(SAY_DEATH);
+ _JustDied();
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
+ return;
- events.Update(diff);
+ events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FEL_FIREBALL:
+ DoCastVictim(SPELL_FEL_FIREBALL);
+ events.Repeat(11s, 13s);
+ break;
+ case EVENT_FEL_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_FEL_LIGHTNING);
+ events.Repeat(10s, 30s);
+ break;
+ case EVENT_INCINERATE_FLESH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{
- case EVENT_FEL_FIREBALL:
- DoCastVictim(SPELL_FEL_FIREBALL);
- events.ScheduleEvent(EVENT_FEL_FIREBALL, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
- break;
- case EVENT_FEL_LIGHTNING:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, true, -SPELL_LORD_HITTIN))
- DoCast(target, SPELL_FEL_LIGHTING);
- events.ScheduleEvent(EVENT_FEL_LIGHTNING, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
- break;
- case EVENT_INCINERATE_FLESH:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, true, -SPELL_LORD_HITTIN))
- {
- Talk(EMOTE_INCINERATE, target);
- Talk(SAY_INCINERATE);
- DoCast(target, SPELL_INCINERATE_FLESH);
- }
- events.ScheduleEvent(EVENT_INCINERATE_FLESH, urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS));
- break;
- case EVENT_NETHER_POWER:
- {
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.AddSpellMod(SPELLVALUE_AURA_STACK, RAID_MODE(5, 10, 5, 10));
- me->CastSpell(me, SPELL_NETHER_POWER, args);
- events.ScheduleEvent(EVENT_NETHER_POWER, 40 * IN_MILLISECONDS);
- break;
- }
- case EVENT_LEGION_FLAME:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, true, -SPELL_LORD_HITTIN))
- {
- Talk(EMOTE_LEGION_FLAME, target);
- DoCast(target, SPELL_LEGION_FLAME);
- }
- events.ScheduleEvent(EVENT_LEGION_FLAME, 30*IN_MILLISECONDS);
- break;
- case EVENT_SUMMONO_NETHER_PORTAL:
- Talk(EMOTE_NETHER_PORTAL);
- Talk(SAY_MISTRESS_OF_PAIN);
- DoCast(SPELL_NETHER_PORTAL);
- events.ScheduleEvent(EVENT_SUMMONO_NETHER_PORTAL, 2*MINUTE*IN_MILLISECONDS);
- break;
- case EVENT_SUMMON_INFERNAL_ERUPTION:
- Talk(EMOTE_INFERNAL_ERUPTION);
- Talk(SAY_INFERNAL_ERUPTION);
- DoCast(SPELL_INFERNAL_ERUPTION);
- events.ScheduleEvent(EVENT_SUMMON_INFERNAL_ERUPTION, 2*MINUTE*IN_MILLISECONDS);
- break;
- case EVENT_INTRO:
- DoCastSelf(SPELL_LORD_JARAXXUS_HITTIN_YA, true);
- me->GetMotionMaster()->MoveAlongSplineChain(POINT_SUMMONED, SPLINE_INITIAL_MOVEMENT, true);
- break;
- case EVENT_TAUNT_GNOME:
- Talk(SAY_INTRO);
- events.ScheduleEvent(EVENT_KILL_GNOME, 9s);
- break;
- case EVENT_KILL_GNOME:
- DoCastSelf(SPELL_FEL_LIGHTNING);
- events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, 3s);
- break;
- case EVENT_CHANGE_ORIENTATION:
- me->SetFacingTo(4.729842f);
- events.ScheduleEvent(EVENT_START_COMBAT, 7s);
- break;
- case EVENT_START_COMBAT:
- me->SetImmuneToPC(false);
- me->SetReactState(REACT_AGGRESSIVE);
- DoZoneInCombat();
- break;
- default:
- break;
+ Talk(EMOTE_INCINERATE, target);
+ Talk(SAY_INCINERATE);
+ DoCast(target, SPELL_INCINERATE_FLESH);
}
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ events.Repeat(23s);
+ break;
+ case EVENT_NETHER_POWER:
+ {
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.AddSpellMod(SPELLVALUE_AURA_STACK, RAID_MODE(5, 10, 5, 10));
+ me->CastSpell(me, SPELL_NETHER_POWER, args);
+ events.Repeat(42s);
+ break;
}
-
- DoMeleeAttackIfReady();
+ case EVENT_LEGION_FLAME:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ {
+ Talk(EMOTE_LEGION_FLAME, target);
+ DoCast(target, SPELL_LEGION_FLAME);
+ }
+ events.Repeat(30s);
+ break;
+ case EVENT_SUMMON_NETHER_PORTAL:
+ Talk(EMOTE_NETHER_PORTAL);
+ Talk(SAY_MISTRESS_OF_PAIN);
+ DoCast(SPELL_NETHER_PORTAL);
+ events.Repeat(2min);
+ break;
+ case EVENT_SUMMON_INFERNAL_ERUPTION:
+ Talk(EMOTE_INFERNAL_ERUPTION);
+ Talk(SAY_INFERNAL_ERUPTION);
+ DoCast(SPELL_INFERNAL_ERUPTION);
+ events.Repeat(2min);
+ break;
+ case EVENT_INTRO:
+ DoCastSelf(SPELL_LORD_JARAXXUS_HITTIN_YA, true);
+ me->GetMotionMaster()->MoveAlongSplineChain(POINT_SUMMONED, SPLINE_INITIAL_MOVEMENT, true);
+ break;
+ case EVENT_TAUNT_GNOME:
+ Talk(SAY_INTRO);
+ events.ScheduleEvent(EVENT_KILL_GNOME, 9s);
+ break;
+ case EVENT_KILL_GNOME:
+ DoCastSelf(SPELL_FEL_LIGHTNING_INTRO);
+ events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, 3s);
+ break;
+ case EVENT_CHANGE_ORIENTATION:
+ me->SetFacingTo(4.729842f);
+ events.ScheduleEvent(EVENT_START_COMBAT, 7s);
+ break;
+ case EVENT_START_COMBAT:
+ me->SetImmuneToPC(false);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat();
+ break;
+ case EVENT_ENRAGE:
+ Talk(SAY_BERSERK);
+ DoCastSelf(SPELL_BERSERK, true);
+ break;
+ default:
+ break;
}
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetTrialOfTheCrusaderAI<boss_jaraxxusAI>(creature);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
+
+ DoMeleeAttackIfReady();
+ }
};
-class npc_legion_flame : public CreatureScript
+struct npc_legion_flame : public ScriptedAI
{
- public:
- npc_legion_flame() : CreatureScript("npc_legion_flame") { }
+ npc_legion_flame(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
+ {
+ SetCombatMovement(false);
+ }
- struct npc_legion_flameAI : public ScriptedAI
+ void Reset() override
+ {
+ if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS)
{
- npc_legion_flameAI(Creature* creature) : ScriptedAI(creature)
- {
- SetCombatMovement(false);
- _instance = creature->GetInstanceScript();
- }
+ me->DespawnOrUnsummon();
+ return;
+ }
- void Reset() override
- {
- me->AddUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE));
- me->SetInCombatWithZone();
- DoCast(SPELL_LEGION_FLAME_EFFECT);
- }
+ if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS))
+ jaraxxus->AI()->JustSummoned(me);
- void UpdateAI(uint32 /*diff*/) override
- {
- UpdateVictim();
- if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS)
- me->DespawnOrUnsummon();
- }
- private:
- InstanceScript* _instance;
- };
+ me->SetReactState(REACT_PASSIVE);
+ DoCastSelf(SPELL_LEGION_FLAME_EFFECT, true);
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetTrialOfTheCrusaderAI<npc_legion_flameAI>(creature);
- }
+private:
+ InstanceScript* _instance;
};
-class npc_infernal_volcano : public CreatureScript
+struct npc_infernal_volcano : public ScriptedAI
{
- public:
- npc_infernal_volcano() : CreatureScript("npc_infernal_volcano") { }
-
- struct npc_infernal_volcanoAI : public ScriptedAI
- {
- npc_infernal_volcanoAI(Creature* creature) : ScriptedAI(creature), _summons(me)
- {
- SetCombatMovement(false);
- }
-
- void Reset() override
- {
- me->SetReactState(REACT_PASSIVE);
-
- if (!IsHeroic())
- me->AddUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED));
- else
- me->RemoveUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED));
-
- _summons.DespawnAll();
- }
-
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- DoCast(SPELL_INFERNAL_ERUPTION_EFFECT);
- }
-
- void JustSummoned(Creature* summoned) override
- {
- _summons.Summon(summoned);
- // makes immediate corpse despawn of summoned Felflame Infernals
- summoned->SetCorpseDelay(0);
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- // used to despawn corpse immediately
- me->DespawnOrUnsummon();
- }
-
- void UpdateAI(uint32 /*diff*/) override { }
-
- private:
- SummonList _summons;
- };
+ npc_infernal_volcano(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetTrialOfTheCrusaderAI<npc_infernal_volcanoAI>(creature);
- }
+ void Reset() override
+ {
+ me->SetReactState(REACT_PASSIVE);
+ DoCastSelf(SPELL_INFERNAL_ERUPTION_EFFECT, true);
+ if (IsHeroic())
+ me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ }
};
-class npc_fel_infernal : public CreatureScript
+struct npc_fel_infernal : public ScriptedAI
{
- public:
- npc_fel_infernal() : CreatureScript("npc_fel_infernal") { }
+ npc_fel_infernal(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- struct npc_fel_infernalAI : public ScriptedAI
+ void Reset() override
+ {
+ if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS)
{
- npc_fel_infernalAI(Creature* creature) : ScriptedAI(creature)
- {
- _instance = creature->GetInstanceScript();
- }
+ me->DespawnOrUnsummon();
+ return;
+ }
- void Reset() override
- {
- _scheduler.Schedule(Seconds(2), [this](TaskContext context)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
- DoCast(target, SPELL_FEL_STREAK_VISUAL);
- context.Repeat(Seconds(15));
- });
- me->SetInCombatWithZone();
- }
+ if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS))
+ jaraxxus->AI()->JustSummoned(me);
- void UpdateAI(uint32 diff) override
- {
- if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS)
- {
- me->DespawnOrUnsummon();
- return;
- }
+ _scheduler.SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ });
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ _scheduler.Schedule(Seconds(2), [this](TaskContext context)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_FEL_STREAK_VISUAL);
+ context.Repeat(Seconds(15));
+ });
- if (!UpdateVictim())
- return;
+ DoCastSelf(SPELL_LORD_JARAXXUS_HITTIN_YA, true);
+ }
- _scheduler.Update(diff, [this]
- {
- DoMeleeAttackIfReady();
- });
- }
- private:
- InstanceScript* _instance;
- TaskScheduler _scheduler;
- };
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- CreatureAI* GetAI(Creature* creature) const override
+ _scheduler.Update(diff, [this]
{
- return GetTrialOfTheCrusaderAI<npc_fel_infernalAI>(creature);
- }
+ DoMeleeAttackIfReady();
+ });
+ }
+
+private:
+ InstanceScript* _instance;
+ TaskScheduler _scheduler;
};
-class npc_nether_portal : public CreatureScript
+struct npc_nether_portal : public ScriptedAI
{
- public:
- npc_nether_portal() : CreatureScript("npc_nether_portal") { }
-
- struct npc_nether_portalAI : public ScriptedAI
- {
- npc_nether_portalAI(Creature* creature) : ScriptedAI(creature), _summons(me) { }
+ npc_nether_portal(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ }
- void Reset() override
- {
- me->SetReactState(REACT_PASSIVE);
+ void Reset() override
+ {
+ me->SetReactState(REACT_PASSIVE);
+ DoCastSelf(SPELL_NETHER_PORTAL_EFFECT, true);
+ if (IsHeroic())
+ me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ }
+};
- if (!IsHeroic())
- me->AddUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED));
- else
- me->RemoveUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED));
+struct npc_mistress_of_pain : public ScriptedAI
+{
+ npc_mistress_of_pain(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- _summons.DespawnAll();
- }
+ void Reset() override
+ {
+ if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS)
+ {
+ me->DespawnOrUnsummon();
+ return;
+ }
- void IsSummonedBy(Unit* /*summoner*/) override
- {
- DoCast(SPELL_NETHER_PORTAL_EFFECT);
- }
+ if (Creature* jaraxxus = _instance->GetCreature(DATA_JARAXXUS))
+ jaraxxus->AI()->JustSummoned(me);
- void JustSummoned(Creature* summoned) override
- {
- _summons.Summon(summoned);
- // makes immediate corpse despawn of summoned Mistress of Pain
- summoned->SetCorpseDelay(0);
- }
+ DoCastSelf(SPELL_LORD_JARAXXUS_HITTIN_YA, true);
+ _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- // used to despawn corpse immediately
- me->DespawnOrUnsummon();
- }
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 4s);
+ _events.ScheduleEvent(EVENT_SPINNING_SPIKE, 9s);
+ if (IsHeroic())
+ _events.ScheduleEvent(EVENT_MISTRESS_KISS, 15s);
+ }
- void UpdateAI(uint32 /*diff*/) override { }
+ void JustDied(Unit* /*killer*/) override
+ {
+ _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
+ }
- private:
- SummonList _summons;
- };
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetTrialOfTheCrusaderAI<npc_nether_portalAI>(creature);
- }
-};
+ _events.Update(diff);
-class npc_mistress_of_pain : public CreatureScript
-{
- public:
- npc_mistress_of_pain() : CreatureScript("npc_mistress_of_pain") { }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- struct npc_mistress_of_painAI : public ScriptedAI
+ while (uint32 eventId = _events.ExecuteEvent())
{
- npc_mistress_of_painAI(Creature* creature) : ScriptedAI(creature)
+ switch (eventId)
{
- _instance = creature->GetInstanceScript();
- _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
- }
-
- void Reset() override
- {
- _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 30*IN_MILLISECONDS);
- _events.ScheduleEvent(EVENT_SPINNING_STRIKE, 30*IN_MILLISECONDS);
- if (IsHeroic())
- _events.ScheduleEvent(EVENT_MISTRESS_KISS, 15*IN_MILLISECONDS);
- me->SetInCombatWithZone();
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (_instance->GetBossState(DATA_JARAXXUS) != IN_PROGRESS)
- {
- me->DespawnOrUnsummon();
+ case EVENT_SHIVAN_SLASH:
+ DoCastVictim(SPELL_SHIVAN_SLASH);
+ _events.Repeat(3s, 10s);
return;
- }
-
- if (!UpdateVictim())
+ case EVENT_SPINNING_SPIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_SPINNING_SPIKE);
+ _events.Repeat(20s);
return;
-
- _events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
+ case EVENT_MISTRESS_KISS:
+ DoCastSelf(SPELL_MISTRESS_KISS);
+ _events.Repeat(30s);
return;
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SHIVAN_SLASH:
- DoCastVictim(SPELL_SHIVAN_SLASH);
- _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 30*IN_MILLISECONDS);
- return;
- case EVENT_SPINNING_STRIKE:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
- DoCast(target, SPELL_SPINNING_STRIKE);
- _events.ScheduleEvent(EVENT_SPINNING_STRIKE, 30*IN_MILLISECONDS);
- return;
- case EVENT_MISTRESS_KISS:
- DoCast(me, SPELL_MISTRESS_KISS);
- _events.ScheduleEvent(EVENT_MISTRESS_KISS, 30*IN_MILLISECONDS);
- return;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
+ default:
+ break;
}
- private:
- InstanceScript* _instance;
- EventMap _events;
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetTrialOfTheCrusaderAI<npc_mistress_of_painAI>(creature);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
-};
-class spell_mistress_kiss : public SpellScriptLoader
-{
- public:
- spell_mistress_kiss() : SpellScriptLoader("spell_mistress_kiss") { }
+ DoMeleeAttackIfReady();
+ }
- class spell_mistress_kiss_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_mistress_kiss_AuraScript);
+private:
+ InstanceScript* _instance;
+ EventMap _events;
+};
- bool Load() override
- {
- return ValidateSpellInfo({ SPELL_MISTRESS_KISS_DAMAGE_SILENCE });
- }
+// 66334, 67905, 67906, 67907 - Mistress' Kiss
+class spell_mistress_kiss : public AuraScript
+{
+ PrepareAuraScript(spell_mistress_kiss);
- void HandleDummyTick(AuraEffect const* /*aurEff*/)
- {
- Unit* caster = GetCaster();
- Unit* target = GetTarget();
- if (caster && target)
- {
- if (target->HasUnitState(UNIT_STATE_CASTING))
- {
- caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true);
- target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
- }
- }
- }
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_MISTRESS_KISS_DAMAGE_SILENCE });
+ }
- void Register() override
+ void HandleDummyTick(AuraEffect const* /*aurEff*/)
+ {
+ Unit* target = GetTarget();
+ if (Unit* caster = GetCaster())
+ if (target->HasUnitState(UNIT_STATE_CASTING))
{
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_mistress_kiss_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true);
+ target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
}
- };
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_mistress_kiss_AuraScript();
- }
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_mistress_kiss::HandleDummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
};
-class MistressKissTargetSelector
+// 66336, 67076, 67077, 67078 - Mistress' Kiss
+class spell_mistress_kiss_area : public SpellScript
{
- public:
- MistressKissTargetSelector() { }
-
- bool operator()(WorldObject* unit) const
- {
- if (unit->GetTypeId() == TYPEID_PLAYER && unit->ToUnit()->GetPowerType() == POWER_MANA)
- return false;
+ PrepareSpellScript(spell_mistress_kiss_area);
- return true;
- }
-};
-
-class spell_mistress_kiss_area : public SpellScriptLoader
-{
- public:
- spell_mistress_kiss_area() : SpellScriptLoader("spell_mistress_kiss_area") { }
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ SpellEffectInfo const* effect0 = spellInfo->GetEffect(EFFECT_0);
+ return effect0 && ValidateSpellInfo({ static_cast<uint32>(effect0->CalcValue()) });
+ }
- class spell_mistress_kiss_area_SpellScript : public SpellScript
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ // get a list of players with mana
+ targets.remove_if([](WorldObject* target)
{
- PrepareSpellScript(spell_mistress_kiss_area_SpellScript);
-
- void FilterTargets(std::list<WorldObject*>& targets)
- {
- // get a list of players with mana
- targets.remove_if(MistressKissTargetSelector());
- if (targets.empty())
- return;
+ return target->GetTypeId() == TYPEID_PLAYER && target->ToUnit()->GetPowerIndex(POWER_MANA) == MAX_POWERS;
+ });
- WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
- targets.clear();
- targets.push_back(target);
- }
+ if (targets.empty())
+ return;
- void HandleScript(SpellEffIndex /*effIndex*/)
- {
- GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
- }
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mistress_kiss_area_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnEffectHitTarget += SpellEffectFn(spell_mistress_kiss_area_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_mistress_kiss_area_SpellScript();
- }
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mistress_kiss_area::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_mistress_kiss_area::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
-class spell_fel_streak_visual : public SpellScriptLoader
+// 66493 - Fel Streak
+class spell_fel_streak_visual : public SpellScript
{
-public:
- spell_fel_streak_visual() : SpellScriptLoader("spell_fel_streak_visual") { }
+ PrepareSpellScript(spell_fel_streak_visual);
- class spell_fel_streak_visual_SpellScript : public SpellScript
+ bool Validate(SpellInfo const* spellInfo) override
{
- PrepareSpellScript(spell_fel_streak_visual_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_FEL_STREAK });
- }
-
- void HandleScript(SpellEffIndex /*effIndex*/)
- {
- GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
- }
+ SpellEffectInfo const* effect0 = spellInfo->GetEffect(EFFECT_0);
+ return effect0 && ValidateSpellInfo({ static_cast<uint32>(effect0->CalcValue()) });
+ }
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_fel_streak_visual_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), static_cast<uint32>(GetEffectValue()), true);
+ }
- SpellScript* GetSpellScript() const override
+ void Register() override
{
- return new spell_fel_streak_visual_SpellScript();
+ OnEffectHitTarget += SpellEffectFn(spell_fel_streak_visual::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
void AddSC_boss_jaraxxus()
{
- new boss_jaraxxus();
- new npc_legion_flame();
- new npc_infernal_volcano();
- new npc_fel_infernal();
- new npc_nether_portal();
- new npc_mistress_of_pain();
-
- new spell_mistress_kiss();
- new spell_mistress_kiss_area();
- new spell_fel_streak_visual();
+ RegisterTrialOfTheCrusaderCreatureAI(boss_jaraxxus);
+ RegisterTrialOfTheCrusaderCreatureAI(npc_legion_flame);
+ RegisterTrialOfTheCrusaderCreatureAI(npc_infernal_volcano);
+ RegisterTrialOfTheCrusaderCreatureAI(npc_fel_infernal);
+ RegisterTrialOfTheCrusaderCreatureAI(npc_nether_portal);
+ RegisterTrialOfTheCrusaderCreatureAI(npc_mistress_of_pain);
+ RegisterAuraScript(spell_mistress_kiss);
+ RegisterSpellScript(spell_mistress_kiss_area);
+ RegisterSpellScript(spell_fel_streak_visual);
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index 7d57afe379b..ce0edfe8d88 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -390,7 +390,11 @@ struct npc_tirion_toc : public ScriptedAI
else if (_instance->GetBossState(DATA_NORTHREND_BEASTS) != DONE)
me->SummonCreature(NPC_BARRETT_BEASTS, BarretSpawnPosition);
else if (_instance->GetBossState(DATA_JARAXXUS) != DONE)
+ {
me->SummonCreature(NPC_BARRETT_JARAXXUS, BarretSpawnPosition);
+ if (_instance->GetBossState(DATA_JARAXXUS) == FAIL)
+ DoAction(ACTION_SUMMON_JARAXXUS);
+ }
else if (_instance->GetBossState(DATA_FACTION_CRUSADERS) != DONE)
me->SummonCreature(NPC_BARRETT_FACTION, BarretSpawnPosition);
else if (_instance->GetBossState(DATA_TWIN_VALKIRIES) != DONE)