TrinityCore
boss_fathomlord_karathress.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_Fathomlord_Karathress
20SD%Complete: 70
21SDComment: Cyclone workaround
22SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "InstanceScript.h"
27#include "MotionMaster.h"
28#include "ObjectAccessor.h"
29#include "ScriptedCreature.h"
30#include "SpellScript.h"
31#include "serpent_shrine.h"
32#include "TemporarySummon.h"
33
35{
43
44 //Karathress spells
49 SPELL_ENRAGE = 24318,
52
53 //Sharkkis spells
60
61 //Tidalvess spells
65 // Spell obsolete
69
70 //Caribdis Spells
74 SPELL_HEAL = 38330,
77
78 //Yells and Quotes
79 SOUND_MISC = 11283,
80
81 //Summoned Unit GUIDs
88};
89
90//entry and position for Seer Olum
91#define SEER_OLUM 22820
92#define OLUM_X 446.78f
93#define OLUM_Y -542.76f
94#define OLUM_Z -7.54773f
95#define OLUM_O 0.401581f
96
97#define SAY_MISC "Alana be'lendor!" //don't know what use this
98
99#define MAX_ADVISORS 3
100//Fathom-Lord Karathress AI
102{
104 {
105 Initialize();
106 }
107
109 {
110 CataclysmicBolt_Timer = 10000;
111 Enrage_Timer = 600000; //10 minutes
112 SearNova_Timer = 20000 + rand32() % 40000; // 20 - 60 seconds
113
114 BlessingOfTides = false;
115 }
116
120
122
124
125 void Reset() override
126 {
127 Initialize();
128
129 ObjectGuid RAdvisors[MAX_ADVISORS];
130 RAdvisors[0] = instance->GetGuidData(DATA_SHARKKIS);
131 RAdvisors[1] = instance->GetGuidData(DATA_TIDALVESS);
132 RAdvisors[2] = instance->GetGuidData(DATA_CARIBDIS);
133 // Respawn of the 3 Advisors
134 for (uint8 i = 0; i < MAX_ADVISORS; ++i)
135 if (!RAdvisors[i].IsEmpty())
136 {
137 Creature* advisor = ObjectAccessor::GetCreature(*me, RAdvisors[i]);
138 if (advisor && !advisor->IsAlive())
139 {
140 advisor->Respawn();
141 advisor->AI()->EnterEvadeMode();
142 advisor->GetMotionMaster()->MoveTargetedHome();
143 }
144 }
145
146 _Reset();
147 }
148
150 {
153 }
154
156 {
159 }
160
162 {
165 }
166
168 {
172 }
173
174 void StartEvent(Unit* who)
175 {
176 GetAdvisors();
177
179
181 }
182
183 void KilledUnit(Unit* /*victim*/) override
184 {
185 Talk(SAY_SLAY);
186 }
187
188 void JustDied(Unit* /*killer*/) override
189 {
191
193
194 //support for quest 10944
196 }
197
198 void JustEngagedWith(Unit* who) override
199 {
200 _JustEngagedWith(who);
201 StartEvent(who);
202 }
203
204 void UpdateAI(uint32 diff) override
205 {
206 //Only if not incombat check if the event is started
208 {
210 {
211 AttackStart(target);
212 GetAdvisors();
213 }
214 }
215
216 //Return since we have no target
217 if (!UpdateVictim())
218 return;
219
220 //someone evaded!
222 {
224 return;
225 }
226
227 //CataclysmicBolt_Timer
228 if (CataclysmicBolt_Timer <= diff)
229 {
230 //select a random unit other than the main tank
232
233 //if there aren't other units, cast on the tank
234 if (!target)
235 target = me->GetVictim();
236
237 if (target)
239 CataclysmicBolt_Timer = 10000;
240 } else CataclysmicBolt_Timer -= diff;
241
242 //SearNova_Timer
243 if (SearNova_Timer <= diff)
244 {
246 SearNova_Timer = 20000 + rand32() % 40000;
247 } else SearNova_Timer -= diff;
248
249 //Enrage_Timer
250 if (Enrage_Timer <= diff)
251 {
253 Enrage_Timer = 90000;
254 } else Enrage_Timer -= diff;
255
256 //Blessing of Tides Trigger
257 if (!HealthAbovePct(75) && !BlessingOfTides)
258 {
259 BlessingOfTides = true;
260 bool continueTriggering = false;
261 for (uint8 i = 0; i < MAX_ADVISORS; ++i)
262 if (!Advisors[i].IsEmpty())
263 {
265 if (advisor && advisor->IsAlive())
266 {
267 continueTriggering = true;
268 break;
269 }
270 }
271 if (continueTriggering)
272 {
275 }
276 }
277 }
278};
279
280//Fathom-Guard Sharkkis AI
282{
284 {
285 Initialize();
286 instance = creature->GetInstanceScript();
287 }
288
290 {
291 LeechingThrow_Timer = 20000;
292 TheBeastWithin_Timer = 30000;
293 Multishot_Timer = 15000;
294 Pet_Timer = 10000;
295
296 pet = false;
297 }
298
300
305
306 bool pet;
307
309
310 void Reset() override
311 {
312 Initialize();
313
315 if (Pet && Pet->IsAlive())
316 Pet->KillSelf();
317
319
321 }
322
323 void JustDied(Unit* /*killer*/) override
324 {
326 ENSURE_AI(boss_fathomlord_karathress, Karathress->AI())->EventSharkkisDeath();
327 }
328
329 void JustEngagedWith(Unit* who) override
330 {
333 }
334
335 void UpdateAI(uint32 diff) override
336 {
337 //Only if not incombat check if the event is started
339 {
341 AttackStart(target);
342 }
343
344 //Return since we have no target
345 if (!UpdateVictim())
346 return;
347
348 //someone evaded!
350 {
352 return;
353 }
354
355 //LeechingThrow_Timer
356 if (LeechingThrow_Timer <= diff)
357 {
359 LeechingThrow_Timer = 20000;
360 } else LeechingThrow_Timer -= diff;
361
362 //Multishot_Timer
363 if (Multishot_Timer <= diff)
364 {
366 Multishot_Timer = 20000;
367 } else Multishot_Timer -= diff;
368
369 //TheBeastWithin_Timer
370 if (TheBeastWithin_Timer <= diff)
371 {
373
375 if (Pet && Pet->IsAlive())
377
378 TheBeastWithin_Timer = 30000;
379 } else TheBeastWithin_Timer -= diff;
380
381 //Pet_Timer
382 if (Pet_Timer < diff && pet == false)
383 {
384 pet = true;
385 //uint32 spell_id;
386 uint32 pet_id;
387 if (!urand(0, 1))
388 {
389 //spell_id = SPELL_SUMMON_FATHOM_LURKER;
390 pet_id = CREATURE_FATHOM_LURKER;
391 }
392 else
393 {
394 //spell_id = SPELL_SUMMON_FATHOM_SPOREBAT;
396 }
397 //DoCast(me, spell_id, true);
399 {
401 {
402 Pet->AI()->AttackStart(target);
404 }
405 }
406 } else Pet_Timer -= diff;
407 }
408};
409
410//Fathom-Guard Tidalvess AI
412{
414 {
415 Initialize();
416 instance = creature->GetInstanceScript();
417 }
418
420 {
421 FrostShock_Timer = 25000;
422 Spitfire_Timer = 60000;
423 PoisonCleansing_Timer = 30000;
424 Earthbind_Timer = 45000;
425 }
426
428
433
434 void Reset() override
435 {
436 Initialize();
437
439 }
440
441 void JustDied(Unit* /*killer*/) override
442 {
444 ENSURE_AI(boss_fathomlord_karathress, Karathress->AI())->EventTidalvessDeath();
445 }
446
447 void JustEngagedWith(Unit* who) override
448 {
452 }
453
454 void UpdateAI(uint32 diff) override
455 {
456 //Only if not incombat check if the event is started
458 {
460 AttackStart(target);
461 }
462
463 //Return since we have no target
464 if (!UpdateVictim())
465 return;
466
467 //someone evaded!
469 {
471 return;
472 }
473
475 {
477 }
478
479 //FrostShock_Timer
480 if (FrostShock_Timer <= diff)
481 {
483 FrostShock_Timer = 25000 + rand32() % 5000;
484 } else FrostShock_Timer -= diff;
485
486 //Spitfire_Timer
487 if (Spitfire_Timer <= diff)
488 {
490 if (Unit* SpitfireTotem = me->FindNearestCreature(CREATURE_SPITFIRE_TOTEM, 100.0f))
491 SpitfireTotem->ToCreature()->AI()->AttackStart(me->GetVictim());
492
493 Spitfire_Timer = 60000;
494 }
495 else
496 Spitfire_Timer -= diff;
497
498 //PoisonCleansing_Timer
499 if (PoisonCleansing_Timer <= diff)
500 {
502 PoisonCleansing_Timer = 30000;
503 }
504 else
505 PoisonCleansing_Timer -= diff;
506
507 //Earthbind_Timer
508 if (Earthbind_Timer <= diff)
509 {
511 Earthbind_Timer = 45000;
512 }
513 else
514 Earthbind_Timer -= diff;
515 }
516};
517
518//Fathom-Guard Caribdis AI
520{
522 {
523 Initialize();
524 instance = creature->GetInstanceScript();
525 }
526
528 {
529 WaterBoltVolley_Timer = 35000;
530 TidalSurge_Timer = 15000 + rand32() % 5000;
531 Heal_Timer = 55000;
532 Cyclone_Timer = 30000 + rand32() % 10000;
533 }
534
536
541
542 void Reset() override
543 {
544 Initialize();
545
547 }
548
549 void JustDied(Unit* /*killer*/) override
550 {
552 ENSURE_AI(boss_fathomlord_karathress, Karathress->AI())->EventCaribdisDeath();
553 }
554
555 void JustEngagedWith(Unit* who) override
556 {
559 }
560
561 void UpdateAI(uint32 diff) override
562 {
563 //Only if not incombat check if the event is started
565 {
567 AttackStart(target);
568 }
569
570 //Return since we have no target
571 if (!UpdateVictim())
572 return;
573
574 //someone evaded!
576 {
578 return;
579 }
580
581 //WaterBoltVolley_Timer
582 if (WaterBoltVolley_Timer <= diff)
583 {
585 WaterBoltVolley_Timer = 30000;
586 } else WaterBoltVolley_Timer -= diff;
587
588 //TidalSurge_Timer
589 if (TidalSurge_Timer <= diff)
590 {
592 TidalSurge_Timer = 15000 + rand32() % 5000;
593 } else TidalSurge_Timer -= diff;
594
595 //Cyclone_Timer
596 if (Cyclone_Timer <= diff)
597 {
598 //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work
599 Cyclone_Timer = 30000 + rand32() % 10000;
600
602 {
603 Cyclone->SetObjectScale(3.0f);
604 Cyclone->SetFaction(me->GetFaction());
605 Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
607 Cyclone->AI()->AttackStart(target);
608 }
609 }
610 else
611 Cyclone_Timer -= diff;
612
613 //Heal_Timer
614 if (Heal_Timer <= diff)
615 {
616 // It can be cast on any of the mobs
617 Unit* unit = nullptr;
618
619 while (unit == nullptr || !unit->IsAlive())
620 unit = selectAdvisorUnit();
621
622 DoCast(unit, SPELL_HEAL);
623 Heal_Timer = 60000;
624 }
625 else
626 Heal_Timer -= diff;
627 }
628
630 {
631 Unit* unit = nullptr;
632 switch (rand32() % 4)
633 {
634 case 0:
636 break;
637 case 1:
639 break;
640 case 2:
642 break;
643 case 3:
644 unit = me;
645 break;
646 }
647 return unit;
648 }
649};
650
651// 38358 - Tidal Surge
653{
654 bool Validate(SpellInfo const* /*spellInfo*/) override
655 {
657 }
658
659 void HandleScript(SpellEffIndex /*effIndex*/)
660 {
662 }
663
664 void Register() override
665 {
667 }
668};
669
671{
677}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ IN_PROGRESS
@ DONE
@ NOT_STARTED
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition: ObjectDefines.h:66
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ SPELL_EFFECT_SCRIPT_EFFECT
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define ENSURE_AI(a, b)
Definition: UnitAI.h:29
#define OLUM_O
#define OLUM_X
#define OLUM_Z
@ CREATURE_EARTHBIND_TOTEM
@ SPELL_EARTHBIND_TOTEM_EFFECT
@ SPELL_SUMMON_FATHOM_SPOREBAT
@ CREATURE_FATHOM_SPOREBAT
@ SPELL_POWER_OF_TIDALVESS
@ SPELL_TIDAL_SURGE_EFFECT
@ SPELL_BLESSING_OF_THE_TIDES
@ CREATURE_POISON_CLEANSING_TOTEM
@ SPELL_POISON_CLEANSING_TOTEM
@ SPELL_SUMMON_FATHOM_LURKER
#define SEER_OLUM
void AddSC_boss_fathomlord_karathress()
#define OLUM_Y
#define MAX_ADVISORS
Advisors
InstanceScript *const instance
void _JustEngagedWith(Unit *who)
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
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 Respawn(bool force=false)
Definition: Creature.cpp:2303
CreatureAI * AI() const
Definition: Creature.h:214
virtual bool SetBossState(uint32 id, EncounterState state)
virtual ObjectGuid GetGuidData(uint32 type) const override
EncounterState GetBossState(uint32 id) const
void MoveTargetedHome()
void Clear()
Definition: ObjectGuid.h:286
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
Definition: Pet.h:40
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
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
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsAlive() const
Definition: Unit.h:1164
uint32 GetFaction() const override
Definition: Unit.h:858
Unit * GetVictim() const
Definition: Unit.h:715
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.h:921
bool IsInCombat() const
Definition: Unit.h:1043
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
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:92
virtual void SetGuidData(uint32, ObjectGuid)
Definition: ZoneScript.h:84
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
@ DATA_CARIBDIS
@ DATA_KARATHRESSEVENT_STARTER
@ DATA_FATHOMLORDKARATHRESSEVENT
@ DATA_KARATHRESS
@ DATA_TIDALVESS
@ DATA_SHARKKIS
@ BOSS_FATHOM_LORD_KARATHRESS
#define RegisterSerpentshrineCavernCreatureAI(ai_name)
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr float GetPositionZ() const
Definition: Position.h:78
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
bool HealthAbovePct(uint32 pct) const
Creature * DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, Milliseconds despawntime)
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void UpdateAI(uint32 diff) override
void JustEngagedWith(Unit *who) override