mirror of
https://github.com/azerothcore/azerothcore-wotlk.git
synced 2025-11-10 12:24:22 +08:00
Merge b33b932b664fe2e2944d7e94608ad857290eae5e into 5bef92d5eaca3e2ecc317f9d599312bc23eb71aa
This commit is contained in:
commit
2b3520ffcc
@ -0,0 +1,74 @@
|
||||
--
|
||||
-- HARD_RESET
|
||||
UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 2147483648 WHERE (`entry` IN (28921, 31611));
|
||||
|
||||
DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (53406, 53317, 53394, 53330, 53322);
|
||||
INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES
|
||||
(53406, 53406, 59420, 0, 0),
|
||||
(53317, 53317, 59343, 0, 0),
|
||||
(53394, 53394, 59344, 0, 0),
|
||||
(53330, 53330, 59348, 0, 0),
|
||||
(53322, 53322, 59347, 0, 0);
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` IN (53406, 59420) AND `ScriptName` = 'spell_hadronox_web_grab';
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(53406, 'spell_hadronox_web_grab'),
|
||||
(59420, 'spell_hadronox_web_grab');
|
||||
|
||||
DELETE FROM `creature_summon_groups` WHERE `summonerId` = 28921;
|
||||
INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES
|
||||
(28921, 0, 1, 28922, 529.691, 547.126, 731.916, 4.79965, 6, 45000, 'Hadronox - Group 1 - Anub''ar Crusher'),
|
||||
(28921, 0, 1, 29117, 539.208, 549.754, 732.867, 4.55531, 6, 30000, 'Hadronox - Group 1 - Anub''ar Champion'),
|
||||
(28921, 0, 1, 29118, 520.391, 548.789, 732.012, 5.0091, 6, 30000, 'Hadronox - Group 1 - Anub''ar Crypt Fiend'),
|
||||
(28921, 0, 2, 28922, 493.477, 603.344, 760.563, 5.44024, 6, 45000, 'Hadronox - Group 2 - Anub''ar Crusher'),
|
||||
(28921, 0, 2, 29117, 490.442, 604.335, 763.182, 5.6256, 6, 30000, 'Hadronox - Group 2 - Anub''ar Champion'),
|
||||
(28921, 0, 2, 29119, 488.825, 609.282, 767.588, 5.59029, 6, 30000, 'Hadronox - Group 2 - Anub''ar Necromancer'),
|
||||
(28921, 0, 3, 28922, 566.979, 602.571, 759.642, 3.88597, 6, 45000, 'Hadronox - Group 3 - Anub''ar Crusher'),
|
||||
(28921, 0, 3, 29118, 569.348, 604.999, 763.214, 4.17983, 6, 30000, 'Hadronox - Group 3 - Anub''ar Crypt Fiend'),
|
||||
(28921, 0, 3, 29119, 572.474, 607.411, 767.178, 3.94417, 6, 30000, 'Hadronox - Group 3 - Anub''ar Necromancer'),
|
||||
(28921, 0, 4, 23472, 581.448, 608.841, 739.405, 1.72788, 6, 3600000, 'Hadronox - Group 4 - World Trigger'),
|
||||
(28921, 0, 4, 23472, 477.016, 618.4, 771.515, 2.35619, 6, 3600000, 'Hadronox - Group 4 - World Trigger'),
|
||||
(28921, 0, 4, 23472, 583.091, 617.371, 771.551, 0.645772, 6, 3600000, 'Hadronox - Group 4 - World Trigger');
|
||||
|
||||
DELETE FROM `creature` WHERE (`id1` = 23472) AND (`guid` IN (127376, 127377, 127378));
|
||||
DELETE FROM `creature_addon` WHERE (`guid` IN (127376, 127377, 127378));
|
||||
|
||||
DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (29117, 29118, 29119));
|
||||
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anub_ar_crusher_champion' WHERE (`entry` = 29117);
|
||||
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anub_ar_crusher_crypt_fiend' WHERE (`entry` = 29118);
|
||||
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anub_ar_crusher_necromancer' WHERE (`entry` = 29119);
|
||||
|
||||
SET @SPAWN_X := 522.53107;
|
||||
SET @SPAWN_Y := 544.91125;
|
||||
SET @SPAWN_Z := 674.6791;
|
||||
SET @SPAWN_O := 5.633617;
|
||||
DELETE FROM `creature` WHERE (`id1` = 28921) AND (`guid` = 127401);
|
||||
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
|
||||
(127401, 28921, 0, 0, 601, 0, 0, 3, 1, 0, @SPAWN_X, @SPAWN_Y, @SPAWN_Z, @SPAWN_O, 86400, 0, 0, 154230, 0, 0, 0, 0, 0, '', NULL, 0);
|
||||
|
||||
DELETE FROM `waypoint_data` WHERE `id` IN (3000012, 3000013) AND `point` IN (13, 14);
|
||||
DELETE FROM `waypoint_data` WHERE `id` = 3000014 AND `point` IN (9, 10);
|
||||
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
|
||||
(3000012, 13, 538.0253, 529.9829, 686.0557, 0, 1, 0, 100, 0),
|
||||
(3000012, 14, 532.7753, 535.2329, 681.0557, 0, 1, 0, 100, 0),
|
||||
(3000013, 13, 538.0253, 529.9829, 686.0557, 0, 1, 0, 100, 0),
|
||||
(3000013, 14, 532.7753, 535.2329, 681.0557, 0, 1, 0, 100, 0),
|
||||
(3000014, 9, 538.0253, 529.9829, 686.0557, 0, 1, 0, 100, 0),
|
||||
(3000014, 10, 532.7753, 535.2329, 681.0557, 0, 1, 0, 100, 0);
|
||||
|
||||
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` IN (29062, 29063, 29064));
|
||||
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||
(29062, 0, 0, 0, 0, 0, 100, 0, 4000, 7000, 12000, 18000, 0, 0, 11, 53317, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - In Combat - Cast \'Rend\''),
|
||||
(29062, 0, 1, 0, 105, 0, 100, 0, 9000, 13000, 9000, 13000, 0, 5, 11, 53394, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - On Hostile Casting in Range - Cast \'Pummel\''),
|
||||
(29062, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - On Just Died - Despawn In 10000 ms'),
|
||||
(29062, 0, 3, 0, 1, 0, 100, 0, 10000, 10000, 1000, 1000, 0, 0, 49, 0, 0, 0, 0, 0, 0, 11, 28921, 50, 1, 0, 0, 0, 0, 0, 'Anub\'ar Champion Out of Combat - Start Attacking'),
|
||||
(29062, 0, 4, 0, 0, 0, 100, 0, 15000, 50000, 15000, 50000, 0, 0, 11, 53798, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - In Combat - Cast \'Taunt\''),
|
||||
(29063, 0, 0, 0, 0, 0, 100, 0, 4000, 7000, 9000, 12000, 0, 0, 11, 53330, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - In Combat - Cast \'Infected Wound\''),
|
||||
(29063, 0, 1, 0, 0, 0, 100, 0, 9000, 12000, 13000, 17000, 0, 0, 11, 53322, 0, 0, 0, 0, 0, 5, 30, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - In Combat - Cast \'Crushing Webs\''),
|
||||
(29063, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - On Just Died - Despawn In 10000 ms'),
|
||||
(29063, 0, 3, 0, 1, 0, 100, 0, 10000, 10000, 1000, 1000, 0, 0, 49, 0, 0, 0, 0, 0, 0, 11, 28921, 50, 1, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - Out of Combat - Start Attacking'),
|
||||
(29063, 0, 4, 0, 0, 0, 100, 0, 15000, 50000, 15000, 50000, 0, 0, 11, 53798, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - In Combat - Cast \'Taunt\''),
|
||||
(29064, 0, 0, 0, 1, 0, 100, 0, 0, 1000, 2000, 3000, 0, 0, 11, 53333, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer - Out of Combat - Cast \'Shadow Bolt\''),
|
||||
(29064, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer - On Just Died - Despawn In 10000 ms'),
|
||||
(29064, 0, 3, 0, 1, 0, 100, 0, 10000, 10000, 1000, 1000, 0, 0, 49, 0, 0, 0, 0, 0, 0, 11, 28921, 50, 1, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer Out of Combat - Start Attacking'),
|
||||
(29064, 0, 4, 0, 0, 0, 100, 0, 15000, 50000, 15000, 50000, 0, 0, 11, 53798, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer - In Combat - Cast \'Taunt\'');
|
||||
@ -43,6 +43,7 @@ enum ANIds
|
||||
NPC_HADRONOX = 28921,
|
||||
NPC_ANUBARAK = 29120,
|
||||
|
||||
NPC_WORLD_TRIGGER_LAOI = 23472,
|
||||
NPC_ANUB_AR_CHAMPION = 29062,
|
||||
NPC_ANUB_AR_NECROMANCER = 29063,
|
||||
NPC_ANUB_AR_CRYPTFIEND = 29064,
|
||||
|
||||
@ -75,7 +75,6 @@ enum Events
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_WORLD_TRIGGER = 22515,
|
||||
NPC_ANUBAR_GUARDIAN = 29216,
|
||||
NPC_ANUBAR_VENOMANCER = 29217,
|
||||
};
|
||||
|
||||
@ -26,19 +26,39 @@
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// World Trigger
|
||||
SPELL_SUMMON_ANUBAR_CHAMPION = 53064,
|
||||
SPELL_SUMMON_ANUBAR_CRYPT_FIEND = 53065,
|
||||
SPELL_SUMMON_ANUBAR_NECROMANCER = 53066,
|
||||
SPELL_SUMMON_ANUBAR_CHAMPION_PERIODIC = 53035,
|
||||
SPELL_SUMMON_ANUBAR_NECROMANCER_PERIODIC = 53036,
|
||||
SPELL_SUMMON_ANUBAR_CRYPT_FIEND_PERIODIC = 53037,
|
||||
|
||||
// Hadronox
|
||||
SPELL_WEB_FRONT_DOORS = 53177,
|
||||
SPELL_WEB_SIDE_DOORS = 53185,
|
||||
SPELL_ACID_CLOUD = 53400,
|
||||
SPELL_LEECH_POISON = 53030,
|
||||
SPELL_LEECH_POISON_HEAL = 53800,
|
||||
SPELL_WEB_GRAB = 57731,
|
||||
SPELL_WEB_GRAB = 53406,
|
||||
SPELL_PIERCE_ARMOR = 53418,
|
||||
|
||||
// Anub'ar Crusher
|
||||
SPELL_SMASH = 53318,
|
||||
SPELL_FRENZY = 53801
|
||||
SPELL_FRENZY = 53801,
|
||||
|
||||
// Anub'ar Champion
|
||||
SPELL_REND = 59343,
|
||||
SPELL_PUMMEL = 59344,
|
||||
|
||||
// Anub'ar Crypt Guard
|
||||
SPELL_CRUSHING_WEBS = 59347,
|
||||
SPELL_INFECTED_WOUND = 59348,
|
||||
|
||||
// Anub'ar Necromancer
|
||||
SPELL_SHADOW_BOLT = 53333,
|
||||
SPELL_ANIMATE_BONES_1 = 53334,
|
||||
SPELL_ANIMATE_BONES_2 = 53336,
|
||||
};
|
||||
|
||||
enum Events
|
||||
@ -54,274 +74,533 @@ enum Events
|
||||
EVENT_HADRONOX_SUMMON = 9,
|
||||
|
||||
EVENT_CRUSHER_SMASH = 20,
|
||||
EVENT_CHECK_HEALTH = 21
|
||||
EVENT_CHECK_HEALTH = 21,
|
||||
EVENT_CHECK_EVADE = 22,
|
||||
|
||||
// Anub'ar Champion
|
||||
EVENT_REND,
|
||||
EVENT_PUMMEL,
|
||||
|
||||
// Anub'ar Crypt Guard
|
||||
EVENT_CRUSHING_WEBS,
|
||||
EVENT_INFECTED_WOUND,
|
||||
|
||||
// Anub'ar Necromancer
|
||||
EVENT_SHADOW_BOLT,
|
||||
EVENT_ANIMATE_BONES
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_ANUB_AR_CRUSHER = 28922,
|
||||
NPC_ANUB_AR_CHAMPION_PACK = 29117,
|
||||
NPC_ANUB_AR_CRYPT_FIEND_PACK = 29118,
|
||||
NPC_ANUB_AR_NECROMANCER_PACK = 29119,
|
||||
};
|
||||
|
||||
enum SummonGroups : uint32
|
||||
{
|
||||
SUMMON_GROUP_CRUSHER_NONE = 0,
|
||||
SUMMON_GROUP_CRUSHER_1 = 1,
|
||||
SUMMON_GROUP_CRUSHER_2 = 2,
|
||||
SUMMON_GROUP_CRUSHER_3 = 3,
|
||||
SUMMON_GROUP_WORLD_TRIGGERS = 4,
|
||||
};
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_CRUSHER_PACK_ID = 1,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_ANUB_AR_CRUSHER = 28922,
|
||||
|
||||
SAY_CRUSHER_AGGRO = 0,
|
||||
SAY_CRUSHER_EMOTE = 1,
|
||||
SAY_CRUSHER_AGGRO = 1,
|
||||
SAY_CRUSHER_EMOTE = 2,
|
||||
SAY_HADRONOX_EMOTE = 0,
|
||||
|
||||
ACTION_DESPAWN_ADDS = 1,
|
||||
ACTION_START_EVENT = 2
|
||||
ACTION_CRUSHER_ENGAGED = 1,
|
||||
ACTION_CRUSHER_DIED = 2,
|
||||
ACTION_PACK_WALK = 3,
|
||||
};
|
||||
|
||||
const Position hadronoxSteps[4] =
|
||||
static const std::array<Position, 3> hadronoxSteps =
|
||||
{{
|
||||
{ 562.191f, 514.068f, 696.50710f },
|
||||
{ 615.802f, 517.418f, 695.68066f },
|
||||
{ 530.420f, 560.003f, 733.22473f },
|
||||
}};
|
||||
|
||||
struct boss_hadronox : public BossAI
|
||||
{
|
||||
{607.9f, 512.8f, 695.3f, 0.0f},
|
||||
{611.67f, 564.11f, 720.0f, 0.0f},
|
||||
{576.1f, 580.0f, 727.5f, 0.0f},
|
||||
{534.87f, 554.0f, 733.0f, 0.0f}
|
||||
explicit boss_hadronox(Creature* creature) : BossAI(creature, DATA_HADRONOX), _crushersLeft(0), _doorsWebbed(false), _lastPlayerCombatState(false) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
SummonCrusherPack(SUMMON_GROUP_CRUSHER_1);
|
||||
me->SummonCreatureGroup(SUMMON_GROUP_WORLD_TRIGGERS);
|
||||
_doorsWebbed = false;
|
||||
_lastPlayerCombatState = false;
|
||||
}
|
||||
|
||||
void SummonedCreatureEvade(Creature* summon) override
|
||||
{
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
case NPC_ANUB_AR_CRUSHER:
|
||||
case NPC_ANUB_AR_CHAMPION_PACK:
|
||||
case NPC_ANUB_AR_CRYPT_FIEND_PACK:
|
||||
case NPC_ANUB_AR_NECROMANCER_PACK:
|
||||
EnterEvadeMode(EVADE_REASON_OTHER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_CRUSHER_DIED)
|
||||
--_crushersLeft;
|
||||
else if (param == ACTION_CRUSHER_ENGAGED)
|
||||
{
|
||||
if (instance->GetBossState(DATA_HADRONOX) == IN_PROGRESS)
|
||||
return;
|
||||
instance->SetBossState(DATA_HADRONOX, IN_PROGRESS);
|
||||
events.ScheduleEvent(EVENT_CHECK_EVADE, 5s);
|
||||
SummonCrusherPack(SUMMON_GROUP_CRUSHER_2);
|
||||
SummonCrusherPack(SUMMON_GROUP_CRUSHER_3);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 0s);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 45s);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 90s);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonCrusherPack(const SummonGroups group)
|
||||
{
|
||||
std::list<TempSummon*> summoned;
|
||||
me->SummonCreatureGroup(group, &summoned);
|
||||
_crushersLeft = summoned.size();
|
||||
for (TempSummon* summon : summoned)
|
||||
{
|
||||
summon->AI()->SetData(DATA_CRUSHER_PACK_ID, group);
|
||||
summon->AI()->DoAction(ACTION_PACK_WALK);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
case NPC_WORLD_TRIGGER_LAOI:
|
||||
summon->AddAura(SPELL_SUMMON_ANUBAR_CHAMPION_PERIODIC, summon);
|
||||
summon->AddAura(SPELL_SUMMON_ANUBAR_NECROMANCER_PERIODIC, summon);
|
||||
summon->AddAura(SPELL_SUMMON_ANUBAR_CRYPT_FIEND_PERIODIC, summon);
|
||||
break;
|
||||
case NPC_ANUB_AR_CHAMPION:
|
||||
case NPC_ANUB_AR_NECROMANCER:
|
||||
case NPC_ANUB_AR_CRYPTFIEND:
|
||||
// Xinef: cannot use pathfinding...
|
||||
if (summon->GetDistance(477.0f, 618.0f, 771.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MoveWaypoint(3000012, false);
|
||||
else if (summon->GetDistance(583.0f, 617.0f, 771.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MoveWaypoint(3000013, false);
|
||||
else if (summon->GetDistance(581.0f, 608.5f, 739.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MoveWaypoint(3000014, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!me->IsAlive() || !victim->HasAura(SPELL_LEECH_POISON))
|
||||
return;
|
||||
|
||||
me->ModifyHealth(static_cast<int32>(me->CountPctFromMaxHealth(10)));
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->setActive(true);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_ACID, 10s);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_LEECH, 4s);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_PIERCE, 1s);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_GRAB, 15s);
|
||||
events.RescheduleEvent(EVENT_CHECK_EVADE, 1s);
|
||||
}
|
||||
|
||||
bool IsInCombatWithPlayer() const
|
||||
{
|
||||
return std::ranges::any_of(me->GetThreatMgr().GetThreatList(), [](auto const& ref) {
|
||||
return ref->getTarget()->IsControlledByPlayer();
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if ((!who || !who->IsControlledByPlayer()) && me->HealthBelowPct(70))
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(5, damage))
|
||||
damage = 0;
|
||||
else
|
||||
damage *= (me->GetHealthPct() - 5.0f) / 65.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HADRONOX_PIERCE:
|
||||
DoCastVictim(SPELL_PIERCE_ARMOR);
|
||||
events.Repeat(8s);
|
||||
break;
|
||||
case EVENT_HADRONOX_ACID:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, false))
|
||||
DoCast(target, SPELL_ACID_CLOUD);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_HADRONOX_LEECH:
|
||||
DoCastSelf(SPELL_LEECH_POISON);
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
case EVENT_HADRONOX_GRAB:
|
||||
DoCastSelf(SPELL_WEB_GRAB);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_HADRONOX_MOVE3:
|
||||
if (_crushersLeft > 0)
|
||||
{
|
||||
events.Repeat(2s);
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case EVENT_HADRONOX_MOVE1:
|
||||
case EVENT_HADRONOX_MOVE2:
|
||||
Talk(SAY_HADRONOX_EMOTE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->MovePoint(eventId, hadronoxSteps[eventId - 1]);
|
||||
break;
|
||||
case EVENT_CHECK_EVADE:
|
||||
if (IsInCombatWithPlayer() != _lastPlayerCombatState)
|
||||
{
|
||||
_lastPlayerCombatState = !_lastPlayerCombatState;
|
||||
if (_lastPlayerCombatState)
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
|
||||
me->GetMotionMaster()->Clear();
|
||||
}
|
||||
else
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
}
|
||||
events.Repeat(1s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void MovementInform(uint32 movementType, uint32 pointId) override
|
||||
{
|
||||
if (movementType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (pointId == EVENT_HADRONOX_MOVE3)
|
||||
{
|
||||
DoCastSelf(SPELL_WEB_FRONT_DOORS, true);
|
||||
_doorsWebbed = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const override
|
||||
{
|
||||
if (data == me->GetEntry()) // 'Hadronox Denied' achievement
|
||||
return _doorsWebbed ? 0 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _crushersLeft;
|
||||
bool _doorsWebbed;
|
||||
bool _lastPlayerCombatState;
|
||||
};
|
||||
|
||||
class boss_hadronox : public CreatureScript
|
||||
struct npc_hadronox_crusherPackAI : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
boss_hadronox() : CreatureScript("boss_hadronox") { }
|
||||
npc_hadronox_crusherPackAI(Creature* creature, Position const* positions) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _positions(positions), _myPack(SUMMON_GROUP_CRUSHER_NONE), _doFacing(false) { }
|
||||
|
||||
struct boss_hadronoxAI : public BossAI
|
||||
virtual void DoEngagedWith() = 0;
|
||||
virtual void DoEvent(uint32 /*eventId*/) = 0;
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
boss_hadronoxAI(Creature* creature) : BossAI(creature, DATA_HADRONOX)
|
||||
if (action == ACTION_PACK_WALK)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS);
|
||||
BossAI::Reset();
|
||||
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 542.9f, 519.5f, 741.24f, 2.14f);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_START_EVENT)
|
||||
switch (_myPack)
|
||||
{
|
||||
instance->SetBossState(DATA_HADRONOX, IN_PROGRESS);
|
||||
me->setActive(true);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 20s);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 40s);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 60s);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE4, 80s);
|
||||
case SUMMON_GROUP_CRUSHER_1:
|
||||
case SUMMON_GROUP_CRUSHER_2:
|
||||
case SUMMON_GROUP_CRUSHER_3:
|
||||
me->GetMotionMaster()->MovePoint(ACTION_PACK_WALK, _positions[_myPack - SUMMON_GROUP_CRUSHER_1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const override
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return !me->isActiveObject() || events.HasTimeUntilEvent(EVENT_HADRONOX_MOVE4) ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
|
||||
// Xinef: cannot use pathfinding...
|
||||
if (summon->GetDistance(477.0f, 618.0f, 771.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MoveWaypoint(3000012, false);
|
||||
else if (summon->GetDistance(583.0f, 617.0f, 771.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MoveWaypoint(3000013, false);
|
||||
else if (summon->GetDistance(581.0f, 608.5f, 739.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MoveWaypoint(3000014, false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!me->IsAlive() || !victim->HasAura(SPELL_LEECH_POISON))
|
||||
return;
|
||||
|
||||
me->ModifyHealth(int32(me->CountPctFromMaxHealth(10)));
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
events.RescheduleEvent(EVENT_HADRONOX_ACID, 10s);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_LEECH, 4s);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_PIERCE, 1s);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_GRAB, 15s);
|
||||
}
|
||||
|
||||
bool AnyPlayerValid() const
|
||||
{
|
||||
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
|
||||
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
|
||||
if (me->GetDistance(itr->GetSource()) < 130.0f && itr->GetSource()->IsAlive() && !itr->GetSource()->IsGameMaster() && me->CanCreatureAttack(itr->GetSource()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if ((!who || !who->IsControlledByPlayer()) && me->HealthBelowPct(70))
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(5, damage))
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
damage *= (me->GetHealthPct() - 5.0f) / 65.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HADRONOX_PIERCE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PIERCE_ARMOR, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_PIERCE, 8s);
|
||||
break;
|
||||
case EVENT_HADRONOX_ACID:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, false))
|
||||
me->CastSpell(target, SPELL_ACID_CLOUD, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_ACID, 25s);
|
||||
break;
|
||||
case EVENT_HADRONOX_LEECH:
|
||||
me->CastSpell(me, SPELL_LEECH_POISON, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_LEECH, 12s);
|
||||
break;
|
||||
case EVENT_HADRONOX_GRAB:
|
||||
me->CastSpell(me, SPELL_WEB_GRAB, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_GRAB, 25s);
|
||||
break;
|
||||
case EVENT_HADRONOX_MOVE4:
|
||||
me->CastSpell(me, SPELL_WEB_FRONT_DOORS, true);
|
||||
[[fallthrough]]; /// @todo: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
|
||||
case EVENT_HADRONOX_MOVE1:
|
||||
case EVENT_HADRONOX_MOVE2:
|
||||
case EVENT_HADRONOX_MOVE3:
|
||||
Talk(SAY_HADRONOX_EMOTE);
|
||||
me->GetMotionMaster()->MoveCharge(hadronoxSteps[eventId - 1].GetPositionX(), hadronoxSteps[eventId - 1].GetPositionY(), hadronoxSteps[eventId - 1].GetPositionZ(), 10.0f, 0, nullptr, true);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const override
|
||||
{
|
||||
return me->isActiveObject() && !AnyPlayerValid();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
return GetAzjolNerubAI<boss_hadronoxAI>(creature);
|
||||
if (type == POINT_MOTION_TYPE && id == ACTION_PACK_WALK)
|
||||
_doFacing = true;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const override
|
||||
{
|
||||
if (data == DATA_CRUSHER_PACK_ID)
|
||||
return _myPack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 data, uint32 value) override
|
||||
{
|
||||
if (data == DATA_CRUSHER_PACK_ID)
|
||||
{
|
||||
_myPack = SummonGroups(value);
|
||||
me->SetReactState(_myPack ? REACT_PASSIVE : REACT_AGGRESSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
std::list<Creature*> creatures;
|
||||
|
||||
me->GetCreatureListWithEntryInGrid(creatures, { NPC_ANUB_AR_CRUSHER, NPC_ANUB_AR_CHAMPION_PACK, NPC_ANUB_AR_NECROMANCER_PACK, NPC_ANUB_AR_CRYPT_FIEND_PACK }, 40.0f);
|
||||
for (Creature* creature : creatures)
|
||||
if (creature->AI()->GetData(DATA_CRUSHER_PACK_ID) == _myPack)
|
||||
{
|
||||
creature->SetReactState(REACT_AGGRESSIVE);
|
||||
creature->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
DoEngagedWith();
|
||||
ScriptedAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->CanStartAttack(who) && me->IsWithinDistInMap(who, me->GetAttackDistance(who) + me->m_CombatDistance))
|
||||
JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (_doFacing)
|
||||
{
|
||||
_doFacing = false;
|
||||
me->SetFacingTo(_positions[_myPack - SUMMON_GROUP_CRUSHER_1].GetOrientation());
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
DoEvent(eventId);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
protected:
|
||||
InstanceScript* const _instance;
|
||||
Position const* const _positions;
|
||||
SummonGroups _myPack;
|
||||
bool _doFacing;
|
||||
};
|
||||
|
||||
static const Position crusherWaypoints[] =
|
||||
{
|
||||
{ 529.6913f, 547.1257f, 731.9155f, 4.799650f },
|
||||
{ 517.51f , 561.439f , 734.0306f, 4.520403f },
|
||||
{ 543.414f , 551.728f , 732.0522f, 3.996804f }
|
||||
};
|
||||
|
||||
struct npc_anub_ar_crusher : public npc_hadronox_crusherPackAI
|
||||
{
|
||||
explicit npc_anub_ar_crusher(Creature* creature) : npc_hadronox_crusherPackAI(creature, crusherWaypoints), _hadFrenzy(false) { }
|
||||
|
||||
void DoEngagedWith() override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 8s, 12s);
|
||||
|
||||
if (_myPack != SUMMON_GROUP_CRUSHER_1)
|
||||
return;
|
||||
|
||||
if (_instance->GetBossState(DATA_HADRONOX) == IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (Creature* hadronox = _instance->GetCreature(DATA_HADRONOX))
|
||||
hadronox->AI()->DoAction(ACTION_CRUSHER_ENGAGED);
|
||||
|
||||
Talk(SAY_CRUSHER_AGGRO);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
|
||||
{
|
||||
if (_hadFrenzy || !me->HealthBelowPctDamaged(25, damage))
|
||||
return;
|
||||
_hadFrenzy = true;
|
||||
Talk(SAY_CRUSHER_EMOTE);
|
||||
DoCastSelf(SPELL_FRENZY);
|
||||
}
|
||||
|
||||
void DoEvent(uint32 eventId) override
|
||||
{
|
||||
if (eventId == EVENT_CRUSHER_SMASH)
|
||||
{
|
||||
DoCastVictim(SPELL_SMASH);
|
||||
events.Repeat(13s, 21s);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
if (Creature* hadronox = _instance->GetCreature(DATA_HADRONOX))
|
||||
hadronox->AI()->DoAction(ACTION_CRUSHER_DIED);
|
||||
ScriptedAI::JustDied(killer);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _hadFrenzy;
|
||||
};
|
||||
|
||||
static const Position championWaypoints[] =
|
||||
{
|
||||
{ 539.2076f, 549.7539f, 732.8668f, 4.55531f },
|
||||
{ 527.3098f, 559.5197f, 732.9407f, 4.742493f },
|
||||
{ }
|
||||
};
|
||||
struct npc_anub_ar_crusher_champion : public npc_hadronox_crusherPackAI
|
||||
{
|
||||
explicit npc_anub_ar_crusher_champion(Creature* creature) : npc_hadronox_crusherPackAI(creature, championWaypoints) { }
|
||||
|
||||
void DoEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_REND:
|
||||
DoCastVictim(SPELL_REND);
|
||||
events.Repeat(12s, 16s);
|
||||
break;
|
||||
case EVENT_PUMMEL:
|
||||
DoCastVictim(SPELL_PUMMEL);
|
||||
events.Repeat(12s, 17s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoEngagedWith() override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_REND, 4s, 8s);
|
||||
events.ScheduleEvent(EVENT_PUMMEL, 15s, 19s);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_anub_ar_crusher : public CreatureScript
|
||||
static const Position cryptFiendWaypoints[] =
|
||||
{
|
||||
public:
|
||||
npc_anub_ar_crusher() : CreatureScript("npc_anub_ar_crusher") { }
|
||||
{ 520.3911f, 548.7895f, 732.0118f, 5.0091f },
|
||||
{ },
|
||||
{ 550.9611f, 545.1674f, 731.9031f, 3.996804f }
|
||||
};
|
||||
struct npc_anub_ar_crusher_crypt_fiend : public npc_hadronox_crusherPackAI
|
||||
{
|
||||
explicit npc_anub_ar_crusher_crypt_fiend(Creature* creature) : npc_hadronox_crusherPackAI(creature, cryptFiendWaypoints) { }
|
||||
|
||||
struct npc_anub_ar_crusherAI : public ScriptedAI
|
||||
void DoEvent(uint32 eventId) override
|
||||
{
|
||||
npc_anub_ar_crusherAI(Creature* c) : ScriptedAI(c), summons(me) {}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
switch (eventId)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
events.Reset();
|
||||
|
||||
if (me->ToTempSummon())
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
|
||||
if (summoner->GetEntry() == me->GetEntry())
|
||||
{
|
||||
me->CastSpell(me, RAND(SPELL_SUMMON_ANUBAR_CHAMPION, SPELL_SUMMON_ANUBAR_CRYPT_FIEND, SPELL_SUMMON_ANUBAR_NECROMANCER), true);
|
||||
me->CastSpell(me, RAND(SPELL_SUMMON_ANUBAR_CHAMPION, SPELL_SUMMON_ANUBAR_CRYPT_FIEND, SPELL_SUMMON_ANUBAR_NECROMANCER), true);
|
||||
}
|
||||
case EVENT_CRUSHING_WEBS:
|
||||
DoCastVictim(SPELL_CRUSHING_WEBS);
|
||||
events.Repeat(12s, 16s);
|
||||
break;
|
||||
case EVENT_INFECTED_WOUND:
|
||||
DoCastVictim(SPELL_INFECTED_WOUND);
|
||||
events.Repeat(16s, 25s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() != me->GetEntry())
|
||||
{
|
||||
summon->GetMotionMaster()->MovePoint(0, *me, FORCED_MOVEMENT_NONE, 0.f, false);
|
||||
summon->GetMotionMaster()->MoveFollow(me, 0.1f, 0.0f + M_PI * 0.3f * summons.size());
|
||||
}
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_DESPAWN_ADDS)
|
||||
{
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS);
|
||||
summons.DespawnAll();
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
if (me->ToTempSummon())
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
|
||||
if (summoner->GetEntry() != me->GetEntry())
|
||||
{
|
||||
summoner->GetAI()->DoAction(ACTION_START_EVENT);
|
||||
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 519.58f, 573.73f, 734.30f, 4.50f);
|
||||
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 539.38f, 573.25f, 732.20f, 4.738f);
|
||||
Talk(SAY_CRUSHER_AGGRO);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 8s, 0, 0);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CRUSHER_SMASH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SMASH, false);
|
||||
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 15s);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(30))
|
||||
{
|
||||
Talk(SAY_CRUSHER_EMOTE);
|
||||
me->CastSpell(me, SPELL_FRENZY, false);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void DoEngagedWith() override
|
||||
{
|
||||
return GetAzjolNerubAI<npc_anub_ar_crusherAI>(creature);
|
||||
events.ScheduleEvent(EVENT_CRUSHING_WEBS, 4s, 8s);
|
||||
events.ScheduleEvent(EVENT_INFECTED_WOUND, 15s, 19s);
|
||||
}
|
||||
};
|
||||
|
||||
static const Position necromancerWaypoints[] =
|
||||
{
|
||||
{ },
|
||||
{ 507.6937f, 563.3471f, 734.8986f, 4.520403f },
|
||||
{ 535.1049f, 552.8961f, 732.8441f, 3.996804f },
|
||||
};
|
||||
struct npc_anub_ar_crusher_necromancer : public npc_hadronox_crusherPackAI
|
||||
{
|
||||
explicit npc_anub_ar_crusher_necromancer(Creature* creature) : npc_hadronox_crusherPackAI(creature, necromancerWaypoints) { }
|
||||
|
||||
void DoEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SHADOW_BOLT:
|
||||
DoCastVictim(SPELL_SHADOW_BOLT);
|
||||
events.Repeat(2s, 5s);
|
||||
break;
|
||||
case EVENT_ANIMATE_BONES:
|
||||
DoCastVictim(RAND(SPELL_ANIMATE_BONES_2, SPELL_ANIMATE_BONES_1));
|
||||
events.Repeat(35s, 50s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoEngagedWith() override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2s, 4s);
|
||||
events.ScheduleEvent(EVENT_ANIMATE_BONES, 37s, 45s);
|
||||
}
|
||||
};
|
||||
|
||||
@ -330,7 +609,7 @@ class spell_hadronox_summon_periodic_aura : public AuraScript
|
||||
PrepareAuraScript(spell_hadronox_summon_periodic_aura);
|
||||
|
||||
public:
|
||||
spell_hadronox_summon_periodic_aura(uint32 delay, uint32 spellEntry) : _delay(delay), _spellEntry(spellEntry) { }
|
||||
spell_hadronox_summon_periodic_aura(int32 delay, uint32 spellEntry) : _delay(delay), _spellEntry(spellEntry) { }
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
@ -342,7 +621,7 @@ public:
|
||||
PreventDefaultAction();
|
||||
Unit* owner = GetUnitOwner();
|
||||
if (InstanceScript* instance = owner->GetInstanceScript())
|
||||
if (!instance->IsBossDone(DATA_HADRONOX))
|
||||
if (!instance->IsBossDone(DATA_HADRONOX) != NOT_STARTED)
|
||||
{
|
||||
if (!owner->HasAura(SPELL_WEB_FRONT_DOORS))
|
||||
owner->CastSpell(owner, _spellEntry, true);
|
||||
@ -363,7 +642,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _delay;
|
||||
int32 _delay;
|
||||
uint32 _spellEntry;
|
||||
};
|
||||
|
||||
@ -389,12 +668,29 @@ class spell_hadronox_leech_poison_aura : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_hadronox_web_grab : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_hadronox_web_grab);
|
||||
|
||||
// hack to avoid pulling Anub'ar Crusher through the floor and causing Hadronox to evade
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if([&](WorldObject* target) -> bool
|
||||
{
|
||||
return target->GetEntry() == NPC_ANUB_AR_CRUSHER;
|
||||
});
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hadronox_web_grab::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_hadronox_denied : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied")
|
||||
{
|
||||
}
|
||||
achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied") { }
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
||||
{
|
||||
@ -407,11 +703,15 @@ public:
|
||||
|
||||
void AddSC_boss_hadronox()
|
||||
{
|
||||
new boss_hadronox();
|
||||
new npc_anub_ar_crusher();
|
||||
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_champion_aura", 15000, SPELL_SUMMON_ANUBAR_CHAMPION);
|
||||
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_necromancer_aura", 10000, SPELL_SUMMON_ANUBAR_NECROMANCER);
|
||||
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_crypt_fiend_aura", 5000, SPELL_SUMMON_ANUBAR_CRYPT_FIEND);
|
||||
RegisterAzjolNerubCreatureAI(boss_hadronox);
|
||||
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher);
|
||||
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher_champion);
|
||||
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher_crypt_fiend);
|
||||
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher_necromancer);
|
||||
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_champion_aura", 15'000, SPELL_SUMMON_ANUBAR_CHAMPION);
|
||||
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_necromancer_aura", 10'000, SPELL_SUMMON_ANUBAR_NECROMANCER);
|
||||
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_crypt_fiend_aura", 5'000, SPELL_SUMMON_ANUBAR_CRYPT_FIEND);
|
||||
RegisterSpellScript(spell_hadronox_leech_poison_aura);
|
||||
RegisterSpellScript(spell_hadronox_web_grab);
|
||||
new achievement_hadronox_denied();
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ ObjectData const summonData[] =
|
||||
{ NPC_ANUB_AR_CHAMPION, DATA_HADRONOX },
|
||||
{ NPC_ANUB_AR_NECROMANCER, DATA_HADRONOX },
|
||||
{ NPC_ANUB_AR_CRYPTFIEND, DATA_HADRONOX },
|
||||
{ NPC_WORLD_TRIGGER_LAOI, DATA_HADRONOX },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user