Scripts/HoO: properly implement the Vault of Lights gauntlet event

This commit is contained in:
Ovahlord
2021-02-23 21:50:32 +01:00
parent f70bd515f3
commit 6c1dc2d56b
5 changed files with 921 additions and 422 deletions

View File

@@ -0,0 +1,82 @@
DELETE FROM `creature` WHERE `guid` IN (320863, 321478, 317305, 320149);
DELETE FROM `creature_addon` WHERE `guid` IN (320863, 321478, 317305, 320149);
DELETE FROM `creature_template_addon` WHERE `entry`= 41245;
UPDATE `creature_template` SET `npcflag`= 0x1 | 0x2, `speed_run`= 1.14286, `ScriptName`= 'npc_hoo_brann_bronzebeard' WHERE `entry`= 39908;
DELETE FROM `creature_text` WHERE `CreatureID`= 39908;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `comment`) VALUES
(39908, 0, 0, 'This symbol, I think I\'ve seen this before... ', 12, 0, 100, 5, 0, 0, 40104, 'Brann Bronzebeard'),
(39908, 1, 0, 'Right, let\'s go! Just need to input the final entry sequence into the door mechanism... and...', 12, 0, 100, 5, 0, 20897, 40231, 'Brann Bronzebeard'),
(39908, 2, 0, 'That did the trick! The control room should be right behind this... oh... wow...', 12, 0, 100, 5, 0, 20898, 40232, 'Brann Bronzebeard'),
(39908, 3, 0, 'What? This isn\'t the control room! There\'s another entire defense mechanism in place, and the blasted Rock Troggs broke into here somehow. Troggs. Why did it have to be Troggs!', 12, 0, 100, 5, 0, 20899, 40233, 'Brann Bronzebeard'),
(39908, 4, 0, 'Ok, let me think a moment.', 12, 0, 100, 1, 0, 20900, 40234, 'Brann Bronzebeard'),
(39908, 5, 0, 'Mirrors pointing all over the place.', 12, 0, 100, 25, 0, 20902, 40240, 'Brann Bronzebeard'),
(39908, 6, 0, 'Four platforms with huge elementals.', 12, 0, 100, 25, 0, 20901, 40235, 'Brann Bronzebeard'),
(39908, 7, 0, 'I got it! I saw a tablet that mentioned this chamber. This is the Vault of Lights! Ok, simple enough. I need you adventurers to take out each of the four elementals to trigger the opening sequence for the far door!', 12, 0, 100, 5, 0, 20903, 40236, 'Brann Bronzebeard'),
(39908, 8, 0, 'One down!', 14, 0, 100, 5, 0, 20904, 40270, 'Brann Bronzebeard'),
(39908, 9, 0, 'Another one down! Just look at those light beams! They seem to be connecting to the far door!', 14, 0, 100, 5, 0, 20905, 40271, 'Brann Bronzebeard'),
(39908, 10, 0, 'One more elemental to go! The door is almost open!', 14, 0, 100, 5, 0, 20906, 40272, 'Brann Bronzebeard'),
(39908, 11, 0, 'That\'s it, you\'ve done it! The vault door is opening! Now we can... oh, no!', 14, 0, 100, 5, 0, 20907, 40273, 'Brann Bronzebeard'),
(39908, 12, 0, 'We\'ve done it! The control room is breached!', 14, 0, 100, 5, 0, 23709, 49687, 'Brann Bronzebeard'),
(39908, 13, 0, 'Here we go! Now this should only take a moment...', 14, 0, 100, 5, 0, 23710, 49688, 'Brann Bronzebeard');
UPDATE `creature_text` SET `TextRange`= 3 WHERE `CreatureID`= 39908;
UPDATE `creature_template` SET `ScriptName`= 'npc_hoo_flame_warden' WHERE `entry`= 39800;
UPDATE `creature_template` SET `ScriptName`= 'npc_hoo_air_warden' WHERE `entry`= 39803;
UPDATE `creature_template` SET `ScriptName`= 'npc_hoo_earth_warden' WHERE `entry`= 39801;
UPDATE `creature_template` SET `ScriptName`= 'npc_hoo_water_warden' WHERE `entry`= 39802;
UPDATE `creature_template` SET `unit_flags`= 34080768, `flags_extra`= 128, `ScriptName`= 'npc_hoo_whirling_winds', `AIName`= '' WHERE `entry`= 41245;
UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `AIName`= 'NullCreatureAI' WHERE `entry`= 41264;
UPDATE `creature_template` SET `difficulty_entry_1`= 48893, `RegenHealth`= 0, `ScriptName`= 'npc_hoo_aqua_bubble' WHERE `entry`= 41257;
UPDATE `creature_template` SET `minlevel`= 85, `maxlevel`= 85, `exp`= 3, `faction`= 14, `flags_extra`= 0x2000, `RegenHealth`= 0 WHERE `entry`= 48893;
DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (41257, 48893);
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`,`Flight`, `Rooted`) VALUES
(41257, 2, 1, 1),
(48893, 2, 1, 1);
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
('spell_hoo_bubble_bound_script',
'spell_hoo_bubble_bound',
'spell_hoo_bubble_bound_periodic');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(77335, 'spell_hoo_bubble_bound'),
(77336, 'spell_hoo_bubble_bound_periodic'),
(91158, 'spell_hoo_bubble_bound_periodic'),
(77339, 'spell_hoo_bubble_bound_script');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=77341;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13,1,77341,0,1,31,0,3,41257,0,0,0,0,'','Bubble Bound Instakill - Target Aqua Bubble');
SET @ENTRY := 39908;
SET @PATH := @ENTRY * 100;
DELETE FROM `waypoint_data` WHERE `id`= @PATH;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`) VALUES
(@PATH, 0, -409.9531, 367.0469, 89.81111, 0, -435),
(@PATH, 1, -397.8246, 366.967, 86.37722, 0, -285),
(@PATH, 2, -383.7813, 366.8229, 82.07919, 0, -304),
(@PATH, 3, -368.2604, 366.7448, 77.0984, 0, -459),
(@PATH, 4, -353.6458, 366.4896, 75.92504, 0, -477),
(@PATH, 5, -309.0608, 366.7205, 75.91345, 0, -1806),
(@PATH, 6, -276.3303, 367, 75.92413, 0, -908),
(@PATH, 7, -246.5104, 366.6389, 75.87791, 0, -980),
(@PATH, 8, -202.0417, 366.7517, 75.92508, 0, -1100),
(@PATH, 9, -187.6024, 366.7656, 76.23077, 0, -1099),
(@PATH, 10, -155.0938, 366.783, 86.45834, 0, -1536),
(@PATH, 11, -143.5694, 366.8177, 89.73354, 0, -1315),
(@PATH, 12, -128.5608, 366.8629, 89.74199, 0, 1092),
(@PATH, 13, -71.58507, 367.02777, 89.77716, 0, -1100),
(@PATH, 14, -35.04861, 366.65625, 89.78094, 0, 0);
UPDATE `waypoint_data` SET `velocity`= 12.0 WHERE `id`= @PATH;
UPDATE `waypoint_data` SET `velocity`= 8.0 WHERE `id`= @PATH AND `point` IN (13, 14);
UPDATE `gameobject`SET `rotation0`= 0.150108814239501953, `rotation1`= -0.15010833740234375, `rotation2`= 0.690989494323730468, `rotation3`= 0.690990805625915527 WHERE `id`= 207375 AND `map`= 644;
UPDATE `gameobject`SET `rotation0`= -0.15010881423950195, `rotation1`= -0.15010833740234375, `rotation2`= -0.69098949432373046, `rotation3`= 0.690990805625915527 WHERE `id`= 207374 AND `map`= 644;
UPDATE `gameobject`SET `rotation0`= 0.150108814239501953, `rotation1`= -0.15010833740234375, `rotation2`= 0.690989494323730468, `rotation3`= 0.690990805625915527 WHERE `id`= 207377 AND `map`= 644;
UPDATE `gameobject`SET `rotation0`= -0.15010881423950195, `rotation1`= -0.15010833740234375, `rotation2`= -0.69098949432373046, `rotation3`= 0.690990805625915527 WHERE `id`= 207376 AND `map`= 644;

View File

@@ -34,58 +34,20 @@ enum Texts
ANRAPHET_SAY_OMEGA_STANCE = 2,
ANRAPHET_SAY_KILL = 3,
ANRAPHET_SAY_DEATH = 4,
BRANN_SAY_DOOR_INTRO = 0, // Right, let's go! Just need to input the final entry sequence into the door mechanism... and...
BRANN_SAY_UNLOCK_DOOR = 1, // That did the trick! The control room should be right behind this... oh... wow...
BRANN_SAY_TROGGS = 2, // What? This isn't the control room! There's another entire defense mechanism in place, and the blasted Rock Troggs broke into here somehow. Troggs. Why did it have to be Troggs!
BRANN_SAY_THINK = 3, // Ok, let me think a moment.
BRANN_SAY_MIRRORS = 4, // Mirrors pointing all over the place.
BRANN_SAY_ELEMENTALS = 5, // Four platforms with huge elementals.
BRANN_SAY_GET_IT = 6, // I got it! I saw a tablet that mentioned this chamber. This is the Vault of Lights! Ok, simple enough. I need you adventurers to take out each of the four elementals to trigger the opening sequence for the far door!
BRANN_1_ELEMENTAL_DEAD = 7, // One down!
BRANN_2_ELEMENTAL_DEAD = 8, // Another one down! Just look at those light beams! They seem to be connecting to the far door!
BRANN_3_ELEMENTAL_DEAD = 9, // One more elemental to go! The door is almost open!
BRANN_4_ELEMENTAL_DEAD = 10, // That''s it, you''ve done it! The vault door is opening! Now we can... oh, no!
BRANN_SAY_ANRAPHET_DIED = 11, // We''ve done it! The control room is breached!
BRANN_SAY_MOMENT = 12, // Here we go! Now this should only take a moment...
BRANN_SAY_BLASTED_TITANS = 13, // Blasted titans... Why do they use a different set of mechanisms at each of their installations?
BRANN_SAY_THIS_SYMBOL = 14 // This symbol, I think I've seen this before...
};
enum Gossip
{
GOSSIP_MENU_NO_TIME_TO_WASTE = 11339, // Great, ye found yer way here!$b$bNo time to waste. Ye ready?
GOSSIP_OPTION_WE_ARE_READY = 0, // We're ready! Go, Brann!
GOSSIP_MENU_DESTROY_ELEMENTAL = 11348, // Yep, destroy the four elementals, then the door will open. I'm sure of it. Just watch out for the Troggs. Nasty tempered, filthy creatures, even if they have not succumbed to the Curse of Flesh.
GOSSIP_MENU_OCH_ITS_NOT_EASY = 12512 // Och!$b$bWhy can''t it just be easy fer once?!
};
enum Events
{
EVENT_BRANN_IDLE_EMOTE_COOLDOWN = 1,
EVENT_BRANN_START_INTRO = 2,
EVENT_BRANN_UNLOCK_DOOR = 3,
EVENT_BRANN_MOVE_INTRO = 4,
EVENT_BRANN_THINK = 5,
EVENT_BRANN_LOOK_RIGHT = 6,
EVENT_BRANN_LOOK_LEFT = 7,
EVENT_BRANN_SAY_ELEMENTALS = 8,
EVENT_BRANN_SAY_GET_IT = 9,
EVENT_BRANN_SET_FLAG_GOSSIP = 10,
EVENT_BRANN_ACTIVATE_LASERBEAMS = 11,
EVENT_BRANN_SAY_ALL_ELEMENTAL_DEAD = 12,
EVENT_BRANN_MOVE_OUTRO = 13,
EVENT_BRANN_MOVE_FINAL = 14,
EVENT_BRANN_TURN_BACK = 15,
EVENT_ANRAPHET_APPEAR = 16,
EVENT_ANRAPHET_ACTIVATE = 17,
EVENT_ANRAPHET_DESTRUCTION = 18,
EVENT_ANRAPHET_READY = 19,
EVENT_ANRAPHET_NEMESIS_STRIKE = 20,
EVENT_ANRAPHET_ALPHA_BEAMS = 21,
EVENT_ANRAPHET_OMEGA_STANCE = 22,
EVENT_ANRAPHET_CRUMBLING_RUIN = 23,
EVENT_ANRAPHET_ACTIVATE_OMEGA = 24
// Anraphet
EVENT_LEAVE_CONTROL_ROOM = 1,
EVENT_ANRAPHET_ACTIVATE,
EVENT_ANRAPHET_DESTRUCTION,
EVENT_ANRAPHET_READY,
EVENT_ANRAPHET_NEMESIS_STRIKE,
EVENT_ANRAPHET_ALPHA_BEAMS,
EVENT_ANRAPHET_OMEGA_STANCE,
EVENT_ANRAPHET_CRUMBLING_RUIN,
EVENT_ANRAPHET_ACTIVATE_OMEGA
};
enum Spells
@@ -100,15 +62,7 @@ enum Spells
// Omega Stance
SPELL_OMEGA_STANCE_SUMMON = 77106,
SPELL_OMEGA_STANCE = 75622,
SPELL_OMEGA_STANCE_SPIDER_TRIGGER = 77121,
// Flame Warden
SPELL_LAVA_ERUPTION_VISUAL = 97317
};
enum Actions
{
ACTION_BRANN_IDLE_EMOTE
SPELL_OMEGA_STANCE_SPIDER_TRIGGER = 77121
};
enum Phases
@@ -158,8 +112,6 @@ Position const BrannOutroPath[BrannOutroPathSize] =
{ -128.5608f, 366.8629f, 89.74199f, 0.0f }
};
Position const BrannFinalHomePos = { -35.04861f, 366.6563f, 89.77447f, 3.141593f };
uint32 const BrannFinalPathSize = 3;
Position const BrannFinalPath[BrannFinalPathSize] =
{
@@ -204,7 +156,8 @@ struct boss_anraphet : public BossAI
_JustDied();
if (Creature* brann = instance->GetCreature(DATA_BRANN_0))
brann->AI()->DoAction(ACTION_ANRAPHET_DIED);
if (brann->IsAIEnabled)
brann->AI()->DoAction(ACTION_ANRAPHET_DIED);
}
void KilledUnit(Unit* victim) override
@@ -215,12 +168,11 @@ struct boss_anraphet : public BossAI
void DoAction(int32 action) override
{
if (action != ACTION_ANRAPHET_INTRO)
return;
// Intro
events.SetPhase(PHASE_INTRO);
events.ScheduleEvent(EVENT_ANRAPHET_APPEAR, Seconds(6), 0, PHASE_INTRO);
if (action == ACTION_ANRAPHET_INTRO)
{
events.SetPhase(PHASE_INTRO);
events.ScheduleEvent(EVENT_LEAVE_CONTROL_ROOM, 10s, 0, PHASE_INTRO);
}
}
void MovementInform(uint32 type, uint32 point) override
@@ -245,7 +197,7 @@ struct boss_anraphet : public BossAI
{
switch (eventId)
{
case EVENT_ANRAPHET_APPEAR:
case EVENT_LEAVE_CONTROL_ROOM:
me->GetMotionMaster()->MoveSmoothPath(POINT_ANRAPHET_ACTIVATE, AnraphetPath, AnraphetPathSize);
break;
case EVENT_ANRAPHET_ACTIVATE:
@@ -287,197 +239,6 @@ struct boss_anraphet : public BossAI
}
};
// 39908 Brann Bronzebeard
struct npc_brann_bronzebeard_anraphet : public CreatureAI
{
npc_brann_bronzebeard_anraphet(Creature* creature) : CreatureAI(creature), _instance(creature->GetInstanceScript()) { }
bool GossipHello(Player* player) override
{
if (!_instance)
return true;
uint32 gossipMenuId = GOSSIP_MENU_NO_TIME_TO_WASTE;
if (_instance->GetData(DATA_VAULT_OF_LIGHTS) == NOT_STARTED)
AddGossipItemFor(player, gossipMenuId, GOSSIP_OPTION_WE_ARE_READY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
else if (_instance->GetData(DATA_VAULT_OF_LIGHTS) != DONE)
gossipMenuId = GOSSIP_MENU_DESTROY_ELEMENTAL;
else
gossipMenuId = GOSSIP_MENU_OCH_ITS_NOT_EASY;
SendGossipMenuFor(player, player->GetGossipTextId(gossipMenuId, me), me->GetGUID());
return true;
}
void Reset() override
{
canSayIdleEmote = _instance->GetData(DATA_VAULT_OF_LIGHTS) == NOT_STARTED;
if (_instance->GetBossState(DATA_ANRAPHET) == DONE)
me->SetHomePosition(BrannFinalHomePos);
else if (_instance->GetData(DATA_VAULT_OF_LIGHTS) != NOT_STARTED)
me->SetHomePosition(BrannBossHomePos);
me->GetMotionMaster()->MoveTargetedHome();
}
bool GossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
if (_instance->GetData(DATA_VAULT_OF_LIGHTS) != NOT_STARTED)
return false;
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
events.Reset();
events.RescheduleEvent(EVENT_BRANN_START_INTRO, Seconds(1));
return true;
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_BRANN_IDLE_EMOTE:
if (canSayIdleEmote)
{
canSayIdleEmote = false;
Talk(urand(0, 1) ? BRANN_SAY_BLASTED_TITANS : BRANN_SAY_THIS_SYMBOL);
events.ScheduleEvent(EVENT_BRANN_IDLE_EMOTE_COOLDOWN, Seconds(45)); // Cooldown for AreaTrigger
}
break;
case ACTION_ELEMENTAL_DIED:
{
uint32 deadElementals = _instance->GetData(DATA_DEAD_ELEMENTALS);
if (deadElementals < 4)
Talk(BRANN_1_ELEMENTAL_DEAD + deadElementals - 1);
else
_instance->SetData(DATA_VAULT_OF_LIGHTS, DONE);
events.RescheduleEvent(EVENT_BRANN_ACTIVATE_LASERBEAMS, Seconds(9));
break;
}
case ACTION_ANRAPHET_DIED:
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
events.ScheduleEvent(EVENT_BRANN_MOVE_OUTRO, Seconds(5));
break;
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BRANN_IDLE_EMOTE_COOLDOWN:
canSayIdleEmote = true;
break;
case EVENT_BRANN_START_INTRO:
Talk(BRANN_SAY_DOOR_INTRO);
events.ScheduleEvent(EVENT_BRANN_UNLOCK_DOOR, Seconds(7));
break;
case EVENT_BRANN_UNLOCK_DOOR:
Talk(BRANN_SAY_UNLOCK_DOOR);
_instance->SetData(DATA_VAULT_OF_LIGHTS, IN_PROGRESS);
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, Seconds(3));
break;
case EVENT_BRANN_MOVE_INTRO:
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_BRANN_SAY_TROGGS, BrannBossHomePos, true);
break;
case EVENT_BRANN_THINK:
Talk(BRANN_SAY_THINK);
events.ScheduleEvent(EVENT_BRANN_LOOK_RIGHT, Seconds(6));
break;
case EVENT_BRANN_LOOK_RIGHT:
me->SetFacingTo(DegToRad(312.0f)); // Sniff: o = 5.445427f
Talk(BRANN_SAY_MIRRORS);
events.ScheduleEvent(EVENT_BRANN_LOOK_LEFT, Seconds(1));
break;
case EVENT_BRANN_LOOK_LEFT:
me->SetFacingTo(DegToRad(36.0f)); // Sniff: o = 0.6283185f
events.ScheduleEvent(EVENT_BRANN_SAY_ELEMENTALS, Seconds(3));
break;
case EVENT_BRANN_SAY_ELEMENTALS:
me->SetFacingTo(DegToRad(1.0f)); // Sniff: o = 0.01745329f
Talk(BRANN_SAY_ELEMENTALS);
events.ScheduleEvent(EVENT_BRANN_SAY_GET_IT, Seconds(4));
break;
case EVENT_BRANN_SAY_GET_IT:
Talk(BRANN_SAY_GET_IT);
events.ScheduleEvent(EVENT_BRANN_SET_FLAG_GOSSIP, Seconds(16));
break;
case EVENT_BRANN_SET_FLAG_GOSSIP:
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
break;
case EVENT_BRANN_ACTIVATE_LASERBEAMS:
{
_instance->SetData(DATA_UPDATE_LASERBEAMS, 0);
if (_instance->GetData(DATA_VAULT_OF_LIGHTS) == DONE)
{
if (GameObject* mirror = _instance->GetGameObject(DATA_ANRAPHET_SUN_MIRROR))
mirror->SetGoState(GO_STATE_ACTIVE);
if (GameObject* door = _instance->GetGameObject(DATA_ANRAPHET_DOOR))
door->SetGoState(GO_STATE_ACTIVE);
events.ScheduleEvent(EVENT_BRANN_SAY_ALL_ELEMENTAL_DEAD, Seconds(4));
}
break;
}
case EVENT_BRANN_SAY_ALL_ELEMENTAL_DEAD:
Talk(BRANN_4_ELEMENTAL_DEAD);
if (Creature* anraphet = _instance->GetCreature(DATA_ANRAPHET))
anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO);
break;
case EVENT_BRANN_MOVE_OUTRO:
Talk(BRANN_SAY_ANRAPHET_DIED);
me->GetMotionMaster()->MoveSmoothPath(POINT_BRANN_SAY_MOMENT, BrannOutroPath, BrannOutroPathSize, false);
break;
case EVENT_BRANN_MOVE_FINAL:
me->GetMotionMaster()->MoveSmoothPath(POINT_BRANN_TURN_BACK, BrannFinalPath, BrannFinalPathSize, false);
break;
case EVENT_BRANN_TURN_BACK:
me->SetFacingTo(DegToRad(180.0f)); // Sniff: 3.141593f
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
break;
}
}
}
void MovementInform(uint32 movementType, uint32 pointId) override
{
if (movementType != POINT_MOTION_TYPE && movementType != EFFECT_MOTION_TYPE)
return;
switch (pointId)
{
case POINT_BRANN_SAY_TROGGS:
me->SetWalk(false);
Talk(BRANN_SAY_TROGGS);
events.ScheduleEvent(EVENT_BRANN_THINK, Seconds(15));
break;
case POINT_BRANN_SAY_MOMENT:
Talk(BRANN_SAY_MOMENT);
events.ScheduleEvent(EVENT_BRANN_MOVE_FINAL, Seconds(2));
break;
case POINT_BRANN_TURN_BACK:
events.ScheduleEvent(EVENT_BRANN_TURN_BACK, Seconds(6));
break;
default:
break;
}
}
private:
InstanceScript * _instance;
EventMap events;
bool canSayIdleEmote;
};
struct npc_alpha_beam : public ScriptedAI
{
npc_alpha_beam(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
@@ -632,25 +393,9 @@ class spell_anraphet_omega_stance_spider_effect : public SpellScript
}
};
// 5811 Brann's AreaTrigger
class at_hoo_brann_idle_emote : public AreaTriggerScript
{
public:
at_hoo_brann_idle_emote() : AreaTriggerScript("at_hoo_brann_idle_emote") { }
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
{
if (InstanceScript* instance = player->GetInstanceScript())
if (Creature* brann = instance->GetCreature(DATA_BRANN_0))
brann->AI()->DoAction(ACTION_BRANN_IDLE_EMOTE);
return true;
}
};
void AddSC_boss_anraphet()
{
RegisterHallsOfOriginationCreatureAI(boss_anraphet);
RegisterHallsOfOriginationCreatureAI(npc_brann_bronzebeard_anraphet);
RegisterHallsOfOriginationCreatureAI(npc_alpha_beam);
RegisterHallsOfOriginationCreatureAI(npc_omega_stance);
RegisterSpellScript(spell_anraphet_destruction_protocol);
@@ -658,5 +403,4 @@ void AddSC_boss_anraphet()
RegisterSpellScript(spell_anraphet_omega_stance);
RegisterSpellScript(spell_anraphet_omega_stance_summon);
RegisterSpellScript(spell_anraphet_omega_stance_spider_effect);
new at_hoo_brann_idle_emote();
}

View File

@@ -28,6 +28,7 @@
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "SpellScript.h"
#include "TemporarySummon.h"
#include "Transport.h"
@@ -181,6 +182,555 @@ struct npc_hoo_aggro_stalker_1 : public npc_hoo_aggro_stalker_base { npc_hoo_agg
struct npc_hoo_aggro_stalker_2 : public npc_hoo_aggro_stalker_base { npc_hoo_aggro_stalker_2(Creature* creature) : npc_hoo_aggro_stalker_base(creature, 1) { } };
struct npc_hoo_aggro_stalker_3 : public npc_hoo_aggro_stalker_base { npc_hoo_aggro_stalker_3(Creature* creature) : npc_hoo_aggro_stalker_base(creature, 2) { } };
enum BrannBronzebeard
{
// Spells
SPELL_KILL_CREDIT = 92439,
// Gossip Menu
GOSSIP_MENU_NO_TIME_TO_WASTE = 11339,
GOSSIP_MENU_DESTROY_ELEMENTAL = 11348,
GOSSIP_MENU_OCH_ITS_NOT_EASY = 12512,
GOSSIP_OPTION_WE_ARE_READY = 0,
// Texts
SAY_DOOR_INTRO = 0,
SAY_INTRO_1 = 1,
SAY_INTRO_2 = 2,
SAY_INTRO_3 = 3,
SAY_INTRO_4 = 4,
SAY_INTRO_5 = 5,
SAY_INTRO_6 = 6,
SAY_INTRO_7 = 7,
SAY_WARDEN_DIED_1 = 8,
SAY_WARDEN_DIED_2 = 9,
SAY_WARDEN_DIED_3 = 10,
SAY_ANRAPHET_INTRO = 11,
SAY_OUTRO_1 = 12,
SAY_OUTRO_2 = 13,
// Events
EVENT_ENABLE_AREA_TRIGGER_TALK = 1,
EVENT_INTRO_1,
EVENT_USE_STANDING_EMOTE,
EVENT_INTRO_2,
EVENT_WALK_INTO_VAULT,
EVENT_INTRO_3,
EVENT_EXCLAMATION_EMOTE,
EVENT_INTRO_4,
EVENT_INTRO_5,
EVENT_TURN_LEFT,
EVENT_INTRO_6,
EVENT_INTRO_7,
EVENT_POINT_EMOTE,
EVENT_ADD_GOSSIP_FLAG,
EVENT_ANRAPHET_INTRO,
EVENT_OUTRO_1,
EVENT_OUTRO_2,
EVENT_FINISH_OUTRO,
// Actions
ACTION_INTRO_AREA_TRIGGER = 0,
// Move Points
POINT_VAULT_OF_LIGHTS_INTRO = 0,
POINT_VAULT_OF_LIGHTS_OUTRO_1 = 12,
POINT_VAULT_OF_LIGHTS_OUTRO_2 = 14
};
Position const BrannVaultOfLightIntroPos = { -429.583f, 367.019f, 89.792816f };
Position const BrannVaultOfLightOutroPos = { -71.58507f, 367.02777f, 89.77716f };
struct npc_hoo_brann_bronzebeard : public CreatureAI
{
npc_hoo_brann_bronzebeard(Creature* creature) : CreatureAI(creature), _allowAreaTriggerText(true), _deadWarden(0), _instance(nullptr) { }
void InitializeAI() override
{
_instance = me->GetInstanceScript();
}
bool GossipHello(Player* player) override
{
uint32 gossipMenuId = GOSSIP_MENU_NO_TIME_TO_WASTE;
if (_instance->GetData(DATA_VAULT_OF_LIGHTS) == NOT_STARTED)
AddGossipItemFor(player, gossipMenuId, GOSSIP_OPTION_WE_ARE_READY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
else if (_instance->GetData(DATA_VAULT_OF_LIGHTS) != DONE)
gossipMenuId = GOSSIP_MENU_DESTROY_ELEMENTAL;
else
gossipMenuId = GOSSIP_MENU_OCH_ITS_NOT_EASY;
SendGossipMenuFor(player, player->GetGossipTextId(gossipMenuId, me), me->GetGUID());
return true;
}
bool GossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
if (_instance->GetData(DATA_VAULT_OF_LIGHTS) != NOT_STARTED || !me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
return false;
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
me->setActive(true);
_events.ScheduleEvent(EVENT_INTRO_1, 2s);
return true;
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_INTRO_AREA_TRIGGER:
if (_allowAreaTriggerText)
{
_allowAreaTriggerText = false;
Talk(SAY_DOOR_INTRO);
_events.ScheduleEvent(EVENT_ENABLE_AREA_TRIGGER_TALK, 45s);
}
break;
case ACTION_ANRAPHET_DIED:
me->setActive(true);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
_events.ScheduleEvent(EVENT_OUTRO_1, 5s);
break;
default:
break;
}
}
void SetData(uint32 type, uint32 /*value*/) override
{
switch (type)
{
case DATA_WARDEN_1_DIED:
case DATA_WARDEN_2_DIED:
case DATA_WARDEN_3_DIED:
case DATA_WARDEN_4_DIED:
if (_deadWarden < 3)
Talk(SAY_WARDEN_DIED_1 + _deadWarden);
else
{
_instance->SetData(DATA_VAULT_OF_LIGHTS, DONE);
_events.ScheduleEvent(EVENT_ANRAPHET_INTRO, 13s);
}
++_deadWarden;
break;
default:
break;
}
}
void MovementInform(uint32 motionType, uint32 pointId) override
{
if (motionType == POINT_MOTION_TYPE && pointId == POINT_VAULT_OF_LIGHTS_INTRO)
_events.ScheduleEvent(EVENT_INTRO_3, 500ms);
else if (motionType == WAYPOINT_MOTION_TYPE)
{
if (pointId == POINT_VAULT_OF_LIGHTS_OUTRO_1)
_events.ScheduleEvent(EVENT_OUTRO_2, 1s);
else if (pointId == POINT_VAULT_OF_LIGHTS_OUTRO_2)
{
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
_events.ScheduleEvent(EVENT_FINISH_OUTRO, 6s);
}
}
}
void UpdateAI(uint32 diff) override
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ENABLE_AREA_TRIGGER_TALK:
_allowAreaTriggerText = true;
break;
case EVENT_INTRO_1:
Talk(SAY_INTRO_1);
_events.ScheduleEvent(EVENT_USE_STANDING_EMOTE, 4s);
_events.ScheduleEvent(EVENT_INTRO_2, 7s + 400ms);
break;
case EVENT_USE_STANDING_EMOTE:
me->HandleEmoteCommand(EMOTE_ONESHOT_USE_STANDING);
break;
case EVENT_INTRO_2:
Talk(SAY_INTRO_2);
_instance->SetData(DATA_VAULT_OF_LIGHTS, IN_PROGRESS);
_events.ScheduleEvent(EVENT_WALK_INTO_VAULT, 3s + 600ms);
break;
case EVENT_WALK_INTO_VAULT:
me->GetMotionMaster()->MovePoint(POINT_VAULT_OF_LIGHTS_INTRO, BrannVaultOfLightIntroPos, true, 2.5f);
break;
case EVENT_INTRO_3:
Talk(SAY_INTRO_3);
_events.ScheduleEvent(EVENT_EXCLAMATION_EMOTE, 10s);
_events.ScheduleEvent(EVENT_INTRO_4, 15s);
break;
case EVENT_EXCLAMATION_EMOTE:
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
break;
case EVENT_INTRO_4:
Talk(SAY_INTRO_4);
_events.ScheduleEvent(EVENT_INTRO_5, 6s);
break;
case EVENT_INTRO_5:
Talk(SAY_INTRO_5);
me->SetFacingTo(5.445427417755126953f);
_events.ScheduleEvent(EVENT_TURN_LEFT, 1s + 200ms);
break;
case EVENT_TURN_LEFT:
me->SetFacingTo(0.628318548202514648f);
_events.ScheduleEvent(EVENT_INTRO_6, 2s + 200ms);
break;
case EVENT_INTRO_6:
me->SetFacingTo(0.01745329238474369f);
Talk(SAY_INTRO_6);
_events.ScheduleEvent(EVENT_INTRO_7, 4s);
break;
case EVENT_INTRO_7:
Talk(SAY_INTRO_7);
_events.ScheduleEvent(EVENT_POINT_EMOTE, 12s);
break;
case EVENT_POINT_EMOTE:
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
_events.ScheduleEvent(EVENT_ADD_GOSSIP_FLAG, 4s);
break;
case EVENT_ADD_GOSSIP_FLAG:
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
me->setActive(false);
break;
case EVENT_ANRAPHET_INTRO:
Talk(SAY_ANRAPHET_INTRO);
break;
case EVENT_OUTRO_1:
Talk(SAY_OUTRO_1);
me->GetMotionMaster()->MovePath(me->GetEntry() * 100, false);
break;
case EVENT_OUTRO_2:
DoCastAOE(SPELL_KILL_CREDIT);
Talk(SAY_OUTRO_2);
me->GetMotionMaster()->MovePoint(1, BrannVaultOfLightOutroPos);
break;
case EVENT_FINISH_OUTRO:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
me->SetFacingTo(3.141592741012573242f);
me->setActive(false);
break;
default:
break;
}
}
}
private:
bool _allowAreaTriggerText;
uint8 _deadWarden;
InstanceScript* _instance;
EventMap _events;
};
enum VaultOfLightsWarden
{
// Flame Warden
SPELL_LAVA_ERUPTION = 77273,
SPELL_RAGING_INFERNO = 77241,
EVENT_LAVA_ERUPTION = 1,
EVENT_RAGING_INFERNO,
// Air Warden
SPELL_WHIRLING_WINDS = 77316,
SPELL_WHIRLING_WINDS_PERIODIC = 77321,
SPELL_WIND_SHEAR = 77334,
EVENT_WHIRLING_WINDS = 1,
EVENT_WIND_SHEAR,
// Earth Warden
SPELL_ROCKWAVE = 77234,
SPELL_IMPALE = 77235,
EVENT_ROCKWAVE = 1,
EVENT_IMPALE,
// Water Warden
SPELL_AQUA_BOMB = 77349,
SPELL_BUBBLE_BOUND = 77335,
SPELL_AUTO_GROW = 77354,
SPELL_AQUA_BOMB_PERIODIC = 77350,
SPELL_BUBBLE_BOUND_SCRIPT = 77339,
SPELL_BUBBLE_BOUND_INSTAKILL = 77341,
SPELL_BUBBLE_BOUND_PERIODIC = 77336,
EVENT_BUBBLE_BOUND = 1
};
struct npc_hoo_vaults_of_light_warden : public ScriptedAI
{
npc_hoo_vaults_of_light_warden(Creature* creature) : ScriptedAI(creature), _instance(nullptr), _wardenNumber(0) { }
void InitializeAI() override
{
_instance = me->GetInstanceScript();
}
void JustDied(Unit* /*killer*/) override
{
_events.Reset();
if (_instance)
_instance->SetData(DATA_WARDEN_1_DIED + _wardenNumber, DONE);
}
void EnterEvadeMode(EvadeReason why) override
{
ScriptedAI::EnterEvadeMode(why);
_events.Reset();
}
void SetData(uint32 type, uint32 value) override
{
if (type == DATA_WARDEN_NUMBER)
_wardenNumber = value;
}
public:
InstanceScript* _instance;
EventMap _events;
private:
uint8 _wardenNumber;
};
struct npc_hoo_flame_warden : public npc_hoo_vaults_of_light_warden
{
npc_hoo_flame_warden(Creature* creature) : npc_hoo_vaults_of_light_warden(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_LAVA_ERUPTION, 2s);
_events.ScheduleEvent(EVENT_RAGING_INFERNO, 5s + 600ms);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_LAVA_ERUPTION:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.f, true, false))
DoCast(target, SPELL_LAVA_ERUPTION);
else
DoCastVictim(SPELL_LAVA_ERUPTION);
_events.Repeat(_events.GetTimeUntilEvent(EVENT_RAGING_INFERNO) > (10 * IN_MILLISECONDS) ? 6s : 12s);
break;
case EVENT_RAGING_INFERNO:
DoCastSelf(SPELL_RAGING_INFERNO);
_events.Repeat(18s);
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
};
struct npc_hoo_air_warden : public npc_hoo_vaults_of_light_warden
{
npc_hoo_air_warden(Creature* creature) : npc_hoo_vaults_of_light_warden(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_WHIRLING_WINDS, 4s + 800ms);
_events.ScheduleEvent(EVENT_WIND_SHEAR, 5s + 600ms);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_WHIRLING_WINDS:
DoCastSelf(SPELL_WHIRLING_WINDS);
_events.Repeat(12s);
_events.ScheduleEvent(EVENT_WIND_SHEAR, 1s + 200ms, 2s + 400ms);
break;
case EVENT_WIND_SHEAR:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.f, true, false))
DoCast(target, SPELL_WIND_SHEAR);
else
DoCastVictim(SPELL_WIND_SHEAR);
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
};
struct npc_hoo_earth_warden : public npc_hoo_vaults_of_light_warden
{
npc_hoo_earth_warden(Creature* creature) : npc_hoo_vaults_of_light_warden(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_ROCKWAVE, 6s);
_events.ScheduleEvent(EVENT_IMPALE, 10s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ROCKWAVE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.f, true, false))
DoCast(target, SPELL_ROCKWAVE);
else
DoCastVictim(SPELL_ROCKWAVE);
_events.Repeat(13s);
break;
case EVENT_IMPALE:
DoCastVictim(SPELL_IMPALE);
_events.Repeat(20s); // Todo: validate. This timer has been taken from DBM as no sniffs of mine had a repeating cast
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
};
struct npc_hoo_water_warden : public npc_hoo_vaults_of_light_warden
{
npc_hoo_water_warden(Creature* creature) : npc_hoo_vaults_of_light_warden(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
DoCastSelf(SPELL_AQUA_BOMB);
_events.ScheduleEvent(EVENT_BUBBLE_BOUND, 10s);
}
void JustSummoned(Creature* summon) override
{
summon->CastSpell(summon, SPELL_AUTO_GROW);
summon->CastSpell(summon, SPELL_AQUA_BOMB_PERIODIC);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BUBBLE_BOUND:
DoCastAOE(SPELL_BUBBLE_BOUND, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_MAX_TARGETS, 1));
_events.Repeat(16s);
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
};
struct npc_hoo_whirling_winds : public ScriptedAI
{
npc_hoo_whirling_winds(Creature* creature) : ScriptedAI(creature) { }
void InitializeAI() override
{
me->SetReactState(REACT_AGGRESSIVE);
me->SetDisplayId(me->GetCreatureTemplate()->Modelid1);
}
void AttackStart(Unit* who) override
{
AttackStartCaster(who, 0.01f);
}
void JustAppeared() override
{
DoCastSelf(SPELL_WHIRLING_WINDS_PERIODIC);
DoZoneInCombat();
}
void UpdateAI(uint32 /*diff*/) override
{
UpdateVictim();
}
};
struct npc_hoo_aqua_bubble : public NullCreatureAI
{
npc_hoo_aqua_bubble(Creature* creature) : NullCreatureAI(creature) { }
void JustDied(Unit* /*killer*/) override
{
DoCastSelf(SPELL_BUBBLE_BOUND_SCRIPT, true);
me->DespawnOrUnsummon(2s);
}
};
// The Maker's Lift
enum ElevatorMisc
{
@@ -319,14 +869,108 @@ class spell_hoo_submerge : public AuraScript
}
};
class spell_hoo_bubble_bound: public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BUBBLE_BOUND_PERIODIC });
}
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.remove_if([](WorldObject const* target)
{
Unit const* unit = target->ToUnit();
return (!unit || unit->HasAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_BUBBLE_BOUND_PERIODIC, unit)));
});
}
void Register() override
{
OnObjectAreaTargetSelect.Register(&spell_hoo_bubble_bound::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
class spell_hoo_bubble_bound_periodic : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BUBBLE_BOUND_INSTAKILL });
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode().HasFlag(AuraRemoveFlags::ByDeath | AuraRemoveFlags::ByDefault))
GetTarget()->CastSpell(GetTarget(), SPELL_BUBBLE_BOUND_INSTAKILL, true);
}
void Register() override
{
AfterEffectRemove.Register(&spell_hoo_bubble_bound_periodic::HandleRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_hoo_bubble_bound_script : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BUBBLE_BOUND_PERIODIC });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
TempSummon* summon = GetHitUnit()->ToTempSummon();
if (!summon)
return;
if (Unit* summoner = summon->GetSummoner())
summoner->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_BUBBLE_BOUND_PERIODIC, summon), ObjectGuid::Empty, 0, AuraRemoveFlags::ByCancel);
}
void Register() override
{
OnEffectHitTarget.Register(&spell_hoo_bubble_bound_script::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 5811 Brann's AreaTrigger
class at_hoo_brann_idle_emote : public AreaTriggerScript
{
public:
at_hoo_brann_idle_emote() : AreaTriggerScript("at_hoo_brann_idle_emote") { }
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
{
if (InstanceScript* instance = player->GetInstanceScript())
if (Creature* brann = instance->GetCreature(DATA_BRANN_0))
if (brann->IsAIEnabled)
brann->AI()->DoAction(ACTION_INTRO_AREA_TRIGGER);
return true;
}
};
void AddSC_halls_of_origination()
{
RegisterHallsOfOriginationCreatureAI(npc_sun_touched_servant);
RegisterHallsOfOriginationCreatureAI(npc_hoo_aggro_stalker_1);
RegisterHallsOfOriginationCreatureAI(npc_hoo_aggro_stalker_2);
RegisterHallsOfOriginationCreatureAI(npc_hoo_aggro_stalker_3);
RegisterHallsOfOriginationCreatureAI(npc_hoo_brann_bronzebeard);
RegisterHallsOfOriginationCreatureAI(npc_hoo_flame_warden);
RegisterHallsOfOriginationCreatureAI(npc_hoo_air_warden);
RegisterHallsOfOriginationCreatureAI(npc_hoo_earth_warden);
RegisterHallsOfOriginationCreatureAI(npc_hoo_water_warden);
RegisterHallsOfOriginationCreatureAI(npc_hoo_whirling_winds);
RegisterHallsOfOriginationCreatureAI(npc_hoo_aqua_bubble);
RegisterGameObjectAI(go_hoo_the_makers_lift_controller);
RegisterSpellScript(spell_hoo_flame_ring_visual);
RegisterSpellScript(spell_hoo_disperse);
RegisterSpellScript(spell_hoo_submerge);
RegisterSpellScript(spell_hoo_bubble_bound);
RegisterSpellScript(spell_hoo_bubble_bound_periodic);
RegisterSpellScript(spell_hoo_bubble_bound_script);
new at_hoo_brann_idle_emote();
}

View File

@@ -45,19 +45,22 @@ enum HOOData
// Anraphet
DATA_BRANN_0,
DATA_VAULT_OF_LIGHTS_DOOR,
DATA_DEAD_ELEMENTALS,
DATA_LIGHTMACHINE_EARTH,
DATA_LIGHTMACHINE_AIR,
DATA_LIGHTMACHINE_FIRE,
DATA_LIGHTMACHINE_WATER,
DATA_LASERBEAMS_EARTH,
DATA_LASERBEAMS_AIR,
DATA_LASERBEAMS_FIRE,
DATA_LASERBEAMS_WATER,
DATA_UPDATE_LASERBEAMS,
DATA_ANRAPHET_SUN_MIRROR,
DATA_ANRAPHET_DOOR,
DATA_VAULT_OF_LIGHTS_ENTRANCE_DOOR,
DATA_LIGHT_MACHINE_1,
DATA_LIGHT_MACHINE_2,
DATA_LIGHT_MACHINE_3,
DATA_LIGHT_MACHINE_4,
DATA_LASER_BEAMS_1,
DATA_LASER_BEAMS_2,
DATA_LASER_BEAMS_3,
DATA_LASER_BEAMS_4,
DATA_SUN_MIRROR,
DATA_VAULT_OF_LIGHTS_BOSS_DOOR,
DATA_WARDEN_1_DIED,
DATA_WARDEN_2_DIED,
DATA_WARDEN_3_DIED,
DATA_WARDEN_4_DIED,
DATA_WARDEN_NUMBER,
DATA_VAULT_OF_LIGHTS,
// Earthrager Ptah
@@ -69,8 +72,6 @@ enum HOOData
DATA_ISISET_CELESTIAL_CALL_ALIVE,
DATA_ISISET_VEIL_OF_SKY_ALIVE,
// Ammunae
// Setesh
DATA_SETESH_ADD_STALKER,
@@ -146,42 +147,42 @@ enum HOOCreatures
enum HOOGameObjects
{
GO_ANHUURS_BRIDGE = 206506,
GO_BEACON_OF_LIGHT_NORMAL_1 = 203136,
GO_BEACON_OF_LIGHT_NORMAL_2 = 203133,
GO_BEACON_OF_LIGHT_HEROIC_1 = 207219,
GO_BEACON_OF_LIGHT_HEROIC_2 = 207218,
GO_ANHUURS_BRIDGE = 206506,
GO_BEACON_OF_LIGHT_NORMAL_1 = 203136,
GO_BEACON_OF_LIGHT_NORMAL_2 = 203133,
GO_BEACON_OF_LIGHT_HEROIC_1 = 207219,
GO_BEACON_OF_LIGHT_HEROIC_2 = 207218,
GO_DOODAD_ULDUM_ELEVATOR_COL01 = 207725,
GO_DOODAD_ULDUM_DOOR_14 = 202306,
GO_DOODAD_ULDUM_DOOR_15 = 202307,
GO_DOODAD_ULDUM_ELEVATOR_COL01 = 207725,
GO_DOODAD_ULDUM_DOOR_14 = 202306,
GO_DOODAD_ULDUM_DOOR_15 = 202307,
GO_VAULT_OF_LIGHTS_DOOR = 202313,
GO_SUN_MIRROR = 207726,
GO_ANRAPHET_DOOR = 202314,
GO_VAULT_OF_LIGHTS_ENTRANCE_DOOR = 202313,
GO_SUN_MIRROR = 207726,
GO_VAULT_OF_LIGHTS_BOSS_DOOR = 202314,
GO_DOODAD_ULDUM_LIGHTMACHINE_02 = 207374, // South-West
GO_DOODAD_ULDUM_LIGHTMACHINE_01 = 207375, // South-East
GO_DOODAD_ULDUM_LIGHTMACHINE_04 = 207376, // North-West
GO_DOODAD_ULDUM_LIGHTMACHINE_03 = 207377, // North-East
GO_DOODAD_ULDUM_LIGHTMACHINE_02 = 207374, // South-West
GO_DOODAD_ULDUM_LIGHTMACHINE_01 = 207375, // South-East
GO_DOODAD_ULDUM_LIGHTMACHINE_04 = 207376, // North-West
GO_DOODAD_ULDUM_LIGHTMACHINE_03 = 207377, // North-East
GO_DOODAD_ULDUM_LASERBEAMS01 = 207662, // South-West
GO_DOODAD_ULDUM_LASERBEAMS_01 = 207663, // South-East
GO_DOODAD_ULDUM_LASERBEAMS_02 = 207664, // North-West
GO_DOODAD_ULDUM_LASERBEAMS_03 = 207665, // North-East
GO_DOODAD_ULDUM_LASERBEAMS01 = 207662, // South-West
GO_DOODAD_ULDUM_LASERBEAMS_01 = 207663, // South-East
GO_DOODAD_ULDUM_LASERBEAMS_02 = 207664, // North-West
GO_DOODAD_ULDUM_LASERBEAMS_03 = 207665, // North-East
GO_ULDUM_TEMPLE = 207802,
GO_REORIGINATION_MECHANISM_1 = 207445,
GO_REORIGINATION_MECHANISM_2 = 207449,
GO_REORIGINATION_MECHANISM_3 = 207452,
GO_REORIGINATION_MECHANISM_4 = 207454,
GO_REORIGINATION_MECHANISM_5 = 207456,
GO_ULDUM_TEMPLE = 207802,
GO_REORIGINATION_MECHANISM_1 = 207445,
GO_REORIGINATION_MECHANISM_2 = 207449,
GO_REORIGINATION_MECHANISM_3 = 207452,
GO_REORIGINATION_MECHANISM_4 = 207454,
GO_REORIGINATION_MECHANISM_5 = 207456,
GO_HOO_TRANSIT_DEVICE = 204979, // Spell ID: 82916 - Teleports the caster to the lower floor of Halls of Origination.
GO_HOO_TRANSIT_DEVICE_2 = 204972, // Spell ID: 82900 - Teleports the caster to the upper floor of Halls of Origination. (dbc desc is wrong)
GO_LIFT_OF_THE_MAKERS = 207547,
GO_LIFT_GLASS_STAR = 207673,
GO_LIFT_GLASS_STAR_2 = 207674
GO_HOO_TRANSIT_DEVICE = 204979, // Spell ID: 82916 - Teleports the caster to the lower floor of Halls of Origination.
GO_HOO_TRANSIT_DEVICE_2 = 204972, // Spell ID: 82900 - Teleports the caster to the upper floor of Halls of Origination. (dbc desc is wrong)
GO_LIFT_OF_THE_MAKERS = 207547,
GO_LIFT_GLASS_STAR = 207673,
GO_LIFT_GLASS_STAR_2 = 207674
};
enum Achievements
@@ -210,11 +211,10 @@ enum HOOMisc
SPELL_SUMMON_DUSTBONE_HORROR = 75521
};
enum HOOGlobalActions
enum HOOActions
{
ACTION_PTAH_ADD_DIED,
ACTION_ANRAPHET_INTRO,
ACTION_ELEMENTAL_DIED,
ACTION_ANRAPHET_DIED,
ACTION_OMEGA_TRIGGER
};
@@ -225,11 +225,6 @@ enum HoODataStates
DISABLE_SHIELD_OF_LIGHT
};
enum HoOEvents
{
EVENT_RESPAWN_ANRAPHET = 1
};
Position const AnraphetSpawnPos = { -90.2726f, 366.339f, 89.8639f, 3.14159f };
Position const AnraphetRespawnPos = { -193.656f, 366.689f, 75.91001f, 3.138207f };

View File

@@ -57,20 +57,41 @@ ObjectData const creatureData[] =
ObjectData const gameObjectData[] =
{
{ GO_DOODAD_ULDUM_DOOR_15, DATA_ANHUUR_DOOR },
{ GO_VAULT_OF_LIGHTS_DOOR, DATA_VAULT_OF_LIGHTS_DOOR },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_02, DATA_LIGHTMACHINE_EARTH },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_01, DATA_LIGHTMACHINE_AIR },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_04, DATA_LIGHTMACHINE_FIRE },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_03, DATA_LIGHTMACHINE_WATER },
{ GO_DOODAD_ULDUM_LASERBEAMS01, DATA_LASERBEAMS_EARTH },
{ GO_DOODAD_ULDUM_LASERBEAMS_01, DATA_LASERBEAMS_AIR },
{ GO_DOODAD_ULDUM_LASERBEAMS_03, DATA_LASERBEAMS_FIRE },
{ GO_DOODAD_ULDUM_LASERBEAMS_02, DATA_LASERBEAMS_WATER },
{ GO_SUN_MIRROR, DATA_ANRAPHET_SUN_MIRROR },
{ GO_ANRAPHET_DOOR, DATA_ANRAPHET_DOOR },
{ GO_LIFT_OF_THE_MAKERS, DATA_LIFT_OF_THE_MAKERS },
{ 0, 0 } //END
{ GO_DOODAD_ULDUM_DOOR_15, DATA_ANHUUR_DOOR },
{ GO_VAULT_OF_LIGHTS_ENTRANCE_DOOR, DATA_VAULT_OF_LIGHTS_ENTRANCE_DOOR },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_01, DATA_LIGHT_MACHINE_1 },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_02, DATA_LIGHT_MACHINE_2 },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_03, DATA_LIGHT_MACHINE_3 },
{ GO_DOODAD_ULDUM_LIGHTMACHINE_04, DATA_LIGHT_MACHINE_4 },
{ GO_DOODAD_ULDUM_LASERBEAMS_01, DATA_LASER_BEAMS_1 },
{ GO_DOODAD_ULDUM_LASERBEAMS01, DATA_LASER_BEAMS_2 },
{ GO_DOODAD_ULDUM_LASERBEAMS_03, DATA_LASER_BEAMS_3 },
{ GO_DOODAD_ULDUM_LASERBEAMS_02, DATA_LASER_BEAMS_4 },
{ GO_SUN_MIRROR, DATA_SUN_MIRROR },
{ GO_VAULT_OF_LIGHTS_BOSS_DOOR, DATA_VAULT_OF_LIGHTS_BOSS_DOOR },
{ GO_LIFT_OF_THE_MAKERS, DATA_LIFT_OF_THE_MAKERS },
{ 0, 0 } //END
};
enum Events
{
EVENT_RESPAWN_ANRAPHET = 1,
// Sequence is important here. Do NOT change the event order.
EVENT_ACTIVATE_LASER_BEAMS_1,
EVENT_ACTIVATE_LASER_BEAMS_2,
EVENT_ACTIVATE_LASER_BEAMS_3,
EVENT_ACTIVATE_LASER_BEAMS_4,
EVENT_OPEN_CONTROL_ROOM
};
constexpr uint8 const MAX_VAULT_OF_LIGHTS_WARDEN = 4;
std::array<Position, MAX_VAULT_OF_LIGHTS_WARDEN> VaultOfLightsWardenPositions =
{
Position(-329.96182f, 246.30208f, 89.21011f, 1.5707964f), // Bottom Right
Position(-329.72745f, 481.14236f, 89.21011f, 4.712389f), // Bottom Left
Position(-223.04861f, 243.16145f, 89.21015f, 1.5882496f), // Top Right
Position(-223.26042f, 488.22223f, 89.21015f, 4.712389f) // Top Left
};
class instance_halls_of_origination : public InstanceMapScript
@@ -80,36 +101,39 @@ class instance_halls_of_origination : public InstanceMapScript
struct instance_halls_of_origination_InstanceMapScript : public InstanceScript
{
instance_halls_of_origination_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
instance_halls_of_origination_InstanceMapScript(InstanceMap* map) : InstanceScript(map), _vaultOfLightState(NOT_STARTED)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
LoadObjectData(creatureData, gameObjectData);
_brannIntroStarted = 0;
_deadElementals = 0;
_anraphetInitialized = false;
_vaultOfLightState = NOT_STARTED;
}
void OnPlayerEnter(Player* /*player*/) override
void Create() override
{
if (!_anraphetInitialized)
InstanceScript::Create();
if (Creature* anraphet = instance->SummonCreature(BOSS_ANRAPHET, AnraphetSpawnPos))
{
if (GetData(DATA_VAULT_OF_LIGHTS) != DONE)
{
if (Creature* anraphet = instance->SummonCreature(BOSS_ANRAPHET, AnraphetSpawnPos))
{
anraphet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_6 | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NOT_SELECTABLE);
anraphet->SetReactState(REACT_PASSIVE);
}
}
else if (GetBossState(DATA_ANRAPHET) != DONE)
instance->SummonCreature(BOSS_ANRAPHET, AnraphetRespawnPos);
_anraphetInitialized = true;
anraphet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NOT_SELECTABLE);
anraphet->SetReactState(REACT_PASSIVE);
}
SetupVaultOfLightsWarden();
}
void Load(char const* data) override
{
InstanceScript::Load(data);
if (GetData(DATA_VAULT_OF_LIGHTS) != DONE)
{
if (Creature* anraphet = instance->SummonCreature(BOSS_ANRAPHET, AnraphetSpawnPos))
{
anraphet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NOT_SELECTABLE);
anraphet->SetReactState(REACT_PASSIVE);
}
SetupVaultOfLightsWarden();
}
else if (GetBossState(DATA_ANRAPHET) != DONE)
instance->SummonCreature(BOSS_ANRAPHET, AnraphetRespawnPos);
}
void OnGameObjectCreate(GameObject* go) override
@@ -126,7 +150,7 @@ class instance_halls_of_origination : public InstanceMapScript
case GO_LIFT_OF_THE_MAKERS:
//go->SetTransportState(GO_STATE_TRANSPORT_STOPPED, 0);
break;
case GO_VAULT_OF_LIGHTS_DOOR:
case GO_VAULT_OF_LIGHTS_ENTRANCE_DOOR:
if (_vaultOfLightState != NOT_STARTED)
go->SetGoState(GO_STATE_ACTIVE);
break;
@@ -139,8 +163,8 @@ class instance_halls_of_origination : public InstanceMapScript
case GO_DOODAD_ULDUM_LIGHTMACHINE_03:
case GO_DOODAD_ULDUM_LIGHTMACHINE_04:
case GO_SUN_MIRROR:
case GO_ANRAPHET_DOOR:
go->setActive(true);
case GO_VAULT_OF_LIGHTS_BOSS_DOOR:
go->SetFarVisible(true);
if (GetData(DATA_VAULT_OF_LIGHTS) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
@@ -182,7 +206,6 @@ class instance_halls_of_origination : public InstanceMapScript
break;
case BOSS_ANRAPHET:
case NPC_BRANN_BRONZEBEARD_0:
creature->setActive(true);
creature->SetFarVisible(true);
break;
case NPC_FIRE_WARDEN:
@@ -227,21 +250,6 @@ class instance_halls_of_origination : public InstanceMapScript
{
switch (data)
{
case DATA_UPDATE_LASERBEAMS:
UpdateAllLaserBeams();
break;
case DATA_ISISET_PHASE:
_isisetPhase = value;
break;
case DATA_ISISET_ASTRAL_RAIN_ALIVE:
_isisetAstralRainAlive = value;
break;
case DATA_ISISET_CELESTIAL_CALL_ALIVE:
_isisetCelestialCallAlive = value;
break;
case DATA_ISISET_VEIL_OF_SKY_ALIVE:
_isisetVeilOfSkyAlive = value;
break;
case DATA_HANDLE_SHIELD_VISUAL:
for (ObjectGuid guid : _caveInStalkerGUIDs)
{
@@ -287,19 +295,33 @@ class instance_halls_of_origination : public InstanceMapScript
}
break;
case DATA_VAULT_OF_LIGHTS:
_vaultOfLightState = value;
_vaultOfLightState = EncounterState(value);
if (value == IN_PROGRESS)
{
if (GameObject* door = GetGameObject(DATA_VAULT_OF_LIGHTS_DOOR))
if (GameObject* door = GetGameObject(DATA_VAULT_OF_LIGHTS_ENTRANCE_DOOR))
door->SetGoState(GO_STATE_ACTIVE);
DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_VAULT_OF_LIGHTS_START_EVENT);
}
else if (value == DONE)
{
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, SPELL_VAULT_OF_LIGHTS_CREDIT);
SaveToDB();
_events.ScheduleEvent(EVENT_OPEN_CONTROL_ROOM, 8s);
SaveToDB();
}
break;
case DATA_WARDEN_1_DIED:
case DATA_WARDEN_2_DIED:
case DATA_WARDEN_3_DIED:
case DATA_WARDEN_4_DIED:
if (value == DONE)
{
ActivateLightMachine(data - DATA_WARDEN_1_DIED);
if (Creature* brann = GetCreature(DATA_BRANN_0))
if (brann->IsAIEnabled)
brann->AI()->SetData(data, value);
}
break;
default:
break;
@@ -310,16 +332,6 @@ class instance_halls_of_origination : public InstanceMapScript
{
switch (data)
{
case DATA_DEAD_ELEMENTALS:
return _deadElementals;
case DATA_ISISET_PHASE:
return _isisetPhase;
case DATA_ISISET_ASTRAL_RAIN_ALIVE:
return _isisetAstralRainAlive;
case DATA_ISISET_CELESTIAL_CALL_ALIVE:
return _isisetCelestialCallAlive;
case DATA_ISISET_VEIL_OF_SKY_ALIVE:
return _isisetVeilOfSkyAlive;
case DATA_VAULT_OF_LIGHTS:
return _vaultOfLightState;
default:
@@ -401,14 +413,6 @@ class instance_halls_of_origination : public InstanceMapScript
if (Creature* ptah = GetCreature(DATA_EARTHRAGER_PTAH))
ptah->GetAI()->DoAction(ACTION_PTAH_ADD_DIED);
break;
case NPC_FIRE_WARDEN:
case NPC_EARTH_WARDEN:
case NPC_WATER_WARDEN:
case NPC_AIR_WARDEN:
_deadElementals++;
if (Creature* brann = GetCreature(DATA_BRANN_0))
brann->AI()->DoAction(ACTION_ELEMENTAL_DIED);
break;
case NPC_SPATIAL_ANOMALY:
case NPC_FLUX_ANIMATOR:
case NPC_STAR_SHARD:
@@ -445,6 +449,23 @@ class instance_halls_of_origination : public InstanceMapScript
case EVENT_RESPAWN_ANRAPHET:
instance->SummonCreature(BOSS_ANRAPHET, AnraphetRespawnPos);
break;
case EVENT_ACTIVATE_LASER_BEAMS_1:
case EVENT_ACTIVATE_LASER_BEAMS_2:
case EVENT_ACTIVATE_LASER_BEAMS_3:
case EVENT_ACTIVATE_LASER_BEAMS_4:
if (GameObject* beams = GetGameObject(DATA_LASER_BEAMS_1 + eventId - EVENT_ACTIVATE_LASER_BEAMS_1))
beams->SetGoState(GO_STATE_ACTIVE);
break;
case EVENT_OPEN_CONTROL_ROOM:
if (GameObject* bossDoor = GetGameObject(DATA_VAULT_OF_LIGHTS_BOSS_DOOR))
bossDoor->SetGoState(GO_STATE_ACTIVE);
if (GameObject* sunMirror = GetGameObject(DATA_SUN_MIRROR))
sunMirror->SetGoState(GO_STATE_ACTIVE);
if (Creature* anraphet = GetCreature(DATA_ANRAPHET))
if (anraphet->IsAIEnabled)
anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO);
break;
default:
break;
}
@@ -453,27 +474,15 @@ class instance_halls_of_origination : public InstanceMapScript
void WriteSaveDataMore(std::ostringstream& data) override
{
data << _vaultOfLightState << ' '
<< _deadElementals;
data << _vaultOfLightState;
}
void ReadSaveDataMore(std::istringstream& data) override
{
data >> _vaultOfLightState;
data >> _deadElementals;
}
private:
void UpdateAllLightMachines()
{
}
// Activated 9 seconds after warden dies (on SetData DATA_UPDATE_LASERBEAMS, called by Brann).
void UpdateAllLaserBeams()
{
}
void UpdateTransitDevice(GameObject* transit)
{
if (transit->GetPositionX() < -900.f) // The southernmost transit: x = -934.576
@@ -484,6 +493,38 @@ class instance_halls_of_origination : public InstanceMapScript
transit->SetRespawnTime(GetBossState(DATA_ANRAPHET) == DONE ? -1 : DAY);
}
void SetupVaultOfLightsWarden()
{
if (GetBossState(DATA_ANRAPHET) == DONE)
return;
std::array<uint32, MAX_VAULT_OF_LIGHTS_WARDEN> wardenEntries =
{
NPC_FIRE_WARDEN,
NPC_EARTH_WARDEN,
NPC_WATER_WARDEN,
NPC_AIR_WARDEN
};
// Wardens are always being randomized on each reset
Trinity::Containers::RandomShuffle(wardenEntries);
for (uint8 i = 0; i < MAX_VAULT_OF_LIGHTS_WARDEN; ++i)
{
if (Creature* warden = instance->SummonCreature(wardenEntries[i], VaultOfLightsWardenPositions[i]))
if (warden->IsAIEnabled)
warden->AI()->SetData(DATA_WARDEN_NUMBER, i);
}
}
void ActivateLightMachine(uint8 number)
{
if (GameObject* lightMachine = GetGameObject(DATA_LIGHT_MACHINE_1 + number))
lightMachine->SetGoState(GO_STATE_ACTIVE);
_events.ScheduleEvent(EVENT_ACTIVATE_LASER_BEAMS_1 + number, 9s);
}
EventMap _events;
GuidSet _transitDeviceGUIDs;
GuidSet _hooCamelGUIDs;
@@ -491,14 +532,7 @@ class instance_halls_of_origination : public InstanceMapScript
GuidSet _caveInStalkerGUIDs;
GuidSet _anhuurEncounterGUIDs;
GuidSet _beetleStalkerGUIDS;
uint32 _brannIntroStarted;
uint32 _deadElementals;
uint32 _isisetPhase;
uint32 _isisetAstralRainAlive;
uint32 _isisetCelestialCallAlive;
uint32 _isisetVeilOfSkyAlive;
uint8 _vaultOfLightState;
bool _anraphetInitialized;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override