TrinityCore
Loading...
Searching...
No Matches
boss_janalai.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_Janalai
20SD%Complete: 100
21SDComment:
22SDCategory: Zul'Aman
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "InstanceScript.h"
27#include "Map.h"
28#include "MotionMaster.h"
29#include "ObjectAccessor.h"
30#include "Player.h"
31#include "ScriptedCreature.h"
32#include "SpellInfo.h"
33#include "TemporarySummon.h"
34#include "zulaman.h"
35
48
50{
51 // Jan'alai
54 SPELL_ENRAGE = 44779,
56 SPELL_TELE_TO_CENTER = 43098, // coord
59
60 // Fire Bob Spells
61 SPELL_FIRE_BOMB_CHANNEL = 42621, // last forever
62 SPELL_FIRE_BOMB_THROW = 42628, // throw visual
63 SPELL_FIRE_BOMB_DUMMY = 42629, // bomb visual
65
66 // Hatcher Spells
67 SPELL_HATCH_EGG = 42471, // 43734
69
70 // Hatchling Spells
71 SPELL_FLAMEBUFFET = 43299
72};
73
75{
77 NPC_HATCHLING = 23598, // 42493
78 NPC_EGG = 23817,
79 NPC_FIRE_BOMB = 23920
80};
81
82const int area_dx = 44;
83const int area_dy = 51;
84
85float JanalainPos[1][3] =
86{
87 {-33.93f, 1149.27f, 19}
88};
89
90float FireWallCoords[4][4] =
91{
92 {-10.13f, 1149.27f, 19, 3.1415f},
93 {-33.93f, 1123.90f, 19, 0.5f*3.1415f},
94 {-54.80f, 1150.08f, 19, 0},
95 {-33.93f, 1175.68f, 19, 1.5f*3.1415f}
96};
97
98float hatcherway[2][5][3] =
99{
100 {
101 {-87.46f, 1170.09f, 6},
102 {-74.41f, 1154.75f, 6},
103 {-52.74f, 1153.32f, 19},
104 {-33.37f, 1172.46f, 19},
105 {-33.09f, 1203.87f, 19}
106 },
107 {
108 {-86.57f, 1132.85f, 6},
109 {-73.94f, 1146.00f, 6},
110 {-52.29f, 1146.51f, 19},
111 {-33.57f, 1125.72f, 19},
112 {-34.29f, 1095.22f, 19}
113 }
114};
116{
117 public:
118 boss_janalai() : CreatureScript("boss_janalai") { }
119
120 struct boss_janalaiAI : public BossAI
121 {
123 {
124 Initialize();
125 }
126
128 {
129 FireBreathTimer = 8000;
130 BombTimer = 30000;
131 BombSequenceTimer = 1000;
132 BombCount = 0;
133 HatcherTimer = 10000;
135
136 noeggs = false;
137 isBombing = false;
138 enraged = false;
139
140 isFlameBreathing = false;
141
142 for (uint8 i = 0; i < 40; ++i)
143 FireBombGUIDs[i].Clear();
144 }
145
152
153 bool noeggs;
156
158
160
161 void Reset() override
162 {
163 _Reset();
164
165 Initialize();
166
167 HatchAllEggs(1);
168 }
169
170 void JustDied(Unit* /*killer*/) override
171 {
173
174 _JustDied();
175 }
176
177 void KilledUnit(Unit* /*victim*/) override
178 {
179 Talk(SAY_SLAY);
180 }
181
182 void JustEngagedWith(Unit* who) override
183 {
185
187 }
188
189 void DamageDealt(Unit* target, uint32& damage, DamageEffectType /*damagetype*/) override
190 {
192 {
193 if (!me->HasInArc(float(M_PI) / 6, target))
194 damage = 0;
195 }
196 }
197
198 void FireWall()
199 {
200 uint8 WallNum;
201 Creature* wall = nullptr;
202 for (uint8 i = 0; i < 4; ++i)
203 {
204 if (i == 0 || i == 2)
205 WallNum = 3;
206 else
207 WallNum = 2;
208
209 for (uint8 j = 0; j < WallNum; j++)
210 {
211 if (WallNum == 3)
213 else
215 if (wall) wall->CastSpell(wall, SPELL_FIRE_WALL, true);
216 }
217 }
218 }
219
221 {
222 float dx, dy;
223 for (int i(0); i < 40; ++i)
224 {
225 dx = float(irand(-area_dx/2, area_dx/2));
226 dy = float(irand(-area_dy/2, area_dy/2));
227
229 if (bomb)
230 FireBombGUIDs[i] = bomb->GetGUID();
231 }
232 BombCount = 0;
233 }
234
235 bool HatchAllEggs(uint32 action) //1: reset, 2: isHatching all
236 {
237 std::list<Creature*> templist;
238
239 GetCreatureListWithEntryInGrid(templist, me, NPC_EGG, 100.0f);
240
241 //TC_LOG_ERROR("scripts", "Eggs {} at middle", templist.size());
242 if (templist.empty())
243 return false;
244
245 for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
246 {
247 if (action == 1)
248 (*i)->SetDisplayId(10056);
249 else if (action == 2 &&(*i)->GetDisplayId() != 11686)
250 (*i)->CastSpell(*i, SPELL_HATCH_EGG, false);
251 }
252 return true;
253 }
254
255 void Boom()
256 {
257 std::list<Creature*> templist;
258
260
261 for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
262 {
263 (*i)->CastSpell(*i, SPELL_FIRE_BOMB_DAMAGE, true);
264 (*i)->RemoveAllAuras();
265 }
266 }
267
269 {
270 if (BombCount < 40)
271 {
273 {
274 FireBomb->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
277 }
278 ++BombCount;
279 if (BombCount == 40)
280 {
281 BombSequenceTimer = 5000;
282 }
283 else
284 BombSequenceTimer = 100;
285 }
286 else
287 {
288 Boom();
289 isBombing = false;
290 BombTimer = urand(20000, 40000);
292 if (EnrageTimer <= 10000)
293 EnrageTimer = 0;
294 else
295 EnrageTimer -= 10000;
296 }
297 }
298
299 void UpdateAI(uint32 diff) override
300 {
302 {
303 if (!me->IsNonMeleeSpellCast(false))
304 isFlameBreathing = false;
305 else
306 return;
307 }
308
309 if (isBombing)
310 {
311 if (BombSequenceTimer <= diff)
313 else
314 BombSequenceTimer -= diff;
315 return;
316 }
317
318 if (!UpdateVictim())
319 return;
320
321 //enrage if under 25% hp before 5 min.
322 if (!enraged && HealthBelowPct(25))
323 EnrageTimer = 0;
324
325 if (EnrageTimer <= diff)
326 {
327 if (!enraged)
328 {
329 DoCast(me, SPELL_ENRAGE, true);
330 enraged = true;
331 EnrageTimer = 300000;
332 }
333 else
334 {
336 DoCast(me, SPELL_BERSERK, true);
337 EnrageTimer = 300000;
338 }
339 }
340 else
341 EnrageTimer -= diff;
342
343 if (BombTimer <= diff)
344 {
346
347 me->AttackStop();
349 DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]);
350 me->StopMoving();
352 //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2], 0);
353 //DoCast(me, SPELL_TELE_TO_CENTER, true);
354
355 FireWall();
356 SpawnBombs();
357 isBombing = true;
358 BombSequenceTimer = 100;
359
360 //Teleport every Player into the middle
361 Map* map = me->GetMap();
362 if (!map->IsDungeon())
363 return;
364
365 Map::PlayerList const& PlayerList = map->GetPlayers();
366 for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
367 if (Player* i_pl = i->GetSource())
368 if (i_pl->IsAlive())
369 DoTeleportPlayer(i_pl, JanalainPos[0][0] - 5 + rand32() % 10, JanalainPos[0][1] - 5 + rand32() % 10, JanalainPos[0][2], 0);
370 //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far
371 return;
372 }
373 else
374 BombTimer -= diff;
375
376 if (!noeggs)
377 {
378 if (HealthBelowPct(35))
379 {
381
382 me->AttackStop();
384 DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]);
385 me->StopMoving();
386 DoCast(me, SPELL_HATCH_ALL, false);
387 HatchAllEggs(2);
388 noeggs = true;
389 }
390 else if (HatcherTimer <= diff)
391 {
392 if (HatchAllEggs(0))
393 {
397 HatcherTimer = 90000;
398 }
399 else
400 noeggs = true;
401 } else HatcherTimer -= diff;
402 }
403
405
406 if (FireBreathTimer <= diff)
407 {
409 {
410 me->AttackStop();
412 DoCast(target, SPELL_FLAME_BREATH, false);
413 me->StopMoving();
414 isFlameBreathing = true;
415 }
416 FireBreathTimer = 8000;
417 }
418 else
419 FireBreathTimer -= diff;
420 }
421 };
422
423 CreatureAI* GetAI(Creature* creature) const override
424 {
425 return GetZulAmanAI<boss_janalaiAI>(creature);
426 }
427};
428
430{
431 public:
432 npc_janalai_firebomb() : CreatureScript("npc_janalai_firebomb") { }
433
435 {
436 npc_janalai_firebombAI(Creature* creature) : ScriptedAI(creature) { }
437
438 void Reset() override { }
439
440 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
441 {
442 if (spellInfo->Id == SPELL_FIRE_BOMB_THROW)
444 }
445
446 void JustEngagedWith(Unit* /*who*/) override { }
447
448 void AttackStart(Unit* /*who*/) override { }
449
450 void MoveInLineOfSight(Unit* /*who*/) override { }
451
452 void UpdateAI(uint32 /*diff*/) override { }
453 };
454
455 CreatureAI* GetAI(Creature* creature) const override
456 {
457 return GetZulAmanAI<npc_janalai_firebombAI>(creature);
458 }
459};
460
462{
463 public:
464 npc_janalai_hatcher() : CreatureScript("npc_janalai_hatcher") { }
465
467 {
469 {
470 Initialize();
471 instance = creature->GetInstanceScript();
472 }
473
475 {
476 waypoint = 0;
477 isHatching = false;
478 hasChangedSide = false;
479 WaitTimer = 1;
480 HatchNum = 0;
481 side = false;
482 }
483
485
489
490 bool side;
493
494 void Reset() override
495 {
496 me->SetWalk(true);
497 Initialize();
498 side =(me->GetPositionY() < 1150);
499 }
500
502 {
503 std::list<Creature*> templist;
504
505 GetCreatureListWithEntryInGrid(templist, me, NPC_EGG, 50.0f);
506
507 //TC_LOG_ERROR("scripts", "Eggs {} at {}", templist.size(), side);
508
509 for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end() && num > 0; ++i)
510 if ((*i)->GetDisplayId() != 11686)
511 {
512 (*i)->CastSpell(*i, SPELL_HATCH_EGG, false);
513 num--;
514 }
515
516 return num == 0; // if num == 0, no more templist
517 }
518
519 void JustEngagedWith(Unit* /*who*/) override { }
520 void AttackStart(Unit* /*who*/) override { }
521 void MoveInLineOfSight(Unit* /*who*/) override { }
522
524 {
525 if (waypoint == 5)
526 {
527 isHatching = true;
528 HatchNum = 1;
529 WaitTimer = 5000;
530 }
531 else
532 WaitTimer = 1;
533 }
534
535 void UpdateAI(uint32 diff) override
536 {
538 {
540 return;
541 }
542
543 if (!isHatching)
544 {
545 if (WaitTimer)
546 {
549 ++waypoint;
550 WaitTimer = 0;
551 }
552 }
553 else
554 {
555 if (WaitTimer <= diff)
556 {
557 if (HatchEggs(HatchNum))
558 {
559 ++HatchNum;
560 WaitTimer = 10000;
561 }
562 else if (!hasChangedSide)
563 {
564 side = side ? 0 : 1;
565 isHatching = false;
566 waypoint = 3;
567 WaitTimer = 1;
568 hasChangedSide = true;
569 }
570 else
572
573 }
574 else
575 WaitTimer -= diff;
576 }
577 }
578 };
579
580 CreatureAI* GetAI(Creature* creature) const override
581 {
582 return GetZulAmanAI<npc_janalai_hatcherAI>(creature);
583 }
584};
585
587{
588 public:
589 npc_janalai_hatchling() : CreatureScript("npc_janalai_hatchling") { }
590
592 {
594 {
595 Initialize();
596 instance = creature->GetInstanceScript();
597 }
598
600 {
601 BuffetTimer = 7000;
602 }
603
606
607 void Reset() override
608 {
609 Initialize();
610 if (me->GetPositionY() > 1150)
611 me->GetMotionMaster()->MovePoint(0, hatcherway[0][3][0] + rand32() % 4 - 2, 1150.0f + rand32() % 4 - 2, hatcherway[0][3][2]);
612 else
613 me->GetMotionMaster()->MovePoint(0, hatcherway[1][3][0] + rand32() % 4 - 2, 1150.0f + rand32() % 4 - 2, hatcherway[1][3][2]);
614
615 me->SetDisableGravity(true);
616 }
617
618 void JustEngagedWith(Unit* /*who*/) override {/*DoZoneInCombat();*/ }
619
620 void UpdateAI(uint32 diff) override
621 {
623 {
625 return;
626 }
627
628 if (!UpdateVictim())
629 return;
630
631 if (BuffetTimer <= diff)
632 {
634 BuffetTimer = 10000;
635 }
636 else
637 BuffetTimer -= diff;
638
640 }
641 };
642
643 CreatureAI* GetAI(Creature* creature) const override
644 {
645 return GetZulAmanAI<npc_janalai_hatchlingAI>(creature);
646 }
647};
648
650{
651 public:
652 npc_janalai_egg(): CreatureScript("npc_janalai_egg") { }
653
655 {
656 npc_janalai_eggAI(Creature* creature) : ScriptedAI(creature) { }
657
658 void Reset() override { }
659
660 void UpdateAI(uint32 /*diff*/) override { }
661
662 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
663 {
664 if (spellInfo->Id == SPELL_HATCH_EGG)
666 }
667 };
668
669 CreatureAI* GetAI(Creature* creature) const override
670 {
671 return GetZulAmanAI<npc_janalai_eggAI>(creature);
672 }
673};
674
676{
677 new boss_janalai();
681 new npc_janalai_egg();
682}
@ IN_MILLISECONDS
Definition Common.h:35
@ MINUTE
Definition Common.h:29
#define M_PI
Definition Common.h:72
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
@ IN_PROGRESS
@ TEMPSUMMON_TIMED_DESPAWN
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Spells
Definition PlayerAI.cpp:32
int32 irand(int32 min, int32 max)
Definition Random.cpp:35
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
uint32 rand32()
Definition Random.cpp:70
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
@ UNIT_FLAG_UNINTERACTIBLE
DamageEffectType
Definition Unit.h:352
Creatures
float hatcherway[2][5][3]
const int area_dx
@ NPC_EGG
@ NPC_AMANI_HATCHER
@ NPC_FIRE_BOMB
@ NPC_HATCHLING
const int area_dy
@ SAY_DEATH
@ SAY_EVENT_STRANGERS
@ SAY_AGGRO
@ SAY_EVENT_FRIENDS
@ SAY_FIRE_BOMBS
@ SAY_SLAY
@ SAY_SUMMON_HATCHER
@ SAY_ALL_EGGS
@ SAY_BERSERK
float JanalainPos[1][3]
@ SPELL_SUMMON_HATCHLING
@ SPELL_ENRAGE
@ SPELL_FIRE_WALL
@ SPELL_HATCH_ALL
@ SPELL_FLAME_BREATH
@ SPELL_FIRE_BOMB_CHANNEL
@ SPELL_FIRE_BOMB_DUMMY
@ SPELL_FLAMEBUFFET
@ SPELL_TELE_TO_CENTER
@ SPELL_SUMMON_PLAYERS
@ SPELL_HATCH_EGG
@ SPELL_BERSERK
@ SPELL_FIRE_BOMB_THROW
@ SPELL_FIRE_BOMB_DAMAGE
float FireWallCoords[4][4]
void AddSC_boss_janalai()
Yells
void JustEngagedWith(Unit *who) override
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void DisappearAndDie()
Definition Creature.h:73
EncounterState GetBossState(uint32 id) const
iterator end()
iterator begin()
Definition Map.h:281
bool IsDungeon() const
Definition Map.cpp:4236
PlayerList const & GetPlayers() const
Definition Map.h:448
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={})
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 Id
Definition SpellInfo.h:289
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
void StopMoving(bool force=false)
Definition Unit.cpp:10312
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:3063
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13286
bool SetWalk(bool enable)
Definition Unit.cpp:13268
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
bool AttackStop()
Definition Unit.cpp:5645
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
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:1992
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
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:120
float GetPositionY() const
Definition Position.h:80
void DoTeleportTo(float x, float y, float z, uint32 time=0)
void DoTeleportPlayer(Unit *unit, float x, float y, float z, float o)
bool HealthBelowPct(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 DamageDealt(Unit *target, uint32 &damage, DamageEffectType) override
void JustDied(Unit *) override
boss_janalaiAI(Creature *creature)
bool HatchAllEggs(uint32 action)
void KilledUnit(Unit *) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void MovementInform(uint32, uint32) override
FireBomb
@ BOSS_JANALAI
Definition zulaman.h:30