mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 10:05:32 +01:00
@@ -9,6 +9,13 @@
|
||||
set(scripts_STAT_SRCS
|
||||
${scripts_STAT_SRCS}
|
||||
Maelstrom/kezan.cpp
|
||||
Maelstrom/Stonecore/instance_stonecore.cpp
|
||||
Maelstrom/Stonecore/stonecore.cpp
|
||||
Maelstrom/Stonecore/stonecore.h
|
||||
Maelstrom/Stonecore/boss_corborus.cpp
|
||||
Maelstrom/Stonecore/boss_slabhide.cpp
|
||||
Maelstrom/Stonecore/boss_ozruk.cpp
|
||||
Maelstrom/Stonecore/boss_high_priestess_azil.cpp
|
||||
)
|
||||
|
||||
message(" -> Prepared: The Maelstrom")
|
||||
|
||||
319
src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
Normal file
319
src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://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 "ScriptedCreature.h"
|
||||
#include "CreatureGroups.h"
|
||||
#include "stonecore.h"
|
||||
|
||||
// TO-DO:
|
||||
// Find heroic sniffs and script spawning Crystal Shards on heroic mode.
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Corborus intro
|
||||
SPELL_TWILIGHT_DOCUMENTS = 93167,
|
||||
SPELL_RING_WYRM_CHARGE = 81237,
|
||||
SPELL_DOOR_BREAK = 81232, // cast by World Trigger 22515
|
||||
|
||||
// Corborus boss
|
||||
SPELL_DAMPENING_WAVE = 82415,
|
||||
SPELL_CRYSTAL_BARRAGE = 86881, // 81638 triggers 81637
|
||||
// SPELL_CRYSTAL_BARRAGE_SHARD = 92012, // heroic only, summons Crystal Shard (TO-DO!)
|
||||
SPELL_CLEAR_ALL_DEBUFFS = 34098,
|
||||
SPELL_SUBMERGE = 81629,
|
||||
SPELL_TRASHING_CHARGE_TELEPORT = 81839, // triggers 81864
|
||||
// SPELL_TRASHING_CHARGE_TELEPORT_2= 81838, // dummy, targets all players, threat update packet follows
|
||||
SPELL_SUMMON_TRASHING_CHARGE = 81816,
|
||||
SPELL_TRASHING_CHARGE_VISUAL = 81801, // cast time 3.5 sec
|
||||
SPELL_TRASHING_CHARGE_EFFECT = 81828, // 40 yard radius
|
||||
SPELL_EMERGE = 81948,
|
||||
|
||||
// Rock Borer npc (43917)
|
||||
SPELL_ROCK_BORER_EMERGE = 82185,
|
||||
SPELL_ROCK_BORE = 80028,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_TRASHING_CHARGE = 43743,
|
||||
// NPC_CRYSTAL_SHARD = 49267, // 49473
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
|
||||
// Corborus intro
|
||||
EVENT_CORBORUS_CHARGE,
|
||||
EVENT_CORBORUS_KNOCKBACK,
|
||||
EVENT_CORBORUS_FACEPLAYERS,
|
||||
|
||||
// Corborus boss
|
||||
EVENT_DAMPENING_WAVE,
|
||||
EVENT_CRYSTAL_BARRAGE,
|
||||
EVENT_SUBMERGE,
|
||||
EVENT_TELEPORT,
|
||||
EVENT_TRASHING_CHARGE,
|
||||
EVENT_SUMMON_BEETLE,
|
||||
EVENT_EMERGE,
|
||||
EVENT_ATTACK,
|
||||
|
||||
// Rock Borer
|
||||
EVENT_EMERGED,
|
||||
EVENT_ROCK_BORE,
|
||||
};
|
||||
|
||||
class boss_corborus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_corborus() : CreatureScript("boss_corborus") { }
|
||||
|
||||
struct boss_corborusAI : public BossAI
|
||||
{
|
||||
boss_corborusAI(Creature* creature) : BossAI(creature, DATA_CORBORUS)
|
||||
{
|
||||
stateIntro = NOT_STARTED;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
countTrashingCharge = 0;
|
||||
events.ScheduleEvent(EVENT_DAMPENING_WAVE, 10000);
|
||||
events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, 15000);
|
||||
events.ScheduleEvent(EVENT_SUBMERGE, 36000);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_CORBORUS_INTRO: // Executes Corborus intro event
|
||||
{
|
||||
if (stateIntro != NOT_STARTED)
|
||||
return;
|
||||
|
||||
stateIntro = IN_PROGRESS;
|
||||
|
||||
if (Creature* Millhouse = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MILLHOUSE_MANASTORM)))
|
||||
{
|
||||
Millhouse->InterruptNonMeleeSpells(true);
|
||||
Millhouse->RemoveAllAuras();
|
||||
Millhouse->HandleEmoteCommand(EMOTE_ONESHOT_KNOCKDOWN);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CORBORUS_CHARGE, 1000);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() && stateIntro != IN_PROGRESS)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CORBORUS_CHARGE:
|
||||
// Face Millhouse and other mobs
|
||||
instance->SetData(DATA_MILLHOUSE_EVENT_FACE, 0);
|
||||
|
||||
// Open rock gate and cast visual from nearby worldtrigger
|
||||
instance->HandleGameObject(instance->GetGuidData(GAMEOBJECT_CORBORUS_ROCKDOOR), true);
|
||||
if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 60.0f))
|
||||
worldtrigger->CastSpell(worldtrigger, SPELL_DOOR_BREAK, true);
|
||||
|
||||
// Make Corborus charge
|
||||
me->CastSpell(me, SPELL_RING_WYRM_CHARGE, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_CORBORUS_KNOCKBACK, 1000);
|
||||
break;
|
||||
case EVENT_CORBORUS_KNOCKBACK:
|
||||
// Spawn Twilight Documents (quest gameobject)
|
||||
if (Creature* Millhouse = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MILLHOUSE_MANASTORM)))
|
||||
Millhouse->CastSpell(Millhouse, SPELL_TWILIGHT_DOCUMENTS, true);
|
||||
|
||||
// Knockback Millhouse and other mobs
|
||||
instance->SetData(DATA_MILLHOUSE_EVENT_KNOCKBACK, 0);
|
||||
|
||||
events.ScheduleEvent(EVENT_CORBORUS_FACEPLAYERS, 2000);
|
||||
break;
|
||||
case EVENT_CORBORUS_FACEPLAYERS:
|
||||
// Face Corborus to players and set new home position
|
||||
me->SetFacingTo(3.176499f);
|
||||
me->SetHomePosition(1154.55f, 878.843f, 284.963f, 3.176499f);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
|
||||
|
||||
// Despawn Millhouse and all trash
|
||||
instance->SetData(DATA_MILLHOUSE_EVENT_DESPAWN, 0);
|
||||
|
||||
stateIntro = DONE;
|
||||
break;
|
||||
case EVENT_DAMPENING_WAVE:
|
||||
DoCastVictim(SPELL_DAMPENING_WAVE);
|
||||
events.ScheduleEvent(EVENT_DAMPENING_WAVE, 15000);
|
||||
break;
|
||||
case EVENT_CRYSTAL_BARRAGE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_CRYSTAL_BARRAGE);
|
||||
events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, 10000);
|
||||
break;
|
||||
case EVENT_SUBMERGE:
|
||||
events.RescheduleEvent(EVENT_DAMPENING_WAVE, 35000);
|
||||
events.RescheduleEvent(EVENT_CRYSTAL_BARRAGE, 30000);
|
||||
events.RescheduleEvent(EVENT_SUBMERGE, 100000);
|
||||
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
|
||||
me->AttackStop();
|
||||
|
||||
DoCast(me, SPELL_SUBMERGE);
|
||||
|
||||
countTrashingCharge = 0;
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 500);
|
||||
break;
|
||||
case EVENT_TELEPORT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_TRASHING_CHARGE_TELEPORT);
|
||||
countTrashingCharge += 1;
|
||||
if (countTrashingCharge <= 4)
|
||||
events.ScheduleEvent(EVENT_TRASHING_CHARGE, 1000);
|
||||
else
|
||||
events.ScheduleEvent(EVENT_EMERGE, 2500);
|
||||
break;
|
||||
case EVENT_TRASHING_CHARGE:
|
||||
DoCast(me, SPELL_SUMMON_TRASHING_CHARGE);
|
||||
DoCast(me, SPELL_TRASHING_CHARGE_VISUAL);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 5000);
|
||||
break;
|
||||
case EVENT_EMERGE:
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoCast(me, SPELL_EMERGE);
|
||||
events.ScheduleEvent(EVENT_ATTACK, 2500);
|
||||
break;
|
||||
case EVENT_ATTACK:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() != NPC_TRASHING_CHARGE)
|
||||
return;
|
||||
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->CastSpell(summon, SPELL_TRASHING_CHARGE_EFFECT);
|
||||
summon->DespawnOrUnsummon(6000);
|
||||
}
|
||||
|
||||
private:
|
||||
EncounterState stateIntro;
|
||||
uint32 countTrashingCharge;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_corborusAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 43391 - Rock Borer
|
||||
class npc_rock_borer : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_rock_borer() : CreatureScript("npc_rock_borer") { }
|
||||
|
||||
struct npc_rock_borerAI : public ScriptedAI
|
||||
{
|
||||
npc_rock_borerAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetDisableGravity(true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
events.ScheduleEvent(EVENT_EMERGED, 1200);
|
||||
events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
me->SetInCombatState(false, summoner);
|
||||
DoCast(SPELL_ROCK_BORER_EMERGE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() && me->GetReactState() != REACT_PASSIVE)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_EMERGED:
|
||||
me->RemoveAurasDueToSpell(SPELL_ROCK_BORER_EMERGE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
case EVENT_ROCK_BORE:
|
||||
DoCast(SPELL_ROCK_BORE);
|
||||
events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_rock_borerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_corborus()
|
||||
{
|
||||
new boss_corborus();
|
||||
new npc_rock_borer();
|
||||
}
|
||||
@@ -0,0 +1,807 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://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 "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Vehicle.h"
|
||||
#include "stonecore.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ENERGY_SHIELD = 82858,
|
||||
|
||||
SPELL_CURSE_OF_BLOOD = 79345,
|
||||
SPELL_FORCE_GRIP = 79351,
|
||||
SPELL_SUMMON_GRAVITY_WELL = 79340,
|
||||
SPELL_EARTH_FURY_ENERGY_SHIELD = 79050,
|
||||
|
||||
// Gravity Well
|
||||
SPELL_GRAVITY_WELL_VISUAL = 79245,
|
||||
SPELL_GRAVITY_WELL_AURA_DAMAGE = 79244,
|
||||
SPELL_GRAVITY_WELL_AURA_PULL = 79333,
|
||||
|
||||
SPELL_GRAVITY_WELL_DAMAGE = 79249,
|
||||
SPELL_GRAVITY_WELL_PULL = 79332,
|
||||
|
||||
// Fury of Earth phase
|
||||
SPELL_EARTH_FURY_CASTING_VISUAL = 79002,
|
||||
SPELL_SEISMIC_SHARD_SUMMON_1 = 86860,
|
||||
SPELL_SEISMIC_SHARD_SUMMON_2 = 86858,
|
||||
SPELL_SEISMIC_SHARD_SUMMON_3 = 86856,
|
||||
SPELL_SEISMIC_SHARD_VISUAL = 79009,
|
||||
SPELL_SEISMIC_SHARD_PREPARE = 86862,
|
||||
SPELL_SEISMIC_SHARD_TARGETING = 80511,
|
||||
SPELL_SEISMIC_SHARD_LAUNCH = 79015,
|
||||
SPELL_SEISMIC_SHARD_MISSLE = 79014,
|
||||
SPELL_EJECT_ALL_PASSENGERS = 68576,
|
||||
|
||||
// Add wave spells
|
||||
SPELL_SUMMON_WAVE_SOUTH = 79200,
|
||||
SPELL_SUMMON_WAVE_WEST = 79196,
|
||||
SPELL_SUMMON_ADD_SOUTH = 79193,
|
||||
SPELL_SUMMON_ADD_WEST = 79199,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_DEVOUT_FOLLOWER = 42428,
|
||||
NPC_SEISMIC_SHARD = 42355,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_PHASE_TWO = 1,
|
||||
SAY_DEATH = 2,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
|
||||
EVENT_INTRO_MOVE,
|
||||
|
||||
EVENT_CURSE_OF_BLOOD,
|
||||
EVENT_FORCE_GRIP,
|
||||
EVENT_SUMMON_GRAVITY_WELL,
|
||||
EVENT_ENERGY_SHIELD,
|
||||
EVENT_EARTH_FURY,
|
||||
|
||||
EVENT_SUMMON_WAVE_SOUTH,
|
||||
EVENT_SUMMON_WAVE_WEST,
|
||||
|
||||
EVENT_GRAVITY_WELL_AURA_DAMAGE,
|
||||
EVENT_GRAVITY_WELL_AURA_PULL,
|
||||
|
||||
// Phase 2: Fury of Earth
|
||||
EVENT_EARTH_FURY_FLY_UP,
|
||||
EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM,
|
||||
EVENT_EARTH_FURY_CHECK_SEAT0,
|
||||
EVENT_EARTH_FURY_LAUNCH_SHARD,
|
||||
EVENT_EARTH_FURY_FLY_DOWN,
|
||||
EVENT_START_ATTACK,
|
||||
|
||||
EVENT_LAUNCH,
|
||||
EVENT_SEISMIC_SHARD_MOUNT
|
||||
};
|
||||
|
||||
enum EventGroups
|
||||
{
|
||||
EVENT_GROUP_PHASE_ONE,
|
||||
EVENT_GROUP_ADDS,
|
||||
};
|
||||
|
||||
enum Points
|
||||
{
|
||||
POINT_NONE,
|
||||
|
||||
POINT_INTRO_MOVE,
|
||||
POINT_FLY_UP,
|
||||
POINT_ABOVE_PLATFORM,
|
||||
POINT_PLATFORM,
|
||||
POINT_GROUND,
|
||||
};
|
||||
|
||||
Position const GroundPos = { 1331.82f, 980.314f, 207.542f };
|
||||
Position const AbovePlatformPos = { 1336.21f, 960.813f, 215.0f };
|
||||
|
||||
// TO-DO:
|
||||
// - Find out why NPCs summoned by boss are usually two times bigger than their normal size.
|
||||
// - Find more sniffs and script Force Grip spell (79351)
|
||||
|
||||
class boss_high_priestess_azil : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_high_priestess_azil() : CreatureScript("boss_high_priestess_azil") { }
|
||||
|
||||
struct boss_high_priestess_azilAI : public BossAI
|
||||
{
|
||||
boss_high_priestess_azilAI(Creature* creature) : BossAI(creature, DATA_HIGH_PRIESTESS_AZIL), vehicle(creature->GetVehicleKit())
|
||||
{
|
||||
ASSERT(vehicle);
|
||||
}
|
||||
|
||||
Vehicle* vehicle;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
|
||||
events.ScheduleEvent(EVENT_INTRO_MOVE, 2000);
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000, EVENT_GROUP_PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000,10000), EVENT_GROUP_PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000, EVENT_GROUP_PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_ENERGY_SHIELD, urand(35000,36000));
|
||||
events.ScheduleEvent(EVENT_SUMMON_WAVE_SOUTH, 0);
|
||||
events.ScheduleEvent(EVENT_SUMMON_WAVE_WEST, 40000);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*victim*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
DoCast(SPELL_ENERGY_SHIELD);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
me->Say(SAY_DEATH);
|
||||
}
|
||||
|
||||
/*
|
||||
void PassengerBoarded(Unit* who, int8 seatId, bool apply) override
|
||||
{
|
||||
if (!apply || who->GetEntry() != NPC_SEISMIC_SHARD)
|
||||
return;
|
||||
|
||||
Movement::MoveSplineInit init(who);
|
||||
init.DisableTransportPathTransformations();
|
||||
if (seatId == 0)
|
||||
init.MoveTo(12.13748f, 0.0f, 2.442475f);
|
||||
else if (seatId == 1)
|
||||
init.MoveTo(12.13748f, 17.5f, 11.19248f);
|
||||
else
|
||||
init.MoveTo(12.13748f, -17.5f, 11.19248f);
|
||||
init.Launch();
|
||||
}
|
||||
*/
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE && id != POINT_INTRO_MOVE)
|
||||
return;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case POINT_INTRO_MOVE:
|
||||
me->RemoveAurasDueToSpell(SPELL_ENERGY_SHIELD);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
case POINT_FLY_UP:
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
events.ScheduleEvent(EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM, 1000);
|
||||
break;
|
||||
case POINT_ABOVE_PLATFORM:
|
||||
me->SetFacingTo(5.218534f);
|
||||
DoCast(SPELL_EARTH_FURY_CASTING_VISUAL);
|
||||
DoCast(SPELL_SEISMIC_SHARD_SUMMON_1);
|
||||
DoCast(SPELL_SEISMIC_SHARD_SUMMON_2);
|
||||
DoCast(SPELL_SEISMIC_SHARD_SUMMON_3);
|
||||
events.ScheduleEvent(EVENT_EARTH_FURY_CHECK_SEAT0, 6700);
|
||||
break;
|
||||
case POINT_GROUND:
|
||||
DoCast(SPELL_EJECT_ALL_PASSENGERS);
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
// Find more sniffs to correct these timers, this was copied from Reset() void.
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000, EVENT_GROUP_PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000, 10000), EVENT_GROUP_PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000, EVENT_GROUP_PHASE_ONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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_INTRO_MOVE:
|
||||
me->GetMotionMaster()->MoveJump(GroundPos, me->GetSpeed(MOVE_FLIGHT), 1.918408f, POINT_INTRO_MOVE);
|
||||
break;
|
||||
case EVENT_CURSE_OF_BLOOD:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_CURSE_OF_BLOOD);
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000), EVENT_GROUP_PHASE_ONE);
|
||||
break;
|
||||
case EVENT_FORCE_GRIP:
|
||||
DoCastVictim(SPELL_FORCE_GRIP);
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000), EVENT_GROUP_PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SUMMON_GRAVITY_WELL:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_SUMMON_GRAVITY_WELL);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, urand(13000, 15000), EVENT_GROUP_PHASE_ONE);
|
||||
break;
|
||||
case EVENT_ENERGY_SHIELD:
|
||||
events.CancelEventGroup(EVENT_GROUP_PHASE_ONE);
|
||||
DoCast(SPELL_EARTH_FURY_ENERGY_SHIELD);
|
||||
events.ScheduleEvent(EVENT_EARTH_FURY, 0);
|
||||
break;
|
||||
case EVENT_EARTH_FURY:
|
||||
countSeismicShard = 3;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFacingTo(5.862942f);
|
||||
events.ScheduleEvent(EVENT_EARTH_FURY_FLY_UP, 1600);
|
||||
break;
|
||||
case EVENT_EARTH_FURY_FLY_UP:
|
||||
Talk(SAY_PHASE_TWO);
|
||||
me->GetMotionMaster()->MovePoint(POINT_FLY_UP, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 5);
|
||||
break;
|
||||
case EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM:
|
||||
me->GetMotionMaster()->MovePoint(POINT_ABOVE_PLATFORM, AbovePlatformPos);
|
||||
break;
|
||||
case EVENT_EARTH_FURY_CHECK_SEAT0:
|
||||
if (!vehicle->GetPassenger(0))
|
||||
DoCast(SPELL_SEISMIC_SHARD_PREPARE);
|
||||
events.ScheduleEvent(EVENT_EARTH_FURY_LAUNCH_SHARD, 1800);
|
||||
break;
|
||||
case EVENT_EARTH_FURY_LAUNCH_SHARD:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
{
|
||||
me->SetFacingToObject(target);
|
||||
DoCast(target, SPELL_SEISMIC_SHARD_TARGETING);
|
||||
DoCast(SPELL_SEISMIC_SHARD_LAUNCH);
|
||||
countSeismicShard -= 1;
|
||||
}
|
||||
events.ScheduleEvent(countSeismicShard > 0 ? EVENT_EARTH_FURY_CHECK_SEAT0 : EVENT_EARTH_FURY_FLY_DOWN, 4800);
|
||||
break;
|
||||
case EVENT_EARTH_FURY_FLY_DOWN:
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_CASTING_VISUAL);
|
||||
me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_ENERGY_SHIELD);
|
||||
Position pos = me->GetPosition();
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
|
||||
me->GetMotionMaster()->MovePoint(POINT_GROUND, pos);
|
||||
break;
|
||||
}
|
||||
case EVENT_SUMMON_WAVE_SOUTH:
|
||||
if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f))
|
||||
worldtrigger->CastSpell(worldtrigger, SPELL_SUMMON_WAVE_SOUTH);
|
||||
events.ScheduleEvent(EVENT_SUMMON_WAVE_SOUTH, 12000);
|
||||
break;
|
||||
case EVENT_SUMMON_WAVE_WEST:
|
||||
if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f))
|
||||
worldtrigger->CastSpell(worldtrigger, SPELL_SUMMON_WAVE_WEST);
|
||||
events.ScheduleEvent(EVENT_SUMMON_WAVE_WEST, 20000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 countSeismicShard;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_high_priestess_azilAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 42428 - Devout Follower
|
||||
class npc_devout_follower : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_devout_follower() : CreatureScript("npc_devout_follower") { }
|
||||
|
||||
struct npc_devout_followerAI : public ScriptedAI
|
||||
{
|
||||
npc_devout_followerAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void IsSummonedBy(Unit* summoner) override
|
||||
{
|
||||
if (summoner->GetEntry() != NPC_WORLDTRIGGER)
|
||||
return;
|
||||
|
||||
if (Unit* target = me->SelectNearestPlayer(200.0f))
|
||||
{
|
||||
me->AddThreat(target, 0.0f);
|
||||
me->SetInCombatWith(target);
|
||||
target->SetInCombatWith(me);
|
||||
DoStartMovement(target);
|
||||
me->Attack(target, true);
|
||||
}
|
||||
else
|
||||
me->GetMotionMaster()->MovePoint(POINT_NONE, summoner->GetPosition());
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_devout_followerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 42499 - Gravity Well
|
||||
class npc_gravity_well : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_gravity_well() : CreatureScript("npc_gravity_well") { }
|
||||
|
||||
struct npc_gravity_wellAI : public ScriptedAI
|
||||
{
|
||||
npc_gravity_wellAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
DoCast(SPELL_GRAVITY_WELL_VISUAL);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_WELL_AURA_DAMAGE, 3200);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_WELL_AURA_PULL, 4500);
|
||||
if (!me->GetMap()->IsHeroic())
|
||||
me->DespawnOrUnsummon(23200);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetEntry() != NPC_DEVOUT_FOLLOWER)
|
||||
return;
|
||||
|
||||
me->SetObjectScale(me->GetObjectScale() - 0.25f);
|
||||
if (me->GetObjectScale() <= 0.0f)
|
||||
me->DespawnOrUnsummon(1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_GRAVITY_WELL_AURA_DAMAGE:
|
||||
me->RemoveAurasDueToSpell(SPELL_GRAVITY_WELL_VISUAL);
|
||||
DoCast(SPELL_GRAVITY_WELL_AURA_DAMAGE);
|
||||
break;
|
||||
case EVENT_GRAVITY_WELL_AURA_PULL:
|
||||
DoCast(SPELL_GRAVITY_WELL_AURA_PULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_gravity_wellAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 42355 - Seismic Shard
|
||||
class npc_seismic_shard : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_seismic_shard() : CreatureScript("npc_seismic_shard") { }
|
||||
|
||||
struct npc_seismic_shardAI : public ScriptedAI
|
||||
{
|
||||
npc_seismic_shardAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
me->SetDisableGravity(true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
DoCast(SPELL_SEISMIC_SHARD_VISUAL);
|
||||
|
||||
Movement::MoveSplineInit init(me);
|
||||
FillPath(me->GetPosition(), init.Path());
|
||||
init.SetFly();
|
||||
init.Launch();
|
||||
|
||||
events.ScheduleEvent(EVENT_SEISMIC_SHARD_MOUNT, 2400);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SEISMIC_SHARD_MOUNT:
|
||||
if (Creature* highPriestAzil = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGH_PRIESTESS_AZIL)))
|
||||
if (Vehicle* vehicle = highPriestAzil->GetVehicleKit())
|
||||
me->EnterVehicle(highPriestAzil, vehicle->GetNextEmptySeat(0, false)->first);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
void FillPath(Position const& pos, Movement::PointsArray& path)
|
||||
{
|
||||
G3D::Vector3 point;
|
||||
|
||||
point.x = pos.GetPositionX();
|
||||
point.y = pos.GetPositionY();
|
||||
point.z = pos.GetPositionZ();
|
||||
|
||||
point.x -= 1.0f;
|
||||
path.push_back(point);
|
||||
|
||||
point.x += 1.0f;
|
||||
path.push_back(point);
|
||||
|
||||
point.z += 25.0f;
|
||||
path.push_back(point);
|
||||
|
||||
path.push_back(point);
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_seismic_shardAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 79200 - Summon Follower
|
||||
class spell_summon_wave_south : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_summon_wave_south() : SpellScriptLoader("spell_summon_wave_south") { }
|
||||
|
||||
class spell_summon_wave_south_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_summon_wave_south_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ADD_SOUTH))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
for (uint8 i = 0; i < 3; i++)
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_ADD_SOUTH, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_summon_wave_south_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_summon_wave_south_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 79196 - Summon Follower
|
||||
class spell_summon_wave_west : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_summon_wave_west() : SpellScriptLoader("spell_summon_wave_west") { }
|
||||
|
||||
class spell_summon_wave_west_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_summon_wave_west_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ADD_WEST))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
for (uint8 i = 0; i < 10; i++)
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_ADD_WEST, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_summon_wave_west_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_summon_wave_west_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 79251 - Gravity Well (casts damage spell on units within 10 yards)
|
||||
class PlayerPetOrDevoutFollowerCheck
|
||||
{
|
||||
public:
|
||||
bool operator()(WorldObject* object) const
|
||||
{
|
||||
// Valid targets are players, pets and Devout Followers
|
||||
if (Creature* creature = object->ToCreature())
|
||||
return (!creature->ToPet() && object->GetEntry() != NPC_DEVOUT_FOLLOWER);
|
||||
return (!object->ToPlayer());
|
||||
}
|
||||
};
|
||||
|
||||
class spell_gravity_well_damage_nearby : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gravity_well_damage_nearby() : SpellScriptLoader("spell_gravity_well_damage_nearby") { }
|
||||
|
||||
class spell_gravity_well_damage_nearby_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gravity_well_damage_nearby_SpellScript);
|
||||
|
||||
void SetRadiusMod()
|
||||
{
|
||||
GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3));
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
unitList.remove_if(PlayerPetOrDevoutFollowerCheck());
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->CastSpell(GetHitUnit(), SPELL_GRAVITY_WELL_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeCast += SpellCastFn(spell_gravity_well_damage_nearby_SpellScript::SetRadiusMod);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gravity_well_damage_nearby_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_gravity_well_damage_nearby_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gravity_well_damage_nearby_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 79249 - Gravity Well (damage)
|
||||
class spell_gravity_well_damage : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gravity_well_damage() : SpellScriptLoader("spell_gravity_well_damage") { }
|
||||
|
||||
class spell_gravity_well_damage_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gravity_well_damage_SpellScript);
|
||||
|
||||
void CalculateDamage(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* target = GetHitUnit();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
float distance = GetCaster()->GetDistance2d(target);
|
||||
|
||||
if (target->GetEntry() == NPC_DEVOUT_FOLLOWER)
|
||||
SetHitDamage(int32(200000 - (1000 * distance))); //need more research on this formula, damage values from sniffs: 189264, 190318, 190478, 196134, 197672, 199735
|
||||
else
|
||||
SetHitDamage(int32(4000 - (200 * distance)));
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_gravity_well_damage_SpellScript::CalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gravity_well_damage_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 79332 - Gravity Well (pull units within 10 yards)
|
||||
class PulledRecentlyCheck
|
||||
{
|
||||
public:
|
||||
bool operator()(WorldObject* object) const
|
||||
{
|
||||
return (object->ToUnit() && object->ToUnit()->HasAura(SPELL_GRAVITY_WELL_PULL));
|
||||
}
|
||||
};
|
||||
|
||||
class spell_gravity_well_pull : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gravity_well_pull() : SpellScriptLoader("spell_gravity_well_pull") { }
|
||||
|
||||
class spell_gravity_well_pull_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gravity_well_pull_SpellScript);
|
||||
|
||||
void SetRadiusMod()
|
||||
{
|
||||
GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3));
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
unitList.remove_if(PulledRecentlyCheck());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeCast += SpellCastFn(spell_gravity_well_pull_SpellScript::SetRadiusMod);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gravity_well_pull_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gravity_well_pull_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 86862 - Seismic Shard (forces target to cast 86863)
|
||||
class spell_seismic_shard_prepare : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_seismic_shard_prepare() : SpellScriptLoader("spell_seismic_shard_prepare") { }
|
||||
|
||||
class spell_seismic_shard_prepare_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_seismic_shard_prepare_SpellScript);
|
||||
|
||||
void SetTarget(WorldObject*& target)
|
||||
{
|
||||
target = GetCaster()->FindNearestCreature(NPC_SEISMIC_SHARD, 50.0f);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_seismic_shard_prepare_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_seismic_shard_prepare_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 86863 - Seismic Shard (moves shard to seat 0)
|
||||
class spell_seismic_shard_change_seat : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_seismic_shard_change_seat() : SpellScriptLoader("spell_seismic_shard_change_seat") { }
|
||||
|
||||
class spell_seismic_shard_change_seat_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_seismic_shard_change_seat_SpellScript);
|
||||
|
||||
void SetTarget(WorldObject*& target)
|
||||
{
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
target = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_HIGH_PRIESTESS_AZIL));
|
||||
}
|
||||
|
||||
void ChangeSeat(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->ExitVehicle();
|
||||
if (GetHitUnit()->IsVehicle())
|
||||
GetCaster()->EnterVehicle(GetHitUnit(), 0);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_seismic_shard_change_seat_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_seismic_shard_change_seat_SpellScript::ChangeSeat, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_seismic_shard_change_seat_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 79015 - Seismic Shard (launches shard)
|
||||
class spell_seismic_shard : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_seismic_shard() : SpellScriptLoader("spell_seismic_shard") { }
|
||||
|
||||
class spell_seismic_shard_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_seismic_shard_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Creature* target = GetHitUnit()->ToCreature();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
target->ExitVehicle();
|
||||
DynamicObject* dynamicObject = GetCaster()->GetDynObject(SPELL_SEISMIC_SHARD_TARGETING);
|
||||
target->CastSpell(dynamicObject->GetPositionX(), dynamicObject->GetPositionY(), dynamicObject->GetPositionZ(), SPELL_SEISMIC_SHARD_MISSLE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_seismic_shard_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_seismic_shard_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_high_priestess_azil()
|
||||
{
|
||||
new boss_high_priestess_azil();
|
||||
new npc_devout_follower();
|
||||
new npc_gravity_well();
|
||||
new npc_seismic_shard();
|
||||
new spell_summon_wave_south();
|
||||
new spell_summon_wave_west();
|
||||
new spell_gravity_well_damage_nearby();
|
||||
new spell_gravity_well_damage();
|
||||
new spell_gravity_well_pull();
|
||||
new spell_seismic_shard_prepare();
|
||||
new spell_seismic_shard_change_seat();
|
||||
new spell_seismic_shard();
|
||||
}
|
||||
287
src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp
Normal file
287
src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://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 "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Vehicle.h"
|
||||
#include "stonecore.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ELEMENTIUM_BULWARK = 78939,
|
||||
SPELL_GROUND_SLAM = 78903,
|
||||
SPELL_ELEMENTIUM_SPIKE_SHIELD = 78835,
|
||||
SPELL_SHATTER = 78807,
|
||||
SPELL_ENRAGE = 80467,
|
||||
|
||||
// Rupture Controller and Rupture
|
||||
SPELL_RUPTURE = 92393,
|
||||
// SPELL_RUPTURE_SUMMON_CENTER? = 95669, // summons rupture 8 yards front
|
||||
// SPELL_RUPTURE_SUMMON_LEFT? = 95348, // summons rupture 3 yards left?
|
||||
// SPELL_RUPTURE_SUMMON_RIGHT? = 92383, // summons rupture 3 yards right?
|
||||
SPELL_RUPTURE_DAMAGE = 92381,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_BOUNCER_SPIKE = 42189,
|
||||
NPC_RUPTURE_CONTROLLER = 49597,
|
||||
NPC_RUPTURE = 49576,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_ELEMENTIUM_BULWARK = 1,
|
||||
SAY_ELEMENTIUM_SPIKE_SHIELD = 2,
|
||||
SAY_ENRAGE = 3,
|
||||
SAY_DEATH = 4,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
|
||||
EVENT_ELEMENTIUM_BULWARK,
|
||||
EVENT_GROUND_SLAM,
|
||||
EVENT_ELEMENTIUM_SPIKE_SHIELD,
|
||||
EVENT_SHATTER,
|
||||
EVENT_ENRAGE,
|
||||
|
||||
EVENT_START_ATTACK,
|
||||
};
|
||||
|
||||
// TO-DO:
|
||||
// - Find heroic sniffs and spawn Ruptures using spells commented above.
|
||||
// - Make Bouncer Spikes enter ozruk without jump animation.
|
||||
|
||||
class boss_ozruk : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ozruk() : CreatureScript("boss_ozruk") { }
|
||||
|
||||
struct boss_ozrukAI : public BossAI
|
||||
{
|
||||
boss_ozrukAI(Creature* creature) : BossAI(creature, DATA_OZRUK) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
events.ScheduleEvent(EVENT_ELEMENTIUM_BULWARK, 5000);
|
||||
events.ScheduleEvent(EVENT_GROUND_SLAM, 10000);
|
||||
events.ScheduleEvent(EVENT_ELEMENTIUM_SPIKE_SHIELD, 13000);
|
||||
|
||||
RemoveBouncerSpikes();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*victim*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() != NPC_RUPTURE_CONTROLLER)
|
||||
return;
|
||||
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->CastSpell(summon, SPELL_RUPTURE, true);
|
||||
summon->DespawnOrUnsummon(10000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
|
||||
{
|
||||
if (!me->HealthBelowPctDamaged(25, damage) || me->HasAura(SPELL_ENRAGE))
|
||||
return;
|
||||
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
me->Say(SAY_ENRAGE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
me->Say(SAY_DEATH, killer); // receiver is the killer, sniff source!
|
||||
|
||||
RemoveBouncerSpikes();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_ELEMENTIUM_SPIKE_SHIELD))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ELEMENTIUM_BULWARK:
|
||||
DoCast(me, SPELL_ELEMENTIUM_BULWARK);
|
||||
Talk(SAY_ELEMENTIUM_BULWARK);
|
||||
break;
|
||||
case EVENT_GROUND_SLAM:
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_GROUND_SLAM);
|
||||
events.ScheduleEvent(EVENT_START_ATTACK, 4600);
|
||||
break;
|
||||
case EVENT_ELEMENTIUM_SPIKE_SHIELD:
|
||||
DoCast(me, SPELL_ELEMENTIUM_SPIKE_SHIELD);
|
||||
Talk(SAY_ELEMENTIUM_SPIKE_SHIELD);
|
||||
events.ScheduleEvent(EVENT_SHATTER, 10000);
|
||||
break;
|
||||
case EVENT_SHATTER:
|
||||
RemoveBouncerSpikes();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_SHATTER);
|
||||
events.ScheduleEvent(EVENT_START_ATTACK, 4600);
|
||||
// Spells are cast in same order everytime after Shatter, so we schedule them here
|
||||
events.ScheduleEvent(EVENT_ELEMENTIUM_BULWARK, urand(3000,4000));
|
||||
events.ScheduleEvent(EVENT_GROUND_SLAM, urand(7000,9000));
|
||||
events.ScheduleEvent(EVENT_ELEMENTIUM_SPIKE_SHIELD, urand(10000,12000));
|
||||
break;
|
||||
case EVENT_START_ATTACK:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void RemoveBouncerSpikes()
|
||||
{
|
||||
Vehicle* vehicle = me->GetVehicleKit();
|
||||
if (!vehicle)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < vehicle->GetAvailableSeatCount(); i++)
|
||||
if (Unit* passenger = vehicle->GetPassenger(i))
|
||||
if (Creature* creature = passenger->ToCreature())
|
||||
creature->RemoveFromWorld();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_ozrukAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 92393 - Rupture
|
||||
class spell_rupture : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rupture() : SpellScriptLoader("spell_rupture") { }
|
||||
|
||||
class spell_rupture_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_rupture_AuraScript);
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
float dist = aurEff->GetTickNumber() * 8.0f;
|
||||
|
||||
// probably hack, should use spells (see Spells enum above)
|
||||
Position pos = caster->GetNearPosition(dist, 0.0f);
|
||||
SummonRupture(caster, pos);
|
||||
|
||||
pos = caster->GetNearPosition(dist, 0.2f);
|
||||
SummonRupture(caster, pos);
|
||||
|
||||
pos = caster->GetNearPosition(dist, -0.2f);
|
||||
SummonRupture(caster, pos);
|
||||
}
|
||||
|
||||
void SummonRupture(Unit* caster, Position pos)
|
||||
{
|
||||
Creature* rupture = caster->SummonCreature(NPC_RUPTURE, pos, TEMPSUMMON_TIMED_DESPAWN, 2500);
|
||||
if (!rupture)
|
||||
return;
|
||||
|
||||
rupture->SetReactState(REACT_PASSIVE);
|
||||
rupture->CastSpell(rupture, SPELL_RUPTURE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_rupture_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_rupture_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 78835 - Elementium Spike Shield
|
||||
class spell_elementium_spike_shield : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_elementium_spike_shield() : SpellScriptLoader("spell_elementium_spike_shield") { }
|
||||
|
||||
class spell_elementium_spike_shield_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_elementium_spike_shield_SpellScript);
|
||||
|
||||
void HandleBouncerSpikes()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Vehicle* vehicle = caster->GetVehicleKit();
|
||||
if (!vehicle)
|
||||
return;
|
||||
|
||||
for (uint8 i = 0; i < vehicle->GetAvailableSeatCount(); i++)
|
||||
if (Creature* summon = caster->SummonCreature(NPC_BOUNCER_SPIKE, caster->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 10000))
|
||||
summon->EnterVehicle(caster, i);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCast += SpellCastFn(spell_elementium_spike_shield_SpellScript::HandleBouncerSpikes);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_elementium_spike_shield_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_ozruk()
|
||||
{
|
||||
new boss_ozruk();
|
||||
new spell_rupture();
|
||||
new spell_elementium_spike_shield();
|
||||
}
|
||||
599
src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp
Normal file
599
src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp
Normal file
@@ -0,0 +1,599 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://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 "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "stonecore.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_FACE_RANDOM_PLAYER = 82530,
|
||||
|
||||
// Stalactite Trigger - Trash, On Ground
|
||||
SPELL_STALACTITE_SUMMON_TRIGGER = 81028,
|
||||
|
||||
// Slabhide
|
||||
SPELL_LAVA_FISSURE = 80803,
|
||||
SPELL_SAND_BLAST = 80807,
|
||||
SPELL_STALACTITE_SUMMON = 80656,
|
||||
// SPELL_COOLDOWN_5S = 95323, Cooldown: Creature Special 1 (5s)?
|
||||
SPELL_CRYSTAL_STORM = 92305,
|
||||
SPELL_CRYSTAL_STORM_TRIGGER = 92265,
|
||||
|
||||
// Lava Fissure
|
||||
SPELL_LAVA_FISSURE_CRACK = 80798,
|
||||
SPELL_LAVA_FISSURE_ERUPTION = 80800,
|
||||
|
||||
// Stalactite Trigger - Boss
|
||||
SPELL_STALACTITE_SHADE = 80654,
|
||||
SPELL_STALACTITE_MISSLE = 80643,
|
||||
SPELL_STALACTITE_CREATE = 80647,
|
||||
};
|
||||
|
||||
enum Entries
|
||||
{
|
||||
NPC_LAVA_FISSURE = 43242,
|
||||
NPC_STALACTITE_TRIGGER_GROUND = 43357,
|
||||
NPC_STALACTITE_TRIGGER = 43159,
|
||||
GO_STALACTITE = 204337,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_STALACTITE_MISSLE,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
|
||||
// Intro events
|
||||
EVENT_ROAR_EMOTE,
|
||||
|
||||
// Slabhide combat
|
||||
EVENT_HANDLE_ROCK_WALLS,
|
||||
EVENT_LAVA_FISSURE,
|
||||
EVENT_SAND_BLAST,
|
||||
EVENT_AIR_PHASE,
|
||||
EVENT_TAKEOFF,
|
||||
EVENT_STALACTITE,
|
||||
EVENT_LAND,
|
||||
EVENT_ATTACK,
|
||||
|
||||
// Lava Fissure
|
||||
EVENT_LAVA_FISSURE_ERUPTION,
|
||||
|
||||
// Stalactite Trigger - Boss
|
||||
EVENT_STALACTITE_MISSLE,
|
||||
};
|
||||
|
||||
enum MovementPoints
|
||||
{
|
||||
POINT_NONE,
|
||||
|
||||
POINT_SLABHIDE_INTRO,
|
||||
POINT_SLABHIDE_INTRO_LAND,
|
||||
|
||||
POINT_SLABHIDE_MIDDLE,
|
||||
POINT_SLABHIDE_IN_AIR,
|
||||
POINT_SLABHIDE_LAND,
|
||||
};
|
||||
|
||||
Position const SlabhideIntroPos = { 1292.27f, 1226.16f, 265.573f };
|
||||
Position const SlabhideIntroLandPos = { 1292.352f, 1226.478f, 247.6368f, 3.630285f };
|
||||
|
||||
Position const SlabhideMiddlePos = { 1280.73f, 1212.31f, 247.3837f };
|
||||
Position const SlabhideInAirPos = { 1280.73f, 1212.31f, 257.3837f };
|
||||
Position const SlabhideLandPos = { 1282.7f, 1229.77f, 247.155f, 3.82227f };
|
||||
|
||||
class boss_slabhide : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_slabhide() : CreatureScript("boss_slabhide") { }
|
||||
|
||||
struct boss_slabhideAI : public BossAI
|
||||
{
|
||||
boss_slabhideAI(Creature* creature) : BossAI(creature, DATA_SLABHIDE)
|
||||
{
|
||||
me->setActive(true);
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
instance->SetData(DATA_SLABHIDE_INTRO, NOT_STARTED);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (instance->GetData(DATA_SLABHIDE_INTRO) == NOT_STARTED)
|
||||
return;
|
||||
|
||||
_Reset();
|
||||
DespawnAll();
|
||||
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*victim*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
events.ScheduleEvent(EVENT_HANDLE_ROCK_WALLS, 4000);
|
||||
events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
|
||||
events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 10000));
|
||||
events.ScheduleEvent(EVENT_AIR_PHASE, 10000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
// Despawn related npcs and gameobjects
|
||||
DespawnAll();
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_SLABHIDE_INTRO:
|
||||
{
|
||||
if (instance->GetData(DATA_SLABHIDE_INTRO) != NOT_STARTED)
|
||||
return;
|
||||
|
||||
instance->SetData(DATA_SLABHIDE_INTRO, IN_PROGRESS);
|
||||
|
||||
// Execute Slabhide intro event
|
||||
me->GetMotionMaster()->MovePoint(POINT_SLABHIDE_INTRO, SlabhideIntroPos);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case POINT_SLABHIDE_INTRO:
|
||||
me->SetFacingTo(SlabhideIntroLandPos.GetOrientation());
|
||||
me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_INTRO_LAND, SlabhideIntroLandPos);
|
||||
break;
|
||||
case POINT_SLABHIDE_INTRO_LAND:
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetHover(false);
|
||||
me->SetHomePosition(SlabhideIntroLandPos);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
instance->SetData(DATA_SLABHIDE_INTRO, DONE);
|
||||
break;
|
||||
case POINT_SLABHIDE_MIDDLE:
|
||||
events.ScheduleEvent(EVENT_TAKEOFF, 100);
|
||||
break;
|
||||
case POINT_SLABHIDE_IN_AIR:
|
||||
events.ScheduleEvent(EVENT_STALACTITE, 400);
|
||||
break;
|
||||
case POINT_SLABHIDE_LAND:
|
||||
//DoCast(SPELL_COOLDOWN_5S); // unknown purpose
|
||||
events.ScheduleEvent(EVENT_ATTACK, 1200);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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_HANDLE_ROCK_WALLS: // Close rock walls
|
||||
instance->SetData(DATA_SLABHIDE_ROCK_WALL, false);
|
||||
break;
|
||||
case EVENT_LAVA_FISSURE:
|
||||
DoCast(SPELL_LAVA_FISSURE);
|
||||
events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
|
||||
break;
|
||||
case EVENT_SAND_BLAST:
|
||||
DoCast(SPELL_SAND_BLAST);
|
||||
events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 11000));
|
||||
break;
|
||||
case EVENT_AIR_PHASE:
|
||||
events.Reset();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->MovePoint(POINT_SLABHIDE_MIDDLE, SlabhideMiddlePos);
|
||||
events.ScheduleEvent(EVENT_AIR_PHASE, 60000);
|
||||
break;
|
||||
case EVENT_TAKEOFF:
|
||||
me->GetMotionMaster()->MoveTakeoff(POINT_SLABHIDE_IN_AIR, SlabhideInAirPos);
|
||||
break;
|
||||
case EVENT_STALACTITE:
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetHover(true);
|
||||
|
||||
DoCast(SPELL_STALACTITE_SUMMON);
|
||||
|
||||
events.ScheduleEvent(EVENT_LAND, 8000);
|
||||
break;
|
||||
case EVENT_LAND:
|
||||
{
|
||||
Position pos = me->GetPosition();
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
|
||||
me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_LAND, pos);
|
||||
break;
|
||||
}
|
||||
case EVENT_ATTACK:
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetHover(false);
|
||||
|
||||
events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
|
||||
events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 10000));
|
||||
DoCast(SPELL_CRYSTAL_STORM);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
void DespawnAll()
|
||||
{
|
||||
// Despawn stalactite triggers npcs
|
||||
std::list<Creature*> listStalactiteTrigger;
|
||||
me->GetCreatureListWithEntryInGrid(listStalactiteTrigger, NPC_STALACTITE_TRIGGER, 200.0f);
|
||||
if (!listStalactiteTrigger.empty())
|
||||
for (std::list<Creature*>::const_iterator itr = listStalactiteTrigger.begin(); itr != listStalactiteTrigger.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
|
||||
// Despawn stalactite objects
|
||||
std::list<GameObject*> listStalactite;
|
||||
me->GetGameObjectListWithEntryInGrid(listStalactite, GO_STALACTITE, 200.0f);
|
||||
if (!listStalactite.empty())
|
||||
for (std::list<GameObject*>::const_iterator itr = listStalactite.begin(); itr != listStalactite.end(); ++itr)
|
||||
(*itr)->Delete();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<boss_slabhideAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 43242 - Lava Fissure
|
||||
class npc_lava_fissure : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_lava_fissure() : CreatureScript("npc_lava_fissure") { }
|
||||
|
||||
struct npc_lava_fissureAI : public ScriptedAI
|
||||
{
|
||||
npc_lava_fissureAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->CastSpell(me, SPELL_LAVA_FISSURE_CRACK, true);
|
||||
events.ScheduleEvent(EVENT_LAVA_FISSURE_ERUPTION, 6000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_LAVA_FISSURE_ERUPTION:
|
||||
me->RemoveAurasDueToSpell(SPELL_LAVA_FISSURE_CRACK);
|
||||
me->CastSpell(me, SPELL_LAVA_FISSURE_ERUPTION, true);
|
||||
me->DespawnOrUnsummon(14000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_lava_fissureAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 43159 - Stalactite Trigger - Boss
|
||||
class npc_stalactite_trigger : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_stalactite_trigger() : CreatureScript("npc_stalactite_trigger") { }
|
||||
|
||||
struct npc_stalactite_triggerAI : public ScriptedAI
|
||||
{
|
||||
npc_stalactite_triggerAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetDisableGravity(true);
|
||||
me->CastSpell(me, SPELL_STALACTITE_SHADE, true);
|
||||
events.ScheduleEvent(EVENT_STALACTITE_MISSLE, 5600);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_STALACTITE_MISSLE:
|
||||
DoCast(SPELL_STALACTITE_MISSLE);
|
||||
me->DespawnOrUnsummon(11000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_stalactite_triggerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 81035 - Stalactite (check if player is near to summon stalactite)
|
||||
class NotPlayerCheck
|
||||
{
|
||||
public:
|
||||
bool operator()(WorldObject* object) const
|
||||
{
|
||||
return (object->GetTypeId() != TYPEID_PLAYER);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_s81035_stalactite : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_s81035_stalactite() : SpellScriptLoader("spell_s81035_stalactite") { }
|
||||
|
||||
class spell_s81035_stalactite_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_s81035_stalactite_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(NotPlayerCheck());
|
||||
}
|
||||
|
||||
void SummonStalactiteTrigger()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
caster->CastSpell(caster, SPELL_STALACTITE_SUMMON_TRIGGER, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_s81035_stalactite_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnHit += SpellHitFn(spell_s81035_stalactite_SpellScript::SummonStalactiteTrigger);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_s81035_stalactite_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 81028 - Stalactite (summons "Stalactite Trigger - Boss", 20 yard radius)
|
||||
// 80650 - Stalactite (summons "Stalactite Trigger - Boss", 40 yard radius)
|
||||
class spell_s81028_s80650_stalactite : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_s81028_s80650_stalactite() : SpellScriptLoader("spell_s81028_s80650_stalactite") { }
|
||||
|
||||
class spell_s81028_s80650_stalactite_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_s81028_s80650_stalactite_SpellScript);
|
||||
|
||||
void ModDestHeight(SpellDestination& dest)
|
||||
{
|
||||
// All stalactite triggers should have Z position 301.3837f, but no way to relocate (not relocateoffset!) height only.
|
||||
Position offset = { 0.0f, 0.0f, 50.0f, 0.0f };
|
||||
dest.RelocateOffset(offset);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_s81028_s80650_stalactite_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_s81028_s80650_stalactite_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 80654 - Stalactite (creates visual shade on ground)
|
||||
// 80643/92653 - Stalactite (launches missle to the ground)
|
||||
// 80647/92309 - Stalactite (creates stalactite object)
|
||||
class spell_stalactite_mod_dest_height : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_stalactite_mod_dest_height() : SpellScriptLoader("spell_stalactite_mod_dest_height") { }
|
||||
|
||||
class spell_stalactite_mod_dest_height_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_stalactite_mod_dest_height_SpellScript);
|
||||
|
||||
void ModDestHeight(SpellDestination& dest)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Position pos = caster->GetPosition();
|
||||
pos.m_positionZ = caster->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f);
|
||||
dest.Relocate(pos);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_stalactite_mod_dest_height_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_stalactite_mod_dest_height_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 92306 - Crystal storm (heroic mode check)
|
||||
class spell_s92306_crystal_storm : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_s92306_crystal_storm() : SpellScriptLoader("spell_s92306_crystal_storm") { }
|
||||
|
||||
class spell_s92306_crystal_storm_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_s92306_crystal_storm_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_CRYSTAL_STORM_TRIGGER))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDummyEffect(SpellEffIndex /*eff*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (caster->GetMap()->IsHeroic())
|
||||
caster->CastSpell(caster, SPELL_CRYSTAL_STORM_TRIGGER, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_s92306_crystal_storm_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_s92306_crystal_storm_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 92300 - Crystal Storm (damage)
|
||||
class BehindObjectCheck
|
||||
{
|
||||
public:
|
||||
BehindObjectCheck(Unit* caster, std::list<GameObject*> objectList) : caster(caster), objectList(objectList) { }
|
||||
|
||||
bool operator()(WorldObject* unit)
|
||||
{
|
||||
for (std::list<GameObject*>::const_iterator itr = objectList.begin(); itr != objectList.end(); ++itr)
|
||||
if (!(*itr)->IsInvisibleDueToDespawn() && (*itr)->IsInBetween(caster, unit, 1.5f))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Unit* caster;
|
||||
std::list<GameObject*> objectList;
|
||||
};
|
||||
|
||||
class spell_s92300_crystal_storm : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_s92300_crystal_storm() : SpellScriptLoader("spell_s92300_crystal_storm") { }
|
||||
|
||||
class spell_s92300_crystal_storm_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_s92300_crystal_storm_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
std::list<GameObject*> goList;
|
||||
caster->GetGameObjectListWithEntryInGrid(goList, GO_STALACTITE, 40.0f);
|
||||
if (goList.empty())
|
||||
return;
|
||||
|
||||
unitList.remove_if(BehindObjectCheck(caster, goList));
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_s92300_crystal_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_s92300_crystal_storm_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_slabhide()
|
||||
{
|
||||
new boss_slabhide();
|
||||
new npc_lava_fissure();
|
||||
new npc_stalactite_trigger();
|
||||
new spell_s81035_stalactite();
|
||||
new spell_s81028_s80650_stalactite();
|
||||
new spell_stalactite_mod_dest_height();
|
||||
new spell_s92306_crystal_storm();
|
||||
new spell_s92300_crystal_storm();
|
||||
}
|
||||
262
src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp
Normal file
262
src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
*
|
||||
* 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 "Player.h"
|
||||
#include "CreatureGroups.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "stonecore.h"
|
||||
|
||||
#define MAX_ENCOUNTER 4
|
||||
|
||||
/* Stonecore encounters:
|
||||
0 - Corborus
|
||||
1 - Slabhide
|
||||
2 - Ozruk
|
||||
3 - High Priestess Azil
|
||||
*/
|
||||
|
||||
// TO-DO:
|
||||
// - Find out spell IDs for both Stonecore Teleporters (spellclick).
|
||||
|
||||
class instance_stonecore : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_stonecore() : InstanceMapScript(SCScriptName, 725) { }
|
||||
|
||||
struct instance_stonecore_InstanceScript : public InstanceScript
|
||||
{
|
||||
instance_stonecore_InstanceScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTER);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GAMEOBJECT_CORBORUS_ROCKDOOR:
|
||||
corborusRockDoorGUID = go->GetGUID();
|
||||
go->SetGoState(GetBossState(DATA_CORBORUS) != DONE ? GO_STATE_READY : GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GAMEOBJECT_SLABHIDE_ROCK_WALL:
|
||||
slabhideRockWallGUIDs.push_back(go->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_MILLHOUSE_MANASTORM:
|
||||
millhouseGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_CORBORUS:
|
||||
corobrusGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_SLABHIDE:
|
||||
slabhideGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HIGH_PRIESTESS_AZIL:
|
||||
highPriestessAzilGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_STONECORE_TELEPORTER:
|
||||
case NPC_STONECORE_TELEPORTER_2:
|
||||
if (GetBossState(DATA_SLABHIDE) != DONE)
|
||||
stonecoreTeleporterGUID[creature->GetEntry() - NPC_STONECORE_TELEPORTER] = creature->GetGUID();
|
||||
else // If Slabhide is already dead, no need to store teleporter guids
|
||||
{
|
||||
creature->CastSpell(creature, SPELL_TELEPORTER_ACTIVE_VISUAL, true);
|
||||
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if creature is part of Millhouse event
|
||||
creature->SearchFormation();
|
||||
if (CreatureGroup* group = creature->GetFormation()) // TO-DO: Fix formations
|
||||
{
|
||||
switch (group->GetId())
|
||||
{
|
||||
case CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH:
|
||||
millhouseTrashGUIDs.push_back(creature->GetGUID());
|
||||
break;
|
||||
case CREATURE_FORMATION_MILLHOUSE_EVENT_LAST_GROUP:
|
||||
millhouseLastGroupGUIDs.push_back(creature->GetGUID());
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
creature->SetMeleeAnimKitId(ANIM_READY2H);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SLABHIDE:
|
||||
// Open rock walls (Slabhide AI handles closing because it must be delayed)
|
||||
if (state != IN_PROGRESS)
|
||||
SetData(DATA_SLABHIDE_ROCK_WALL, true);
|
||||
|
||||
// Activate teleporters
|
||||
if (state == DONE)
|
||||
{
|
||||
for (int8 i = 0; i < MAX_STONECORE_TELEPORTERS; i++)
|
||||
{
|
||||
if (Creature* teleporter = GetCreature(stonecoreTeleporterGUID[i]))
|
||||
{
|
||||
teleporter->CastSpell(teleporter, SPELL_TELEPORTER_ACTIVE_VISUAL, true);
|
||||
teleporter->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return InstanceScript::SetBossState(type, state);
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SLABHIDE_INTRO:
|
||||
return slabhideIntro;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_MILLHOUSE_EVENT_FACE:
|
||||
MillhouseEvent_Face();
|
||||
break;
|
||||
case DATA_MILLHOUSE_EVENT_KNOCKBACK:
|
||||
MillhouseEvent_Knockback();
|
||||
break;
|
||||
case DATA_MILLHOUSE_EVENT_DESPAWN:
|
||||
MillhouseEvent_Despawn();
|
||||
break;
|
||||
case DATA_SLABHIDE_INTRO:
|
||||
slabhideIntro = EncounterState(data);
|
||||
break;
|
||||
case DATA_SLABHIDE_ROCK_WALL: // Handles rock walls
|
||||
for (std::vector<ObjectGuid>::iterator itr = slabhideRockWallGUIDs.begin(); itr != slabhideRockWallGUIDs.end(); ++itr)
|
||||
HandleGameObject((*itr), data ? true : false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_MILLHOUSE_MANASTORM:
|
||||
return millhouseGUID;
|
||||
case GAMEOBJECT_CORBORUS_ROCKDOOR:
|
||||
return corborusRockDoorGUID;
|
||||
case DATA_CORBORUS:
|
||||
return corobrusGUID;
|
||||
case DATA_SLABHIDE:
|
||||
return slabhideGUID;
|
||||
case DATA_HIGH_PRIESTESS_AZIL:
|
||||
return highPriestessAzilGUID;
|
||||
case NPC_STONECORE_TELEPORTER:
|
||||
case NPC_STONECORE_TELEPORTER_2:
|
||||
return stonecoreTeleporterGUID[type - NPC_STONECORE_TELEPORTER];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
private:
|
||||
// Face Millhouse and other nearby mobs to Corborus
|
||||
void MillhouseEvent_Face()
|
||||
{
|
||||
if (Creature* Millhouse = instance->GetCreature(millhouseGUID))
|
||||
Millhouse->SetFacingTo(1.570796f);
|
||||
for (GuidVector::const_iterator i = millhouseLastGroupGUIDs.begin(); i != millhouseLastGroupGUIDs.end(); ++i)
|
||||
if (Creature* creature = instance->GetCreature(*i))
|
||||
creature->SetFacingTo(1.570796f);
|
||||
}
|
||||
|
||||
// Knock back Millhouse and other mobs
|
||||
void MillhouseEvent_Knockback()
|
||||
{
|
||||
if (Creature* Millhouse = instance->GetCreature(millhouseGUID))
|
||||
Millhouse->CastSpell(Millhouse, SPELL_RING_WYRM_KNOCKBACK, true);
|
||||
for (GuidVector::const_iterator itr = millhouseLastGroupGUIDs.begin(); itr != millhouseLastGroupGUIDs.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->CastSpell(creature, SPELL_RING_WYRM_KNOCKBACK, true);
|
||||
}
|
||||
|
||||
// Despawn all mobs
|
||||
void MillhouseEvent_Despawn()
|
||||
{
|
||||
if (Creature* Millhouse = instance->GetCreature(millhouseGUID))
|
||||
Millhouse->DespawnOrUnsummon(3000);
|
||||
for (GuidVector::const_iterator itr = millhouseTrashGUIDs.begin(); itr != millhouseTrashGUIDs.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->DespawnOrUnsummon(3000);
|
||||
for (GuidVector::const_iterator itr = millhouseLastGroupGUIDs.begin(); itr != millhouseLastGroupGUIDs.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->DespawnOrUnsummon(3000);
|
||||
}
|
||||
|
||||
ObjectGuid millhouseGUID;
|
||||
GuidVector millhouseTrashGUIDs;
|
||||
GuidVector millhouseLastGroupGUIDs;
|
||||
ObjectGuid corborusRockDoorGUID;
|
||||
ObjectGuid corobrusGUID;
|
||||
ObjectGuid slabhideGUID;
|
||||
ObjectGuid highPriestessAzilGUID;
|
||||
ObjectGuid stonecoreTeleporterGUID[2];
|
||||
GuidVector slabhideRockWallGUIDs;
|
||||
|
||||
EncounterState slabhideIntro;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_stonecore_InstanceScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_stonecore()
|
||||
{
|
||||
new instance_stonecore();
|
||||
}
|
||||
440
src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
Normal file
440
src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://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 "ObjectGuid.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "stonecore.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
// Millhouse Manastorm
|
||||
SAY_MILLHOUSE_EVENT_1 = 0,
|
||||
SAY_MILLHOUSE_EVENT_2 = 1,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_GENERIC_TRIGGER_LAB = 40350,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Millhouse Manastorm
|
||||
SPELL_SHADOW_BOLT = 81439,
|
||||
SPELL_FROSTBOLT_VOLLEY = 81440,
|
||||
SPELL_SHADOWFURY = 81441,
|
||||
SPELL_FEAR = 81442,
|
||||
// SPELL_MILLHOUSE_SAFE_CHECK = 81213, // unknown purpose
|
||||
SPELL_CLEAR_ALL_DEBUFFS = 34098,
|
||||
SPELL_BLUR = 81216,
|
||||
SPELL_ANCHOR_HERE = 45313,
|
||||
SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND = 81220,
|
||||
SPELL_IMPENDING_DOOM = 86838,
|
||||
SPELL_IMPENDING_DOOM_CHANNEL = 86830,
|
||||
|
||||
// SPELL_PORTAL_VISUAL = 79754,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
|
||||
// Millhouse Manastorm
|
||||
EVENT_FROSTBOLT_VOLLEY,
|
||||
EVENT_SHADOWFURY,
|
||||
EVENT_FEAR,
|
||||
|
||||
EVENT_READY_FOR_COMBAT,
|
||||
EVENT_CAST_IMPENDING_DOOM,
|
||||
EVENT_INTERRUPT_IMPENDING_DOOM,
|
||||
};
|
||||
|
||||
enum Phase
|
||||
{
|
||||
PHASE_NONE,
|
||||
|
||||
PHASE_MILLHOUSE_GROUP_1,
|
||||
PHASE_MILLHOUSE_GROUP_2,
|
||||
PHASE_MILLHOUSE_GROUP_3,
|
||||
PHASE_MILLHOUSE_GROUP_4,
|
||||
|
||||
PHASE_MASK_MILLHOUSE_GROUP_1 = (1 << (PHASE_MILLHOUSE_GROUP_1 - 1)),
|
||||
PHASE_MASK_MILLHOUSE_GROUP_2 = (1 << (PHASE_MILLHOUSE_GROUP_2 - 1)),
|
||||
PHASE_MASK_MILLHOUSE_GROUP_3 = (1 << (PHASE_MILLHOUSE_GROUP_3 - 1)),
|
||||
PHASE_MASK_MILLHOUSE_GROUP_4 = (1 << (PHASE_MILLHOUSE_GROUP_4 - 1)),
|
||||
};
|
||||
|
||||
enum MovementPoints
|
||||
{
|
||||
POINT_NONE,
|
||||
|
||||
POINT_MILLHOUSE_GROUP_2,
|
||||
POINT_MILLHOUSE_GROUP_3,
|
||||
POINT_MILLHOUSE_GROUP_4,
|
||||
};
|
||||
|
||||
// Millhouse trash groups
|
||||
Position const MillhousePointGroup2 = { 977.3045f, 895.2347f, 306.3298f };
|
||||
Position const MillhousePointGroup3 = { 1049.823f, 871.4349f, 295.006f };
|
||||
Position const MillhousePointGroup4 = { 1149.04f, 884.431f, 284.9406f };
|
||||
|
||||
// 43391 - Millhouse Manastorm
|
||||
class npc_sc_millhouse_manastorm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_sc_millhouse_manastorm() : CreatureScript("npc_sc_millhouse_manastorm") { }
|
||||
|
||||
struct npc_sc_millhouse_manastormAI : public ScriptedAI
|
||||
{
|
||||
npc_sc_millhouse_manastormAI(Creature* creature) : ScriptedAI(creature),
|
||||
_instance(creature->GetInstanceScript())
|
||||
{
|
||||
events.SetPhase(PHASE_MILLHOUSE_GROUP_1);
|
||||
}
|
||||
|
||||
void ScheduleEvents()
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SHADOWFURY, 3000);
|
||||
events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 5000);
|
||||
events.ScheduleEvent(EVENT_FEAR, 8000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
damage = me->GetHealth() - 1;
|
||||
|
||||
if (!HealthBelowPct(50) || me->HasAura(SPELL_BLUR))
|
||||
return;
|
||||
|
||||
switch (events.GetPhaseMask())
|
||||
{
|
||||
case PHASE_MASK_MILLHOUSE_GROUP_1:
|
||||
events.Reset();
|
||||
events.SetPhase(PHASE_MILLHOUSE_GROUP_2);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
|
||||
DoCast(me, SPELL_BLUR);
|
||||
Talk(SAY_MILLHOUSE_EVENT_1);
|
||||
me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_2, MillhousePointGroup2);
|
||||
break;
|
||||
case PHASE_MASK_MILLHOUSE_GROUP_2:
|
||||
events.Reset();
|
||||
events.SetPhase(PHASE_MILLHOUSE_GROUP_3);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
|
||||
DoCast(me, SPELL_BLUR);
|
||||
Talk(SAY_MILLHOUSE_EVENT_1);
|
||||
me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_3, MillhousePointGroup3);
|
||||
break;
|
||||
case PHASE_MASK_MILLHOUSE_GROUP_3:
|
||||
events.Reset();
|
||||
events.SetPhase(PHASE_MILLHOUSE_GROUP_4);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
|
||||
DoCast(me, SPELL_BLUR);
|
||||
me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_4, MillhousePointGroup4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 pointId) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (pointId < POINT_MILLHOUSE_GROUP_2 || pointId > POINT_MILLHOUSE_GROUP_4)
|
||||
return;
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->CombatStop(true);
|
||||
me->DeleteThreatList();
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
switch (pointId)
|
||||
{
|
||||
case POINT_MILLHOUSE_GROUP_2:
|
||||
if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f))
|
||||
me->SetFacingToObject(worldtrigger); // o: 5.497359f (sniff data)
|
||||
me->CastSpell(me, SPELL_ANCHOR_HERE, true);
|
||||
me->AddAura(SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, me);
|
||||
events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000);
|
||||
break;
|
||||
case POINT_MILLHOUSE_GROUP_3:
|
||||
me->SetFacingTo(5.931499f);
|
||||
me->CastSpell(me, SPELL_ANCHOR_HERE, true);
|
||||
me->AddAura(SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, me);
|
||||
events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000);
|
||||
break;
|
||||
case POINT_MILLHOUSE_GROUP_4:
|
||||
me->SetFacingTo(3.455752f);
|
||||
me->CastSpell(me, SPELL_ANCHOR_HERE, true);
|
||||
Talk(SAY_MILLHOUSE_EVENT_2);
|
||||
events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 1000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
// Only update events if Millhouse is aggressive
|
||||
if (me->GetReactState() != REACT_AGGRESSIVE)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
// Impending Doom is exception because it needs to be interrupted.
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) && !me->GetCurrentSpell(SPELL_IMPENDING_DOOM))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FROSTBOLT_VOLLEY:
|
||||
DoCast(SPELL_FROSTBOLT_VOLLEY);
|
||||
events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 7000);
|
||||
break;
|
||||
case EVENT_SHADOWFURY:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
DoCast(target, SPELL_SHADOWFURY);
|
||||
events.ScheduleEvent(EVENT_SHADOWFURY, 7000);
|
||||
break;
|
||||
case EVENT_FEAR:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
DoCast(target, SPELL_FEAR);
|
||||
events.ScheduleEvent(EVENT_FEAR, 18000);
|
||||
break;
|
||||
case EVENT_READY_FOR_COMBAT:
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
ScheduleEvents();
|
||||
break;
|
||||
case EVENT_CAST_IMPENDING_DOOM:
|
||||
DoCast(SPELL_IMPENDING_DOOM);
|
||||
DoCast(SPELL_IMPENDING_DOOM_CHANNEL);
|
||||
events.ScheduleEvent(EVENT_INTERRUPT_IMPENDING_DOOM, urand(15000,20000));
|
||||
break;
|
||||
case EVENT_INTERRUPT_IMPENDING_DOOM:
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->RemoveAllAuras();
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_KNOCKDOWN);
|
||||
events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 3000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoSpellAttackIfReady(SPELL_SHADOW_BOLT);
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetInstanceAI<npc_sc_millhouse_manastormAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 81459 - Force of Earth
|
||||
class spell_force_of_earth : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_force_of_earth() : SpellScriptLoader("spell_force_of_earth") { }
|
||||
|
||||
class spell_force_of_earth_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_force_of_earth_SpellScript);
|
||||
|
||||
void DummyEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->SetDisplayId(26693); // can be moved to SAI part, need sniffs to see what this dummy does (note: npc 43552)
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectLaunch += SpellEffectFn(spell_force_of_earth_SpellScript::DummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_force_of_earth_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 45313 - Anchor Here
|
||||
class spell_sc_anchor_here : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_sc_anchor_here() : SpellScriptLoader("spell_sc_anchor_here") { }
|
||||
|
||||
class spell_sc_anchor_here_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sc_anchor_here_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Creature* creature = GetHitUnit()->ToCreature())
|
||||
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_sc_anchor_here_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_sc_anchor_here_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 93167 - Twilight Documents
|
||||
class spell_sc_twilight_documents : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_sc_twilight_documents() : SpellScriptLoader("spell_sc_twilight_documents") { }
|
||||
|
||||
class spell_sc_twilight_documents_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sc_twilight_documents_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/) override
|
||||
{
|
||||
if (!sObjectMgr->GetGameObjectTemplate(GAMEOBJECT_TWILIGHT_DOCUMENTS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetTarget(WorldObject*& target)
|
||||
{
|
||||
target = GetCaster()->FindNearestCreature(NPC_GENERIC_TRIGGER_LAB, 100.0f);
|
||||
}
|
||||
|
||||
void SpawnGameObject(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (WorldLocation* loc = GetHitDest())
|
||||
GetCaster()->SummonGameObject(GAMEOBJECT_TWILIGHT_DOCUMENTS, loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), loc->GetOrientation(), 0, 0, 0, 0, 7200);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_sc_twilight_documents_SpellScript::SetTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY);
|
||||
OnEffectHit += SpellEffectFn(spell_sc_twilight_documents_SpellScript::SpawnGameObject, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_sc_twilight_documents_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 81008 - Quake
|
||||
class JumpCheck
|
||||
{
|
||||
public:
|
||||
bool operator()(WorldObject* object) const
|
||||
{
|
||||
Player* player = object->ToPlayer();
|
||||
return (player && player->HasUnitState(UNIT_STATE_JUMPING));
|
||||
}
|
||||
};
|
||||
|
||||
class spell_sc_quake : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_sc_quake() : SpellScriptLoader("spell_sc_quake") { }
|
||||
|
||||
class spell_sc_quake_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sc_quake_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
{
|
||||
unitList.remove_if(JumpCheck());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sc_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_sc_quake_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class at_sc_corborus_intro : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_sc_corborus_intro() : AreaTriggerScript("at_sc_corborus_intro") { }
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
if (Creature* corborus = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_CORBORUS)))
|
||||
corborus->AI()->DoAction(ACTION_CORBORUS_INTRO);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class at_sc_slabhide_intro : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_sc_slabhide_intro() : AreaTriggerScript("at_sc_slabhide_intro") { }
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
if (Creature* slabhide = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SLABHIDE)))
|
||||
slabhide->AI()->DoAction(ACTION_SLABHIDE_INTRO);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_stonecore()
|
||||
{
|
||||
new npc_sc_millhouse_manastorm();
|
||||
new spell_force_of_earth();
|
||||
new spell_sc_anchor_here();
|
||||
new spell_sc_twilight_documents();
|
||||
new spell_sc_quake();
|
||||
new at_sc_corborus_intro();
|
||||
new at_sc_slabhide_intro();
|
||||
}
|
||||
72
src/server/scripts/Maelstrom/Stonecore/stonecore.h
Normal file
72
src/server/scripts/Maelstrom/Stonecore/stonecore.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 TrinityCore <http://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 DEF_STONECORE_H
|
||||
#define DEF_STONECORE_H
|
||||
|
||||
#define SCScriptName "instance_stonecore"
|
||||
#define DataHeader "SC"
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
// Encounter States/Boss GUIDs
|
||||
DATA_CORBORUS,
|
||||
DATA_SLABHIDE,
|
||||
DATA_OZRUK,
|
||||
DATA_HIGH_PRIESTESS_AZIL,
|
||||
|
||||
// Additional Data
|
||||
DATA_MILLHOUSE_MANASTORM,
|
||||
DATA_MILLHOUSE_EVENT_FACE,
|
||||
DATA_MILLHOUSE_EVENT_KNOCKBACK,
|
||||
DATA_MILLHOUSE_EVENT_DESPAWN,
|
||||
|
||||
DATA_SLABHIDE_INTRO,
|
||||
DATA_SLABHIDE_ROCK_WALL,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_CORBORUS_INTRO,
|
||||
ACTION_SLABHIDE_INTRO,
|
||||
|
||||
NPC_WORLDTRIGGER = 22515,
|
||||
NPC_MILLHOUSE_MANASTORM = 43391,
|
||||
|
||||
NPC_CORBORUS = 43438,
|
||||
NPC_SLABHIDE = 43214,
|
||||
NPC_OZRUK = 42188,
|
||||
NPC_HIGH_PRIESTESS_AZIL = 42333,
|
||||
|
||||
// Stonecore Teleporter misc
|
||||
MAX_STONECORE_TELEPORTERS = 2,
|
||||
NPC_STONECORE_TELEPORTER = 51396, // Entrance teleporter
|
||||
NPC_STONECORE_TELEPORTER_2 = 51397, // Slabhide teleporter
|
||||
SPELL_TELEPORTER_ACTIVE_VISUAL = 95298,
|
||||
|
||||
GAMEOBJECT_TWILIGHT_DOCUMENTS = 207415,
|
||||
GAMEOBJECT_CORBORUS_ROCKDOOR = 207343,
|
||||
GAMEOBJECT_SLABHIDE_ROCK_WALL = 204381,
|
||||
|
||||
SPELL_RING_WYRM_KNOCKBACK = 81235,
|
||||
|
||||
// Creature Formation IDs
|
||||
CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH = 340418,
|
||||
CREATURE_FORMATION_MILLHOUSE_EVENT_LAST_GROUP = 340492,
|
||||
};
|
||||
|
||||
#endif // DEF_STONECORE
|
||||
Reference in New Issue
Block a user