fix(Scripts/Scholomance): Grandmaster Gandling correctly drops threat if teleports the tank (#8455)
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1633884280859489900');
|
||||||
|
|
||||||
|
-- gandling
|
||||||
|
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_darkmaster_gandling' WHERE `entry` = 1853;
|
||||||
|
|
||||||
|
-- risen guardians
|
||||||
|
UPDATE `creature_template` SET `AIName` = '' , `ScriptName` = 'npc_risen_guardian' WHERE `entry` = 11598;
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` = 11598 AND `source_type` = 0;
|
||||||
|
|
||||||
|
-- gates
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (177371, 177372, 177373, 177375, 177376, 177377) AND `source_type` = 1;
|
||||||
|
UPDATE `gameobject_template` SET `AIName` = '' WHERE `entry` IN (177371, 177372, 177373, 177375, 177376, 177377);
|
||||||
|
|
||||||
|
-- portal spells
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_scholomance_shadow_portal', 'spell_scholomance_shadow_portal_rooms');
|
||||||
@@ -0,0 +1,417 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 3 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 Affero 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 "scholomance.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
|
#include "ScriptMgr.h"
|
||||||
|
#include "SpellScript.h"
|
||||||
|
#include "Map.h"
|
||||||
|
#include "Player.h"
|
||||||
|
|
||||||
|
enum Spells
|
||||||
|
{
|
||||||
|
SPELL_ARCANE_MISSILES = 15790,
|
||||||
|
SPELL_CURSE_DARKMASTER = 18702,
|
||||||
|
SPELL_SHADOW_SHIELD = 12040,
|
||||||
|
SPELL_SHADOW_PORTAL = 17950
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BossData
|
||||||
|
{
|
||||||
|
DATA_PLAYER_KILLED,
|
||||||
|
GANDLING_ROOM_TO_USE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Timers
|
||||||
|
{
|
||||||
|
TIMER_ARCANE_MIN = 8000,
|
||||||
|
TIMER_ARCANE_MAX = 14000,
|
||||||
|
TIMER_CURSE_MIN = 20000,
|
||||||
|
TIMER_CURSE_MAX = 30000,
|
||||||
|
TIMER_SHIELD_MIN = 30000,
|
||||||
|
TIMER_SHIELD_MAX = 40000,
|
||||||
|
TIMER_PORTAL = 25000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IdPortalSpells
|
||||||
|
{
|
||||||
|
SPELL_SHADOW_PORTAL_UP_NORTH = 17863,
|
||||||
|
SPELL_SHADOW_PORTAL_UP_EAST = 17939,
|
||||||
|
SPELL_SHADOW_PORTAL_UP_SOUTH = 17943,
|
||||||
|
SPELL_SHADOW_PORTAL_DOWN_NORTH = 17944,
|
||||||
|
SPELL_SHADOW_PORTAL_DOWN_EAST = 17946,
|
||||||
|
SPELL_SHADOW_PORTAL_DOWN_SOUTH = 17948
|
||||||
|
};
|
||||||
|
|
||||||
|
// don't change the order of these 3 arrays. The order of the arrays should match and match also with scholomance.cpp
|
||||||
|
const uint32 GandlingGateIds[] = {GO_GATE_GANDLING_DOWN_NORTH, GO_GATE_GANDLING_DOWN_EAST, GO_GATE_GANDLING_DOWN_SOUTH,
|
||||||
|
GO_GATE_GANDLING_UP_NORTH, GO_GATE_GANDLING_UP_EAST, GO_GATE_GANDLING_UP_SOUTH, GO_GATE_GANDLING_ENTRANCE};
|
||||||
|
|
||||||
|
const uint32 GandlingPortalSpells[] = {SPELL_SHADOW_PORTAL_DOWN_NORTH, SPELL_SHADOW_PORTAL_DOWN_EAST, SPELL_SHADOW_PORTAL_DOWN_SOUTH,
|
||||||
|
SPELL_SHADOW_PORTAL_UP_NORTH, SPELL_SHADOW_PORTAL_UP_EAST, SPELL_SHADOW_PORTAL_UP_SOUTH};
|
||||||
|
|
||||||
|
Position const SummonPos[3 * 6] =
|
||||||
|
{
|
||||||
|
// The Shadow Vault // down north
|
||||||
|
{ 245.3716f, 0.628038f, 72.73877f, 0.01745329f },
|
||||||
|
{ 240.9920f, 3.405653f, 72.73877f, 6.143559f },
|
||||||
|
{ 240.9543f, -3.182943f, 72.73877f, 0.2268928f },
|
||||||
|
// Barov Family Vault // down east
|
||||||
|
{ 181.8245f, -42.58117f, 75.4812f, 4.660029f },
|
||||||
|
{ 177.7456f, -42.74745f, 75.4812f, 4.886922f },
|
||||||
|
{ 185.6157f, -42.91200f, 75.4812f, 4.45059f },
|
||||||
|
// Vault of the Ravenian // down south
|
||||||
|
{ 136.362f, 6.221f, 75.40f, 3.14f },
|
||||||
|
{ 130.79f, -0.91f, 75.40f, 3.14f },
|
||||||
|
{ 136.362f, -8.221f, 75.40f, 3.14f },
|
||||||
|
// Hall of Secrets // up north
|
||||||
|
{230.80f, 0.138f, 85.23f, 0.0f},
|
||||||
|
{241.23f, -6.979f, 85.23f, 0.0f},
|
||||||
|
{246.65f, 4.227f, 84.85f, 0.0f},
|
||||||
|
// The Hall of the damned // up east
|
||||||
|
{177.9624f, -68.23893f, 84.95197f, 3.228859f},
|
||||||
|
{183.7705f, -61.43489f, 84.92424f, 5.148721f},
|
||||||
|
{184.7035f, -77.74805f, 84.92424f, 4.660029f},
|
||||||
|
// The Coven // up south
|
||||||
|
{111.7203f, -1.105035f, 85.45985f, 3.961897f},
|
||||||
|
{118.0079f, 6.430664f, 85.31169f, 2.408554f},
|
||||||
|
{120.0276f, -7.496636f, 85.31169f, 2.984513f}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DoorState
|
||||||
|
{
|
||||||
|
OPEN = true,
|
||||||
|
CLOSED = false
|
||||||
|
};
|
||||||
|
|
||||||
|
class boss_darkmaster_gandling : public CreatureScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
boss_darkmaster_gandling() : CreatureScript("boss_darkmaster_gandling") {}
|
||||||
|
|
||||||
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
{
|
||||||
|
return GetScholomanceAI<boss_darkmaster_gandlingAI>(creature);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct boss_darkmaster_gandlingAI : public BossAI
|
||||||
|
{
|
||||||
|
boss_darkmaster_gandlingAI(Creature* creature) : BossAI(creature, DATA_DARKMASTER_GANDLING), summons(me) { }
|
||||||
|
|
||||||
|
SummonList summons;
|
||||||
|
Creature* Guardians[6][3]; // 6 rooms, 3 mobs, access through GuardiansList[NORTH+EAST][1]
|
||||||
|
uint32 current_room;
|
||||||
|
|
||||||
|
// Only the 6 gates that gandling plays with.
|
||||||
|
void SetGate(uint8 gate, bool open)
|
||||||
|
{
|
||||||
|
if (gate < 6)
|
||||||
|
{
|
||||||
|
instance->HandleGameObject(instance->GetGuidData(GandlingGateIds[gate]), open);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// opens gates directly closed by me. Not the entrance
|
||||||
|
void OpenAllGates()
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
SetGate(i, OPEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SummonedCreatureDespawn(Creature* cr) override
|
||||||
|
{
|
||||||
|
int room = -1;
|
||||||
|
// remove the mob from the list and keep track of which room he is in.
|
||||||
|
for (uint8 i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
for (uint8 j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
if (Guardians[i][j] && Guardians[i][j]->GetGUID() == cr->GetGUID())
|
||||||
|
{
|
||||||
|
room = i;
|
||||||
|
Guardians[i][j] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the room is now empty
|
||||||
|
if (room >= 0)
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (Guardians[room][i])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// everybody is dead in there, we can open the gate.
|
||||||
|
SetGate(room, OPEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add mob to the room of the last portal, that's the only place we can have added mobs.
|
||||||
|
void JustSummoned(Creature* cr) override
|
||||||
|
{
|
||||||
|
summons.Summon(cr);
|
||||||
|
uint32 room = GetData(GANDLING_ROOM_TO_USE);
|
||||||
|
if (room < 6)
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (Guardians[room][i] == nullptr)
|
||||||
|
{
|
||||||
|
Guardians[room][i] = cr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnterCombat(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
DoZoneInCombat();
|
||||||
|
instance->SetData(DATA_DARKMASTER_GANDLING, IN_PROGRESS);
|
||||||
|
events.Reset();
|
||||||
|
events.ScheduleEvent(SPELL_ARCANE_MISSILES, TIMER_ARCANE_MIN);
|
||||||
|
events.ScheduleEvent(SPELL_CURSE_DARKMASTER, TIMER_CURSE_MIN);
|
||||||
|
events.ScheduleEvent(SPELL_SHADOW_SHIELD, TIMER_SHIELD_MIN);
|
||||||
|
events.ScheduleEvent(SPELL_SHADOW_PORTAL, TIMER_PORTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* /*killer*/) override
|
||||||
|
{
|
||||||
|
instance->SetData(DATA_DARKMASTER_GANDLING, DONE);
|
||||||
|
OpenAllGates();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetData(uint32 type, uint32 data) override
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DATA_PLAYER_KILLED:
|
||||||
|
if (data < 6)
|
||||||
|
{
|
||||||
|
SetGate(data, OPEN);
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (Guardians[data][i])
|
||||||
|
{
|
||||||
|
Guardians[data][i]->SetInCombatWithZone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GANDLING_ROOM_TO_USE:
|
||||||
|
if (data < 6)
|
||||||
|
{
|
||||||
|
current_room = data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetData(uint32 type) const override
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GANDLING_ROOM_TO_USE:
|
||||||
|
return current_room;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
_Reset();
|
||||||
|
instance->SetData(DATA_DARKMASTER_GANDLING, NOT_STARTED);
|
||||||
|
if (instance->GetData(DATA_MINI_BOSSES) != 6)
|
||||||
|
{
|
||||||
|
me->SetVisible(false);
|
||||||
|
me->setFaction(35);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
me->SetVisible(true);
|
||||||
|
me->setFaction(21);
|
||||||
|
}
|
||||||
|
OpenAllGates();
|
||||||
|
summons.DespawnAll();
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
for (int j =0; j < 3; j++)
|
||||||
|
{
|
||||||
|
Guardians[i][j] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds a random room that is not in use
|
||||||
|
uint32 FindRoom()
|
||||||
|
{
|
||||||
|
uint32 attempts = 0;
|
||||||
|
uint32 room = urand(0, 5);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
room = (room + 1) % 6;
|
||||||
|
attempts++;
|
||||||
|
} while ((Guardians[room][0] || Guardians[room][1] || Guardians[room][2]) && attempts < 7);
|
||||||
|
|
||||||
|
if (attempts == 7)
|
||||||
|
{
|
||||||
|
room = 7; // used as error
|
||||||
|
}
|
||||||
|
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawns the 3 mobs in a given room.
|
||||||
|
void SpawnMobsInRoom(uint32 room)
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
if (Creature* summon = me->SummonCreature(NPC_RISEN_GUARDIAN, SummonPos[room*3 + i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000))
|
||||||
|
{
|
||||||
|
summon->GetMotionMaster()->MoveRandom(8.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for shadow portal
|
||||||
|
void SpellHitTarget(Unit* target, const SpellInfo* spellinfo) override
|
||||||
|
{
|
||||||
|
uint32 room = 0;
|
||||||
|
if (spellinfo && spellinfo->Id == SPELL_SHADOW_PORTAL)
|
||||||
|
{
|
||||||
|
room = GetData(GANDLING_ROOM_TO_USE);
|
||||||
|
SetGate(room, CLOSED);
|
||||||
|
SpawnMobsInRoom(room);
|
||||||
|
DoCast(target, GandlingPortalSpells[room], true); // needs triggered somehow.
|
||||||
|
if (target->GetGUID() == me->GetVictim()->GetGUID())
|
||||||
|
{
|
||||||
|
me->AddThreat(me->GetVictim(), -1000000); // drop current player, add a ton to second. This should guarantee that we don't end up with both 1 and 2 in a cage...
|
||||||
|
if (Unit* newTarget = SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 200.0f)) // search in whole room
|
||||||
|
{
|
||||||
|
me->AddThreat(newTarget, 1000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
uint32 room = 0;
|
||||||
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
events.Update(diff);
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (uint32 eventId = events.ExecuteEvent())
|
||||||
|
{
|
||||||
|
switch (eventId)
|
||||||
|
{
|
||||||
|
case SPELL_ARCANE_MISSILES:
|
||||||
|
DoCastVictim(SPELL_ARCANE_MISSILES);
|
||||||
|
events.ScheduleEvent(SPELL_ARCANE_MISSILES, urand(TIMER_ARCANE_MIN, TIMER_ARCANE_MAX));
|
||||||
|
break;
|
||||||
|
case SPELL_CURSE_DARKMASTER:
|
||||||
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_CURSE_DARKMASTER);
|
||||||
|
}
|
||||||
|
events.ScheduleEvent(SPELL_ARCANE_MISSILES, urand(TIMER_ARCANE_MIN, TIMER_ARCANE_MAX));
|
||||||
|
break;
|
||||||
|
case SPELL_SHADOW_SHIELD:
|
||||||
|
DoCastSelf(SPELL_SHADOW_SHIELD);
|
||||||
|
events.ScheduleEvent(SPELL_ARCANE_MISSILES, urand(TIMER_ARCANE_MIN, TIMER_ARCANE_MAX));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPELL_SHADOW_PORTAL:
|
||||||
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 15.0, true))
|
||||||
|
{
|
||||||
|
room = FindRoom();
|
||||||
|
if (room < 6)
|
||||||
|
{
|
||||||
|
SetData(GANDLING_ROOM_TO_USE, room);
|
||||||
|
DoCast(target, SPELL_SHADOW_PORTAL); // don't use triggered here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
events.ScheduleEvent(SPELL_SHADOW_PORTAL, TIMER_PORTAL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class npc_risen_guardian : public CreatureScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
npc_risen_guardian() : CreatureScript("npc_risen_guardian") {}
|
||||||
|
|
||||||
|
struct npc_risen_guardianAI : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_risen_guardianAI(Creature* creature) : ScriptedAI(creature)
|
||||||
|
{
|
||||||
|
instance = me->GetInstanceScript();
|
||||||
|
room = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceScript* instance;
|
||||||
|
int room;
|
||||||
|
Unit* Gandling;
|
||||||
|
|
||||||
|
void IsSummonedBy(Unit* summoner) override
|
||||||
|
{
|
||||||
|
Gandling = summoner;
|
||||||
|
if (instance)
|
||||||
|
{
|
||||||
|
room = Gandling->GetAI()->GetData(GANDLING_ROOM_TO_USE); // it's set just before my spawn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KilledUnit(Unit* /* target */) override
|
||||||
|
{
|
||||||
|
if (Gandling)
|
||||||
|
{
|
||||||
|
Gandling->GetAI()->SetData(DATA_PLAYER_KILLED, room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
{
|
||||||
|
return GetScholomanceAI<npc_risen_guardianAI>(creature);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void AddSC_boss_darkmaster_gandling()
|
||||||
|
{
|
||||||
|
new boss_darkmaster_gandling();
|
||||||
|
new npc_risen_guardian();
|
||||||
|
}
|
||||||
@@ -36,11 +36,22 @@ public:
|
|||||||
|
|
||||||
struct instance_scholomance_InstanceMapScript : public InstanceScript
|
struct instance_scholomance_InstanceMapScript : public InstanceScript
|
||||||
{
|
{
|
||||||
instance_scholomance_InstanceMapScript(Map* map) : InstanceScript(map),
|
instance_scholomance_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||||
_kirtonosState { 0 },
|
{
|
||||||
_miniBosses { 0 },
|
_miniBosses = 0;
|
||||||
_rasHuman { 0 }
|
_kirtonosState = 0;
|
||||||
{ }
|
_rasHuman = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCreatureCreate(Creature* cr) override
|
||||||
|
{
|
||||||
|
switch (cr->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_DARKMASTER_GANDLING:
|
||||||
|
GandlingGUID = cr->GetGUID();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnGameObjectCreate(GameObject* go) override
|
void OnGameObjectCreate(GameObject* go) override
|
||||||
{
|
{
|
||||||
@@ -49,23 +60,26 @@ public:
|
|||||||
case GO_GATE_KIRTONOS:
|
case GO_GATE_KIRTONOS:
|
||||||
GateKirtonosGUID = go->GetGUID();
|
GateKirtonosGUID = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
case GO_GATE_MALICIA:
|
case GO_GATE_GANDLING_DOWN_NORTH:
|
||||||
GateMiliciaGUID = go->GetGUID();
|
GandlingGatesGUID[0] = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
case GO_GATE_THEOLEN:
|
case GO_GATE_GANDLING_DOWN_EAST:
|
||||||
GateTheolenGUID = go->GetGUID();
|
GandlingGatesGUID[1] = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
case GO_GATE_POLKELT:
|
case GO_GATE_GANDLING_DOWN_SOUTH:
|
||||||
GatePolkeltGUID = go->GetGUID();
|
GandlingGatesGUID[2] = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
case GO_GATE_RAVENIAN:
|
case GO_GATE_GANDLING_UP_NORTH:
|
||||||
GateRavenianGUID = go->GetGUID();
|
GandlingGatesGUID[3] = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
case GO_GATE_BAROV:
|
case GO_GATE_GANDLING_UP_EAST:
|
||||||
GateBarovGUID = go->GetGUID();
|
GandlingGatesGUID[4] = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
case GO_GATE_ILLUCIA:
|
case GO_GATE_GANDLING_UP_SOUTH:
|
||||||
GateIlluciaGUID = go->GetGUID();
|
GandlingGatesGUID[5] = go->GetGUID();
|
||||||
|
break;
|
||||||
|
case GO_GATE_GANDLING_ENTRANCE:
|
||||||
|
GandlingGatesGUID[6] = go->GetGUID();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,20 +90,23 @@ public:
|
|||||||
{
|
{
|
||||||
case GO_GATE_KIRTONOS:
|
case GO_GATE_KIRTONOS:
|
||||||
return GateKirtonosGUID;
|
return GateKirtonosGUID;
|
||||||
case GO_GATE_MALICIA:
|
case GO_GATE_GANDLING_DOWN_NORTH:
|
||||||
return GateMiliciaGUID;
|
return GandlingGatesGUID[0];
|
||||||
case GO_GATE_THEOLEN:
|
case GO_GATE_GANDLING_DOWN_EAST:
|
||||||
return GateTheolenGUID;
|
return GandlingGatesGUID[1];
|
||||||
case GO_GATE_POLKELT:
|
case GO_GATE_GANDLING_DOWN_SOUTH:
|
||||||
return GatePolkeltGUID;
|
return GandlingGatesGUID[2];
|
||||||
case GO_GATE_RAVENIAN:
|
case GO_GATE_GANDLING_UP_NORTH:
|
||||||
return GateRavenianGUID;
|
return GandlingGatesGUID[3];
|
||||||
case GO_GATE_BAROV:
|
case GO_GATE_GANDLING_UP_EAST:
|
||||||
return GateBarovGUID;
|
return GandlingGatesGUID[4];
|
||||||
case GO_GATE_ILLUCIA:
|
case GO_GATE_GANDLING_UP_SOUTH:
|
||||||
return GateIlluciaGUID;
|
return GandlingGatesGUID[5];
|
||||||
|
case GO_GATE_GANDLING_ENTRANCE:
|
||||||
|
return GandlingGatesGUID[6];
|
||||||
|
case NPC_DARKMASTER_GANDLING:
|
||||||
|
return GandlingGUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ObjectGuid::Empty;
|
return ObjectGuid::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +119,27 @@ public:
|
|||||||
break;
|
break;
|
||||||
case DATA_MINI_BOSSES:
|
case DATA_MINI_BOSSES:
|
||||||
++_miniBosses;
|
++_miniBosses;
|
||||||
|
if (_miniBosses == 6)
|
||||||
|
{
|
||||||
|
if (Creature* Gandling = instance->GetCreature(GandlingGUID))
|
||||||
|
{
|
||||||
|
Gandling->AI()->Talk(0);
|
||||||
|
Gandling->AI()->Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DATA_DARKMASTER_GANDLING:
|
||||||
|
switch (data)
|
||||||
|
{
|
||||||
|
case DONE:
|
||||||
|
case NOT_STARTED:
|
||||||
|
case FAIL:
|
||||||
|
HandleGameObject(GandlingGatesGUID[6], true);
|
||||||
|
break;
|
||||||
|
case IN_PROGRESS:
|
||||||
|
HandleGameObject(GandlingGatesGUID[6], false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DATA_RAS_HUMAN:
|
case DATA_RAS_HUMAN:
|
||||||
_rasHuman = data;
|
_rasHuman = data;
|
||||||
@@ -160,6 +198,9 @@ public:
|
|||||||
ObjectGuid GateBarovGUID;
|
ObjectGuid GateBarovGUID;
|
||||||
ObjectGuid GateIlluciaGUID;
|
ObjectGuid GateIlluciaGUID;
|
||||||
|
|
||||||
|
ObjectGuid GandlingGatesGUID[7]; // 6 is the entrance
|
||||||
|
ObjectGuid GandlingGUID; // boss
|
||||||
|
|
||||||
uint32 _kirtonosState;
|
uint32 _kirtonosState;
|
||||||
uint32 _miniBosses;
|
uint32 _miniBosses;
|
||||||
uint32 _rasHuman;
|
uint32 _rasHuman;
|
||||||
@@ -259,215 +300,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Rooms
|
|
||||||
{
|
|
||||||
ROOM_HALL_OF_SECRETS = 0,
|
|
||||||
ROOM_HALL_OF_THE_DAMNED = 1,
|
|
||||||
ROOM_THE_COVEN = 2,
|
|
||||||
ROOM_THE_SHADOW_VAULT = 3,
|
|
||||||
ROOM_BAROV_FAMILY_VAULT = 4,
|
|
||||||
ROOM_VAULT_OF_THE_RAVENIAN = 5,
|
|
||||||
ROOM_MAX = 6
|
|
||||||
};
|
|
||||||
|
|
||||||
class spell_scholomance_shadow_portal : public SpellScriptLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
spell_scholomance_shadow_portal() : SpellScriptLoader("spell_scholomance_shadow_portal") { }
|
|
||||||
|
|
||||||
class spell_scholomance_shadow_portal_SpellScript : public SpellScript
|
|
||||||
{
|
|
||||||
PrepareSpellScript(spell_scholomance_shadow_portal_SpellScript);
|
|
||||||
|
|
||||||
bool Load() override
|
|
||||||
{
|
|
||||||
return GetCaster()->GetTypeId() == TYPEID_UNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
|
||||||
{
|
|
||||||
Creature* caster = GetCaster()->ToCreature();
|
|
||||||
uint8 attempts = 0;
|
|
||||||
uint8 room = urand(ROOM_HALL_OF_SECRETS, ROOM_VAULT_OF_THE_RAVENIAN);
|
|
||||||
uint32 spellId = 0;
|
|
||||||
|
|
||||||
while (attempts < ROOM_MAX)
|
|
||||||
{
|
|
||||||
switch (room)
|
|
||||||
{
|
|
||||||
case ROOM_HALL_OF_SECRETS:
|
|
||||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(GO_GATE_RAVENIAN)))
|
|
||||||
if (gate->GetGoState() == GO_STATE_ACTIVE)
|
|
||||||
spellId = SPELL_SHADOW_PORTAL_HALLOFSECRETS;
|
|
||||||
break;
|
|
||||||
case ROOM_HALL_OF_THE_DAMNED:
|
|
||||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(GO_GATE_THEOLEN)))
|
|
||||||
if (gate->GetGoState() == GO_STATE_ACTIVE)
|
|
||||||
spellId = SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED;
|
|
||||||
break;
|
|
||||||
case ROOM_THE_COVEN:
|
|
||||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(GO_GATE_MALICIA)))
|
|
||||||
if (gate->GetGoState() == GO_STATE_ACTIVE)
|
|
||||||
spellId = SPELL_SHADOW_PORTAL_THECOVEN;
|
|
||||||
break;
|
|
||||||
case ROOM_THE_SHADOW_VAULT:
|
|
||||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(GO_GATE_ILLUCIA)))
|
|
||||||
if (gate->GetGoState() == GO_STATE_ACTIVE)
|
|
||||||
spellId = SPELL_SHADOW_PORTAL_THESHADOWVAULT;
|
|
||||||
break;
|
|
||||||
case ROOM_BAROV_FAMILY_VAULT:
|
|
||||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(GO_GATE_BAROV)))
|
|
||||||
if (gate->GetGoState() == GO_STATE_ACTIVE)
|
|
||||||
spellId = SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT;
|
|
||||||
break;
|
|
||||||
case ROOM_VAULT_OF_THE_RAVENIAN:
|
|
||||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(GO_GATE_POLKELT)))
|
|
||||||
if (gate->GetGoState() == GO_STATE_ACTIVE)
|
|
||||||
spellId = SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spellId)
|
|
||||||
{
|
|
||||||
caster->CastSpell(GetHitUnit(), spellId, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
room = (room + 1) % ROOM_MAX;
|
|
||||||
++attempts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Register() override
|
|
||||||
{
|
|
||||||
OnEffectHitTarget += SpellEffectFn(spell_scholomance_shadow_portal_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SpellScript* GetSpellScript() const override
|
|
||||||
{
|
|
||||||
return new spell_scholomance_shadow_portal_SpellScript();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Position const SummonPos[3 * ROOM_MAX] =
|
|
||||||
{
|
|
||||||
// Hall of Secrects
|
|
||||||
{ 230.80f, 0.138f, 85.23f, 0.0f },
|
|
||||||
{ 241.23f, -6.979f, 85.23f, 0.0f },
|
|
||||||
{ 246.65f, 4.227f, 84.85f, 0.0f },
|
|
||||||
// The Hall of the damned
|
|
||||||
{ 177.9624f, -68.23893f, 84.95197f, 3.228859f },
|
|
||||||
{ 183.7705f, -61.43489f, 84.92424f, 5.148721f },
|
|
||||||
{ 184.7035f, -77.74805f, 84.92424f, 4.660029f },
|
|
||||||
// The Coven
|
|
||||||
{ 111.7203f, -1.105035f, 85.45985f, 3.961897f },
|
|
||||||
{ 118.0079f, 6.430664f, 85.31169f, 2.408554f },
|
|
||||||
{ 120.0276f, -7.496636f, 85.31169f, 2.984513f },
|
|
||||||
// The Shadow Vault
|
|
||||||
{ 245.3716f, 0.628038f, 72.73877f, 0.01745329f },
|
|
||||||
{ 240.9920f, 3.405653f, 72.73877f, 6.143559f },
|
|
||||||
{ 240.9543f, -3.182943f, 72.73877f, 0.2268928f },
|
|
||||||
// Barov Family Vault
|
|
||||||
{ 181.8245f, -42.58117f, 75.4812f, 4.660029f },
|
|
||||||
{ 177.7456f, -42.74745f, 75.4812f, 4.886922f },
|
|
||||||
{ 185.6157f, -42.91200f, 75.4812f, 4.45059f },
|
|
||||||
// Vault of the Ravenian
|
|
||||||
{ 136.362f, 6.221f, 75.40f, 3.14f },
|
|
||||||
{ 130.79f, -0.91f, 75.40f, 3.14f },
|
|
||||||
{ 136.362f, -8.221f, 75.40f, 3.14f },
|
|
||||||
};
|
|
||||||
|
|
||||||
class spell_scholomance_shadow_portal_rooms : public SpellScriptLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
spell_scholomance_shadow_portal_rooms() : SpellScriptLoader("spell_scholomance_shadow_portal_rooms") { }
|
|
||||||
|
|
||||||
class spell_scholomance_shadow_portal_rooms_SpellScript : public SpellScript
|
|
||||||
{
|
|
||||||
PrepareSpellScript(spell_scholomance_shadow_portal_rooms_SpellScript);
|
|
||||||
|
|
||||||
bool Load() override
|
|
||||||
{
|
|
||||||
return GetCaster()->GetTypeId() == TYPEID_UNIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleSendEvent(SpellEffIndex effIndex)
|
|
||||||
{
|
|
||||||
PreventHitEffect(effIndex);
|
|
||||||
Creature* caster = GetCaster()->ToCreature();
|
|
||||||
|
|
||||||
uint8 summonPos = 0;
|
|
||||||
uint32 gateId = 0;
|
|
||||||
|
|
||||||
switch (GetSpellInfo()->Id)
|
|
||||||
{
|
|
||||||
case SPELL_SHADOW_PORTAL_HALLOFSECRETS:
|
|
||||||
summonPos = ROOM_HALL_OF_SECRETS * 3;
|
|
||||||
gateId = GO_GATE_POLKELT;
|
|
||||||
break;
|
|
||||||
case SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED:
|
|
||||||
summonPos = ROOM_HALL_OF_THE_DAMNED * 3;
|
|
||||||
gateId = GO_GATE_THEOLEN;
|
|
||||||
break;
|
|
||||||
case SPELL_SHADOW_PORTAL_THECOVEN:
|
|
||||||
summonPos = ROOM_THE_COVEN * 3;
|
|
||||||
gateId = GO_GATE_MALICIA;
|
|
||||||
break;
|
|
||||||
case SPELL_SHADOW_PORTAL_THESHADOWVAULT:
|
|
||||||
summonPos = ROOM_THE_SHADOW_VAULT * 3;
|
|
||||||
gateId = GO_GATE_ILLUCIA;
|
|
||||||
break;
|
|
||||||
case SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT:
|
|
||||||
summonPos = ROOM_BAROV_FAMILY_VAULT * 3;
|
|
||||||
gateId = GO_GATE_BAROV;
|
|
||||||
break;
|
|
||||||
case SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN:
|
|
||||||
summonPos = ROOM_VAULT_OF_THE_RAVENIAN * 3;
|
|
||||||
gateId = GO_GATE_RAVENIAN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gateId && (GetCaster()->GetMap()->GetId() == 289))
|
|
||||||
{
|
|
||||||
for (uint8 i = 0; i < 3; ++i)
|
|
||||||
{
|
|
||||||
if (Creature* summon = GetCaster()->SummonCreature(NPC_RISEN_GUARDIAN, SummonPos[summonPos + i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000))
|
|
||||||
{
|
|
||||||
summon->GetMotionMaster()->MoveRandom(8.0f);
|
|
||||||
summon->AI()->SetData(0, summonPos / 3 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
|
||||||
if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, instance->GetGuidData(gateId)))
|
|
||||||
{
|
|
||||||
gate->SetGoState(GO_STATE_READY);
|
|
||||||
gate->AI()->SetData(1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Register() override
|
|
||||||
{
|
|
||||||
OnEffectHit += SpellEffectFn(spell_scholomance_shadow_portal_rooms_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SpellScript* GetSpellScript() const override
|
|
||||||
{
|
|
||||||
return new spell_scholomance_shadow_portal_rooms_SpellScript();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class spell_scholomance_boon_of_life : public SpellScriptLoader
|
class spell_scholomance_boon_of_life : public SpellScriptLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -648,8 +480,6 @@ void AddSC_instance_scholomance()
|
|||||||
new spell_scholomance_fixate();
|
new spell_scholomance_fixate();
|
||||||
new spell_kormok_summon_bone_mages();
|
new spell_kormok_summon_bone_mages();
|
||||||
new spell_kormok_summon_bone_minions();
|
new spell_kormok_summon_bone_minions();
|
||||||
new spell_scholomance_shadow_portal();
|
|
||||||
new spell_scholomance_shadow_portal_rooms();
|
|
||||||
new spell_scholomance_boon_of_life();
|
new spell_scholomance_boon_of_life();
|
||||||
new npc_scholomance_occultist();
|
new npc_scholomance_occultist();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ enum DataTypes
|
|||||||
{
|
{
|
||||||
DATA_KIRTONOS_THE_HERALD = 0,
|
DATA_KIRTONOS_THE_HERALD = 0,
|
||||||
DATA_MINI_BOSSES = 1,
|
DATA_MINI_BOSSES = 1,
|
||||||
DATA_RAS_HUMAN = 2
|
DATA_RAS_HUMAN = 2,
|
||||||
|
DATA_DARKMASTER_GANDLING = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ModelIds
|
enum ModelIds
|
||||||
@@ -41,18 +42,22 @@ enum TalkGroupIds
|
|||||||
|
|
||||||
enum CreatureIds
|
enum CreatureIds
|
||||||
{
|
{
|
||||||
NPC_RISEN_GUARDIAN = 11598
|
NPC_RISEN_GUARDIAN = 11598,
|
||||||
|
NPC_DARKMASTER_GANDLING = 1853
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GameobjectIds
|
enum GameobjectIds
|
||||||
{
|
{
|
||||||
GO_GATE_KIRTONOS = 175570,
|
GO_GATE_KIRTONOS = 175570,
|
||||||
GO_GATE_RAVENIAN = 177372,
|
|
||||||
GO_GATE_THEOLEN = 177377,
|
GO_GATE_GANDLING_ENTRANCE = 177374,
|
||||||
GO_GATE_ILLUCIA = 177371,
|
|
||||||
GO_GATE_MALICIA = 177375,
|
GO_GATE_GANDLING_DOWN_NORTH = 177371,
|
||||||
GO_GATE_BAROV = 177373,
|
GO_GATE_GANDLING_DOWN_EAST = 177373,
|
||||||
GO_GATE_POLKELT = 177376
|
GO_GATE_GANDLING_DOWN_SOUTH = 177372,
|
||||||
|
GO_GATE_GANDLING_UP_NORTH = 177376,
|
||||||
|
GO_GATE_GANDLING_UP_EAST = 177377,
|
||||||
|
GO_GATE_GANDLING_UP_SOUTH = 177375
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SpellIds
|
enum SpellIds
|
||||||
@@ -65,14 +70,7 @@ enum SpellIds
|
|||||||
SPELL_SUMMON_BONE_MINION1 = 27690,
|
SPELL_SUMMON_BONE_MINION1 = 27690,
|
||||||
SPELL_SUMMON_BONE_MINION2 = 27691,
|
SPELL_SUMMON_BONE_MINION2 = 27691,
|
||||||
SPELL_SUMMON_BONE_MINION3 = 27692,
|
SPELL_SUMMON_BONE_MINION3 = 27692,
|
||||||
SPELL_SUMMON_BONE_MINION4 = 27693,
|
SPELL_SUMMON_BONE_MINION4 = 27693
|
||||||
|
|
||||||
SPELL_SHADOW_PORTAL_HALLOFSECRETS = 17863,
|
|
||||||
SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED = 17939,
|
|
||||||
SPELL_SHADOW_PORTAL_THECOVEN = 17943,
|
|
||||||
SPELL_SHADOW_PORTAL_THESHADOWVAULT = 17944,
|
|
||||||
SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT = 17946,
|
|
||||||
SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN = 17948
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class AI, class T>
|
template <class AI, class T>
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ void AddSC_the_scarlet_enclave_c2();
|
|||||||
void AddSC_the_scarlet_enclave_c5();
|
void AddSC_the_scarlet_enclave_c5();
|
||||||
void AddSC_instance_scarlet_monastery(); //Scarlet Monastery
|
void AddSC_instance_scarlet_monastery(); //Scarlet Monastery
|
||||||
void AddSC_boss_kirtonos_the_herald();
|
void AddSC_boss_kirtonos_the_herald();
|
||||||
|
void AddSC_boss_darkmaster_gandling();
|
||||||
void AddSC_instance_scholomance(); //Scholomance
|
void AddSC_instance_scholomance(); //Scholomance
|
||||||
void AddSC_instance_shadowfang_keep(); //Shadowfang keep
|
void AddSC_instance_shadowfang_keep(); //Shadowfang keep
|
||||||
void AddSC_boss_baroness_anastari();
|
void AddSC_boss_baroness_anastari();
|
||||||
@@ -226,6 +227,7 @@ void AddEasternKingdomsScripts()
|
|||||||
AddSC_the_scarlet_enclave_c5();
|
AddSC_the_scarlet_enclave_c5();
|
||||||
AddSC_instance_scarlet_monastery(); //Scarlet Monastery
|
AddSC_instance_scarlet_monastery(); //Scarlet Monastery
|
||||||
AddSC_boss_kirtonos_the_herald();
|
AddSC_boss_kirtonos_the_herald();
|
||||||
|
AddSC_boss_darkmaster_gandling();
|
||||||
AddSC_instance_scholomance(); //Scholomance
|
AddSC_instance_scholomance(); //Scholomance
|
||||||
AddSC_instance_shadowfang_keep(); //Shadowfang keep
|
AddSC_instance_shadowfang_keep(); //Shadowfang keep
|
||||||
AddSC_boss_baroness_anastari();
|
AddSC_boss_baroness_anastari();
|
||||||
|
|||||||
Reference in New Issue
Block a user