Scripts/AQ20: Implement Andorov's event (#31512)
Closes #9636 (cherry picked from commit 20927ba78f6a3a68df1cf432c188462d70692fbe)
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
--
|
||||
SET @SPAWN_GROUP_ID := 333; -- 1
|
||||
SET @CGUID := 142800; -- 5
|
||||
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave1' WHERE `guid` IN (144611,144653,144610,144656,144655,144654,144676);
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave2' WHERE `guid` IN (144619,144617,144616,144660,144659,144658,144677);
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave3' WHERE `guid` IN (144614,144613,144612,144618,144657,144615,144674);
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave4' WHERE `guid` IN (144665,144662,144661,144626,144625,144623,144675);
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave5' WHERE `guid` IN (144622,144621,144620,144664,144624,144663,144652);
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave6' WHERE `guid` IN (144631,144670,144630,144672,144671,144669,144673);
|
||||
UPDATE `creature` SET `StringId` = 'GeneralRajaxxWave7' WHERE `guid` IN (144629,144628,144627,144668,144667,144666,144651);
|
||||
|
||||
UPDATE `creature` SET `spawntimesecs` = 604800 WHERE `id` IN (15385,15386,15388,15389,15390,15391,15392,15344,15387);
|
||||
|
||||
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (144611,144619,144614,144665,144622,144631,144629);
|
||||
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
|
||||
(144611,144611,0,0,3,0,0),
|
||||
(144611,144653,0,0,3,0,0),
|
||||
(144611,144610,0,0,3,0,0),
|
||||
(144611,144656,0,0,3,0,0),
|
||||
(144611,144655,0,0,3,0,0),
|
||||
(144611,144654,0,0,3,0,0),
|
||||
(144611,144676,0,0,3,0,0),
|
||||
|
||||
(144619,144619,0,0,3,0,0),
|
||||
(144619,144617,0,0,3,0,0),
|
||||
(144619,144616,0,0,3,0,0),
|
||||
(144619,144660,0,0,3,0,0),
|
||||
(144619,144659,0,0,3,0,0),
|
||||
(144619,144658,0,0,3,0,0),
|
||||
(144619,144677,0,0,3,0,0),
|
||||
|
||||
(144614,144614,0,0,3,0,0),
|
||||
(144614,144613,0,0,3,0,0),
|
||||
(144614,144612,0,0,3,0,0),
|
||||
(144614,144618,0,0,3,0,0),
|
||||
(144614,144657,0,0,3,0,0),
|
||||
(144614,144615,0,0,3,0,0),
|
||||
(144614,144674,0,0,3,0,0),
|
||||
|
||||
(144665,144665,0,0,3,0,0),
|
||||
(144665,144662,0,0,3,0,0),
|
||||
(144665,144661,0,0,3,0,0),
|
||||
(144665,144626,0,0,3,0,0),
|
||||
(144665,144625,0,0,3,0,0),
|
||||
(144665,144623,0,0,3,0,0),
|
||||
(144665,144675,0,0,3,0,0),
|
||||
|
||||
(144622,144622,0,0,3,0,0),
|
||||
(144622,144621,0,0,3,0,0),
|
||||
(144622,144620,0,0,3,0,0),
|
||||
(144622,144664,0,0,3,0,0),
|
||||
(144622,144624,0,0,3,0,0),
|
||||
(144622,144663,0,0,3,0,0),
|
||||
(144622,144652,0,0,3,0,0),
|
||||
|
||||
(144631,144631,0,0,3,0,0),
|
||||
(144631,144670,0,0,3,0,0),
|
||||
(144631,144630,0,0,3,0,0),
|
||||
(144631,144672,0,0,3,0,0),
|
||||
(144631,144671,0,0,3,0,0),
|
||||
(144631,144669,0,0,3,0,0),
|
||||
(144631,144673,0,0,3,0,0),
|
||||
|
||||
(144629,144629,0,0,3,0,0),
|
||||
(144629,144628,0,0,3,0,0),
|
||||
(144629,144627,0,0,3,0,0),
|
||||
(144629,144668,0,0,3,0,0),
|
||||
(144629,144667,0,0,3,0,0),
|
||||
(144629,144666,0,0,3,0,0),
|
||||
(144629,144651,0,0,3,0,0);
|
||||
|
||||
DELETE FROM `spawn_group` WHERE `spawnId` BETWEEN @CGUID+0 AND @CGUID+4 AND `spawnType` = 0;
|
||||
INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES
|
||||
(@SPAWN_GROUP_ID+0,0,@CGUID+0),
|
||||
(@SPAWN_GROUP_ID+0,0,@CGUID+1),
|
||||
(@SPAWN_GROUP_ID+0,0,@CGUID+2),
|
||||
(@SPAWN_GROUP_ID+0,0,@CGUID+3),
|
||||
(@SPAWN_GROUP_ID+0,0,@CGUID+4);
|
||||
|
||||
DELETE FROM `spawn_group_template` WHERE `groupId` = @SPAWN_GROUP_ID+0;
|
||||
INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES
|
||||
(@SPAWN_GROUP_ID+0,"Ruins of Ahn'Qiraj - Lieutenant General Andorov",4);
|
||||
|
||||
-- These positions are not default, no CreateObject2
|
||||
DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+4;
|
||||
INSERT INTO `creature` (`guid`,`id`,`map`,`zoneId`,`areaId`,`spawnDifficulties`,`phaseId`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`wander_distance`,`curHealthPct`,`MovementType`,`unit_flags`,`ScriptName`,`StringId`,`VerifiedBuild`) VALUES
|
||||
(@CGUID+0,15471,509,0,0,'3',0,0,1,-8624.473,1471.7743,32.0758,2.3319497,604800,0,100,0,0x8200,'',NULL,0),
|
||||
(@CGUID+1,15473,509,0,0,'3',0,0,1,-8624.473,1471.7743,32.0758,2.3319497,604800,0,100,0,0x8200,'',NULL,0),
|
||||
(@CGUID+2,15473,509,0,0,'3',0,0,1,-8624.473,1471.7743,32.0758,2.3319497,604800,0,100,0,0x8200,'',NULL,0),
|
||||
(@CGUID+3,15473,509,0,0,'3',0,0,1,-8624.473,1471.7743,32.0758,2.3319497,604800,0,100,0,0x8200,'',NULL,0),
|
||||
(@CGUID+4,15473,509,0,0,'3',0,0,1,-8624.473,1471.7743,32.0758,2.3319497,604800,0,100,0,0x8200,'',NULL,0);
|
||||
|
||||
DELETE FROM `creature_formations` WHERE `leaderGUID` = @CGUID+0;
|
||||
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
|
||||
(@CGUID+0,@CGUID+0,0,0,515,0,0),
|
||||
(@CGUID+0,@CGUID+1,5,75,515,0,0),
|
||||
(@CGUID+0,@CGUID+2,5,285,515,0,0),
|
||||
(@CGUID+0,@CGUID+3,5,330,515,0,0),
|
||||
(@CGUID+0,@CGUID+4,5,30,515,0,0);
|
||||
|
||||
DELETE FROM `creature_template_movement` WHERE `CreatureId` = 15471;
|
||||
INSERT INTO `creature_template_movement` (`CreatureId`, `InteractionPauseTimer`) VALUES
|
||||
(15471,0);
|
||||
|
||||
UPDATE `creature_template_addon` SET `SheathState` = 1 WHERE `entry` IN (15471,15473);
|
||||
|
||||
DELETE FROM `creature_template_gossip` WHERE `CreatureID` = 15471;
|
||||
|
||||
UPDATE `creature_template` SET `RegenHealth` = 0, `ScriptName` = 'npc_andorov' WHERE `entry` = 15471;
|
||||
UPDATE `creature_template` SET `RegenHealth` = 0 WHERE `entry` = 15473;
|
||||
|
||||
-- First path is incomplete
|
||||
DELETE FROM `waypoint_path` WHERE `PathId` IN (4,5);
|
||||
INSERT INTO `waypoint_path` (`PathId`, `MoveType`, `Flags`, `Velocity`, `Comment`) VALUES
|
||||
(4,1,0,NULL,'Migrated from refactor'),
|
||||
(5,1,0,NULL,'Migrated from refactor');
|
||||
|
||||
DELETE FROM `waypoint_path_node` WHERE `PathId` IN (4,5);
|
||||
INSERT INTO `waypoint_path_node` (`PathId`, `NodeId`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `Delay`) VALUES
|
||||
(4,1,-8679.187,1535.1178,31.96736,NULL,0),
|
||||
(4,2,-8701.477,1561.7574,32.17472,NULL,0),
|
||||
(4,3,-8720.072,1580.9626,21.511324,NULL,0),
|
||||
(4,4,-8746.162,1603.494,21.613367,NULL,0),
|
||||
(4,5,-8780.431,1617.8787,21.455776,NULL,0),
|
||||
(4,6,-8823.478,1624.6688,19.80574,NULL,0),
|
||||
(4,7,-8855.329,1637.9473,19.790516,NULL,0),
|
||||
(4,8,-8870.721,1648.4009,21.511328,5.637413501739501953,1),
|
||||
|
||||
(5,1,-8886.095,1598.713,21.4053,NULL,0),
|
||||
(5,2,-8904.383,1578.6167,21.511332,NULL,0),
|
||||
(5,3,-8920.576,1551.9479,21.407932,NULL,0),
|
||||
(5,4,-8939.951,1551.127,21.566868,NULL,0);
|
||||
|
||||
DELETE FROM `gossip_menu` WHERE `MenuID` = 6629 AND `TextID` = 7883;
|
||||
DELETE FROM `gossip_menu` WHERE `MenuID` = 7048 AND `TextID` IN (7883,8305);
|
||||
INSERT INTO `gossip_menu` (`MenuID`, `TextID`, `VerifiedBuild`) VALUES
|
||||
(6629,7883,0);
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 15471;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(15471,0,0,"Remember, Rajaxx, when I said I'd kill you last?",14,0,100,22,0,0,11028,0,"Lieutenant General Andorov"),
|
||||
(15471,1,0,"I lied...",14,0,100,0,0,0,11477,0,"Lieutenant General Andorov"),
|
||||
(15471,2,0,"They come now. Try not to get yourself killed, young blood.",14,0,100,22,0,0,11012,0,"Lieutenant General Andorov"),
|
||||
(15471,3,0,"Come get some!",12,0,100,25,0,0,11478,0,"Lieutenant General Andorov"),
|
||||
(15471,4,0,"Kill first, ask questions later... Incoming!",14,0,100,45,0,0,11032,0,"Lieutenant General Andorov"),
|
||||
(15471,5,0,"My work here is done. I'll be sure to let Mar'alith and the others at Cenarion Hold know that you helped me out a little. Be careful in here, you don't have me holdin' your hand past this point.",14,0,100,0,0,0,11560,0,"Lieutenant General Andorov");
|
||||
|
||||
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 15473;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` = 15473 AND `source_type` = 0;
|
||||
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`,`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
|
||||
(15473,0,0,0,0,0,100,0,5000,10000,5000,15000,0,11,16856,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Kaldorei Elite - In Combat - Cast 'Mortal Strike'"),
|
||||
(15473,0,1,0,0,0,100,0,10000,15000,10000,20000,0,11,26350,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Kaldorei Elite - In Combat - Cast 'Cleave'");
|
||||
|
||||
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 15344;
|
||||
UPDATE `creature_template_difficulty` SET `GoldMin` = 0, `GoldMax` = 0 WHERE `entry` = 15344;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (15344,15387) AND `source_type` = 0;
|
||||
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`,`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
|
||||
(15344,0,0,0,37,0,100,0,0,0,0,0,0,116,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Swarmguard Needler - On AI Initialize - Set Corpse Delay"),
|
||||
(15344,0,1,0,0,0,100,0,5000,10000,5000,10000,0,11,40504,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Swarmguard Needler - In Combat - Cast 'Cleave'"),
|
||||
|
||||
(15387,0,0,0,37,0,100,0,0,0,0,0,0,116,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Qiraji Warrior - On AI Initialize - Set Corpse Delay"),
|
||||
(15387,0,1,0,0,0,100,0,10000,15000,10000,15000,0,11,10966,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Qiraji Warrior - In Combat - Cast 'Uppercut'"),
|
||||
(15387,0,2,0,0,0,100,0,10000,20000,15000,25000,0,11,15588,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Qiraji Warrior - In Combat - Cast 'Thunderclap'"),
|
||||
(15387,0,3,0,2,0,100,1,0,25,0,0,0,11,8599,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Qiraji Warrior - Between 0-25% Health - Cast 'Enrage' (No Repeat)"),
|
||||
(15387,0,4,0,83,0,100,0,8599,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Qiraji Warrior - On Spell Cast 'Enrage' - Say Line 0");
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellInfo.h"
|
||||
@@ -230,7 +229,7 @@ struct npc_buru_egg : public ScriptedAI
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (Creature* buru = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BURU)))
|
||||
if (Creature* buru = _instance->GetCreature(DATA_BURU))
|
||||
if (!buru->IsInCombat())
|
||||
buru->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "Containers.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellInfo.h"
|
||||
@@ -93,13 +92,6 @@ struct boss_kurinnaxx : public BossAI
|
||||
Talk(EMOTE_FRENZY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
if (Creature* ossirian = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_OSSIRIAN)))
|
||||
ossirian->AI()->Talk(SAY_KURINAXX_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
|
||||
@@ -35,7 +35,8 @@ enum Texts
|
||||
SAY_INTRO = 1,
|
||||
SAY_AGGRO = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
SAY_DEATH = 4,
|
||||
SAY_KURINAXX_DEATH = 5
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -67,6 +68,12 @@ enum Events
|
||||
EVENT_STOMP = 3
|
||||
};
|
||||
|
||||
enum OssirianMisc
|
||||
{
|
||||
NPC_SAND_VORTEX = 15428,
|
||||
NPC_OSSIRIAN_TRIGGER = 15590
|
||||
};
|
||||
|
||||
uint8 const NUM_CRYSTALS = 12;
|
||||
|
||||
Position CrystalCoordinates[NUM_CRYSTALS] =
|
||||
@@ -145,6 +152,9 @@ class boss_ossirian : public CreatureScript
|
||||
if (Creature* Trigger = ObjectAccessor::GetCreature(*me, TriggerGUID))
|
||||
if (!Trigger->HasUnitState(UNIT_STATE_CASTING))
|
||||
Trigger->CastSpell(Trigger, SpellWeakness[urand(0, 4)], false);
|
||||
|
||||
if (action == ACTION_KURINNAXX_DEFEATED && me->IsAlive())
|
||||
Talk(SAY_KURINAXX_DEATH);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
|
||||
@@ -89,6 +89,37 @@ struct boss_rajaxx : public BossAI
|
||||
Talk(EMOTE_FRENZY);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (!me->IsAlive())
|
||||
return;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_WAVE_STARTS_3:
|
||||
Talk(SAY_WAVE_3);
|
||||
break;
|
||||
case ACTION_WAVE_STARTS_4:
|
||||
Talk(SAY_WAVE_4);
|
||||
break;
|
||||
case ACTION_WAVE_STARTS_5:
|
||||
Talk(SAY_WAVE_5);
|
||||
break;
|
||||
case ACTION_WAVE_STARTS_6:
|
||||
Talk(SAY_WAVE_6);
|
||||
break;
|
||||
case ACTION_WAVE_STARTS_7:
|
||||
Talk(SAY_WAVE_7);
|
||||
break;
|
||||
case ACTION_RAJAXX_ENTER:
|
||||
Talk(SAY_INTRO);
|
||||
DoZoneInCombat();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
@@ -17,10 +17,24 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
#include <algorithm>
|
||||
|
||||
DungeonEncounterData const encounters[] =
|
||||
static constexpr ObjectData creatureData[] =
|
||||
{
|
||||
{ NPC_KURINAXX, DATA_KURINNAXX },
|
||||
{ NPC_RAJAXX, DATA_RAJAXX },
|
||||
{ NPC_MOAM, DATA_MOAM },
|
||||
{ NPC_BURU, DATA_BURU },
|
||||
{ NPC_AYAMISS, DATA_AYAMISS },
|
||||
{ NPC_OSSIRIAN, DATA_OSSIRIAN },
|
||||
{ NPC_ANDOROV, DATA_ANDOROV }
|
||||
};
|
||||
|
||||
static constexpr DungeonEncounterData encounters[] =
|
||||
{
|
||||
{ DATA_KURINNAXX, {{ 718 }} },
|
||||
{ DATA_RAJAXX, {{ 719 }} },
|
||||
@@ -30,6 +44,23 @@ DungeonEncounterData const encounters[] =
|
||||
{ DATA_OSSIRIAN, {{ 723 }} }
|
||||
};
|
||||
|
||||
struct RajaxxWave
|
||||
{
|
||||
std::string_view StringId;
|
||||
int32 BossActionIdOnClear;
|
||||
};
|
||||
|
||||
static constexpr std::array<RajaxxWave, 7> RajaxxWaves =
|
||||
{{
|
||||
{ "GeneralRajaxxWave1", 0 },
|
||||
{ "GeneralRajaxxWave2", ACTION_WAVE_STARTS_3 },
|
||||
{ "GeneralRajaxxWave3", ACTION_WAVE_STARTS_4 },
|
||||
{ "GeneralRajaxxWave4", ACTION_WAVE_STARTS_5 },
|
||||
{ "GeneralRajaxxWave5", ACTION_WAVE_STARTS_6 },
|
||||
{ "GeneralRajaxxWave6", ACTION_WAVE_STARTS_7 },
|
||||
{ "GeneralRajaxxWave7", ACTION_RAJAXX_ENTER }
|
||||
}};
|
||||
|
||||
class instance_ruins_of_ahnqiraj : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
@@ -40,32 +71,46 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript
|
||||
instance_ruins_of_ahnqiraj_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(NUM_ENCOUNTER);
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadObjectData(creatureData, {});
|
||||
|
||||
AndorovEventState = NOT_STARTED;
|
||||
LoadDungeonEncounterData(encounters);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
auto rajaxxWave = std::ranges::find_if(RajaxxWaves, [creature](std::string_view stringId) { return creature->HasStringId(stringId); }, &RajaxxWave::StringId);
|
||||
if (rajaxxWave != RajaxxWaves.end())
|
||||
WaveGuidList[std::ranges::distance(RajaxxWaves.begin(), rajaxxWave)].insert(creature->GetGUID());
|
||||
}
|
||||
|
||||
void OnUnitDeath(Unit* unit) override
|
||||
{
|
||||
case NPC_KURINAXX:
|
||||
_kurinaxxGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_RAJAXX:
|
||||
_rajaxxGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_MOAM:
|
||||
_moamGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_BURU:
|
||||
_buruGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_AYAMISS:
|
||||
_ayamissGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_OSSIRIAN:
|
||||
_ossirianGUID = creature->GetGUID();
|
||||
break;
|
||||
InstanceScript::OnUnitDeath(unit);
|
||||
|
||||
if (unit->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
auto rajaxxWave = std::ranges::find_if(RajaxxWaves, [creature = unit->ToCreature()](std::string_view stringId) { return creature->HasStringId(stringId); }, &RajaxxWave::StringId);
|
||||
if (rajaxxWave != RajaxxWaves.end())
|
||||
{
|
||||
std::ptrdiff_t waveIndex = std::ranges::distance(RajaxxWaves.begin(), rajaxxWave);
|
||||
if (WaveGuidList[waveIndex].erase(unit->GetGUID()) && WaveGuidList[waveIndex].empty())
|
||||
{
|
||||
// start next wave
|
||||
if (waveIndex + 1 < std::ranges::ssize(WaveGuidList))
|
||||
for (ObjectGuid guid : WaveGuidList[waveIndex + 1])
|
||||
if (Creature* creature = instance->GetCreature(guid))
|
||||
if (creature->IsAlive() && !creature->IsInCombat())
|
||||
creature->AI()->DoZoneInCombat();
|
||||
|
||||
if (rajaxxWave->BossActionIdOnClear)
|
||||
if (Creature* rajaxx = GetCreature(DATA_RAJAXX))
|
||||
rajaxx->AI()->DoAction(rajaxxWave->BossActionIdOnClear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,46 +119,79 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript
|
||||
if (!InstanceScript::SetBossState(bossId, state))
|
||||
return false;
|
||||
|
||||
switch (bossId)
|
||||
{
|
||||
case DATA_KURINNAXX:
|
||||
if (state == DONE)
|
||||
{
|
||||
instance->SpawnGroupSpawn(SPAWN_GROUP_ANDOROV);
|
||||
|
||||
if (Creature* ossirian = GetCreature(DATA_OSSIRIAN))
|
||||
ossirian->AI()->DoAction(ACTION_KURINNAXX_DEFEATED);
|
||||
}
|
||||
break;
|
||||
case DATA_RAJAXX:
|
||||
if (state == DONE)
|
||||
{
|
||||
/// @todo: This part requires additional research. Here we check if Andorov's event was started
|
||||
/// and only then change it to finished to enable vendor. Otherwise players can complete
|
||||
/// Rajaxx's encounter without Andorov and then talk to him to buy items, doubt that should happen
|
||||
if (GetData(DATA_ANDOROV_EVENT_STATE) == IN_PROGRESS)
|
||||
{
|
||||
SetData(DATA_ANDOROV_EVENT_STATE, DONE);
|
||||
|
||||
if (Creature* andorov = GetCreature(DATA_ANDOROV))
|
||||
andorov->AI()->DoAction(ACTION_RAJAXX_DEFEATED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
if (type == DATA_ANDOROV_EVENT_STATE)
|
||||
{
|
||||
AndorovEventState = data;
|
||||
if (data == IN_PROGRESS)
|
||||
{
|
||||
// Wave 1
|
||||
for (ObjectGuid guid : WaveGuidList[0])
|
||||
if (Creature* creature = instance->GetCreature(guid))
|
||||
if (creature->IsAlive() && !creature->IsInCombat())
|
||||
creature->AI()->DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
if (type == DATA_ANDOROV_EVENT_STATE)
|
||||
return AndorovEventState;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetGuidData(uint32 type, ObjectGuid data) override
|
||||
{
|
||||
if (type == DATA_PARALYZED)
|
||||
_paralyzedGUID = data;
|
||||
ParalyzedGUID = data;
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_KURINNAXX:
|
||||
return _kurinaxxGUID;
|
||||
case DATA_RAJAXX:
|
||||
return _rajaxxGUID;
|
||||
case DATA_MOAM:
|
||||
return _moamGUID;
|
||||
case DATA_BURU:
|
||||
return _buruGUID;
|
||||
case DATA_AYAMISS:
|
||||
return _ayamissGUID;
|
||||
case DATA_OSSIRIAN:
|
||||
return _ossirianGUID;
|
||||
case DATA_PARALYZED:
|
||||
return _paralyzedGUID;
|
||||
}
|
||||
if (type == DATA_PARALYZED)
|
||||
return ParalyzedGUID;
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectGuid _kurinaxxGUID;
|
||||
ObjectGuid _rajaxxGUID;
|
||||
ObjectGuid _moamGUID;
|
||||
ObjectGuid _buruGUID;
|
||||
ObjectGuid _ayamissGUID;
|
||||
ObjectGuid _ossirianGUID;
|
||||
ObjectGuid _paralyzedGUID;
|
||||
protected:
|
||||
uint8 AndorovEventState;
|
||||
GuidSet WaveGuidList[7];
|
||||
ObjectGuid ParalyzedGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
|
||||
@@ -16,9 +16,248 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "Player.h"
|
||||
#include "ruins_of_ahnqiraj.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Unit.h"
|
||||
|
||||
/*
|
||||
* Some quick facts about the event:
|
||||
*
|
||||
* Event can be completed with or without Andorov, waves will be engaged one after one
|
||||
* Looks like waves aren't linked in some order, for example engaging and killing all waves at once will engage Rajaxx
|
||||
without any issues. Engaging and killing several waves at once will engage next wave. It is unclear what happens if
|
||||
random waves are engaged and killed, probably linked to them waves will be engaged. As well it is unclear what happens
|
||||
if waves are engaged and killed in reverse order
|
||||
* There is a bug on retail when all waves respawn. It is unclear how exactly waves should respawn, NYI
|
||||
* According to patch notes, Andorov should respawn after 15 min if killed, NYI
|
||||
* It is unclear if next wave should be started after specific amount of time even if previous is not yet defeated
|
||||
* Entire event requires additional research since some things may be missing or implemented wrongly
|
||||
*/
|
||||
|
||||
enum AndorovTexts
|
||||
{
|
||||
SAY_PROGRESS_1 = 0,
|
||||
SAY_PROGRESS_2 = 1,
|
||||
SAY_PROGRESS_3 = 2,
|
||||
SAY_PROGRESS_4 = 3,
|
||||
SAY_PROGRESS_5 = 4,
|
||||
SAY_PROGRESS_6 = 5
|
||||
};
|
||||
|
||||
enum AndorovSpells
|
||||
{
|
||||
SPELL_STRIKE = 22591,
|
||||
SPELL_BASH = 25515,
|
||||
SPELL_AURA_OF_COMMAND = 25516
|
||||
};
|
||||
|
||||
enum AndorovEvents
|
||||
{
|
||||
EVENT_INTRO_1 = 1,
|
||||
|
||||
EVENT_PROGRESS_1,
|
||||
EVENT_PROGRESS_2,
|
||||
EVENT_PROGRESS_3,
|
||||
EVENT_PROGRESS_4,
|
||||
EVENT_PROGRESS_5,
|
||||
EVENT_PROGRESS_6,
|
||||
|
||||
EVENT_OUTRO_1,
|
||||
EVENT_OUTRO_2,
|
||||
|
||||
EVENT_STRIKE,
|
||||
EVENT_BASH,
|
||||
EVENT_AURA_OF_COMMAND
|
||||
};
|
||||
|
||||
enum AndorovMisc
|
||||
{
|
||||
PATH_SPAWN = 4,
|
||||
PATH_EVENT = 5,
|
||||
|
||||
GOSSIP_MENU_NOT_STARTED = 6629,
|
||||
GOSSIP_MENU_IN_PROGRESS = 7048,
|
||||
GOSSIP_MENU_FINISHED = 7047,
|
||||
|
||||
NPC_KALDOREI_ELITE = 15473
|
||||
};
|
||||
|
||||
// 15471 - Lieutenant General Andorov
|
||||
struct npc_andorov : public ScriptedAI
|
||||
{
|
||||
npc_andorov(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
void JustAppeared() override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_INTRO_1, 0s);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_combatEvents.Reset();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_combatEvents.ScheduleEvent(EVENT_STRIKE, 10s, 15s);
|
||||
_combatEvents.ScheduleEvent(EVENT_BASH, 15s, 25s);
|
||||
_combatEvents.ScheduleEvent(EVENT_AURA_OF_COMMAND, 10s, 20s);
|
||||
}
|
||||
|
||||
void WaypointPathEnded(uint32 /*waypointId*/, uint32 pathId) override
|
||||
{
|
||||
if (pathId == PATH_EVENT)
|
||||
_events.ScheduleEvent(EVENT_PROGRESS_3, 0s);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
/// @todo: This part is guessed, nothing is changed when Rajaxx is defeated
|
||||
/// but we want to enable vendor, perform emote and despawn. Maybe it is delayed a little?
|
||||
if (action == ACTION_RAJAXX_DEFEATED && me->IsAlive())
|
||||
_events.ScheduleEvent(EVENT_OUTRO_1, 0s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_INTRO_1:
|
||||
me->SetGossipMenuId(GOSSIP_MENU_NOT_STARTED);
|
||||
me->SetVendor(UNIT_NPC_FLAG_VENDOR, false);
|
||||
me->GetMotionMaster()->MovePath(PATH_SPAWN, false);
|
||||
break;
|
||||
|
||||
case EVENT_PROGRESS_1:
|
||||
{
|
||||
me->SetGossipMenuId(GOSSIP_MENU_IN_PROGRESS);
|
||||
_instance->SetData(DATA_ANDOROV_EVENT_STATE, SPECIAL);
|
||||
|
||||
Talk(SAY_PROGRESS_1);
|
||||
|
||||
std::vector<Creature*> elites;
|
||||
GetCreatureListWithEntryInGrid(elites, me, NPC_KALDOREI_ELITE, 50.0f);
|
||||
for (Creature* elite : elites)
|
||||
elite->SetImmuneToNPC(false);
|
||||
me->SetImmuneToNPC(false);
|
||||
_events.ScheduleEvent(EVENT_PROGRESS_2, 3s);
|
||||
break;
|
||||
}
|
||||
case EVENT_PROGRESS_2:
|
||||
Talk(SAY_PROGRESS_2);
|
||||
me->GetMotionMaster()->MovePath(PATH_EVENT, false);
|
||||
break;
|
||||
|
||||
case EVENT_PROGRESS_3:
|
||||
Talk(SAY_PROGRESS_3);
|
||||
_events.ScheduleEvent(EVENT_PROGRESS_4, 4s);
|
||||
break;
|
||||
case EVENT_PROGRESS_4:
|
||||
Talk(SAY_PROGRESS_4);
|
||||
_events.ScheduleEvent(EVENT_PROGRESS_5, 6s);
|
||||
break;
|
||||
case EVENT_PROGRESS_5:
|
||||
Talk(SAY_PROGRESS_5);
|
||||
_events.ScheduleEvent(EVENT_PROGRESS_6, 1s);
|
||||
break;
|
||||
case EVENT_PROGRESS_6:
|
||||
{
|
||||
_instance->SetData(DATA_ANDOROV_EVENT_STATE, IN_PROGRESS);
|
||||
|
||||
std::vector<Creature*> elites;
|
||||
GetCreatureListWithEntryInGrid(elites, me, NPC_KALDOREI_ELITE, 50.0f);
|
||||
for (Creature* elite : elites)
|
||||
elite->SetEmoteState(EMOTE_STATE_READY1H);
|
||||
me->SetEmoteState(EMOTE_STATE_READY1H);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_OUTRO_1:
|
||||
me->SetGossipMenuId(GOSSIP_MENU_FINISHED);
|
||||
me->SetVendor(UNIT_NPC_FLAG_VENDOR, true);
|
||||
_events.ScheduleEvent(EVENT_OUTRO_2, 2min);
|
||||
break;
|
||||
case EVENT_OUTRO_2:
|
||||
{
|
||||
Talk(SAY_PROGRESS_6);
|
||||
|
||||
std::vector<Creature*> elites;
|
||||
GetCreatureListWithEntryInGrid(elites, me, NPC_KALDOREI_ELITE, 50.0f);
|
||||
for (Creature* elite : elites)
|
||||
elite->DespawnOrUnsummon();
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_combatEvents.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = _combatEvents.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_STRIKE:
|
||||
DoCastVictim(SPELL_STRIKE);
|
||||
_combatEvents.Repeat(10s, 15s);
|
||||
break;
|
||||
case EVENT_BASH:
|
||||
DoCastVictim(SPELL_BASH);
|
||||
_combatEvents.Repeat(20s, 25s);
|
||||
break;
|
||||
case EVENT_AURA_OF_COMMAND:
|
||||
DoCastSelf(SPELL_AURA_OF_COMMAND);
|
||||
_combatEvents.Repeat(30s, 50s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
|
||||
{
|
||||
if (menuId == GOSSIP_MENU_NOT_STARTED)
|
||||
{
|
||||
/// @todo: This part requires additional research.
|
||||
/// What should happen if event wasn't started but Rajaxx was defeated?
|
||||
if (_instance->GetBossState(DATA_RAJAXX) != DONE)
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
_events.ScheduleEvent(EVENT_PROGRESS_1, 0s);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
EventMap _combatEvents;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
enum AQ20Itch
|
||||
{
|
||||
@@ -50,5 +289,6 @@ class spell_ruins_of_ahnqiraj_itch : public AuraScript
|
||||
|
||||
void AddSC_ruins_of_ahnqiraj()
|
||||
{
|
||||
RegisterAQ20CreatureAI(npc_andorov);
|
||||
RegisterSpellScript(spell_ruins_of_ahnqiraj_itch);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#define AQ20ScriptName "instance_ruins_of_ahnqiraj"
|
||||
#define DataHeader "AQR"
|
||||
|
||||
uint32 constexpr EncounterCount = 6;
|
||||
|
||||
enum AQRDataTypes
|
||||
{
|
||||
DATA_KURINNAXX = 0,
|
||||
@@ -31,9 +33,10 @@ enum AQRDataTypes
|
||||
DATA_BURU = 3,
|
||||
DATA_AYAMISS = 4,
|
||||
DATA_OSSIRIAN = 5,
|
||||
NUM_ENCOUNTER = 6,
|
||||
|
||||
DATA_PARALYZED = 7
|
||||
DATA_ANDOROV_EVENT_STATE,
|
||||
DATA_ANDOROV,
|
||||
DATA_PARALYZED
|
||||
};
|
||||
|
||||
enum AQRCreatures
|
||||
@@ -44,15 +47,8 @@ enum AQRCreatures
|
||||
NPC_BURU = 15370,
|
||||
NPC_AYAMISS = 15369,
|
||||
NPC_OSSIRIAN = 15339,
|
||||
NPC_HIVEZARA_HORNET = 15934,
|
||||
NPC_HIVEZARA_SWARMER = 15546,
|
||||
NPC_HIVEZARA_LARVA = 15555,
|
||||
NPC_SAND_VORTEX = 15428,
|
||||
NPC_OSSIRIAN_TRIGGER = 15590,
|
||||
NPC_HATCHLING = 15521,
|
||||
NPC_LARVA = 15555,
|
||||
NPC_SWARMER = 15546,
|
||||
NPC_HORNET = 15934
|
||||
|
||||
NPC_ANDOROV = 15471
|
||||
};
|
||||
|
||||
enum AQRGameObjectIds
|
||||
@@ -60,6 +56,23 @@ enum AQRGameObjectIds
|
||||
GO_OSSIRIAN_CRYSTAL = 180619
|
||||
};
|
||||
|
||||
enum AQRSpawnGroups
|
||||
{
|
||||
SPAWN_GROUP_ANDOROV = 333
|
||||
};
|
||||
|
||||
enum AQRActionIds
|
||||
{
|
||||
ACTION_WAVE_STARTS_3 = 0,
|
||||
ACTION_WAVE_STARTS_4 = 1,
|
||||
ACTION_WAVE_STARTS_5 = 2,
|
||||
ACTION_WAVE_STARTS_6 = 3,
|
||||
ACTION_WAVE_STARTS_7 = 4,
|
||||
ACTION_RAJAXX_ENTER = 5,
|
||||
ACTION_KURINNAXX_DEFEATED = 6,
|
||||
ACTION_RAJAXX_DEFEATED = 7
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
inline AI* GetAQ20AI(T* obj)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user