aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/8265_world_script_texts.sql1
-rw-r--r--sql/updates/8265_world_scriptname.sql2
-rw-r--r--src/game/ScriptLoader.cpp2
-rw-r--r--src/scripts/CMakeLists.txt1
-rw-r--r--src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp397
-rw-r--r--src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp249
-rw-r--r--src/scripts/kalimdor/onyxias_lair/onyxias_lair.h65
7 files changed, 563 insertions, 154 deletions
diff --git a/sql/updates/8265_world_script_texts.sql b/sql/updates/8265_world_script_texts.sql
new file mode 100644
index 00000000000..8f21b86f895
--- /dev/null
+++ b/sql/updates/8265_world_script_texts.sql
@@ -0,0 +1 @@
+UPDATE `script_texts` SET `type`=3,`content_default`='%s takes in a deep breath...' WHERE `entry`=-1249004;
diff --git a/sql/updates/8265_world_scriptname.sql b/sql/updates/8265_world_scriptname.sql
new file mode 100644
index 00000000000..dfb6557beb3
--- /dev/null
+++ b/sql/updates/8265_world_scriptname.sql
@@ -0,0 +1,2 @@
+UPDATE `instance_template` SET `script`='instance_onyxias_lair' WHERE `map`=249;
+UPDATE `creature_template` SET `AIName`='EventAI' WHERE `entry`=36561;
diff --git a/src/game/ScriptLoader.cpp b/src/game/ScriptLoader.cpp
index 2a619352420..2006c091287 100644
--- a/src/game/ScriptLoader.cpp
+++ b/src/game/ScriptLoader.cpp
@@ -262,6 +262,7 @@ void AddSC_boss_landslide();
void AddSC_boss_noxxion();
void AddSC_boss_ptheradras();
void AddSC_boss_onyxia(); //Onyxia's Lair
+void AddSC_instance_onyxias_lair();
void AddSC_boss_amnennar_the_coldbringer(); //Razorfen Downs
void AddSC_razorfen_downs();
void AddSC_instance_razorfen_downs();
@@ -763,6 +764,7 @@ void AddScripts()
AddSC_boss_noxxion();
AddSC_boss_ptheradras();
AddSC_boss_onyxia(); //Onyxia's Lair
+ AddSC_instance_onyxias_lair();
AddSC_boss_amnennar_the_coldbringer(); //Razorfen Downs
AddSC_razorfen_downs();
AddSC_instance_razorfen_downs();
diff --git a/src/scripts/CMakeLists.txt b/src/scripts/CMakeLists.txt
index 47dffe924dc..c61054fd5b2 100644
--- a/src/scripts/CMakeLists.txt
+++ b/src/scripts/CMakeLists.txt
@@ -262,6 +262,7 @@ SET(scripts_STAT_SRCS
kalimdor/maraudon/boss_noxxion.cpp
kalimdor/maraudon/boss_princess_theradras.cpp
kalimdor/onyxias_lair/boss_onyxia.cpp
+ kalimdor/onyxias_lair/instance_onyxias_lair.cpp
kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp
kalimdor/razorfen_downs/razorfen_downs.cpp
kalimdor/razorfen_downs/instance_razorfen_downs.cpp
diff --git a/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp b/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp
index f14b73c0319..2d351d6c6a2 100644
--- a/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp
+++ b/src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp
@@ -1,44 +1,52 @@
-/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Onyxia
-SD%Complete: 90
-SDComment: Phase 3 need additianal code. Phase 2 requires entries in spell_target_position with specific locations. See bottom of file.
+SD%Complete: 95
+SDComment: <Known bugs>
+ Ground visual for Deep Breath effect;
+ Wing Buffet not ignoring armor;
+ Not summoning whelps on phase 3 (lacks info)
+ </Known bugs>
SDCategory: Onyxia's Lair
EndScriptData */
#include "ScriptedPch.h"
+#include "onyxias_lair.h"
-enum
+enum eYells
{
SAY_AGGRO = -1249000,
SAY_KILL = -1249001,
SAY_PHASE_2_TRANS = -1249002,
SAY_PHASE_3_TRANS = -1249003,
EMOTE_BREATH = -1249004,
+};
- SPELL_WINGBUFFET = 18500,
- SPELL_FLAMEBREATH = 18435,
- SPELL_CLEAVE = 19983,
- SPELL_TAILSWEEP = 15847,
- SPELL_KNOCK_AWAY = 19633,
-
- SPELL_ENGULFINGFLAMES = 20019,
- SPELL_DEEPBREATH = 23461,
+enum eSpells
+{
+ // Phase 1 spells
+ SPELL_WING_BUFFET = 18500,
+ SPELL_FLAME_BREATH = 18435,
+ SPELL_CLEAVE = 68868,
+ SPELL_TAIL_SWEEP = 68867,
+
+ // Phase 2 spells
+ SPELL_DEEP_BREATH = 23461,
SPELL_FIREBALL = 18392,
//Not much choise about these. We have to make own defintion on the direction/start-end point
@@ -55,20 +63,8 @@ enum
//SPELL_BREATH = 21131, // 8x in "array", different initial cast than the other arrays
- SPELL_BELLOWINGROAR = 18431,
- SPELL_HEATED_GROUND = 22191,
-
- SPELL_SUMMONWHELP = 17646,
- SPELL_SUMMONLAIRGUARD = 68968,
- NPC_WHELP = 11262,
- MAX_WHELP = 20,
- NPC_LAIRGUARD = 36561,
-
- PHASE_START = 1,
- PHASE_BREATH = 2,
- PHASE_END = 3,
-
- ACHIEV_TIMED_START_EVENT = 6601,
+ // Phase 3 spells
+ SPELL_BELLOWING_ROAR = 18431,
};
struct sOnyxMove
@@ -81,30 +77,37 @@ struct sOnyxMove
static sOnyxMove aMoveData[]=
{
- {0, 1, SPELL_BREATH_WEST_TO_EAST, -33.5561f, -182.682f, -60.9457f},//west
- {1, 0, SPELL_BREATH_EAST_TO_WEST, -31.4963f, -250.123f, -60.1278f},//east
- {2, 4, SPELL_BREATH_NW_TO_SE, 6.8951f, -180.246f, -60.896f},//north-west
- {3, 5, SPELL_BREATH_NE_TO_SW, 10.2191f, -247.912f, -60.896f},//north-east
- {4, 2, SPELL_BREATH_SE_TO_NW, -63.5156f, -240.096f, -60.477f},//south-east
- {5, 3, SPELL_BREATH_SW_TO_NE, -58.2509f, -189.020f, -60.790f},//south-west
- {6, 7, SPELL_BREATH_SOUTH_TO_NORTH, -65.8444f, -213.809f, -60.2985f},//south
- {7, 6, SPELL_BREATH_NORTH_TO_SOUTH, 22.8763f, -217.152f, -60.0548f},//north
+ {0, 1, SPELL_BREATH_WEST_TO_EAST, -33.5561f, -182.682f, -56.9457f},//west
+ {1, 0, SPELL_BREATH_EAST_TO_WEST, -31.4963f, -250.123f, -55.1278f},//east
+ {2, 4, SPELL_BREATH_NW_TO_SE, 6.8951f, -180.246f, -55.896f},//north-west
+ {3, 5, SPELL_BREATH_NE_TO_SW, 10.2191f, -247.912f, -55.896f},//north-east
+ {4, 2, SPELL_BREATH_SE_TO_NW, -63.5156f, -240.096f, -55.477f},//south-east
+ {5, 3, SPELL_BREATH_SW_TO_NE, -58.2509f, -189.020f, -55.790f},//south-west
+ {6, 7, SPELL_BREATH_SOUTH_TO_NORTH, -65.8444f, -213.809f, -55.2985f},//south
+ {7, 6, SPELL_BREATH_NORTH_TO_SOUTH, 22.8763f, -217.152f, -55.0548f},//north
};
-static float afSpawnLocations[2][3]=
+const Position MiddleRoomLocation = {-23.6155, -215.357, -55.7344};
+
+static Position aSpawnLocations[3]=
{
+ //Whelps
{-30.127, -254.463, -89.440},
- {-30.817, -177.106, -89.258}
+ {-30.817, -177.106, -89.258},
+ //Lair Guard
+ {-145.950, -212.831, -68.659}
};
struct boss_onyxiaAI : public ScriptedAI
{
- boss_onyxiaAI(Creature* pCreature) : ScriptedAI(pCreature)
+ boss_onyxiaAI(Creature* pCreature) : ScriptedAI(pCreature), Summons(me)
{
- instance = me->GetInstanceData();
+ m_pInstance = pCreature->GetInstanceData();
+ Reset();
}
- InstanceData *instance;
+ ScriptedInstance* m_pInstance;
+ SummonList Summons;
uint32 m_uiPhase;
@@ -117,21 +120,19 @@ struct boss_onyxiaAI : public ScriptedAI
uint32 m_uiMovementTimer;
sOnyxMove* m_pPointData;
- uint32 m_uiEngulfingFlamesTimer;
- uint32 m_uiSummonWhelpsTimer;
- uint32 m_uiBellowingRoarTimer;
+ uint32 m_uiFireballTimer;
uint32 m_uiWhelpTimer;
uint32 m_uiLairGuardTimer;
+ uint32 m_uiDeepBreathTimer;
- uint8 m_uiSummonCount;
- bool m_bIsSummoningWhelps;
- bool m_bIsSummoningLairGuards;
+ uint32 m_uiBellowingRoarTimer;
+ uint8 m_uiSummonWhelpCount;
+ uint8 m_uiSummonLairGuardCount;
+ bool m_bIsMoving;
+
void Reset()
{
- if (instance)
- instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
-
if (!IsCombatMovement())
SetCombatMovement(true);
@@ -146,40 +147,77 @@ struct boss_onyxiaAI : public ScriptedAI
m_uiMovementTimer = 20000;
m_pPointData = GetMoveData();
- m_uiEngulfingFlamesTimer = 15000;
- m_uiSummonWhelpsTimer = 45000;
- m_uiBellowingRoarTimer = 30000;
+ m_uiFireballTimer = 15000;
m_uiWhelpTimer = 1000;
- m_uiLairGuardTimer = 1000;
+ m_uiLairGuardTimer = 15000;
+ m_uiDeepBreathTimer = 85000;
+
+ m_uiBellowingRoarTimer = 30000;
- m_uiSummonCount = 0;
- m_bIsSummoningWhelps = false;
- m_bIsSummoningLairGuards = false;
+ Summons.DespawnAll();
+ m_uiSummonWhelpCount = 0;
+ m_uiSummonLairGuardCount = 0;
+ m_bIsMoving = false;
+
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(DATA_ONYXIA, NOT_STARTED);
+ m_pInstance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
+ m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
}
- void EnterCombat(Unit* /*pWho*/)
+ void EnterCombat(Unit* pWho)
{
DoScriptText(SAY_AGGRO, me);
me->SetInCombatWithZone();
+
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(DATA_ONYXIA, IN_PROGRESS);
+ m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ sLog.outBasic("[Onyxia] DoStartTimedAchievement(%u,%u)",ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (m_pInstance)
+ m_pInstance->SetData(DATA_ONYXIA, DONE);
- if (instance)
- instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ Summons.DespawnAll();
}
void JustSummoned(Creature *pSummoned)
{
+ pSummoned->SetInCombatWithZone();
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
pSummoned->AI()->AttackStart(pTarget);
+
+ switch (pSummoned->GetEntry())
+ {
+ case NPC_WHELP:
+ ++m_uiSummonWhelpCount;
+ break;
+ case NPC_LAIRGUARD:
+ pSummoned->setActive(true);
+ ++m_uiSummonLairGuardCount;
+ break;
+ }
+ Summons.Summon(pSummoned);
+ }
- ++m_uiSummonCount;
+ void SummonedCreatureDespawn(Creature *summon)
+ {
+ Summons.Despawn(summon);
}
- void KilledUnit(Unit* /*pVictim*/)
+ void KilledUnit(Unit* pVictim)
{
DoScriptText(SAY_KILL, me);
}
- void SpellHit(Unit * /*pCaster*/, const SpellEntry* pSpell)
+ void SpellHit(Unit *pCaster, const SpellEntry* pSpell)
{
if (pSpell->Id == SPELL_BREATH_EAST_TO_WEST ||
pSpell->Id == SPELL_BREATH_WEST_TO_EAST ||
@@ -188,11 +226,58 @@ struct boss_onyxiaAI : public ScriptedAI
pSpell->Id == SPELL_BREATH_SW_TO_NE ||
pSpell->Id == SPELL_BREATH_NE_TO_SW)
{
- if (m_pPointData)
- {
- me->GetMap()->CreatureRelocation(me, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ, 0.0f);
- me->GetMotionMaster()->MovePoint(0, -10.6155, -219.357, -87.7344);
+ m_pPointData = GetMoveData();
+ m_uiMovePoint = m_pPointData->uiLocIdEnd;
+
+ me->SetSpeed(MOVE_FLIGHT, 1.5f);
+ me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation);
+ }
+ }
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type == POINT_MOTION_TYPE)
+ {
+ switch (id)
+ {
+ case 8:
+ m_pPointData = GetMoveData();
+ if (m_pPointData)
+ {
+ me->SetSpeed(MOVE_FLIGHT, 1.0f);
+ me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
+ }
+ break;
+ case 9:
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ m_uiBellowingRoarTimer = 1000;
+ break;
+ default:
+ m_bIsMoving = false;
+ break;
+ }
+ }
+ }
+
+ void SpellHitTarget(Unit* target, const SpellEntry* pSpell)
+ {
+ //Workaround - Couldn't find a way to group this spells (All Eruption)
+ if (((pSpell->Id >= 17086 && pSpell->Id <= 17095) ||
+ (pSpell->Id == 17097) ||
+ (pSpell->Id >= 18351 && pSpell->Id <= 18361) ||
+ (pSpell->Id >= 18564 && pSpell->Id <= 18576) ||
+ (pSpell->Id >= 18578 && pSpell->Id <= 18607) ||
+ (pSpell->Id == 18609) ||
+ (pSpell->Id >= 18611 && pSpell->Id <= 18628) ||
+ (pSpell->Id >= 21132 && pSpell->Id <= 21133) ||
+ (pSpell->Id >= 21135 && pSpell->Id <= 21139) ||
+ (pSpell->Id >= 22191 && pSpell->Id <= 22202) ||
+ (pSpell->Id >= 22267 && pSpell->Id <= 22268)) &&
+ (target->GetTypeId() == TYPEID_PLAYER))
+ {
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(DATA_SHE_DEEP_BREATH_MORE, FAIL);
}
}
}
@@ -227,11 +312,54 @@ struct boss_onyxiaAI : public ScriptedAI
if (!UpdateVictim())
return;
+ //Common to PHASE_START && PHASE_END
if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END)
{
+ //Specific to PHASE_START || PHASE_END
+ if (m_uiPhase == PHASE_START)
+ {
+ if (me->GetHealth()*100 / me->GetMaxHealth() < 60)
+ {
+ m_uiPhase = PHASE_BREATH;
+
+ if (m_pInstance)
+ m_pInstance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
+
+ SetCombatMovement(false);
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
+ me->SetFlying(true);
+
+ DoScriptText(SAY_PHASE_2_TRANS, me);
+
+ if (m_pPointData)
+ me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
+
+ m_uiWhelpTimer = 1000;
+ return;
+ }
+ }
+ else
+ {
+ if (m_uiBellowingRoarTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_BELLOWING_ROAR);
+ // Eruption
+ GameObject* pFloor = NULL;
+ Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15);
+ Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, pFloor, check);
+ me->VisitNearbyGridObject(30, searcher);
+ if (m_pInstance && pFloor)
+ m_pInstance->SetData64(DATA_FLOOR_ERUPTION_GUID, pFloor->GetGUID());
+ m_uiBellowingRoarTimer = 30000;
+ }
+ else
+ m_uiBellowingRoarTimer -= uiDiff;
+ }
+
if (m_uiFlameBreathTimer <= uiDiff)
{
- DoCast(me->getVictim(), SPELL_FLAMEBREATH);
+ DoCastVictim(SPELL_FLAME_BREATH);
m_uiFlameBreathTimer = urand(10000, 20000);
}
else
@@ -239,7 +367,7 @@ struct boss_onyxiaAI : public ScriptedAI
if (m_uiTailSweepTimer <= uiDiff)
{
- DoCast(me, SPELL_TAILSWEEP);
+ DoCastAOE(SPELL_TAIL_SWEEP);
m_uiTailSweepTimer = urand(15000, 20000);
}
else
@@ -247,7 +375,7 @@ struct boss_onyxiaAI : public ScriptedAI
if (m_uiCleaveTimer <= uiDiff)
{
- DoCast(me->getVictim(), SPELL_CLEAVE);
+ DoCastVictim(SPELL_CLEAVE);
m_uiCleaveTimer = urand(2000, 5000);
}
else
@@ -255,43 +383,12 @@ struct boss_onyxiaAI : public ScriptedAI
if (m_uiWingBuffetTimer <= uiDiff)
{
- DoCast(me->getVictim(), SPELL_WINGBUFFET);
+ DoCastVictim(SPELL_WING_BUFFET);
m_uiWingBuffetTimer = urand(15000, 30000);
}
else
m_uiWingBuffetTimer -= uiDiff;
- if (m_uiPhase == PHASE_END)
- {
- if (m_uiBellowingRoarTimer <= uiDiff)
- {
- DoCast(me->getVictim(), SPELL_BELLOWINGROAR);
- m_uiBellowingRoarTimer = 30000;
- }
- else
- m_uiBellowingRoarTimer -= uiDiff;
- }
- else
- {
- if (me->GetHealth()*100 / me->GetMaxHealth() < 60)
- {
- m_uiPhase = PHASE_BREATH;
-
- SetCombatMovement(false);
-
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
-
- DoScriptText(SAY_PHASE_2_TRANS, me);
-
- if (m_pPointData)
- me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
-
- SetNextRandomPoint();
- return;
- }
- }
-
DoMeleeAttackIfReady();
}
else
@@ -299,99 +396,91 @@ struct boss_onyxiaAI : public ScriptedAI
if (me->GetHealth()*100 / me->GetMaxHealth() < 40)
{
m_uiPhase = PHASE_END;
+ if (m_pInstance)
+ m_pInstance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
DoScriptText(SAY_PHASE_3_TRANS, me);
SetCombatMovement(true);
- me->GetMotionMaster()->MoveChase(me->getVictim());
-
+ me->SetFlying(false);
+ m_bIsMoving = false;
+ me->GetMotionMaster()->MovePoint(9,me->GetHomePosition());
return;
}
- if (m_uiMovementTimer <= uiDiff)
+ if (m_uiDeepBreathTimer <= uiDiff)
{
- m_pPointData = GetMoveData();
-
- SetNextRandomPoint();
-
- m_uiMovementTimer = 25000;
-
- if (!m_pPointData)
- return;
-
- if (m_uiMovePoint == m_pPointData->uiLocIdEnd)
+ if (!m_bIsMoving)
{
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
DoScriptText(EMOTE_BREATH, me);
DoCast(me, m_pPointData->uiSpellId);
+ m_uiDeepBreathTimer = 70000;
}
- else
+ }
+ else
+ m_uiDeepBreathTimer -= uiDiff;
+
+ if (m_uiMovementTimer <= uiDiff)
+ {
+ if (!m_bIsMoving)
{
+ SetNextRandomPoint();
+ m_pPointData = GetMoveData();
+
+ if (!m_pPointData)
+ return;
+
me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
+ m_bIsMoving = true;
+ m_uiMovementTimer = 25000;
}
}
else
m_uiMovementTimer -= uiDiff;
- if (m_uiEngulfingFlamesTimer <= uiDiff)
+ if (m_uiFireballTimer <= uiDiff)
{
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
{
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_FIREBALL);
- m_uiEngulfingFlamesTimer = 8000;
+ m_uiFireballTimer = 8000;
}
}
else
- m_uiEngulfingFlamesTimer -= uiDiff; //engulfingflames is supposed to be activated by a fireball but haven't come by
+ m_uiFireballTimer -= uiDiff;
- if (m_bIsSummoningWhelps)
+ if (m_uiLairGuardTimer <= uiDiff)
{
- if (m_uiSummonCount < MAX_WHELP)
+ me->SummonCreature(NPC_LAIRGUARD, aSpawnLocations[2].GetPositionX(), aSpawnLocations[2].GetPositionY(), aSpawnLocations[2].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
+ if (m_uiSummonLairGuardCount >= RAID_MODE(1,2))
{
- if (m_uiWhelpTimer <= uiDiff)
- {
- me->SummonCreature(NPC_WHELP, afSpawnLocations[0][0], afSpawnLocations[0][1], afSpawnLocations[0][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
- me->SummonCreature(NPC_WHELP, afSpawnLocations[1][0], afSpawnLocations[1][1], afSpawnLocations[1][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
- m_uiWhelpTimer = 1000;
- }
- else
- m_uiWhelpTimer -= uiDiff;
+ m_uiSummonLairGuardCount = 0;
+ m_uiLairGuardTimer = 30000;
}
else
- {
- m_bIsSummoningWhelps = false;
- m_uiSummonCount = 0;
- m_uiSummonWhelpsTimer = 30000;
- }
+ m_uiLairGuardTimer = 2000;
}
else
+ m_uiLairGuardTimer -= uiDiff;
+
+ if (m_uiWhelpTimer <= uiDiff)
{
- if (m_uiSummonWhelpsTimer <= uiDiff)
- m_bIsSummoningWhelps = true;
- else
- m_uiSummonWhelpsTimer -= uiDiff;
- }
- if (m_bIsSummoningLairGuards)
- {
- if (m_uiLairGuardTimer <= uiDiff)
+ me->SummonCreature(NPC_WHELP, aSpawnLocations[0].GetPositionX(), aSpawnLocations[0].GetPositionY(), aSpawnLocations[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
+ me->SummonCreature(NPC_WHELP, aSpawnLocations[1].GetPositionX(), aSpawnLocations[1].GetPositionY(), aSpawnLocations[1].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
+ if (m_uiSummonWhelpCount >= RAID_MODE(20,40))
{
- me->SummonCreature(NPC_LAIRGUARD, afSpawnLocations[0][0], afSpawnLocations[0][1], afSpawnLocations[0][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
- me->SummonCreature(NPC_LAIRGUARD, afSpawnLocations[1][0], afSpawnLocations[1][1], afSpawnLocations[1][2], 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
- m_uiLairGuardTimer = 30000;
- }
+ m_uiSummonWhelpCount = 0;
+ m_uiWhelpTimer = 90000;
+ }
else
- m_uiLairGuardTimer -= uiDiff;
+ m_uiWhelpTimer = 500;
}
else
- {
- if (m_uiLairGuardTimer <= uiDiff)
- m_bIsSummoningLairGuards = true;
- else
- m_uiLairGuardTimer -= uiDiff;
- }
+ m_uiWhelpTimer -= uiDiff;
}
}
};
diff --git a/src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp b/src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp
new file mode 100644
index 00000000000..c230e28cc9d
--- /dev/null
+++ b/src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp
@@ -0,0 +1,249 @@
+/* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Instance_Onyxias_Lair
+SD%Complete: 100
+SDComment:
+SDCategory: Onyxia's Lair
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "onyxias_lair.h"
+
+struct instance_onyxias_lair : public ScriptedInstance
+{
+ instance_onyxias_lair(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ //Eruption is a BFS graph problem
+ //One map to remember all floor, one map to keep floor that still need to erupt and one queue to know what needs to be removed
+ std::map<uint64,uint32> FloorEruptionGUID[2];
+ std::queue<uint64> FloorEruptionGUIDQueue;
+
+ uint64 m_uiOnyxiasGUID;
+ uint32 m_uiOnyxiaLiftoffTimer;
+ uint32 m_uiManyWhelpsCounter;
+ uint32 m_uiEruptTimer;
+
+ uint8 m_auiEncounter[MAX_ENCOUNTER];
+
+ bool m_bAchievManyWhelpsHandleIt;
+ bool m_bAchievSheDeepBreathMore;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+
+ m_uiOnyxiasGUID = 0;
+ m_uiOnyxiaLiftoffTimer = 0;
+ m_uiManyWhelpsCounter = 0;
+ m_bAchievManyWhelpsHandleIt = false;
+ m_bAchievSheDeepBreathMore = true;
+
+ m_uiEruptTimer = 0;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool add)
+ {
+ switch (pCreature->GetEntry())
+ {
+ case NPC_ONYXIA:
+ m_uiOnyxiasGUID = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool add)
+ {
+ if ((pGo->GetGOInfo()->displayId == 4392 || pGo->GetGOInfo()->displayId == 4472) && pGo->GetGOInfo()->trap.spellId == 17731)
+ {
+ if (add)
+ FloorEruptionGUID[0].insert(std::make_pair(pGo->GetGUID(),0));
+ else
+ FloorEruptionGUID[0].erase(pGo->GetGUID());
+ return;
+ }
+
+ switch(pGo->GetEntry())
+ {
+ case GO_WHELP_SPAWNER:
+ Position pGoPos;
+ pGo->GetPosition(&pGoPos);
+ if (Creature* pTemp = pGo->SummonCreature(NPC_WHELP,pGoPos,TEMPSUMMON_CORPSE_DESPAWN))
+ {
+ pTemp->SetInCombatWithZone();
+ ++m_uiManyWhelpsCounter;
+ }
+ break;
+ }
+ }
+
+ void FloorEruption(uint64 floorEruptedGUID)
+ {
+ if (GameObject *pFloorEruption = instance->GetGameObject(floorEruptedGUID))
+ {
+ //THIS GOB IS A TRAP - What shall i do? =(
+ //Cast it spell? Copyed Heigan method
+ pFloorEruption->SendCustomAnim();
+ pFloorEruption->CastSpell(NULL, Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_10MAN_NORMAL ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId
+
+ //Get all immediatly nearby floors
+ std::list<GameObject*> nearFloorList;
+ Trinity::GameObjectInRangeCheck check(pFloorEruption->GetPositionX(), pFloorEruption->GetPositionY(), pFloorEruption->GetPositionZ(), 15);
+ Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(pFloorEruption, nearFloorList, check);
+ pFloorEruption->VisitNearbyGridObject(999, searcher);
+ //remove all that are not present on FloorEruptionGUID[1] and update treeLen on each GUID
+ for (std::list<GameObject*>::const_iterator itr = nearFloorList.begin(); itr != nearFloorList.end(); ++itr)
+ {
+ if (((*itr)->GetGOInfo()->displayId == 4392 || (*itr)->GetGOInfo()->displayId == 4472) && (*itr)->GetGOInfo()->trap.spellId == 17731)
+ {
+ uint64 nearFloorGUID = (*itr)->GetGUID();
+ if (FloorEruptionGUID[1].find(nearFloorGUID) != FloorEruptionGUID[1].end() && (*FloorEruptionGUID[1].find(nearFloorGUID)).second == 0)
+ {
+ (*FloorEruptionGUID[1].find(nearFloorGUID)).second = (*FloorEruptionGUID[1].find(floorEruptedGUID)).second+1;
+ FloorEruptionGUIDQueue.push(nearFloorGUID);
+ }
+ }
+ }
+ }
+ FloorEruptionGUID[1].erase(floorEruptedGUID);
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case DATA_ONYXIA:
+ m_auiEncounter[0] = uiData;
+ if (uiData == IN_PROGRESS)
+ SetData(DATA_SHE_DEEP_BREATH_MORE, IN_PROGRESS);
+ break;
+ case DATA_ONYXIA_PHASE:
+ if (uiData == PHASE_BREATH) //Used to mark the liftoff phase
+ {
+ m_bAchievManyWhelpsHandleIt = false;
+ m_uiManyWhelpsCounter = 0;
+ m_uiOnyxiaLiftoffTimer = 10*IN_MILISECONDS;
+ }
+ break;
+ case DATA_SHE_DEEP_BREATH_MORE:
+ if (uiData == IN_PROGRESS)
+ {
+ m_bAchievSheDeepBreathMore = true;
+ }
+ else if (uiData == FAIL)
+ {
+ m_bAchievSheDeepBreathMore = false;
+ }
+ break;
+ }
+
+ if (uiType < MAX_ENCOUNTER && uiData == DONE)
+ SaveToDB();
+ }
+
+ void SetData64(uint32 uiType, uint64 uiData)
+ {
+ switch(uiType)
+ {
+ case DATA_FLOOR_ERUPTION_GUID:
+ FloorEruptionGUID[1] = FloorEruptionGUID[0];
+ FloorEruptionGUIDQueue.push(uiData);
+ m_uiEruptTimer = 2500;
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case DATA_ONYXIA:
+ return m_auiEncounter[0];
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case DATA_ONYXIA_GUID:
+ return m_uiOnyxiasGUID;
+ }
+
+ return 0;
+ }
+
+ void Update(uint32 uiDiff)
+ {
+ if (GetData(DATA_ONYXIA) == IN_PROGRESS)
+ {
+ if (m_uiOnyxiaLiftoffTimer && m_uiOnyxiaLiftoffTimer <= uiDiff)
+ {
+ m_uiOnyxiaLiftoffTimer = 0;
+ if (m_uiManyWhelpsCounter >= 50)
+ m_bAchievManyWhelpsHandleIt = true;
+ } else m_uiOnyxiaLiftoffTimer -= uiDiff;
+ }
+
+ if (!FloorEruptionGUIDQueue.empty())
+ {
+ if (m_uiEruptTimer <= uiDiff)
+ {
+ uint32 treeHeight = 0;
+ do
+ {
+ treeHeight = (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second;
+ FloorEruption(FloorEruptionGUIDQueue.front());
+ FloorEruptionGUIDQueue.pop();
+ } while (!FloorEruptionGUIDQueue.empty() && (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second == treeHeight);
+ m_uiEruptTimer = 1000;
+ }
+ else
+ m_uiEruptTimer -= uiDiff;
+ }
+ }
+
+ bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
+ {
+ switch(criteria_id)
+ {
+ case ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER: // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
+ case ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER: // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
+ return m_bAchievManyWhelpsHandleIt;
+ case ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER: // Criteria for achievement 4404: She Deep Breaths More (10 player) Everybody evade Deep Breath
+ case ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER: // Criteria for achievement 4407: She Deep Breaths More (25 player) Everybody evade Deep Breath
+ return m_bAchievSheDeepBreathMore;
+ }
+ return false;
+ }
+};
+
+InstanceData* GetInstanceData_instance_onyxias_lair(Map* pMap)
+{
+ return new instance_onyxias_lair(pMap);
+}
+
+void AddSC_instance_onyxias_lair()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_onyxias_lair";
+ newscript->GetInstanceData = &GetInstanceData_instance_onyxias_lair;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/kalimdor/onyxias_lair/onyxias_lair.h b/src/scripts/kalimdor/onyxias_lair/onyxias_lair.h
new file mode 100644
index 00000000000..cfbbc11e396
--- /dev/null
+++ b/src/scripts/kalimdor/onyxias_lair/onyxias_lair.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_ONYXIAS_LAIR_H
+#define DEF_ONYXIAS_LAIR_H
+
+enum eData64
+{
+ DATA_ONYXIA_GUID,
+ DATA_FLOOR_ERUPTION_GUID
+};
+
+enum eInstanceData
+{
+ DATA_ONYXIA,
+ MAX_ENCOUNTER,
+
+ DATA_ONYXIA_PHASE,
+ DATA_SHE_DEEP_BREATH_MORE,
+ DATA_MANY_WHELPS_COUNT
+};
+
+enum eCreatures
+{
+ NPC_WHELP = 11262,
+ NPC_LAIRGUARD = 36561,
+
+ NPC_ONYXIA = 10184
+};
+
+enum eOnyxiaPhases
+{
+ PHASE_START = 1,
+ PHASE_BREATH = 2,
+ PHASE_END = 3
+};
+
+enum eGameObjects
+{
+ GO_WHELP_SPAWNER = 176510,
+ GO_WHELP_EGG = 176511
+};
+
+enum eAchievementData
+{
+ ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER = 12565, // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
+ ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER = 12568, // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
+ ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER = 12566, // Criteria for achievement 4404: She Deep Breaths More (10 player) Everybody evade Deep Breath
+ ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER = 12569, // Criteria for achievement 4407: She Deep Breaths More (25 player) Everybody evade Deep Breath
+ ACHIEV_TIMED_START_EVENT = 6601, // Timed event for achievement 4402, 4005: More Dots! (10,25 player) 5 min kill
+};
+#endif