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};
122
124{
125 NPC_CRUSHER = 28922,
128
130{
135
136// Movement IDs used by the permanently spawning Anub'ar opponents - they are done in sequence, as one finishes, the next one starts
138{
143 MOVE_HADRONOX, // this one might have us take a detour to avoid pathfinding "through" the floor...
144 MOVE_HADRONOX_REAL // while this one will always make us movechase
146
147static const uint8 NUM_STEPS = 4;
149{
150 { 515.5848f, 544.2007f, 673.6272f },
151 { 562.191f , 514.068f , 696.4448f },
152 { 610.3828f, 518.6407f, 695.9385f },
153 { 530.42f , 560.003f, 733.0308f }
154};
155
156struct boss_hadronox : public BossAI
157{
159
161 {
162 for (auto const& pair : me->GetCombatManager().GetPvECombatRefs())
163 if (pair.second->GetOther(me)->IsControlledByPlayer())
164 return true;
165 return false;
166 }
167
168 void SetStep(uint8 step)
169 {
171 return;
172
173 _step = step;
177 me->AttackStop();
179 }
180
182 {
183 std::list<TempSummon*> summoned;
184 me->SummonCreatureGroup(group, &summoned);
185 for (TempSummon* summon : summoned)
186 {
187 summon->AI()->SetData(DATA_CRUSHER_PACK_ID, group);
188 summon->AI()->DoAction(ACTION_PACK_WALK);
189 }
190 }
191
192 void MovementInform(uint32 type, uint32 /*id*/) override
193 {
194 if (type != POINT_MOTION_TYPE)
195 return;
197 if (_step < NUM_STEPS-1)
198 return;
201 _doorsWebbed = true;
203 }
204
205 uint32 GetData(uint32 data) const override
206 {
208 return _enteredCombat ? 1 : 0;
209 if (data == DATA_HADRONOX_WEBBED_DOORS)
210 return _doorsWebbed ? 1 : 0;
211 return 0;
212 }
213
214 bool CanAIAttack(Unit const* target) const override
215 {
216 // Prevent Hadronox from going too far from her current home position
217 if (!target->IsControlledByPlayer() && target->GetDistance(me->GetHomePosition()) > 70.0f)
218 return false;
219 return BossAI::CanAIAttack(target);
220 }
221
222 void JustEngagedWith(Unit* /*who*/) override
223 {
229 me->setActive(true);
230 }
231
232 void DoAction(int32 action) override
233 {
234 switch (action)
235 {
237 if (_enteredCombat)
238 break;
240 _enteredCombat = true;
243 break;
245 if (_step < NUM_STEPS-1)
246 {
247 SetStep(_step + 1);
249 }
250 break;
251 }
252 }
253
254 void EnterEvadeMode(EvadeReason /*why*/) override
255 {
256 std::list<Creature*> triggers;
258 for (Creature* trigger : triggers)
259 if (trigger->HasAura(SPELL_SUMMON_CHAMPION_PERIODIC) || trigger->HasAura(SPELL_WEB_FRONT_DOORS) || trigger->HasAura(SPELL_WEB_SIDE_DOORS))
260 _DespawnAtEvade(25s, trigger);
261 _DespawnAtEvade(25s);
263 for (ObjectGuid gNerubian : _anubar)
264 if (Creature* nerubian = ObjectAccessor::GetCreature(*me, gNerubian))
265 nerubian->DespawnOrUnsummon();
266 }
267
268 void SetGUID(ObjectGuid const& guid, int32 id) override
269 {
270 if (id != DATA_ANUBAR_GUID)
271 return;
272
273 _anubar.push_back(guid);
274 }
275
276 void InitializeAI() override
277 {
280 me->SetBoundingRadius(9.0f);
281 me->SetCombatReach(9.0f);
282 _enteredCombat = false;
283 _doorsWebbed = false;
285 SetStep(0);
286 }
287
288 void JustAppeared() override
289 {
291 SetCombatMovement(true);
293 }
294
295 void UpdateAI(uint32 diff) override
296 {
297 if (!UpdateVictim())
298 return;
299
300 events.Update(diff);
301
303 return;
304
305 while (uint32 eventId = events.ExecuteEvent())
306 {
307 switch (eventId)
308 {
312 break;
313 case EVENT_ACID_CLOUD:
314 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f))
315 DoCast(target, SPELL_ACID_CLOUD);
317 break;
318 case EVENT_WEB_GRAB:
321 break;
325 break;
328 {
330 if (_lastPlayerCombatState) // we are now in combat with players
331 {
333 {
335 return;
336 }
337 // cancel current point movement if engaged by players
339 {
341 SetCombatMovement(true);
343 }
344 }
345 else // we are no longer in combat with players - reset the encounter
347 }
349 break;
350 }
351
353 return;
354 }
355 }
356
357 // Safeguard to prevent Hadronox dying to NPCs
358 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
359 {
360 if ((!who || !who->IsControlledByPlayer()) && me->HealthBelowPct(70))
361 {
362 if (me->HealthBelowPctDamaged(5, damage))
363 damage = 0;
364 else
365 damage *= (me->GetHealthPct()-5.0f)/ 65.0f;
366 }
367 }
368
369 void JustSummoned(Creature* summon) override
370 {
371 summons.Summon(summon);
372 // Do not enter combat with zone
373 }
374
375 private:
376 bool _enteredCombat; // has a player entered combat with the first crusher pack? (talk and spawn two more packs)
377 bool _doorsWebbed; // obvious - have we reached the top and webbed the doors shut? (trigger for hadronox denied achievement)
378 bool _lastPlayerCombatState; // was there a player in our threat list the last time we checked (we check every second)
380 std::list<ObjectGuid> _anubar;
381};
382
384{
385 npc_hadronox_crusherPackAI(Creature* creature, Position const* positions) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _positions(positions), _myPack(SummonGroups(0)), _doFacing(false) { }
386
387 void DoAction(int32 action) override
388 {
389 if (action == ACTION_PACK_WALK)
390 {
391 switch (_myPack)
392 {
397 break;
398 default:
399 break;
400 }
401 }
402 }
403
404 void MovementInform(uint32 type, uint32 id) override
405 {
406 if (type == POINT_MOTION_TYPE && id == ACTION_PACK_WALK)
407 _doFacing = true;
408 }
409
410 void EnterEvadeMode(EvadeReason /*why*/) override
411 {
413 hadronox->AI()->EnterEvadeMode(EvadeReason::Other);
414 }
415
416 uint32 GetData(uint32 data) const override
417 {
418 if (data == DATA_CRUSHER_PACK_ID)
419 return _myPack;
420 return 0;
421 }
422
423 void SetData(uint32 data, uint32 value) override
424 {
425 if (data == DATA_CRUSHER_PACK_ID)
426 {
427 _myPack = SummonGroups(value);
429 }
430 }
431
432 void JustEngagedWith(Unit* who) override
433 {
435 {
436 std::list<Creature*> others;
437 me->GetCreatureListWithEntryInGrid(others, 0, 40.0f);
438 for (Creature* other : others)
439 if (other->AI()->GetData(DATA_CRUSHER_PACK_ID) == _myPack)
440 {
441 other->SetReactState(REACT_AGGRESSIVE);
442 other->AI()->AttackStart(who);
443 }
444 }
447 }
448
449 virtual void _JustEngagedWith() = 0;
450 virtual void DoEvent(uint32 /*eventId*/) = 0;
451
452 void MoveInLineOfSight(Unit* who) override
453 {
455 {
457 return;
458 }
459
460 if (me->CanStartAttack(who, false) && me->IsWithinDistInMap(who, me->GetAttackDistance(who) + me->m_CombatDistance))
461 JustEngagedWith(who);
462 }
463
464 void UpdateAI(uint32 diff) override
465 {
466 if (_doFacing)
467 {
468 _doFacing = false;
470 }
471
472 if (!UpdateVictim())
473 return;
474
475 _events.Update(diff);
476
477 while (uint32 eventId = _events.ExecuteEvent())
478 DoEvent(eventId);
479 }
480
481 protected:
484 Position const* const _positions;
487
488};
489
491{
492 { 529.6913f, 547.1257f, 731.9155f, 4.799650f },
493 { 517.51f , 561.439f , 734.0306f, 4.520403f },
494 { 543.414f , 551.728f , 732.0522f, 3.996804f }
495};
497{
499
500 void _JustEngagedWith() override
501 {
503
505 return;
506
508 {
509 if (hadronox->AI()->GetData(DATA_HADRONOX_ENTERED_COMBAT))
510 return;
511 hadronox->AI()->DoAction(ACTION_CRUSHER_ENGAGED);
512 }
513
515 }
516
517 void DamageTaken(Unit* /*source*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
518 {
519 if (_hadFrenzy || !me->HealthBelowPctDamaged(25, damage))
520 return;
521 _hadFrenzy = true;
524 }
525
526 void DoEvent(uint32 eventId) override
527 {
528 switch (eventId)
529 {
530 case EVENT_SMASH:
533 break;
534 }
535 }
536
537 void JustDied(Unit* killer) override
538 {
540 hadronox->AI()->DoAction(ACTION_HADRONOX_MOVE);
541 ScriptedAI::JustDied(killer);
542 }
543
544 private:
546};
547
549{
550 { 539.2076f, 549.7539f, 732.8668f, 4.55531f },
551 { 527.3098f, 559.5197f, 732.9407f, 4.742493f },
552 { }
553};
555{
557
558 void DoEvent(uint32 eventId) override
559 {
560 switch (eventId)
561 {
562 case EVENT_REND:
565 break;
566 case EVENT_PUMMEL:
569 break;
570 }
571 }
572
573 void _JustEngagedWith() override
574 {
577 }
578};
579
581{
582 { 520.3911f, 548.7895f, 732.0118f, 5.0091f },
583 { },
584 { 550.9611f, 545.1674f, 731.9031f, 3.996804f }
585};
587{
589
590 void DoEvent(uint32 eventId) override
591 {
592 switch (eventId)
593 {
597 break;
601 break;
602 }
603 }
604
605 void _JustEngagedWith() override
606 {
609 }
610};
611
613{
614 { },
615 { 507.6937f, 563.3471f, 734.8986f, 4.520403f },
616 { 535.1049f, 552.8961f, 732.8441f, 3.996804f },
617};
619{
621
622 void DoEvent(uint32 eventId) override
623 {
624 switch (eventId)
625 {
629 break;
633 break;
634 }
635 }
636
637 void _JustEngagedWith() override
638 {
641 }
642};
643
644static const uint8 NUM_SPAWNS = 3;
646{
647 { 485.314606f, 611.418640f, 771.428406f },
648 { 575.760437f, 611.516418f, 771.427368f },
649 { 588.930725f, 598.233276f, 739.142151f }
650};
652{
653 { 513.574341f, 587.022156f, 736.229065f },
654 { 537.920410f, 580.436157f, 732.796692f },
655 { 601.289246f, 583.259644f, 725.443054f },
656};
658{
659 { 571.498718f, 576.978333f, 727.582947f },
660 { 571.498718f, 576.978333f, 727.582947f },
661 { }
662};
664{
665 npc_hadronox_foeAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _nextMovement(MOVE_OUTSIDE), _mySpawn(0) { }
666
667 void InitializeAI() override
668 {
671 hadronox->AI()->SetGUID(me->GetGUID(), DATA_ANUBAR_GUID);
672 }
673
674 void MovementInform(uint32 type, uint32 id) override
675 {
676 if (type == POINT_MOTION_TYPE)
677 _nextMovement = Movements(id+1);
678 }
679
680 void EnterEvadeMode(EvadeReason /*why*/) override
681 {
683 }
684
685 virtual void DoEvent(uint32 /*eventId*/) = 0;
686
687 void UpdateAI(uint32 diff) override
688 {
689 if (_nextMovement)
690 {
691 switch (_nextMovement)
692 {
693 case MOVE_OUTSIDE:
694 {
695 float dist = HUGE_VALF;
696 for (uint8 spawn = 0; spawn < NUM_SPAWNS; ++spawn)
697 {
698 float thisDist = initialMoves[spawn].GetExactDistSq(me);
699 if (thisDist < dist)
700 {
701 _mySpawn = spawn;
702 dist = thisDist;
703 }
704 }
705 me->GetMotionMaster()->MovePoint(MOVE_OUTSIDE, initialMoves[_mySpawn], false); // do not pathfind here, we have to pass through a "wall" of webbing
706 break;
707 }
708 case MOVE_DOWNSTAIRS:
710 break;
712 if (downstairsMoves2[_mySpawn].GetPositionX() > 0.0f) // might be unset for this spawn - if yes, skip
713 {
715 break;
716 }
717 [[fallthrough]];
718 case MOVE_HADRONOX:
720 {
721 static const float zCutoff = 702.0f;
723 if (hadronox && hadronox->IsAlive())
724 {
726 if (hadronox->GetPositionZ() < zCutoff)
727 {
729 break;
730 }
731 AttackStart(hadronox);
732 }
733 break;
734 }
735 default:
736 break;
737 }
739 }
740
741 if (!UpdateVictim())
742 return;
743
744 _events.Update(diff);
745
746 while (uint32 eventId = _events.ExecuteEvent())
747 DoEvent(eventId);
748 }
749
750 protected:
753
754 private:
757};
758
760{
762
763 void DoEvent(uint32 eventId) override
764 {
765 switch (eventId)
766 {
767 case EVENT_REND:
770 break;
771 case EVENT_PUMMEL:
774 break;
775 case EVENT_TAUNT:
778 break;
779 }
780 }
781
782 void JustEngagedWith(Unit* /*who*/) override
783 {
787 }
788};
789
791{
793
794 void DoEvent(uint32 eventId) override
795 {
796 switch (eventId)
797 {
801 break;
805 break;
806 case EVENT_TAUNT:
809 break;
810 }
811 }
812
813 void JustEngagedWith(Unit* /*who*/) override
814 {
818 }
819};
820
822{
824
825 void DoEvent(uint32 eventId) override
826 {
827 switch (eventId)
828 {
832 break;
836 break;
837 case EVENT_TAUNT:
840 break;
841 }
842 }
843
844 void JustEngagedWith(Unit* /*who*/) override
845 {
849 }
850};
851
853{
854 public:
855 spell_hadronox_periodic_summon_template_AuraScript(uint32 topSpellId, uint32 bottomSpellId) : AuraScript(), _topSpellId(topSpellId), _bottomSpellId(bottomSpellId) { }
856
857 private:
858 bool Validate(SpellInfo const* /*spell*/) override
859 {
861 }
862
863 void HandleApply(AuraEffect const* /*eff*/, AuraEffectHandleModes /*mode*/)
864 {
865 if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_0))
866 effect->SetPeriodicTimer(urandms(2, 17));
867 }
868
869 void HandlePeriodic(AuraEffect const* /*eff*/)
870 {
871 Unit* caster = GetCaster();
872 if (!caster)
873 return;
874 InstanceScript* instance = caster->GetInstanceScript();
875 if (!instance)
876 return;
877 if (!instance->instance->HavePlayers())
878 return;
879 if (instance->GetBossState(DATA_HADRONOX) == DONE)
880 GetAura()->Remove();
881 else
882 {
883 if (caster->GetPositionZ() >= 750.0f)
884 caster->CastSpell(caster, _topSpellId, true);
885 else
886 caster->CastSpell(caster, _bottomSpellId, true);
887 }
888 }
889
890 void Register() override
891 {
894 }
895
898};
899
900// 53035 - Summon Anub'ar Champion Periodic
902{
903 public:
904 spell_hadronox_periodic_summon_champion() : SpellScriptLoader("spell_hadronox_periodic_summon_champion") { }
905
907 {
908 public:
910 };
911
912 AuraScript* GetAuraScript() const override
913 {
915 }
916};
917
918// 53037 - Summon Anub'ar Crypt Fiend Periodic
920{
921 public:
922 spell_hadronox_periodic_summon_crypt_fiend() : SpellScriptLoader("spell_hadronox_periodic_summon_crypt_fiend") { }
923
925 {
926 public:
928 };
929
930 AuraScript* GetAuraScript() const override
931 {
933 }
934};
935
936// 53036 - Summon Anub'ar Necromancer Periodic
938{
939 public:
940 spell_hadronox_periodic_summon_necromancer() : SpellScriptLoader("spell_hadronox_periodic_summon_necromancer") { }
941
943 {
944 public:
946 };
947
948 AuraScript* GetAuraScript() const override
949 {
951 }
952};
953
954// 53030, 59417 - Leech Poison
956{
957 bool Validate(SpellInfo const* /*spell*/) override
958 {
960 }
961
962 void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
963 {
964 if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
965 return;
966
967 if (GetTarget()->IsGuardian())
968 return;
969
970 if (Unit* caster = GetCaster())
971 caster->CastSpell(caster, SPELL_LEECH_POISON_HEAL, true);
972 }
973
974 void Register() override
975 {
977 }
978};
979
980// 53177 - Web Front Doors
981// 53185 - Web Side Door
983{
984 bool Validate(SpellInfo const* /*spell*/) override
985 {
987 }
988
989 void HandleDummy(SpellEffIndex /*effIndex*/)
990 {
991 if (Unit* target = GetHitUnit())
992 {
993 target->RemoveAurasDueToSpell(SPELL_SUMMON_CHAMPION_PERIODIC);
994 target->RemoveAurasDueToSpell(SPELL_SUMMON_CRYPT_FIEND_PERIODIC);
995 target->RemoveAurasDueToSpell(SPELL_SUMMON_NECROMANCER_PERIODIC);
996 }
997 }
998
999 void Register() override
1000 {
1002 }
1003};
1004
1006{
1007 public:
1008 achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied") { }
1009
1010 bool OnCheck(Player* /*player*/, Unit* target) override
1011 {
1012 if (!target)
1013 return false;
1014
1015 if (Creature* cTarget = target->ToCreature())
1016 if (!cTarget->AI()->GetData(DATA_HADRONOX_WEBBED_DOORS))
1017 return true;
1018
1019 return false;
1020 }
1021};
1022
1024{
1026
1031
1035
1039
1042
1044}
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:27
@ 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:1349
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:888
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2163
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2146
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2157
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:537
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:539
DamageEffectType
Definition: UnitDefines.h:154
@ UNIT_STATE_CASTING
Definition: Unit.h:272
Creatures
@ 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_ANUBAR_GUID
@ 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:2162
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2145
Unit * GetCaster() const
AuraEffect * GetEffect(uint8 effIndex) const
Aura * GetAura() const
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:2152
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:193
bool UpdateVictim()
Definition: CreatureAI.cpp:244
Creature *const me
Definition: CreatureAI.h:61
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:386
float GetAttackDistance(Unit const *player) const
Definition: Creature.cpp:2150
void GetHomePosition(float &x, float &y, float &z, float &ori) const
Definition: Creature.h:388
bool HasReactState(ReactStates state) const
Definition: Creature.h:176
void SetReactState(ReactStates st)
Definition: Creature.h:174
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2420
float m_CombatDistance
Definition: Creature.h:427
bool CanStartAttack(Unit const *u, bool force) const
Definition: Creature.cpp:2096
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:390
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={}, Optional< Scripting::v2::ActionResultSetter< MovementStopReason > > &&scriptResult={})
static Creature * ToCreature(Object *o)
Definition: Object.h:255
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:195
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:886
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:630
float GetHealthPct() const
Definition: Unit.h:791
MotionMaster * GetMotionMaster()
Definition: Unit.h:1682
bool IsAlive() const
Definition: Unit.h:1175
void SetBoundingRadius(float boundingRadius)
Definition: Unit.h:703
void SetCombatReach(float combatReach)
Definition: Unit.h:701
bool HealthBelowPct(int32 pct) const
Definition: Unit.h:787
Unit * GetVictim() const
Definition: Unit.h:721
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:13027
bool HasUnitState(const uint32 f) const
Definition: Unit.h:738
bool IsControlledByPlayer() const
Definition: Unit.h:1204
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:788
CombatManager & GetCombatManager()
Definition: Unit.h:1032
bool AttackStop()
Definition: Unit.cpp:5871
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1091
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3410
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2977
void setActive(bool isActiveObject)
Definition: Object.cpp:971
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1196
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1127
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition: Object.cpp:2217
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)
Actions
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
constexpr float GetExactDistSq(float x, float y, float z) const
Definition: Position.h:120
constexpr float GetPositionZ() const
Definition: Position.h:88
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)
boss_hadronox(Creature *creature)
bool CanAIAttack(Unit const *target) const override
void JustAppeared() override
void EnterEvadeMode(EvadeReason) override
void SetGUID(ObjectGuid const &guid, int32 id) 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)