mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Scripts/Shadowfang Keep: dropped deprecated scripts and updated instance script and definitions to Cataclysm
This commit is contained in:
1
sql/updates/world/master/2023_12_22_06_world.sql
Normal file
1
sql/updates/world/master/2023_12_22_06_world.sql
Normal file
@@ -0,0 +1 @@
|
||||
UPDATE `creature_template` SET `ScriptName`= '' WHERE `ScriptName` IN ('npc_shadowfang_prisoner', 'npc_arugal_voidwalker', 'boss_archmage_arugal');
|
||||
@@ -94,7 +94,7 @@ Position const FryeMovePos = { -196.2483f, 2197.224f, 79.9315f, 0.0f };
|
||||
|
||||
struct boss_apothecary_hummel : public BossAI
|
||||
{
|
||||
boss_apothecary_hummel(Creature* creature) : BossAI(creature, DATA_APOTHECARY_HUMMEL), _deadCount(0), _isDead(false) { }
|
||||
boss_apothecary_hummel(Creature* creature) : BossAI(creature, BOSS_APOTHECARY_HUMMEL), _deadCount(0), _isDead(false) { }
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
|
||||
{
|
||||
@@ -171,7 +171,7 @@ struct boss_apothecary_hummel : public BossAI
|
||||
|
||||
events.Reset();
|
||||
me->SetUninteractible(false);
|
||||
instance->SetBossState(DATA_APOTHECARY_HUMMEL, DONE);
|
||||
instance->SetBossState(BOSS_APOTHECARY_HUMMEL, DONE);
|
||||
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
|
||||
@@ -15,229 +15,50 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Shadowfang_Keep
|
||||
SD%Complete: 90
|
||||
SDComment:
|
||||
SDCategory: Shadowfang Keep
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "shadowfang_keep.h"
|
||||
#include "GameObject.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Log.h"
|
||||
#include "Map.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
#define MAX_ENCOUNTER 4
|
||||
|
||||
enum Yells
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
SAY_BOSS_DIE_AD = 4,
|
||||
SAY_BOSS_DIE_AS = 3,
|
||||
SAY_ARCHMAGE = 0
|
||||
{ NPC_BARON_ASHBURY, BOSS_BARON_ASHBURY },
|
||||
{ NPC_BARON_SILVERLAINE, BOSS_BARON_SILVERLAINE },
|
||||
{ NPC_COMMANDER_SPRINGVALE, BOSS_COMMANDER_SPRINGVALE },
|
||||
{ NPC_LORD_WALDEN, BOSS_LORD_WALDEN },
|
||||
{ NPC_LORD_GODFREY, BOSS_LORD_GODFREY },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
DungeonEncounterData const encounters[] =
|
||||
{
|
||||
NPC_ASH = 3850,
|
||||
NPC_ADA = 3849,
|
||||
NPC_ARCHMAGE_ARUGAL = 4275,
|
||||
NPC_ARUGAL_VOIDWALKER = 4627
|
||||
{ BOSS_BARON_ASHBURY, {{ 1069 }} },
|
||||
{ BOSS_BARON_SILVERLAINE, {{ 1070 }} },
|
||||
{ BOSS_COMMANDER_SPRINGVALE, {{ 1071 }} },
|
||||
{ BOSS_LORD_WALDEN, {{ 1073 }} },
|
||||
{ BOSS_LORD_GODFREY, {{ 1072 }} },
|
||||
{ BOSS_APOTHECARY_HUMMEL, {{ 2879 }} }
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_COURTYARD_DOOR = 18895, //door to open when talking to NPC's
|
||||
GO_SORCERER_DOOR = 18972, //door to open when Fenrus the Devourer
|
||||
GO_ARUGAL_DOOR = 18971 //door to open when Wolf Master Nandos
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ASHCROMBE_TELEPORT = 15742
|
||||
};
|
||||
|
||||
const Position SpawnLocation[] =
|
||||
{
|
||||
{-148.199f, 2165.647f, 128.448f, 1.026f},
|
||||
{-153.110f, 2168.620f, 128.448f, 1.026f},
|
||||
{-145.905f, 2180.520f, 128.448f, 4.183f},
|
||||
{-140.794f, 2178.037f, 128.448f, 4.090f},
|
||||
{-138.640f, 2170.159f, 136.577f, 2.737f}
|
||||
};
|
||||
class instance_shadowfang_keep : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_shadowfang_keep() : InstanceMapScript(SFKScriptName, 33) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_shadowfang_keep_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_shadowfang_keep_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_shadowfang_keep_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTER);
|
||||
|
||||
uiPhase = 0;
|
||||
uiTimer = 0;
|
||||
}
|
||||
|
||||
ObjectGuid uiAshGUID;
|
||||
ObjectGuid uiAdaGUID;
|
||||
ObjectGuid uiArchmageArugalGUID;
|
||||
|
||||
ObjectGuid DoorCourtyardGUID;
|
||||
ObjectGuid DoorSorcererGUID;
|
||||
ObjectGuid DoorArugalGUID;
|
||||
|
||||
uint8 uiPhase;
|
||||
uint16 uiTimer;
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ASH: uiAshGUID = creature->GetGUID(); break;
|
||||
case NPC_ADA: uiAdaGUID = creature->GetGUID(); break;
|
||||
case NPC_ARCHMAGE_ARUGAL: uiArchmageArugalGUID = creature->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_COURTYARD_DOOR:
|
||||
DoorCourtyardGUID = go->GetGUID();
|
||||
if (GetBossState(0) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
break;
|
||||
case GO_SORCERER_DOOR:
|
||||
DoorSorcererGUID = go->GetGUID();
|
||||
if (GetBossState(2) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
break;
|
||||
case GO_ARUGAL_DOOR:
|
||||
DoorArugalGUID = go->GetGUID();
|
||||
if (GetBossState(3) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoSpeech()
|
||||
{
|
||||
Creature* pAda = instance->GetCreature(uiAdaGUID);
|
||||
Creature* pAsh = instance->GetCreature(uiAshGUID);
|
||||
|
||||
if (pAda && pAda->IsAlive() && pAsh && pAsh->IsAlive())
|
||||
{
|
||||
pAda->AI()->Talk(SAY_BOSS_DIE_AD);
|
||||
pAsh->AI()->Talk(SAY_BOSS_DIE_AS);
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_FREE_NPC:
|
||||
if (data == DONE)
|
||||
DoUseDoorOrButton(DoorCourtyardGUID);
|
||||
SetBossState(0, EncounterState(data));
|
||||
break;
|
||||
case TYPE_RETHILGORE:
|
||||
if (data == DONE)
|
||||
DoSpeech();
|
||||
SetBossState(1, EncounterState(data));
|
||||
break;
|
||||
case TYPE_FENRUS:
|
||||
switch (data)
|
||||
{
|
||||
case DONE:
|
||||
uiTimer = 1000;
|
||||
uiPhase = 1;
|
||||
break;
|
||||
case 7:
|
||||
DoUseDoorOrButton(DoorSorcererGUID);
|
||||
break;
|
||||
}
|
||||
SetBossState(2, EncounterState(data));
|
||||
break;
|
||||
case TYPE_NANDOS:
|
||||
if (data == DONE)
|
||||
DoUseDoorOrButton(DoorArugalGUID);
|
||||
SetBossState(3, EncounterState(data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_FREE_NPC:
|
||||
return GetBossState(0);
|
||||
case TYPE_RETHILGORE:
|
||||
return GetBossState(1);
|
||||
case TYPE_FENRUS:
|
||||
return GetBossState(2);
|
||||
case TYPE_NANDOS:
|
||||
return GetBossState(3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update(uint32 uiDiff) override
|
||||
{
|
||||
if (GetData(TYPE_FENRUS) != DONE)
|
||||
return;
|
||||
|
||||
Creature* pArchmage = instance->GetCreature(uiArchmageArugalGUID);
|
||||
|
||||
if (!pArchmage || !pArchmage->IsAlive())
|
||||
return;
|
||||
|
||||
if (uiPhase)
|
||||
{
|
||||
if (uiTimer <= uiDiff)
|
||||
{
|
||||
switch (uiPhase)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Creature* summon = pArchmage->SummonCreature(pArchmage->GetEntry(), SpawnLocation[4], TEMPSUMMON_TIMED_DESPAWN, 10s);
|
||||
summon->SetImmuneToPC(true);
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
summon->CastSpell(summon, SPELL_ASHCROMBE_TELEPORT, true);
|
||||
summon->AI()->Talk(SAY_ARCHMAGE);
|
||||
uiTimer = 2000;
|
||||
uiPhase = 2;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1min);
|
||||
pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1min);
|
||||
pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1min);
|
||||
pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1min);
|
||||
uiPhase = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
} else uiTimer -= uiDiff;
|
||||
}
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
LoadDungeonEncounterData(encounters);
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_shadowfang_keep_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_shadowfang_keep()
|
||||
|
||||
@@ -15,354 +15,39 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Shadowfang_Keep
|
||||
SD%Complete: 75
|
||||
SDComment: npc_shadowfang_prisoner using escortAI for movement to door. Might need additional code in case being attacked. Add proper texts/say().
|
||||
SDCategory: Shadowfang Keep
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_shadowfang_prisoner
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "shadowfang_keep.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
/*######
|
||||
## npc_shadowfang_prisoner
|
||||
######*/
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_FREE_AS = 0,
|
||||
SAY_OPEN_DOOR_AS = 1,
|
||||
SAY_POST_DOOR_AS = 2,
|
||||
SAY_FREE_AD = 0,
|
||||
SAY_OPEN_DOOR_AD = 1,
|
||||
SAY_POST1_DOOR_AD = 2,
|
||||
SAY_POST2_DOOR_AD = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_UNLOCK = 6421,
|
||||
SPELL_DARK_OFFERING = 7154
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_ASH = 3850
|
||||
};
|
||||
|
||||
class npc_shadowfang_prisoner : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_shadowfang_prisoner() : CreatureScript("npc_shadowfang_prisoner") { }
|
||||
|
||||
struct npc_shadowfang_prisonerAI : public EscortAI
|
||||
{
|
||||
npc_shadowfang_prisonerAI(Creature* creature) : EscortAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
if (me->GetEntry() == NPC_ASH)
|
||||
Talk(SAY_FREE_AS, player);
|
||||
else
|
||||
Talk(SAY_FREE_AD, player);
|
||||
break;
|
||||
case 10:
|
||||
if (me->GetEntry() == NPC_ASH)
|
||||
Talk(SAY_OPEN_DOOR_AS, player);
|
||||
else
|
||||
Talk(SAY_OPEN_DOOR_AD, player);
|
||||
break;
|
||||
case 11:
|
||||
if (me->GetEntry() == NPC_ASH)
|
||||
DoCast(me, SPELL_UNLOCK);
|
||||
break;
|
||||
case 12:
|
||||
if (me->GetEntry() == NPC_ASH)
|
||||
Talk(SAY_POST_DOOR_AS, player);
|
||||
else
|
||||
Talk(SAY_POST1_DOOR_AD, player);
|
||||
|
||||
instance->SetData(TYPE_FREE_NPC, DONE);
|
||||
break;
|
||||
case 13:
|
||||
if (me->GetEntry() != NPC_ASH)
|
||||
Talk(SAY_POST2_DOOR_AD, player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override { }
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
{
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
LoadPath((me->GetEntry() << 3) | 2);
|
||||
Start(false, player->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
uint32 gossipMenuId = player->GetGossipMenuForSource(me);
|
||||
InitGossipMenuFor(player, gossipMenuId);
|
||||
if (instance->GetData(TYPE_FREE_NPC) != DONE && instance->GetData(TYPE_RETHILGORE) == DONE)
|
||||
AddGossipItemFor(player, gossipMenuId, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetShadowfangKeepAI<npc_shadowfang_prisonerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_arugal_voidwalker : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_arugal_voidwalker() : CreatureScript("npc_arugal_voidwalker") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetShadowfangKeepAI<npc_arugal_voidwalkerAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_arugal_voidwalkerAI : public ScriptedAI
|
||||
{
|
||||
npc_arugal_voidwalkerAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiDarkOffering = urand(200, 1000);
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 uiDarkOffering;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 uiDiff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiDarkOffering <= uiDiff)
|
||||
{
|
||||
if (Creature* pFriend = me->FindNearestCreature(me->GetEntry(), 25.0f, true))
|
||||
DoCast(pFriend, SPELL_DARK_OFFERING);
|
||||
else
|
||||
DoCast(me, SPELL_DARK_OFFERING);
|
||||
uiDarkOffering = urand(4400, 12500);
|
||||
} else uiDarkOffering -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SetData(TYPE_FENRUS, instance->GetData(TYPE_FENRUS) + 1);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
enum ArugalSpells
|
||||
{
|
||||
SPELL_TELE_UPPER = 7587,
|
||||
SPELL_TELE_SPAWN = 7586,
|
||||
SPELL_TELE_STAIRS = 7136,
|
||||
NUM_TELEPORT_SPELLS = 3,
|
||||
SPELL_ARUGAL_CURSE = 7621,
|
||||
SPELL_THUNDERSHOCK = 7803,
|
||||
SPELL_VOIDBOLT = 7588
|
||||
};
|
||||
|
||||
enum ArugalTexts
|
||||
{
|
||||
SAY_AGGRO = 1, // You, too, shall serve!
|
||||
SAY_TRANSFORM = 2, // Release your rage!
|
||||
SAY_SLAY = 3 // Another falls!
|
||||
};
|
||||
|
||||
enum ArugalEvents
|
||||
{
|
||||
EVENT_VOID_BOLT = 1,
|
||||
EVENT_TELEPORT,
|
||||
EVENT_THUNDERSHOCK,
|
||||
EVENT_CURSE
|
||||
};
|
||||
|
||||
class boss_archmage_arugal : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_archmage_arugal() : CreatureScript("boss_archmage_arugal") { }
|
||||
|
||||
struct boss_archmage_arugalAI : public BossAI
|
||||
{
|
||||
boss_archmage_arugalAI(Creature* creature) : BossAI(creature, BOSS_ARUGAL) { }
|
||||
|
||||
uint32 teleportSpells[NUM_TELEPORT_SPELLS] =
|
||||
{
|
||||
SPELL_TELE_SPAWN,
|
||||
SPELL_TELE_UPPER,
|
||||
SPELL_TELE_STAIRS
|
||||
};
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void SpellHitTarget(WorldObject* /*target*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_ARUGAL_CURSE)
|
||||
Talk(SAY_TRANSFORM);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_CURSE, 7s);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 15s);
|
||||
events.ScheduleEvent(EVENT_VOID_BOLT, 1s);
|
||||
events.ScheduleEvent(EVENT_THUNDERSHOCK, 10s);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
AttackStartCaster(who, 100.0f); // void bolt range is 100.f
|
||||
}
|
||||
|
||||
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_CURSE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 30.0f, true))
|
||||
DoCast(target, SPELL_ARUGAL_CURSE);
|
||||
events.Repeat(Seconds(15));
|
||||
break;
|
||||
case EVENT_TELEPORT:
|
||||
{
|
||||
// ensure we never cast the same teleport twice in a row
|
||||
uint8 spellIndex = urand(1, NUM_TELEPORT_SPELLS-1);
|
||||
std::swap(teleportSpells[0], teleportSpells[spellIndex]);
|
||||
DoCast(teleportSpells[0]);
|
||||
events.Repeat(Seconds(20));
|
||||
break;
|
||||
}
|
||||
case EVENT_THUNDERSHOCK:
|
||||
DoCastAOE(SPELL_THUNDERSHOCK);
|
||||
events.Repeat(Seconds(30));
|
||||
break;
|
||||
case EVENT_VOID_BOLT:
|
||||
DoCastVictim(SPELL_VOIDBOLT);
|
||||
events.Repeat(Seconds(5));
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetShadowfangKeepAI<boss_archmage_arugalAI>(creature);
|
||||
}
|
||||
};
|
||||
#include "Unit.h"
|
||||
|
||||
// 7057 - Haunting Spirits
|
||||
class spell_shadowfang_keep_haunting_spirits : public SpellScriptLoader
|
||||
class spell_shadowfang_keep_haunting_spirits : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_shadowfang_keep_haunting_spirits() : SpellScriptLoader("spell_shadowfang_keep_haunting_spirits") { }
|
||||
void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude)
|
||||
{
|
||||
isPeriodic = true;
|
||||
amplitude = (irand(0, 60) + 30) * IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
class spell_shadowfang_keep_haunting_spirits_AuraScript : public AuraScript
|
||||
{
|
||||
void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude)
|
||||
{
|
||||
isPeriodic = true;
|
||||
amplitude = (irand(0, 60) + 30) * IN_MILLISECONDS;
|
||||
}
|
||||
void HandleDummyTick(AuraEffect const* aurEff)
|
||||
{
|
||||
GetTarget()->CastSpell(nullptr, aurEff->GetAmount(), true);
|
||||
}
|
||||
|
||||
void HandleDummyTick(AuraEffect const* aurEff)
|
||||
{
|
||||
GetTarget()->CastSpell(nullptr, aurEff->GetAmount(), true);
|
||||
}
|
||||
void HandleUpdatePeriodic(AuraEffect* aurEff)
|
||||
{
|
||||
aurEff->CalculatePeriodic(GetCaster());
|
||||
}
|
||||
|
||||
void HandleUpdatePeriodic(AuraEffect* aurEff)
|
||||
{
|
||||
aurEff->CalculatePeriodic(GetCaster());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_shadowfang_keep_haunting_spirits_AuraScript();
|
||||
}
|
||||
void Register() override
|
||||
{
|
||||
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_shadowfang_keep_haunting_spirits::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadowfang_keep_haunting_spirits::HandleDummyTick, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_shadowfang_keep_haunting_spirits::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_shadowfang_keep()
|
||||
{
|
||||
new npc_shadowfang_prisoner();
|
||||
new npc_arugal_voidwalker();
|
||||
new boss_archmage_arugal();
|
||||
new spell_shadowfang_keep_haunting_spirits();
|
||||
RegisterSpellScript(spell_shadowfang_keep_haunting_spirits);
|
||||
}
|
||||
|
||||
@@ -15,22 +15,35 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_SHADOWFANG_H
|
||||
#define DEF_SHADOWFANG_H
|
||||
#ifndef _Shadownfang_Keep_h__
|
||||
#define _Shadownfang_Keep_h__
|
||||
|
||||
#include "CreatureAIImpl.h"
|
||||
|
||||
#define SFKScriptName "instance_shadowfang_keep"
|
||||
#define DataHeader "SK"
|
||||
constexpr char const* SFKScriptName = "instance_shadowfang_keep";
|
||||
constexpr char const* DataHeader = "SFK";
|
||||
|
||||
enum SKDataTypes
|
||||
constexpr uint32 const EncounterCount = 6;
|
||||
|
||||
enum SFKDataTypes
|
||||
{
|
||||
TYPE_FREE_NPC = 1,
|
||||
TYPE_RETHILGORE = 2,
|
||||
TYPE_FENRUS = 3,
|
||||
TYPE_NANDOS = 4,
|
||||
BOSS_ARUGAL = 5,
|
||||
DATA_APOTHECARY_HUMMEL = 6
|
||||
// Encounters
|
||||
BOSS_BARON_ASHBURY = 0,
|
||||
BOSS_BARON_SILVERLAINE = 1,
|
||||
BOSS_COMMANDER_SPRINGVALE = 2,
|
||||
BOSS_LORD_WALDEN = 3,
|
||||
BOSS_LORD_GODFREY = 4,
|
||||
BOSS_APOTHECARY_HUMMEL = 5
|
||||
};
|
||||
|
||||
enum SFKCreatureIds
|
||||
{
|
||||
// Bosses
|
||||
NPC_BARON_ASHBURY = 46962,
|
||||
NPC_BARON_SILVERLAINE = 3887,
|
||||
NPC_COMMANDER_SPRINGVALE = 4278,
|
||||
NPC_LORD_WALDEN = 46963,
|
||||
NPC_LORD_GODFREY = 46964
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
@@ -41,4 +54,4 @@ inline AI* GetShadowfangKeepAI(T* obj)
|
||||
|
||||
#define RegisterShadowfangKeepCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetShadowfangKeepAI)
|
||||
|
||||
#endif
|
||||
#endif // _Shadownfang_Keep_h__
|
||||
|
||||
Reference in New Issue
Block a user