From ee0bc7d592c9517f8acc6b13da3f97496c5d28ab Mon Sep 17 00:00:00 2001 From: patou01 <2592673+patou01@users.noreply.github.com> Date: Mon, 1 Nov 2021 09:55:01 +0100 Subject: [PATCH] fix(Scripts/Scholomance): Grandmaster Gandling correctly drops threat if teleports the tank (#8455) --- .../rev_1633884280859489900.sql | 15 + .../Scholomance/boss_darkmaster_gandling.cpp | 417 ++++++++++++++++++ .../Scholomance/instance_scholomance.cpp | 312 +++---------- .../EasternKingdoms/Scholomance/scholomance.h | 36 +- .../eastern_kingdoms_script_loader.cpp | 2 + 5 files changed, 522 insertions(+), 260 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1633884280859489900.sql create mode 100644 src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp diff --git a/data/sql/updates/pending_db_world/rev_1633884280859489900.sql b/data/sql/updates/pending_db_world/rev_1633884280859489900.sql new file mode 100644 index 000000000..da2c02a97 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1633884280859489900.sql @@ -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'); diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp new file mode 100644 index 000000000..2792f41cb --- /dev/null +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp @@ -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 . + */ + +#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(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(creature); + } +}; + +void AddSC_boss_darkmaster_gandling() +{ + new boss_darkmaster_gandling(); + new npc_risen_guardian(); +} diff --git a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp index b9fc6be9a..096f9bb49 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp @@ -36,11 +36,22 @@ public: struct instance_scholomance_InstanceMapScript : public InstanceScript { - instance_scholomance_InstanceMapScript(Map* map) : InstanceScript(map), - _kirtonosState { 0 }, - _miniBosses { 0 }, - _rasHuman { 0 } - { } + instance_scholomance_InstanceMapScript(Map* map) : InstanceScript(map) + { + _miniBosses = 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 { @@ -49,23 +60,26 @@ public: case GO_GATE_KIRTONOS: GateKirtonosGUID = go->GetGUID(); break; - case GO_GATE_MALICIA: - GateMiliciaGUID = go->GetGUID(); + case GO_GATE_GANDLING_DOWN_NORTH: + GandlingGatesGUID[0] = go->GetGUID(); break; - case GO_GATE_THEOLEN: - GateTheolenGUID = go->GetGUID(); + case GO_GATE_GANDLING_DOWN_EAST: + GandlingGatesGUID[1] = go->GetGUID(); break; - case GO_GATE_POLKELT: - GatePolkeltGUID = go->GetGUID(); + case GO_GATE_GANDLING_DOWN_SOUTH: + GandlingGatesGUID[2] = go->GetGUID(); break; - case GO_GATE_RAVENIAN: - GateRavenianGUID = go->GetGUID(); + case GO_GATE_GANDLING_UP_NORTH: + GandlingGatesGUID[3] = go->GetGUID(); break; - case GO_GATE_BAROV: - GateBarovGUID = go->GetGUID(); + case GO_GATE_GANDLING_UP_EAST: + GandlingGatesGUID[4] = go->GetGUID(); break; - case GO_GATE_ILLUCIA: - GateIlluciaGUID = go->GetGUID(); + case GO_GATE_GANDLING_UP_SOUTH: + GandlingGatesGUID[5] = go->GetGUID(); + break; + case GO_GATE_GANDLING_ENTRANCE: + GandlingGatesGUID[6] = go->GetGUID(); break; } } @@ -76,20 +90,23 @@ public: { case GO_GATE_KIRTONOS: return GateKirtonosGUID; - case GO_GATE_MALICIA: - return GateMiliciaGUID; - case GO_GATE_THEOLEN: - return GateTheolenGUID; - case GO_GATE_POLKELT: - return GatePolkeltGUID; - case GO_GATE_RAVENIAN: - return GateRavenianGUID; - case GO_GATE_BAROV: - return GateBarovGUID; - case GO_GATE_ILLUCIA: - return GateIlluciaGUID; + case GO_GATE_GANDLING_DOWN_NORTH: + return GandlingGatesGUID[0]; + case GO_GATE_GANDLING_DOWN_EAST: + return GandlingGatesGUID[1]; + case GO_GATE_GANDLING_DOWN_SOUTH: + return GandlingGatesGUID[2]; + case GO_GATE_GANDLING_UP_NORTH: + return GandlingGatesGUID[3]; + case GO_GATE_GANDLING_UP_EAST: + return GandlingGatesGUID[4]; + case GO_GATE_GANDLING_UP_SOUTH: + return GandlingGatesGUID[5]; + case GO_GATE_GANDLING_ENTRANCE: + return GandlingGatesGUID[6]; + case NPC_DARKMASTER_GANDLING: + return GandlingGUID; } - return ObjectGuid::Empty; } @@ -102,6 +119,27 @@ public: break; case DATA_MINI_BOSSES: ++_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; case DATA_RAS_HUMAN: _rasHuman = data; @@ -160,6 +198,9 @@ public: ObjectGuid GateBarovGUID; ObjectGuid GateIlluciaGUID; + ObjectGuid GandlingGatesGUID[7]; // 6 is the entrance + ObjectGuid GandlingGUID; // boss + uint32 _kirtonosState; uint32 _miniBosses; 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 { public: @@ -648,8 +480,6 @@ void AddSC_instance_scholomance() new spell_scholomance_fixate(); new spell_kormok_summon_bone_mages(); new spell_kormok_summon_bone_minions(); - new spell_scholomance_shadow_portal(); - new spell_scholomance_shadow_portal_rooms(); new spell_scholomance_boon_of_life(); new npc_scholomance_occultist(); } diff --git a/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h b/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h index 11e22b8a9..d3071551c 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h +++ b/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h @@ -26,33 +26,38 @@ enum DataTypes { DATA_KIRTONOS_THE_HERALD = 0, DATA_MINI_BOSSES = 1, - DATA_RAS_HUMAN = 2 + DATA_RAS_HUMAN = 2, + DATA_DARKMASTER_GANDLING = 3 }; enum ModelIds { - MODEL_RAS_HUMAN = 3975 + MODEL_RAS_HUMAN = 3975 }; enum TalkGroupIds { - TALK_RAS_HUMAN = 0 + TALK_RAS_HUMAN = 0 }; enum CreatureIds { - NPC_RISEN_GUARDIAN = 11598 + NPC_RISEN_GUARDIAN = 11598, + NPC_DARKMASTER_GANDLING = 1853 }; enum GameobjectIds { - GO_GATE_KIRTONOS = 175570, - GO_GATE_RAVENIAN = 177372, - GO_GATE_THEOLEN = 177377, - GO_GATE_ILLUCIA = 177371, - GO_GATE_MALICIA = 177375, - GO_GATE_BAROV = 177373, - GO_GATE_POLKELT = 177376 + GO_GATE_KIRTONOS = 175570, + + GO_GATE_GANDLING_ENTRANCE = 177374, + + GO_GATE_GANDLING_DOWN_NORTH = 177371, + GO_GATE_GANDLING_DOWN_EAST = 177373, + 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 @@ -65,14 +70,7 @@ enum SpellIds SPELL_SUMMON_BONE_MINION1 = 27690, SPELL_SUMMON_BONE_MINION2 = 27691, SPELL_SUMMON_BONE_MINION3 = 27692, - 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 + SPELL_SUMMON_BONE_MINION4 = 27693 }; template diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index b04cd11c1..7fb6188df 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -91,6 +91,7 @@ void AddSC_the_scarlet_enclave_c2(); void AddSC_the_scarlet_enclave_c5(); void AddSC_instance_scarlet_monastery(); //Scarlet Monastery void AddSC_boss_kirtonos_the_herald(); +void AddSC_boss_darkmaster_gandling(); void AddSC_instance_scholomance(); //Scholomance void AddSC_instance_shadowfang_keep(); //Shadowfang keep void AddSC_boss_baroness_anastari(); @@ -226,6 +227,7 @@ void AddEasternKingdomsScripts() AddSC_the_scarlet_enclave_c5(); AddSC_instance_scarlet_monastery(); //Scarlet Monastery AddSC_boss_kirtonos_the_herald(); + AddSC_boss_darkmaster_gandling(); AddSC_instance_scholomance(); //Scholomance AddSC_instance_shadowfang_keep(); //Shadowfang keep AddSC_boss_baroness_anastari();