aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNaddley <64811442+Naddley@users.noreply.github.com>2024-05-05 05:30:37 +0200
committerGitHub <noreply@github.com>2024-05-05 05:30:37 +0200
commit62156f57b285ee252c2c4143236a3df95f219ca5 (patch)
tree5bbb3bffc7034ae9adf695cfeace3b72757f809f /src
parent240b7e58d81688e31d84511db4afd6229337c9e9 (diff)
Scripts/ScarletHalls: Implement Armsmaster Harlan encounter (#29944)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Spells/SpellMgr.cpp28
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/boss_armsmaster_harlan.cpp334
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.cpp69
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.h57
-rw-r--r--src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp4
5 files changed, 492 insertions, 0 deletions
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index d689481661d..6bd0010f723 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -4643,6 +4643,34 @@ void SpellMgr::LoadSpellInfoCorrections()
// ENDOF FIRELANDS
//
+ // SCARLET HALLS SPELLS
+ //
+
+ // 111755 - Call Reinforcement
+ ApplySpellFix({ 111755 }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
+
+ ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo)
+ {
+ spellEffectInfo->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
+ });
+ });
+
+ // 111756 - Call Reinforcement
+ ApplySpellFix({ 111756 }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
+
+ ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo)
+ {
+ spellEffectInfo->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
+ });
+ });
+
+ // ENDOF SCARLET HALLS SPELLS
+
+ //
// MARDUM SPELLS
//
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/boss_armsmaster_harlan.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/boss_armsmaster_harlan.cpp
new file mode 100644
index 00000000000..7ebb5a47785
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/boss_armsmaster_harlan.cpp
@@ -0,0 +1,334 @@
+/*
+ * 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 "CreatureAI.h"
+#include "CreatureAIImpl.h"
+#include "InstanceScript.h"
+#include "MotionMaster.h"
+#include "ObjectAccessor.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuras.h"
+#include "SharedDefines.h"
+#include "Vehicle.h"
+#include "scarlet_halls.h"
+
+enum HarlanSpells
+{
+ // Armsmaster Harlan
+ SPELL_HARLAN_DRAGONS_REACH = 111217,
+ SPELL_HARLAN_CALL_REINFORCEMENT = 111755,
+ SPELL_HARLAN_HEROIC_LEAP_JUMP = 111219,
+ SPELL_HARLAN_BERSERKERS_RAGE = 111221,
+ SPELL_HARLAN_BLADES_OF_LIGHT_CAST = 111216,
+ SPELL_HARLAN_BLADES_OF_LIGHT_VEHICLE = 112955,
+ SPELL_HARLAN_BLADES_OF_LIGHT_DAMAGE = 111215,
+ SPELL_HARLAN_LEAVE_VEHICLE = 112953,
+
+ // Scarlet Defender
+ SPELL_SCARLET_DEFENDER_UNARMORED = 113969
+};
+
+enum HarlanEvents
+{
+ EVENT_HARLAN_DRAGONS_REACH = 1,
+ EVENT_HARLAN_CALL_FOR_HELP,
+ EVENT_HARLAN_HEROIC_LEAP,
+ EVENT_HARLAN_BERSERKER_RAGE,
+ EVENT_HARLAN_BLADES_OF_LIGHT,
+ EVENT_HARLAN_CALL_REINFORCEMENT,
+ EVENT_HARLAN_FINISH_BLADES_OF_LIGHT,
+};
+
+enum HarlanTexts
+{
+ SAY_HARLAN_AGGRO = 0,
+ SAY_HARLAN_CALL_FOR_HELP = 1,
+ ANNOUNCE_HARLAN_CALL_FOR_HELP = 2,
+ ANNOUNCE_HARLAN_BLADE_FOR_LIGHT = 3,
+ SAY_HARLAN_DEATH = 4
+};
+
+enum HarlanPathIds
+{
+ PATH_HARLAN_BLADES_OF_LIGHT_LEFT = 5863200,
+ PATH_HARLAN_BLADES_OF_LIGHT_RIGHT = 5863201
+};
+
+// 58632 - Armsmaster Harlan
+struct boss_armsmaster_harlan : public BossAI
+{
+ boss_armsmaster_harlan(Creature* creature) : BossAI(creature, DATA_ARMSMASTER_HARLAN), _berserkerRage(false) { }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+ Talk(SAY_HARLAN_AGGRO);
+ events.ScheduleEvent(EVENT_HARLAN_DRAGONS_REACH, 7s);
+ events.ScheduleEvent(EVENT_HARLAN_CALL_FOR_HELP, 20s);
+ events.ScheduleEvent(EVENT_HARLAN_HEROIC_LEAP, 41s);
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ summons.DespawnAll();
+ _EnterEvadeMode();
+ _DespawnAtEvade();
+ }
+
+ void Reset() override
+ {
+ _Reset();
+ _berserkerRage = false;
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ Talk(SAY_HARLAN_DEATH);
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ }
+
+ void MovementInform(uint32 /*type*/, uint32 id) override
+ {
+ if (id == EVENT_JUMP)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ Talk(ANNOUNCE_HARLAN_BLADE_FOR_LIGHT);
+ events.CancelEvent(EVENT_HARLAN_DRAGONS_REACH);
+ events.CancelEvent(EVENT_HARLAN_CALL_FOR_HELP);
+ events.CancelEvent(EVENT_HARLAN_HEROIC_LEAP);
+ DoCastSelf(SPELL_HARLAN_BLADES_OF_LIGHT_CAST);
+ }
+ }
+
+ void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (!_berserkerRage && me->HealthBelowPctDamaged(50, damage))
+ {
+ _berserkerRage = true;
+ DoCastSelf(SPELL_HARLAN_BERSERKERS_RAGE);
+ }
+ }
+
+ void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override
+ {
+ events.ScheduleEvent(EVENT_HARLAN_FINISH_BLADES_OF_LIGHT, 1s);
+ events.ScheduleEvent(EVENT_HARLAN_DRAGONS_REACH, 6s);
+ events.ScheduleEvent(EVENT_HARLAN_CALL_FOR_HELP, 19s);
+ events.ScheduleEvent(EVENT_HARLAN_HEROIC_LEAP, 29s);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ scheduler.Update(diff);
+
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_HARLAN_DRAGONS_REACH:
+ DoCastVictim(SPELL_HARLAN_DRAGONS_REACH);
+ events.ScheduleEvent(EVENT_HARLAN_DRAGONS_REACH, 7s);
+ break;
+ case EVENT_HARLAN_CALL_FOR_HELP:
+ Talk(SAY_HARLAN_CALL_FOR_HELP);
+ events.ScheduleEvent(EVENT_HARLAN_CALL_REINFORCEMENT, 4s);
+ break;
+ case EVENT_HARLAN_HEROIC_LEAP:
+ DoCast(SPELL_HARLAN_HEROIC_LEAP_JUMP);
+ break;
+ case EVENT_HARLAN_CALL_REINFORCEMENT:
+ Talk(ANNOUNCE_HARLAN_CALL_FOR_HELP);
+ DoCast(SPELL_HARLAN_CALL_REINFORCEMENT);
+ events.ScheduleEvent(EVENT_HARLAN_CALL_FOR_HELP, 20s);
+ break;
+ case EVENT_HARLAN_FINISH_BLADES_OF_LIGHT:
+ me->RemoveAurasDueToSpell(SPELL_HARLAN_BLADES_OF_LIGHT_CAST);
+ me->SetHover(false);
+ DoCastSelf(SPELL_HARLAN_LEAVE_VEHICLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ default:
+ break;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+ }
+private:
+ bool _berserkerRage;
+};
+
+// 111216 - Blades of Light
+class spell_harlan_blades_of_light : public SpellScript
+{
+ void HandleAfterCast()
+ {
+ Creature* caster = GetCaster()->ToCreature();
+ if (!caster)
+ return;
+
+ caster->GetMotionMaster()->Clear();
+ caster->SetHover(true);
+
+ if (urand(0, 1) == 0)
+ caster->GetMotionMaster()->MovePath(PATH_HARLAN_BLADES_OF_LIGHT_LEFT, false);
+ else
+ caster->GetMotionMaster()->MovePath(PATH_HARLAN_BLADES_OF_LIGHT_RIGHT, false);
+ }
+
+ void Register() override
+ {
+ AfterCast += SpellCastFn(spell_harlan_blades_of_light::HandleAfterCast);
+ }
+};
+
+// 111394 - Blades of Light
+class spell_harlan_blades_of_light_selector : public SpellScript
+{
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_HARLAN_BLADES_OF_LIGHT_CAST });
+ }
+
+ void HandleHit(SpellEffIndex /*effIndex*/)
+ {
+ if (GetHitUnit()->HasAuraType(AuraType::SPELL_AURA_SPIRIT_OF_REDEMPTION))
+ return;
+
+ GetHitUnit()->CastSpell(GetCaster(), SPELL_HARLAN_BLADES_OF_LIGHT_VEHICLE, true);
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_HARLAN_BLADES_OF_LIGHT_DAMAGE, false);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_harlan_blades_of_light_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+};
+
+// 112953 - Leave Vehicle
+class spell_harlan_leave_vehicle : public SpellScript
+{
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ GetHitUnit()->ExitVehicle();
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_harlan_leave_vehicle::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+// 113959 - Heavy Armor
+class spell_scarlet_defender_heavy_armor : public AuraScript
+{
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_SCARLET_DEFENDER_UNARMORED);
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_scarlet_defender_heavy_armor::OnRemove, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
+ }
+};
+
+constexpr Position CallReinforcmentsRightPosition = { 1182.020f, 447.325f, 11.98933f };
+constexpr Position CallReinforcmentsLeftPosition = { 1181.833f, 440.649f, 11.98763f };
+
+// 111755 - Call Reinforcements
+class spell_call_reinforcements_right : public SpellScript
+{
+ void SetDest(SpellDestination& dest)
+ {
+ dest.Relocate(CallReinforcmentsRightPosition);
+ }
+
+ void Register() override
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_call_reinforcements_right::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY);
+ }
+};
+
+// 111756 - Call Reinforcements
+class spell_call_reinforcements_left : public SpellScript
+{
+ void SetDest(SpellDestination& dest)
+ {
+ dest.Relocate(CallReinforcmentsLeftPosition);
+ }
+
+ void Register() override
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_call_reinforcements_left::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY);
+ }
+};
+
+// 128930 - Eject Spirits of Redemption
+class spell_eject_spirits_of_redemption : public SpellScript
+{
+ void HandleHitTarget(SpellEffIndex /*effIndex*/)
+ {
+ Vehicle* veh = GetCaster()->GetVehicleKit();
+ if (!veh)
+ return;
+
+ for (auto const& [_, seat] : veh->Seats)
+ {
+ Unit* passenger = ObjectAccessor::GetUnit(*GetCaster(), seat.Passenger.Guid);
+ if (!passenger)
+ continue;
+
+ if (passenger->HasAuraType(AuraType::SPELL_AURA_SPIRIT_OF_REDEMPTION))
+ passenger->ExitVehicle();
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_eject_spirits_of_redemption::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+};
+
+void AddSC_boss_armsmaster_harlan()
+{
+ // Creature
+ RegisterScarletHallsCreatureAI(boss_armsmaster_harlan);
+
+ // Spells
+ RegisterSpellScript(spell_harlan_blades_of_light);
+ RegisterSpellScript(spell_harlan_blades_of_light_selector);
+ RegisterSpellScript(spell_harlan_leave_vehicle);
+ RegisterSpellScript(spell_scarlet_defender_heavy_armor);
+ RegisterSpellScript(spell_call_reinforcements_right);
+ RegisterSpellScript(spell_call_reinforcements_left);
+ RegisterSpellScript(spell_eject_spirits_of_redemption);
+}
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.cpp
new file mode 100644
index 00000000000..c3acef9db49
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "InstanceScript.h"
+#include "ScriptMgr.h"
+#include "scarlet_halls.h"
+
+ObjectData const creatureData[] =
+{
+ { BOSS_HOUNDMASTER_BRAUN, DATA_HOUNDMASTER_BRAUN },
+ { BOSS_ARMSMASTER_HARLAN, DATA_ARMSMASTER_HARLAN },
+ { BOSS_FLAMEWEAVER_KOEGLER, DATA_FLAMEWEAVER_KOEGLER },
+ { 0, 0 } // END
+};
+
+DoorData const doorData[] =
+{
+ { GO_HERODS_DOOR_HARLAN_ENCOUNTER_ENTRANCE, DATA_ARMSMASTER_HARLAN, EncounterDoorBehavior::OpenWhenNotInProgress },
+ { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } //End
+};
+
+DungeonEncounterData const encounters[] =
+{
+ { DATA_HOUNDMASTER_BRAUN, {{ 1422 }} },
+ { DATA_ARMSMASTER_HARLAN, {{ 1421 }} },
+ { DATA_FLAMEWEAVER_KOEGLER, {{ 1420 }} },
+};
+
+class instance_scarlet_halls : public InstanceMapScript
+{
+public:
+ instance_scarlet_halls() : InstanceMapScript(ScarletHallsScriptName, 1001) { }
+
+ struct instance_scarlet_halls_InstanceMapScript : public InstanceScript
+ {
+ instance_scarlet_halls_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
+ {
+ SetHeaders(DataHeader);
+ SetBossNumber(EncounterCount);
+ LoadObjectData(creatureData, nullptr);
+ LoadDoorData(doorData);
+ LoadDungeonEncounterData(encounters);
+ }
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const override
+ {
+ return new instance_scarlet_halls_InstanceMapScript(map);
+ }
+};
+
+void AddSC_instance_scarlet_halls()
+{
+ new instance_scarlet_halls();
+}
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.h b/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.h
new file mode 100644
index 00000000000..599895acdd2
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/ScarletHalls/scarlet_halls.h
@@ -0,0 +1,57 @@
+/*
+ * 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 DEF_SCARLET_HALLS_H_
+#define DEF_SCARLET_HALLS_H_
+
+#include "CreatureAIImpl.h"
+
+#define DataHeader "ScarletHalls"
+#define ScarletHallsScriptName "instance_scarlet_halls"
+
+uint32 const EncounterCount = 3;
+
+enum ScarletHallsTypes
+{
+ // Encounters
+ DATA_HOUNDMASTER_BRAUN = 0,
+ DATA_ARMSMASTER_HARLAN = 1,
+ DATA_FLAMEWEAVER_KOEGLER = 2
+};
+
+enum ScarletHallsCreatureIds
+{
+ // Bosses
+ BOSS_HOUNDMASTER_BRAUN = 59303,
+ BOSS_ARMSMASTER_HARLAN = 58632,
+ BOSS_FLAMEWEAVER_KOEGLER = 59150
+};
+
+enum ScarletHallsGameObjectIds
+{
+ GO_HERODS_DOOR_HARLAN_ENCOUNTER_ENTRANCE = 210480
+};
+
+template <class AI, class T>
+inline AI* GetScarletHallsAI(T* obj)
+{
+ return GetInstanceAI<AI>(obj, ScarletHallsScriptName);
+}
+
+#define RegisterScarletHallsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetScarletHallsAI)
+
+#endif
diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
index b818c1e6f10..8316eec13f4 100644
--- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
+++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp
@@ -112,6 +112,8 @@ void AddSC_boss_interrogator_vishas();
void AddSC_boss_scorn();
void AddSC_instance_scarlet_monastery();
void AddSC_boss_mograine_and_whitemane();
+void AddSC_instance_scarlet_halls(); // Scarlet Halls
+void AddSC_boss_armsmaster_harlan();
void AddSC_boss_darkmaster_gandling(); //Scholomance
void AddSC_boss_death_knight_darkreaver();
void AddSC_boss_theolenkrastinov();
@@ -301,6 +303,8 @@ void AddEasternKingdomsScripts()
AddSC_boss_scorn();
AddSC_instance_scarlet_monastery();
AddSC_boss_mograine_and_whitemane();
+ AddSC_instance_scarlet_halls(); // Scarlet Halls
+ AddSC_boss_armsmaster_harlan();
AddSC_boss_darkmaster_gandling(); //Scholomance
AddSC_boss_death_knight_darkreaver();
AddSC_boss_theolenkrastinov();