mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 17:05:44 +01:00
Script/CoS: full instance rewrite (#23388)
(cherry picked from commit ca62280675)
This commit is contained in:
1730
sql/updates/world/master/2021_12_12_01_world_2019_06_25_01_world.sql
Normal file
1730
sql/updates/world/master/2021_12_12_01_world_2019_06_25_01_world.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,41 +15,39 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Script Data Start
|
||||
SDName: Boss epoch
|
||||
SDAuthor: Tartalo
|
||||
SD%Complete: 80
|
||||
SDComment: @todo Intro, consecutive attacks to a random target durin time wrap, adjust timers
|
||||
SDCategory:
|
||||
Script Data End */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include <vector>
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CURSE_OF_EXERTION = 52772,
|
||||
SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec.
|
||||
SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec.
|
||||
SPELL_WOUNDING_STRIKE = 52771 //Used only on the tank
|
||||
SPELL_CURSE_OF_EXERTION = 52772,
|
||||
SPELL_TIME_WARP = 52766,
|
||||
SPELL_TIME_STOP = 58848,
|
||||
SPELL_TIME_STEP_DUMMY = 52736,
|
||||
};
|
||||
|
||||
#define SPELL_TIME_STEP_CHARGE DUNGEON_MODE(52737,58829)
|
||||
#define SPELL_WOUNDING_STRIKE DUNGEON_MODE(52771,58830)
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_TIME_WARP = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
SAY_TIME_WARP = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CURSE_OF_EXERTION = 1,
|
||||
EVENT_CURSE_OF_EXERTION = 1,
|
||||
EVENT_TIME_WARP,
|
||||
EVENT_TIME_STOP,
|
||||
EVENT_WOUNDING_STRIKE
|
||||
EVENT_WOUNDING_STRIKE,
|
||||
EVENT_TIME_STEP
|
||||
};
|
||||
|
||||
class boss_epoch : public CreatureScript
|
||||
@@ -59,17 +57,25 @@ class boss_epoch : public CreatureScript
|
||||
|
||||
struct boss_epochAI : public BossAI
|
||||
{
|
||||
boss_epochAI(Creature* creature) : BossAI(creature, DATA_EPOCH) { }
|
||||
boss_epochAI(Creature* creature) : BossAI(creature, DATA_EPOCH), _stepTargetIndex(0) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
if (instance->GetBossState(DATA_EPOCH) == DONE)
|
||||
me->RemoveLootMode(LOOT_MODE_DEFAULT);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300ms);
|
||||
events.ScheduleEvent(EVENT_TIME_WARP, 25300);
|
||||
events.ScheduleEvent(EVENT_TIME_STOP, 21300);
|
||||
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 5300ms);
|
||||
_stepTargetIndex = 0;
|
||||
_stepTargets.clear();
|
||||
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, Seconds(4), Seconds(6));
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, Seconds(10), Seconds(17));
|
||||
events.ScheduleEvent(EVENT_TIME_WARP, Seconds(25));
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_TIME_STOP, Seconds(15));
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
@@ -79,26 +85,59 @@ class boss_epoch : public CreatureScript
|
||||
case EVENT_CURSE_OF_EXERTION:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_CURSE_OF_EXERTION);
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300ms);
|
||||
events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300);
|
||||
break;
|
||||
case EVENT_TIME_WARP:
|
||||
Talk(SAY_TIME_WARP);
|
||||
DoCastAOE(SPELL_TIME_WARP);
|
||||
events.ScheduleEvent(EVENT_TIME_WARP, 25300);
|
||||
DoCastAOE(SPELL_TIME_STEP_DUMMY);
|
||||
events.Repeat(Seconds(25));
|
||||
break;
|
||||
case EVENT_TIME_STOP:
|
||||
DoCastAOE(SPELL_TIME_STOP);
|
||||
events.ScheduleEvent(EVENT_TIME_STOP, 21300);
|
||||
events.Repeat(Seconds(25));
|
||||
break;
|
||||
case EVENT_WOUNDING_STRIKE:
|
||||
DoCastVictim(SPELL_WOUNDING_STRIKE);
|
||||
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 5300ms);
|
||||
events.Repeat(Seconds(12), Seconds(18));
|
||||
break;
|
||||
case EVENT_TIME_STEP:
|
||||
{
|
||||
// In each step, we charge to a random target that was previously hit by SPELL_TIME_STEP_DUMMY
|
||||
// Once we run out of targets, we charge back to the tank, then stop
|
||||
uint32 nTargets = _stepTargets.size();
|
||||
Unit* target = nullptr;
|
||||
while (nTargets > _stepTargetIndex)
|
||||
{
|
||||
uint32 selected = urand(_stepTargetIndex, nTargets - 1);
|
||||
if (_stepTargetIndex != selected)
|
||||
std::swap(_stepTargets[_stepTargetIndex], _stepTargets[selected]);
|
||||
if ((target = ObjectAccessor::GetUnit(*me, _stepTargets[_stepTargetIndex++])))
|
||||
break;
|
||||
}
|
||||
if (target)
|
||||
events.Repeat(Milliseconds(500));
|
||||
else
|
||||
target = me->GetVictim();
|
||||
|
||||
if (target)
|
||||
DoCast(target, SPELL_TIME_STEP_CHARGE, true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* info) override
|
||||
{
|
||||
if (info->Id == SPELL_TIME_STEP_DUMMY && me->IsHostileTo(target))
|
||||
{
|
||||
_stepTargets.push_back(target->GetGUID());
|
||||
events.RescheduleEvent(EVENT_TIME_STEP, Milliseconds(500));
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
@@ -110,6 +149,10 @@ class boss_epoch : public CreatureScript
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _stepTargetIndex;
|
||||
std::vector<ObjectGuid> _stepTargets;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
@@ -15,31 +15,45 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CORRUPTING_BLIGHT = 60588,
|
||||
SPELL_VOID_STRIKE = 60590,
|
||||
SPELL_CORRUPTION_OF_TIME_CHANNEL = 60422,
|
||||
SPELL_CORRUPTION_OF_TIME_TARGET = 60451
|
||||
SPELL_CORRUPTING_BLIGHT = 60588,
|
||||
SPELL_VOID_STRIKE = 60590,
|
||||
SPELL_CORRUPTION_OF_TIME_CHANNEL = 60422,
|
||||
SPELL_CORRUPTION_OF_TIME_TARGET = 60451
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEATH = 1,
|
||||
SAY_FAIL = 2
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEATH = 1,
|
||||
SAY_FAIL = 2
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CORRUPTING_BLIGHT = 1,
|
||||
EVENT_CORRUPTING_BLIGHT = 1,
|
||||
EVENT_VOID_STRIKE
|
||||
};
|
||||
|
||||
enum Entries
|
||||
{
|
||||
NPC_TIME_RIFT = 28409,
|
||||
NPC_GUARDIAN_OF_TIME = 32281
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
MOVEMENT_TIME_RIFT = 1
|
||||
};
|
||||
|
||||
class boss_infinite_corruptor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -47,17 +61,18 @@ class boss_infinite_corruptor : public CreatureScript
|
||||
|
||||
struct boss_infinite_corruptorAI : public BossAI
|
||||
{
|
||||
boss_infinite_corruptorAI(Creature* creature) : BossAI(creature, DATA_INFINITE) { }
|
||||
boss_infinite_corruptorAI(Creature* creature) : BossAI(creature, DATA_INFINITE_CORRUPTOR) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
DoCastAOE(SPELL_CORRUPTION_OF_TIME_CHANNEL); // implicitly targets the Guardian
|
||||
}
|
||||
|
||||
if (Creature* guardian = me->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
|
||||
{
|
||||
DoCast(nullptr, SPELL_CORRUPTION_OF_TIME_CHANNEL, false);
|
||||
guardian->CastSpell(guardian, SPELL_CORRUPTION_OF_TIME_TARGET, false);
|
||||
}
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_CORRUPTION_OF_TIME_CHANNEL)
|
||||
target->CastSpell(target, SPELL_CORRUPTION_OF_TIME_TARGET, true);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
@@ -100,6 +115,40 @@ class boss_infinite_corruptor : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (me->HasReactState(REACT_PASSIVE))
|
||||
return;
|
||||
BossAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == MOVEMENT_TIME_RIFT)
|
||||
{
|
||||
me->DespawnOrUnsummon(Seconds(2));
|
||||
instance->SetBossState(DATA_INFINITE_CORRUPTOR, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == -ACTION_CORRUPTOR_LEAVE)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Talk(SAY_FAIL);
|
||||
if (Creature* rift = me->FindNearestCreature(NPC_TIME_RIFT, 300.0f))
|
||||
{
|
||||
if (me->IsWithinDist2d(rift, 5.0f))
|
||||
MovementInform(POINT_MOTION_TYPE, MOVEMENT_TIME_RIFT);
|
||||
else
|
||||
me->GetMotionMaster()->MovePoint(MOVEMENT_TIME_RIFT, rift->GetPosition()); // @todo offset
|
||||
}
|
||||
else
|
||||
MovementInform(POINT_MOTION_TYPE, MOVEMENT_TIME_RIFT);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
@@ -15,238 +15,181 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Script Data Start
|
||||
SDName: Boss mal_ganis
|
||||
SDAuthor: Tartalo
|
||||
SD%Complete: 80
|
||||
SDComment: @todo Intro & outro
|
||||
SDCategory:
|
||||
Script Data End */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CARRION_SWARM = 52720, //A cresting wave of chaotic magic splashes over enemies in front of the caster, dealing 3230 to 3570 Shadow damage and 380 to 420 Shadow damage every 3 sec. for 15 sec.
|
||||
SPELL_MIND_BLAST = 52722, //Inflicts 4163 to 4837 Shadow damage to an enemy.
|
||||
SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target.
|
||||
SPELL_VAMPIRIC_TOUCH = 52723, //Heals the caster for half the damage dealt by a melee attack.
|
||||
SPELL_MAL_GANIS_KILL_CREDIT = 58124, // Quest credit
|
||||
SPELL_KILL_CREDIT = 58630 // Non-existing spell as encounter credit, created in spell_dbc
|
||||
SPELL_VAMPIRIC_TOUCH = 52723
|
||||
};
|
||||
|
||||
#define SPELL_CARRION_SWARM DUNGEON_MODE(52720,58852)
|
||||
#define SPELL_MIND_BLAST DUNGEON_MODE(52722,58850)
|
||||
#define SPELL_SLEEP DUNGEON_MODE(52721,58849)
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 2,
|
||||
SAY_KILL = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_SLEEP = 5,
|
||||
SAY_30HEALTH = 6,
|
||||
SAY_15HEALTH = 7,
|
||||
SAY_ESCAPE_SPEECH_1 = 8,
|
||||
SAY_ESCAPE_SPEECH_2 = 9,
|
||||
SAY_OUTRO = 10
|
||||
SAY_KILL = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_SLEEP = 5,
|
||||
SAY_30HEALTH = 6,
|
||||
SAY_15HEALTH = 7
|
||||
};
|
||||
|
||||
enum CombatPhases
|
||||
enum Events
|
||||
{
|
||||
COMBAT,
|
||||
OUTRO
|
||||
EVENT_CARRION_SWARM = 1,
|
||||
EVENT_MIND_BLAST,
|
||||
EVENT_VAMPIRIC_TOUCH,
|
||||
EVENT_SLEEP
|
||||
};
|
||||
|
||||
class boss_mal_ganis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_mal_ganis() : CreatureScript("boss_mal_ganis") { }
|
||||
public:
|
||||
boss_mal_ganis() : CreatureScript("boss_mal_ganis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetCullingOfStratholmeAI<boss_mal_ganisAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_mal_ganisAI : public ScriptedAI
|
||||
{
|
||||
boss_mal_ganisAI(Creature* creature) : ScriptedAI(creature)
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
uiOutroStep = 0;
|
||||
if (!InstanceHasScript(creature, CoSScriptName))
|
||||
return nullptr;
|
||||
|
||||
if (creature->GetInstanceScript()->GetData(DATA_INSTANCE_PROGRESS) < MALGANIS_IN_PROGRESS)
|
||||
return new NullCreatureAI(creature);
|
||||
else
|
||||
return new boss_mal_ganisAI(creature);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
struct boss_mal_ganisAI : public BossAI
|
||||
{
|
||||
bYelled = false;
|
||||
bYelled2 = false;
|
||||
Phase = COMBAT;
|
||||
uiCarrionSwarmTimer = 6000;
|
||||
uiMindBlastTimer = 11000;
|
||||
uiVampiricTouchTimer = urand(10000, 15000);
|
||||
uiSleepTimer = urand(15000, 20000);
|
||||
uiOutroTimer = 1000;
|
||||
}
|
||||
boss_mal_ganisAI(Creature* creature) : BossAI(creature, DATA_MAL_GANIS), _defeated(false), _hadYell30(false), _hadYell15(false) { }
|
||||
|
||||
uint32 uiCarrionSwarmTimer;
|
||||
uint32 uiMindBlastTimer;
|
||||
uint32 uiVampiricTouchTimer;
|
||||
uint32 uiSleepTimer;
|
||||
|
||||
uint8 uiOutroStep;
|
||||
uint32 uiOutroTimer;
|
||||
|
||||
bool bYelled;
|
||||
bool bYelled2;
|
||||
|
||||
CombatPhases Phase;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
instance->SetBossState(DATA_MAL_GANIS, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_MAL_GANIS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* done_by, uint32 &damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && done_by != me)
|
||||
damage = me->GetHealth()-1;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
switch (Phase)
|
||||
void Reset() override
|
||||
{
|
||||
case COMBAT:
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!bYelled && HealthBelowPct(30))
|
||||
{
|
||||
Talk(SAY_30HEALTH);
|
||||
bYelled = true;
|
||||
}
|
||||
|
||||
if (!bYelled2 && HealthBelowPct(15))
|
||||
{
|
||||
Talk(SAY_15HEALTH);
|
||||
bYelled2 = true;
|
||||
}
|
||||
|
||||
if (HealthBelowPct(1))
|
||||
{
|
||||
//Handle Escape Event: Don't forget to add Player::RewardPlayerAndGroupAtEvent
|
||||
me->AddUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE));
|
||||
uiOutroStep = 1;
|
||||
Phase = OUTRO;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Creature* pArthas = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ARTHAS)))
|
||||
if (pArthas->isDead())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
me->DisappearAndDie();
|
||||
instance->SetBossState(DATA_MAL_GANIS, FAIL);
|
||||
}
|
||||
|
||||
if (uiCarrionSwarmTimer < diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CARRION_SWARM);
|
||||
uiCarrionSwarmTimer = 7000;
|
||||
} else uiCarrionSwarmTimer -= diff;
|
||||
|
||||
if (uiMindBlastTimer < diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_MIND_BLAST);
|
||||
uiMindBlastTimer = 6000;
|
||||
} else uiMindBlastTimer -= diff;
|
||||
|
||||
if (uiVampiricTouchTimer < diff)
|
||||
{
|
||||
DoCast(me, SPELL_VAMPIRIC_TOUCH);
|
||||
uiVampiricTouchTimer = 32000;
|
||||
} else uiVampiricTouchTimer -= diff;
|
||||
|
||||
if (uiSleepTimer < diff)
|
||||
{
|
||||
Talk(SAY_SLEEP);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_SLEEP);
|
||||
uiSleepTimer = urand(15000, 20000);
|
||||
} else uiSleepTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
break;
|
||||
case OUTRO:
|
||||
if (uiOutroTimer < diff)
|
||||
{
|
||||
switch (uiOutroStep)
|
||||
{
|
||||
case 1:
|
||||
Talk(SAY_OUTRO);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
++uiOutroStep;
|
||||
uiOutroTimer = 8000;
|
||||
break;
|
||||
case 2:
|
||||
me->SetTarget(instance->GetGuidData(DATA_ARTHAS));
|
||||
me->HandleEmoteCommand(29);
|
||||
Talk(SAY_ESCAPE_SPEECH_2);
|
||||
++uiOutroStep;
|
||||
uiOutroTimer = 9000;
|
||||
break;
|
||||
case 3:
|
||||
Talk(SAY_OUTRO);
|
||||
++uiOutroStep;
|
||||
//uiOutroTimer = 16000;
|
||||
break;
|
||||
case 4:
|
||||
me->HandleEmoteCommand(33);
|
||||
++uiOutroStep;
|
||||
uiOutroTimer = 500;
|
||||
break;
|
||||
case 5:
|
||||
me->SetVisible(false);
|
||||
me->KillSelf();
|
||||
break;
|
||||
|
||||
}
|
||||
} else uiOutroTimer -= diff;
|
||||
break;
|
||||
if (!_defeated)
|
||||
instance->SetBossState(DATA_MAL_GANIS, NOT_STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SetBossState(DATA_MAL_GANIS, DONE);
|
||||
DoCastAOE(SPELL_MAL_GANIS_KILL_CREDIT, true);
|
||||
// give achievement credit and LFG rewards to players. criteria use spell 58630 which doesn't exist, but it was created in spell_dbc
|
||||
DoCastAOE(SPELL_KILL_CREDIT);
|
||||
}
|
||||
void DamageTaken(Unit* /*source*/, uint32 &damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
if (_defeated)
|
||||
return;
|
||||
_defeated = true;
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
// @todo hack most likely
|
||||
if (InstanceMap* map = instance->instance->ToInstanceMap())
|
||||
map->PermBindAllPlayers();
|
||||
}
|
||||
}
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
};
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_defeated = false;
|
||||
_hadYell30 = false;
|
||||
_hadYell15 = false;
|
||||
events.ScheduleEvent(EVENT_CARRION_SWARM, Seconds(5));
|
||||
events.ScheduleEvent(EVENT_MIND_BLAST, Seconds(6), Seconds(8));
|
||||
events.ScheduleEvent(EVENT_VAMPIRIC_TOUCH, Seconds(4));
|
||||
events.ScheduleEvent(EVENT_SLEEP, Seconds(17), Seconds(21));
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
if (!_defeated)
|
||||
me->DespawnOrUnsummon(Seconds(1));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (_defeated)
|
||||
{
|
||||
if (me->IsInCombat())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
me->SetImmuneToAll(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!_hadYell30 && HealthBelowPct(30))
|
||||
{
|
||||
Talk(SAY_30HEALTH);
|
||||
_hadYell30 = true;
|
||||
}
|
||||
|
||||
if (!_hadYell15 && HealthBelowPct(15))
|
||||
{
|
||||
Talk(SAY_15HEALTH);
|
||||
_hadYell15 = true;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CARRION_SWARM:
|
||||
DoCastAOE(SPELL_CARRION_SWARM);
|
||||
events.Repeat(Seconds(6));
|
||||
break;
|
||||
case EVENT_MIND_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, -int32(SPELL_SLEEP)))
|
||||
DoCast(target, SPELL_MIND_BLAST);
|
||||
else
|
||||
DoCastVictim(SPELL_MIND_BLAST);
|
||||
events.Repeat(Seconds(8), Seconds(12));
|
||||
break;
|
||||
case EVENT_VAMPIRIC_TOUCH:
|
||||
DoCastSelf(SPELL_VAMPIRIC_TOUCH);
|
||||
events.Repeat(Seconds(30));
|
||||
break;
|
||||
case EVENT_SLEEP:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f))
|
||||
DoCast(target, SPELL_SLEEP);
|
||||
else
|
||||
DoCastVictim(SPELL_SLEEP);
|
||||
events.Repeat(Seconds(10), Seconds(15));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!_defeated && victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _defeated;
|
||||
bool _hadYell30;
|
||||
bool _hadYell15;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_mal_ganis()
|
||||
|
||||
@@ -15,28 +15,30 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CONSTRICTING_CHAINS = 52696, //Encases the targets in chains, dealing 1800 Physical damage every 1 sec. and stunning the target for 5 sec.
|
||||
SPELL_DISEASE_EXPULSION = 52666, //Meathook belches out a cloud of disease, dealing 1710 to 1890 Nature damage and interrupting the spell casting of nearby enemy targets for 4 sec.
|
||||
SPELL_FRENZY = 58841 //Increases the caster's Physical damage by 10% for 30 sec.
|
||||
SPELL_FRENZY = 58841
|
||||
};
|
||||
|
||||
#define SPELL_CONSTRICTING_CHAINS DUNGEON_MODE(52696,58823)
|
||||
#define SPELL_DISEASE_EXPULSION DUNGEON_MODE(52666,58824)
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SPAWN = 2,
|
||||
SAY_DEATH = 3
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SPAWN = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CHAIN = 1,
|
||||
EVENT_CHAIN = 1,
|
||||
EVENT_DISEASE,
|
||||
EVENT_FRENZY
|
||||
};
|
||||
@@ -48,18 +50,22 @@ class boss_meathook : public CreatureScript
|
||||
|
||||
struct boss_meathookAI : public BossAI
|
||||
{
|
||||
boss_meathookAI(Creature* creature) : BossAI(creature, DATA_MEATHOOK)
|
||||
boss_meathookAI(Creature* creature) : BossAI(creature, DATA_MEATHOOK) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
if (instance->GetBossState(DATA_MEATHOOK) == DONE)
|
||||
me->RemoveLootMode(LOOT_MODE_DEFAULT);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
events.ScheduleEvent(EVENT_CHAIN, 12s, 17s);
|
||||
events.ScheduleEvent(EVENT_DISEASE, 2s, 4s);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 21s, 26s);
|
||||
events.ScheduleEvent(EVENT_CHAIN, Seconds(7), Seconds(11));
|
||||
events.ScheduleEvent(EVENT_DISEASE, Seconds(2));
|
||||
events.ScheduleEvent(EVENT_FRENZY, Seconds(13), Seconds(17));
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
@@ -67,17 +73,21 @@ class boss_meathook : public CreatureScript
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHAIN:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, -20.0f, true))
|
||||
DoCast(target, SPELL_CONSTRICTING_CHAINS);
|
||||
events.ScheduleEvent(EVENT_CHAIN, 2s, 4s);
|
||||
else if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
||||
DoCast(target, SPELL_CONSTRICTING_CHAINS);
|
||||
else
|
||||
DoCastVictim(SPELL_CONSTRICTING_CHAINS);
|
||||
events.Repeat(Seconds(10), Seconds(15));
|
||||
break;
|
||||
case EVENT_DISEASE:
|
||||
DoCastAOE(SPELL_DISEASE_EXPULSION);
|
||||
events.ScheduleEvent(EVENT_DISEASE, 1500ms, 4s);
|
||||
events.Repeat(Seconds(3)+Milliseconds(500));
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 21s, 26s);
|
||||
events.Repeat(Seconds(13), Seconds(17));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -88,6 +98,7 @@ class boss_meathook : public CreatureScript
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
instance->SetData(DATA_NOTIFY_DEATH, 1);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
|
||||
@@ -15,34 +15,41 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CURSE_OF_TWISTED_FLESH = 58845,
|
||||
SPELL_EXPLODE_GHOUL = 52480,
|
||||
SPELL_SHADOW_BOLT = 57725,
|
||||
SPELL_STEAL_FLESH = 52708,
|
||||
SPELL_SUMMON_GHOULS = 52451
|
||||
SPELL_CURSE_OF_TWISTED_FLESH = 58845,
|
||||
SPELL_STEAL_FLESH = 52708,
|
||||
SPELL_STEAL_FLESH_DEBUFF = 52711,
|
||||
SPELL_STEAL_FLESH_BUFF = 52712,
|
||||
SPELL_SUMMON_GHOULS = 52451
|
||||
};
|
||||
|
||||
#define SPELL_EXPLODE_GHOUL DUNGEON_MODE(52480,58825)
|
||||
#define SPELL_SHADOW_BOLT DUNGEON_MODE(57725,58827)
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SPAWN = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_EXPLODE_GHOUL = 4,
|
||||
SAY_STEAL_FLESH = 5,
|
||||
SAY_SUMMON_GHOULS = 6
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SPAWN = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_EXPLODE_GHOUL = 4,
|
||||
SAY_STEAL_FLESH = 5,
|
||||
SAY_SUMMON_GHOULS = 6
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CURSE_FLESH = 1,
|
||||
EVENT_EXPLODE_GHOUL,
|
||||
EVENT_CURSE_FLESH = 1,
|
||||
EVENT_EXPLODE_GHOUL1,
|
||||
EVENT_EXPLODE_GHOUL2,
|
||||
EVENT_SHADOW_BOLT,
|
||||
EVENT_STEAL_FLESH,
|
||||
EVENT_SUMMON_GHOULS
|
||||
@@ -55,9 +62,13 @@ class boss_salramm : public CreatureScript
|
||||
|
||||
struct boss_salrammAI : public BossAI
|
||||
{
|
||||
boss_salrammAI(Creature* creature) : BossAI(creature, DATA_SALRAMM)
|
||||
boss_salrammAI(Creature* creature) : BossAI(creature, DATA_SALRAMM) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
if (instance->GetBossState(DATA_SALRAMM) == DONE)
|
||||
me->RemoveLootMode(LOOT_MODE_DEFAULT);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
@@ -65,10 +76,11 @@ class boss_salramm : public CreatureScript
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
|
||||
events.ScheduleEvent(EVENT_CURSE_FLESH, 30s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GHOULS, 19s, 24s);
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, 8s, 12s);
|
||||
events.ScheduleEvent(EVENT_STEAL_FLESH, 12345); /// @todo: adjust timer
|
||||
events.ScheduleEvent(EVENT_SUMMON_GHOULS, randtime(Seconds(19),Seconds(24)));
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, Seconds(2));
|
||||
events.ScheduleEvent(EVENT_STEAL_FLESH, Seconds(25), Seconds(35));
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_CURSE_FLESH, Seconds(40));
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
@@ -77,28 +89,31 @@ class boss_salramm : public CreatureScript
|
||||
{
|
||||
case EVENT_CURSE_FLESH:
|
||||
DoCastVictim(SPELL_CURSE_OF_TWISTED_FLESH);
|
||||
events.ScheduleEvent(EVENT_CURSE_FLESH, 35s);
|
||||
events.Repeat(Seconds(37));
|
||||
break;
|
||||
case EVENT_SUMMON_GHOULS:
|
||||
Talk(SAY_SUMMON_GHOULS);
|
||||
DoCast(me, SPELL_SUMMON_GHOULS);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GHOULS, 10s);
|
||||
events.ScheduleEvent(EVENT_EXPLODE_GHOUL, 6s);
|
||||
DoCastAOE(SPELL_SUMMON_GHOULS);
|
||||
events.ScheduleEvent(EVENT_EXPLODE_GHOUL1, Seconds(20), Seconds(24));
|
||||
events.ScheduleEvent(EVENT_EXPLODE_GHOUL2, Seconds(25), Seconds(29));
|
||||
break;
|
||||
case EVENT_SHADOW_BOLT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
|
||||
DoCast(target, SPELL_SHADOW_BOLT);
|
||||
events.ScheduleEvent(EVENT_SHADOW_BOLT, 8s, 12s);
|
||||
events.Repeat(Seconds(3));
|
||||
break;
|
||||
case EVENT_STEAL_FLESH:
|
||||
Talk(SAY_STEAL_FLESH);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 50.0f, true))
|
||||
DoCast(target, SPELL_STEAL_FLESH);
|
||||
events.ScheduleEvent(EVENT_STEAL_FLESH, 12345);
|
||||
events.Repeat(Seconds(15), Seconds(20));
|
||||
break;
|
||||
case EVENT_EXPLODE_GHOUL:
|
||||
case EVENT_EXPLODE_GHOUL2:
|
||||
events.ScheduleEvent(EVENT_SUMMON_GHOULS, Seconds(4));
|
||||
// intentional missing break
|
||||
case EVENT_EXPLODE_GHOUL1:
|
||||
Talk(SAY_EXPLODE_GHOUL);
|
||||
DoCast(me, SPELL_EXPLODE_GHOUL, true);
|
||||
DoCastAOE(SPELL_EXPLODE_GHOUL, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -109,6 +124,7 @@ class boss_salramm : public CreatureScript
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
instance->SetData(DATA_NOTIFY_DEATH, 1);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
@@ -124,7 +140,24 @@ class boss_salramm : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_salramm_steal_flesh : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_salramm_steal_flesh);
|
||||
|
||||
void HandlePeriodic(AuraEffect const* /*eff*/)
|
||||
{
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_STEAL_FLESH_BUFF, true);
|
||||
GetCaster()->CastSpell(GetTarget(), SPELL_STEAL_FLESH_DEBUFF, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_salramm_steal_flesh::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_salramm()
|
||||
{
|
||||
new boss_salramm();
|
||||
RegisterAuraScript(spell_salramm_steal_flesh);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,92 +15,156 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_CULLING_OF_STRATHOLME_H
|
||||
#define DEF_CULLING_OF_STRATHOLME_H
|
||||
#ifndef CULLING_OF_STRATHOLME_H
|
||||
#define CULLING_OF_STRATHOLME_H
|
||||
|
||||
#include "CreatureAIImpl.h"
|
||||
|
||||
#define CoSScriptName "instance_culling_of_stratholme"
|
||||
#define DataHeader "CS"
|
||||
#define CoSScriptName "instance_culling_of_stratholme"
|
||||
|
||||
uint32 const EncounterCount = 5;
|
||||
uint32 constexpr EncounterCount = 5;
|
||||
|
||||
enum CSDataTypes
|
||||
/***********************************************************************************************************************\
|
||||
|************************* A DEVELOPER'S GUIDE TO FINDING YOUR WAY AROUND THIS INSTANCE SCRIPT *************************|
|
||||
|***********************************************************************************************************************|
|
||||
* The primary instance logic is split between the instance control script (instance_culling_of_stratholme.cpp) and *
|
||||
* Arthas' creature AI (npc_arthas.cpp). The instance script is responsible for global state management and control *
|
||||
* of the Scourge Wave event, as well as spawn control (ties into state management) with the help of the templated *
|
||||
* CreatureScript wrapper (CanSpawn override as well as Despawn checks on state change) defined in this very header. *
|
||||
* Arthas handles all the actual RP timings, pathing, spawns, casts and everything else, really. He also does tons *
|
||||
* of state control for himself (positional snapback and gossip/flag management). *
|
||||
* Communication between these two scripts (with some auxiliary other scripts throwing stuff in too) is handled *
|
||||
* via the SetData/SetGuidData/SetGUID methods on CreatureAI and InstanceScript (as appropriate), as well as *
|
||||
* data retrieval using GetData (instance states and the like). *
|
||||
* All values specified in this header find use across multiple files (used for communication between them) while *
|
||||
* the enums in the files themselves contain action IDs, event IDs, entries and whatnot that only find use in that *
|
||||
* particular file. *
|
||||
* Generally, any RP sequence will follow the form: *
|
||||
* 1. RP sequence is started (creature gossip sends SetGuidData with starting player GUID to InstanceScript) *
|
||||
* 2. InstanceScript verifies state consistency and advances the global instance state *
|
||||
* 3. InstanceScript passes the player GUID to Arthas AI using SetGUID. The int32 data type serves as action ID. *
|
||||
* 4. Arthas AI schedules all necessary events for the sequence and handles it from there using its UpdateAI loop. *
|
||||
* 5. At the end of the sequence, Arthas AI notifies the instance script (using SetData). *
|
||||
* 6. The instance script advances the global state again. This state change is propagated to Arthas AI (SetData). *
|
||||
* 7. Arthas AI is notified of a state change, gets current progress (GetData) and adjusts gossip availability etc. *
|
||||
* 8. The cycle repeats. RP sequences (as above) can (and do) also include combat sequences and similar. *
|
||||
|***********************************************************************************************************************|
|
||||
|*********************************************** KEY METHODS TO LOOK FOR ***********************************************|
|
||||
|***********************************************************************************************************************|
|
||||
* Arthas AI: (npc_arthas_stratholmeAI in npc_arthas.cpp) *
|
||||
* - AdvanceToState: *
|
||||
* - handles all the state updating/position consistency logic *
|
||||
* - invoked from SetData when the instance script notifies Arthas of a state change *
|
||||
* - ScheduleActionOOC: *
|
||||
* - queues the specified action to be passed to DoAction after Arthas finishes combat (JustReachedHome) *
|
||||
* - typically called during RP sequences just after ensuring Arthas has entered combat with all enemies involved *
|
||||
* - MovementInform: *
|
||||
* - handles movement notifications not just for Arthas, but also some other creatures that run RP slave AI *
|
||||
* - all movement IDs are taken from one single PointIDs enum, which means they are still unique *
|
||||
* - EnterCombat: *
|
||||
* - stores the current spline chain state so we can resume after (JustReachedHome) *
|
||||
|***********************************************************************************************************************|
|
||||
* Instance script: (instance_culling_of_stratholme in instance_culling_of_stratholme.cpp) *
|
||||
* - GetStableStateFor: *
|
||||
* - handles state regression; only certain states should be loaded after a wipe/soft reset *
|
||||
* - SetInstanceProgress: *
|
||||
* - any changing of the global instance state is done through this method *
|
||||
* - handles world state adjustments, spawn control (through AI notification) as well as reset behavior *
|
||||
* - SetWorldState/PropagateWorldStateUpdate: *
|
||||
* - the instance script stores a std::map of all current world state values for the instance *
|
||||
* - SetWorldState adjusts this map, PropagateWorldStateUpdate sends any changed values to all players *
|
||||
* - FillInitialWorldStates also draws upon this map to ensure all players have the same states at all times *
|
||||
|***********************************************************************************************************************|
|
||||
* Spawn control script: (StratholmeCreatureScript<ParentAI> in culling_of_stratholme.h) *
|
||||
* - CanSpawn override: *
|
||||
* - gets current instance state using GetData, then checks if we should be allowed to respawn (bitmask check) *
|
||||
* - StratholmeNPCAIWrapper::CheckDespawn: *
|
||||
* - gets current instance state using GetData, then checks if we should despawn ourselves (bitmask check) *
|
||||
\***********************************************************************************************************************/
|
||||
|
||||
struct Position;
|
||||
|
||||
// Note: These are bitmask values to allow combining, but only a single bit will ever be true in instance script
|
||||
enum COSProgressStates : uint32
|
||||
{
|
||||
JUST_STARTED = 0x00001, // dungeon just started, crate count not visible yet; pending chromie interaction
|
||||
CRATES_IN_PROGRESS = 0x00002, // freshly started dungeon, players are revealing scourge crates
|
||||
CRATES_DONE = 0x00004, // all crates revealed, chromie spawns at Stratholme entrance; waiting for player input to begin first RP event
|
||||
UTHER_TALK = 0x00008, // RP event in progress, Uther+Arthas talking
|
||||
PURGE_PENDING = 0x00010, // RP event done, pending player input to start wave event
|
||||
PURGE_STARTING = 0x00020, // Arthas entering Stratholme, RP sequence with Mal'ganis
|
||||
WAVES_IN_PROGRESS = 0x00040, // first section is underway, players are battling waves
|
||||
WAVES_DONE = 0x00080, // wave section completed; Arthas moving to take position in front of Stratholme Town Hall
|
||||
TOWN_HALL_PENDING = 0x00100, // Arthas has reached the Town Hall; pending player input to begin escort section
|
||||
TOWN_HALL = 0x00200, // now escorting Arthas through Stratholme Town Hall
|
||||
TOWN_HALL_COMPLETE = 0x00400, // Town Hall event complete, third boss defeated; pending player input to begin gauntlet transition
|
||||
GAUNTLET_TRANSITION = 0x00800, // Arthas is leading players through the secret passage from Town Hall to the gauntlet
|
||||
GAUNTLET_PENDING = 0x01000, // Pending player input to begin escorting Arthas through the final gauntlet section
|
||||
GAUNTLET_IN_PROGRESS = 0x02000, // Arthas is being escorted through the gauntlet section
|
||||
GAUNTLET_COMPLETE = 0x04000, // Arthas has reached the end of the gauntlet section; player input pending to begin Mal'ganis encounter
|
||||
MALGANIS_IN_PROGRESS = 0x08000, // Arthas has moved into the final square and Mal'ganis encounter begins
|
||||
COMPLETE = 0x10000, // Mal'ganis encounter is completed; dungeon over
|
||||
|
||||
ALL = 0x1FFFF
|
||||
};
|
||||
COSProgressStates GetStableStateFor(COSProgressStates const state); // defined by instance script
|
||||
Position const& GetArthasSnapbackFor(COSProgressStates state); // defined by arthas script
|
||||
|
||||
enum COSInstanceData
|
||||
{
|
||||
DATA_ARTHAS,
|
||||
DATA_MEATHOOK,
|
||||
DATA_SALRAMM,
|
||||
DATA_EPOCH,
|
||||
DATA_MAL_GANIS,
|
||||
DATA_INFINITE,
|
||||
DATA_CRATE_COUNT,
|
||||
DATA_SHKAF_GATE,
|
||||
DATA_MAL_GANIS_GATE_1,
|
||||
DATA_MAL_GANIS_GATE_2,
|
||||
DATA_EXIT_GATE,
|
||||
DATA_MAL_GANIS_CHEST,
|
||||
DATA_INFINITE_COUNTER
|
||||
DATA_INFINITE_CORRUPTOR,
|
||||
NUM_BOSS_ENCOUNTERS,
|
||||
|
||||
DATA_INSTANCE_PROGRESS = NUM_BOSS_ENCOUNTERS, // GET only
|
||||
DATA_GM_RECALL, // sent by chromie #1 in response to GM recall command (teleport all to arthas)
|
||||
DATA_GM_OVERRIDE, // sent by chromie #1 in response to GM instance state change commands
|
||||
DATA_ARTHAS_DIED, // failure signal, sent by arthas AI on death - regress instance
|
||||
DATA_CRATES_START, // sent by chromie #1 creature script to initiate crate phase
|
||||
DATA_CRATE_REVEALED, // sent by crate helper AI to trigger re-check of crate status
|
||||
DATA_UTHER_START, // sent by chromie #2 creature script to initiate uther RP sequence
|
||||
DATA_UTHER_FINISHED, // sent by arthas AI to signal transition to pre-purge
|
||||
DATA_SKIP_TO_PURGE, // sent by chromie #1 creature script to skip straight to start of purge
|
||||
DATA_START_PURGE, // sent by arthas creature script to begin pre-purge RP event
|
||||
DATA_START_WAVES, // sent by arthas AI to begin wave event
|
||||
DATA_NOTIFY_DEATH, // sent by wave mob AI to instance script on death
|
||||
DATA_REACH_TOWN_HALL, // sent by arthas AI once he reaches stratholme town hall
|
||||
DATA_START_TOWN_HALL, // sent by arthas creature script to begin town hall sequence
|
||||
DATA_TOWN_HALL_DONE, // sent by arthas AI once Epoch is defeated
|
||||
DATA_TO_GAUNTLET, // sent by arthas creature script to begin gauntlet transition
|
||||
DATA_GAUNTLET_REACHED, // sent by arthas AI once he arrives at the beginning of the gauntlet section
|
||||
DATA_START_GAUNTLET, // sent by arthas creature script to begin gauntlet escort
|
||||
DATA_GAUNTLET_DONE, // sent by arthas AI once he arrives at the end of the gauntlet section
|
||||
DATA_START_MALGANIS, // sent by arthas creature script to begin mal'ganis event
|
||||
DATA_MALGANIS_DONE // sent by arthas AI once mal'ganis outro is over
|
||||
};
|
||||
|
||||
enum CSCreatureIds
|
||||
// these are sent by instance AI to creatures; they are passed as negative values to avoid conflicts with creature script specific actions
|
||||
enum COSInstanceActions
|
||||
{
|
||||
NPC_MEATHOOK = 26529,
|
||||
NPC_SALRAMM = 26530,
|
||||
NPC_EPOCH = 26532,
|
||||
NPC_MAL_GANIS = 26533,
|
||||
NPC_INFINITE = 32273,
|
||||
NPC_ARTHAS = 26499,
|
||||
NPC_JAINA = 26497,
|
||||
NPC_UTHER = 26528,
|
||||
NPC_CHROMIE = 26527,
|
||||
NPC_CHROMIE_2 = 27915,
|
||||
NPC_CHROMIE_3 = 30997,
|
||||
NPC_GENERIC_BUNNY = 28960,
|
||||
|
||||
NPC_TIME_RIFT = 28409,
|
||||
NPC_GUARDIAN_OF_TIME = 32281
|
||||
ACTION_PROGRESS_UPDATE = 1,
|
||||
ACTION_CORRUPTOR_LEAVE,
|
||||
ACTION_START_RP_EVENT1, // Arthas/Uther chat in front of town
|
||||
ACTION_START_RP_EVENT2, // Arthas/Mal'ganis chat at entrance
|
||||
ACTION_START_RP_EVENT3, // Town Hall sequence
|
||||
ACTION_START_RP_EVENT4_1, // Bookcase transition sequence
|
||||
ACTION_START_RP_EVENT4_2, // Gauntlet escort phase
|
||||
ACTION_START_RP_EVENT5 // Mal'ganis encounter
|
||||
};
|
||||
|
||||
enum CSGameObjectIds
|
||||
enum COSInstanceEntries
|
||||
{
|
||||
GO_SHKAF_GATE = 188686,
|
||||
GO_MALGANIS_GATE_1 = 187711,
|
||||
GO_MALGANIS_GATE_2 = 187723,
|
||||
GO_EXIT_GATE = 191788,
|
||||
GO_MALGANIS_CHEST_N = 190663,
|
||||
GO_MALGANIS_CHEST_H = 193597,
|
||||
GO_SUSPICIOUS_CRATE = 190094,
|
||||
GO_PLAGUED_CRATE = 190095
|
||||
};
|
||||
|
||||
enum CSWorldStatesCoT
|
||||
{
|
||||
WORLDSTATE_SHOW_CRATES = 3479,
|
||||
WORLDSTATE_CRATES_REVEALED = 3480,
|
||||
WORLDSTATE_WAVE_COUNT = 3504,
|
||||
WORLDSTATE_TIME_GUARDIAN = 3931,
|
||||
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932
|
||||
};
|
||||
|
||||
enum CSCrateSpells
|
||||
{
|
||||
SPELL_CRATES_CREDIT = 58109
|
||||
};
|
||||
|
||||
enum CSTexts
|
||||
{
|
||||
SAY_CRATES_COMPLETED = 0,
|
||||
// Chromie
|
||||
SAY_INFINITE_START = 0, // On Infinite Corruptor event start
|
||||
SAY_INFINITE = 1, // On Infinite Corruptor event at 5 minutes
|
||||
SAY_INFINITE_FAIL = 2, // On Infinite Corruptor event fail
|
||||
// Infinite Corruptor
|
||||
SAY_FAIL_EVENT = 2 // On Infinite Corruptor event fail
|
||||
};
|
||||
|
||||
enum CSInstanceEvents
|
||||
{
|
||||
EVENT_INFINITE_TIMER = 1
|
||||
NPC_ARTHAS = 26499,
|
||||
GO_HIDDEN_PASSAGE = 188686,
|
||||
SPAWNGRP_CHROMIE_MID = 52,
|
||||
SPAWNGRP_CRATE_HELPERS = 53,
|
||||
SPAWNGRP_GAUNTLET_TRASH = 54,
|
||||
SPAWNGRP_UNDEAD_TRASH = 55,
|
||||
SPAWNGRP_RESIDENTS = 56
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,12 +16,14 @@
|
||||
*/
|
||||
|
||||
// This is where scripts' loading functions should be declared:
|
||||
void AddSC_blackfathom_deeps(); //Blackfathom Depths
|
||||
// Blackfathom Depths
|
||||
void AddSC_blackfathom_deeps();
|
||||
void AddSC_boss_gelihast();
|
||||
void AddSC_boss_kelris();
|
||||
void AddSC_boss_aku_mai();
|
||||
void AddSC_instance_blackfathom_deeps();
|
||||
void AddSC_hyjal(); //CoT Battle for Mt. Hyjal
|
||||
// CoT Battle for Mt. Hyjal
|
||||
void AddSC_hyjal();
|
||||
void AddSC_boss_archimonde();
|
||||
void AddSC_instance_mount_hyjal();
|
||||
void AddSC_hyjal_trash();
|
||||
@@ -29,48 +31,60 @@ void AddSC_boss_rage_winterchill();
|
||||
void AddSC_boss_anetheron();
|
||||
void AddSC_boss_kazrogal();
|
||||
void AddSC_boss_azgalor();
|
||||
void AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad
|
||||
// CoT Old Hillsbrad
|
||||
void AddSC_boss_captain_skarloc();
|
||||
void AddSC_boss_epoch_hunter();
|
||||
void AddSC_boss_lieutenant_drake();
|
||||
void AddSC_instance_old_hillsbrad();
|
||||
void AddSC_old_hillsbrad();
|
||||
void AddSC_boss_aeonus(); //CoT The Black Morass
|
||||
// CoT The Black Morass
|
||||
void AddSC_boss_aeonus();
|
||||
void AddSC_boss_chrono_lord_deja();
|
||||
void AddSC_boss_temporus();
|
||||
void AddSC_the_black_morass();
|
||||
void AddSC_instance_the_black_morass();
|
||||
void AddSC_boss_epoch(); //CoT Culling Of Stratholme
|
||||
// CoT Culling Of Stratholme
|
||||
void AddSC_boss_epoch();
|
||||
void AddSC_npc_arthas_stratholme();
|
||||
void AddSC_boss_infinite_corruptor();
|
||||
void AddSC_boss_salramm();
|
||||
void AddSC_boss_mal_ganis();
|
||||
void AddSC_boss_meathook();
|
||||
void AddSC_culling_of_stratholme();
|
||||
void AddSC_instance_culling_of_stratholme();
|
||||
void AddSC_instance_dire_maul(); //Dire Maul
|
||||
void AddSC_instance_ragefire_chasm(); //Ragefire Chasm
|
||||
void AddSC_boss_celebras_the_cursed(); //Maraudon
|
||||
// Dire Maul
|
||||
void AddSC_instance_dire_maul();
|
||||
// Ragefire Chasm
|
||||
void AddSC_instance_ragefire_chasm();
|
||||
// Maraudon
|
||||
void AddSC_boss_celebras_the_cursed();
|
||||
void AddSC_boss_landslide();
|
||||
void AddSC_boss_noxxion();
|
||||
void AddSC_boss_ptheradras();
|
||||
void AddSC_instance_maraudon();
|
||||
void AddSC_boss_onyxia(); //Onyxia's Lair
|
||||
// Onyxia's Lair
|
||||
void AddSC_boss_onyxia();
|
||||
void AddSC_instance_onyxias_lair();
|
||||
void AddSC_boss_tuten_kash(); //Razorfen Downs
|
||||
// Razorfen Downs
|
||||
void AddSC_boss_tuten_kash();
|
||||
void AddSC_boss_mordresh_fire_eye();
|
||||
void AddSC_boss_glutton();
|
||||
void AddSC_boss_amnennar_the_coldbringer();
|
||||
void AddSC_razorfen_downs();
|
||||
void AddSC_instance_razorfen_downs();
|
||||
void AddSC_razorfen_kraul(); //Razorfen Kraul
|
||||
// Razorfen Kraul
|
||||
void AddSC_razorfen_kraul();
|
||||
void AddSC_instance_razorfen_kraul();
|
||||
void AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj
|
||||
// Ruins of ahn'qiraj
|
||||
void AddSC_boss_kurinnaxx();
|
||||
void AddSC_boss_rajaxx();
|
||||
void AddSC_boss_moam();
|
||||
void AddSC_boss_buru();
|
||||
void AddSC_boss_ayamiss();
|
||||
void AddSC_boss_ossirian();
|
||||
void AddSC_instance_ruins_of_ahnqiraj();
|
||||
void AddSC_boss_cthun(); //Temple of ahn'qiraj
|
||||
// Temple of ahn'qiraj
|
||||
void AddSC_boss_cthun();
|
||||
void AddSC_boss_viscidus();
|
||||
void AddSC_boss_fankriss();
|
||||
void AddSC_boss_huhuran();
|
||||
@@ -81,9 +95,11 @@ void AddSC_boss_twinemperors();
|
||||
void AddSC_boss_ouro();
|
||||
void AddSC_npc_anubisath_sentinel();
|
||||
void AddSC_instance_temple_of_ahnqiraj();
|
||||
void AddSC_wailing_caverns(); //Wailing caverns
|
||||
// Wailing caverns
|
||||
void AddSC_wailing_caverns();
|
||||
void AddSC_instance_wailing_caverns();
|
||||
void AddSC_boss_zum_rah(); //Zul'Farrak
|
||||
// Zul'Farrak
|
||||
void AddSC_boss_zum_rah();
|
||||
void AddSC_zulfarrak();
|
||||
void AddSC_instance_zulfarrak();
|
||||
void AddSC_instance_halls_of_origination();
|
||||
@@ -121,12 +137,14 @@ void AddSC_winterspring();
|
||||
// void Add${NameOfDirectory}Scripts()
|
||||
void AddKalimdorScripts()
|
||||
{
|
||||
AddSC_blackfathom_deeps(); //Blackfathom Depths
|
||||
// Blackfathom Depths
|
||||
AddSC_blackfathom_deeps();
|
||||
AddSC_boss_gelihast();
|
||||
AddSC_boss_kelris();
|
||||
AddSC_boss_aku_mai();
|
||||
AddSC_instance_blackfathom_deeps();
|
||||
AddSC_hyjal(); //CoT Battle for Mt. Hyjal
|
||||
// CoT Battle for Mt. Hyjal
|
||||
AddSC_hyjal();
|
||||
AddSC_boss_archimonde();
|
||||
AddSC_instance_mount_hyjal();
|
||||
AddSC_hyjal_trash();
|
||||
@@ -134,48 +152,60 @@ void AddKalimdorScripts()
|
||||
AddSC_boss_anetheron();
|
||||
AddSC_boss_kazrogal();
|
||||
AddSC_boss_azgalor();
|
||||
AddSC_boss_captain_skarloc(); //CoT Old Hillsbrad
|
||||
// CoT Old Hillsbrad
|
||||
AddSC_boss_captain_skarloc();
|
||||
AddSC_boss_epoch_hunter();
|
||||
AddSC_boss_lieutenant_drake();
|
||||
AddSC_instance_old_hillsbrad();
|
||||
AddSC_old_hillsbrad();
|
||||
AddSC_boss_aeonus(); //CoT The Black Morass
|
||||
// CoT The Black Morass
|
||||
AddSC_boss_aeonus();
|
||||
AddSC_boss_chrono_lord_deja();
|
||||
AddSC_boss_temporus();
|
||||
AddSC_the_black_morass();
|
||||
AddSC_instance_the_black_morass();
|
||||
AddSC_boss_epoch(); //CoT Culling Of Stratholme
|
||||
// CoT Culling Of Stratholme
|
||||
AddSC_boss_epoch();
|
||||
AddSC_npc_arthas_stratholme();
|
||||
AddSC_boss_infinite_corruptor();
|
||||
AddSC_boss_salramm();
|
||||
AddSC_boss_mal_ganis();
|
||||
AddSC_boss_meathook();
|
||||
AddSC_culling_of_stratholme();
|
||||
AddSC_instance_culling_of_stratholme();
|
||||
AddSC_instance_dire_maul(); //Dire Maul
|
||||
AddSC_instance_ragefire_chasm(); //Ragefire Chasm
|
||||
AddSC_boss_celebras_the_cursed(); //Maraudon
|
||||
// Dire Maul
|
||||
AddSC_instance_dire_maul();
|
||||
// Ragefire Chasm
|
||||
AddSC_instance_ragefire_chasm();
|
||||
//Maraudon
|
||||
AddSC_boss_celebras_the_cursed();
|
||||
AddSC_boss_landslide();
|
||||
AddSC_boss_noxxion();
|
||||
AddSC_boss_ptheradras();
|
||||
AddSC_instance_maraudon();
|
||||
AddSC_boss_onyxia(); //Onyxia's Lair
|
||||
// Onyxia's Lair
|
||||
AddSC_boss_onyxia();
|
||||
AddSC_instance_onyxias_lair();
|
||||
AddSC_boss_tuten_kash(); //Razorfen Downs
|
||||
// Razorfen Downs
|
||||
AddSC_boss_tuten_kash();
|
||||
AddSC_boss_mordresh_fire_eye();
|
||||
AddSC_boss_glutton();
|
||||
AddSC_boss_amnennar_the_coldbringer();
|
||||
AddSC_razorfen_downs();
|
||||
AddSC_instance_razorfen_downs();
|
||||
AddSC_razorfen_kraul(); //Razorfen Kraul
|
||||
// Razorfen Kraul
|
||||
AddSC_razorfen_kraul();
|
||||
AddSC_instance_razorfen_kraul();
|
||||
AddSC_boss_kurinnaxx(); //Ruins of ahn'qiraj
|
||||
// Ruins of ahn'qiraj
|
||||
AddSC_boss_kurinnaxx();
|
||||
AddSC_boss_rajaxx();
|
||||
AddSC_boss_moam();
|
||||
AddSC_boss_buru();
|
||||
AddSC_boss_ayamiss();
|
||||
AddSC_boss_ossirian();
|
||||
AddSC_instance_ruins_of_ahnqiraj();
|
||||
AddSC_boss_cthun(); //Temple of ahn'qiraj
|
||||
// Temple of ahn'qiraj
|
||||
AddSC_boss_cthun();
|
||||
AddSC_boss_viscidus();
|
||||
AddSC_boss_fankriss();
|
||||
AddSC_boss_huhuran();
|
||||
@@ -186,9 +216,11 @@ void AddKalimdorScripts()
|
||||
AddSC_boss_ouro();
|
||||
AddSC_npc_anubisath_sentinel();
|
||||
AddSC_instance_temple_of_ahnqiraj();
|
||||
AddSC_wailing_caverns(); //Wailing caverns
|
||||
// Wailing caverns
|
||||
AddSC_wailing_caverns();
|
||||
AddSC_instance_wailing_caverns();
|
||||
AddSC_boss_zum_rah(); //Zul'Farrak
|
||||
// Zul'Farrak
|
||||
AddSC_boss_zum_rah();
|
||||
AddSC_zulfarrak();
|
||||
AddSC_instance_zulfarrak();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user