From 7bd1b9a48ae48d8d8456090c5ccfa6354cdfc84a Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Thu, 30 May 2019 11:49:33 +0200 Subject: [PATCH] Scripts/BWD: initial work on Atramedes encounter --- sql/updates/WIP/atramedes.sql | 96 ++++ src/server/game/Spells/SpellMgr.cpp | 44 ++ .../BlackwingDescent/blackwing_decent.cpp | 2 + .../BlackwingDescent/blackwing_descent.h | 15 +- .../BlackwingDescent/boss_atramedes.cpp | 464 ++++++++++++++++++ .../instance_blackwing_descent.cpp | 43 +- .../eastern_kingdoms_script_loader.cpp | 2 + 7 files changed, 661 insertions(+), 5 deletions(-) create mode 100644 sql/updates/WIP/atramedes.sql create mode 100644 src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp diff --git a/sql/updates/WIP/atramedes.sql b/sql/updates/WIP/atramedes.sql new file mode 100644 index 00000000000..6a7a6cd57f9 --- /dev/null +++ b/sql/updates/WIP/atramedes.sql @@ -0,0 +1,96 @@ +-- Template Updates +-- Atramedes +UPDATE `creature_template` SET `ScriptName`= 'boss_atramedes' WHERE `entry`= 41442; +UPDATE `creature_template` SET `speed_run`= 1.429, `VehicleId`= 891, `flags_extra`= 1 | 512, `DamageModifier`= 120, `BaseVariance`= 0.5, `mechanic_immune_mask`= 650854271 WHERE `entry` IN (41442, 49583, 49584, 49585); +-- Blind Dragon Tail +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 130 WHERE `entry`= 42356; +-- Sonar Pulse +UPDATE `creature_template` SET `speed_run`= 1, `unit_flags`= 34080768, `flags_extra`= 130 WHERE `entry`= 41546; +-- Sonar Pulse Target +UPDATE `creature_template` SET `unit_flags`= 33554688, `flags_extra`= 128 WHERE `entry`= 49679; +-- Roaring Flame +UPDATE `creature_template` SET `unit_flags`= 33554688, `flags_extra`= 130 WHERE `entry`= 41807; +-- Tracking Flames +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 130, `speed_run`= 0.714 WHERE `entry`= 41879; +-- Sonar Pulse +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 130 WHERE `entry`= 49623; +-- Reverberating Flame +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 130, `speed_run`= 0.714 WHERE `entry`= 41962; +-- Reverberating Flame (Fire) +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 130, `speed_run`= 0.714 WHERE `entry`= 42001; + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID`= 41442; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `comment`) VALUES +(41442, 0, 0, 'I have no need for eyes to see my enemies. Your clumsy footsteps and foul stench give you away!', 14, 0, 100, 0, 0, 20820, 48030, 'Atramedes - Aggro'), +(41442, 1, 0, '|TInterface\\Icons\\spell_fire_selfdestruct.blp:20|t%s rears back and casts |cFFFF0000|Hspell:77982|h[Searing Flame]|h|r!\n', 41, 0, 100, 0, 0, 20826, 42180, 'Atramedes - Announce Searing Flame'), +(41442, 2, 0, 'You cannot hide from searing flame!', 14, 0, 100, 0, 0, 20826, 48036, 'Atramedes - Searing Flame'), +(41442, 3, 0, 'Yes, run! With every step your heart quickens. The beating, loud and thunderous... Almost deafening. You cannot escape!', 14, 0, 100, 0, 0, 20827, 48038, 'Atramedes'), +(41442, 4, 0, 'This miserable existence finally ends.', 14, 0, 100, 0, 0, 20823, 48034, 'Atramedes to Player'); + +-- Spell Scripts +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_atramedes_modulation', +'spell_atramedes_roaring_flame_breath_reverse_cast', +'spell_atramedes_roaring_flame_breath', +'spell_atramedes_roaring_flame_breath_fire_periodic', +'spell_atramedes_resonating_clash_ground', +'spell_atramedes_vertigo'); + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(92452, 'spell_atramedes_modulation'), +(92453, 'spell_atramedes_modulation'), +(78230, 'spell_atramedes_roaring_flame_breath_reverse_cast'), +(78221, 'spell_atramedes_roaring_flame_breath'), +(78431, 'spell_atramedes_roaring_flame_breath_fire_periodic'), +(77611, 'spell_atramedes_resonating_clash_ground'), +(77717, 'spell_atramedes_vertigo'), +(92389, 'spell_atramedes_vertigo'), +(92390, 'spell_atramedes_vertigo'), +(92391, 'spell_atramedes_vertigo'); + +-- Addons +DELETE FROM `creature_template_addon` WHERE `entry` IN (41807, 42001, 41962); +INSERT INTO `creature_template_addon` (`entry`, `bytes1`, `bytes2`, `auras`) VALUES +(41807, 0, 1, '78024 78018'), +(42001, 0, 1, '78024 78018'), +(41962, 0, 1, '78217 78354'); + +-- Conditions +DELETE FROM `conditions` WHERE `SourceEntry` IN (77673, 78098, 92403, 92404, 92405, 78230, 78431, 77611, 78168) AND `SourceTypeOrReferenceId`= 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES +(13, 1, 77673, 0, 0, 31, 0, 3, 41442, 0, 0, 0, '', 'Sonar Pulse Summon - Target Atramedes'), +(13, 1, 78098, 0, 0, 31, 0, 3, 41879, 0, 0, 0, '', 'Sonic Breath - Target Tracking Flames'), +(13, 1, 92403, 0, 0, 31, 0, 3, 41879, 0, 0, 0, '', 'Sonic Breath - Target Tracking Flames'), +(13, 1, 92404, 0, 0, 31, 0, 3, 41879, 0, 0, 0, '', 'Sonic Breath - Target Tracking Flames'), +(13, 1, 92405, 0, 0, 31, 0, 3, 41879, 0, 0, 0, '', 'Sonic Breath - Target Tracking Flames'), +(13, 1, 78230, 0, 0, 31, 0, 3, 41442, 0, 0, 0, '', 'Roaring Flame Breath Reverse Cast - Target Atramedes'), +(13, 1, 78431, 0, 0, 31, 0, 3, 42001, 0, 0, 0, '', 'Roaring Flame Breath Fire Periodic - Target Reverberating Flame'), +(13, 3, 77611, 0, 0, 31, 0, 3, 41442, 0, 0, 0, '', 'Resonating Clash - Target Atramedes'), +(13, 1, 78168, 0, 0, 31, 0, 3, 41442, 0, 0, 0, '', 'Resonating Clash - Target Atramedes'); + +-- Vehicle Accessory +DELETE FROM `vehicle_template_accessory` WHERE `entry` IN (41442, 49583, 49584, 49585); +INSERT INTO `vehicle_template_accessory` (`entry`, `accessory_entry`, `seat_id`, `minion`, `description`, `summontype`, `summontimer`) VALUES +(41442, 42356, 0, 1, 'Atramedes - Blind Dragon Tail', 8, 0), -- Atramedes - Blind Dragon Tail +(49583, 42356, 0, 1, 'Atramedes - Blind Dragon Tail', 8, 0), -- Atramedes - Blind Dragon Tail +(49584, 42356, 0, 1, 'Atramedes - Blind Dragon Tail', 8, 0), -- Atramedes - Blind Dragon Tail +(49585, 42356, 0, 1, 'Atramedes - Blind Dragon Tail', 8, 0); -- Atramedes - Blind Dragon Tail + +-- Spellclicks +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (41442, 49583, 49584, 49585); +INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES +(41442, 46598, 1, 1), +(49583, 46598, 1, 1), +(49584, 46598, 1, 1), +(49585, 46598, 1, 1); + +-- Movement +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (41546, 41962); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`) VALUES +(41546, 0, 1, 1), +(41962, 0, 0, 2); + +-- Correct Athenaeum Door Rotation +UPDATE `gameobject` SET `rotation2`= -1, `rotation3`= 0 WHERE `guid`= 235177; +UPDATE `gameobject_addon` SET `parent_rotation2`= 1, `parent_rotation3`= -0.00000004371139 WHERE `guid`= 235177; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index ef757a1253c..c9ae4676484 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -5270,6 +5270,50 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS); }); + // Sonar Pulse (10n, 10h) + ApplySpellFix({ + 77672, + 92412 + }, [](SpellInfo* spellInfo) + { + spellInfo->MaxAffectedTargets = 3; + }); + + // Sonar Pulse (25n, 25h) + ApplySpellFix({ + 92411, + 92413 + }, [](SpellInfo* spellInfo) + { + spellInfo->MaxAffectedTargets = 4; + }); + + // Searing Flame + ApplySpellFix({ 77840 }, [](SpellInfo* spellInfo) + { + + spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA; + spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_PERIODIC_TRIGGER_SPELL; + spellInfo->Effects[EFFECT_1].Amplitude = 2000; + }); + + // Sonar Pulse + ApplySpellFix({ + 92526, + 92531, + 92532, + 92533 + }, [](SpellInfo* spellInfo) + { + spellInfo->MaxAffectedTargets = 4; + }); + + // Roaring Flame Breath + ApplySpellFix({ 78207 }, [](SpellInfo* spellInfo) + { + spellInfo->MaxAffectedTargets = 1; + }); + // END OF BLACKWING DESCENT SPELLS // Living Bomb diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_decent.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_decent.cpp index b09a76a6c51..5e8f8bb02aa 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_decent.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_decent.cpp @@ -43,6 +43,8 @@ struct go_bwd_ancient_bell : public GameObjectAI if (Creature* column = _instance->GetCreature(DATA_COLUMN_OF_LIGHT)) column->DespawnOrUnsummon(); + + me->DespawnOrUnsummon(7s + 400ms); } return true; } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h index 90a9341581b..3e0255bb74e 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h @@ -51,8 +51,10 @@ enum BWDDataTypes DATA_MAGMATRON, DATA_TOXITRON, DATA_ARCANOTRON, - DATA_LORD_VICTOR_NEFARIUS_OMNOTRON + DATA_LORD_VICTOR_NEFARIUS_OMNOTRON, + /*Atramedes*/ + DATA_ATHENAEUM_DOOR, }; enum BWDCreatureIds @@ -92,6 +94,14 @@ enum BWDCreatureIds NPC_POWER_GENERATOR = 42733, NPC_LORD_VICTOR_NEFARIUS_OMNOTRON = 49226, + /*Atramedes*/ + NPC_SONAR_PULSE = 41546, + NPC_SONAR_PULSE_TARGET = 49679, + NPC_SONAR_PULSE_BOMB = 49623, + NPC_TRACKING_FLAMES = 41879, + NPC_REVERBERATING_FLAME = 41962, + NPC_REVERBERATING_FLAME_FIRE = 42001, + /*Events*/ NPC_SPIRIT_OF_MOLTENFIST = 43125, NPC_SPIRIT_OF_ANVILRAGE = 43128, @@ -107,7 +117,8 @@ enum BWDCreatureIds enum BWDGameObjectIds { GO_INNER_CHAMBER_DOOR = 205830, - GO_ANCIENT_BELL = 204276 + GO_ANCIENT_BELL = 204276, + GO_ATHENAEUM_DOOR = 208291, }; enum BWDMisc diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp new file mode 100644 index 00000000000..92ff9dc569c --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp @@ -0,0 +1,464 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * 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 . + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "GameObject.h" +#include "GridNotifiers.h" +#include "PassiveAI.h" +#include "Player.h" +#include "MoveSpline.h" +#include "SpellMgr.h" +#include "blackwing_descent.h" + +enum Spells +{ + // Atramedes + SPELL_ROARING_BREATH = 81573, + SPELL_DEVASTATION_TRIGGER = 78898, + SPELL_SOUND_BAR = 89683, + SPELL_DEVASTATION = 78868, + SPELL_SONAR_PULSE = 77672, + SPELL_MODULATION = 77612, + SPELL_SEARING_FLAME = 77840, + SPELL_SONIC_BREATH = 78075, + SPELL_SONIC_BREATH_CAST = 78098, + SPELL_TAKE_OFF_ANIM_KIT = 86915, + SPELL_SONAR_PULSE_TRIGGER = 92519, + SPELL_SONAR_BOMB = 92765, + SPELL_ROARING_FLAME_BREATH = 78207, + SPELL_RESONATING_CLASH_AIR_CLEAR = 78958, + + // Sonar Pulse + SPELL_SONAR_PULSE_PERIODIC_TRIGGER = 77674, + + // Tracking Flames & Reverberating Flame + SPELL_TRACKING = 78092, + + // Reverberating Flame + SPELL_ROARING_FLAME_BREATH_REVERSE_CAST = 78230, + SPELL_ROARING_FLAME_SUMMON = 78272, + SPELL_AGGRO_CREATOR = 63709, + + // Player + SPELL_RESONATING_CLASH_GROUND = 77611, + SPELL_RESONATING_CLASH_AIR = 78168, + SPELL_RESONATING_CLASH_RESET_ENERGY = 77709, + SPELL_NOISY = 78897 +}; + +enum Texts +{ + // Atramedes + SAY_AGGRO = 0, + SAY_ANNOUNCE_SEARING_FLAME = 1, + SAY_SEARING_FLAME = 2, + SAY_FLIGHT_PHASE = 3, +}; + +enum Sounds +{ + SOUND_ID_ATRAMEDES_VERTIGO = 20828 +}; + +enum Events +{ + // Atramedes + EVENT_ROARING_BREATH = 1, + EVENT_CLOSE_DOOR, + EVENT_FLY_TO_INTRO_LAND_POSITION, + EVENT_SONAR_PULSE, + EVENT_MODULATION, + EVENT_SEARING_FLAME, + EVENT_SONIC_BREATH, + EVENT_LIFTOFF +}; + +enum Actions +{ + // Atramedes + ACTION_START_INTRO = 0 +}; + +enum MovePoints +{ + POINT_NONE = 0, + POINT_CAST_ROARING_BREATH, + POINT_PREPARE_LAND_INTRO, + POINT_LAND_INTRO, + POINT_LIFTOFF +}; + +enum Phases +{ + PHASE_INTRO = 0, + PHASE_COMBAT = 1 +}; + +enum Data +{ + DATA_LAST_ANCIENT_DWARVEN_SHIELD = 0 +}; + +Position const IntroFlightPosition1 = { 249.432f, -223.616f, 98.6447f }; +Position const IntroFlightPosition2 = { 214.531f, -223.918f, 93.4661f }; +Position const IntroLandingPosition = { 214.531f, -223.918f, 74.7668f }; +Position const LiftoffPosition = { 130.655f, -226.637f, 113.21f }; + +struct boss_atramedes : public BossAI +{ + boss_atramedes(Creature* creature) : BossAI(creature, DATA_ATRAMEDES) { } + + void Reset() override + { + _Reset(); + events.SetPhase(PHASE_INTRO); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _JustEngagedWith(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + Talk(SAY_AGGRO); + //DoCastSelf(SPELL_DEVASTATION_TRIGGER); + DoCastSelf(SPELL_SOUND_BAR); + events.SetPhase(PHASE_COMBAT); + events.ScheduleEvent(EVENT_CLOSE_DOOR, 5s); + events.ScheduleEvent(EVENT_SONAR_PULSE, 14s + 500ms); + events.ScheduleEvent(EVENT_MODULATION, 13s); + events.ScheduleEvent(EVENT_SEARING_FLAME, 46s); + events.ScheduleEvent(EVENT_SONIC_BREATH, 24s); + events.ScheduleEvent(EVENT_LIFTOFF, 1min + 31s); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + summons.DespawnAll(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + instance->SetBossState(DATA_ATRAMEDES, FAIL); + CleanupEncounter(); + me->DespawnOrUnsummon(); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + + switch (summon->GetEntry()) + { + case NPC_SONAR_PULSE: + summon->SetReactState(REACT_PASSIVE); + summon->m_Events.AddEventAtOffset([summon]() + { + Unit* summoner = summon->ToTempSummon()->GetSummoner(); + if (!summoner) + return; + + summon->CastSpell(summon, SPELL_SONAR_PULSE_PERIODIC_TRIGGER); + summon->m_Events.AddEventAtOffset([summon, summoner]() + { + Position pos = summon->GetPosition(); + pos.m_positionZ += 2.0f; // avoid hickups due to uneven terrain + float angle = summon->GetAngle(summoner) - summon->GetOrientation(); + + summon->MovePositionToFirstCollision(pos, 100.0f, angle); + summon->GetMotionMaster()->MovePoint(POINT_NONE, pos, false); + if (uint32 duration = summon->movespline->Duration()) + summon->DespawnOrUnsummon(duration); + }, 800ms); + }, 400ms); + break; + case NPC_TRACKING_FLAMES: + summon->SetReactState(REACT_PASSIVE); + if (Unit* summoner = summon->ToTempSummon()->GetSummoner()) + { + summon->CastSpell(summoner, SPELL_TRACKING); + summon->GetMotionMaster()->MoveFollow(summoner, 0.0f, ChaseAngle(0.0f, 0.0f)); + me->SetFacingToObject(summon); + DoCast(summon, SPELL_SONIC_BREATH_CAST); + } + break; + case NPC_SONAR_PULSE_BOMB: + DoCast(summon, SPELL_SONAR_BOMB, true); + break; + case NPC_REVERBERATING_FLAME: + summon->SetReactState(REACT_PASSIVE); + if (Unit* summoner = summon->ToTempSummon()->GetSummoner()) + { + summon->CastSpell(summon, SPELL_ROARING_FLAME_BREATH_REVERSE_CAST); + summon->CastSpell(summon, SPELL_AGGRO_CREATOR); + summon->CastSpell(summoner, SPELL_TRACKING); + summon->GetMotionMaster()->MoveFollow(summoner, 0.0f, ChaseAngle(0.0f, 0.0f)); + } + break; + default: + break; + } + } + + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE && motionType != EFFECT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_CAST_ROARING_BREATH: + events.ScheduleEvent(EVENT_ROARING_BREATH, 2s); + break; + case POINT_PREPARE_LAND_INTRO: + me->GetMotionMaster()->MoveLand(POINT_LAND_INTRO, IntroLandingPosition); + break; + case POINT_LAND_INTRO: + me->SetDisableGravity(false); + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + me->SetHover(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); + me->SetReactState(REACT_AGGRESSIVE); + break; + case POINT_LIFTOFF: + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); + me->SetDisableGravity(true); + me->SendSetPlayHoverAnim(true); + Talk(SAY_FLIGHT_PHASE); + DoCastSelf(SPELL_SONAR_PULSE_TRIGGER); + DoCastSelf(SPELL_ROARING_FLAME_BREATH); + break; + default: + break; + } + } + + void SpellHit(Unit* caster, SpellInfo const* spell) + { + switch (spell->Id) + { + case SPELL_RESONATING_CLASH_GROUND: + me->InterruptNonMeleeSpells(true); + me->PlayDirectSound(SOUND_ID_ATRAMEDES_VERTIGO); + break; + case SPELL_RESONATING_CLASH_AIR: + me->InterruptNonMeleeSpells(true); + summons.DespawnEntry(NPC_REVERBERATING_FLAME); + me->PlayDirectSound(SOUND_ID_ATRAMEDES_VERTIGO); + break; + default: + break; + } + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_START_INTRO: + me->SetReactState(REACT_PASSIVE); + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); + me->GetMotionMaster()->MovePoint(POINT_CAST_ROARING_BREATH, IntroFlightPosition1, false); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && (!events.IsInPhase(PHASE_INTRO))) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ROARING_BREATH: + DoCastSelf(SPELL_ROARING_BREATH); + events.ScheduleEvent(EVENT_FLY_TO_INTRO_LAND_POSITION, 4s + 300ms); + break; + case EVENT_CLOSE_DOOR: + if (GameObject* door = instance->GetGameObject(DATA_ATHENAEUM_DOOR)) + door->SetGoState(GO_STATE_READY); + break; + case EVENT_FLY_TO_INTRO_LAND_POSITION: + me->GetMotionMaster()->MovePoint(POINT_PREPARE_LAND_INTRO, IntroFlightPosition2, false); + break; + case EVENT_SONAR_PULSE: + DoCastAOE(SPELL_SONAR_PULSE); + events.Repeat(11s); + break; + case EVENT_MODULATION: + DoCastAOE(SPELL_MODULATION); + events.Repeat(12s); + break; + case EVENT_SEARING_FLAME: + Talk(SAY_ANNOUNCE_SEARING_FLAME); + Talk(SAY_SEARING_FLAME); + me->StopMoving(); + DoCastSelf(SPELL_SEARING_FLAME); + // Patch 4.1: Searing Flame will put Modulation on a 6 seconds cooldown + events.RescheduleEvent(EVENT_MODULATION, 6s); + break; + case EVENT_SONIC_BREATH: + DoCastAOE(SPELL_SONIC_BREATH); + break; + case EVENT_LIFTOFF: + events.Reset(); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + DoCastSelf(SPELL_TAKE_OFF_ANIM_KIT); + me->GetMotionMaster()->MoveTakeoff(POINT_LIFTOFF, LiftoffPosition); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + +private: + void CleanupEncounter() + { + if (GameObject* door = instance->GetGameObject(DATA_ATHENAEUM_DOOR)) + door->SetGoState(GO_STATE_ACTIVE); + } +}; + +class spell_atramedes_modulation : public SpellScript +{ + PrepareSpellScript(spell_atramedes_modulation); + + void ChangeDamage(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + if (!target) + return; + + int32 damage = GetHitDamage(); + AddPct(damage, target->GetPower(POWER_ALTERNATE_POWER)); + SetHitDamage(damage); + } + + void Register() override + { + OnEffectLaunchTarget += SpellEffectFn(spell_atramedes_modulation::ChangeDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } +}; + +class spell_atramedes_roaring_flame_breath_reverse_cast : public SpellScript +{ + PrepareSpellScript(spell_atramedes_roaring_flame_breath_reverse_cast); + + void HandleScriptEffect(SpellEffIndex effIndex) + { + if (Unit* caster = GetCaster()) + GetHitUnit()->CastSpell(caster, GetSpellInfo()->Effects[effIndex].BasePoints); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_atramedes_roaring_flame_breath_reverse_cast::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_atramedes_roaring_flame_breath : public AuraScript +{ + PrepareAuraScript(spell_atramedes_roaring_flame_breath); + + void HandleTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_atramedes_roaring_flame_breath::HandleTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +class spell_atramedes_roaring_flame_breath_fire_periodic : public SpellScript +{ + PrepareSpellScript(spell_atramedes_roaring_flame_breath_fire_periodic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ROARING_FLAME_SUMMON }); + } + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + GetCaster()->CastSpell(GetCaster(), SPELL_ROARING_FLAME_SUMMON, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_roaring_flame_breath_fire_periodic::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + } +}; + +class spell_atramedes_resonating_clash_ground : public SpellScript +{ + PrepareSpellScript(spell_atramedes_resonating_clash_ground); + + void HandleScriptEffect(SpellEffIndex effIndex) + { + Unit* target = GetHitUnit(); + target->CastSpell(target, GetSpellInfo()->Effects[effIndex].BasePoints, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_atramedes_resonating_clash_ground::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_atramedes_vertigo : public AuraScript +{ + PrepareAuraScript(spell_atramedes_vertigo); + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_1].BasePoints, true); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_atramedes_vertigo::AfterRemove, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + } +}; + +void AddSC_boss_atramedes() +{ + RegisterBlackwingDescentCreatureAI(boss_atramedes); + RegisterSpellScript(spell_atramedes_modulation); + RegisterSpellScript(spell_atramedes_roaring_flame_breath_reverse_cast); + RegisterAuraScript(spell_atramedes_roaring_flame_breath); + RegisterSpellScript(spell_atramedes_roaring_flame_breath_fire_periodic); + RegisterSpellScript(spell_atramedes_resonating_clash_ground); + + RegisterAuraScript(spell_atramedes_vertigo); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp index c4240264ef5..7ad548150d0 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp @@ -25,6 +25,7 @@ ObjectData const creatureData[] = { { BOSS_MAGMAW, DATA_MAGMAW }, { BOSS_OMNOTRON, DATA_OMNOTRON_DEFENSE_SYSTEM }, + { BOSS_ATRAMEDES, DATA_ATRAMEDES }, { NPC_ELECTRON, DATA_ELECTRON }, { NPC_MAGMATRON, DATA_MAGMATRON }, { NPC_TOXITRON, DATA_TOXITRON }, @@ -38,6 +39,7 @@ ObjectData const creatureData[] = ObjectData const gameobjectData[] = { { GO_ANCIENT_BELL, DATA_ANCIENT_BELL }, + { GO_ATHENAEUM_DOOR, DATA_ATHENAEUM_DOOR }, { 0, 0 } // END }; @@ -52,10 +54,18 @@ Position const MassiveCrashRightSpawnPosition = { -288.59f, -14.8472f, 211.2 Position const MassiveCrashTargetPositionLeft = { -304.181f, -90.1806f, 214.1653f }; Position const MassiveCrashTargetPositionRight = { -337.375f, -43.6615f, 212.0853f }; Position const ColumnOfLightPosition = { 231.3559f, -224.3038f, 74.95496f, 3.193953f }; +Position const AtramedesIntroSummonPosition = { 288.325f, -222.438f, 96.61964f, 3.089233f }; +Position const AtramedesRespawnPosition = { 220.0347f, -224.3125f, 74.88777f, 3.141593f }; enum Events { - EVENT_MAKE_ANCIENT_BELL_SELECTABLE = 1 + EVENT_MAKE_ANCIENT_BELL_SELECTABLE = 1, + EVENT_RESPAWN_ATRAMEDES +}; + +enum Actions +{ + ACTION_START_ATRAMEDES_INTRO = 0 }; class instance_blackwing_descent : public InstanceMapScript @@ -102,7 +112,7 @@ class instance_blackwing_descent : public InstanceMapScript break; case NPC_ROOM_STALKER: - _roomStalkerGUIDs.insert(creature->GetGUID()); + _roomStalkerGUIDs.push_back(creature->GetGUID()); if (creature->GetExactDist2d(MassiveCrashTargetPositionLeft) < 1.0f) _roomStalkerTargetDummyLeftGuid = creature->GetGUID(); @@ -119,6 +129,14 @@ class instance_blackwing_descent : public InstanceMapScript if (Creature* nefarius = GetCreature(DATA_LORD_VICTOR_NEFARIUS_OMNOTRON)) nefarius->AI()->JustSummoned(creature); break; + case NPC_SONAR_PULSE: + case NPC_TRACKING_FLAMES: + case NPC_SONAR_PULSE_BOMB: + case NPC_REVERBERATING_FLAME: + case NPC_REVERBERATING_FLAME_FIRE: + if (Creature* atramedes = GetCreature(DATA_ATRAMEDES)) + atramedes->AI()->JustSummoned(creature); + break; default: break; } @@ -194,6 +212,10 @@ class instance_blackwing_descent : public InstanceMapScript _roomStalkerGUIDs.clear(); } break; + case DATA_ATRAMEDES: + if (state == FAIL) + _events.ScheduleEvent(EVENT_RESPAWN_ATRAMEDES, 30s); + break; default: break; } @@ -218,6 +240,14 @@ class instance_blackwing_descent : public InstanceMapScript break; case DATA_ATRAMEDES_INTRO: _atramedesIntro = data; + + if (Creature* atramedes = instance->SummonCreature(BOSS_ATRAMEDES, AtramedesIntroSummonPosition)) + { + atramedes->SetDisableGravity(true); + atramedes->SetHover(true); + atramedes->AI()->DoAction(ACTION_START_ATRAMEDES_INTRO); + } + SaveToDB(); break; default: @@ -306,6 +336,9 @@ class instance_blackwing_descent : public InstanceMapScript if (Creature* column = GetCreature(DATA_COLUMN_OF_LIGHT)) column->CastSpell(column, SPELL_COLUMN_OF_LIGHT); break; + case EVENT_RESPAWN_ATRAMEDES: + instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition); + break; default: break; } @@ -322,6 +355,10 @@ class instance_blackwing_descent : public InstanceMapScript { data >> _deadDwarfSpirits; data >> _atramedesIntro; + + // Atramedes' intro is done but he has not been defeated yet: spawm him at his respawn location + if (_atramedesIntro == DONE && GetBossState(DATA_ATRAMEDES) != DONE) + instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition); } private: @@ -330,7 +367,7 @@ class instance_blackwing_descent : public InstanceMapScript ObjectGuid _massiveCrashRightDummyGUID; ObjectGuid _roomStalkerTargetDummyLeftGuid; ObjectGuid _roomStalkerTargetDummyRightGuid; - GuidSet _roomStalkerGUIDs; + GuidVector _roomStalkerGUIDs; uint8 _deadDwarfSpirits; uint8 _atramedesIntro; diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 36597c6bff7..c24eded408c 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -76,6 +76,7 @@ void AddSC_instance_blackwing_lair(); void AddSC_instance_blackwing_descent(); //Blackwing Descent void AddSC_boss_magmaw(); void AddSC_boss_omnotron_defense_system(); +void AddSC_boss_atramedes(); void AddSC_blackwing_descent(); void AddSC_instance_deadmines(); //Deadmines void AddSC_boss_glubtok(); @@ -303,6 +304,7 @@ void AddEasternKingdomsScripts() AddSC_instance_blackwing_descent(); //Blackwing Descent AddSC_boss_magmaw(); AddSC_boss_omnotron_defense_system(); + AddSC_boss_atramedes(); AddSC_blackwing_descent(); AddSC_instance_deadmines(); //Deadmines AddSC_boss_glubtok();