TrinityCore
Loading...
Searching...
No Matches
boss_vazruden_the_herald.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/*
19 * Purpose of SPELL_LOGIC_TIMER is unknown
20 * Combat timers requires to be revisited, especially Fireball (victim and random)
21 * Not sure if Cone of Fire Script Effect uses same spell in heroic difficulty
22 * Liquid fire should be disturbed by Activate Object action, however currently object can't disturb itself.
23 But even if we force any creature to disturb object, triggered spell will hit player not always and always as miss.
24 Currently we force creature to cast spell, that is a hack
25 * Vazruden doesn't cast Revenge spell. Maybe required AURA_STATE_DEFENSE is not applied?
26 * SPELL_BELLOWING_ROAR_H gets interrupted instantly, probably because of No Move Flags Update extra flag
27 */
28
29#include "ScriptMgr.h"
30#include "Containers.h"
31#include "GameObject.h"
32#include "GameObjectAI.h"
33#include "InstanceScript.h"
34#include "hellfire_ramparts.h"
35#include "Map.h"
36#include "MotionMaster.h"
37#include "ScriptedCreature.h"
38#include "SpellInfo.h"
39#include "SpellScript.h"
40#include "TemporarySummon.h"
41
43{
44 // Vazruden the Herald
46
47 // Vazruden
52
53 // Nazan
55};
56
58{
59 // Vazruden the Herald / Nazan - Intro
61
62 // Vazruden the Herald / Nazan - Flying Phase
69
70 // Vazruden the Herald / Nazan - Flying Phase - Combat
75
76 // Vazruden the Herald / Nazan - Descending
78
79 // Vazruden the Herald / Nazan - Ground Phase - Combat
85
86 // Vazruden
91
92 // Scripts
96};
97
99{
100 // Vazruden the Herald / Nazan - Special: Intro
103
104 // Vazruden the Herald / Nazan - Special: Descend
109
110 // Vazruden the Herald / Nazan - Fly
112
113 // Vazruden the Herald / Nazan - Flying Phase - Combat
116
117 // Vazruden the Herald / Nazan - Ground Phase - Combat
121
122 // Vazruden
127
137
143
144static Position const CenterPos = { -1410.5204f, 1740.5852f, 89.05998f, 0.0f };
145static Position const FlyWestPos = { -1423.4910f, 1710.4010f, 103.7056f, 0.0f };
146static Position const FlyEastPos = { -1375.3560f, 1744.6040f, 99.14612f, 0.0f };
147static Position const FlyNorthPos = { -1444.9900f, 1752.9600f, 98.20342f, 0.0f };
148static Position const DescendPos = { -1429.1720f, 1749.1290f, 84.34760f, 0.0f };
149
150// 17307 - Vazruden the Herald
152{
157
159 {
161 _isEncounterStarted = false;
162 _isPerformingIntro = true;
163 _startedDescending = false;
164 _isOtherDead = false;
165 _isUnkillable = true;
166 }
167
168 void JustAppeared() override
169 {
170 me->SetDisableGravity(true);
171 }
172
183
184 void DoAction(int32 action) override
185 {
186 switch (action)
187 {
190 {
191 _isEncounterStarted = true;
193 }
194 break;
197 {
198 _startedDescending = true;
200 }
201 break;
203 _isOtherDead = true;
204 break;
205 default:
206 break;
207 }
208 }
209
210 // Do not despawn Vazruden
211 void JustSummoned(Creature* /*summon*/) override { }
212
213 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
214 {
215 if (damage >= me->GetHealth() && _isUnkillable)
216 damage = me->GetHealth() - 1;
217
219 {
220 _startedDescending = true;
222 }
223 }
224
225 void MovementInform(uint32 type, uint32 id) override
226 {
227 if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
228 return;
229
230 switch (id)
231 {
232 case POINT_CENTER:
234 break;
235 case POINT_FLY_NORTH:
236 case POINT_FLY_WEST:
237 case POINT_FLY_EAST:
241 break;
242 case POINT_DESCEND:
244 break;
245 case POINT_FALL:
247 break;
248 default:
249 break;
250 }
251 }
252
253 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
254 {
255 switch (spellInfo->Id)
256 {
257 case SPELL_FLY_NORTH:
259 break;
260 case SPELL_FLY_WEST:
262 break;
263 case SPELL_FLY_EAST:
265 break;
269 break;
270 default:
271 break;
272 }
273 }
274
275 void EnterEvadeMode(EvadeReason /*why*/) override
276 {
278
280 }
281
282 void JustDied(Unit* /*killer*/) override
283 {
284 if (_isOtherDead)
285 _JustDied();
286
287 if (Creature* vazruden = instance->GetCreature(DATA_VAZRUDEN))
288 vazruden->AI()->DoAction(ACTION_OTHER_IS_DEAD);
289 }
290
292 {
294
295 while (uint32 eventId = _specialEvents.ExecuteEvent())
296 {
297 switch (eventId)
298 {
299 case EVENT_INTRO_1:
304 break;
305 case EVENT_INTRO_2:
307 me->SetDisableGravity(false);
311 me->SetDisableGravity(true);
315 _isPerformingIntro = false;
316 break;
317
318 case EVENT_DESCEND_1:
325 events.Reset();
326 break;
327 case EVENT_DESCEND_2:
329 break;
330 case EVENT_DESCEND_3:
331 me->SetDisableGravity(false);
334 break;
335 case EVENT_DESCEND_4:
338
339 _isUnkillable = false;
340
343 if (IsHeroic())
345 break;
346 default:
347 break;
348 }
349 }
350 }
351
352 void UpdateAI(uint32 diff) override
353 {
355
356 if (!UpdateVictim())
357 return;
358
359 events.Update(diff);
360
362 return;
363
364 while (uint32 eventId = events.ExecuteEvent())
365 {
366 switch (eventId)
367 {
368 // Fly
369 case EVENT_FLY_TO_LOC:
370 {
373
374 std::vector<uint32> availableFlyToSpells = { SPELL_FLY_NORTH, SPELL_FLY_WEST, SPELL_FLY_EAST };
375
376 std::erase(availableFlyToSpells, _lastFlyToSpell);
377
378 uint32 selectedSpell = Trinity::Containers::SelectRandomContainerElement(availableFlyToSpells);
379
380 _lastFlyToSpell = selectedSpell;
381
382 DoCastSelf(selectedSpell);
383 events.Repeat(20s, 30s);
384 break;
385 }
386
387 // Flying Phase
391 events.Repeat(3200ms);
392 break;
397 events.Repeat(10s, 15s);
398 break;
399
400 // Ground Phase
404 events.Repeat(5s, 15s);
405 break;
408 events.Repeat(10s, 15s);
409 break;
412 events.Repeat(40s, 50s);
413 break;
414 default:
415 break;
416 }
417
419 return;
420 }
421
423 }
424
425private:
433};
434
435// 17537 - Vazruden
436struct boss_vazruden : public BossAI
437{
439
440 void JustAppeared() override
441 {
444 }
445
446 void JustEngagedWith(Unit* who) override
447 {
449
452 }
453
454 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
455 {
456 if (!_hasCalledNazan && me->HealthBelowPctDamaged(40, damage))
457 {
458 _hasCalledNazan = true;
460 }
461 }
462
463 void DoAction(int32 action) override
464 {
465 if (action == ACTION_OTHER_IS_DEAD)
466 _isOtherDead = true;
467 }
468
476
477 void KilledUnit(Unit* /*who*/) override
478 {
479 Talk(SAY_SLAY);
480 }
481
482 void JustDied(Unit* /*killer*/) override
483 {
484 if (_isOtherDead)
485 _JustDied();
486
488
490
492 vazruden->AI()->DoAction(ACTION_OTHER_IS_DEAD);
493 }
494
495 void UpdateAI(uint32 diff) override
496 {
497 if (!UpdateVictim())
498 return;
499
500 events.Update(diff);
501
503 return;
504
505 while (uint32 eventId = events.ExecuteEvent())
506 {
507 switch (eventId)
508 {
509 case EVENT_SAY_AGGRO:
511 break;
512 case EVENT_REVENGE:
514 events.Repeat(5s, 10s);
515 break;
516 case EVENT_CALL_NAZAN:
518 break;
519 default:
520 break;
521 }
522
524 return;
525 }
526
528 }
529
530private:
533};
534
535// 180125, 181890, 182533 - Liquid Fire
537{
539
540 void Reset() override
541 {
542 _scheduler.Schedule(0s, [this](TaskContext task)
543 {
544 if (Creature* creature = me->SummonCreature(21252, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 1s))
545 creature->CastSpell(creature, me->GetGOInfo()->trap.spellId);
546 task.Repeat(2s);
547 });
548 }
549
550 void UpdateAI(uint32 diff) override
551 {
552 _scheduler.Update(diff);
553 }
554
555private:
557};
558
559// 30693 - Call Nazan
575
576// 30691, 32491 - Fireball
577// 33793, 33794 - Fireball
578// 34653, 36920 - Fireball
598
599// 30926, 36921 - Cone of Fire
619
620// 30717 - Summon Vazruden
636
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ FAIL
@ POINT_MOTION_TYPE
@ EFFECT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ TARGET_DEST_CASTER_SUMMON
@ EMOTE_ONESHOT_LAND
#define SpellEffectFn(F, I, N)
#define SpellDestinationTargetSelectFn(F, I, N)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ ACTION_START_ENCOUNTER
@ SPELL_SUMMON_LIQUID_FIRE_CONE
@ SPELL_FIREBALL_VICTIM_H
@ SPELL_SUMMON_LIQUID_FIRE
@ SPELL_SUMMON_LIQUID_FIRE_H
@ SPELL_FIREBALL_GROUND_H
@ SPELL_FIREBALL_RANDOM_H
@ SPELL_FACE_HIGHEST_THREAT
static Position const FlyEastPos
void AddSC_boss_vazruden_the_herald()
static Position const DescendPos
static Position const FlyWestPos
static Position const CenterPos
static Position const FlyNorthPos
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
EventMap events
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:540
ReactStates GetReactState() const
Definition Creature.h:120
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
GameObject *const me
GameObjectAI(GameObject *go)
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:102
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
void MoveFall(uint32 id=0)
uint32 Id
Definition SpellInfo.h:289
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
TaskContext & Repeat(std::chrono::duration< _Rep, _Period > const &duration)
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13286
uint32 GetHealth() const
Definition Unit.h:913
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void HandleEmoteCommand(Emote emoteId)
Definition Unit.cpp:1568
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3606
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1992
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
PrepareSpellScript(spell_vazruden_call_nazan)
PrepareSpellScript(spell_vazruden_cone_of_fire)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_vazruden_fireball)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_vazruden_summon_vazruden)
#define RegisterHellfireRampartsGameObjectAI(ai_name)
@ DATA_VAZRUDEN_THE_HERALD
@ DATA_VAZRUDEN
@ NPC_NAZAN
#define RegisterHellfireRampartsCreatureAI(ai_name)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition Containers.h:108
struct GameObjectTemplate::@191::@198 trap
float m_positionZ
Definition Position.h:58
float GetPositionZ() const
Definition Position.h:81
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:128
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80
bool IsHeroic() const
T const & DUNGEON_MODE(T const &normal5, T const &heroic10) const
WorldLocation _position
void JustEngagedWith(Unit *who) override
void EnterEvadeMode(EvadeReason) override
void JustSummoned(Creature *) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void DoAction(int32 action) override
boss_vazruden_the_herald(Creature *creature)
void MovementInform(uint32 type, uint32 id) override
void JustDied(Unit *) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustEngagedWith(Unit *who) override
void KilledUnit(Unit *) override
boss_vazruden(Creature *creature)
void EnterEvadeMode(EvadeReason) override
void DoAction(int32 action) override
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override