Core/Script/Spells: Trial of the Crusader

* Keep in mind that this is a WIP although is extremely playable as it is.
* Known bugs are writen at the header of each file.
* If u know how to correctly solve any of those bugs or found a new bug, please report and, if you may, provide a fix for us to review.
* I'd like to thank all Trinity Community (in special, Shauren, QAston, Bio, Josh), rsa from SD2 for providing the base, all the ppl that helped me test and review so many many times.
* I personally have been working on this code since TC was near rev 8000 so i will take a break from it to work on other stuff (specially cause most of the bugs i was unable to solve alone).
* I'd like to strongly encourage others to provide the improvements that this instance need to become perfect.
* FInally, this commit might have something missing... i'll recheck as soon as i wake up tomorrow morning.

--HG--
branch : trunk
This commit is contained in:
John Holiver
2010-08-22 05:55:54 -03:00
parent 2a130e07bf
commit 3fb1c08d20
16 changed files with 6959 additions and 5 deletions
@@ -329,6 +329,13 @@ void AddSC_boss_black_knight();
void AddSC_boss_grand_champions();
void AddSC_instance_trial_of_the_champion();
void AddSC_trial_of_the_champion();
void AddSC_boss_anubarak_trial(); //Trial of the Crusader
void AddSC_boss_faction_champions();
void AddSC_boss_jaraxxus();
void AddSC_boss_northrend_beasts();
void AddSC_boss_twin_valkyr();
void AddSC_trial_of_the_crusader();
void AddSC_instance_trial_of_the_crusader();
void AddSC_boss_anubrekhan(); //Naxxramas
void AddSC_boss_maexxna();
void AddSC_boss_patchwerk();
@@ -990,6 +997,13 @@ void AddNorthrendScripts()
AddSC_boss_grand_champions();
AddSC_instance_trial_of_the_champion();
AddSC_trial_of_the_champion();
AddSC_boss_anubarak_trial(); //Trial of the Crusader
AddSC_boss_faction_champions();
AddSC_boss_jaraxxus();
AddSC_trial_of_the_crusader();
AddSC_boss_twin_valkyr();
AddSC_boss_northrend_beasts();
AddSC_instance_trial_of_the_crusader();
AddSC_boss_krik_thir(); //Azjol-Nerub Azjol-Nerub
AddSC_boss_hadronox();
AddSC_boss_anub_arak();
@@ -2342,9 +2342,6 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
default:
break;
}
// Reget trigger spell proto
triggeredSpellInfo = sSpellStore.LookupEntry(triggerSpellId);
}
else
{
@@ -2359,8 +2356,21 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
case RAID_DIFFICULTY_25MAN_NORMAL: triggerSpellId = 67622; break;
case RAID_DIFFICULTY_25MAN_HEROIC: triggerSpellId = 67623; break;
}
// Reget trigger spell proto
triggeredSpellInfo = sSpellStore.LookupEntry(triggerSpellId);
break;
// Pursuing Spikes (Anub'arak)
case 65920:
case 65922:
case 65923:
if (caster->HasAura(66193))
{
if (Unit* permafrostCaster = caster->GetAura(66193)->GetCaster())
if (permafrostCaster->ToCreature())
permafrostCaster->ToCreature()->ForcedDespawn(3000);
caster->CastSpell(caster,66181,false);
caster->RemoveAllAuras();
if (caster->ToCreature())
caster->ToCreature()->DisappearAndDie();
}
break;
// Mana Tide
case 16191:
@@ -2387,6 +2397,9 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
}
}
// Reget trigger spell proto
triggeredSpellInfo = sSpellStore.LookupEntry(triggerSpellId);
if (triggeredSpellInfo)
{
Unit * triggerCaster = GetTriggeredSpellCaster(triggeredSpellInfo, caster, triggerTarget);
@@ -0,0 +1,716 @@
/* Copyright (C) 2006 - 2010 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: boss_anubarak_trial
SD%Complete: ??%
SDComment: based on /dev/rsa
SDCategory:
EndScriptData */
// Known bugs:
// Anubarak - underground phase partially not worked
// - tele after impale hit a permafrost doesn't work (the entire tele spell should be better)
// Burrow - visual is vanishing
// Burrower - Spider Frenzy not working as it should (frenzy not stacking)
// Scarab - Kill credit isn't crediting?
// FrostSph - often they are casting Permafrost a little above the ground
#include "ScriptPCH.h"
#include "trial_of_the_crusader.h"
enum Yells
{
SAY_INTRO = -1649055,
SAY_AGGRO = -1649056,
SAY_KILL1 = -1649057,
SAY_KILL2 = -1649058,
SAY_DEATH = -1649059,
EMOTE_SPIKE = -1649060,
SAY_BURROWER = -1649061,
EMOTE_LEECHING_SWARM = -1649062,
SAY_LEECHING_SWARM = -1649063,
};
enum Summons
{
NPC_FROST_SPHERE = 34606,
NPC_BURROW = 34862,
NPC_BURROWER = 34607,
NPC_SCARAB = 34605,
NPC_SPIKE = 34660,
};
enum BossSpells
{
SPELL_FREEZE_SLASH = 66012,
SPELL_PENETRATING_COLD = 66013,
SPELL_LEECHING_SWARM = 66118,
SPELL_LEECHING_HEAL = 66125,
SPELL_LEECHING_DAMAGE = 66240,
SPELL_MARK = 67574,
SPELL_SPIKE_CALL = 66169,
SPELL_SUBMERGE_ANUBARAK = 65981,
SPELL_CLEAR_ALL_DEBUFFS = 34098,
SPELL_EMERGE_ANUBARAK = 65982,
SPELL_SUMMON_BEATLES = 66339,
SPELL_SUMMON_BURROWER = 66332,
// Burrow
SPELL_CHURNING_GROUND = 66969,
// Scarab
SPELL_DETERMINATION = 66092,
SPELL_ACID_MANDIBLE = 65774, //Passive - Triggered
// Burrower
SPELL_SPIDER_FRENZY = 66128,
SPELL_EXPOSE_WEAKNESS = 67720, //Passive - Triggered
SPELL_SHADOW_STRIKE = 66134,
SPELL_SUBMERGE_EFFECT = 53421,
SPELL_EMERGE_EFFECT = 66947,
SUMMON_SCARAB = NPC_SCARAB,
SUMMON_FROSTSPHERE = NPC_FROST_SPHERE,
SPELL_BERSERK = 26662,
//Frost Sphere
SPELL_FROST_SPHERE = 67539,
SPELL_PERMAFROST = 66193,
SPELL_PERMAFROST_VISUAL = 65882,
//Spike
SPELL_SUMMON_SPIKE = 66169,
SPELL_SPIKE_SPEED1 = 65920,
SPELL_SPIKE_TRAIL = 65921,
SPELL_SPIKE_SPEED2 = 65922,
SPELL_SPIKE_SPEED3 = 65923,
SPELL_SPIKE_FAIL = 66181,
SPELL_SPIKE_TELE = 66170,
};
enum SummonActions
{
ACTION_SHADOW_STRIKE,
ACTION_SCARAB_SUBMERGE,
};
␍const Position SphereSpawn[6] =
{
{ 786.6439, 108.2498, 155.6701 },
{ 806.8429, 150.5902, 155.6701 },
{ 759.1386, 163.9654, 155.6701 },
{ 744.3701, 119.5211, 155.6701 },
{ 710.0211, 120.8152, 155.6701 },
{ 706.6383, 161.5266, 155.6701 },
};␍␍class boss_anubarak_trial : public CreatureScript
{
public:
boss_anubarak_trial() : CreatureScript("boss_anubarak_trial") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_anubarak_trialAI(pCreature);
};
struct boss_anubarak_trialAI : public ScriptedAI
{
boss_anubarak_trialAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
SummonList Summons;
std::list<uint64> m_vBurrowGUID;
uint64 m_aSphereGUID[6];
uint32 m_uiFreezeSlashTimer;
uint32 m_uiPenetratingColdTimer;
uint32 m_uiSummonNerubianTimer;
uint32 m_uiNerubianShadowStrikeTimer;
uint32 m_uiSubmergeTimer;
uint32 m_uiPursuingSpikeTimer;
uint32 m_uiSummonScarabTimer;
uint32 m_uiSummonFrostSphereTimer;
uint32 m_uiBerserkTimer;
uint8 m_uiStage;
bool m_bIntro;
bool m_bReachedPhase3;
uint64 m_uiTargetGUID;
uint8 m_uiScarabSummoned;
void Reset()
{
m_uiFreezeSlashTimer = 15*IN_MILLISECONDS;
m_uiPenetratingColdTimer = 20*IN_MILLISECONDS;
m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
m_uiSummonNerubianTimer = 10*IN_MILLISECONDS;
m_uiSubmergeTimer = 80*IN_MILLISECONDS;
m_uiPursuingSpikeTimer = 2*IN_MILLISECONDS;
m_uiSummonScarabTimer = 2*IN_MILLISECONDS;
m_uiSummonFrostSphereTimer = 20*IN_MILLISECONDS;
m_uiBerserkTimer = 15*MINUTE*IN_MILLISECONDS;
m_uiStage = 0;
m_uiScarabSummoned = 0;
m_bIntro = true;
m_bReachedPhase3 = false;
m_uiTargetGUID = 0;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
Summons.DespawnAll();
m_vBurrowGUID.clear();
}
void KilledUnit(Unit* pWho)
{
if (pWho->GetTypeId() == TYPEID_PLAYER)
{
DoScriptText(urand(0,1) ? SAY_KILL1 : SAY_KILL2,me);
if (m_pInstance)
m_pInstance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
}
void MoveInLineOfSight(Unit* pWho)
{
if (!m_bIntro)
{
DoScriptText(SAY_INTRO,me);
m_bIntro = false;
}
}
void JustReachedHome()
{
if (m_pInstance)
m_pInstance->SetData(TYPE_ANUBARAK, FAIL);
//Summon Scarab Swarms neutral at random places
for (int i=0; i < 10; i++)
if (Creature* pTemp = me->SummonCreature(NPC_SCARAB,AnubarakLoc[1].GetPositionX()+urand(0,50)-25,AnubarakLoc[1].GetPositionY()+urand(0,50)-25,AnubarakLoc[1].GetPositionZ()))
pTemp->setFaction(31);
}
void JustDied(Unit* pKiller)
{
Summons.DespawnAll();
DoScriptText(SAY_DEATH,me);
if (m_pInstance)
m_pInstance->SetData(TYPE_ANUBARAK, DONE);
}
void JustSummoned(Creature* pSummoned)
{
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
switch(pSummoned->GetEntry())
{
case NPC_BURROW:
m_vBurrowGUID.push_back(pSummoned->GetGUID());
pSummoned->SetReactState(REACT_PASSIVE);
pSummoned->CastSpell(pSummoned,SPELL_CHURNING_GROUND,false);
break;
case NPC_SPIKE:
pSummoned->CombatStart(pTarget);
DoScriptText(EMOTE_SPIKE,me,pTarget);
break;
}
Summons.Summon(pSummoned);
}
void SummonedCreatureDespawn(Creature* pSummoned)
{
switch(pSummoned->GetEntry())
{
case NPC_SPIKE:
m_uiPursuingSpikeTimer = 2*IN_MILLISECONDS;
break;
}
}
void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO,me);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->SetInCombatWithZone();
if (m_pInstance)
m_pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS);
//Despawn Scarab Swarms neutral
Summons.DoAction(NPC_SCARAB,ACTION_SCARAB_SUBMERGE);
//Spawn Burrow
for (int i=0; i < 4; i++)
me->SummonCreature(NPC_BURROW,AnubarakLoc[i+2]);
//Spawn Frost Spheres
for (int i=0; i < 6; i++)
if (Unit *pSummoned = me->SummonCreature(NPC_FROST_SPHERE,SphereSpawn[i]))
m_aSphereGUID[i] = pSummoned->GetGUID();
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
switch(m_uiStage)
{
case 0:
if (m_uiFreezeSlashTimer <= uiDiff)
{
DoCastVictim(SPELL_FREEZE_SLASH);
m_uiFreezeSlashTimer = 15*IN_MILLISECONDS;
} else m_uiFreezeSlashTimer -= uiDiff;
if (m_uiPenetratingColdTimer <= uiDiff)
{
me->CastCustomSpell(SPELL_PENETRATING_COLD, SPELLVALUE_MAX_TARGETS, RAID_MODE(2,5));
m_uiPenetratingColdTimer = 20*IN_MILLISECONDS;
} else m_uiPenetratingColdTimer -= uiDiff;
if (m_uiSummonNerubianTimer <= uiDiff && (IsHeroic() || !m_bReachedPhase3))
{
me->CastCustomSpell(SPELL_SUMMON_BURROWER, SPELLVALUE_MAX_TARGETS, RAID_MODE(1,2,2,4));
m_uiSummonNerubianTimer = 45*IN_MILLISECONDS;
} else m_uiSummonNerubianTimer -= uiDiff;
if (IsHeroic() && m_uiNerubianShadowStrikeTimer <= uiDiff)
{
Summons.DoAction(NPC_BURROWER,ACTION_SHADOW_STRIKE);
m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
} else m_uiNerubianShadowStrikeTimer -= uiDiff;
if (m_uiSubmergeTimer <= uiDiff && !m_bReachedPhase3 && !me->HasAura(SPELL_BERSERK))
{
m_uiStage = 1;
m_uiSubmergeTimer = 60*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
break;
case 1:
DoCast(me,SPELL_SUBMERGE_ANUBARAK);
DoCast(me,SPELL_CLEAR_ALL_DEBUFFS);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
DoScriptText(SAY_BURROWER,me);
m_uiScarabSummoned = 0;
m_uiSummonScarabTimer = 4*IN_MILLISECONDS;
m_uiStage = 2;
break;
case 2:
if (m_uiPursuingSpikeTimer <= uiDiff)
{
DoCast(SPELL_SPIKE_CALL);
// Just to make sure it won't happen again in this phase
m_uiPursuingSpikeTimer = 90*IN_MILLISECONDS;
} else m_uiPursuingSpikeTimer -= uiDiff;
if (m_uiSummonScarabTimer <= uiDiff)
{
/* WORKAROUND
* - The correct implementation is more likely the comment below but it needs spell knowledge
*/
std::list<uint64>::iterator i = m_vBurrowGUID.begin();
uint32 at = urand(0,m_vBurrowGUID.size()-1);
for (uint32 k = 0; k < at; k++)
++i;
if (Creature *pBurrow = Unit::GetCreature(*me, *i))
pBurrow->CastSpell(pBurrow,66340,false);
m_uiScarabSummoned++;
m_uiSummonScarabTimer = 4*IN_MILLISECONDS;
if (m_uiScarabSummoned == 4) m_uiSummonScarabTimer = RAID_MODE(4,20)*IN_MILLISECONDS;
/*It seems that this spell have something more that needs to be taken into account
//Need more sniff info
DoCast(SPELL_SUMMON_BEATLES);
// Just to make sure it won't happen again in this phase
m_uiSummonScarabTimer = 90*IN_MILLISECONDS;*/
} else m_uiSummonScarabTimer -= uiDiff;
if (m_uiSubmergeTimer <= uiDiff)
{
m_uiStage = 3;
m_uiSubmergeTimer = 80*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
break;
case 3:
m_uiStage = 0;
DoCast(SPELL_SPIKE_TELE);
Summons.DespawnEntry(NPC_SPIKE);
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_ANUBARAK);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
DoCast(me,SPELL_EMERGE_ANUBARAK);
me->GetMotionMaster()->MoveChase(me->getVictim());
m_uiSummonNerubianTimer = 10*IN_MILLISECONDS;
m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
m_uiSummonScarabTimer = 2*IN_MILLISECONDS;
break;
}
if (!IsHeroic())
{
if (m_uiSummonFrostSphereTimer <= uiDiff)
{
uint8 startAt = urand(0,5);
uint8 i = startAt;
do
{
if (Unit *pSphere = Unit::GetCreature(*me,m_aSphereGUID[i]))
{
if (!pSphere->HasAura(SPELL_FROST_SPHERE))
{
if (Creature *pSummon = me->SummonCreature(NPC_FROST_SPHERE,SphereSpawn[i]))
m_aSphereGUID[i] = pSummon->GetGUID();
break;
}
}
i = (i+1)%6;
} while (i != startAt);
m_uiSummonFrostSphereTimer = urand(20,30)*IN_MILLISECONDS;
} else m_uiSummonFrostSphereTimer -= uiDiff;
}
if (HealthBelowPct(30) && m_uiStage == 0 && !m_bReachedPhase3)
{
m_bReachedPhase3 = true;
DoCastAOE(SPELL_LEECHING_SWARM);
DoScriptText(EMOTE_LEECHING_SWARM,me);
DoScriptText(SAY_LEECHING_SWARM,me);
}
if (m_uiBerserkTimer <= uiDiff && !me->HasAura(SPELL_BERSERK))
{
DoCast(me,SPELL_BERSERK);
} else m_uiBerserkTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
␍class mob_swarm_scarab : public CreatureScript
{
public:
mob_swarm_scarab() : CreatureScript("mob_swarm_scarab") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_swarm_scarabAI(pCreature);
};
struct mob_swarm_scarabAI : public ScriptedAI
{
mob_swarm_scarabAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiDeterminationTimer;
void Reset()
{
me->SetCorpseDelay(0);
m_uiDeterminationTimer = urand(5*IN_MILLISECONDS,60*IN_MILLISECONDS);
DoCast(me,SPELL_ACID_MANDIBLE);
me->SetInCombatWithZone();
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
me->AddThreat(pTarget,20000.0f);
if (!me->isInCombat())
me->DisappearAndDie();
}
void DoAction(const int32 actionId)
{
switch(actionId)
{
case ACTION_SCARAB_SUBMERGE:
DoCast(SPELL_SUBMERGE_EFFECT);
me->ForcedDespawn(1000);
break;
}
}
void JustDied(Unit* pKiller)
{
DoCast(pKiller,RAID_MODE(SPELL_TRAITOR_KING_10,SPELL_TRAITOR_KING_25));
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
/* Bosskillers don't recognize */
if (m_uiDeterminationTimer <= uiDiff)
{
DoCast(me,SPELL_DETERMINATION);
m_uiDeterminationTimer = urand(10*IN_MILLISECONDS,60*IN_MILLISECONDS);
} else m_uiDeterminationTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
␍class mob_nerubian_burrower : public CreatureScript
{
public:
mob_nerubian_burrower() : CreatureScript("mob_nerubian_burrower") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_nerubian_burrowerAI(pCreature);
};
struct mob_nerubian_burrowerAI : public ScriptedAI
{
mob_nerubian_burrowerAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiSpiderFrenzyTimer;
uint32 m_uiSubmergeTimer;
void Reset()
{
me->SetCorpseDelay(0);
m_uiSpiderFrenzyTimer = urand(10*IN_MILLISECONDS,20*IN_MILLISECONDS);
m_uiSubmergeTimer = 30*IN_MILLISECONDS;
DoCast(me,SPELL_EXPOSE_WEAKNESS);
DoCast(me,SPELL_SPIDER_FRENZY);
me->SetInCombatWithZone();
if (!me->isInCombat())
me->DisappearAndDie();
}
void DoAction(const int32 actionId)
{
switch(actionId)
{
case ACTION_SHADOW_STRIKE:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,SPELL_SHADOW_STRIKE);
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if ((m_uiSubmergeTimer <= uiDiff) && HealthBelowPct(80))
{
if (me->HasAura(SPELL_SUBMERGE_EFFECT))
{
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_EFFECT);
DoCast(me,SPELL_EMERGE_EFFECT);
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->CombatStart(me->SelectNearestTarget());
}
else
{
if (!me->HasAura(SPELL_PERMAFROST))
{
DoCast(me,SPELL_SUBMERGE_EFFECT);
me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->CombatStop();
}
}
m_uiSubmergeTimer = 20*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
␍class mob_frost_sphere : public CreatureScript
{
public:
mob_frost_sphere() : CreatureScript("mob_frost_sphere") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_frost_sphereAI(pCreature);
};
struct mob_frost_sphereAI : public ScriptedAI
{
mob_frost_sphereAI(Creature* pCreature) : ScriptedAI(pCreature)
{
}
bool m_bFall;
uint32 m_uiPermafrostTimer;
void Reset()
{
m_bFall = false;
m_uiPermafrostTimer = 0;
me->SetReactState(REACT_PASSIVE);
me->SetFlying(true);
me->SetDisplayId(25144);
me->SetSpeed(MOVE_RUN, 0.5, false);
me->GetMotionMaster()->MoveRandom(20.0f);
DoCast(SPELL_FROST_SPHERE);
}
void DamageTaken(Unit* pWho, uint32& uiDamage)
{
if (me->GetHealth() < uiDamage)
{
uiDamage = 0;
if (!m_bFall)
{
m_bFall = true;
me->SetFlying(false);
me->GetMotionMaster()->MoveIdle();
me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_SELECTABLE);
//At hit the ground
me->GetMotionMaster()->MoveFall(142.2f, 0);
//me->FallGround(); //need correct vmap use (i believe it isn't working properly right now)
}
}
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if(uiType != POINT_MOTION_TYPE) return;
switch (uiId)
{
case 0:
m_uiPermafrostTimer = IN_MILLISECONDS;
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
if (m_uiPermafrostTimer)
{
if (m_uiPermafrostTimer <= uiDiff)
{
m_uiPermafrostTimer = 0;
me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE);
me->SetDisplayId(11686);
me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
DoCast(SPELL_PERMAFROST_VISUAL);
DoCast(SPELL_PERMAFROST);
} else m_uiPermafrostTimer -= uiDiff;
}
}
};
};
␍class mob_anubarak_spike : public CreatureScript
{
public:
mob_anubarak_spike() : CreatureScript("mob_anubarak_spike") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_anubarak_spikeAI(pCreature);
};
struct mob_anubarak_spikeAI : public ScriptedAI
{
mob_anubarak_spikeAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiIncreaseSpeedTimer;
uint8 m_uiSpeed;
uint64 m_uiTargetGUID;
void Reset()
{
// For an unknown reason this npc isn't recognize the Aura of Permafrost with this flags =/
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
m_uiTargetGUID = 0;
}
void EnterCombat(Unit *pWho)
{
m_uiTargetGUID = pWho->GetGUID();
DoCast(pWho,SPELL_MARK);
me->SetSpeed(MOVE_RUN, 0.5f);
m_uiSpeed = 0;
m_uiIncreaseSpeedTimer = 1*IN_MILLISECONDS;
me->TauntApply(pWho);
}
void DamageTaken(Unit* pWho, uint32& uiDamage)
{
uiDamage = 0;
}
void UpdateAI(const uint32 uiDiff)
{
Unit* pTarget = Unit::GetPlayer(*me, m_uiTargetGUID);
if (!pTarget || !pTarget->isAlive() || !pTarget->HasAura(SPELL_MARK))
{
if (Creature* pAnubarak = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_ANUBARAK)))
pAnubarak->CastSpell(pAnubarak,SPELL_SPIKE_TELE,false);
me->DisappearAndDie();
return;
}
if (m_uiIncreaseSpeedTimer)
if (m_uiIncreaseSpeedTimer <= uiDiff)
{
switch (m_uiSpeed)
{
case 0:
DoCast(me,SPELL_SPIKE_SPEED1);
DoCast(me,SPELL_SPIKE_TRAIL);
m_uiSpeed = 1;
m_uiIncreaseSpeedTimer = 7*IN_MILLISECONDS;
break;
case 1:
DoCast(me,SPELL_SPIKE_SPEED2);
m_uiSpeed = 2;
m_uiIncreaseSpeedTimer = 7*IN_MILLISECONDS;
break;
case 2:
DoCast(me,SPELL_SPIKE_SPEED3);
m_uiIncreaseSpeedTimer = 0;
break;
}
} else m_uiIncreaseSpeedTimer -= uiDiff;
}
};
};
void AddSC_boss_anubarak_trial()
{
new boss_anubarak_trial();
new mob_swarm_scarab();
new mob_nerubian_burrower();
new mob_anubarak_spike();
new mob_frost_sphere();
}
@@ -0,0 +1,566 @@
/* Copyright (C) 2006 - 2010 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: trial_of_the_crusader
SD%Complete: ??%
SDComment: based on /dev/rsa
SDCategory: Crusader Coliseum
EndScriptData */
// Known bugs:
// Some visuals aren't appearing right sometimes
// Mistress of Pain - Isn't working as a vehicle yet
// - SPELL_SPINNING_STRIKE not working
#include "ScriptPCH.h"
#include "trial_of_the_crusader.h"
enum Yells
{
SAY_INTRO = -1649030,
SAY_AGGRO = -1649031,
SAY_DEATH = -1649032,
EMOTE_INCINERATE = -1649033,
SAY_INCINERATE = -1649034,
EMOTE_LEGION_FLAME = -1649035,
EMOTE_NETHER_PORTAL = -1649036,
SAY_NETHER_PORTAL = -1649037,
EMOTE_INFERNAL_ERUPTION = -1649038,
SAY_INFERNAL_ERUPTION = -1649039,
};
enum Equipment
{
EQUIP_MAIN = 47266,
EQUIP_OFFHAND = 46996,
EQUIP_RANGED = 47267,
EQUIP_DONE = EQUIP_NO_CHANGE,
};
enum Summons
{
NPC_LEGION_FLAME = 34784,
NPC_INFERNAL_VOLCANO = 34813,
NPC_FEL_INFERNAL = 34815,
NPC_NETHER_PORTAL = 34825,
NPC_MISTRESS_OF_PAIN = 34826,
};
enum BossSpells
{
SPELL_NETHER_POWER = 67108,
SPELL_INFERNAL = 66258,
SPELL_INFERNAL_ERUPTION = 66255,
SPELL_FEL_FIREBALL = 66532,
SPELL_FEL_LIGHTING = 66528,
SPELL_INCINERATE_FLESH = 66237,
SPELL_TOUCH_OF_JARAXXUS = 66209,
SPELL_BURNING_INFERNO = 66242,
SPELL_NETHER_PORTAL = 66263,
SPELL_LEGION_FLAME = 66197,
SPELL_LEGION_FLAME_EFFECT = 66201,
SPELL_SHIVAN_SLASH = 67098,
SPELL_SPINNING_STRIKE = 66316,
SPELL_MISTRESS_KISS = 67077,
SPELL_FEL_INFERNO = 67047,
SPELL_FEL_STREAK = 66494,
SPELL_BERSERK = 64238,
};
/*######
## boss_jaraxxus
######*/
␍class boss_jaraxxus : public CreatureScript
{
public:
boss_jaraxxus() : CreatureScript("boss_jaraxxus") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_jaraxxusAI(pCreature);
}
struct boss_jaraxxusAI : public ScriptedAI
{
boss_jaraxxusAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
Reset();
}
InstanceScript* m_pInstance;
SummonList Summons;
uint32 m_uiFelFireballTimer;
uint32 m_uiFelLightningTimer;
uint32 m_uiIncinerateFleshTimer;
uint32 m_uiNetherPowerTimer;
uint32 m_uiLegionFlameTimer;
uint32 m_uiTouchOfJaraxxusTimer;
uint32 m_uiSummonNetherPortalTimer;
uint32 m_uiSummonInfernalEruptionTimer;
void Reset()
{
if(m_pInstance)
m_pInstance->SetData(TYPE_JARAXXUS, NOT_STARTED);
SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
m_uiFelFireballTimer = 5*IN_MILLISECONDS;
m_uiFelLightningTimer = urand(10*IN_MILLISECONDS,15*IN_MILLISECONDS);
m_uiIncinerateFleshTimer = urand(20*IN_MILLISECONDS,25*IN_MILLISECONDS);
m_uiNetherPowerTimer = 40*IN_MILLISECONDS;
m_uiLegionFlameTimer = 30*IN_MILLISECONDS;
m_uiTouchOfJaraxxusTimer = urand(10*IN_MILLISECONDS,15*IN_MILLISECONDS);
m_uiSummonNetherPortalTimer = 1*MINUTE*IN_MILLISECONDS;
m_uiSummonInfernalEruptionTimer = 2*MINUTE*IN_MILLISECONDS;
Summons.DespawnAll();
}
void JustReachedHome()
{
if (m_pInstance)
m_pInstance->SetData(TYPE_JARAXXUS, FAIL);
DoCast(me,SPELL_JARAXXUS_CHAINS);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_PASSIVE);
}
void KilledUnit(Unit *pWho)
{
if (pWho->GetTypeId() == TYPEID_PLAYER)
{
if (m_pInstance)
m_pInstance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
}
void JustDied(Unit* pKiller)
{
Summons.DespawnAll();
DoScriptText(SAY_DEATH,me);
if (m_pInstance)
m_pInstance->SetData(TYPE_JARAXXUS, DONE);
}
void JustSummoned(Creature* pSummoned)
{
Summons.Summon(pSummoned);
}
void EnterCombat(Unit* pWho)
{
me->SetInCombatWithZone();
if (m_pInstance)
m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS);
DoScriptText(SAY_AGGRO,me);
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (m_uiSummonInfernalEruptionTimer <= uiDiff)
{
DoScriptText(EMOTE_INFERNAL_ERUPTION,me);
DoScriptText(SAY_INFERNAL_ERUPTION,me);
uint8 i = urand(2,3);
me->SummonCreature(NPC_INFERNAL_VOLCANO,JaraxxusLoc[i].GetPositionX(),JaraxxusLoc[i].GetPositionY(),JaraxxusLoc[i].GetPositionZ(),TEMPSUMMON_CORPSE_DESPAWN);
m_uiSummonInfernalEruptionTimer = 2*MINUTE*IN_MILLISECONDS;
} else m_uiSummonInfernalEruptionTimer -= uiDiff;
if (m_uiSummonNetherPortalTimer <= uiDiff)
{
DoScriptText(EMOTE_NETHER_PORTAL,me);
DoScriptText(SAY_NETHER_PORTAL,me);
uint8 i = urand(2,3);
me->SummonCreature(NPC_NETHER_PORTAL,JaraxxusLoc[i].GetPositionX(),JaraxxusLoc[i].GetPositionY(),JaraxxusLoc[i].GetPositionZ(),TEMPSUMMON_CORPSE_DESPAWN);
m_uiSummonNetherPortalTimer = 2*MINUTE*IN_MILLISECONDS;
} else m_uiSummonNetherPortalTimer -= uiDiff;
if (m_uiFelFireballTimer <= uiDiff)
{
DoCastVictim(SPELL_FEL_FIREBALL);
m_uiFelFireballTimer = urand(10*IN_MILLISECONDS,15*IN_MILLISECONDS);
} else m_uiFelFireballTimer -= uiDiff;
if (m_uiFelLightningTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
DoCast(pTarget,SPELL_FEL_LIGHTING);
m_uiFelLightningTimer = urand(10*IN_MILLISECONDS,15*IN_MILLISECONDS);
} else m_uiFelLightningTimer -= uiDiff;
if (m_uiIncinerateFleshTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,1))
{
DoScriptText(EMOTE_INCINERATE,me,pTarget);
DoScriptText(SAY_INCINERATE,me);
DoCast(pTarget,SPELL_INCINERATE_FLESH);
}
m_uiIncinerateFleshTimer = urand(20*IN_MILLISECONDS,25*IN_MILLISECONDS);
} else m_uiIncinerateFleshTimer -= uiDiff;
if (m_uiNetherPowerTimer <= uiDiff)
{
DoCast(me,SPELL_NETHER_POWER);
m_uiNetherPowerTimer = 40*IN_MILLISECONDS;
} else m_uiNetherPowerTimer -= uiDiff;
if (m_uiLegionFlameTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,1))
{
DoScriptText(EMOTE_LEGION_FLAME,me,pTarget);
DoCast(pTarget,SPELL_LEGION_FLAME);
}
m_uiLegionFlameTimer = 30*IN_MILLISECONDS;
} else m_uiLegionFlameTimer -= uiDiff;
if (getDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC && m_uiTouchOfJaraxxusTimer <= uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,SPELL_TOUCH_OF_JARAXXUS);
m_uiTouchOfJaraxxusTimer = urand(10*IN_MILLISECONDS,15*IN_MILLISECONDS);
} else m_uiTouchOfJaraxxusTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
␍class mob_legion_flame : public CreatureScript
{
public:
mob_legion_flame() : CreatureScript("mob_legion_flame") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_legion_flameAI(pCreature);
}
struct mob_legion_flameAI : public Scripted_NoMovementAI
{
mob_legion_flameAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
{
Reset();
}
void Reset()
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->SetInCombatWithZone();
DoCast(SPELL_LEGION_FLAME_EFFECT);
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
}
};
};
␍class mob_infernal_volcano : public CreatureScript
{
public:
mob_infernal_volcano() : CreatureScript("mob_infernal_volcano") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_infernal_volcanoAI(pCreature);
}
struct mob_infernal_volcanoAI : public Scripted_NoMovementAI
{
mob_infernal_volcanoAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
Reset();
}
InstanceScript* m_pInstance;
SummonList Summons;
uint8 m_Count;
uint8 m_CountMax;
uint32 m_Timer;
void Reset()
{
me->SetReactState(REACT_PASSIVE);
m_Count = 0;
if (!IsHeroic())
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
m_CountMax = 3;
m_Timer = 15*IN_MILLISECONDS;
}
else
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
m_CountMax = 0;
m_Timer = 0;
}
Summons.DespawnAll();
}
void JustSummoned(Creature* pSummoned)
{
Summons.Summon(pSummoned);
pSummoned->SetCorpseDelay(0);
}
void JustDied(Unit* pKiller)
{
me->ForcedDespawn();
}
void UpdateAI(const uint32 uiDiff)
{
if (m_Timer <= uiDiff)
{
if (m_CountMax && m_CountMax == m_Count)
me->ForcedDespawn();
else
{
DoCast(SPELL_INFERNAL_ERUPTION);
++m_Count;
}
m_Timer = 5*IN_MILLISECONDS;
} else m_Timer -= uiDiff;
if (!UpdateVictim())
return;
}
};
};
␍class mob_fel_infernal : public CreatureScript
{
public:
mob_fel_infernal() : CreatureScript("mob_fel_infernal") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_fel_infernalAI(pCreature);
}
struct mob_fel_infernalAI : public ScriptedAI
{
mob_fel_infernalAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
Reset();
}
InstanceScript* m_pInstance;
uint32 m_uiFelStreakTimer;
void Reset()
{
m_uiFelStreakTimer = 30*IN_MILLISECONDS;
me->SetInCombatWithZone();
}
/*void SpellHitTarget(Unit *pTarget, const SpellEntry *pSpell)
{
if (pSpell->Id == SPELL_FEL_STREAK)
DoCastAOE(SPELL_FEL_INFERNO); //66517
}*/
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (m_pInstance && m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
me->ForcedDespawn();
if (m_uiFelStreakTimer <= uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,SPELL_FEL_STREAK);
m_uiFelStreakTimer = 30*IN_MILLISECONDS;
} else m_uiFelStreakTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
␍class mob_nether_portal : public CreatureScript
{
public:
mob_nether_portal() : CreatureScript("mob_nether_portal") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_nether_portalAI(pCreature);
}
struct mob_nether_portalAI : public ScriptedAI
{
mob_nether_portalAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
Reset();
}
InstanceScript* m_pInstance;
SummonList Summons;
uint32 m_Timer;
uint8 m_Count;
uint8 m_CountMax;
void Reset()
{
me->SetReactState(REACT_PASSIVE);
m_Timer = 10*IN_MILLISECONDS;
m_Count = 0;
if (!IsHeroic())
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
m_CountMax = 1;
}
else
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
m_CountMax = 0;
}
Summons.DespawnAll();
}
void JustSummoned(Creature* pSummoned)
{
Summons.Summon(pSummoned);
pSummoned->SetCorpseDelay(0);
}
void UpdateAI(const uint32 uiDiff)
{
if (m_Timer <= uiDiff)
{
if (m_CountMax && m_CountMax == m_Count)
me->ForcedDespawn();
else
{
DoCast(SPELL_NETHER_PORTAL);
++m_Count;
}
m_Timer = 15*IN_MILLISECONDS;
} else m_Timer -= uiDiff;
if (!UpdateVictim())
return;
}
};
};
␍class mob_mistress_of_pain : public CreatureScript
{
public:
mob_mistress_of_pain() : CreatureScript("mob_mistress_of_pain") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_mistress_of_painAI(pCreature);
}
struct mob_mistress_of_painAI : public ScriptedAI
{
mob_mistress_of_painAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
if (m_pInstance)
m_pInstance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
Reset();
}
InstanceScript* m_pInstance;
uint32 m_uiShivanSlashTimer;
uint32 m_uiSpinningStrikeTimer;
uint32 m_uiMistressKissTimer;
void Reset()
{
m_uiShivanSlashTimer = 30*IN_MILLISECONDS;
m_uiSpinningStrikeTimer = 30*IN_MILLISECONDS;
m_uiMistressKissTimer = 15*IN_MILLISECONDS;
me->SetInCombatWithZone();
}
void JustDied(Unit* pKiller)
{
if (m_pInstance)
m_pInstance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (m_pInstance && m_pInstance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
me->ForcedDespawn();
if (m_uiShivanSlashTimer <= uiDiff)
{
DoCastVictim(SPELL_SHIVAN_SLASH);
m_uiShivanSlashTimer = 30*IN_MILLISECONDS;
} else m_uiShivanSlashTimer -= uiDiff;
if (m_uiSpinningStrikeTimer <= uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,SPELL_SPINNING_STRIKE);
m_uiSpinningStrikeTimer = 30*IN_MILLISECONDS;
} else m_uiSpinningStrikeTimer -= uiDiff;
if (IsHeroic() && m_uiMistressKissTimer <= uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,SPELL_MISTRESS_KISS);
m_uiMistressKissTimer = 30*IN_MILLISECONDS;
} else m_uiMistressKissTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_jaraxxus()
{
new boss_jaraxxus();
new mob_legion_flame();
new mob_infernal_volcano();
new mob_fel_infernal();
new mob_nether_portal();
new mob_mistress_of_pain();
}
@@ -0,0 +1,906 @@
/* Copyright (C) 2006 - 2010 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: northrend_beasts
SD%Complete: 90%
SDComment: based on /dev/rsa
SDCategory:
EndScriptData */
// Known bugs:
// Gormok - Not implemented as a vehicle
// - Snobold Firebomb
// - Snobolled (creature at back)
// Snakes - miss the 1-hitkill from emerging
// - visual changes between mobile and stationary models seems not to work sometimes
#include "ScriptPCH.h"
#include "trial_of_the_crusader.h"
enum Yells
{
//Gormok
SAY_SNOBOLLED = -1649000,
//Acidmaw & Dreadscale
SAY_SUBMERGE = -1649010,
SAY_EMERGE = -1649011,
SAY_BERSERK = -1649012,
//Icehowl
SAY_TRAMPLE_STARE = -1649020,
SAY_TRAMPLE_FAIL = -1649021,
SAY_TRAMPLE_START = -1649022,
};
enum Equipment
{
EQUIP_MAIN = 50760,
EQUIP_OFFHAND = 48040,
EQUIP_RANGED = 47267,
EQUIP_DONE = EQUIP_NO_CHANGE,
};
enum Model
{
MODEL_ACIDMAW_STATIONARY = 29815,
MODEL_ACIDMAW_MOBILE = 29816,
MODEL_DREADSCALE_STATIONARY = 26935,
MODEL_DREADSCALE_MOBILE = 24564,
};
enum Summons
{
NPC_SNOBOLD_VASSAL = 34800,
NPC_SLIME_POOL = 35176,
};
enum BossSpells
{
//Gormok
SPELL_IMPALE = 66331,
SPELL_STAGGERING_STOMP = 67648,
SPELL_RISING_ANGER = 66636,
//Snobold
SPELL_SNOBOLLED = 66406,
SPELL_BATTER = 66408,
SPELL_FIRE_BOMB = 66313,
SPELL_FIRE_BOMB_1 = 66317,
SPELL_FIRE_BOMB_DOT = 66318,
SPELL_HEAD_CRACK = 66407,
//Acidmaw & Dreadscale
SPELL_ACID_SPIT = 66880,
SPELL_PARALYTIC_SPRAY = 66901,
SPELL_ACID_SPEW = 66819,
SPELL_PARALYTIC_BITE = 66824,
SPELL_SWEEP_0 = 66794,
SUMMON_SLIME_POOL = 66883,
SPELL_FIRE_SPIT = 66796,
SPELL_MOLTEN_SPEW = 66821,
SPELL_BURNING_BITE = 66879,
SPELL_BURNING_SPRAY = 66902,
SPELL_SWEEP_1 = 67646,
SPELL_EMERGE_0 = 66947,
SPELL_SUBMERGE_0 = 53421,
SPELL_ENRAGE = 68335,
SPELL_SLIME_POOL_EFFECT = 66882, //In 60s it diameter grows from 10y to 40y (r=r+0.25 per second)
//Icehowl
SPELL_FEROCIOUS_BUTT = 66770,
SPELL_MASSIVE_CRASH = 66683,
SPELL_WHIRL = 67345,
SPELL_ARCTIC_BREATH = 66689,
SPELL_TRAMPLE = 66734,
SPELL_FROTHING_RAGE = 66759,
SPELL_STAGGERED_DAZE = 66758,
};
␍class boss_gormok : public CreatureScript
{
public:
boss_gormok() : CreatureScript("boss_gormok") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_gormokAI(pCreature);
}
struct boss_gormokAI : public ScriptedAI
{
boss_gormokAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiImpaleTimer;
uint32 m_uiStaggeringStompTimer;
SummonList Summons;
uint32 m_uiSummonTimer;
uint32 m_uiSummonCount;
void Reset()
{
m_uiImpaleTimer = urand(8*IN_MILLISECONDS,10*IN_MILLISECONDS);
m_uiStaggeringStompTimer = 15*IN_MILLISECONDS;
m_uiSummonTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);;
if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL ||
getDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
m_uiSummonCount = 5;
else
m_uiSummonCount = 4;
Summons.DespawnAll();
}
void JustDied(Unit* pKiller)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS,GORMOK_DONE);
}
void JustReachedHome()
{
if (m_pInstance)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS,FAIL);
me->ForcedDespawn();
}
void EnterCombat(Unit* pWho)
{
me->SetInCombatWithZone();
m_pInstance->SetData(TYPE_NORTHREND_BEASTS,GORMOK_IN_PROGRESS);
}
void JustSummoned(Creature* pSummoned)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
switch(pSummoned->GetEntry())
{
case NPC_SNOBOLD_VASSAL:
pSummoned->GetMotionMaster()->MoveJump(pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),10.0f,20.0f);
DoCast(me, SPELL_RISING_ANGER);
--m_uiSummonCount;
break;
}
pSummoned->AI()->AttackStart(pTarget);
Summons.Summon(pSummoned);
}
void SummonedCreatureDespawn(Creature* pSummoned)
{
switch(pSummoned->GetEntry())
{
case NPC_SNOBOLD_VASSAL:
if (pSummoned->isAlive()) ++m_uiSummonCount;
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
if (m_uiImpaleTimer <= uiDiff)
{
DoCast(me->getVictim(),SPELL_IMPALE);
m_uiImpaleTimer = urand(8*IN_MILLISECONDS,10*IN_MILLISECONDS);
} else m_uiImpaleTimer -= uiDiff;
if (m_uiStaggeringStompTimer <= uiDiff)
{
DoCast(me->getVictim(),SPELL_STAGGERING_STOMP);
m_uiStaggeringStompTimer = urand(20*IN_MILLISECONDS,25*IN_MILLISECONDS);
} else m_uiStaggeringStompTimer -= uiDiff;
if (m_uiSummonTimer <= uiDiff)
{
if (m_uiSummonCount > 0)
{
me->SummonCreature(NPC_SNOBOLD_VASSAL,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),0,TEMPSUMMON_CORPSE_DESPAWN);
DoScriptText(SAY_SNOBOLLED,me);
}
m_uiSummonTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiSummonTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
␍class mob_snobold_vassal : public CreatureScript
{
public:
mob_snobold_vassal() : CreatureScript("mob_snobold_vassal") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_snobold_vassalAI(pCreature);
}
struct mob_snobold_vassalAI : public ScriptedAI
{
mob_snobold_vassalAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
if (m_pInstance)
m_pInstance->SetData(DATA_SNOBOLD_COUNT, INCREASE);
}
InstanceScript* m_pInstance;
uint32 m_uiFireBombTimer;
uint32 m_uiBatterTimer;
uint32 m_uiHeadCrackTimer;
uint64 m_uiBossGUID;
uint64 m_uiTargetGUID;
bool m_bTargetDied;
void Reset()
{
m_uiFireBombTimer = 15000;
m_uiBatterTimer = 5000;
m_uiHeadCrackTimer = 25000;
m_uiTargetGUID = 0;
m_bTargetDied = false;
if (m_pInstance)
m_uiBossGUID = m_pInstance->GetData64(NPC_GORMOK);
//Workaround for Snobold
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
}
void EnterCombat(Unit *pWho)
{
m_uiTargetGUID = pWho->GetGUID();
me->TauntApply(pWho);
DoCast(pWho, SPELL_SNOBOLLED);
}
void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
{
if (pDoneBy->GetGUID()==m_uiTargetGUID)
uiDamage = 0;
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if(uiType != POINT_MOTION_TYPE) return;
switch (uiId)
{
case 0: // JUMP!? Fuck! THAT'S BEEZARR! Would someone PLEASE make MotionMaster->Move* work better?
if (m_bTargetDied)
me->ForcedDespawn();
break;
}
}
void JustDied(Unit* pKiller)
{
if (Unit *pTarget = Unit::GetPlayer(*me,m_uiTargetGUID))
if (pTarget->isAlive())
pTarget->RemoveAurasDueToSpell(SPELL_SNOBOLLED);
if (m_pInstance)
m_pInstance->SetData(DATA_SNOBOLD_COUNT, DECREASE);
}
void UpdateAI(const uint32 uiDiff)
{
if (m_bTargetDied || !UpdateVictim())
return;
if (Unit* pTarget = Unit::GetPlayer(*me,m_uiTargetGUID))
if (!pTarget->isAlive())
if (m_pInstance)
if (Unit* pGormok = Unit::GetCreature(*me,m_pInstance->GetData64(NPC_GORMOK)))
{
if (pGormok->isAlive())
{
SetCombatMovement(false);
m_bTargetDied = true;
me->GetMotionMaster()->MoveJump(pGormok->GetPositionX(),pGormok->GetPositionY(),pGormok->GetPositionZ(),15.0f,15.0f);
}
else
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
m_uiTargetGUID = pTarget->GetGUID();
me->GetMotionMaster()->MoveJump(pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),15.0f,15.0f);
}
}
}
if (m_uiFireBombTimer < uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_FIRE_BOMB);
m_uiFireBombTimer = 20000;
}
else m_uiFireBombTimer -= uiDiff;
if (m_uiBatterTimer < uiDiff)
{
if (Unit *pTarget = Unit::GetPlayer(*me,m_uiTargetGUID))
DoCast(pTarget, SPELL_BATTER);
m_uiBatterTimer = 10000;
}
else m_uiBatterTimer -= uiDiff;
if (m_uiHeadCrackTimer < uiDiff)
{
if (Unit *pTarget = Unit::GetPlayer(*me,m_uiTargetGUID))
DoCast(pTarget, SPELL_HEAD_CRACK);
m_uiHeadCrackTimer = 35000;
}
else m_uiHeadCrackTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
};
struct boss_jormungarAI : public ScriptedAI
{
boss_jormungarAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiSisterID;
uint32 m_uiModelStationary;
uint32 m_uiModelMobile;
uint32 m_uiBiteSpell;
uint32 m_uiSpewSpell;
uint32 m_uiSpitSpell;
uint32 m_uiSpraySpell;
uint32 m_uiBiteTimer;
uint32 m_uiSpewTimer;
uint32 m_uiSlimePoolTimer;
uint32 m_uiSpitTimer;
uint32 m_uiSprayTimer;
uint32 m_uiSweepTimer;
uint32 m_uiSubmergeTimer;
uint8 m_uiStage;
bool m_bEnraged;
void Reset()
{
m_bEnraged = false;
m_uiBiteTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
m_uiSpewTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
m_uiSlimePoolTimer = 15*IN_MILLISECONDS;
m_uiSpitTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
m_uiSprayTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
m_uiSweepTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
}
void JustDied(Unit* pKiller)
{
if (m_pInstance)
if (Creature* pSister = Unit::GetCreature((*me),m_pInstance->GetData64(m_uiSisterID)))
if (!pSister->isAlive())
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE);
else
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL);
}
void JustReachedHome()
{
if (m_pInstance && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
me->ForcedDespawn();
}
void KilledUnit(Unit *pWho)
{
if (pWho->GetTypeId() == TYPEID_PLAYER)
{
if (m_pInstance)
m_pInstance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
}
void EnterCombat(Unit* pWho)
{
me->SetInCombatWithZone();
if (m_pInstance)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_IN_PROGRESS);
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim()) return;
if (m_pInstance && m_pInstance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL && !m_bEnraged)
{
DoScriptText(SAY_EMERGE,me);
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
DoCast(SPELL_ENRAGE);
m_bEnraged = true;
DoScriptText(SAY_BERSERK,me);
switch (m_uiStage)
{
case 0: break;
case 4:
m_uiStage = 5;
m_uiSubmergeTimer = 5*IN_MILLISECONDS;
default:
m_uiStage = 7;
}
}
switch (m_uiStage)
{
case 0: // Mobile
if (m_uiBiteTimer <= uiDiff)
{
DoCastVictim(m_uiBiteSpell);
m_uiBiteTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiBiteTimer -= uiDiff;
if (m_uiSpewTimer <= uiDiff)
{
DoCastAOE(m_uiSpewSpell);
m_uiSpewTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiSpewTimer -= uiDiff;
if (m_uiSlimePoolTimer <= uiDiff)
{
/* Spell summon has only 30s duration */
//DoCast(SUMMON_SLIME_POOL);
me->SummonCreature(NPC_SLIME_POOL,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),0);
m_uiSlimePoolTimer = 30*IN_MILLISECONDS;
} else m_uiSlimePoolTimer -= uiDiff;
if (m_uiSubmergeTimer <= uiDiff && !m_bEnraged)
{
m_uiStage = 1;
m_uiSubmergeTimer = 5*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
DoMeleeAttackIfReady();
break;
case 1: // Submerge
me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
DoCast(me,SPELL_SUBMERGE_0);
DoScriptText(SAY_SUBMERGE,me);
me->GetMotionMaster()->MovePoint(0,ToCCommonLoc[1].GetPositionX()+urand(0,80)-40,ToCCommonLoc[1].GetPositionY()+urand(0,80)-40,ToCCommonLoc[1].GetPositionZ());
m_uiStage = 2;
case 2: // Wait til emerge
if (m_uiSubmergeTimer <= uiDiff)
{
m_uiStage = 3;
m_uiSubmergeTimer = 50*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
break;
case 3: // Emerge
me->SetDisplayId(m_uiModelStationary);
DoScriptText(SAY_EMERGE,me);
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
DoCast(me,SPELL_EMERGE_0);
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE);
SetCombatMovement(false);
me->GetMotionMaster()->MoveIdle();
m_uiStage = 4;
break;
case 4: // Stationary
if (m_uiSprayTimer <= uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,m_uiSpraySpell);
m_uiSprayTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiSprayTimer -= uiDiff;
if (m_uiSweepTimer <= uiDiff)
{
DoCastAOE(SPELL_SWEEP_0);
m_uiSweepTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiSweepTimer -= uiDiff;
if (m_uiSubmergeTimer <= uiDiff)
{
m_uiStage = 5;
m_uiSubmergeTimer = 10*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
DoSpellAttackIfReady(m_uiSpitSpell);
break;
case 5: // Submerge
me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
DoCast(me,SPELL_SUBMERGE_0);
DoScriptText(SAY_SUBMERGE,me);
me->GetMotionMaster()->MovePoint(0,ToCCommonLoc[1].GetPositionX()+urand(0,80)-40,ToCCommonLoc[1].GetPositionY()+urand(0,80)-40,ToCCommonLoc[1].GetPositionZ());
m_uiStage = 6;
case 6: // Wait til emerge
if (m_uiSubmergeTimer <= uiDiff)
{
m_uiStage = 7;
m_uiSubmergeTimer = 45*IN_MILLISECONDS;
} else m_uiSubmergeTimer -= uiDiff;
break;
case 7: // Emerge
me->SetDisplayId(m_uiModelMobile);
DoScriptText(SAY_EMERGE,me);
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
DoCast(me,SPELL_EMERGE_0);
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE);
SetCombatMovement(true);
me->GetMotionMaster()->MoveChase(me->getVictim());
m_uiStage = 0;
break;
}
}
};
␍class boss_acidmaw : public CreatureScript
{
public:
boss_acidmaw() : CreatureScript("boss_acidmaw") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_acidmawAI(pCreature);
}
struct boss_acidmawAI : public boss_jormungarAI
{
boss_acidmawAI(Creature* pCreature) : boss_jormungarAI(pCreature) { }
void Reset()
{
boss_jormungarAI::Reset();
m_uiBiteSpell = SPELL_PARALYTIC_BITE;
m_uiSpewSpell = SPELL_ACID_SPEW;
m_uiSpitSpell = SPELL_ACID_SPIT;
m_uiSpraySpell = SPELL_PARALYTIC_SPRAY;
m_uiModelStationary = MODEL_ACIDMAW_STATIONARY;
m_uiModelMobile = MODEL_ACIDMAW_MOBILE;
m_uiSisterID = NPC_DREADSCALE;
m_uiSubmergeTimer = 500;
DoCast(me,SPELL_SUBMERGE_0);
m_uiStage = 2;
}
};
};
␍class boss_dreadscale : public CreatureScript
{
public:
boss_dreadscale() : CreatureScript("boss_dreadscale") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_dreadscaleAI(pCreature);
}
struct boss_dreadscaleAI : public boss_jormungarAI
{
boss_dreadscaleAI(Creature* pCreature) : boss_jormungarAI(pCreature) { }
void Reset()
{
boss_jormungarAI::Reset();
m_uiBiteSpell = SPELL_BURNING_BITE;
m_uiSpewSpell = SPELL_MOLTEN_SPEW;
m_uiSpitSpell = SPELL_FIRE_SPIT;
m_uiSpraySpell = SPELL_BURNING_SPRAY;
m_uiModelStationary = MODEL_DREADSCALE_STATIONARY;
m_uiModelMobile = MODEL_DREADSCALE_MOBILE;
m_uiSisterID = NPC_ACIDMAW;
m_uiSubmergeTimer = 45*IN_MILLISECONDS;
m_uiStage = 0;
}
};
};
␍class mob_slime_pool : public CreatureScript
{
public:
mob_slime_pool() : CreatureScript("mob_slime_pool") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_slime_poolAI(pCreature);
}
struct mob_slime_poolAI : public ScriptedAI
{
mob_slime_poolAI(Creature *pCreature) : ScriptedAI(pCreature)
{
}
bool casted;
void Reset()
{
casted = false;
me->SetReactState(REACT_PASSIVE);
me->ForcedDespawn(60*IN_MILLISECONDS);
}
void UpdateAI(const uint32 uiDiff)
{
if (!casted)
{
casted = true;
DoCast(me,SPELL_SLIME_POOL_EFFECT);
}
}
};
};
␍class boss_icehowl : public CreatureScript
{
public:
boss_icehowl() : CreatureScript("boss_icehowl") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_icehowlAI(pCreature);
}
struct boss_icehowlAI : public ScriptedAI
{
boss_icehowlAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiFerociousButtTimer;
uint32 m_uiArticBreathTimer;
uint32 m_uiWhirlTimer;
uint32 m_uiMassiveCrashTimer;
uint32 m_uiTrampleTimer;
float m_fTrampleTargetX,m_fTrampleTargetY,m_fTrampleTargetZ;
uint64 m_uiTrampleTargetGUID;
bool m_bMovementStarted;
bool m_bMovementFinish;
bool m_bTrampleCasted;
uint8 m_uiStage;
Unit* pTarget;
void Reset()
{
m_uiFerociousButtTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
m_uiArticBreathTimer = urand(25*IN_MILLISECONDS,40*IN_MILLISECONDS);
m_uiWhirlTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
m_uiMassiveCrashTimer = 30*IN_MILLISECONDS;
m_uiTrampleTimer = IN_MILLISECONDS;
m_bMovementStarted = false;
m_bMovementFinish = false;
m_bTrampleCasted = false;
m_uiTrampleTargetGUID = 0;
m_fTrampleTargetX = 0;
m_fTrampleTargetY = 0;
m_fTrampleTargetZ = 0;
m_uiStage = 0;
}
void JustDied(Unit* pKiller)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_DONE);
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if(uiType != POINT_MOTION_TYPE) return;
switch (uiId)
{
case 0: // JUMP!? Fuck! THAT'S BEEZARR! Would someone PLEASE make MotionMaster->Move* work better?
if (me->GetDistance2d(ToCCommonLoc[1].GetPositionX(),ToCCommonLoc[1].GetPositionY()) < 6.0f)
{
// Middle of the room
m_uiStage = 1;
}
else
{
// Landed from Hop backwards (start trample)
if(Unit* pTarget = Unit::GetPlayer(*me,m_uiTrampleTargetGUID))
{
m_uiStage = 4;
} else m_uiStage = 6;
}
break;
case 1: // Finish trample
m_bMovementFinish = true;
break;
}
}
void JustReachedHome()
{
if (m_pInstance)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
me->ForcedDespawn();
}
void KilledUnit(Unit *pWho)
{
if (pWho->GetTypeId() == TYPEID_PLAYER)
{
if (m_pInstance)
m_pInstance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
}
void EnterCombat(Unit* pWho)
{
if (m_pInstance)
m_pInstance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_IN_PROGRESS);
me->SetInCombatWithZone();
}
void SpellHitTarget(Unit* target, const SpellEntry* spell)
{
if(spell->Id == SPELL_TRAMPLE && target->GetTypeId() == TYPEID_PLAYER)
{
if (!m_bTrampleCasted)
{
DoCast(me, SPELL_FROTHING_RAGE, true);
m_bTrampleCasted = true;
}
}
}
void UpdateAI(const uint32 uiDiff)
{
if (!UpdateVictim())
return;
switch (m_uiStage)
{
case 0:
if (m_uiFerociousButtTimer <= uiDiff)
{
DoCastVictim(SPELL_FEROCIOUS_BUTT);
m_uiFerociousButtTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiFerociousButtTimer -= uiDiff;
if (m_uiArticBreathTimer <= uiDiff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(pTarget,SPELL_ARCTIC_BREATH);
m_uiArticBreathTimer = urand(25*IN_MILLISECONDS,40*IN_MILLISECONDS);
} else m_uiArticBreathTimer -= uiDiff;
if (m_uiWhirlTimer <= uiDiff)
{
DoCastAOE(SPELL_WHIRL);
m_uiWhirlTimer = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
} else m_uiWhirlTimer -= uiDiff;
if (m_uiMassiveCrashTimer <= uiDiff)
{
me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(),ToCCommonLoc[1].GetPositionY(),ToCCommonLoc[1].GetPositionZ(),10.0f,20.0f); // 1: Middle of the room
m_uiStage = 7; //Invalid (Do nothing more than move)
m_uiMassiveCrashTimer = 30*IN_MILLISECONDS;
} else m_uiMassiveCrashTimer -= uiDiff;
DoMeleeAttackIfReady();
break;
case 1:
DoCastAOE(SPELL_MASSIVE_CRASH);
m_uiStage = 2;
break;
case 2:
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
{
m_uiTrampleTargetGUID = pTarget->GetGUID();
me->SetUInt64Value(UNIT_FIELD_TARGET, m_uiTrampleTargetGUID);
DoScriptText(SAY_TRAMPLE_STARE,me,pTarget);
m_bTrampleCasted = false;
SetCombatMovement(false);
me->GetMotionMaster()->MoveIdle();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_uiTrampleTimer = 4*IN_MILLISECONDS;
m_uiStage = 3;
} else m_uiStage = 6;
break;
case 3:
if (m_uiTrampleTimer <= uiDiff)
{
if(Unit* pTarget = Unit::GetPlayer(*me,m_uiTrampleTargetGUID))
{
m_bTrampleCasted = false;
m_bMovementStarted = true;
m_fTrampleTargetX = pTarget->GetPositionX();
m_fTrampleTargetY = pTarget->GetPositionY();
m_fTrampleTargetZ = pTarget->GetPositionZ();
me->GetMotionMaster()->MoveJump(2*me->GetPositionX()-m_fTrampleTargetX,
2*me->GetPositionY()-m_fTrampleTargetY,
me->GetPositionZ(),
10.0f,20.0f); // 2: Hop Backwards
m_uiStage = 7; //Invalid (Do nothing more than move)
} else m_uiStage = 6;
} else m_uiTrampleTimer -= uiDiff;
break;
case 4:
DoScriptText(SAY_TRAMPLE_START,me);
me->GetMotionMaster()->MoveCharge(m_fTrampleTargetX,m_fTrampleTargetY,m_fTrampleTargetZ+2, 42, 1);
me->SetUInt64Value(UNIT_FIELD_TARGET, 0);
m_uiStage = 5;
break;
case 5:
if (m_bMovementFinish)
{
if (m_uiTrampleTimer <= uiDiff) DoCastAOE(SPELL_TRAMPLE);
m_bMovementFinish = false;
m_uiStage = 6;
return;
}
if (m_uiTrampleTimer <= uiDiff)
{
Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers();
for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
{
if (Unit* pPlayer = itr->getSource())
if (pPlayer->isAlive() && pPlayer->IsWithinDistInMap(me, 6.0f))
{
DoCastAOE(SPELL_TRAMPLE);
m_uiTrampleTimer = IN_MILLISECONDS;
break;
}
}
} else m_uiTrampleTimer -= uiDiff;
break;
case 6:
if (!m_bTrampleCasted)
{
DoCast(me,SPELL_STAGGERED_DAZE);
DoScriptText(SAY_TRAMPLE_FAIL,me);
}
m_bMovementStarted = false;
me->GetMotionMaster()->MovementExpired();
me->GetMotionMaster()->MoveChase(me->getVictim());
SetCombatMovement(true);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_uiStage = 0;
break;
}
}
};
};
void AddSC_boss_northrend_beasts()
{
new boss_gormok();
new mob_snobold_vassal();
new boss_acidmaw();
new boss_dreadscale();
new mob_slime_pool();
new boss_icehowl();
}
@@ -0,0 +1,669 @@
/* Copyright (C) 2006 - 2010 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: trial_of_the_crusader
SD%Complete: ??%
SDComment: based on /dev/rsa
SDCategory: Crusader Coliseum
EndScriptData */
// Known bugs:
// - They should be floating but they aren't respecting the floor =(
// - Lacks the powering up effect that leads to Empowering
// - There's a workaround for the shared life effect
#include "ScriptPCH.h"
#include "trial_of_the_crusader.h"
enum Yells
{
SAY_AGGRO = -1649040,
SAY_DEATH = -1649041,
SAY_BERSERK = -1649042,
EMOTE_SHIELD = -1649043,
SAY_SHIELD = -1649044,
SAY_KILL1 = -1649045,
SAY_KILL2 = -1649046,
EMOTE_LIGHT_VORTEX = -1649047,
SAY_LIGHT_VORTEX = -1649048,
EMOTE_DARK_VORTEX = -1649049,
SAY_DARK_VORTEX = -1649050,
};
enum Equipment
{
EQUIP_MAIN_1 = 49303,
EQUIP_OFFHAND_1 = 47146,
EQUIP_RANGED_1 = 47267,
EQUIP_MAIN_2 = 45990,
EQUIP_OFFHAND_2 = 47470,
EQUIP_RANGED_2 = 47267,
EQUIP_DONE = EQUIP_NO_CHANGE,
};
enum Summons
{
NPC_DARK_ESSENCE = 34567,
NPC_LIGHT_ESSENCE = 34568,
NPC_UNLEASHED_DARK = 34628,
NPC_UNLEASHED_LIGHT = 34630,
};
enum BossSpells
{
SPELL_LIGHT_TWIN_SPIKE = 66075,
SPELL_LIGHT_SURGE = 65766,
SPELL_LIGHT_SHIELD = 65858,
SPELL_LIGHT_TWIN_PACT = 65876,
SPELL_LIGHT_VORTEX = 66046,
SPELL_LIGHT_TOUCH = 67297,
SPELL_DARK_TWIN_SPIKE = 66069,
SPELL_DARK_SURGE = 65768,
SPELL_DARK_SHIELD = 65874,
SPELL_DARK_TWIN_PACT = 65875,
SPELL_DARK_VORTEX = 66058,
SPELL_DARK_TOUCH = 67282,
SPELL_TWIN_POWER = 65916,
SPELL_LIGHT_ESSENCE = 65686,
SPELL_DARK_ESSENCE = 65684,
SPELL_BERSERK = 64238,
SPELL_NONE = 0,
SPELL_EMPOWERED_DARK = 67215,
SPELL_EMPOWERED_LIGHT = 67218,
SPELL_UNLEASHED_DARK = 65808,
SPELL_UNLEASHED_LIGHT = 65795,
//PowerUp 67604
};
enum Actions
{
ACTION_VORTEX,
ACTION_PACT
};
/*######
## boss_twin_base
######*/
struct boss_twin_baseAI : public ScriptedAI
{
boss_twin_baseAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
SummonList Summons;
uint8 m_uiStage;
bool m_bIsBerserk;
uint8 m_uiWaveCount;
uint32 m_uiColorballsTimer;
uint32 m_uiSpecialAbilityTimer;
uint32 m_uiSpikeTimer;
uint32 m_uiTouchTimer;
uint32 m_uiBerserkTimer;
uint32 m_uiVortexSay;
uint32 m_uiVortexEmote;
uint32 m_uiSisterNpcId;
uint32 m_uiColorballNpcId;
uint32 m_uiEssenceNpcId;
uint32 m_uiMyEssenceSpellId;
uint32 m_uiOtherEssenceSpellId;
uint32 m_uiEmpoweredWeaknessSpellId;
uint32 m_uiSurgeSpellId;
uint32 m_uiVortexSpellId;
uint32 m_uiShieldSpellId;
uint32 m_uiTwinPactSpellId;
uint32 m_uiSpikeSpellId;
uint32 m_uiTouchSpellId;
Position HomeLocation;
Position EssenceLocation[2];
void Reset() {
me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
/* Uncomment this once that they are flying above the ground
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SetFlying(true); */
m_bIsBerserk = false;
m_uiWaveCount = 1;
m_uiColorballsTimer = 15*IN_MILLISECONDS;
m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS;
m_uiSpikeTimer = 20*IN_MILLISECONDS;
m_uiTouchTimer = urand(10,15)*IN_MILLISECONDS;
m_uiBerserkTimer = IsHeroic() ? 6*MINUTE*IN_MILLISECONDS : 10*MINUTE*IN_MILLISECONDS;
Summons.DespawnAll();
}
void JustReachedHome()
{
if (m_pInstance)
{
m_pInstance->SetData(TYPE_VALKIRIES, FAIL);
m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetMaxHealth());
}
me->ForcedDespawn();
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if(uiType != POINT_MOTION_TYPE) return;
switch (uiId)
{
case 0:
me->GetMotionMaster()->MovePoint(1, HomeLocation.GetPositionX(), HomeLocation.GetPositionY(), HomeLocation.GetPositionZ());
me->SetHomePosition(HomeLocation);
break;
case 1:
me->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_AGGRESSIVE);
me->SetInCombatWithZone();
break;
}
}
void KilledUnit(Unit* pWho)
{
if (pWho->GetTypeId() == TYPEID_PLAYER)
{
DoScriptText(urand(0,1) ? SAY_KILL1 : SAY_KILL2,me);
if (m_pInstance)
m_pInstance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
}
void JustSummoned(Creature* pSummoned)
{
switch(pSummoned->GetEntry())
{
case NPC_UNLEASHED_DARK:
case NPC_UNLEASHED_LIGHT:
pSummoned->SetCorpseDelay(0);
break;
}
Summons.Summon(pSummoned);
}
void SummonedCreatureDespawn(Creature* pSummoned)
{
switch(pSummoned->GetEntry())
{
case NPC_LIGHT_ESSENCE:
case NPC_DARK_ESSENCE:
Map* pMap = me->GetMap();
Map::PlayerList const &lPlayers = pMap->GetPlayers();
for(Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
{
Unit* pPlayer = itr->getSource();
if (!pPlayer) continue;
if (pPlayer->isAlive())
if (pSummoned->GetEntry() == NPC_LIGHT_ESSENCE)
pPlayer->RemoveAurasDueToSpell(SPELL_LIGHT_ESSENCE);
if (pSummoned->GetEntry() == NPC_DARK_ESSENCE)
pPlayer->RemoveAurasDueToSpell(SPELL_DARK_ESSENCE);
}
break;
}
Summons.Despawn(pSummoned);
}
void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
{
if (!me || !me->isAlive())
return;
if (pDoneBy->GetGUID() == me->GetGUID())
return;
if (pDoneBy->GetTypeId() == TYPEID_PLAYER)
{
if(pDoneBy->HasAura(m_uiOtherEssenceSpellId))
uiDamage += uiDamage/2;
if(pDoneBy->HasAura(m_uiEmpoweredWeaknessSpellId))
uiDamage += uiDamage;
else
if(pDoneBy->HasAura(m_uiMyEssenceSpellId))
uiDamage /= 2;
}
if (m_pInstance)
m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetHealth() >= uiDamage ? me->GetHealth() - uiDamage : 0);
}
void SpellHit(Unit* caster, const SpellEntry* spell)
{
if (caster->ToCreature() == me)
if (spell->Effect[0] == 136) //Effect Heal
if (m_pInstance)
m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetHealth() + me->GetMaxHealth()*spell->EffectBasePoints[0]/100);
}
void SummonColorballs(uint8 quantity)
{
float x0 = ToCCommonLoc[1].GetPositionX(), y0 = ToCCommonLoc[1].GetPositionY(), r = 47.0f;
float y = y0;
for (uint8 i = 0; i < quantity; i++)
{
float x = urand(x0-r,x0+r);
if (urand(0,1))
y = y0 + sqrt(pow(r,2) - pow((x-x0),2));
else
y = y0 - sqrt(pow(r,2) - pow((x-x0),2));
me->SummonCreature(m_uiColorballNpcId,x,y,me->GetPositionZ(),TEMPSUMMON_CORPSE_DESPAWN);
}
}
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_DEATH,me);
if (m_pInstance)
{
m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, 0);
if (Creature* pSister = GetSister())
if (!pSister->isAlive())
{
m_pInstance->SetData(TYPE_VALKIRIES, DONE);
Summons.DespawnAll();
}
else m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL);
}
Summons.DespawnAll();
}
// Called when sister pointer needed
Creature* GetSister()
{
return Unit::GetCreature((*me),m_pInstance->GetData64(m_uiSisterNpcId));
}
void EnterCombat(Unit* pWho)
{
me->SetInCombatWithZone();
if (m_pInstance)
{
m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS);
m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetMaxHealth());
}
if (me->isAlive())
{
me->SummonCreature(m_uiEssenceNpcId, EssenceLocation[0].GetPositionX(), EssenceLocation[0].GetPositionY(), EssenceLocation[0].GetPositionZ());
me->SummonCreature(m_uiEssenceNpcId, EssenceLocation[1].GetPositionX(), EssenceLocation[1].GetPositionY(), EssenceLocation[1].GetPositionZ());
}
DoScriptText(SAY_AGGRO,me);
DoCast(me,m_uiSurgeSpellId);
}
void DoAction(const int32 action)
{
switch(action)
{
case ACTION_VORTEX:
m_uiStage = me->GetEntry() == NPC_LIGHTBANE ? 2 : 1;
break;
case ACTION_PACT:
m_uiStage = me->GetEntry() == NPC_LIGHTBANE ? 1 : 2;
DoCast(me,SPELL_TWIN_POWER);
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
if (!m_pInstance || !UpdateVictim())
return;
if (m_pInstance->GetData(DATA_HEALTH_TWIN_SHARED) != 0)
me->SetHealth(m_pInstance->GetData(DATA_HEALTH_TWIN_SHARED));
else
me->SetHealth(1);
switch (m_uiStage)
{
case 0:
break;
case 1: // Vortex
if (m_uiSpecialAbilityTimer <= uiDiff)
{
if (Creature* pSister = GetSister())
pSister->AI()->DoAction(ACTION_VORTEX);
DoScriptText(m_uiVortexEmote,me);
DoScriptText(m_uiVortexSay,me);
DoCastAOE(m_uiVortexSpellId);
m_uiStage = 0;
m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS;
} else m_uiSpecialAbilityTimer -= uiDiff;
break;
case 2: // Shield+Pact
if (m_uiSpecialAbilityTimer <= uiDiff)
{
if (Creature* pSister = GetSister())
pSister->AI()->DoAction(ACTION_PACT);
DoScriptText(EMOTE_SHIELD,me);
DoScriptText(SAY_SHIELD,me);
DoCast(me,m_uiShieldSpellId);
DoCast(me,m_uiTwinPactSpellId);
m_uiStage = 0;
m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS;
} m_uiSpecialAbilityTimer -= uiDiff;
break;
default:
break;
}
if (m_uiSpikeTimer <= uiDiff)
{
DoCastVictim(m_uiSpikeSpellId);
m_uiSpikeTimer = 20*IN_MILLISECONDS;
} m_uiSpikeTimer -= uiDiff;
if (IsHeroic() && m_uiTouchTimer <= uiDiff)
{
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0,200,true,m_uiOtherEssenceSpellId))
DoCast(pTarget,m_uiTouchSpellId);
m_uiTouchTimer = urand(10,15)*IN_MILLISECONDS;
} m_uiTouchTimer -= uiDiff;
if (m_uiColorballsTimer <= uiDiff)
{
if (m_uiWaveCount >= 2)
{
SummonColorballs(12);
m_uiWaveCount = 0;
}
else
{
SummonColorballs(2);
m_uiWaveCount++;
}
m_uiColorballsTimer = 15*IN_MILLISECONDS;
} else m_uiColorballsTimer -= uiDiff;
if (!m_bIsBerserk && m_uiBerserkTimer <= uiDiff)
{
DoCast(me,SPELL_BERSERK);
DoScriptText(SAY_BERSERK,me);
m_bIsBerserk = true;
} else m_uiBerserkTimer -= uiDiff;
DoMeleeAttackIfReady();
}
};
/*######
## boss_fjola
######*/
␍class boss_fjola : public CreatureScript
{
public:
boss_fjola() : CreatureScript("boss_fjola") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_fjolaAI(pCreature);
}
struct boss_fjolaAI : public boss_twin_baseAI
{
boss_fjolaAI(Creature* pCreature) : boss_twin_baseAI(pCreature) {}
void Reset() {
boss_twin_baseAI::Reset();
SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_OFFHAND_1, EQUIP_RANGED_1);
m_uiStage = 0;
m_uiVortexEmote = EMOTE_LIGHT_VORTEX;
m_uiVortexSay = SAY_LIGHT_VORTEX;
m_uiSisterNpcId = NPC_DARKBANE;
m_uiColorballNpcId = NPC_UNLEASHED_LIGHT;
m_uiEssenceNpcId = NPC_LIGHT_ESSENCE;
m_uiMyEssenceSpellId = SPELL_LIGHT_ESSENCE;
m_uiOtherEssenceSpellId = SPELL_DARK_ESSENCE;
m_uiEmpoweredWeaknessSpellId = SPELL_EMPOWERED_DARK;
m_uiSurgeSpellId = SPELL_LIGHT_SURGE;
m_uiVortexSpellId = SPELL_LIGHT_VORTEX;
m_uiShieldSpellId = SPELL_LIGHT_SHIELD;
m_uiTwinPactSpellId = SPELL_LIGHT_TWIN_PACT;
m_uiTouchSpellId = SPELL_LIGHT_TOUCH;
m_uiSpikeSpellId = SPELL_LIGHT_TWIN_SPIKE;
HomeLocation = ToCCommonLoc[8];
EssenceLocation[0] = TwinValkyrsLoc[2];
EssenceLocation[1] = TwinValkyrsLoc[3];
if (m_pInstance)
{
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
}
}
void EnterCombat(Unit* pWho)
{
boss_twin_baseAI::EnterCombat(pWho);
if (m_pInstance)
{
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
}
}
};
};
/*######
## boss_eydis
######*/
␍class boss_eydis : public CreatureScript
{
public:
boss_eydis() : CreatureScript("boss_eydis") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_eydisAI(pCreature);
}
struct boss_eydisAI : public boss_twin_baseAI
{
boss_eydisAI(Creature* pCreature) : boss_twin_baseAI(pCreature) {}
void Reset() {
boss_twin_baseAI::Reset();
SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_OFFHAND_2, EQUIP_RANGED_2);
m_uiStage = 1;
m_uiVortexEmote = EMOTE_DARK_VORTEX;
m_uiVortexSay = SAY_DARK_VORTEX;
m_uiSisterNpcId = NPC_LIGHTBANE;
m_uiColorballNpcId = NPC_UNLEASHED_DARK;
m_uiEssenceNpcId = NPC_DARK_ESSENCE;
m_uiMyEssenceSpellId = SPELL_DARK_ESSENCE;
m_uiOtherEssenceSpellId = SPELL_LIGHT_ESSENCE;
m_uiEmpoweredWeaknessSpellId = SPELL_EMPOWERED_LIGHT;
m_uiSurgeSpellId = SPELL_DARK_SURGE;
m_uiVortexSpellId = SPELL_DARK_VORTEX;
m_uiShieldSpellId = SPELL_DARK_SHIELD;
m_uiTwinPactSpellId = SPELL_DARK_TWIN_PACT;
m_uiTouchSpellId = SPELL_DARK_TOUCH;
m_uiSpikeSpellId = SPELL_DARK_TWIN_SPIKE;
HomeLocation = ToCCommonLoc[9];
EssenceLocation[0] = TwinValkyrsLoc[0];
EssenceLocation[1] = TwinValkyrsLoc[1];
}
};
};
␍class mob_essence_of_twin : public CreatureScript
{
public:
mob_essence_of_twin() : CreatureScript("mob_essence_of_twin") { }
bool OnGossipHello(Player* pPlayer, Creature* pCreature)
{
switch(pCreature->GetEntry())
{
case NPC_LIGHT_ESSENCE:
if (pPlayer || pPlayer->HasAura(SPELL_DARK_ESSENCE))
pPlayer->RemoveAura(SPELL_DARK_ESSENCE);
pPlayer->CastSpell(pPlayer,SPELL_LIGHT_ESSENCE,true);
break;
case NPC_DARK_ESSENCE:
if (pPlayer || pPlayer->HasAura(SPELL_LIGHT_ESSENCE))
pPlayer->RemoveAura(SPELL_LIGHT_ESSENCE);
pPlayer->CastSpell(pPlayer,SPELL_DARK_ESSENCE,true);
break;
}
pPlayer->CLOSE_GOSSIP_MENU();
return true;
}
};
struct mob_unleashed_ballAI : public ScriptedAI
{
mob_unleashed_ballAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiRangeCheckTimer;
void MoveToNextPoint()
{
float x0 = ToCCommonLoc[1].GetPositionX(), y0 = ToCCommonLoc[1].GetPositionY(), r = 47.0f;
float y = y0;
float x = urand(x0-r,x0+r);
if (urand(0,1))
y = y0 + sqrt(pow(r,2) - pow((x-x0),2));
else
y = y0 - sqrt(pow(r,2) - pow((x-x0),2));
me->GetMotionMaster()->MovePoint(0,x,y,me->GetPositionZ());
}
void Reset()
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SetFlying(true);
SetCombatMovement(false);
MoveToNextPoint();
m_uiRangeCheckTimer = IN_MILLISECONDS;
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if(uiType != POINT_MOTION_TYPE) return;
switch (uiId)
{
case 0:
if (urand(0,3) == 0)
MoveToNextPoint();
else
me->DisappearAndDie();
break;
}
}
};
␍class mob_unleashed_dark : public CreatureScript
{
public:
mob_unleashed_dark() : CreatureScript("mob_unleashed_dark") { }
CreatureAI* GetAI(Creature *pCreature) const
{
return new mob_unleashed_darkAI(pCreature);
}
struct mob_unleashed_darkAI : public mob_unleashed_ballAI
{
mob_unleashed_darkAI(Creature *pCreature) : mob_unleashed_ballAI(pCreature) {}
void UpdateAI(const uint32 uiDiff)
{
if (m_uiRangeCheckTimer < uiDiff)
{
if (Unit *pTarget = me->SelectNearestTarget(2.0f))
if (pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive())
{
DoCastAOE(SPELL_UNLEASHED_DARK);
me->GetMotionMaster()->MoveIdle();
me->ForcedDespawn(500);
}
m_uiRangeCheckTimer = IN_MILLISECONDS;
}
else m_uiRangeCheckTimer -= uiDiff;
}
};
};
␍class mob_unleashed_light : public CreatureScript
{
public:
mob_unleashed_light() : CreatureScript("mob_unleashed_light") { }
CreatureAI* GetAI(Creature *pCreature) const
{
return new mob_unleashed_lightAI(pCreature);
}
struct mob_unleashed_lightAI : public mob_unleashed_ballAI
{
mob_unleashed_lightAI(Creature *pCreature) : mob_unleashed_ballAI(pCreature) {}
void UpdateAI(const uint32 uiDiff)
{
if (m_uiRangeCheckTimer < uiDiff)
{
if (Unit *pTarget = me->SelectNearestTarget(2.0f))
if (pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive())
{
DoCastAOE(SPELL_UNLEASHED_LIGHT);
me->GetMotionMaster()->MoveIdle();
me->ForcedDespawn(500);
}
m_uiRangeCheckTimer = IN_MILLISECONDS;
}
else m_uiRangeCheckTimer -= uiDiff;
}
};
};
void AddSC_boss_twin_valkyr()
{
new boss_fjola();
new boss_eydis();
new mob_unleashed_light();
new mob_unleashed_dark();
new mob_essence_of_twin();
}
@@ -0,0 +1,629 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: instance_trial_of_the_crusader
SD%Complete: 80%
SDComment: by /dev/rsa
SDCategory: Trial of the Crusader
EndScriptData */
#include "ScriptPCH.h"
#include "trial_of_the_crusader.h"
␍class instance_trial_of_the_crusader : public InstanceMapScript
{
public:
instance_trial_of_the_crusader() : InstanceMapScript("instance_trial_of_the_crusader", 649) { }
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
{
return new instance_trial_of_the_crusader_InstanceMapScript(pMap);
}
struct instance_trial_of_the_crusader_InstanceMapScript : public InstanceScript
{
instance_trial_of_the_crusader_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {Initialize();};
uint32 m_auiEncounter[MAX_ENCOUNTERS];
uint32 m_uiTrialCounter;
uint32 m_uiEvent;
uint32 m_uiEventTimer;
uint32 m_uiEventNPCId;
uint32 m_uiNorthrendBeasts;
std::string m_strInstData;
bool m_bNeedSave;
uint32 m_uiDataDamageTwin;
uint32 m_uiFjolaCasting;
uint32 m_uiEydisCasting;
uint64 m_uiBarrentGUID;
uint64 m_uiTirionGUID;
uint64 m_uiFizzlebangGUID;
uint64 m_uiGarroshGUID;
uint64 m_uiVarianGUID;
uint64 m_uiGormokGUID;
uint64 m_uiAcidmawGUID;
uint64 m_uiDreadscaleGUID;
uint64 m_uiIcehowlGUID;
uint64 m_uiJaraxxusGUID;
uint64 m_uiChampionsControllerGUID;
uint64 m_uiDarkbaneGUID;
uint64 m_uiLightbaneGUID;
uint64 m_uiAnubarakGUID;
uint64 m_uiCrusadersCacheGUID;
uint64 m_uiFloorGUID;
uint64 m_uiTributeChestGUID;
uint64 m_uiMainGateDoorGUID;
uint64 m_uiEastPortcullisGUID;
uint64 m_uiWebDoorGUID;
// Achievement stuff
uint32 m_uiNotOneButTwoJormungarsTimer;
uint32 m_uiResilienceWillFixItTimer;
uint8 m_uiSnoboldCount;
uint8 m_uiMistressOfPainCount;
bool m_bTributeToImmortalityElegible;
std::list<uint32> m_vScarabTimeOfDeath;
void Initialize()
{
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
m_auiEncounter[i] = NOT_STARTED;
m_uiTrialCounter = 50;
m_uiEvent = 0;
m_uiTributeChestGUID = 0;
m_uiDataDamageTwin = 0;
m_uiMainGateDoorGUID = 0;
m_uiEastPortcullisGUID = 0;
m_uiWebDoorGUID = 0;
m_uiNorthrendBeasts = NOT_STARTED;
m_uiEventTimer = 1000;
m_uiNotOneButTwoJormungarsTimer = 0;
m_uiResilienceWillFixItTimer = 0;
m_uiSnoboldCount = 0;
m_uiMistressOfPainCount = 0;
m_bTributeToImmortalityElegible = true;
m_bNeedSave = false;
}
bool IsEncounterInProgress() const
{
for(uint8 i = 0; i < MAX_ENCOUNTERS ; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
return true;
return false;
}
void OnPlayerEnter(Player *m_player)
{
if (instance->IsHeroic())
{
m_player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW,1);
m_player->SendUpdateWorldState(UPDATE_STATE_UI_COUNT, GetData(TYPE_COUNTER));
}
}
bool IsRaidWiped()
{
Map::PlayerList const &players = instance->GetPlayers();
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
if(Player* pPlayer = i->getSource())
{
if(pPlayer->isAlive())
return false;
}
}
return true;
}
void OpenDoor(uint64 guid)
{
if(!guid) return;
GameObject* pGo = instance->GetGameObject(guid);
if(pGo) pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
void CloseDoor(uint64 guid)
{
if(!guid) return;
GameObject* pGo = instance->GetGameObject(guid);
if(pGo) pGo->SetGoState(GO_STATE_READY);
}
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
{
switch(pCreature->GetEntry())
{
case NPC_BARRENT: m_uiBarrentGUID = pCreature->GetGUID(); break;
case NPC_TIRION: m_uiTirionGUID = pCreature->GetGUID(); break;
case NPC_FIZZLEBANG: m_uiFizzlebangGUID = pCreature->GetGUID(); break;
case NPC_GARROSH: m_uiGarroshGUID = pCreature->GetGUID(); break;
case NPC_VARIAN: m_uiVarianGUID = pCreature->GetGUID(); break;
case NPC_GORMOK: m_uiGormokGUID = pCreature->GetGUID(); break;
case NPC_ACIDMAW: m_uiAcidmawGUID = pCreature->GetGUID(); break;
case NPC_DREADSCALE: m_uiDreadscaleGUID = pCreature->GetGUID(); break;
case NPC_ICEHOWL: m_uiIcehowlGUID = pCreature->GetGUID(); break;
case NPC_JARAXXUS: m_uiJaraxxusGUID = pCreature->GetGUID(); break;
case NPC_CHAMPIONS_CONTROLLER: m_uiChampionsControllerGUID = pCreature->GetGUID(); break;
case NPC_DARKBANE: m_uiDarkbaneGUID = pCreature->GetGUID(); break;
case NPC_LIGHTBANE: m_uiLightbaneGUID = pCreature->GetGUID(); break;
case NPC_ANUBARAK: m_uiAnubarakGUID = pCreature->GetGUID(); break;
}
}
void OnGameObjectCreate(GameObject* pGO, bool bAdd)
{
switch(pGO->GetEntry())
{
case GO_CRUSADERS_CACHE_10:
if(instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL)
m_uiCrusadersCacheGUID = pGO->GetGUID();
break;
case GO_CRUSADERS_CACHE_25:
if(instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL)
m_uiCrusadersCacheGUID = pGO->GetGUID();
break;
case GO_CRUSADERS_CACHE_10_H:
if(instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
m_uiCrusadersCacheGUID = pGO->GetGUID();
break;
case GO_CRUSADERS_CACHE_25_H:
if(instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
m_uiCrusadersCacheGUID = pGO->GetGUID();
break;
case GO_ARGENT_COLISEUM_FLOOR: m_uiFloorGUID = pGO->GetGUID(); break;
case GO_MAIN_GATE_DOOR: m_uiMainGateDoorGUID = pGO->GetGUID(); break;
case GO_EAST_PORTCULLIS: m_uiEastPortcullisGUID = pGO->GetGUID(); break;
case GO_WEB_DOOR: m_uiWebDoorGUID = pGO->GetGUID(); break;
case GO_TRIBUTE_CHEST_10H_25:
case GO_TRIBUTE_CHEST_10H_45:
case GO_TRIBUTE_CHEST_10H_50:
case GO_TRIBUTE_CHEST_10H_99:
case GO_TRIBUTE_CHEST_25H_25:
case GO_TRIBUTE_CHEST_25H_45:
case GO_TRIBUTE_CHEST_25H_50:
case GO_TRIBUTE_CHEST_25H_99:
m_uiTributeChestGUID = pGO->GetGUID(); break;
}
}
void SetData(uint32 uiType, uint32 uiData)
{
switch(uiType)
{
case TYPE_JARAXXUS:
if (uiData == DONE) m_uiEvent = 2000;
break;
case TYPE_CRUSADERS:
switch (uiData)
{
case IN_PROGRESS: m_uiResilienceWillFixItTimer = 0; break;
case SPECIAL: //Means the first blood
m_uiResilienceWillFixItTimer = 60*IN_MILLISECONDS;
uiData = IN_PROGRESS;
break;
case DONE:
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DEFEAT_FACTION_CHAMPIONS);
if (m_uiResilienceWillFixItTimer > 0)
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS_KILLED_IN_MINUTE);
if (GameObject* pChest = instance->GetGameObject(m_uiCrusadersCacheGUID))
if (pChest && !pChest->isSpawned())
pChest->SetRespawnTime(7*DAY);
m_uiEvent = 3100;
break;
}
break;
case TYPE_VALKIRIES:
switch (uiData)
{
case FAIL:
if (m_auiEncounter[TYPE_VALKIRIES] == NOT_STARTED) uiData = NOT_STARTED;
break;
case SPECIAL:
if (m_auiEncounter[TYPE_VALKIRIES] == SPECIAL) uiData = DONE;
break;
case DONE:
if (instance->GetPlayers().getFirst()->getSource()->GetTeam() == ALLIANCE)
m_uiEvent = 4020;
else
m_uiEvent = 4030;
break;
}
break;
case TYPE_ANUBARAK:
switch (uiData)
{
case DONE:
m_uiEvent = 6000;
break;
case SPECIAL:
uint32 tributeChest = 0;
if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
{
if (m_uiTrialCounter >= 50)
tributeChest = GO_TRIBUTE_CHEST_10H_99;
else
if (m_uiTrialCounter >= 45)
tributeChest = GO_TRIBUTE_CHEST_10H_50;
else
if (m_uiTrialCounter >= 25)
tributeChest = GO_TRIBUTE_CHEST_10H_45;
else
tributeChest = GO_TRIBUTE_CHEST_10H_25;
}
else if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
{
if (m_uiTrialCounter >= 50)
tributeChest = GO_TRIBUTE_CHEST_25H_99;
else
if (m_uiTrialCounter >= 45)
tributeChest = GO_TRIBUTE_CHEST_25H_50;
else
if (m_uiTrialCounter >= 25)
tributeChest = GO_TRIBUTE_CHEST_25H_45;
else
tributeChest = GO_TRIBUTE_CHEST_25H_25;
}
if (tributeChest)
if (Creature* pTirion = instance->GetCreature(m_uiTirionGUID))
if (GameObject* pChest = pTirion->SummonGameObject(tributeChest,805.62,134.87,142.16,3.27,0,0,0,0,90000000))
pChest->SetRespawnTime(pChest->GetRespawnDelay());
break;
}
break;
case TYPE_COUNTER: m_uiTrialCounter = uiData; uiData = DONE; break;
case TYPE_EVENT: m_uiEvent = uiData; uiData = NOT_STARTED; break;
case TYPE_EVENT_TIMER: m_uiEventTimer = uiData; uiData = NOT_STARTED; break;
case TYPE_NORTHREND_BEASTS:
m_uiNorthrendBeasts = uiData;
switch (uiData)
{
case GORMOK_DONE:
m_uiEvent = 200;
SetData(TYPE_NORTHREND_BEASTS,IN_PROGRESS);
SetData(TYPE_BEASTS,IN_PROGRESS);
break;
case SNAKES_IN_PROGRESS: m_uiNotOneButTwoJormungarsTimer = 0; break;
case SNAKES_SPECIAL: m_uiNotOneButTwoJormungarsTimer = 10*IN_MILLISECONDS; break;
case SNAKES_DONE:
if (m_uiNotOneButTwoJormungarsTimer > 0)
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_WORMS_KILLED_IN_10_SECONDS);
m_uiEvent = 300;
SetData(TYPE_NORTHREND_BEASTS,IN_PROGRESS);
SetData(TYPE_BEASTS,IN_PROGRESS);
break;
case ICEHOWL_DONE:
m_uiEvent = 400;
SetData(TYPE_NORTHREND_BEASTS,DONE);
SetData(TYPE_BEASTS,DONE);
break;
case FAIL:
SetData(TYPE_BEASTS,FAIL);
break;
}
break;
case DATA_HEALTH_TWIN_SHARED: m_uiDataDamageTwin = uiData; uiData = NOT_STARTED; break;
//Achievements
case DATA_SNOBOLD_COUNT:
if (uiData == INCREASE)
++m_uiSnoboldCount;
else if (uiData == DECREASE)
--m_uiSnoboldCount;
break;
case DATA_MISTRESS_OF_PAIN_COUNT:
if (uiData == INCREASE)
++m_uiMistressOfPainCount;
else if (uiData == DECREASE)
--m_uiMistressOfPainCount;
break;
case DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE:
m_bTributeToImmortalityElegible = false;
break;
}
if (IsEncounterInProgress())
{
CloseDoor(GetData64(GO_EAST_PORTCULLIS));
CloseDoor(GetData64(GO_WEB_DOOR));
} else {
OpenDoor(GetData64(GO_EAST_PORTCULLIS));
OpenDoor(GetData64(GO_WEB_DOOR));
}
if (uiType < MAX_ENCOUNTERS)
{
sLog.outBasic("[ToCr] m_auiEncounter[uiType %u] %u = uiData %u;",uiType,m_auiEncounter[uiType],uiData);
if (uiData == FAIL)
{
if (IsRaidWiped())
{
--m_uiTrialCounter;
m_bNeedSave = true;
m_uiEvent = (uiType == TYPE_BEASTS? 666 : 0);
}
uiData = NOT_STARTED;
}
m_auiEncounter[uiType] = uiData;
if (uiData == DONE || m_bNeedSave == true)
{
if (Unit* pAnnouncer = instance->GetCreature(GetData64(NPC_BARRENT)))
pAnnouncer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
Save();
}
}
}
uint64 GetData64(uint32 uiData)
{
switch(uiData)
{
case NPC_BARRENT: return m_uiBarrentGUID;
case NPC_TIRION: return m_uiTirionGUID;
case NPC_FIZZLEBANG: return m_uiFizzlebangGUID;
case NPC_GARROSH: return m_uiGarroshGUID;
case NPC_VARIAN: return m_uiVarianGUID;
case NPC_GORMOK: return m_uiGormokGUID;
case NPC_ACIDMAW: return m_uiAcidmawGUID;
case NPC_DREADSCALE: return m_uiDreadscaleGUID;
case NPC_ICEHOWL: return m_uiIcehowlGUID;
case NPC_JARAXXUS: return m_uiJaraxxusGUID;
case NPC_CHAMPIONS_CONTROLLER: return m_uiChampionsControllerGUID;
case NPC_DARKBANE: return m_uiDarkbaneGUID;
case NPC_LIGHTBANE: return m_uiLightbaneGUID;
case NPC_ANUBARAK: return m_uiAnubarakGUID;
case GO_ARGENT_COLISEUM_FLOOR: return m_uiFloorGUID;
case GO_MAIN_GATE_DOOR: return m_uiMainGateDoorGUID;
case GO_EAST_PORTCULLIS: return m_uiEastPortcullisGUID;
case GO_WEB_DOOR: return m_uiWebDoorGUID;
}
return 0;
}
uint32 GetData(uint32 uiType)
{
switch(uiType)
{
case TYPE_BEASTS: return m_auiEncounter[TYPE_BEASTS];
case TYPE_JARAXXUS: return m_auiEncounter[TYPE_JARAXXUS];
case TYPE_CRUSADERS: return m_auiEncounter[TYPE_CRUSADERS];
case TYPE_VALKIRIES: return m_auiEncounter[TYPE_VALKIRIES];
case TYPE_LICH_KING: return m_auiEncounter[TYPE_LICH_KING];
case TYPE_ANUBARAK: return m_auiEncounter[TYPE_ANUBARAK];
case TYPE_COUNTER: return m_uiTrialCounter;
case TYPE_EVENT: return m_uiEvent;
case TYPE_NORTHREND_BEASTS: return m_uiNorthrendBeasts;
case TYPE_EVENT_TIMER: return m_uiEventTimer;
case TYPE_EVENT_NPC:
switch (m_uiEvent)
{
case 110:
case 140:
case 150:
case 155:
case 200:
case 205:
case 210:
case 220:
case 300:
case 305:
case 310:
case 315:
case 400:
case 666:
case 1010:
case 1180:
case 2000:
case 2030:
case 3000:
case 3001:
case 3060:
case 3061:
case 3090:
case 3091:
case 3092:
case 3100:
case 3110:
case 4000:
case 4010:
case 4015:
case 4016:
case 4040:
case 4050:
case 5000:
case 5005:
case 5020:
case 6000:
case 6005:
case 6010:
m_uiEventNPCId = NPC_TIRION;
break;
case 5010:
case 5030:
case 5040:
case 5050:
case 5060:
case 5070:
case 5080:
m_uiEventNPCId = NPC_LICH_KING_1;
break;
case 120:
case 122:
case 2020:
case 3080:
case 3051:
case 3071:
case 4020:
m_uiEventNPCId = NPC_VARIAN;
break;
case 130:
case 132:
case 2010:
case 3050:
case 3070:
case 3081:
case 4030:
m_uiEventNPCId = NPC_GARROSH;
break;
case 1110:
case 1120:
case 1130:
case 1132:
case 1134:
case 1135:
case 1140:
case 1142:
case 1144:
case 1150:
m_uiEventNPCId = NPC_FIZZLEBANG;
break;
default:
m_uiEventNPCId = NPC_TIRION;
break;
};
return m_uiEventNPCId;
case DATA_HEALTH_TWIN_SHARED: return m_uiDataDamageTwin;
}
return 0;
}
void Update(uint32 uiDiff)
{
if (GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL)
{
if (m_uiNotOneButTwoJormungarsTimer)
if (m_uiNotOneButTwoJormungarsTimer <= uiDiff)
m_uiNotOneButTwoJormungarsTimer = 0;
else m_uiNotOneButTwoJormungarsTimer -= uiDiff;
}
if (GetData(TYPE_CRUSADERS) == IN_PROGRESS)
{
if (m_uiResilienceWillFixItTimer)
if (m_uiResilienceWillFixItTimer <= uiDiff)
m_uiResilienceWillFixItTimer = 0;
else m_uiResilienceWillFixItTimer -= uiDiff;
}
}
void Save()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
saveStream << m_auiEncounter[i] << " ";
saveStream << m_uiTrialCounter;
m_strInstData = saveStream.str();
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
m_bNeedSave = false;
}
std::string GetSaveData()
{
return m_strInstData;
}
void Load(const char* strIn)
{
if (!strIn)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(strIn);
std::istringstream loadStream(strIn);
for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
{
loadStream >> m_auiEncounter[i];
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
}
loadStream >> m_uiTrialCounter;
m_uiEvent = 0;
OUT_LOAD_INST_DATA_COMPLETE;
}
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/)
{
switch (criteria_id)
{
case UPPER_BACK_PAIN_10_PLAYER:
case UPPER_BACK_PAIN_10_PLAYER_HEROIC:
return m_uiSnoboldCount >= 2;
case UPPER_BACK_PAIN_25_PLAYER:
case UPPER_BACK_PAIN_25_PLAYER_HEROIC:
return m_uiSnoboldCount >= 4;
case THREE_SIXTY_PAIN_SPIKE_10_PLAYER:
case THREE_SIXTY_PAIN_SPIKE_10_PLAYER_HEROIC:
case THREE_SIXTY_PAIN_SPIKE_25_PLAYER:
case THREE_SIXTY_PAIN_SPIKE_25_PLAYER_HEROIC:
return m_uiMistressOfPainCount >= 2;
case A_TRIBUTE_TO_SKILL_10_PLAYER:
case A_TRIBUTE_TO_SKILL_25_PLAYER:
return m_uiTrialCounter >= 25;
case A_TRIBUTE_TO_MAD_SKILL_10_PLAYER:
case A_TRIBUTE_TO_MAD_SKILL_25_PLAYER:
return m_uiTrialCounter >= 45;
case A_TRIBUTE_TO_INSANITY_10_PLAYER:
case A_TRIBUTE_TO_INSANITY_25_PLAYER:
case REALM_FIRST_GRAND_CRUSADER:
return m_uiTrialCounter == 50;
case A_TRIBUTE_TO_IMMORTALITY_HORDE:
case A_TRIBUTE_TO_IMMORTALITY_ALLIANCE:
return m_uiTrialCounter == 50 && m_bTributeToImmortalityElegible;
case A_TRIBUTE_TO_DEDICATED_INSANITY:
return false/*uiGrandCrusaderAttemptsLeft == 50 && !bHasAtAnyStagePlayerEquippedTooGoodItem*/;
}
return false;
}
};
};
void AddSC_instance_trial_of_the_crusader()
{
new instance_trial_of_the_crusader();
}
@@ -0,0 +1,987 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Trial Of the crusader
SD%Complete: ??%
SDComment: event script based on /dev/rsa
SDCategory: trial_of_the_crusader
EndScriptData */
//Known Bugs:
// - Need better implementation of Gossip and correct gossip text and option
// - Misses Dalaran Teleport at the end.
#include "ScriptPCH.h"
#include "trial_of_the_crusader.h"
enum eYells
{
SAY_STAGE_0_01 = -1649070,
SAY_STAGE_0_02 = -1649071,
SAY_STAGE_0_03a = -1649072,
SAY_STAGE_0_03h = -1649073,
SAY_STAGE_0_04 = -1649074,
SAY_STAGE_0_05 = -1649075,
SAY_STAGE_0_06 = -1649076,
SAY_STAGE_0_WIPE = -1649077,
SAY_STAGE_1_01 = -1649080,
SAY_STAGE_1_02 = -1649081,
SAY_STAGE_1_03 = -1649082,
SAY_STAGE_1_04 = -1649083,
SAY_STAGE_1_05 = -1649030, //INTRO Jaraxxus
SAY_STAGE_1_06 = -1649084,
SAY_STAGE_1_07 = -1649086,
SAY_STAGE_1_08 = -1649087,
SAY_STAGE_1_09 = -1649088,
SAY_STAGE_1_10 = -1649089,
SAY_STAGE_1_11 = -1649090,
SAY_STAGE_2_01 = -1649091,
SAY_STAGE_2_02a = -1649092,
SAY_STAGE_2_02h = -1649093,
SAY_STAGE_2_03 = -1649094,
SAY_STAGE_2_04a = -1649095,
SAY_STAGE_2_04h = -1649096,
SAY_STAGE_2_05a = -1649097,
SAY_STAGE_2_05h = -1649098,
SAY_STAGE_2_06 = -1649099,
SAY_STAGE_3_01 = -1649100,
SAY_STAGE_3_02 = -1649101,
SAY_STAGE_3_03a = -1649102,
SAY_STAGE_3_03h = -1649103,
SAY_STAGE_4_01 = -1649104,
SAY_STAGE_4_02 = -1649105,
SAY_STAGE_4_03 = -1649106,
SAY_STAGE_4_04 = -1649107,
SAY_STAGE_4_05 = -1649108,
SAY_STAGE_4_06 = -1649109,
SAY_STAGE_4_07 = -1649110,
};
struct _Messages
{
eAnnouncerMessages msgnum;
uint32 id;
bool state;
uint32 encounter;
};
static _Messages _GossipMessage[]=
{
{MSG_BEASTS,GOSSIP_ACTION_INFO_DEF+1,false,TYPE_BEASTS},
{MSG_JARAXXUS,GOSSIP_ACTION_INFO_DEF+2,false,TYPE_JARAXXUS},
{MSG_CRUSADERS,GOSSIP_ACTION_INFO_DEF+3,false,TYPE_CRUSADERS},
{MSG_VALKIRIES,GOSSIP_ACTION_INFO_DEF+4,false,TYPE_VALKIRIES},
{MSG_LICH_KING,GOSSIP_ACTION_INFO_DEF+5,false,TYPE_ANUBARAK},
{MSG_ANUBARAK,GOSSIP_ACTION_INFO_DEF+6,true,TYPE_ANUBARAK}
};
enum
{
NUM_MESSAGES = 6,
};
class npc_announcer_toc10 : public CreatureScript
{
public:
npc_announcer_toc10() : CreatureScript("npc_announcer_toc10") { }
struct npc_announcer_toc10AI : public ScriptedAI
{
npc_announcer_toc10AI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
void Reset()
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if(Creature *pAlly = GetClosestCreatureWithEntry(me, NPC_THRALL, 300.0f))
pAlly->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
if(Creature *pAlly = GetClosestCreatureWithEntry(me, NPC_PROUDMOORE, 300.0f))
pAlly->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
void AttackStart(Unit* pWho) {}
};
bool OnGossipHello(Player* pPlayer, Creature* pCreature)
{
InstanceScript* m_pInstance;
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
if (!m_pInstance) return false;
char const* _message = "We are ready!";
if (!pPlayer->getAttackers().empty() || m_pInstance->IsEncounterInProgress() || m_pInstance->GetData(TYPE_EVENT))
return true;
uint8 i;
for(i = 0; i < NUM_MESSAGES; i++)
{
if ((!_GossipMessage[i].state && m_pInstance->GetData(_GossipMessage[i].encounter) != DONE)
|| (_GossipMessage[i].state && m_pInstance->GetData(_GossipMessage[i].encounter) == DONE))
{
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _message, GOSSIP_SENDER_MAIN,_GossipMessage[i].id);
break;
}
}
pPlayer->SEND_GOSSIP_MENU(_GossipMessage[i].msgnum, pCreature->GetGUID());
return true;
}
bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
{
InstanceScript* m_pInstance;
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
if (!m_pInstance) return false;
pPlayer->CLOSE_GOSSIP_MENU();
switch(uiAction) {
case GOSSIP_ACTION_INFO_DEF+1:
if (m_pInstance->GetData(TYPE_BEASTS) != DONE)
{
m_pInstance->SetData(TYPE_EVENT,110);
m_pInstance->SetData(TYPE_NORTHREND_BEASTS,NOT_STARTED);
m_pInstance->SetData(TYPE_BEASTS,NOT_STARTED);
}
break;
case GOSSIP_ACTION_INFO_DEF+2:
if (Creature* pJaraxxus = Unit::GetCreature(*pCreature,m_pInstance->GetData64(NPC_JARAXXUS)))
{
pJaraxxus->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
pJaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pJaraxxus->SetReactState(REACT_AGGRESSIVE);
pJaraxxus->SetInCombatWithZone();
}
else
{
if (m_pInstance->GetData(TYPE_JARAXXUS) != DONE)
{
m_pInstance->SetData(TYPE_EVENT,1010);
m_pInstance->SetData(TYPE_JARAXXUS,NOT_STARTED);
}
}
break;
case GOSSIP_ACTION_INFO_DEF+3:
if (m_pInstance->GetData(TYPE_CRUSADERS) != DONE)
{
if (pPlayer->GetTeam() == ALLIANCE) m_pInstance->SetData(TYPE_EVENT,3000);
else m_pInstance->SetData(TYPE_EVENT,3001);
m_pInstance->SetData(TYPE_CRUSADERS,NOT_STARTED);
}
break;
case GOSSIP_ACTION_INFO_DEF+4:
if (m_pInstance->GetData(TYPE_VALKIRIES) != DONE)
{
m_pInstance->SetData(TYPE_EVENT,4000);
m_pInstance->SetData(TYPE_VALKIRIES,NOT_STARTED);
}
break;
case GOSSIP_ACTION_INFO_DEF+5:
{
if (m_pInstance->GetData(TYPE_LICH_KING) != DONE && !pPlayer->isGameMaster())
return false;
if (GameObject* pGoFloor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
pGoFloor->TakenDamage(1000000);
pCreature->CastSpell(pCreature,69016,false);
Creature* pTemp = Unit::GetCreature((*pCreature),m_pInstance->GetData64(NPC_ANUBARAK));
if (!pTemp || !pTemp->isAlive())
pTemp = pCreature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
m_pInstance->SetData(TYPE_ANUBARAK,NOT_STARTED);
if (pCreature->GetVisibility() == VISIBILITY_ON)
pCreature->SetVisibility(VISIBILITY_OFF);
break;
}
}
pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
return true;
}
CreatureAI* GetAI(Creature* pCreature) const
{
return new npc_announcer_toc10AI(pCreature);
}
};
class boss_lich_king_toc : public CreatureScript
{
public:
boss_lich_king_toc() : CreatureScript("boss_lich_king_toc") { }
struct boss_lich_king_tocAI : public ScriptedAI
{
boss_lich_king_tocAI(Creature *pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)pCreature->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiUpdateTimer;
void Reset()
{
m_uiUpdateTimer = 0;
me->SetReactState(REACT_PASSIVE);
if (Creature* pSummoned = me->SummonCreature(NPC_TRIGGER, ToCCommonLoc[2].GetPositionX(), ToCCommonLoc[2].GetPositionY(), ToCCommonLoc[2].GetPositionZ(), 5, TEMPSUMMON_TIMED_DESPAWN, 60000))
{
pSummoned->CastSpell(pSummoned, 51807, false);
pSummoned->SetDisplayId(11686);
}
if (m_pInstance) m_pInstance->SetData(TYPE_LICH_KING,IN_PROGRESS);
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if (uiType != POINT_MOTION_TYPE)
return;
switch (uiId)
{
case 0:
m_pInstance->SetData(TYPE_EVENT,5030);
break;
case 1:
m_pInstance->SetData(TYPE_EVENT,5050);
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
if (!m_pInstance) return;
if (m_pInstance->GetData(TYPE_EVENT_NPC) != NPC_LICH_KING_1) return;
m_uiUpdateTimer = m_pInstance->GetData(TYPE_EVENT_TIMER);
if (m_uiUpdateTimer <= uiDiff)
{
switch (m_pInstance->GetData(TYPE_EVENT))
{
case 5010:
DoScriptText(SAY_STAGE_4_02,me);
m_uiUpdateTimer = 3000;
me->GetMotionMaster()->MovePoint(0,LichKingLoc[0]);
m_pInstance->SetData(TYPE_EVENT,5020);
break;
case 5030:
DoScriptText(SAY_STAGE_4_04,me);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
m_uiUpdateTimer = 10000;
m_pInstance->SetData(TYPE_EVENT,5040);
break;
case 5040:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
me->GetMotionMaster()->MovePoint(1,LichKingLoc[1]);
m_uiUpdateTimer = 1000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 5050:
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,5060);
break;
case 5060:
DoScriptText(SAY_STAGE_4_05,me);
me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
m_uiUpdateTimer = 2500;
m_pInstance->SetData(TYPE_EVENT,5070);
break;
case 5070:
me->CastSpell(me,68198,false);
m_uiUpdateTimer = 1500;
m_pInstance->SetData(TYPE_EVENT,5080);
break;
case 5080:
if (GameObject* pGoFloor = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
pGoFloor->TakenDamage(1000000);
me->CastSpell(me,69016,false);
if(m_pInstance) m_pInstance->SetData(TYPE_LICH_KING,DONE);
Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_ANUBARAK));
if (!pTemp || !pTemp->isAlive())
pTemp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
me->ForcedDespawn();
m_pInstance->SetData(TYPE_EVENT,0);
m_uiUpdateTimer = 20000;
break;
}
} else m_uiUpdateTimer -= uiDiff;
m_pInstance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
}
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_lich_king_tocAI(pCreature);
}
};
class npc_fizzlebang_toc : public CreatureScript
{
public:
npc_fizzlebang_toc() : CreatureScript("npc_fizzlebang_toc") { }
struct npc_fizzlebang_tocAI : public ScriptedAI
{
npc_fizzlebang_tocAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
m_pInstance = (InstanceScript*)me->GetInstanceScript();
}
InstanceScript* m_pInstance;
SummonList Summons;
uint32 m_uiUpdateTimer;
uint64 m_uiPortalGUID;
uint64 m_uiTriggerGUID;
void JustDied(Unit* pKiller)
{
DoScriptText(SAY_STAGE_1_06, me, pKiller);
m_pInstance->SetData(TYPE_EVENT, 1180);
if (Creature* pTemp = Unit::GetCreature(*me,m_pInstance->GetData64(NPC_JARAXXUS)))
{
pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pTemp->SetReactState(REACT_AGGRESSIVE);
pTemp->SetInCombatWithZone();
}
}
void Reset()
{
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
m_uiPortalGUID = 0;
me->GetMotionMaster()->MovePoint(1, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY()-60, ToCCommonLoc[10].GetPositionZ());
}
void MovementInform(uint32 uiType, uint32 uiId)
{
if(uiType != POINT_MOTION_TYPE) return;
switch (uiId)
{
case 1:
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
if (m_pInstance)
{
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
m_pInstance->SetData(TYPE_EVENT, 1120);
m_pInstance->SetData(TYPE_EVENT_TIMER, 1000);
}
break;
}
}
void JustSummoned(Creature* pSummoned)
{
Summons.Summon(pSummoned);
}
void UpdateAI(const uint32 uiDiff)
{
if(!m_pInstance) return;
if (m_pInstance->GetData(TYPE_EVENT_NPC) != NPC_FIZZLEBANG) return;
m_uiUpdateTimer = m_pInstance->GetData(TYPE_EVENT_TIMER);
if (m_uiUpdateTimer <= uiDiff)
{
switch (m_pInstance->GetData(TYPE_EVENT))
{
case 1110:
m_pInstance->SetData(TYPE_EVENT, 1120);
m_uiUpdateTimer = 4000;
break;
case 1120:
DoScriptText(SAY_STAGE_1_02, me);
m_pInstance->SetData(TYPE_EVENT, 1130);
m_uiUpdateTimer = 12000;
break;
case 1130:
me->GetMotionMaster()->MovementExpired();
DoScriptText(SAY_STAGE_1_03, me);
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST_OMNI);
if (Unit* pTrigger = me->SummonCreature(NPC_TRIGGER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 4.69494f, TEMPSUMMON_MANUAL_DESPAWN))
{
m_uiTriggerGUID = pTrigger->GetGUID();
pTrigger->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
pTrigger->SetDisplayId(22862);
pTrigger->CastSpell(pTrigger, SPELL_WILFRED_PORTAL, false);
}
m_pInstance->SetData(TYPE_EVENT, 1132);
m_uiUpdateTimer = 4000;
break;
case 1132:
me->GetMotionMaster()->MovementExpired();
m_pInstance->SetData(TYPE_EVENT, 1134);
m_uiUpdateTimer = 4000;
break;
case 1134:
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST_OMNI);
if (Creature* pPortal = me->SummonCreature(NPC_WILFRED_PORTAL, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 4.71239f, TEMPSUMMON_MANUAL_DESPAWN))
{
pPortal->SetReactState(REACT_PASSIVE);
pPortal->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
pPortal->CastSpell(pPortal,SPELL_WILFRED_PORTAL,false);
m_uiPortalGUID = pPortal->GetGUID();
}
m_uiUpdateTimer = 4000;
m_pInstance->SetData(TYPE_EVENT, 1135);
break;
case 1135:
m_pInstance->SetData(TYPE_EVENT, 1140);
m_uiUpdateTimer = 3000;
break;
case 1140:
DoScriptText(SAY_STAGE_1_04, me);
if (Creature* pTemp = me->SummonCreature(NPC_JARAXXUS, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 5.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME))
{
pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pTemp->SetReactState(REACT_PASSIVE);
pTemp->GetMotionMaster()->MovePoint(0,ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY()-10, ToCCommonLoc[1].GetPositionZ());
}
m_pInstance->SetData(TYPE_EVENT, 1142);
m_uiUpdateTimer = 5000;
break;
case 1142:
if (Creature* pTemp = Unit::GetCreature(*me,m_pInstance->GetData64(NPC_JARAXXUS)))
pTemp->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID());
if (Creature* pTrigger = Unit::GetCreature(*me,m_uiTriggerGUID))
pTrigger->ForcedDespawn();
if (Creature* pPortal = Unit::GetCreature(*me,m_uiPortalGUID))
pPortal->ForcedDespawn();
m_pInstance->SetData(TYPE_EVENT, 1144);
m_uiUpdateTimer = 10000;
break;
case 1144:
if (Creature* pTemp = Unit::GetCreature(*me,m_pInstance->GetData64(NPC_JARAXXUS)))
DoScriptText(SAY_STAGE_1_05,pTemp);
m_pInstance->SetData(TYPE_EVENT, 1150);
m_uiUpdateTimer = 5000;
break;
case 1150:
if (Creature* pTemp = Unit::GetCreature(*me,m_pInstance->GetData64(NPC_JARAXXUS)))
{
//1-shot Fizzlebang
pTemp->CastSpell(me,67888,false);
me->SetInCombatWith(pTemp);
pTemp->AddThreat(me, 1000.0f);
pTemp->AI()->AttackStart(me);
}
m_pInstance->SetData(TYPE_EVENT, 1160);
m_uiUpdateTimer = 3000;
break;
}
} else m_uiUpdateTimer -= uiDiff;
m_pInstance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
}
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new npc_fizzlebang_tocAI(pCreature);
}
};
class npc_tirion_toc : public CreatureScript
{
public:
npc_tirion_toc() : CreatureScript("npc_tirion_toc") { }
struct npc_tirion_tocAI : public ScriptedAI
{
npc_tirion_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)me->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiUpdateTimer;
void Reset() {}
void AttackStart(Unit* pWho) {}
void UpdateAI(const uint32 uiDiff)
{
if (!m_pInstance) return;
if (m_pInstance->GetData(TYPE_EVENT_NPC) != NPC_TIRION) return;
m_uiUpdateTimer = m_pInstance->GetData(TYPE_EVENT_TIMER);
if (m_uiUpdateTimer <= uiDiff)
{
switch (m_pInstance->GetData(TYPE_EVENT))
{
case 110:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
DoScriptText(SAY_STAGE_0_01, me);
m_uiUpdateTimer = 22000;
m_pInstance->SetData(TYPE_EVENT,120);
break;
case 140:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
DoScriptText(SAY_STAGE_0_02, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,150);
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
break;
case 150:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
if (m_pInstance->GetData(TYPE_BEASTS) != DONE)
{
me->SummonCreature(NPC_GORMOK, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY(), ToCCommonLoc[10].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS);
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_GORMOK)))
{
pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
pTemp->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
pTemp->SetReactState(REACT_PASSIVE);
}
}
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,155);
break;
case 155:
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_GORMOK)))
{
pTemp->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
pTemp->SetReactState(REACT_AGGRESSIVE);
pTemp->SetInCombatWithZone();
}
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
m_pInstance->SetData(TYPE_BEASTS,IN_PROGRESS);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,160);
break;
case 200:
DoScriptText(SAY_STAGE_0_04, me);
m_uiUpdateTimer = 8000;
m_pInstance->SetData(TYPE_EVENT,205);
break;
case 205:
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,210);
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
break;
case 210:
if (m_pInstance->GetData(TYPE_BEASTS) != DONE)
{
me->SummonCreature(NPC_DREADSCALE, ToCCommonLoc[3].GetPositionX(), ToCCommonLoc[3].GetPositionY(), ToCCommonLoc[3].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS);
me->SummonCreature(NPC_ACIDMAW, ToCCommonLoc[4].GetPositionX(), ToCCommonLoc[4].GetPositionY(), ToCCommonLoc[4].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS);
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_DREADSCALE)))
{
pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ());
pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
pTemp->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
pTemp->SetReactState(REACT_PASSIVE);
}
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_ACIDMAW)))
{
pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ());
pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
pTemp->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
pTemp->SetReactState(REACT_PASSIVE);
}
}
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,220);
break;
case 220:
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_DREADSCALE)))
{
pTemp->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
pTemp->SetReactState(REACT_AGGRESSIVE);
pTemp->SetInCombatWithZone();
}
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_ACIDMAW)))
{
pTemp->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
pTemp->SetReactState(REACT_AGGRESSIVE);
pTemp->SetInCombatWithZone();
}
m_pInstance->SetData(TYPE_EVENT,230);
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
break;
case 300:
DoScriptText(SAY_STAGE_0_05, me);
m_uiUpdateTimer = 8000;
m_pInstance->SetData(TYPE_EVENT,305);
break;
case 305:
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,310);
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
break;
case 310:
if (m_pInstance->GetData(TYPE_BEASTS) != DONE)
{
me->SummonCreature(NPC_ICEHOWL, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY(), ToCCommonLoc[10].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN);
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_ICEHOWL)))
{
pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
pTemp->SetInCombatWithZone();
}
}
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,315);
break;
case 315:
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
m_pInstance->SetData(TYPE_EVENT,320);
break;
case 400:
DoScriptText(SAY_STAGE_0_06, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 666:
DoScriptText(SAY_STAGE_0_WIPE, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 1010:
DoScriptText(SAY_STAGE_1_01, me);
m_uiUpdateTimer = 7000;
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
me->SummonCreature(NPC_FIZZLEBANG, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY(), ToCCommonLoc[10].GetPositionZ(), 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 1180:
DoScriptText(SAY_STAGE_1_07, me);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 2000:
DoScriptText(SAY_STAGE_1_08, me);
m_uiUpdateTimer = 18000;
m_pInstance->SetData(TYPE_EVENT,2010);
break;
case 2030:
DoScriptText(SAY_STAGE_1_11, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 3000:
DoScriptText(SAY_STAGE_2_01, me);
m_uiUpdateTimer = 12000;
m_pInstance->SetData(TYPE_EVENT,3050);
break;
case 3001:
DoScriptText(SAY_STAGE_2_01, me);
m_uiUpdateTimer = 12000;
m_pInstance->SetData(TYPE_EVENT,3051);
break;
case 3060:
DoScriptText(SAY_STAGE_2_03, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,3070);
break;
case 3061:
DoScriptText(SAY_STAGE_2_03, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,3071);
break;
//Summoning crusaders
case 3091:
me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1]);
if (Creature* pChampionController = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
pChampionController->AI()->SetData(0,HORDE);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,3092);
break;
//Summoning crusaders
case 3090:
me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1]);
if (Creature* pChampionController = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
pChampionController->AI()->SetData(0,ALLIANCE);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,3092);
break;
case 3092:
if (Creature* pChampionController = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
pChampionController->AI()->SetData(1,NOT_STARTED);
m_pInstance->SetData(TYPE_EVENT,3095);
break;
//Crusaders battle end
case 3100:
DoScriptText(SAY_STAGE_2_06, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 4000:
DoScriptText(SAY_STAGE_3_01, me);
m_uiUpdateTimer = 13000;
m_pInstance->SetData(TYPE_EVENT,4010);
break;
case 4010:
DoScriptText(SAY_STAGE_3_02, me);
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,4015);
break;
case 4015:
me->SummonCreature(NPC_LIGHTBANE, ToCCommonLoc[3].GetPositionX(), ToCCommonLoc[3].GetPositionY(), ToCCommonLoc[3].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_LIGHTBANE)))
{
pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[6].GetPositionX(), ToCCommonLoc[6].GetPositionY(), ToCCommonLoc[6].GetPositionZ());
pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
me->SetReactState(REACT_PASSIVE);
}
me->SummonCreature(NPC_DARKBANE, ToCCommonLoc[4].GetPositionX(), ToCCommonLoc[4].GetPositionY(), ToCCommonLoc[4].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
if (Creature* pTemp = Unit::GetCreature((*me),m_pInstance->GetData64(NPC_DARKBANE)))
{
pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[7].GetPositionX(), ToCCommonLoc[7].GetPositionY(), ToCCommonLoc[7].GetPositionZ());
pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
me->SetReactState(REACT_PASSIVE);
}
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,4016);
break;
case 4016:
m_pInstance->SetData(TYPE_EVENT,4017);
m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR));
break;
case 4040:
m_uiUpdateTimer = 60000;
m_pInstance->SetData(TYPE_EVENT,5000);
break;
case 5000:
DoScriptText(SAY_STAGE_4_01, me);
m_uiUpdateTimer = 10000;
m_pInstance->SetData(TYPE_EVENT,5005);
break;
case 5005:
m_uiUpdateTimer = 8000;
m_pInstance->SetData(TYPE_EVENT,5010);
me->SummonCreature(NPC_LICH_KING_1, ToCCommonLoc[2].GetPositionX(), ToCCommonLoc[2].GetPositionY(), ToCCommonLoc[2].GetPositionZ(), 5);
break;
case 5020:
DoScriptText(SAY_STAGE_4_03, me);
m_uiUpdateTimer = 1000;
m_pInstance->SetData(TYPE_EVENT,0);
break;
case 6000:
me->NearTeleportTo(AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 4.0f);
m_uiUpdateTimer = 20000;
m_pInstance->SetData(TYPE_EVENT,6005);
break;
case 6005:
DoScriptText(SAY_STAGE_4_06, me);
m_uiUpdateTimer = 20000;
m_pInstance->SetData(TYPE_EVENT,6010);
break;
case 6010:
if (IsHeroic())
{
DoScriptText(SAY_STAGE_4_07, me);
m_uiUpdateTimer = 60000;
m_pInstance->SetData(TYPE_ANUBARAK,SPECIAL);
m_pInstance->SetData(TYPE_EVENT,6020);
} else m_pInstance->SetData(TYPE_EVENT,6030);
break;
case 6020:
me->ForcedDespawn();
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,6030);
break;
}
} else m_uiUpdateTimer -= uiDiff;
m_pInstance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
}
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new npc_tirion_tocAI(pCreature);
}
};
class npc_garrosh_toc : public CreatureScript
{
public:
npc_garrosh_toc() : CreatureScript("npc_garrosh_toc") { }
struct npc_garrosh_tocAI : public ScriptedAI
{
npc_garrosh_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)me->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiUpdateTimer;
void Reset() {}
void AttackStart(Unit* pWho) {}
void UpdateAI(const uint32 uiDiff)
{
if (!m_pInstance) return;
if (m_pInstance->GetData(TYPE_EVENT_NPC) != NPC_GARROSH) return;
m_uiUpdateTimer = m_pInstance->GetData(TYPE_EVENT_TIMER);
if (m_uiUpdateTimer <= uiDiff)
{
switch (m_pInstance->GetData(TYPE_EVENT))
{
case 130:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
DoScriptText(SAY_STAGE_0_03h, me);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,132);
break;
case 132:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,140);
break;
case 2010:
DoScriptText(SAY_STAGE_1_09, me);
m_uiUpdateTimer = 9000;
m_pInstance->SetData(TYPE_EVENT,2020);
break;
case 3050:
DoScriptText(SAY_STAGE_2_02h, me);
m_uiUpdateTimer = 15000;
m_pInstance->SetData(TYPE_EVENT,3060);
break;
case 3070:
DoScriptText(SAY_STAGE_2_04h, me);
m_uiUpdateTimer = 6000;
m_pInstance->SetData(TYPE_EVENT,3080);
break;
case 3081:
DoScriptText(SAY_STAGE_2_05h, me);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,3091);
break;
case 4030:
DoScriptText(SAY_STAGE_3_03h, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,4040);
break;
}
} else m_uiUpdateTimer -= uiDiff;
m_pInstance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
}
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new npc_garrosh_tocAI(pCreature);
}
};
class npc_varian_toc : public CreatureScript
{
public:
npc_varian_toc() : CreatureScript("npc_varian_toc") { }
struct npc_varian_tocAI : public ScriptedAI
{
npc_varian_tocAI(Creature* pCreature) : ScriptedAI(pCreature)
{
m_pInstance = (InstanceScript*)me->GetInstanceScript();
}
InstanceScript* m_pInstance;
uint32 m_uiUpdateTimer;
void Reset() {}
void AttackStart(Unit* pWho) {}
void UpdateAI(const uint32 uiDiff)
{
if (!m_pInstance) return;
if (m_pInstance->GetData(TYPE_EVENT_NPC) != NPC_VARIAN) return;
m_uiUpdateTimer = m_pInstance->GetData(TYPE_EVENT_TIMER);
if (m_uiUpdateTimer <= uiDiff)
{
switch (m_pInstance->GetData(TYPE_EVENT))
{
case 120:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
DoScriptText(SAY_STAGE_0_03a, me);
m_uiUpdateTimer = 2000;
m_pInstance->SetData(TYPE_EVENT,122);
break;
case 122:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,130);
break;
case 2020:
DoScriptText(SAY_STAGE_1_10, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,2030);
break;
case 3051:
DoScriptText(SAY_STAGE_2_02a, me);
m_uiUpdateTimer = 10000;
m_pInstance->SetData(TYPE_EVENT,3061);
break;
case 3071:
DoScriptText(SAY_STAGE_2_04a, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,3081);
break;
case 3080:
DoScriptText(SAY_STAGE_2_05a, me);
m_uiUpdateTimer = 3000;
m_pInstance->SetData(TYPE_EVENT,3090);
break;
case 4020:
DoScriptText(SAY_STAGE_3_03a, me);
m_uiUpdateTimer = 5000;
m_pInstance->SetData(TYPE_EVENT,4040);
break;
}
} else m_uiUpdateTimer -= uiDiff;
m_pInstance->SetData(TYPE_EVENT_TIMER,m_uiUpdateTimer);
}
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new npc_varian_tocAI(pCreature);
}
};
void AddSC_trial_of_the_crusader()
{
new npc_announcer_toc10();
new boss_lich_king_toc();
new npc_fizzlebang_toc();
new npc_tirion_toc();
new npc_garrosh_toc();
new npc_varian_toc();
}
@@ -0,0 +1,276 @@
/* Copyright (C) 2009 - 2010 by /dev/rsa for ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_CRUSADER_H
#define DEF_CRUSADER_H
enum
{
TYPE_BEASTS = 0,
TYPE_JARAXXUS = 1,
TYPE_CRUSADERS = 2,
TYPE_VALKIRIES = 3,
TYPE_LICH_KING = 4,
TYPE_ANUBARAK = 5,
MAX_ENCOUNTERS = 6,
TYPE_COUNTER = 8,
TYPE_EVENT = 9,
TYPE_EVENT_TIMER = 101,
TYPE_EVENT_NPC = 102,
TYPE_NORTHREND_BEASTS = 103,
DATA_HEALTH_TWIN_SHARED = 201,
DATA_SNOBOLD_COUNT = 301,
DATA_MISTRESS_OF_PAIN_COUNT = 302,
DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE = 303,
INCREASE = 501,
DECREASE = 502,
SPELL_WILFRED_PORTAL = 68424,
SPELL_JARAXXUS_CHAINS = 67924,
DESPAWN_TIME = 300000,
};
static Position ToCCommonLoc[]=
{
{559.257996f, 90.266197f, 395.122986f}, // 0 Barrent
{563.672974f, 139.571f, 393.837006f}, // 1 Center
{563.833008f, 187.244995f, 394.5f}, // 2 Backdoor
{577.347839f, 195.338888f, 395.14f}, // 3 - Right
{550.955933f, 195.338888f, 395.14f}, // 4 - Left
{563.833008f, 195.244995f, 394.585561f}, // 5 - Center
{573.5f, 180.5f, 395.14f}, // 6 Move 0 Right
{553.5f, 180.5f, 395.14f}, // 7 Move 0 Left
{585.5f, 170.0f, 395.14f}, // 8 Move 1 Right
{545.5f, 170.0f, 395.14f}, // 9 Move 1 Left
{563.8f, 216.1f, 395.1f}, // 10 Behind the door
{575.042358f, 195.260727f, 395.137146f}, // 5
{552.248901f, 195.331955f, 395.132658f}, // 6
{573.342285f, 195.515823f, 395.135956f}, // 7
{554.239929f, 195.825577f, 395.137909f}, // 8
{571.042358f, 195.260727f, 395.137146f}, // 9
{556.720581f, 195.015472f, 395.132658f}, // 10
{569.534119f, 195.214478f, 395.139526f}, // 11
{569.231201f, 195.941071f, 395.139526f}, // 12
{558.811610f, 195.985779f, 394.671661f}, // 13
{567.641724f, 195.351501f, 394.659943f}, // 14
{560.633972f, 195.391708f, 395.137543f}, // 15
{565.816956f, 195.477921f, 395.136810f}, // 16
};
static Position JaraxxusLoc[]=
{
{508.104767f, 138.247345f, 395.128052f}, // 0 - Fizzlebang start location
{548.610596f, 139.807800f, 394.321838f}, // 1 - fizzlebang end
{581.854187f, 138.0f, 394.319f}, // 2 - Portal Right
{550.558838f, 138.0f, 394.319f}, // 3 - Portal Left
};
static Position FactionChampionLoc[]=
{
{514.231,105.569,418.234}, // 0 - Horde Initial Pos 0
{508.334,115.377,418.234}, // 1 - Horde Initial Pos 1
{506.454,126.291,418.234}, // 2 - Horde Initial Pos 2
{506.243,106.596,421.592}, // 3 - Horde Initial Pos 3
{499.885,117.717,421.557}, // 4 - Horde Initial Pos 4
{613.127,100.443,419.74}, // 5 - Ally Initial Pos 0
{621.126,128.042,418.231}, // 6 - Ally Initial Pos 1
{618.829,113.606,418.232}, // 7 - Ally Initial Pos 2
{625.845,112.914,421.575}, // 8 - Ally Initial Pos 3
{615.566,109.653,418.234}, // 9 - Ally Initial Pos 4
{535.469,113.012,394.66}, // 10 - Horde Final Pos 0
{526.417,137.465,394.749}, // 11 - Horde Final Pos 1
{528.108,111.057,395.289}, // 12 - Horde Final Pos 2
{519.92,134.285,395.289}, // 13 - Horde Final Pos 3
{533.648,119.148,394.646}, // 14 - Horde Final Pos 4
{531.399,125.63,394.708}, // 15 - Horde Final Pos 5
{528.958,131.47,394.73}, // 16 - Horde Final Pos 6
{526.309,116.667,394.833}, // 17 - Horde Final Pos 7
{524.238,122.411,394.819}, // 18 - Horde Final Pos 8
{521.901,128.488,394.832}, // 19 - Horde Final Pos 9
};
static Position TwinValkyrsLoc[]=
{
{586.060242f, 117.514809f, 394.314026f}, // 0 - Dark essence 1
{541.602112f, 161.879837f, 394.587952f}, // 1 - Dark essence 2
{541.021118f, 117.262932f, 395.314819f}, // 2 - Light essence 1
{586.200562f, 162.145523f, 394.626129f}, // 3 - Light essence 2
};
static Position LichKingLoc[]=
{
{563.549f, 152.474f, 394.393f}, // 0 - Lich king start
{563.547f, 141.613f, 393.908f}, // 1 - Lich king end
};
static Position AnubarakLoc[]=
{
{787.932556f, 133.289780f, 142.612152f}, // 0 - Anub'arak start location
{695.240051f, 137.834824f, 142.200000f}, // 1 - Anub'arak move point location
{694.886353f, 102.484665f, 142.119614f}, // 3 - Nerub Spawn
{694.500671f, 185.363968f, 142.117905f}, // 5 - Nerub Spawn
{731.987244f, 83.3824690f, 142.119614f}, // 2 - Nerub Spawn
{740.184509f, 193.443390f, 142.117584f}, // 4 - Nerub Spawn
};
enum euiWorldStates
{
UPDATE_STATE_UI_SHOW = 4390,
UPDATE_STATE_UI_COUNT = 4389,
};
enum eNorthrendBeasts
{
GORMOK_IN_PROGRESS = 1000,
GORMOK_DONE = 1001,
SNAKES_IN_PROGRESS = 2000,
DREADSCALE_SUBMERGED = 2001,
ACIDMAW_SUBMERGED = 2002,
SNAKES_SPECIAL = 2003,
SNAKES_DONE = 2004,
ICEHOWL_IN_PROGRESS = 3000,
ICEHOWL_DONE = 3001,
};
enum eAnnouncerMessages
{
MSG_BEASTS = 724001,
MSG_JARAXXUS = 724002,
MSG_CRUSADERS = 724003,
MSG_VALKIRIES = 724004,
MSG_LICH_KING = 724005,
MSG_ANUBARAK = 724006,
};
enum eCreature
{
NPC_BARRENT = 34816,
NPC_TIRION = 34996,
NPC_FIZZLEBANG = 35458,
NPC_GARROSH = 34995,
NPC_VARIAN = 34990,
NPC_LICH_KING_0 = 16980,
NPC_LICH_KING_1 = 35877,
NPC_THRALL = 34994,
NPC_PROUDMOORE = 34992,
NPC_WILFRED_PORTAL = 17965,
NPC_TRIGGER = 35651,
NPC_ICEHOWL = 34797,
NPC_GORMOK = 34796,
NPC_DREADSCALE = 34799,
NPC_ACIDMAW = 35144,
NPC_JARAXXUS = 34780,
NPC_CHAMPIONS_CONTROLLER = 34781,
NPC_ALLIANCE_DEATH_KNIGHT = 34461,
NPC_ALLIANCE_DRUID_BALANCE = 34460,
NPC_ALLIANCE_DRUID_RESTORATION = 34469,
NPC_ALLIANCE_HUNTER = 34467,
NPC_ALLIANCE_MAGE = 34468,
NPC_ALLIANCE_PALADIN_HOLY = 34465,
NPC_ALLIANCE_PALADIN_RETRIBUTION = 34471,
NPC_ALLIANCE_PRIEST_DISCIPLINE = 34466,
NPC_ALLIANCE_PRIEST_SHADOW = 34473,
NPC_ALLIANCE_ROGUE = 34472,
NPC_ALLIANCE_SHAMAN_ENHANCEMENT = 34463,
NPC_ALLIANCE_SHAMAN_RESTORATION = 34470,
NPC_ALLIANCE_WARLOCK = 34474,
NPC_ALLIANCE_WARRIOR = 34475,
NPC_HORDE_DEATH_KNIGHT = 34458,
NPC_HORDE_DRUID_BALANCE = 34451,
NPC_HORDE_DRUID_RESTORATION = 34459,
NPC_HORDE_HUNTER = 34448,
NPC_HORDE_MAGE = 34449,
NPC_HORDE_PALADIN_HOLY = 34445,
NPC_HORDE_PALADIN_RETRIBUTION = 34456,
NPC_HORDE_PRIEST_DISCIPLINE = 34447,
NPC_HORDE_PRIEST_SHADOW = 34441,
NPC_HORDE_ROGUE = 34454,
NPC_HORDE_SHAMAN_ENHANCEMENT = 34455,
NPC_HORDE_SHAMAN_RESTORATION = 34444,
NPC_HORDE_WARLOCK = 34450,
NPC_HORDE_WARRIOR = 34453,
NPC_LIGHTBANE = 34497,
NPC_DARKBANE = 34496,
NPC_ANUBARAK = 34564,
};
enum eGameObject
{
GO_CRUSADERS_CACHE_10 = 195631,
GO_CRUSADERS_CACHE_25 = 195632,
GO_CRUSADERS_CACHE_10_H = 195633,
GO_CRUSADERS_CACHE_25_H = 195635,
// Tribute Chest (heroic)
// 10-man modes
GO_TRIBUTE_CHEST_10H_25 = 195668, // 10man 01-24 attempts
GO_TRIBUTE_CHEST_10H_45 = 195667, // 10man 25-44 attempts
GO_TRIBUTE_CHEST_10H_50 = 195666, // 10man 45-49 attempts
GO_TRIBUTE_CHEST_10H_99 = 195665, // 10man 50 attempts
// 25-man modes
GO_TRIBUTE_CHEST_25H_25 = 195672, // 25man 01-24 attempts
GO_TRIBUTE_CHEST_25H_45 = 195671, // 25man 25-44 attempts
GO_TRIBUTE_CHEST_25H_50 = 195670, // 25man 45-49 attempts
GO_TRIBUTE_CHEST_25H_99 = 195669, // 25man 50 attempts
GO_ARGENT_COLISEUM_FLOOR = 195527, //20943
GO_MAIN_GATE_DOOR = 195647,
GO_EAST_PORTCULLIS = 195648,
GO_WEB_DOOR = 195485,
};
enum eAchievementData
{
// Northrend Beasts
UPPER_BACK_PAIN_10_PLAYER = 11779,
UPPER_BACK_PAIN_10_PLAYER_HEROIC = 11802,
UPPER_BACK_PAIN_25_PLAYER = 11780,
UPPER_BACK_PAIN_25_PLAYER_HEROIC = 11801,
// Lord Jaraxxus
THREE_SIXTY_PAIN_SPIKE_10_PLAYER = 11838,
THREE_SIXTY_PAIN_SPIKE_10_PLAYER_HEROIC = 11861,
THREE_SIXTY_PAIN_SPIKE_25_PLAYER = 11839,
THREE_SIXTY_PAIN_SPIKE_25_PLAYER_HEROIC = 11862,
// Tribute
A_TRIBUTE_TO_SKILL_10_PLAYER = 12344,
A_TRIBUTE_TO_SKILL_25_PLAYER = 12338,
A_TRIBUTE_TO_MAD_SKILL_10_PLAYER = 12347,
A_TRIBUTE_TO_MAD_SKILL_25_PLAYER = 12341,
A_TRIBUTE_TO_INSANITY_10_PLAYER = 12349,
A_TRIBUTE_TO_INSANITY_25_PLAYER = 12343,
A_TRIBUTE_TO_IMMORTALITY_HORDE = 12358,
A_TRIBUTE_TO_IMMORTALITY_ALLIANCE = 12359,
A_TRIBUTE_TO_DEDICATED_INSANITY = 12360,
REALM_FIRST_GRAND_CRUSADER = 12350,
// Dummy spells - not existing in dbc but we don't need that
SPELL_WORMS_KILLED_IN_10_SECONDS = 68523,
SPELL_CHAMPIONS_KILLED_IN_MINUTE = 68620,
SPELL_DEFEAT_FACTION_CHAMPIONS = 68184,
SPELL_TRAITOR_KING_10 = 68186,
SPELL_TRAITOR_KING_25 = 68515,
// Timed events
EVENT_START_TWINS_FIGHT = 21853
};
#endif