diff options
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; |