Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_nexusprince_shaffar.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/* ScriptData
7SDName: Boss_NexusPrince_Shaffar
8SD%Complete: 80
9SDComment: Need more tuning of spell timers, it should not be as linear fight as current. Also should possibly find a better way to deal with his three initial beacons to make sure all aggro.
10SDCategory: Auchindoun, Mana Tombs
11EndScriptData */
12
13/* ContentData
14boss_nexusprince_shaffar
15npc_ethereal_beacon
16EndContentData */
17
18#include "ScriptMgr.h"
19#include "ScriptedCreature.h"
20
22{
28};
29
31{
32 SPELL_BLINK = 34605,
36
37 SPELL_ETHEREAL_BEACON = 32371, // Summons NPC_BEACON
39
40 // Ethereal Beacon
42 SPELL_ETHEREAL_APPRENTICE = 32372 // Summon 18430
43};
44
46{
47 NPC_BEACON = 18431,
49};
50
51enum Misc
52{
54};
55
57{
58public:
59 boss_nexusprince_shaffar() : CreatureScript("boss_nexusprince_shaffar") { }
60
62 {
63 return new boss_nexusprince_shaffarAI(creature);
64 }
65
67 {
68 boss_nexusprince_shaffarAI(Creature* creature) : ScriptedAI(creature), summons(me) { HasTaunted = false; }
69
75
77
80
82 {
83 Blink_Timer = 1500;
84 Beacon_Timer = 10000;
85 FireBall_Timer = 8000;
86 Frostbolt_Timer = 4000;
87 FrostNova_Timer = 15000;
88
89 CanBlink = false;
90
91 float dist = 8.0f;
92 float posX, posY, posZ, angle;
93 me->GetHomePosition(posX, posY, posZ, angle);
94
95 me->SummonCreature(NPC_BEACON, posX - dist, posY - dist, posZ, angle, TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
96 me->SummonCreature(NPC_BEACON, posX - dist, posY + dist, posZ, angle, TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
97 me->SummonCreature(NPC_BEACON, posX + dist, posY, posZ, angle, TempSummonType::TEMPSUMMON_CORPSE_TIMED_DESPAWN, 7200000);
98 }
99
101 {
102 summons.DespawnAll();
104 }
105
107
108 {
109 if (!HasTaunted && who->GetTypeId() == TypeID::TYPEID_PLAYER && me->IsWithinDistInMap(who, 100.0f))
110 {
112 HasTaunted = true;
113 }
114 }
115
116 void EnterCombat(Unit* /*who*/) OVERRIDE
117 {
119
121 summons.DoZoneInCombat();
122 }
123
125 {
126 if (summoned->GetEntry() == NPC_BEACON)
127 {
128 summoned->CastSpell(summoned, SPELL_ETHEREAL_BEACON_VISUAL, false);
129
130 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
131 summoned->AI()->AttackStart(target);
132 }
133
134 summons.Summon(summoned);
135 }
136
138 {
139 summons.Despawn(summon);
140 }
141
142 void KilledUnit(Unit* /*victim*/) OVERRIDE
143 {
144 Talk(SAY_SLAY);
145 }
146
147 void JustDied(Unit* /*killer*/) OVERRIDE
148 {
149 Talk(SAY_DEAD);
150 summons.DespawnAll();
151 }
152
154 {
155 if (!UpdateVictim())
156 return;
157
158 if (FrostNova_Timer <= diff)
159 {
160 if (me->IsNonMeleeSpellCasted(false))
161 me->InterruptNonMeleeSpells(true);
162
164 FrostNova_Timer = std::rand() % 25000 + 17500;
165 CanBlink = true;
166 } else FrostNova_Timer -= diff;
167
168 if (Frostbolt_Timer <= diff)
169 {
171 Frostbolt_Timer = std::rand() % 6000 + 4500;
172 } else Frostbolt_Timer -= diff;
173
174 if (FireBall_Timer <= diff)
175 {
177 FireBall_Timer = std::rand() % 6000 + 4500;
178 } else FireBall_Timer -= diff;
179
180 if (CanBlink)
181 {
182 if (Blink_Timer <= diff)
183 {
184 if (me->IsNonMeleeSpellCasted(false))
185 me->InterruptNonMeleeSpells(true);
186
187 //expire movement, will prevent from running right back to victim after cast
188 //(but should MoveChase be used again at a certain time or should he not move?)
189 if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
190 me->GetMotionMaster()->MovementExpired();
191
193 Blink_Timer = std::rand() % 2500 + 1000;
194 CanBlink = false;
195 } else Blink_Timer -= diff;
196 }
197
198 if (Beacon_Timer <= diff)
199 {
200 if (me->IsNonMeleeSpellCasted(false))
201 me->InterruptNonMeleeSpells(true);
202
203 if (!(std::rand() % 3))
205
207
208 Beacon_Timer = 10000;
209 } else Beacon_Timer -= diff;
210
212 }
213 };
214};
215
217{
218public:
219 npc_ethereal_beacon() : CreatureScript("npc_ethereal_beacon") { }
220
222 {
223 return new npc_ethereal_beaconAI(creature);
224 }
225
227 {
229 {
230 }
231
235
236 void KillSelf()
237 {
238 me->Kill(me);
239 }
240
242 {
243 Apprentice_Timer = DUNGEON_MODE(20000, 10000);
244 ArcaneBolt_Timer = 1000;
245 Check_Timer = 1000;
246 }
247
249 {
250 // Send Shaffar to fight
251 Creature* Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100);
252 if (!Shaffar || Shaffar->isDead())
253 {
254 KillSelf();
255 return;
256 }
257 if (!Shaffar->IsInCombat())
258 Shaffar->AI()->AttackStart(who);
259 }
260
262 {
263 summoned->AI()->AttackStart(me->GetVictim());
264 }
265
267 {
268 if (!UpdateVictim())
269 return;
270
271 if (Check_Timer <= diff)
272 {
273 Creature* Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100);
274 if (!Shaffar || Shaffar->isDead() || !Shaffar->IsInCombat())
275 {
276 KillSelf();
277 return;
278 }
279 Check_Timer = 1000;
280 } else Check_Timer -= diff;
281
282 if (ArcaneBolt_Timer <= diff)
283 {
285 ArcaneBolt_Timer = std::rand() % 4500 + 2000;
286 } else ArcaneBolt_Timer -= diff;
287
288 if (Apprentice_Timer <= diff)
289 {
290 if (me->IsNonMeleeSpellCasted(false))
291 me->InterruptNonMeleeSpells(true);
292
294 me->DespawnOrUnsummon();
295 return;
296 } else Apprentice_Timer -= diff;
297 }
298 };
299};
300
306
308{
309public:
310 npc_ethereal_apprentice() : CreatureScript("npc_ethereal_apprentice") { }
311
313 {
314 return new npc_ethereal_apprenticeAI(creature);
315 }
316
318 {
320
322
324
326 {
327 Cast_Timer = 3000;
328 isFireboltTurn = true;
329 }
330
332 {
333 if (!UpdateVictim())
334 return;
335
336 if (Cast_Timer <= diff)
337 {
338 if (isFireboltTurn)
339 {
341 isFireboltTurn = false;
342 }else{
344 isFireboltTurn = true;
345 }
346 Cast_Timer = 3000;
347 } else Cast_Timer -= diff;
348 }
349 };
350};
351
357
359{
360public:
361 npc_yor() : CreatureScript("npc_yor") { }
362
363 struct npc_yorAI : public ScriptedAI
364 {
365 npc_yorAI(Creature* creature) : ScriptedAI(creature) { }
366
367 void Reset() OVERRIDE { }
368
369 void EnterCombat(Unit* /*who*/) OVERRIDE
370 {
371 events.ScheduleEvent(EVENT_DOUBLE_BREATH, std::rand() % 9000 + 6000);
372 }
373
375 {
376 if (!UpdateVictim())
377 return;
378
379 events.Update(diff);
380
381 while (uint32 eventId = events.ExecuteEvent())
382 {
383 switch (eventId)
384 {
386 if (me->IsWithinDist(me->GetVictim(), ATTACK_DISTANCE))
388 events.ScheduleEvent(EVENT_DOUBLE_BREATH, std::rand() % 9000 + 6000);
389 break;
390 default:
391 break;
392 }
393 }
395 }
396
397 private:
399 };
400
402 {
403 return new npc_yorAI(creature);
404 }
405};
406
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ CHASE_MOTION_TYPE
#define ATTACK_DISTANCE
Definition Object.h:22
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition Object.h:73
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
Creatures
@ SAY_SLAY
@ SAY_INTRO
@ SPELL_FROSTBOLT
@ SPELL_FIREBALL
#define SAY_AGGRO
@ SPELL_ETHEREAL_APPRENTICE
@ SPELL_ETHEREAL_BEACON_VISUAL
@ SPELL_ETHEREAL_APPRENTICE_FROSTBOLT
@ SPELL_ETHEREAL_APPRENTICE_FIREBOLT
void AddSC_boss_nexusprince_shaffar()
#define SPELL_BLINK
Definition boss_noth.cpp:28
@ SPELL_FROSTNOVA
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(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
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
Definition Unit.h:1367
bool IsInCombat() const
Definition Unit.h:1896
bool isDead() const
Definition Unit.h:2040
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Creature * me
ScriptedAI(Creature *creature)
const T & DUNGEON_MODE(const T &normal5, const T &heroic5) const
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void EnterCombat(Unit *) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================