Merge pull request #12927 from MitchesD/misc_3

Scripts/CoS: implemented Infinite Corruptor, improvements in instance sc...
This commit is contained in:
MitchesD
2014-09-12 15:25:07 +02:00
9 changed files with 421 additions and 347 deletions

View File

@@ -87,14 +87,14 @@ public:
{
Initialize();
instance->SetData(DATA_EPOCH_EVENT, NOT_STARTED);
instance->SetBossState(DATA_EPOCH, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_EPOCH_EVENT, IN_PROGRESS);
instance->SetBossState(DATA_EPOCH, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
@@ -136,7 +136,7 @@ public:
{
Talk(SAY_DEATH);
instance->SetData(DATA_EPOCH_EVENT, DONE);
instance->SetBossState(DATA_EPOCH, DONE);
}
void KilledUnit(Unit* victim) override

View File

@@ -22,7 +22,9 @@
enum Spells
{
SPELL_CORRUPTING_BLIGHT = 60588,
SPELL_VOID_STRIKE = 60590
SPELL_VOID_STRIKE = 60590,
SPELL_CORRUPTION_OF_TIME_CHANNEL = 60422,
SPELL_CORRUPTION_OF_TIME_TARGET = 60451
};
enum Yells
@@ -32,52 +34,78 @@ enum Yells
SAY_FAIL = 2
};
enum Events
{
EVENT_CORRUPTING_BLIGHT = 1,
EVENT_VOID_STRIKE
};
class boss_infinite_corruptor : public CreatureScript
{
public:
boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { }
public:
boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_infinite_corruptorAI>(creature);
}
struct boss_infinite_corruptorAI : public ScriptedAI
{
boss_infinite_corruptorAI(Creature* creature) : ScriptedAI(creature)
struct boss_infinite_corruptorAI : public BossAI
{
instance = creature->GetInstanceScript();
}
boss_infinite_corruptorAI(Creature* creature) : BossAI(creature, DATA_INFINITE) { }
InstanceScript* instance;
void Reset() override
{
_Reset();
void Reset() override
if (Creature* guardian = me->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
{
DoCast((Unit*)NULL, SPELL_CORRUPTION_OF_TIME_CHANNEL, false);
guardian->CastSpell(guardian, SPELL_CORRUPTION_OF_TIME_TARGET, false);
}
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
_EnterCombat();
events.ScheduleEvent(EVENT_CORRUPTING_BLIGHT, 7000);
events.ScheduleEvent(EVENT_VOID_STRIKE, 5000);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
if (Creature* guardian = me->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
{
guardian->RemoveAurasDueToSpell(SPELL_CORRUPTION_OF_TIME_TARGET);
guardian->DespawnOrUnsummon(5000);
}
if (Creature* rift = me->FindNearestCreature(NPC_TIME_RIFT, 100.0f))
rift->DespawnOrUnsummon();
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_CORRUPTING_BLIGHT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
DoCast(target, SPELL_CORRUPTING_BLIGHT);
events.ScheduleEvent(EVENT_CORRUPTING_BLIGHT, 17000);
break;
case EVENT_VOID_STRIKE:
DoCastVictim(SPELL_VOID_STRIKE);
events.ScheduleEvent(EVENT_VOID_STRIKE, 5000);
break;
default:
break;
}
}
};
CreatureAI* GetAI(Creature* creature) const override
{
instance->SetData(DATA_INFINITE_EVENT, NOT_STARTED);
return GetInstanceAI<boss_infinite_corruptorAI>(creature);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_INFINITE_EVENT, IN_PROGRESS);
}
void UpdateAI(uint32 /*diff*/) override
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
instance->SetData(DATA_INFINITE_EVENT, DONE);
}
};
};
void AddSC_boss_infinite_corruptor()

View File

@@ -26,15 +26,13 @@ Script Data End */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "culling_of_stratholme.h"
#include "Player.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.
H_SPELL_CARRION_SWARM = 58852,
SPELL_MIND_BLAST = 52722, //Inflicts 4163 to 4837 Shadow damage to an enemy.
H_SPELL_MIND_BLAST = 58850,
SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target.
H_SPELL_SLEEP = 58849,
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
@@ -75,7 +73,6 @@ public:
{
Initialize();
instance = creature->GetInstanceScript();
uiOutroStep = 0;
}
void Initialize()
@@ -108,14 +105,13 @@ public:
void Reset() override
{
Initialize();
instance->SetData(DATA_MAL_GANIS_EVENT, NOT_STARTED);
instance->SetBossState(DATA_MAL_GANIS, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_MAL_GANIS_EVENT, IN_PROGRESS);
instance->SetBossState(DATA_MAL_GANIS, IN_PROGRESS);
}
void DamageTaken(Unit* done_by, uint32 &damage) override
@@ -159,7 +155,7 @@ public:
{
EnterEvadeMode();
me->DisappearAndDie();
instance->SetData(DATA_MAL_GANIS_EVENT, FAIL);
instance->SetBossState(DATA_MAL_GANIS, FAIL);
}
if (uiCarrionSwarmTimer < diff)
@@ -197,7 +193,7 @@ public:
switch (uiOutroStep)
{
case 1:
Talk(SAY_ESCAPE_SPEECH_1);
Talk(SAY_OUTRO);
me->GetMotionMaster()->MoveTargetedHome();
++uiOutroStep;
uiOutroTimer = 8000;
@@ -212,7 +208,7 @@ public:
case 3:
Talk(SAY_OUTRO);
++uiOutroStep;
uiOutroTimer = 16000;
//uiOutroTimer = 16000;
break;
case 4:
me->HandleEmoteCommand(33);
@@ -232,7 +228,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
instance->SetData(DATA_MAL_GANIS_EVENT, DONE);
instance->SetBossState(DATA_MAL_GANIS, DONE);
DoCastAOE(SPELL_MAL_GANIS_KILL_CREDIT);
// 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);

View File

@@ -15,14 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Script Data Start
SDName: Boss meathook
SDAuthor: Tartalo
SD%Complete: 100
SDComment: It may need timer adjustment
SDCategory:
Script Data End */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "culling_of_stratholme.h"
@@ -30,9 +22,7 @@ Script Data End */
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.
H_SPELL_CONSTRICTING_CHAINS = 58823,
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.
H_SPELL_DISEASE_EXPULSION = 58824,
SPELL_FRENZY = 58841 //Increases the caster's Physical damage by 10% for 30 sec.
};
@@ -44,96 +34,72 @@ enum Yells
SAY_DEATH = 3
};
enum Events
{
EVENT_CHAIN = 1,
EVENT_DISEASE,
EVENT_FRENZY
};
class boss_meathook : public CreatureScript
{
public:
boss_meathook() : CreatureScript("boss_meathook") { }
public:
boss_meathook() : CreatureScript("boss_meathook") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_meathookAI>(creature);
}
struct boss_meathookAI : public ScriptedAI
{
boss_meathookAI(Creature* creature) : ScriptedAI(creature)
struct boss_meathookAI : public BossAI
{
Initialize();
instance = creature->GetInstanceScript();
Talk(SAY_SPAWN);
}
void Initialize()
{
uiChainTimer = urand(12000, 17000); //seen on video 13, 17, 15, 12, 16
uiDiseaseTimer = urand(2000, 4000); //approx 3s
uiFrenzyTimer = urand(21000, 26000); //made it up
}
uint32 uiChainTimer;
uint32 uiDiseaseTimer;
uint32 uiFrenzyTimer;
InstanceScript* instance;
void Reset() override
{
Initialize();
instance->SetData(DATA_MEATHOOK_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_MEATHOOK_EVENT, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiDiseaseTimer <= diff)
boss_meathookAI(Creature* creature) : BossAI(creature, DATA_MEATHOOK)
{
DoCastAOE(SPELL_DISEASE_EXPULSION);
uiDiseaseTimer = urand(1500, 4000);
} else uiDiseaseTimer -= diff;
Talk(SAY_SPAWN);
}
if (uiFrenzyTimer <= diff)
void EnterCombat(Unit* /*who*/) override
{
DoCast(me, SPELL_FRENZY);
uiFrenzyTimer = urand(21000, 26000);
} else uiFrenzyTimer -= diff;
Talk(SAY_AGGRO);
_EnterCombat();
events.ScheduleEvent(EVENT_CHAIN, urand(12000, 17000));
events.ScheduleEvent(EVENT_DISEASE, urand(2000, 4000));
events.ScheduleEvent(EVENT_FRENZY, urand(21000, 26000));
}
if (uiChainTimer <= diff)
void ExecuteEvent(uint32 eventId) override
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_CONSTRICTING_CHAINS); //anyone but the tank
uiChainTimer = urand(2000, 4000);
} else uiChainTimer -= diff;
switch (eventId)
{
case EVENT_CHAIN:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
DoCast(target, SPELL_CONSTRICTING_CHAINS);
events.ScheduleEvent(EVENT_CHAIN, urand(2000, 4000));
case EVENT_DISEASE:
DoCastAOE(SPELL_DISEASE_EXPULSION);
events.ScheduleEvent(EVENT_DISEASE, urand(1500, 4000));
break;
case EVENT_FRENZY:
DoCast(me, SPELL_FRENZY);
events.ScheduleEvent(EVENT_FRENZY, urand(21000, 26000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
}
void JustDied(Unit* /*killer*/) override
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
};
CreatureAI* GetAI(Creature* creature) const override
{
Talk(SAY_DEATH);
instance->SetData(DATA_MEATHOOK_EVENT, DONE);
return GetInstanceAI<boss_meathookAI>(creature);
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
Talk(SAY_SLAY);
}
};
};
void AddSC_boss_meathook()

View File

@@ -89,14 +89,14 @@ public:
{
Initialize();
instance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED);
instance->SetBossState(DATA_SALRAMM, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS);
instance->SetBossState(DATA_SALRAMM, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
@@ -145,7 +145,7 @@ public:
{
Talk(SAY_DEATH);
instance->SetData(DATA_SALRAMM_EVENT, DONE);
instance->SetBossState(DATA_SALRAMM, DONE);
}
void KilledUnit(Unit* victim) override

View File

@@ -103,7 +103,7 @@ enum Says
//Drakonian
SAY_PHASE302 = 0,
SAY_PHASE305 = 1,
SAY_PHASE305 = 1
};
enum NPCs
@@ -111,7 +111,6 @@ enum NPCs
NPC_INFINITE_ADVERSARY = 27742,
NPC_INFINITE_HUNTER = 27743,
NPC_INFINITE_AGENT = 27744,
NPC_TIME_RIFT = 28409,
NPC_ZOMBIE = 27737,
NPC_GHOUL = 28249,
NPC_NECROMANCER = 28200,
@@ -128,7 +127,7 @@ enum NPCs
NPC_CITY_MAN = 28167,
NPC_CITY_MAN2 = 28169,
NPC_CITY_MAN3 = 31126,
NPC_CITY_MAN4 = 31127,
NPC_CITY_MAN4 = 31127
};
enum Spells
@@ -138,7 +137,7 @@ enum Spells
SPELL_EXORCISM_N = 52445,
SPELL_EXORCISM_H = 58822,
SPELL_HOLY_LIGHT = 52444,
SPELL_ARCANE_DISRUPTION = 49590,
SPELL_ARCANE_DISRUPTION = 49590
};
enum GossipMenuArthas
@@ -392,6 +391,7 @@ public:
uint32 gossipStep;
uint32 bossEvent;
uint32 wave;
uint32 WavesCounter;
uint64 utherGUID;
uint64 jainaGUID;
@@ -411,17 +411,19 @@ public:
{
Initialize();
instance->SetData(DATA_ARTHAS_EVENT, NOT_STARTED);
switch (instance->GetData(DATA_ARTHAS_EVENT))
{
case NOT_STARTED:
bStepping = true;
step = 0;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
bossEvent = DATA_MEATHOOK_EVENT;
gossipStep = 0;
break;
}
instance->SetBossState(DATA_ARTHAS, NOT_STARTED);
bStepping = true;
step = 0;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
bossEvent = DATA_MEATHOOK;
gossipStep = 0;
}
void AttackStart(Unit* who)
{
if (who && !who->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
npc_escortAI::AttackStart(who);
}
void EnterCombat(Unit* /*who*/) override
@@ -431,7 +433,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
instance->SetData(DATA_ARTHAS_EVENT, FAIL);
instance->SetBossState(DATA_ARTHAS, FAIL);
}
void SpawnTimeRift(uint32 timeRiftID, uint64* guidVector)
@@ -488,16 +490,15 @@ public:
case 11:
case 22:
case 23:
case 26:
case 55:
case 56:
SetHoldState(true);
bStepping = true;
break;
case 7:
if (Unit* cityman0 = me->SummonCreature(NPC_CITY_MAN, 2091.977f, 1275.021f, 140.757f, 0.558f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
if (Unit* cityman0 = me->FindNearestCreature(NPC_CITY_MAN, 160.0f))
citymenGUID[0] = cityman0->GetGUID();
if (Unit* cityman1 = me->SummonCreature(NPC_CITY_MAN2, 2093.514f, 1275.842f, 140.408f, 3.801f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
if (Unit* cityman1 = me->FindNearestCreature(NPC_CITY_MAN2, 160.0f))
citymenGUID[1] = cityman1->GetGUID();
break;
case 8:
@@ -534,10 +535,12 @@ public:
case 21:
Talk(SAY_PHASE301);
break;
case 25:
case 26:
SetRun(false);
SpawnTimeRift(0, &infiniteDraconianGUID[0]);
Talk(SAY_PHASE307);
SetHoldState(true);
bStepping = true;
break;
case 29:
SetRun(false);
@@ -565,8 +568,8 @@ public:
Talk(SAY_PHASE403);
break;
case 36:
if (GameObject* pGate = instance->instance->GetGameObject(instance->GetData64(DATA_SHKAF_GATE)))
pGate->SetGoState(GO_STATE_ACTIVE);
if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_SHKAF_GATE)))
gate->SetGoState(GO_STATE_ACTIVE);
break;
case 45:
SetRun(true);
@@ -575,18 +578,18 @@ public:
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
SetHoldState(true);
break;
case 47:
case 48:
SetRun(false);
Talk(SAY_PHASE405);
break;
case 48:
case 49:
SetRun(true);
Talk(SAY_PHASE406);
break;
case 53:
case 50:
Talk(SAY_PHASE407);
break;
case 54:
case 51:
gossipStep = 5;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
SetHoldState(true);
@@ -598,8 +601,6 @@ public:
{
npc_escortAI::UpdateAI(diff);
DoMeleeAttackIfReady();
if (bStepping)
{
if (phaseTimer <= diff)
@@ -765,6 +766,9 @@ public:
stalkerGUID = pStalker->GetGUID();
me->SetTarget(stalkerGUID);
}
instance->DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, 0);
JumpToNextStep(1000);
break;
case 25:
@@ -892,14 +896,15 @@ public:
}
Talk(SAY_PHASE209);
bossEvent = DATA_MEATHOOK_EVENT;
instance->SetData(DATA_ARTHAS_EVENT, IN_PROGRESS);
bossEvent = DATA_MEATHOOK;
instance->SetBossState(DATA_ARTHAS, IN_PROGRESS);
me->SetReactState(REACT_DEFENSIVE);
SetDespawnAtFar(false);
JumpToNextStep(5000);
break;
case 41: //Summon wave group
// Summon wave groups - start the Infinite Corruptor timer
case 41:
case 43:
case 45:
case 47:
@@ -907,10 +912,15 @@ public:
case 53:
case 55:
case 57:
if (instance->GetData(bossEvent) != DONE)
if (!wave && IsHeroic() && instance->GetData(DATA_INFINITE_COUNTER) == NOT_STARTED)
instance->SetData(DATA_INFINITE_COUNTER, IN_PROGRESS);
if (instance->GetBossState(bossEvent) != DONE)
{
SpawnWaveGroup(wave, waveGUID);
wave++;
WavesCounter++;
instance->DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, WavesCounter);
}
JumpToNextStep(500);
break;
@@ -922,7 +932,7 @@ public:
case 54:
case 56:
case 58:
if (instance->GetData(bossEvent) != DONE)
if (instance->GetBossState(bossEvent) != DONE)
{
uint32 mobCounter = 0;
uint32 deadCounter = 0;
@@ -946,12 +956,14 @@ public:
break;
case 49: //Summon Boss
case 59:
if (instance->GetData(bossEvent) != DONE)
if (instance->GetBossState(bossEvent) != DONE)
{
WavesCounter++;
instance->DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, WavesCounter);
uint32 uiBossID = 0;
if (bossEvent == DATA_MEATHOOK_EVENT)
if (bossEvent == DATA_MEATHOOK)
uiBossID = NPC_MEATHOOK;
else if (bossEvent == DATA_SALRAMM_EVENT)
else if (bossEvent == DATA_SALRAMM)
uiBossID = NPC_SALRAMM;
if (Unit* pBoss = me->SummonCreature(uiBossID, 2232.19f, 1331.933f, 126.662f, 3.15f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
@@ -965,19 +977,19 @@ public:
break;
case 50: //Wait Boss death
case 60:
if (instance->GetData(bossEvent) == DONE)
if (instance->GetBossState(bossEvent) == DONE)
{
JumpToNextStep(1000);
if (bossEvent == DATA_MEATHOOK_EVENT)
bossEvent = DATA_SALRAMM_EVENT;
else if (bossEvent == DATA_SALRAMM_EVENT)
if (bossEvent == DATA_MEATHOOK)
bossEvent = DATA_SALRAMM;
else if (bossEvent == DATA_SALRAMM)
{
SetHoldState(false);
bStepping = false;
bossEvent = DATA_EPOCH_EVENT;
bossEvent = DATA_EPOCH;
}
}
else if (instance->GetData(bossEvent) == FAIL)
else if (instance->GetBossState(bossEvent) == FAIL)
npc_escortAI::EnterEvadeMode();
else
phaseTimer = 10000;
@@ -1074,9 +1086,12 @@ public:
phaseTimer = 1000;
else
{
if (step == 72) Talk(SAY_PHASE308);
if (step == 74) Talk(SAY_PHASE308);
if (step == 76) Talk(SAY_PHASE310);
if (step == 72)
Talk(SAY_PHASE308);
if (step == 74)
Talk(SAY_PHASE308);
if (step == 76)
Talk(SAY_PHASE310);
SetHoldState(false);
bStepping = false;
SetRun(true);
@@ -1097,7 +1112,7 @@ public:
JumpToNextStep(1000);
break;
case 80:
if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
if (instance->GetBossState(DATA_EPOCH) != DONE)
{
SpawnTimeRift(17, &epochGUID);
if (Creature* epoch = ObjectAccessor::GetCreature(*me, epochGUID))
@@ -1107,12 +1122,12 @@ public:
JumpToNextStep(18000);
break;
case 81:
if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
if (instance->GetBossState(DATA_EPOCH) != DONE)
Talk(SAY_PHASE315);
JumpToNextStep(6000);
break;
case 82:
if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
if (instance->GetBossState(DATA_EPOCH) != DONE)
{
if (Creature* epoch = ObjectAccessor::GetCreature(*me, epochGUID))
{
@@ -1126,15 +1141,15 @@ public:
JumpToNextStep(1000);
break;
case 83:
if (instance->GetData(DATA_EPOCH_EVENT) == DONE)
if (instance->GetBossState(DATA_EPOCH) == DONE)
{
gossipStep = 3;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
bStepping = false;
bossEvent = DATA_MAL_GANIS_EVENT;
bossEvent = DATA_MAL_GANIS;
JumpToNextStep(15000);
}
else if (instance->GetData(DATA_EPOCH_EVENT) == FAIL)
else if (instance->GetBossState(DATA_EPOCH) == FAIL)
npc_escortAI::EnterEvadeMode();
else
phaseTimer = 10000;
@@ -1153,8 +1168,8 @@ public:
malganisGUID = malganis->GetGUID();
malganis->SetReactState(REACT_PASSIVE);
}
if (GameObject* pGate = instance->instance->GetGameObject(instance->GetData64(DATA_MAL_GANIS_GATE_1)))
pGate->SetGoState(GO_STATE_ACTIVE);
if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_MAL_GANIS_GATE_1)))
gate->SetGoState(GO_STATE_ACTIVE);
SetHoldState(false);
bStepping = false;
JumpToNextStep(0);
@@ -1174,12 +1189,12 @@ public:
JumpToNextStep(1000);
break;
case 88:
if (instance->GetData(DATA_MAL_GANIS_EVENT) == DONE)
if (instance->GetBossState(DATA_MAL_GANIS) == DONE)
{
SetHoldState(false);
JumpToNextStep(1000);
}
else if (instance->GetData(DATA_MAL_GANIS_EVENT) == FAIL)
else if (instance->GetBossState(DATA_MAL_GANIS) == FAIL)
npc_escortAI::EnterEvadeMode();
else
phaseTimer = 10000;
@@ -1192,7 +1207,7 @@ public:
JumpToNextStep(7000);
break;
case 90:
instance->SetData(DATA_ARTHAS_EVENT, DONE); //Rewards: Achiev & Chest ;D
instance->SetBossState(DATA_ARTHAS, DONE); //Rewards: Achiev & Chest ;D
me->SetTarget(instance->GetData64(DATA_MAL_GANIS_GATE_2)); //Look behind
Talk(SAY_PHASE504);
bStepping = false;
@@ -1214,6 +1229,8 @@ public:
if (HealthBelowPct(40))
DoCast(me, SPELL_HOLY_LIGHT);
DoMeleeAttackIfReady();
}
};

View File

@@ -19,19 +19,10 @@
#define DEF_CULLING_OF_STRATHOLME_H
#define DataHeader "CS"
#define CoSScriptName "instance_culling_of_stratholme"
uint32 const EncounterCount = 5;
enum Data
{
DATA_MEATHOOK_EVENT,
DATA_SALRAMM_EVENT,
DATA_EPOCH_EVENT,
DATA_MAL_GANIS_EVENT,
DATA_INFINITE_EVENT,
DATA_ARTHAS_EVENT,
DATA_CRATE_COUNT,
};
enum Data64
enum DataTypes
{
DATA_ARTHAS,
DATA_MEATHOOK,
@@ -39,28 +30,35 @@ enum Data64
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_MAL_GANIS_CHEST,
DATA_INFINITE_COUNTER
};
enum Creatures
enum CreatureIds
{
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_2 = 27915,
NPC_GENERIC_BUNNY = 28960,
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
};
enum GameObjects
enum GameObjectIds
{
GO_SHKAF_GATE = 188686,
GO_MALGANIS_GATE_1 = 187711,
@@ -69,7 +67,7 @@ enum GameObjects
GO_MALGANIS_CHEST_N = 190663,
GO_MALGANIS_CHEST_H = 193597,
GO_SUSPICIOUS_CRATE = 190094,
GO_PLAGUED_CRATE = 190095,
GO_PLAGUED_CRATE = 190095
};
enum WorldStatesCoT
@@ -78,12 +76,28 @@ enum WorldStatesCoT
WORLDSTATE_CRATES_REVEALED = 3480,
WORLDSTATE_WAVE_COUNT = 3504,
WORLDSTATE_TIME_GUARDIAN = 3931,
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932,
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932
};
enum CrateSpells
{
SPELL_CRATES_CREDIT = 58109,
SPELL_CRATES_CREDIT = 58109
};
enum Texts
{
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 InstanceEvents
{
EVENT_INFINITE_TIMER = 1
};
#endif

View File

@@ -23,8 +23,6 @@
#include "TemporarySummon.h"
#include "SpellInfo.h"
#define MAX_ENCOUNTER 5
/* Culling of Stratholme encounters:
0 - Meathook
1 - Salramm the Fleshcrafter
@@ -33,51 +31,51 @@
4 - Infinite Corruptor (Heroic only)
*/
enum Texts
Position const ChromieSummonPos[] =
{
SAY_CRATES_COMPLETED = 0,
{ 1813.298f, 1283.578f, 142.3258f, 3.878161f },
{ 2273.725f, 1483.684f, 128.7205f, 6.057528f }
};
Position const ChromieSummonPos = {1813.298f, 1283.578f, 142.3258f, 3.878161f};
Position const InfiniteCorruptorPos = { 2335.47f, 1262.04f, 132.921f, 1.42079f };
Position const TimeRiftPos = { 2334.626f, 1280.45f, 133.0066f, 1.727876f };
Position const GuardianOfTimePos = { 2321.489f, 1268.383f, 132.8507f, 0.418879f };
DoorData const doorData[] =
{
{ GO_MALGANIS_GATE_2, DATA_MAL_GANIS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
{ GO_EXIT_GATE, DATA_MAL_GANIS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
};
class instance_culling_of_stratholme : public InstanceMapScript
{
public:
instance_culling_of_stratholme() : InstanceMapScript("instance_culling_of_stratholme", 595) { }
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_culling_of_stratholme_InstanceMapScript(map);
}
instance_culling_of_stratholme() : InstanceMapScript(CoSScriptName, 595) { }
struct instance_culling_of_stratholme_InstanceMapScript : public InstanceScript
{
instance_culling_of_stratholme_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
_arthasGUID = 0;
_meathookGUID = 0;
_salrammGUID = 0;
_epochGUID = 0;
_malGanisGUID = 0;
_infiniteGUID = 0;
_shkafGateGUID = 0;
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
_chromieGUID = 0;
_arthasGUID = 0;
_meathookGUID = 0;
_salrammGUID = 0;
_epochGUID = 0;
_malGanisGUID = 0;
_infiniteGUID = 0;
_shkafGateGUID = 0;
_malGanisGate1GUID = 0;
_malGanisGate2GUID = 0;
_exitGateGUID = 0;
_exitGateGUID = 0;
_malGanisChestGUID = 0;
_genericBunnyGUID = 0;
memset(&_encounterState[0], 0, sizeof(uint32) * MAX_ENCOUNTER);
_crateCount = 0;
}
bool IsEncounterInProgress() const override
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (_encounterState[i] == IN_PROGRESS)
return true;
return false;
_genericBunnyGUID = 0;
_crateCount = 0;
_eventTimer = 0;
}
void FillInitialWorldStates(WorldPacket& data) override
@@ -93,6 +91,9 @@ class instance_culling_of_stratholme : public InstanceMapScript
{
switch (creature->GetEntry())
{
case NPC_CHROMIE:
_chromieGUID = creature->GetGUID();
break;
case NPC_ARTHAS:
_arthasGUID = creature->GetGUID();
break;
@@ -110,10 +111,13 @@ class instance_culling_of_stratholme : public InstanceMapScript
break;
case NPC_INFINITE:
_infiniteGUID = creature->GetGUID();
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 1);
break;
case NPC_GENERIC_BUNNY:
_genericBunnyGUID = creature->GetGUID();
break;
default:
break;
}
}
@@ -129,17 +133,30 @@ class instance_culling_of_stratholme : public InstanceMapScript
break;
case GO_MALGANIS_GATE_2:
_malGanisGate2GUID = go->GetGUID();
AddDoor(go, true);
break;
case GO_EXIT_GATE:
_exitGateGUID = go->GetGUID();
if (_encounterState[3] == DONE)
HandleGameObject(_exitGateGUID, true);
AddDoor(go, true);
break;
case GO_MALGANIS_CHEST_N:
case GO_MALGANIS_CHEST_H:
_malGanisChestGUID = go->GetGUID();
if (_encounterState[3] == DONE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
break;
default:
break;
}
}
void OnGameObjectRemove(GameObject* go) override
{
switch (go->GetEntry())
{
case GO_MALGANIS_GATE_2:
case GO_EXIT_GATE:
AddDoor(go, false);
break;
default:
break;
}
}
@@ -148,36 +165,6 @@ class instance_culling_of_stratholme : public InstanceMapScript
{
switch (type)
{
case DATA_MEATHOOK_EVENT:
_encounterState[0] = data;
break;
case DATA_SALRAMM_EVENT:
_encounterState[1] = data;
break;
case DATA_EPOCH_EVENT:
_encounterState[2] = data;
break;
case DATA_MAL_GANIS_EVENT:
_encounterState[3] = data;
switch (_encounterState[3])
{
case NOT_STARTED:
HandleGameObject(_malGanisGate2GUID, true);
break;
case IN_PROGRESS:
HandleGameObject(_malGanisGate2GUID, false);
break;
case DONE:
HandleGameObject(_exitGateGUID, true);
if (GameObject* go = instance->GetGameObject(_malGanisChestGUID))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
break;
}
break;
case DATA_INFINITE_EVENT:
_encounterState[4] = data;
break;
case DATA_CRATE_COUNT:
_crateCount = data;
if (_crateCount == 5)
@@ -186,34 +173,70 @@ class instance_culling_of_stratholme : public InstanceMapScript
bunny->CastSpell(bunny, SPELL_CRATES_CREDIT, true);
// Summon Chromie and global whisper
if (Creature* chromie = instance->SummonCreature(NPC_CHROMIE_2, ChromieSummonPos))
if (Creature* chromie = instance->SummonCreature(NPC_CHROMIE_2, ChromieSummonPos[0]))
if (!instance->GetPlayers().isEmpty())
chromie->AI()->TalkToMap(SAY_CRATES_COMPLETED);
}
DoUpdateWorldState(WORLDSTATE_CRATES_REVEALED, _crateCount);
break;
case DATA_INFINITE_COUNTER:
_infiniteCouterState = data;
if (data == IN_PROGRESS)
{
if (!_infiniteGUID)
{
_eventTimer = 25;
instance->SummonCreature(NPC_INFINITE, InfiniteCorruptorPos);
instance->SummonCreature(NPC_TIME_RIFT, TimeRiftPos);
instance->SummonCreature(NPC_GUARDIAN_OF_TIME, GuardianOfTimePos);
events.ScheduleEvent(EVENT_INFINITE_TIMER, 1);
}
}
break;
default:
break;
}
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
switch (type)
{
case DATA_INFINITE:
if (state == DONE)
{
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 0);
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, 0);
}
break;
case DATA_MAL_GANIS:
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(_malGanisChestGUID))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
instance->SummonCreature(NPC_CHROMIE_3, ChromieSummonPos[1]);
}
break;
default:
break;
}
if (data == DONE)
SaveToDB();
return true;
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
case DATA_MEATHOOK_EVENT:
return _encounterState[0];
case DATA_SALRAMM_EVENT:
return _encounterState[1];
case DATA_EPOCH_EVENT:
return _encounterState[2];
case DATA_MAL_GANIS_EVENT:
return _encounterState[3];
case DATA_INFINITE_EVENT:
return _encounterState[4];
case DATA_CRATE_COUNT:
return _crateCount;
case DATA_INFINITE_COUNTER:
return _infiniteCouterState;
default:
break;
}
return 0;
}
@@ -244,58 +267,70 @@ class instance_culling_of_stratholme : public InstanceMapScript
return _exitGateGUID;
case DATA_MAL_GANIS_CHEST:
return _malGanisChestGUID;
default:
break;
}
return 0;
}
std::string GetSaveData() override
void Update(uint32 diff) override
{
OUT_SAVE_INST_DATA;
events.Update(diff);
std::ostringstream saveStream;
saveStream << "C S " << _encounterState[0] << ' ' << _encounterState[1] << ' '
<< _encounterState[2] << ' ' << _encounterState[3] << ' ' << _encounterState[4];
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
void Load(const char* in) override
{
if (!in)
while (uint32 eventId = events.ExecuteEvent())
{
OUT_LOAD_INST_DATA_FAIL;
return;
switch (eventId)
{
case EVENT_INFINITE_TIMER:
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, _eventTimer);
switch (_eventTimer)
{
case 25:
if (instance->HavePlayers())
if (Creature* chromie = instance->GetCreature(_chromieGUID))
chromie->AI()->TalkToMap(SAY_INFINITE_START);
break;
case 5:
if (instance->HavePlayers())
if (Creature* chromie = instance->GetCreature(_chromieGUID))
chromie->AI()->TalkToMap(SAY_INFINITE);
break;
case 0:
if (instance->HavePlayers())
if (Creature* chromie = instance->GetCreature(_chromieGUID))
chromie->AI()->TalkToMap(SAY_INFINITE_FAIL);
if (Creature* infinite = instance->GetCreature(_infiniteGUID))
{
if (Creature* guardian = infinite->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
infinite->Kill(guardian);
if (Creature* rift = infinite->FindNearestCreature(NPC_TIME_RIFT, 100.0f))
{
infinite->GetMotionMaster()->MovePoint(0, rift->GetPositionX(), rift->GetPositionY(), rift->GetPositionZ());
rift->DespawnOrUnsummon(3000);
}
infinite->DespawnOrUnsummon(3000);
infinite->AI()->Talk(SAY_FAIL_EVENT);
}
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 0);
return;
default:
break;
}
events.ScheduleEvent(EVENT_INFINITE_TIMER, 60000);
--_eventTimer;
break;
default:
break;
}
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3, data4;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4;
if (dataHead1 == 'C' && dataHead2 == 'S')
{
_encounterState[0] = data0;
_encounterState[1] = data1;
_encounterState[2] = data2;
_encounterState[3] = data3;
_encounterState[4] = data4;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (_encounterState[i] == IN_PROGRESS)
_encounterState[i] = NOT_STARTED;
}
else
OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
private:
uint64 _chromieGUID;
uint64 _arthasGUID;
uint64 _meathookGUID;
uint64 _salrammGUID;
@@ -308,9 +343,18 @@ class instance_culling_of_stratholme : public InstanceMapScript
uint64 _exitGateGUID;
uint64 _malGanisChestGUID;
uint64 _genericBunnyGUID;
uint32 _encounterState[MAX_ENCOUNTER];
uint32 _crateCount;
uint32 _eventTimer;
uint32 _infiniteCouterState;
EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_culling_of_stratholme_InstanceMapScript(map);
}
};
void AddSC_instance_culling_of_stratholme()