Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_eredar_twins.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_Eredar_Twins
8SD%Complete: 100
9SDComment:
10EndScriptData */
11
12#include "ScriptMgr.h"
13#include "ScriptedCreature.h"
14#include "sunwell_plateau.h"
15#include "SpellInfo.h"
16
41
43{
44 //Lady Sacrolash spells
46 SPELL_SHADOW_BLADES = 45248, //10 secs
48 SPELL_SHADOW_NOVA = 45329, //30-35 secs
49 SPELL_CONFOUNDING_BLOW = 45256, //25 secs
50
51 //Shadow Image spells
54
55 //Misc spells
56 SPELL_ENRAGE = 46587,
59
60 //Grand Warlock Alythess spells
61 SPELL_PYROGENICS = 45230, //15secs
63 SPELL_CONFLAGRATION = 45342, //30-35 secs
64 SPELL_BLAZE = 45235, //on main target every 3 secs
66 SPELL_BLAZE_SUMMON = 45236, //187366 GO
68};
69
71{
72public:
73 boss_sacrolash() : CreatureScript("boss_sacrolash") { }
74
76 {
77 return new boss_sacrolashAI(creature);
78 };
79
81 {
82 boss_sacrolashAI(Creature* creature) : ScriptedAI(creature)
83 {
84 instance = creature->GetInstanceScript();
85 }
86
88
90 bool Enraged;
91
98
100 {
101 Enraged = false;
102
103 if (instance)
104 {
105 if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ALYTHESS)))
106 {
107 if (temp->isDead())
108 temp->Respawn();
109 else if (temp->GetVictim())
110 me->getThreatManager().addThreat(temp->GetVictim(), 0.0f);
111 }
112 }
113
114 if (!me->IsInCombat())
115 {
116 ShadowbladesTimer = 10000;
117 ShadownovaTimer = 30000;
118 ConfoundingblowTimer = 25000;
119 ShadowimageTimer = 20000;
120 ConflagrationTimer = 30000;
121 EnrageTimer = 360000;
122
123 SisterDeath = false;
124 }
125
126 if (instance)
128 }
129
131 {
133
134 if (instance)
135 {
136 Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_ALYTHESS));
137 if (temp && temp->IsAlive() && !temp->GetVictim())
138 temp->AI()->AttackStart(who);
139 }
140
141 if (instance)
143 }
144
145 void KilledUnit(Unit* /*victim*/) OVERRIDE
146 {
147 if (rand()%4 == 0)
149 }
150
151 void JustDied(Unit* /*killer*/) OVERRIDE
152 {
153 // only if ALY death
154 if (SisterDeath)
155 {
157
158 if (instance)
160 }
161 else
163 }
164
165 void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE
166 {
167 switch (spell->Id)
168 {
174 break;
177 break;
178 }
179 }
180
181 void HandleTouchedSpells(Unit* target, uint32 TouchedType)
182 {
183 switch (TouchedType)
184 {
186 if (!target->HasAura(SPELL_DARK_FLAME))
187 {
188 if (target->HasAura(SPELL_DARK_TOUCHED))
189 {
191 target->CastSpell(target, SPELL_DARK_FLAME, true);
192 } else target->CastSpell(target, SPELL_FLAME_TOUCHED, true);
193 }
194 break;
196 if (!target->HasAura(SPELL_DARK_FLAME))
197 {
198 if (target->HasAura(SPELL_FLAME_TOUCHED))
199 {
201 target->CastSpell(target, SPELL_DARK_FLAME, true);
202 } else target->CastSpell(target, SPELL_DARK_TOUCHED, true);
203 }
204 break;
205 }
206 }
207
209 {
210 if (!SisterDeath)
211 {
212 if (instance)
213 {
214 Unit* Temp = NULL;
215 Temp = Unit::GetUnit(*me, instance->GetData64(DATA_ALYTHESS));
216 if (Temp && Temp->isDead())
217 {
220 me->InterruptSpell(CURRENT_GENERIC_SPELL);
221 SisterDeath = true;
222 }
223 }
224 }
225
226 if (!UpdateVictim())
227 return;
228
229 if (SisterDeath)
230 {
231 if (ConflagrationTimer <= diff)
232 {
233 if (!me->IsNonMeleeSpellCasted(false))
234 {
235 me->InterruptSpell(CURRENT_GENERIC_SPELL);
236 Unit* target = NULL;
238 if (target)
240 ConflagrationTimer = 30000+(rand()%5000);
241 }
242 } else ConflagrationTimer -= diff;
243 }
244 else
245 {
246 if (ShadownovaTimer <= diff)
247 {
248 if (!me->IsNonMeleeSpellCasted(false))
249 {
250 Unit* target = NULL;
252 if (target)
253 DoCast(target, SPELL_SHADOW_NOVA);
254
255 if (!SisterDeath)
256 {
257 if (target)
258 Talk(EMOTE_SHADOW_NOVA, target);
260 }
261 ShadownovaTimer = 30000+(rand()%5000);
262 }
263 } else ShadownovaTimer -=diff;
264 }
265
266 if (ConfoundingblowTimer <= diff)
267 {
268 if (!me->IsNonMeleeSpellCasted(false))
269 {
270 Unit* target = NULL;
272 if (target)
274 ConfoundingblowTimer = 20000 + (rand()%5000);
275 }
276 } else ConfoundingblowTimer -=diff;
277
278 if (ShadowimageTimer <= diff)
279 {
280 Unit* target = NULL;
281 Creature* temp = NULL;
282 for (uint8 i = 0; i<3; ++i)
283 {
286 if (temp && target)
287 {
288 temp->AddThreat(target, 1000000);//don't change target(healers)
289 temp->AI()->AttackStart(target);
290 }
291 }
292 ShadowimageTimer = 20000;
293 } else ShadowimageTimer -=diff;
294
295 if (ShadowbladesTimer <= diff)
296 {
297 if (!me->IsNonMeleeSpellCasted(false))
298 {
300 ShadowbladesTimer = 10000;
301 }
302 } else ShadowbladesTimer -=diff;
303
304 if (EnrageTimer < diff && !Enraged)
305 {
306 me->InterruptSpell(CURRENT_GENERIC_SPELL);
309 Enraged = true;
310 } else EnrageTimer -= diff;
311
312 if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false))
313 {
314 //If we are within range melee the target
315 if (me->IsWithinMeleeRange(me->GetVictim()))
316 {
318 me->AttackerStateUpdate(me->GetVictim());
319 me->resetAttackTimer();
320 }
321 }
322 }
323 };
324};
325
327{
328public:
329 boss_alythess() : CreatureScript("boss_alythess") { }
330
332 {
333 return new boss_alythessAI(creature);
334 };
335
337 {
338 boss_alythessAI(Creature* creature) : ScriptedAI(creature)
339 {
340 SetCombatMovement(false);
341
342 instance = creature->GetInstanceScript();
343 IntroStepCounter = 10;
344 }
345
347
350
353
360
362 {
363 Enraged = false;
364
365 if (instance)
366 {
367 if (Creature* temp = Unit::GetCreature((*me), instance->GetData64(DATA_SACROLASH)))
368 {
369 if (temp->isDead())
370 temp->Respawn();
371 else if (temp->GetVictim())
372 me->getThreatManager().addThreat(temp->GetVictim(), 0.0f);
373 }
374 }
375
376 if (!me->IsInCombat())
377 {
378 ConflagrationTimer = 45000;
379 BlazeTimer = 100;
380 PyrogenicsTimer = 15000;
381 ShadownovaTimer = 40000;
382 EnrageTimer = 360000;
383 FlamesearTimer = 15000;
384 IntroYellTimer = 10000;
385
386 SisterDeath = false;
387 }
388
389 if (instance)
391 }
392
394 {
396
397 if (instance)
398 {
399 Creature* temp = Unit::GetCreature(*me, instance->GetData64(DATA_SACROLASH));
400 if (temp && temp->IsAlive() && !temp->GetVictim())
401 temp->AI()->AttackStart(who);
402 }
403
404 if (instance)
406 }
407
409 {
410 if (!me->IsInCombat())
412 }
413
415
416 {
417 if (!who || me->GetVictim())
418 return;
419
420 if (me->CanCreatureAttack(who))
421 {
422 float attackRadius = me->GetAttackDistance(who);
423 if (me->IsWithinDistInMap(who, attackRadius) && me->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && me->IsWithinLOSInMap(who))
424 {
425 if (!me->IsInCombat())
426 {
428 }
429 }
430 }
431 else if (IntroStepCounter == 10 && me->IsWithinLOSInMap(who)&& me->IsWithinDistInMap(who, 30))
432 {
434 }
435 }
436
437 void KilledUnit(Unit* /*victim*/) OVERRIDE
438 {
439 if (rand()%4 == 0)
440 {
442 }
443 }
444
445 void JustDied(Unit* /*killer*/) OVERRIDE
446 {
447 if (SisterDeath)
448 {
450
451 if (instance)
453 }
454 else
456 }
457
458 void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE
459 {
460 switch (spell->Id)
461 {
462 case SPELL_BLAZE:
463 target->CastSpell(target, SPELL_BLAZE_SUMMON, true);
464 break;
466 case SPELL_FLAME_SEAR:
468 break;
471 break;
472 }
473 }
474
475 void HandleTouchedSpells(Unit* target, uint32 TouchedType)
476 {
477 switch (TouchedType)
478 {
480 if (!target->HasAura(SPELL_DARK_FLAME))
481 {
482 if (target->HasAura(SPELL_DARK_TOUCHED))
483 {
485 target->CastSpell(target, SPELL_DARK_FLAME, true);
486 }else
487 {
488 target->CastSpell(target, SPELL_FLAME_TOUCHED, true);
489 }
490 }
491 break;
493 if (!target->HasAura(SPELL_DARK_FLAME))
494 {
495 if (target->HasAura(SPELL_FLAME_TOUCHED))
496 {
498 target->CastSpell(target, SPELL_DARK_FLAME, true);
499 } else target->CastSpell(target, SPELL_DARK_TOUCHED, true);
500 }
501 break;
502 }
503 }
504
506 {
507 Creature* Sacrolash = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_SACROLASH) : 0);
508 switch (step)
509 {
510 case 0: return 0;
511 case 1:
512 if (Sacrolash)
513 Sacrolash->AI()->Talk(YELL_INTRO_SAC_1);
514 return 1000;
515 case 2: Talk(YELL_INTRO_ALY_2); return 1000;
516 case 3:
517 if (Sacrolash)
518 Sacrolash->AI()->Talk(YELL_INTRO_SAC_3);
519 return 2000;
520 case 4: Talk(YELL_INTRO_ALY_4); return 1000;
521 case 5:
522 if (Sacrolash)
523 Sacrolash->AI()->Talk(YELL_INTRO_SAC_5);
524 return 2000;
525 case 6: Talk(YELL_INTRO_ALY_6); return 1000;
526 case 7:
527 if (Sacrolash)
528 Sacrolash->AI()->Talk(YELL_INTRO_SAC_7);
529 return 3000;
530 case 8: Talk(YELL_INTRO_ALY_8); return 900000;
531 }
532 return 10000;
533 }
534
536 {
537 if (IntroStepCounter < 9)
538 {
539 if (IntroYellTimer <= diff)
540 {
542 } else IntroYellTimer -= diff;
543 }
544
545 if (!SisterDeath)
546 {
547 if (instance)
548 {
549 Unit* Temp = NULL;
550 Temp = Unit::GetUnit(*me, instance->GetData64(DATA_SACROLASH));
551 if (Temp && Temp->isDead())
552 {
555 me->InterruptSpell(CURRENT_GENERIC_SPELL);
556 SisterDeath = true;
557 }
558 }
559 }
560 if (!me->GetVictim())
561 {
562 if (instance)
563 {
564 Creature* sisiter = Unit::GetCreature((*me), instance->GetData64(DATA_SACROLASH));
565 if (sisiter && !sisiter->isDead() && sisiter->GetVictim())
566 {
567 me->AddThreat(sisiter->GetVictim(), 0.0f);
568 DoStartNoMovement(sisiter->GetVictim());
569 me->Attack(sisiter->GetVictim(), false);
570 }
571 }
572 }
573
574 if (!UpdateVictim())
575 return;
576
577 if (SisterDeath)
578 {
579 if (ShadownovaTimer <= diff)
580 {
581 if (!me->IsNonMeleeSpellCasted(false))
582 {
583 Unit* target = NULL;
585 if (target)
586 DoCast(target, SPELL_SHADOW_NOVA);
587 ShadownovaTimer= 30000+(rand()%5000);
588 }
589 } else ShadownovaTimer -=diff;
590 }
591 else
592 {
593 if (ConflagrationTimer <= diff)
594 {
595 if (!me->IsNonMeleeSpellCasted(false))
596 {
597 me->InterruptSpell(CURRENT_GENERIC_SPELL);
598 Unit* target = NULL;
600 if (target)
602 ConflagrationTimer = 30000+(rand()%5000);
603
604 if (!SisterDeath)
605 {
606 if (target)
607 Talk(EMOTE_CONFLAGRATION, target);
609 }
610
611 BlazeTimer = 4000;
612 }
613 } else ConflagrationTimer -= diff;
614 }
615
616 if (FlamesearTimer <= diff)
617 {
618 if (!me->IsNonMeleeSpellCasted(false))
619 {
621 FlamesearTimer = 15000;
622 }
623 } else FlamesearTimer -=diff;
624
625 if (PyrogenicsTimer <= diff)
626 {
627 if (!me->IsNonMeleeSpellCasted(false))
628 {
629 DoCast(me, SPELL_PYROGENICS, true);
630 PyrogenicsTimer = 15000;
631 }
632 } else PyrogenicsTimer -= diff;
633
634 if (BlazeTimer <= diff)
635 {
636 if (!me->IsNonMeleeSpellCasted(false))
637 {
639 BlazeTimer = 3800;
640 }
641 } else BlazeTimer -= diff;
642
643 if (EnrageTimer < diff && !Enraged)
644 {
645 me->InterruptSpell(CURRENT_GENERIC_SPELL);
648 Enraged = true;
649 } else EnrageTimer -= diff;
650 }
651 };
652};
653
655{
656public:
657 npc_shadow_image() : CreatureScript("npc_shadow_image") { }
658
660 {
661 return new npc_shadow_imageAI(creature);
662 };
663
665 {
666 npc_shadow_imageAI(Creature* creature) : ScriptedAI(creature) { }
667
671
673 {
675 ShadowfuryTimer = 5000 + (rand()%15000);
676 DarkstrikeTimer = 3000;
677 KillTimer = 15000;
678 }
679
680 void EnterCombat(Unit* /*who*/)OVERRIDE { }
681
682 void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE
683 {
684 switch (spell->Id)
685 {
688 if (!target->HasAura(SPELL_DARK_FLAME))
689 {
690 if (target->HasAura(SPELL_FLAME_TOUCHED))
691 {
692 target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
693 target->CastSpell(target, SPELL_DARK_FLAME, true);
694 } else target->CastSpell(target, SPELL_DARK_TOUCHED, true);
695 }
696 break;
697 }
698 }
699
701 {
702 if (!me->HasAura(SPELL_IMAGE_VISUAL))
704
705 if (KillTimer <= diff)
706 {
707 me->Kill(me);
708 KillTimer = 9999999;
709 } else KillTimer -= diff;
710
711 if (!UpdateVictim())
712 return;
713
714 if (ShadowfuryTimer <= diff)
715 {
717 ShadowfuryTimer = 10000;
718 } else ShadowfuryTimer -=diff;
719
720 if (DarkstrikeTimer <= diff)
721 {
722 if (!me->IsNonMeleeSpellCasted(false))
723 {
724 //If we are within range melee the target
725 if (me->IsWithinMeleeRange(me->GetVictim()))
727 }
728 DarkstrikeTimer = 3000;
729 } else DarkstrikeTimer -= diff;
730 }
731 };
732};
733
735{
736 new boss_sacrolash();
737 new boss_alythess();
738 new npc_shadow_image();
739}
#define CREATURE_Z_ATTACK_RANGE
Definition Creature.h:422
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
@ TEMPSUMMON_CORPSE_DESPAWN
Definition Object.h:72
@ UNIT_DYNFLAG_LOOTABLE
@ CURRENT_GENERIC_SPELL
Definition Unit.h:1109
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ OBJECT_FIELD_DYNAMIC_FLAGS
@ SPELL_ENRAGE
@ YELL_BERSERK
@ YELL_SHADOW_NOVA
@ YELL_INTRO_ALY_2
@ YELL_SAC_KILL
@ YELL_INTRO_ALY_6
@ YELL_ENRAGE
@ EMOTE_CONFLAGRATION
@ YELL_ALY_KILL
@ YELL_INTRO_SAC_1
@ YELL_SAC_DEAD
@ YELL_INTRO_SAC_5
@ YELL_INTRO_ALY_8
@ YELL_BERSERK
@ YELL_ALY_DEAD
@ YELL_SISTER_SACROLASH_DEAD
@ YELL_CANFLAGRATION
@ YELL_SISTER_ALYTHESS_DEAD
@ YELL_INTRO_SAC_3
@ EMOTE_SHADOW_NOVA
@ YELL_INTRO_ALY_4
@ YELL_INTRO_SAC_7
void AddSC_boss_eredar_twins()
@ SPELL_EMPOWER
@ SPELL_CONFOUNDING_BLOW
@ SPELL_FLAME_TOUCHED
@ SPELL_SHADOW_BLADES
@ SPELL_ENRAGE
@ SPELL_BLAZE_BURN
@ SPELL_CONFLAGRATION
@ SPELL_PYROGENICS
@ SPELL_BLAZE_SUMMON
@ SPELL_SHADOW_FURY
@ SPELL_IMAGE_VISUAL
@ SPELL_SHADOW_NOVA
@ SPELL_DARK_FLAME
@ SPELL_BLAZE
@ SPELL_DARK_STRIKE
@ SPELL_DARK_TOUCHED
@ SPELL_FLAME_SEAR
@ SPELL_CONFLAGRATION
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)
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)
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=NULL)
Definition Unit.cpp:4463
bool IsAlive() const
Definition Unit.h:2032
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
Unit * GetVictim() const
Definition Unit.h:1468
bool isDead() const
Definition Unit.h:2040
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
void DoStartNoMovement(Unit *target)
void SetCombatMovement(bool allowMovement)
Creature * me
Creature * DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, TempSummonType type, uint32 despawntime)
ScriptedAI(Creature *creature)
void AttackStart(Unit *) OVERRIDE
void SpellHitTarget(Unit *target, const SpellInfo *spell) OVERRIDE
void HandleTouchedSpells(Unit *target, uint32 TouchedType)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void AttackStart(Unit *who) OVERRIDE
void MoveInLineOfSight(Unit *who) OVERRIDE
void EnterCombat(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void HandleTouchedSpells(Unit *target, uint32 TouchedType)
void SpellHitTarget(Unit *target, const SpellInfo *spell) OVERRIDE
void EnterCombat(Unit *who) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SpellHitTarget(Unit *target, const SpellInfo *spell) OVERRIDE
@ NPC_SHADOW_IMAGE
@ DATA_ALYTHESS
@ DATA_SACROLASH
@ DATA_EREDAR_TWINS_EVENT