mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 18:40:28 +00:00
410 lines
14 KiB
C++
410 lines
14 KiB
C++
|
|
#include "ScriptMgr.h"
|
|
#include "InstanceScript.h"
|
|
#include "karazhan.h"
|
|
|
|
const Position OptionalSpawn[] =
|
|
{
|
|
{ -10960.981445f, -1940.138428f, 46.178097f, 4.12f }, // Hyakiss the Lurker
|
|
{ -10945.769531f, -2040.153320f, 49.474438f, 0.077f }, // Shadikith the Glider
|
|
{ -10899.903320f, -2085.573730f, 49.474449f, 1.38f } // Rokad the Ravager
|
|
};
|
|
|
|
class instance_karazhan : public InstanceMapScript
|
|
{
|
|
public:
|
|
instance_karazhan() : InstanceMapScript("instance_karazhan", 532) { }
|
|
|
|
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
|
{
|
|
return new instance_karazhan_InstanceMapScript(map);
|
|
}
|
|
|
|
struct instance_karazhan_InstanceMapScript : public InstanceScript
|
|
{
|
|
instance_karazhan_InstanceMapScript(Map* map) : InstanceScript(map)
|
|
{
|
|
SetBossNumber(EncounterCount);
|
|
|
|
// 1 - OZ, 2 - HOOD, 3 - RAJ, this never gets altered.
|
|
OperaEvent = urand(EVENT_OZ, EVENT_RAJ);
|
|
OzDeathCount = 0;
|
|
OptionalBossCount = 0;
|
|
}
|
|
|
|
void OnCreatureCreate(Creature* creature) override
|
|
{
|
|
switch (creature->GetEntry())
|
|
{
|
|
case NPC_KILREK:
|
|
m_uiKilrekGUID = creature->GetGUID();
|
|
break;
|
|
case NPC_TERESTIAN_ILLHOOF:
|
|
m_uiTerestianGUID = creature->GetGUID();
|
|
break;
|
|
case NPC_MOROES:
|
|
m_uiMoroesGUID = creature->GetGUID();
|
|
break;
|
|
case NPC_NIGHTBANE:
|
|
m_uiNightBaneGUID = creature->GetGUID();
|
|
case NPC_RELAY:
|
|
m_uiRelayGUID = creature->GetGUID();
|
|
}
|
|
}
|
|
|
|
void OnUnitDeath(Unit* unit) override
|
|
{
|
|
Creature* creature = unit->ToCreature();
|
|
if (!creature)
|
|
return;
|
|
|
|
switch (creature->GetEntry())
|
|
{
|
|
case NPC_COLDMIST_WIDOW:
|
|
case NPC_COLDMIST_STALKER:
|
|
case NPC_SHADOWBAT:
|
|
case NPC_VAMPIRIC_SHADOWBAT:
|
|
case NPC_GREATER_SHADOWBAT:
|
|
case NPC_PHASE_HOUND:
|
|
case NPC_DREADBEAST:
|
|
case NPC_SHADOWBEAST:
|
|
if (GetBossState(DATA_OPTIONAL_BOSS) == TO_BE_DECIDED)
|
|
{
|
|
++OptionalBossCount;
|
|
if (OptionalBossCount == OPTIONAL_BOSS_REQUIRED_DEATH_COUNT)
|
|
{
|
|
switch (urand(NPC_HYAKISS_THE_LURKER, NPC_ROKAD_THE_RAVAGER))
|
|
{
|
|
case NPC_HYAKISS_THE_LURKER:
|
|
instance->SummonCreature(NPC_HYAKISS_THE_LURKER, OptionalSpawn[0]);
|
|
break;
|
|
case NPC_SHADIKITH_THE_GLIDER:
|
|
instance->SummonCreature(NPC_SHADIKITH_THE_GLIDER, OptionalSpawn[1]);
|
|
break;
|
|
case NPC_ROKAD_THE_RAVAGER:
|
|
instance->SummonCreature(NPC_ROKAD_THE_RAVAGER, OptionalSpawn[2]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SetData(uint32 type, uint32 data) override
|
|
{
|
|
switch (type)
|
|
{
|
|
case DATA_OPERA_OZ_DEATHCOUNT:
|
|
if (data == SPECIAL)
|
|
++OzDeathCount;
|
|
else if (data == IN_PROGRESS)
|
|
OzDeathCount = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool SetBossState(uint32 type, EncounterState state) override
|
|
{
|
|
if (!InstanceScript::SetBossState(type, state))
|
|
return false;
|
|
|
|
switch (type)
|
|
{
|
|
case DATA_OPERA_PERFORMANCE:
|
|
if (state == DONE)
|
|
{
|
|
HandleGameObject(m_uiStageDoorLeftGUID, true);
|
|
HandleGameObject(m_uiStageDoorRightGUID, true);
|
|
if (GameObject* sideEntrance = instance->GetGameObject(m_uiSideEntranceDoor))
|
|
sideEntrance->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
|
|
}
|
|
break;
|
|
case DATA_CHESS:
|
|
if (state == DONE)
|
|
DoRespawnGameObject(DustCoveredChest, DAY);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void OnGameObjectCreate(GameObject* go) override
|
|
{
|
|
switch (go->GetEntry())
|
|
{
|
|
case GO_STAGE_CURTAIN:
|
|
m_uiCurtainGUID = go->GetGUID();
|
|
break;
|
|
case GO_STAGE_DOOR_LEFT:
|
|
m_uiStageDoorLeftGUID = go->GetGUID();
|
|
if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE)
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
break;
|
|
case GO_STAGE_DOOR_RIGHT:
|
|
m_uiStageDoorRightGUID = go->GetGUID();
|
|
if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE)
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
break;
|
|
case GO_PRIVATE_LIBRARY_DOOR:
|
|
m_uiLibraryDoor = go->GetGUID();
|
|
break;
|
|
case GO_MASSIVE_DOOR:
|
|
m_uiMassiveDoor = go->GetGUID();
|
|
if (GetBossState(DATA_ARAN) == !IN_PROGRESS)
|
|
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
else
|
|
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
break;
|
|
case GO_GAMESMAN_HALL_DOOR:
|
|
m_uiGamesmansDoor = go->GetGUID();
|
|
break;
|
|
case GO_GAMESMAN_HALL_EXIT_DOOR:
|
|
m_uiGamesmansExitDoor = go->GetGUID();
|
|
break;
|
|
case GO_NETHERSPACE_DOOR:
|
|
m_uiNetherspaceDoor = go->GetGUID();
|
|
if (GetBossState(DATA_PRINCE) == !IN_PROGRESS)
|
|
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
else
|
|
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
break;
|
|
case GO_MASTERS_TERRACE_DOOR:
|
|
MastersTerraceDoor[0] = go->GetGUID();
|
|
break;
|
|
case GO_MASTERS_TERRACE_DOOR2:
|
|
MastersTerraceDoor[1] = go->GetGUID();
|
|
break;
|
|
case GO_SIDE_ENTRANCE_DOOR:
|
|
m_uiSideEntranceDoor = go->GetGUID();
|
|
if (GetBossState(DATA_OPERA_PERFORMANCE) == DONE)
|
|
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
else
|
|
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
|
break;
|
|
case GO_DUST_COVERED_CHEST:
|
|
DustCoveredChest = go->GetGUID();
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
switch (OperaEvent)
|
|
{
|
|
/// @todo Set Object visibilities for Opera based on performance
|
|
case EVENT_OZ:
|
|
break;
|
|
|
|
case EVENT_HOOD:
|
|
break;
|
|
|
|
case EVENT_RAJ:
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint32 GetData(uint32 type) const override
|
|
{
|
|
switch (type)
|
|
{
|
|
case DATA_OPERA_PERFORMANCE:
|
|
return OperaEvent;
|
|
case DATA_OPERA_OZ_DEATHCOUNT:
|
|
return OzDeathCount;
|
|
|
|
case DATA_KILREK:
|
|
return m_uiKilrekGUID;
|
|
case DATA_TERESTIAN:
|
|
return m_uiTerestianGUID;
|
|
case DATA_MOROES:
|
|
return m_uiMoroesGUID;
|
|
case DATA_GO_STAGEDOORLEFT:
|
|
return m_uiStageDoorLeftGUID;
|
|
case DATA_GO_STAGEDOORRIGHT:
|
|
return m_uiStageDoorRightGUID;
|
|
case DATA_GO_CURTAINS:
|
|
return m_uiCurtainGUID;
|
|
case DATA_GO_LIBRARY_DOOR:
|
|
return m_uiLibraryDoor;
|
|
case DATA_GO_MASSIVE_DOOR:
|
|
return m_uiMassiveDoor;
|
|
case DATA_GO_SIDE_ENTRANCE_DOOR:
|
|
return m_uiSideEntranceDoor;
|
|
case DATA_GO_GAME_DOOR:
|
|
return m_uiGamesmansDoor;
|
|
case DATA_GO_GAME_EXIT_DOOR:
|
|
return m_uiGamesmansExitDoor;
|
|
case DATA_GO_NETHER_DOOR:
|
|
return m_uiNetherspaceDoor;
|
|
case DATA_MASTERS_TERRACE_DOOR_1:
|
|
return MastersTerraceDoor[0];
|
|
case DATA_MASTERS_TERRACE_DOOR_2:
|
|
return MastersTerraceDoor[1];
|
|
case DATA_IMAGE_OF_MEDIVH:
|
|
return ImageGUID;
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
uint64 GetData64(uint32 data) const
|
|
{
|
|
switch (data)
|
|
{
|
|
case DATA_KILREK: return m_uiKilrekGUID;
|
|
case DATA_TERESTIAN: return m_uiTerestianGUID;
|
|
case DATA_MOROES: return m_uiMoroesGUID;
|
|
case DATA_GO_STAGEDOORLEFT: return m_uiStageDoorLeftGUID;
|
|
case DATA_GO_STAGEDOORRIGHT: return m_uiStageDoorRightGUID;
|
|
case DATA_GO_CURTAINS: return m_uiCurtainGUID;
|
|
case DATA_GO_LIBRARY_DOOR: return m_uiLibraryDoor;
|
|
case DATA_GO_MASSIVE_DOOR: return m_uiMassiveDoor;
|
|
case DATA_GO_SIDE_ENTRANCE_DOOR: return m_uiSideEntranceDoor;
|
|
case DATA_GO_GAME_DOOR: return m_uiGamesmansDoor;
|
|
case DATA_GO_GAME_EXIT_DOOR: return m_uiGamesmansExitDoor;
|
|
case DATA_GO_NETHER_DOOR: return m_uiNetherspaceDoor;
|
|
case DATA_MASTERS_TERRACE_DOOR_1: return MastersTerraceDoor[0];
|
|
case DATA_MASTERS_TERRACE_DOOR_2: return MastersTerraceDoor[1];
|
|
case DATA_IMAGE_OF_MEDIVH: return ImageGUID;
|
|
case DATA_NIGHTBANE: return m_uiNightBaneGUID;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private:
|
|
uint32 OperaEvent;
|
|
uint32 OzDeathCount;
|
|
uint32 OptionalBossCount;
|
|
uint32 m_auiEncounter[MAX_ENCOUNTERS];
|
|
uint32 m_uiTeam;
|
|
uint64 m_uiCurtainGUID;
|
|
uint64 m_uiStageDoorLeftGUID;
|
|
uint64 m_uiStageDoorRightGUID;
|
|
uint64 m_uiKilrekGUID;
|
|
uint64 m_uiTerestianGUID;
|
|
uint64 m_uiMoroesGUID;
|
|
uint64 m_uiNightBaneGUID;
|
|
uint64 EchoOfMedivhGUID;
|
|
uint64 m_uiLibraryDoor; // Door at Shade of Aran
|
|
uint64 m_uiMassiveDoor; // Door at Netherspite
|
|
uint64 m_uiSideEntranceDoor; // Side Entrance
|
|
uint64 m_uiGamesmansDoor; // Door before Chess
|
|
uint64 m_uiGamesmansExitDoor; // Door after Chess
|
|
uint64 m_uiNetherspaceDoor; // Door at Malchezaar
|
|
uint64 m_uiServantsAccessDoor; // Door to Brocken Stair
|
|
uint64 MastersTerraceDoor[2];
|
|
uint64 ImageGUID;
|
|
uint64 DustCoveredChest;
|
|
uint64 m_uiRelayGUID;
|
|
};
|
|
};
|
|
|
|
class spell_karazhan_brittle_bones : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_karazhan_brittle_bones() : SpellScriptLoader("spell_karazhan_brittle_bones") { }
|
|
|
|
class spell_karazhan_brittle_bones_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_karazhan_brittle_bones_AuraScript);
|
|
|
|
void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude)
|
|
{
|
|
isPeriodic = true;
|
|
amplitude = 5000;
|
|
}
|
|
|
|
void Update(AuraEffect const* effect)
|
|
{
|
|
PreventDefaultAction();
|
|
if (roll_chance_i(35))
|
|
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_RATTLED, true);
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_karazhan_brittle_bones_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_karazhan_brittle_bones_AuraScript::Update, EFFECT_0, SPELL_AURA_DUMMY);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const
|
|
{
|
|
return new spell_karazhan_brittle_bones_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_karazhan_overload : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_karazhan_overload() : SpellScriptLoader("spell_karazhan_overload") { }
|
|
|
|
class spell_karazhan_overload_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_karazhan_overload_AuraScript);
|
|
|
|
void PeriodicTick(AuraEffect const* auraEffect)
|
|
{
|
|
PreventDefaultAction();
|
|
GetUnitOwner()->CastCustomSpell(SPELL_OVERLOAD, SPELLVALUE_BASE_POINT0, int32(auraEffect->GetAmount() * (2.0, auraEffect->GetTickNumber())), GetUnitOwner(), true);
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_karazhan_overload_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const
|
|
{
|
|
return new spell_karazhan_overload_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_karazhan_blink : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_karazhan_blink() : SpellScriptLoader("spell_karazhan_blink") { }
|
|
|
|
class spell_karazhan_blink_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_karazhan_blink_SpellScript);
|
|
|
|
void HandleDummy(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
GetCaster()->getThreatManager().resetAllAggro();
|
|
if (Unit* target = GetHitUnit())
|
|
GetCaster()->CastSpell(target, SPELL_BLINK, true);
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_karazhan_blink_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const
|
|
{
|
|
return new spell_karazhan_blink_SpellScript();
|
|
}
|
|
};
|
|
|
|
|
|
void AddSC_instance_karazhan()
|
|
{
|
|
new instance_karazhan();
|
|
new spell_karazhan_brittle_bones();
|
|
new spell_karazhan_overload();
|
|
new spell_karazhan_blink();
|
|
}
|