TrinityCore
boss_lady_vashj.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_Lady_Vashj
20SD%Complete: 99
21SDComment: Missing blizzlike Shield Generators coords
22SDCategory: Coilfang Resevoir, Serpent Shrine Cavern
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "GameObject.h"
27#include "InstanceScript.h"
28#include "Map.h"
29#include "MotionMaster.h"
30#include "ObjectAccessor.h"
31#include "Player.h"
32#include "ScriptedCreature.h"
33#include "serpent_shrine.h"
34#include "TemporarySummon.h"
35
37{
46
47 SPELL_SURGE = 38044,
53 SPELL_SHOOT = 40873,
57
65};
66
67#define MIDDLE_X 30.134f
68#define MIDDLE_Y -923.65f
69#define MIDDLE_Z 42.9f
70
71#define SPOREBAT_X 30.977156f
72#define SPOREBAT_Y -925.297761f
73#define SPOREBAT_Z 77.176567f
74#define SPOREBAT_O 5.223932f
75
76float ElementPos[8][4] =
77{
78 {8.3f, -835.3f, 21.9f, 5.0f},
79 {53.4f, -835.3f, 21.9f, 4.5f},
80 {96.0f, -861.9f, 21.8f, 4.0f},
81 {96.0f, -986.4f, 21.4f, 2.5f},
82 {54.4f, -1010.6f, 22, 1.8f},
83 {9.8f, -1012, 21.7f, 1.4f},
84 {-35.0f, -987.6f, 21.5f, 0.8f},
85 {-58.9f, -901.6f, 21.5f, 6.0f}
86};
87
88float ElementWPPos[8][3] =
89{
90 {71.700752f, -883.905884f, 41.097168f},
91 {45.039848f, -868.022827f, 41.097015f},
92 {14.585141f, -867.894470f, 41.097061f},
93 {-25.415508f, -906.737732f, 41.097061f},
94 {-11.801594f, -963.405884f, 41.097067f},
95 {14.556657f, -979.051514f, 41.097137f},
96 {43.466549f, -979.406677f, 41.097027f},
97 {69.945908f, -964.663940f, 41.097054f}
98};
99
100float SporebatWPPos[8][3] =
101{
102 {31.6f, -896.3f, 59.1f},
103 {9.1f, -913.9f, 56.0f},
104 {5.2f, -934.4f, 52.4f},
105 {20.7f, -946.9f, 49.7f},
106 {41.0f, -941.9f, 51.0f},
107 {47.7f, -927.3f, 55.0f},
108 {42.2f, -912.4f, 51.7f},
109 {27.0f, -905.9f, 50.0f}
110};
111
112float CoilfangElitePos[3][4] =
113{
114 {28.84f, -923.28f, 42.9f, 6.0f},
115 {31.183281f, -953.502625f, 41.523602f, 1.640957f},
116 {58.895180f, -923.124268f, 41.545307f, 3.152848f}
117};
118
120{
121 {66.427010f, -948.778503f, 41.262245f, 2.584220f},
122 {7.513962f, -959.538208f, 41.300422f, 1.034629f},
123 {-12.843201f, -907.798401f, 41.239620f, 6.087094f}
124};
125
127{
128 {49.6262f, -902.181f, 43.0975f, 3.95683f},
129 {10.988f, -901.616f, 42.5371f, 5.4373f},
130 {10.3859f, -944.036f, 42.5446f, 0.779888f},
131 {49.3126f, -943.398f, 42.5501f, 2.40174f}
132};
133
134struct boss_lady_vashj : public BossAI
135{
137 {
138 Initialize();
139 instance = creature->GetInstanceScript();
140 Intro = false;
141 JustCreated = true;
142 CanAttack = false;
143 creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // set it only once on Creature create (no need do intro if wiped)
144 }
145
147 {
148 AggroTimer = 19000;
149 ShockBlastTimer = 1 + rand32() % 60000;
150 EntangleTimer = 30000;
151 StaticChargeTimer = 10000 + rand32() % 15000;
153 CheckTimer = 15000;
155 TaintedElementalTimer = 50000;
156 CoilfangEliteTimer = 45000 + rand32() % 5000;
157 CoilfangStriderTimer = 60000 + rand32() % 10000;
158 SummonSporebatTimer = 10000;
161 Phase = 0;
162
163 Entangle = false;
164 }
165
167
169
184
186 bool Intro;
189
190 void Reset() override
191 {
192 Initialize();
193
194 if (JustCreated)
195 {
196 CanAttack = false;
197 JustCreated = false;
198 } else CanAttack = true;
199
200 for (uint8 i = 0; i < 4; ++i)
201 {
202 if (!ShieldGeneratorChannel[i].IsEmpty())
203 {
205 {
206 remo->setDeathState(JUST_DIED);
208 }
209 }
210 }
211
212 _Reset();
213
214 me->SetCorpseDelay(1000*60*60);
215 me->SetCanMelee(true);
216 }
217
218 // Called when a tainted elemental dies
220 {
221 // the next will spawn 50 seconds after the previous one's death
222 if (TaintedElementalTimer > 50000)
223 TaintedElementalTimer = 50000;
224 }
225 void KilledUnit(Unit* /*victim*/) override
226 {
227 Talk(SAY_SLAY);
228 }
229
230 void JustDied(Unit* /*killer*/) override
231 {
233
234 _JustDied();
235 }
236
237 void StartEvent(Unit* who)
238 {
240
241 Phase = 1;
242
243 _JustEngagedWith(who);
244 }
245
246 void JustEngagedWith(Unit* who) override
247 {
248 // remove old tainted cores to prevent cheating in phase 2
249 Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
250 for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
251 if (Player* player = itr->GetSource())
252 player->DestroyItemCount(31088, 1, true);
253 StartEvent(who); // this is JustEngagedWith(), so were are 100% in combat, start the event
254
255 if (Phase != 2)
256 AttackStart(who);
257 }
258
259 void MoveInLineOfSight(Unit* who) override
260
261 {
262 if (!Intro)
263 {
264 Intro = true;
266 }
267 if (!CanAttack)
268 return;
269 if (!who || me->GetVictim())
270 return;
271
272 if (me->CanCreatureAttack(who))
273 {
274 float attackRadius = me->GetAttackDistance(who);
275 if (me->IsWithinDistInMap(who, attackRadius) && me->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && me->IsWithinLOSInMap(who))
276 {
277 if (!me->IsInCombat()) // AttackStart() sets UNIT_FLAG_IN_COMBAT, so this msut be before attacking
278 StartEvent(who);
279
280 if (Phase != 2)
281 AttackStart(who);
282 }
283 }
284 }
285
287 {
288 switch (urand(0, 1))
289 {
290 case 0:
291 // Shoot
292 // Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage.
294 break;
295 case 1:
296 // Multishot
297 // Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage.
299 break;
300 }
301 if (rand32() % 3)
302 {
304 }
305 }
306
307 void UpdateAI(uint32 diff) override
308 {
309 if (!CanAttack && Intro)
310 {
311 if (AggroTimer <= diff)
312 {
313 CanAttack = true;
315 AggroTimer=19000;
316 }
317 else
318 {
319 AggroTimer -= diff;
320 return;
321 }
322 }
323 // to prevent abuses during phase 2
324 if (Phase == 2 && !me->GetVictim() && me->IsInCombat())
325 {
327 return;
328 }
329 // Return since we have no target
330 if (!UpdateVictim())
331 return;
332
333 if (Phase == 1 || Phase == 3)
334 {
335 // ShockBlastTimer
336 if (ShockBlastTimer <= diff)
337 {
338 // Shock Burst
339 // Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list.
341
342 ShockBlastTimer = 1000 + rand32() % 14000; // random cooldown
343 } else ShockBlastTimer -= diff;
344
345 // StaticChargeTimer
346 if (StaticChargeTimer <= diff)
347 {
348 // Static Charge
349 // Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic.
350 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 200, true);
351 if (target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER))
352 DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); // cast Static Charge every 2 seconds for 20 seconds
353
354 StaticChargeTimer = 10000 + rand32() % 20000;
355 } else StaticChargeTimer -= diff;
356
357 // EntangleTimer
358 if (EntangleTimer <= diff)
359 {
360 if (!Entangle)
361 {
362 // Entangle
363 // Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom.
365 Entangle = true;
366 EntangleTimer = 10000;
367 }
368 else
369 {
371 Entangle = false;
372 EntangleTimer = 20000 + rand32() % 5000;
373 }
374 } else EntangleTimer -= diff;
375
376 // Phase 1
377 if (Phase == 1)
378 {
379 // Start phase 2
380 if (HealthBelowPct(70))
381 {
382 // Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable.
383 Phase = 2;
384 me->SetCanMelee(false);
385
388
389 for (uint8 i = 0; i < 4; ++i)
391 ShieldGeneratorChannel[i] = creature->GetGUID();
392
394 }
395 }
396 // Phase 3
397 else
398 {
399 // SummonSporebatTimer
400 if (SummonSporebatTimer <= diff)
401 {
404 sporebat->AI()->AttackStart(target);
405
406 // summon sporebats faster and faster
407 if (SummonSporebatStaticTimer > 1000)
409
411
412 if (SummonSporebatTimer < 5000)
413 SummonSporebatTimer = 5000;
414
415 } else SummonSporebatTimer -= diff;
416 }
417
418 // CheckTimer - used to check if somebody is in melee range
419 if (CheckTimer <= diff)
420 {
421 bool inMeleeRange = false;
422 for (auto* ref : me->GetThreatManager().GetUnsortedThreatList())
423 {
424 Unit* target = ref->GetVictim();
425 if (target->IsWithinMeleeRange(me)) // if in melee range
426 {
427 inMeleeRange = true;
428 break;
429 }
430 }
431
432 // if nobody is in melee range
433 if (!inMeleeRange)
435
436 CheckTimer = 5000;
437 } else CheckTimer -= diff;
438 }
439 // Phase 2
440 else
441 {
442 // ForkedLightningTimer
443 if (ForkedLightningTimer <= diff)
444 {
445 // Forked Lightning
446 // Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage.
448
449 if (!target)
450 target = me->GetVictim();
451
453
454 ForkedLightningTimer = 2000 + rand32() % 6000;
455 } else ForkedLightningTimer -= diff;
456
457 // EnchantedElementalTimer
458 if (EnchantedElementalTimer <= diff)
459 {
461
462 if (EnchantedElementalPos == 7)
464 else
466
467 EnchantedElementalTimer = 10000 + rand32() % 5000;
468 } else EnchantedElementalTimer -= diff;
469
470 // TaintedElementalTimer
471 if (TaintedElementalTimer <= diff)
472 {
473 uint32 pos = rand32() % 8;
475
476 TaintedElementalTimer = 120000;
477 } else TaintedElementalTimer -= diff;
478
479 // CoilfangEliteTimer
480 if (CoilfangEliteTimer <= diff)
481 {
482 uint32 pos = rand32() % 3;
484 if (coilfangElite)
485 {
487 coilfangElite->AI()->AttackStart(target);
488 else if (me->GetVictim())
489 coilfangElite->AI()->AttackStart(me->GetVictim());
490 }
491 CoilfangEliteTimer = 45000 + rand32() % 5000;
492 } else CoilfangEliteTimer -= diff;
493
494 // CoilfangStriderTimer
495 if (CoilfangStriderTimer <= diff)
496 {
497 uint32 pos = rand32() % 3;
499 {
501 CoilfangStrider->AI()->AttackStart(target);
502 else if (me->GetVictim())
503 CoilfangStrider->AI()->AttackStart(me->GetVictim());
504 }
505 CoilfangStriderTimer = 60000 + rand32() % 10000;
506 } else CoilfangStriderTimer -= diff;
507
508 // CheckTimer
509 if (CheckTimer <= diff)
510 {
511 // Start Phase 3
513 {
514 // set life 50%
516
518
519 me->SetCanMelee(true);
520
522
523 Phase = 3;
524
525 // return to the tank
527 }
528 CheckTimer = 1000;
529 } else CheckTimer -= diff;
530 }
531 }
532};
533
534// Enchanted Elemental
535// If one of them reaches Vashj he will increase her damage done by 5%.
537{
539 {
540 Initialize();
541 instance = creature->GetInstanceScript();
542 }
543
545 {
546 Move = 0;
547 Phase = 1;
548
549 X = ElementWPPos[0][0];
550 Y = ElementWPPos[0][1];
551 Z = ElementWPPos[0][2];
552 }
553
557 float X, Y, Z;
558
560
561 void Reset() override
562 {
563 me->SetSpeedRate(MOVE_WALK, 0.6f); // walk
564 me->SetSpeedRate(MOVE_RUN, 0.6f); // run
565 Initialize();
566
567 //search for nearest waypoint (up on stairs)
568 for (uint32 i = 1; i < 8; ++i)
569 {
570 if (me->GetDistance(ElementWPPos[i][0], ElementWPPos[i][1], ElementWPPos[i][2]) < me->GetDistance(X, Y, Z))
571 {
572 X = ElementWPPos[i][0];
573 Y = ElementWPPos[i][1];
574 Z = ElementWPPos[i][2];
575 }
576 }
577
579 }
580
581 void JustEngagedWith(Unit* /*who*/) override { }
582
583 void MoveInLineOfSight(Unit* /*who*/) override { }
584
585 void UpdateAI(uint32 diff) override
586 {
587 if (!VashjGUID)
588 return;
589
590 if (Move <= diff)
591 {
592 me->SetWalk(true);
593 if (Phase == 1)
594 me->GetMotionMaster()->MovePoint(0, X, Y, Z);
595 if (Phase == 1 && me->IsWithinDist3d(X, Y, Z, 0.1f))
596 Phase = 2;
597 if (Phase == 2)
598 {
600 Phase = 3;
601 }
602 if (Phase == 3)
603 {
607 }
609 if (!vashj->IsInCombat() || ENSURE_AI(boss_lady_vashj, vashj->AI())->Phase != 2 || vashj->isDead())
610 me->KillSelf();
611 Move = 1000;
612 } else Move -= diff;
613 }
614};
615
616// Tainted Elemental
617// This mob has 7, 900 life, doesn't move, and shoots Poison Bolts at one person anywhere in the area, doing 3, 000 nature damage and placing a posion doing 2, 000 damage every 2 seconds. He will switch targets often, or sometimes just hang on a single player, but there is nothing you can do about it except heal the damage and kill the Tainted Elemental
619{
621 {
622 Initialize();
623 instance = creature->GetInstanceScript();
624 }
625
627 {
628 PoisonBoltTimer = 5000 + rand32() % 5000;
629 DespawnTimer = 30000;
630 }
631
633
636
637 void Reset() override
638 {
639 Initialize();
640 }
641
642 void JustDied(Unit* /*killer*/) override
643 {
645 ENSURE_AI(boss_lady_vashj, vashj->AI())->EventTaintedElementalDeath();
646 }
647
648 void JustEngagedWith(Unit* who) override
649 {
650 AddThreat(who, 0.1f);
651 }
652
653 void UpdateAI(uint32 diff) override
654 {
655 // PoisonBoltTimer
656 if (PoisonBoltTimer <= diff)
657 {
659
660 if (target && target->IsWithinDistInMap(me, 30))
661 DoCast(target, SPELL_POISON_BOLT);
662
663 PoisonBoltTimer = 5000 + rand32() % 5000;
664 } else PoisonBoltTimer -= diff;
665
666 // DespawnTimer
667 if (DespawnTimer <= diff)
668 {
669 // call Unsummon()
671
672 // to prevent crashes
673 DespawnTimer = 1000;
674 } else DespawnTimer -= diff;
675 }
676};
677
678//Toxic Sporebat
679//Toxic Spores: Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it.
681{
683 {
684 Initialize();
685 instance = creature->GetInstanceScript();
686 }
687
689 {
690 MovementTimer = 0;
691 ToxicSporeTimer = 5000;
692 BoltTimer = 5500;
693 CheckTimer = 1000;
694 }
695
697
702
703 void Reset() override
704 {
705 me->SetDisableGravity(true);
707 Initialize();
708 }
709
710 void MoveInLineOfSight(Unit* /*who*/) override
711 {
712 }
713
714 void MovementInform(uint32 type, uint32 id) override
715 {
716 if (type != POINT_MOTION_TYPE)
717 return;
718
719 if (id == 1)
720 MovementTimer = 0;
721 }
722
723 void UpdateAI(uint32 diff) override
724 {
725 // Random movement
726 if (MovementTimer <= diff)
727 {
728 uint32 rndpos = rand32() % 8;
729 me->GetMotionMaster()->MovePoint(1, SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]);
730 MovementTimer = 6000;
731 } else MovementTimer -= diff;
732
733 // toxic spores
734 if (BoltTimer <= diff)
735 {
737 {
738 if (Creature* trig = me->SummonCreature(TOXIC_SPORES_TRIGGER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30s))
739 {
740 trig->SetFaction(FACTION_MONSTER);
741 trig->CastSpell(trig, SPELL_TOXIC_SPORES, true);
742 }
743 }
744 BoltTimer = 10000 + rand32() % 5000;
745 }
746 else BoltTimer -= diff;
747
748 // CheckTimer
749 if (CheckTimer <= diff)
750 {
751 // check if vashj is death
753 if (!Vashj || !Vashj->IsAlive() || ENSURE_AI(boss_lady_vashj, Vashj->ToCreature()->AI())->Phase != 3)
754 {
755 // remove
758 return;
759 }
760
761 CheckTimer = 1000;
762 }
763 else
764 CheckTimer -= diff;
765 }
766};
767
769{
771 {
772 Initialize();
773 instance = creature->GetInstanceScript();
774 }
775
777 {
778 CheckTimer = 0;
779 Cast = false;
780 }
781
784 bool Cast;
785
786 void Reset() override
787 {
788 Initialize();
789 me->SetDisplayId(11686); // invisible
790 }
791
792 void MoveInLineOfSight(Unit* /*who*/) override { }
793
794 void UpdateAI(uint32 diff) override
795 {
796 if (CheckTimer <= diff)
797 {
799
800 if (vashj && vashj->IsAlive())
801 {
802 // start visual channel
803 if (!Cast || !vashj->HasAura(SPELL_MAGIC_BARRIER))
804 {
805 DoCast(vashj, SPELL_MAGIC_BARRIER, true);
806 Cast = true;
807 }
808 }
809 CheckTimer = 1000;
810 } else CheckTimer -= diff;
811 }
812};
813
815{
816public:
817 item_tainted_core() : ItemScript("item_tainted_core") { }
818
819 bool OnUse(Player* player, Item* /*item*/, SpellCastTargets const& targets, ObjectGuid /*castId*/) override
820 {
821 InstanceScript* instance = player->GetInstanceScript();
822 if (!instance)
823 return true;
824
825 Creature* vashj = ObjectAccessor::GetCreature((*player), instance->GetGuidData(DATA_LADYVASHJ));
826 if (vashj && (ENSURE_AI(boss_lady_vashj, vashj->AI())->Phase == 2))
827 {
828 if (GameObject* gObj = targets.GetGOTarget())
829 {
830 uint32 identifier;
831 uint8 channelIdentifier;
832 switch (gObj->GetEntry())
833 {
834 case 185052:
835 identifier = DATA_SHIELDGENERATOR1;
836 channelIdentifier = 0;
837 break;
838 case 185053:
839 identifier = DATA_SHIELDGENERATOR2;
840 channelIdentifier = 1;
841 break;
842 case 185051:
843 identifier = DATA_SHIELDGENERATOR3;
844 channelIdentifier = 2;
845 break;
846 case 185054:
847 identifier = DATA_SHIELDGENERATOR4;
848 channelIdentifier = 3;
849 break;
850 default:
851 return true;
852 }
853
854 if (instance->GetData(identifier))
855 return true;
856
857 // get and remove channel
858 if (Unit* channel = ObjectAccessor::GetCreature(*vashj, ENSURE_AI(boss_lady_vashj, vashj->AI())->ShieldGeneratorChannel[channelIdentifier]))
859 channel->setDeathState(JUST_DIED); // call Unsummon()
860
861 instance->SetData(identifier, 1);
862
863 // remove this item
864 player->DestroyItemCount(31088, 1, true);
865 return true;
866 }
867 else if (targets.GetUnitTarget()->GetTypeId() == TYPEID_UNIT)
868 return false;
869 else if (targets.GetUnitTarget()->GetTypeId() == TYPEID_PLAYER)
870 {
871 player->DestroyItemCount(31088, 1, true);
872 player->CastSpell(targets.GetUnitTarget(), 38134, true);
873 return true;
874 }
875 }
876 return true;
877 }
878
879};
880
882{
888 new item_tainted_core();
889}
#define CREATURE_Z_ATTACK_RANGE
Definition: Creature.h:52
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ POINT_MOTION_TYPE
@ TEMPSUMMON_DEAD_DESPAWN
Definition: ObjectDefines.h:69
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition: ObjectDefines.h:66
@ TEMPSUMMON_CORPSE_DESPAWN
Definition: ObjectDefines.h:67
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
@ FACTION_FRIENDLY
@ FACTION_MONSTER
#define ENSURE_AI(a, b)
Definition: UnitAI.h:29
@ MOVE_RUN
Definition: UnitDefines.h:118
@ MOVE_WALK
Definition: UnitDefines.h:117
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:145
@ DEAD
Definition: Unit.h:249
@ JUST_DIED
Definition: Unit.h:247
#define MIDDLE_X
#define SPOREBAT_X
float ElementPos[8][4]
void AddSC_boss_lady_vashj()
float SporebatWPPos[8][3]
LadyVashj
@ SHIED_GENERATOR_CHANNEL
@ SAY_DEATH
@ SPELL_SHOOT
@ SPELL_SHOCK_BLAST
@ SAY_AGGRO
@ SPELL_POISON_BOLT
@ SAY_PHASE3
@ COILFANG_ELITE
@ SPELL_MAGIC_BARRIER
@ SPELL_TOXIC_SPORES
@ TAINTED_ELEMENTAL
@ COILFANG_STRIDER
@ SAY_BOWSHOT
@ SAY_SLAY
@ SPELL_ENTANGLE
@ SPELL_STATIC_CHARGE_TRIGGER
@ TOXIC_SPOREBAT
@ ENCHANTED_ELEMENTAL
@ SPELL_MULTI_SHOT
@ SAY_PHASE2
@ TOXIC_SPORES_TRIGGER
@ SPELL_SURGE
@ SAY_PHASE1
@ SPELL_FORKED_LIGHTNING
@ SAY_INTRO
#define MIDDLE_Y
float CoilfangElitePos[3][4]
#define MIDDLE_Z
#define SPOREBAT_Z
#define SPOREBAT_Y
#define SPOREBAT_O
float CoilfangStriderPos[3][4]
float ShieldGeneratorChannelPos[4][4]
float ElementWPPos[8][3]
void _JustEngagedWith(Unit *who)
void _JustDied()
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 SetCanMelee(bool canMelee, bool fleeFromMelee=false)
Definition: Creature.cpp:2822
void setDeathState(DeathState s) override
Definition: Creature.cpp:2197
float GetAttackDistance(Unit const *player) const
Definition: Creature.cpp:2153
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
bool CanCreatureAttack(Unit const *victim, bool force=true) const
Definition: Creature.cpp:2686
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition: Creature.h:104
CreatureAI * AI() const
Definition: Creature.h:214
virtual ObjectGuid GetGuidData(uint32 type) const override
Definition: Item.h:170
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
PlayerList const & GetPlayers() const
Definition: Map.h:367
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void Clear()
Definition: ObjectGuid.h:286
static Creature * ToCreature(Object *o)
Definition: Object.h:219
TypeID GetTypeId() const
Definition: Object.h:173
uint32 DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: Player.cpp:12281
GameObject * GetGOTarget() const
Definition: Spell.cpp:244
Unit * GetUnitTarget() const
Definition: Spell.cpp:218
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
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
bool IsWithinMeleeRange(Unit const *obj) const
Definition: Unit.h:699
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void SetFaction(uint32 faction) override
Definition: Unit.h:859
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsAlive() const
Definition: Unit.h:1164
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition: Unit.cpp:12725
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
Unit * GetVictim() const
Definition: Unit.h:715
uint64 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:785
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.cpp:8525
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.h:921
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
bool IsInCombat() const
Definition: Unit.h:1043
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1122
Map * GetMap() const
Definition: Object.h:624
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 IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition: Object.cpp:1181
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1078
float GetDistanceZ(WorldObject const *obj) const
Definition: Object.cpp:1048
virtual uint32 GetData(uint32) const
Definition: ZoneScript.h:91
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:92
bool OnUse(Player *player, Item *, SpellCastTargets const &targets, ObjectGuid) override
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
@ DATA_SHIELDGENERATOR1
@ DATA_SHIELDGENERATOR3
@ DATA_SHIELDGENERATOR2
@ DATA_CANSTARTPHASE3
@ DATA_SHIELDGENERATOR4
@ DATA_LADYVASHJ
@ BOSS_LADY_VASHJ
#define RegisterSerpentshrineCavernCreatureAI(ai_name)
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void DoTeleportTo(float x, float y, float z, uint32 time=0)
bool HealthBelowPct(uint32 pct) const
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void KilledUnit(Unit *) override
void Reset() override
void EventTaintedElementalDeath()
uint32 SummonSporebatStaticTimer
void JustEngagedWith(Unit *who) override
void JustDied(Unit *) override
boss_lady_vashj(Creature *creature)
void MoveInLineOfSight(Unit *who) override
ObjectGuid ShieldGeneratorChannel[4]
void UpdateAI(uint32 diff) override
InstanceScript * instance
uint32 EnchantedElementalTimer
void StartEvent(Unit *who)
void UpdateAI(uint32 diff) override
void MoveInLineOfSight(Unit *) override
npc_enchanted_elemental(Creature *creature)
void JustEngagedWith(Unit *) override
void MoveInLineOfSight(Unit *) override
npc_shield_generator_channel(Creature *creature)
void UpdateAI(uint32 diff) override
InstanceScript * instance
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
npc_tainted_elemental(Creature *creature)
void JustDied(Unit *) override
InstanceScript * instance
void UpdateAI(uint32 diff) override
void MovementInform(uint32 type, uint32 id) override
void MoveInLineOfSight(Unit *) override
npc_toxic_sporebat(Creature *creature)
void Reset() override