mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Scripts/ScarletHalls: Implement Armsmaster Harlan encounter (#29944)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user