mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-27 20:32:21 +01:00
Merge branch '4.3.4' of https://github.com/TrinityCore/TrinityCore into phases
Conflicts: sql/updates/world/2014_10_30_00_world.sql
This commit is contained in:
@@ -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")
|
||||
|
||||
323
src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
Normal file
323
src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 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 = instance->GetCreature(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->SetData(DATA_HANDLE_CORBORUS_ROCKDOOR, 0);
|
||||
if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 60.0f))
|
||||
worldtrigger->CastSpell(worldtrigger, SPELL_DOOR_BREAK, true);
|
||||
|
||||
// Make Corborus charge
|
||||
DoCast(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 = instance->GetCreature(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)
|
||||
{
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->CastSpell(summon, SPELL_TRASHING_CHARGE_EFFECT);
|
||||
summon->DespawnOrUnsummon(6000);
|
||||
}
|
||||
|
||||
BossAI::JustSummoned(summon);
|
||||
}
|
||||
|
||||
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(me, 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(me, 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,726 @@
|
||||
/*
|
||||
* 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_PREPARE_SHARD,
|
||||
EVENT_EARTH_FURY_LAUNCH_SHARD,
|
||||
EVENT_EARTH_FURY_FLY_DOWN,
|
||||
EVENT_START_ATTACK,
|
||||
|
||||
EVENT_LAUNCH,
|
||||
EVENT_SEISMIC_SHARD_MOUNT
|
||||
};
|
||||
|
||||
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 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) { }
|
||||
|
||||
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);
|
||||
events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000,10000));
|
||||
events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000);
|
||||
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(me, SPELL_ENERGY_SHIELD);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
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);
|
||||
DoStartMovement(me->GetVictim());
|
||||
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(me, SPELL_EARTH_FURY_CASTING_VISUAL);
|
||||
DoCast(me, SPELL_SEISMIC_SHARD_SUMMON_1);
|
||||
DoCast(me, SPELL_SEISMIC_SHARD_SUMMON_2);
|
||||
DoCast(me, SPELL_SEISMIC_SHARD_SUMMON_3);
|
||||
events.ScheduleEvent(EVENT_EARTH_FURY_PREPARE_SHARD, 6700);
|
||||
break;
|
||||
case POINT_GROUND:
|
||||
DoCast(me, SPELL_EJECT_ALL_PASSENGERS);
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoStartMovement(me->GetVictim());
|
||||
// Find more sniffs to correct these timers, this was copied from Reset() void.
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000);
|
||||
events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000, 10000));
|
||||
events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000);
|
||||
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));
|
||||
break;
|
||||
case EVENT_FORCE_GRIP:
|
||||
DoCastVictim(SPELL_FORCE_GRIP);
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000));
|
||||
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));
|
||||
break;
|
||||
case EVENT_ENERGY_SHIELD:
|
||||
events.Reset();
|
||||
DoCast(me, 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_PREPARE_SHARD:
|
||||
DoCast(me, 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(me, SPELL_SEISMIC_SHARD_LAUNCH);
|
||||
countSeismicShard -= 1;
|
||||
}
|
||||
events.ScheduleEvent(countSeismicShard > 0 ? EVENT_EARTH_FURY_PREPARE_SHARD : 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)
|
||||
{
|
||||
DoCast(me, 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(me, SPELL_GRAVITY_WELL_AURA_DAMAGE);
|
||||
break;
|
||||
case EVENT_GRAVITY_WELL_AURA_PULL:
|
||||
DoCast(me, 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);
|
||||
DoCast(me, 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 (int i = 0; i < 3; i++)
|
||||
caster->CastSpell(caster, 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 (int i = 0; i < 10; i++)
|
||||
caster->CastSpell(caster, 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 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 Register() override
|
||||
{
|
||||
BeforeCast += SpellCastFn(spell_gravity_well_pull_SpellScript::SetRadiusMod);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gravity_well_pull_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 86863 - Seismic Shard (makes shard reenter Azil)
|
||||
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 ExitVehicle()
|
||||
{
|
||||
GetCaster()->ExitVehicle();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
BeforeCast += SpellCastFn(spell_seismic_shard_change_seat_SpellScript::ExitVehicle);
|
||||
}
|
||||
};
|
||||
|
||||
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_change_seat();
|
||||
new spell_seismic_shard();
|
||||
}
|
||||
274
src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp
Normal file
274
src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*victim*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (summon->GetEntry() == NPC_RUPTURE_CONTROLLER)
|
||||
{
|
||||
summon->CastSpell(summon, SPELL_RUPTURE, true);
|
||||
summon->DespawnOrUnsummon(10000);
|
||||
}
|
||||
|
||||
BossAI::JustSummoned(summon);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
|
||||
{
|
||||
if (!me->HealthBelowPctDamaged(25, damage) || me->HasAura(SPELL_ENRAGE))
|
||||
return;
|
||||
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Talk(SAY_ENRAGE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
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_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:
|
||||
summons.DespawnEntry(NPC_BOUNCER_SPIKE);
|
||||
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);
|
||||
DoStartMovement(me->GetVictim());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
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->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();
|
||||
}
|
||||
586
src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp
Normal file
586
src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* 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(me, 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:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_LAVA_FISSURE);
|
||||
events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000));
|
||||
break;
|
||||
case EVENT_SAND_BLAST:
|
||||
DoCast(me, 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(me, 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(me, 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)
|
||||
{
|
||||
DoCast(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);
|
||||
DoCast(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->SetDisableGravity(true);
|
||||
DoCast(me, SPELL_STALACTITE_SHADE, true);
|
||||
events.ScheduleEvent(EVENT_STALACTITE_MISSLE, 5600);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (events.Empty())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_STALACTITE_MISSLE:
|
||||
DoCast(me, 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 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 SummonStalactiteTrigger()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
caster->CastSpell(caster, SPELL_STALACTITE_SUMMON_TRIGGER, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
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();
|
||||
}
|
||||
235
src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp
Normal file
235
src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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).
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_MILLHOUSE_MANASTORM, DATA_MILLHOUSE_MANASTORM },
|
||||
{ NPC_CORBORUS, DATA_CORBORUS },
|
||||
{ NPC_SLABHIDE, DATA_SLABHIDE },
|
||||
{ NPC_HIGH_PRIESTESS_AZIL, DATA_HIGH_PRIESTESS_AZIL },
|
||||
{ NPC_STONECORE_TELEPORTER, DATA_STONECORE_TELEPORTER },
|
||||
{ NPC_STONECORE_TELEPORTER_2, DATA_STONECORE_TELEPORTER_2 },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
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);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
}
|
||||
|
||||
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_STONECORE_TELEPORTER:
|
||||
case NPC_STONECORE_TELEPORTER_2:
|
||||
if (GetBossState(DATA_SLABHIDE) == DONE)
|
||||
ActivateTeleporter(creature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if creature is part of Millhouse event
|
||||
creature->SearchFormation();
|
||||
if (CreatureGroup* group = creature->GetFormation())
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ActivateTeleporter(GetCreature(DATA_STONECORE_TELEPORTER));
|
||||
ActivateTeleporter(GetCreature(DATA_STONECORE_TELEPORTER_2));
|
||||
}
|
||||
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_HANDLE_CORBORUS_ROCKDOOR:
|
||||
HandleGameObject(corborusRockDoorGUID, true);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Face Millhouse and other nearby mobs to Corborus
|
||||
void MillhouseEvent_Face()
|
||||
{
|
||||
if (Creature* Millhouse = GetCreature(DATA_MILLHOUSE_MANASTORM))
|
||||
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 = GetCreature(DATA_MILLHOUSE_MANASTORM))
|
||||
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 = GetCreature(DATA_MILLHOUSE_MANASTORM))
|
||||
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);
|
||||
}
|
||||
|
||||
void ActivateTeleporter(Creature* teleporter)
|
||||
{
|
||||
if (!teleporter)
|
||||
return;
|
||||
|
||||
teleporter->CastSpell(teleporter, SPELL_TELEPORTER_ACTIVE_VISUAL, true);
|
||||
teleporter->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
|
||||
GuidVector millhouseTrashGUIDs;
|
||||
GuidVector millhouseLastGroupGUIDs;
|
||||
ObjectGuid corborusRockDoorGUID;
|
||||
GuidVector slabhideRockWallGUIDs;
|
||||
|
||||
EncounterState slabhideIntro;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_stonecore_InstanceScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_stonecore()
|
||||
{
|
||||
new instance_stonecore();
|
||||
}
|
||||
433
src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
Normal file
433
src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* 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 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 };
|
||||
|
||||
// TO-DO:
|
||||
// - Millhouse Manastorm should face and cast SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, but he won't. :(
|
||||
|
||||
// 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();
|
||||
|
||||
switch (pointId)
|
||||
{
|
||||
case POINT_MILLHOUSE_GROUP_2:
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 200.0f))
|
||||
me->SetFacingToObject(worldtrigger);
|
||||
DoCast(me, SPELL_ANCHOR_HERE);
|
||||
DoCast(me, SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND);
|
||||
events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000);
|
||||
break;
|
||||
case POINT_MILLHOUSE_GROUP_3:
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetFacingTo(5.931499f);
|
||||
DoCast(me, SPELL_ANCHOR_HERE);
|
||||
DoCast(me, SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND);
|
||||
events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000);
|
||||
break;
|
||||
case POINT_MILLHOUSE_GROUP_4:
|
||||
me->SetFacingTo(3.455752f);
|
||||
DoCast(me, SPELL_ANCHOR_HERE);
|
||||
Talk(SAY_MILLHOUSE_EVENT_2);
|
||||
events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 1000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
// Do not update events if Millhouse is aggressive and has no combat.
|
||||
if (!UpdateVictim() && 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->FindCurrentSpellBySpellId(SPELL_IMPENDING_DOOM))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FROSTBOLT_VOLLEY:
|
||||
DoCastAOE(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(me, SPELL_IMPENDING_DOOM);
|
||||
DoCast(me, 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 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
|
||||
{
|
||||
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->IsFalling() || 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 = instance->GetCreature(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 = instance->GetCreature(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();
|
||||
}
|
||||
77
src/server/scripts/Maelstrom/Stonecore/stonecore.h
Normal file
77
src/server/scripts/Maelstrom/Stonecore/stonecore.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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_HANDLE_CORBORUS_ROCKDOOR,
|
||||
DATA_MILLHOUSE_EVENT_KNOCKBACK,
|
||||
DATA_MILLHOUSE_EVENT_DESPAWN,
|
||||
|
||||
DATA_SLABHIDE_INTRO,
|
||||
DATA_SLABHIDE_ROCK_WALL,
|
||||
|
||||
// Teleporters
|
||||
DATA_STONECORE_TELEPORTER,
|
||||
DATA_STONECORE_TELEPORTER_2,
|
||||
};
|
||||
|
||||
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
|
||||
@@ -205,10 +205,7 @@ class boss_anubarak_trial : public CreatureScript
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_KILL_PLAYER);
|
||||
instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override
|
||||
@@ -611,9 +608,7 @@ class npc_frost_sphere : public CreatureScript
|
||||
|
||||
struct npc_frost_sphereAI : public ScriptedAI
|
||||
{
|
||||
npc_frost_sphereAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
npc_frost_sphereAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -766,7 +761,6 @@ class npc_anubarak_spike : public CreatureScript
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* pWho) override
|
||||
|
||||
{
|
||||
if (!pWho)
|
||||
return;
|
||||
|
||||
@@ -647,8 +647,6 @@ struct boss_faction_championsAI : public BossAI
|
||||
if (Creature* temp = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GARROSH)))
|
||||
temp->AI()->Talk(SAY_KILL_PLAYER);
|
||||
|
||||
|
||||
instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,9 +97,7 @@ class boss_jaraxxus : public CreatureScript
|
||||
|
||||
struct boss_jaraxxusAI : public BossAI
|
||||
{
|
||||
boss_jaraxxusAI(Creature* creature) : BossAI(creature, BOSS_JARAXXUS)
|
||||
{
|
||||
}
|
||||
boss_jaraxxusAI(Creature* creature) : BossAI(creature, BOSS_JARAXXUS) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -124,10 +122,7 @@ class boss_jaraxxus : public CreatureScript
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_KILL_PLAYER);
|
||||
instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -136,11 +131,6 @@ class boss_jaraxxus : public CreatureScript
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
summons.Summon(summoned);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
@@ -370,9 +360,7 @@ class npc_nether_portal : public CreatureScript
|
||||
|
||||
struct npc_nether_portalAI : public ScriptedAI
|
||||
{
|
||||
npc_nether_portalAI(Creature* creature) : ScriptedAI(creature), _summons(me)
|
||||
{
|
||||
}
|
||||
npc_nether_portalAI(Creature* creature) : ScriptedAI(creature), _summons(me) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
|
||||
@@ -156,9 +156,7 @@ class boss_gormok : public CreatureScript
|
||||
|
||||
struct boss_gormokAI : public BossAI
|
||||
{
|
||||
boss_gormokAI(Creature* creature) : BossAI(creature, BOSS_BEASTS)
|
||||
{
|
||||
}
|
||||
boss_gormokAI(Creature* creature) : BossAI(creature, BOSS_BEASTS) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -542,12 +540,6 @@ struct boss_jormungarAI : public BossAI
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE, 0);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
@@ -642,7 +634,6 @@ struct boss_jormungarAI : public BossAI
|
||||
me->SetDisplayId(ModelMobile);
|
||||
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->GetMotionMaster()->Clear();
|
||||
|
||||
// if the worm was mobile before submerging, make him stationary now
|
||||
if (WasMobile)
|
||||
@@ -723,9 +714,7 @@ class boss_dreadscale : public CreatureScript
|
||||
|
||||
struct boss_dreadscaleAI : public boss_jormungarAI
|
||||
{
|
||||
boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature)
|
||||
{
|
||||
}
|
||||
boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -948,14 +937,6 @@ class boss_icehowl : public CreatureScript
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
#include "CellImpl.h"
|
||||
#include "trial_of_the_crusader.h"
|
||||
|
||||
enum Yells
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_NIGHT = 1,
|
||||
SAY_LIGHT = 2,
|
||||
EMOTE_VORTEX = 3,
|
||||
EMOTE_TWINK_PACT = 4,
|
||||
SAY_TWINK_PACT = 5,
|
||||
EMOTE_TWIN_PACT = 4,
|
||||
SAY_TWIN_PACT = 5,
|
||||
SAY_KILL_PLAYER = 6,
|
||||
SAY_BERSERK = 7,
|
||||
SAY_DEATH = 8
|
||||
@@ -91,6 +91,23 @@ enum BossSpells
|
||||
SPELL_SURGE_OF_SPEED = 65828
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_TWIN_SPIKE = 1,
|
||||
EVENT_TOUCH = 2,
|
||||
EVENT_SPECIAL_ABILITY = 3,
|
||||
EVENT_BERSERK = 4
|
||||
};
|
||||
|
||||
enum Stages
|
||||
{
|
||||
STAGE_DARK_VORTEX,
|
||||
STAGE_DARK_PACT,
|
||||
STAGE_LIGHT_VORTEX,
|
||||
STAGE_LIGHT_PACT,
|
||||
MAX_STAGES
|
||||
};
|
||||
|
||||
#define SPELL_DARK_ESSENCE_HELPER RAID_MODE<uint32>(65684, 67176, 67177, 67178)
|
||||
#define SPELL_LIGHT_ESSENCE_HELPER RAID_MODE<uint32>(65686, 67222, 67223, 67224)
|
||||
|
||||
@@ -101,8 +118,8 @@ enum BossSpells
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_VORTEX = 0,
|
||||
ACTION_PACT = 1
|
||||
ACTION_VORTEX,
|
||||
ACTION_PACT
|
||||
};
|
||||
|
||||
#define ESSENCE_REMOVE 0
|
||||
@@ -143,14 +160,8 @@ struct boss_twin_baseAI : public BossAI
|
||||
{
|
||||
boss_twin_baseAI(Creature* creature) : BossAI(creature, BOSS_VALKIRIES)
|
||||
{
|
||||
Initialize();
|
||||
AuraState = AURA_STATE_NONE;
|
||||
|
||||
Stage = 0;
|
||||
|
||||
Weapon = 0;
|
||||
|
||||
VortexEmote = 0;
|
||||
SisterNpcId = 0;
|
||||
MyEmphatySpellId = 0;
|
||||
OtherEssenceSpellId = 0;
|
||||
@@ -162,16 +173,6 @@ struct boss_twin_baseAI : public BossAI
|
||||
TouchSpellId = 0;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
IsBerserk = false;
|
||||
|
||||
SpecialAbilityTimer = 1 * MINUTE*IN_MILLISECONDS;
|
||||
SpikeTimer = 20 * IN_MILLISECONDS;
|
||||
TouchTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
|
||||
BerserkTimer = IsHeroic() ? 6 * MINUTE*IN_MILLISECONDS : 10 * MINUTE*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
@@ -180,7 +181,6 @@ struct boss_twin_baseAI : public BossAI
|
||||
/* Uncomment this once that they are floating above the ground
|
||||
me->SetLevitate(true);
|
||||
me->SetFlying(true); */
|
||||
Initialize();
|
||||
|
||||
summons.DespawnAll();
|
||||
}
|
||||
@@ -212,15 +212,7 @@ struct boss_twin_baseAI : public BossAI
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_KILL_PLAYER);
|
||||
instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
summons.Summon(summoned);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summoned) override
|
||||
@@ -282,6 +274,11 @@ struct boss_twin_baseAI : public BossAI
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoCast(me, SurgeSpellId);
|
||||
|
||||
events.ScheduleEvent(EVENT_TWIN_SPIKE, 20 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 6 * MINUTE*IN_MILLISECONDS : 10 * MINUTE*IN_MILLISECONDS);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_TOUCH, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
@@ -289,10 +286,16 @@ struct boss_twin_baseAI : public BossAI
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_VORTEX:
|
||||
Stage = me->GetEntry() == NPC_LIGHTBANE ? 2 : 1;
|
||||
Talk(EMOTE_VORTEX);
|
||||
DoCastAOE(VortexSpellId);
|
||||
break;
|
||||
case ACTION_PACT:
|
||||
Stage = me->GetEntry() == NPC_LIGHTBANE ? 1 : 2;
|
||||
Talk(EMOTE_TWIN_PACT);
|
||||
Talk(SAY_TWIN_PACT);
|
||||
if (Creature* sister = GetSister())
|
||||
sister->CastSpell(sister, SPELL_POWER_TWINS, false);
|
||||
DoCast(me, ShieldSpellId);
|
||||
DoCast(me, TwinPactSpellId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -305,95 +308,31 @@ struct boss_twin_baseAI : public BossAI
|
||||
me->SetCanDualWield(mode);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
if (!instance || !UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (Stage)
|
||||
switch (eventId)
|
||||
{
|
||||
case 0:
|
||||
case EVENT_TWIN_SPIKE:
|
||||
DoCastVictim(SpikeSpellId);
|
||||
events.ScheduleEvent(EVENT_TWIN_SPIKE, 20 * IN_MILLISECONDS);
|
||||
break;
|
||||
case 1: // Vortex
|
||||
if (SpecialAbilityTimer <= diff)
|
||||
{
|
||||
if (Creature* pSister = GetSister())
|
||||
pSister->AI()->DoAction(ACTION_VORTEX);
|
||||
Talk(VortexEmote);
|
||||
DoCastAOE(VortexSpellId);
|
||||
Stage = 0;
|
||||
SpecialAbilityTimer = 1*MINUTE*IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
SpecialAbilityTimer -= diff;
|
||||
case EVENT_TOUCH:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true, OtherEssenceSpellId))
|
||||
me->CastCustomSpell(TouchSpellId, SPELLVALUE_MAX_TARGETS, 1, target, false);
|
||||
events.ScheduleEvent(EVENT_TOUCH, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
|
||||
break;
|
||||
case 2: // Shield + Pact
|
||||
if (SpecialAbilityTimer <= diff)
|
||||
{
|
||||
Talk(EMOTE_TWINK_PACT);
|
||||
Talk(SAY_TWINK_PACT);
|
||||
if (Creature* pSister = GetSister())
|
||||
{
|
||||
pSister->AI()->DoAction(ACTION_PACT);
|
||||
pSister->CastSpell(pSister, SPELL_POWER_TWINS, false);
|
||||
}
|
||||
DoCast(me, ShieldSpellId);
|
||||
DoCast(me, TwinPactSpellId);
|
||||
Stage = 0;
|
||||
SpecialAbilityTimer = 1*MINUTE*IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
SpecialAbilityTimer -= diff;
|
||||
case EVENT_BERSERK:
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Talk(SAY_BERSERK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (SpikeTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SpikeSpellId);
|
||||
SpikeTimer = 20*IN_MILLISECONDS;
|
||||
}
|
||||
else
|
||||
SpikeTimer -= diff;
|
||||
|
||||
if (IsHeroic() && TouchTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true, OtherEssenceSpellId))
|
||||
me->CastCustomSpell(TouchSpellId, SPELLVALUE_MAX_TARGETS, 1, target, false);
|
||||
TouchTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
TouchTimer -= diff;
|
||||
|
||||
if (!IsBerserk && BerserkTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Talk(SAY_BERSERK);
|
||||
IsBerserk = true;
|
||||
}
|
||||
else
|
||||
BerserkTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
protected:
|
||||
AuraStateType AuraState;
|
||||
|
||||
uint8 Stage;
|
||||
bool IsBerserk;
|
||||
|
||||
uint32 Weapon;
|
||||
uint32 SpecialAbilityTimer;
|
||||
uint32 SpikeTimer;
|
||||
uint32 TouchTimer;
|
||||
uint32 BerserkTimer;
|
||||
|
||||
int32 VortexEmote;
|
||||
uint32 SisterNpcId;
|
||||
uint32 MyEmphatySpellId;
|
||||
uint32 OtherEssenceSpellId;
|
||||
@@ -414,15 +353,14 @@ class boss_fjola : public CreatureScript
|
||||
{
|
||||
boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature)
|
||||
{
|
||||
GenerateStageSequence();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
Stage = 0;
|
||||
Weapon = EQUIP_MAIN_1;
|
||||
AuraState = AURA_STATE_UNKNOWN22;
|
||||
VortexEmote = EMOTE_VORTEX;
|
||||
SisterNpcId = NPC_DARKBANE;
|
||||
MyEmphatySpellId = SPELL_TWIN_EMPATHY_DARK;
|
||||
OtherEssenceSpellId = SPELL_DARK_ESSENCE_HELPER;
|
||||
@@ -437,10 +375,43 @@ class boss_fjola : public CreatureScript
|
||||
boss_twin_baseAI::Reset();
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
if (eventId == EVENT_SPECIAL_ABILITY)
|
||||
{
|
||||
if (CurrentStage == MAX_STAGES)
|
||||
GenerateStageSequence();
|
||||
|
||||
switch (Stage[CurrentStage])
|
||||
{
|
||||
case STAGE_DARK_VORTEX:
|
||||
if (Creature* sister = GetSister())
|
||||
sister->AI()->DoAction(ACTION_VORTEX);
|
||||
break;
|
||||
case STAGE_DARK_PACT:
|
||||
if (Creature* sister = GetSister())
|
||||
sister->AI()->DoAction(ACTION_PACT);
|
||||
break;
|
||||
case STAGE_LIGHT_VORTEX:
|
||||
DoAction(ACTION_VORTEX);
|
||||
break;
|
||||
case STAGE_LIGHT_PACT:
|
||||
DoAction(ACTION_PACT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++CurrentStage;
|
||||
events.ScheduleEvent(EVENT_SPECIAL_ABILITY, 45 * IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
boss_twin_baseAI::ExecuteEvent(eventId);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPECIAL_ABILITY, 45 * IN_MILLISECONDS);
|
||||
me->SummonCreature(NPC_BULLET_CONTROLLER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
boss_twin_baseAI::EnterCombat(who);
|
||||
}
|
||||
@@ -457,6 +428,27 @@ class boss_fjola : public CreatureScript
|
||||
|
||||
boss_twin_baseAI::JustReachedHome();
|
||||
}
|
||||
|
||||
void GenerateStageSequence()
|
||||
{
|
||||
CurrentStage = 0;
|
||||
|
||||
// Initialize and clean up.
|
||||
for (int i = 0; i < MAX_STAGES; ++i)
|
||||
Stage[i] = i;
|
||||
|
||||
// Allocate an unique random stage to each position in the array.
|
||||
for (int i = 0; i < MAX_STAGES - 1; ++i)
|
||||
{
|
||||
int random = i + (rand32() % (MAX_STAGES - i));
|
||||
int temp = Stage[i];
|
||||
Stage[i] = Stage[random];
|
||||
Stage[random] = temp;
|
||||
}
|
||||
}
|
||||
private:
|
||||
uint8 Stage[4];
|
||||
uint8 CurrentStage;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -477,10 +469,8 @@ class boss_eydis : public CreatureScript
|
||||
void Reset() override
|
||||
{
|
||||
SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
Stage = 1;
|
||||
Weapon = EQUIP_MAIN_2;
|
||||
AuraState = AURA_STATE_UNKNOWN19;
|
||||
VortexEmote = EMOTE_VORTEX;
|
||||
SisterNpcId = NPC_LIGHTBANE;
|
||||
MyEmphatySpellId = SPELL_TWIN_EMPATHY_LIGHT;
|
||||
OtherEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER;
|
||||
|
||||
@@ -190,6 +190,13 @@ class instance_trial_of_the_crusader : public InstanceMapScript
|
||||
}
|
||||
}
|
||||
|
||||
void OnUnitDeath(Unit* unit) override
|
||||
{
|
||||
if (unit->GetTypeId() == TYPEID_PLAYER && IsEncounterInProgress())
|
||||
TributeToImmortalityEligible = false;
|
||||
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
@@ -427,9 +434,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript
|
||||
else if (data == DECREASE)
|
||||
--MistressOfPainCount;
|
||||
break;
|
||||
case DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE:
|
||||
TributeToImmortalityEligible = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -111,9 +111,7 @@ class npc_announcer_toc10 : public CreatureScript
|
||||
|
||||
struct npc_announcer_toc10AI : public ScriptedAI
|
||||
{
|
||||
npc_announcer_toc10AI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
npc_announcer_toc10AI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
|
||||
@@ -24,9 +24,8 @@ enum DataTypes
|
||||
TYPE_EVENT_NPC = 102,
|
||||
TYPE_NORTHREND_BEASTS = 103,
|
||||
|
||||
DATA_SNOBOLD_COUNT = 301,
|
||||
DATA_MISTRESS_OF_PAIN_COUNT = 302,
|
||||
DATA_TRIBUTE_TO_IMMORTALITY_ELIGIBLE = 303,
|
||||
DATA_SNOBOLD_COUNT = 301,
|
||||
DATA_MISTRESS_OF_PAIN_COUNT = 302,
|
||||
|
||||
INCREASE = 501,
|
||||
DECREASE = 502,
|
||||
|
||||
@@ -50,6 +50,7 @@ enum Spells
|
||||
SPELL_HEAT = 65667,
|
||||
SPELL_MOLTEN = 62373,
|
||||
SPELL_BRITTLE = 62382,
|
||||
SPELL_BRITTLE_25 = 67114,
|
||||
SPELL_SHATTER = 62383,
|
||||
SPELL_GROUND = 62548,
|
||||
};
|
||||
@@ -240,7 +241,7 @@ class boss_ignis : public CreatureScript
|
||||
case EVENT_CHANGE_POT:
|
||||
if (Unit* slagPotTarget = ObjectAccessor::GetUnit(*me, _slagPotGUID))
|
||||
{
|
||||
slagPotTarget->AddAura(SPELL_SLAG_POT, slagPotTarget);
|
||||
DoCast(slagPotTarget, SPELL_SLAG_POT, true);
|
||||
slagPotTarget->EnterVehicle(me, 1);
|
||||
events.CancelEvent(EVENT_CHANGE_POT);
|
||||
events.ScheduleEvent(EVENT_END_POT, 10000);
|
||||
@@ -320,7 +321,7 @@ class npc_iron_construct : public CreatureScript
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (me->HasAura(SPELL_BRITTLE) && damage >= 5000)
|
||||
if (me->HasAura(RAID_MODE(SPELL_BRITTLE, SPELL_BRITTLE_25)) && damage >= 5000)
|
||||
{
|
||||
DoCast(SPELL_SHATTER);
|
||||
if (Creature* ignis = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(BOSS_IGNIS)))
|
||||
@@ -457,14 +458,13 @@ class spell_ignis_slag_pot : public SpellScriptLoader
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
||||
void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
Unit* aurEffCaster = aurEff->GetCaster();
|
||||
if (!aurEffCaster)
|
||||
return;
|
||||
|
||||
Unit* target = GetTarget();
|
||||
aurEffCaster->CastSpell(target, SPELL_SLAG_POT_DAMAGE, true);
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
caster->CastSpell(target, SPELL_SLAG_POT_DAMAGE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
|
||||
@@ -166,7 +166,6 @@ class boss_kologarn : public CreatureScript
|
||||
left = apply;
|
||||
if (!apply && isEncounterInProgress)
|
||||
{
|
||||
who->ToCreature()->DespawnOrUnsummon();
|
||||
Talk(SAY_LEFT_ARM_GONE);
|
||||
events.ScheduleEvent(EVENT_RESPAWN_LEFT_ARM, 40000);
|
||||
}
|
||||
@@ -177,7 +176,6 @@ class boss_kologarn : public CreatureScript
|
||||
right = apply;
|
||||
if (!apply && isEncounterInProgress)
|
||||
{
|
||||
who->ToCreature()->DespawnOrUnsummon();
|
||||
Talk(SAY_RIGHT_ARM_GONE);
|
||||
events.ScheduleEvent(EVENT_RESPAWN_RIGHT_ARM, 40000);
|
||||
}
|
||||
@@ -194,6 +192,7 @@ class boss_kologarn : public CreatureScript
|
||||
{
|
||||
rubbleStalker->CastSpell(rubbleStalker, SPELL_FALLING_RUBBLE, true);
|
||||
rubbleStalker->CastSpell(rubbleStalker, SPELL_SUMMON_RUBBLE, true);
|
||||
who->ToCreature()->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
if (!right && !left)
|
||||
|
||||
Reference in New Issue
Block a user