Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_ignis.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 "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "SpellScript.h"
9#include "SpellAuraEffects.h"
10#include "ulduar.h"
11#include "Vehicle.h"
12
24
26{
28 SPELL_SCORCH = 62546,
34 SPELL_GRAB = 62707,
36
37 // Iron Construct
38 SPELL_HEAT = 65667,
39 SPELL_MOLTEN = 62373,
42 SPELL_GROUND = 62548,
43};
44
56
58{
60};
61
67
73
74#define CONSTRUCT_SPAWN_POINTS 20
75
77{
78 {630.366f, 216.772f, 360.891f, 3.001970f},
79 {630.594f, 231.846f, 360.891f, 3.124140f},
80 {630.435f, 337.246f, 360.886f, 3.211410f},
81 {630.493f, 313.349f, 360.886f, 3.054330f},
82 {630.444f, 321.406f, 360.886f, 3.124140f},
83 {630.366f, 247.307f, 360.888f, 3.211410f},
84 {630.698f, 305.311f, 360.886f, 3.001970f},
85 {630.500f, 224.559f, 360.891f, 3.054330f},
86 {630.668f, 239.840f, 360.890f, 3.159050f},
87 {630.384f, 329.585f, 360.886f, 3.159050f},
88 {543.220f, 313.451f, 360.886f, 0.104720f},
89 {543.356f, 329.408f, 360.886f, 6.248280f},
90 {543.076f, 247.458f, 360.888f, 6.213370f},
91 {543.117f, 232.082f, 360.891f, 0.069813f},
92 {543.161f, 305.956f, 360.886f, 0.157080f},
93 {543.277f, 321.482f, 360.886f, 0.052360f},
94 {543.316f, 337.468f, 360.886f, 6.195920f},
95 {543.280f, 239.674f, 360.890f, 6.265730f},
96 {543.265f, 217.147f, 360.891f, 0.174533f},
97 {543.256f, 224.831f, 360.891f, 0.122173f},
98};
99
101{
102 public:
103 boss_ignis() : CreatureScript("boss_ignis") { }
104
105 struct boss_ignis_AI : public BossAI
106 {
107 boss_ignis_AI(Creature* creature) : BossAI(creature, BOSS_IGNIS), _vehicle(me->GetVehicleKit())
108 {
110 }
111
113 {
114 _Reset();
115 if (_vehicle)
116 _vehicle->RemoveAllPassengers();
117
119 }
120
121 void EnterCombat(Unit* /*who*/) OVERRIDE
122 {
123 _EnterCombat();
125 events.ScheduleEvent(EVENT_JET, 30000);
126 events.ScheduleEvent(EVENT_SCORCH, 25000);
127 events.ScheduleEvent(EVENT_SLAG_POT, 35000);
128 events.ScheduleEvent(EVENT_CONSTRUCT, 15000);
129 events.ScheduleEvent(EVENT_END_POT, 40000);
130 events.ScheduleEvent(EVENT_BERSERK, 480000);
131 _slagPotGUID = 0;
132 _shattered = false;
135 }
136
137 void JustDied(Unit* /*killer*/) OVERRIDE
138 {
139 _JustDied();
141 }
142
144 {
145 if (type == DATA_SHATTERED)
146 return _shattered ? 1 : 0;
147
148 return 0;
149 }
150
152 {
153 if (who->GetTypeId() == TypeID::TYPEID_PLAYER)
154 Talk(SAY_SLAY);
155 }
156
158 {
159 if (summon->GetEntry() == NPC_IRON_CONSTRUCT)
160 {
161 summon->setFaction(16);
162 summon->SetReactState(REACT_AGGRESSIVE);
164 }
165
166 summon->AI()->AttackStart(me->GetVictim());
167 summon->AI()->DoZoneInCombat();
168 summons.Summon(summon);
169 }
170
172 {
173 if (action != ACTION_REMOVE_BUFF)
174 return;
175
176 me->RemoveAuraFromStack(SPELL_STRENGHT);
177 // Shattered Achievement
178 time_t secondKill = sWorld->GetGameTime();
179 if ((secondKill - _firstConstructKill) < 5)
180 _shattered = true;
181 _firstConstructKill = secondKill;
182 }
183
185 {
186 if (!UpdateVictim())
187 return;
188
189 events.Update(diff);
190
191 if (me->HasUnitState(UNIT_STATE_CASTING))
192 return;
193
194 while (uint32 eventId = events.ExecuteEvent())
195 {
196 switch (eventId)
197 {
198 case EVENT_JET:
201 events.ScheduleEvent(EVENT_JET, std::rand() % 40000 + 35000);
202 break;
203 case EVENT_SLAG_POT:
204 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
205 {
207 _slagPotGUID = target->GetGUID();
208 DoCast(target, SPELL_GRAB);
209 events.DelayEvents(3000);
210 events.ScheduleEvent(EVENT_GRAB_POT, 500);
211 }
212 events.ScheduleEvent(EVENT_SLAG_POT, RAID_MODE(30000, 15000));
213 break;
214 case EVENT_GRAB_POT:
215 if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID))
216 {
217 slagPotTarget->EnterVehicle(me, 0);
218 events.CancelEvent(EVENT_GRAB_POT);
219 events.ScheduleEvent(EVENT_CHANGE_POT, 1000);
220 }
221 break;
222 case EVENT_CHANGE_POT:
223 if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID))
224 {
225 slagPotTarget->AddAura(SPELL_SLAG_POT, slagPotTarget);
226 slagPotTarget->EnterVehicle(me, 1);
227 events.CancelEvent(EVENT_CHANGE_POT);
228 events.ScheduleEvent(EVENT_END_POT, 10000);
229 }
230 break;
231 case EVENT_END_POT:
232 if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID))
233 {
234 slagPotTarget->ExitVehicle();
235 slagPotTarget = NULL;
236 _slagPotGUID = 0;
237 events.CancelEvent(EVENT_END_POT);
238 }
239 break;
240 case EVENT_SCORCH:
242 if (Unit* target = me->GetVictim())
243 me->SummonCreature(NPC_GROUND_SCORCH, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 45000);
245 events.ScheduleEvent(EVENT_SCORCH, 25000);
246 break;
247 case EVENT_CONSTRUCT:
252 events.ScheduleEvent(EVENT_CONSTRUCT, RAID_MODE(40000, 30000));
253 break;
254 case EVENT_BERSERK:
255 DoCast(me, SPELL_BERSERK, true);
257 break;
258 }
259 }
260
262
264 }
265
266 private:
271 };
272
274 {
275 return GetUlduarAI<boss_ignis_AI>(creature);
276 }
277};
278
280{
281 public:
282 npc_iron_construct() : CreatureScript("npc_iron_construct") { }
283
285 {
286 npc_iron_constructAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
287 {
288 creature->SetReactState(REACT_PASSIVE);
289 }
290
292 {
293 _brittled = false;
294 }
295
296 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
297 {
298 if (me->HasAura(SPELL_BRITTLE) && damage >= 5000)
299 {
301 if (Creature* ignis = ObjectAccessor::GetCreature(*me, _instance->GetData64(BOSS_IGNIS)))
302 if (ignis->AI())
303 ignis->AI()->DoAction(ACTION_REMOVE_BUFF);
304
305 me->DespawnOrUnsummon(1000);
306 }
307 }
308
309 void UpdateAI(uint32 /*uiDiff*/) OVERRIDE
310 {
311 if (!UpdateVictim())
312 return;
313
314 if (Aura* aur = me->GetAura(SPELL_HEAT))
315 {
316 if (aur->GetStackAmount() >= 10)
317 {
318 me->RemoveAura(SPELL_HEAT);
320 _brittled = false;
321 }
322 }
323
324 // Water pools
325 if (me->IsInWater() && !_brittled && me->HasAura(SPELL_MOLTEN))
326 {
328 me->RemoveAura(SPELL_MOLTEN);
329 _brittled = true;
330 }
331
333 }
334
335 private:
338 };
339
341 {
342 return GetUlduarAI<npc_iron_constructAI>(creature);
343 }
344};
345
347{
348 public:
349 npc_scorch_ground() : CreatureScript("npc_scorch_ground") { }
350
352 {
354 {
356 creature->SetDisplayId(16925); //model 2 in db cannot overwrite wdb fields
357 }
358
360
361 {
362 if (!_heat)
363 {
364 if (who->GetEntry() == NPC_IRON_CONSTRUCT)
365 {
366 if (!who->HasAura(SPELL_HEAT) || !who->HasAura(SPELL_MOLTEN))
367 {
368 _constructGUID = who->GetGUID();
369 _heat = true;
370 }
371 }
372 }
373 }
374
376 {
377 _heat = false;
379 _constructGUID = 0;
380 _heatTimer = 0;
381 }
382
384 {
385 if (_heat)
386 {
387 if (_heatTimer <= uiDiff)
388 {
389 Creature* construct = me->GetCreature(*me, _constructGUID);
390 if (construct && !construct->HasAura(SPELL_MOLTEN))
391 {
392 me->AddAura(SPELL_HEAT, construct);
393 _heatTimer = 1000;
394 }
395 }
396 else
397 _heatTimer -= uiDiff;
398 }
399 }
400
401 private:
404 bool _heat;
405 };
406
408 {
409 return GetUlduarAI<npc_scorch_groundAI>(creature);
410 }
411};
412
414{
415 public:
416 spell_ignis_slag_pot() : SpellScriptLoader("spell_ignis_slag_pot") { }
417
419 {
421
422 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
423 {
424 if (!sSpellMgr->GetSpellInfo(SPELL_SLAG_POT_DAMAGE)
425 || !sSpellMgr->GetSpellInfo(SPELL_SLAG_IMBUED))
426 return false;
427 return true;
428 }
429
431 {
432 Unit* aurEffCaster = aurEff->GetCaster();
433 if (!aurEffCaster)
434 return;
435
436 Unit* target = GetTarget();
437 aurEffCaster->CastSpell(target, SPELL_SLAG_POT_DAMAGE, true);
438 }
439
440 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
441 {
442 if (GetTarget()->IsAlive())
444 }
445
451 };
452
454 {
456 }
457};
458
460{
461 public:
462 achievement_ignis_shattered() : AchievementCriteriaScript("achievement_ignis_shattered") { }
463
464 bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE
465 {
466 if (target && target->IsAIEnabled)
467 return target->GetAI()->GetData(DATA_SHATTERED);
468
469 return false;
470 }
471};
472
474{
475 new boss_ignis();
476 new npc_iron_construct();
477 new npc_scorch_ground();
480}
Actions
@ ACHIEVEMENT_TIMED_TYPE_EVENT
Definition DBCEnums.h:158
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
@ EFFECT_0
@ SPELL_AURA_PERIODIC_DUMMY
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
#define sSpellMgr
Definition SpellMgr.h:744
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ REACT_PASSIVE
Definition Unit.h:1156
@ REACT_AGGRESSIVE
Definition Unit.h:1158
@ UNIT_FLAG_STUNNED
Definition Unit.h:643
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_PACIFIED
Definition Unit.h:642
@ UNIT_FLAG_DISABLE_MOVE
Definition Unit.h:627
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
Creatures
@ SAY_BERSERK
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
#define SPELL_BERSERK
@ ACTION_REMOVE_BUFF
@ NPC_IRON_CONSTRUCT
@ NPC_GROUND_SCORCH
Position const ConstructSpawnPosition[CONSTRUCT_SPAWN_POINTS]
@ SAY_DEATH
@ SAY_AGGRO
@ EMOTE_JETS
@ SAY_SCORCH
@ SAY_SLAY
@ SAY_SUMMON
@ SAY_BERSERK
@ SAY_SLAG_POT
@ SPELL_BRITTLE
@ SPELL_GRAB
@ SPELL_ACTIVATE_CONSTRUCT
@ SPELL_SLAG_IMBUED
@ SPELL_SLAG_POT
@ SPELL_HEAT
@ SPELL_FLAME_JETS
@ SPELL_SCORCH
@ SPELL_GROUND
@ SPELL_STRENGHT
@ SPELL_SHATTER
@ SPELL_BERSERK
@ SPELL_MOLTEN
@ SPELL_SLAG_POT_DAMAGE
void AddSC_boss_ignis()
#define CONSTRUCT_SPAWN_POINTS
@ DATA_SHATTERED
@ ACHIEVEMENT_IGNIS_START_EVENT
@ EVENT_END_POT
@ EVENT_GRAB_POT
@ EVENT_JET
@ EVENT_CONSTRUCT
@ EVENT_CHANGE_POT
@ EVENT_BERSERK
@ EVENT_SLAG_POT
@ EVENT_SCORCH
@ SPELL_SHATTER
@ EVENT_BERSERK
AchievementCriteriaScript(const char *name)
Unit * GetCaster() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
Unit * GetTarget() const
InstanceScript *const instance
SummonList summons
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
Creature * DoSummon(uint32 entry, Position const &pos, uint32 despawnTime=30000, TempSummonType summonType=TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
void SetDisplayId(uint32 modelId) OVERRIDE
void SetReactState(ReactStates st)
Definition Creature.h:460
CreatureScript(const char *name)
static Creature * GetCreature(WorldObject const &u, uint64 guid)
static Unit * GetUnit(WorldObject const &, uint64 guid)
SpellScriptLoader(const char *name)
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
Definition Unit.h:1367
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)
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
bool OnCheck(Player *, Unit *target) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
PrepareAuraScript(spell_ignis_slag_pot_AuraScript)
void HandleEffectPeriodic(AuraEffect const *aurEff)
void OnRemove(AuraEffect const *, AuraEffectHandleModes)
AuraScript * GetAuraScript() const OVERRIDE
#define sWorld
Definition World.h:910
AchievementData
Creature * me
bool EnterEvadeIfOutOfCombatArea(uint32 const diff)
const T & RAID_MODE(const T &normal10, const T &normal25) const
ScriptedAI(Creature *creature)
void DoAction(int32 action) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
uint32 GetData(uint32 type) const OVERRIDE
void JustDied(Unit *) OVERRIDE
void JustSummoned(Creature *summon) OVERRIDE
boss_ignis_AI(Creature *creature)
void KilledUnit(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32) OVERRIDE
== Triggered Actions Requested ==================
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void UpdateAI(uint32 uiDiff) OVERRIDE
== Triggered Actions Requested ==================
void MoveInLineOfSight(Unit *who) OVERRIDE
@ BOSS_IGNIS
Definition ulduar.h:21
AI * GetUlduarAI(T *obj)
Definition ulduar.h:336