From 06448306c39f88b73e28de14a8b147d9782d3393 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Fri, 16 Nov 2018 07:49:04 +0100 Subject: [PATCH] Scripts/TotFW: implement Al'akir phase 1, 2 and the intro of phase 3 --- sql/updates/WIP/alakir.sql | 86 +++- src/server/game/Spells/SpellMgr.cpp | 22 + .../ZulGurub/boss_jindo_the_godbreaker.cpp | 132 +++-- .../ZulGurub/instance_zulgurub.cpp | 38 ++ .../EasternKingdoms/ZulGurub/zulgurub.h | 10 +- .../ThroneOfTheFourWinds/boss_alakir.cpp | 470 ++++++++++++++++-- .../instance_throne_of_the_four_winds.cpp | 47 +- .../throne_of_the_four_winds.h | 42 +- 8 files changed, 727 insertions(+), 120 deletions(-) diff --git a/sql/updates/WIP/alakir.sql b/sql/updates/WIP/alakir.sql index 84dec88739..7c4e58b89a 100644 --- a/sql/updates/WIP/alakir.sql +++ b/sql/updates/WIP/alakir.sql @@ -13,18 +13,33 @@ UPDATE `creature_template` SET `InhabitType`= 4 WHERE `entry`= 48977; UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `ScriptName`= 'npc_alakir_ice_storm' WHERE `entry`= 46734; -- Ice Storm (Ice Patch Field) UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 46973; +-- Squall Line Vehicle SW +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `VehicleId`= 1358, `speed_walk`= 2.8 WHERE `entry`= 47034; +-- Squall Line Vehicle SE +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `VehicleId`= 1360, `speed_walk`= 2.8 WHERE `entry`= 48852; +-- Ice Storm Trigger +UPDATE `creature_template` SET `InhabitType`= 4 WHERE `entry`= 46766; +-- Stormling Pre-Effect +UPDATE `creature_template` SET `unit_flags`= 33555200, `flags_extra`= 2 WHERE `entry`= 47177; +-- Stormling +UPDATE `creature_template` SET `DamageModifier`= 30, `ScriptName`= 'npc_alakir_stormling' WHERE `entry`= 47175; +-- Relentless Storm Initial Vehicle +UPDATE `creature_template` SET `InhabitType`= 4 WHERE `entry`= 47806; + +-- Model Info +UPDATE `creature_model_info` SET `CombatReach`= 400 WHERE `DisplayId`= 36062; -- Texts DELETE FROM `creature_text` WHERE `CreatureID`= 46753; INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES (46753, 0, 0, 'The Conclave of Wind has dissipated. Your honorable conduct and determination have earned you the right to face me in battle, mortals. I await your assault on my platform! Come!', 14, 0, 100, 0, 0, 0, 50553, 3, 'Al''Akir - Conclave of Wind defeated'), (46753, 1, 0, 'Your challenge is accepted, mortals! Know that you face Al''Akir, Elemental Lord of Air! You have no hope of defeating me!', 14, 0, 100, 0, 0, 0, 50565, 3, 'Al''Akir - Aggro'), -(46753, 2, 0, '|TINTERFACE\\ICONS\\Spell_Frost_WindWalkOn.blp:20|t%s begins to cast |cFFFF0000|Hspell:87770|h[Wind Burst]|h|r!', 41, 0, 100, 0, 0, 0, 49014, 3, 'Al''Akir - Announce Wind Burst'); - +(46753, 2, 0, '|TINTERFACE\\ICONS\\Spell_Frost_WindWalkOn.blp:20|t%s begins to cast |cFFFF0000|Hspell:87770|h[Wind Burst]|h|r!', 41, 0, 100, 0, 0, 0, 49014, 3, 'Al''Akir - Announce Wind Burst'), +(46753, 3, 0, 'Winds! Obey my command!', 14, 0, 100, 0, 0, 0, 50586, 3, 'Al''Akir - Squall Line'), +(46753, 4, 0, 'Your futile persistance angers me!', 14, 0, 100, 0, 0, 0, 50584, 3, 'Al''Akir - Phase 2'), +(46753, 5, 0, 'Storms! I summon you to my side!', 14, 0, 100, 0, 0, 0, 50587, 3, 'Al''Akir - Stormling'), +(46753, 6, 0, 'Enough! I will no longer be contained!', 14, 0, 100, 0, 0, 0, 50585, 3, 'Al''Akir - Phase 3'); /* -(46753, @GROUP_ID+3, @ID+, 'Winds! Obey my command!', 14, 0, 100, 0, 0, 0, UNKNOWN, 'Al''Akir'), -(46753, @GROUP_ID+4, @ID+, 'Your futile persistance angers me!', 14, 0, 100, 0, 0, 0, UNKNOWN, 'Al''Akir'), -(46753, @GROUP_ID+5, @ID+, 'Storms! I summon you to my side!', 14, 0, 100, 0, 0, 0, UNKNOWN, 'Al''Akir'), (46753, @GROUP_ID+6, @ID+, 'Enough! I will no longer be contained!', 14, 0, 100, 0, 0, 0, UNKNOWN, 'Al''Akir'), (46753, @GROUP_ID+7, @ID+, 'After every storm, comes the calm...', 14, 0, 100, 0, 0, 0, UNKNOWN, 'Al''Akir to Player'); */ @@ -33,7 +48,13 @@ INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Lan DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_alakir_lightning_strike_script', 'spell_alakir_lightning_strike_periodic', -'spell_alakir_lightning_strike_damage'); +'spell_alakir_lightning_strike_damage', +'spell_alakir_electrocute', +'spell_alakir_squall_line_pre_aura', +'spell_alakir_squall_line_script', +'spell_alakir_relentless_storm_initial_vehicle_ride_trigger', +'spell_alakir_relentless_storm_initial_vehicle_ride', +'spell_alakir_eye_of_the_storm'); INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (91326, 'spell_alakir_lightning_strike_script'), @@ -42,14 +63,21 @@ INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (93855, 'spell_alakir_lightning_strike_periodic'), (93856, 'spell_alakir_lightning_strike_periodic'), (88214, 'spell_alakir_lightning_strike_damage'), -(93255, 'spell_alakir_lightning_strike_damage'); +(93255, 'spell_alakir_lightning_strike_damage'), +(88427, 'spell_alakir_electrocute'), +(87652, 'spell_alakir_squall_line_pre_aura'), +(87855, 'spell_alakir_squall_line_script'), +(89528, 'spell_alakir_relentless_storm_initial_vehicle_ride_trigger'), +(89527, 'spell_alakir_relentless_storm_initial_vehicle_ride'), +(82724, 'spell_alakir_eye_of_the_storm'); -- Template Addons -DELETE FROM `creature_template_addon` WHERE `entry` IN (47066, 50254, 46734); +DELETE FROM `creature_template_addon` WHERE `entry` IN (47066, 50254, 46734, 47175); INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES (47066, '87713'), (50254, '93247'), -(46734, '87053'); +(46734, '87053'), +(47175, '87906 87905'); -- Summon Groups DELETE FROM `creature_summon_groups` WHERE `summonerId`= 46753 AND `summonerType`= 0; @@ -60,15 +88,47 @@ INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, ` (46753, 0, 0, 47066, 188.823, 813.54, 209.7063, 3.124139, 8, 0); -- Spellclicks -DELETE FROM `npc_spellclick_spells` WHERE `npc_entry`= 47066; +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (47066, 47034, 48852); INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES -(47066, 87742, 1, 0); +(47066, 87742, 1, 0), +(47034, 46598, 1, 1), +(48852, 46598, 1, 1); -- Conditions -DELETE FROM `conditions` WHERE `SourceEntry` IN (91326, 87406) AND `SourceTypeOrReferenceId`= 13; +DELETE FROM `conditions` WHERE `SourceEntry` IN (91326, 87406, 88779, 87652, 87904, 101458, 101459, 101460, 89527) AND `SourceTypeOrReferenceId`= 13; INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES (13, 1, 91326, 0, 0, 31, 0, 3, 48977, 0, 0, 0, '', 'Lightning Strike - Target Lightning Strike Trigger'), -(13, 1, 87406, 0, 0, 31, 0, 3, 46766, 0, 0, 0, '', 'Ice Storm - Target Ice Storm Trigger'); +(13, 1, 87406, 0, 0, 31, 0, 3, 46766, 0, 0, 0, '', 'Ice Storm - Target Ice Storm Trigger'), +(13, 1, 88779, 0, 0, 31, 0, 3, 46753, 0, 0, 0, '', 'Squall Line - Target Al''akir'), +(13, 1, 87652, 0, 0, 31, 0, 3, 48854, 0, 0, 0, '', 'Squall Line - Target Squall Line SW'), +(13, 1, 87652, 0, 1, 31, 0, 3, 48855, 0, 0, 0, '', 'Squall Line - Target Squall Line SE'), +(13, 1, 87904, 0, 0, 31, 0, 3, 46753, 0, 0, 0, '', 'Feedback - Target Al''akir'), +(13, 1, 101458, 0, 0, 31, 0, 3, 46753, 0, 0, 0, '', 'Feedback - Target Al''akir'), +(13, 1, 101459, 0, 0, 31, 0, 3, 46753, 0, 0, 0, '', 'Feedback - Target Al''akir'), +(13, 1, 101460, 0, 0, 31, 0, 3, 46753, 0, 0, 0, '', 'Feedback - Target Al''akir'), +(13, 1, 89527, 0, 0, 31, 0, 3, 47806, 0, 0, 0, '', 'Relentless Storm Initial Vehicle Ride - Target Relentless Storm Initial Vehicle'); + +-- Vehicle Accessories +DELETE FROM `vehicle_template_accessory` WHERE `entry` IN (47034, 48852); +INSERT INTO `vehicle_template_accessory` (`entry`, `accessory_entry`, `seat_id`, `minion`, `description`, `summonType`, `summontimer`) VALUES +-- Squall Line Vehicle SW +(47034, 48854, 0, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 1, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 2, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 3, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 4, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 5, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 6, 1, 'Squall Line SW', 5, 0), +(47034, 48854, 7, 1, 'Squall Line SW', 5, 0), +-- Squall Line Vehicle SE +(48852, 48855, 0, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 1, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 2, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 3, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 4, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 5, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 6, 1, 'Squall Line SE', 5, 0), +(48852, 48855, 7, 1, 'Squall Line SE', 5, 0); -- Spawns DELETE FROM `creature` WHERE `guid` IN (340413, 340414, 340415); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 6632e13e6a..2ebf31cad9 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4917,6 +4917,28 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(467); // 22 seconds }); + // Ice Storm + ApplySpellFix({ 87055 }, [](SpellInfo* spellInfo) + { + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(63); // 25 seconds + }); + + // Stormling + ApplySpellFix({ 88272 }, [](SpellInfo* spellInfo) + { + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds + }); + + // Squall Line + ApplySpellFix({ + 88781, + 91104, + }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_0].MaxRadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50_YARDS); + spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(245); // 50 seconds + }); + // ENDOF THRONE OF THE FOUR WINDS SPELLS // Disenchant diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp index a05fc85d99..69daa71918 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp @@ -42,67 +42,105 @@ enum Yells enum Spells { + // Jin'do the Godbreaker + SPELL_DRAIN_SPIRIT_ESSENCE = 97321, }; enum Events { + EVENT_TALK_INTRO = 1, + EVENT_DRAIN_SPIRIT_ESSENCE }; -class boss_jindo_the_godbreaker : public CreatureScript +enum Phases { - public: - boss_jindo_the_godbreaker() : CreatureScript("boss_jindo_the_godbreaker") { } + PHASE_PRE_FIGHT = 1, + PHASE_COMBAT = 2 +}; - struct boss_jindo_the_godbreakerAI : public BossAI + + +struct boss_jindo_the_godbreaker : public BossAI +{ + boss_jindo_the_godbreaker(Creature* creature) : BossAI(creature, DATA_JINDO_THE_GODBREAKER) { } + + void Reset() override + { + _Reset(); + events.SetPhase(PHASE_PRE_FIGHT); + events.ScheduleEvent(EVENT_DRAIN_SPIRIT_ESSENCE, 1s, 0, PHASE_PRE_FIGHT); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _JustEngagedWith(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + Talk(SAY_AGGRO); + events.SetPhase(PHASE_COMBAT); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + summons.DespawnAll(); + _EnterEvadeMode(); + _DespawnAtEvade(); + } + + void JustDied(Unit* /*killer*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _JustDied(); + } + + void DoAction(int32 action) override + { + switch (action) { - boss_jindo_the_godbreakerAI(Creature* creature) : BossAI(creature, DATA_JINDO_THE_GODBREAKER) { } - - void Reset() override - { - _Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _JustEngagedWith(); - Talk(SAY_AGGRO); - } - - void JustDied(Unit* /*killer*/) override - { - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - /* - while (uint32 eventId = events.ExecuteEvent()) + case ACTION_TRIGGER_JINDO_INTRO: + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) { - switch (eventId) - { - default: - break; - } + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAurasDueToSpell(SPELL_COSMETIC_ALPHA_STATE_25_PCT); + events.ScheduleEvent(EVENT_TALK_INTRO, 11s, 0, PHASE_PRE_FIGHT); } - */ - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI(creature); + break; + default: + break; } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !events.IsInPhase(PHASE_PRE_FIGHT)) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TALK_INTRO: + Talk(SAY_INTRO); + break; + case EVENT_DRAIN_SPIRIT_ESSENCE: + DoCastSelf(SPELL_DRAIN_SPIRIT_ESSENCE); + events.Repeat(20s); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } }; void AddSC_boss_jindo_the_godbreaker() { - new boss_jindo_the_godbreaker(); + RegisterZulGurubCreatureAI(boss_jindo_the_godbreaker); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index f435d2828f..33a7c2583c 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -55,6 +55,12 @@ class instance_zulgurub : public InstanceMapScript SetBossNumber(EncounterCount); LoadObjectData(creatureData, nullptr); LoadDoorData(doorData); + Initialize(); + } + + void Initialize() + { + _defeatedBossesCount = 0; } void OnCreatureCreate(Creature* creature) override @@ -81,6 +87,15 @@ class instance_zulgurub : public InstanceMapScript if (GetBossState(DATA_HIGH_PRIEST_VENOXIS) != DONE) creature->CastSpell(creature, SPELL_POISON_CLOUD); break; + case BOSS_JINDO_THE_GODBREAKER: + creature->setActive(true); + + if (_defeatedBossesCount >= 2) + { + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); + creature->RemoveAurasDueToSpell(SPELL_COSMETIC_ALPHA_STATE_25_PCT); + } + break; default: break; } @@ -108,6 +123,17 @@ class instance_zulgurub : public InstanceMapScript break; } + if (state == DONE) + { + _defeatedBossesCount++; + + if (_defeatedBossesCount >= 2) + if (Creature* jindo = GetCreature(DATA_JINDO_THE_GODBREAKER)) + jindo->AI()->DoAction(ACTION_TRIGGER_JINDO_INTRO); + + SaveToDB(); + } + return true; } @@ -135,9 +161,21 @@ class instance_zulgurub : public InstanceMapScript return 0; } */ + + void WriteSaveDataMore(std::ostringstream& data) override + { + data << _defeatedBossesCount; + } + + void ReadSaveDataMore(std::istringstream& data) override + { + data >> _defeatedBossesCount; + } + private: GuidVector _caveInStalkerGUIDs; GuidVector _poisonPlantGUIDs; + uint8 _defeatedBossesCount; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index 8cc7398dbe..85bc4a44be 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -121,10 +121,16 @@ enum ZGGameObjectIds GO_THE_CACHE_OF_MADNESS_DOOR = 208843 }; +enum ZGActions +{ + ACTION_TRIGGER_JINDO_INTRO = 0 +}; + enum ZGSpells { - SPELL_CAVE_IN_VISUAL = 96935, - SPELL_POISON_CLOUD = 96729 + SPELL_CAVE_IN_VISUAL = 96935, + SPELL_POISON_CLOUD = 96729, + SPELL_COSMETIC_ALPHA_STATE_25_PCT = 82978 }; template diff --git a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_alakir.cpp b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_alakir.cpp index f8f6a8a880..729c95e5c6 100644 --- a/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_alakir.cpp +++ b/src/server/scripts/Kalimdor/ThroneOfTheFourWinds/boss_alakir.cpp @@ -24,30 +24,76 @@ #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "Spell.h" +#include "Vehicle.h" enum Spells { // Al'Akir - SPELL_WIND_BURST = 87770, - SPELL_LIGHTNING_STRIKE_TARGETING = 91327, - SPELL_ICE_STORM = 88239, - SPELL_ELECTROCUTE = 88427, + SPELL_WIND_BURST = 87770, + SPELL_LIGHTNING_STRIKE_TARGETING = 91327, + SPELL_ICE_STORM = 88239, + SPELL_ELECTROCUTE = 88427, + SPELL_SQUALL_LINE_BACK_LEFT = 88781, + SPELL_SQUALL_LINE_BACK_RIGHT = 91104, + SPELL_SQUALL_LINE_SCRIPT = 91129, + SPELL_SQUALL_LINE_SCRIPT_2 = 91110, + SPELL_ACID_RAIN = 88290, + SPELL_STORMLING = 88272, + SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE_TRIGGER = 89528, + SPELL_RELENTLESS_STORM_CHANNEL = 88875, + + // Squall Line Vehicle + SPELL_SQUALL_LINE_FORCE_CAST = 88779, // Lightning Strike Trigger - SPELL_LIGHTNING_STRIKE_SUMMON = 93250, - SPELL_LIGHTNING_STRIKE_PERIODIC = 88238, + SPELL_LIGHTNING_STRIKE_SUMMON = 93250, + SPELL_LIGHTNING_STRIKE_PERIODIC = 88238, // Lightning Strike Trigger (Heroic Chain-Caster) - SPELL_LIGHTNING_STRIKE_DAMAGE = 88214, - SPELL_LIGHTNING_STRIKE_VISUAL = 88230, + SPELL_LIGHTNING_STRIKE_DAMAGE = 88214, + SPELL_LIGHTNING_STRIKE_VISUAL = 88230, // Ice Storm - SPELL_ICE_STORM_PING = 87406, - SPELL_ICE_STORM_CHARGE = 87103, + SPELL_ICE_STORM_PING = 87406, + SPELL_ICE_STORM_CHARGE = 87103, + SPELL_ICE_STORM_UNK = 87408, // Todo: research purpose // Ice Storm (Damage) - SPELL_ICE_STORM_PRE_VISUAL = 87472, - SPELL_ICE_STORM_AURA = 87469, + SPELL_ICE_STORM_PRE_VISUAL = 87472, + SPELL_ICE_STORM_AURA = 87469, + + // Stormling Pre-effect + SPELL_STORMLING_PRE_EFFECT_VISUAL = 87913, + SPELL_STORMLING_SUMMON = 87914, + + // Stormling + SPELL_FEEDBACK = 87904, + + // Relentless Storm Initial Vehicle + SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE = 89527, + + // World Trigger (Infinite AOI) + SPELL_RELENTLESS_STORM_VISUAL = 88866, + SPELL_STORM_DISTANCE_CHECK = 88899, + + // Player + SPELL_EYE_OF_THE_STORM = 82724, + SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE_TELEPORT = 89661, + SPELL_PET_FLIGHT = 90786, +}; + +#define SPELL_ACID_RAIN RAID_MODE(88290, 101451, 101452, 101453) +#define SPELL_ACID_RAIN_DAMAGE RAID_MODE(88301, 93279, 93280, 93281) + +enum Texts +{ + SAY_CONCLAVE_OF_WIND_DEFEATED = 0, + SAY_AGGRO = 1, + SAY_ANNOUNCE_WIND_BURST = 2, + SAY_SQUALL_LINE = 3, + SAY_PHASE_TWO = 4, + SAY_SUMMON_STORMLING = 5, + SAY_PHASE_THREE = 6, }; enum Events @@ -56,10 +102,16 @@ enum Events EVENT_WIND_BURST = 1, EVENT_LIGHTNING_STRIKE, EVENT_ICE_STORM, + EVENT_SQUALL_LINE, + EVENT_SUMMON_STORMLING, + EVENT_EYE_OF_THE_STORM, // Ice Storm EVENT_PING_ICE_STORM_TRIGGERS, EVENT_ICE_STORM_CHARGE, + + // Stormling + EVENT_ATTACK_PLAYERS, }; enum Phases @@ -73,13 +125,6 @@ enum Actions { }; -enum Texts -{ - SAY_CONCLAVE_OF_WIND_DEFEATED = 0, - SAY_AGGRO = 1, - SAY_ANNOUNCE_WIND_BURST = 2, -}; - enum Data { DATA_PRIMARY_LIGHTNING_STRIKE_TARGET = 0 @@ -90,20 +135,41 @@ enum SummonGroups SUMMON_GROUP_SLIPSTREAM = 0 }; -class IceStormAuraEvent : public BasicEvent +#define MAX_HOME_POSITION_DISTANCE 70.0f + +class DelayedSpellCastEvent : public BasicEvent { public: - IceStormAuraEvent(Creature* owner) : _owner(owner) { } + DelayedSpellCastEvent(Creature* owner, uint32 spellId) : _owner(owner), _spellId(spellId) { } bool Execute(uint64 /*time*/, uint32 /*diff*/) override { - _owner->CastSpell(_owner, SPELL_ICE_STORM_AURA); + _owner->CastSpell(_owner, _spellId); return true; } private: Creature* _owner; + uint32 _spellId; }; +class SquallLineImmunityRemovalEvent : public BasicEvent +{ + public: + SquallLineImmunityRemovalEvent(Unit* owner, uint32 spellId) : _owner(owner), _spellId(spellId) { } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) override + { + _owner->ApplySpellImmune(0, IMMUNITY_ID, _spellId, false); + return true; + } + private: + Unit* _owner; + uint32 _spellId; +}; + +Position const SquallLineDistanceReferencePos = { -13.16094f, 780.8931f, 191.1842f }; +Position const RelentlessStormTeleportReferencePosition = { -126.0f, 838.0f, 316.0f }; + struct boss_alakir : public BossAI { boss_alakir(Creature* creature) : BossAI(creature, DATA_ALAKIR) @@ -114,6 +180,7 @@ struct boss_alakir : public BossAI void Initialize() { me->SetReactState(REACT_PASSIVE); + _useLeftSquallLineSpell = true; } void JustEngagedWith(Unit* who) override @@ -127,6 +194,7 @@ struct boss_alakir : public BossAI events.ScheduleEvent(EVENT_WIND_BURST, 23s, 0, PHASE_ONE); events.ScheduleEvent(EVENT_LIGHTNING_STRIKE, 9s, 0, PHASE_ONE); events.ScheduleEvent(EVENT_ICE_STORM, 5s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SQUALL_LINE, 10s); } void Reset() @@ -142,11 +210,23 @@ struct boss_alakir : public BossAI // Talk(SAY_SLAY); } - void EnterEvadeMode(EvadeReason why) override + void EnterEvadeMode(EvadeReason /*why*/) override { _EnterEvadeMode(); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + instance->SetData(DATA_ACID_RAIN_WEATHER, NOT_STARTED); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ACID_RAIN_DAMAGE); summons.DespawnAll(); + + if (GameObject* platform = instance->GetGameObject(DATA_SKYWALL_RAID_CENTER_PLATFORM)) + platform->SetDestructibleState(GO_DESTRUCTIBLE_INTACT); + + if (GameObject* draftEffect = instance->GetGameObject(DATA_SKYWALL_WIND_DRAFT_EFFECT_CENTER)) + draftEffect->ResetDoorOrButton(); + + if (Creature* worldTrigger = instance->GetCreature(DATA_WORLD_TRIGGER_INFINITE_AOI)) + worldTrigger->RemoveAllAuras(); + _DespawnAtEvade(); } @@ -154,10 +234,11 @@ struct boss_alakir : public BossAI { _JustDied(); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - } + instance->SetData(DATA_ACID_RAIN_WEATHER, NOT_STARTED); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ACID_RAIN_DAMAGE); - void DamageTaken(Unit* /*attacker*/, uint32& damage) override - { + if (Creature* worldTrigger = instance->GetCreature(DATA_WORLD_TRIGGER_INFINITE_AOI)) + worldTrigger->RemoveAllAuras(); } void DoAction(int32 action) override @@ -188,6 +269,48 @@ struct boss_alakir : public BossAI { } + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(80, damage) && events.IsInPhase(PHASE_ONE)) + { + DoCastSelf(SPELL_ACID_RAIN); + instance->SetData(DATA_ACID_RAIN_WEATHER, IN_PROGRESS); + Talk(SAY_PHASE_TWO); + events.SetPhase(PHASE_TWO); + events.ScheduleEvent(EVENT_SUMMON_STORMLING, 10s, 11s, 0, PHASE_TWO); + } + else if (me->HealthBelowPctDamaged(25, damage) && events.IsInPhase(PHASE_TWO)) + { + Talk(SAY_PHASE_THREE); + me->SetCanFly(true); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + me->SetFacingTo(3.141593f); + me->InterruptNonMeleeSpells(true); + me->RemoveAurasDueToSpell(SPELL_ACID_RAIN); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ACID_RAIN_DAMAGE); + instance->SetData(DATA_ACID_RAIN_WEATHER, NOT_STARTED); + DoCastAOE(SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE_TRIGGER); + DoCastAOE(SPELL_RELENTLESS_STORM_CHANNEL); + summons.DespawnAll(); + events.CancelEvent(EVENT_SQUALL_LINE); + events.SetPhase(PHASE_THREE); + events.ScheduleEvent(EVENT_EYE_OF_THE_STORM, 7s, 0, PHASE_THREE); + + if (GameObject* platform = instance->GetGameObject(DATA_SKYWALL_RAID_CENTER_PLATFORM)) + platform->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); + + if (GameObject* draftEffect = instance->GetGameObject(DATA_SKYWALL_WIND_DRAFT_EFFECT_CENTER)) + draftEffect->UseDoorOrButton(); + + if (Creature* worldTrigger = instance->GetCreature(DATA_WORLD_TRIGGER_INFINITE_AOI)) + { + worldTrigger->CastSpell(worldTrigger, SPELL_RELENTLESS_STORM_VISUAL); + worldTrigger->CastSpell(worldTrigger, SPELL_STORM_DISTANCE_CHECK); + } + } + } + void JustSummoned(Creature* summon) override { summons.Summon(summon); @@ -199,7 +322,27 @@ struct boss_alakir : public BossAI break; case NPC_ICE_STORM: summon->CastSpell(summon, SPELL_ICE_STORM_PRE_VISUAL); - summon->m_Events.AddEvent(new IceStormAuraEvent(summon), summon->m_Events.CalculateTime(3500)); + summon->m_Events.AddEvent(new DelayedSpellCastEvent(summon, SPELL_ICE_STORM_AURA), summon->m_Events.CalculateTime(3500)); + break; + case NPC_SQUALL_LINE_VEHICLE_SW: + DoCastSelf(SPELL_SQUALL_LINE_SCRIPT); + summon->GetMotionMaster()->MoveCirclePath(me->GetPositionX(), me->GetPositionY(), SquallLineDistanceReferencePos.GetPositionZ(), me->GetExactDist(SquallLineDistanceReferencePos), true, 11); + // Delay the spell cast by 100ms to give the core time to place the accessories into the seats for the following spellscript to take effect + summon->m_Events.AddEvent(new DelayedSpellCastEvent(summon, SPELL_SQUALL_LINE_FORCE_CAST), summon->m_Events.CalculateTime(100)); + break; + case NPC_SQUALL_LINE_VEHICLE_SE: + DoCastSelf(SPELL_SQUALL_LINE_SCRIPT); + summon->GetMotionMaster()->MoveCirclePath(me->GetPositionX(), me->GetPositionY(), SquallLineDistanceReferencePos.GetPositionZ(), me->GetExactDist(SquallLineDistanceReferencePos), false, 11); + summon->m_Events.AddEvent(new DelayedSpellCastEvent(summon, SPELL_SQUALL_LINE_FORCE_CAST), summon->m_Events.CalculateTime(100)); + break; + case NPC_SQUALL_LINE_SW: + case NPC_SQUALL_LINE_SE: + // We don't use that spell. We just cast it because in sniffs they do the same + DoCast(summon, SPELL_SQUALL_LINE_SCRIPT_2); + break; + case NPC_STORMLING_PRE_EFFECT: + summon->CastSpell(summon, SPELL_STORMLING_PRE_EFFECT_VISUAL); + summon->m_Events.AddEvent(new DelayedSpellCastEvent(summon, SPELL_STORMLING_SUMMON), summon->m_Events.CalculateTime(3500)); break; default: break; @@ -253,15 +396,36 @@ struct boss_alakir : public BossAI DoCast(target, SPELL_ICE_STORM); events.Repeat(16s); break; + case EVENT_SQUALL_LINE: + if (events.IsInPhase(PHASE_ONE)) + Talk(SAY_SQUALL_LINE); + + DoCastSelf(_useLeftSquallLineSpell ? SPELL_SQUALL_LINE_BACK_LEFT : SPELL_SQUALL_LINE_BACK_RIGHT); + _useLeftSquallLineSpell = !_useLeftSquallLineSpell; + events.Repeat(31s); + break; + case EVENT_SUMMON_STORMLING: + Talk(SAY_SUMMON_STORMLING); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_STORMLING); + events.Repeat(20s); + break; + case EVENT_EYE_OF_THE_STORM: + instance->DoCastSpellOnPlayers(SPELL_EYE_OF_THE_STORM); + break; default: break; } } - DoMeleeAttackIfReady(); + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else + DoSpellAttackIfReady(SPELL_ELECTROCUTE); } private: ObjectGuid _primaryLightningStrikeTarget; + bool _useLeftSquallLineSpell; }; struct npc_alakir_ice_storm : public ScriptedAI @@ -275,7 +439,7 @@ struct npc_alakir_ice_storm : public ScriptedAI void SpellHitTarget(Unit* target, SpellInfo const* spell) override { - if (spell->Id == SPELL_ICE_STORM_PING) + if (spell->Id == SPELL_ICE_STORM_PING && target->GetExactDist2d(me) > 10.0f) _iceStormPositions.push_back(target->GetPosition()); } @@ -303,14 +467,13 @@ struct npc_alakir_ice_storm : public ScriptedAI if (!alakir) break; - Position* pos = &alakir->GetPosition(); - pos->SetOrientation(alakir->GetAngle(me)); - pos->RelocateOffset({ 0.0f, 0.0f, 0.0f, float(M_PI / 2)}); + Position pos = alakir->GetPosition(); + pos.SetOrientation(alakir->GetAngle(me) + float(M_PI / 4)); std::vector possibleDestinations; for (Position destination : _iceStormPositions) { - if (pos->HasInArc(float(M_PI / 2), &destination, 0.0f)) + if (pos.HasInLine(&destination, alakir->GetCombatReach())) possibleDestinations.push_back(destination); } @@ -332,6 +495,76 @@ private: std::vector _iceStormPositions; }; +struct npc_alakir_stormling : public ScriptedAI +{ + npc_alakir_stormling(Creature* creature) : ScriptedAI(creature), _instance(me->GetInstanceScript()) + { + Initialize(); + } + + void Initialize() + { + me->SetReactState(REACT_PASSIVE); + } + + void IsSummonedBy(Unit* /*summoner*/) override + { + _events.ScheduleEvent(EVENT_ATTACK_PLAYERS, 2s + 300ms); + if (Creature* alakir = _instance->GetCreature(DATA_ALAKIR)) + _alakirPos = alakir->GetHomePosition(); + } + + void AttackStart(Unit* who) override + { + if (IsTargetOnPlatform(who)) + ScriptedAI::AttackStart(who); + } + + void JustDied(Unit* /*killer*/) override + { + DoCastAOE(SPELL_FEEDBACK, true); + me->DespawnOrUnsummon(4s); + } + + void UpdateAI(uint32 diff) override + { + UpdateVictim(); + UpdatePlatformVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ATTACK_PLAYERS: + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(); + break; + default: + break; + } + } + } + +private: + EventMap _events; + InstanceScript* _instance; + Position _alakirPos; + + void UpdatePlatformVictim() + { + if (Unit* victim = me->GetVictim()) + if (victim->GetExactDist2d(_alakirPos) > MAX_HOME_POSITION_DISTANCE) + me->AttackStop(); + } + + bool IsTargetOnPlatform(Unit* target) const + { + return (target->GetExactDist2d(_alakirPos) < MAX_HOME_POSITION_DISTANCE); + } +}; + class spell_alakir_lightning_strike_script : public SpellScript { PrepareSpellScript(spell_alakir_lightning_strike_script); @@ -424,12 +657,183 @@ class spell_alakir_lightning_strike_damage : public SpellScript } }; +class spell_alakir_electrocute : public AuraScript +{ + PrepareAuraScript(spell_alakir_electrocute); + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + Unit* caster = GetCaster(); + Unit* target = GetTarget(); + + if (!caster || !target) + return; + + if (caster->IsWithinMeleeRange(target)) + { + Remove(); + return; + } + + if (AuraEffect* aurEff = GetEffect(EFFECT_0)) + { + int32 basePoints = 3600; + basePoints += CalculatePct(basePoints * (aurEff->GetTickNumber() - 1), 50); + aurEff->ChangeAmount(basePoints); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_alakir_electrocute::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } +}; + +class SquallLineGapTargetSelector +{ + public: + SquallLineGapTargetSelector(uint8 seatIndex) : _seatIndex(seatIndex) { } + + bool operator()(WorldObject* object) + { + Unit* target = object->ToUnit(); + if (!target) + return true; + + if (Vehicle* vehicle = target->GetVehicle()) + if (TempSummon* summon = vehicle->GetBase()->ToTempSummon()) + if (summon->GetTimer() < 49 * IN_MILLISECONDS) + return true; + + + if (target->GetTransSeat() == _seatIndex || target->GetTransSeat() == _seatIndex + 2) + return true; + + return false; + } + private: + uint8 _seatIndex; +}; + +class spell_alakir_squall_line_pre_aura : public SpellScript +{ + PrepareSpellScript(spell_alakir_squall_line_pre_aura); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + uint8 seatIndex = urand(0, 5); + targets.remove_if(SquallLineGapTargetSelector(seatIndex)); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_alakir_squall_line_pre_aura::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + } +}; + +class spell_alakir_squall_line_script : public SpellScript +{ + PrepareSpellScript(spell_alakir_squall_line_script); + + void HandleScriptEffect(SpellEffIndex effIndex) + { + if (Unit* caster = GetCaster()) + { + Unit* target = GetHitUnit(); + if (caster->GetVehicleKit() && caster->GetVehicleKit()->GetAvailableSeatCount()) + { + target->CastSpell(caster, GetSpellInfo()->Effects[effIndex].BasePoints, true); + target->ApplySpellImmune(0, IMMUNITY_ID, GetSpellInfo()->Id, true); + target->m_Events.AddEvent(new SquallLineImmunityRemovalEvent(target, GetSpellInfo()->Id), target->m_Events.CalculateTime(6000)); + } + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_alakir_squall_line_script::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_alakir_relentless_storm_initial_vehicle_ride_trigger : public SpellScript +{ + PrepareSpellScript(spell_alakir_relentless_storm_initial_vehicle_ride_trigger); + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE }); + } + + void HandleDummyEffect(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_alakir_relentless_storm_initial_vehicle_ride_trigger::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +class spell_alakir_relentless_storm_initial_vehicle_ride : public SpellScript +{ + PrepareSpellScript(spell_alakir_relentless_storm_initial_vehicle_ride); + + void SetTarget(WorldObject*& target) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (ObjectGuid guid = instance->GetObjectGuid(DATA_FREE_RELENTLESS_STORM_VEHICLE)) + if (Creature* hurricane = ObjectAccessor::GetCreature(*GetCaster(), guid)) + target = hurricane; + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_alakir_relentless_storm_initial_vehicle_ride::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + } +}; + +class spell_alakir_eye_of_the_storm : public SpellScript +{ + PrepareSpellScript(spell_alakir_eye_of_the_storm); + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE_TELEPORT }); + } + + void HandleExtraEffect(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + float x = RelentlessStormTeleportReferencePosition.GetPositionX() + frand(-15.0f, 15.0f); + float y = RelentlessStormTeleportReferencePosition.GetPositionY() + frand(-15.0f, 15.0f); + float z = RelentlessStormTeleportReferencePosition.GetPositionZ() + frand(-15.0f, 15.0f); + + target->CastSpell(x, y, z, SPELL_RELENTLESS_STORM_INITIAL_VEHICLE_RIDE_TELEPORT, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_alakir_eye_of_the_storm::HandleExtraEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } +}; + void AddSC_boss_alakir() { RegisterThroneOfTheFourWindsCreatureAI(boss_alakir); RegisterThroneOfTheFourWindsCreatureAI(npc_alakir_ice_storm); + RegisterThroneOfTheFourWindsCreatureAI(npc_alakir_stormling); RegisterSpellScript(spell_alakir_lightning_strike_script); RegisterSpellScript(spell_alakir_lightning_strike_periodic); RegisterSpellScript(spell_alakir_lightning_strike_damage); + RegisterAuraScript(spell_alakir_electrocute); + RegisterSpellScript(spell_alakir_squall_line_pre_aura); + RegisterSpellScript(spell_alakir_squall_line_script); + RegisterSpellScript(spell_alakir_relentless_storm_initial_vehicle_ride_trigger); + RegisterSpellScript(spell_alakir_relentless_storm_initial_vehicle_ride); + RegisterSpellScript(spell_alakir_eye_of_the_storm); } 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 6313f8fc1c..262310b8d3 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 @@ -30,20 +30,22 @@ ObjectData const creatureData[] = { - { BOSS_ANSHAL, DATA_ANSHAL }, - { BOSS_NEZIR, DATA_NEZIR }, - { BOSS_ROHASH, DATA_ROHASH }, - { BOSS_ALAKIR, DATA_ALAKIR }, - { 0, 0 } // End + { BOSS_ANSHAL, DATA_ANSHAL }, + { BOSS_NEZIR, DATA_NEZIR }, + { BOSS_ROHASH, DATA_ROHASH }, + { BOSS_ALAKIR, DATA_ALAKIR }, + { NPC_WORLD_TRIGGER_INFINITE_AOI, DATA_WORLD_TRIGGER_INFINITE_AOI }, + { 0, 0 } // End }; 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 + { 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 }, + { GO_SKYWALL_WIND_DRAFT_EFFECT_CENTER, DATA_SKYWALL_WIND_DRAFT_EFFECT_CENTER }, + { 0, 0 } // End }; enum Events @@ -101,9 +103,15 @@ class instance_throne_of_the_four_winds : public InstanceMapScript break; case NPC_LIGHTNING_STRIKE_TRIGGER_HEROIC_CHAIN_CASTER: case NPC_ICE_STORM: + case NPC_SQUALL_LINE_SW: + case NPC_SQUALL_LINE_SE: + case NPC_STORMLING: if (Creature* alakir = GetCreature(DATA_ALAKIR)) alakir->AI()->JustSummoned(creature); break; + case NPC_RELENTLESS_STORM_INITIAL_VEHICLE: + _relentlessStormInitialVehicleGUIDs.push_back(creature->GetGUID()); + break; default: break; } @@ -180,6 +188,14 @@ class instance_throne_of_the_four_winds : public InstanceMapScript void SetData(uint32 data, uint32 value) override { + switch (data) + { + case DATA_ACID_RAIN_WEATHER: + instance->SetZoneWeather(ZONE_ID_THRONE_OF_THE_FOUR_WINDS, WEATHER_STATE_HEAVY_RAIN, value == IN_PROGRESS ? 1.0f : 0.0f); + break; + default: + break; + } } ObjectGuid GetGuidData(uint32 type) const override @@ -190,7 +206,15 @@ class instance_throne_of_the_four_winds : public InstanceMapScript for (ObjectGuid guid : _hurricaneGUIDs) { if (Creature* hurricane = instance->GetCreature(guid)) - if (hurricane->GetVehicleKit()->GetAvailableSeatCount()) + if (hurricane->GetVehicleKit() && hurricane->GetVehicleKit()->GetAvailableSeatCount()) + return guid; + } + break; + case DATA_FREE_RELENTLESS_STORM_VEHICLE: + for (ObjectGuid guid : _relentlessStormInitialVehicleGUIDs) + { + if (Creature* storm = instance->GetCreature(guid)) + if (storm->GetVehicleKit() && storm->GetVehicleKit()->GetAvailableSeatCount()) return guid; } break; @@ -250,6 +274,7 @@ class instance_throne_of_the_four_winds : public InstanceMapScript EventMap events; ObjectGuid _engerizeWorldTriggerGUID; GuidVector _hurricaneGUIDs; + GuidVector _relentlessStormInitialVehicleGUIDs; }; 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 2cafa20ef5..09b423098c 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 @@ -28,18 +28,22 @@ uint32 const EncounterCount = 2; enum TFWDataTypes { // Encounter States - DATA_CONCLAVE_OF_WIND = 0, - DATA_ALAKIR = 1, + DATA_CONCLAVE_OF_WIND = 0, + DATA_ALAKIR = 1, // Additional Data - DATA_ANSHAL = 2, - DATA_NEZIR = 3, - DATA_ROHASH = 4, - 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 + DATA_ANSHAL = 2, + DATA_NEZIR = 3, + DATA_ROHASH = 4, + DATA_SKYWALL_RAID_CENTER_PLATFORM = 5, + DATA_SKYWALL_DJIN_TORNADO = 6, + DATA_SKYWALL_DJIN_FROST = 7, + DATA_SKYWALL_DJIN_HEALING = 8, + DATA_SKYWALL_WIND_DRAFT_EFFECT_CENTER = 9, + DATA_FREE_HURRICANE_VEHICLE = 10, + DATA_ACID_RAIN_WEATHER = 11, + DATA_FREE_RELENTLESS_STORM_VEHICLE = 12, + DATA_WORLD_TRIGGER_INFINITE_AOI = 13, }; enum TFWCreatureIds @@ -64,6 +68,14 @@ enum TFWCreatureIds NPC_SLIPSTREAM = 47066, NPC_LIGHTNING_STRIKE_TRIGGER_HEROIC_CHAIN_CASTER = 50254, NPC_ICE_STORM = 46973, + NPC_SQUALL_LINE_VEHICLE_SW = 47034, + NPC_SQUALL_LINE_VEHICLE_SE = 48852, + NPC_SQUALL_LINE_SW = 48854, + NPC_SQUALL_LINE_SE = 48855, + NPC_STORMLING_PRE_EFFECT = 47177, + NPC_STORMLING = 47175, + NPC_RELENTLESS_STORM_INITIAL_VEHICLE = 47806, + NPC_WORLD_TRIGGER_INFINITE_AOI = 36171, }; enum TFWSpells @@ -75,10 +87,11 @@ enum TFWSpells enum TFWGameObjectIds { - GO_SKYWALL_RAID_CENTER_PLATFORM = 207737, - GO_SKYALL_DJIN_TORNADO = 206701, - GO_SKYALL_DJIN_FROST = 206700, - GO_SKYALL_DJIN_HEALING = 206699 + GO_SKYWALL_RAID_CENTER_PLATFORM = 207737, + GO_SKYWALL_WIND_DRAFT_EFFECT_CENTER = 207922, + GO_SKYALL_DJIN_TORNADO = 206701, + GO_SKYALL_DJIN_FROST = 206700, + GO_SKYALL_DJIN_HEALING = 206699 }; enum TFWTexts @@ -96,6 +109,7 @@ enum TFWActions enum TFWMisc { + ZONE_ID_THRONE_OF_THE_FOUR_WINDS = 5638 }; template