TrinityCore
boss_lord_jaraxxus.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "Containers.h"
20#include "InstanceScript.h"
21#include "MotionMaster.h"
22#include "Player.h"
23#include "ScriptedCreature.h"
24#include "SpellInfo.h"
25#include "SpellScript.h"
27
29{
41 SAY_BERSERK = 11
42};
43
45{
48 NPC_FEL_INFERNAL = 34815, // immune to all CC on Heroic (stuns, banish, interrupt, etc)
51};
52
54{
69
70 // Mistress of Pain spells
75
76 // Felflame Infernal
78};
79
81{
82 // Lord Jaraxxus
96
97 // Mistress of Pain
102
104{
110
111struct boss_jaraxxus : public BossAI
112{
113 boss_jaraxxus(Creature* creature) : BossAI(creature, DATA_JARAXXUS) { }
114
115 void Reset() override
116 {
118 me->ResetLootMode();
119 events.Reset();
121
125 {
127 me->SetImmuneToPC(true);
129 }
130 }
131
132 void JustEngagedWith(Unit* who) override
133 {
144 }
145
146 void EnterEvadeMode(EvadeReason /*why*/) override
147 {
151 }
152
153 void DoAction(int32 action) override
154 {
155 if (action == ACTION_JARAXXUS_INTRO)
156 {
160 }
161 else if (action == ACTION_JARAXXUS_ENGAGE)
162 {
164 me->SetImmuneToPC(false);
167 }
168 }
169
170 void MovementInform(uint32 type, uint32 pointId) override
171 {
172 if (type == SPLINE_CHAIN_MOTION_TYPE && pointId == POINT_SUMMONED)
174 {
175 me->SetFacingToObject(wilfred);
177 }
178 }
179
180 void KilledUnit(Unit* who) override
181 {
182 if (who->GetTypeId() == TYPEID_PLAYER)
184 }
185
186 void JustDied(Unit* /*killer*/) override
187 {
189 _JustDied();
190 }
191
192 void UpdateAI(uint32 diff) override
193 {
195 return;
196
197 events.Update(diff);
198
200 return;
201
202 while (uint32 eventId = events.ExecuteEvent())
203 {
204 switch (eventId)
205 {
208 events.Repeat(11s, 13s);
209 break;
211 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
213 events.Repeat(10s, 30s);
214 break;
216 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
217 {
218 Talk(EMOTE_INCINERATE, target);
221 }
222 events.Repeat(23s);
223 break;
225 {
227 args.AddSpellMod(SPELLVALUE_AURA_STACK, RAID_MODE(5, 10, 5, 10));
229 events.Repeat(42s);
230 break;
231 }
233 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
234 {
235 Talk(EMOTE_LEGION_FLAME, target);
236 DoCast(target, SPELL_LEGION_FLAME);
237 }
238 events.Repeat(30s);
239 break;
244 events.Repeat(2min);
245 break;
250 events.Repeat(2min);
251 break;
252 case EVENT_INTRO:
255 break;
259 break;
260 case EVENT_KILL_GNOME:
263 break;
265 me->SetFacingTo(4.729842f);
267 break;
269 me->SetImmuneToPC(false);
272 break;
273 case EVENT_ENRAGE:
276 break;
277 default:
278 break;
279 }
280
282 return;
283 }
284 }
285};
286
288{
289 npc_legion_flame(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
290 {
291 SetCombatMovement(false);
292 }
293
294 void Reset() override
295 {
297 {
299 return;
300 }
301
303 jaraxxus->AI()->JustSummoned(me);
304
307 }
308
309private:
311};
312
314{
316 {
317 SetCombatMovement(false);
318 }
319
320 void Reset() override
321 {
324 if (IsHeroic())
325 me->SetUninteractible(false);
326 }
327};
328
330{
331 npc_fel_infernal(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
332
333 void Reset() override
334 {
336 {
338 return;
339 }
340
342 jaraxxus->AI()->JustSummoned(me);
343
345 {
347 });
348
349 _scheduler.Schedule(Seconds(2), [this](TaskContext context)
350 {
351 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
353 context.Repeat(Seconds(15));
354 });
355
357 }
358
359 void UpdateAI(uint32 diff) override
360 {
361 if (!UpdateVictim())
362 return;
363
364 _scheduler.Update(diff);
365 }
366
367private:
370};
371
373{
374 npc_nether_portal(Creature* creature) : ScriptedAI(creature)
375 {
376 SetCombatMovement(false);
377 }
378
379 void Reset() override
380 {
383 if (IsHeroic())
384 me->SetUninteractible(false);
385 }
386};
387
389{
390 npc_mistress_of_pain(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
391
392 void Reset() override
393 {
395 {
397 return;
398 }
399
401 jaraxxus->AI()->JustSummoned(me);
402
405 }
406
407 void JustEngagedWith(Unit* /*who*/) override
408 {
411 if (IsHeroic())
413 }
414
415 void JustDied(Unit* /*killer*/) override
416 {
418 }
419
420 void UpdateAI(uint32 diff) override
421 {
422 if (!UpdateVictim())
423 return;
424
425 _events.Update(diff);
426
428 return;
429
430 while (uint32 eventId = _events.ExecuteEvent())
431 {
432 switch (eventId)
433 {
436 _events.Repeat(3s, 10s);
437 return;
439 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
441 _events.Repeat(20s);
442 return;
445 _events.Repeat(30s);
446 return;
447 default:
448 break;
449 }
450
452 return;
453 }
454 }
455
456private:
459};
460
461// 66334, 67905, 67906, 67907 - Mistress' Kiss
463{
464 bool Validate(SpellInfo const* /*spellInfo*/) override
465 {
467 }
468
469 void HandleDummyTick(AuraEffect const* /*aurEff*/)
470 {
471 Unit* target = GetTarget();
472 if (Unit* caster = GetCaster())
473 if (target->HasUnitState(UNIT_STATE_CASTING))
474 {
475 caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true);
476 target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
477 }
478 }
479
480 void Register() override
481 {
483 }
484};
485
486// 66336, 67076, 67077, 67078 - Mistress' Kiss
488{
489 bool Validate(SpellInfo const* spellInfo) override
490 {
491 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
492 }
493
494 void FilterTargets(std::list<WorldObject*>& targets)
495 {
496 // get a list of players with mana
497 targets.remove_if([](WorldObject* target)
498 {
499 return target->GetTypeId() == TYPEID_PLAYER && target->ToUnit()->GetPowerIndex(POWER_MANA) == MAX_POWERS;
500 });
501
502 if (targets.empty())
503 return;
504
506 targets.clear();
507 targets.push_back(target);
508 }
509
510 void HandleScript(SpellEffIndex /*effIndex*/)
511 {
513 }
514
515 void Register() override
516 {
519 }
520};
521
522// 66493 - Fel Streak
524{
525 bool Validate(SpellInfo const* spellInfo) override
526 {
527 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
528 }
529
530 void HandleScript(SpellEffIndex /*effIndex*/)
531 {
532 GetCaster()->CastSpell(GetHitUnit(), static_cast<uint32>(GetEffectValue()), true);
533 }
534
535 void Register() override
536 {
538 }
539};
540
542{
552}
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
@ IN_PROGRESS
@ FAIL
@ NOT_STARTED
@ SPLINE_CHAIN_MOTION_TYPE
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ MAX_POWERS
@ POWER_MANA
@ SPELL_AURA_PERIODIC_DUMMY
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:231
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ PHASE_INTRO
@ POINT_SUMMONED
@ SPLINE_INITIAL_MOVEMENT
@ PHASE_COMBAT
@ SAY_DEATH
@ SAY_MISTRESS_OF_PAIN
@ SAY_AGGRO
@ EMOTE_NETHER_PORTAL
@ SAY_INCINERATE
@ SAY_INFERNAL_ERUPTION
@ EMOTE_LEGION_FLAME
@ EMOTE_INCINERATE
@ EMOTE_INFERNAL_ERUPTION
@ SAY_KILL_PLAYER
@ SAY_BERSERK
@ SAY_INTRO
@ SPELL_INFERNAL_ERUPTION
@ SPELL_NETHER_PORTAL
@ SPELL_LEGION_FLAME_EFFECT
@ SPELL_SPINNING_SPIKE
@ SPELL_INCINERATE_FLESH
@ SPELL_BURNING_INFERNO
@ SPELL_INFERNAL_ERUPTION_EFFECT
@ SPELL_NETHER_POWER
@ SPELL_FEL_LIGHTNING
@ SPELL_NETHER_PORTAL_EFFECT
@ SPELL_FEL_FIREBALL
@ SPELL_LEGION_FLAME
@ SPELL_MISTRESS_KISS
@ SPELL_MISTRESS_KISS_DAMAGE_SILENCE
@ SPELL_SHIVAN_SLASH
@ SPELL_FEL_LIGHTNING_INTRO
@ SPELL_BERSERK
@ SPELL_FEL_STREAK_VISUAL
@ SPELL_LORD_JARAXXUS_HITTIN_YA
@ NPC_NETHER_PORTAL
@ NPC_MISTRESS_OF_PAIN
@ NPC_INFERNAL_VOLCANO
@ NPC_LEGION_FLAME
@ NPC_FEL_INFERNAL
void AddSC_boss_jaraxxus()
@ EVENT_TAUNT_GNOME
@ EVENT_NETHER_POWER
@ EVENT_START_COMBAT
@ EVENT_FEL_LIGHTNING
@ EVENT_ENRAGE
@ EVENT_CHANGE_ORIENTATION
@ EVENT_KILL_GNOME
@ EVENT_SPINNING_SPIKE
@ EVENT_LEGION_FLAME
@ EVENT_SUMMON_NETHER_PORTAL
@ EVENT_MISTRESS_KISS
@ EVENT_SHIVAN_SLASH
@ EVENT_INCINERATE_FLESH
@ EVENT_INTRO
@ EVENT_FEL_FIREBALL
@ EVENT_SUMMON_INFERNAL_ERUPTION
Yells
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
SpellInfo const * GetSpellInfo() const
Unit * GetCaster() const
Unit * GetTarget() const
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
SummonList summons
EventMap events
void _JustDied()
void DoZoneInCombat()
Definition: CreatureAI.h:161
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:299
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetCombatPulseDelay(uint32 delay)
Definition: Creature.h:345
void ResetLootMode()
Definition: Creature.h:300
void SetImmuneToPC(bool apply) override
Definition: Creature.h:170
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void Reset()
Definition: EventMap.cpp:21
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
EncounterState GetBossState(uint32 id) const
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
static Unit * ToUnit(Object *o)
Definition: Object.h:225
TypeID GetTypeId() const
Definition: Object.h:173
uint32 const Id
Definition: SpellInfo.h:325
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
Unit * GetCaster() const
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
TaskContext & Repeat(std::chrono::duration< Rep, Period > duration)
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & Update(success_t const &callback=nullptr)
TaskScheduler & SetValidator(P &&predicate)
Sets a validator which is asked if tasks are allowed to be executed.
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
virtual uint32 GetPowerIndex(Powers power) const =0
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:92
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *spellInfo) override
void FilterTargets(std::list< WorldObject * > &targets)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
void HandleDummyTick(AuraEffect const *)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
Definition: SpellDefines.h:474
bool IsHeroic() const
void SetCombatMovement(bool allowMovement)
T const & RAID_MODE(T const &normal10, T const &normal25) const
void UpdateAI(uint32 diff) override
void EnterEvadeMode(EvadeReason) override
void JustEngagedWith(Unit *who) override
boss_jaraxxus(Creature *creature)
void JustDied(Unit *) override
void DoAction(int32 action) override
void Reset() override
void KilledUnit(Unit *who) override
void MovementInform(uint32 type, uint32 pointId) override
void UpdateAI(uint32 diff) override
InstanceScript * _instance
npc_fel_infernal(Creature *creature)
void Reset() override
TaskScheduler _scheduler
npc_infernal_volcano(Creature *creature)
npc_legion_flame(Creature *creature)
InstanceScript * _instance
void Reset() override
npc_mistress_of_pain(Creature *creature)
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
InstanceScript * _instance
npc_nether_portal(Creature *creature)
@ SPELL_JARAXXUS_CHAINS
@ ACTION_JARAXXUS_ENGAGE
@ ACTION_JARAXXUS_INTRO
@ DATA_JARAXXUS
@ DATA_MISTRESS_OF_PAIN_COUNT
@ DATA_FIZZLEBANG
#define RegisterTrialOfTheCrusaderCreatureAI(ai_name)