TrinityCore
boss_general_vezax.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 "Map.h"
22#include "MotionMaster.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "SpellAuraEffects.h"
26#include "SpellScript.h"
27#include "ulduar.h"
28
30{
37};
38
40{
44
45 // Saronite Vapor
46 EMOTE_VAPORS = 0
47};
48
50{
64
68
71};
72
74{
78};
79
81{
82 // Vezax
89
90 // Saronite Animus
92
93 // Saronite Vapor
95};
96
97enum Misc
98{
100 DATA_SHADOWDODGER = 29962997
102
104{
105 public:
106 boss_general_vezax() : CreatureScript("boss_general_vezax") { }
107
109 {
111 {
112 Initialize();
113 }
114
116 {
117 shadowDodger = true;
118 smellSaronite = true;
119 animusDead = false;
120 vaporCount = 0;
121 }
122
124 bool smellSaronite; // HardMode
125 bool animusDead; // Check against getting a HardMode achievement before killing Saronite Animus
127
128 void Reset() override
129 {
130 _Reset();
131
132 Initialize();
133 }
134
135 void JustEngagedWith(Unit* who) override
136 {
138
142
149 }
150
151 void UpdateAI(uint32 diff) override
152 {
153 if (!UpdateVictim())
154 return;
155
156 events.Update(diff);
157
159 return;
160
161 while (uint32 eventId = events.ExecuteEvent())
162 {
163 switch (eventId)
164 {
166 {
167 Unit* target = CheckPlayersInRange(RAID_MODE<uint8>(4, 9), 15.0f, 50.0f);
168 if (!target)
169 target = SelectTarget(SelectTargetMethod::Random, 0, 150.0f, true);
170 if (target)
171 DoCast(target, SPELL_SHADOW_CRASH);
173 break;
174 }
178 break;
180 {
181 Unit* target = CheckPlayersInRange(RAID_MODE<uint8>(4, 9), 15.0f, 50.0f);
182 if (!target)
183 target = SelectTarget(SelectTargetMethod::Random, 0, 150.0f, true);
184 if (target)
187 break;
188 }
194 break;
198 if (++vaporCount == 6 && smellSaronite)
199 {
208 }
209 break;
210 case EVENT_BERSERK:
213 break;
214 }
215
217 return;
218 }
219 }
220
221 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
222 {
223 if (target->GetTypeId() == TYPEID_PLAYER && spellInfo->Id == SPELL_SHADOW_CRASH_HIT)
224 shadowDodger = false;
225 }
226
227 void KilledUnit(Unit* who) override
228 {
229 if (who->GetTypeId() == TYPEID_PLAYER)
230 Talk(SAY_SLAY);
231 }
232
233 void JustDied(Unit* /*killer*/) override
234 {
235 _JustDied();
238 }
239
241 {
242 // If Shaman has Shamanistic Rage and use it during the fight, it will cast Corrupted Rage on him
243 Map::PlayerList const& Players = me->GetMap()->GetPlayers();
244 for (Map::PlayerList::const_iterator itr = Players.begin(); itr != Players.end(); ++itr)
245 if (Player* player = itr->GetSource())
246 if (player->HasSpell(SPELL_SHAMANTIC_RAGE))
247 player->CastSpell(player, SPELL_CORRUPTED_RAGE, false);
248 }
249
250 uint32 GetData(uint32 type) const override
251 {
252 switch (type)
253 {
255 return shadowDodger ? 1 : 0;
257 return smellSaronite ? 1 : 0;
258 }
259
260 return 0;
261 }
262
263 void DoAction(int32 action) override
264 {
265 switch (action)
266 {
268 smellSaronite = false;
269 break;
273 animusDead = true;
274 break;
275 }
276 }
277
278 /* Player Range Check
279 Purpose: If there are playersMin people within rangeMin, rangeMax: return a random players in that range.
280 If not, return nullptr and allow other target selection
281 */
282 Unit* CheckPlayersInRange(uint8 playersMin, float rangeMin, float rangeMax)
283 {
284 std::list<Player*> PlayerList;
285 Map::PlayerList const& Players = me->GetMap()->GetPlayers();
286 for (Map::PlayerList::const_iterator itr = Players.begin(); itr != Players.end(); ++itr)
287 {
288 if (Player* player = itr->GetSource())
289 {
290 float distance = player->GetDistance(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
291 if (rangeMin > distance || distance > rangeMax)
292 continue;
293
294 PlayerList.push_back(player);
295 }
296 }
297
298 if (PlayerList.empty())
299 return nullptr;
300
301 size_t size = PlayerList.size();
302 if (size < playersMin)
303 return nullptr;
304
306 }
307 };
308
309 CreatureAI* GetAI(Creature* creature) const override
310 {
311 return GetUlduarAI<boss_general_vezaxAI>(creature);
312 }
313};
314
316{
317 public:
318 boss_saronite_animus() : CreatureScript("npc_saronite_animus") { }
319
321 {
323 {
325 }
326
327 void Reset() override
328 {
330 events.Reset();
332 }
333
334 void JustDied(Unit* /*killer*/) override
335 {
337 vezax->AI()->DoAction(ACTION_ANIMUS_DIE);
338 }
339
340 void UpdateAI(uint32 diff) override
341 {
342 if (!UpdateVictim())
343 return;
344
345 events.Update(diff);
346
348 return;
349
350 while (uint32 eventId = events.ExecuteEvent())
351 {
352 switch (eventId)
353 {
357 break;
358 default:
359 break;
360 }
361
363 return;
364 }
365 }
366
367 private:
370 };
371
372 CreatureAI* GetAI(Creature* creature) const override
373 {
374 return GetUlduarAI<boss_saronite_animusAI>(creature);
375 }
376};
377
379{
380 public:
381 npc_saronite_vapors() : CreatureScript("npc_saronite_vapors") { }
382
384 {
386 {
389 me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip jump effect
391 }
392
393 void Reset() override
394 {
395 events.Reset();
397 }
398
399 void UpdateAI(uint32 diff) override
400 {
401 events.Update(diff);
402
403 while (uint32 eventId = events.ExecuteEvent())
404 {
405 switch (eventId)
406 {
408 me->GetMotionMaster()->MoveRandom(30.0f);
410 break;
411 default:
412 break;
413 }
414 }
415 }
416
417 void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
418 {
419 // This can't be on JustDied. In 63322 dummy handler caster needs to be this NPC
420 // if caster == target then damage mods will increase the damage taken
421 if (damage >= me->GetHealth())
422 {
423 damage = 0;
425 me->SetUninteractible(true);
431 me->DespawnOrUnsummon(30s);
432
434 vezax->AI()->DoAction(ACTION_VAPORS_DIE);
435 }
436 }
437
438 private:
441 };
442
443 CreatureAI* GetAI(Creature* creature) const override
444 {
445 return GetUlduarAI<npc_saronite_vaporsAI>(creature);
446 }
447};
448
449// 63276 - Mark of the Faceless
451{
452 public:
453 spell_general_vezax_mark_of_the_faceless() : SpellScriptLoader("spell_general_vezax_mark_of_the_faceless") { }
454
456 {
457 bool Validate(SpellInfo const* /*spellInfo*/) override
458 {
460 }
461
463 {
464 if (Unit* caster = GetCaster())
465 {
468 caster->CastSpell(GetTarget(), SPELL_MARK_OF_THE_FACELESS_DAMAGE, args);
469 }
470 }
471
472 void Register() override
473 {
475 }
476 };
477
478 AuraScript* GetAuraScript() const override
479 {
481 }
482};
483
484// 63278 - Mark of the Faceless
486{
487 public:
488 spell_general_vezax_mark_of_the_faceless_leech() : SpellScriptLoader("spell_general_vezax_mark_of_the_faceless_leech") { }
489
491 {
492 void FilterTargets(std::list<WorldObject*>& targets)
493 {
494 targets.remove(GetExplTargetWorldObject());
495
496 if (targets.empty())
498 }
499
500 void Register() override
501 {
503 }
504 };
505
506 SpellScript* GetSpellScript() const override
507 {
509 }
510};
511
512// 63322 - Saronite Vapors
514{
515 public:
516 spell_general_vezax_saronite_vapors() : SpellScriptLoader("spell_general_vezax_saronite_vapors") { }
517
519 {
520 bool Validate(SpellInfo const* /*spell*/) override
521 {
523 }
524
526 {
527 if (Unit* caster = GetCaster())
528 {
529 int32 mana = int32(aurEff->GetAmount() * std::pow(2.0f, GetStackAmount())); // mana restore - bp * 2^stackamount
531 args1.AddSpellBP0(mana);
532 args2.AddSpellBP0(mana * 2);
533 caster->CastSpell(GetTarget(), SPELL_SARONITE_VAPORS_ENERGIZE, args1);
534 caster->CastSpell(GetTarget(), SPELL_SARONITE_VAPORS_DAMAGE, args2);
535 }
536 }
537
538 void Register() override
539 {
541 }
542 };
543
544 AuraScript* GetAuraScript() const override
545 {
547 }
548};
549
551{
552 public:
554 {
555 }
556
557 bool OnCheck(Player* /*player*/, Unit* target) override
558 {
559 if (!target)
560 return false;
561
562 if (Creature* Vezax = target->ToCreature())
563 if (Vezax->AI()->GetData(DATA_SHADOWDODGER))
564 return true;
565
566 return false;
567 }
568};
569
571{
572 public:
574 {
575 }
576
577 bool OnCheck(Player* /*player*/, Unit* target) override
578 {
579 if (!target)
580 return false;
581
582 if (Creature* Vezax = target->ToCreature())
583 if (Vezax->AI()->GetData(DATA_SMELL_SARONITE))
584 return true;
585
586 return false;
587 }
588};
589
591{
592 new boss_general_vezax();
600}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_DEST_AREA_ENEMY
@ IMMUNITY_ID
@ LOOT_MODE_HARD_MODE_1
Definition: SharedDefines.h:78
@ SPELL_FAILED_NO_VALID_TARGETS
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_DUMMY
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:197
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ UNIT_STAND_STATE_DEAD
Definition: UnitDefines.h:49
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:145
@ UNIT_STATE_ROOT
Definition: Unit.h:265
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ EVENT_SHADOW_CRASH
@ EVENT_MARK_OF_THE_FACELESS
@ EVENT_RANDOM_MOVE
@ EVENT_BERSERK
@ EVENT_PROFOUND_OF_DARKNESS
@ EVENT_SARONITE_VAPORS
@ EVENT_SURGE_OF_DARKNESS
@ EVENT_SEARING_FLAMES
@ ACTION_VAPORS_SPAWN
@ ACTION_ANIMUS_DIE
@ ACTION_VAPORS_DIE
@ DATA_SMELL_SARONITE
@ DATA_SHADOWDODGER
@ SPELL_SHADOW_CRASH
@ SPELL_CORRUPTED_RAGE
@ SPELL_SARONITE_VAPORS_DAMAGE
@ SPELL_SUMMON_SARONITE_VAPORS
@ SPELL_SURGE_OF_DARKNESS
@ SPELL_VISUAL_SARONITE_ANIMUS
@ SPELL_SARONITE_VAPORS_ENERGIZE
@ SPELL_SARONITE_BARRIER
@ SPELL_SARONITE_VAPORS
@ SPELL_AURA_OF_DESPAIR
@ SPELL_SEARING_FLAMES
@ SPELL_SHADOW_CRASH_HIT
@ SPELL_SUMMON_SARONITE_ANIMUS
@ SPELL_BERSERK
@ SPELL_SHAMANTIC_RAGE
@ SPELL_PROFOUND_OF_DARKNESS
@ SPELL_MARK_OF_THE_FACELESS_DAMAGE
@ SPELL_MARK_OF_THE_FACELESS
@ SAY_DEATH
@ SAY_AGGRO
@ SAY_SURGE_OF_DARKNESS
@ SAY_SLAY
@ SAY_BERSERK
@ SAY_HARDMODE
@ EMOTE_SURGE_OF_DARKNESS
@ EMOTE_BARRIER
@ EMOTE_VAPORS
@ EMOTE_ANIMUS
void AddSC_boss_general_vezax()
int32 GetAmount() const
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2028
Unit * GetCaster() const
Unit * GetTarget() const
uint8 GetStackAmount() const
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
SummonList summons
EventMap events
void _JustDied()
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
void AddLootMode(uint16 lootMode)
Definition: Creature.h:298
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
void CancelEvent(uint32 eventId)
Definition: EventMap.cpp:131
void Reset()
Definition: EventMap.cpp:21
void DoRemoveAurasDueToSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
Creature * GetCreature(uint32 type)
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
PlayerList const & GetPlayers() const
Definition: Map.h:367
void MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT)
static Creature * ToCreature(Object *o)
Definition: Object.h:219
TypeID GetTypeId() const
Definition: Object.h:173
uint32 const Id
Definition: SpellInfo.h:325
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
void FinishCast(SpellCastResult result, int32 *param1=nullptr, int32 *param2=nullptr)
WorldObject * GetExplTargetWorldObject() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
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 DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition: Unit.cpp:7845
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:10911
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
uint64 GetMaxHealth() const
Definition: Unit.h:777
uint64 GetHealth() const
Definition: Unit.h:776
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
void RemoveAllAuras()
Definition: Unit.cpp:4242
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
Map * GetMap() const
Definition: Object.h:624
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
bool OnCheck(Player *, Unit *target) override
bool OnCheck(Player *, Unit *target) override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
AuraScript * GetAuraScript() const override
AuraScript * GetAuraScript() const override
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
constexpr std::size_t size()
Definition: UpdateField.h:796
CastSpellExtraArgs & AddSpellBP0(int32 val)
Definition: SpellDefines.h:475
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
Definition: SpellDefines.h:474
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr float GetPositionZ() const
Definition: Position.h:78
uint32 GetData(uint32 type) const override
Unit * CheckPlayersInRange(uint8 playersMin, float rangeMin, float rangeMax)
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
@ DATA_VEZAX
Definition: ulduar.h:48