mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-24 10:56:38 +01:00
Scripts/GB: implement General Umbriss encounter
*todo: loot
This commit is contained in:
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* 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 "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Player.h"
|
||||
#include "grim_batol.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// General Umbriss
|
||||
SPELL_BLEEDING_WOUND = 74846,
|
||||
SPELL_BLITZ_SUMMON_TRIGGER = 74668,
|
||||
SPELL_BLITZ = 74670,
|
||||
SPELL_GROUND_SIEGE_SUMMON_TRIGGER = 74640,
|
||||
SPELL_GROUND_SIEGE = 74634,
|
||||
SPELL_SUMMON_SKARDYN = 74859,
|
||||
SPELL_FRENZY = 74853,
|
||||
|
||||
// Troggs
|
||||
SPELL_MODGUDS_MALADY = 74837,
|
||||
SPELL_MODGUDS_MALICE_SPREAD = 90170,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
// General Husam
|
||||
EVENT_BLEEDING_WOUND = 1,
|
||||
EVENT_BLITZ,
|
||||
EVENT_GROUND_SIEGE,
|
||||
EVENT_SUMMON_SKARDYN
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_BOMBARDMENT = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SUMMON_SKARDYN = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_ANNOUNCE_BLITZ = 4,
|
||||
SAY_ANNOUNCE_GROUND_SIEGE = 5,
|
||||
SAY_ANNOUNCE_FRENZY = 6,
|
||||
};
|
||||
|
||||
enum MovementPoints
|
||||
{
|
||||
POINT_SKARDYN_SUMMON = 1
|
||||
};
|
||||
|
||||
Position const MalignantTroggSummonPosition = { -705.4689f, -485.3758f, 281.0951f, 1.265874f };
|
||||
Position const MalignantTroggMovePosition = { -691.993f, -456.1111f, 268.7674f };
|
||||
|
||||
Position const TroggDwellerSummonPositions[3] =
|
||||
{
|
||||
{ -723.0738f, -488.2023f, 292.2519f, 1.432476f },
|
||||
{ -749.5168f, -469.0633f, 309.0818f, 0.5629198f },
|
||||
{ -697.3342f, -486.9066f, 281.0173f, 1.33856f }
|
||||
};
|
||||
|
||||
Position const TroggDwellerMovePositions[3] =
|
||||
{
|
||||
{ -718.5313f, -443.1129f, 268.7674f },
|
||||
{ -729.0295f, -443.5573f, 268.7674f },
|
||||
{ -693.0521f, -458.2517f, 268.7674f }
|
||||
};
|
||||
|
||||
class boss_general_umbriss : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_general_umbriss() : CreatureScript("boss_general_umbriss") { }
|
||||
|
||||
struct boss_general_umbrissAI : public BossAI
|
||||
{
|
||||
boss_general_umbrissAI(Creature* creature) : BossAI(creature, DATA_GENERAL_UMBRISS)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_frenzyCasted = false;
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_JustEngagedWith();
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SKARDYN, Seconds(6));
|
||||
events.ScheduleEvent(EVENT_BLEEDING_WOUND, Seconds(11));
|
||||
events.ScheduleEvent(EVENT_GROUND_SIEGE, Seconds(25) + Milliseconds(500));
|
||||
events.ScheduleEvent(EVENT_BLITZ, Seconds(16));
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
summons.DespawnAll();
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
_EnterEvadeMode();
|
||||
summons.DespawnAll();
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_DespawnAtEvade();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
case NPC_BLITZ_STALKER:
|
||||
me->StopMoving();
|
||||
me->SetFacingToObject(summon);
|
||||
DoCast(summon, SPELL_BLITZ);
|
||||
break;
|
||||
case NPC_GROUND_SIEGE_STALKER:
|
||||
me->StopMoving();
|
||||
me->SetFacingToObject(summon);
|
||||
DoCast(summon, SPELL_GROUND_SIEGE);
|
||||
Talk(SAY_ANNOUNCE_GROUND_SIEGE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
|
||||
{
|
||||
if (me->HealthBelowPct(30) && !_frenzyCasted && !me->HasAura(SPELL_FRENZY))
|
||||
{
|
||||
_frenzyCasted = true;
|
||||
DoCastSelf(SPELL_FRENZY, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_FRENZY)
|
||||
Talk(SAY_ANNOUNCE_FRENZY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BLEEDING_WOUND:
|
||||
DoCastVictim(SPELL_BLEEDING_WOUND);
|
||||
events.Repeat(Seconds(10) + Milliseconds(500));
|
||||
break;
|
||||
case EVENT_BLITZ:
|
||||
DoCastAOE(SPELL_BLITZ_SUMMON_TRIGGER, true);
|
||||
events.Repeat(Seconds(23));
|
||||
break;
|
||||
case EVENT_GROUND_SIEGE:
|
||||
DoCastAOE(SPELL_GROUND_SIEGE_SUMMON_TRIGGER, true);
|
||||
break;
|
||||
case EVENT_SUMMON_SKARDYN:
|
||||
Talk(SAY_SUMMON_SKARDYN);
|
||||
DoCastAOE(SPELL_SUMMON_SKARDYN); // sends a event but since event_scripts does not support multiple spawns...
|
||||
if (Creature* malignantTrogg = DoSummon(NPC_MALIGNANT_TROGG, MalignantTroggSummonPosition, 5000))
|
||||
malignantTrogg->GetMotionMaster()->MovePoint(POINT_SKARDYN_SUMMON, MalignantTroggMovePosition, false);
|
||||
for (uint8 i = 0; i < 3; i++)
|
||||
if (Creature* troggDweller = DoSummon(NPC_TROGG_DWELLER, TroggDwellerSummonPositions[i], 5000))
|
||||
troggDweller->GetMotionMaster()->MovePoint(POINT_SKARDYN_SUMMON, TroggDwellerMovePositions[i], false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool _frenzyCasted;
|
||||
};
|
||||
|
||||
|
||||
CreatureAI* GetAI(Creature *creature) const override
|
||||
{
|
||||
return GetGrimBatolAI<boss_general_umbrissAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_umbriss_summon_blitz_trigger : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_umbriss_summon_blitz_trigger() : SpellScriptLoader("spell_umbriss_summon_blitz_trigger") { }
|
||||
|
||||
class spell_umbriss_summon_blitz_trigger_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_umbriss_summon_blitz_trigger_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Trinity::Containers::RandomResize(targets, 1);
|
||||
}
|
||||
|
||||
void HandleSummon(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Creature* umbriss = GetCaster()->ToCreature())
|
||||
umbriss->AI()->Talk(SAY_ANNOUNCE_BLITZ, GetHitUnit());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_umbriss_summon_blitz_trigger_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_umbriss_summon_blitz_trigger_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_umbriss_summon_blitz_trigger_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_umbriss_summon_blitz_trigger_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_umbriss_summon_ground_siege_trigger : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_umbriss_summon_ground_siege_trigger() : SpellScriptLoader("spell_umbriss_summon_ground_siege_trigger") { }
|
||||
|
||||
class spell_umbriss_summon_ground_siege_trigger_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_umbriss_summon_ground_siege_trigger_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Trinity::Containers::RandomResize(targets, 1);
|
||||
}
|
||||
|
||||
void HandleSummon(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_umbriss_summon_ground_siege_trigger_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_umbriss_summon_ground_siege_trigger_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_umbriss_summon_ground_siege_trigger_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_umbriss_bleeding_wound : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_umbriss_bleeding_wound() : SpellScriptLoader("spell_umbriss_bleeding_wound") { }
|
||||
|
||||
class spell_umbriss_bleeding_wound_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_umbriss_bleeding_wound_AuraScript);
|
||||
|
||||
void HandleRemoval(AuraEffect const* aurEff)
|
||||
{
|
||||
if (Unit* owner = GetOwner()->ToUnit())
|
||||
if (owner->GetHealthPct() >= 90.0f)
|
||||
aurEff->GetBase()->Remove();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_umbriss_bleeding_wound_AuraScript::HandleRemoval, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_umbriss_bleeding_wound_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_umbriss_modguds_malice : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_umbriss_modguds_malice() : SpellScriptLoader("spell_umbriss_modguds_malice") { }
|
||||
|
||||
class spell_umbriss_modguds_malice_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_umbriss_modguds_malice_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo(
|
||||
{
|
||||
SPELL_MODGUDS_MALADY,
|
||||
SPELL_MODGUDS_MALICE_SPREAD
|
||||
});
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* owner = GetOwner()->ToUnit())
|
||||
{
|
||||
owner->CastSpell(owner, SPELL_MODGUDS_MALADY, true);
|
||||
owner->CastSpell(owner, SPELL_MODGUDS_MALICE_SPREAD, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectApplyFn(spell_umbriss_modguds_malice_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_umbriss_modguds_malice_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_general_umbriss()
|
||||
{
|
||||
new boss_general_umbriss();
|
||||
new spell_umbriss_summon_blitz_trigger();
|
||||
new spell_umbriss_summon_ground_siege_trigger();
|
||||
new spell_umbriss_bleeding_wound();
|
||||
new spell_umbriss_modguds_malice();
|
||||
}
|
||||
56
src/server/scripts/EasternKingdoms/GrimBatol/grim_batol.h
Normal file
56
src/server/scripts/EasternKingdoms/GrimBatol/grim_batol.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* 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 GRIM_BATOL_H_
|
||||
#define GRIM_BATOL_H_
|
||||
|
||||
#define GBScriptName "instance_grim_batol"
|
||||
#define DataHeader "GB"
|
||||
|
||||
uint32 const EncounterCount = 5;
|
||||
|
||||
enum GBDataTypes
|
||||
{
|
||||
// Encounter States
|
||||
DATA_GENERAL_UMBRISS = 0,
|
||||
DATA_FORGEMASTER_THRONGUS = 1,
|
||||
DATA_DRAHGA_SHADOWBURNER = 2,
|
||||
DATA_ERUDAX = 3
|
||||
};
|
||||
|
||||
enum GBCreatureIds
|
||||
{
|
||||
// Bosses
|
||||
BOSS_GENERAL_UMBRISS = 39625,
|
||||
BOSS_FORGEMASTER_THRONGUS = 40177,
|
||||
BOSS_DRAHGA_SHADOWBURNER = 40319,
|
||||
BOSS_ERUDAX = 40484,
|
||||
|
||||
// General Umbriss encounter
|
||||
NPC_BLITZ_STALKER = 40040,
|
||||
NPC_GROUND_SIEGE_STALKER = 40030,
|
||||
NPC_MALIGNANT_TROGG = 39984,
|
||||
NPC_TROGG_DWELLER = 45467
|
||||
};
|
||||
|
||||
template<class AI>
|
||||
AI* GetGrimBatolAI(Creature* creature)
|
||||
{
|
||||
return GetInstanceAI<AI>(creature, GBScriptName);
|
||||
}
|
||||
|
||||
#endif // GRIM_BATOL_H_
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* 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 "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "grim_batol.h"
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ BOSS_GENERAL_UMBRISS, DATA_GENERAL_UMBRISS },
|
||||
{ BOSS_FORGEMASTER_THRONGUS, DATA_FORGEMASTER_THRONGUS },
|
||||
{ BOSS_DRAHGA_SHADOWBURNER, DATA_DRAHGA_SHADOWBURNER },
|
||||
{ BOSS_ERUDAX, DATA_ERUDAX },
|
||||
{ 0, 0 } // End
|
||||
};
|
||||
|
||||
class instance_grim_batol : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_grim_batol() : InstanceMapScript(GBScriptName, 670) { }
|
||||
|
||||
struct instance_grim_batol_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_grim_batol_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_BLITZ_STALKER:
|
||||
case NPC_GROUND_SIEGE_STALKER:
|
||||
if (Creature* umbriss = GetCreature(DATA_GENERAL_UMBRISS))
|
||||
umbriss->AI()->JustSummoned(creature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData(uint32 data, uint32 value) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_grim_batol_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_grim_batol()
|
||||
{
|
||||
new instance_grim_batol();
|
||||
}
|
||||
@@ -73,6 +73,8 @@ void AddSC_boss_mr_smite();
|
||||
void AddSC_gilneas_c1(); //Gilneas
|
||||
void AddSC_gnomeregan(); //Gnomeregan
|
||||
void AddSC_instance_gnomeregan();
|
||||
void AddSC_instance_grim_batol(); //Grim Batol
|
||||
void AddSC_boss_general_umbriss();
|
||||
void AddSC_boss_attumen(); //Karazhan
|
||||
void AddSC_boss_curator();
|
||||
void AddSC_boss_maiden_of_virtue();
|
||||
@@ -270,6 +272,8 @@ void AddEasternKingdomsScripts()
|
||||
AddSC_gilneas_c1(); //Gilneas
|
||||
AddSC_gnomeregan(); //Gnomeregan
|
||||
AddSC_instance_gnomeregan();
|
||||
AddSC_instance_grim_batol(); //Grim Batol
|
||||
AddSC_boss_general_umbriss();
|
||||
AddSC_boss_attumen(); //Karazhan
|
||||
AddSC_boss_curator();
|
||||
AddSC_boss_maiden_of_virtue();
|
||||
|
||||
Reference in New Issue
Block a user