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();