Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_alysrazor.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ObjectMgr.h"
7#include "ScriptMgr.h"
8#include "ScriptedCreature.h"
9#include "PassiveAI.h"
10#include "SpellScript.h"
11#include "MoveSplineInit.h"
12#include "Cell.h"
13#include "CellImpl.h"
14#include "GridNotifiers.h"
15#include "GridNotifiersImpl.h"
16#include "firelands.h"
17
19{
20 // Egg Pile
21 EMOTE_CRACKING_EGGS = 0, // The Molten Eggs begin to crack and splinter!
22};
23
64
65#define SPELL_SHARE_HEALTH (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_SHARE_HEALTH_LEFT : SPELL_SHARE_HEALTH_RIGHT)
66#define SPELL_MOLTEN_BARRAGE (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_MOLTEN_BARRAGE_LEFT : SPELL_MOLTEN_BARRAGE_RIGHT)
67#define SPELL_MOLTEN_BARRAGE_EFFECT (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_MOLTEN_BARRAGE_EFFECT_L : SPELL_MOLTEN_BARRAGE_EFFECT_R)
68
70{
71 // Blazing Monstrosity
74
75 // Harbinger of Flame
78
79 // Egg Pile
81};
82
89
91{
92 public:
93 explicit RespawnEggEvent(Creature* egg) : _egg(egg) { }
94
95 bool Execute(uint64 /*time*/, uint32 /*diff*/)
96 {
97 _egg->RestoreDisplayId();
98 return true;
99 }
100
101 private:
103};
104
106{
107 public:
108 explicit MoltenEggCheck(Creature* pile) : _eggPile(pile) { }
109
110 bool operator()(Unit* object) const
111 {
112 if (object->GetEntry() != NPC_MOLTEN_EGG_TRASH)
113 return false;
114
115 if (object->GetDisplayId() != object->GetNativeDisplayId())
116 return false;
117
118 if (_eggPile->GetDistance2d(object) > 20.0f)
119 return false;
120
121 return true;
122 }
123
124 private:
126};
127
129{
130 public:
131 void operator()(Creature* creature) const
132 {
133 switch (creature->GetEntry())
134 {
137 case NPC_EGG_PILE:
140 if (!creature->IsAlive())
141 creature->Respawn(true);
142 break;
144 creature->DespawnOrUnsummon();
145 break;
146 }
147 }
148};
149
150static void AlysrazorTrashEvaded(Creature* creature)
151{
152 TrashRespawnWorker check;
153 Skyfire::CreatureWorker<TrashRespawnWorker> worker(creature, check);
154 creature->VisitNearbyGridObject(SIZE_OF_GRIDS, worker);
155}
156
158{
159 public:
160 npc_harbinger_of_flame() : CreatureScript("npc_harbinger_of_flame") { }
161
163 {
165 {
166 }
167
168 void EnterCombat(Unit* /*target*/) OVERRIDE
169 {
171 DoZoneInCombat(bird, 200.0f);
172
173 me->InterruptSpell(CURRENT_CHANNELED_SPELL);
174 _events.Reset();
175 _events.ScheduleEvent(EVENT_FIEROBLAST, 1);
176 _events.ScheduleEvent(EVENT_FIEROCLAST_BARRAGE, 6000);
177 }
178
183
185 {
186 if (me->IsInCombat())
187 return;
188
189 if (!unit->IsCharmedOwnedByPlayerOrPlayer())
190 return;
191
193 }
194
196 {
197 if (!me->IsInCombat())
198 if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
199 if (Creature* fireBird = me->FindNearestCreature((me->GetHomePosition().GetPositionY() > -275.0f ? NPC_BLAZING_MONSTROSITY_LEFT : NPC_BLAZING_MONSTROSITY_RIGHT), 100.0f))
200 DoCast(fireBird, SPELL_FIRE_CHANNELING);
201
202 if (!UpdateVictim())
203 return;
204
205 _events.Update(diff);
206
207 if (me->HasUnitState(UNIT_STATE_CASTING))
208 return;
209
210 while (uint32 eventId = _events.ExecuteEvent())
211 {
212 switch (eventId)
213 {
214 case EVENT_FIEROBLAST:
215 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, -SPELL_RIDE_MONSTROSITY))
217 _events.RescheduleEvent(EVENT_FIEROBLAST, 500); // cast time is longer, but thanks to UNIT_STATE_CASTING check it won't trigger more often (need this because this creature gets a stacking haste aura)
218 break;
221 _events.ScheduleEvent(EVENT_FIEROCLAST_BARRAGE, std::rand() % 12000 + 9000);
222 break;
223 }
224 }
225
227 }
228
229 private:
231 };
232
234 {
235 return new npc_harbinger_of_flameAI(creature);
236 }
237};
238
240{
241 public:
242 npc_blazing_monstrosity() : CreatureScript("npc_blazing_monstrosity") { }
243
245 {
246 npc_blazing_monstrosityAI(Creature* creature) : PassiveAI(creature), _summons(creature)
247 {
248 }
249
251 {
252 _summons.DespawnAll();
253 _events.Reset();
255 }
256
257 void JustDied(Unit* /*killer*/) OVERRIDE
258 {
259 _summons.DespawnAll();
260 _events.Reset();
261 }
262
267
268 void EnterCombat(Unit* /*target*/) OVERRIDE
269 {
271 me->RemoveAurasDueToSpell(SPELL_SLEEP_ULTRA_HIGH_PRIORITY);
272 me->PlayOneShotAnimKit(ANIM_KIT_BIRD_WAKE);
273 _events.Reset();
274 _events.ScheduleEvent(EVENT_START_SPITTING, 6000);
275 _events.ScheduleEvent(EVENT_CONTINUE_SPITTING, 9000);
276 }
277
278 void PassengerBoarded(Unit* passenger, int8 /*seat*/, bool apply) OVERRIDE
279 {
280 if (!apply)
281 return;
282
283 // Our passenger is another vehicle (boardable by players)
284 DoCast(passenger, SPELL_SHARE_HEALTH, true);
285 passenger->setFaction(35);
286 passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
287
288 // Hack to relocate vehicle on vehicle so exiting players are not moved under map
289 Movement::MoveSplineInit init(passenger);
291 init.MoveTo(0.6654003f, 0.0f, 1.9815f);
292 init.SetFacing(0.0f);
293 init.Launch();
294 }
295
297 {
298 _summons.Summon(summon);
299 }
300
302 {
303 _summons.Despawn(summon);
304 }
305
307 {
308 if (!UpdateVictim())
309 return;
310
311 _events.Update(diff);
312
313 while (uint32 eventId = _events.ExecuteEvent())
314 {
315 switch (eventId)
316 {
318 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, -SPELL_RIDE_MONSTROSITY))
320 break;
323 if (Creature* egg = me->FindNearestCreature(NPC_EGG_PILE, 100.0f))
324 egg->AI()->DoAction(me->GetEntry());
325 break;
326 }
327 }
328 }
329
330 private:
333 };
334
336 {
337 return new npc_blazing_monstrosityAI(creature);
338 }
339};
340
342{
343 public:
344 npc_molten_barrage() : CreatureScript("npc_molten_barrage") { }
345
347 {
349 {
350 }
351
353 {
354 if (target)
355 me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f, MOTION_SLOT_IDLE);
356 }
357
364
365 void MovementInform(uint32 movementType, uint32 /*pointId*/) OVERRIDE
366 {
367 if (movementType != EFFECT_MOTION_TYPE)
368 return;
369
371 me->ClearUnitState(UNIT_STATE_CANNOT_TURN);
372 }
373 };
374
376 {
377 return new npc_molten_barrageAI(creature);
378 }
379};
380
382{
383 public:
384 npc_egg_pile() : CreatureScript("npc_egg_pile") { }
385
387 {
388 npc_egg_pileAI(Creature* creature) : CreatureAI(creature)
389 {
390 }
391
392 void AttackStart(Unit* /*target*/) OVERRIDE { }
393
395 {
396 me->SetReactState(REACT_PASSIVE);
397 _events.Reset();
399 }
400
401 void JustDied(Unit* /*killer*/) OVERRIDE
402 {
403 _events.Reset();
404 std::list<Creature*> eggs;
406 for (std::list<Creature*>::const_iterator itr = eggs.begin(); itr != eggs.end(); ++itr)
408
410 }
411
416
431
433 {
434 if (!UpdateVictim())
435 return;
436
437 _events.Update(diff);
438
439 if (me->HasUnitState(UNIT_STATE_CASTING))
440 return;
441
442 while (uint32 eventId = _events.ExecuteEvent())
443 {
444 switch (eventId)
445 {
447 {
448 std::list<Creature*> eggs;
449 MoltenEggCheck check(me);
451 me->VisitNearbyGridObject(20.0f, searcher);
452 if (!eggs.empty())
453 {
457 egg->m_Events.AddEvent(new RespawnEggEvent(egg), egg->m_Events.CalculateTime(5000));
458 }
459
462 _events.ScheduleEvent(EVENT_SUMMON_SMOULDERING_HATCHLING, std::rand() % 10000 + 6000);
463 break;
464 }
465 default:
466 break;
467 }
468 }
469
471 }
472
473 private:
476 };
477
479 {
480 return new npc_egg_pileAI(creature);
481 }
482};
483
519
521{
522 public:
523 spell_alysrazor_turn_monstrosity() : SpellScriptLoader("spell_alysrazor_turn_monstrosity") { }
524
526 {
528
529 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
530 {
531 if (!sSpellMgr->GetSpellInfo(SPELL_GENERIC_DUMMY_CAST))
532 return false;
533 if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_RIGHT))
534 return false;
535 if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_LEFT))
536 return false;
537 if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_FORWARD))
538 return false;
539 if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_BACK))
540 return false;
541 return true;
542 }
543
545 {
546 PreventHitDefaultEffect(effIndex);
548 if (TempSummon* summ = GetHitUnit()->ToTempSummon())
549 if (Unit* summoner = summ->GetSummoner())
551
552 float angle = 0.0f;
553 if (Unit* bird = GetCaster()->GetVehicleBase())
554 {
555 bird->SetInFront(GetHitUnit());
556 angle = bird->GetOrientation();
557 }
558
559 uint32 spellId = 0;
560 switch (GetSpellInfo()->Id)
561 {
564 spellId = SPELL_KNOCKBACK_RIGHT;
565 angle -= M_PI * 0.5f;
566 break;
569 spellId = SPELL_KNOCKBACK_LEFT;
570 angle += M_PI * 0.5f;
571 break;
574 spellId = SPELL_KNOCKBACK_FORWARD;
575 break;
576 case SPELL_TICKLE_R:
577 case SPELL_TICKLE_L:
578 spellId = SPELL_KNOCKBACK_BACK;
579 angle -= M_PI;
580 break;
581 }
582
583 // Cannot wait for object update to process facing spline, it's needed in next spell cast
584 GetHitUnit()->SetOrientation(angle);
585 GetHitUnit()->SetFacingTo(angle);
588 }
589
595
601 };
602
607};
608
648
650{
651 public:
652 spell_alysrazor_fieroblast() : SpellScriptLoader("spell_alysrazor_fieroblast") { }
653
655 {
657
658 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
659 {
660 if (!sSpellMgr->GetSpellInfo(SPELL_FIRE_IT_UP))
661 return false;
662 return true;
663 }
664
669
674 };
675
680};
681
#define M_PI
Definition Common.h:192
DBCStorage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore(CreatureDisplayInfofmt)
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
#define SIZE_OF_GRIDS
Definition GridDefines.h:26
@ MOTION_SLOT_IDLE
@ EFFECT_MOTION_TYPE
@ TYPEID_UNIT
Definition Object.h:54
void GetCreatureListWithEntryInGrid(std::list< Creature * > &list, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
#define sSpellMgr
Definition SpellMgr.h:744
#define SpellEffectFn(F, I, N)
#define SpellCastFn(F)
@ TRIGGERED_FULL_MASK
Will ignore most target checks (mostly DBC target checks).
Definition Unit.h:435
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ UNIT_STATE_CANNOT_TURN
Definition Unit.h:547
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_CHANNEL_OBJECT
@ UNIT_FIELD_FLAGS
#define SPELL_MOLTEN_BARRAGE
@ ANIM_KIT_BIRD_WAKE
@ MODEL_INVISIBLE_STALKER
@ ANIM_KIT_BIRD_TURN
#define SPELL_SHARE_HEALTH
static void AlysrazorTrashEvaded(Creature *creature)
@ SPELL_HEAD_BONK_L
@ SPELL_MOLTEN_BARRAGE_LEFT
@ SPELL_RIGHT_SIDE_SMACK_R
@ SPELL_FIRE_IT_UP
@ SPELL_INVISIBILITY_AND_STEALTH_DETECTION
@ SPELL_KNOCKBACK_LEFT
@ SPELL_FIEROBLAST_TRASH
@ SPELL_LEFT_SIDE_SMACK_L
@ SPELL_HEAD_BONK_R
@ SPELL_AGGRO_CLOSEST
@ SPELL_SHARE_HEALTH_RIGHT
@ SPELL_FIEROCLAST_BARRAGE
@ SPELL_FIRE_CHANNELING
@ SPELL_GENERIC_DUMMY_CAST
@ SPELL_MOLTEN_BARRAGE_VISUAL
@ SPELL_RIGHT_SIDE_SMACK_L
@ SPELL_KNOCKBACK_FORWARD
@ SPELL_RIDE_MONSTROSITY
@ SPELL_TICKLE_R
@ SPELL_MOLTEN_EGG_TRASH_CALL_L
@ SPELL_SHARE_HEALTH_LEFT
@ SPELL_LEFT_SIDE_SMACK_R
@ SPELL_MOLTEN_BARRAGE_RIGHT
@ SPELL_SUMMON_SMOULDERING_HATCHLING
@ SPELL_MOLTEN_BARRAGE_EFFECT_L
@ SPELL_KNOCKBACK_RIGHT
@ SPELL_MOLTEN_BARRAGE_EFFECT_R
@ SPELL_TICKLE_L
@ SPELL_SLEEP_ULTRA_HIGH_PRIORITY
@ SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION
@ SPELL_KNOCKBACK_BACK
@ SPELL_MOLTEN_EGG_TRASH_CALL_R
@ EMOTE_CRACKING_EGGS
void AddSC_boss_alysrazor()
#define SPELL_MOLTEN_BARRAGE_EFFECT
@ EVENT_CONTINUE_SPITTING
@ EVENT_FIEROCLAST_BARRAGE
@ EVENT_FIEROBLAST
@ EVENT_SUMMON_SMOULDERING_HATCHLING
@ EVENT_START_SPITTING
CreatureAI(Creature *creature)
Definition CreatureAI.h:69
virtual void MoveInLineOfSight(Unit *)
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:56
virtual void EnterEvadeMode()
void Respawn(bool force=false)
void SetDisplayId(uint32 modelId) OVERRIDE
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
CreatureScript(const char *name)
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
uint64 CalculateTime(uint64 t_offset) const
bool operator()(Unit *object) const
MoltenEggCheck(Creature *pile)
void SetFacing(float angle)
void MoveTo(const Vector3 &destination, bool generatePath=true, bool forceDestination=false)
NullCreatureAI(Creature *c)
Definition PassiveAI.cpp:12
static Creature * GetCreature(WorldObject const &u, uint64 guid)
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:125
PassiveAI(Creature *c)
Definition PassiveAI.cpp:10
RespawnEggEvent(Creature *egg)
bool Execute(uint64, uint32)
Creature * GetHitCreature()
HookList< CastHandler > AfterCast
SpellInfo const * GetSpellInfo()
void PreventHitDefaultEffect(SpellEffIndex effIndex)
HookList< EffectHandler > OnEffectHitTarget
Unit * GetHitUnit()
Unit * GetCaster()
SpellScriptLoader(const char *name)
float getThreat(Unit *victim, bool alsoSearchOfflineList=false)
void addThreat(Unit *victim, float threat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=NULL)
void operator()(Creature *creature) const
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastAOE(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:176
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
Definition Unit.h:1367
void ClearUnitState(uint32 f)
Definition Unit.h:1489
void SetFacingTo(float ori)
Definition Unit.cpp:9114
void PlayOneShotAnimKit(uint32 id)
Definition Unit.cpp:6328
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
bool IsAlive() const
Definition Unit.h:2032
void AddUnitState(uint32 f)
Definition Unit.h:1481
uint32 GetDisplayId() const
Definition Unit.h:2490
uint32 GetNativeDisplayId() const
Definition Unit.h:2495
EventProcessor m_Events
Definition Unit.h:2396
virtual void SetDisplayId(uint32 modelId)
Definition Unit.cpp:5941
ThreatManager & getThreatManager()
Definition Unit.h:2455
UnitAI * GetAI()
Definition Unit.h:1393
void VisitNearbyGridObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:783
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
PrepareSpellScript(spell_alysrazor_fieroblast_SpellScript)
SpellScript * GetSpellScript() const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
@ NPC_HARBINGER_OF_FLAME
Definition firelands.h:32
@ NPC_SMOULDERING_HATCHLING
Definition firelands.h:34
@ NPC_BLAZING_MONSTROSITY_RIGHT
Definition firelands.h:30
@ NPC_MOLTEN_EGG_TRASH
Definition firelands.h:33
@ NPC_EGG_PILE
Definition firelands.h:31
@ NPC_BLAZING_MONSTROSITY_LEFT
Definition firelands.h:29
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
void SetOrientation(float orientation)
Definition Object.h:323
Creature * me
ScriptedAI(Creature *creature)
void SummonedCreatureDespawn(Creature *summon) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void PassengerBoarded(Unit *passenger, int8, bool apply) OVERRIDE
== Fields =======================================
void DoAction(int32 action) OVERRIDE
void AttackStart(Unit *) OVERRIDE
npc_egg_pileAI(Creature *creature)
void JustDied(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void MovementInform(uint32 movementType, uint32) OVERRIDE
void AttackStart(Unit *target) OVERRIDE