Implement Script CoS. Thanks Johnholiver.

Fixes issue #336.

Requires DB update.
Still WiP but functional.

--HG--
branch : trunk
This commit is contained in:
Trazom62
2010-03-27 18:39:22 +01:00
parent eba6ae5ffd
commit d02f303b8d
17 changed files with 1821 additions and 138 deletions

View File

@@ -221,6 +221,7 @@ SET(scripts_STAT_SRCS
kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp
kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp
kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp
kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp
kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h
kalimdor/caverns_of_time/dark_portal/dark_portal.h
kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp

View File

@@ -30,30 +30,24 @@ Script Data End */
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
H_SPELL_WOUNDING_STRIKE = 58830
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
H_SPELL_WOUNDING_STRIKE = 58830
};
//not in db
enum Yells
{
SAY_INTRO = -1595000, //"Prince Arthas Menethil, on this day, a powerful darkness has taken hold of your soul. The death you are destined to visit upon others will this day be your own."
SAY_AGGRO = -1595001, //"We'll see about that, young prince."
SAY_TIME_WARP_1 = -1595002, //"Tick tock, tick tock..."
SAY_TIME_WARP_2 = -1595003, //"Not quick enough!"
SAY_TIME_WARP_3 = -1595004, //"Let's get this over with. "
SAY_SLAY_1 = -1595005, //"There is no future for you."
SAY_SLAY_2 = -1595006, //"This is the hour of our greatest triumph!"
SAY_SLAY_3 = -1595007, //"You were destined to fail. "
SAY_DEATH = -1595008 //"*gurgles*"
};
enum CombatPhases
{
INTRO,
COMBAT
SAY_INTRO = -1595000, //"Prince Arthas Menethil, on this day, a powerful darkness has taken hold of your soul. The death you are destined to visit upon others will this day be your own."
SAY_AGGRO = -1595001, //"We'll see about that, young prince."
SAY_TIME_WARP_1 = -1595002, //"Tick tock, tick tock..."
SAY_TIME_WARP_2 = -1595003, //"Not quick enough!"
SAY_TIME_WARP_3 = -1595004, //"Let's get this over with. "
SAY_SLAY_1 = -1595005, //"There is no future for you."
SAY_SLAY_2 = -1595006, //"This is the hour of our greatest triumph!"
SAY_SLAY_3 = -1595007, //"You were destined to fail. "
SAY_DEATH = -1595008 //"*gurgles*"
};
struct boss_epochAI : public ScriptedAI
@@ -71,8 +65,6 @@ struct boss_epochAI : public ScriptedAI
uint32 uiTimeStopTimer;
uint32 uiCurseOfExertionTimer;
CombatPhases Phase;
ScriptedInstance* pInstance;
void Reset()
@@ -98,11 +90,6 @@ struct boss_epochAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
if (Phase == INTRO)
{
return;
}
//Return since we have no target
if (!UpdateVictim())
return;

View File

@@ -21,13 +21,21 @@
enum Spells
{
SPELL_CORRUPTING_BLIGHT = 60588,
SPELL_VOID_STRIKE = 60590
SPELL_CORRUPTING_BLIGHT = 60588,
SPELL_VOID_STRIKE = 60590
};
struct boss_infiniteAI : public ScriptedAI
enum Yells
{
boss_infiniteAI(Creature *c) : ScriptedAI(c)
SAY_AGGRO = -1595045,
SAY_FAIL = -1595046,
SAY_DEATH = -1595047
};
struct boss_infinite_corruptorAI : public ScriptedAI
{
boss_infinite_corruptorAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
@@ -64,17 +72,17 @@ struct boss_infiniteAI : public ScriptedAI
}
};
CreatureAI* GetAI_boss_infinite(Creature* pCreature)
CreatureAI* GetAI_boss_infinite_corruptor(Creature* pCreature)
{
return new boss_infiniteAI (pCreature);
return new boss_infinite_corruptorAI(pCreature);
}
void AddSC_infinite_epoch()
void AddSC_boss_infinite_corruptor()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_infinite";
newscript->GetAI = &GetAI_boss_infinite;
newscript->Name = "boss_infinite_corruptor";
newscript->GetAI = &GetAI_boss_infinite_corruptor;
newscript->RegisterSelf();
}

View File

@@ -32,35 +32,34 @@ update creature_template set scriptname = 'boss_mal_ganis' where entry = '';
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_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.
};
//not in db
enum Yells
{
SAY_INTRO_1 = -1595009,
SAY_INTRO_2 = -1595010,
SAY_OUTRO = -1595011,
SAY_AGGRO = -1595012,
SAY_KILL_1 = -1595013,
SAY_KILL_2 = -1595014,
SAY_KILL_3 = -1595015,
SAY_SLAY_1 = -1595016,
SAY_SLAY_2 = -1595017,
SAY_SLAY_3 = -1595018,
SAY_SLAY_4 = -1595019,
SAY_SLEEP_1 = -1595020,
SAY_SLEEP_2 = -1595021,
SAY_30HEALTH = -1595022,
SAY_15HEALTH = -1595023,
SAY_ESCAPE_SPEECH_1 = -1595024,
SAY_ESCAPE_SPEECH_2 = -1595025
SAY_INTRO_1 = -1595009,
SAY_INTRO_2 = -1595010,
SAY_AGGRO = -1595011,
SAY_KILL_1 = -1595012,
SAY_KILL_2 = -1595013,
SAY_KILL_3 = -1595014,
SAY_SLAY_1 = -1595015,
SAY_SLAY_2 = -1595016,
SAY_SLAY_3 = -1595017,
SAY_SLAY_4 = -1595018,
SAY_SLEEP_1 = -1595019,
SAY_SLEEP_2 = -1595020,
SAY_30HEALTH = -1595021,
SAY_15HEALTH = -1595022,
SAY_ESCAPE_SPEECH_1 = -1595023,
SAY_ESCAPE_SPEECH_2 = -1595024,
SAY_OUTRO = -1595025,
};
enum CombatPhases
@@ -82,6 +81,7 @@ struct boss_mal_ganisAI : public ScriptedAI
uint32 uiSleepTimer;
uint8 uiOutroStep;
uint32 uiOutroTimer;
bool bYelled;
bool bYelled2;
@@ -101,6 +101,7 @@ struct boss_mal_ganisAI : public ScriptedAI
uiMindBlastTimer = 11000;
uiVampiricTouchTimer = urand(10000,15000);
uiSleepTimer = urand(15000,20000);
uiOutroTimer = 1000;
if (pInstance)
pInstance->SetData(DATA_MAL_GANIS_EVENT, NOT_STARTED);
@@ -116,6 +117,12 @@ struct boss_mal_ganisAI : public ScriptedAI
pInstance->SetData(DATA_MAL_GANIS_EVENT, IN_PROGRESS);
}
void DamageTaken(Unit *done_by, uint32 &damage)
{
if (damage >= m_creature->GetHealth() && done_by != m_creature)
damage = m_creature->GetHealth()-1;
}
void UpdateAI(const uint32 diff)
{
switch(Phase)
@@ -164,16 +171,18 @@ struct boss_mal_ganisAI : public ScriptedAI
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_MIND_BLAST, H_SPELL_MIND_BLAST));
uiMindBlastTimer = 6000;
} else uiMindBlastTimer -= diff;
if (uiVampiricTouchTimer < diff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, SPELL_VAMPIRIC_TOUCH);
DoCast(m_creature, SPELL_VAMPIRIC_TOUCH);
uiVampiricTouchTimer = 32000;
} else uiVampiricTouchTimer -= diff;
if (uiSleepTimer < diff)
{
DoScriptText(RAND(SAY_SLEEP_1,SAY_SLEEP_2), m_creature);
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(pTarget, DUNGEON_MODE(SPELL_SLEEP, H_SPELL_SLEEP));
uiSleepTimer = urand(15000,20000);
@@ -181,13 +190,57 @@ struct boss_mal_ganisAI : public ScriptedAI
DoMeleeAttackIfReady();
break;
case OUTRO:
if (uiOutroTimer < diff)
{
switch(uiOutroStep)
{
case 1:
DoScriptText(SAY_ESCAPE_SPEECH_1, m_creature);
me->GetMotionMaster()->MoveTargetedHome();
++uiOutroStep;
uiOutroTimer = 8000;
break;
case 2:
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, pArthas->GetGUID());
m_creature->HandleEmoteCommand(29);
DoScriptText(SAY_ESCAPE_SPEECH_2, m_creature);
++uiOutroStep;
uiOutroTimer = 9000;
break;
case 3:
DoScriptText(SAY_OUTRO, m_creature);
++uiOutroStep;
uiOutroTimer = 16000;
break;
case 4:
m_creature->HandleEmoteCommand(33);
++uiOutroStep;
uiOutroTimer = 500;
break;
case 5:
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->Kill(m_creature);
break;
}
} else uiOutroTimer -= diff;
break;
}
}
void JustDied(Unit* killer)
{
if (pInstance)
pInstance->SetData(DATA_MAL_GANIS_EVENT, DONE);
{
pInstance->SetData(DATA_MAL_GANIS_EVENT, DONE);
// give achievement credit to players. criteria use spell 58630 which doesn't exist.
if (pInstance)
pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58630);
}
}
void KilledUnit(Unit *victim)
{
if (victim == m_creature)

View File

@@ -29,21 +29,21 @@ 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.
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.
};
//not in db
enum Yells
{
SAY_AGGRO = -1595026,
SAY_SLAY_1 = -1595027,
SAY_SLAY_2 = -1595028,
SAY_SLAY_3 = -1595029,
SAY_SPAWN = -1595030,
SAY_DEATH = -1595031
SAY_AGGRO = -1595026,
SAY_SLAY_1 = -1595027,
SAY_SLAY_2 = -1595028,
SAY_SLAY_3 = -1595029,
SAY_SPAWN = -1595030,
SAY_DEATH = -1595031
};
struct boss_meathookAI : public ScriptedAI

View File

@@ -41,22 +41,21 @@ enum Spells
SPELL_SUMMON_GHOULS = 52451
};
//not in db
enum Yells
{
SAY_AGGRO = -1595032,
SAY_SPAWN = -1595033,
SAY_SLAY_1 = -1595034,
SAY_SLAY_2 = -1595035,
SAY_SLAY_3 = -1595036,
SAY_DEATH = -1595037,
SAY_EXPLODE_GHOUL_1 = -1595038,
SAY_EXPLODE_GHOUL_2 = -1595039,
SAY_STEAL_FLESH_1 = -1595040,
SAY_STEAL_FLESH_2 = -1595041,
SAY_STEAL_FLESH_3 = -1595042,
SAY_SUMMON_GHOULS_1 = -1595043,
SAY_SUMMON_GHOULS_2 = -1595044
SAY_AGGRO = -1595032,
SAY_SPAWN = -1595033,
SAY_SLAY_1 = -1595034,
SAY_SLAY_2 = -1595035,
SAY_SLAY_3 = -1595036,
SAY_DEATH = -1595037,
SAY_EXPLODE_GHOUL_1 = -1595038,
SAY_EXPLODE_GHOUL_2 = -1595039,
SAY_STEAL_FLESH_1 = -1595040,
SAY_STEAL_FLESH_2 = -1595041,
SAY_STEAL_FLESH_3 = -1595042,
SAY_SUMMON_GHOULS_1 = -1595043,
SAY_SUMMON_GHOULS_2 = -1595044
};
struct boss_salrammAI : public ScriptedAI
@@ -64,23 +63,25 @@ struct boss_salrammAI : public ScriptedAI
boss_salrammAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
if (pInstance)
DoScriptText(SAY_SPAWN,m_creature);
}
uint32 Curse_flesh_Timer;
uint32 Explode_ghoul_Timer;
uint32 Shadow_bolt_Timer;
uint32 Steal_flesh_Timer;
uint32 Summon_ghouls_Timer;
uint32 uiCurseFleshTimer;
uint32 uiExplodeGhoulTimer;
uint32 uiShadowBoltTimer;
uint32 uiStealFleshTimer;
uint32 uiSummonGhoulsTimer;
ScriptedInstance* pInstance;
void Reset()
{
Curse_flesh_Timer = 30000; //30s DBM
Explode_ghoul_Timer = urand(25000,28000); //approx 6 sec after summon ghouls
Shadow_bolt_Timer = urand(8000,12000); // approx 10s
Steal_flesh_Timer = 12345;
Summon_ghouls_Timer = urand(19000,24000); //on a video approx 24s after aggro
uiCurseFleshTimer = 30000; //30s DBM
uiExplodeGhoulTimer = urand(25000,28000); //approx 6 sec after summon ghouls
uiShadowBoltTimer = urand(8000,12000); // approx 10s
uiStealFleshTimer = 12345;
uiSummonGhoulsTimer = urand(19000,24000); //on a video approx 24s after aggro
if (pInstance)
pInstance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED);
@@ -94,8 +95,6 @@ struct boss_salrammAI : public ScriptedAI
pInstance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS);
}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
@@ -103,37 +102,37 @@ struct boss_salrammAI : public ScriptedAI
return;
//Curse of twisted flesh timer
if (Curse_flesh_Timer <= diff)
if (uiCurseFleshTimer <= diff)
{
DoCast(m_creature->getVictim(), SPELL_CURSE_OF_TWISTED_FLESH);
Curse_flesh_Timer = 37000;
} else Curse_flesh_Timer -= diff;
uiCurseFleshTimer = 37000;
} else uiCurseFleshTimer -= diff;
//Shadow bolt timer
if (Shadow_bolt_Timer <= diff)
if (uiShadowBoltTimer <= diff)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, DUNGEON_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT));
Shadow_bolt_Timer = urand(8000,12000);
} else Shadow_bolt_Timer -= diff;
uiShadowBoltTimer = urand(8000,12000);
} else uiShadowBoltTimer -= diff;
//Steal Flesh timer
if (Steal_flesh_Timer <= diff)
if (uiStealFleshTimer <= diff)
{
DoScriptText(RAND(SAY_STEAL_FLESH_1,SAY_STEAL_FLESH_2,SAY_STEAL_FLESH_3), m_creature);
if (Unit* random_pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(random_pTarget, SPELL_STEAL_FLESH);
Steal_flesh_Timer = 10000;
} else Steal_flesh_Timer -= diff;
uiStealFleshTimer = 10000;
} else uiStealFleshTimer -= diff;
//Summon ghouls timer
if (Summon_ghouls_Timer <= diff)
if (uiSummonGhoulsTimer <= diff)
{
DoScriptText(RAND(SAY_SUMMON_GHOULS_1,SAY_SUMMON_GHOULS_2), m_creature);
if (Unit* random_pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(random_pTarget, SPELL_SUMMON_GHOULS);
Summon_ghouls_Timer = 10000;
} else Summon_ghouls_Timer -= diff;
uiSummonGhoulsTimer = 10000;
} else uiSummonGhoulsTimer -= diff;
DoMeleeAttackIfReady();
}

View File

@@ -25,7 +25,8 @@ enum Data
DATA_SALRAMM_EVENT,
DATA_EPOCH_EVENT,
DATA_MAL_GANIS_EVENT,
DATA_INFINITE_EVENT
DATA_INFINITE_EVENT,
DATA_ARTHAS_EVENT
};
enum Data64
@@ -38,17 +39,20 @@ enum Data64
DATA_SHKAF_GATE,
DATA_MAL_GANIS_GATE_1,
DATA_MAL_GANIS_GATE_2,
DATA_EXIT_GATE,
DATA_MAL_GANIS_CHEST
};
enum Creatures
{
NPC_MEATHOOK = 26529,
NPC_SALRAMM = 26530,
NPC_EPOCH = 26532,
NPC_MAL_GANIS = 26533,
NPC_INFINITE = 32273,
NPC_ARTHAS = 26499
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
};
enum GameObjects
@@ -56,6 +60,8 @@ enum GameObjects
GO_SHKAF_GATE = 188686,
GO_MALGANIS_GATE_1 = 187711,
GO_MALGANIS_GATE_2 = 187723,
GO_MALGANIS_CHEST = 190663
GO_EXIT_GATE = 191788,
GO_MALGANIS_CHEST_N = 190663,
GO_MALGANIS_CHEST_H = 193597
};
#endif

View File

@@ -42,9 +42,10 @@ struct instance_culling_of_stratholme : public ScriptedInstance
uint64 uiShkafGate;
uint64 uiMalGanisGate1;
uint64 uiMalGanisGate2;
uint64 uiExitGate;
uint64 uiMalGanisChest;
uint8 m_auiEncounter[MAX_ENCOUNTER];
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
bool IsEncounterInProgress() const
@@ -90,8 +91,16 @@ struct instance_culling_of_stratholme : public ScriptedInstance
case GO_MALGANIS_GATE_2:
uiMalGanisGate2 = pGo->GetGUID();
break;
case GO_MALGANIS_CHEST:
case GO_EXIT_GATE:
uiExitGate = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)
HandleGameObject(uiExitGate,true);
break;
case GO_MALGANIS_CHEST_N:
case GO_MALGANIS_CHEST_H:
uiMalGanisChest = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
break;
}
}
@@ -111,9 +120,21 @@ struct instance_culling_of_stratholme : public ScriptedInstance
break;
case DATA_MAL_GANIS_EVENT:
m_auiEncounter[3] = data;
GameObject *pGate;
if (data == IN_PROGRESS && (pGate = instance->GetGameObject(uiMalGanisGate2)))
pGate->SetGoState(GO_STATE_READY);
switch(m_auiEncounter[3])
{
case NOT_STARTED:
HandleGameObject(uiMalGanisGate2,true);
break;
case IN_PROGRESS:
HandleGameObject(uiMalGanisGate2,false);
break;
case DONE:
HandleGameObject(uiExitGate, true);
if (GameObject *pGo = instance->GetGameObject(uiMalGanisChest))
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
break;
}
break;
case DATA_INFINITE_EVENT:
m_auiEncounter[4] = data;
@@ -146,8 +167,10 @@ struct instance_culling_of_stratholme : public ScriptedInstance
case DATA_EPOCH: return uiEpoch;
case DATA_MAL_GANIS: return uiMalGanis;
case DATA_INFINITE: return uiInfinite;
case DATA_SHKAF_GATE: return uiShkafGate;
case DATA_MAL_GANIS_GATE_1: return uiMalGanisGate1;
case DATA_MAL_GANIS_GATE_2: return uiMalGanisGate2;
case DATA_EXIT_GATE: return uiExitGate;
case DATA_MAL_GANIS_CHEST: return uiMalGanisChest;
}
return 0;