Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_lord_jaraxxus.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "SpellScript.h"
9#include "Player.h"
11
27
29{
32 NPC_FEL_INFERNAL = 34815, // immune to all CC on Heroic (stuns, banish, interrupt, etc)
35};
36
38{
39 SPELL_LEGION_FLAME = 66197, // player should run away from raid because he triggers Legion Flame
40 SPELL_LEGION_FLAME_EFFECT = 66201, // used by trigger npc
41 SPELL_NETHER_POWER = 66228, // +20% of spell damage per stack, stackable up to 5/10 times, must be dispelled/stealed
42 SPELL_FEL_LIGHTING = 66528, // jumps to nearby targets
43 SPELL_FEL_FIREBALL = 66532, // does heavy damage to the tank, interruptable
44 SPELL_INCINERATE_FLESH = 66237, // target must be healed or will trigger Burning Inferno
45 SPELL_BURNING_INFERNO = 66242, // triggered by Incinerate Flesh
46 SPELL_INFERNAL_ERUPTION = 66258, // summons Infernal Volcano
47 SPELL_INFERNAL_ERUPTION_EFFECT = 66252, // summons Felflame Infernal (3 at Normal and inifinity at Heroic)
48 SPELL_NETHER_PORTAL = 66269, // summons Nether Portal
49 SPELL_NETHER_PORTAL_EFFECT = 66263, // summons Mistress of Pain (1 at Normal and infinity at Heroic)
50
51 SPELL_BERSERK = 64238, // unused
52
53 // Mistress of Pain spells
59 SPELL_LORD_HITTIN = 66326, // special effect preventing more specific spells be cast on the same player within 10 seconds
61};
62
79
81{
82 public:
83 boss_jaraxxus() : CreatureScript("boss_jaraxxus") { }
84
85 struct boss_jaraxxusAI : public BossAI
86 {
88 {
89 }
90
92 {
93 _Reset();
95 events.ScheduleEvent(EVENT_FEL_LIGHTNING, std::rand() % (15 * IN_MILLISECONDS) + (10*IN_MILLISECONDS));
96 events.ScheduleEvent(EVENT_INCINERATE_FLESH, std::rand() % (25 * IN_MILLISECONDS) + (20 * IN_MILLISECONDS));
97 events.ScheduleEvent(EVENT_NETHER_POWER, 40*IN_MILLISECONDS);
98 events.ScheduleEvent(EVENT_LEGION_FLAME, 30*IN_MILLISECONDS);
101 }
102
111
113 {
114 if (who->GetTypeId() == TypeID::TYPEID_PLAYER)
115 {
117 if (instance)
119 }
120 }
121
122 void JustDied(Unit* /*killer*/) OVERRIDE
123 {
124 _JustDied();
126 }
127
129 {
130 summons.Summon(summoned);
131 }
132
133 void EnterCombat(Unit* /*who*/) OVERRIDE
134 {
135 _EnterCombat();
137 }
138
140 {
141 if (!UpdateVictim())
142 return;
143
144 events.Update(diff);
145
146 if (me->HasUnitState(UNIT_STATE_CASTING))
147 return;
148
149 while (uint32 eventId = events.ExecuteEvent())
150 {
151 switch (eventId)
152 {
155 events.ScheduleEvent(EVENT_FEL_FIREBALL, std::rand() % (15 * IN_MILLISECONDS) + (10*IN_MILLISECONDS));
156 return;
158 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_LORD_HITTIN))
159 DoCast(target, SPELL_FEL_LIGHTING);
160 events.ScheduleEvent(EVENT_FEL_LIGHTNING, std::rand() % (15 * IN_MILLISECONDS) + (10*IN_MILLISECONDS));
161 return;
163 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_LORD_HITTIN))
164 {
165 Talk(EMOTE_INCINERATE, target);
168 }
169 events.ScheduleEvent(EVENT_INCINERATE_FLESH, std::rand() % (25 * IN_MILLISECONDS) + (20 * IN_MILLISECONDS));
170 return;
172 me->CastCustomSpell(SPELL_NETHER_POWER, SPELLVALUE_AURA_STACK, RAID_MODE<uint32>(5, 10, 5, 10), me, true);
173 events.ScheduleEvent(EVENT_NETHER_POWER, 40*IN_MILLISECONDS);
174 return;
176 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_LORD_HITTIN))
177 {
178 Talk(EMOTE_LEGION_FLAME, target);
179 DoCast(target, SPELL_LEGION_FLAME);
180 }
181 events.ScheduleEvent(EVENT_LEGION_FLAME, 30*IN_MILLISECONDS);
182 return;
188 return;
194 return;
195 }
196 }
197
199 }
200 };
201
203 {
204 return new boss_jaraxxusAI(creature);
205 }
206};
207
209{
210 public:
211 npc_legion_flame() : CreatureScript("npc_legion_flame") { }
212
214 {
216 {
217 SetCombatMovement(false);
218 _instance = creature->GetInstanceScript();
219 }
220
222 {
224 me->SetInCombatWithZone();
226 }
227
228 void UpdateAI(uint32 /*diff*/) OVERRIDE
229 {
230 UpdateVictim();
231 if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
232 me->DespawnOrUnsummon();
233 }
234 private:
236 };
237
239 {
240 return new npc_legion_flameAI(creature);
241 }
242};
243
245{
246 public:
247 npc_infernal_volcano() : CreatureScript("npc_infernal_volcano") { }
248
250 {
252 {
253 SetCombatMovement(false);
254 }
255
257 {
258 me->SetReactState(REACT_PASSIVE);
259
260 if (!IsHeroic())
262 else
264
265 _summons.DespawnAll();
266 }
267
268 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
269 {
271 }
272
274 {
275 _summons.Summon(summoned);
276 // makes immediate corpse despawn of summoned Felflame Infernals
277 summoned->SetCorpseDelay(0);
278 }
279
280 void JustDied(Unit* /*killer*/) OVERRIDE
281 {
282 // used to despawn corpse immediately
283 me->DespawnOrUnsummon();
284 }
285
286 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
287
288 private:
290 };
291
293 {
294 return new npc_infernal_volcanoAI(creature);
295 }
296};
297
299{
300 public:
301 npc_fel_infernal() : CreatureScript("npc_fel_infernal") { }
302
304 {
306 {
307 _instance = creature->GetInstanceScript();
308 }
309
311 {
313 me->SetInCombatWithZone();
314 }
315
317 {
318 if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
319 {
320 me->DespawnOrUnsummon();
321 return;
322 }
323
324 if (!UpdateVictim())
325 return;
326
327 if (_felStreakTimer <= diff)
328 {
329 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
330 DoCast(target, SPELL_FEL_STREAK);
332 }
333 else
334 _felStreakTimer -= diff;
335
337 }
338 private:
341 };
342
344 {
345 return new npc_fel_infernalAI(creature);
346 }
347};
348
350{
351 public:
352 npc_nether_portal() : CreatureScript("npc_nether_portal") { }
353
355 {
357 {
358 }
359
361 {
362 me->SetReactState(REACT_PASSIVE);
363
364 if (!IsHeroic())
366 else
368
369 _summons.DespawnAll();
370 }
371
372 void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
373 {
375 }
376
378 {
379 _summons.Summon(summoned);
380 // makes immediate corpse despawn of summoned Mistress of Pain
381 summoned->SetCorpseDelay(0);
382 }
383
384 void JustDied(Unit* /*killer*/) OVERRIDE
385 {
386 // used to despawn corpse immediately
387 me->DespawnOrUnsummon();
388 }
389
390 void UpdateAI(uint32 /*diff*/) OVERRIDE { }
391
392 private:
394 };
395
397 {
398 return new npc_nether_portalAI(creature);
399 }
400};
401
403{
404 public:
405 npc_mistress_of_pain() : CreatureScript("npc_mistress_of_pain") { }
406
408 {
410 {
411 _instance = creature->GetInstanceScript();
412 if (_instance)
414 }
415
417 {
418 _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 30*IN_MILLISECONDS);
420 if (IsHeroic())
422 me->SetInCombatWithZone();
423 }
424
425 void JustDied(Unit* /*killer*/) OVERRIDE
426 {
427 if (_instance)
429 }
430
432 {
433 if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
434 {
435 me->DespawnOrUnsummon();
436 return;
437 }
438
439 if (!UpdateVictim())
440 return;
441
442 _events.Update(diff);
443
444 if (me->HasUnitState(UNIT_STATE_CASTING))
445 return;
446
447 while (uint32 eventId = _events.ExecuteEvent())
448 {
449 switch (eventId)
450 {
453 _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 30*IN_MILLISECONDS);
454 return;
456 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
459 return;
463 return;
464 default:
465 break;
466 }
467 }
468
470 }
471 private:
474 };
475
477 {
478 return new npc_mistress_of_painAI(creature);
479 }
480};
481
483{
484 public:
485 spell_mistress_kiss() : SpellScriptLoader("spell_mistress_kiss") { }
486
488 {
490
492 {
493 if (GetCaster())
494 if (sSpellMgr->GetSpellIdForDifficulty(SPELL_MISTRESS_KISS_DAMAGE_SILENCE, GetCaster()))
495 return true;
496 return false;
497 }
498
499 void HandleDummyTick(AuraEffect const* /*aurEff*/)
500 {
501 Unit* caster = GetCaster();
502 Unit* target = GetTarget();
503 if (caster && target)
504 {
505 if (target->HasUnitState(UNIT_STATE_CASTING))
506 {
507 caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true);
508 target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
509 }
510 }
511 }
512
517 };
518
520 {
522 }
523};
524
526{
527 public:
529
530 bool operator()(WorldObject* unit) const
531 {
532 if (unit->GetTypeId() == TypeID::TYPEID_PLAYER)
533 if (unit->ToPlayer()->getPowerType() == POWER_MANA)
534 return false;
535
536 return true;
537 }
538};
539
541{
542 public:
543 spell_mistress_kiss_area() : SpellScriptLoader("spell_mistress_kiss_area") { }
544
546 {
548
549 void FilterTargets(std::list<WorldObject*>& targets)
550 {
551 // get a list of players with mana
552 targets.remove_if(MistressKissTargetSelector());
553 if (targets.empty())
554 return;
555
557 targets.clear();
558 targets.push_back(target);
559 }
560
561 void HandleScript(SpellEffIndex /*effIndex*/)
562 {
564 }
565
571 };
572
577};
578
580{
581 new boss_jaraxxus();
582 new npc_legion_flame();
584 new npc_fel_infernal();
585 new npc_nether_portal();
587
590}
@ IN_MILLISECONDS
Definition Common.h:125
@ MINUTE
Definition Common.h:119
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ IN_PROGRESS
@ FAIL
@ TYPEID_PLAYER
Definition Object.h:55
SpellEffIndex
@ EFFECT_0
@ POWER_MANA
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_AURA_PERIODIC_DUMMY
#define sSpellMgr
Definition SpellMgr.h:744
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
@ SPELLVALUE_AURA_STACK
Definition Unit.h:119
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_PACIFIED
Definition Unit.h:642
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ SAY_BERSERK
@ SAY_INTRO
#define SAY_DEATH
#define SAY_AGGRO
#define SPELL_BERSERK
@ SAY_MISTRESS_OF_PAIN
@ EMOTE_NETHER_PORTAL
@ SAY_INCINERATE
@ SAY_INFERNAL_ERUPTION
@ EMOTE_LEGION_FLAME
@ EMOTE_INCINERATE
@ EMOTE_INFERNAL_ERUPTION
@ SAY_KILL_PLAYER
@ SPELL_INFERNAL_ERUPTION
@ SPELL_NETHER_PORTAL
@ SPELL_SPINNING_STRIKE
@ SPELL_LEGION_FLAME_EFFECT
@ SPELL_FEL_STREAK
@ SPELL_LORD_HITTIN
@ SPELL_INCINERATE_FLESH
@ SPELL_BURNING_INFERNO
@ SPELL_INFERNAL_ERUPTION_EFFECT
@ SPELL_NETHER_POWER
@ SPELL_FEL_INFERNO
@ SPELL_NETHER_PORTAL_EFFECT
@ SPELL_FEL_FIREBALL
@ SPELL_LEGION_FLAME
@ SPELL_MISTRESS_KISS
@ SPELL_MISTRESS_KISS_DAMAGE_SILENCE
@ SPELL_SHIVAN_SLASH
@ SPELL_FEL_LIGHTING
@ NPC_NETHER_PORTAL
@ NPC_MISTRESS_OF_PAIN
@ NPC_INFERNAL_VOLCANO
@ NPC_LEGION_FLAME
@ NPC_FEL_INFERNAL
void AddSC_boss_jaraxxus()
@ EVENT_SUMMONO_NETHER_PORTAL
@ EVENT_NETHER_POWER
@ EVENT_FEL_LIGHTNING
@ EVENT_LEGION_FLAME
@ EVENT_MISTRESS_KISS
@ EVENT_SPINNING_STRIKE
@ EVENT_SHIVAN_SLASH
@ EVENT_INCINERATE_FLESH
@ EVENT_FEL_FIREBALL
@ EVENT_SUMMON_INFERNAL_ERUPTION
@ SPELL_FEL_FIREBALL
Definition boss_muru.cpp:45
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
Unit * GetCaster() const
Unit * GetTarget() const
InstanceScript *const instance
void _JustReachedHome()
SummonList summons
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
bool operator()(WorldObject *unit) const
Player * ToPlayer()
Definition Object.h:204
TypeID GetTypeId() const
Definition Object.h:131
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
int32 GetEffectValue()
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
SpellScriptLoader(const char *name)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
bool HasUnitState(const uint32 f) const
Definition Unit.h:1485
Powers getPowerType() const
Definition Unit.h:1651
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
PrepareAuraScript(spell_mistress_kiss_AuraScript)
PrepareSpellScript(spell_mistress_kiss_area_SpellScript) void FilterTargets(std
SpellScript * GetSpellScript() const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
bool IsHeroic() const
void SetCombatMovement(bool allowMovement)
Creature * me
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
void JustSummoned(Creature *summoned) OVERRIDE
void KilledUnit(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustSummoned(Creature *summoned) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustSummoned(Creature *summoned) OVERRIDE
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
@ SPELL_JARAXXUS_CHAINS
@ DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE
@ DATA_MISTRESS_OF_PAIN_COUNT
@ BOSS_JARAXXUS