TrinityCore
Loading...
Searching...
No Matches
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
43
45{
48 NPC_FEL_INFERNAL = 34815, // immune to all CC on Heroic (stuns, banish, interrupt, etc)
51};
52
79
102
110
111struct boss_jaraxxus : public BossAI
112{
113 boss_jaraxxus(Creature* creature) : BossAI(creature, DATA_JARAXXUS) { }
114
130
144
145 void EnterEvadeMode(EvadeReason /*why*/) override
146 {
150 }
151
152 void DoAction(int32 action) override
153 {
154 if (action == ACTION_JARAXXUS_INTRO)
155 {
159 }
160 else if (action == ACTION_JARAXXUS_ENGAGE)
161 {
163 me->SetImmuneToPC(false);
166 }
167 }
168
169 void MovementInform(uint32 type, uint32 pointId) override
170 {
171 if (type == SPLINE_CHAIN_MOTION_TYPE && pointId == POINT_SUMMONED)
173 {
174 me->SetFacingToObject(wilfred);
176 }
177 }
178
179 void KilledUnit(Unit* who) override
180 {
181 if (who->GetTypeId() == TYPEID_PLAYER)
183 }
184
185 void JustDied(Unit* /*killer*/) override
186 {
188 _JustDied();
189 }
190
191 void UpdateAI(uint32 diff) override
192 {
194 return;
195
196 events.Update(diff);
197
199 return;
200
201 while (uint32 eventId = events.ExecuteEvent())
202 {
203 switch (eventId)
204 {
207 events.Repeat(11s, 13s);
208 break;
210 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
212 events.Repeat(10s, 30s);
213 break;
215 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
216 {
217 Talk(EMOTE_INCINERATE, target);
220 }
221 events.Repeat(23s);
222 break;
224 {
226 args.AddSpellMod(SPELLVALUE_AURA_STACK, RAID_MODE(5, 10, 5, 10));
228 events.Repeat(42s);
229 break;
230 }
232 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
233 {
234 Talk(EMOTE_LEGION_FLAME, target);
235 DoCast(target, SPELL_LEGION_FLAME);
236 }
237 events.Repeat(30s);
238 break;
243 events.Repeat(2min);
244 break;
249 events.Repeat(2min);
250 break;
251 case EVENT_INTRO:
254 break;
258 break;
259 case EVENT_KILL_GNOME:
262 break;
264 me->SetFacingTo(4.729842f);
266 break;
268 me->SetImmuneToPC(false);
271 break;
272 case EVENT_ENRAGE:
275 break;
276 default:
277 break;
278 }
279
281 return;
282 }
283 }
284};
285
287{
288 npc_legion_flame(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
289 {
290 SetCombatMovement(false);
291 }
292
293 void Reset() override
294 {
296 {
298 return;
299 }
300
302 jaraxxus->AI()->JustSummoned(me);
303
306 }
307
308private:
310};
311
313{
315 {
316 SetCombatMovement(false);
317 }
318
319 void Reset() override
320 {
323 if (IsHeroic())
324 me->SetUninteractible(false);
325 }
326};
327
329{
330 npc_fel_infernal(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
331
332 void Reset() override
333 {
335 {
337 return;
338 }
339
341 jaraxxus->AI()->JustSummoned(me);
342
344 {
346 });
347
348 _scheduler.Schedule(Seconds(2), [this](TaskContext& context)
349 {
350 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
352 context.Repeat(Seconds(15));
353 });
354
356 }
357
358 void UpdateAI(uint32 diff) override
359 {
360 if (!UpdateVictim())
361 return;
362
363 _scheduler.Update(diff);
364 }
365
366private:
369};
370
372{
373 npc_nether_portal(Creature* creature) : ScriptedAI(creature)
374 {
375 SetCombatMovement(false);
376 }
377
378 void Reset() override
379 {
382 if (IsHeroic())
383 me->SetUninteractible(false);
384 }
385};
386
388{
389 npc_mistress_of_pain(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
390
391 void Reset() override
392 {
394 {
396 return;
397 }
398
400 jaraxxus->AI()->JustSummoned(me);
401
404 }
405
413
414 void JustDied(Unit* /*killer*/) override
415 {
417 }
418
419 void UpdateAI(uint32 diff) override
420 {
421 if (!UpdateVictim())
422 return;
423
424 _events.Update(diff);
425
427 return;
428
429 while (uint32 eventId = _events.ExecuteEvent())
430 {
431 switch (eventId)
432 {
435 _events.Repeat(3s, 10s);
436 return;
438 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
440 _events.Repeat(20s);
441 return;
444 _events.Repeat(30s);
445 return;
446 default:
447 break;
448 }
449
451 return;
452 }
453 }
454
455private:
458};
459
460// 66334, 67905, 67906, 67907 - Mistress' Kiss
462{
463 bool Validate(SpellInfo const* /*spellInfo*/) override
464 {
466 }
467
468 void HandleDummyTick(AuraEffect const* /*aurEff*/)
469 {
470 Unit* target = GetTarget();
471 if (Unit* caster = GetCaster())
472 if (target->HasUnitState(UNIT_STATE_CASTING))
473 {
474 caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true);
475 target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
476 }
477 }
478
483};
484
485// 66336, 67076, 67077, 67078 - Mistress' Kiss
487{
488 bool Validate(SpellInfo const* spellInfo) override
489 {
490 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValueAsInt()) });
491 }
492
493 void FilterTargets(std::list<WorldObject*>& targets)
494 {
495 // get a list of players with mana
496 targets.remove_if([](WorldObject* target)
497 {
498 return target->GetTypeId() == TYPEID_PLAYER && target->ToUnit()->GetPowerIndex(POWER_MANA) == MAX_POWERS;
499 });
500
501 if (targets.empty())
502 return;
503
505 targets.clear();
506 targets.push_back(target);
507 }
508
509 void HandleScript(SpellEffIndex /*effIndex*/)
510 {
512 }
513
519};
520
521// 66493 - Fel Streak
523{
524 bool Validate(SpellInfo const* spellInfo) override
525 {
526 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ static_cast<uint32>(spellInfo->GetEffect(EFFECT_0).CalcValueAsInt()) });
527 }
528
529 void HandleScript(SpellEffIndex /*effIndex*/)
530 {
531 GetCaster()->CastSpell(GetHitUnit(), static_cast<uint32>(GetEffectValueAsInt()), true);
532 }
533
538};
539
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
@ IN_PROGRESS
@ FAIL
@ NOT_STARTED
@ SPLINE_CHAIN_MOTION_TYPE
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
SpellEffIndex
@ EFFECT_0
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ MAX_POWERS
@ POWER_MANA
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELLVALUE_AURA_STACK
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
EvadeReason
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_STATE_CASTING
Definition Unit.h:276
@ POINT_SUMMONED
@ SPLINE_INITIAL_MOVEMENT
@ SAY_MISTRESS_OF_PAIN
@ EMOTE_NETHER_PORTAL
@ SAY_INCINERATE
@ SAY_INFERNAL_ERUPTION
@ EMOTE_LEGION_FLAME
@ EMOTE_INCINERATE
@ EMOTE_INFERNAL_ERUPTION
@ SAY_KILL_PLAYER
@ SAY_BERSERK
@ 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
SpellInfo const * GetSpellInfo() const
Unit * GetCaster() const
Unit * GetTarget() const
TypeID GetTypeId() const
Definition BaseEntity.h:166
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
SummonList summons
EventMap events
void DoZoneInCombat()
Definition CreatureAI.h:169
bool _EnterEvadeMode(EvadeReason why=EvadeReason::Other)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void ResetLootMode()
Definition Creature.h:322
void SetImmuneToPC(bool apply) override
Definition Creature.h:184
void SetReactState(ReactStates st)
Definition Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
uint32 ExecuteEvent()
Definition EventMap.cpp:77
void Update(uint32 time)
Definition EventMap.h:61
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition EventMap.cpp:40
bool IsInPhase(uint8 phase) const
Definition EventMap.h:222
void SetPhase(uint8 phase)
Definition EventMap.cpp:32
void Reset()
Definition EventMap.cpp:25
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
EncounterState GetBossState(uint32 id) const
void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk)
Unit * ToUnit()
Definition Object.h:116
uint32 const Id
Definition SpellInfo.h:328
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:588
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Unit * GetCaster() const
int32 GetEffectValueAsInt() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & SetValidator(P &&predicate)
Sets a validator which is asked if tasks are allowed to be executed.
TaskScheduler & Update()
Update the scheduler to the current time.
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
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:635
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition Unit.cpp:13307
void SetUninteractible(bool apply)
Definition Unit.cpp:8564
virtual uint32 GetPowerIndex(Powers power) const =0
void SetFacingTo(float const ori, bool force=true)
Definition Unit.cpp:13289
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:100
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) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
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)
npc_infernal_volcano(Creature *creature)
npc_legion_flame(Creature *creature)
InstanceScript * _instance
npc_mistress_of_pain(Creature *creature)
void JustEngagedWith(Unit *) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
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)