aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/FULL/world_scripts_full.sql14
-rw-r--r--sql/updates/5724_world_utgarde_pinnacle.sql12
-rw-r--r--src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp550
-rw-r--r--src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp208
-rw-r--r--src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp323
-rw-r--r--src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp38
-rw-r--r--src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/def_pinnacle.h17
-rw-r--r--src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp197
-rw-r--r--src/bindings/scripts/system/ScriptLoader.cpp5
-rw-r--r--src/game/PetAI.cpp4
-rw-r--r--src/game/Unit.h2
11 files changed, 1303 insertions, 67 deletions
diff --git a/sql/FULL/world_scripts_full.sql b/sql/FULL/world_scripts_full.sql
index 49bd5f5c99e..a80cb98e73d 100644
--- a/sql/FULL/world_scripts_full.sql
+++ b/sql/FULL/world_scripts_full.sql
@@ -1125,6 +1125,20 @@ UPDATE `creature_template` SET `ScriptName`='mob_annhylde_the_caller' WHERE `ent
UPDATE `creature_template` SET `ScriptName`='mob_ingvar_throw_dummy' WHERE `entry`=23997;
UPDATE `creature_template` SET `ScriptName`='npc_dragonflayer_forge_master' WHERE `entry`=24079;
+/* UTGARDE PINNACLE */
+UPDATE `creature_template` SET `ScriptName`='boss_svala_sorrowgrave' WHERE `entry`=26668;
+UPDATE `creature_template` SET `ScriptName`='mob_ritual_channeler' WHERE `entry`=27281;
+UPDATE `creature_template` SET `ScriptName`='boss_svala' WHERE `entry`=29281;
+UPDATE `creature_template` SET `ScriptName`='boss_palehoof' WHERE `entry`=26687;
+UPDATE `creature_template` SET `ScriptName`='boss_skadi' WHERE `entry`=26693;
+UPDATE `creature_template` SET `ScriptName`='boss_ymiron' WHERE `entry`=26861;
+UPDATE `creature_template` SET `ScriptName`='mob_frenzied_worgen' WHERE `entry`=26683;
+UPDATE `creature_template` SET `ScriptName`='mob_ravenous_furbolg' WHERE `entry`=26684;
+UPDATE `creature_template` SET `ScriptName`='mob_ferocious_rhino' WHERE `entry`=26685;
+UPDATE `creature_template` SET `ScriptName`='mob_massive_jormungar' WHERE `entry`=26686;
+UPDATE `instance_template` SET `script`='instance_utgarde_pinnacle' WHERE `map`=575;
+UPDATE `gameobject_template` SET `ScriptName`='go_palehoof_sphere'WHERE `entry`=188593;
+
/* VAULT OF ARCHAVON */
UPDATE `creature_template` SET `ScriptName`='boss_archavon' WHERE `entry`=31125;
UPDATE `creature_template` SET `ScriptName`='mob_archavon_warder' WHERE `entry`=32353;
diff --git a/sql/updates/5724_world_utgarde_pinnacle.sql b/sql/updates/5724_world_utgarde_pinnacle.sql
new file mode 100644
index 00000000000..9b2987d3b58
--- /dev/null
+++ b/sql/updates/5724_world_utgarde_pinnacle.sql
@@ -0,0 +1,12 @@
+UPDATE `creature_template` SET `ScriptName`='boss_svala_sorrowgrave' WHERE `entry`=26668;
+UPDATE `creature_template` SET `ScriptName`='mob_ritual_channeler' WHERE `entry`=27281;
+UPDATE `creature_template` SET `ScriptName`='boss_svala' WHERE `entry`=29281;
+UPDATE `creature_template` SET `ScriptName`='boss_palehoof' WHERE `entry`=26687;
+UPDATE `creature_template` SET `ScriptName`='boss_skadi' WHERE `entry`=26693;
+UPDATE `creature_template` SET `ScriptName`='boss_ymiron' WHERE `entry`=26861;
+UPDATE `creature_template` SET `ScriptName`='mob_frenzied_worgen' WHERE `entry`=26683;
+UPDATE `creature_template` SET `ScriptName`='mob_ravenous_furbolg' WHERE `entry`=26684;
+UPDATE `creature_template` SET `ScriptName`='mob_ferocious_rhino' WHERE `entry`=26685;
+UPDATE `creature_template` SET `ScriptName`='mob_massive_jormungar' WHERE `entry`=26686;
+UPDATE `instance_template` SET `script`='instance_utgarde_pinnacle' WHERE `map`=575;
+UPDATE `gameobject_template` SET `ScriptName`='go_palehoof_sphere'WHERE `entry`=188593; \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
index d7df4d4faca..8b0b8c74b27 100644
--- a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
+++ b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
@@ -10,11 +10,44 @@ Script Data End */
update creature_template set scriptname = 'boss_palehoof' where entry = '';
*** SQL END ***/
#include "precompiled.h"
+#include "def_pinnacle.h"
//Spells
#define SPELL_ARCING_SMASH 48260
#define SPELL_IMPALE 48261
+#define H_SPELL_IMPALE 59268
#define SPELL_WITHERING_ROAR 48256
+#define H_SPELL_WITHERING_ROAR 59267
+
+#define SPELL_FREEZE 16245
+
+//ravenous furbolg's spells
+#define SPELL_CHAIN_LIGHTING 48140
+#define H_SPELL_CHAIN_LIGHTING 59273
+#define SPELL_CRAZED 48139
+#define SPELL_TERRIFYING_ROAR 48144
+
+//frenzied worgen's spells
+#define SPELL_MORTAL_WOUND 48137
+#define H_SPELL_MORTAL_WOUND 59265
+#define SPELL_ENRAGE_1 48138
+#define SPELL_ENRAGE_2 48142
+
+//ferocious rhino's spells
+#define SPELL_GORE 48130
+#define H_SPELL_GORE 59264
+#define SPELL_GRIEVOUS_WOUND 48105
+#define H_SPELL_GRIEVOUS_WOUND 59263
+#define SPELL_STOMP 48131
+
+//massive jormungar's spells
+#define SPELL_ACID_SPIT 48132
+#define SPELL_ACID_SPLATTER 48136
+#define H_SPELL_ACID_SPLATTER 59272
+#define SPELL_POISON_BREATH 48133
+#define H_SPELL_POISON_BREATH 59271
+
+#define CREATURE_JORMUNGAR_WORM 27228
//not in db
//Yell
@@ -25,49 +58,513 @@ update creature_template set scriptname = 'boss_palehoof' where entry = '';
struct TRINITY_DLL_DECL boss_palehoofAI : public ScriptedAI
{
- boss_palehoofAI(Creature *c) : ScriptedAI(c) {}
+ boss_palehoofAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiArcingSmashTimer;
+ uint32 uiImpaleTimer;
+ uint32 uiWhiteringRoarTimer;
+ uint32 uiWaitingTimer;
+
+ uint8 Phase;
+
+ bool bWaiting;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiArcingSmashTimer = 15000;
+ uiImpaleTimer = 12000;
+ uiWhiteringRoarTimer = 10000;
+
+ Phase = 0;
+ bWaiting = false;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_FREEZE);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, NOT_STARTED);
+
+ Creature* pTemp;
+ if ((pTemp = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MOB_FRENZIED_WORGEN))) && !pTemp->isAlive())
+ pTemp->Respawn();
+ if ((pTemp = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MOB_FEROCIOUS_RHINO))) && !pTemp->isAlive())
+ pTemp->Respawn();
+ if ((pTemp = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MOB_MASSIVE_JORMUNGAR))) && !pTemp->isAlive())
+ pTemp->Respawn();
+ if ((pTemp = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_MOB_RAVENOUS_FURBOLG))) && !pTemp->isAlive())
+ pTemp->Respawn();
+
+ if (GameObject* pGo = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_GORTOK_PALEHOOF_SPHERE)))
+ {
+ pGo->SetGoState(GO_STATE_READY);
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ }
+ }
- void Reset() {}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
}
- void AttackStart(Unit* who) {}
- void MoveInLineOfSight(Unit* who) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (Phase == 6)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiArcingSmashTimer < diff)
+ {
+ DoCast(m_creature,SPELL_ARCING_SMASH);
+ uiArcingSmashTimer = 13000 + rand()%4000;
+ } else uiArcingSmashTimer -= diff;
+
+ if (uiImpaleTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (pTarget)
+ DoCast(pTarget, HeroicMode ? H_SPELL_IMPALE : SPELL_IMPALE);
+ uiImpaleTimer = 8000 + rand()%4000;
+ } else uiImpaleTimer -= diff;
+
+ if (uiWhiteringRoarTimer < diff)
+ {
+ DoCast(m_creature, HeroicMode ? H_SPELL_WITHERING_ROAR : SPELL_WITHERING_ROAR);
+ uiWhiteringRoarTimer = 8000 + rand()%4000;
+ } else uiWhiteringRoarTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ else if (Phase != 0 && bWaiting)
+ {
+ if (uiWaitingTimer < diff)
+ {
+ Creature *pNext;
+ switch(Phase)
+ {
+ case 1: pNext = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_MOB_FRENZIED_WORGEN) : 0); break;
+ case 2: pNext = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_MOB_RAVENOUS_FURBOLG) : 0); break;
+ case 3: pNext = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_MOB_MASSIVE_JORMUNGAR) : 0); break;
+ case 4: pNext = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_MOB_FEROCIOUS_RHINO) : 0); break;
+ case 5: pNext = m_creature; ++Phase; break;
+ }
+
+ if (pNext)
+ {
+ pNext->RemoveAurasDueToSpell(SPELL_FREEZE);
+ pNext->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pNext->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ ((Unit*)pNext)->SetStandState(UNIT_STAND_STATE_STAND);
+ pNext->SetInCombatWithZone();
+ }
+
+ bWaiting = false;
+ } else uiWaitingTimer -= diff;
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ if (pInstance)
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
+ }
+
+ void NextPhase()
+ {
+ ++Phase;
+ bWaiting = true;
+ uiWaitingTimer = 1000;
+ }
+};
+
+struct TRINITY_DLL_DECL mob_ravenous_furbolgAI : public ScriptedAI
+{
+ mob_ravenous_furbolgAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiChainLightingTimer;
+ uint32 uiCrazedTimer;
+ uint32 uiTerrifyingRoarTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiChainLightingTimer = 5000;
+ uiCrazedTimer = 10000;
+ uiTerrifyingRoarTimer = 15000;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_FREEZE);
+ }
+
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
+ if (uiChainLightingTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), HeroicMode ? H_SPELL_CHAIN_LIGHTING : SPELL_CHAIN_LIGHTING);
+ uiChainLightingTimer = 5000 + rand()%5000;
+ } else uiChainLightingTimer -= diff;
+
+ if (uiCrazedTimer < diff)
+ {
+ DoCast(m_creature, SPELL_CRAZED);
+ uiCrazedTimer = 8000 + rand()%4000;
+ } else uiCrazedTimer -= diff;
+
+ if (uiTerrifyingRoarTimer < diff)
+ {
+ DoCast(m_creature, SPELL_TERRIFYING_ROAR);
+ uiTerrifyingRoarTimer = 10000 + rand()%10000;
+ } else uiTerrifyingRoarTimer -= diff;
+
DoMeleeAttackIfReady();
}
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (m_creature->Attack(who, true))
+ {
+ m_creature->AddThreat(who, 0.0f);
+ m_creature->SetInCombatWith(who);
+ who->SetInCombatWith(m_creature);
+ DoStartMovement(who);
+ }
+ }
+
void JustDied(Unit* killer)
{
- DoScriptText(SAY_DEATH, m_creature);
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
}
- void KilledUnit(Unit *victim)
+};
+
+struct TRINITY_DLL_DECL mob_frenzied_worgenAI : public ScriptedAI
+{
+ mob_frenzied_worgenAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiMortalWoundTimer;
+ uint32 uiEnrage1Timer;
+ uint32 uiEnrage2Timer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uint32 uiMortalWoundTimer = 5000;
+ uint32 uiEnrage1Timer = 15000;
+ uint32 uiEnrage2Timer = 10000;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_FREEZE);
+ }
+
+ void UpdateAI(const uint32 diff)
{
- if (victim == m_creature)
+ //Return since we have no target
+ if (!UpdateVictim())
return;
- switch(rand()%2)
+ if (uiMortalWoundTimer < diff)
{
- case 0:
- DoScriptText(SAY_SLAY_1, m_creature);
- break;
- case 1:
- DoScriptText(SAY_SLAY_2, m_creature);
- break;
+ DoCast(m_creature->getVictim(), HeroicMode ? H_SPELL_MORTAL_WOUND : SPELL_MORTAL_WOUND);
+ uiMortalWoundTimer = 3000 + rand()%4000;
+ } else uiMortalWoundTimer -= diff;
+
+ if (uiEnrage1Timer < diff)
+ {
+ DoCast(m_creature, SPELL_ENRAGE_1);
+ uiEnrage1Timer = 15000;
+ } else uiEnrage1Timer -= diff;
+
+ if (uiEnrage2Timer < diff)
+ {
+ DoCast(m_creature, SPELL_ENRAGE_2);
+ uiEnrage2Timer = 10000;
+ } else uiEnrage2Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (m_creature->Attack(who, true))
+ {
+ m_creature->AddThreat(who, 0.0f);
+ m_creature->SetInCombatWith(who);
+ who->SetInCombatWith(m_creature);
+ DoStartMovement(who);
+ }
+ if (pInstance)
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
}
}
};
+struct TRINITY_DLL_DECL mob_ferocious_rhinoAI : public ScriptedAI
+{
+ mob_ferocious_rhinoAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiStompTimer;
+ uint32 uiGoreTimer;
+ uint32 uiGrievousWoundTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiStompTimer = 10000;
+ uiGoreTimer = 15000;
+ uiGrievousWoundTimer = 20000;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_FREEZE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiStompTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_STOMP);
+ uiStompTimer = 8000 + rand()%4000;
+ } else uiStompTimer -= diff;
+
+ if (uiGoreTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), HeroicMode ? H_SPELL_GORE : SPELL_GORE);
+ uiGoreTimer = 13000 + rand()%4000;
+ } else uiGoreTimer -= diff;
+
+ if (uiGrievousWoundTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (pTarget)
+ DoCast(pTarget, HeroicMode ? H_SPELL_GRIEVOUS_WOUND : SPELL_GRIEVOUS_WOUND);
+ uiGrievousWoundTimer = 18000 + rand()%4000;
+ } else uiGrievousWoundTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (m_creature->Attack(who, true))
+ {
+ m_creature->AddThreat(who, 0.0f);
+ m_creature->SetInCombatWith(who);
+ who->SetInCombatWith(m_creature);
+ DoStartMovement(who);
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
+ }
+};
+
+struct TRINITY_DLL_DECL mob_massive_jormungarAI : public ScriptedAI
+{
+ mob_massive_jormungarAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiAcidSpitTimer;
+ uint32 uiAcidSplatterTimer;
+ uint32 uiPoisonBreathTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiAcidSpitTimer = 3000;
+ uiAcidSplatterTimer = 12000;
+ uiPoisonBreathTimer = 10000;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(m_creature, SPELL_FREEZE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiAcidSpitTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (pTarget)
+ DoCast(pTarget, SPELL_ACID_SPIT);
+ uiAcidSpitTimer = 2000 + rand()%2000;
+ } else uiAcidSpitTimer -= diff;
+
+ if (uiAcidSplatterTimer < diff)
+ {
+ DoCast(m_creature, HeroicMode ? H_SPELL_POISON_BREATH : SPELL_POISON_BREATH);
+ uiAcidSplatterTimer = 10000 + rand()%4000;
+ } else uiAcidSplatterTimer -= diff;
+
+ if (uiPoisonBreathTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (pTarget)
+ DoCast(pTarget, HeroicMode ? H_SPELL_POISON_BREATH : SPELL_POISON_BREATH);
+ uiPoisonBreathTimer = 8000 + rand()%4000;
+ } else uiPoisonBreathTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (m_creature->Attack(who, true))
+ {
+ m_creature->AddThreat(who, 0.0f);
+ m_creature->SetInCombatWith(who);
+ who->SetInCombatWith(m_creature);
+ DoStartMovement(who);
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI,pPalehoof->AI())->NextPhase();
+ }
+ }
+};
+
+bool GOHello_palehoof_sphere(Player *pPlayer, GameObject *pGO)
+{
+ ScriptedInstance *pInstance = pGO->GetInstanceData();
+
+ Creature *pPalehoof = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof && pPalehoof->isAlive())
+ {
+ // maybe these are hacks :(
+ pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pGO->SetGoState(GO_STATE_ACTIVE);
+
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
+ return true;
+}
+
CreatureAI* GetAI_boss_palehoof(Creature* pCreature)
{
return new boss_palehoofAI (pCreature);
}
+CreatureAI* GetAI_mob_ravenous_furbolg(Creature* pCreature)
+{
+ return new mob_ravenous_furbolgAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_frenzied_worgen(Creature* pCreature)
+{
+ return new mob_frenzied_worgenAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_ferocious_rhino(Creature* pCreature)
+{
+ return new mob_ferocious_rhinoAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_massive_jormungar(Creature* pCreature)
+{
+ return new mob_massive_jormungarAI (pCreature);
+}
+
void AddSC_boss_palehoof()
{
Script *newscript;
@@ -76,4 +573,29 @@ void AddSC_boss_palehoof()
newscript->Name="boss_palehoof";
newscript->GetAI = &GetAI_boss_palehoof;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ravenous_furbolg";
+ newscript->GetAI = &GetAI_mob_ravenous_furbolg;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_frenzied_worgen";
+ newscript->GetAI = &GetAI_mob_frenzied_worgen;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ferocious_rhino";
+ newscript->GetAI = &GetAI_mob_ferocious_rhino;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_massive_jormungar";
+ newscript->GetAI = &GetAI_mob_massive_jormungar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="go_palehoof_sphere";
+ newscript->pGOHello=&GOHello_palehoof_sphere;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
index 099174e59e2..a86e304f68f 100644
--- a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
+++ b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
@@ -10,6 +10,7 @@ Script Data End */
update creature_template set scriptname = 'boss_skadi' where entry = '';
*** SQL END ***/
#include "precompiled.h"
+#include "def_pinnacle.h"
//Phase 0 "gauntlet even" Skadi on a flying mount, waves of adds charging to the group periodicaly carrying harpoons
//Phase 1 Kill the Skadi drake mount with harppons launcher
@@ -17,8 +18,18 @@ update creature_template set scriptname = 'boss_skadi' where entry = '';
//Skadi Spells
#define SPELL_CRUSH 50234
+#define H_SPELL_CRUSH 59330
#define SPELL_POISONED_SPEAR 50225
+#define H_SPELL_POISONED_SPEAR 59331
#define SPELL_WHIRLWIND 50228 //random target, but not the tank approx. every 20s
+#define H_SPELL_WHIRLWIND 59332
+
+//Spawned creatures
+#define CREATURE_YMIRJAR_WARRIOR 26690
+#define CREATURE_YMIRJAR_WITCH_DOCTOR 26691
+#define CREATURE_YMIRJAR_HARPOONER 26692
+
+#define DATA_MOUNT 27043
//not in db
//Yell
@@ -34,42 +45,207 @@ update creature_template set scriptname = 'boss_skadi' where entry = '';
#define SAY_DRAKE_BREATH_2 -1575013
#define SAY_DRAKE_BREATH_3 -1575014
+//Spawn locations
+struct Locations
+{
+ float x, y, z;
+ uint32 id;
+};
+
+static Locations SpawnLoc[]=
+{
+ {340.556, -511.493, 104.352},
+ {367.741, -512.865, 104.828},
+ {399.546, -512.755, 104.834},
+ {430.551, -514.320, 105.055},
+ {468.931, -513.555, 104.723}
+};
+
+enum CombatPhase
+{
+ FLYING,
+ SKADI
+};
+
struct TRINITY_DLL_DECL boss_skadiAI : public ScriptedAI
{
- boss_skadiAI(Creature *c) : ScriptedAI(c) {}
+ boss_skadiAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiCrushTimer;
+ uint32 uiPoisonedSpearTimer;
+ uint32 uiWhirlwindTimer;
+ uint32 uiMovementTimer;
+ uint32 uiWaypointId;
+ uint32 uiSpawnCounter;
- uint32 phase;
+ CombatPhase Phase;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiCrushTimer = 8000;
+ uiPoisonedSpearTimer = 10000;
+ uiWhirlwindTimer = 20000;
+ uiSpawnCounter = 0;
+
+ uiWaypointId = 0;
+
+ Phase = SKADI;
+
+ m_creature->Unmount();
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, NOT_STARTED);
+ }
- void Reset() {}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
+
+ m_creature->Mount(DATA_MOUNT);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->GetMotionMaster()->MovePoint(uiWaypointId, 340.259, -510.541, 120.869);
+
+ Phase = FLYING;
+
+ if (pInstance)
+ pInstance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, IN_PROGRESS);
}
- void AttackStart(Unit* who) {}
- void MoveInLineOfSight(Unit* who) {}
+
void UpdateAI(const uint32 diff)
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ switch(Phase)
+ {
+ case FLYING:
+ if (uiMovementTimer < diff)
+ {
+ switch(uiWaypointId)
+ {
+ case 0: m_creature->GetMotionMaster()->MovePoint(uiWaypointId, 340.259, -510.541, 120.869); break;
+ case 1: m_creature->GetMotionMaster()->MovePoint(uiWaypointId, 472.977, -513.636, 120.869); break;
+ case 200:
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->Unmount();
+ Phase = SKADI;
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
+ if (pTarget)
+ AttackStart(pTarget);
+ break;
+ }
+ } else uiMovementTimer -= diff;
+ break;
+ case SKADI:
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiCrushTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), HeroicMode ? H_SPELL_CRUSH : SPELL_CRUSH);
+ uiCrushTimer = 8000;
+ } else uiCrushTimer -= diff;
- phase = 0;
+ if (uiPoisonedSpearTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ {
+ SelectUnit(SELECT_TARGET_RANDOM, 0);
+ }
+ if (pTarget)
+ DoCast(pTarget, HeroicMode ? H_SPELL_POISONED_SPEAR : SPELL_POISONED_SPEAR);
+ uiPoisonedSpearTimer = 10000;
+ } else uiPoisonedSpearTimer -= diff;
- DoMeleeAttackIfReady();
+ if (uiWhirlwindTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ while (pTarget && (pTarget->GetTypeId() != TYPEID_PLAYER || pTarget == m_creature->getVictim()))
+ {
+ SelectUnit(SELECT_TARGET_RANDOM, 0);
+ }
+ if (pTarget)
+ m_creature->CastSpell(pTarget, HeroicMode ? H_SPELL_WHIRLWIND : SPELL_WHIRLWIND, false);
+ } else uiWhirlwindTimer = 20000;
+
+ DoMeleeAttackIfReady();
+ break;
+ }
}
+
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, DONE);
}
+
void KilledUnit(Unit *victim)
{
- if (victim == m_creature)
- return;
- switch(rand()%3)
+ DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2,SAY_KILL_3), m_creature);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if(type != POINT_MOTION_TYPE)
+ return;
+
+ if (HeroicMode ? (uiSpawnCounter >= 4) : (uiSpawnCounter >= 5))
+ {
+ uiWaypointId = 200;
+ uiMovementTimer = 3000;
+ }
+ else
+ {
+ switch(id)
+ {
+ case 0:
+ SpawnMobs(uiSpawnCounter);
+ uiWaypointId = 1;
+ ++uiSpawnCounter;
+ uiMovementTimer = 3000;
+ break;
+ case 1:
+ SpawnMobs(uiSpawnCounter);
+ uiWaypointId = 0;
+ ++uiSpawnCounter;
+ uiMovementTimer = 3000;
+ break;
+ }
+ }
+ }
+
+ void SpawnMobs(uint32 spot)
+ {
+ uint8 uiMaxSpawn = (HeroicMode ? 6 : 5);
+ for(uint8 i = 0; i < uiMaxSpawn; ++i)
{
- case 0: DoScriptText(SAY_KILL_1, m_creature);break;
- case 1: DoScriptText(SAY_KILL_2, m_creature);break;
- case 2: DoScriptText(SAY_KILL_3, m_creature);break;
+ Creature* pTemp;
+ switch (rand()%3)
+ {
+ case 0: pTemp = m_creature->SummonCreature(CREATURE_YMIRJAR_WARRIOR, SpawnLoc[spot].x+rand()%5, SpawnLoc[spot].y+rand()%5, SpawnLoc[spot].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break;
+ case 1: pTemp = m_creature->SummonCreature(CREATURE_YMIRJAR_WITCH_DOCTOR, SpawnLoc[spot].x+rand()%5, SpawnLoc[spot].y+rand()%5, SpawnLoc[spot].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break;
+ case 2: pTemp = m_creature->SummonCreature(CREATURE_YMIRJAR_HARPOONER, SpawnLoc[spot].x+rand()%5, SpawnLoc[spot].y+rand()%5, SpawnLoc[spot].z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break;
+ }
+ if (pTemp)
+ {
+ pTemp->SetInCombatWithZone();
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if (pTarget)
+ pTemp->AI()->AttackStart(pTarget);
+ }
}
}
};
diff --git a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
index 4d46be7fbb2..ab3fbd9accf 100644
--- a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
+++ b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
@@ -1,6 +1,6 @@
/* Script Data Start
SDName: Boss svala
-SDAuthor: LordVanMartin
+SDAuthor: Tartalo
SD%Complete:
SDComment:
SDCategory:
@@ -10,11 +10,16 @@ Script Data End */
update creature_template set scriptname = 'boss_svala' where entry = '';
*** SQL END ***/
#include "precompiled.h"
+#include "def_pinnacle.h"
//Spells
#define SPELL_CALL_FLAMES 48258
#define SPELL_RITUAL_OF_THE_SWORD 48276 //Effect #1 Teleport, Effect #2 Dummy
#define SPELL_SINSTER_STRIKE 15667
+#define H_SPELL_SINSTER_STRIKE 59409
+
+#define SPELL_SVALA_TRANSFORMING1 54140
+#define SPELL_SVALA_TRANSFORMING2 54205
//not in db
//Yells
@@ -31,40 +36,302 @@ update creature_template set scriptname = 'boss_svala' where entry = '';
#define SAY_SACRIFICE_PLAYER_3 -1575025
#define SAY_SACRIFICE_PLAYER_4 -1575026
#define SAY_SACRIFICE_PLAYER_5 -1575027
+#define SAY_DIALOG_OF_ARTHAS_1 -1575028
+#define SAY_DIALOG_OF_ARTHAS_2 -1575029
+
+//creatures
+#define CREATURE_ARTHAS 24266
+#define CREATURE_SVALA_SORROWGRAVE 24668
+#define CREATURE_SVALA 29281
+#define CREATURE_RITUAL_CHANNELER 27281
+//ritual channeler's spells
+#define SPELL_PARALYZE 48278
+#define SPELL_SHADOWS_IN_THE_DARK 59407
+
+//other data
+#define DATA_SVALA_DISPLAY_ID 11686
+
+enum IntroPhase
+{
+ IDLE,
+ INTRO,
+ FINISHED
+};
+
+enum CombatPhase
+{
+ NORMAL,
+ SACRIFICING
+};
+
+struct Locations
+{
+ float x, y, z;
+};
+
+static Locations RitualChannelerLocations[]=
+{
+ {296.42, -355.01, 90.94},
+ {302.36, -352.01, 90.54},
+ {291.39, -350.89, 90.54}
+};
struct TRINITY_DLL_DECL boss_svalaAI : public ScriptedAI
{
- boss_svalaAI(Creature *c) : ScriptedAI(c) {}
+ boss_svalaAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiIntroTimer;
+
+ uint8 uiIntroPhase;
+
+ IntroPhase Phase;
+
+ Creature* pArthas;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ Phase = IDLE;
+ uiIntroTimer = 1000;
+ uiIntroPhase = 0;
+
+ if (pInstance)
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+ if (pWho->isTargetableForAttack() && m_creature->IsHostileTo(pWho) && Phase == IDLE && m_creature->IsWithinDistInMap(pWho, 40))
+ {
+ Phase = INTRO;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (pArthas = m_creature->SummonCreature(CREATURE_ARTHAS, 295.81, -366.16, 92.57, 1.58, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 16000))
+ {
+ pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pArthas->SetFloatValue(OBJECT_FIELD_SCALE_X, 5);
+ }
+ }
+ }
+
+ void AttackStart(Unit* who) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiIntroTimer < diff)
+ {
+ switch (uiIntroPhase)
+ {
+ case 0:
+ DoScriptText(SAY_DIALOG_WITH_ARTHAS_1, m_creature);
+ ++uiIntroPhase;
+ uiIntroTimer = 3500;
+ break;
+ case 1:
+ DoScriptText(SAY_DIALOG_OF_ARTHAS_1, pArthas);
+ ++uiIntroPhase;
+ uiIntroTimer = 3500;
+ break;
+ case 2:
+ DoScriptText(SAY_DIALOG_WITH_ARTHAS_2, m_creature);
+ ++uiIntroPhase;
+ uiIntroTimer = 3500;
+ break;
+ case 3:
+ DoScriptText(SAY_DIALOG_OF_ARTHAS_2, pArthas);
+ ++uiIntroPhase;
+ uiIntroTimer = 3500;
+ break;
+ case 4:
+ DoScriptText(SAY_DIALOG_WITH_ARTHAS_3, m_creature);
+ DoCast(m_creature,SPELL_SVALA_TRANSFORMING1);
+ ++uiIntroPhase;
+ uiIntroTimer = 2800;
+ break;
+ case 5:
+ DoCast(m_creature,SPELL_SVALA_TRANSFORMING2);
+ ++uiIntroPhase;
+ uiIntroTimer = 200;
+ break;
+ case 6:
+ if (Creature* pSvalaSorrowgrave = m_creature->SummonCreature(CREATURE_SVALA_SORROWGRAVE, 296.632, -346.075, 90.6307, 1.58, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000))
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetDisplayId(DATA_SVALA_DISPLAY_ID);
+ pArthas->DealDamage(pArthas, pArthas->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ pArthas->RemoveCorpse();
+ Phase = FINISHED;
+ }
+ else Reset();
+ break;
+ }
+ } else uiIntroTimer -= diff;
+ }
+};
+
+struct TRINITY_DLL_DECL mob_ritual_channelerAI : public ScriptedAI
+{
+ mob_ritual_channelerAI(Creature *c) :ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ DoCast(m_creature, SPELL_SHADOWS_IN_THE_DARK);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ if (who && who->HasAura(SPELL_PARALYZE,0))
+ DoCast(who,SPELL_PARALYZE);
+ return;
+ }
+};
+
+struct TRINITY_DLL_DECL boss_svala_sorrowgraveAI : public ScriptedAI
+{
+ boss_svala_sorrowgraveAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiSinsterStrikeTimer;
+ uint32 uiCallFlamesTimer;
+ uint32 uiRitualOfSwordTimer;
+ uint32 uiSacrificeTimer;
+
+ CombatPhase Phase;
+
+ Creature* pRitualChanneler[3];
+ Unit* pSacrificeTarget;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiSinsterStrikeTimer = 7000;
+ uiCallFlamesTimer = 10000;
+ uiRitualOfSwordTimer = 20000;
+ uiSacrificeTimer = 8000;
+
+ Phase = NORMAL;
+
+ DoTeleportTo(296.632, -346.075, 90.6307);
+
+ for (uint8 i = 0; i < 3; ++i)
+ pRitualChanneler[i] = NULL;
+ pSacrificeTarget = NULL;
+
+ if (pInstance)
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
+ }
- void Reset() {}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
}
- void AttackStart(Unit* who) {}
- void MoveInLineOfSight(Unit* who) {}
+
void UpdateAI(const uint32 diff)
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ if (Phase == NORMAL)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiSinsterStrikeTimer < diff)
+ {
+ DoCast(m_creature->getVictim(), HeroicMode ? H_SPELL_SINSTER_STRIKE : SPELL_SINSTER_STRIKE);
+ uiSinsterStrikeTimer = 5000 + rand()%4000;
+ } else uiSinsterStrikeTimer -= diff;
- DoMeleeAttackIfReady();
+ if (uiCallFlamesTimer < diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ while (pTarget && pTarget->GetTypeId() != TYPEID_PLAYER)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if (pTarget)
+ DoCast(pTarget, SPELL_CALL_FLAMES);
+ uiCallFlamesTimer = 8000 + rand()%4000;
+ } else uiCallFlamesTimer -= diff;
+
+ if (uiRitualOfSwordTimer < diff)
+ {
+ pSacrificeTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ while (pSacrificeTarget && pSacrificeTarget->GetTypeId() != TYPEID_PLAYER)
+ pSacrificeTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if (pSacrificeTarget)
+ {
+ DoScriptText(RAND(SAY_SACRIFICE_PLAYER_1,SAY_SACRIFICE_PLAYER_2,SAY_SACRIFICE_PLAYER_3,SAY_SACRIFICE_PLAYER_4,SAY_SACRIFICE_PLAYER_5),m_creature);
+ DoCast(pSacrificeTarget,SPELL_RITUAL_OF_THE_SWORD);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ DoTeleportTo(296.632, -346.075, 120.85);
+ Phase = SACRIFICING;
+
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ if (pRitualChanneler[i] = m_creature->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerLocations[i].x, RitualChannelerLocations[i].y, RitualChannelerLocations[i].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
+ {
+ CAST_AI(mob_ritual_channelerAI,pRitualChanneler[i])->AttackStartNoMove(pSacrificeTarget);
+ }
+ }
+ }
+ uiRitualOfSwordTimer = 18000 + rand()%4000;
+ } else uiRitualOfSwordTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ else //SACRIFICING
+ {
+ if (uiSacrificeTimer < diff)
+ {
+ bool bSacrificed = false;
+ for (uint8 i=0; i < 3; ++i)
+ {
+ if (pRitualChanneler[i] && pRitualChanneler[i]->isAlive())
+ {
+ bSacrificed = true;
+ break;
+ }
+ }
+ if (bSacrificed && pSacrificeTarget && pSacrificeTarget->isAlive())
+ m_creature->DealDamage(pSacrificeTarget, pSacrificeTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+
+ uiSacrificeTimer = 8000;
+ }
+ else uiSacrificeTimer -= diff;
+ }
}
- void JustDied(Unit* killer)
+
+ void KilledUnit(Unit* pVictim)
{
- DoScriptText(SAY_DEATH, m_creature);
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
}
- void KilledUnit(Unit *victim)
+
+ void JustDied(Unit* pKiller)
{
- if (victim == m_creature)
- return;
- switch(rand()%3)
+ if (pInstance)
{
- case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
- case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
- case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
+ Creature* pSvala = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_SVALA));
+ if (pSvala && pSvala->isAlive())
+ pKiller->DealDamage(pSvala, pSvala->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
}
+ DoScriptText(SAY_DEATH, m_creature);
}
};
@@ -73,6 +340,16 @@ CreatureAI* GetAI_boss_svala(Creature* pCreature)
return new boss_svalaAI (pCreature);
}
+CreatureAI* GetAI_mob_ritual_channeler(Creature* pCreature)
+{
+ return new mob_ritual_channelerAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_svala_sorrowgrave(Creature* pCreature)
+{
+ return new boss_svala_sorrowgraveAI(pCreature);
+}
+
void AddSC_boss_svala()
{
Script *newscript;
@@ -81,4 +358,14 @@ void AddSC_boss_svala()
newscript->Name="boss_svala";
newscript->GetAI = &GetAI_boss_svala;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ritual_channeler";
+ newscript->GetAI = &GetAI_boss_svala;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="boss_svala_sorrowgrave";
+ newscript->GetAI = &GetAI_boss_svala_sorrowgrave;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
index 4c1dae4cef6..0c2177b0d0a 100644
--- a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
+++ b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
@@ -10,6 +10,7 @@ Script Data End */
update creature_template set scriptname = 'boss_ymiron' where entry = '';
*** SQL END ***/
#include "precompiled.h"
+#include "def_pinnacle.h"
//Spells
#define SPELL_BANE 48294
@@ -35,15 +36,27 @@ update creature_template set scriptname = 'boss_ymiron' where entry = '';
struct TRINITY_DLL_DECL boss_ymironAI : public ScriptedAI
{
- boss_ymironAI(Creature *c) : ScriptedAI(c) {}
+ boss_ymironAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_KING_YMIRON_EVENT, NOT_STARTED);
+ }
- void Reset() {}
void EnterCombat(Unit* who)
{
DoScriptText(SAY_AGGRO, m_creature);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KING_YMIRON_EVENT, IN_PROGRESS);
}
- void AttackStart(Unit* who) {}
- void MoveInLineOfSight(Unit* who) {}
+
void UpdateAI(const uint32 diff)
{
//Return since we have no target
@@ -52,27 +65,24 @@ struct TRINITY_DLL_DECL boss_ymironAI : public ScriptedAI
DoMeleeAttackIfReady();
}
+
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KING_YMIRON_EVENT, DONE);
}
+
void KilledUnit(Unit *victim)
{
- if (victim == m_creature)
- return;
- switch(rand()%4)
- {
- case 0: DoScriptText(SAY_SLAY_1, m_creature);break;
- case 1: DoScriptText(SAY_SLAY_2, m_creature);break;
- case 2: DoScriptText(SAY_SLAY_3, m_creature);break;
- case 3: DoScriptText(SAY_SLAY_4, m_creature);break;
- }
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), m_creature);
}
};
CreatureAI* GetAI_boss_ymiron(Creature* pCreature)
{
- return new boss_ymironAI (pCreature);
+ return new boss_ymironAI(pCreature);
}
void AddSC_boss_ymiron()
diff --git a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/def_pinnacle.h b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/def_pinnacle.h
index 82e2173fab5..b446b441c17 100644
--- a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/def_pinnacle.h
+++ b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/def_pinnacle.h
@@ -1,4 +1,21 @@
#ifndef DEF_PINNACLE_H
#define DEF_PINNACLE_H
+#define DATA_SVALA 1
+#define DATA_SVALA_SORROWGRAVE 2
+#define DATA_GORTOK_PALEHOOF 3
+#define DATA_SKADI_THE_RUTHLESS 4
+#define DATA_KING_YMIRON 5
+
+#define DATA_SVALA_SORROWGRAVE_EVENT 6
+#define DATA_GORTOK_PALEHOOF_EVENT 7
+#define DATA_SKADI_THE_RUTHLESS_EVENT 8
+#define DATA_KING_YMIRON_EVENT 9
+
+#define DATA_MOB_FRENZIED_WORGEN 10
+#define DATA_MOB_RAVENOUS_FURBOLG 11
+#define DATA_MOB_MASSIVE_JORMUNGAR 12
+#define DATA_MOB_FEROCIOUS_RHINO 13
+
+#define DATA_GORTOK_PALEHOOF_SPHERE 14
#endif
diff --git a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
index e1361c8960e..7eb661668df 100644
--- a/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
+++ b/src/bindings/scripts/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
@@ -1,21 +1,210 @@
#include "precompiled.h"
#include "def_pinnacle.h"
+#define MAX_ENCOUNTER 4
+
+/* Utgarde Pinnacle encounters:
+0 - Svala Sorrowgrave
+1 - Gortok Palehoof
+2 - Skadi the Ruthless
+3 - King Ymiron
+*/
+
+#define ENTRY_SKADI_THE_RUTHLESS_DOOR 192173
+#define ENTRY_KING_YMIRON_DOOR 192174
+#define ENTRY_GORK_PALEHOOF_SPHERE 188593
+
struct TRINITY_DLL_DECL instance_pinnacle : public ScriptedInstance
{
instance_pinnacle(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 uiSvalaSorrowgrave;
+ uint64 uiGortokPalehoof;
+ uint64 uiSkadiTheRuthless;
+ uint64 uiKingYmiron;
+
+ uint64 uiSkadiTheRuthlessDoor;
+ uint64 uiKingYmironDoor;
+ uint64 uiGortokPalehoofSphere;
+
+ uint64 uiFrenziedWorgen;
+ uint64 uiRavenousFurbolg;
+ uint64 uiFerociousRhino;
+ uint64 uiMassiveJormungar;
+
+ uint64 uiSvala;
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool add)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case 26668: uiSvalaSorrowgrave = pCreature->GetGUID(); break;
+ case 26687: uiGortokPalehoof = pCreature->GetGUID(); break;
+ case 26693: uiSkadiTheRuthless = pCreature->GetGUID(); break;
+ case 26861: uiKingYmiron = pCreature->GetGUID(); break;
+ case 26683: uiFrenziedWorgen = pCreature->GetGUID(); break;
+ case 26684: uiRavenousFurbolg = pCreature->GetGUID(); break;
+ case 26685: uiFerociousRhino = pCreature->GetGUID(); break;
+ case 26686: uiMassiveJormungar = pCreature->GetGUID(); break;
+ case 29281: uiSvala = pCreature->GetGUID(); break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool add)
+ {
+ switch(pGo->GetEntry())
+ {
+ case ENTRY_SKADI_THE_RUTHLESS_DOOR:
+ uiSkadiTheRuthlessDoor = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE) HandleGameObject(NULL,true,pGo);
+ break;
+ case ENTRY_KING_YMIRON_DOOR:
+ uiKingYmironDoor = pGo->GetGUID();
+ if (m_auiEncounter[3] == DONE) HandleGameObject(NULL,true,pGo);
+ break;
+ case ENTRY_GORK_PALEHOOF_SPHERE:
+ uiGortokPalehoofSphere = pGo->GetGUID();
+ if (m_auiEncounter[1] == DONE)
+ {
+ HandleGameObject(NULL,true,pGo);
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_SVALA_SORROWGRAVE_EVENT:
+ m_auiEncounter[0] = data;
+ break;
+ case DATA_GORTOK_PALEHOOF_EVENT:
+ m_auiEncounter[1] = data;
+ break;
+ case DATA_SKADI_THE_RUTHLESS_EVENT:
+ if (data == DONE)
+ HandleGameObject(uiSkadiTheRuthlessDoor,true);
+ m_auiEncounter[2] = data;
+ break;
+ case DATA_KING_YMIRON_EVENT:
+ if (data == DONE)
+ HandleGameObject(uiKingYmironDoor,true);
+ m_auiEncounter[3] = data;
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_SVALA_SORROWGRAVE_EVENT: return m_auiEncounter[0];
+ case DATA_GORTOK_PALEHOOF_EVENT: return m_auiEncounter[1];
+ case DATA_SKADI_THE_RUTHLESS_EVENT: return m_auiEncounter[2];
+ case DATA_KING_YMIRON_EVENT: return m_auiEncounter[3];
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_SVALA_SORROWGRAVE: return uiSvalaSorrowgrave;
+ case DATA_GORTOK_PALEHOOF: return uiGortokPalehoof;
+ case DATA_SKADI_THE_RUTHLESS: return uiSkadiTheRuthless;
+ case DATA_KING_YMIRON: return uiKingYmiron;
+ case DATA_MOB_FRENZIED_WORGEN: return uiFrenziedWorgen;
+ case DATA_MOB_RAVENOUS_FURBOLG: return uiRavenousFurbolg;
+ case DATA_MOB_MASSIVE_JORMUNGAR: return uiMassiveJormungar;
+ case DATA_MOB_FEROCIOUS_RHINO: return uiFerociousRhino;
+ case DATA_SVALA: return uiSvala;
+ case DATA_GORTOK_PALEHOOF_SPHERE: return uiGortokPalehoofSphere;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "U P " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+
+ if (dataHead1 == 'U' && dataHead2 == 'K')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for(uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
};
-InstanceData* GetInstanceData_instance_pinnacle(Map* pMap)
+InstanceData* GetInstanceData_instance_utgarde_pinnacle(Map* pMap)
{
return new instance_pinnacle(pMap);
}
-void AddSC_instance_pinnacle()
+void AddSC_instance_utgarde_pinnacle()
{
Script *newscript;
newscript = new Script;
- newscript->Name = "instance_pinnacle";
- newscript->GetInstanceData = &GetInstanceData_instance_pinnacle;
+ newscript->Name = "instance_utgarde_pinnacle";
+ newscript->GetInstanceData = &GetInstanceData_instance_utgarde_pinnacle;
newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/system/ScriptLoader.cpp b/src/bindings/scripts/system/ScriptLoader.cpp
index 0144a5e3068..fd5abfa09d4 100644
--- a/src/bindings/scripts/system/ScriptLoader.cpp
+++ b/src/bindings/scripts/system/ScriptLoader.cpp
@@ -306,6 +306,11 @@ extern void AddSC_boss_keleseth(); //Utgarde Keep
extern void AddSC_boss_skarvald_dalronn();
extern void AddSC_boss_ingvar_the_plunderer();
extern void AddSC_instance_utgarde_keep();
+extern void AddSC_boss_svala(); //Utgarde pinnacle
+extern void AddSC_boss_palehoof();
+extern void AddSC_boss_skadi();
+extern void AddSC_boss_ymiron();
+extern void AddSC_instance_utgarde_pinnacle();
extern void AddSC_utgarde_keep();
extern void AddSC_boss_archavon(); //Vault of Archavon
extern void AddSC_boss_emalon();
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 783f74c38b8..25125c2a0dc 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -447,6 +447,10 @@ bool PetAI::_CanAttack(Unit *target)
if (me->HasReactState(REACT_PASSIVE))
return me->GetCharmInfo()->IsCommandAttack();
+ // Pets commanded to attack should not stop their approach if attacked by another creature
+ if (me->getVictim() && (me->getVictim() != target))
+ return !me->GetCharmInfo()->IsCommandAttack();
+
// From this point on, pet will always be either aggressive or defensive
// Stay - can attack if target is within range or commanded to
diff --git a/src/game/Unit.h b/src/game/Unit.h
index f8a94c3b678..961a5c980e3 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1953,7 +1953,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
//uint32 m_unit_movement_flags;
uint32 m_reactiveTimer[MAX_REACTIVE];
- int32 m_regenTimer;
+ uint32 m_regenTimer;
ThreatManager m_ThreatManager;