From e5c895b7704f67c649a607dcf6da6b893c179bdc Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Fri, 12 Oct 2018 14:43:17 +0200 Subject: [PATCH] Scripts/TotFW: finished Conclave of Wind encounter implementation --- .../custom/custom_2018_10_12_00_world.sql} | 143 ++++-- src/server/game/Spells/SpellMgr.cpp | 25 +- .../boss_conclave_of_wind.cpp | 470 ++++++++++++++++-- .../instance_throne_of_the_four_winds.cpp | 103 +++- .../throne_of_the_four_winds.h | 38 +- 5 files changed, 674 insertions(+), 105 deletions(-) rename sql/updates/{WIP/conclaveofwind.sql => world/custom/custom_2018_10_12_00_world.sql} (57%) diff --git a/sql/updates/WIP/conclaveofwind.sql b/sql/updates/world/custom/custom_2018_10_12_00_world.sql similarity index 57% rename from sql/updates/WIP/conclaveofwind.sql rename to sql/updates/world/custom/custom_2018_10_12_00_world.sql index be208a0c39..9f92f3959d 100644 --- a/sql/updates/WIP/conclaveofwind.sql +++ b/sql/updates/world/custom/custom_2018_10_12_00_world.sql @@ -1,64 +1,31 @@ -/* -0x243CC85E402CCB8000434F0000195AB6 -- anshal guid - --- Anshal -20:19:42.125 -- rohash aggro -20:19:43.207 -- winds pre effect warning cast -20:19:45.207 -- "you think you can outrun the wind? -20:19:45.208 -- withering winds start -20:19:45.641 -- winds pre effect warning start -20:19:48.074 -- winds pre effect warning -20:19:50.508 -- winds pre effect warning -20:19:52.941 -- winds pre effect warning -20:19:42.125 - -20:19:42.125 -- anshal aggro (not engaged) -20:19:57.808 -- soothing breeze (casted on self because there is nothing else - - -20:20:09.540 -20:20:09.824 -- nurture - -20:20:57.708 -- the conclive is nearning full strength -20:21:11.892 -- zephyr - - -20:25:39.343 -- jet stream cast -20:25:41.376 -- wind pre effect warning - -20:25:43.394 -- -20:25:43.493 -- you think you outrun the wind??? -20:26:44.509 -- teleport to center west - - - -20:23:53.994 -- creeper trigger cassts dummy visual -20:24:02.258 -- 85429 - -*/ - -- Template Updates UPDATE `creature_template` SET `ScriptName`= 'boss_anshal', `difficulty_entry_1`= 50103, `difficulty_entry_2`= 50113, `difficulty_entry_3`= 50123 WHERE `entry`= 45870; UPDATE `creature_template` SET `ScriptName`= 'boss_nezir', `difficulty_entry_1`= 50098, `difficulty_entry_2`= 50108, `difficulty_entry_3`= 50118 WHERE `entry`= 45871; UPDATE `creature_template` SET `ScriptName`= 'boss_rohash', `difficulty_entry_1`= 50095, `difficulty_entry_2`= 50105, `difficulty_entry_3`= 50115 WHERE `entry`= 45872; -- Anshal -UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `unit_flags2`= 1075838976, `vehicleId`= 1321, `InhabitType`= 1 WHERE `entry` IN (45872, 50103, 50113, 50123); +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `unit_flags2`= 1075838976, `vehicleId`= 1321, `InhabitType`= 1, `DamageModifier`= 60, `BaseVariance`= 0.5, `unit_class`= 2, `mechanic_immune_mask`= 617299839 WHERE `entry` IN (45870, 50103, 50113, 50123); -- Nezir -UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `unit_flags2`= 1075838976, `vehicleId`= 1319, `InhabitType`= 1 WHERE `entry` IN (45872, 50098, 50108, 50118); +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `unit_flags2`= 1075838976, `vehicleId`= 1319, `InhabitType`= 1, +`DamageModifier`= 60, `BaseVariance`= 0.5, `unit_class`= 2, `mechanic_immune_mask`= 617299839 WHERE `entry` IN (45871, 50098, 50108, 50118); -- Rohash -UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `unit_flags2`= 1075838976, `vehicleId`= 1318, `InhabitType`= 9 WHERE `entry` IN (45872, 50095, 50105, 50115); +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `unit_flags2`= 1075838976, `vehicleId`= 1318, `InhabitType`= 9, `unit_class`= 2, `mechanic_immune_mask`= 617299839 WHERE `entry` IN (45872, 50095, 50105, 50115); -- Ravenous Creeper Trigger -UPDATE `creature_template` SET `unit_flags`= 33555200, `flags_extra`= 128, `ScriptName`= 'npc_conclave_of_wind_ravenous_creeper_trigger' WHERE `entry`= 45813; +UPDATE `creature_template` SET `unit_flags`= 33555200, `flags_extra`= 128, `ScriptName`= 'npc_conclave_of_wind_ravenous_creeper_trigger' WHERE `entry`= 45813; -- Soothing Breeze UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 46246; -- North Wind, East Wind and West Wind UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `InhabitType`= 4 WHERE `entry` IN (47926, 47924, 47925); -- Ravenous Creeper -UPDATE `creature_template` SET `ScriptName`= 'npc_conclave_of_wind_ravenous_creeper' WHERE `entry`= 45812; +UPDATE `creature_template` SET `difficulty_entry_1`= 50100, `difficulty_entry_2`= 50110, `difficulty_entry_3`= 50120, `ScriptName`= 'npc_conclave_of_wind_ravenous_creeper' WHERE `entry`= 45812; +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 16, `InhabitType`= 1, `DamageModifier`= 10, `BaseVariance`= 0.5, `unit_class`= 2 WHERE `entry` IN (45812, 50110, 50110, 50120); -- Tornado UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 46207; -- World Trigger World Trigger (Not Immune NPC) UPDATE `creature_template` SET `speed_walk`= 1, `speed_run`= 1 WHERE `entry`= 19871; +-- Ice Patch +UPDATE `creature_template` SET `InhabitType`= 4, `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 46186; +-- Hurricane +UPDATE `creature_template` SET `VehicleId`= 1185, `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 46419; -- Creature Text DELETE FROM `creature_text` WHERE `CreatureID` IN (21252, 45870, 45871, 45872); @@ -66,7 +33,7 @@ INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Lan -- World Trigger (21252, 0, 0, 'The Conclave of Wind is nearing full strength!', 41, 0, 100, 0, 0, 0, 48590, 3, 'World Trigger - Announce Special Ability Warning'), -- Anshal -(45870, 0, 0, 'It shall be I that earns the favor of our lord by casting out the intruders. My calmest wind shall still prove too much for them!', 14, 0, 100, 0, 0, 0, 50596, 3, 'Anshal - Aggro'), +(45870, 0, 0, 'It shall be I that earns the favor of our lord by casting out the intruders. My calmest wind shall still prove too much for them!', 14, 0, 100, 0, 0, 0, 50596, 0, 'Anshal - Aggro'), (45870, 1, 0, 'You think to outrun the wind? A fatal mistake.', 14, 0, 100, 0, 0, 0, 50599, 3, 'Anshal - Out of Range'), (45870, 2, 0, 'My power grows feeble, brothers. I shamefully must rely on you for a time.', 14, 0, 100, 0, 0, 0, 50601, 3, 'Anshal - Gather Strength'), (45870, 3, 0, '%s begins to gather strength from the remaining Wind Lords!', 41, 0, 100, 0, 0, 0, 48593, 3, 'Anshal - Announce Gather Strength'), @@ -74,7 +41,7 @@ INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Lan (45870, 5, 0, 'Begone, outsider!', 14, 0, 100, 0, 0, 0, 50597, 3, 'Anshal - Slay 1'), (45870, 5, 1, 'Your presence shall no longer defile our home!', 14, 0, 100, 0, 0, 0, 50598, 3, 'Anshal - Slay 2'), -- Nezir -(45871, 0, 0, 'The honor of slaying the interlopers shall be mine, brothers! Their feeble bodies will freeze solid from my wind''s icy chill!', 14, 0, 100, 0, 0, 0, 50589, 3, 'Nezir - Aggro'), +(45871, 0, 0, 'The honor of slaying the interlopers shall be mine, brothers! Their feeble bodies will freeze solid from my wind''s icy chill!', 14, 0, 100, 0, 0, 0, 50589, 0, 'Nezir - Aggro'), (45871, 1, 0, 'You throw away your honor and flee as cowards? Then die!', 14, 0, 100, 0, 0, 0, 50592, 3, 'Nezir - Out of Range'), (45871, 2, 0, 'Brothers, beware! These mortals are dangerous. I must pause and gather my strength.', 14, 0, 100, 0, 0, 0, 50595, 3, 'Nezir - Gather Strength'), (45871, 3, 0, '%s begins to gather strength from the remaining Wind Lords!', 41, 0, 100, 0, 0, 0, 48593, 3, 'Nezir - Announce Gather Strength'), @@ -82,7 +49,7 @@ INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Lan (45871, 5, 0, 'Frozen solid.', 14, 0, 100, 0, 0, 0, 50590, 3, 'Nezir - Slay 1'), (45871, 5, 1, 'Another mortal has taken their last breath!', 14, 0, 100, 0, 0, 0, 50591, 3, 'Nezir - Slay 2'), -- Rohash -(45872, 0, 0, 'As I am the strongest wind, it shall be I that tears the invaders apart!', 14, 0, 100, 0, 0, 0, 50602, 3, 'Rohash - Aggro'), +(45872, 0, 0, 'As I am the strongest wind, it shall be I that tears the invaders apart!', 14, 0, 100, 0, 0, 0, 50602, 0, 'Rohash - Aggro'), (45872, 1, 0, 'Why do you flee, mortals? There is nowhere you can run or hide here!', 14, 0, 100, 0, 0, 0, 50606, 3, 'Rohash - Out of Range'), (45872, 2, 0, 'The intruders stand fast, brothers, I cannot break them. Allow me a brief respite to strengthen my winds.', 14, 0, 100, 0, 0, 0, 50607, 3, 'Rohash - Gather Strength'), (45872, 3, 0, '%s begins to gather strength from the remaining Wind Lords!', 41, 0, 100, 0, 0, 0, 48593, 3, 'Rohash - Announce Gather Strength'), @@ -97,10 +64,11 @@ UPDATE `creature_model_info` SET `BoundingRadius`= 6.987639, `CombatReach`= 12.5 UPDATE `creature_model_info` SET `BoundingRadius`= 6.987639 WHERE `DisplayID`= 35232; -- Template Addon -DELETE FROM `creature_template_addon` WHERE `entry` IN (46246, 46207); +DELETE FROM `creature_template_addon` WHERE `entry` IN (46246, 46207, 46186, 45870, 45871, 45872); INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES (46246, '86206 86207 86208'), -(46207, '86134'); +(46207, '86134'), +(46186, '86107'); -- Spells DELETE FROM `spell_script_names` WHERE `ScriptName` IN @@ -108,7 +76,10 @@ DELETE FROM `spell_script_names` WHERE `ScriptName` IN 'spell_conclave_of_wind_teleport_to_center', 'spell_conclave_of_wind_winds', 'spell_conclave_of_wind_wind_blast', -'spell_conclave_of_wind_wind_blast_triggered'); +'spell_conclave_of_wind_wind_blast_triggered', +'spell_conclave_of_wind_hurricane', +'spell_conclave_of_wind_hurricane_ride_vehicle', +'spell_conclave_of_wind_toxic_spores'); INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (96508, 'spell_conclave_of_wind_winds_pre_effect_warning'), @@ -127,15 +98,79 @@ INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (93182, 'spell_conclave_of_wind_winds'), (93183, 'spell_conclave_of_wind_winds'), (86193, 'spell_conclave_of_wind_wind_blast'), -(85480, 'spell_conclave_of_wind_wind_blast_triggered'); +(85480, 'spell_conclave_of_wind_wind_blast_triggered'), +(86498, 'spell_conclave_of_wind_hurricane'), +(86481, 'spell_conclave_of_wind_hurricane_ride_vehicle'), +(86290, 'spell_conclave_of_wind_toxic_spores'); - -DELETE FROM `conditions` WHERE `SourceEntry` IN (89844, 89843) AND `SourceTypeOrReferenceId`= 13; +DELETE FROM `conditions` WHERE `SourceEntry` IN (89844, 89843, 89898, 86481, 90262, 86290) AND `SourceTypeOrReferenceId`= 13; INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES (13, 1, 89844, 0, 0, 31, 0, 3, 47925, 0, 0, 0, '', 'Teleport to Center (West) - Target West Wind'), -(13, 1, 89843, 0, 0, 31, 0, 3, 47926, 0, 0, 0, '', 'Teleport to Center (North) - Target North Wind'); +(13, 1, 89843, 0, 0, 31, 0, 3, 47926, 0, 0, 0, '', 'Teleport to Center (North) - Target North Wind'), +(13, 1, 89898, 0, 0, 31, 0, 3, 45870, 0, 0, 0, '', 'Power Gain - Target Anshal'), +(13, 1, 89898, 0, 1, 31, 0, 3, 45871, 0, 0, 0, '', 'Power Gain - Target Nezir'), +(13, 1, 89898, 0, 2, 31, 0, 3, 45872, 0, 0, 0, '', 'Power Gain - Target Roash'), +(13, 1, 86481, 0, 0, 31, 0, 3, 46419, 0, 0, 0, '', 'Hurricane - Target Hurricane'), +(13, 1, 90262, 0, 0, 31, 0, 3, 46419, 0, 0, 0, '', 'Hurricane - Target Hurricane'), +(13, 1, 86290, 0, 0, 31, 0, 3, 45812, 0, 0, 0, '', 'Toxic Spores - Target Ravenous Creeper'); +-- Loot +DELETE FROM `creature_loot_template` WHERE `Entry` IN (45870, 45871, 45872, 50103, 50113, 50123, 50098, 50108, 50118, 50095, 50105, 50115); +UPDATE `creature_template` SET `lootid`= `entry` WHERE `entry` IN (45870, 45871, 45872, 50103, 50113, 50123, 50098, 50108, 50118, 50095, 50105, 50115); +DELETE FROM `reference_loot_template` WHERE `Entry` IN (458700, 458701); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES +-- Normal Mode +(458700, 63497, 0, 1, 1, 1, 1), +(458700, 63496, 0, 1, 1, 1, 1), +(458700, 63490, 0, 1, 1, 1, 1), +(458700, 63498, 0, 1, 1, 1, 1), +(458700, 63492, 0, 1, 1, 1, 1), +(458700, 63495, 0, 1, 1, 1, 1), +(458700, 63491, 0, 1, 1, 1, 1), +(458700, 63493, 0, 1, 1, 1, 1), +(458700, 63488, 0, 1, 1, 1, 1), +(458700, 63489, 0, 1, 1, 1, 1), +(458700, 63494, 0, 1, 1, 1, 1), +-- Heroic Mode +(458701, 65374, 0, 1, 1, 1, 1), +(458701, 65377, 0, 1, 1, 1, 1), +(458701, 65369, 0, 1, 1, 1, 1), +(458701, 65376, 0, 1, 1, 1, 1), +(458701, 65368, 0, 1, 1, 1, 1), +(458701, 65375, 0, 1, 1, 1, 1), +(458701, 65370, 0, 1, 1, 1, 1), +(458701, 65371, 0, 1, 1, 1, 1), +(458701, 65367, 0, 1, 1, 1, 1), +(458701, 65372, 0, 1, 1, 1, 1), +(458701, 65373, 0, 1, 1, 1, 1); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `Reference`, `MaxCount`) VALUES +-- 10 Player Normal +(45870, 458700, 100, 1, 458700, 1), +(45871, 458700, 100, 1, 458700, 1), +(45872, 458700, 100, 1, 458700, 1), +-- 25 Player Normal +(50103, 458700, 100, 1, 458700, 2), +(50098, 458700, 100, 1, 458700, 2), +(50095, 458700, 100, 1, 458700, 2), +-- 10 Player Heroic +(50113, 458701, 100, 1, 458701, 1), +(50108, 458701, 100, 1, 458701, 1), +(50105, 458701, 100, 1, 458701, 1), +-- 25 Player Heroic +(50123, 458701, 100, 1, 458701, 2), +(50118, 458701, 100, 1, 458701, 2), +(50115, 458701, 100, 1, 458701, 2); +-- Gold loot +UPDATE `creature_template` SET `mingold`= 740000, `maxgold`= 800000 WHERE `entry` IN (45870, 45871, 45872, 50113, 50108, 50105); +UPDATE `creature_template` SET `mingold`= 1500000, `maxgold`= 1700000 WHERE `entry` IN (50103, 50098, 50095, 50123, 50118, 50115); +-- Currency loot +DELETE FROM `creature_onkill_reward` WHERE `creature_id` IN (45871, 50098, 50108, 50118); +INSERT INTO `creature_onkill_reward` (`creature_id`, `CurrencyId1`, `CurrencyCount1`) VALUES +(45871, 396, 11500), +(50098, 396, 13500), +(50108, 396, 11500), +(50118, 396, 13500); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 8094ab1658..3be64f4a99 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4788,6 +4788,7 @@ void SpellMgr::LoadSpellInfoCorrections() // THRONE OF THE FOUR WINDS SPELLS // + // Conclave of Wind // Teleport to Center ApplySpellFix({ 89844, // West @@ -4803,6 +4804,18 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_2; }); + // Soothing Breeze + ApplySpellFix({ 86204 }, [](SpellInfo* spellInfo) + { + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30seconds + }); + + // Ice Patch + ApplySpellFix({ 86122 }, [](SpellInfo* spellInfo) + { + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(9); // 30seconds + }); + // Tornado ApplySpellFix({ 86189, @@ -4811,7 +4824,17 @@ void SpellMgr::LoadSpellInfoCorrections() }, [](SpellInfo* spellInfo) { spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); - spellInfo->Effects[EFFECT_0].MaxRadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_15_YARDS); + }); + + // Wind Blast + ApplySpellFix({ + 85483, + 93138, + 93139, + 93140 + }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CONE_ENEMY_104); }); // ENDOF THRONE OF THE FOUR WINDS SPELLS diff --git a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_conclave_of_wind.cpp b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_conclave_of_wind.cpp index ede66391fb..8d130cee8b 100644 --- a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_conclave_of_wind.cpp +++ b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_conclave_of_wind.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "throne_of_the_four_winds.h" #include "AreaBoundary.h" +#include "GameObject.h" #include "ObjectMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" @@ -38,13 +39,19 @@ enum Spells SPELL_WITHERING_WINDS_DAMAGE = 93168, SPELL_NURTURE = 85422, SPELL_SOOTHING_BREEZE = 86205, - SPELL_ZEPHYR = 84638, SPELL_TELEPORT_TO_CENTER_WEST = 89844, + SPELL_ZEPHYR = 84638, + SPELL_ZEPHYR_UNK = 89813, // todo: find purpose + SPELL_TOXIC_SPORES = 86290, // Nezir SPELL_PRE_FIGHT_VISUAL_NORTH = 85532, SPELL_CHILLING_WINDS_DAMAGE = 93163, SPELL_TELEPORT_TO_CENTER_NORTH = 89843, + SPELL_PERMAFROST = 86082, + SPELL_ICE_PATCH = 86122, + SPELL_SLEET_STORM = 84644, + SPELL_STAY_CHILL_ACHIEVEMENT_CREDIT = 94119, // Rohash SPELL_PRE_FIGHT_VISUAL_EAST = 85538, @@ -53,9 +60,9 @@ enum Spells SPELL_STORM_SHIELD = 93059, SPELL_SUMMON_TORNADOS = 86192, SPELL_WIND_BLAST = 86193, - - // World Trigger - SPELL_POWER_GAIN = 89898, + SPELL_WIND_BLAST_TRIGGERED = 85480, + SPELL_HURRICANE = 84643, + SPELL_HURRICANE_RIDE_VEHICLE = 86481, // West Wind SPELL_WITHERING_WINDS_RESET_AURA = 89137, @@ -71,47 +78,53 @@ enum Spells SPELL_NURTURE_SUMMON = 85429, // Ravenous Creeper - SPELL_TOXIC_SPORES = 86281, - SPELL_AI_CLEAR_TARGET = 89020, - - // World Trigger - SPELL_WIND_BLAST_SPEED_BUFF = 93106, + SPELL_AI_CLEAR_TARGET = 89020 }; #define SPELL_DEAFENING_WINDS RAID_MODE(85573, 93190, 93191, 93192) #define SPELL_CHILLING_WINDS RAID_MODE(85578, 93147, 93148, 93149) #define SPELL_WITHERING_WINDS RAID_MODE(85576, 93181, 93182, 93183) +#define SPELL_GATHER_STRENGTH RAID_MODE(86307, 101444, 101445, 101446) +#define SPELL_WIND_CHILL RAID_MODE(84645, 93123, 93124, 93125) enum Events { // Conclave of Wind EVENT_PRE_WIND_EFFECT_WARNING = 1, EVENT_TELEPORT_TO_CENTER, + EVENT_REENGAGE_PLAYERS, // Anshal EVENT_SOOTHING_BREEZE, EVENT_NURTURE, + EVENT_TOXIC_SPORES, + EVENT_ZEPHYR, // Nezir + EVENT_WIND_CHILL, + EVENT_PERMAFROST, + EVENT_ICE_PATCH, + EVENT_SLEET_STORM, // Rohash EVENT_SLICING_GALE, EVENT_STORM_SHIELD, EVENT_SUMMON_TORNADOS, EVENT_WIND_BLAST, + EVENT_HURRICANE, + EVENT_FINISH_WIND_BLAST, // Ravenous Creeper Trigger EVENT_SUMMON_RAVENOUS_CREEPER, // Ravenous Creeper - EVENT_ATTACK_PLAYERS, - EVENT_TOXIC_SPORES, + EVENT_ATTACK_PLAYERS }; enum Actions { ACTION_NO_NEARBY_PLAYER = 1, - ACTION_PLAYER_LEFT_PLATFORM = 2, + ACTION_PLAYER_LEFT_PLATFORM = 2 }; enum Texts @@ -120,7 +133,7 @@ enum Texts SAY_AGGRO = 0, SAY_OUT_OF_RANGE = 1, SAY_GATHER_STRENGTH = 2, - SAY_ANNOUNCE_GATHER_POWER = 3, + SAY_ANNOUNCE_GATHER_STRENGTH = 3, SAY_SPECIAL_ABILITY = 4, SAY_SLAY = 5, @@ -136,9 +149,10 @@ enum SpellVisualKits SPELL_VISUAL_STORM_SHIELD = 18812 }; -enum GuidData +enum Data { - DATA_WIND_BLAST_TRIGGER = 0 + DATA_WIND_BLAST_TRIGGER = 0, + DATA_IS_GATHERING_STRENGTH = 1 }; #define MAX_HOME_POSITION_DISTANCE 65.0f @@ -154,6 +168,38 @@ namespace ConclaveHandler return target->GetExactDist2d(attackerPosition) < MAX_HOME_POSITION_DISTANCE; } + + bool KillConclaveIfAllowed(Unit* councillor) + { + if (InstanceScript* instance = councillor->GetInstanceScript()) + { + uint8 weakenedCouncillorCount = 0; + Creature* anshal = instance->GetCreature(DATA_ANSHAL); + Creature* nezir = instance->GetCreature(DATA_NEZIR); + Creature* rohash = instance->GetCreature(DATA_ROHASH); + if (!anshal || !nezir || !rohash) + return false; + + if (councillor != anshal && anshal->AI()->GetData(DATA_IS_GATHERING_STRENGTH)) + weakenedCouncillorCount++; + + if (councillor != rohash && rohash->AI()->GetData(DATA_IS_GATHERING_STRENGTH)) + weakenedCouncillorCount++; + + if (councillor != nezir && nezir->AI()->GetData(DATA_IS_GATHERING_STRENGTH)) + weakenedCouncillorCount++; + + if (weakenedCouncillorCount == 2) + { + anshal->KillSelf(); + nezir->KillSelf(); + rohash->KillSelf(); + return true; + } + } + + return false; + } } Position const WesternPlatformCenterPosition = { -48.081f, 1053.930f, 199.572f }; @@ -168,6 +214,7 @@ struct boss_anshal : public BossAI void Initialize() { + _isGatheringStrength = false; } void AttackStart(Unit* who) override @@ -185,8 +232,8 @@ struct boss_anshal : public BossAI me->SetReactState(REACT_AGGRESSIVE); instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); me->RemoveAurasDueToSpell(SPELL_PRE_FIGHT_VISUAL_WEST); - events.ScheduleEvent(EVENT_SOOTHING_BREEZE, 15s, 16s); - events.ScheduleEvent(EVENT_NURTURE, 27s, 28s); + events.ScheduleEvent(EVENT_SOOTHING_BREEZE, 15s + 500ms); + events.ScheduleEvent(EVENT_NURTURE, 27s); if (ConclaveHandler::IsTargetOnPlatform(me->GetHomePosition(), who)) Talk(SAY_AGGRO); @@ -199,7 +246,7 @@ struct boss_anshal : public BossAI _Reset(); Initialize(); me->SetReactState(REACT_PASSIVE); - me->SetPower(POWER_MANA, 0); + DoCastSelf(SPELL_PRE_FIGHT_VISUAL_WEST); _ravenousCreeperGUIDs.clear(); } @@ -221,10 +268,38 @@ struct boss_anshal : public BossAI { _JustDied(); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WIND_CHILL); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(1, damage) && !_isGatheringStrength) + { + if (ConclaveHandler::KillConclaveIfAllowed(me)) + return; + + Talk(SAY_GATHER_STRENGTH); + Talk(SAY_ANNOUNCE_GATHER_STRENGTH); + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + DoCastSelf(SPELL_GATHER_STRENGTH); + events.Reset(); + _isGatheringStrength = true; + } + + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; } void DoAction(int32 action) override { + if (action == ACTION_CONCLAVE_AT_FULL_STRENGTH && _isGatheringStrength) + me->SetPower(POWER_MANA, 0); + + if (_isGatheringStrength) + return; + switch (action) { case ACTION_NO_NEARBY_PLAYER: @@ -239,10 +314,21 @@ struct boss_anshal : public BossAI } break; case ACTION_PLAYER_LEFT_PLATFORM: - if (!me->IsInCombat()) + if (!me->IsInCombat() || me->HasAura(SPELL_ZEPHYR)) break; events.ScheduleEvent(EVENT_PRE_WIND_EFFECT_WARNING, 2s); break; + case ACTION_CONCLAVE_AT_FULL_STRENGTH: + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); + me->RemoveAurasDueToSpell(SPELL_WITHERING_WINDS); + Talk(SAY_SPECIAL_ABILITY); + DoCastSelf(SPELL_TELEPORT_TO_CENTER_WEST); + events.Reset(); + events.ScheduleEvent(EVENT_ZEPHYR, 2s + 500ms); + break; default: break; } @@ -252,11 +338,21 @@ struct boss_anshal : public BossAI { if (spell->Id == SPELL_WIND_DISTANCE_CHECKER) { + events.CancelEvent(EVENT_PRE_WIND_EFFECT_WARNING); me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); me->RemoveAurasDueToSpell(SPELL_WITHERING_WINDS); } } + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_GATHER_STRENGTH) + { + _isGatheringStrength = false; + events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 1ms); + } + } + void JustSummoned(Creature* summon) override { summons.Summon(summon); @@ -267,6 +363,9 @@ struct boss_anshal : public BossAI uint32 GetData(uint32 type) const override { + if (type == DATA_IS_GATHERING_STRENGTH) + return uint8(_isGatheringStrength); + return 0; } @@ -305,10 +404,31 @@ struct boss_anshal : public BossAI target = creeper; DoCast(target, SPELL_SOOTHING_BREEZE); + events.Repeat(31s, 33s); break; } case EVENT_NURTURE: + me->StopMoving(); DoCastSelf(SPELL_NURTURE); + events.ScheduleEvent(EVENT_TOXIC_SPORES, 20s + 500ms); + break; + case EVENT_TOXIC_SPORES: + DoCastAOE(SPELL_TOXIC_SPORES, true); + events.Repeat(20s); + break; + case EVENT_ZEPHYR: + DoCastSelf(SPELL_ZEPHYR); + if (GameObject* effect = instance->GetGameObject(DATA_SKYWALL_DJIN_HEALING)) + effect->SetGoState(GO_STATE_ACTIVE); + events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 15s); + break; + case EVENT_REENGAGE_PLAYERS: + if (GameObject* effect = instance->GetGameObject(DATA_SKYWALL_DJIN_HEALING)) + effect->SetGoState(GO_STATE_READY); + me->SetReactState(REACT_AGGRESSIVE); + events.ScheduleEvent(EVENT_SOOTHING_BREEZE, 16s); + events.ScheduleEvent(EVENT_NURTURE, 35s); + events.ScheduleEvent(EVENT_PRE_WIND_EFFECT_WARNING, 1ms); break; default: break; @@ -319,6 +439,7 @@ struct boss_anshal : public BossAI private: GuidSet _ravenousCreeperGUIDs; + bool _isGatheringStrength; }; struct boss_nezir : public BossAI @@ -330,6 +451,7 @@ struct boss_nezir : public BossAI void Initialize() { + _isGatheringStrength = false; } void AttackStart(Unit* who) override @@ -347,6 +469,9 @@ struct boss_nezir : public BossAI me->SetReactState(REACT_AGGRESSIVE); instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); me->RemoveAurasDueToSpell(SPELL_PRE_FIGHT_VISUAL_NORTH); + events.ScheduleEvent(EVENT_WIND_CHILL, 11s); + events.ScheduleEvent(EVENT_PERMAFROST, 12s); + events.ScheduleEvent(EVENT_ICE_PATCH, 14s); if (ConclaveHandler::IsTargetOnPlatform(me->GetHomePosition(), who)) Talk(SAY_AGGRO); @@ -359,7 +484,7 @@ struct boss_nezir : public BossAI _Reset(); Initialize(); me->SetReactState(REACT_PASSIVE); - me->SetPower(POWER_MANA, 0); + DoCastSelf(SPELL_PRE_FIGHT_VISUAL_NORTH); } void KilledUnit(Unit* killed) override @@ -382,8 +507,35 @@ struct boss_nezir : public BossAI instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(1, damage) && !_isGatheringStrength) + { + if (ConclaveHandler::KillConclaveIfAllowed(me)) + return; + + Talk(SAY_GATHER_STRENGTH); + Talk(SAY_ANNOUNCE_GATHER_STRENGTH); + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + DoCastSelf(SPELL_GATHER_STRENGTH); + events.Reset(); + _isGatheringStrength = true; + } + + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } + void DoAction(int32 action) override { + if (action == ACTION_CONCLAVE_AT_FULL_STRENGTH && _isGatheringStrength) + me->SetPower(POWER_MANA, 0); + + if (_isGatheringStrength) + return; + switch (action) { case ACTION_NO_NEARBY_PLAYER: @@ -398,10 +550,21 @@ struct boss_nezir : public BossAI } break; case ACTION_PLAYER_LEFT_PLATFORM: - if (!me->IsInCombat()) + if (!me->IsInCombat() || me->HasAura(SPELL_SLEET_STORM)) break; events.ScheduleEvent(EVENT_PRE_WIND_EFFECT_WARNING, 2s); break; + case ACTION_CONCLAVE_AT_FULL_STRENGTH: + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); + me->RemoveAurasDueToSpell(SPELL_CHILLING_WINDS); + Talk(SAY_SPECIAL_ABILITY); + DoCastSelf(SPELL_TELEPORT_TO_CENTER_NORTH); + events.Reset(); + events.ScheduleEvent(EVENT_SLEET_STORM, 2s + 500ms); + break; default: break; } @@ -411,11 +574,21 @@ struct boss_nezir : public BossAI { if (spell->Id == SPELL_WIND_DISTANCE_CHECKER) { + events.CancelEvent(EVENT_PRE_WIND_EFFECT_WARNING); me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); me->RemoveAurasDueToSpell(SPELL_CHILLING_WINDS); } } + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_GATHER_STRENGTH) + { + _isGatheringStrength = false; + events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 1ms); + } + } + void JustSummoned(Creature* summon) override { summons.Summon(summon); @@ -423,6 +596,9 @@ struct boss_nezir : public BossAI uint32 GetData(uint32 type) const override { + if (type == DATA_IS_GATHERING_STRENGTH) + return uint8(_isGatheringStrength); + return 0; } @@ -446,12 +622,50 @@ struct boss_nezir : public BossAI case EVENT_TELEPORT_TO_CENTER: DoCastSelf(SPELL_TELEPORT_TO_CENTER_NORTH); break; + case EVENT_WIND_CHILL: + DoCastAOE(SPELL_WIND_CHILL); + events.Repeat(11s); + break; + case EVENT_PERMAFROST: + if (Unit* target = me->GetVictim()) + { + if (ConclaveHandler::IsTargetOnPlatform(me->GetHomePosition(), target)) + { + me->StopMoving(); + DoCast(target, SPELL_PERMAFROST); + } + } + events.Repeat(12s); + break; + case EVENT_ICE_PATCH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, MAX_HOME_POSITION_DISTANCE, true, 0)) + if (ConclaveHandler::IsTargetOnPlatform(me->GetHomePosition(), target)) + DoCast(target, SPELL_ICE_PATCH); + events.Repeat(14s); + break; + case EVENT_SLEET_STORM: + DoCastSelf(SPELL_SLEET_STORM); + if (GameObject* effect = instance->GetGameObject(DATA_SKYWALL_DJIN_FROST)) + effect->SetGoState(GO_STATE_ACTIVE); + events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 15s); + break; + case EVENT_REENGAGE_PLAYERS: + if (GameObject* effect = instance->GetGameObject(DATA_SKYWALL_DJIN_FROST)) + effect->SetGoState(GO_STATE_READY); + me->SetReactState(REACT_AGGRESSIVE); + events.ScheduleEvent(EVENT_WIND_CHILL, 11s); + events.ScheduleEvent(EVENT_PERMAFROST, 12s); + events.ScheduleEvent(EVENT_ICE_PATCH, 14s); + events.ScheduleEvent(EVENT_PRE_WIND_EFFECT_WARNING, 1ms); + break; default: break; } } DoMeleeAttackIfReady(); } +private: + bool _isGatheringStrength; }; struct boss_rohash : public BossAI @@ -463,6 +677,7 @@ struct boss_rohash : public BossAI void Initialize() { + _isGatheringStrength = false; } void AttackStart(Unit* who) override @@ -485,7 +700,7 @@ struct boss_rohash : public BossAI events.ScheduleEvent(EVENT_WIND_BLAST, 32s + 500ms); if (IsHeroic()) - events.ScheduleEvent(EVENT_STORM_SHIELD, 30s); + events.ScheduleEvent(EVENT_STORM_SHIELD, 30s + 100ms); if (ConclaveHandler::IsTargetOnPlatform(me->GetHomePosition(), who)) Talk(SAY_AGGRO); @@ -498,7 +713,7 @@ struct boss_rohash : public BossAI _Reset(); Initialize(); me->SetReactState(REACT_PASSIVE); - me->SetPower(POWER_MANA, 0); + DoCastSelf(SPELL_PRE_FIGHT_VISUAL_EAST); if (Creature* dummy = DoSummon(NPC_WORLD_TRIGGER_IMMUNE_TO_PC, WindBlastTriggerPosition, 0, TEMPSUMMON_MANUAL_DESPAWN)) { _windBlastTriggerGUID = dummy->GetGUID(); @@ -527,8 +742,35 @@ struct boss_rohash : public BossAI instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(1, damage) && !_isGatheringStrength) + { + if (ConclaveHandler::KillConclaveIfAllowed(me)) + return; + + Talk(SAY_GATHER_STRENGTH); + Talk(SAY_ANNOUNCE_GATHER_STRENGTH); + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + DoCastSelf(SPELL_GATHER_STRENGTH); + events.Reset(); + _isGatheringStrength = true; + } + + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } + void DoAction(int32 action) override { + if (action == ACTION_CONCLAVE_AT_FULL_STRENGTH && _isGatheringStrength) + me->SetPower(POWER_MANA, 0); + + if (_isGatheringStrength) + return; + switch (action) { case ACTION_NO_NEARBY_PLAYER: @@ -541,21 +783,45 @@ struct boss_rohash : public BossAI } break; case ACTION_PLAYER_LEFT_PLATFORM: - if (!me->IsInCombat()) + if (!me->IsInCombat() || me->HasAura(SPELL_HURRICANE)) break; events.ScheduleEvent(EVENT_PRE_WIND_EFFECT_WARNING, 2s); break; + case ACTION_CONCLAVE_AT_FULL_STRENGTH: + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); + me->RemoveAurasDueToSpell(SPELL_DEAFENING_WINDS); + Talk(SAY_SPECIAL_ABILITY); + events.Reset(); + events.ScheduleEvent(EVENT_HURRICANE, 2s + 500ms); + break; default: break; } } - void SpellHitTarget(Unit* target, SpellInfo const* spell) override + void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) override { - if (spell->Id == SPELL_WIND_DISTANCE_CHECKER) + switch (spell->Id) { - me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); - me->RemoveAurasDueToSpell(SPELL_DEAFENING_WINDS); + case SPELL_WIND_DISTANCE_CHECKER: + events.CancelEvent(EVENT_PRE_WIND_EFFECT_WARNING); + me->RemoveAurasDueToSpell(SPELL_WINDS_PRE_EFFECT_WARNING); + me->RemoveAurasDueToSpell(SPELL_DEAFENING_WINDS); + break; + default: + break; + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override + { + if (spell->Id == SPELL_GATHER_STRENGTH) + { + _isGatheringStrength = false; + events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 1ms); } } @@ -576,6 +842,9 @@ struct boss_rohash : public BossAI uint32 GetData(uint32 type) const override { + if (type == DATA_IS_GATHERING_STRENGTH) + return uint8(_isGatheringStrength); + return 0; } @@ -610,14 +879,49 @@ struct boss_rohash : public BossAI events.Repeat(2s + 100ms); break; case EVENT_STORM_SHIELD: - me->SendPlaySpellVisualKit(SPELL_VISUAL_STORM_SHIELD, 0, 0); - DoCastSelf(SPELL_STORM_SHIELD); + if (me->GetPower(POWER_MANA) == 30) + { + me->SendPlaySpellVisualKit(SPELL_VISUAL_STORM_SHIELD, 0, 0); + DoCastSelf(SPELL_STORM_SHIELD); + } + else + events.Repeat(1s); break; case EVENT_SUMMON_TORNADOS: DoCastSelf(SPELL_SUMMON_TORNADOS); break; case EVENT_WIND_BLAST: + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); DoCastAOE(SPELL_WIND_BLAST); + events.ScheduleEvent(EVENT_FINISH_WIND_BLAST, 11s); + events.Repeat(60s); + break; + case EVENT_FINISH_WIND_BLAST: + me->SetReactState(REACT_AGGRESSIVE); + break; + case EVENT_HURRICANE: + DoCastSelf(SPELL_HURRICANE); + if (GameObject* effect = instance->GetGameObject(DATA_SKYWALL_DJIN_TORNADO)) + effect->SetGoState(GO_STATE_ACTIVE); + events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 15s); + + for (ObjectGuid guid : summons) + if (Creature* creature = ObjectAccessor::GetCreature(*me, guid)) + if (creature->GetEntry() == NPC_TORNADO) + creature->DespawnOrUnsummon(4s + 500ms); + break; + case EVENT_REENGAGE_PLAYERS: + if (GameObject* effect = instance->GetGameObject(DATA_SKYWALL_DJIN_TORNADO)) + effect->SetGoState(GO_STATE_READY); + me->SetReactState(REACT_AGGRESSIVE); + events.ScheduleEvent(EVENT_SLICING_GALE, 1s); + events.ScheduleEvent(EVENT_WIND_BLAST, 5s); + events.ScheduleEvent(EVENT_SUMMON_TORNADOS, 17s); + + if (IsHeroic()) + events.ScheduleEvent(EVENT_STORM_SHIELD, 37s + 500ms); + events.ScheduleEvent(EVENT_PRE_WIND_EFFECT_WARNING, 1ms); break; default: break; @@ -626,6 +930,7 @@ struct boss_rohash : public BossAI } private: ObjectGuid _windBlastTriggerGUID; + bool _isGatheringStrength; }; struct npc_conclave_of_wind_ravenous_creeper_trigger : public ScriptedAI @@ -680,11 +985,6 @@ struct npc_conclave_of_wind_ravenous_creeper : public ScriptedAI _events.ScheduleEvent(EVENT_ATTACK_PLAYERS, 1s + 500ms); } - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_TOXIC_SPORES, 5s, 6s); - } - void AttackStart(Unit* who) override { if (ConclaveHandler::IsTargetOnPlatform(WesternPlatformCenterPosition, who)) @@ -720,9 +1020,6 @@ struct npc_conclave_of_wind_ravenous_creeper : public ScriptedAI case EVENT_ATTACK_PLAYERS: me->SetReactState(REACT_AGGRESSIVE); break; - case EVENT_TOXIC_SPORES: - DoCastSelf(SPELL_TOXIC_SPORES); - break; default: break; } @@ -835,6 +1132,96 @@ class spell_conclave_of_wind_wind_blast : public SpellScript } }; +class spell_conclave_of_wind_wind_blast_AuraScript : public AuraScript +{ + PrepareAuraScript(spell_conclave_of_wind_wind_blast_AuraScript); + + void HandleTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_conclave_of_wind_wind_blast_AuraScript::HandleTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +class spell_conclave_of_wind_wind_blast_triggered : public SpellScript +{ + PrepareSpellScript(spell_conclave_of_wind_wind_blast_triggered); + + void SetTarget(WorldObject*& target) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* rohash = instance->GetCreature(DATA_ROHASH)) + if (Creature* trigger = ObjectAccessor::GetCreature(*GetCaster(), rohash->AI()->GetGUID(DATA_WIND_BLAST_TRIGGER))) + target = trigger; + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_conclave_of_wind_wind_blast_triggered::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + } +}; + +class spell_conclave_of_wind_hurricane : public SpellScript +{ + PrepareSpellScript(spell_conclave_of_wind_hurricane); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_HURRICANE_RIDE_VEHICLE }); + } + + void HandleScriptEffect(SpellEffIndex effIndex) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_HURRICANE_RIDE_VEHICLE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_conclave_of_wind_hurricane::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +class spell_conclave_of_wind_hurricane_ride_vehicle : public SpellScript +{ + PrepareSpellScript(spell_conclave_of_wind_hurricane_ride_vehicle); + + void SetTarget(WorldObject*& target) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (ObjectGuid guid = instance->GetObjectGuid(DATA_FREE_HURRICANE_VEHICLE)) + if (Creature* hurricane = ObjectAccessor::GetCreature(*GetCaster(), guid)) + target = hurricane; + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_conclave_of_wind_hurricane_ride_vehicle::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + } +}; + +class spell_conclave_of_wind_toxic_spores : public SpellScript +{ + PrepareSpellScript(spell_conclave_of_wind_toxic_spores); + + // Handle the cast as non-triggered to inform the client and its addons properly + void HandleCast(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].TriggerSpell, false); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_conclave_of_wind_toxic_spores::HandleCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } +}; + void AddSC_boss_conclave_of_wind() { RegisterThroneOfTheFourWindsCreatureAI(boss_anshal); @@ -842,9 +1229,12 @@ void AddSC_boss_conclave_of_wind() RegisterThroneOfTheFourWindsCreatureAI(boss_rohash); RegisterThroneOfTheFourWindsCreatureAI(npc_conclave_of_wind_ravenous_creeper_trigger); RegisterThroneOfTheFourWindsCreatureAI(npc_conclave_of_wind_ravenous_creeper); - RegisterAuraScript(spell_conclave_of_wind_winds_pre_effect_warning); RegisterSpellScript(spell_conclave_of_wind_teleport_to_center); RegisterAuraScript(spell_conclave_of_wind_winds); - RegisterSpellScript(spell_conclave_of_wind_wind_blast); + RegisterSpellAndAuraScriptPair(spell_conclave_of_wind_wind_blast, spell_conclave_of_wind_wind_blast_AuraScript); + RegisterSpellScript(spell_conclave_of_wind_wind_blast_triggered); + RegisterSpellScript(spell_conclave_of_wind_hurricane); + RegisterSpellScript(spell_conclave_of_wind_hurricane_ride_vehicle); + RegisterSpellScript(spell_conclave_of_wind_toxic_spores); } diff --git a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/instance_throne_of_the_four_winds.cpp b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/instance_throne_of_the_four_winds.cpp index 889da81f4f..6e1b778e01 100644 --- a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/instance_throne_of_the_four_winds.cpp +++ b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/instance_throne_of_the_four_winds.cpp @@ -25,6 +25,7 @@ #include "AreaBoundary.h" #include "Map.h" #include "TemporarySummon.h" +#include "Vehicle.h" #include "Weather.h" ObjectData const creatureData[] = @@ -39,9 +40,21 @@ ObjectData const creatureData[] = ObjectData const gameObjectData[] = { { GO_SKYWALL_RAID_CENTER_PLATFORM, DATA_SKYWALL_RAID_CENTER_PLATFORM }, + { GO_SKYALL_DJIN_HEALING, DATA_SKYWALL_DJIN_HEALING }, + { GO_SKYALL_DJIN_FROST, DATA_SKYWALL_DJIN_FROST }, + { GO_SKYALL_DJIN_TORNADO, DATA_SKYWALL_DJIN_TORNADO }, { 0, 0 } // End }; +enum Events +{ + EVENT_ENERGIZE = 1, + EVENT_ANNOUNCE_ALMOST_FULL_STRENGTH, + EVENT_CONCLAVE_AT_FULL_STRENGTH, +}; + +Position const EnergizeWorldTriggerPos = { -287.795f, 816.681f, 199.5723f }; + class instance_throne_of_the_four_winds : public InstanceMapScript { public: @@ -70,14 +83,21 @@ class instance_throne_of_the_four_winds : public InstanceMapScript switch (creature->GetEntry()) { - case BOSS_ANSHAL: - case BOSS_NEZIR: - case BOSS_ROHASH: + + case BOSS_ALAKIR: + if (GetBossState(DATA_CONCLAVE_OF_WIND) != DONE) + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); break; case NPC_RAVENOUS_CREEPER: if (Creature* anshal = GetCreature(DATA_ANSHAL)) anshal->AI()->JustSummoned(creature); break; + case NPC_WORLD_TRIGGER: + if (creature->GetExactDist2d(EnergizeWorldTriggerPos) < 0.1f) + _engerizeWorldTriggerGUID = creature->GetGUID(); + break; + case NPC_HURRICANE: + _hurricaneGUIDs.push_back(creature->GetGUID()); default: break; } @@ -109,6 +129,36 @@ class instance_throne_of_the_four_winds : public InstanceMapScript if (Creature* rohash = GetCreature(DATA_ROHASH)) rohash->AI()->DoZoneInCombat(); + + events.ScheduleEvent(EVENT_ENERGIZE, 1ms); + events.ScheduleEvent(EVENT_ANNOUNCE_ALMOST_FULL_STRENGTH, 80s); + events.ScheduleEvent(EVENT_CONCLAVE_AT_FULL_STRENGTH, 90s); + } + else + { + if (GameObject* effect1 = GetGameObject(DATA_SKYWALL_DJIN_TORNADO)) + effect1->SetGoState(GO_STATE_READY); + if (GameObject* effect2 = GetGameObject(DATA_SKYWALL_DJIN_TORNADO)) + effect2->SetGoState(GO_STATE_READY); + if (GameObject* effect3 = GetGameObject(DATA_SKYWALL_DJIN_TORNADO)) + effect3->SetGoState(GO_STATE_READY); + + events.CancelEvent(EVENT_ENERGIZE); + events.CancelEvent(EVENT_ANNOUNCE_ALMOST_FULL_STRENGTH); + events.CancelEvent(EVENT_CONCLAVE_AT_FULL_STRENGTH); + + for (ObjectGuid guid : _hurricaneGUIDs) + { + if (Creature* hurricane = instance->GetCreature(guid)) + hurricane->DespawnOrUnsummon(0, 30s); + } + + _hurricaneGUIDs.clear(); + + if (state == DONE) + if (Creature* alakir = GetCreature(DATA_ALAKIR)) + alakir->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + // alakir->DoAction(ACTION_CONCLAVE_DEFEATED); } break; default: @@ -122,6 +172,24 @@ class instance_throne_of_the_four_winds : public InstanceMapScript { } + ObjectGuid GetGuidData(uint32 type) const override + { + switch (type) + { + case DATA_FREE_HURRICANE_VEHICLE: + for (ObjectGuid guid : _hurricaneGUIDs) + { + if (Creature* hurricane = instance->GetCreature(guid)) + if (hurricane->GetVehicleKit()->GetAvailableSeatCount()) + return guid; + } + break; + default: + break; + } + + return ObjectGuid::Empty; + } void Update(uint32 diff) override { @@ -131,7 +199,32 @@ class instance_throne_of_the_four_winds : public InstanceMapScript { switch (eventId) { - case 0: + case EVENT_ENERGIZE: + if (Creature* trigger = instance->GetCreature(_engerizeWorldTriggerGUID)) + trigger->CastSpell(trigger, SPELL_POWER_GAIN, true); + events.Repeat(1s); + break; + case EVENT_ANNOUNCE_ALMOST_FULL_STRENGTH: + if (Creature* trigger = instance->GetCreature(_engerizeWorldTriggerGUID)) + if (trigger->IsAIEnabled) + trigger->AI()->Talk(SAY_ANNOUNCE_ALMOST_FULL_STRENGTH); + break; + case EVENT_CONCLAVE_AT_FULL_STRENGTH: + if (Creature* anshal = GetCreature(DATA_ANSHAL)) + anshal->AI()->DoAction(ACTION_CONCLAVE_AT_FULL_STRENGTH); + + if (Creature* nezir = GetCreature(DATA_NEZIR)) + nezir->AI()->DoAction(ACTION_CONCLAVE_AT_FULL_STRENGTH); + + if (Creature* rohash = GetCreature(DATA_ROHASH)) + rohash->AI()->DoAction(ACTION_CONCLAVE_AT_FULL_STRENGTH); + + if (Creature* trigger = instance->GetCreature(_engerizeWorldTriggerGUID)) + trigger->CastSpell(trigger, SPELL_POWER_GAIN, true); + + events.RescheduleEvent(EVENT_ENERGIZE, 23s + 500ms); + events.ScheduleEvent(EVENT_ANNOUNCE_ALMOST_FULL_STRENGTH, 1min + 43s + 500ms); + events.Repeat(1min + 53s + 500ms); break; default: break; @@ -145,6 +238,8 @@ class instance_throne_of_the_four_winds : public InstanceMapScript protected: EventMap events; + ObjectGuid _engerizeWorldTriggerGUID; + GuidVector _hurricaneGUIDs; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/throne_of_the_four_winds.h b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/throne_of_the_four_winds.h index eba0d40f2b..d2d74b7d49 100644 --- a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/throne_of_the_four_winds.h +++ b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/throne_of_the_four_winds.h @@ -35,7 +35,11 @@ enum TFWDataTypes DATA_ANSHAL = 2, DATA_NEZIR = 3, DATA_ROHASH = 4, - DATA_SKYWALL_RAID_CENTER_PLATFORM = 5 + DATA_SKYWALL_RAID_CENTER_PLATFORM = 5, + DATA_SKYWALL_DJIN_TORNADO = 6, + DATA_SKYWALL_DJIN_FROST = 7, + DATA_SKYWALL_DJIN_HEALING = 8, + DATA_FREE_HURRICANE_VEHICLE = 9 }; enum TFWCreatureIds @@ -49,18 +53,40 @@ enum TFWCreatureIds // Creatures NPC_WORLD_TRIGGER = 21252, NPC_FALL_CATCHER = 45710, + + // Conclave of Wind NPC_RAVENOUS_CREEPER = 45812, NPC_TORNADO = 46207, NPC_WORLD_TRIGGER_IMMUNE_TO_PC = 19871, -}; - -enum TFWGameObjectIds -{ - GO_SKYWALL_RAID_CENTER_PLATFORM = 207737 + NPC_HURRICANE = 46419 }; enum TFWSpells { + // World Trigger + SPELL_POWER_GAIN = 89898, + SPELL_WIND_BLAST_SPEED_BUFF = 93106, +}; + +enum TFWGameObjectIds +{ + GO_SKYWALL_RAID_CENTER_PLATFORM = 207737, + GO_SKYALL_DJIN_TORNADO = 206701, + GO_SKYALL_DJIN_FROST = 206700, + GO_SKYALL_DJIN_HEALING = 206699 +}; + +enum TFWTexts +{ + // World Trigger + SAY_ANNOUNCE_ALMOST_FULL_STRENGTH = 0 +}; + +enum TFWActions +{ + ACTION_CONCLAVE_DEFEATED = 1, + // 2 - Re-use + ACTION_CONCLAVE_AT_FULL_STRENGTH = 3 }; enum TFWMisc