Scripts/Deadmines: implement Foe Reaper 5000 encounter

This commit is contained in:
Ovalord
2018-02-18 18:29:00 +01:00
parent 6fce2ab1dc
commit e9753cf1b0
6 changed files with 879 additions and 7 deletions

View File

@@ -0,0 +1,595 @@
/*
* Copyright (C) 2008-2017 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 "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "Player.h"
#include "deadmines.h"
enum Texts
{
// Foe Reaper 5000
SAY_ON_LINE = 0,
SAY_ANNOUNCE_OVERDRIVE = 1,
SAY_OVERDRIVE = 2,
SAY_HARVEST_ACQUIRING_TARGET = 3,
SAY_HARVEST = 4,
SAY_SAFETY_RESTRICTIONS_OFFLINE = 5,
SAY_ANNOUNCE_RESTRICTIONS_OFFLINE = 6,
SAY_SLAY = 7,
SAY_DEATH = 8,
// General Purpose Bunny
SAY_ANNOUNCE_FOUNDRY_DISRUPTED = 0,
SAY_ANNOUNCE_MOLTEN_SLAG = 1
};
enum Spells
{
// Foe Reaper 5000
SPELL_ENERGIZE = 89132,
SPELL_ON_LINE = 89198,
SPELL_OFF_LINE = 88348,
SPELL_RED_EYES = 24263,
SPELL_ON_LINE_2 = 89121,
SPELL_REAPER_STRIKE = 88490,
SPELL_OVERDRIVE = 88481,
SPELL_ACQUIRING_TARGET = 88492,
SPELL_HARVEST = 88497,
SPELL_HARVEST_SWEEP = 88521,
SPELL_SAFETY_RESTRICTIONS_OFFLINE = 88522,
// General Purpose Bunny
SPELL_SUMMON_MOLTEN_SLAG_1 = 91839,
SPELL_SUMMON_MOLTEN_SLAG_2 = 91841,
SPELL_SUMMON_MOLTEN_SLAG_3 = 91842,
SPELL_SUMMON_MOLTEN_SLAG_4 = 91843,
// Molten Slag
SPELL_MOLTEN_SHIELD = 91815,
SPELL_FIXATE_TARGETING = 91831,
// Player
SPELL_FIXATE_TAUNT = 91829
};
uint32 randomSlagSpells[] =
{
SPELL_SUMMON_MOLTEN_SLAG_1,
SPELL_SUMMON_MOLTEN_SLAG_2,
SPELL_SUMMON_MOLTEN_SLAG_3,
SPELL_SUMMON_MOLTEN_SLAG_4,
};
enum Events
{
// Foe Reaper 5000
EVENT_ON_LINE = 1,
EVENT_RED_EYES,
EVENT_ON_LINE_2,
EVENT_ANNOUNCE_DISRUPTING_FOUNDRY,
EVENT_ANNOUNCE_MOLTEN_SLAG,
EVENT_SUMMON_MOLTEN_SLAG,
EVENT_OVERDRIVE,
EVENT_MOVE_OVERDRIVE,
EVENT_END_OVERDRIVE,
EVENT_ACQUIRING_TARGET,
EVENT_HARVEST,
EVENT_HARVEST_SWEEP,
EVENT_ANNOUNCE_SAFETY_RESTRICTIONS_OFFLINE,
// Molten Slag
EVENT_MOLTEN_SHIELD,
EVENT_FIXATE_PLAYER
};
enum Phases
{
PHASE_INTRO = 1,
PHASE_1 = 2,
};
enum Actions
{
ACTION_ELECTRICAL_CHARGE = 1
};
enum Points
{
POINT_MOVE_OVERDRIVE = 1,
POINT_MOVE_HARVEST = 2
};
class boss_foe_reaper_5000 : public CreatureScript
{
public:
boss_foe_reaper_5000() : CreatureScript("boss_foe_reaper_5000") { }
struct boss_foe_reaper_5000AI : public BossAI
{
boss_foe_reaper_5000AI(Creature* creature) : BossAI(creature, DATA_HELIX_GEARBREAKER)
{
me->setPowerType(POWER_ENERGY);
me->SetMaxPower(POWER_ENERGY, 100);
Initialize();
}
void Initialize()
{
_safetyRestrictionsOffline = false;
}
void Reset() override
{
_Reset();
Initialize();
if (!instance->GetData(DATA_FOE_REAPER_INTRO))
events.SetPhase(PHASE_INTRO);
else
{
me->RemoveAurasDueToSpell(SPELL_OFF_LINE);
{
DoCast(me, SPELL_RED_EYES, true);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_PC);
}
}
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
events.SetPhase(PHASE_1);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
events.ScheduleEvent(EVENT_OVERDRIVE, Seconds(9));
events.ScheduleEvent(EVENT_ACQUIRING_TARGET, Seconds(35));
if (IsHeroic())
{
events.ScheduleEvent(EVENT_ANNOUNCE_DISRUPTING_FOUNDRY, Seconds(4));
events.ScheduleEvent(EVENT_ANNOUNCE_MOLTEN_SLAG, Seconds(6) + Milliseconds(400));
events.ScheduleEvent(EVENT_SUMMON_MOLTEN_SLAG, Seconds(17));
}
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
if (IsHeroic())
if (Creature* prototypeReaper = instance->GetCreature(DATA_PROTOTYPE_REAPER))
prototypeReaper->DespawnOrUnsummon(0);
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
_EnterEvadeMode();
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
if (IsHeroic())
if (Creature* prototypeReaper = instance->GetCreature(DATA_PROTOTYPE_REAPER))
prototypeReaper->DespawnOrUnsummon(0, Seconds(30));
_DespawnAtEvade();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_FOE_REAPER_TARGETING_BUNNY)
{
me->StopMoving();
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
me->SetFacingToObject(summon);
}
}
void MovementInform(uint32 type, uint32 point) override
{
if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
return;
switch (point)
{
case POINT_MOVE_OVERDRIVE:
events.ScheduleEvent(EVENT_MOVE_OVERDRIVE, Seconds(1));
break;
case POINT_MOVE_HARVEST:
me->RemoveAurasDueToSpell(SPELL_HARVEST);
events.ScheduleEvent(EVENT_HARVEST_SWEEP, Seconds(1));
break;
default:
break;
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
switch (spell->Id)
{
case SPELL_ENERGIZE:
if (me->GetPower(POWER_ENERGY) == 100)
{
instance->SetData(DATA_FOE_REAPER_INTRO, DONE);
events.ScheduleEvent(EVENT_ON_LINE, Seconds(3));
}
break;
case SPELL_OVERDRIVE:
Talk(SAY_OVERDRIVE);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
events.ScheduleEvent(EVENT_MOVE_OVERDRIVE, Seconds(2));
events.ScheduleEvent(EVENT_END_OVERDRIVE, Seconds(10));
break;
case SPELL_HARVEST:
Talk(SAY_HARVEST);
events.ScheduleEvent(EVENT_HARVEST, Seconds(2));
break;
default:
break;
}
}
void DoAction(int32 action) override
{
switch (action)
{
case 0:
break;
default:
break;
}
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
{
if (me->HealthBelowPct(30) && !_safetyRestrictionsOffline)
{
Talk(SAY_SAFETY_RESTRICTIONS_OFFLINE);
DoCastSelf(SPELL_SAFETY_RESTRICTIONS_OFFLINE, true);
events.ScheduleEvent(EVENT_ANNOUNCE_SAFETY_RESTRICTIONS_OFFLINE, Seconds(3) + Milliseconds(800));
_safetyRestrictionsOffline = true;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ON_LINE:
{
me->CastSpell(me, SPELL_ON_LINE);
events.ScheduleEvent(EVENT_RED_EYES, Seconds(8) + Milliseconds(400));
std::list<Creature*> units;
GetCreatureListWithEntryInGrid(units, me, NPC_GENERAL_PURPOSE_BUNNY_L2, 15.0f);
if (!units.empty())
for (auto itr = units.begin(); itr != units.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_ELECTRICAL_CHARGE);
break;
}
case EVENT_RED_EYES:
DoCastSelf(SPELL_RED_EYES, true);
events.ScheduleEvent(EVENT_ON_LINE_2, Seconds(2) + Milliseconds(400));
break;
case EVENT_ON_LINE_2:
me->RemoveAurasDueToSpell(SPELL_OFF_LINE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_PC);
DoCastSelf(SPELL_ON_LINE_2, true);
Talk(SAY_ON_LINE);
break;
case EVENT_ANNOUNCE_DISRUPTING_FOUNDRY:
if (Creature* bunny = me->FindNearestCreature(NPC_GENERAL_PURPOSE_DUMMY_JMF, 100.0f, true))
bunny->AI()->Talk(SAY_ANNOUNCE_FOUNDRY_DISRUPTED);
break;
case EVENT_ANNOUNCE_MOLTEN_SLAG:
if (Creature* bunny = me->FindNearestCreature(NPC_GENERAL_PURPOSE_DUMMY_JMF, 100.0f, true))
bunny->AI()->Talk(SAY_ANNOUNCE_MOLTEN_SLAG);
break;
case EVENT_SUMMON_MOLTEN_SLAG:
{
uint8 i = RAND(0, 3);
if (Creature* bunny = me->FindNearestCreature(NPC_GENERAL_PURPOSE_DUMMY_JMF, 100.0f, true))
bunny->CastSpell(bunny, randomSlagSpells[i], true);
events.Repeat(Seconds(21), Seconds(22));
break;
}
case EVENT_OVERDRIVE:
DoCastSelf(SPELL_OVERDRIVE);
Talk(SAY_ANNOUNCE_OVERDRIVE);
events.Repeat(Seconds(53));
break;
case EVENT_MOVE_OVERDRIVE:
{
// Let's just copy the random movement generator part here except we are walking
// and use our own position instead of our home position
float respX, respY, respZ, respO, destX, destY, destZ, travelDistZ;
me->GetPosition(respX, respY, respZ, respO);
Map const* map = me->GetBaseMap();
const float angle = float(rand_norm()) * static_cast<float>(M_PI*2.0f);
const float range = 15.0f;
const float distanceX = range * std::cos(angle);
const float distanceY = range * std::sin(angle);
destX = respX + distanceX;
destY = respY + distanceY;
Trinity::NormalizeMapCoord(destX);
Trinity::NormalizeMapCoord(destY);
travelDistZ = 10.0f;
destZ = map->GetHeight(me->GetPhases(), destX, destY, respZ + travelDistZ - 2.0f, false);
if (std::fabs(destZ - respZ) > travelDistZ)
{
destZ = map->GetHeight(me->GetPhases(), destX, destY, respZ - 2.0f, true);
if (std::fabs(destZ - respZ) > travelDistZ)
{
destZ = map->GetHeight(me->GetPhases(), destX, destY, respZ + travelDistZ - 2.0f, true);
if (std::fabs(destZ - respZ) > travelDistZ)
return;
}
}
me->GetMotionMaster()->MovePoint(POINT_MOVE_OVERDRIVE, destX, destY, destZ, true);
break;
}
case EVENT_END_OVERDRIVE:
me->GetMotionMaster()->Clear();
me->SetReactState(REACT_AGGRESSIVE);
me->AI()->AttackStart(me->GetVictim());
events.CancelEvent(EVENT_MOVE_OVERDRIVE);
break;
case EVENT_ACQUIRING_TARGET:
Talk(SAY_HARVEST_ACQUIRING_TARGET);
DoCastAOE(SPELL_ACQUIRING_TARGET, true);
events.Repeat(Seconds(55));
break;
case EVENT_HARVEST:
if (Creature* bunny = instance->GetCreature(DATA_FOE_REAPER_BUNNY))
me->GetMotionMaster()->MovePoint(POINT_MOVE_HARVEST, bunny->GetPosition(), true);
break;
case EVENT_HARVEST_SWEEP:
DoCastAOE(SPELL_HARVEST_SWEEP);
me->setAttackTimer(BASE_ATTACK, me->GetFloatValue(UNIT_FIELD_BASEATTACKTIME));
summons.DespawnEntry(NPC_FOE_REAPER_TARGETING_BUNNY);
me->SetReactState(REACT_AGGRESSIVE);
me->AI()->AttackStart(me->GetVictim());
break;
case EVENT_ANNOUNCE_SAFETY_RESTRICTIONS_OFFLINE:
Talk(SAY_ANNOUNCE_RESTRICTIONS_OFFLINE);
break;
default:
break;
}
}
DoSpellAttackIfReady(SPELL_REAPER_STRIKE);
}
private:
bool _safetyRestrictionsOffline;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetDeadminesAI<boss_foe_reaper_5000AI>(creature);
}
};
class npc_foe_reaper_5000_molten_slag : public CreatureScript
{
public:
npc_foe_reaper_5000_molten_slag() : CreatureScript("npc_foe_reaper_5000_molten_slag") { }
struct npc_foe_reaper_5000_molten_slagAI : public ScriptedAI
{
npc_foe_reaper_5000_molten_slagAI(Creature* creature) : ScriptedAI(creature) { }
void InitializeAI() override
{
me->SetReactState(REACT_PASSIVE);
}
void IsSummonedBy(Unit* /*summoner*/) override
{
DoZoneInCombat();
_events.ScheduleEvent(EVENT_MOLTEN_SHIELD, Seconds(3));
_events.ScheduleEvent(EVENT_FIXATE_PLAYER, Seconds(3));
}
void JustDied(Unit* /*killer*/) override
{
me->DespawnOrUnsummon(Seconds(5));
}
void UpdateAI(uint32 diff) override
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_MOLTEN_SHIELD:
DoCastSelf(SPELL_MOLTEN_SHIELD, true);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
break;
case EVENT_FIXATE_PLAYER:
DoCastAOE(SPELL_FIXATE_TARGETING, true);
_events.Repeat(Seconds(12));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetDeadminesAI<npc_foe_reaper_5000_molten_slagAI>(creature);
}
};
class spell_foe_reaper_5000_acquire_target : public SpellScriptLoader
{
public:
spell_foe_reaper_5000_acquire_target() : SpellScriptLoader("spell_foe_reaper_5000_acquire_target") { }
class spell_foe_reaper_5000_acquire_target_SpellScript : public SpellScript
{
PrepareSpellScript(spell_foe_reaper_5000_acquire_target_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
Trinity::Containers::RandomResize(targets, 1);
}
void HandleHit(SpellEffIndex effIndex)
{
GetCaster()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_foe_reaper_5000_acquire_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_foe_reaper_5000_acquire_target_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_foe_reaper_5000_acquire_target_SpellScript();
}
};
class FixateTargetingCheck
{
public:
FixateTargetingCheck() { }
bool operator()(WorldObject* object)
{
if (Unit* unit = object->ToUnit())
if ((unit->GetEntry() == NPC_PROTOTYPE_REAPER && unit->IsCharmedOwnedByPlayerOrPlayer()) || unit->GetTypeId() == TYPEID_PLAYER)
return false;
return true;
}
};
class spell_foe_reaper_5000_fixate_targeting : public SpellScriptLoader
{
public:
spell_foe_reaper_5000_fixate_targeting() : SpellScriptLoader("spell_foe_reaper_5000_fixate_targeting") { }
class spell_foe_reaper_5000_fixate_targeting_SpellScript : public SpellScript
{
PrepareSpellScript(spell_foe_reaper_5000_fixate_targeting_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.remove_if(FixateTargetingCheck());
if (targets.empty())
return;
Trinity::Containers::RandomResize(targets, 1);
}
void HandleHit(SpellEffIndex effIndex)
{
GetCaster()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints, true);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_foe_reaper_5000_fixate_targeting_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_foe_reaper_5000_fixate_targeting_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_foe_reaper_5000_fixate_targeting_SpellScript();
}
};
class spell_foe_reaper_5000_fixate : public SpellScriptLoader
{
public:
spell_foe_reaper_5000_fixate() : SpellScriptLoader("spell_foe_reaper_5000_fixate") { }
class spell_foe_reaper_5000_fixate_SpellScript : public SpellScript
{
PrepareSpellScript(spell_foe_reaper_5000_fixate_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_FIXATE_TAUNT });
}
void HandleHit(SpellEffIndex effIndex)
{
if (Unit* caster = GetCaster())
GetHitUnit()->CastSpell(caster, SPELL_FIXATE_TAUNT, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_foe_reaper_5000_fixate_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_foe_reaper_5000_fixate_SpellScript();
}
};
void AddSC_boss_foe_reaper_5000()
{
new boss_foe_reaper_5000();
new npc_foe_reaper_5000_molten_slag();
new spell_foe_reaper_5000_acquire_target();
new spell_foe_reaper_5000_fixate_targeting();
new spell_foe_reaper_5000_fixate();
}

View File

@@ -22,6 +22,130 @@
#include "Player.h"
#include "WorldSession.h"
enum DefiasWatcherSpells
{
SPELL_ON_FIRE = 91737,
SPELL_EXPLOSIVE_SUICIDE = 91738,
SPELL_ENERGIZE = 89132,
};
enum DefiasWatcherFaction
{
FACTION_CONTROLABLE = 1816
};
class npc_deadmines_defias_watcher : public CreatureScript
{
public:
npc_deadmines_defias_watcher() : CreatureScript("npc_deadmines_defias_watcher") { }
struct npc_deadmines_defias_watcherAI : public ScriptedAI
{
npc_deadmines_defias_watcherAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
{
Initialize();
}
void Initialize()
{
_suicideStarted = false;
}
void JustEngagedWith(Unit* who) override
{
}
void Reset() override
{
me->SetHealth(me->GetMaxHealth());
}
void JustDied(Unit* /*killer*/) override
{
if (!_suicideStarted)
DoCastAOE(SPELL_ENERGIZE, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (me->GetHealthPct() <= 30.0f && !_suicideStarted)
{
DoCastSelf(SPELL_ON_FIRE, true);
DoCastAOE(SPELL_ENERGIZE, true);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
me->SetFaction(FACTION_CONTROLABLE);
me->setRegeneratingHealth(false);
_events.Reset();
_suicideStarted = true;
}
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case 0:
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
InstanceScript* _instance;
bool _suicideStarted;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetDeadminesAI<npc_deadmines_defias_watcherAI>(creature);
}
};
class spell_deadmines_on_fire : public SpellScriptLoader
{
public:
spell_deadmines_on_fire() : SpellScriptLoader("spell_deadmines_on_fire") { }
class spell_deadmines_on_fire_AuraScript : public AuraScript
{
PrepareAuraScript(spell_deadmines_on_fire_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_EXPLOSIVE_SUICIDE });
}
void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Unit* owner = GetOwner()->ToUnit())
owner->CastSpell(owner, SPELL_EXPLOSIVE_SUICIDE, true);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_deadmines_on_fire_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE_PERCENT, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_deadmines_on_fire_AuraScript();
}
};
void AddSC_deadmines()
{
new npc_deadmines_defias_watcher();
new spell_deadmines_on_fire();
}

View File

@@ -35,7 +35,10 @@ enum DMDataTypes
DATA_TEAM_IN_INSTANCE = 6,
DATA_FIREWALL_PLATTER = 7,
DATA_LUMBERING_OAF = 8
DATA_LUMBERING_OAF = 8,
DATA_FOE_REAPER_INTRO = 9,
DATA_FOE_REAPER_BUNNY = 10,
DATA_PROTOTYPE_REAPER = 11,
};
enum DMCreatures
@@ -43,6 +46,7 @@ enum DMCreatures
// Bosses
BOSS_GLUBTOK = 47162,
BOSS_HELIX_GEARBREAKER = 47296,
BOSS_FOE_REAPER_5000 = 43778,
// Horde Creatures
NPC_SLINKY_SHARPSHIV = 46906,
@@ -72,7 +76,12 @@ enum DMCreatures
NPC_FROST_BLOSSOM_BUNNY = 47284,
NPC_LUMBERING_OAF = 47297,
NPC_HELIX_CREW = 49139,
NPC_STICKY_BOMB = 47314
NPC_STICKY_BOMB = 47314,
NPC_DEFIAS_REAPER = 47403,
NPC_DEFIAS_WATCHER = 47404,
NPC_FOE_REAPER_TARGETING_BUNNY = 47468,
NPC_PROTOTYPE_REAPER = 49208,
NPC_MOLTEN_SLAG = 49229,
};
enum DMGameObjects

View File

@@ -24,10 +24,13 @@
ObjectData const creatureData[] =
{
{ BOSS_GLUBTOK, DATA_GLUBTOK },
{ BOSS_HELIX_GEARBREAKER, DATA_HELIX_GEARBREAKER },
{ NPC_LUMBERING_OAF, DATA_LUMBERING_OAF },
{ 0, 0 }, // END
{ BOSS_GLUBTOK, DATA_GLUBTOK },
{ BOSS_HELIX_GEARBREAKER, DATA_HELIX_GEARBREAKER },
{ BOSS_FOE_REAPER_5000, DATA_FOE_REAPER_5000 },
{ NPC_LUMBERING_OAF, DATA_LUMBERING_OAF },
{ NPC_FOE_REAPER_TARGETING_BUNNY, DATA_FOE_REAPER_BUNNY },
{ NPC_PROTOTYPE_REAPER, DATA_PROTOTYPE_REAPER },
{ 0, 0 }, // END
};
ObjectData const gameobjectData[] =
@@ -57,6 +60,7 @@ class instance_deadmines : public InstanceMapScript
LoadDoorData(doorData);
LoadObjectData(creatureData, gameobjectData);
_teamInInstance = 0;
_foeReaper5000Intro = 0;
}
void OnPlayerEnter(Player* player) override
@@ -106,6 +110,19 @@ class instance_deadmines : public InstanceMapScript
if (creature->isDead() && GetBossState(DATA_HELIX_GEARBREAKER) != DONE)
creature->Respawn();
break;
case NPC_DEFIAS_REAPER:
case NPC_DEFIAS_WATCHER:
if (!GetData(DATA_FOE_REAPER_INTRO) && creature->isDead())
creature->Respawn();
break;
case NPC_PROTOTYPE_REAPER:
if (!instance->IsHeroic())
creature->SetVisible(false);
break;
case NPC_MOLTEN_SLAG:
if (Creature* reaper = GetCreature(DATA_FOE_REAPER_5000))
reaper->AI()->JustSummoned(creature);
break;
default:
break;
}
@@ -119,6 +136,10 @@ class instance_deadmines : public InstanceMapScript
_teamInInstance = data;
SaveToDB();
break;
case DATA_FOE_REAPER_INTRO:
_foeReaper5000Intro = data;
SaveToDB();
break;
default:
break;
}
@@ -130,6 +151,8 @@ class instance_deadmines : public InstanceMapScript
{
case DATA_TEAM_IN_INSTANCE:
return _teamInInstance;
case DATA_FOE_REAPER_INTRO:
return _foeReaper5000Intro;
default:
return 0;
}
@@ -137,16 +160,20 @@ class instance_deadmines : public InstanceMapScript
void WriteSaveDataMore(std::ostringstream& data) override
{
data << _teamInInstance;
data << _teamInInstance << ' '
<< _foeReaper5000Intro;
}
void ReadSaveDataMore(std::istringstream& data) override
{
data >> _teamInInstance;
data >> _foeReaper5000Intro;
}
protected:
uint32 _teamInInstance;
uint32 _foeReaper5000Intro;
};

View File

@@ -71,6 +71,7 @@ void AddSC_deadmines(); //Deadmines
void AddSC_instance_deadmines();
void AddSC_boss_glubtok();
void AddSC_boss_helix_gearbreaker();
void AddSC_boss_foe_reaper_5000();
void AddSC_gilneas_c1(); //Gilneas
void AddSC_gnomeregan(); //Gnomeregan
void AddSC_instance_gnomeregan();
@@ -274,6 +275,7 @@ void AddEasternKingdomsScripts()
AddSC_instance_deadmines();
AddSC_boss_glubtok();
AddSC_boss_helix_gearbreaker();
AddSC_boss_foe_reaper_5000();
AddSC_gilneas_c1(); //Gilneas
AddSC_gnomeregan(); //Gnomeregan
AddSC_instance_gnomeregan();