diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/ScriptLoader.cpp | 2 | ||||
-rw-r--r-- | src/scripts/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp | 397 | ||||
-rw-r--r-- | src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp | 249 | ||||
-rw-r--r-- | src/scripts/kalimdor/onyxias_lair/onyxias_lair.h | 65 |
5 files changed, 560 insertions, 154 deletions
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
|