TrinityCore
boss_hadronox.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#include "ScriptMgr.h"
19#include "azjol_nerub.h"
20#include "InstanceScript.h"
21#include "Map.h"
22#include "MotionMaster.h"
23#include "ObjectAccessor.h"
24#include "ScriptedCreature.h"
25#include "SpellAuraEffects.h"
26#include "SpellAuras.h"
27#include "SpellScript.h"
28#include "TemporarySummon.h"
29
31{
32 // Hadronox
38
39 // Anub'ar Crusher
41
42 // Anub'ar foes - Shared
44
45 // Anub'ar Champion
48
49 // Anub'ar Crypt Guard
52
53 // Anub'ar Necromancer
56};
57
59{
60 // Hadronox
68
69 // Anub'ar opponent summoning spells
79
80 // Anub'ar Crusher
81 SPELL_SMASH = 53318,
82 SPELL_FRENZY = 53801,
83
84 // Anub'ar foes - Shared
85 SPELL_TAUNT = 53798,
86
87 // Anub'ar Champion
88 SPELL_REND = 59343,
89 SPELL_PUMMEL = 59344,
90
91 // Anub'ar Crypt Guard
94
95 // Anub'ar Necromancer
99};
100
102{
107
109{
114
116{
121
123{
124 NPC_CRUSHER = 28922,
127
129{
134
135// Movement IDs used by the permanently spawning Anub'ar opponents - they are done in sequence, as one finishes, the next one starts
137{
142 MOVE_HADRONOX, // this one might have us take a detour to avoid pathfinding "through" the floor...
143 MOVE_HADRONOX_REAL // while this one will always make us movechase
145
146static const uint8 NUM_STEPS = 4;
148{
149 { 515.5848f, 544.2007f, 673.6272f },
150 { 562.191f , 514.068f , 696.4448f },
151 { 610.3828f, 518.6407f, 695.9385f },
152 { 530.42f , 560.003f, 733.0308f }
153};
154
155struct boss_hadronox : public BossAI
156{
158
160 {
161 for (auto const& pair : me->GetCombatManager().GetPvECombatRefs())
162 if (pair.second->GetOther(me)->IsControlledByPlayer())
163 return true;
164 return false;
165 }
166
167 void SetStep(uint8 step)
168 {
170 return;
171
172 _step = step;
176 me->AttackStop();
178 }
179
181 {
182 std::list<TempSummon*> summoned;
183 me->SummonCreatureGroup(group, &summoned);
184 for (TempSummon* summon : summoned)
185 {
186 summon->AI()->SetData(DATA_CRUSHER_PACK_ID, group);
187 summon->AI()->DoAction(ACTION_PACK_WALK);
188 }
189 }
190
191 void MovementInform(uint32 type, uint32 /*id*/) override
192 {
193 if (type != POINT_MOTION_TYPE)
194 return;
196 if (_step < NUM_STEPS-1)
197 return;
200 _doorsWebbed = true;
202 }
203
204 uint32 GetData(uint32 data) const override
205 {
207 return _enteredCombat ? 1 : 0;
208 if (data == DATA_HADRONOX_WEBBED_DOORS)
209 return _doorsWebbed ? 1 : 0;
210 return 0;
211 }
212
213 bool CanAIAttack(Unit const* target) const override
214 {
215 // Prevent Hadronox from going too far from her current home position
216 if (!target->IsControlledByPlayer() && target->GetDistance(me->GetHomePosition()) > 70.0f)
217 return false;
218 return BossAI::CanAIAttack(target);
219 }
220
221 void JustEngagedWith(Unit* /*who*/) override
222 {
228 me->setActive(true);
229 }
230
231 void DoAction(int32 action) override
232 {
233 switch (action)
234 {
236 if (_enteredCombat)
237 break;
239 _enteredCombat = true;
242 break;
244 if (_step < NUM_STEPS-1)
245 {
246 SetStep(_step + 1);
248 }
249 break;
250 }
251 }
252
253 void EnterEvadeMode(EvadeReason /*why*/) override
254 {
255 std::list<Creature*> triggers;
257 for (Creature* trigger : triggers)
258 if (trigger->HasAura(SPELL_SUMMON_CHAMPION_PERIODIC) || trigger->HasAura(SPELL_WEB_FRONT_DOORS) || trigger->HasAura(SPELL_WEB_SIDE_DOORS))
259 _DespawnAtEvade(25s, trigger);
260 _DespawnAtEvade(25s);
262 for (ObjectGuid gNerubian : _anubar)
263 if (Creature* nerubian = ObjectAccessor::GetCreature(*me, gNerubian))
264 nerubian->DespawnOrUnsummon();
265 }
266
267 void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
268 {
269 _anubar.push_back(guid);
270 }
271
272 void InitializeAI() override
273 {
276 me->SetBoundingRadius(9.0f);
277 me->SetCombatReach(9.0f);
278 _enteredCombat = false;
279 _doorsWebbed = false;
281 SetStep(0);
282 }
283
284 void JustAppeared() override
285 {
287 SetCombatMovement(true);
289 }
290
291 void UpdateAI(uint32 diff) override
292 {
293 if (!UpdateVictim())
294 return;
295
296 events.Update(diff);
297
299 return;
300
301 while (uint32 eventId = events.ExecuteEvent())
302 {
303 switch (eventId)
304 {
308 break;
309 case EVENT_ACID_CLOUD:
310 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f))
311 DoCast(target, SPELL_ACID_CLOUD);
313 break;
314 case EVENT_WEB_GRAB:
317 break;
321 break;
324 {
326 if (_lastPlayerCombatState) // we are now in combat with players
327 {
329 {
331 return;
332 }
333 // cancel current point movement if engaged by players
335 {
337 SetCombatMovement(true);
339 }
340 }
341 else // we are no longer in combat with players - reset the encounter
343 }
345 break;
346 }
347
349 return;
350 }
351 }
352
353 // Safeguard to prevent Hadronox dying to NPCs
354 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
355 {
356 if ((!who || !who->IsControlledByPlayer()) && me->HealthBelowPct(70))
357 {
358 if (me->HealthBelowPctDamaged(5, damage))
359 damage = 0;
360 else
361 damage *= (me->GetHealthPct()-5.0f)/ 65.0f;
362 }
363 }
364
365 void JustSummoned(Creature* summon) override
366 {
367 summons.Summon(summon);
368 // Do not enter combat with zone
369 }
370
371 private:
372 bool _enteredCombat; // has a player entered combat with the first crusher pack? (talk and spawn two more packs)
373 bool _doorsWebbed; // obvious - have we reached the top and webbed the doors shut? (trigger for hadronox denied achievement)
374 bool _lastPlayerCombatState; // was there a player in our threat list the last time we checked (we check every second)
376 std::list<ObjectGuid> _anubar;
377};
378
380{
381 npc_hadronox_crusherPackAI(Creature* creature, Position const* positions) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _positions(positions), _myPack(SummonGroups(0)), _doFacing(false) { }
382
383 void DoAction(int32 action) override
384 {
385 if (action == ACTION_PACK_WALK)
386 {
387 switch (_myPack)
388 {
393 break;
394 default:
395 break;
396 }
397 }
398 }
399
400 void MovementInform(uint32 type, uint32 id) override
401 {
402 if (type == POINT_MOTION_TYPE && id == ACTION_PACK_WALK)
403 _doFacing = true;
404 }
405
406 void EnterEvadeMode(EvadeReason /*why*/) override
407 {
409 hadronox->AI()->EnterEvadeMode(EvadeReason::Other);
410 }
411
412 uint32 GetData(uint32 data) const override
413 {
414 if (data == DATA_CRUSHER_PACK_ID)
415 return _myPack;
416 return 0;
417 }
418
419 void SetData(uint32 data, uint32 value) override
420 {
421 if (data == DATA_CRUSHER_PACK_ID)
422 {
423 _myPack = SummonGroups(value);
425 }
426 }
427
428 void JustEngagedWith(Unit* who) override
429 {
431 {
432 std::list<Creature*> others;
433 me->GetCreatureListWithEntryInGrid(others, 0, 40.0f);
434 for (Creature* other : others)
435 if (other->AI()->GetData(DATA_CRUSHER_PACK_ID) == _myPack)
436 {
437 other->SetReactState(REACT_AGGRESSIVE);
438 other->AI()->AttackStart(who);
439 }
440 }
443 }
444
445 virtual void _JustEngagedWith() = 0;
446 virtual void DoEvent(uint32 /*eventId*/) = 0;
447
448 void MoveInLineOfSight(Unit* who) override
449 {
451 {
453 return;
454 }
455
456 if (me->CanStartAttack(who, false) && me->IsWithinDistInMap(who, me->GetAttackDistance(who) + me->m_CombatDistance))
457 JustEngagedWith(who);
458 }
459
460 void UpdateAI(uint32 diff) override
461 {
462 if (_doFacing)
463 {
464 _doFacing = false;
466 }
467
468 if (!UpdateVictim())
469 return;
470
471 _events.Update(diff);
472
473 while (uint32 eventId = _events.ExecuteEvent())
474 DoEvent(eventId);
475 }
476
477 protected:
480 Position const* const _positions;
483
484};
485
487{
488 { 529.6913f, 547.1257f, 731.9155f, 4.799650f },
489 { 517.51f , 561.439f , 734.0306f, 4.520403f },
490 { 543.414f , 551.728f , 732.0522f, 3.996804f }
491};
493{
495
496 void _JustEngagedWith() override
497 {
499
501 return;
502
504 {
505 if (hadronox->AI()->GetData(DATA_HADRONOX_ENTERED_COMBAT))
506 return;
507 hadronox->AI()->DoAction(ACTION_CRUSHER_ENGAGED);
508 }
509
511 }
512
513 void DamageTaken(Unit* /*source*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
514 {
515 if (_hadFrenzy || !me->HealthBelowPctDamaged(25, damage))
516 return;
517 _hadFrenzy = true;
520 }
521
522 void DoEvent(uint32 eventId) override
523 {
524 switch (eventId)
525 {
526 case EVENT_SMASH:
529 break;
530 }
531 }
532
533 void JustDied(Unit* killer) override
534 {
536 hadronox->AI()->DoAction(ACTION_HADRONOX_MOVE);
537 ScriptedAI::JustDied(killer);
538 }
539
540 private:
542};
543
545{
546 { 539.2076f, 549.7539f, 732.8668f, 4.55531f },
547 { 527.3098f, 559.5197f, 732.9407f, 4.742493f },
548 { }
549};
551{
553
554 void DoEvent(uint32 eventId) override
555 {
556 switch (eventId)
557 {
558 case EVENT_REND:
561 break;
562 case EVENT_PUMMEL:
565 break;
566 }
567 }
568
569 void _JustEngagedWith() override
570 {
573 }
574};
575
577{
578 { 520.3911f, 548.7895f, 732.0118f, 5.0091f },
579 { },
580 { 550.9611f, 545.1674f, 731.9031f, 3.996804f }
581};
583{
585
586 void DoEvent(uint32 eventId) override
587 {
588 switch (eventId)
589 {
593 break;
597 break;
598 }
599 }
600
601 void _JustEngagedWith() override
602 {
605 }
606};
607
609{
610 { },
611 { 507.6937f, 563.3471f, 734.8986f, 4.520403f },
612 { 535.1049f, 552.8961f, 732.8441f, 3.996804f },
613};
615{
617
618 void DoEvent(uint32 eventId) override
619 {
620 switch (eventId)
621 {
625 break;
629 break;
630 }
631 }
632
633 void _JustEngagedWith() override
634 {
637 }
638};
639
640static const uint8 NUM_SPAWNS = 3;
642{
643 { 485.314606f, 611.418640f, 771.428406f },
644 { 575.760437f, 611.516418f, 771.427368f },
645 { 588.930725f, 598.233276f, 739.142151f }
646};
648{
649 { 513.574341f, 587.022156f, 736.229065f },
650 { 537.920410f, 580.436157f, 732.796692f },
651 { 601.289246f, 583.259644f, 725.443054f },
652};
654{
655 { 571.498718f, 576.978333f, 727.582947f },
656 { 571.498718f, 576.978333f, 727.582947f },
657 { }
658};
660{
661 npc_hadronox_foeAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _nextMovement(MOVE_OUTSIDE), _mySpawn(0) { }
662
663 void InitializeAI() override
664 {
667 hadronox->AI()->SetGUID(me->GetGUID());
668 }
669
670 void MovementInform(uint32 type, uint32 id) override
671 {
672 if (type == POINT_MOTION_TYPE)
673 _nextMovement = Movements(id+1);
674 }
675
676 void EnterEvadeMode(EvadeReason /*why*/) override
677 {
679 }
680
681 virtual void DoEvent(uint32 /*eventId*/) = 0;
682
683 void UpdateAI(uint32 diff) override
684 {
685 if (_nextMovement)
686 {
687 switch (_nextMovement)
688 {
689 case MOVE_OUTSIDE:
690 {
691 float dist = HUGE_VALF;
692 for (uint8 spawn = 0; spawn < NUM_SPAWNS; ++spawn)
693 {
694 float thisDist = initialMoves[spawn].GetExactDistSq(me);
695 if (thisDist < dist)
696 {
697 _mySpawn = spawn;
698 dist = thisDist;
699 }
700 }
701 me->GetMotionMaster()->MovePoint(MOVE_OUTSIDE, initialMoves[_mySpawn], false); // do not pathfind here, we have to pass through a "wall" of webbing
702 break;
703 }
704 case MOVE_DOWNSTAIRS:
706 break;
708 if (downstairsMoves2[_mySpawn].GetPositionX() > 0.0f) // might be unset for this spawn - if yes, skip
709 {
711 break;
712 }
713 [[fallthrough]];
714 case MOVE_HADRONOX:
716 {
717 static const float zCutoff = 702.0f;
719 if (hadronox && hadronox->IsAlive())
720 {
722 if (hadronox->GetPositionZ() < zCutoff)
723 {
725 break;
726 }
727 AttackStart(hadronox);
728 }
729 break;
730 }
731 default:
732 break;
733 }
735 }
736
737 if (!UpdateVictim())
738 return;
739
740 _events.Update(diff);
741
742 while (uint32 eventId = _events.ExecuteEvent())
743 DoEvent(eventId);
744 }
745
746 protected:
749
750 private:
753};
754
756{
758
759 void DoEvent(uint32 eventId) override
760 {
761 switch (eventId)
762 {
763 case EVENT_REND:
766 break;
767 case EVENT_PUMMEL:
770 break;
771 case EVENT_TAUNT:
774 break;
775 }
776 }
777
778 void JustEngagedWith(Unit* /*who*/) override
779 {
783 }
784};
785
787{
789
790 void DoEvent(uint32 eventId) override
791 {
792 switch (eventId)
793 {
797 break;
801 break;
802 case EVENT_TAUNT:
805 break;
806 }
807 }
808
809 void JustEngagedWith(Unit* /*who*/) override
810 {
814 }
815};
816
818{
820
821 void DoEvent(uint32 eventId) override
822 {
823 switch (eventId)
824 {
828 break;
832 break;
833 case EVENT_TAUNT:
836 break;
837 }
838 }
839
840 void JustEngagedWith(Unit* /*who*/) override
841 {
845 }
846};
847
849{
850 public:
851 spell_hadronox_periodic_summon_template_AuraScript(uint32 topSpellId, uint32 bottomSpellId) : AuraScript(), _topSpellId(topSpellId), _bottomSpellId(bottomSpellId) { }
852
853 private:
854 bool Validate(SpellInfo const* /*spell*/) override
855 {
857 }
858
859 void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
860 {
861 if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_0))
862 effect->SetPeriodicTimer(urandms(2, 17));
863 }
864
865 void HandlePeriodic(AuraEffect const* /*eff*/)
866 {
867 Unit* caster = GetCaster();
868 if (!caster)
869 return;
870 InstanceScript* instance = caster->GetInstanceScript();
871 if (!instance)
872 return;
873 if (!instance->instance->HavePlayers())
874 return;
875 if (instance->GetBossState(DATA_HADRONOX) == DONE)
876 GetAura()->Remove();
877 else
878 {
879 if (caster->GetPositionZ() >= 750.0f)
880 caster->CastSpell(caster, _topSpellId, true);
881 else
882 caster->CastSpell(caster, _bottomSpellId, true);
883 }
884 }
885
886 void Register() override
887 {
890 }
891
894};
895
896// 53035 - Summon Anub'ar Champion Periodic
898{
899 public:
900 spell_hadronox_periodic_summon_champion() : SpellScriptLoader("spell_hadronox_periodic_summon_champion") { }
901
903 {
904 public:
906 };
907
908 AuraScript* GetAuraScript() const override
909 {
911 }
912};
913
914// 53037 - Summon Anub'ar Crypt Fiend Periodic
916{
917 public:
918 spell_hadronox_periodic_summon_crypt_fiend() : SpellScriptLoader("spell_hadronox_periodic_summon_crypt_fiend") { }
919
921 {
922 public:
924 };
925
926 AuraScript* GetAuraScript() const override
927 {
929 }
930};
931
932// 53036 - Summon Anub'ar Necromancer Periodic
934{
935 public:
936 spell_hadronox_periodic_summon_necromancer() : SpellScriptLoader("spell_hadronox_periodic_summon_necromancer") { }
937
939 {
940 public:
942 };
943
944 AuraScript* GetAuraScript() const override
945 {
947 }
948};
949
950// 53030, 59417 - Leech Poison
952{
953 bool Validate(SpellInfo const* /*spell*/) override
954 {
956 }
957
958 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
959 {
960 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
961 return;
962
963 if (GetTarget()->IsGuardian())
964 return;
965
966 if (Unit* caster = GetCaster())
967 caster->CastSpell(caster, SPELL_LEECH_POISON_HEAL, true);
968 }
969
970 void Register() override
971 {
973 }
974};
975
976// 53177 - Web Front Doors
977// 53185 - Web Side Door
979{
980 bool Validate(SpellInfo const* /*spell*/) override
981 {
983 }
984
985 void HandleDummy(SpellEffIndex /*effIndex*/)
986 {
987 if (Unit* target = GetHitUnit())
988 {
989 target->RemoveAurasDueToSpell(SPELL_SUMMON_CHAMPION_PERIODIC);
990 target->RemoveAurasDueToSpell(SPELL_SUMMON_CRYPT_FIEND_PERIODIC);
991 target->RemoveAurasDueToSpell(SPELL_SUMMON_NECROMANCER_PERIODIC);
992 }
993 }
994
995 void Register() override
996 {
998 }
999};
1000
1002{
1003 public:
1004 achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied") { }
1005
1006 bool OnCheck(Player* /*player*/, Unit* target) override
1007 {
1008 if (!target)
1009 return false;
1010
1011 if (Creature* cTarget = target->ToCreature())
1012 if (!cTarget->AI()->GetData(DATA_HADRONOX_WEBBED_DOORS))
1013 return true;
1014
1015 return false;
1016 }
1017};
1018
1020{
1022
1027
1031
1035
1038
1040}
Actions
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
@ IN_PROGRESS
@ DONE
@ POINT_MOTION_TYPE
Spells
Definition: PlayerAI.cpp:32
Milliseconds randtime(Milliseconds min, Milliseconds max)
Definition: Random.cpp:62
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 urandms(uint32 min, uint32 max)
Definition: Random.cpp:49
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_EFFECT_APPLY_AURA
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_DEATH
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_PERIODIC_DUMMY
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ DATA_HADRONOX
Definition: azjol_nerub.h:32
#define RegisterAzjolNerubCreatureAI(ai_name)
Definition: azjol_nerub.h:75
@ SUMMON_GROUP_CRUSHER_3
@ SUMMON_GROUP_CRUSHER_2
@ SUMMON_GROUP_CRUSHER_1
static const Position initialMoves[NUM_SPAWNS]
@ ACTION_CRUSHER_ENGAGED
@ ACTION_PACK_WALK
@ ACTION_HADRONOX_MOVE
@ NPC_WORLDTRIGGER_LARGE
@ NPC_CRUSHER
static const uint8 NUM_SPAWNS
static const Position necromancerWaypoints[]
@ SPELL_SUMMON_CRYPT_FIEND_BOTTOM
@ SPELL_SUMMON_NECROMANCER_BOTTOM
@ SPELL_CRUSHING_WEBS
@ SPELL_LEECH_POISON
@ SPELL_ACID_CLOUD
@ SPELL_SUMMON_CRYPT_FIEND_PERIODIC
@ SPELL_ANIMATE_BONES_1
@ SPELL_WEB_FRONT_DOORS
@ SPELL_SUMMON_NECROMANCER_TOP
@ SPELL_SUMMON_CHAMPION_TOP
@ SPELL_PUMMEL
@ SPELL_LEECH_POISON_HEAL
@ SPELL_TAUNT
@ SPELL_SUMMON_CRYPT_FIEND_TOP
@ SPELL_SHADOW_BOLT
@ SPELL_SMASH
@ SPELL_FRENZY
@ SPELL_WEB_GRAB
@ SPELL_SUMMON_NECROMANCER_PERIODIC
@ SPELL_REND
@ SPELL_SUMMON_CHAMPION_PERIODIC
@ SPELL_WEB_SIDE_DOORS
@ SPELL_ANIMATE_BONES_2
@ SPELL_PIERCE_ARMOR
@ SPELL_SUMMON_CHAMPION_BOTTOM
@ SPELL_INFECTED_WOUND
static const Position hadronoxStep[NUM_STEPS]
@ HADRONOX_EMOTE_MOVE
@ CRUSHER_EMOTE_FRENZY
@ CRUSHER_SAY_AGGRO
SummonGroups
static const uint8 NUM_STEPS
static const Position downstairsMoves[NUM_SPAWNS]
static const Position cryptFiendWaypoints[]
void AddSC_boss_hadronox()
static const Position crusherWaypoints[]
static const Position championWaypoints[]
Movements
@ MOVE_OUTSIDE
@ MOVE_HADRONOX
@ MOVE_DOWNSTAIRS_2
@ MOVE_DOWNSTAIRS
@ MOVE_NONE
@ MOVE_HADRONOX_REAL
@ DATA_HADRONOX_WEBBED_DOORS
@ DATA_CRUSHER_PACK_ID
@ DATA_HADRONOX_ENTERED_COMBAT
@ EVENT_INFECTED_WOUND
@ EVENT_LEECH_POISON
@ EVENT_ACID_CLOUD
@ EVENT_REND
@ EVENT_TAUNT
@ EVENT_SMASH
@ EVENT_PLAYER_CHECK
@ EVENT_PUMMEL
@ EVENT_PIERCE_ARMOR
@ EVENT_ANIMATE_BONES
@ EVENT_WEB_GRAB
@ EVENT_SHADOW_BOLT
@ EVENT_CRUSHING_WEBS
static const Position downstairsMoves2[NUM_SPAWNS]
SummonGroups
AuraApplication const * GetTargetApplication() const
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2028
Unit * GetCaster() const
AuraEffect * GetEffect(uint8 effIndex) const
Aura * GetAura() const
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:2035
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
InstanceScript *const instance
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
bool CanAIAttack(Unit const *target) const override
SummonList summons
EventMap events
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
virtual void MoveInLineOfSight(Unit *)
Definition: CreatureAI.cpp:122
virtual void JustEngagedWith(Unit *)
Definition: CreatureAI.h:99
void DoZoneInCombat()
Definition: CreatureAI.h:161
virtual void JustDied(Unit *)
Definition: CreatureAI.h:105
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
virtual void JustAppeared()
Definition: CreatureAI.cpp:194
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:371
float GetAttackDistance(Unit const *player) const
Definition: Creature.cpp:2153
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition: Creature.h:373
bool HasReactState(ReactStates state) const
Definition: Creature.h:162
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
float m_CombatDistance
Definition: Creature.h:412
bool CanStartAttack(Unit const *u, bool force) const
Definition: Creature.cpp:2099
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
virtual bool SetBossState(uint32 id, EncounterState state)
Creature * GetCreature(uint32 type)
InstanceMap * instance
EncounterState GetBossState(uint32 id) const
virtual bool CheckRequiredBosses(uint32, Player const *=nullptr) const
bool HavePlayers() const
Definition: Map.h:357
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
static Creature * ToCreature(Object *o)
Definition: Object.h:219
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
void Summon(Creature const *summon)
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
virtual void InitializeAI()
Definition: UnitAI.cpp:43
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 DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
float GetHealthPct() const
Definition: Unit.h:784
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsAlive() const
Definition: Unit.h:1164
void SetBoundingRadius(float boundingRadius)
Definition: Unit.h:697
void SetCombatReach(float combatReach)
Definition: Unit.h:695
bool HealthBelowPct(int32 pct) const
Definition: Unit.h:780
Unit * GetVictim() const
Definition: Unit.h:715
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool IsControlledByPlayer() const
Definition: Unit.h:1193
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:781
CombatManager & GetCombatManager()
Definition: Unit.h:1023
bool AttackStop()
Definition: Unit.cpp:5781
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3312
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
void setActive(bool isActiveObject)
Definition: Object.cpp:922
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
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition: Object.cpp:2131
bool OnCheck(Player *, Unit *target) override
bool Validate(SpellInfo const *) override
void HandleEffectRemove(AuraEffect const *, AuraEffectHandleModes)
AuraScript * GetAuraScript() const override
AuraScript * GetAuraScript() const override
AuraScript * GetAuraScript() const override
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
spell_hadronox_periodic_summon_template_AuraScript(uint32 topSpellId, uint32 bottomSpellId)
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
constexpr float GetExactDistSq(float x, float y, float z) const
Definition: Position.h:110
constexpr float GetPositionZ() const
Definition: Position.h:78
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void SetCombatMovement(bool allowMovement)
bool IsInCombatWithPlayer() const
void DamageTaken(Unit *who, uint32 &damage, DamageEffectType, SpellInfo const *) override
bool _lastPlayerCombatState
void JustEngagedWith(Unit *) override
void DoAction(int32 action) override
void InitializeAI() override
void JustSummoned(Creature *summon) override
void MovementInform(uint32 type, uint32) override
void SetStep(uint8 step)
void SetGUID(ObjectGuid const &guid, int32) override
boss_hadronox(Creature *creature)
bool CanAIAttack(Unit const *target) const override
void JustAppeared() override
void EnterEvadeMode(EvadeReason) override
std::list< ObjectGuid > _anubar
uint32 GetData(uint32 data) const override
void SummonCrusherPack(SummonGroups group)
void UpdateAI(uint32 diff) override
void DoEvent(uint32 eventId) override
npc_anub_ar_champion(Creature *creature)
void JustEngagedWith(Unit *) override
void DoEvent(uint32 eventId) override
npc_anub_ar_crusher_champion(Creature *creature)
void DoEvent(uint32 eventId) override
npc_anub_ar_crusher_crypt_fiend(Creature *creature)
npc_anub_ar_crusher_necromancer(Creature *creature)
void DoEvent(uint32 eventId) override
npc_anub_ar_crusher(Creature *creature)
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustDied(Unit *killer) override
void _JustEngagedWith() override
void DoEvent(uint32 eventId) override
void DoEvent(uint32 eventId) override
void JustEngagedWith(Unit *) override
npc_anub_ar_crypt_fiend(Creature *creature)
void DoEvent(uint32 eventId) override
npc_anub_ar_necromancer(Creature *creature)
void JustEngagedWith(Unit *) override
InstanceScript *const _instance
void UpdateAI(uint32 diff) override
void MoveInLineOfSight(Unit *who) override
void DoAction(int32 action) override
virtual void _JustEngagedWith()=0
virtual void DoEvent(uint32)=0
void MovementInform(uint32 type, uint32 id) override
Position const *const _positions
npc_hadronox_crusherPackAI(Creature *creature, Position const *positions)
void SetData(uint32 data, uint32 value) override
void JustEngagedWith(Unit *who) override
void EnterEvadeMode(EvadeReason) override
uint32 GetData(uint32 data) const override
void MovementInform(uint32 type, uint32 id) override
virtual void DoEvent(uint32)=0
void EnterEvadeMode(EvadeReason) override
void InitializeAI() override
void UpdateAI(uint32 diff) override
InstanceScript *const _instance
npc_hadronox_foeAI(Creature *creature)