Scripts/ShrineOfTheStorm: Implement Aqu'sirr encounter (#30122)

Co-authored-by: ModoX <moardox@gmail.com>
This commit is contained in:
Aqua Deus
2024-09-21 06:29:15 +02:00
committed by GitHub
parent 35b8868763
commit 52d4e0f9ef
6 changed files with 1027 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
SET @ATID := 95;
SEt @ATCP := 83;
SET @ATIDSPAWN := 97;
SET @CGUID := 7001525;
SET @SPAWNGROUP := 1258;
-- Instance
DELETE FROM `instance_template` WHERE `map`=1864;
INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES
(1864, 0, 'instance_shrine_of_the_storm');
-- Creature
DELETE FROM `creature` WHERE `guid`= @CGUID+0;
DELETE FROM `creature_addon` WHERE `guid`= @CGUID+0;
INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `PhaseGroup`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curHealthPct`, `MovementType`, `npcflag`, `unit_flags`, `unit_flags2`, `unit_flags3`, `VerifiedBuild`) VALUES
(@CGUID+0, 134056, 1864, 9525, 9964, '1,2,23,8', 0, 0, 0, 0, 3931.7275390625, -1244.4896240234375, 128.450714111328125, 0.069714099168777465, 7200, 0, 0, 100, 0, NULL, NULL, NULL, NULL, 55664); -- Aqu'sirr (Area: Tidewater Sanctum - Difficulty: Normal) CreateObject2 (Auras: )
UPDATE `creature_template_difficulty` SET `ContentTuningID`=500, `StaticFlags1`=805306624, `VerifiedBuild`=55664 WHERE (`Entry`=134828 AND `DifficultyID`=1); -- 134828 (Aqualing) - Sessile, CanSwim, Floating
UPDATE `creature_template_difficulty` SET `ContentTuningID`=500, `StaticFlags1`=805306624, `VerifiedBuild`=55664 WHERE (`Entry`=134056 AND `DifficultyID`=1); -- 134056 (Aqu'sirr) - Sessile, CanSwim, Floating
UPDATE `creature_template_difficulty` SET `HealthScalingExpansion`=7 WHERE (`Entry`=134056 AND `DifficultyID`=1); -- Aqu'sirr
UPDATE `creature_template_difficulty` SET `HealthScalingExpansion`=7 WHERE (`Entry`=139737 AND `DifficultyID`=1); -- Lord Stormsong
UPDATE `creature_template_difficulty` SET `HealthScalingExpansion`=7 WHERE (`Entry`=134828 AND `DifficultyID`=1); -- Aqualing
UPDATE `creature_template_addon` SET `auras`='274341' WHERE `entry`=139737; -- 139737 (Lord Stormsong) - Water Ritual
UPDATE `creature_template` SET `ScriptName`='npc_aqusirr_intro_lord_stormsong' WHERE `entry`=139737; -- 139737 (Lord Stormsong)
UPDATE `creature_template` SET `ScriptName`='boss_aqusirr' WHERE `entry`=134056; -- 134056 (Aqu'sirr)
UPDATE `creature_template` SET `ScriptName`='boss_aqusirr_aqualing' WHERE `entry`=134828; -- 134828 (Aqualing)
UPDATE `creature_template` SET `faction`=16, `speed_run`=1.285714268684387207, `BaseAttackTime`=2000, `unit_flags`=64, `unit_flags2`=2048, `unit_flags3`=524288 WHERE `entry`=134828; -- Aqualing
DELETE FROM `creature_template_addon` WHERE `entry` IN (134828, 134612);
INSERT INTO `creature_template_addon` (`entry`, `PathId`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES
(134828, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, '264899'), -- 134828 (Aqualing) - Diminish
(134612, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, ''); -- 134612 (Grasping Tentacles)
-- Conversations
DELETE FROM `conversation_actors` WHERE (`Idx`=0 AND `ConversationId` IN (8762, 8761));
INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES
(8762, 65085, 0, 139971, 60766, 0, 0, 34601),
(8761, 0, 0, 139970, 81302, 0, 0, 27843);
DELETE FROM `conversation_template` WHERE `Id` IN (8762, 8761);
INSERT INTO `conversation_template` (`Id`, `FirstLineID`, `TextureKitId`, `VerifiedBuild`) VALUES
(8762, 19643, 0, 34601),
(8761, 19642, 0, 27843);
DELETE FROM `conversation_line_template` WHERE `Id` IN (19643, 19642);
INSERT INTO `conversation_line_template` (`Id`, `UiCameraID`, `ActorIdx`, `Flags`, `ChatType`, `VerifiedBuild`) VALUES
(19643, 1060, 0, 0, 0, 34601),
(19642, 82, 0, 0, 0, 27843);
-- Spawngroup
DELETE FROM `spawn_group_template` WHERE `groupId`= @SPAWNGROUP+0;
INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES
(@SPAWNGROUP+0, 'Shrine of the Storm - Aqu\'sirr spawn', 4);
DELETE FROM `spawn_group` WHERE `groupId`= @SPAWNGROUP+0;
INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES
(@SPAWNGROUP+0, 0, @CGUID+0);
-- Areatrigger
DELETE FROM `areatrigger_template` WHERE (`Id` = @ATID+0 AND `IsCustom` = 1);
INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `VerifiedBuild`) VALUES
(@ATID+0, 1, 1, 0);
DELETE FROM `areatrigger` WHERE `SpawnId`= @ATIDSPAWN+0;
INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerCreatePropertiesId`, `IsCustom`, `MapId`, `SpawnDifficulties`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `PhaseId`, `PhaseGroup`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
(@ATIDSPAWN+0, @ATCP+0, 1, 1864, '1,2,23,8', 3925.384, -1245.656, 128.339, 3.31631, 1, 0, 0, 'at_aqusirr_intro', 'Shrine of the Storm - Trigger Aqu\'sirr intro', 0);
DELETE FROM `areatrigger_create_properties` WHERE `Id`= @ATCP+0 AND `IsCustom`=1;
INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES
(@ATCP+0, 1, @ATID+0, 1, 0, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 1, 18, 30, 5, 18, 30, 5, 0, 0, '', 0);
DELETE FROM `areatrigger_template` WHERE (`IsCustom`=0 AND `Id` IN (17428, 17427));
INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `VerifiedBuild`) VALUES
(17428, 0, 0, 55664),
(17427, 0, 0, 55664);
DELETE FROM `areatrigger_create_properties` WHERE (`IsCustom`=0 AND `Id` IN (12773, 12775));
INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES
(12773, 0, 17427, 0, 4, 0, 0, 0, 0, -1, 0, 0, 0, 6000, 0, 100, 100, 0, 0, 0, 0, 0, 0, 'at_aqusirr_undertow', 55664), -- Spell: 264144 (Undertow)
(12775, 0, 17428, 0, 4, 0, 0, 0, 0, -1, 0, 0, 0, 4000, 0, 6, 6, 0, 0, 0, 0, 0, 0, 'at_aqusirr_surging_rush', 55664); -- Spell: 264101 (Surging Rush)
-- Spells
DELETE FROM `spell_script_names` WHERE `spell_id` IN (274365, 274367, 274364, 264903, 264911, 264912, 264913, 274260, 264102, 264560, 264941, 264477, 264526);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(274365, 'spell_aqusirr_requiem_of_the_abyss'),
(274367, 'spell_aqusirr_requiem_of_the_abyss'),
(274364, 'spell_aqusirr_requiem_of_the_abyss_periodic'),
(264903, 'spell_aqusirr_erupting_waters_aura'),
(264911, 'spell_aqusirr_erupting_waters_split_1'),
(264912, 'spell_aqusirr_erupting_waters_split_2'),
(264913, 'spell_aqusirr_erupting_waters_split_3'),
(264560, 'spell_aqusirr_choking_brine'),
(274260, 'spell_aqusirr_surging_rush'),
(264102, 'spell_aqusirr_surging_rush_selector'),
(264941, 'spell_aqusirr_erupting_waters'),
(264477, 'spell_aqusirr_grasp_from_the_depths_selector'),
(264526, 'spell_aqusirr_grasp_from_the_depths_damage');
-- Conditions
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=265030;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 265030, 0, 0, 51, 0, 5, 134056, 0, '', 0, 0, 0, '', 'Spell \'Erupting Waters\' can only hit \'Aqu\'sirr\'');
-- Texts
DELETE FROM `creature_text` WHERE `CreatureID` = 139737;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(139737, 0, 0, 'How dare you sully this holy place with your presence!', 14, 0, 100, 25, 0, 108219, 150520, 0, 'Lord Stormsong to Player'),
(139737, 1, 0, 'I call upon the surging waters! Arise, and wipe out these intruders!', 14, 0, 100, 5, 0, 108220, 150521, 0, 'Lord Stormsong to Player');
-- SAI
UPDATE `creature_template` SET `faction`=14, `BaseAttackTime`=2000, `unit_flags`=0, `unit_flags2`=32800, `unit_flags3`=524288, `AIName`='SmartAI' WHERE `entry`=134612; -- Grasping Tentacles
DELETE FROM `smart_scripts` WHERE `entryorguid`=134612 AND `source_type`=0;
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `Difficulties`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param_string`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `action_param7`, `action_param_string`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_param_string`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(134612, 0, 0, 0, '', 63, 0, 100, 0, 0, 0, 0, 0, 0, '', 85, 264526, 2, 128, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Grasping Tentacles - On Just Created - Self: Cast Spell 264526');
UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`=1, `LevelScalingDeltaMax`=1, `ContentTuningID`=501, `StaticFlags1`=805306624, `VerifiedBuild`=56647 WHERE (`Entry`=134828 AND `DifficultyID`=2); -- 134828 (Aqualing) - Sessile, CanSwim, Floating
UPDATE `creature_template_difficulty` SET `ContentTuningID`=501, `StaticFlags1`=805306624, `VerifiedBuild`=56647 WHERE (`Entry`=134612 AND `DifficultyID`=2); -- 134612 (Grasping Tentacles) - Sessile, CanSwim, Floating
UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`=1, `LevelScalingDeltaMax`=1, `ContentTuningID`=502, `StaticFlags1`=805306624, `VerifiedBuild`=56647 WHERE (`Entry`=134828 AND `DifficultyID`=23); -- 134828 (Aqualing) - Sessile, CanSwim, Floating
UPDATE `creature_template_difficulty` SET `ContentTuningID`=502, `StaticFlags1`=805306624, `VerifiedBuild`=56647 WHERE (`Entry`=134612 AND `DifficultyID`=23); -- 134612 (Grasping Tentacles) - Sessile, CanSwim, Floating

View File

@@ -4891,6 +4891,37 @@ void SpellMgr::LoadSpellInfoCorrections()
// ENDOF THE AZURE VAULT SPELLS
//
//
// SHRINE OF THE STORM SPELLS
//
// These spells have TARGET_DEST_NEARBY_ENTRY for serverside unit
ApplySpellFix({
274365, // Requiem of the Abyss
274367, // Requiem of the Abyss
264911, // Erupting Waters
264912, // Erupting Waters
264913, // Erupting Waters
}, [](SpellInfo* spellInfo)
{
ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo)
{
spellEffectInfo->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
});
});
// Conversation
ApplySpellFix({ 274668, 274669 }, [](SpellInfo* spellInfo)
{
ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo)
{
spellEffectInfo->Effect = SPELL_EFFECT_CREATE_CONVERSATION;
});
});
// ENDOF SHRINE OF THE STORM SPELLS
//
//
// WAYCREST MANOR SPELLS
//

View File

@@ -0,0 +1,733 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "Creature.h"
#include "GridNotifiers.h"
#include "InstanceScript.h"
#include "Map.h"
#include "ObjectAccessor.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "TaskScheduler.h"
#include "shrine_of_the_storm.h"
enum AqusirrSpells
{
// Lord Stormsong
SPELL_WATER_RITUAL = 274341,
SPELL_REQUIEM_OF_THE_ABYSS_PERIODIC = 274364,
SPELL_REQUIEM_OF_THE_ABYSS = 274359,
SPELL_REQUIEM_OF_THE_ABYSS_KNOCKBACK = 274367,
SPELL_SPLASHING_WATERS = 241680,
// Aqu'sirr
SPELL_EMERGE_VISUAL = 274948,
SPELL_UNDERTOW = 264144,
SPELL_SEA_BLAST = 265001,
SPELL_SURGING_RUSH_SELECTOR = 264102,
SPELL_SURGING_RUSH_DAMAGE = 264155,
SPELL_SURGING_RUSH = 264101,
SPELL_ERUPTING_WATERS_SPLIT = 264903,
SPELL_ERUPTING_WATERS_DAMAGE = 264941,
SPELL_ERUPTING_WATERS_AQUALING = 265030,
SPELL_CHOKING_BRINE = 264560,
SPELL_CHOKING_BRINE_MISSILE = 264714,
SPELL_CHOKING_BRINE_MISSILE_2 = 264703,
SPELL_GRASP_FROM_THE_DEPTHS_SELECTOR = 264477,
SPELL_GRASP_FROM_THE_DEPTHS_SUMMON = 264522,
SPELL_GRASP_FROM_THE_DEPTHS_DAMAGE = 264526,
SPELL_CONVERSATION_HORDE = 274669,
SPELL_CONVERSATION_ALLIANCE = 274668
};
enum AqusirrEvents
{
EVENT_SURGING_RUSH = 1,
EVENT_CHOKING_BRINE,
EVENT_SEA_BLAST,
EVENT_UNDERTOW,
EVENT_GRASP_FROM_THE_DEPTHS
};
enum AqusirrActions
{
ACTION_START_INTRO = 1
};
enum AqusirrTexts
{
SAY_AQUSIRR_INTRO_1 = 0,
SAY_AQUSIRR_INTRO_2 = 1
};
enum AqusirrMisc
{
SPAWN_GROUP_ID_AQUSIRR = 1258,
ANIM_KIT_SURGING_RUSH = 11428
};
constexpr Position RequiemOfTheAbyssPosition = { 3932.82f, -1243.81f, 128.368f };
constexpr Position EruptingWatersSummonPosition1 = { 3917.31f, -1234.08f, 128.130f };
constexpr Position EruptingWatersSummonPosition2 = { 3924.02f, -1259.52f, 128.141f };
constexpr Position EruptingWatersSummonPosition3 = { 3950.80f, -1238.47f, 127.831f };
namespace AqusirrEventHandler
{
void Schedule(Creature* me, EventMap& events)
{
events.ScheduleEvent(EVENT_SURGING_RUSH, 17s);
if (me->GetMap()->GetPlayersCountExceptGMs() > 1)
events.ScheduleEvent(EVENT_CHOKING_BRINE, 8900ms);
events.ScheduleEvent(EVENT_UNDERTOW, 36800ms);
events.ScheduleEvent(EVENT_SEA_BLAST, 1s);
if (me->GetMap()->IsHeroicOrHigher())
events.ScheduleEvent(EVENT_GRASP_FROM_THE_DEPTHS, 14300ms);
}
void Execute(Creature* me, EventMap& events, uint32 eventId)
{
switch (eventId)
{
case EVENT_SEA_BLAST:
{
if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) && !me->IsWithinMeleeRange(me->GetVictim()))
{
if (Unit* target = me->GetAI()->SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, SPELL_SEA_BLAST);
events.Repeat(2400ms);
}
events.Repeat(1s);
break;
}
case EVENT_CHOKING_BRINE:
{
if (Unit* target = me->GetAI()->SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, SPELL_CHOKING_BRINE);
events.Repeat(34s, 39s);
break;
}
case EVENT_SURGING_RUSH:
{
me->CastSpell(nullptr, SPELL_SURGING_RUSH_SELECTOR);
events.RescheduleEvent(EVENT_SEA_BLAST, 10s);
events.Repeat(31500ms, 39300ms);
break;
}
case EVENT_UNDERTOW:
{
if (Unit* target = me->GetAI()->SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, SPELL_UNDERTOW);
events.Repeat(32400ms, 34s);
break;
}
case EVENT_GRASP_FROM_THE_DEPTHS:
{
me->CastSpell(nullptr, SPELL_GRASP_FROM_THE_DEPTHS_SELECTOR);
events.Repeat(38s);
break;
}
default:
break;
}
}
}
// 134056 - Aqu'sirr
struct boss_aqusirr : public BossAI
{
boss_aqusirr(Creature* creature) : BossAI(creature, DATA_AQUSIRR), _triggeredSplit(false), _aqualingDefeatedCount(0) { }
void JustAppeared() override
{
DoCastSelf(SPELL_EMERGE_VISUAL);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
AqusirrEventHandler::Schedule(me, events);
}
void Reset() override
{
events.Reset();
_triggeredSplit = false;
_aqualingDefeatedCount = 0;
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
if (me->IsInEvadeMode())
return;
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->SetBossState(DATA_AQUSIRR, FAIL);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GRASP_FROM_THE_DEPTHS_DAMAGE);
summons.DespawnAll();
_EnterEvadeMode();
_DespawnAtEvade();
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->SetBossState(DATA_AQUSIRR, DONE);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GRASP_FROM_THE_DEPTHS_DAMAGE);
if (Creature* shrineDummy = GetClosestCreatureWithOptions(me, 50.0f, { .CreatureId = NPC_SHRINE_OF_THE_STORM_DUMMY, .IgnorePhases = true }))
shrineDummy->CastSpell(shrineDummy, instance->instance->GetTeamInInstance() == HORDE ? SPELL_CONVERSATION_HORDE : SPELL_CONVERSATION_ALLIANCE, true);
}
void ToggleSplit(bool toggle)
{
if (toggle)
{
me->InterruptNonMeleeSpells(true);
DoCastSelf(SPELL_ERUPTING_WATERS_SPLIT);
events.Reset();
me->SetReactState(REACT_PASSIVE);
}
else
{
DoCastSelf(SPELL_ERUPTING_WATERS_DAMAGE);
me->RemoveAurasDueToSpell(SPELL_ERUPTING_WATERS_SPLIT);
AqusirrEventHandler::Schedule(me, events);
me->SetReactState(REACT_AGGRESSIVE);
}
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
if (me->HealthBelowPctDamaged(50, damage) && !_triggeredSplit)
{
_triggeredSplit = true;
ToggleSplit(true);
}
}
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_ERUPTING_WATERS_AQUALING)
{
DoCastSelf(SPELL_ERUPTING_WATERS_DAMAGE);
_aqualingDefeatedCount++;
if (_aqualingDefeatedCount == 3)
ToggleSplit(false);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
AqusirrEventHandler::Execute(me, events, eventId);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
}
private:
bool _triggeredSplit;
uint8 _aqualingDefeatedCount;
};
// 134828 - Aqualing
struct boss_aqusirr_aqualing : public ScriptedAI
{
boss_aqusirr_aqualing(Creature* creature) : ScriptedAI(creature)
{
SetBoundary(me->GetInstanceScript()->GetBossBoundary(DATA_AQUSIRR));
}
void JustAppeared() override
{
DoZoneInCombat();
}
void JustDied(Unit* /*killer*/) override
{
me->GetInstanceScript()->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
DoCast(SPELL_ERUPTING_WATERS_AQUALING);
me->DespawnOrUnsummon(3s);
}
void EnterEvadeMode(EvadeReason why) override
{
if (Creature* aqusirr = me->GetInstanceScript()->GetCreature(DATA_AQUSIRR))
aqusirr->AI()->EnterEvadeMode(why);
}
void JustEngagedWith(Unit* /*who*/) override
{
me->GetInstanceScript()->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 2);
AqusirrEventHandler::Schedule(me, events);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
AqusirrEventHandler::Execute(me, events, eventId);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
}
private:
EventMap events;
};
// 139737 - Lord Stormsong
struct npc_aqusirr_intro_lord_stormsong : public CreatureAI
{
npc_aqusirr_intro_lord_stormsong(Creature* creature) : CreatureAI(creature) { }
void DoAction(int32 action) override
{
if (action == ACTION_START_INTRO)
{
me->RemoveAurasDueToSpell(SPELL_WATER_RITUAL);
Milliseconds delay = 1s;
_scheduler.Schedule(delay, [this](TaskContext)
{
me->SetFacingTo(0.1939797f);
});
delay += 3s;
_scheduler.Schedule(delay, [this](TaskContext)
{
Talk(SAY_AQUSIRR_INTRO_1);
});
delay += 6s;
_scheduler.Schedule(delay, [this](TaskContext)
{
Talk(SAY_AQUSIRR_INTRO_2);
});
delay += 6s;
_scheduler.Schedule(delay, [this](TaskContext)
{
DoCastSelf(SPELL_REQUIEM_OF_THE_ABYSS);
});
delay += 1s;
_scheduler.Schedule(delay, [this](TaskContext)
{
DoCastSelf(SPELL_REQUIEM_OF_THE_ABYSS_PERIODIC, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
});
delay += 6s;
_scheduler.Schedule(delay, [this](TaskContext)
{
me->GetMap()->SpawnGroupSpawn(SPAWN_GROUP_ID_AQUSIRR);
});
delay += 3800ms;
_scheduler.Schedule(delay, [this](TaskContext)
{
DoCastSelf(SPELL_SPLASHING_WATERS);
});
}
}
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_SPLASHING_WATERS)
me->DespawnOrUnsummon();
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
};
// 274365 - Requiem of the Abyss (Visual)
// 274367 - Requiem of the Abyss (Knockback)
class spell_aqusirr_requiem_of_the_abyss : public SpellScript
{
void SetDest(SpellDestination& dest)
{
dest.Relocate(RequiemOfTheAbyssPosition);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_aqusirr_requiem_of_the_abyss::SetDest, EFFECT_0, TARGET_DEST_DEST);
}
};
// 274364 - Requiem of the Abyss
class spell_aqusirr_requiem_of_the_abyss_periodic : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_REQUIEM_OF_THE_ABYSS_KNOCKBACK });
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* creature = GetTarget()->ToCreature();
if (!creature)
return;
creature->CastSpell(nullptr, SPELL_REQUIEM_OF_THE_ABYSS_KNOCKBACK, false);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_aqusirr_requiem_of_the_abyss_periodic::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
// 264903 - Erupting Waters
class spell_aqusirr_erupting_waters_aura : public AuraScript
{
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* target = GetTarget()->ToCreature();
if (!target)
return;
target->SetUnkillable(true);
target->SetImmuneToPC(true);
target->SetUninteractible(true);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* target = GetTarget()->ToCreature();
if (!target)
return;
target->SetUnkillable(false);
target->SetImmuneToPC(false);
target->SetUninteractible(false);
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_aqusirr_erupting_waters_aura::OnApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_aqusirr_erupting_waters_aura::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
}
};
// 264911 - Erupting Waters
class spell_aqusirr_erupting_waters_split_1 : public SpellScript
{
void SetDest(SpellDestination& dest)
{
dest.Relocate(EruptingWatersSummonPosition1);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_aqusirr_erupting_waters_split_1::SetDest, EFFECT_0, TARGET_DEST_DEST);
}
};
// 264912 - Erupting Waters
class spell_aqusirr_erupting_waters_split_2 : public SpellScript
{
void SetDest(SpellDestination& dest)
{
dest.Relocate(EruptingWatersSummonPosition2);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_aqusirr_erupting_waters_split_2::SetDest, EFFECT_0, TARGET_DEST_DEST);
}
};
// 264913 - Erupting Waters
class spell_aqusirr_erupting_waters_split_3 : public SpellScript
{
void SetDest(SpellDestination& dest)
{
dest.Relocate(EruptingWatersSummonPosition3);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_aqusirr_erupting_waters_split_3::SetDest, EFFECT_0, TARGET_DEST_DEST);
}
};
// 264941 - Erupting Waters
class spell_aqusirr_erupting_waters : public SpellScript
{
void HandleDamage(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
caster->SetHealth(caster->GetHealth() - caster->CountPctFromMaxHealth(GetEffectValue()));
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_aqusirr_erupting_waters::HandleDamage, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 264560 - Choking Brine
class spell_aqusirr_choking_brine : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_CHOKING_BRINE_MISSILE, SPELL_CHOKING_BRINE_MISSILE_2 });
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
return;
Unit* target = GetTarget();
target->CastSpell(target, SPELL_CHOKING_BRINE_MISSILE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
for (uint8 i = 0; i < 5; ++i)
target->CastSpell(target, SPELL_CHOKING_BRINE_MISSILE_2, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_aqusirr_choking_brine::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
// 274260 - Surging Rush
class spell_aqusirr_surging_rush : public SpellScript
{
void HandleScript(SpellEffIndex /*effIndex*/)
{
Creature* creatureTarget = GetHitCreature();
if (!creatureTarget)
return;
creatureTarget->RemoveAurasDueToSpell(SPELL_SURGING_RUSH);
creatureTarget->SetDisableGravity(true);
creatureTarget->AddUnitState(UNIT_STATE_ROOT);
creatureTarget->PlayOneShotAnimKitId(ANIM_KIT_SURGING_RUSH);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_aqusirr_surging_rush::HandleScript, EFFECT_0, SPELL_EFFECT_TRIGGER_ACTION_SET);
}
};
// 264102 - Surging Rush
class spell_aqusirr_surging_rush_selector : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SURGING_RUSH });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
static constexpr float MAX_DISTANCE = 40.0f;
constexpr Position CenterPosition = { 3935.63f, -1243.41f, 128.40f };
float angle = GetCaster()->GetEntry() == NPC_AQUALING ? GetCaster()->GetAbsoluteAngle(CenterPosition) + frand(-float(M_PI) / 3, float(M_PI) / 3) : GetCaster()->GetAbsoluteAngle(GetHitUnit());
Position dest = GetCaster()->GetPosition();
GetCaster()->MovePosition(dest, MAX_DISTANCE, angle - GetCaster()->GetOrientation(), 2.5f);
GetCaster()->CastSpell(dest, SPELL_SURGING_RUSH, false);
}
void HandleActionSet(SpellEffIndex /*effIndex*/)
{
Creature* creatureTarget = GetHitCreature();
if (!creatureTarget)
return;
creatureTarget->SetDisableGravity(false);
creatureTarget->ClearUnitState(UNIT_STATE_ROOT);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_aqusirr_surging_rush_selector::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
OnEffectHitTarget += SpellEffectFn(spell_aqusirr_surging_rush_selector::HandleActionSet, EFFECT_2, SPELL_EFFECT_TRIGGER_ACTION_SET);
}
};
// 264477 - Grasp from the Depths
class spell_aqusirr_grasp_from_the_depths_selector : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_GRASP_FROM_THE_DEPTHS_SUMMON });
}
void HandleHitTarget(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GRASP_FROM_THE_DEPTHS_SUMMON, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_aqusirr_grasp_from_the_depths_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 264526 - Grasp from the Depths
class spell_aqusirr_grasp_from_the_depths_damage : public AuraScript
{
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* caster = Object::ToCreature(GetCaster());
if (!caster)
return;
caster->DespawnOrUnsummon();
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_aqusirr_grasp_from_the_depths_damage::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// 95 - Areatrigger
struct at_aqusirr_intro : AreaTriggerAI
{
at_aqusirr_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
void OnUnitEnter(Unit* unit) override
{
Player* player = unit->ToPlayer();
if (!player)
return;
if (player->IsGameMaster())
return;
Creature* lordSongstorm = unit->FindNearestCreature(NPC_LORD_SONGSTORM_AQUSIRR, 50.0f);
if (!lordSongstorm)
return;
lordSongstorm->AI()->DoAction(ACTION_START_INTRO);
at->Remove();
}
};
// 264144 - Undertow
struct at_aqusirr_undertow : AreaTriggerAI
{
at_aqusirr_undertow(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
unit->ApplyMovementForce(at->GetGUID(), at->GetPosition(), -5.0f, MovementForceType::Gravity);
}
void OnUnitExit(Unit* unit) override
{
if (!unit->IsPlayer())
return;
unit->RemoveMovementForce(at->GetGUID());
}
};
// 264101 - Surging Rush
struct at_aqusirr_surging_rush : AreaTriggerAI
{
at_aqusirr_surging_rush(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { }
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
Unit* caster = at->GetCaster();
if (!caster)
return;
caster->CastSpell(unit, SPELL_SURGING_RUSH_DAMAGE, false);
}
};
void AddSC_boss_aqusirr()
{
RegisterShrineOfTheStormCreatureAI(boss_aqusirr);
RegisterShrineOfTheStormCreatureAI(boss_aqusirr_aqualing);
RegisterShrineOfTheStormCreatureAI(npc_aqusirr_intro_lord_stormsong);
RegisterSpellScript(spell_aqusirr_requiem_of_the_abyss);
RegisterSpellScript(spell_aqusirr_requiem_of_the_abyss_periodic);
RegisterSpellScript(spell_aqusirr_erupting_waters_aura);
RegisterSpellScript(spell_aqusirr_erupting_waters_split_1);
RegisterSpellScript(spell_aqusirr_erupting_waters_split_2);
RegisterSpellScript(spell_aqusirr_erupting_waters_split_3);
RegisterSpellScript(spell_aqusirr_erupting_waters);
RegisterSpellScript(spell_aqusirr_choking_brine);
RegisterSpellScript(spell_aqusirr_surging_rush);
RegisterSpellScript(spell_aqusirr_surging_rush_selector);
RegisterSpellScript(spell_aqusirr_grasp_from_the_depths_selector);
RegisterAreaTriggerAI(at_aqusirr_intro);
RegisterAreaTriggerAI(at_aqusirr_undertow);
RegisterAreaTriggerAI(at_aqusirr_surging_rush);
}

View File

@@ -0,0 +1,72 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AreaBoundary.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"
#include "shrine_of_the_storm.h"
static BossBoundaryData const boundaries =
{
{ DATA_AQUSIRR, new ZRangeBoundary(119.89f, 132.9f) }
};
ObjectData const creatureData[] =
{
{ BOSS_AQUSIRR, DATA_AQUSIRR },
{ BOSS_BROTHER_IRONHULL, DATA_BROTHER_IRONHULL },
{ BOSS_GALECALLER_FAYE, DATA_GALECALLER_FAYE },
{ BOSS_LORD_STORMSONG, DATA_LORD_STORMSONG },
{ BOSS_VOLZITH_THE_WHISPERER, DATA_VOLZITH_THE_WHISPERER },
{ 0, 0 } // END
};
DungeonEncounterData const encounters[] =
{
{ DATA_AQUSIRR, {{ 2130 }} },
{ DATA_TIDESAGE_COUNCIL, {{ 2131 }} },
{ DATA_LORD_STORMSONG, {{ 2132 }} },
{ DATA_VOLZITH_THE_WHISPERER, {{ 2133 }} }
};
class instance_shrine_of_the_storm : public InstanceMapScript
{
public:
instance_shrine_of_the_storm() : InstanceMapScript("instance_shrine_of_the_storm", 1864) { }
struct instance_shrine_of_the_storm_InstanceMapScript : public InstanceScript
{
instance_shrine_of_the_storm_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadBossBoundaries(boundaries);
LoadObjectData(creatureData, nullptr);
LoadDungeonEncounterData(encounters);
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_shrine_of_the_storm_InstanceMapScript(map);
}
};
void AddSC_instance_shrine_of_the_storm()
{
new instance_shrine_of_the_storm();
}

View File

@@ -0,0 +1,63 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _Shrine_Of_The_Storm_h__
#define _Shrine_Of_The_Storm_h__
#include "CreatureAIImpl.h"
constexpr char const* DataHeader = "SOTS";
constexpr char const* ShrineOfTheStormScriptName = "instance_shrine_of_the_storm";
constexpr uint32 const EncounterCount = 4;
enum ShrineOfTheStormDataTypes
{
// Encounters
DATA_AQUSIRR = 0,
DATA_TIDESAGE_COUNCIL = 1,
DATA_LORD_STORMSONG = 2,
DATA_VOLZITH_THE_WHISPERER = 3,
DATA_BROTHER_IRONHULL,
DATA_GALECALLER_FAYE
};
enum ShrineOfTheStormCreatureIds
{
// Bosses
BOSS_AQUSIRR = 134056,
BOSS_BROTHER_IRONHULL = 134063,
BOSS_GALECALLER_FAYE = 134058,
BOSS_LORD_STORMSONG = 134060,
BOSS_VOLZITH_THE_WHISPERER = 134069,
NPC_LORD_SONGSTORM_AQUSIRR = 139737,
NPC_SHRINE_OF_THE_STORM_DUMMY = 139986,
NPC_GRASPING_TENTACLE = 134612,
NPC_AQUALING = 134828,
};
template <class AI, class T>
inline AI* GetShrineOfTheStormAI(T* obj)
{
return GetInstanceAI<AI>(obj, ShrineOfTheStormScriptName);
}
#define RegisterShrineOfTheStormCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetShrineOfTheStormAI)
#endif // _Shrine_Of_The_Storm_h__

View File

@@ -19,6 +19,10 @@
void AddSC_zone_boralus();
// Shrine of the Storm
void AddSC_boss_aqusirr();
void AddSC_instance_shrine_of_the_storm();
// Waycrest Manor
void AddSC_boss_heartsbane_triad();
void AddSC_boss_soulbound_goliath();
@@ -32,6 +36,10 @@ void AddKulTirasScripts()
{
AddSC_zone_boralus();
// Shrine of the Storm
AddSC_boss_aqusirr();
AddSC_instance_shrine_of_the_storm();
// Waycrest Manor
AddSC_boss_heartsbane_triad();
AddSC_boss_soulbound_goliath();