Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_astromancer.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_Astromancer
8SD%Complete: 80
9SDComment:
10SDCategory: Tempest Keep, The Eye
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "SpellScript.h"
16#include "SpellAuraEffects.h"
17
18#include "the_eye.h"
19
30
46
54
56{
57 MODEL_HUMAN = 18239,
59};
60
61enum Misc
62{
63 WV_ARMOR = 31000
64};
65
66const float CENTER_X = 432.909f;
67const float CENTER_Y = -373.424f;
68const float CENTER_Z = 17.9608f;
69const float CENTER_O = 1.06421f;
70const float SMALL_PORTAL_RADIUS = 12.6f;
71const float LARGE_PORTAL_RADIUS = 26.0f;
72const float PORTAL_Z = 17.005f;
73
74/* not used // x, y, z, o
75static float SolarianPos[4] = {432.909f, -373.424f, 17.9608f, 1.06421f};
76*/
77
79{
80 public:
81 boss_high_astromancer_solarian() : CreatureScript("boss_high_astromancer_solarian") { }
82
84 {
86 {
87 instance = creature->GetInstanceScript();
88
89 defaultarmor = creature->GetArmor();
90 defaultsize = creature->GetObjectScale();
91 }
92
95
97
109
111 float Portals[3][3];
112
115
117 {
120 BlindingLight_Timer = 41000;
121 Fear_Timer = 20000;
122 VoidBolt_Timer = 10000;
123 Phase1_Timer = 50000;
124 Phase2_Timer = 10000;
125 Phase3_Timer = 15000;
126 AppearDelay_Timer = 2000;
127 BlindingLight = false;
128 AppearDelay = false;
129 Wrath_Timer = 20000+rand()%5000;//twice in phase one
130 Phase = 1;
131
132 if (instance)
134
135 me->SetArmor(defaultarmor);
137 me->SetVisible(true);
138 me->SetObjectScale(defaultsize);
139 me->SetDisplayId(MODEL_HUMAN);
140
141 Summons.DespawnAll();
142 }
143
144 void KilledUnit(Unit* /*victim*/) OVERRIDE
145 {
146 Talk(SAY_KILL);
147 }
148
149 void JustDied(Unit* /*killer*/) OVERRIDE
150 {
151 me->SetObjectScale(defaultsize);
152 me->SetDisplayId(MODEL_HUMAN);
154 if (instance)
156 }
157
158 void EnterCombat(Unit* /*who*/) OVERRIDE
159 {
162
163 if (instance)
165 }
166
167 void SummonMinion(uint32 entry, float x, float y, float z)
168 {
169 Creature* Summoned = me->SummonCreature(entry, x, y, z, 0, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
170 if (Summoned)
171 {
172 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
173 Summoned->AI()->AttackStart(target);
174
175 Summons.Summon(Summoned);
176 }
177 }
178
179 float Portal_X(float radius)
180 {
181 if (std::rand() % 1)
182 radius = -radius;
183
184 return radius * (float)(rand()%100)/100.0f + CENTER_X;
185 }
186
187 float Portal_Y(float x, float radius)
188 {
189 float z = RAND(1.0f, -1.0f);
190
191 return (z*sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y);
192 }
193
195 {
196 if (!UpdateVictim())
197 return;
198 if (AppearDelay)
199 {
200 me->StopMoving();
201 me->AttackStop();
202 if (AppearDelay_Timer <= diff)
203 {
204 AppearDelay = false;
205 if (Phase == 2)
206 {
208 me->SetVisible(false);
209 }
210 AppearDelay_Timer = 2000;
211 }
212 else
213 AppearDelay_Timer -= diff;
214 }
215 if (Phase == 1)
216 {
217 if (BlindingLight_Timer <= diff)
218 {
219 BlindingLight = true;
220 BlindingLight_Timer = 45000;
221 }
222 else
223 BlindingLight_Timer -= diff;
224
225 if (Wrath_Timer <= diff)
226 {
227 me->InterruptNonMeleeSpells(false);
228 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
230 Wrath_Timer = 20000+rand()%5000;
231 }
232 else
233 Wrath_Timer -= diff;
234
235 if (ArcaneMissiles_Timer <= diff)
236 {
237 if (BlindingLight)
238 {
240 BlindingLight = false;
241 }
242 else
243 {
244 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
245 {
246 if (!me->HasInArc(2.5f, target))
247 target = me->GetVictim();
248
250 }
251 }
253 }
254 else
255 ArcaneMissiles_Timer -= diff;
256
258 {
259 me->InterruptNonMeleeSpells(false);
260 //Target the tank ?
261 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
262 {
263 if (target->GetTypeId() == TypeID::TYPEID_PLAYER)
264 {
267 }
268 else
270 }
271 }
272 else
274
275 //Phase1_Timer
276 if (Phase1_Timer <= diff)
277 {
278 Phase = 2;
279 Phase1_Timer = 50000;
280 //After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
281 me->GetMotionMaster()->Clear();
282 me->SetPosition(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O);
283 for (uint8 i=0; i <= 2; ++i)
284 {
285 if (!i)
286 {
289 Portals[i][2] = CENTER_Z;
290 }
291 else
292 {
295 Portals[i][2] = PORTAL_Z;
296 }
297 }
298 if ((std::abs(Portals[2][0] - Portals[1][0]) < 7) && (std::abs(Portals[2][1] - Portals[1][1]) < 7))
299 {
300 int i=1;
301 if (std::abs(CENTER_X + 26.0f - Portals[2][0]) < 7)
302 i = -1;
303 Portals[2][0] = Portals[2][0]+7*i;
305 }
306 for (int i=0; i <= 2; ++i)
307 {
309 {
310 Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
311 Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false);
312 }
313 }
314 AppearDelay = true;
315 }
316 else
317 Phase1_Timer-=diff;
318 }
319 else
320 if (Phase == 2)
321 {
322 //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
323 me->AttackStop();
324 me->StopMoving();
325 if (Phase2_Timer <= diff)
326 {
327 Phase = 3;
328 for (int i=0; i <= 2; ++i)
329 for (int j=1; j <= 4; j++)
331
333 Phase2_Timer = 10000;
334 }
335 else
336 Phase2_Timer -= diff;
337 }
338 else
339 if (Phase == 3)
340 {
341 me->AttackStop();
342 me->StopMoving();
343 //Check Phase3_Timer
344 if (Phase3_Timer <= diff)
345 {
346 Phase = 1;
347 //15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
348 int i = rand()%3;
349 me->GetMotionMaster()->Clear();
350 me->SetPosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
351
352 for (int j=0; j <= 2; j++)
353 if (j != i)
355
357 me->SetVisible(true);
358
360 AppearDelay = true;
361 Phase3_Timer = 15000;
362 }
363 else
364 Phase3_Timer -= diff;
365 }
366 else
367 if (Phase == 4)
368 {
369 //Fear_Timer
370 if (Fear_Timer <= diff)
371 {
373 Fear_Timer = 20000;
374 }
375 else
376 Fear_Timer -= diff;
377 //VoidBolt_Timer
378 if (VoidBolt_Timer <= diff)
379 {
381 VoidBolt_Timer = 10000;
382 }
383 else
384 VoidBolt_Timer -= diff;
385 }
386 //When Solarian reaches 20% she will transform into a huge void walker.
387 if (Phase != 4 && me->HealthBelowPct(20))
388 {
389 Phase = 4;
390 //To make sure she wont be invisible or not selecatble
392 me->SetVisible(true);
395 me->SetArmor(WV_ARMOR);
396 me->SetDisplayId(MODEL_VOIDWALKER);
397 me->SetObjectScale(defaultsize*2.5f);
398 }
400 }
401 };
402
404 {
405 return new boss_high_astromancer_solarianAI(creature);
406 }
407};
408
410{
411 public:
412 npc_solarium_priest() : CreatureScript("npc_solarium_priest") { }
413
415 {
417 {
418 instance = creature->GetInstanceScript();
419 }
420
422
426
428 {
429 healTimer = 9000;
430 holysmiteTimer = 1;
431 aoesilenceTimer = 15000;
432 }
433
434 void EnterCombat(Unit* /*who*/) OVERRIDE
435 {
436 }
437
439 {
440 if (!UpdateVictim())
441 return;
442
443 if (healTimer <= diff)
444 {
445 Unit* target = NULL;
446 switch (std::rand() % 1)
447 {
448 case 0:
449 if (instance)
450 target = Unit::GetUnit(*me, instance->GetData64(DATA_ASTROMANCER));
451 break;
452 case 1:
453 target = me;
454 break;
455 }
456
457 if (target)
458 {
460 healTimer = 9000;
461 }
462 }
463 else
464 healTimer -= diff;
465
466 if (holysmiteTimer <= diff)
467 {
469 holysmiteTimer = 4000;
470 }
471 else
472 holysmiteTimer -= diff;
473
474 if (aoesilenceTimer <= diff)
475 {
477 aoesilenceTimer = 13000;
478 }
479 else
480 aoesilenceTimer -= diff;
481
483 }
484 };
485
487 {
488 return new npc_solarium_priestAI(creature);
489 }
490};
491
493{
494 public:
495 spell_astromancer_wrath_of_the_astromancer() : SpellScriptLoader("spell_astromancer_wrath_of_the_astromancer") { }
496
498 {
500
501 bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
502 {
504 return false;
505 return true;
506 }
507
508 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
509 {
510 // Final heal only on duration end
511 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
512 return;
513
514 Unit* target = GetUnitOwner();
515 target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_1].CalcValue(), false);
516 }
517
522 };
523
528};
529
536
const T & RAND(const T &v1, const T &v2)
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ IN_PROGRESS
@ DONE
@ NOT_STARTED
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
@ EFFECT_1
@ EFFECT_0
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
#define sSpellMgr
Definition SpellMgr.h:744
#define AuraEffectRemoveFn(F, I, N, M)
@ AURA_REMOVE_BY_EXPIRE
Definition Unit.h:410
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
Creatures
const float SMALL_PORTAL_RADIUS
@ NPC_ASTROMANCER_SOLARIAN_SPOTLIGHT
@ NPC_SOLARIUM_AGENT
@ NPC_SOLARIUM_PRIEST
const float CENTER_Z
@ WV_ARMOR
@ SAY_DEATH
@ SAY_VOIDA
@ SAY_SUMMON2
@ SAY_AGGRO
@ SAY_KILL
@ SAY_SUMMON1
@ SAY_VOIDB
const float PORTAL_Z
void AddSC_boss_high_astromancer_solarian()
@ SPELL_BLINDING_LIGHT
@ SPELL_WRATH_OF_THE_ASTROMANCER_DOT
@ SPELL_FEAR
@ SPELL_VOID_BOLT
@ SPELL_SPOTLIGHT
@ SPELL_SOLARIUM_GREAT_HEAL
@ SPELL_SOLARIUM_HOLY_SMITE
@ SPELL_SOLARIUM_ARCANE_TORRENT
@ SPELL_WRATH_OF_THE_ASTROMANCER
@ SPELL_ARCANE_MISSILES
const float CENTER_Y
const float CENTER_O
const float CENTER_X
@ MODEL_HUMAN
@ MODEL_VOIDWALKER
const float LARGE_PORTAL_RADIUS
#define SAY_DEATH
#define SAY_AGGRO
#define SAY_KILL
@ SPELL_VOID_BOLT
#define CENTER_Z
#define CENTER_Y
#define CENTER_X
@ SPELL_ARCANE_MISSILES
@ SPELL_FEAR
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
SpellInfo const * GetSpellInfo() const
Unit * GetUnitOwner() const
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
float GetObjectScale() const
Definition Object.h:128
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
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:16
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)
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
uint32 GetArmor() const
Definition Unit.h:1581
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
AuraScript * GetAuraScript() const OVERRIDE
@ SPELL_SPOTLIGHT
Definition karazhan.cpp:29
Creature * me
ScriptedAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SummonMinion(uint32 entry, float x, float y, float z)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
@ DATA_HIGHASTROMANCERSOLARIANEVENT
Definition the_eye.h:14
@ DATA_ASTROMANCER
Definition the_eye.h:12