Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_fathomlord_karathress.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_Fathomlord_Karathress
8SD%Complete: 70
9SDComment: Cyclone workaround
10SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "serpent_shrine.h"
16#include "ScriptedEscortAI.h"
17
74
75//entry and position for Seer Olum
76#define SEER_OLUM 22820
77#define OLUM_X 446.78f
78#define OLUM_Y -542.76f
79#define OLUM_Z -7.54773f
80#define OLUM_O 0.401581f
81
82#define SAY_GAIN_BLESSING_OF_TIDES "Your overconfidence will be your undoing! Guards, lend me your strength!"
83#define SAY_MISC "Alana be'lendor!" //don't know what use this
84
85#define MAX_ADVISORS 3
86//Fathom-Lord Karathress AI
88{
89public:
90 boss_fathomlord_karathress() : CreatureScript("boss_fathomlord_karathress") { }
91
93 {
94 return new boss_fathomlord_karathressAI(creature);
95 }
96
98 {
100 {
101 instance = creature->GetInstanceScript();
102 Advisors[0] = 0;
103 Advisors[1] = 0;
104 Advisors[2] = 0;
105 }
106
108
112
114
116
118 {
119 CataclysmicBolt_Timer = 10000;
120 Enrage_Timer = 600000; //10 minutes
121 SearNova_Timer = 20000+rand()%40000; // 20 - 60 seconds
122
123 BlessingOfTides = false;
124
125 if (instance)
126 {
127 uint64 RAdvisors[MAX_ADVISORS];
128 RAdvisors[0] = instance->GetData64(DATA_SHARKKIS);
129 RAdvisors[1] = instance->GetData64(DATA_TIDALVESS);
130 RAdvisors[2] = instance->GetData64(DATA_CARIBDIS);
131 //Respawn of the 3 Advisors
132 Creature* pAdvisor = NULL;
133 for (int i=0; i<MAX_ADVISORS; ++i)
134 if (RAdvisors[i])
135 {
136 pAdvisor = (Unit::GetCreature((*me), RAdvisors[i]));
137 if (pAdvisor && !pAdvisor->IsAlive())
138 {
139 pAdvisor->Respawn();
140 pAdvisor->AI()->EnterEvadeMode();
141 pAdvisor->GetMotionMaster()->MoveTargetedHome();
142 }
143 }
145 }
146 }
147
153
159
165
167 {
168 if (!instance)
169 return;
170
171 Advisors[0] = instance->GetData64(DATA_SHARKKIS);
172 Advisors[1] = instance->GetData64(DATA_TIDALVESS);
173 Advisors[2] = instance->GetData64(DATA_CARIBDIS);
174 }
175
176 void StartEvent(Unit* who)
177 {
178 if (!instance)
179 return;
180
181 GetAdvisors();
182
185
188 }
189
190 void KilledUnit(Unit* /*victim*/) OVERRIDE
191 {
192 Talk(SAY_SLAY);
193 }
194
195 void JustDied(Unit* /*killer*/) OVERRIDE
196 {
198
199 if (instance)
201
202 //support for quest 10944
204 }
205
207 {
208 StartEvent(who);
209 }
210
212 {
213 //Only if not incombat check if the event is started
214 if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
215 {
216 if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
217 {
218 AttackStart(target);
219 GetAdvisors();
220 }
221 }
222
223 //Return since we have no target
224 if (!UpdateVictim())
225 return;
226
227 //someone evaded!
228 if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
229 {
231 return;
232 }
233
234 //CataclysmicBolt_Timer
235 if (CataclysmicBolt_Timer <= diff)
236 {
237 //select a random unit other than the main tank
239
240 //if there aren't other units, cast on the tank
241 if (!target)
242 target = me->GetVictim();
243
244 if (target)
246 CataclysmicBolt_Timer = 10000;
247 } else CataclysmicBolt_Timer -= diff;
248
249 //SearNova_Timer
250 if (SearNova_Timer <= diff)
251 {
253 SearNova_Timer = 20000+rand()%40000;
254 } else SearNova_Timer -= diff;
255
256 //Enrage_Timer
257 if (Enrage_Timer <= diff)
258 {
260 Enrage_Timer = 90000;
261 } else Enrage_Timer -= diff;
262
263 //Blessing of Tides Trigger
264 if (!HealthAbovePct(75) && !BlessingOfTides)
265 {
266 BlessingOfTides = true;
267 bool continueTriggering = false;
268 Creature* Advisor;
269 for (uint8 i = 0; i < MAX_ADVISORS; ++i)
270 if (Advisors[i])
271 {
272 Advisor = (Unit::GetCreature(*me, Advisors[i]));
273 if (Advisor && Advisor->IsAlive())
274 {
275 continueTriggering = true;
276 break;
277 }
278 }
279 if (continueTriggering)
280 {
284 }
285 }
286
288 }
289 };
290};
291
292//Fathom-Guard Sharkkis AI
294{
295public:
296 boss_fathomguard_sharkkis() : CreatureScript("boss_fathomguard_sharkkis") { }
297
299 {
300 return new boss_fathomguard_sharkkisAI(creature);
301 }
302
304 {
306 {
307 instance = creature->GetInstanceScript();
308 }
309
311
316
317 bool pet;
318
320
322 {
323 LeechingThrow_Timer = 20000;
324 TheBeastWithin_Timer = 30000;
325 Multishot_Timer = 15000;
326 Pet_Timer = 10000;
327
328 pet = false;
329
331 if (Pet && Pet->IsAlive())
332 {
334 }
335
336 SummonedPet = 0;
337
338 if (instance)
340 }
341
342 void JustDied(Unit* /*killer*/) OVERRIDE
343 {
344 if (instance)
345 {
346 if (Creature* Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))))
347 CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath();
348 }
349 }
350
352 {
353 if (instance)
354 {
355 instance->SetData64(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
357 }
358 }
359
361 {
362 //Only if not incombat check if the event is started
363 if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
364 {
365 if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
366 AttackStart(target);
367 }
368
369 //Return since we have no target
370 if (!UpdateVictim())
371 return;
372
373 //someone evaded!
374 if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
375 {
377 return;
378 }
379
380 //LeechingThrow_Timer
381 if (LeechingThrow_Timer <= diff)
382 {
384 LeechingThrow_Timer = 20000;
385 } else LeechingThrow_Timer -= diff;
386
387 //Multishot_Timer
388 if (Multishot_Timer <= diff)
389 {
391 Multishot_Timer = 20000;
392 } else Multishot_Timer -= diff;
393
394 //TheBeastWithin_Timer
395 if (TheBeastWithin_Timer <= diff)
396 {
399 if (Pet && Pet->IsAlive())
400 {
402 }
403 TheBeastWithin_Timer = 30000;
404 } else TheBeastWithin_Timer -= diff;
405
406 //Pet_Timer
407 if (Pet_Timer < diff && pet == false)
408 {
409 pet = true;
410 //uint32 spell_id;
411 uint32 pet_id;
412 if (!(std::rand() % 1))
413 {
414 //spell_id = SPELL_SUMMON_FATHOM_LURKER;
415 pet_id = CREATURE_FATHOM_LURKER;
416 }
417 else
418 {
419 //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT;
421 }
422 //DoCast(me, spell_id, true);
423 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
424 {
426 {
427 Pet->AI()->AttackStart(target);
429 }
430 }
431 } else Pet_Timer -= diff;
432
434 }
435 };
436};
437
438//Fathom-Guard Tidalvess AI
440{
441public:
442 boss_fathomguard_tidalvess() : CreatureScript("boss_fathomguard_tidalvess") { }
443
445 {
446 return new boss_fathomguard_tidalvessAI(creature);
447 }
448
450 {
452 {
453 instance = creature->GetInstanceScript();
454 }
455
457
462
464 {
465 FrostShock_Timer = 25000;
466 Spitfire_Timer = 60000;
467 PoisonCleansing_Timer = 30000;
468 Earthbind_Timer = 45000;
469
470 if (instance)
472 }
473
474 void JustDied(Unit* /*killer*/) OVERRIDE
475 {
476 if (instance)
477 {
478 if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS)))
479 CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath();
480 }
481 }
482
484 {
485 if (instance)
486 {
487 instance->SetData64(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
489 }
491 }
492
494 {
495 //Only if not incombat check if the event is started
496 if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
497 {
498 if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
499 AttackStart(target);
500 }
501
502 //Return since we have no target
503 if (!UpdateVictim())
504 return;
505
506 //someone evaded!
507 if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
508 {
510 return;
511 }
512
513 if (!me->HasAura(SPELL_WINDFURY_WEAPON))
514 {
516 }
517
518 //FrostShock_Timer
519 if (FrostShock_Timer <= diff)
520 {
522 FrostShock_Timer = 25000+rand()%5000;
523 } else FrostShock_Timer -= diff;
524
525 //Spitfire_Timer
526 if (Spitfire_Timer <= diff)
527 {
529 if (Unit* SpitfireTotem = Unit::GetUnit(*me, CREATURE_SPITFIRE_TOTEM))
530 SpitfireTotem->ToCreature()->AI()->AttackStart(me->GetVictim());
531
532 Spitfire_Timer = 60000;
533 }
534 else
535 Spitfire_Timer -= diff;
536
537 //PoisonCleansing_Timer
538 if (PoisonCleansing_Timer <= diff)
539 {
541 PoisonCleansing_Timer = 30000;
542 }
543 else
544 PoisonCleansing_Timer -= diff;
545
546 //Earthbind_Timer
547 if (Earthbind_Timer <= diff)
548 {
550 Earthbind_Timer = 45000;
551 }
552 else
553 Earthbind_Timer -= diff;
554
556 }
557 };
558};
559
560//Fathom-Guard Caribdis AI
562{
563public:
564 boss_fathomguard_caribdis() : CreatureScript("boss_fathomguard_caribdis") { }
565
567 {
568 return new boss_fathomguard_caribdisAI(creature);
569 }
570
572 {
574 {
575 instance = creature->GetInstanceScript();
576 }
577
579
584
586 {
587 WaterBoltVolley_Timer = 35000;
588 TidalSurge_Timer = 15000+rand()%5000;
589 Heal_Timer = 55000;
590 Cyclone_Timer = 30000+rand()%10000;
591
592 if (instance)
594 }
595
596 void JustDied(Unit* /*killer*/) OVERRIDE
597 {
598 if (instance)
599 {
600 if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS)))
601 CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath();
602 }
603 }
604
606 {
607 if (instance)
608 {
609 instance->SetData64(DATA_KARATHRESSEVENT_STARTER, who->GetGUID());
611 }
612 }
613
615 {
616 //Only if not incombat check if the event is started
617 if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
618 {
619 if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
620 AttackStart(target);
621 }
622
623 //Return since we have no target
624 if (!UpdateVictim())
625 return;
626
627 //someone evaded!
628 if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
629 {
631 return;
632 }
633
634 //WaterBoltVolley_Timer
635 if (WaterBoltVolley_Timer <= diff)
636 {
638 WaterBoltVolley_Timer = 30000;
639 } else WaterBoltVolley_Timer -= diff;
640
641 //TidalSurge_Timer
642 if (TidalSurge_Timer <= diff)
643 {
645 // Hacky way to do it - won't trigger elseways
646 me->GetVictim()->CastSpell(me->GetVictim(), SPELL_TIDAL_SURGE_FREEZE, true);
647 TidalSurge_Timer = 15000+rand()%5000;
648 } else TidalSurge_Timer -= diff;
649
650 //Cyclone_Timer
651 if (Cyclone_Timer <= diff)
652 {
653 //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work
654 Cyclone_Timer = 30000+rand()%10000;
655
656 if (Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand()%5), TempSummonType::TEMPSUMMON_TIMED_DESPAWN, 15000))
657 {
658 Cyclone->SetObjectScale(3.0f);
660 Cyclone->setFaction(me->getFaction());
661 Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
662 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
663 Cyclone->AI()->AttackStart(target);
664 }
665 }
666 else
667 Cyclone_Timer -= diff;
668
669 //Heal_Timer
670 if (Heal_Timer <= diff)
671 {
672 // It can be cast on any of the mobs
673 Unit* unit = NULL;
674
675 while (unit == NULL || !unit->IsAlive())
676 unit = selectAdvisorUnit();
677
678 if (unit && unit->IsAlive())
679 DoCast(unit, SPELL_HEAL);
680 Heal_Timer = 60000;
681 }
682 else
683 Heal_Timer -= diff;
684
686 }
687
689 {
690 Unit* unit = NULL;
691 if (instance)
692 {
693 switch (rand()%4)
694 {
695 case 0:
696 unit = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESS));
697 break;
698 case 1:
699 unit = Unit::GetUnit(*me, instance->GetData64(DATA_SHARKKIS));
700 break;
701 case 2:
702 unit = Unit::GetUnit(*me, instance->GetData64(DATA_TIDALVESS));
703 break;
704 case 3:
705 unit = me;
706 break;
707 }
708 } else unit = me;
709 return unit;
710 }
711 };
712};
713
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ IN_PROGRESS
@ DONE
@ NOT_STARTED
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
#define CAST_AI(a, b)
@ SPELL_SCHOOL_MASK_NORMAL
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ DIRECT_DAMAGE
Definition Unit.h:614
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
@ SPELL_ENRAGE
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
#define SAY_GAIN_BLESSING_OF_TIDES
@ SOUND_GAIN_BLESSING_OF_TIDES
@ SPELL_EARTHBIND_TOTEM_EFFECT
@ SPELL_SUMMON_FATHOM_SPOREBAT
@ SPELL_BLESSING_OF_THE_TIDES
@ CREATURE_POISON_CLEANSING_TOTEM
@ SPELL_POISON_CLEANSING_TOTEM
#define SEER_OLUM
void AddSC_boss_fathomlord_karathress()
#define MAX_ADVISORS
@ SPELL_WATER_BOLT_VOLLEY
@ SPELL_EARTHBIND_TOTEM
@ CREATURE_CYCLONE
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
void Respawn(bool force=false)
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
void MoveTargetedHome()
uint64 GetGUID() const
Definition Object.h:119
Definition Pet.h:28
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)
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
bool IsAlive() const
Definition Unit.h:2032
uint32 DealDamage(Unit *victim, uint32 damage, CleanDamage const *cleanDamage=NULL, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=NULL, bool durabilityLoss=true)
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
uint32 GetHealth() const
Definition Unit.h:1600
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ DATA_CARIBDIS
@ DATA_KARATHRESSEVENT_STARTER
@ DATA_FATHOMLORDKARATHRESSEVENT
@ DATA_KARATHRESS
@ DATA_TIDALVESS
@ DATA_KARATHRESSEVENT
@ DATA_SHARKKIS
Creature * me
bool HealthAbovePct(uint32 pct) const
Creature * DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, TempSummonType type, uint32 despawntime)
ScriptedAI(Creature *creature)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void AttackStart(Unit *) OVERRIDE
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 UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================