diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 64de9ea4652..074a5f9b25b 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -5363,8 +5363,8 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->MaxAffectedTargets = 4; }); - // Sonic Breath - ApplySpellFix({ 78075 }, [](SpellInfo* spellInfo) + // Roaring Flame Breath + ApplySpellFix({ 78207 }, [](SpellInfo* spellInfo) { spellInfo->MaxAffectedTargets = 1; }); @@ -5375,12 +5375,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY); }); - // Sonic Flames - ApplySpellFix({ 78945 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_500_YARDS); - }); - // END OF BLACKWING DESCENT SPELLS // Living Bomb diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h index e4584301971..0027d4e7270 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h @@ -55,6 +55,7 @@ enum BWDDataTypes /*Atramedes*/ DATA_ATHENAEUM_DOOR, + DATA_LORD_VICTOR_NEFARIUS_ATRAMEDES }; enum BWDCreatureIds @@ -100,6 +101,7 @@ enum BWDCreatureIds NPC_SONAR_PULSE_BOMB = 49623, NPC_TRACKING_FLAMES = 41879, NPC_REVERBERATING_FLAME = 41962, + NPC_LORD_VICTOR_NEFARIUS_ATRAMEDES = 49580, /*Events*/ NPC_SPIRIT_OF_MOLTENFIST = 43125, @@ -138,12 +140,6 @@ enum BWDSpells SPELL_COLUMN_OF_LIGHT = 95660 }; -enum BWDSummonGroups -{ - SUMMON_GROUP_ATRAMEDES_INTRO = 0, - SUMMON_GROUP_ANCIENT_DWARVEN_SHIELDS = 1 -}; - template inline AI* GetBlackwingDescentAI(T* obj) { diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp index 8b1573165f3..f289a2a2426 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_atramedes.cpp @@ -17,15 +17,14 @@ #include "ObjectMgr.h" #include "ScriptMgr.h" +#include "CommonPredicates.h" +#include "GridNotifiers.h" +#include "MoveSpline.h" +#include "PassiveAI.h" #include "ScriptedCreature.h" #include "SpellScript.h" #include "SpellAuraEffects.h" #include "SpellMgr.h" -#include "GameObject.h" -#include "GridNotifiers.h" -#include "PassiveAI.h" -#include "Player.h" -#include "MoveSpline.h" #include "blackwing_descent.h" enum Spells @@ -44,7 +43,6 @@ enum Spells 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, @@ -56,7 +54,11 @@ enum Spells SPELL_ROARING_FLAME_BREATH_REVERSE_CAST = 78230, SPELL_ROARING_FLAME_SUMMON = 78272, SPELL_AGGRO_CREATOR = 63709, - SPELL_SONIC_FLAMES_FLIGHT = 78945, + SPELL_SONIC_FLAMES = 78945, + + // Lord Victor Nefarius + SPELL_SUMMON_IMP = 92625, + SPELL_DESTROY_SHIELD = 92607, // Player SPELL_RESONATING_CLASH_GROUND = 77611, @@ -72,6 +74,11 @@ enum Texts SAY_ANNOUNCE_SEARING_FLAME = 1, SAY_SEARING_FLAME = 2, SAY_FLIGHT_PHASE = 3, + + // Lord Victor Nefarius + SAY_INTRO = 0, + SAY_SUMMON_IMP = 1, + SAY_DESTROY_SHIELD = 2 }; enum Sounds @@ -90,16 +97,23 @@ enum Events EVENT_SEARING_FLAME, EVENT_SONIC_BREATH, EVENT_LIFTOFF, - EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT, + EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD, + EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING, EVENT_LAND, - EVENT_REENGAGE_PLAYERS + EVENT_LANDED, + EVENT_REENGAGE_PLAYERS, + + // Lord Victor Nefarius + EVENT_SAY_INTRO, + EVENT_SUMMON_IMP }; enum Actions { // Atramedes ACTION_START_INTRO = 0, - ACTION_HALT_REVERBERATING_FLAME = 1 + ACTION_HALT_REVERBERATING_FLAME = 1, + ACTION_DESTROY_SHIELD = 2 }; enum MovePoints @@ -122,39 +136,27 @@ enum Phases enum Data { // Setter - DATA_LAST_ANCIENT_DWARVEN_SHIELD = 0, - DATA_ADD_NOISY_PLAYER = 1, - DATA_REMOVE_NOISY_PLAYER = 2, - DATA_LAST_SHIELD_USER = 3, + DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD = 0, + DATA_ADD_NOISY_PLAYER = 1, + DATA_REMOVE_NOISY_PLAYER = 2, + DATA_LAST_SHIELD_USER = 3, // Getter - DATA_IS_IN_AIR = 0, - DATA_HAS_NOISY_PLAYER = 1 + DATA_IS_IN_AIR = 0, + DATA_HAS_NOISY_PLAYER = 1, + DATA_IS_IN_INTRO_PHASE = 2 }; -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 }; -Position const LandPosition = { 124.575f, -224.797f, 75.4534f }; +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 }; +Position const LandPosition = { 124.575f, -224.797f, 75.4534f }; +Position const LordVictorNefariusSummonPosition = { 92.91319f, -223.9931f, 96.8985f, 0.0f }; struct boss_atramedes : public BossAI { - boss_atramedes(Creature* creature) : BossAI(creature, DATA_ATRAMEDES) - { - Initialize(); - } - - ~boss_atramedes() - { - delete _lastAncientDwarvenShieldGUIDs; - } - - void Initialize() - { - _allowVertigoCast = false; - _lastAncientDwarvenShieldGUIDs = new std::queue(); - } + boss_atramedes(Creature* creature) : BossAI(creature, DATA_ATRAMEDES) { } void Reset() override { @@ -177,7 +179,8 @@ struct boss_atramedes : public BossAI events.ScheduleEvent(EVENT_SONIC_BREATH, 24s, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_LIFTOFF, 1min + 31s, 0, PHASE_GROUND); - _allowVertigoCast = !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); + if (IsHeroic()) + DoSummon(NPC_LORD_VICTOR_NEFARIUS_ATRAMEDES, LordVictorNefariusSummonPosition, 0, TEMPSUMMON_MANUAL_DESPAWN); } void EnterEvadeMode(EvadeReason /*why*/) override @@ -190,6 +193,12 @@ struct boss_atramedes : public BossAI me->DespawnOrUnsummon(); } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + void JustSummoned(Creature* summon) override { summons.Summon(summon); @@ -252,6 +261,8 @@ struct boss_atramedes : public BossAI return (uint8(events.IsInPhase(PHASE_AIR))); case DATA_HAS_NOISY_PLAYER: return (uint8(!_noisyPlayerGUIDs.empty())); + case DATA_IS_IN_INTRO_PHASE: + return (uint8(events.IsInPhase(PHASE_INTRO))); } return 0; @@ -261,8 +272,8 @@ struct boss_atramedes : public BossAI { switch (type) { - case DATA_LAST_ANCIENT_DWARVEN_SHIELD: - _lastAncientDwarvenShieldGUIDs->push(guid); + case DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD: + _lastUsedAncientDwarvenShieldGUID = guid; break; case DATA_ADD_NOISY_PLAYER: _noisyPlayerGUIDs.insert(guid); @@ -282,15 +293,8 @@ struct boss_atramedes : public BossAI { switch (type) { - case DATA_LAST_ANCIENT_DWARVEN_SHIELD: - { - if (_lastAncientDwarvenShieldGUIDs->empty()) - return ObjectGuid::Empty; - - ObjectGuid guid = _lastAncientDwarvenShieldGUIDs->front(); - _lastAncientDwarvenShieldGUIDs->pop(); - return guid; - } + case DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD: + return _lastUsedAncientDwarvenShieldGUID; } return ObjectGuid::Empty; @@ -311,16 +315,14 @@ struct boss_atramedes : public BossAI break; case POINT_LAND_INTRO: me->SetDisableGravity(false); - me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - me->SetHover(false); + me->SendSetPlayHoverAnim(false); me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); me->SetReactState(REACT_AGGRESSIVE); - _allowVertigoCast = true; 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); @@ -348,23 +350,18 @@ struct boss_atramedes : public BossAI 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; case ACTION_HALT_REVERBERATING_FLAME: if (Creature* flame = ObjectAccessor::GetCreature(*me, _reverberatingFlameGUID)) { - flame->m_Events.AddEventAtOffset([flame]() - { - flame->InterruptNonMeleeSpells(true); - flame->GetMotionMaster()->Clear(); - flame->StopMoving(); - flame->CastSpell(flame, SPELL_SONIC_FLAMES_FLIGHT, true); - }, 1s); + flame->InterruptNonMeleeSpells(true); + flame->GetMotionMaster()->Clear(); + flame->StopMoving(); - events.CancelEvent(EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT); - events.ScheduleEvent(EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT, 7s, 0, PHASE_AIR); + events.CancelEvent(EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD); + events.CancelEvent(EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING); + events.ScheduleEvent(EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD, 2s, 0, PHASE_AIR); } break; default: @@ -411,7 +408,7 @@ struct boss_atramedes : public BossAI me->StopMoving(); DoCastSelf(SPELL_SEARING_FLAME); // Patch 4.1: Searing Flame will put Modulation on a 6 seconds cooldown - events.RescheduleEvent(EVENT_MODULATION, 6s); + events.RescheduleEvent(EVENT_MODULATION, 6s, 0, PHASE_GROUND); break; case EVENT_SONIC_BREATH: DoCastAOE(SPELL_SONIC_BREATH); @@ -424,11 +421,22 @@ struct boss_atramedes : public BossAI DoCastSelf(SPELL_TAKE_OFF_ANIM_KIT); me->GetMotionMaster()->MoveTakeoff(POINT_LIFTOFF, LiftoffPosition); break; - case EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT: + case EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD: + if (Creature* flame = ObjectAccessor::GetCreature(*me, _reverberatingFlameGUID)) + { + if (Creature* shield = ObjectAccessor::GetCreature(*me, _lastUsedAncientDwarvenShieldGUID)) + flame->GetMotionMaster()->MovePoint(POINT_NONE, shield->GetPosition()); + + if (flame->movespline) + events.ScheduleEvent(EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING, flame->movespline->Duration(), 0, PHASE_AIR); + } + break; + case EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING: if (Unit* target = ObjectAccessor::GetUnit(*me, _lastShieldUserGUID)) { if (Unit* flame = ObjectAccessor::GetUnit(*me, _reverberatingFlameGUID)) { + flame->CastSpell(flame, SPELL_SONIC_FLAMES); flame->CastSpell(target, SPELL_TRACKING); flame->GetMotionMaster()->MoveFollow(target, 0.0f, ChaseAngle(0.0f, 0.0f)); } @@ -458,10 +466,9 @@ private: door->SetGoState(GO_STATE_ACTIVE); } - bool _allowVertigoCast; - std::queue* _lastAncientDwarvenShieldGUIDs; GuidSet _noisyPlayerGUIDs; ObjectGuid _lastShieldUserGUID; + ObjectGuid _lastUsedAncientDwarvenShieldGUID; ObjectGuid _reverberatingFlameGUID; }; @@ -493,6 +500,51 @@ private: InstanceScript* _instance; }; +struct npc_atramedes_lord_victor_nefarius : public NullCreatureAI +{ + npc_atramedes_lord_victor_nefarius(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { } + + void IsSummonedBy(Unit* /*summoner*/) override + { + _events.ScheduleEvent(EVENT_SAY_INTRO, 10s); + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SAY_INTRO: + Talk(SAY_INTRO); + break; + default: + break; + } + } + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_DESTROY_SHIELD: + Talk(SAY_DESTROY_SHIELD); + DoCastAOE(SPELL_DESTROY_SHIELD); + break; + default: + break; + } + } + +private: + EventMap _events; + InstanceScript* _instance; +}; + class spell_atramedes_modulation : public SpellScript { PrepareSpellScript(spell_atramedes_modulation); @@ -578,10 +630,7 @@ class spell_atramedes_resonating_clash_ground : public SpellScript if (!target || !caster || !target->IsAIEnabled) return; - target->AI()->SetGUID(caster->GetGUID(), DATA_LAST_ANCIENT_DWARVEN_SHIELD); - - // Verify this if it's blizzlike to destroy the shield immediately or just leave it not selectable... - target->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(GetSpellInfo()->Effects[effIndex].BasePoints, target)); + target->AI()->SetGUID(caster->GetGUID(), DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD); target->CastSpell(target, GetSpellInfo()->Effects[effIndex].BasePoints, true); target->PlayDirectSound(SOUND_ID_ATRAMEDES_VERTIGO); @@ -607,7 +656,7 @@ class spell_atramedes_resonating_clash_air : public SpellScript return; if (Unit* shield = GetSpell()->GetOriginalCaster()) - target->AI()->SetGUID(shield->GetGUID(), DATA_LAST_ANCIENT_DWARVEN_SHIELD); + target->AI()->SetGUID(shield->GetGUID(), DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD); target->AI()->SetGUID(caster->GetGUID(), DATA_LAST_SHIELD_USER); @@ -688,7 +737,24 @@ class spell_atramedes_vertigo : public AuraScript void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_1].BasePoints, true); + Unit* target = GetTarget(); + target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_1].BasePoints, true); + + if (Creature* atramedes = target->ToCreature()) + { + if (atramedes->IsAIEnabled) + { + if (InstanceScript* instance = atramedes->GetInstanceScript()) + { + if (instance->GetData(DATA_IS_IN_INTRO_PHASE)) + atramedes->GetMotionMaster()->MovePoint(POINT_PREPARE_LAND_INTRO, IntroFlightPosition2, false); + + if (Creature* nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_ATRAMEDES)) + if (nefarius->IsAIEnabled) + nefarius->AI()->DoAction(ACTION_DESTROY_SHIELD); + } + } + } } void Register() override @@ -705,7 +771,7 @@ class spell_atramedes_sonic_flames : public SpellScript { if (InstanceScript* instance = GetCaster()->GetInstanceScript()) if (Creature* atramedes = instance->GetCreature(DATA_ATRAMEDES)) - if (Creature* shield = ObjectAccessor::GetCreature(*GetCaster(), atramedes->AI()->GetGUID(DATA_LAST_ANCIENT_DWARVEN_SHIELD))) + if (Creature* shield = ObjectAccessor::GetCreature(*GetCaster(), atramedes->AI()->GetGUID(DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD))) target = shield; } @@ -748,27 +814,6 @@ private: ObjectGuid _guid; }; -class spell_atramedes_sonic_flames_flight : public SpellScript -{ - PrepareSpellScript(spell_atramedes_sonic_flames_flight); - - void FilterTargets(std::list& targets) - { - if (targets.empty()) - return; - - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - if (Creature* atramedes = instance->GetCreature(DATA_ATRAMEDES)) - if (ObjectGuid guid = atramedes->AI()->GetGUID(DATA_LAST_ANCIENT_DWARVEN_SHIELD)) - targets.remove_if(SonicFlamesGuidCheck(guid)); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_sonic_flames_flight::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - } -}; - class spell_atramedes_devastation_trigger : public AuraScript { PrepareAuraScript(spell_atramedes_devastation_trigger); @@ -787,10 +832,68 @@ class spell_atramedes_devastation_trigger : public AuraScript } }; +class spell_atramedes_sonic_breath : public SpellScript +{ + PrepareSpellScript(spell_atramedes_sonic_breath); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + targets.remove_if(Trinity::Predicates::IsVictimOf(GetCaster())); + + if (targets.size() > 1) + Trinity::Containers::RandomResize(targets, 1); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_sonic_breath::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + +class ValidInvalidShieldCheck +{ +public: + ValidInvalidShieldCheck(ObjectGuid guid) : _guid(guid) { } + + bool operator()(WorldObject const* obj) const + { + return obj->GetGUID() == _guid || obj->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } +private: + ObjectGuid _guid; +}; + +class spell_atramedes_destroy_shield : public SpellScript +{ + PrepareSpellScript(spell_atramedes_destroy_shield); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + if (Creature* creature = GetCaster()->ToCreature()) + if (creature->IsAIEnabled) + targets.remove_if(ValidInvalidShieldCheck(creature->AI()->GetGUID(DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD))); + + if (targets.size() > 1) + Trinity::Containers::RandomResize(targets, 1); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_destroy_shield::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + } +}; + void AddSC_boss_atramedes() { RegisterBlackwingDescentCreatureAI(boss_atramedes); RegisterBlackwingDescentCreatureAI(npc_atramedes_ancient_dwarven_shield); + RegisterBlackwingDescentCreatureAI(npc_atramedes_lord_victor_nefarius); RegisterSpellScript(spell_atramedes_modulation); RegisterSpellScript(spell_atramedes_roaring_flame_breath_reverse_cast); RegisterAuraScript(spell_atramedes_roaring_flame_breath); @@ -802,6 +905,7 @@ void AddSC_boss_atramedes() RegisterAuraScript(spell_atramedes_noisy); RegisterAuraScript(spell_atramedes_vertigo); RegisterSpellAndAuraScriptPair(spell_atramedes_sonic_flames, spell_atramedes_sonic_flames_AuraScript); - RegisterSpellScript(spell_atramedes_sonic_flames_flight); RegisterAuraScript(spell_atramedes_devastation_trigger); + RegisterSpellScript(spell_atramedes_sonic_breath); + RegisterSpellScript(spell_atramedes_destroy_shield); } 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 dc1371ca506..a8f06dedece 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp @@ -19,6 +19,7 @@ #include "Creature.h" #include "GameObject.h" #include "InstanceScript.h" +#include "MapManager.h" #include "blackwing_descent.h" ObjectData const creatureData[] = @@ -33,6 +34,7 @@ ObjectData const creatureData[] = { NPC_NEFARIAN_MAGMAW, DATA_NEFARIAN_MAGMAW }, { NPC_LORD_VICTOR_NEFARIUS_OMNOTRON, DATA_LORD_VICTOR_NEFARIUS_OMNOTRON }, { NPC_COLUMN_OF_LIGHT, DATA_COLUMN_OF_LIGHT }, + { NPC_LORD_VICTOR_NEFARIUS_ATRAMEDES, DATA_LORD_VICTOR_NEFARIUS_ATRAMEDES }, { 0, 0 } // END }; @@ -68,6 +70,16 @@ enum Actions ACTION_START_ATRAMEDES_INTRO = 0 }; +enum SpawnGroup +{ + SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS = 400 +}; + +enum SummonGroups +{ + SUMMON_GROUP_ATRAMEDES_INTRO = 0 +}; + class instance_blackwing_descent : public InstanceMapScript { public: @@ -87,21 +99,12 @@ class instance_blackwing_descent : public InstanceMapScript void Initialize() { _deadDwarfSpirits = 0; - _initialized = false; - _atramedesIntro = NOT_STARTED; + _atramedesIntroState = NOT_STARTED; } - void OnPlayerEnter(Player* /*player*/) override + void Create() override { - if (_initialized) - return; - - std::list summoned; - instance->SummonCreatureGroup(SUMMON_GROUP_ANCIENT_DWARVEN_SHIELDS, &summoned); - for (TempSummon* summon : summoned) - _ancientDwarvenShieldGUIDs.push_back(summon->GetGUID()); - - _initialized = true; + instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true); } void OnCreatureCreate(Creature* creature) override @@ -166,7 +169,7 @@ class instance_blackwing_descent : public InstanceMapScript go->SetGoState(GO_STATE_ACTIVE); break; case GO_ANCIENT_BELL: - if (_deadDwarfSpirits == 8 && _atramedesIntro != DONE) + if (_deadDwarfSpirits == 8 && _atramedesIntroState != DONE) { go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (Creature* column = instance->SummonCreature(NPC_COLUMN_OF_LIGHT, ColumnOfLightPosition)) @@ -228,13 +231,11 @@ class instance_blackwing_descent : public InstanceMapScript case DATA_ATRAMEDES: if (state == FAIL) { - for (ObjectGuid guid : _ancientDwarvenShieldGUIDs) - if (Creature* shield = instance->GetCreature(guid)) - shield->DespawnOrUnsummon(); - - _ancientDwarvenShieldGUIDs.clear(); _events.ScheduleEvent(EVENT_RESPAWN_ATRAMEDES, 30s); + instance->SpawnGroupDespawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, false); } + else if (state == DONE) + instance->SpawnGroupDespawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, false); break; default: break; @@ -253,18 +254,28 @@ class instance_blackwing_descent : public InstanceMapScript if (_deadDwarfSpirits == 8) { - instance->SummonCreatureGroup(SUMMON_GROUP_ATRAMEDES_INTRO); + std::list summoned; + instance->SummonCreatureGroup(SUMMON_GROUP_ATRAMEDES_INTRO, &summoned); + for (TempSummon* summon : summoned) + _atramedesIntroGUIDs.push_back(summon->GetGUID()); + instance->SummonCreature(NPC_COLUMN_OF_LIGHT, ColumnOfLightPosition); _events.ScheduleEvent(EVENT_MAKE_ANCIENT_BELL_SELECTABLE, 4s + 500ms); } break; case DATA_ATRAMEDES_INTRO: - _atramedesIntro = data; + _atramedesIntroState = data; if (Creature* atramedes = instance->SummonCreature(BOSS_ATRAMEDES, AtramedesIntroSummonPosition)) { + for (ObjectGuid guid : _atramedesIntroGUIDs) + if (Creature* intro = instance->GetCreature(guid)) + intro->DespawnOrUnsummon(); + atramedes->SetDisableGravity(true); - atramedes->SetHover(true); + atramedes->SetReactState(REACT_PASSIVE); + atramedes->SendSetPlayHoverAnim(true); + atramedes->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER); atramedes->AI()->DoAction(ACTION_START_ATRAMEDES_INTRO); } @@ -280,7 +291,7 @@ class instance_blackwing_descent : public InstanceMapScript switch (type) { case DATA_ATRAMEDES_INTRO: - return _atramedesIntro; + return _atramedesIntroState; } return 0; } @@ -357,7 +368,7 @@ class instance_blackwing_descent : public InstanceMapScript column->CastSpell(column, SPELL_COLUMN_OF_LIGHT); break; case EVENT_RESPAWN_ATRAMEDES: - instance->SummonCreatureGroup(SUMMON_GROUP_ANCIENT_DWARVEN_SHIELDS); + instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true); instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition); break; default: @@ -369,17 +380,20 @@ class instance_blackwing_descent : public InstanceMapScript void WriteSaveDataMore(std::ostringstream& data) override { data << _deadDwarfSpirits << ' ' - << _atramedesIntro; + << _atramedesIntroState; } void ReadSaveDataMore(std::istringstream& data) override { data >> _deadDwarfSpirits; - data >> _atramedesIntro; + data >> _atramedesIntroState; // Atramedes' intro is done but he has not been defeated yet: spawm him at his respawn location - if (_atramedesIntro == DONE && GetBossState(DATA_ATRAMEDES) != DONE) + if (_atramedesIntroState == DONE && GetBossState(DATA_ATRAMEDES) != DONE) instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition); + + if (GetBossState(DATA_ATRAMEDES) != DONE) + instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true); } private: @@ -389,10 +403,9 @@ class instance_blackwing_descent : public InstanceMapScript ObjectGuid _roomStalkerTargetDummyLeftGuid; ObjectGuid _roomStalkerTargetDummyRightGuid; GuidVector _roomStalkerGUIDs; - GuidVector _ancientDwarvenShieldGUIDs; + GuidVector _atramedesIntroGUIDs; uint8 _deadDwarfSpirits; - uint8 _atramedesIntro; - bool _initialized; + uint8 _atramedesIntroState; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override