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 }
422
423private:
431};
432
433// 17537 - Vazruden
434struct boss_vazruden : public BossAI
435{
437
438 void JustAppeared() override
439 {
442 }
443
444 void JustEngagedWith(Unit* who) override
445 {
447
450 }
451
452 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
453 {
454 if (!_hasCalledNazan && me->HealthBelowPctDamaged(40, damage))
455 {
456 _hasCalledNazan = true;
458 }
459 }
460
461 void DoAction(int32 action) override
462 {
463 if (action == ACTION_OTHER_IS_DEAD)
464 _isOtherDead = true;
465 }
466
474
475 void KilledUnit(Unit* /*who*/) override
476 {
477 Talk(SAY_SLAY);
478 }
479
480 void JustDied(Unit* /*killer*/) override
481 {
482 if (_isOtherDead)
483 _JustDied();
484
486
488
490 vazruden->AI()->DoAction(ACTION_OTHER_IS_DEAD);
491 }
492
493 void UpdateAI(uint32 diff) override
494 {
495 if (!UpdateVictim())
496 return;
497
498 events.Update(diff);
499
501 return;
502
503 while (uint32 eventId = events.ExecuteEvent())
504 {
505 switch (eventId)
506 {
507 case EVENT_SAY_AGGRO:
509 break;
510 case EVENT_REVENGE:
512 events.Repeat(5s, 10s);
513 break;
514 case EVENT_CALL_NAZAN:
516 break;
517 default:
518 break;
519 }
520
522 return;
523 }
524 }
525
526private:
529};
530
531// 180125, 181890, 182533 - Liquid Fire
533{
535
536 void Reset() override
537 {
538 _scheduler.Schedule(0s, [this](TaskContext& task)
539 {
540 if (Creature* creature = me->SummonCreature(21252, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 1s))
541 creature->CastSpell(creature, me->GetGOInfo()->trap.spell);
542 task.Repeat(2s);
543 });
544 }
545
546 void UpdateAI(uint32 diff) override
547 {
548 _scheduler.Update(diff);
549 }
550
551private:
553};
554
555// 30693 - Call Nazan
557{
558 void HandleScript(SpellEffIndex /*effIndex*/)
559 {
560 if (Creature* creature = GetHitCreature())
561 creature->AI()->DoAction(ACTION_START_DESCENDING);
562 }
563
568};
569
570// 30691, 32491 - Fireball
571// 33793, 33794 - Fireball
572// 34653, 36920 - Fireball
590
591// 30926, 36921 - Cone of Fire
609
610// 30717 - Summon Vazruden
624
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
@ FAIL
@ POINT_MOTION_TYPE
@ EFFECT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
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)
EvadeReason
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
DamageEffectType
@ UNIT_STATE_CASTING
Definition Unit.h:290
@ 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()
Definition CreatureAI.h:169
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void SetReactState(ReactStates st)
Definition Creature.h:180
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:591
ReactStates GetReactState() const
Definition Creature.h:181
void Update(uint32 time)
Definition EventMap.h:77
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
EventId ExecuteEvent()
Definition EventMap.cpp:77
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:40
void Reset()
Definition EventMap.cpp:25
GameObject *const me
GameObjectAI(GameObject *go, uint32 scriptId={}) noexcept
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:209
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
void MoveFall(uint32 id=0, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={}, Optional< MovementFadeObject > fadeObject={}, Scripting::v2::ActionResultSetter< MovementStopReason > &&scriptResult={})
uint32 const Id
Definition SpellInfo.h:328
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
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:172
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:71
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:81
Definition Unit.h:647
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3253
MotionMaster * GetMotionMaster()
Definition Unit.h:1750
uint64 GetHealth() const
Definition Unit.h:800
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:805
bool HasUnitState(const uint32 f) const
Definition Unit.h:755
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13385
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition Unit.cpp:1662
bool SetDisableGravity(bool disable, bool updateAnimTier=true, bool updatePlayHoverAnim=true)
Definition Unit.cpp:13440
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3131
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
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:1403
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
#define RegisterHellfireRampartsGameObjectAI(ai_name)
@ DATA_VAZRUDEN_THE_HERALD
@ DATA_VAZRUDEN
@ NPC_NAZAN
#define RegisterHellfireRampartsCreatureAI(ai_name)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
struct GameObjectTemplate::@199::@207 trap
constexpr float GetPositionX() const
Definition Position.h:87
float m_positionZ
Definition Position.h:66
constexpr float GetPositionY() const
Definition Position.h:88
float GetAbsoluteAngle(float x, float y) const
Definition Position.h:136
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr float GetPositionZ() const
Definition Position.h:89
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