TrinityCore
boss_astromancer.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/* ScriptData
19SDName: Boss_Astromancer
20SD%Complete: 80
21SDComment:
22SDCategory: Tempest Keep, The Eye
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "InstanceScript.h"
27#include "MotionMaster.h"
28#include "ObjectAccessor.h"
29#include "ScriptedCreature.h"
30#include "SpellAuras.h"
31#include "SpellScript.h"
32#include "TemporarySummon.h"
33#include "the_eye.h"
34
36{
43 SAY_VOIDB = 6
44};
45
47{
52 SPELL_FEAR = 34322,
54
56
60};
61
63{
65
68};
69
71{
72 MODEL_HUMAN = 18239,
73 MODEL_VOIDWALKER = 18988
74};
75
76enum Misc
77{
78 WV_ARMOR = 31000
79};
80
81const float CENTER_X = 432.909f;
82const float CENTER_Y = -373.424f;
83const float CENTER_Z = 17.9608f;
84const float CENTER_O = 1.06421f;
85const float SMALL_PORTAL_RADIUS = 12.6f;
86const float LARGE_PORTAL_RADIUS = 26.0f;
87const float PORTAL_Z = 17.005f;
88
89/* not used // x, y, z, o
90static float SolarianPos[4] = {432.909f, -373.424f, 17.9608f, 1.06421f};
91*/
92
94{
96 {
97 Initialize();
98
99 defaultarmor = creature->GetArmor();
100 memset(Portals, 0, sizeof(Portals));
101 }
102
104 {
107 BlindingLight_Timer = 41000;
108 Fear_Timer = 20000;
109 VoidBolt_Timer = 10000;
110 Phase1_Timer = 50000;
111 Phase2_Timer = 10s;
112 Phase3_Timer = 15s;
114 BlindingLight = false;
115 AppearDelay = false;
116 Wrath_Timer = 20000 + rand32() % 5000;//twice in phase one
117 Phase = 1;
118 }
119
121
133
134 float Portals[3][3];
135
138
139 void Reset() override
140 {
141 Initialize();
142 _Reset();
144 me->SetUninteractible(false);
145 me->SetVisible(true);
147
148 }
149
150 void KilledUnit(Unit* /*victim*/) override
151 {
152 Talk(SAY_KILL);
153 }
154
155 void JustDied(Unit* /*killer*/) override
156 {
159 _JustDied();
160 }
161
162 void JustEngagedWith(Unit* who) override
163 {
166 me->CallForHelp(120.0f);
167 }
168
169 void SummonMinion(uint32 entry, float x, float y, float z)
170 {
171 Creature* Summoned = me->SummonCreature(entry, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
172 if (Summoned)
173 {
175 Summoned->AI()->AttackStart(target);
176
177 summons.Summon(Summoned);
178 }
179 }
180
181 float Portal_X(float radius)
182 {
183 if (urand(0, 1))
184 radius = -radius;
185
186 return radius * (float)(rand32() % 100) / 100.0f + CENTER_X;
187 }
188
189 float Portal_Y(float x, float radius)
190 {
191 float z = RAND(1.0f, -1.0f);
192
193 return (z*std::sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y);
194 }
195
196 void UpdateAI(uint32 diff) override
197 {
198 if (!UpdateVictim())
199 return;
200 if (AppearDelay)
201 {
202 me->StopMoving();
203 me->AttackStop();
204 if (AppearDelay_Timer <= Milliseconds(diff))
205 {
206 AppearDelay = false;
207 if (Phase == 2)
208 {
209 me->SetUninteractible(true);
210 me->SetVisible(false);
211 }
213 }
214 else
216 }
217 if (Phase == 1)
218 {
219 if (BlindingLight_Timer <= diff)
220 {
221 BlindingLight = true;
222 BlindingLight_Timer = 45000;
223 }
224 else
225 BlindingLight_Timer -= diff;
226
227 if (Wrath_Timer <= diff)
228 {
230 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true))
232 Wrath_Timer = 20000 + rand32() % 5000;
233 }
234 else
235 Wrath_Timer -= diff;
236
237 if (ArcaneMissiles_Timer <= diff)
238 {
239 if (BlindingLight)
240 {
242 BlindingLight = false;
243 }
244 else
245 {
247 {
248 if (!me->HasInArc(2.5f, target))
249 target = me->GetVictim();
250
252 }
253 }
255 }
256 else
257 ArcaneMissiles_Timer -= diff;
258
260 {
262 //Target the tank ?
264 {
265 if (target->GetTypeId() == TYPEID_PLAYER)
266 {
269 }
270 else
272 }
273 }
274 else
276
277 //Phase1_Timer
278 if (Phase1_Timer <= diff)
279 {
280 Phase = 2;
281 Phase1_Timer = 50000;
282 //After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
285 for (uint8 i = 0; i <= 2; ++i)
286 {
287 if (!i)
288 {
291 Portals[i][2] = CENTER_Z;
292 }
293 else
294 {
297 Portals[i][2] = PORTAL_Z;
298 }
299 }
300 if ((std::abs(Portals[2][0] - Portals[1][0]) < 7) && (std::abs(Portals[2][1] - Portals[1][1]) < 7))
301 {
302 int i = 1;
303 if (std::abs(CENTER_X + 26.0f - Portals[2][0]) < 7)
304 i = -1;
305 Portals[2][0] = Portals[2][0] + 7 * i;
307 }
308 for (int i = 0; i <= 2; ++i)
309 {
311 {
312 Summoned->SetUninteractible(true);
313 Summoned->CastSpell(Summoned, SPELL_SPOTLIGHT, false);
314 }
315 }
316 AppearDelay = true;
317 }
318 else
319 Phase1_Timer -= diff;
320 }
321 else if (Phase == 2)
322 {
323 //10 seconds after Solarian disappears, 12 mobs spawn out of the three portals.
324 me->AttackStop();
325 me->StopMoving();
326 if (Phase2_Timer <= Milliseconds(diff))
327 {
328 Phase = 3;
329 for (int i=0; i <= 2; ++i)
330 for (int j=1; j <= 4; j++)
332
334 Phase2_Timer = 10s;
335 }
336 else
337 Phase2_Timer -= Milliseconds(diff);
338 }
339 else if (Phase == 3)
340 {
341 me->AttackStop();
342 me->StopMoving();
343 //Check Phase3_Timer
344 if (Phase3_Timer <= Milliseconds(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 = rand32() % 3;
350 me->UpdatePosition(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
356 me->SetUninteractible(false);
357 me->SetVisible(true);
358
360 AppearDelay = true;
361 Phase3_Timer = 15s;
362 }
363 else
364 Phase3_Timer -= Milliseconds(diff);
365 }
366 else if (Phase == 4)
367 {
368 //Fear_Timer
369 if (Fear_Timer <= diff)
370 {
372 Fear_Timer = 20000;
373 }
374 else
375 Fear_Timer -= diff;
376 //VoidBolt_Timer
377 if (VoidBolt_Timer <= diff)
378 {
380 VoidBolt_Timer = 10000;
381 }
382 else
383 VoidBolt_Timer -= diff;
384 }
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
391 me->SetUninteractible(false);
392 me->SetVisible(true);
395 me->SetArmor(WV_ARMOR, 0);
397 }
398 }
399};
400
402{
404 {
405 Initialize();
406 instance = creature->GetInstanceScript();
407 }
408
410 {
411 healTimer = 9000;
412 holysmiteTimer = 1;
413 aoesilenceTimer = 15000;
414 }
415
417
421
422 void Reset() override
423 {
424 Initialize();
425 }
426
427 void JustEngagedWith(Unit* /*who*/) override { }
428
429 void UpdateAI(uint32 diff) override
430 {
431 if (!UpdateVictim())
432 return;
433
434 if (healTimer <= diff)
435 {
436 Unit* target = nullptr;
437 switch (urand(0, 1))
438 {
439 case 0:
441 break;
442 case 1:
443 target = me;
444 break;
445 }
446
447 if (target)
448 {
450 healTimer = 9000;
451 }
452 }
453 else
454 healTimer -= diff;
455
456 if (holysmiteTimer <= diff)
457 {
459 holysmiteTimer = 4000;
460 }
461 else
462 holysmiteTimer -= diff;
463
464 if (aoesilenceTimer <= diff)
465 {
467 aoesilenceTimer = 13000;
468 }
469 else
470 aoesilenceTimer -= diff;
471 }
472};
473
474// 42783 - Wrath of the Astromancer
476{
477 bool Validate(SpellInfo const* spellInfo) override
478 {
480 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
481 }
482
483 void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
484 {
485 // Final heal only on duration end
486 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
487 return;
488
489 Unit* target = GetUnitOwner();
490 target->CastSpell(target, GetEffectInfo(EFFECT_1).CalcValue(), false);
491 }
492
493 void Register() override
494 {
496 }
497};
498
500{
504}
First const & RAND(First const &first, Second const &second, Rest const &... rest)
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition: ObjectDefines.h:66
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
Spells
Definition: PlayerAI.cpp:32
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_EXPIRE
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
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
Yells
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
SpellEffectInfo const & GetEffectInfo(SpellEffIndex effIndex) const
Unit * GetUnitOwner() const
void JustEngagedWith(Unit *who) override
SummonList summons
void _JustDied()
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void AttackStart(Unit *victim) override
== Triggered Actions Requested ==================
Definition: CreatureAI.cpp:328
Creature *const me
Definition: CreatureAI.h:61
void CallForHelp(float fRadius)
Definition: Creature.cpp:2563
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
CreatureAI * AI() const
Definition: Creature.h:214
virtual ObjectGuid GetGuidData(uint32 type) const override
uint32 const Id
Definition: SpellInfo.h:325
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
void Summon(Creature const *summon)
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void SetVisible(bool x)
Definition: Unit.cpp:8351
void SetArmor(int32 val, int32 bonusVal)
Definition: Unit.h:763
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void StopMoving()
Definition: Unit.cpp:10049
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition: Unit.cpp:12392
bool HealthBelowPct(int32 pct) const
Definition: Unit.h:780
uint32 GetArmor() const
Definition: Unit.h:762
Unit * GetVictim() const
Definition: Unit.h:715
bool AttackStop()
Definition: Unit.cpp:5781
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
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:2025
bool Validate(SpellInfo const *spellInfo) override
void AfterRemove(AuraEffect const *, AuraEffectHandleModes)
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
bool HasInArc(float arcangle, Position const *pos, float border=2.0f) const
Definition: Position.cpp:99
void UpdateAI(uint32 diff) override
void KilledUnit(Unit *) override
float Portal_Y(float x, float radius)
void SummonMinion(uint32 entry, float x, float y, float z)
boss_high_astromancer_solarian(Creature *creature)
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
npc_solarium_priest(Creature *creature)
void JustEngagedWith(Unit *) override
InstanceScript * instance
#define RegisterTheEyeCreatureAI(ai_name)
Definition: the_eye.h:74
@ DATA_SOLARIAN
Definition: the_eye.h:33