diff --git a/data/sql/updates/db_world/2022_05_21_00.sql b/data/sql/updates/db_world/2022_05_21_00.sql new file mode 100644 index 000000000..67b26acdf --- /dev/null +++ b/data/sql/updates/db_world/2022_05_21_00.sql @@ -0,0 +1,26 @@ +-- DB update 2022_05_18_01 -> 2022_05_21_00 +-- Ulduar / Thorim +DELETE FROM `creature_text` WHERE `CreatureID`=32865; + +-- Thorim - SPECIAL 1 and 3 have no BroadcastTextId +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(32865, 0,0,'Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...',14,0,100,0,0,15733,33145,0,'Thorim SAY_AGGRO_1'), +(32865, 1,0,'I remember you... In the mountains... But you... what is this? Where am--',14,0,100,0,0,15734,33270,0,'Thorim SAY_AGGRO_2'), +(32865, 2,0,'Behold the power of the storms and despair!',14,0,100,0,0,15735,0,0,'Thorim SAY_SPECIAL_1'), +(32865, 3,0,'Do not hold back! Destroy them!',14,0,100,0,0,15736,34241,0,'Thorim SAY_SPECIAL_2'), +(32865, 4,0,'Have you begun to regret your intrusion?',14,0,100,0,0,15737,0,0,'Thorim SAY_SPECIAL_3'), +(32865, 5,0,'Impertinent whelps, you dare challenge me atop my pedestal? I will crush you myself!',14,0,100,0,0,15738,33148,0,'Thorim SAY_JUMPDOWN'), +(32865, 6,0,'Can''t you at least put up a fight!?',14,0,100,0,0,15739,34239,0,'Thorim SAY_SLAY_1'), +(32865, 6,1,'Pathetic.',14,0,100,0,0,15740,35768,0,'Thorim SAY_SLAY_2'), +(32865, 7,0,'My patience has reached its limit!',14,0,100,0,0,15741,33365,0,'Thorim SAY_BERSERK'), +(32865, 8,0,'Failures! Weaklings!',14,0,100,0,0,15742,33274,0,'Thorim SAY_WIPE'), +(32865, 9,0,'Stay your arms! I yield!',14,0,100,0,0,15743,33948,0,'Thorim SAY_DEATH'), +(32865,10,0,'I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.',14,0,100,0,0,15744,33949,0,'Thorim SAY_END_NORMAL_1'), +(32865,11,0,'Sif... was Sif here? Impossible--she died by my brother''s hand. A dark nightmare indeed....',14,0,100,0,0,15745,33950,0,'Thorim SAY_END_NORMAL_2'), +(32865,12,0,'I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.',14,0,100,0,0,15746,33951,0,'Thorim SAY_END_NORMAL_3'), +(32865,13,0,'You! Fiend! You are not my beloved! Be gone!',14,0,100,0,0,15747,33952,0,'Thorim SAY_END_HARD_1'), +(32865,14,0,'Behold the hand behind all the evil that has befallen Ulduar, left my kingdom in ruins, corrupted my brother, and slain my wife.',14,0,100,0,0,15748,33953,0,'Thorim SAY_END_HARD_2'), +(32865,15,0,'And now it falls to you, champions, to avenge us all. The task before you is great, but I will lend you my aid as I am able. You must prevail.',14,0,100,0,0,15749,33954,0,'Thorim SAY_END_HARD_3'); + +-- Set Thorim's traps trigger creature(s) flag +UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 128 WHERE `entry` IN (33054,33725); diff --git a/data/sql/updates/db_world/2022_05_21_01.sql b/data/sql/updates/db_world/2022_05_21_01.sql new file mode 100644 index 000000000..3e6e4aca2 --- /dev/null +++ b/data/sql/updates/db_world/2022_05_21_01.sql @@ -0,0 +1,9 @@ +-- DB update 2022_05_21_00 -> 2022_05_21_01 +-- Ulduar/Mimiron, set Computer model to be female +UPDATE `creature_template` SET `modelid1` = 29101 WHERE `entry` = 34143; + +-- Leviathan Mk II +DELETE FROM `creature_text` WHERE `CreatureID` = 33432; +-- Leviathan Mk II - Plasma Blast boss emote +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(33432, 0, 0, '%s begins to cast Plasma Blast!', 41, 0, 100, 0, 0, 15800, 0, 0, 'Leviathan Mk II - EMOTE_PLASMA_BLAST'); diff --git a/data/sql/updates/db_world/2022_05_21_02.sql b/data/sql/updates/db_world/2022_05_21_02.sql new file mode 100644 index 000000000..42146d55c --- /dev/null +++ b/data/sql/updates/db_world/2022_05_21_02.sql @@ -0,0 +1,14 @@ +-- DB update 2022_05_21_01 -> 2022_05_21_02 +-- Horde Scout, fix wrong broadcastTextId(previously 1934, now 1935) +DELETE FROM `creature_text` WHERE `CreatureID` = 11680; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(11680, 0, 0, 'Time to die, $c.', 12, 0, 100, 0, 0, 0, 1935, 0, 'Horde Scout'); + +-- Horde Scout SAI +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 11680; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 11680; +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 +(11680, 0, 0, 0, 4, 0, 15, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Horde Scout - On Aggro - Say Line 0 (No Repeat)'), +(11680, 0, 1, 0, 0, 0, 100, 0, 0, 0, 2300, 3900, 0, 11, 6660, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Horde Scout - Combat CMC - Cast \'Shoot\''), +(11680, 0, 2, 0, 9, 0, 100, 0, 5, 30, 12000, 15000, 0, 11, 18545, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Horde Scout - Within 5-30 Range - Cast \'Scorpid Sting\''), +(11680, 0, 3, 0, 2, 0, 100, 1, 0, 15, 0, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Horde Scout - 0-15% Health - Flee For Assist (No Repeat)'); diff --git a/data/sql/updates/db_world/2022_05_21_03.sql b/data/sql/updates/db_world/2022_05_21_03.sql new file mode 100644 index 000000000..695984708 --- /dev/null +++ b/data/sql/updates/db_world/2022_05_21_03.sql @@ -0,0 +1,18 @@ +-- DB update 2022_05_21_02 -> 2022_05_21_03 +-- Dungeon/BRD Link mobs in the 2 rooms before High Interrogator Gerstahn (no previous creature_formations for the listed GUIDs) +-- Left room +DELETE FROM `creature_formations` WHERE `memberguid` IN (90695,91054,91082,90850); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(91054, 90695, 0, 0, 3, 0, 0), +(91054, 91054, 0, 0, 3, 0, 0), +(91054, 91082, 0, 0, 3, 0, 0), +(91054, 90850, 0, 0, 3, 0, 0); + +-- Right room +DELETE FROM `creature_formations` WHERE `memberguid` IN (91037,45892,91076,90899,91087); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(91037, 91037, 0, 0, 3, 0, 0), +(91037, 45892, 0, 0, 3, 0, 0), +(91037, 91076, 0, 0, 3, 0, 0), +(91037, 90899, 0, 0, 3, 0, 0), +(91037, 91087, 0, 0, 3, 0, 0); diff --git a/data/sql/updates/db_world/2022_05_21_04.sql b/data/sql/updates/db_world/2022_05_21_04.sql new file mode 100644 index 000000000..9c67a717c --- /dev/null +++ b/data/sql/updates/db_world/2022_05_21_04.sql @@ -0,0 +1,7 @@ +-- DB update 2022_05_21_03 -> 2022_05_21_04 +-- +ALTER TABLE `waypoint_data` CHANGE `orientation` `orientation` FLOAT DEFAULT NULL NULL; +UPDATE `waypoint_data` SET `orientation`= NULL WHERE `orientation`= 0; + +ALTER TABLE `waypoints` CHANGE `orientation` `orientation` FLOAT DEFAULT NULL NULL; +UPDATE `waypoints` SET `orientation`= NULL WHERE `orientation`= 0; diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp index 955c3959c..c34fa3828 100644 --- a/src/common/Collision/Maps/TileAssembler.cpp +++ b/src/common/Collision/Maps/TileAssembler.cpp @@ -382,6 +382,7 @@ namespace VMAP char ident[8]; if (fread(ident, 1, 8, model_list) != 8 || memcmp(ident, VMAP::RAW_VMAP_MAGIC, 8) != 0) { + fclose(model_list); return; } diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index eb4f58b8e..13c9d1c3f 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -57,6 +57,7 @@ void LoadGameObjectModelList(std::string const& dataPath) if (fread(magic, 1, 8, model_list_file) != 8 || memcmp(magic, VMAP::VMAP_MAGIC, 8) != 0) { LOG_ERROR("maps", "File '{}' has wrong header, expected {}.", VMAP::GAMEOBJECT_MODELS, VMAP::VMAP_MAGIC); + fclose(model_list_file); return; } diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 81362efba..612981260 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -257,9 +257,9 @@ void SmartAI::PausePath(uint32 delay, bool forced) me->GetMotionMaster()->MoveIdle();//force stop auto waypoint = mWayPoints->find(mCurrentWPID); - if (float orientation = waypoint->second->o) + if (waypoint->second->o.has_value()) { - me->SetFacingTo(orientation); + me->SetFacingTo(waypoint->second->o.has_value()); } } GetScript()->ProcessEventsFor(SMART_EVENT_WAYPOINT_PAUSED, nullptr, mCurrentWPID, GetScript()->GetPathId()); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index fb98247a1..23a93f166 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -79,11 +79,12 @@ void SmartWaypointMgr::LoadFromDB() Field* fields = result->Fetch(); uint32 entry = fields[0].Get(); uint32 id = fields[1].Get(); - float x, y, z, o; - x = fields[2].Get(); - y = fields[3].Get(); - z = fields[4].Get(); - o = fields[5].Get(); + float x = fields[2].Get(); + float y = fields[3].Get(); + float z = fields[4].Get(); + Optional o; + if (!fields[5].IsNull()) + o = fields[5].Get(); uint32 delay = fields[6].Get(); if (last_entry != entry) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index be9357fab..0867679fe 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -22,6 +22,7 @@ #include "Creature.h" #include "CreatureAI.h" #include "DBCStores.h" +#include "Optional.h" #include "Spell.h" #include "SpellMgr.h" #include "Unit.h" @@ -30,7 +31,7 @@ typedef uint32 SAIBool; struct WayPoint { - WayPoint(uint32 _id, float _x, float _y, float _z, float _o, uint32 _delay) + WayPoint(uint32 _id, float _x, float _y, float _z, Optional _o, uint32 _delay) { id = _id; x = _x; @@ -44,7 +45,7 @@ struct WayPoint float x; float y; float z; - float o; + std::optional o; uint32 delay; }; diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index ffb8b174d..10c9563df 100644 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -175,9 +175,8 @@ bool WaypointMovementGenerator::StartMove(Creature* creature) //! but formationDest contains global coordinates init.MoveTo(node->x, node->y, z, true, true); - //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table - if (node->orientation && node->delay) - init.SetFacing(node->orientation); + if (node->orientation.has_value() && node->delay > 0) + init.SetFacing(*node->orientation); switch (node->move_type) { diff --git a/src/server/game/Movement/Waypoints/WaypointMgr.cpp b/src/server/game/Movement/Waypoints/WaypointMgr.cpp index 9be0b3bd0..6b8601fa1 100644 --- a/src/server/game/Movement/Waypoints/WaypointMgr.cpp +++ b/src/server/game/Movement/Waypoints/WaypointMgr.cpp @@ -70,7 +70,9 @@ void WaypointMgr::Load() float x = fields[2].Get(); float y = fields[3].Get(); float z = fields[4].Get(); - float o = fields[5].Get(); + std::optional o; + if (!fields[5].IsNull()) + o = fields[5].Get(); Acore::NormalizeMapCoord(x); Acore::NormalizeMapCoord(y); @@ -131,7 +133,9 @@ void WaypointMgr::ReloadPath(uint32 id) float x = fields[1].Get(); float y = fields[2].Get(); float z = fields[3].Get(); - float o = fields[4].Get(); + std::optional o; + if (!fields[4].IsNull()) + o = fields[4].Get(); Acore::NormalizeMapCoord(x); Acore::NormalizeMapCoord(y); diff --git a/src/server/game/Movement/Waypoints/WaypointMgr.h b/src/server/game/Movement/Waypoints/WaypointMgr.h index c9ea8e709..0d81e14cf 100644 --- a/src/server/game/Movement/Waypoints/WaypointMgr.h +++ b/src/server/game/Movement/Waypoints/WaypointMgr.h @@ -35,7 +35,8 @@ enum WaypointMoveType struct WaypointData { uint32 id; - float x, y, z, orientation; + float x, y, z; + std::optional orientation; uint32 delay; uint32 event_id; uint32 move_type; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 62e1fd872..d2ae3c9ae 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -214,29 +214,6 @@ enum EVENTS EVENT_EMERGENCY_BOT_ATTACK = 70, }; -enum SOUNDS -{ - SOUND_TANK_INTRO = 15611, - SOUND_TANK_ACTIVE = 15612, - SOUND_TANK_SLAY_1 = 15613, - SOUND_TANK_SLAY_2 = 15614, - SOUND_TANK_DEATH = 15615, - SOUND_TORSO_ACTIVE = 15616, - SOUND_TORSO_SLAY_1 = 15617, - SOUND_TORSO_SLAY_2 = 15618, - SOUND_TORSO_DEATH = 15619, - SOUND_HEAD_ACTIVE = 15620, - SOUND_HEAD_SLAY_1 = 15621, - SOUND_HEAD_SLAY_2 = 15622, - SOUND_HEAD_DEATH = 15623, - SOUND_VOLTRON_ACTIVE = 15624, - SOUND_VOLTRON_SLAY_1 = 15625, - SOUND_VOLTRON_SLAY_2 = 15626, - SOUND_VOLTRON_DEATH = 15627, - SOUND_BERSERK = 15628, - SOUND_TANK_HARD_INTRO = 15629, -}; - #define SPELL_NAPALM_SHELL RAID_MODE(SPELL_NAPALM_SHELL_10, SPELL_NAPALM_SHELL_25) #define SPELL_PLASMA_BLAST RAID_MODE(SPELL_PLASMA_BLAST_10, SPELL_PLASMA_BLAST_25) #define SPELL_MINE_EXPLOSION RAID_MODE(SPELL_MINE_EXPLOSION_10, SPELL_MINE_EXPLOSION_25) @@ -245,41 +222,42 @@ enum SOUNDS #define SPELL_HAND_PULSE_L RAID_MODE(SPELL_HAND_PULSE_10_L, SPELL_HAND_PULSE_25_L) #define SPELL_FROST_BOMB_EXPLOSION RAID_MODE(SPELL_FROST_BOMB_EXPLOSION_10, SPELL_FROST_BOMB_EXPLOSION_25) -#define TEXT_AGGRO "Oh, my! I wasn't expecting company! The workshop is such a mess! How embarrassing!" -#define TEXT_BERSERK "Oh, my! It would seem that we are out of time, my friends!" -#define TEXT_HARDMODE "Now why would you go and do something like that? Didn't you see the sign that said 'DO NOT PUSH THIS BUTTON!'? How will we finish testing with the self-destruct mechanism active?" -#define TEXT_LMK2_ACTIVATE "We haven't much time, friends! You're going to help me test out my latest and greatest creation. Now, before you change your minds, remember, that you kind of owe it to me after the mess you made with the XT-002." -#define TEXT_LMK2_SLAIN_1 "MEDIC!" -#define TEXT_LMK2_SLAIN_2 "I can fix that... or, maybe not! Sheesh, what a mess..." -#define TEXT_LMK2_DEATH "WONDERFUL! Positively marvelous results! Hull integrity at 98.9 percent! Barely a dent! Moving right along." -#define TEXT_VX001_ACTIVATE "Behold the VX-001 Anti-personnel Assault Cannon! You might want to take cover." -#define TEXT_VX001_SLAIN_1 "Fascinating. I think they call that a \"clean kill\"." -#define TEXT_VX001_SLAIN_2 "Note to self: Cannon highly effective against flesh." -#define TEXT_VX001_DEATH "Thank you, friends! Your efforts have yielded some fantastic data! Now, where did I put-- oh, there it is!" -#define TEXT_ACU_ACTIVATE "Isn't it beautiful? I call it the magnificent aerial command unit!" -#define TEXT_ACU_SLAIN_1 "Outplayed!" -#define TEXT_ACU_SLAIN_2 "You can do better than that!" -#define TEXT_ACU_DEATH "Preliminary testing phase complete. Now comes the true test!!" -#define TEXT_VOLTRON_ACTIVATE "Gaze upon its magnificence! Bask in its glorious, um, glory! I present you... V-07-TR-0N!" -#define TEXT_VOLTRON_SLAIN_1 "Prognosis: Negative!" -#define TEXT_VOLTRON_SLAIN_2 "You're not going to get up from that one, friend." -#define TEXT_VOLTRON_DEATH "It would appear that I've made a slight miscalculation. I allowed my mind to be corrupted by the fiend in the prison, overriding my primary directive. All systems seem to be functional now. Clear." - -enum ComputerTalks +enum Texts { - TALK_COMPUTER_INITIATED = 0, - TALK_COMPUTER_TERMINATED = 1, - TALK_COMPUTER_TEN = 2, - TALK_COMPUTER_NINE = 3, - TALK_COMPUTER_EIGHT = 4, - TALK_COMPUTER_SEVEN = 5, - TALK_COMPUTER_SIX = 6, - TALK_COMPUTER_FIVE = 7, - TALK_COMPUTER_FOUR = 8, - TALK_COMPUTER_THREE = 9, - TALK_COMPUTER_TWO = 10, - TALK_COMPUTER_ONE = 11, - TALK_COMPUTER_ZERO = 12, + // Mimiron + SAY_AGGRO = 0, // Unused + SAY_HARDMODE_ON = 1, + SAY_MKII_ACTIVATE = 2, + SAY_MKII_SLAY = 3, + SAY_MKII_DEATH = 4, + SAY_VX001_ACTIVATE = 5, + SAY_VX001_SLAY = 6, + SAY_VX001_DEATH = 7, + SAY_AERIAL_ACTIVATE = 8, + SAY_AERIAL_SLAY = 9, + SAY_AERIAL_DEATH = 10, + SAY_V07TRON_ACTIVATE = 11, + SAY_V07TRON_SLAY = 12, + SAY_V07TRON_DEATH = 13, + SAY_BERSERK = 14, + + // MK II + EMOTE_PLASMA_BLAST = 0, + + // Computer (Hardmode countdown) + TALK_COMPUTER_INITIATED = 0, + TALK_COMPUTER_TERMINATED = 1, + TALK_COMPUTER_TEN = 2, + TALK_COMPUTER_NINE = 3, + TALK_COMPUTER_EIGHT = 4, + TALK_COMPUTER_SEVEN = 5, + TALK_COMPUTER_SIX = 6, + TALK_COMPUTER_FIVE = 7, + TALK_COMPUTER_FOUR = 8, + TALK_COMPUTER_THREE = 9, + TALK_COMPUTER_TWO = 10, + TALK_COMPUTER_ONE = 11, + TALK_COMPUTER_ZERO = 12, }; #define GetMimiron() ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(TYPE_MIMIRON)) @@ -382,8 +360,7 @@ public: if (!hardmode) { - me->Yell(TEXT_LMK2_ACTIVATE, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_TANK_ACTIVE); + Talk(SAY_MKII_ACTIVATE); events.ScheduleEvent(EVENT_SIT_LMK2, 6000); events.ScheduleEvent(EVENT_BERSERK, 900000); } @@ -448,8 +425,7 @@ public: computer->AI()->Talk(minutesTalkNum++); break; case EVENT_MIMIRON_SAY_HARDMODE: - me->Yell(TEXT_HARDMODE, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_TANK_HARD_INTRO); + Talk(SAY_HARDMODE_ON); events.ScheduleEvent(EVENT_SPAWN_FLAMES_INITIAL, 0); events.ScheduleEvent(EVENT_SIT_LMK2, 4000); break; @@ -485,8 +461,7 @@ public: break; case EVENT_BERSERK: berserk = true; - me->Yell(TEXT_BERSERK, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_BERSERK); + Talk(SAY_BERSERK); if( hardmode ) me->SummonCreature(33576, 2744.78f, 2569.47f, 364.32f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 120000); events.ScheduleEvent(EVENT_BERSERK_2, 0); @@ -533,8 +508,7 @@ public: if (Creature* LMK2 = GetLMK2()) { me->EnterVehicle(LMK2, 1); - me->Yell(TEXT_LMK2_DEATH, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_TANK_DEATH); + Talk(SAY_MKII_DEATH); LMK2->SetFacingTo(3.58f); events.ScheduleEvent(EVENT_ELEVATOR_INTERVAL_0, 6000); break; @@ -574,8 +548,7 @@ public: EnterEvadeMode(EVADE_REASON_OTHER); break; case EVENT_SITTING_ON_VX001: - me->Yell(TEXT_VX001_ACTIVATE, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_TORSO_ACTIVE); + Talk(SAY_VX001_ACTIVATE); events.ScheduleEvent(EVENT_ENTER_VX001, 5000); break; case EVENT_ENTER_VX001: @@ -632,8 +605,7 @@ public: break; case EVENT_SAY_VX001_DEAD: changeAllowedFlameSpreadTime = true; - me->Yell(TEXT_VX001_DEATH, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_TORSO_DEATH); + Talk(SAY_VX001_DEATH); events.ScheduleEvent(EVENT_ENTER_ACU, 7000); break; case EVENT_ENTER_ACU: @@ -646,8 +618,7 @@ public: EnterEvadeMode(EVADE_REASON_OTHER); break; case EVENT_SAY_ACU_ACTIVATE: - me->Yell(TEXT_ACU_ACTIVATE, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_HEAD_ACTIVE); + Talk(SAY_AERIAL_ACTIVATE); events.ScheduleEvent(EVENT_ACU_START_ATTACK, 4000); break; case EVENT_ACU_START_ATTACK: @@ -662,8 +633,7 @@ public: EnterEvadeMode(EVADE_REASON_OTHER); break; case EVENT_SAY_ACU_DEAD: - me->Yell(TEXT_ACU_DEATH, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_HEAD_DEATH); + Talk(SAY_AERIAL_DEATH); events.ScheduleEvent(EVENT_LEVIATHAN_COME_CLOSER, 5000); break; case EVENT_LEVIATHAN_COME_CLOSER: @@ -721,8 +691,7 @@ public: ACU->SetDisableGravity(false); ACU->EnterVehicle(VX001, 3); me->EnterVehicle(VX001, 1); - me->Yell(TEXT_VOLTRON_ACTIVATE, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_VOLTRON_ACTIVE); + Talk(SAY_V07TRON_ACTIVATE); events.ScheduleEvent(EVENT_START_PHASE4, 10000); } break; @@ -815,8 +784,7 @@ public: } break; case EVENT_SAY_VOLTRON_DEAD: - me->Yell(TEXT_VOLTRON_DEATH, LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_VOLTRON_DEATH); + Talk(SAY_V07TRON_DEATH); // spawn chest if (uint32 chestId = (hardmode ? RAID_MODE(GO_MIMIRON_CHEST_HARD, GO_MIMIRON_CHEST_HERO_HARD) : RAID_MODE(GO_MIMIRON_CHEST, GO_MIMIRON_CHEST_HERO))) { @@ -1168,7 +1136,7 @@ public: case EVENT_SPELL_PLASMA_BLAST: if (Unit* victim = me->GetVictim()) { - me->TextEmote("Leviathan Mk II begins to cast Plasma Blast!", nullptr, true); + Talk(EMOTE_PLASMA_BLAST); cannon->CastSpell(victim, SPELL_PLASMA_BLAST, false); } events.RepeatEvent(22000); @@ -1194,34 +1162,16 @@ public: void KilledUnit(Unit* who) override { - if( who->GetTypeId() == TYPEID_PLAYER ) + if (who->GetTypeId() == TYPEID_PLAYER) if (Creature* c = GetMimiron()) { - if( Phase == 1 ) + if (Phase == 1) { - if( rand() % 2 ) - { - c->Yell(TEXT_LMK2_SLAIN_1, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_TANK_SLAY_1); - } - else - { - c->Yell(TEXT_LMK2_SLAIN_2, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_TANK_SLAY_2); - } + c->AI()->Talk(SAY_MKII_SLAY); } else { - if( rand() % 2 ) - { - c->Yell(TEXT_VOLTRON_SLAIN_1, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_VOLTRON_SLAY_1); - } - else - { - c->Yell(TEXT_VOLTRON_SLAIN_2, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_VOLTRON_SLAY_2); - } + c->AI()->Talk(SAY_V07TRON_SLAY); } } } @@ -1548,34 +1498,16 @@ public: void KilledUnit(Unit* who) override { - if( who->GetTypeId() == TYPEID_PLAYER ) - if( Creature* c = GetMimiron() ) + if (who->GetTypeId() == TYPEID_PLAYER) + if (Creature* c = GetMimiron()) { - if( Phase == 2 ) + if (Phase == 2) { - if( rand() % 2 ) - { - c->Yell(TEXT_VX001_SLAIN_1, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_TORSO_SLAY_1); - } - else - { - c->Yell(TEXT_VX001_SLAIN_2, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_TORSO_SLAY_2); - } + c->AI()->Talk(SAY_VX001_SLAY); } else { - if( rand() % 2 ) - { - c->Yell(TEXT_VOLTRON_SLAIN_1, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_VOLTRON_SLAY_1); - } - else - { - c->Yell(TEXT_VOLTRON_SLAIN_2, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_VOLTRON_SLAY_2); - } + c->AI()->Talk(SAY_V07TRON_SLAY); } } } @@ -1871,34 +1803,16 @@ public: void KilledUnit(Unit* who) override { - if( who->GetTypeId() == TYPEID_PLAYER ) - if( Creature* c = GetMimiron() ) + if (who->GetTypeId() == TYPEID_PLAYER) + if (Creature* c = GetMimiron()) { - if( Phase == 3 ) + if (Phase == 3) { - if( rand() % 2 ) - { - c->Yell(TEXT_ACU_SLAIN_1, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_HEAD_SLAY_1); - } - else - { - c->Yell(TEXT_ACU_SLAIN_2, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_HEAD_SLAY_2); - } + c->AI()->Talk(SAY_AERIAL_SLAY); } else { - if( rand() % 2 ) - { - c->Yell(TEXT_VOLTRON_SLAIN_1, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_VOLTRON_SLAY_1); - } - else - { - c->Yell(TEXT_VOLTRON_SLAIN_2, LANG_UNIVERSAL); - c->PlayDirectSound(SOUND_VOLTRON_SLAY_2); - } + c->AI()->Talk(SAY_V07TRON_SLAY); } } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index 16bc0d23b..44dbcd34b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -267,29 +267,36 @@ const Position ArenaNPCs[] = {2087.46f, -298.71f, 440.5f, 0.59f} }; -enum ThorimSounds +enum Texts { - SOUND_AGGRO1 = 15733, - SOUND_AGGRO2 = 15734, - SOUND_SPECIAL1 = 15735, - SOUND_SPECIAL2 = 15736, - SOUND_SPECIAL3 = 15737, - SOUND_JUMPDOWN = 15738, - SOUND_SLAY1 = 15739, - SOUND_SLAY2 = 15740, - SOUND_BERSERK = 15741, - SOUND_AWIPE = 15742, - SOUND_DEFEATED = 15743, - SOUND_NORM1 = 15744, - SOUND_NORM2 = 15745, - SOUND_NORM3 = 15746, - SOUND_HARD1 = 15747, - SOUND_HARD2 = 15748, - SOUND_HARD3 = 15749, + // Thorim + SAY_AGGRO_1 = 0, + SAY_AGGRO_2 = 1, + SAY_SPECIAL_1 = 2, // Unused + SAY_SPECIAL_2 = 3, + SAY_SPECIAL_3 = 4, // Unused + SAY_JUMPDOWN = 5, + SAY_SLAY = 6, + SAY_BERSERK = 7, + SAY_WIPE = 8, + SAY_DEATH = 9, + SAY_END_NORMAL_1 = 10, + SAY_END_NORMAL_2 = 11, + SAY_END_NORMAL_3 = 12, + SAY_END_HARD_1 = 13, + SAY_END_HARD_2 = 14, + SAY_END_HARD_3 = 15, - SOUND_SIF_START = 15668, - SOUND_SIF_DESPAWN = 15669, - SOUND_SIF_EVENT = 15670, + // Sif + SAY_SIF_AGGRO = 0, + SAY_SIF_HM_MISSED = 1, + SAY_SIF_HM_REACHED = 2, + + // Ancient Rune Giant + SAY_GIANT_RUNIC_MIGHT = 0, + + // Runic Colossus + SAY_COLOSSUS_RUNIC_BARRIER = 0, }; enum Misc @@ -487,32 +494,20 @@ public: if (GameObject* go = GetThorimObject(DATA_THORIM_LEVER)) go->RemoveGameObjectFlag((GameObjectFlags)48); + events.ScheduleEvent(EVENT_THORIM_AGGRO, 0); events.SetPhase(EVENT_PHASE_START); events.ScheduleEvent(EVENT_THORIM_START_PHASE1, 20000); _trashCounter = 0; } - else if (_trashCounter == 5) - events.ScheduleEvent(EVENT_THORIM_AGGRO, 0); } else if (param == ACTION_ALLOW_HIT) _isHitAllowed = true; } - void KilledUnit(Unit*) override + void KilledUnit(Unit* victim) override { - if (urand(0, 2)) - return; - - if (urand(0, 1)) - { - me->Yell("Can't you at least put up a fight!?", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SLAY1); - } - else - { - me->Yell("Pathetic!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SLAY2); - } + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void JustReachedHome() override { me->setActive(false); } @@ -544,8 +539,7 @@ public: me->GetMotionMaster()->MoveJump(Middle.GetPositionX(), Middle.GetPositionY(), Middle.GetPositionZ(), 20, 20); me->RemoveAura(SPELL_SHEATH_OF_LIGHTNING); - me->Yell("Impertinent whelps! You dare challenge me atop my pedestal! I will crush you myself!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_JUMPDOWN); + Talk(SAY_JUMPDOWN); // Hard Mode if (!me->HasAura(62565 /*TOUCH OF DOMINION TRIGGER*/)) @@ -577,8 +571,7 @@ public: events.Reset(); DisableThorim(true); - me->Yell("Stay your arms! I yield!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_DEFEATED); + Talk(SAY_DEATH); events.SetPhase(EVENT_PHASE_OUTRO); events.ScheduleEvent(EVENT_THORIM_OUTRO1, 2000, 0, EVENT_PHASE_OUTRO); @@ -591,7 +584,7 @@ public: if (_hardMode) chestId += 1; // hard mode offset - if ((go = me->SummonGameObject(chestId, 2134.73f, -286.32f, 419.51f, 0.0f, 0, 0, 0, 0, 0))) + if ((go = me->SummonGameObject(chestId, 2134.73f, -286.32f, 419.51f, 4.65f, 0, 0, 0, 0, 0))) { go->ReplaceAllGameObjectFlags((GameObjectFlags)0); go->SetLootRecipient(me->GetMap()); @@ -642,28 +635,6 @@ public: _hitByLightning = true; } - void PlaySpecial() - { - if (urand(0, 9)) - return; - - switch (urand(0, 2)) - { - case 0: - me->Yell("Behold the power of the storms and despair!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SPECIAL1); - break; - case 1: - me->Yell("Do not hold back! Destroy them!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SPECIAL2); - break; - case 2: - me->Yell("Have you begun to regret your intrusion? ", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SPECIAL3); - break; - } - } - Player* GetArenaPlayer() { Map::PlayerList const& pList = me->GetMap()->GetPlayers(); @@ -686,8 +657,7 @@ public: switch (events.ExecuteEvent()) { case EVENT_THORIM_AGGRO: - me->Yell("Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_AGGRO1); + Talk(SAY_AGGRO_1); events.ScheduleEvent(EVENT_THORIM_AGGRO2, 9000); if (GameObject* go = GetThorimObject(DATA_THORIM_FENCE)) @@ -696,8 +666,7 @@ public: break; case EVENT_THORIM_AGGRO2: { - me->Yell("I remember you... In the mountains... But you... what is this? Where am--", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_AGGRO2); + Talk(SAY_AGGRO_2); EntryCheckPredicate pred(NPC_SIF); summons.DoAction(ACTION_SIF_START_TALK, pred); @@ -718,12 +687,10 @@ public: case EVENT_THORIM_STORMHAMMER: me->CastCustomSpell(SPELL_STORMHAMMER, SPELLVALUE_MAX_TARGETS, 1, me->GetVictim(), false); events.RepeatEvent(16000); - PlaySpecial(); break; case EVENT_THORIM_CHARGE_ORB: me->CastCustomSpell(SPELL_CHARGE_ORB, SPELLVALUE_MAX_TARGETS, 1, me, false); events.RepeatEvent(16000); - PlaySpecial(); break; case EVENT_THORIM_LIGHTNING_ORB: { @@ -735,8 +702,7 @@ public: } // No players found - me->Yell("Failures! Weaklings!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_AWIPE); + Talk(SAY_WIPE); me->SummonCreature(NPC_LIGHTNING_ORB, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); _isArenaEmpty = true; @@ -752,7 +718,6 @@ public: case EVENT_THORIM_FILL_ARENA: SpawnArenaNPCs(); events.RepeatEvent(10000); - PlaySpecial(); break; case EVENT_THORIM_UNBALANCING_STRIKE: me->CastSpell(me->GetVictim(), SPELL_UNBALANCING_STRIKE, false); @@ -768,49 +733,42 @@ public: break; case EVENT_THORIM_BERSERK: me->CastSpell(me, SPELL_BERSERK, true); - me->Yell("My patience has reached its limit!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_BERSERK); + Talk(SAY_BERSERK); break; case EVENT_THORIM_OUTRO1: if (_hardMode) { - me->Yell("You! Fiend! You are not my beloved! Be gone!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_HARD1); + Talk(SAY_END_HARD_1); events.ScheduleEvent(EVENT_THORIM_OUTRO2, 5000, 0, 3); EntryCheckPredicate pred(NPC_SIF); summons.DoAction(ACTION_SIF_TRANSFORM, pred); } else { - me->Yell("I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_NORM1); + Talk(SAY_END_NORMAL_1); events.ScheduleEvent(EVENT_THORIM_OUTRO2, 9000, 0, 3); } break; case EVENT_THORIM_OUTRO2: if (_hardMode) { - me->Yell("Behold the hand behind all the evil that has befallen Ulduar! Left my kingdom in ruins, corrupted my brother and slain my wife!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_HARD2); + Talk(SAY_END_HARD_2); events.ScheduleEvent(EVENT_THORIM_OUTRO3, 12000, 0, 3); } else { - me->Yell("Sif... was Sif here? Impossible--she died by my brother's hand. A dark nightmare indeed....", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_NORM2); + Talk(SAY_END_NORMAL_2); events.ScheduleEvent(EVENT_THORIM_OUTRO3, 10000, 0, 3); } break; case EVENT_THORIM_OUTRO3: if (_hardMode) { - me->Yell("And now it falls to you, champions, to avenge us all! The task before you is great, but I will lend you my aid as I am able. You must prevail!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_HARD3); + Talk(SAY_END_HARD_3); } else { - me->Yell("I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_NORM3); + Talk(SAY_END_NORMAL_3); } // Defeat credit @@ -891,17 +849,14 @@ public: switch (events.ExecuteEvent()) { case EVENT_SIF_FINISH_DOMINION: - me->PlayDirectSound(SOUND_SIF_DESPAWN); - me->Yell("This pathetic morons are harmless. Relive my station, dispose of them!", LANG_UNIVERSAL); + Talk(SAY_SIF_HM_MISSED); me->DespawnOrUnsummon(5000); break; case EVENT_SIF_START_TALK: - me->Yell("Thorim, my lord, why else would these invaders have come into your sanctum but to slay you? They must be stopped!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SIF_START); + Talk(SAY_SIF_AGGRO); break; case EVENT_SIF_JOIN_TALK: - me->PlayDirectSound(SOUND_SIF_EVENT); - me->Yell("Impossible! Lord Thorim, I will bring your foes a frigid death!", LANG_UNIVERSAL); + Talk(SAY_SIF_HM_REACHED); events.ScheduleEvent(EVENT_SIF_FROST_NOVA_START, 1000); events.ScheduleEvent(EVENT_SIF_FROSTBOLT_VALLEY, 11000); events.ScheduleEvent(EVENT_SIF_BLIZZARD, 15000); @@ -1420,8 +1375,13 @@ public: void JustDied(Unit*) override { if (me->GetInstanceScript()) + { if (GameObject* go = ObjectAccessor::GetGameObject(*me, me->GetInstanceScript()->GetGuidData(DATA_THORIM_FIRST_DOORS))) go->SetGoState(GO_STATE_ACTIVE); + + if (Creature* cr = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(TYPE_THORIM))) + cr->AI()->Talk(SAY_SPECIAL_2); + } } void EnterCombat(Unit*) override @@ -1494,7 +1454,7 @@ public: break; case EVENT_RC_RUNIC_BARRIER: me->CastSpell(me, SPELL_RUNIC_BARRIER, false); - me->TextEmote("Runic Colossus surrounds itself with a crackling Runic Barrier!", nullptr, true); + Talk(SAY_COLOSSUS_RUNIC_BARRIER); events.RepeatEvent(20000); break; case EVENT_RC_SMASH: @@ -1544,7 +1504,7 @@ public: events.ScheduleEvent(EVENT_ARG_STOMP, 8000); me->CastSpell(me, SPELL_RUNIC_FORTIFICATION, false); - me->TextEmote("Ancient Rune Giant fortifies nearby allies with runic might", nullptr, true); + Talk(SAY_GIANT_RUNIC_MIGHT); } void JustDied(Unit*) override diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp index 08d6b0ce4..88d0a87f5 100644 --- a/src/server/scripts/Northrend/zone_dalaran.cpp +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -115,6 +115,10 @@ enum DisguiseMisc SPELL_EVOCATION_VISUAL = 69659, NPC_AQUANOS_ENTRY = 36851, + + GOSSIP_MENU_AQUANOS = 10854, + GOSSIP_AQUANOS_ALLIANCE = 0, + GOSSIP_AQUANOS_HORDE = 1, }; enum spells @@ -246,9 +250,9 @@ public: player->GetQuestStatus(QUEST_SUITABLE_DISGUISE_H) == QUEST_STATUS_INCOMPLETE) { if(player->GetTeamId() == TEAM_ALLIANCE) - AddGossipItemFor(player, 0, "Arcanist Tybalin said you might be able to lend me a certain tabard.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + AddGossipItemFor(player, GOSSIP_MENU_AQUANOS, GOSSIP_AQUANOS_ALLIANCE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); else - AddGossipItemFor(player, 0, "Magister Hathorel said you might be able to lend me a certain tabard.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + AddGossipItemFor(player, GOSSIP_MENU_AQUANOS, GOSSIP_AQUANOS_HORDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); } SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID()); diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index 878fae16b..63692bec2 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -15,16 +15,6 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Dragonblight -SD%Complete: 100 -SDComment: -SDCategory: Dragonblight -EndScriptData */ - -/* ContentData -EndContentData */ - #include "CellImpl.h" #include "Chat.h" #include "CombatAI.h" @@ -43,19 +33,33 @@ EndContentData */ /******** QUEST Conversing With the Depths (12032) ********/ -#define QUEST_CONVERSING_WITH_THE_DEPTHS 12032 -#define DEEPDIVING_PEARL_BUFF 41273 -#define NPC_OACHANOA 26648 -#define NPC_CONVERSING_WITH_THE_DEPTHS_TRIGGER 70100 -#define OACHANOA_T_1_1 "Little " -#define OACHANOA_T_1_2 ", why do you call me forth? Are you working with the trolls of this land? Have you come to kill me and take my power as your own?" -#define OACHANOA_T_2 "I sense uncertainty in you, and I do not trust it whether you are with them, or not. If you wish my augury for the Kalu'ak, you will have to prove yourself first." -#define OACHANOA_T_3 "I will lay a mild compulsion upon you. Jump into the depths before me so that you put yourself into my element and thereby display your submission." -#define OACHANOA_T_4_1 "Well done, " -#define OACHANOA_T_4_2 ". Your display of respect is duly noted. Now, I have information for you that you must convey to the Kalu'ak." -#define OACHANOA_T_5 "Simply put, you must tell the tuskarr that they cannot run. If they do so, their spirits will be destroyed by the evil rising within Northrend." -#define OACHANOA_T_6 "Tell the mystic that his people are to stand and fight alongside the Horde and Alliance against the forces of Malygos and the Lich King." -#define OACHANOA_T_7_1 "Now swim back with the knowledge I have granted you. Do what you can for them " + +enum DepthsMisc +{ + QUEST_CONVERSING_WITH_THE_DEPTHS = 12032, + DEEPDIVING_PEARL_BUFF = 41273, + NPC_OACHANOA = 26648, + NPC_CONVERSING_WITH_THE_DEPTHS_TRIGGER = 70100, +}; + +enum DepthsTexts +{ + // Oacha'noa being summoned + SAY_OACHANOA_SUMMONED_0 = 0, + SAY_OACHANOA_SUMMONED_1 = 1, + SAY_OACHANOA_SUMMONED_2 = 2, + SAY_OACHANOA_SUMMONED_3 = 3, + //SAY_OACHANOA_SUMMONED_4 = 4, // Unused(no source) and no BroadcastTextId + + // If success + SAY_OACHANOA_SUCCESS = 5, + WHISPER_OACHANOA_SUCCESS_0 = 6, + WHISPER_OACHANOA_SUCCESS_1 = 7, + WHISPER_OACHANOA_SUCCESS_2 = 8, + + // If failed + SAY_OACHANOA_FAILED = 9, +}; class npc_conversing_with_the_depths_trigger : public CreatureScript { @@ -73,15 +77,20 @@ public: bool running; bool secondpart; + bool canjump; int32 timer; uint8 step; ObjectGuid pGUID; ObjectGuid oachanoaGUID; + Creature* GetOachanoa() {return ObjectAccessor::GetCreature(*me, oachanoaGUID);} + Player* GetPlayer() {return ObjectAccessor::GetPlayer(*me, pGUID);} + void Reset() override { running = false; secondpart = false; + canjump = false; timer = 0; step = 0; pGUID.Clear(); @@ -94,63 +103,48 @@ public: timer = time; } - void Say(std::string text, bool yell) - { - Creature* c = ObjectAccessor::GetCreature(*me, oachanoaGUID); - Player* player = ObjectAccessor::GetPlayer(*me, pGUID); - if (!c || !player) - { - Reset(); - return; - } - - if (yell) - c->Yell(text.c_str(), LANG_UNIVERSAL, player); - else - c->Whisper(text.c_str(), LANG_UNIVERSAL, player); - } - void DespawnOachanoa() { - if (Creature* c = ObjectAccessor::GetCreature(*me, oachanoaGUID)) + if (Creature* c = GetOachanoa()) c->DespawnOrUnsummon(); } void UpdateAI(uint32 diff) override { - if( running ) + if (running) { - if( Player* p = ObjectAccessor::GetPlayer(*me, pGUID) ) - if( p->GetPositionZ() < 1.0f && !secondpart ) + if (Player* p = GetPlayer()) + if (p->GetPositionZ() < 1.0f && !secondpart) // Player is in the water { - if( p->HasAura(DEEPDIVING_PEARL_BUFF) ) + if (p->HasAura(DEEPDIVING_PEARL_BUFF) && canjump) { NextStep(500); secondpart = true; } - else + else // Despawn and fail quest if player jumps too early { + p->SendQuestFailed(QUEST_CONVERSING_WITH_THE_DEPTHS); DespawnOachanoa(); Reset(); } } - if( timer != 0 ) + if (timer != 0) { timer -= diff; - if( timer < 0 ) + if (timer < 0) timer = 0; } else - switch( step ) + switch (step) { case 0: NextStep(10000); break; - case 1: + case 1: // Oacha'noa being summoned { Creature* c = me->SummonCreature(NPC_OACHANOA, 2406.24f, 1701.98f, 0.1f, 0.3f, TEMPSUMMON_TIMED_DESPAWN, 90000, 0); - if( !c ) + if (!c) { Reset(); return; @@ -158,85 +152,111 @@ public: c->SetCanFly(true); c->GetMotionMaster()->MovePoint(0, 2406.25f, 1701.98f, 0.1f); oachanoaGUID = c->GetGUID(); + NextStep(3000); break; } case 2: { - Player* p = ObjectAccessor::GetPlayer(*me, pGUID); - if( !p ) + Player* p = GetPlayer(); + if (!p) { Reset(); return; } - std::string text = (OACHANOA_T_1_1 + p->GetName() + OACHANOA_T_1_2); - Say(text, true); + if (Creature* c = GetOachanoa()) + c->AI()->Talk(SAY_OACHANOA_SUMMONED_0, p); + NextStep(6000); break; } case 3: - Say(OACHANOA_T_2, true); - NextStep(6000); - break; + { + if (Creature* c = GetOachanoa()) + c->AI()->Talk(SAY_OACHANOA_SUMMONED_1); + + NextStep(6000); + break; + } case 4: { - Say(OACHANOA_T_3, true); - Player* p = ObjectAccessor::GetPlayer(*me, pGUID); - if( !p ) + if (Creature* c = GetOachanoa()) + c->AI()->Talk(SAY_OACHANOA_SUMMONED_2); + Player* p = GetPlayer(); + if (!p) { Reset(); return; } p->CastSpell(p, DEEPDIVING_PEARL_BUFF, true); - NextStep(30000); - break; - } - case 5: - DespawnOachanoa(); - Reset(); - break; - case 6: - { - Player* p = ObjectAccessor::GetPlayer(*me, pGUID); - if( !p ) - { - Reset(); - return; - } - - std::string text = (OACHANOA_T_4_1 + p->GetName() + OACHANOA_T_4_2); - Say(text, true); NextStep(6000); break; } - case 7: - Say(OACHANOA_T_5, false); - NextStep(6000); - break; + case 5: // 20s countdown starts, the player can jump now + { + canjump = true; + if (Creature* c = GetOachanoa()) + c->AI()->Talk(SAY_OACHANOA_SUMMONED_3); + + NextStep(20500); + break; + } + case 6: // If failed (player DOESN'T jump within 20 seconds) + { + Player* p = GetPlayer(); + if (Creature* c = GetOachanoa()) + c->AI()->Talk(SAY_OACHANOA_FAILED, p); + + DespawnOachanoa(); + Reset(); + break; + } + case 7: // If success (player jumps) + { + Player* p = GetPlayer(); + if (!p) + { + Reset(); + return; + } + if (Creature* c = GetOachanoa()) + c->AI()->Talk(SAY_OACHANOA_SUCCESS, p); + + NextStep(6000); + break; + } case 8: - Say(OACHANOA_T_6, false); - NextStep(6000); - break; + { + Player* p = GetPlayer(); + if (Creature* c = GetOachanoa()) + c->AI()->Talk(WHISPER_OACHANOA_SUCCESS_0, p); + + NextStep(6000); + break; + } case 9: { - Player* p = ObjectAccessor::GetPlayer(*me, pGUID); - if( !p ) - { - Reset(); - return; - } - const char* name_races[RACE_DRAENEI] = {"human", "orc", "dwarf", "nightelf", "undead", "tauren", "gnome", "troll", "", "bloodelf", "draenei"}; - if( p->getRace() > 11 ) + Player* p = GetPlayer(); + if (Creature* c = GetOachanoa()) + c->AI()->Talk(WHISPER_OACHANOA_SUCCESS_1, p); + + NextStep(6000); + break; + } + case 10: + { + Player* p = GetPlayer(); + if (!p) { Reset(); return; } - std::string text = (OACHANOA_T_7_1 + std::string(name_races[p->getRace() - 1])); - Say(text, true); + if (Creature* c = GetOachanoa()) + c->AI()->Talk(WHISPER_OACHANOA_SUCCESS_2, p); - p->AreaExploredOrEventHappens(12032); + p->AreaExploredOrEventHappens(QUEST_CONVERSING_WITH_THE_DEPTHS); DespawnOachanoa(); Reset();