Trial of the Champion: Rewrite of Boss Black Knight script and Raisen Ghoul script.

--HG--
branch : trunk
This commit is contained in:
maanuel
2009-12-26 03:25:06 -03:00
parent 458588f726
commit a83ec4536c
3 changed files with 265 additions and 259 deletions

View File

@@ -1200,6 +1200,10 @@ UPDATE `gameobject_template` SET `ScriptName`='go_panther_cage' WHERE `entry`=17
/* THUNDER BLUFF */
UPDATE `creature_template` SET `ScriptName`='npc_cairne_bloodhoof' WHERE `entry`=3057;
/* TRIAL OF THE CHAMPION */
UPDATE `creature_template` SET `ScriptName`='npc_risen_ghoul' WHERE `entry` IN (35545,35564);
UPDATE `creature_template` SET `ScriptName`='boss_black_knight' WHERE `entry`=35451;
/* TIRISFAL GLADES */
UPDATE `creature_template` SET `ScriptName`='npc_calvin_montague' WHERE `entry`=6784;

View File

@@ -0,0 +1,2 @@
UPDATE `creature_template` SET `ScriptName`='npc_risen_ghoul' WHERE `entry` IN (35545, 35564);

View File

@@ -15,318 +15,318 @@
*/
/* ScriptData
SDName: boss_black_knight
SD%Complete: 92%
SDName: Boss Black Knight
SD%Complete: 80%
SDComment: missing yells. not sure about timers.
SDCategory: Trial Of the Champion
SDCategory: Trial of the Champion
EndScriptData */
#include "precompiled.h"
#include "trial_of_the_champion.h"
enum
enum eSpells
{
//yells
//phase 1
SPELL_PLAGUE_STRIKE = 67884,
SPELL_PLAGUE_STRIKE_2 = 67724,
SPELL_ICY_TOUCH_H = 67881,
SPELL_ICY_TOUCH = 67718,
SPELL_DEATH_RESPITE = 67745,
SPELL_DEATH_RESPITE_2 = 68306,
SPELL_DEATH_RESPITE_3 = 66798,
SPELL_OBLITERATE_H = 67883,
SPELL_OBLITERATE = 67725,
//in this phase should rise herald (the spell is missing)
//undead
SPELL_PLAGUE_STRIKE = 67724,
SPELL_PLAGUE_STRIKE_H = 67884,
SPELL_ICY_TOUCH = 67718,
SPELL_ICY_TOUCH_H = 67881,
SPELL_OBLITERATE = 67725,
SPELL_OBLITERATE_H = 67883,
SPELL_CHOKE = 68306,
//skeleton
SPELL_ARMY = 42650, //replacing original one, since that one spawns millions of ghouls!!
//ghost
SPELL_DEATH = 67808,
SPELL_DEATH_H = 67875,
SPELL_MARK = 67823,
//phase 2 - During this phase, the Black Knight will use the same abilities as in phase 1, except for Death's Respite
SPELL_ARMY_DEAD = 67761,
SPELL_DESECRATION = 67778,
SPELL_DESECRATION_2 = 67778,
SPELL_GHOUL_EXPLODE = 67751,
//risen ghoul
SPELL_CLAW = 67879,
SPELL_EXPLODE = 67729,
SPELL_EXPLODE_H = 67886,
SPELL_LEAP = 67749,
SPELL_LEAP_H = 67880,
//phase 3
SPELL_DEATH_BITE_H = 67875,
SPELL_DEATH_BITE = 67808,
SPELL_MARKED_DEATH = 67882,
SPELL_MARKED_DEATH_2 = 67823,
//sword ID
EQUIP_SWORD = 40343
SPELL_BLACK_KNIGHT_RES = 67693,
SPELL_LEAP = 67749,
SPELL_LEAP_H = 67880
};
// Risen Ghoul
struct TRINITY_DLL_DECL mob_toc5_risen_ghoulAI : public ScriptedAI
enum eModels
{
mob_toc5_risen_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
uint32 Attack;
void Reset()
{
Attack = 2500;
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (Attack < diff)
{
if (Creature* pTemp = ((Creature*)Unit::GetUnit((*m_creature), m_pInstance->GetData64(DATA_BLACK_KNIGHT))))
if (pTemp->isAlive())
if ((pTemp->GetHealth()*100 / pTemp->GetMaxHealth()) < 25)
DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLODE : SPELL_EXPLODE_H);
if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 4))
{
DoCast(m_creature->getVictim(), SPELL_CLAW);
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
m_creature->AI()->AttackStart(target);
Attack = 2500;
}
else
if (m_creature->IsWithinDistInMap(m_creature->getVictim(), 30))
{
DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_LEAP : SPELL_LEAP_H);
Attack = 2500;
}
}
else
Attack -= diff;
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)
DoCast(m_creature, m_bIsRegularMode ? SPELL_EXPLODE : SPELL_EXPLODE_H);
DoMeleeAttackIfReady();
}
MODEL_SKELETON = 29846,
MODEL_GHOST = 21300
};
CreatureAI* GetAI_mob_toc5_risen_ghoul(Creature* pCreature)
enum ePhases
{
return new mob_toc5_risen_ghoulAI(pCreature);
}
PHASE_UNDEAD = 1,
PHASE_SKELETON = 2,
PHASE_GHOST = 3
};
// The Black Knight
struct TRINITY_DLL_DECL boss_black_knightAI : public ScriptedAI
{
boss_black_knightAI(Creature* pCreature) : ScriptedAI(pCreature)
{
Reset();
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance* m_pInstance;
bool m_bIsRegularMode;
ScriptedInstance* pInstance;
uint32 Plague_Strike_Timer;
uint32 Icy_Touch_Timer;
uint32 Obliterate_Timer;
uint32 Choke_Timer;
uint32 Death_Timer;
uint32 Mark_Timer;
uint32 Phase_Delay;
uint32 Summon_Ghoul;
std::list<uint64> SummonList;
bool phase1;
bool phase2;
bool phase3;
bool ghoul;
bool bEventInProgress;
bool bEvent;
bool bSummonArmy;
bool bDeathArmyDone;
uint8 uiPhase;
uint32 uiPlagueStrikeTimer;
uint32 uiIcyTouchTimer;
uint32 uiDeathRespiteTimer;
uint32 uiObliterateTimer;
uint32 uiDesecration;
uint32 uiResurrectTimer;
uint32 uiDeathArmyCheckTimer;
uint32 uiGhoulExplodeTimer;
uint32 uiDeathBiteTimer;
uint32 uiMarkedDeathTimer;
void Reset()
{
m_creature->SetRespawnDelay(999999999);
m_creature->SetDisplayId(29837);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
Plague_Strike_Timer = 5000;
Icy_Touch_Timer = 10000;
Obliterate_Timer = 16000;
Choke_Timer = 15000;
Summon_Ghoul = 4000;
phase1 = true;
phase2 = false;
phase3 = false;
ghoul = false;
RemoveSummons();
m_creature->SetDisplayId(m_creature->GetNativeDisplayId());
m_creature->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
bEventInProgress = false;
bEvent = false;
bSummonArmy = false;
bDeathArmyDone = false;
uiPhase = PHASE_UNDEAD;
uiIcyTouchTimer = urand(5000,9000);
uiPlagueStrikeTimer = urand(10000,13000);
uiDeathRespiteTimer = urand(15000,16000);
uiObliterateTimer = urand(17000,19000);
uiDesecration = urand(15000,16000);
uiDeathArmyCheckTimer = 7000;
uiResurrectTimer = 4000;
uiGhoulExplodeTimer = 8000;
uiDeathBiteTimer = urand (2000, 4000);
uiMarkedDeathTimer = urand (5000, 7000);
}
void EnterEvadeMode()
void RemoveSummons()
{
m_creature->SetDisplayId(29837);
Plague_Strike_Timer = 5000;
Icy_Touch_Timer = 10000;
Obliterate_Timer = 16000;
Choke_Timer = 15000;
Summon_Ghoul = 4000;
phase1 = true;
phase2 = false;
phase3 = false;
ghoul = false;
m_creature->RemoveArenaAuras(true);
m_creature->SendMonsterMove(746.864441, 660.918762, 411.695465, 4.698700, m_creature->GetDefaultMovementType(), 1);
m_creature->GetMap()->CreatureRelocation(m_creature, 754.360779, 660.816162, 412.395996, 4.698700);
m_creature->SetHealth(m_creature->GetMaxHealth());
if (SummonList.empty())
return;
for(std::list<uint64>::iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
{
if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
if (pTemp)
pTemp->DisappearAndDie();
}
SummonList.clear();
}
void Aggro(Unit* pWho)
void JustSummoned(Creature* pSummon)
{
if (!m_pInstance)
return;
SummonList.push_back(pSummon->GetGUID());
pSummon->AI()->AttackStart(m_creature->getVictim());
}
if (m_pInstance->GetData(TYPE_BLACK_KNIGHT) == DONE)
m_creature->ForcedDespawn();
else
m_pInstance->SetData(TYPE_BLACK_KNIGHT, IN_PROGRESS);
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (bEventInProgress)
if (uiResurrectTimer <= uiDiff)
{
m_creature->SetHealth(m_creature->GetMaxHealth());
DoCast(m_creature,SPELL_BLACK_KNIGHT_RES,true);
uiPhase++;
uiResurrectTimer = 4000;
bEventInProgress = false;
m_creature->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
} else uiResurrectTimer -= uiDiff;
switch(uiPhase)
{
case PHASE_UNDEAD:
case PHASE_SKELETON:
{
if (uiIcyTouchTimer <= uiDiff)
{
DoCastVictim(HEROIC(SPELL_ICY_TOUCH_H,SPELL_ICY_TOUCH));
uiIcyTouchTimer = urand(5000,7000);
} else uiIcyTouchTimer -= uiDiff;
if (uiPlagueStrikeTimer <= uiDiff)
{
DoCastVictim(HEROIC(SPELL_ICY_TOUCH_H,SPELL_ICY_TOUCH));
uiPlagueStrikeTimer = urand(12000,15000);
} else uiPlagueStrikeTimer -= uiDiff;
if (uiObliterateTimer <= uiDiff)
{
DoCastVictim(HEROIC(SPELL_OBLITERATE_H,SPELL_OBLITERATE));
uiObliterateTimer = urand(17000,19000);
} else uiObliterateTimer -= uiDiff;
switch(uiPhase)
{
case PHASE_UNDEAD:
{
if (uiDeathRespiteTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,SPELL_DEATH_RESPITE);
}
uiDeathRespiteTimer = urand(15000,16000);
} else uiDeathRespiteTimer -= uiDiff;
break;
}
case PHASE_SKELETON:
{
if (!bSummonArmy)
{
bSummonArmy = true;
m_creature->addUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
DoCast(m_creature, SPELL_ARMY_DEAD);
}
if (!bDeathArmyDone)
if (uiDeathArmyCheckTimer <= uiDiff)
{
m_creature->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
uiDeathArmyCheckTimer = 0;
bDeathArmyDone = true;
} else uiDeathArmyCheckTimer -= uiDiff;
if (uiDesecration <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,SPELL_DESECRATION);
}
uiDesecration = urand(15000,16000);
} else uiDesecration -= uiDiff;
if (uiGhoulExplodeTimer <= uiDiff)
{
DoCast(m_creature, SPELL_GHOUL_EXPLODE);
uiGhoulExplodeTimer = 8000;
} else uiGhoulExplodeTimer -= uiDiff;
break;
}
break;
}
break;
}
case PHASE_GHOST:
{
if (uiDeathBiteTimer <= uiDiff)
{
DoCastAOE(HEROIC(SPELL_DEATH_BITE_H,SPELL_DEATH_BITE));
uiDeathBiteTimer = urand (2000, 4000);
} else uiDeathBiteTimer -= uiDiff;
if (uiMarkedDeathTimer <= uiDiff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget,SPELL_MARKED_DEATH);
}
uiMarkedDeathTimer = urand (5000, 7000);
} else uiMarkedDeathTimer -= uiDiff;
break;
}
}
if (!m_creature->hasUnitState(UNIT_STAT_ROOT) && !m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 0)
DoMeleeAttackIfReady();
}
void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
{
if (uiDamage > m_creature->GetHealth() && !phase3){
uiDamage = 0;
if (phase2)
StartPhase3();
if (phase1)
StartPhase2();
}
}
void JustDied(Unit* pKiller)
{
if (!m_pInstance)
return;
if (phase3)
m_pInstance->SetData(TYPE_BLACK_KNIGHT, DONE);
if (phase2)
if (!m_creature->isAlive())
{
m_creature->Respawn();
StartPhase3();
}
if (phase1)
if (!m_creature->isAlive())
{
m_creature->Respawn();
StartPhase2();
}
}
void StartPhase2()
{
m_creature->SetHealth(m_creature->GetMaxHealth());
m_creature->SetDisplayId(27550);
phase1 = false;
phase2 = true;
phase3 = false;
DoCast(m_creature, SPELL_ARMY);
Plague_Strike_Timer = 14000;
Icy_Touch_Timer = 12000;
Obliterate_Timer = 18000;
}
void StartPhase3()
{
m_creature->SetHealth(m_creature->GetMaxHealth());
m_creature->SetDisplayId(14560);
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
phase1 = false;
phase2 = false;
phase3 = true;
Death_Timer = 5000;
Mark_Timer = 9000;
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectVictim() || !m_creature->getVictim())
return;
if (Plague_Strike_Timer < diff && !phase3)
if (uiDamage > m_creature->GetHealth() && uiPhase <= PHASE_SKELETON)
{
DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_PLAGUE_STRIKE : SPELL_PLAGUE_STRIKE_H);
Plague_Strike_Timer = 10500;
uiDamage = 0;
m_creature->SetHealth(0);
m_creature->addUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
RemoveSummons();
switch(uiPhase)
{
case PHASE_UNDEAD:
m_creature->SetDisplayId(MODEL_SKELETON);
break;
case PHASE_SKELETON:
m_creature->SetDisplayId(MODEL_GHOST);
break;
}
bEventInProgress = true;
}
else
Plague_Strike_Timer -= diff;
if (Icy_Touch_Timer < diff && !phase3)
{
DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_ICY_TOUCH : SPELL_ICY_TOUCH_H);
Icy_Touch_Timer = 10000;
}
else
Icy_Touch_Timer -= diff;
if (Obliterate_Timer < diff && !phase3)
{
DoCast(m_creature->getVictim(), m_bIsRegularMode ? SPELL_OBLITERATE : SPELL_OBLITERATE_H);
Obliterate_Timer = 11000;
}
else
Obliterate_Timer -= diff;
if (Choke_Timer < diff && phase1)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
DoCast(m_creature->getVictim(), SPELL_CHOKE);
Choke_Timer = 15000;
}
else
Choke_Timer -= diff;
if (Summon_Ghoul < diff && phase1 && !ghoul)
{
if (m_pInstance->GetData(DATA_TOC5_ANNOUNCER) == m_pInstance->GetData(DATA_JAEREN))
m_creature->SummonCreature(NPC_RISEN_JAEREN, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
else
m_creature->SummonCreature(NPC_RISEN_ARELAS, 0.0f, 0.0f, 0.0f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
ghoul = true;
}
else
Summon_Ghoul -= diff;
if (Mark_Timer < diff && phase3)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,1))
DoCast(target, SPELL_MARK);
Mark_Timer = 15000;
}
else
Mark_Timer -= diff;
if (Death_Timer < diff && phase3)
{
DoCast(m_creature, m_bIsRegularMode ? SPELL_DEATH : SPELL_DEATH_H);
Death_Timer = 3500;
}
else
Death_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_black_knight(Creature* pCreature)
CreatureAI* GetAI_boss_black_knight(Creature *pCreature)
{
return new boss_black_knightAI(pCreature);
return new boss_black_knightAI (pCreature);
}
struct TRINITY_DLL_DECL npc_risen_ghoulAI : public ScriptedAI
{
npc_risen_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature) {}
uint32 uiAttackTimer;
void Reset()
{
uiAttackTimer = 3500;
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (uiAttackTimer <= uiDiff)
{
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
{
if (pTarget && pTarget->isAlive())
DoCast(pTarget, (HEROIC(SPELL_LEAP_H,SPELL_LEAP)));
}
uiAttackTimer = 3500;
} else uiAttackTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_risen_ghoul(Creature* pCreature)
{
return new npc_risen_ghoulAI(pCreature);
}
void AddSC_boss_black_knight()
{
Script* NewScript;
NewScript = new Script;
NewScript->Name = "mob_toc5_risen_ghoul";
NewScript->GetAI = &GetAI_mob_toc5_risen_ghoul;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "boss_black_knight";
NewScript->GetAI = &GetAI_boss_black_knight;
NewScript->RegisterSelf();
NewScript = new Script;
NewScript->Name = "npc_risen_ghoul";
NewScript->GetAI = &GetAI_npc_risen_ghoul;
NewScript->RegisterSelf();
}