From f151ffbd32391e6ecb3f6bf593174fa38cff9800 Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Mon, 7 Jun 2010 01:11:15 +0200 Subject: * Last round of script directory renames. --HG-- branch : trunk --- .../BattleForMountHyjal/boss_anetheron.cpp | 309 +++++ .../BattleForMountHyjal/boss_archimonde.cpp | 635 +++++++++ .../BattleForMountHyjal/boss_azgalor.cpp | 285 ++++ .../BattleForMountHyjal/boss_kazrogal.cpp | 197 +++ .../BattleForMountHyjal/boss_rage_winterchill.cpp | 192 +++ .../CavernsOfTime/BattleForMountHyjal/hyjal.cpp | 247 ++++ .../CavernsOfTime/BattleForMountHyjal/hyjal.h | 38 + .../CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp | 1157 ++++++++++++++++ .../CavernsOfTime/BattleForMountHyjal/hyjalAI.h | 248 ++++ .../BattleForMountHyjal/hyjal_trash.cpp | 1440 ++++++++++++++++++++ .../BattleForMountHyjal/hyjal_trash.h | 35 + .../BattleForMountHyjal/instance_hyjal.cpp | 324 +++++ .../CullingOfStratholme/boss_epoch.cpp | 156 +++ .../CullingOfStratholme/boss_infinite.cpp | 88 ++ .../CullingOfStratholme/boss_mal_ganis.cpp | 262 ++++ .../CullingOfStratholme/boss_meathook.cpp | 140 ++ .../CullingOfStratholme/boss_salramm.cpp | 170 +++ .../CullingOfStratholme/culling_of_stratholme.cpp | 1210 ++++++++++++++++ .../CullingOfStratholme/culling_of_stratholme.h | 68 + .../instance_culling_of_stratholme.cpp | 244 ++++ .../CavernsOfTime/DarkPortal/boss_aeonus.cpp | 145 ++ .../DarkPortal/boss_chrono_lord_deja.cpp | 154 +++ .../CavernsOfTime/DarkPortal/boss_temporus.cpp | 152 +++ .../CavernsOfTime/DarkPortal/dark_portal.cpp | 404 ++++++ .../CavernsOfTime/DarkPortal/dark_portal.h | 35 + .../DarkPortal/instance_dark_portal.cpp | 346 +++++ .../boss_captain_skarloc.cpp | 152 +++ .../EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp | 138 ++ .../boss_leutenant_drake.cpp | 190 +++ .../instance_old_hillsbrad.cpp | 238 ++++ .../EscapeFromDurnholdeKeep/old_hillsbrad.cpp | 658 +++++++++ .../EscapeFromDurnholdeKeep/old_hillsbrad.h | 19 + .../culling_of_stratholme/boss_epoch.cpp | 156 --- .../culling_of_stratholme/boss_infinite.cpp | 88 -- .../culling_of_stratholme/boss_mal_ganis.cpp | 262 ---- .../culling_of_stratholme/boss_meathook.cpp | 140 -- .../culling_of_stratholme/boss_salramm.cpp | 170 --- .../culling_of_stratholme.cpp | 1210 ---------------- .../culling_of_stratholme/culling_of_stratholme.h | 68 - .../instance_culling_of_stratholme.cpp | 244 ---- .../CavernsOfTime/dark_portal/boss_aeonus.cpp | 145 -- .../dark_portal/boss_chrono_lord_deja.cpp | 154 --- .../CavernsOfTime/dark_portal/boss_temporus.cpp | 152 --- .../CavernsOfTime/dark_portal/dark_portal.cpp | 404 ------ .../CavernsOfTime/dark_portal/dark_portal.h | 35 - .../dark_portal/instance_dark_portal.cpp | 346 ----- .../CavernsOfTime/hyjal/boss_anetheron.cpp | 309 ----- .../CavernsOfTime/hyjal/boss_archimonde.cpp | 635 --------- .../Kalimdor/CavernsOfTime/hyjal/boss_azgalor.cpp | 285 ---- .../Kalimdor/CavernsOfTime/hyjal/boss_kazrogal.cpp | 197 --- .../CavernsOfTime/hyjal/boss_rage_winterchill.cpp | 192 --- .../scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.cpp | 247 ---- .../scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.h | 38 - .../Kalimdor/CavernsOfTime/hyjal/hyjalAI.cpp | 1157 ---------------- .../scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.h | 248 ---- .../Kalimdor/CavernsOfTime/hyjal/hyjal_trash.cpp | 1440 -------------------- .../Kalimdor/CavernsOfTime/hyjal/hyjal_trash.h | 35 - .../CavernsOfTime/hyjal/instance_hyjal.cpp | 324 ----- .../old_hillsbrad/boss_captain_skarloc.cpp | 152 --- .../old_hillsbrad/boss_epoch_hunter.cpp | 138 -- .../old_hillsbrad/boss_leutenant_drake.cpp | 190 --- .../old_hillsbrad/instance_old_hillsbrad.cpp | 238 ---- .../CavernsOfTime/old_hillsbrad/old_hillsbrad.cpp | 658 --------- .../CavernsOfTime/old_hillsbrad/old_hillsbrad.h | 19 - 64 files changed, 10076 insertions(+), 10076 deletions(-) create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_epoch.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_infinite.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_mal_ganis.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_meathook.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_salramm.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/instance_culling_of_stratholme.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_aeonus.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_chrono_lord_deja.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_temporus.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/instance_dark_portal.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_anetheron.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_archimonde.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_azgalor.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_kazrogal.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_rage_winterchill.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/hyjal/instance_hyjal.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_captain_skarloc.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_epoch_hunter.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_leutenant_drake.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/instance_old_hillsbrad.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.h (limited to 'src/server/scripts/Kalimdor') diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp new file mode 100644 index 00000000000..14ce4a59b37 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -0,0 +1,309 @@ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "hyjal_trash.h" + +#define SPELL_CARRION_SWARM 31306 +#define SPELL_SLEEP 31298 +#define SPELL_VAMPIRIC_AURA 38196 +#define SPELL_INFERNO 31299 + +#define SAY_ONDEATH "The clock... is still... ticking." +#define SOUND_ONDEATH 10982 + +#define SAY_ONSLAY1 "Your hopes are lost!" +#define SAY_ONSLAY2 "Scream for me!" +#define SAY_ONSLAY3 "Pity, no time for a slow death!" +#define SOUND_ONSLAY1 10981 +#define SOUND_ONSLAY2 11038 +#define SOUND_ONSLAY3 11039 + +#define SAY_SWARM1 "The swarm is eager to feed!" +#define SAY_SWARM2 "Pestilence upon you!" +#define SOUND_SWARM1 10979 +#define SOUND_SWARM2 11037 + +#define SAY_SLEEP1 "You look tired..." +#define SAY_SLEEP2 "Sweet dreams..." +#define SOUND_SLEEP1 10978 +#define SOUND_SLEEP2 11545 + +#define SAY_INFERNO1 "Let fire rain from above!" +#define SAY_INFERNO2 "Earth and sky shall burn!" +#define SOUND_INFERNO1 10980 +#define SOUND_INFERNO2 11036 + +#define SAY_ONAGGRO "You are defenders of a doomed world! Flee here, and perhaps you will prolong your pathetic lives!" +#define SOUND_ONAGGRO 10977 + +struct boss_anetheronAI : public hyjal_trashAI +{ + boss_anetheronAI(Creature *c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + SpellEntry *TempSpell = GET_SPELL(SPELL_SLEEP); + if (TempSpell && TempSpell->EffectImplicitTargetA[0] != 1) + { + TempSpell->EffectImplicitTargetA[0] = 1; + TempSpell->EffectImplicitTargetB[0] = 0; + } + } + + uint32 SwarmTimer; + uint32 SleepTimer; + uint32 AuraTimer; + uint32 InfernoTimer; + bool pGo; + uint32 pos; + + void Reset() + { + damageTaken = 0; + SwarmTimer = 45000; + SleepTimer = 60000; + AuraTimer = 5000; + InfernoTimer = 45000; + + if (pInstance && IsEvent) + pInstance->SetData(DATA_ANETHERONEVENT, NOT_STARTED); + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance && IsEvent) + pInstance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS); + DoPlaySoundToSet(me, SOUND_ONAGGRO); + me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); + } + + void KilledUnit(Unit * /*victim*/) + { + switch (urand(0,2)) + { + case 0: + DoPlaySoundToSet(me, SOUND_ONSLAY1); + me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0); + break; + case 1: + DoPlaySoundToSet(me, SOUND_ONSLAY2); + me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0); + break; + case 2: + DoPlaySoundToSet(me, SOUND_ONSLAY3); + me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0); + break; + } + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + + void JustDied(Unit *victim) + { + hyjal_trashAI::JustDied(victim); + if (pInstance && IsEvent) + pInstance->SetData(DATA_ANETHERONEVENT, DONE); + DoPlaySoundToSet(me, SOUND_ONDEATH); + me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0); + } + + void UpdateAI(const uint32 diff) + { + if (IsEvent) + { + //Must update npc_escortAI + npc_escortAI::UpdateAI(diff); + if (!pGo) + { + pGo = true; + if (pInstance) + { + AddWaypoint(0, 4896.08, -1576.35, 1333.65); + AddWaypoint(1, 4898.68, -1615.02, 1329.48); + AddWaypoint(2, 4907.12, -1667.08, 1321.00); + AddWaypoint(3, 4963.18, -1699.35, 1340.51); + AddWaypoint(4, 4989.16, -1716.67, 1335.74); + AddWaypoint(5, 5026.27, -1736.89, 1323.02); + AddWaypoint(6, 5037.77, -1770.56, 1324.36); + AddWaypoint(7, 5067.23, -1789.95, 1321.17); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + + //Return since we have no target + if (!UpdateVictim()) + return; + + if (SwarmTimer <= diff) + { + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(pTarget, SPELL_CARRION_SWARM); + + SwarmTimer = urand(45000,60000); + switch (urand(0,1)) + { + case 0: + DoPlaySoundToSet(me, SOUND_SWARM1); + me->MonsterYell(SAY_SWARM1, LANG_UNIVERSAL, 0); + break; + case 1: + DoPlaySoundToSet(me, SOUND_SWARM2); + me->MonsterYell(SAY_SWARM2, LANG_UNIVERSAL, 0); + break; + } + } else SwarmTimer -= diff; + + if (SleepTimer <= diff) + { + for (uint8 i = 0; i < 3; ++i) + { + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + pTarget->CastSpell(pTarget,SPELL_SLEEP,true); + } + SleepTimer = 60000; + switch (urand(0,1)) + { + case 0: + DoPlaySoundToSet(me, SOUND_SLEEP1); + me->MonsterYell(SAY_SLEEP1, LANG_UNIVERSAL, 0); + break; + case 1: + DoPlaySoundToSet(me, SOUND_SLEEP2); + me->MonsterYell(SAY_SLEEP2, LANG_UNIVERSAL, 0); + break; + } + } else SleepTimer -= diff; + if (AuraTimer <= diff) + { + DoCast(me, SPELL_VAMPIRIC_AURA, true); + AuraTimer = urand(10000,20000); + } else AuraTimer -= diff; + if (InfernoTimer <= diff) + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO); + InfernoTimer = 45000; + switch (urand(0,1)) + { + case 0: + DoPlaySoundToSet(me, SOUND_INFERNO1); + me->MonsterYell(SAY_INFERNO1, LANG_UNIVERSAL, 0); + break; + case 1: + DoPlaySoundToSet(me, SOUND_INFERNO2); + me->MonsterYell(SAY_INFERNO2, LANG_UNIVERSAL, 0); + break; + } + } else InfernoTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_anetheron(Creature* pCreature) +{ + return new boss_anetheronAI (pCreature); +} + +#define SPELL_IMMOLATION 31303 +#define SPELL_INFERNO_EFFECT 31302 + +struct mob_towering_infernalAI : public ScriptedAI +{ + mob_towering_infernalAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + if (pInstance) + AnetheronGUID = pInstance->GetData64(DATA_ANETHERON); + } + + uint32 ImmolationTimer; + uint32 CheckTimer; + uint64 AnetheronGUID; + ScriptedInstance* pInstance; + + void Reset() + { + DoCast(me, SPELL_INFERNO_EFFECT); + ImmolationTimer = 5000; + CheckTimer = 5000; + } + + void EnterCombat(Unit * /*who*/) + { + } + + void KilledUnit(Unit * /*victim*/) + { + } + + void JustDied(Unit * /*victim*/) + { + } + + void MoveInLineOfSight(Unit *who) + { + if (me->IsWithinDist(who, 50) && !me->isInCombat() && me->IsHostileTo(who)) + AttackStart(who); + } + + void UpdateAI(const uint32 diff) + { + if (CheckTimer <= diff) + { + if (AnetheronGUID) + { + Creature* boss = Unit::GetCreature((*me),AnetheronGUID); + if (!boss || (boss && boss->isDead())) + { + me->setDeathState(JUST_DIED); + me->RemoveCorpse(); + return; + } + } + CheckTimer = 5000; + } else CheckTimer -= diff; + + //Return since we have no target + if (!UpdateVictim()) + return; + + if (ImmolationTimer <= diff) + { + DoCast(me, SPELL_IMMOLATION); + ImmolationTimer = 5000; + } else ImmolationTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_towering_infernal(Creature* pCreature) +{ + return new mob_towering_infernalAI (pCreature); +} + +void AddSC_boss_anetheron() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_anetheron"; + newscript->GetAI = &GetAI_boss_anetheron; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_towering_infernal"; + newscript->GetAI = &GetAI_mob_towering_infernal; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp new file mode 100644 index 00000000000..8e1fa378e07 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -0,0 +1,635 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Archimonde +SD%Complete: 85 +SDComment: Doomfires not completely offlike due to core limitations for random moving. Tyrande and second phase not fully implemented. +SDCategory: Caverns of Time, Mount Hyjal +EndScriptData */ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "SpellAuras.h" +#include "hyjal_trash.h" + +//text id -1534018 are the text used when previous events complete. Not part of this script. +#define SAY_AGGRO -1534019 +#define SAY_DOOMFIRE1 -1534020 +#define SAY_DOOMFIRE2 -1534021 +#define SAY_AIR_BURST1 -1534022 +#define SAY_AIR_BURST2 -1534023 +#define SAY_SLAY1 -1534024 +#define SAY_SLAY2 -1534025 +#define SAY_SLAY3 -1534026 +#define SAY_ENRAGE -1534027 +#define SAY_DEATH -1534028 +#define SAY_SOUL_CHARGE1 -1534029 +#define SAY_SOUL_CHARGE2 -1534030 + +#define SPELL_DENOUEMENT_WISP 32124 +#define SPELL_ANCIENT_SPARK 39349 +#define SPELL_PROTECTION_OF_ELUNE 38528 + +#define SPELL_DRAIN_WORLD_TREE 39140 +#define SPELL_DRAIN_WORLD_TREE_2 39141 + +#define SPELL_FINGER_OF_DEATH 31984 +#define SPELL_HAND_OF_DEATH 35354 +#define SPELL_AIR_BURST 32014 +#define SPELL_GRIP_OF_THE_LEGION 31972 +#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures +#define SPELL_DOOMFIRE_SPAWN 32074 +#define SPELL_DOOMFIRE 31945 +#define SPELL_SOUL_CHARGE_YELLOW 32045 +#define SPELL_SOUL_CHARGE_GREEN 32051 +#define SPELL_SOUL_CHARGE_RED 32052 +#define SPELL_UNLEASH_SOUL_YELLOW 32054 +#define SPELL_UNLEASH_SOUL_GREEN 32057 +#define SPELL_UNLEASH_SOUL_RED 32053 +#define SPELL_FEAR 31970 + +#define CREATURE_ARCHIMONDE 17968 +#define CREATURE_DOOMFIRE 18095 +#define CREATURE_DOOMFIRE_SPIRIT 18104 +#define CREATURE_ANCIENT_WISP 17946 +#define CREATURE_CHANNEL_TARGET 22418 + +#define NORDRASSIL_X 5503.713 +#define NORDRASSIL_Y -3523.436 +#define NORDRASSIL_Z 1608.781 + +struct mob_ancient_wispAI : public ScriptedAI +{ + mob_ancient_wispAI(Creature* c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + ArchimondeGUID = 0; + } + + ScriptedInstance* pInstance; + uint64 ArchimondeGUID; + uint32 CheckTimer; + + void Reset() + { + CheckTimer = 1000; + + if (pInstance) + ArchimondeGUID = pInstance->GetData64(DATA_ARCHIMONDE); + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void EnterCombat(Unit* /*who*/) {} + + void DamageTaken(Unit* /*done_by*/, uint32 &damage) { damage = 0; } + + void UpdateAI(const uint32 diff) + { + if (CheckTimer <= diff) + { + if (Unit* Archimonde = Unit::GetUnit((*me), ArchimondeGUID)) + { + if ((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive()) + DoCast(me, SPELL_DENOUEMENT_WISP); + else + DoCast(Archimonde, SPELL_ANCIENT_SPARK); + } + CheckTimer = 1000; + } else CheckTimer -= diff; + } +}; + +/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will + MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */ +struct mob_doomfireAI : public ScriptedAI +{ + mob_doomfireAI(Creature* c) : ScriptedAI(c) {} + + void Reset() { } + + void MoveInLineOfSight(Unit* /*who*/) {} + void EnterCombat(Unit* /*who*/) {} + void DamageTaken(Unit * /*done_by*/, uint32 &damage) { damage = 0; } +}; + +/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or + travels in random directions if pTarget cannot be found. */ +struct mob_doomfire_targettingAI : public ScriptedAI +{ + mob_doomfire_targettingAI(Creature* c) : ScriptedAI(c) {} + + uint64 TargetGUID; + uint32 ChangeTargetTimer; + + void Reset() + { + TargetGUID = 0; + ChangeTargetTimer = 5000; + } + + void MoveInLineOfSight(Unit* who) + { + //will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0 + //when UpdateAI needs it, it will be forced to select randomPoint + if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER) + TargetGUID = who->GetGUID(); + } + + void EnterCombat(Unit* /*who*/) {} + + void DamageTaken(Unit * /*done_by*/, uint32 &damage) { damage = 0; } + + void UpdateAI(const uint32 diff) + { + if (ChangeTargetTimer <= diff) + { + if (Unit *temp = Unit::GetUnit(*me,TargetGUID)) + { + me->GetMotionMaster()->MoveFollow(temp,0.0f,0.0f); + TargetGUID = 0; + } + else + { + Position pos; + me->GetRandomNearPosition(pos, 40); + me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ); + } + + ChangeTargetTimer = 5000; + } else ChangeTargetTimer -= diff; + } +}; + +/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers. + The only complicated aspect of the battle is Finger of Death and Doomfire, with Doomfire being the + hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then + select a random pTarget and cast the spell on them. However, if someone IS in melee range, and this + is NOT the main tank (creature's victim), then we aggro that player and they become the new victim. + For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will + randomly select it's pTarget to follow and then we create the random movement making it unpredictable. */ + +struct boss_archimondeAI : public hyjal_trashAI +{ + boss_archimondeAI(Creature *c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance* pInstance; + + uint64 DoomfireSpiritGUID; + uint64 WorldTreeGUID; + + uint32 DrainNordrassilTimer; + uint32 FearTimer; + uint32 AirBurstTimer; + uint32 GripOfTheLegionTimer; + uint32 DoomfireTimer; + uint32 SoulChargeTimer; + uint32 SoulChargeCount; + uint32 MeleeRangeCheckTimer; + uint32 HandOfDeathTimer; + uint32 SummonWispTimer; + uint32 WispCount; + uint32 EnrageTimer; + uint32 CheckDistanceTimer; + + bool Enraged; + bool BelowTenPercent; + bool HasProtected; + bool IsChanneling; + + void Reset() + { + if (pInstance) + pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED); + + DoomfireSpiritGUID = 0; + damageTaken = 0; + WorldTreeGUID = 0; + + DrainNordrassilTimer = 0; + FearTimer = 42000; + AirBurstTimer = 30000; + GripOfTheLegionTimer = urand(5000,25000); + DoomfireTimer = 20000; + SoulChargeTimer = urand(2000,30000); + SoulChargeCount = 0; + MeleeRangeCheckTimer = 15000; + HandOfDeathTimer = 2000; + WispCount = 0; // When ~30 wisps are summoned, Archimonde dies + EnrageTimer = 600000; // 10 minutes + CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage + SummonWispTimer = 0; + + Enraged = false; + BelowTenPercent = false; + HasProtected = false; + IsChanneling = false; + } + + void EnterCombat(Unit * /*who*/) + { + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + DoScriptText(SAY_AGGRO, me); + DoZoneInCombat(); + + if (pInstance) + pInstance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS); + } + + void KilledUnit(Unit * victim) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me); + + if (victim && (victim->GetTypeId() == TYPEID_PLAYER)) + GainSoulCharge(CAST_PLR(victim)); + } + + void GainSoulCharge(Player* victim) + { + switch(victim->getClass()) + { + case CLASS_PRIEST: + case CLASS_PALADIN: + case CLASS_WARLOCK: + victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true); + break; + case CLASS_MAGE: + case CLASS_ROGUE: + case CLASS_WARRIOR: + victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true); + break; + case CLASS_DRUID: + case CLASS_SHAMAN: + case CLASS_HUNTER: + victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true); + break; + } + + SoulChargeTimer = urand(2000,30000); + ++SoulChargeCount; + } + + void JustDied(Unit *victim) + { + hyjal_trashAI::JustDied(victim); + DoScriptText(SAY_DEATH, me); + + if (pInstance) + pInstance->SetData(DATA_ARCHIMONDEEVENT, DONE); + } + + bool CanUseFingerOfDeath() + { + // First we check if our current victim is in melee range or not. + Unit* victim = me->getVictim(); + if (victim && me->IsWithinDistInMap(victim, me->GetAttackDistance(victim))) + return false; + + std::list& m_threatlist = me->getThreatManager().getThreatList(); + if (m_threatlist.empty()) + return false; + + std::list targets; + std::list::const_iterator itr = m_threatlist.begin(); + for (; itr != m_threatlist.end(); ++itr) + { + Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (pUnit && pUnit->isAlive()) + targets.push_back(pUnit); + } + + if (targets.empty()) + return false; + + targets.sort(Trinity::ObjectDistanceOrderPred(me)); + Unit *pTarget = targets.front(); + if (pTarget) + { + if (!me->IsWithinDistInMap(pTarget, me->GetAttackDistance(pTarget))) + return true; // Cast Finger of Death + else // This target is closest, he is our new tank + me->AddThreat(pTarget, me->getThreatManager().getThreat(me->getVictim())); + } + + return false; + } + + void JustSummoned(Creature *summoned) + { + if (summoned->GetEntry() == CREATURE_ANCIENT_WISP) + summoned->AI()->AttackStart(me); + else + { + summoned->setFaction(me->getFaction()); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT) + { + DoomfireSpiritGUID = summoned->GetGUID(); + } + + if (summoned->GetEntry() == CREATURE_DOOMFIRE) + { + summoned->CastSpell(summoned,SPELL_DOOMFIRE_SPAWN,false); + summoned->CastSpell(summoned,SPELL_DOOMFIRE,true,0,0,me->GetGUID()); + + if (Unit *DoomfireSpirit = Unit::GetUnit(*me, DoomfireSpiritGUID)) + { + summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit,0.0f,0.0f); + DoomfireSpiritGUID = 0; + } + } + } + + //this is code doing close to what the summoning spell would do (spell 31903) + void SummonDoomfire(Unit *pTarget) + { + me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT, + pTarget->GetPositionX()+15.0,pTarget->GetPositionY()+15.0,pTarget->GetPositionZ(),0, + TEMPSUMMON_TIMED_DESPAWN, 27000); + + me->SummonCreature(CREATURE_DOOMFIRE, + pTarget->GetPositionX()-15.0,pTarget->GetPositionY()-15.0,pTarget->GetPositionZ(),0, + TEMPSUMMON_TIMED_DESPAWN, 27000); + } + + void UnleashSoulCharge() + { + me->InterruptNonMeleeSpells(false); + + bool HasCast = false; + uint32 chargeSpell = 0; + uint32 unleashSpell = 0; + + switch (urand(0,2)) + { + case 0: + chargeSpell = SPELL_SOUL_CHARGE_RED; + unleashSpell = SPELL_UNLEASH_SOUL_RED; + break; + case 1: + chargeSpell = SPELL_SOUL_CHARGE_YELLOW; + unleashSpell = SPELL_UNLEASH_SOUL_YELLOW; + break; + case 2: + chargeSpell = SPELL_SOUL_CHARGE_GREEN; + unleashSpell = SPELL_UNLEASH_SOUL_GREEN; + break; + } + + if (me->HasAura(chargeSpell)) + { + me->RemoveAuraFromStack(chargeSpell); + DoCast(me->getVictim(), unleashSpell); + HasCast = true; + SoulChargeCount--; + } + + if (HasCast) + SoulChargeTimer = urand(2000,30000); + } + + void UpdateAI(const uint32 diff) + { + if (!me->isInCombat()) + { + if (pInstance) + { + // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. + if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((me->GetVisibility() != VISIBILITY_OFF) || (me->getFaction() != 35))) + { + me->SetVisibility(VISIBILITY_OFF); + me->setFaction(35); + } + else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((me->GetVisibility() != VISIBILITY_ON) || (me->getFaction() == 35))) + { + me->setFaction(1720); + me->SetVisibility(VISIBILITY_ON); + } + } + + if (DrainNordrassilTimer <= diff) + { + if (!IsChanneling) + { + Creature *temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000); + + if (temp) + WorldTreeGUID = temp->GetGUID(); + + if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) + { + Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Nordrassil->SetDisplayId(11686); + DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); + IsChanneling = true; + } + } + + if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) + { + Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); + DrainNordrassilTimer = 1000; + } + } else DrainNordrassilTimer -= diff; + } + + if (!UpdateVictim()) + return; + + if (((me->GetHealth()*100 / me->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged) + BelowTenPercent = true; + + if (!Enraged) + { + if (EnrageTimer <= diff) + { + if ((me->GetHealth()*100 / me->GetMaxHealth()) > 10) + { + me->GetMotionMaster()->Clear(false); + me->GetMotionMaster()->MoveIdle(); + Enraged = true; + DoScriptText(SAY_ENRAGE, me); + } + } else EnrageTimer -= diff; + + if (CheckDistanceTimer <= diff) + { + // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature + Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000); + if (Check) + { + Check->SetVisibility(VISIBILITY_OFF); + + if (me->IsWithinDistInMap(Check, 75)) + { + me->GetMotionMaster()->Clear(false); + me->GetMotionMaster()->MoveIdle(); + Enraged = true; + DoScriptText(SAY_ENRAGE, me); + } + } + CheckDistanceTimer = 5000; + } else CheckDistanceTimer -= diff; + } + + if (BelowTenPercent) + { + if (!HasProtected) + { + me->GetMotionMaster()->Clear(false); + me->GetMotionMaster()->MoveIdle(); + + //all members of raid must get this buff + DoCast(me->getVictim(), SPELL_PROTECTION_OF_ELUNE); + HasProtected = true; + Enraged = true; + } + + if (SummonWispTimer <= diff) + { + DoSpawnCreature(CREATURE_ANCIENT_WISP, rand()%40, rand()%40, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); + SummonWispTimer = 1500; + ++WispCount; + } else SummonWispTimer -= diff; + + if (WispCount >= 30) + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + if (Enraged) + { + if (HandOfDeathTimer <= diff) + { + DoCast(me->getVictim(), SPELL_HAND_OF_DEATH); + HandOfDeathTimer = 2000; + } else HandOfDeathTimer -= diff; + return; // Don't do anything after this point. + } + + if (SoulChargeCount) + { + if (SoulChargeTimer <= diff) + UnleashSoulCharge(); + else SoulChargeTimer -= diff; + } + + if (GripOfTheLegionTimer <= diff) + { + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); + GripOfTheLegionTimer = urand(5000,25000); + } else GripOfTheLegionTimer -= diff; + + if (AirBurstTimer <= diff) + { + if (urand(0,1)) + DoScriptText(SAY_AIR_BURST1, me); + else + DoScriptText(SAY_AIR_BURST2, me); + + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank + AirBurstTimer = urand(25000,40000); + } else AirBurstTimer -= diff; + + if (FearTimer <= diff) + { + DoCast(me->getVictim(), SPELL_FEAR); + FearTimer = 42000; + } else FearTimer -= diff; + + if (DoomfireTimer <= diff) + { + if (urand(0,1)) + DoScriptText(SAY_DOOMFIRE1, me); + else + DoScriptText(SAY_DOOMFIRE2, me); + + Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1); + if (!temp) + temp = me->getVictim(); + + //replace with spell cast 31903 once implicitTarget 73 implemented + SummonDoomfire(temp); + + //supposedly three doomfire can be up at the same time + DoomfireTimer = 20000; + } else DoomfireTimer -= diff; + + if (MeleeRangeCheckTimer <= diff) + { + if (CanUseFingerOfDeath()) + { + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); + MeleeRangeCheckTimer = 1000; + } + + MeleeRangeCheckTimer = 5000; + } else MeleeRangeCheckTimer -= diff; + + DoMeleeAttackIfReady(); + } + void WaypointReached(uint32 /*i*/){} +}; + +CreatureAI* GetAI_boss_archimonde(Creature* pCreature) +{ + return new boss_archimondeAI (pCreature); +} + +CreatureAI* GetAI_mob_doomfire(Creature* pCreature) +{ + return new mob_doomfireAI(pCreature); +} + +CreatureAI* GetAI_mob_doomfire_targetting(Creature* pCreature) +{ + return new mob_doomfire_targettingAI(pCreature); +} + +CreatureAI* GetAI_mob_ancient_wisp(Creature* pCreature) +{ + return new mob_ancient_wispAI(pCreature); +} + +void AddSC_boss_archimonde() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_archimonde"; + newscript->GetAI = &GetAI_boss_archimonde; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_doomfire"; + newscript->GetAI = &GetAI_mob_doomfire; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_doomfire_targetting"; + newscript->GetAI = &GetAI_mob_doomfire_targetting; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ancient_wisp"; + newscript->GetAI = &GetAI_mob_ancient_wisp; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp new file mode 100644 index 00000000000..69e37f7f740 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -0,0 +1,285 @@ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "hyjal_trash.h" + +#define SPELL_RAIN_OF_FIRE 31340 +#define SPELL_DOOM 31347 +#define SPELL_HOWL_OF_AZGALOR 31344 +#define SPELL_CLEAVE 31345 +#define SPELL_BERSERK 26662 + +#define SAY_ONDEATH "Your time is almost... up" +#define SOUND_ONDEATH 11002 + +#define SAY_ONSLAY1 "Reesh, hokta!" +#define SAY_ONSLAY2 "Don't fight it" +#define SAY_ONSLAY3 "No one is going to save you" +#define SOUND_ONSLAY1 11001 +#define SOUND_ONSLAY2 11048 +#define SOUND_ONSLAY3 11047 + +#define SAY_DOOM1 "Just a taste... of what awaits you" +#define SAY_DOOM2 "Suffer you despicable insect!" +#define SOUND_DOOM1 11046 +#define SOUND_DOOM2 11000 + +#define SAY_ONAGGRO "Abandon all hope! The legion has returned to finish what was begun so many years ago. This time there will be no escape!" +#define SOUND_ONAGGRO 10999 + +struct boss_azgalorAI : public hyjal_trashAI +{ + boss_azgalorAI(Creature *c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + SpellEntry *TempSpell = GET_SPELL(SPELL_HOWL_OF_AZGALOR); + if (TempSpell) + TempSpell->EffectRadiusIndex[0] = 12;//100yards instead of 50000?! + } + + uint32 RainTimer; + uint32 DoomTimer; + uint32 HowlTimer; + uint32 CleaveTimer; + uint32 EnrageTimer; + bool enraged; + + bool pGo; + uint32 pos; + + void Reset() + { + damageTaken = 0; + RainTimer = 20000; + DoomTimer = 50000; + HowlTimer = 30000; + CleaveTimer = 10000; + EnrageTimer = 600000; + enraged = false; + + if (pInstance && IsEvent) + pInstance->SetData(DATA_AZGALOREVENT, NOT_STARTED); + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance && IsEvent) + pInstance->SetData(DATA_AZGALOREVENT, IN_PROGRESS); + DoPlaySoundToSet(me, SOUND_ONAGGRO); + me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, NULL); + } + + void KilledUnit(Unit * /*victim*/) + { + switch (urand(0,2)) + { + case 0: + DoPlaySoundToSet(me, SOUND_ONSLAY1); + me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, NULL); + break; + case 1: + DoPlaySoundToSet(me, SOUND_ONSLAY2); + me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, NULL); + break; + case 2: + DoPlaySoundToSet(me, SOUND_ONSLAY3); + me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, NULL); + break; + } + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + + void JustDied(Unit *victim) + { + hyjal_trashAI::JustDied(victim); + if (pInstance && IsEvent) + pInstance->SetData(DATA_AZGALOREVENT, DONE); + DoPlaySoundToSet(me, SOUND_ONDEATH); + } + + void UpdateAI(const uint32 diff) + { + if (IsEvent) + { + //Must update npc_escortAI + npc_escortAI::UpdateAI(diff); + if (!pGo) + { + pGo = true; + if (pInstance) + { + AddWaypoint(0, 5492.91, -2404.61, 1462.63); + AddWaypoint(1, 5531.76, -2460.87, 1469.55); + AddWaypoint(2, 5554.58, -2514.66, 1476.12); + AddWaypoint(3, 5554.16, -2567.23, 1479.90); + AddWaypoint(4, 5540.67, -2625.99, 1480.89); + AddWaypoint(5, 5508.16, -2659.2, 1480.15); + AddWaypoint(6, 5489.62, -2704.05, 1482.18); + AddWaypoint(7, 5457.04, -2726.26, 1485.10); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + + //Return since we have no target + if (!UpdateVictim()) + return; + + if (RainTimer <= diff) + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,30,true), SPELL_RAIN_OF_FIRE); + RainTimer = 20000+rand()%15000; + } else RainTimer -= diff; + + if (DoomTimer <= diff) + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM,1,100,true), SPELL_DOOM);//never on tank + DoomTimer = 45000+rand()%5000; + } else DoomTimer -= diff; + + if (HowlTimer <= diff) + { + DoCast(me, SPELL_HOWL_OF_AZGALOR); + HowlTimer = 30000; + } else HowlTimer -= diff; + + if (CleaveTimer <= diff) + { + DoCast(me->getVictim(), SPELL_CLEAVE); + CleaveTimer = 10000+rand()%5000; + } else CleaveTimer -= diff; + + if (EnrageTimer < diff && !enraged) + { + me->InterruptNonMeleeSpells(false); + DoCast(me, SPELL_BERSERK, true); + enraged = true; + EnrageTimer = 600000; + } else EnrageTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_azgalor(Creature* pCreature) +{ + return new boss_azgalorAI (pCreature); +} + +#define SPELL_THRASH 12787 +#define SPELL_CRIPPLE 31406 +#define SPELL_WARSTOMP 31408 + +struct mob_lesser_doomguardAI : public hyjal_trashAI +{ + mob_lesser_doomguardAI(Creature *c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + if (pInstance) + AzgalorGUID = pInstance->GetData64(DATA_AZGALOR); + } + + uint32 CrippleTimer; + uint32 WarstompTimer; + uint32 CheckTimer; + uint64 AzgalorGUID; + ScriptedInstance* pInstance; + + void Reset() + { + CrippleTimer = 50000; + WarstompTimer = 10000; + DoCast(me, SPELL_THRASH); + CheckTimer = 5000; + } + + void EnterCombat(Unit * /*who*/) + { + } + + void KilledUnit(Unit * /*victim*/) + { + } + + void WaypointReached(uint32 /*i*/) + { + } + + void MoveInLineOfSight(Unit *who) + { + if (me->IsWithinDist(who, 50) && !me->isInCombat() && me->IsHostileTo(who)) + AttackStart(who); + } + + void JustDied(Unit * /*victim*/) + { + } + + void UpdateAI(const uint32 diff) + { + if (CheckTimer <= diff) + { + if (AzgalorGUID) + { + Creature* boss = Unit::GetCreature((*me),AzgalorGUID); + if (!boss || (boss && boss->isDead())) + { + me->setDeathState(JUST_DIED); + me->RemoveCorpse(); + return; + } + } + CheckTimer = 5000; + } else CheckTimer -= diff; + + //Return since we have no target + if (!UpdateVictim()) + return; + + if (WarstompTimer <= diff) + { + DoCast(me, SPELL_WARSTOMP); + WarstompTimer = 10000+rand()%5000; + } else WarstompTimer -= diff; + + if (CrippleTimer <= diff) + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CRIPPLE); + CrippleTimer = 25000+rand()%5000; + } else CrippleTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_lesser_doomguard(Creature* pCreature) +{ + return new mob_lesser_doomguardAI (pCreature); +} + +void AddSC_boss_azgalor() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_azgalor"; + newscript->GetAI = &GetAI_boss_azgalor; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_lesser_doomguard"; + newscript->GetAI = &GetAI_mob_lesser_doomguard; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp new file mode 100644 index 00000000000..b52d22842e3 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -0,0 +1,197 @@ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "hyjal_trash.h" + +#define SPELL_CLEAVE 31436 +#define SPELL_WARSTOMP 31480 +#define SPELL_MARK 31447 + +#define SOUND_ONDEATH 11018 + +#define SAY_ONSLAY1 "Shaza-Kiel!" +#define SAY_ONSLAY2 "You... are nothing!" +#define SAY_ONSLAY3 "Miserable nuisance!" +#define SOUND_ONSLAY1 11017 +#define SOUND_ONSLAY2 11053 +#define SOUND_ONSLAY3 11054 + +#define SAY_MARK1 "Your death will be a painful one." +#define SAY_MARK2 "You... are marked." +#define SOUND_MARK1 11016 +#define SOUND_MARK2 11052 + +#define SAY_ONAGGRO "Cry for mercy! Your meaningless lives will soon be forfeit." +#define SOUND_ONAGGRO 11015 + +struct boss_kazrogalAI : public hyjal_trashAI +{ + boss_kazrogalAI(Creature *c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + SpellEntry *TempSpell = GET_SPELL(SPELL_MARK); + if (TempSpell && TempSpell->EffectImplicitTargetA[0] != 1) + { + TempSpell->EffectImplicitTargetA[0] = 1; + TempSpell->EffectImplicitTargetB[0] = 0; + } + } + + uint32 CleaveTimer; + uint32 WarStompTimer; + uint32 MarkTimer; + uint32 MarkTimerBase; + bool pGo; + uint32 pos; + + void Reset() + { + damageTaken = 0; + CleaveTimer = 5000; + WarStompTimer = 15000; + MarkTimer = 45000; + MarkTimerBase = 45000; + + if (pInstance && IsEvent) + pInstance->SetData(DATA_KAZROGALEVENT, NOT_STARTED); + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance && IsEvent) + pInstance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS); + DoPlaySoundToSet(me, SOUND_ONAGGRO); + me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, NULL); + } + + void KilledUnit(Unit * /*victim*/) + { + switch (urand(0,2)) + { + case 0: + DoPlaySoundToSet(me, SOUND_ONSLAY1); + me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, NULL); + break; + case 1: + DoPlaySoundToSet(me, SOUND_ONSLAY2); + me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, NULL); + break; + case 2: + DoPlaySoundToSet(me, SOUND_ONSLAY3); + me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, NULL); + break; + } + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + + void JustDied(Unit *victim) + { + hyjal_trashAI::JustDied(victim); + if (pInstance && IsEvent) + pInstance->SetData(DATA_KAZROGALEVENT, DONE); + DoPlaySoundToSet(me, SOUND_ONDEATH); + } + + void UpdateAI(const uint32 diff) + { + if (IsEvent) + { + //Must update npc_escortAI + npc_escortAI::UpdateAI(diff); + if (!pGo) + { + pGo = true; + if (pInstance) + { + AddWaypoint(0, 5492.91, -2404.61, 1462.63); + AddWaypoint(1, 5531.76, -2460.87, 1469.55); + AddWaypoint(2, 5554.58, -2514.66, 1476.12); + AddWaypoint(3, 5554.16, -2567.23, 1479.90); + AddWaypoint(4, 5540.67, -2625.99, 1480.89); + AddWaypoint(5, 5508.16, -2659.2, 1480.15); + AddWaypoint(6, 5489.62, -2704.05, 1482.18); + AddWaypoint(7, 5457.04, -2726.26, 1485.10); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + + //Return since we have no target + if (!UpdateVictim()) + return; + + if (CleaveTimer <= diff) + { + DoCast(me, SPELL_CLEAVE); + CleaveTimer = 6000+rand()%15000; + } else CleaveTimer -= diff; + + if (WarStompTimer <= diff) + { + DoCast(me, SPELL_WARSTOMP); + WarStompTimer = 60000; + } else WarStompTimer -= diff; + + if (me->HasAura(SPELL_MARK)) + me->RemoveAurasDueToSpell(SPELL_MARK); + if (MarkTimer <= diff) + { + //cast dummy, useful for bos addons + me->CastCustomSpell(me, SPELL_MARK, NULL, NULL, NULL, false, NULL, NULL, me->GetGUID()); + + std::list t_list = me->getThreatManager().getThreatList(); + for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); + if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->getPowerType() == POWER_MANA) + { + pTarget->CastSpell(pTarget, SPELL_MARK,true);//only cast on mana users + } + } + MarkTimerBase -= 5000; + if (MarkTimerBase < 5500) + MarkTimerBase = 5500; + MarkTimer = MarkTimerBase; + switch (urand(0,2)) + { + case 0: + DoPlaySoundToSet(me, SOUND_MARK1); + me->MonsterYell(SAY_MARK1, LANG_UNIVERSAL, NULL); + break; + case 1: + DoPlaySoundToSet(me, SOUND_MARK2); + me->MonsterYell(SAY_MARK2, LANG_UNIVERSAL, NULL); + break; + } + } else MarkTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_kazrogal(Creature* pCreature) +{ + return new boss_kazrogalAI (pCreature); +} + +void AddSC_boss_kazrogal() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_kazrogal"; + newscript->GetAI = &GetAI_boss_kazrogal; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp new file mode 100644 index 00000000000..7465b997117 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp @@ -0,0 +1,192 @@ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "hyjal_trash.h" + +#define SPELL_FROST_ARMOR 31256 +#define SPELL_DEATH_AND_DECAY 31258 + +#define SPELL_FROST_NOVA 31250 +#define SPELL_ICEBOLT 31249 + +#define SAY_ONDEATH "You have won this battle, but not... the... war" +#define SOUND_ONDEATH 11026 + +#define SAY_ONSLAY1 "All life must perish!" +#define SAY_ONSLAY2 "Victory to the Legion!" +#define SOUND_ONSLAY1 11025 +#define SOUND_ONSLAY2 11057 + +#define SAY_DECAY1 "Crumble and rot!" +#define SAY_DECAY2 "Ashes to ashes, dust to dust" +#define SOUND_DECAY1 11023 +#define SOUND_DECAY2 11055 + +#define SAY_NOVA1 "Succumb to the icy chill... of death!" +#define SAY_NOVA2 "It will be much colder in your grave" +#define SOUND_NOVA1 11024 +#define SOUND_NOVA2 11058 + +#define SAY_ONAGGRO "The Legion's final conquest has begun! Once again the subjugation of this world is within our grasp. Let none survive!" +#define SOUND_ONAGGRO 11022 + +struct boss_rage_winterchillAI : public hyjal_trashAI +{ + boss_rage_winterchillAI(Creature *c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + } + + uint32 FrostArmorTimer; + uint32 DecayTimer; + uint32 NovaTimer; + uint32 IceboltTimer; + bool pGo; + uint32 pos; + + void Reset() + { + damageTaken = 0; + FrostArmorTimer = 37000; + DecayTimer = 45000; + NovaTimer = 15000; + IceboltTimer = 10000; + + if (pInstance && IsEvent) + pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED); + } + + void EnterCombat(Unit * /*who*/) + { + if (pInstance && IsEvent) + pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS); + DoPlaySoundToSet(me, SOUND_ONAGGRO); + me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); + } + + void KilledUnit(Unit * /*victim*/) + { + switch (urand(0,1)) + { + case 0: + DoPlaySoundToSet(me, SOUND_ONSLAY1); + me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, NULL); + break; + case 1: + DoPlaySoundToSet(me, SOUND_ONSLAY2); + me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, NULL); + break; + } + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0f); + } + } + + void JustDied(Unit *victim) + { + hyjal_trashAI::JustDied(victim); + if (pInstance && IsEvent) + pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE); + DoPlaySoundToSet(me, SOUND_ONDEATH); + me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, NULL); + } + + void UpdateAI(const uint32 diff) + { + if (IsEvent) + { + //Must update npc_escortAI + npc_escortAI::UpdateAI(diff); + if (!pGo) + { + pGo = true; + if (pInstance) + { + AddWaypoint(0, 4896.08, -1576.35, 1333.65); + AddWaypoint(1, 4898.68, -1615.02, 1329.48); + AddWaypoint(2, 4907.12, -1667.08, 1321.00); + AddWaypoint(3, 4963.18, -1699.35, 1340.51); + AddWaypoint(4, 4989.16, -1716.67, 1335.74); + AddWaypoint(5, 5026.27, -1736.89, 1323.02); + AddWaypoint(6, 5037.77, -1770.56, 1324.36); + AddWaypoint(7, 5067.23, -1789.95, 1321.17); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + + //Return since we have no target + if (!UpdateVictim()) + return; + + if (FrostArmorTimer <= diff) + { + DoCast(me, SPELL_FROST_ARMOR); + FrostArmorTimer = 40000+rand()%20000; + } else FrostArmorTimer -= diff; + if (DecayTimer <= diff) + { + DoCast(me->getVictim(), SPELL_DEATH_AND_DECAY); + DecayTimer = 60000+rand()%20000; + switch (urand(0,1)) + { + case 0: + DoPlaySoundToSet(me, SOUND_DECAY1); + me->MonsterYell(SAY_DECAY1, LANG_UNIVERSAL, NULL); + break; + case 1: + DoPlaySoundToSet(me, SOUND_DECAY2); + me->MonsterYell(SAY_DECAY2, LANG_UNIVERSAL, NULL); + break; + } + } else DecayTimer -= diff; + if (NovaTimer <= diff) + { + DoCast(me->getVictim(), SPELL_FROST_NOVA); + NovaTimer = 30000+rand()%15000; + switch (urand(0,1)) + { + case 0: + DoPlaySoundToSet(me, SOUND_NOVA1); + me->MonsterYell(SAY_NOVA1, LANG_UNIVERSAL, NULL); + break; + case 1: + DoPlaySoundToSet(me, SOUND_NOVA2); + me->MonsterYell(SAY_NOVA2, LANG_UNIVERSAL, NULL); + break; + } + } else NovaTimer -= diff; + if (IceboltTimer <= diff) + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,40,true), SPELL_ICEBOLT); + IceboltTimer = 11000+rand()%20000; + } else IceboltTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_rage_winterchill(Creature* pCreature) +{ + return new boss_rage_winterchillAI (pCreature); +} + +void AddSC_boss_rage_winterchill() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_rage_winterchill"; + newscript->GetAI = &GetAI_boss_rage_winterchill; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp new file mode 100644 index 00000000000..16a050939cc --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -0,0 +1,247 @@ + /* Copyright (C) 2006 - 2009 ScriptDev2 + * 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: Hyjal +SD%Complete: 80 +SDComment: gossip text id's unknown +SDCategory: Caverns of Time, Mount Hyjal +EndScriptData */ + +/* ContentData +npc_jaina_proudmoore +npc_thrall +npc_tyrande_whisperwind +EndContentData */ + +#include "ScriptedPch.h" +#include "hyjalAI.h" + +#define GOSSIP_ITEM_BEGIN_ALLY "My companions and I are with you, Lady Proudmoore." +#define GOSSIP_ITEM_ANETHERON "We are ready for whatever Archimonde might send our way, Lady Proudmoore." + +#define GOSSIP_ITEM_BEGIN_HORDE "I am with you, Thrall." +#define GOSSIP_ITEM_AZGALOR "We have nothing to fear." + +#define GOSSIP_ITEM_RETREAT "We can't keep this up. Let's retreat!" + +#define GOSSIP_ITEM_TYRANDE "Aid us in defending Nordrassil" +#define ITEM_TEAR_OF_GODDESS 24494 + +#define GOSSIP_ITEM_GM1 "[GM] Toggle Debug Timers" + +CreatureAI* GetAI_npc_jaina_proudmoore(Creature* pCreature) +{ + hyjalAI* ai = new hyjalAI(pCreature); + + ai->Reset(); + ai->EnterEvadeMode(); + + ai->Spell[0].SpellId = SPELL_BLIZZARD; + ai->Spell[0].Cooldown = 15000 + rand()%20000; + ai->Spell[0].TargetType = TARGETTYPE_RANDOM; + + ai->Spell[1].SpellId = SPELL_PYROBLAST; + ai->Spell[1].Cooldown = 5500 + rand()%4000; + ai->Spell[1].TargetType = TARGETTYPE_RANDOM; + + ai->Spell[2].SpellId = SPELL_SUMMON_ELEMENTALS; + ai->Spell[2].Cooldown = 15000 + rand()%30000; + ai->Spell[2].TargetType = TARGETTYPE_SELF; + + return ai; +} + +bool GossipHello_npc_jaina_proudmoore(Player* pPlayer, Creature* pCreature) +{ + hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); + if (ai->EventBegun) + return false; + + uint32 RageEncounter = ai->GetInstanceData(DATA_RAGEWINTERCHILLEVENT); + uint32 AnetheronEncounter = ai->GetInstanceData(DATA_ANETHERONEVENT); + if (RageEncounter == NOT_STARTED) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_ALLY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + else if (RageEncounter == DONE && AnetheronEncounter == NOT_STARTED) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ANETHERON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + else if (RageEncounter == DONE && AnetheronEncounter == DONE) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + + if (pPlayer->isGameMaster()) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_jaina_proudmoore(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); + switch(uiAction) + { + case GOSSIP_ACTION_INFO_DEF + 1: + ai->StartEvent(pPlayer); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + ai->FirstBossDead = true; + ai->WaveCount = 9; + ai->StartEvent(pPlayer); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + ai->Retreat(); + break; + case GOSSIP_ACTION_INFO_DEF: + ai->Debug = !ai->Debug; + debug_log("TSCR: HyjalAI - Debug mode has been toggled"); + break; + } + return true; +} + +CreatureAI* GetAI_npc_thrall(Creature* pCreature) +{ + hyjalAI* ai = new hyjalAI(pCreature); + + ai->Reset(); + ai->EnterEvadeMode(); + + ai->Spell[0].SpellId = SPELL_CHAIN_LIGHTNING; + ai->Spell[0].Cooldown = 3000 + rand()%5000; + ai->Spell[0].TargetType = TARGETTYPE_VICTIM; + + ai->Spell[1].SpellId = SPELL_SUMMON_DIRE_WOLF; + ai->Spell[1].Cooldown = 6000 + rand()%35000; + ai->Spell[1].TargetType = TARGETTYPE_RANDOM; + + return ai; +} + +bool GossipHello_npc_thrall(Player* pPlayer, Creature* pCreature) +{ + hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); + if (ai->EventBegun) + return false; + + uint32 AnetheronEvent = ai->GetInstanceData(DATA_ANETHERONEVENT); + // Only let them start the Horde phases if Anetheron is dead. + if (AnetheronEvent == DONE && ai->GetInstanceData(DATA_ALLIANCE_RETREAT)) + { + uint32 KazrogalEvent = ai->GetInstanceData(DATA_KAZROGALEVENT); + uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT); + if (KazrogalEvent == NOT_STARTED) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_HORDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + else if (KazrogalEvent == DONE && AzgalorEvent == NOT_STARTED) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AZGALOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + else if (AzgalorEvent == DONE) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + } + + if (pPlayer->isGameMaster()) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_thrall(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); + ai->DeSpawnVeins();//despawn the alliance veins + switch(uiAction) + { + case GOSSIP_ACTION_INFO_DEF + 1: + ai->StartEvent(pPlayer); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + ai->FirstBossDead = true; + ai->WaveCount = 9; + ai->StartEvent(pPlayer); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + ai->Retreat(); + break; + case GOSSIP_ACTION_INFO_DEF: + ai->Debug = !ai->Debug; + debug_log("TSCR: HyjalAI - Debug mode has been toggled"); + break; + } + return true; +} + +CreatureAI* GetAI_npc_tyrande_whisperwind(Creature* pCreature) +{ + hyjalAI* ai = new hyjalAI(pCreature); + ai->Reset(); + ai->EnterEvadeMode(); + return ai; +} + +bool GossipHello_npc_tyrande_whisperwind(Player* pPlayer, Creature* pCreature) +{ + hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); + uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT); + + // Only let them get item if Azgalor is dead. + if (AzgalorEvent == DONE && !pPlayer->HasItemCount(ITEM_TEAR_OF_GODDESS,1)) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TYRANDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_tyrande_whisperwind(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + if (uiAction == GOSSIP_ACTION_INFO_DEF) + { + ItemPosCountVec dest; + uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_TEAR_OF_GODDESS, 1); + if (msg == EQUIP_ERR_OK) + { + Item* item = pPlayer->StoreNewItem(dest, ITEM_TEAR_OF_GODDESS, true); + if (item && pPlayer) + pPlayer->SendNewItem(item,1,true,false,true); + } + pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); + CAST_AI(hyjalAI, pCreature->AI()); + } + return true; +} + +void AddSC_hyjal() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_jaina_proudmoore"; + newscript->GetAI = &GetAI_npc_jaina_proudmoore; + newscript->pGossipHello = &GossipHello_npc_jaina_proudmoore; + newscript->pGossipSelect = &GossipSelect_npc_jaina_proudmoore; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_thrall"; + newscript->GetAI = &GetAI_npc_thrall; + newscript->pGossipHello = &GossipHello_npc_thrall; + newscript->pGossipSelect = &GossipSelect_npc_thrall; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_tyrande_whisperwind"; + newscript->pGossipHello = &GossipHello_npc_tyrande_whisperwind; + newscript->pGossipSelect = &GossipSelect_npc_tyrande_whisperwind; + newscript->GetAI = &GetAI_npc_tyrande_whisperwind; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h new file mode 100644 index 00000000000..bfc9a54dfd9 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_HYJAL_H +#define DEF_HYJAL_H + +#define ERROR_INST_DATA "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy." + +enum eTypes +{ + WORLD_STATE_WAVES = 2842, + WORLD_STATE_ENEMY = 2453, + WORLD_STATE_ENEMYCOUNT = 2454, + + DATA_ANETHERON = 1, + DATA_ANETHERONEVENT = 2, + DATA_ARCHIMONDE = 3, + DATA_ARCHIMONDEEVENT = 4, + DATA_AZGALOR = 5, + DATA_AZGALOREVENT = 6, + DATA_JAINAPROUDMOORE = 7, + DATA_KAZROGAL = 8, + DATA_KAZROGALEVENT = 9, + DATA_RAGEWINTERCHILL = 10, + DATA_RAGEWINTERCHILLEVENT = 11, + DATA_THRALL = 12, + DATA_TYRANDEWHISPERWIND = 13, + DATA_TRASH = 14, + DATA_RESET_TRASH_COUNT = 15, + DATA_ALLIANCE_RETREAT = 16, + DATA_HORDE_RETREAT = 17, + DATA_RAIDDAMAGE = 18, + DATA_RESET_RAIDDAMAGE = 19, + TYPE_RETREAT = 20 +}; +#endif + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp new file mode 100644 index 00000000000..3c12b54f3f4 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -0,0 +1,1157 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * 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: HyjalAI +SD%Complete: 90 +SDComment: +SDCategory: Caverns of Time, Mount Hyjal +EndScriptData */ + +#include "ScriptedPch.h" +#include "hyjalAI.h" +#include "hyjal_trash.h" +#include "MapManager.h" +#include "Language.h" +#include "Chat.h" +#include "Object.h" + +#define SPAWN_GARG_GATE 0 +#define SPAWN_WYRM_GATE 1 +#define SPAWN_NEAR_TOWER 2 + +#define YELL_HURRY "Hurry, we don't have much time" + +// Locations for summoning gargoyls and frost wyrms in special cases +float SpawnPointSpecial[3][3]= +{ + {5497.08, -2493.23, 1535.72}, //spawn point for the gargoyles near the horde gate + {5624.53, -2548.12, 1551.54}, //spawn point for the frost wyrm near the horde gate + {5604.41, -2811.98, 1547.77} //spawn point for the gargoyles and wyrms near the horde tower +}; + +// Locations for summoning waves in Alliance base +float AllianceBase[4][3]= +{ + {4928.48, -1526.38, 1326.83}, + {4923.54, -1514.29, 1327.98}, + {4928.41, -1510.35, 1327.99}, + {4938.35, -1521.00, 1326.69} +}; + +float JainaDummySpawn[2][4]= +{ + {5497.01, -2719.03, 1483.08, 2.90426}, + {5484.98, -2721.69, 1483.39, 6.00656} +}; + +// Locations for summoning waves in Horde base +float HordeBase[4][3]= +{ + {5458.01, -2340.27, 1459.60}, + {5466.01, -2334.69, 1460.06}, + {5468.45, -2355.13, 1459.99}, + {5479.06, -2344.16, 1461.74} +}; + +// Lady Jaina's waypoints when retreathing +float JainaWPs[2][3]= +{ + {5078.56, -1789.79, 1320.73},//next to the small stairs + {5037.38, -1778.39, 1322.61},//center of alliance base +}; + +float InfernalPos[8][3]=//spawn points for the infernals in the horde base +{ + {5453.59, -2764.52, 1493.50}, + {5478.4, -2781.77, 1497.52}, + {5506.09, -2780.53, 1496.32}, + {5532.1, -2763.42, 1492.37}, + {5544.16, -2733.99, 1487.14}, + {5536.19, -2708.18, 1480.01}, + {5510.16, -2691.75, 1479.66}, + {5482.39, -2689.19, 1481.09} +}; + +float InfernalSPWP[26][4]=//spawn points for the infernals in the horde base used in the cleaning wave +{ + {5490.96, -2718.72, 1482.96, 0.49773}, + {5449.51, -2723.32, 1485.69, 2.69685}, + {5520.83, -2624.68, 1483.82, 1.20459}, + {5558.28, -2629.26, 1485.76, 0.37992}, + {5567.97, -2758.69, 1494.10, 5.04125}, + {5384.90, -2793.47, 1503.90, 5.55412}, + {5495.33, -2814.06, 1501.56, 1.12055}, + {5472.63, -2929.39, 1538.31, 1.95777}, + {5334.72, -2952.29, 1534.34, 0.50869}, + {5398.36, -2872.46, 1512.38, 0.76787}, + {5514.39, -2768.63, 1492.30, 1.55721}, + {5598.91, -2703.75, 1495.64, 2.56644}, + {5467.80, -2655.93, 1482.27, 0.85819}, + {5399.83, -2985.24, 1545.04, 5.92559}, + {5232.13, -2967.05, 1553.09, 5.41351}, + {5272.02, -3082.52, 1567.09, 3.40681}, + {5343.26, -3120.71, 1582.92, 3.16727}, + {5371.26, -3175.24, 1587.41, 6.10466}, + {5434.67, -3177.91, 1579.25, 2.77850}, + {5237.39, -3149.25, 1593.59, 0.83855}, + {5202.15, -3016.64, 1566.28, 3.31256}, + {5302.54, -2914.37, 1528.53, 3.37146}, + {5439.04, -2834.81, 1508.80, 2.14231}, + {5421.33, -2771.04, 1494.28, 6.06223}, + {5549.76, -2692.93, 1482.68, 2.19414}, + {5459.78, -2755.71, 1490.68, 1.05139} +}; + +float VeinPos[14][8]=//spawn points of the ancient gem veins +{ + {5184.84, -1982.59, 1382.66, 2.58079, 0, 0, 0.960944, 0.276742}, //alliance + {5107.66, -2071.16, 1368.37, 2.65148, 0, 0, 0.970124, 0.242611}, //alliance + {5040.53, -2227.65, 1403.17, 3.35049, 0, 0, 0.99455, -0.104257}, //alliance + {5187.59, -2453.12, 1455.51, 5.87943, 0, 0, 0.20051, -0.979692}, //alliance + {5429.43, -2340.65, 1465.38, 4.7681, 0, 0, 0.687138, -0.726527}, //alliance + {5463.99, -2315.95, 1470.29, 1.52045, 0, 0, 0.689084, 0.724682}, //alliance + {5624.65, -2495.09, 1510.11, 0.0124869, 0, 0, 0.00624342, 0.999981}, //alliance + {5285.41, -3348.32, 1663.01, 1.57152, 0, 0, 0.707362, 0.706852}, //horde + {5417.69, -3372.52, 1656.31, 0.361993, 0, 0, 0.18001, 0.983665}, //horde + {5315.34, -3238.32, 1622.88, 3.03627, 0, 0, 0.998614, 0.0526347}, //horde + {5303.4, -3096.44, 1596.41, 1.72073, 0, 0, 0.758081, 0.65216}, //horde + {5265.13, -3177.27, 1616.22, 0.813604, 0, 0, 0.395674, 0.918391}, //horde + {5374.3, -3420.59, 1653.43, 1.45762, 0, 0, 0.665981, 0.745969}, //horde + {5441.54, -3321.59, 1651.55, 0.258306, 0, 0, 0.128794, 0.991671} //horde +}; + +float AllianceOverrunGargPos[5][4]=//gargoyle spawn points in the alliance overrun +{ + {5279.94, -2049.68, 1311.38, 0},//garg1 + {5289.15, -2219.06, 1291.12, 0},//garg2 + {5202.07, -2136.10, 1305.07, 2.8},//garg3 + {5071.52, -2425.63, 1454.48, 5.54},//garg4 + {5120.65, -2467.92, 1463.93, 2.54}//garg5 +}; + +float AllianceFirePos[92][8]=//spawn points for the fire visuals (GO) in the alliance base +{ + {5039.9, -1796.84, 1323.88, 2.59222, 0, 0, 0.962511, 0.271243}, + {5087.2, -1795.2, 1320.68, 1.03946, 0, 0, 0.496644, 0.867954}, + {5112.68, -1806.66, 1359.93, 1.37799, 0, 0, 0.63576, 0.771887}, + {5095.61, -1793.27, 1359.78, 0.580806, 0, 0, 0.286338, 0.958129}, + {5090.43, -1784.45, 1360.44, 0.796784, 0, 0, 0.387937, 0.921686}, + {5139.25, -1783.11, 1359.39, 3.30849, 0, 0, 0.99652, -0.0833509}, + {5112.16, -1763.72, 1361.35, 5.10312, 0, 0, 0.556388, -0.830922}, + {4981.18, -1793.98, 1335.7, 3.23072, 0, 0, 0.999007, -0.0445498}, + {4996.57, -1766.75, 1341.62, 3.5331, 0, 0, 0.980902, -0.194505}, + {4983.74, -1769.25, 1345.75, 3.79228, 0, 0, 0.947541, -0.319635}, + {4996.01, -1774.43, 1330.71, 3.07364, 0, 0, 0.999423, 0.0339693}, + {5094.2, -1726.13, 1330.55, 1.56175, 0, 0, 0.703901, 0.710298}, + {5079.82, -1721.24, 1336.26, 1.18868, 0, 0, 0.559964, 0.828517}, + {5077.68, -1717.15, 1327.78, 0.0145145, 0, 0, 0.00725717, 0.999974}, + {5122.27, -1738.22, 1341.67, 0.835256, 0, 0, 0.405593, 0.914054}, + {5131.88, -1741.15, 1335.25, 2.15472, 0, 0, 0.880712, 0.473653}, + {5196.93, -1772.99, 1345.2, 0.128397, 0, 0, 0.0641544, 0.99794}, + {5225.33, -1756.06, 1344.17, 3.04223, 0, 0, 0.998766, 0.0496599}, + {5224.84, -1767.05, 1360.06, 3.19538, 0, 0, 0.999638, -0.0268922}, + {5202.05, -1763.47, 1361.68, 2.59455, 0, 0, 0.962826, 0.270122}, + {5194.74, -1766.66, 1356.94, 0.0734191, 0, 0, 0.0367013, 0.999326}, + {5159.67, -1832.97, 1344.5, 5.17457, 0, 0, 0.526356, -0.850264}, + {5096.17, -1858.73, 1332.46, 5.30021, 0, 0, 0.471939, -0.881631}, + {5110.7, -1856.59, 1342.84, 5.97564, 0, 0, 0.153167, -0.9882}, + {5109.76, -1855.3, 1332.38, 4.89572, 0, 0, 0.639411, -0.768865}, + {5068.95, -1837.37, 1328.81, 2.61569, 0, 0, 0.965628, 0.25993}, + {5064.4, -1824.77, 1329.02, 2.16409, 0, 0, 0.88292, 0.469524}, + {5059.89, -1848.79, 1329.59, 0.0709955, 0, 0, 0.0354903, 0.99937}, + {5014.37, -1851.39, 1322.56, 4.66949, 0, 0, 0.722111, -0.691777}, + {5025.1, -1848.27, 1323.39, 4.44565, 0, 0, 0.794854, -0.606801}, + {4942.63, -1890.13, 1326.59, 3.28719, 0, 0, 0.997351, -0.0727343}, + {4937.95, -1888.71, 1352.41, 3.41678, 0, 0, 0.990549, -0.13716}, + {4922.48, -1881.92, 1352.41, 5.03077, 0, 0, 0.586075, -0.810257}, + {4915.35, -1894.32, 1351.24, 6.22457, 0, 0, 0.0293048, -0.999571}, + {4922.71, -1904.84, 1352.56, 1.37866, 0, 0, 0.63602, 0.771672}, + {4932.89, -1905.49, 1352.56, 1.89702, 0, 0, 0.812549, 0.582893}, + {5011.83, -1861.05, 1345.86, 4.43777, 0, 0, 0.797239, -0.603664}, + {5011.83, -1861.05, 1363.26, 4.748, 0, 0, 0.694406, -0.719583}, + {5021.46, -1858.35, 1342.17, 4.86188, 0, 0, 0.652329, -0.757936}, + {4995.02, -1698.3, 1370.38, 6.15779, 0, 0, 0.0626579, -0.998035}, + {5119.85, -1728.9, 1336.04, 5.87112, 0, 0, 0.204579, -0.97885}, + {5214.75, -1751.02, 1342.5, 5.08965, 0, 0, 0.561972, -0.827156}, + {5075.04, -1822.43, 1328.87, 3.99951, 0, 0, 0.9094, -0.415924}, + {5057.09, -1823.32, 1350.35, 3.88169, 0, 0, 0.93231, -0.361659}, + {4984.6, -1816.99, 1329.21, 3.05308, 0, 0, 0.999021, 0.0442417}, + {4983.35, -1811.55, 1356.82, 3.33975, 0, 0, 0.995096, -0.098917}, + {4984.11, -1825.73, 1350.76, 2.26375, 0, 0, 0.905211, 0.424962}, + {4968.47, -1786.46, 1354.09, 3.07663, 0, 0, 0.999473, 0.0324733}, + {5061.82, -1751.16, 1339.07, 5.94727, 0, 0, 0.167171, -0.985928}, + {5063.75, -1763, 1351.91, 0.759707, 0, 0, 0.370784, 0.928719}, + {5078.65, -1708.26, 1353.9, 1.27022, 0, 0, 0.593264, 0.805008}, + {4983.19, -1755.96, 1331.13, 4.28221, 0, 0, 0.841733, -0.539894}, + {4972.76, -1755.3, 1332.5, 4.21938, 0, 0, 0.858276, -0.513188}, + {4961.65, -1760.82, 1351.69, 3.56515, 0, 0, 0.977659, -0.210198}, + {5086.45, -1779.83, 1321.62, 6.23157, 0, 0, 0.0258051, -0.999667}, + {5063.15, -1756.74, 1328.56, 0.886926, 0, 0, 0.42907, 0.903271}, + {5042.45, -1800.61, 1323.88, 2.50093, 0, 0, 0.949131, 0.31488}, + {5084.74, -1725.35, 1327.89, 1.65034, 0, 0, 0.734663, 0.678432}, + {4993.25, -1758.1, 1331.07, 3.49995, 0, 0, 0.98399, -0.178223}, + {5078.53, -1867.85, 1348.91, 5.85612, 0, 0, 0.211913, -0.977288}, + {5080.74, -1869.73, 1333.18, 6.18206, 0, 0, 0.0505424, -0.998722}, + {5089.55, -1894.13, 1356.08, 1.52072, 0, 0, 0.689181, 0.724589}, + {5113.24, -1899.49, 1363.77, 1.50108, 0, 0, 0.682034, 0.731321}, + {4984.18, -1907.69, 1325.62, 3.82193, 0, 0, 0.942698, -0.333646}, + {5094.14, -2432.08, 1429.38, 4.70083, 0, 0, 0.711182, -0.703007}, + {5329.89, -2113.30, 1281.06, 5.60560, 0, 0, 0.332347, -0.943157}, + {5170.87, -2148.13, 1278.32, 1.63540, 0, 0, 0.729573, 0.683903 }, + {5132.94, -1960.25, 1367.8, 3.69787, 0, 0, 0.961568, -0.274566}, + {5280.82, -2351.55, 1431.57, 4.46913, 0, 0, 0.787677, -0.616088}, + {5176.78, -2121.43, 1295.27, 3.24153, 0, 0, 0.998752, -0.04995}, + {5332.75, -2101.41, 1296.37, 5.50350, 0, 0, 0.380043, -0.924969}, + {5265.70, -2050.27, 1287.57, 0.50051, 0, 0, 0.247655, 0.968848 }, + {5194.21, -2129.89, 1274.04, 3.08053, 0, 0, 0.999534, 0.0305272}, + {5225.81, -1985.50, 1364.15, 0.37247, 0, 0, 0.185163, 0.982708 }, + {5339.46, -2204.47, 1280.45, 0.99921, 0, 0, 0.479081, 0.877771 }, + {5269.63, -2020.57, 1299.62, 3.00201, 0, 0, 0.997566, 0.0697332}, + {5111.54, -2445.70, 1435.31, 2.70983, 0, 0, 0.976788, 0.214207 }, + {5111.24, -1901.14, 1355.33, 1.61028, 0, 0, 0.720929, 0.693009 }, + {5310.42, -2207.82, 1277.46, 0.50441, 0, 0, 0.249544, 0.968363 }, + {5150.81, -2042.13, 1394.3, 2.21031, 0, 0, 0.893534, 0.448995 }, + {5224.84, -2376.61, 1366.33, 5.0621, 0, 0, 0.573311, -0.819338}, + {5105.41, -2454.86, 1446.16, 4.64584, 0, 0, 0.730239, -0.683191}, + {5309.65, -2188.28, 1266.84, 5.56631, 0, 0, 0.350811, -0.936446}, + {5281.46, -2047.82, 1287.67, 2.44909, 0, 0, 0.940652, 0.339373 }, + {5325.45, -2189.41, 1309.6, 6.23783, 0, 0, 0.0226771, -0.999743}, + {5190.96, -2142.54, 1293.03, 6.25668, 0, 0, 0.0132544, -0.999912}, + {5089.99, -2467.49, 1441.8, 0.77381, 0, 0, 0.377326, 0.92608 }, + {5195.08, -2129.01, 1285.36, 3.55727, 0, 0, 0.978480, -0.206344}, + {5353.76, -2116.28, 1299.27, 6.17894, 0, 0, 0.0521006, -0.998642}, + {5271.14, -2037.38, 1299.24, 4.07879, 0, 0, 0.892201, -0.451638}, + {5332.5 , -2181.28, 1279.95, 4.6906, 0, 0, 0.714768, -0.699362}, + {5108.2 , -2429.84, 1427.73, 4.5194, 0, 0, 0.771943, -0.635691} +}; + +float HordeFirePos[65][8]=//spawn points for the fire visuals (GO) in the horde base +{ + {5524.11, -2612.73, 1483.38, 1.96198, 0, 0, 0.831047, 0.556202}, + {5514.42, -2617.19, 1505.77, 1.82453, 0, 0, 0.790892, 0.611956}, + {5510.21, -2624.77, 1485.34, 1.71065, 0, 0, 0.754783, 0.655974}, + {5570.72, -2619.04, 1487.62, 0.728898, 0, 0, 0.356435, 0.93432}, + {5570.29, -2639.37, 1487.31, 1.49308, 0, 0, 0.679104, 0.734042}, + {5583.56, -2637.2, 1503.78, 1.46559, 0, 0, 0.668951, 0.743307}, + {5571.53, -2626.81, 1510.99, 0.362107, 0, 0, 0.180066, 0.983654}, + {5545.97, -2659.62, 1489.64, 5.07055, 0, 0, 0.569845, -0.821752}, + {5557.44, -2675.91, 1482.58, 1.70118, 0, 0, 0.751671, 0.659539}, + {5594.98, -2742.31, 1495.51, 4.5993, 0, 0, 0.74594, -0.666013}, + {5599.65, -2755.6, 1505.05, 1.66896, 0, 0, 0.740947, 0.671564}, + {5565.95, -2774.75, 1499.48, 6.22425, 0, 0, 0.0294611, -0.999566}, + {5567.1, -2769.7, 1511.17, 5.99257, 0, 0, 0.144799, -0.989461}, + {5572.84, -2774.16, 1527.06, 0.836428, 0, 0, 0.406129, 0.913816}, + {5538.32, -2805.94, 1498.87, 4.30082, 0, 0, 0.836674, -0.547701}, + {5515.66, -2801.74, 1503.53, 5.57316, 0, 0, 0.347602, -0.937642}, + {5516.76, -2827.14, 1501.15, 0.35026, 0, 0, 0.174236, 0.984704}, + {5536.13, -2813.51, 1537.21, 4.51681, 0, 0, 0.772765, -0.634692}, + {5525.05, -2825.16, 1538.53, 0.489275, 0, 0, 0.242205, 0.970225}, + {5534.42, -2815.45, 1562.84, 4.62834, 0, 0, 0.736191, -0.676774}, + {5519.64, -2831.12, 1526.46, 0.611008, 0, 0, 0.300774, 0.953696}, + {5551.04, -2827.55, 1523.5, 3.35206, 0, 0, 0.994468, -0.10504}, + {5469.22, -2802.87, 1503.5, 4.99509, 0, 0, 0.600436, -0.799673}, + {5427.8, -2737.26, 1487.12, 1.78673, 0, 0, 0.779186, 0.626793}, + {5454.1, -2709.1, 1485.92, 3.03552, 0, 0, 0.998594, 0.0530137}, + {5436.3, -2718.2, 1506.02, 2.7567, 0, 0, 0.981539, 0.191261}, + {5412.6, -2740.55, 1510.79, 2.98446, 0, 0, 0.996915, 0.0784832}, + {5406.12, -2752.48, 1521.01, 2.05769, 0, 0, 0.856705, 0.515807}, + {5445.24, -2676.35, 1521.89, 2.91378, 0, 0, 0.99352, 0.113661}, + {5481.4, -2665.08, 1482.23, 4.30001, 0, 0, 0.836895, -0.547363}, + {5443.51, -2675.44, 1487.12, 2.90986, 0, 0, 0.993295, 0.115606}, + {5391.72, -2647.3, 1528.9, 3.76987, 0, 0, 0.951063, -0.308997}, + {5421.09, -2734.12, 1521.01, 2.70567, 0, 0, 0.97634, 0.216242}, + {5405.39, -2710.33, 1533.77, 2.51324, 0, 0, 0.951052, 0.309032}, + {5423.96, -2703.76, 1516.34, 2.79206, 0, 0, 0.984767, 0.173879}, + {5444.75, -2735.23, 1486.37, 2.22657, 0, 0, 0.897155, 0.441715}, + {5570.98, -2747.91, 1495.7, 5.14433, 0, 0, 0.53915, -0.84221}, + {5567.79, -2673.9, 1484.66, 2.72529, 0, 0, 0.978415, 0.20665}, + {5600.71, -2696.8, 1500.42, 0.443704, 0, 0, 0.220036, 0.975492}, + {5600.7, -2693.04, 1515.2, 5.16003, 0, 0, 0.532522, -0.846416}, + {5627.56, -2839.66, 1510.53, 5.41527, 0, 0, 0.420463, -0.907309}, + {5622.02, -2868.71, 1516.22, 2.25482, 0, 0, 0.903303, 0.429002}, + {5586.61, -2878.97, 1510.34, 4.55604, 0, 0, 0.76017, -0.649724}, + {5583.78, -2843.71, 1509.54, 5.35715, 0, 0, 0.44665, -0.894709}, + {5580.95, -2811.3, 1513.3, 3.57587, 0, 0, 0.976518, -0.215434}, + {5542.52, -2869.31, 1523.13, 5.23304, 0, 0, 0.501275, -0.865288}, + {5557.35, -2866.36, 1518.76, 4.48299, 0, 0, 0.783388, -0.621533}, + {5380.91, -2849.36, 1512.81, 3.90962, 0, 0, 0.927168, -0.374646}, + {5395.76, -2881.41, 1521.11, 4.28426, 0, 0, 0.84118, -0.540755}, + {5374.87, -2859.63, 1528.98, 3.30252, 0, 0, 0.996765, -0.0803745}, + {5356.07, -2854.66, 1520.34, 5.83933, 0, 0, 0.220108, -0.975475}, + {5363.01, -2975.72, 1539.02, 4.13738, 0, 0, 0.87859, -0.477576}, + {5336.85, -2980.74, 1561.24, 5.11126, 0, 0, 0.553001, -0.83318}, + {5335.23, -2974.62, 1540.05, 5.04451, 0, 0, 0.580496, -0.814263}, + {5422.37, -2998.87, 1549.98, 4.51831, 0, 0, 0.772288, -0.635272}, + {5405.54, -3014.6, 1562.16, 5.86761, 0, 0, 0.206298, -0.978489}, + {5427.96, -3019.4, 1561.58, 3.53498, 0, 0, 0.980718, -0.19543}, + {5348.12, -2977.84, 1582.47, 3.94025, 0, 0, 0.921323, -0.388799}, + {5331.12, -2993.71, 1576.14, 0.0642734, 0, 0, 0.0321311, 0.999484}, + {5321.63, -2986.55, 1552.2, 5.29503, 0, 0, 0.474219, -0.880407}, + {5292.1, -2914.36, 1529.52, 2.9742, 0, 0, 0.996499, 0.083601}, + {5281.77, -2926.5, 1530.62, 1.67829, 0, 0, 0.744071, 0.6681}, + {5287.19, -2909.94, 1543.49, 3.31192, 0, 0, 0.996376, -0.0850591}, + {5534.15, -2679.35, 1483.61, 0.428685, 0, 0, 0.212705, 0.977116}, + {5545.43, -2647.82, 1483.05, 5.38848, 0, 0, 0.432578, -0.901596} +}; + +hyjalAI::hyjalAI(Creature *c) : npc_escortAI(c), Summons(me) +{ + pInstance = c->GetInstanceData(); + VeinsSpawned[0] = false; + VeinsSpawned[1] = false; + for (uint8 i=0; i<14; ++i) + VeinGUID[i] = 0; + InfernalCount = 0; + TeleportTimer = 1000; + Overrun = false; + Teleported = false; + WaitForTeleport = false; + OverrunCounter = 0; + OverrunCounter2 = 0; + InfernalPoint = 0; + RespawnTimer = 10000; + DoRespawn = false; + DoHide = false; + MassTeleportTimer = 0; + DoMassTeleport = false; +} + +void hyjalAI::JustSummoned(Creature *summoned) +{ + Summons.Summon(summoned); +} + +void hyjalAI::SummonedCreatureDespawn(Creature* summoned) +{ + Summons.Despawn(summoned); +} + +void hyjalAI::Reset() +{ + IsDummy = false; + me->setActive(true); + // GUIDs + PlayerGUID = 0; + BossGUID[0] = 0; + BossGUID[1] = 0; + + // Timers + NextWaveTimer = 10000; + CheckTimer = 0; + RetreatTimer = 1000; + + // Misc + WaveCount = 0; + EnemyCount = 0; + + // Set faction properly based on Creature entry + switch(me->GetEntry()) + { + case JAINA: + Faction = 0; + DoCast(me, SPELL_BRILLIANCE_AURA, true); + break; + + case THRALL: + Faction = 1; + break; + + case TYRANDE: + Faction = 2; + break; + } + + //Bools + EventBegun = false; + FirstBossDead = false; + SecondBossDead = false; + Summon = false; + bRetreat = false; + Debug = false; + + //Flags + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + //Initialize spells + memset(Spell, 0, sizeof(Spell)); + + //Reset Instance Data for trash count + if (pInstance) + { + if ((!pInstance->GetData(DATA_ALLIANCE_RETREAT) && me->GetEntry() == JAINA) || (pInstance->GetData(DATA_ALLIANCE_RETREAT) && me->GetEntry() == THRALL)) + { + //Reset World States + pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, 0); + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, 0); + pInstance->SetData(DATA_RESET_TRASH_COUNT, 0); + } + } else error_log(ERROR_INST_DATA); + + //Visibility + DoHide = true; +} + +void hyjalAI::EnterEvadeMode() +{ + if (me->GetEntry() != JAINA) + me->RemoveAllAuras(); + me->DeleteThreatList(); + me->CombatStop(true); + me->LoadCreaturesAddon(); + + if (me->isAlive()) + me->GetMotionMaster()->MoveTargetedHome(); + + me->SetLootRecipient(NULL); +} + +void hyjalAI::EnterCombat(Unit * /*who*/) +{ + if (IsDummy)return; + for (uint8 i = 0; i < 3; ++i) + if (Spell[i].Cooldown) + SpellTimer[i] = Spell[i].Cooldown; + + Talk(ATTACKED); +} + +void hyjalAI::MoveInLineOfSight(Unit *who) +{ + if (IsDummy) + return; + + npc_escortAI::MoveInLineOfSight(who); +} + +void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) +{ + uint32 random = rand()%4; + float SpawnLoc[3]; + + for (uint8 i = 0; i < 3; ++i) + { + SpawnLoc[i] = Base[random][i]; + } + Creature* pCreature = NULL; + switch(entry) + { + case 17906: //GARGOYLE + + if (!FirstBossDead && (WaveCount == 1 || WaveCount == 3)) + {//summon at tower + pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0]+irand(-20,20), SpawnPointSpecial[SPAWN_NEAR_TOWER][1]+irand(-20,20), SpawnPointSpecial[SPAWN_NEAR_TOWER][2]+irand(-10,10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + if (pCreature) + CAST_AI(hyjal_trashAI, pCreature->AI())->useFlyPath = true; + }else{//summon at gate + pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_GARG_GATE][0]+irand(-10,10), SpawnPointSpecial[SPAWN_GARG_GATE][1]+irand(-10,10), SpawnPointSpecial[SPAWN_GARG_GATE][2]+irand(-10,10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + } + break; + case 17907: //FROST_WYRM , + if (FirstBossDead && WaveCount == 1) //summon at gate + pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_WYRM_GATE][0],SpawnPointSpecial[SPAWN_WYRM_GATE][1],SpawnPointSpecial[SPAWN_WYRM_GATE][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + else + { + pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0], SpawnPointSpecial[SPAWN_NEAR_TOWER][1],SpawnPointSpecial[SPAWN_NEAR_TOWER][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + if (pCreature) + CAST_AI(hyjal_trashAI, pCreature->AI())->useFlyPath = true; + } + break; + case 17908: //GIANT_INFERNAL + ++InfernalCount; + if (InfernalCount > 7) + InfernalCount = 0; + pCreature = me->SummonCreature(entry, InfernalPos[InfernalCount][0], InfernalPos[InfernalCount][1], InfernalPos[InfernalCount][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + break; + default: + pCreature = me->SummonCreature(entry, SpawnLoc[0], SpawnLoc[1], SpawnLoc[2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + break; + + } + + if (pCreature) + { + // Increment Enemy Count to be used in World States and instance script + ++EnemyCount; + + pCreature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + pCreature->setActive(true); + switch(entry) + { + case NECROMANCER: + case ABOMINATION: + case GHOUL: + case BANSHEE: + case CRYPT_FIEND: + case GARGOYLE: + case FROST_WYRM: + case GIANT_INFERNAL: + case FEL_STALKER: + case RAGE_WINTERCHILL: + case ANETHERON: + case KAZROGAL: + case AZGALOR: + CAST_AI(hyjal_trashAI, pCreature->AI())->IsEvent = true; + break; + } + if (pInstance) + { + if (pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE) + pCreature->SetDisableReputationGain(true);//no repu for solo farming + } + // Check if Creature is a boss. + if (pCreature->isWorldBoss()) + { + if (!FirstBossDead) BossGUID[0] = pCreature->GetGUID(); + else BossGUID[1] = pCreature->GetGUID(); + CheckTimer = 5000; + } + } +} + +void hyjalAI::SummonNextWave(Wave wave[18], uint32 Count, float Base[4][3]) +{ + // 1 in 4 chance we give a rally yell. Not sure if the chance is offilike. + if (rand()%4 == 0) + Talk(RALLY); + + if (!pInstance) + { + error_log(ERROR_INST_DATA); + return; + } + InfernalCount = 0;//reset infernal count every new wave + + EnemyCount = pInstance->GetData(DATA_TRASH); + for (uint8 i = 0; i < 18; ++i) + { + if (wave[Count].Mob[i]) + SummonCreature(wave[Count].Mob[i], Base); + } + + if (!wave[Count].IsBoss) + { + uint32 stateValue = Count+1; + if (FirstBossDead) + stateValue -= 9; // Subtract 9 from it to give the proper wave number if we are greater than 8 + + // Set world state to our current wave number + pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, stateValue); // Set world state to our current wave number + // Enable world state + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 1); // Enable world state + + pInstance->SetData(DATA_TRASH, EnemyCount); // Send data for instance script to update count + + if (!Debug) + NextWaveTimer = wave[Count].WaveTimer; + else + { + NextWaveTimer = 15000; + debug_log("TSCR: HyjalAI: debug mode is enabled. Next Wave in 15 seconds"); + } + } + else + { + // Set world state for waves to 0 to disable it. + pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, 0); + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 1); + + // Set World State for enemies invading to 1. + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, 1); + + Summon = false; + } + CheckTimer = 5000; +} + +void hyjalAI::StartEvent(Player* pPlayer) +{ + if (!pPlayer || IsDummy || !pInstance) + return; + + Talk(BEGIN); + + EventBegun = true; + Summon = true; + + NextWaveTimer = 15000; + CheckTimer = 5000; + PlayerGUID = pPlayer->GetGUID(); + + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, 0); + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, 0); + + DeSpawnVeins(); +} + +uint32 hyjalAI::GetInstanceData(uint32 Event) +{ + if (pInstance) + return pInstance->GetData(Event); + else error_log(ERROR_INST_DATA); + + return 0; +} + +void hyjalAI::Talk(uint32 id) +{ + std::list index; + for (uint8 i = 0; i < 9; ++i) + { + if (Faction == 0) // Alliance + { + if (JainaQuotes[i].id == id) + index.push_back(i); + } + else if (Faction == 1) // Horde + { + if (ThrallQuotes[i].id == id) + index.push_back(i); + } + } + + if (index.empty()) + return; // No quotes found, no use to continue + + uint8 ind = *(index.begin()) + rand()%index.size(); + + int32 YellId = 0; + if (Faction == 0) // Alliance + { + YellId = JainaQuotes[ind].textid; + } + else if (Faction == 1) // Horde + { + YellId = ThrallQuotes[ind].textid; + } + + if (YellId) + DoScriptText(YellId, me); +} + +void hyjalAI::Retreat() +{ + if (pInstance) + { + pInstance->SetData(TYPE_RETREAT,SPECIAL); + + if (Faction == 0) + { + pInstance->SetData(DATA_ALLIANCE_RETREAT, 1); + AddWaypoint(0,JainaWPs[0][0],JainaWPs[0][1],JainaWPs[0][2]); + AddWaypoint(1,JainaWPs[1][0],JainaWPs[1][1],JainaWPs[1][2]); + Start(false, false); + SetDespawnAtEnd(false);//move to center of alliance base + } + if (Faction == 1) + { + pInstance->SetData(DATA_HORDE_RETREAT, 1); + Creature* JainaDummy = me->SummonCreature(JAINA,JainaDummySpawn[0][0],JainaDummySpawn[0][1],JainaDummySpawn[0][2],JainaDummySpawn[0][3],TEMPSUMMON_TIMED_DESPAWN,60000); + if (JainaDummy) + { + JainaDummy->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + CAST_AI(hyjalAI, JainaDummy->AI())->IsDummy = true; + DummyGuid = JainaDummy->GetGUID(); + } + AddWaypoint(0,JainaDummySpawn[1][0],JainaDummySpawn[1][1],JainaDummySpawn[1][2]); + Start(false, false); + SetDespawnAtEnd(false);//move to center of alliance base + } + } + SpawnVeins(); + Overrun = true; + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);//cant talk after overrun event started +} + +void hyjalAI::SpawnVeins() +{ + if (Faction == 0) + { + if (VeinsSpawned[0])//prevent any buggers + return; + for (uint8 i = 0; i<7; ++i) + { + GameObject* gem = me->SummonGameObject(ANCIENT_VEIN,VeinPos[i][0],VeinPos[i][1],VeinPos[i][2],VeinPos[i][3],VeinPos[i][4],VeinPos[i][5],VeinPos[i][6],VeinPos[i][7],0); + if (gem) + VeinGUID[i]=gem->GetGUID(); + } + VeinsSpawned[0] = true; + }else{ + if (VeinsSpawned[1]) + return; + for (uint8 i = 7; i<14; ++i) + { + GameObject* gem = me->SummonGameObject(ANCIENT_VEIN,VeinPos[i][0],VeinPos[i][1],VeinPos[i][2],VeinPos[i][3],VeinPos[i][4],VeinPos[i][5],VeinPos[i][6],VeinPos[i][7],0); + if (gem) + VeinGUID[i]=gem->GetGUID(); + } + VeinsSpawned[1] = true; + } +} + +void hyjalAI::DeSpawnVeins() +{ + if (!pInstance) + return; + if (Faction == 1) + { + Creature* pUnit=Unit::GetCreature((*me),pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (!pUnit)return; + hyjalAI* ai = CAST_AI(hyjalAI, pUnit->AI()); + if (!ai)return; + for (uint8 i = 0; i<7; ++i) + { + if (GameObject* gem = pInstance->instance->GetGameObject(pInstance->GetData64(ai->VeinGUID[i]))) + gem->Delete(); + } + } else if (Faction) + { + Creature* pUnit=Unit::GetCreature((*me),pInstance->GetData64(DATA_THRALL)); + if (!pUnit)return; + hyjalAI* ai = CAST_AI(hyjalAI, pUnit->AI()); + if (!ai)return; + for (uint8 i = 7; i<14; ++i) + { + if (GameObject* gem = pInstance->instance->GetGameObject(pInstance->GetData64(ai->VeinGUID[i]))) + gem->Delete(); + } + } +} + +void hyjalAI::UpdateAI(const uint32 diff) +{ + if (IsDummy) + { + if (MassTeleportTimer < diff && DoMassTeleport) + { + DoCast(me, SPELL_MASS_TELEPORT, false); + DoMassTeleport = false; + } else MassTeleportTimer -= diff; + return; + } + if (DoHide) + { + DoHide = false; + switch(me->GetEntry()) + { + case JAINA: + if (pInstance && pInstance->GetData(DATA_ALLIANCE_RETREAT)) + { + me->SetVisibility(VISIBILITY_OFF); + HideNearPos(me->GetPositionX(), me->GetPositionY()); + HideNearPos(5037.76, -1889.71); + for (uint8 i = 0; i < 92; ++i)//summon fires + me->SummonGameObject(FLAMEOBJECT,AllianceFirePos[i][0],AllianceFirePos[i][1],AllianceFirePos[i][2],AllianceFirePos[i][3],AllianceFirePos[i][4],AllianceFirePos[i][5],AllianceFirePos[i][6],AllianceFirePos[i][7],0); + + } + else me->SetVisibility(VISIBILITY_ON); + break; + case THRALL: //thrall + if (pInstance && pInstance->GetData(DATA_HORDE_RETREAT)) + { + me->SetVisibility(VISIBILITY_OFF); + HideNearPos(me->GetPositionX(), me->GetPositionY()); + HideNearPos(5563, -2763.19); + HideNearPos(5542.2, -2629.36); + for (uint8 i = 0; i < 65; ++i)//summon fires + me->SummonGameObject(FLAMEOBJECT,HordeFirePos[i][0],HordeFirePos[i][1],HordeFirePos[i][2],HordeFirePos[i][3],HordeFirePos[i][4],HordeFirePos[i][5],HordeFirePos[i][6],HordeFirePos[i][7],0); + + } + else me->SetVisibility(VISIBILITY_ON); + break; + } + } + if (DoRespawn) + { + if (RespawnTimer <= diff) + { + DoRespawn = false; + RespawnNearPos(me->GetPositionX(), me->GetPositionY()); + if (Faction == 0) + { + RespawnNearPos(5037.76, -1889.71); + } else if (Faction == 1) + { + RespawnNearPos(5563, -2763.19); + RespawnNearPos(5542.2, -2629.36); + } + me->SetVisibility(VISIBILITY_ON); + }else{ + RespawnTimer -= diff; + me->SetVisibility(VISIBILITY_OFF); + } + return; + } + if (Overrun) + DoOverrun(Faction, diff); + if (bRetreat) + { + if (RetreatTimer <= diff) + { + IsDummy = true; + bRetreat = false; + HideNearPos(me->GetPositionX(), me->GetPositionY()); + switch(me->GetEntry()) + { + case JAINA://jaina + HideNearPos(5037.76, -1889.71); + break; + case THRALL://thrall + HideNearPos(5563, -2763.19); + HideNearPos(5542.2, -2629.36); + HideNearPos(5603.75, -2853.12); + break; + } + me->SetVisibility(VISIBILITY_OFF); + } else RetreatTimer -= diff; + } + + if (!EventBegun) + return; + + if (Summon) + { + if (pInstance && EnemyCount) + { + EnemyCount = pInstance->GetData(DATA_TRASH); + if (!EnemyCount) + NextWaveTimer = 5000; + } + + if (NextWaveTimer <= diff) + { + if (Faction == 0) + SummonNextWave(AllianceWaves, WaveCount, AllianceBase); + else if (Faction == 1) + SummonNextWave(HordeWaves, WaveCount, HordeBase); + ++WaveCount; + } else NextWaveTimer -= diff; + } + + if (CheckTimer <= diff) + { + for (uint8 i = 0; i < 2; ++i) + { + if (BossGUID[i]) + { + Unit* pUnit = Unit::GetUnit((*me), BossGUID[i]); + if (pUnit && (!pUnit->isAlive())) + { + if (BossGUID[i] == BossGUID[0]) + { + Talk(INCOMING); + FirstBossDead = true; + } + else if (BossGUID[i] == BossGUID[1]) + { + Talk(SUCCESS); + SecondBossDead = true; + } + EventBegun = false; + CheckTimer = 0; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + BossGUID[i] = 0; + if (pInstance) + pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); // Reset world state for enemies to disable it + } + } + } + CheckTimer = 5000; + } else CheckTimer -= diff; + + if (!UpdateVictim()) + return; + + for (uint8 i = 0; i < 3; ++i) + { + if (Spell[i].SpellId) + { + if (SpellTimer[i] <= diff) + { + if (me->IsNonMeleeSpellCasted(false)) + me->InterruptNonMeleeSpells(false); + + Unit *pTarget = NULL; + + switch(Spell[i].TargetType) + { + case TARGETTYPE_SELF: pTarget = me; break; + case TARGETTYPE_RANDOM: pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); break; + case TARGETTYPE_VICTIM: pTarget = me->getVictim(); break; + } + + if (pTarget && pTarget->isAlive()) + { + DoCast(pTarget, Spell[i].SpellId); + SpellTimer[i] = Spell[i].Cooldown; + } + } else SpellTimer[i] -= diff; + } + } + + DoMeleeAttackIfReady(); +} +void hyjalAI::JustDied(Unit* /*killer*/) +{ + if (IsDummy)return; + me->Respawn(); + me->SetVisibility(VISIBILITY_OFF); + DoRespawn = true; + RespawnTimer = 120000; + Talk(DEATH); + Summons.DespawnAll();//despawn all wave's summons + if (pInstance) + {//reset encounter if boss is despawned (ex: thrall is killed, boss despawns, event stucks at inprogress) + if (pInstance->GetData(DATA_RAGEWINTERCHILLEVENT) == IN_PROGRESS) + pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED); + if (pInstance->GetData(DATA_ANETHERONEVENT) == IN_PROGRESS) + pInstance->SetData(DATA_ANETHERONEVENT, NOT_STARTED); + if (pInstance->GetData(DATA_KAZROGALEVENT) == IN_PROGRESS) + pInstance->SetData(DATA_KAZROGALEVENT, NOT_STARTED); + if (pInstance->GetData(DATA_AZGALOREVENT) == IN_PROGRESS) + pInstance->SetData(DATA_AZGALOREVENT, NOT_STARTED); + pInstance->SetData(DATA_RESET_RAIDDAMAGE, NULL);//reset damage on die + } +} +void hyjalAI::HideNearPos(float x, float y) +{ + CellPair pair(Trinity::ComputeCellPair(x, y)); + Cell cell(pair); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + // First get all creatures. + std::list creatures; + Trinity::AllFriendlyCreaturesInGrid creature_check(me); + Trinity::CreatureListSearcher creature_searcher(me, creatures, creature_check); + TypeContainerVisitor + , + GridTypeMapContainer> creature_visitor(creature_searcher); + + // Get Creatures + cell.Visit(pair, creature_visitor, *(me->GetMap())); + + if (!creatures.empty()) + { + for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + (*itr)->SetVisibility(VISIBILITY_OFF); + (*itr)->setFaction(35);//make them friendly so mobs won't attack them + } + } +} +void hyjalAI::RespawnNearPos(float x, float y) +{ + CellPair p(Trinity::ComputeCellPair(x, y)); + Cell cell(p); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + Trinity::RespawnDo u_do; + Trinity::WorldObjectWorker worker(me, u_do); + TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); + cell.Visit(p, obj_worker, *me->GetMap()); +} +void hyjalAI::WaypointReached(uint32 i) +{ + if (i == 1 || (i == 0 && me->GetEntry() == THRALL)) + { + me->MonsterYell(YELL_HURRY,0,0); + WaitForTeleport = true; + TeleportTimer = 20000; + if (me->GetEntry() == JAINA) + DoCast(me, SPELL_MASS_TELEPORT, false); + if (me->GetEntry() == THRALL && DummyGuid) + { + Unit* Dummy = Unit::GetUnit((*me),DummyGuid); + if (Dummy) + { + CAST_AI(hyjalAI, CAST_CRE(Dummy)->AI())->DoMassTeleport = true; + CAST_AI(hyjalAI, CAST_CRE(Dummy)->AI())->MassTeleportTimer = 20000; + Dummy->CastSpell(me, SPELL_MASS_TELEPORT, false); + } + } + //do some talking + //all alive guards walk near here + CellPair pair(Trinity::ComputeCellPair(me->GetPositionX(), me->GetPositionY())); + Cell cell(pair); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + // First get all creatures. + std::list creatures; + Trinity::AllFriendlyCreaturesInGrid creature_check(me); + Trinity::CreatureListSearcher creature_searcher(me, creatures, creature_check); + TypeContainerVisitor + , + GridTypeMapContainer> creature_visitor(creature_searcher); + + cell.Visit(pair, creature_visitor, *(me->GetMap())); + + if (!creatures.empty()) + { + for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + if ((*itr) && (*itr)->isAlive() && (*itr) != me && (*itr)->GetEntry() != JAINA) + { + if (!(*itr)->IsWithinDist(me, 60)) + (*itr)->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + float x, y, z; + (*itr)->SetDefaultMovementType(IDLE_MOTION_TYPE); + (*itr)->GetMotionMaster()->Initialize(); + float range = 10; + if (me->GetEntry() == THRALL)range = 20; + me->GetNearPoint(me, x, y, z, range, 0, me->GetAngle((*itr))); + (*itr)->GetMotionMaster()->MovePoint(0, x+irand(-5,5), y+irand(-5,5), me->GetPositionZ()); + } + } + } + } +} +void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) +{ + npc_escortAI::UpdateAI(diff); + if (WaitForTeleport) + { + if (TeleportTimer <= diff) + { + CellPair pair(Trinity::ComputeCellPair(me->GetPositionX(), me->GetPositionY())); + Cell cell(pair); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); + + std::list creatures; + Trinity::AllFriendlyCreaturesInGrid creature_check(me); + Trinity::CreatureListSearcher creature_searcher(me, creatures, creature_check); + TypeContainerVisitor + , + GridTypeMapContainer> creature_visitor(creature_searcher); + + cell.Visit(pair, creature_visitor, *(me->GetMap())); + + if (!creatures.empty()) + { + for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + if ((*itr) && (*itr)->isAlive()) + { + (*itr)->CastSpell(*itr, SPELL_TELEPORT_VISUAL, true); + (*itr)->setFaction(35);//make them friendly so mobs won't attack them + (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + DoCast(me, SPELL_TELEPORT_VISUAL); + bRetreat = true; + RetreatTimer = 1000; + } + + WaitForTeleport = false; + Teleported = true; + }TeleportTimer -= diff; + } + if (!Teleported) + return; + Overrun = false;//execute once + switch(faction) + { + case 0://alliance + for (uint8 i = 0; i < 92; ++i)//summon fires + me->SummonGameObject(FLAMEOBJECT,AllianceFirePos[i][0],AllianceFirePos[i][1],AllianceFirePos[i][2],AllianceFirePos[i][3],AllianceFirePos[i][4],AllianceFirePos[i][5],AllianceFirePos[i][6],AllianceFirePos[i][7],0); + + for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls + { + uint8 r = rand()%4; + Creature* pUnit = me->SummonCreature(GHOUL, AllianceBase[r][0]+irand(-15,15), AllianceBase[r][1]+irand(-15,15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (pUnit) + { + CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; + pUnit->setActive(true); + } + } + for (uint8 i = 0; i < 3; ++i)//summon 3 abominations + { + uint8 r = rand()%4; + Creature* pUnit = me->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15,15), AllianceBase[r][1]+irand(-15,15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (pUnit) + { + CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; + pUnit->setActive(true); + } + } + for (uint8 i = 0; i < 5; ++i)//summon 5 gargoyles + { + Creature* pUnit = me->SummonCreature(GARGOYLE, AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (pUnit) + { + pUnit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]); + CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; + pUnit->setActive(true); + } + } + break; + case 1://horde + for (uint8 i = 0; i < 65; ++i)//summon fires + me->SummonGameObject(FLAMEOBJECT,HordeFirePos[i][0],HordeFirePos[i][1],HordeFirePos[i][2],HordeFirePos[i][3],HordeFirePos[i][4],HordeFirePos[i][5],HordeFirePos[i][6],HordeFirePos[i][7],0); + + for (uint8 i = 0; i < 26; ++i)//summon infernals + { + Creature* pUnit = me->SummonCreature(GIANT_INFERNAL, InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (pUnit) + { + pUnit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]); + CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; + pUnit->setActive(true); + } + } + for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls + { + uint8 r = rand()%4; + Creature* pUnit = me->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15,15), HordeBase[r][1]+irand(-15,15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (pUnit) + { + CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; + pUnit->setActive(true); + } + } + for (uint8 i = 0; i < 5; ++i)//summon 5 abominations + { + uint8 r = rand()%4; + Creature* pUnit = me->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15,15), HordeBase[r][1]+irand(-15,15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (pUnit) + { + CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; + pUnit->setActive(true); + } + } + break; + } +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h new file mode 100644 index 00000000000..5c75465b7b4 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h @@ -0,0 +1,248 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef SC_HYJALAI_H +#define SC_HYJALAI_H + +#include "hyjal.h" +#include "ScriptedEscortAI.h" + +// Trash Mobs summoned in waves +#define NECROMANCER 17899//done +#define ABOMINATION 17898//done +#define GHOUL 17895//done +#define BANSHEE 17905//done +#define CRYPT_FIEND 17897//done +#define GARGOYLE 17906//done +#define FROST_WYRM 17907//done +#define GIANT_INFERNAL 17908//done +#define FEL_STALKER 17916//done + +#define JAINA 17772 +#define THRALL 17852 +#define TYRANDE 17948 + +#define ANCIENT_VEIN 185557 +#define FLAMEOBJECT 182592 + +// Bosses summoned after every 8 waves +#define RAGE_WINTERCHILL 17767 +#define ANETHERON 17808 +#define KAZROGAL 17888 +#define AZGALOR 17842 +#define ARCHIMONDE 17968 + +#define SPELL_TELEPORT_VISUAL 41232 +#define SPELL_MASS_TELEPORT 16807 + +//Spells for Jaina +#define SPELL_BRILLIANCE_AURA 31260 // The database must handle this spell via creature_addon(it should, but is removed in evade..) +#define SPELL_BLIZZARD 31266 +#define SPELL_PYROBLAST 31263 +#define SPELL_SUMMON_ELEMENTALS 31264 + +//Thrall spells +#define SPELL_CHAIN_LIGHTNING 31330 +#define SPELL_SUMMON_DIRE_WOLF 31331 + +struct Wave +{ + uint32 Mob[18]; // Stores Creature Entries to be summoned in Waves + uint32 WaveTimer; // The timer before the next wave is summoned + bool IsBoss; // Simply used to inform the wave summoner that the next wave contains a boss to halt all waves after that +}; + +static Wave AllianceWaves[]= // Waves that will be summoned in the Alliance Base +{ // Rage Winterchill Wave 1-8 + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, + // All 8 Waves are summoned, summon Rage Winterchill, next few waves are for Anetheron + {RAGE_WINTERCHILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true}, + // Anetheron Wave 1-8 + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, + {NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, + {CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, BANSHEE, BANSHEE, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, GHOUL, GHOUL, 0, 0, 0, 0, 120000, false}, + {GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, + // All 8 Waves are summoned, summon Anatheron + {ANETHERON, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true} +}; + +static Wave HordeWaves[]= // Waves that are summoned in the Horde base +{ // Kaz'Rogal Wave 1-8 + {GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, + {CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, + {GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 240000, false}, + // All 8 Waves are summoned, summon Kaz'Rogal, next few waves are for Azgalor + {KAZROGAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true}, + // Azgalor Wave 1-8 + {ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, FROST_WYRM, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0, 180000, false}, + {GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, 0, 0, 0, 0, 180000, false}, + {FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, + {NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 180000, false}, + {GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0, 180000, false}, + {CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 240000, false}, + // All 8 Waves are summoned, summon Azgalor + {AZGALOR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true} +}; + +enum TargetType // Used in the spell cast system for the AI +{ + TARGETTYPE_SELF = 0, + TARGETTYPE_RANDOM = 1, + TARGETTYPE_VICTIM = 2, +}; + +struct Yells +{ + uint32 id; // Used to determine the type of yell (attack, rally, etc) + int32 textid; // The text id to be yelled +}; + +enum YellId +{ + ATTACKED = 0, // Used when attacked and set in combat + BEGIN = 1, // Used when the event is begun + INCOMING = 2, // Used to warn the raid that another wave phase is coming + RALLY = 3, // Used to rally the raid and warn that the next wave has been summoned + FAILURE = 4, // Used when raid has failed (unsure where to place) + SUCCESS = 5, // Used when the raid has sucessfully defeated a wave phase + DEATH = 6, // Used on death +}; + +static Yells JainaQuotes[]= +{ + {ATTACKED, -1534000}, + {ATTACKED, -1534001}, + {INCOMING, -1534002}, + {BEGIN, -1534003}, + {RALLY, -1534004}, + {RALLY, -1534005}, + {FAILURE, -1534006}, + {SUCCESS, -1534007}, + {DEATH, -1534008}, +}; + +static Yells ThrallQuotes[]= +{ + {ATTACKED, -1534009}, + {ATTACKED, -1534010}, + {INCOMING, -1534011}, + {BEGIN, -1534012}, + {RALLY, -1534013}, + {RALLY, -1534014}, + {FAILURE, -1534015}, + {SUCCESS, -1534016}, + {DEATH, -1534017}, +}; + +struct hyjalAI : public npc_escortAI +{ + hyjalAI(Creature *c); + + void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat + + void EnterEvadeMode(); // Send creature back to spawn location and evade. + + void EnterCombat(Unit * /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack + + void UpdateAI(const uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells. + + void JustDied(Unit* /*killer*/); // Called on death, informs the raid that they have failed. + + void SetFaction(uint32 _faction) // Set the faction to either Alliance or Horde in Hyjal + { + Faction = _faction; + } + + void Retreat(); // "Teleport" (teleport visual + set invisible) all friendly creatures away from the base. + + void SpawnVeins(); + void DeSpawnVeins(); + void JustSummoned(Creature *summoned); + void SummonedCreatureDespawn(Creature* summoned); + void HideNearPos(float x, float y); + void RespawnNearPos(float x, float y); + void WaypointReached(uint32 i); + void DoOverrun(uint32 faction, const uint32 diff); + void MoveInLineOfSight(Unit *who); + + void SummonCreature(uint32 entry, float Base[4][3]); // Summons a creature for that wave in that base + + // Summons the next wave, calls SummonCreature + void SummonNextWave(Wave wave[18], uint32 Count, float Base[4][3]); + + void StartEvent(Player* player); // Begins the event by gossip click + + uint32 GetInstanceData(uint32 Event); // Gets instance data for this instance, used to check if raid has gotten past a certain point and can access the next phase + + void Talk(uint32 id); // Searches for the appropriate yell and sound and uses it to inform the raid of various things + + public: + ScriptedInstance* pInstance; + + uint64 PlayerGUID; + uint64 BossGUID[2]; + uint64 VeinGUID[14]; + + uint32 NextWaveTimer; + uint32 WaveCount; + uint32 CheckTimer; + uint32 Faction; + uint32 EnemyCount; + uint32 RetreatTimer; + + bool EventBegun; + bool FirstBossDead; + bool SecondBossDead; + bool Summon; + bool bRetreat; + bool Debug; + bool VeinsSpawned[2]; + uint8 InfernalCount; + SummonList Summons; + bool Overrun; + bool Teleported; + bool WaitForTeleport; + uint32 TeleportTimer; + uint32 OverrunCounter; + uint32 OverrunCounter2; + uint32 InfernalPoint; + uint32 RespawnTimer; + bool DoRespawn; + bool DoHide; + bool IsDummy; + uint32 MassTeleportTimer; + bool DoMassTeleport; + uint64 DummyGuid; + + struct Spell + { + uint32 SpellId; + uint32 Cooldown; + uint32 TargetType; + }Spell[3]; + + private: + uint32 SpellTimer[3]; + //std::list CreatureList; +}; +#endif + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp new file mode 100644 index 00000000000..c4cf9ede397 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -0,0 +1,1440 @@ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "hyjal_trash.h" +#include "hyjalAI.h" + +#define SPELL_METEOR 33814 //infernal visual +#define SPELL_IMMOLATION 37059 +#define SPELL_FLAME_BUFFET 31724 +#define NPC_TRIGGER 21987 //World Trigger (Tiny) +#define MODEL_INVIS 11686 //invisible model + +float HordeWPs[8][3]=//basic waypoints from spawn to leader +{ + {5492.91, -2404.61, 1462.63}, + {5531.76, -2460.87, 1469.55}, + {5554.58, -2514.66, 1476.12}, + {5554.16, -2567.23, 1479.90}, + {5540.67, -2625.99, 1480.89}, + {5508.16, -2659.20, 1480.15},//random rush starts from here + {5489.62, -2704.05, 1482.18}, + {5457.04, -2726.26, 1485.10} +}; +float AllianceWPs[8][3]=//basic waypoints from spawn to leader +{ + {4896.08, -1576.35, 1333.65}, + {4898.68, -1615.02, 1329.48}, + {4907.12, -1667.08, 1321.00}, + {4963.18, -1699.35, 1340.51}, + {4989.16, -1716.67, 1335.74},//first WP in the base, after the gate + {5026.27, -1736.89, 1323.02}, + {5037.77, -1770.56, 1324.36}, + {5067.23, -1789.95, 1321.17} +}; + +float FrostWyrmWPs[3][3]=//waypoints for the frost wyrms in horde base +{ + {5580.82, -2628.83, 1528.28}, + {5550.90, -2667.16, 1505.45}, + {5459.64, -2725.91, 1484.83} +}; + +float GargoyleWPs[3][3]=//waypoints for the gargoyles in horde base +{ + {5533.66, -2634.32, 1495.33}, + {5517.88, -2712.05, 1490.54}, + {5459.64, -2725.91, 1484.83} +}; + +float FlyPathWPs[3][3]=//waypoints for the gargoyls and frost wyrms in horde base in wave 1/3 +{ + {5531.96, -2772.83, 1516.68}, + {5498.32, -2734.84, 1497.01}, + {5456.67, -2725.48, 1493.08} +}; + +float AllianceOverrunWP[55][3]=//waypoints in the alliance base used in the end in the cleaning wave +{ + {4976.37,-1708.02,1339.43},//0spawn + {4994.83,-1725.52,1333.25},//1 start + {4982.92,-1753.7,1330.69},//2 end + {4996.75,-1721.47,1332.95},//3 start + {5015.74,-1755.05,1322.49},//4 + {4998.68,-1773.44,1329.59},//5 + {4994.83,-1725.52,1333.25},//6 start + {5022.8,-1735.46,1323.53},//7 + {5052.15,-1729.02,1320.88},//8 + {5082.43,-1726.29,1327.87},//9 + {4994.83,-1725.52,1333.25},//10 start + {5018.92,-1751.14,1322.19},//11 + {5040.09,-1792.09,1322.1},//12 + {4994.83,-1725.52,1333.25},//13 start + {5023.47,-1748.1,1322.51},//14 + {5013.43,-1842.39,1322.07},//15 + {4994.83,-1725.52,1333.25},//16 start + {5020.8,-1756.86,1322.2},//17 + {5019.53,-1824.6,1321.96},//18 + {5043.42,-1853.75,1324.52},//19 + {5053.02,-1864.13,1330.36},//20 + {5062.49,-1852.47,1330.49},//21 + {5015.27, -1738.77, 1324.83},//35//start 22 + {5027.97, -1775.25, 1321.87},//34 23 + {5015.94, -1821.24, 1321.86},//33 24 + {4983.25, -1857.4, 1320.48},//32 25 + {4981.51, -1883.7, 1322.34},//31 26 + {5002.33, -1893.98, 1325.88},//30 27 + {5049.32, -1886.54, 1331.69},//29 28 + {5089.68, -1846.88, 1328.99},//28 29 + {5127.90, -1825.14, 1335.58},//27 30 + {5163.27, -1789.08, 1337.04},//26 31 + {5138.97, -1755.88, 1334.57},//25 32 + {5096.63, -1742.22, 1329.61},//24 33 + {5065.81, -1729.43, 1325.66},//23 34 + {5049.32, -1726.31, 1320.64},//22 start + {5081.07, -1902.10, 1346.36},//36 abo start + {5107.65, -1912.03, 1356.49},//37 + {5132.83, -1927.07, 1362.42},//38 + {5147.78, -1954.41, 1365.98},//39 + {5164.96, -1966.48, 1367.04},//40 + {5189.04, -1961.06, 1367.90},//41 + {5212.27, -1975.30, 1365.58},//42 + {5221.82, -1994.18, 1364.97},//43 end1 + {5202.23, -1994.94, 1367.59},//44 end2 + {5279.94, -2049.68, 1311.38},//45 garg1 + {5289.15, -2219.06, 1291.12},//46 garg2 + {5202.07, -2136.10, 1305.07},//47 garg3 + {5071.52, -2425.63, 1454.48},//48 garg4 + {5120.65, -2467.92, 1463.93},//49 garg5 + {5283.04, -2043.26, 1300.11},//50 garg target1 + {5313.22, -2207.60, 1290.06},//51 garg target2 + {5180.41, -2121.87, 1292.62},//52 garg target3 + {5088.68, -2432.04, 1441.73},//53 garg target4 + {5111.26, -2454.73, 1449.63}//54 garg target5 + +}; + +float HordeOverrunWP[21][3]=//waypoints in the horde base used in the end in the cleaning wave +{ + {5490.72,-2702.94,1482.14},//0 start + {5469.77,-2741.34,1486.95}, + {5439.47,-2771.02,1494.59}, + {5408.85,-2811.92,1505.68}, + {5423.87,-2857.80,1515.55}, + {5428.19,-2898.15,1524.61}, + {5394.59,-2930.05,1528.23}, + {5351.11,-2935.80,1532.24}, + {5312.37,-2959.06,1536.21}, + {5264.93,-2989.80,1545.70}, + {5256.63,-3056.16,1559.24}, + {5267.32,-3119.55,1575.36}, + {5305.61,-3139.88,1586.38}, + {5330.56,-3135.37,1588.58}, + {5365.87,-3139.78,1583.96}, + {5389.39,-3163.57,1582.57},//15 end + {5500.86,-2669.89,1481.04},//16 start + {5472.08,-2715.14,1483.55}, + {5450.11,-2721.47,1485.61}, + {5433.25,-2712.93,1493.02},//19 end 1 + {5429.91,-2718.44,1493.42}//20 end 2 +}; + +hyjal_trashAI::hyjal_trashAI(Creature *c) : npc_escortAI(c) +{ + pInstance = c->GetInstanceData(); + IsEvent = false; + Delay = 0; + LastOverronPos = 0; + IsOverrun = false; + OverrunType = 0; + SetupOverrun = false; + faction = 0; + useFlyPath = false; + damageTaken = 0; + Reset(); +} + +void hyjal_trashAI::DamageTaken(Unit *done_by, uint32 &damage) +{ + if (done_by->GetTypeId() == TYPEID_PLAYER || (done_by->GetTypeId() == TYPEID_UNIT && CAST_CRE(done_by)->isPet())) + { + damageTaken += damage; + if (pInstance) + pInstance->SetData(DATA_RAIDDAMAGE,damage);//store raid's damage + } +} + +void hyjal_trashAI::UpdateAI(const uint32 /*diff*/) +{ + if (IsOverrun && !SetupOverrun) + { + SetupOverrun = true; + if (faction == 0) + { + if (me->GetEntry() == GARGOYLE) + { + DummyTarget[0] = AllianceOverrunWP[50+OverrunType][0]; //+OverrunType 0 - 4 + DummyTarget[1] = AllianceOverrunWP[50+OverrunType][1]; + DummyTarget[2] = AllianceOverrunWP[50+OverrunType][2]; + } + if (me->GetEntry() == ABOMINATION) + { + for (uint8 i = 0; i < 4; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + switch(OverrunType) + { + case 0: + AddWaypoint(4, AllianceOverrunWP[22][0]+irand(-3,3), AllianceOverrunWP[22][1]+irand(-3,3), AllianceOverrunWP[22][2]); + AddWaypoint(5, AllianceOverrunWP[23][0]+irand(-3,3), AllianceOverrunWP[23][1]+irand(-3,3), AllianceOverrunWP[23][2]); + AddWaypoint(6, AllianceOverrunWP[24][0]+irand(-3,3), AllianceOverrunWP[24][1]+irand(-3,3), AllianceOverrunWP[24][2]); + AddWaypoint(7, AllianceOverrunWP[25][0]+irand(-3,3), AllianceOverrunWP[25][1]+irand(-3,3), AllianceOverrunWP[25][2]); + AddWaypoint(8, AllianceOverrunWP[26][0]+irand(-3,3), AllianceOverrunWP[26][1]+irand(-3,3), AllianceOverrunWP[26][2]); + AddWaypoint(9, AllianceOverrunWP[27][0]+irand(-3,3), AllianceOverrunWP[27][1]+irand(-3,3), AllianceOverrunWP[27][2]); + AddWaypoint(10, AllianceOverrunWP[28][0]+irand(-3,3), AllianceOverrunWP[28][1]+irand(-3,3), AllianceOverrunWP[28][2]); + + AddWaypoint(11, AllianceOverrunWP[36][0]+irand(-3,3), AllianceOverrunWP[36][1]+irand(-3,3), AllianceOverrunWP[36][2]); + AddWaypoint(12, AllianceOverrunWP[37][0]+irand(-3,3), AllianceOverrunWP[37][1]+irand(-3,3), AllianceOverrunWP[37][2]); + AddWaypoint(13, AllianceOverrunWP[38][0]+irand(-3,3), AllianceOverrunWP[38][1]+irand(-3,3), AllianceOverrunWP[38][2]); + AddWaypoint(14, AllianceOverrunWP[39][0]+irand(-3,3), AllianceOverrunWP[39][1]+irand(-3,3), AllianceOverrunWP[39][2]); + AddWaypoint(15, AllianceOverrunWP[40][0]+irand(-3,3), AllianceOverrunWP[40][1]+irand(-3,3), AllianceOverrunWP[40][2]); + AddWaypoint(16, AllianceOverrunWP[41][0]+irand(-3,3), AllianceOverrunWP[41][1]+irand(-3,3), AllianceOverrunWP[41][2]); + AddWaypoint(17, AllianceOverrunWP[42][0]+irand(-3,3), AllianceOverrunWP[42][1]+irand(-3,3), AllianceOverrunWP[42][2]); + AddWaypoint(18, AllianceOverrunWP[43][0]+irand(-3,3), AllianceOverrunWP[43][1]+irand(-3,3), AllianceOverrunWP[43][2]); + me->SetHomePosition(AllianceOverrunWP[43][0]+irand(-3,3), AllianceOverrunWP[43][1]+irand(-3,3), AllianceOverrunWP[43][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 18; + Start(true, true); + break; + case 1: + AddWaypoint(4, AllianceOverrunWP[22][0]+irand(-3,3), AllianceOverrunWP[22][1]+irand(-3,3), AllianceOverrunWP[22][2]); + AddWaypoint(5, AllianceOverrunWP[23][0]+irand(-3,3), AllianceOverrunWP[23][1]+irand(-3,3), AllianceOverrunWP[23][2]); + AddWaypoint(6, AllianceOverrunWP[24][0]+irand(-3,3), AllianceOverrunWP[24][1]+irand(-3,3), AllianceOverrunWP[24][2]); + AddWaypoint(7, AllianceOverrunWP[25][0]+irand(-3,3), AllianceOverrunWP[25][1]+irand(-3,3), AllianceOverrunWP[25][2]); + AddWaypoint(8, AllianceOverrunWP[26][0]+irand(-3,3), AllianceOverrunWP[26][1]+irand(-3,3), AllianceOverrunWP[26][2]); + AddWaypoint(9, AllianceOverrunWP[27][0]+irand(-3,3), AllianceOverrunWP[27][1]+irand(-3,3), AllianceOverrunWP[27][2]); + AddWaypoint(10, AllianceOverrunWP[28][0]+irand(-3,3), AllianceOverrunWP[28][1]+irand(-3,3), AllianceOverrunWP[28][2]); + + AddWaypoint(11, AllianceOverrunWP[36][0]+irand(-3,3), AllianceOverrunWP[36][1]+irand(-3,3), AllianceOverrunWP[36][2]); + AddWaypoint(12, AllianceOverrunWP[37][0]+irand(-3,3), AllianceOverrunWP[37][1]+irand(-3,3), AllianceOverrunWP[37][2]); + AddWaypoint(13, AllianceOverrunWP[38][0]+irand(-3,3), AllianceOverrunWP[38][1]+irand(-3,3), AllianceOverrunWP[38][2]); + AddWaypoint(14, AllianceOverrunWP[39][0]+irand(-3,3), AllianceOverrunWP[39][1]+irand(-3,3), AllianceOverrunWP[39][2]); + AddWaypoint(15, AllianceOverrunWP[40][0]+irand(-3,3), AllianceOverrunWP[40][1]+irand(-3,3), AllianceOverrunWP[40][2]); + AddWaypoint(16, AllianceOverrunWP[41][0]+irand(-3,3), AllianceOverrunWP[41][1]+irand(-3,3), AllianceOverrunWP[41][2]); + AddWaypoint(17, AllianceOverrunWP[42][0]+irand(-3,3), AllianceOverrunWP[42][1]+irand(-3,3), AllianceOverrunWP[42][2]); + AddWaypoint(18, AllianceOverrunWP[44][0]+irand(-3,3), AllianceOverrunWP[44][1]+irand(-3,3), AllianceOverrunWP[44][2]); + me->SetHomePosition(AllianceOverrunWP[44][0]+irand(-3,3), AllianceOverrunWP[44][1]+irand(-3,3), AllianceOverrunWP[44][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 18; + Start(true, true); + break; + default: + for (uint8 i = 22; i < 36; ++i) + AddWaypoint(i-18, AllianceOverrunWP[i][0]+irand(-3,3), AllianceOverrunWP[i][1]+irand(-3,3), AllianceOverrunWP[i][2]); + + SetDespawnAtEnd(true); + LastOverronPos = 17; + Start(true, true); + break; + } + } + if (me->GetEntry() == GHOUL) + { + for (uint8 i = 0; i < 4; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + switch(OverrunType) + { + case 0: + AddWaypoint(4, AllianceOverrunWP[1][0]+irand(-3,3), AllianceOverrunWP[1][1]+irand(-3,3), AllianceOverrunWP[1][2]); + AddWaypoint(5, AllianceOverrunWP[2][0]+irand(-3,3), AllianceOverrunWP[2][1]+irand(-3,3), AllianceOverrunWP[2][2]); + me->SetHomePosition(AllianceOverrunWP[2][0]+irand(-3,3), AllianceOverrunWP[2][1]+irand(-3,3), AllianceOverrunWP[2][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 5; + Start(true, true); + break; + case 1: + AddWaypoint(4, AllianceOverrunWP[3][0]+irand(-3,3), AllianceOverrunWP[3][1]+irand(-3,3), AllianceOverrunWP[3][2]); + AddWaypoint(5, AllianceOverrunWP[4][0]+irand(-3,3), AllianceOverrunWP[4][1]+irand(-3,3), AllianceOverrunWP[4][2]); + AddWaypoint(6, AllianceOverrunWP[5][0]+irand(-3,3), AllianceOverrunWP[5][1]+irand(-3,3), AllianceOverrunWP[5][2]); + me->SetHomePosition(AllianceOverrunWP[5][0]+irand(-3,3), AllianceOverrunWP[5][1]+irand(-3,3), AllianceOverrunWP[5][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 6; + Start(true, true); + break; + case 2: + AddWaypoint(4, AllianceOverrunWP[6][0]+irand(-3,3), AllianceOverrunWP[6][1]+irand(-3,3), AllianceOverrunWP[6][2]); + AddWaypoint(5, AllianceOverrunWP[7][0]+irand(-3,3), AllianceOverrunWP[7][1]+irand(-3,3), AllianceOverrunWP[7][2]); + AddWaypoint(6, AllianceOverrunWP[8][0]+irand(-3,3), AllianceOverrunWP[8][1]+irand(-3,3), AllianceOverrunWP[8][2]); + AddWaypoint(7, AllianceOverrunWP[9][0]+irand(-3,3), AllianceOverrunWP[9][1]+irand(-3,3), AllianceOverrunWP[9][2]); + me->SetHomePosition(AllianceOverrunWP[9][0]+irand(-3,3), AllianceOverrunWP[9][1]+irand(-3,3), AllianceOverrunWP[9][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 7; + Start(true, true); + break; + case 3: + AddWaypoint(4, AllianceOverrunWP[10][0]+irand(-3,3), AllianceOverrunWP[10][1]+irand(-3,3), AllianceOverrunWP[10][2]); + AddWaypoint(5, AllianceOverrunWP[11][0]+irand(-3,3), AllianceOverrunWP[11][1]+irand(-3,3), AllianceOverrunWP[11][2]); + AddWaypoint(6, AllianceOverrunWP[12][0]+irand(-3,3), AllianceOverrunWP[12][1]+irand(-3,3), AllianceOverrunWP[12][2]); + me->SetHomePosition(AllianceOverrunWP[12][0]+irand(-3,3), AllianceOverrunWP[12][1]+irand(-3,3), AllianceOverrunWP[12][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 6; + Start(true, true); + break; + case 4: + AddWaypoint(4, AllianceOverrunWP[13][0]+irand(-3,3), AllianceOverrunWP[13][1]+irand(-3,3), AllianceOverrunWP[13][2]); + AddWaypoint(5, AllianceOverrunWP[14][0]+irand(-3,3), AllianceOverrunWP[14][1]+irand(-3,3), AllianceOverrunWP[14][2]); + AddWaypoint(6, AllianceOverrunWP[15][0]+irand(-3,3), AllianceOverrunWP[15][1]+irand(-3,3), AllianceOverrunWP[15][2]); + me->SetHomePosition(AllianceOverrunWP[15][0]+irand(-3,3), AllianceOverrunWP[15][1]+irand(-3,3), AllianceOverrunWP[15][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 6; + Start(true, true); + break; + case 5: + AddWaypoint(4, AllianceOverrunWP[16][0]+irand(-3,3), AllianceOverrunWP[16][1]+irand(-3,3), AllianceOverrunWP[16][2]); + AddWaypoint(5, AllianceOverrunWP[17][0]+irand(-3,3), AllianceOverrunWP[17][1]+irand(-3,3), AllianceOverrunWP[17][2]); + AddWaypoint(6, AllianceOverrunWP[18][0]+irand(-3,3), AllianceOverrunWP[18][1]+irand(-3,3), AllianceOverrunWP[18][2]); + AddWaypoint(7, AllianceOverrunWP[19][0]+irand(-3,3), AllianceOverrunWP[19][1]+irand(-3,3), AllianceOverrunWP[19][2]); + AddWaypoint(8, AllianceOverrunWP[20][0]+irand(-3,3), AllianceOverrunWP[20][1]+irand(-3,3), AllianceOverrunWP[20][2]); + AddWaypoint(9, AllianceOverrunWP[21][0]+irand(-3,3), AllianceOverrunWP[21][1]+irand(-3,3), AllianceOverrunWP[21][2]); + me->SetHomePosition(AllianceOverrunWP[21][0]+irand(-3,3), AllianceOverrunWP[21][1]+irand(-3,3), AllianceOverrunWP[21][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 9; + Start(true, true); + break; + default: + for (uint8 i = 22; i < 36; ++i) + AddWaypoint(i-18, AllianceOverrunWP[i][0]+irand(-3,3), AllianceOverrunWP[i][1]+irand(-3,3), AllianceOverrunWP[i][2]); + SetDespawnAtEnd(true); + LastOverronPos = 17; + Start(true, true); + break; + } + } + } + if (faction == 1) + { + if (me->GetEntry() == GHOUL) + { + for (uint8 i = 0; i < 6; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + switch(OverrunType) + { + case 0: + AddWaypoint(5, HordeOverrunWP[16][0]+irand(-10,10), HordeOverrunWP[16][1]+irand(-10,10), HordeOverrunWP[16][2]); + AddWaypoint(6, HordeOverrunWP[17][0]+irand(-10,10), HordeOverrunWP[17][1]+irand(-10,10), HordeOverrunWP[17][2]); + AddWaypoint(7, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]); + AddWaypoint(8, HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2]); + me->SetHomePosition(HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 8; + Start(true, true); + break; + case 1: + AddWaypoint(5, HordeOverrunWP[16][0]+irand(-10,10), HordeOverrunWP[16][1]+irand(-10,10), HordeOverrunWP[16][2]); + AddWaypoint(6, HordeOverrunWP[17][0]+irand(-10,10), HordeOverrunWP[17][1]+irand(-10,10), HordeOverrunWP[17][2]); + AddWaypoint(7, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]); + AddWaypoint(8, HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2]); + me->SetHomePosition(HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2],0); + SetDespawnAtEnd(false); + LastOverronPos = 8; + Start(true, true); + break; + default: + for (uint8 i = 0; i < 16; ++i) + AddWaypoint(i+6, HordeOverrunWP[i][0]+irand(-10,10), HordeOverrunWP[i][1]+irand(-10,10), HordeOverrunWP[i][2]); + SetDespawnAtEnd(true); + LastOverronPos = 21; + Start(true, true); + break; + } + } + if (me->GetEntry() == ABOMINATION) + { + for (uint8 i = 0; i < 6; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-10,10), HordeWPs[i][1]+irand(-10,10), HordeWPs[i][2]); + for (uint8 i = 0; i < 16; ++i) + AddWaypoint(i+6, HordeOverrunWP[i][0]+irand(-10,10), HordeOverrunWP[i][1]+irand(-10,10), HordeOverrunWP[i][2]); + SetDespawnAtEnd(true); + LastOverronPos = 21; + Start(true, true); + } + } + } +} + +void hyjal_trashAI::JustDied(Unit * /*victim*/) +{ + if (!pInstance) + return; + if (IsEvent && !me->isWorldBoss()) + pInstance->SetData(DATA_TRASH, 0);//signal trash is dead + + if ((pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE && !me->isWorldBoss()) || (damageTaken < me->GetMaxHealth()/4 && me->isWorldBoss())) + me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);//no loot +} + +struct mob_giant_infernalAI : public hyjal_trashAI +{ + mob_giant_infernalAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + meteor = false;//call once! + CanMove = false; + Delay = rand()%30000; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetDisplayId(MODEL_INVIS); + pGo = false; + pos = 0; + Reset(); + } + + bool meteor; + bool CanMove; + bool WpEnabled; + bool pGo; + uint32 pos; + uint32 spawnTimer; + uint32 FlameBuffetTimer; + bool imol; + + void Reset() + { + spawnTimer = 2000; + FlameBuffetTimer= 2000; + imol = false; + } + + void EnterCombat(Unit* /*who*/) {} + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 0 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (Delay <= diff) + { + Delay=0; + }else{ + Delay-=diff; + return; + } + if (!meteor) + { + float x,y,z; + me->GetPosition(x,y,z); + Creature* trigger = me->SummonCreature(NPC_TRIGGER,x+8,y+8,z+25+rand()%10,me->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,1000); + if (trigger) + { + trigger->SetVisibility(VISIBILITY_OFF); + trigger->setFaction(me->getFaction()); + trigger->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + trigger->CastSpell(me,SPELL_METEOR,true); + } + me->GetMotionMaster()->Clear(); + meteor = true; + } else if (!CanMove){ + if (spawnTimer <= diff) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetDisplayId(me->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); + CanMove = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT) && !pInstance->GetData(DATA_HORDE_RETREAT)) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } else if (pInstance->GetData(DATA_ALLIANCE_RETREAT) && pInstance->GetData(DATA_HORDE_RETREAT)){ + //do overrun + } + } + } else spawnTimer -= diff; + } + if (!CanMove)return; + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + AddWaypoint(0, HordeWPs[7][0]+irand(-3,3), HordeWPs[7][1]+irand(-3,3), HordeWPs[7][2]);//HordeWPs[7] infront of thrall + Start(true, true); + SetDespawnAtEnd(false); + } + } + } + + if (!UpdateVictim()) + return; + if (!imol) + { + DoCast(me, SPELL_IMMOLATION); + imol=true; + } + if (FlameBuffetTimer <= diff) + { + DoCast(me->getVictim(), SPELL_FLAME_BUFFET, true); + FlameBuffetTimer = 7000; + } else FlameBuffetTimer -= diff; + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_giant_infernal(Creature* pCreature) +{ + return new mob_giant_infernalAI(pCreature); +} + +#define SPELL_DISEASE_CLOUD 31607 +#define SPELL_KNOCKDOWN 31610 + +struct mob_abominationAI : public hyjal_trashAI +{ + mob_abominationAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + + bool pGo; + uint32 KnockDownTimer; + uint32 pos; + void Reset() + { + KnockDownTimer = 10000; + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + }else{ + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + if (i == LastOverronPos && IsOverrun) + { + if ((faction == 0 && LastOverronPos == 17) || (faction == 1 && LastOverronPos == 21)) + { + me->setDeathState(DEAD); + me->RemoveCorpse(); + } + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else//use alliance WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + } + if (!me->HasAura(SPELL_DISEASE_CLOUD)) + DoCast(me, SPELL_DISEASE_CLOUD); + if (!UpdateVictim()) + return; + if (KnockDownTimer <= diff) + { + DoCast(me->getVictim(), SPELL_KNOCKDOWN); + KnockDownTimer = 15000+rand()%10000; + } else KnockDownTimer -= diff; + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_abomination(Creature* pCreature) +{ + return new mob_abominationAI(pCreature); +} + +#define SPELL_FRENZY 31540 + +struct mob_ghoulAI : public hyjal_trashAI +{ + mob_ghoulAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + + bool pGo; + uint32 FrenzyTimer; + uint32 pos; + uint32 MoveTimer; + bool RandomMove; + void Reset() + { + FrenzyTimer = 5000+rand()%5000; + MoveTimer = 2000; + RandomMove = false; + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + }else{ + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + if (i == LastOverronPos && IsOverrun) + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACKUNARMED); + if ((faction == 0 && LastOverronPos == 17) || (faction == 1 && LastOverronPos == 21)) + { + me->setDeathState(DEAD); + me->RemoveCorpse(); + } + + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else//use alliance WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + } + if (FrenzyTimer <= diff) + { + DoCast(me, SPELL_FRENZY); + FrenzyTimer = 15000+rand()%15000; + } else FrenzyTimer -= diff; + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_ghoul(Creature* pCreature) +{ + return new mob_ghoulAI(pCreature); +} + +#define SPELL_RAISE_DEAD_1 31617 +#define SPELL_RAISE_DEAD_2 31624 +#define SPELL_RAISE_DEAD_3 31625 +#define SPELL_SHADOW_BOLT 31627 + +struct mob_necromancerAI : public hyjal_trashAI +{ + mob_necromancerAI(Creature* c) : hyjal_trashAI(c), summons(me) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + SummonList summons; + bool pGo; + uint32 ShadowBoltTimer; + uint32 pos; + void Reset() + { + ShadowBoltTimer = 1000+rand()%5000; + summons.DespawnAll(); + } + + void JustSummoned(Creature* summon) + { + Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0,30,true); + if (pTarget && summon) + summon->Attack(pTarget,false); + summons.Summon(summon); + } + void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + }else{ + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + } + + void KilledUnit(Unit* /*victim*/) + { + switch (urand(0,2)) + { + case 0: + DoSpawnCreature(17902,3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); + DoSpawnCreature(17902,-3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); + break; + case 1: + DoSpawnCreature(17903,3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); + DoSpawnCreature(17903,-3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); + break; + case 2: + DoSpawnCreature(RAND(17902,17903),3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); + break; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + Start(true, true); + SetDespawnAtEnd(false); + }else//use alliance WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + Start(true, true); + SetDespawnAtEnd(false); + } + } + } + } + if (!UpdateVictim()) + return; + if (ShadowBoltTimer <= diff) + { + DoCast(me->getVictim(), SPELL_SHADOW_BOLT); + ShadowBoltTimer = 20000+rand()%10000; + } else ShadowBoltTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_necromancer(Creature* pCreature) +{ + return new mob_necromancerAI(pCreature); +} + +#define SPELL_BANSHEE_CURSE 31651 +#define SPELL_BANSHEE_WAIL 38183 +#define SPELL_ANTI_MAGIC_SHELL 31662 + +struct mob_bansheeAI : public hyjal_trashAI +{ + mob_bansheeAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + + bool pGo; + uint32 CourseTimer; + uint32 WailTimer; + uint32 ShellTimer; + uint32 pos; + void Reset() + { + CourseTimer = 20000+rand()%5000; + WailTimer = 15000+rand()%5000; + ShellTimer = 50000+rand()%10000; + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + }else{ + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else//use alliance WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + } + if (!UpdateVictim()) + return; + if (CourseTimer <= diff) + { + DoCast(me->getVictim(), SPELL_BANSHEE_CURSE); + CourseTimer = 20000+rand()%5000; + } else CourseTimer -= diff; + if (WailTimer <= diff) + { + DoCast(me->getVictim(), SPELL_BANSHEE_WAIL); + WailTimer = 15000+rand()%5000; + } else WailTimer -= diff; + if (ShellTimer <= diff) + { + DoCast(me, SPELL_ANTI_MAGIC_SHELL); + ShellTimer = 50000+rand()%10000; + } else ShellTimer -= diff; + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_banshee(Creature* pCreature) +{ + return new mob_bansheeAI(pCreature); +} + +#define SPELL_WEB 28991 + +struct mob_crypt_fiendAI : public hyjal_trashAI +{ + mob_crypt_fiendAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + + bool pGo; + uint32 WebTimer; + uint32 pos; + void Reset() + { + WebTimer = 20000+rand()%5000; + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + }else{ + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else//use alliance WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + + } + } + } + if (!UpdateVictim()) + return; + if (WebTimer <= diff) + { + DoCast(me->getVictim(), SPELL_WEB); + WebTimer = 20000+rand()%5000; + } else WebTimer -= diff; + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_crypt_fiend(Creature* pCreature) +{ + return new mob_crypt_fiendAI(pCreature); +} + +#define SPELL_MANA_BURN 31729 + +struct mob_fel_stalkerAI : public hyjal_trashAI +{ + mob_fel_stalkerAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + + bool pGo; + uint32 ManaBurnTimer; + uint32 pos; + void Reset() + { + ManaBurnTimer = 9000+rand()%5000; + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 7 && pInstance && !IsOverrun) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + }else{ + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (pTarget && pTarget->isAlive()) + me->AddThreat(pTarget,0.0); + } + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + npc_escortAI::UpdateAI(diff); + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else//use alliance WPs + { + for (uint8 i = 0; i < 8; ++i) + AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + + } + } + } + if (!UpdateVictim()) + return; + if (ManaBurnTimer <= diff) + { + DoCast(me->getVictim(), SPELL_MANA_BURN); + ManaBurnTimer = 9000+rand()%5000; + } else ManaBurnTimer -= diff; + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_fel_stalker(Creature* pCreature) +{ + return new mob_fel_stalkerAI(pCreature); +} + +#define SPELL_FROST_BREATH 31688 + +struct mob_frost_wyrmAI : public hyjal_trashAI +{ + mob_frost_wyrmAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + Reset(); + } + + bool pGo; + uint32 FrostBreathTimer; + uint32 pos; + uint32 MoveTimer; + + void Reset() + { + FrostBreathTimer = 5000; + MoveTimer = 0; + me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 2 && pInstance && !IsOverrun) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + { + me->AddThreat(pTarget,0.0); + DoCast(pTarget, SPELL_FROST_BREATH, true); + } + } + } + + void JustDied(Unit * /*victim*/) + { + if (pInstance && IsEvent) + pInstance->SetData(DATA_TRASH, 0);//signal trash is dead + + float x,y,z; + me->GetPosition(x,y,z); + z = me->GetMap()->GetHeight(x, y, z); + me->GetMotionMaster()->MovePoint(0,x,y,z); + me->GetMap()->CreatureRelocation(me, x,y,z,0); + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + { + CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); + npc_escortAI::UpdateAI(diff); + } + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (!useFlyPath) + { + for (uint8 i = 0; i < 3; ++i) + AddWaypoint(i, FrostWyrmWPs[i][0], FrostWyrmWPs[i][1], FrostWyrmWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else{//fly path FlyPathWPs + for (uint8 i = 0; i < 3; ++i) + AddWaypoint(i, FlyPathWPs[i][0]+irand(-10,10), FlyPathWPs[i][1]+irand(-10,10), FlyPathWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + } + if (!UpdateVictim()) + return; + if (!me->IsWithinDist(me->getVictim(), 25)){ + if (MoveTimer <= diff) + { + me->GetMotionMaster()->MoveChase(me->getVictim()); + MoveTimer = 2000; + } else MoveTimer-=diff; + } + + if (FrostBreathTimer <= diff) + { + if (!me->IsWithinDist(me->getVictim(), 25)) + { + DoCast(me->getVictim(), SPELL_FROST_BREATH); + me->StopMoving(); + me->GetMotionMaster()->Clear(); + FrostBreathTimer = 4000; + } + } else FrostBreathTimer -= diff; + } +}; + +CreatureAI* GetAI_mob_frost_wyrm(Creature* pCreature) +{ + return new mob_frost_wyrmAI(pCreature); +} + +#define SPELL_GARGOYLE_STRIKE 31664 + +struct mob_gargoyleAI : public hyjal_trashAI +{ + mob_gargoyleAI(Creature* c) : hyjal_trashAI(c) + { + pInstance = c->GetInstanceData(); + pGo = false; + pos = 0; + DummyTarget[0] = 0;DummyTarget[1] = 0;DummyTarget[2] = 0; + Reset(); + } + + bool pGo; + uint32 StrikeTimer; + uint32 pos; + uint32 MoveTimer; + float Zpos; + bool forcemove; + + void Reset() + { + forcemove = true; + Zpos = 10.0; + StrikeTimer = 2000+rand()%5000; + MoveTimer = 0; + me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + } + + void WaypointReached(uint32 i) + { + pos = i; + if (i == 2 && pInstance && !IsOverrun) + { + Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); + if (pTarget && pTarget->isAlive()) + { + me->AddThreat(pTarget,0.0); + DoCast(pTarget, SPELL_GARGOYLE_STRIKE, true); + } + } + } + + void JustDied(Unit *victim) + { + float x,y,z; + me->GetPosition(x,y,z); + z = me->GetMap()->GetHeight(x, y, z); + me->GetMotionMaster()->MovePoint(0,x,y,z); + me->GetMap()->CreatureRelocation(me, x,y,z,0); + hyjal_trashAI::JustDied(victim); + } + + void UpdateAI(const uint32 diff) + { + hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) + { + CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); + npc_escortAI::UpdateAI(diff); + } + if (IsEvent) + { + if (!pGo) + { + pGo = true; + if (pInstance) + { + if (!useFlyPath) + { + for (uint8 i = 0; i < 3; ++i) + AddWaypoint(i, GargoyleWPs[i][0]+irand(-10,10), GargoyleWPs[i][1]+irand(-10,10), GargoyleWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + }else{//fly path FlyPathWPs + for (uint8 i = 0; i < 3; ++i) + AddWaypoint(i, FlyPathWPs[i][0]+irand(-10,10), FlyPathWPs[i][1]+irand(-10,10), FlyPathWPs[i][2]); + Start(false, true); + SetDespawnAtEnd(false); + } + } + } + } + if (IsOverrun && !UpdateVictim()) + { + if (faction == 0)//alliance + { + if (StrikeTimer <= diff) + { + me->CastSpell(DummyTarget[0],DummyTarget[1],DummyTarget[2],SPELL_GARGOYLE_STRIKE,false); + StrikeTimer = 2000+rand()%1000; + } else StrikeTimer -= diff; + } + } + if (!UpdateVictim()) + return; + if (!me->IsWithinDist(me->getVictim(), 20) || forcemove) + { + forcemove = false; + if (forcemove) + { + Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (pTarget) + me->Attack(pTarget,false); + } + if (MoveTimer <= diff) + { + float x,y,z; + me->getVictim()->GetPosition(x,y,z); + me->GetMotionMaster()->MovePoint(0,x,y,z+Zpos); + Zpos-=1.0; + if (Zpos <= 0)Zpos=0; + MoveTimer = 2000; + } else MoveTimer-=diff; + } + if (StrikeTimer <= diff) + { + if (me->IsWithinDist(me->getVictim(), 20)) + { + DoCast(me->getVictim(), SPELL_GARGOYLE_STRIKE); + me->StopMoving(); + me->GetMotionMaster()->Clear(); + StrikeTimer = 2000+rand()%1000; + } else StrikeTimer=0; + } else StrikeTimer -= diff; + } +}; + +CreatureAI* GetAI_mob_gargoyle(Creature* pCreature) +{ + return new mob_gargoyleAI(pCreature); +} + +#define SPELL_EXPLODING_SHOT 7896 + +struct alliance_riflemanAI : public Scripted_NoMovementAI +{ + alliance_riflemanAI(Creature *c) : Scripted_NoMovementAI(c) + { + Reset(); + } + + uint32 ExplodeTimer; + + void JustDied(Unit* /*who*/) + { + } + + void Reset() + { + ExplodeTimer = 5000+rand()%5000; + } + + void MoveInLineOfSight(Unit *who) + { + if (!who || me->getVictim()) + return; + + if (who->isTargetableForAttack() && me->IsHostileTo(who)) + { + //float attackRadius = me->GetAttackDistance(who); + if (me->IsWithinDistInMap(who, 30)) + AttackStart(who); + } + } + + void EnterCombat(Unit * /*who*/) + { + } + + void UpdateAI(const uint32 diff) + { + //Check if we have a target + if (!UpdateVictim()) + return; + if (ExplodeTimer <= diff) + { + if (!me->IsWithinDistInMap(me->getVictim(), 30)) + { + EnterEvadeMode(); + return; + } + int dmg = 500+rand()%700; + me->CastCustomSpell(me->getVictim(), SPELL_EXPLODING_SHOT, &dmg, 0, 0, false); + ExplodeTimer = 5000+rand()%5000; + } else ExplodeTimer -= diff; + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_alliance_rifleman(Creature* pCreature) +{ + return new alliance_riflemanAI(pCreature); +} + +void AddSC_hyjal_trash() +{ + Script *newscript = new Script; + newscript->Name = "mob_giant_infernal"; + newscript->GetAI = &GetAI_mob_giant_infernal; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_abomination"; + newscript->GetAI = &GetAI_mob_abomination; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ghoul"; + newscript->GetAI = &GetAI_mob_ghoul; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_necromancer"; + newscript->GetAI = &GetAI_mob_necromancer; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_banshee"; + newscript->GetAI = &GetAI_mob_banshee; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_crypt_fiend"; + newscript->GetAI = &GetAI_mob_crypt_fiend; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_fel_stalker"; + newscript->GetAI = &GetAI_mob_fel_stalker; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_frost_wyrm"; + newscript->GetAI = &GetAI_mob_frost_wyrm; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_gargoyle"; + newscript->GetAI = &GetAI_mob_gargoyle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "alliance_rifleman"; + newscript->GetAI = &GetAI_alliance_rifleman; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h new file mode 100644 index 00000000000..21ee4bc06cc --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h @@ -0,0 +1,35 @@ + +#ifndef SC_HYJAL_TRASH_AI_H +#define SC_HYJAL_TRASH_AI_H + +#include "hyjal.h" +#include "ScriptedEscortAI.h" + +#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies + +struct hyjal_trashAI : public npc_escortAI +{ + hyjal_trashAI(Creature *c); + + void UpdateAI(const uint32 diff); + + void JustDied(Unit* /*killer*/); + + void DamageTaken(Unit *done_by, uint32 &damage); + + public: + ScriptedInstance* pInstance; + bool IsEvent; + uint32 Delay; + uint32 LastOverronPos; + bool IsOverrun; + bool SetupOverrun; + uint32 OverrunType; + uint8 faction; + bool useFlyPath; + uint32 damageTaken; + float DummyTarget[3]; + + //private: +}; +#endif diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp new file mode 100644 index 00000000000..e89d518c5bc --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -0,0 +1,324 @@ + /* Copyright (C) 2006 - 2009 ScriptDev2 + * 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_Mount_Hyjal +SD%Complete: 100 +SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Hyjal Scripts +SDCategory: Caverns of Time, Mount Hyjal +EndScriptData */ + +#include "ScriptedPch.h" +#include "hyjal.h" +#include "hyjal_trash.h" + +enum eEnums +{ + MAX_ENCOUNTER = 5, + + GO_ANCIENT_GEM = 185557 +}; +/* Battle of Mount Hyjal encounters: +0 - Rage Winterchill event +1 - Anetheron event +2 - Kaz'rogal event +3 - Azgalor event +4 - Archimonde event +*/ + +struct instance_mount_hyjal : public ScriptedInstance +{ + instance_mount_hyjal(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string str_data; + + std::list m_uiAncientGemGUID; + + uint64 RageWinterchill; + uint64 Anetheron; + uint64 Kazrogal; + uint64 Azgalor; + uint64 Archimonde; + uint64 JainaProudmoore; + uint64 Thrall; + uint64 TyrandeWhisperwind; + uint64 HordeGate; + uint64 ElfGate; + + uint32 Trash; + + uint32 hordeRetreat; + uint32 allianceRetreat; + bool ArchiYell; + + uint32 RaidDamage; + + #define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more." + #define YELL_EFFORTS_NAME "Archimonde" + + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + m_uiAncientGemGUID.clear(); + + RageWinterchill = 0; + Anetheron = 0; + Kazrogal = 0; + Azgalor = 0; + Archimonde = 0; + JainaProudmoore = 0; + Thrall = 0; + TyrandeWhisperwind = 0; + HordeGate = 0; + ElfGate = 0; + ArchiYell = false; + RaidDamage = 0; + + Trash = 0; + + hordeRetreat = 0; + allianceRetreat = 0; + } + + bool IsEncounterInProgress() const + { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) return true; + + return false; + } + + void OnGameObjectCreate(GameObject* pGo, bool /*add*/) + { + switch(pGo->GetEntry()) + { + case 182060: + HordeGate = pGo->GetGUID(); + if (allianceRetreat) + HandleGameObject(0, true, pGo); + else + HandleGameObject(0, false, pGo); + break; + case 182061: + ElfGate = pGo->GetGUID(); + if (hordeRetreat) + HandleGameObject(0, true, pGo); + else + HandleGameObject(0, false, pGo); + break; + case GO_ANCIENT_GEM: + m_uiAncientGemGUID.push_back(pGo->GetGUID()); + break; + } + } + + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + switch(pCreature->GetEntry()) + { + case 17767: RageWinterchill = pCreature->GetGUID(); break; + case 17808: Anetheron = pCreature->GetGUID(); break; + case 17888: Kazrogal = pCreature->GetGUID(); break; + case 17842: Azgalor = pCreature->GetGUID(); break; + case 17968: Archimonde = pCreature->GetGUID(); break; + case 17772: JainaProudmoore = pCreature->GetGUID(); break; + case 17852: Thrall = pCreature->GetGUID(); break; + case 17948: TyrandeWhisperwind = pCreature->GetGUID(); break; + } + } + + uint64 GetData64(uint32 identifier) + { + switch(identifier) + { + case DATA_RAGEWINTERCHILL: return RageWinterchill; + case DATA_ANETHERON: return Anetheron; + case DATA_KAZROGAL: return Kazrogal; + case DATA_AZGALOR: return Azgalor; + case DATA_ARCHIMONDE: return Archimonde; + case DATA_JAINAPROUDMOORE: return JainaProudmoore; + case DATA_THRALL: return Thrall; + case DATA_TYRANDEWHISPERWIND: return TyrandeWhisperwind; + } + + return 0; + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case DATA_RAGEWINTERCHILLEVENT: m_auiEncounter[0] = data; break; + case DATA_ANETHERONEVENT: + m_auiEncounter[1] = data; + break; + case DATA_KAZROGALEVENT: m_auiEncounter[2] = data; break; + case DATA_AZGALOREVENT: + { + m_auiEncounter[3] = data; + if (data == DONE) + { + if (ArchiYell)break; + ArchiYell = true; + + Creature* pCreature = instance->GetCreature(Azgalor); + if (pCreature) + { + Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); + + Map* pMap = pCreature->GetMap(); + if (pMap->IsDungeon() && pUnit) + { + pUnit->SetVisibility(VISIBILITY_OFF); + Map::PlayerList const &PlayerList = pMap->GetPlayers(); + if (PlayerList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + { + if (i->getSource()) + { + WorldPacket data(SMSG_MESSAGECHAT, 200); + pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,YELL_EFFORTS,0,YELL_EFFORTS_NAME,i->getSource()->GetGUID()); + i->getSource()->GetSession()->SendPacket(&data); + + WorldPacket data2(SMSG_PLAY_SOUND, 4); + data2 << 10986; + i->getSource()->GetSession()->SendPacket(&data2); + } + } + } + } + } + } + break; + case DATA_ARCHIMONDEEVENT: m_auiEncounter[4] = data; break; + case DATA_RESET_TRASH_COUNT: Trash = 0; break; + + case DATA_TRASH: + if (data) Trash = data; + else Trash--; + DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); + break; + case TYPE_RETREAT: + if (data == SPECIAL) + { + if (!m_uiAncientGemGUID.empty()) + { + for (std::list::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr) + { + //don't know how long it expected + DoRespawnGameObject(*itr,DAY); + } + } + } + break; + case DATA_ALLIANCE_RETREAT: + allianceRetreat = data; + HandleGameObject(HordeGate, true); + SaveToDB(); + break; + case DATA_HORDE_RETREAT: + hordeRetreat = data; + HandleGameObject(ElfGate, true); + SaveToDB(); + break; + case DATA_RAIDDAMAGE: + RaidDamage += data; + if (RaidDamage >= MINRAIDDAMAGE) + RaidDamage = MINRAIDDAMAGE; + break; + case DATA_RESET_RAIDDAMAGE: + RaidDamage = 0; + break; + } + + debug_log("TSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); + + if (data == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " + << m_auiEncounter[3] << " " << m_auiEncounter[4] + << " " << allianceRetreat << " " << hordeRetreat + << " " << RaidDamage; + + str_data = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + + } + + uint32 GetData(uint32 type) + { + switch(type) + { + case DATA_RAGEWINTERCHILLEVENT: return m_auiEncounter[0]; + case DATA_ANETHERONEVENT: return m_auiEncounter[1]; + case DATA_KAZROGALEVENT: return m_auiEncounter[2]; + case DATA_AZGALOREVENT: return m_auiEncounter[3]; + case DATA_ARCHIMONDEEVENT: return m_auiEncounter[4]; + case DATA_TRASH: return Trash; + case DATA_ALLIANCE_RETREAT: return allianceRetreat; + case DATA_HORDE_RETREAT: return hordeRetreat; + case DATA_RAIDDAMAGE: return RaidDamage; + } + return 0; + } + + std::string GetSaveData() + { + return str_data; + } + + void Load(const char* in) + { + if (!in) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(in); + std::istringstream loadStream(in); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4] >> allianceRetreat >> hordeRetreat >> RaidDamage; + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as IN_PROGRESS - reset it instead. + m_auiEncounter[i] = NOT_STARTED; + OUT_LOAD_INST_DATA_COMPLETE; + } +}; + +InstanceData* GetInstanceData_instance_mount_hyjal(Map* pMap) +{ + return new instance_mount_hyjal(pMap); +} + +void AddSC_instance_mount_hyjal() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_hyjal"; + newscript->GetInstanceData = &GetInstanceData_instance_mount_hyjal; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp new file mode 100644 index 00000000000..287d3cf8e9b --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_epoch.cpp @@ -0,0 +1,156 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + + +/* Script Data Start +SDName: Boss epoch +SDAuthor: Tartalo +SD%Complete: 80 +SDComment: TODO: Intro, consecutive attacks to a random target durin time wrap, adjust timers +SDCategory: +Script Data End */ + +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CURSE_OF_EXERTION = 52772, + SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec. + SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec. + SPELL_WOUNDING_STRIKE = 52771, //Used only on the tank + H_SPELL_WOUNDING_STRIKE = 58830 +}; + +enum Yells +{ + SAY_INTRO = -1595000, //"Prince Arthas Menethil, on this day, a powerful darkness has taken hold of your soul. The death you are destined to visit upon others will this day be your own." + SAY_AGGRO = -1595001, //"We'll see about that, young prince." + SAY_TIME_WARP_1 = -1595002, //"Tick tock, tick tock..." + SAY_TIME_WARP_2 = -1595003, //"Not quick enough!" + SAY_TIME_WARP_3 = -1595004, //"Let's get this over with. " + SAY_SLAY_1 = -1595005, //"There is no future for you." + SAY_SLAY_2 = -1595006, //"This is the hour of our greatest triumph!" + SAY_SLAY_3 = -1595007, //"You were destined to fail. " + SAY_DEATH = -1595008 //"*gurgles*" +}; + +struct boss_epochAI : public ScriptedAI +{ + boss_epochAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + uint8 uiStep; + + uint32 uiStepTimer; + uint32 uiWoundingStrikeTimer; + uint32 uiTimeWarpTimer; + uint32 uiTimeStopTimer; + uint32 uiCurseOfExertionTimer; + + ScriptedInstance* pInstance; + + void Reset() + { + uiStep = 1; + uiStepTimer = 26000; + uiCurseOfExertionTimer = 9300; + uiTimeWarpTimer = 25300; + uiTimeStopTimer = 21300; + uiWoundingStrikeTimer = 5300; + + if (pInstance) + pInstance->SetData(DATA_EPOCH_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + DoScriptText(SAY_AGGRO, me); + + if (pInstance) + pInstance->SetData(DATA_EPOCH_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + if (uiCurseOfExertionTimer < diff) + { + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(pTarget, SPELL_CURSE_OF_EXERTION); + uiCurseOfExertionTimer = 9300; + } else uiCurseOfExertionTimer -= diff; + + if (uiWoundingStrikeTimer < diff) + { + DoCastVictim(SPELL_WOUNDING_STRIKE); + uiWoundingStrikeTimer = 5300; + } else uiWoundingStrikeTimer -= diff; + + if (uiTimeStopTimer < diff) + { + DoCastAOE(SPELL_TIME_STOP); + uiTimeStopTimer = 21300; + } else uiTimeStopTimer -= diff; + + if (uiTimeWarpTimer < diff) + { + DoScriptText(RAND(SAY_TIME_WARP_1,SAY_TIME_WARP_2,SAY_TIME_WARP_3), me); + DoCastAOE(SPELL_TIME_WARP); + uiTimeWarpTimer = 25300; + } else uiTimeWarpTimer -= diff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance) + pInstance->SetData(DATA_EPOCH_EVENT, DONE); + } + + void KilledUnit(Unit * victim) + { + if (victim == me) + return; + + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me); + } +}; + +CreatureAI* GetAI_boss_epoch(Creature* pCreature) +{ + return new boss_epochAI (pCreature); +} + +void AddSC_boss_epoch() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_epoch"; + newscript->GetAI = &GetAI_boss_epoch; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp new file mode 100644 index 00000000000..12cdf00f2a5 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_infinite.cpp @@ -0,0 +1,88 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CORRUPTING_BLIGHT = 60588, + SPELL_VOID_STRIKE = 60590 +}; + +enum Yells +{ + SAY_AGGRO = -1595045, + SAY_FAIL = -1595046, + SAY_DEATH = -1595047 +}; + + +struct boss_infinite_corruptorAI : public ScriptedAI +{ + boss_infinite_corruptorAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance* pInstance; + + void Reset() + { + if (pInstance) + pInstance->SetData(DATA_INFINITE_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + if (pInstance) + pInstance->SetData(DATA_INFINITE_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; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + if (pInstance) + pInstance->SetData(DATA_INFINITE_EVENT, DONE); + } +}; + +CreatureAI* GetAI_boss_infinite_corruptor(Creature* pCreature) +{ + return new boss_infinite_corruptorAI(pCreature); +} + +void AddSC_boss_infinite_corruptor() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_infinite_corruptor"; + newscript->GetAI = &GetAI_boss_infinite_corruptor; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp new file mode 100644 index 00000000000..a39f3289a5a --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp @@ -0,0 +1,262 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + +/* Script Data Start +SDName: Boss mal_ganis +SDAuthor: Tartalo +SD%Complete: 80 +SDComment: TODO: Intro & outro +SDCategory: +Script Data End */ + +/*** SQL START *** +update creature_template set scriptname = 'boss_mal_ganis' where entry = ''; +*** SQL END ***/ +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CARRION_SWARM = 52720, //A cresting wave of chaotic magic splashes over enemies in front of the caster, dealing 3230 to 3570 Shadow damage and 380 to 420 Shadow damage every 3 sec. for 15 sec. + H_SPELL_CARRION_SWARM = 58852, + SPELL_MIND_BLAST = 52722, //Inflicts 4163 to 4837 Shadow damage to an enemy. + H_SPELL_MIND_BLAST = 58850, + SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target. + H_SPELL_SLEEP = 58849, + SPELL_VAMPIRIC_TOUCH = 52723 //Heals the caster for half the damage dealt by a melee attack. +}; + +enum Yells +{ + SAY_INTRO_1 = -1595009, + SAY_INTRO_2 = -1595010, + SAY_AGGRO = -1595011, + SAY_KILL_1 = -1595012, + SAY_KILL_2 = -1595013, + SAY_KILL_3 = -1595014, + SAY_SLAY_1 = -1595015, + SAY_SLAY_2 = -1595016, + SAY_SLAY_3 = -1595017, + SAY_SLAY_4 = -1595018, + SAY_SLEEP_1 = -1595019, + SAY_SLEEP_2 = -1595020, + SAY_30HEALTH = -1595021, + SAY_15HEALTH = -1595022, + SAY_ESCAPE_SPEECH_1 = -1595023, + SAY_ESCAPE_SPEECH_2 = -1595024, + SAY_OUTRO = -1595025, +}; + +enum CombatPhases +{ + COMBAT, + OUTRO +}; + +struct boss_mal_ganisAI : public ScriptedAI +{ + boss_mal_ganisAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + uint32 uiCarrionSwarmTimer; + uint32 uiMindBlastTimer; + uint32 uiVampiricTouchTimer; + uint32 uiSleepTimer; + + uint8 uiOutroStep; + uint32 uiOutroTimer; + + bool bYelled; + bool bYelled2; + + CombatPhases Phase; + + ScriptedInstance* pInstance; + + void Reset() + { + bYelled = false; + bYelled2 = false; + Phase = COMBAT; + uiCarrionSwarmTimer = 6000; + uiMindBlastTimer = 11000; + uiVampiricTouchTimer = urand(10000,15000); + uiSleepTimer = urand(15000,20000); + uiOutroTimer = 1000; + + if (pInstance) + pInstance->SetData(DATA_MAL_GANIS_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + DoScriptText(SAY_AGGRO, me); + if (pInstance) + pInstance->SetData(DATA_MAL_GANIS_EVENT, IN_PROGRESS); + } + + void DamageTaken(Unit *done_by, uint32 &damage) + { + if (damage >= me->GetHealth() && done_by != me) + damage = me->GetHealth()-1; + } + + void UpdateAI(const uint32 diff) + { + switch(Phase) + { + case COMBAT: + //Return since we have no target + if (!UpdateVictim()) + return; + + if (!bYelled && HealthBelowPct(30)) + { + DoScriptText(SAY_30HEALTH, me); + bYelled = true; + } + + if (!bYelled2 && HealthBelowPct(15)) + { + DoScriptText(SAY_15HEALTH, me); + bYelled2 = true; + } + + if (HealthBelowPct(1)) + { + //Handle Escape Event: Don't forget to add Player::RewardPlayerAndGroupAtEvent + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + uiOutroStep = 1; + Phase = OUTRO; + return; + } + + if (Creature* pArthas = me->GetCreature(*me, pInstance ? pInstance->GetData64(DATA_ARTHAS) : 0)) + if (pArthas->isDead()) + { + EnterEvadeMode(); + me->DisappearAndDie(); + if (pInstance) + pInstance->SetData(DATA_MAL_GANIS_EVENT, FAIL); + } + + if (uiCarrionSwarmTimer < diff) + { + DoCastVictim(SPELL_CARRION_SWARM); + uiCarrionSwarmTimer = 7000; + } else uiCarrionSwarmTimer -= diff; + + if (uiMindBlastTimer < diff) + { + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(pTarget, SPELL_MIND_BLAST); + uiMindBlastTimer = 6000; + } else uiMindBlastTimer -= diff; + + if (uiVampiricTouchTimer < diff) + { + DoCast(me, SPELL_VAMPIRIC_TOUCH); + uiVampiricTouchTimer = 32000; + } else uiVampiricTouchTimer -= diff; + + if (uiSleepTimer < diff) + { + DoScriptText(RAND(SAY_SLEEP_1,SAY_SLEEP_2), me); + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(pTarget, SPELL_SLEEP); + uiSleepTimer = urand(15000,20000); + } else uiSleepTimer -= diff; + + DoMeleeAttackIfReady(); + break; + case OUTRO: + if (uiOutroTimer < diff) + { + switch(uiOutroStep) + { + case 1: + DoScriptText(SAY_ESCAPE_SPEECH_1, me); + me->GetMotionMaster()->MoveTargetedHome(); + ++uiOutroStep; + uiOutroTimer = 8000; + break; + case 2: + me->SetUInt64Value(UNIT_FIELD_TARGET, pInstance ? pInstance->GetData64(DATA_ARTHAS) : 0); + me->HandleEmoteCommand(29); + DoScriptText(SAY_ESCAPE_SPEECH_2, me); + ++uiOutroStep; + uiOutroTimer = 9000; + break; + case 3: + DoScriptText(SAY_OUTRO, me); + ++uiOutroStep; + uiOutroTimer = 16000; + break; + case 4: + me->HandleEmoteCommand(33); + ++uiOutroStep; + uiOutroTimer = 500; + break; + case 5: + me->SetVisibility(VISIBILITY_OFF); + me->Kill(me); + break; + + } + } else uiOutroTimer -= diff; + break; + } + } + + void JustDied(Unit* /*killer*/) + { + if (pInstance) + { + pInstance->SetData(DATA_MAL_GANIS_EVENT, DONE); + + // give achievement credit to players. criteria use spell 58630 which doesn't exist. + if (pInstance) + pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58630); + } + } + + void KilledUnit(Unit * victim) + { + if (victim == me) + return; + + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), me); + } +}; + +CreatureAI* GetAI_boss_mal_ganis(Creature* pCreature) +{ + return new boss_mal_ganisAI (pCreature); +} + +void AddSC_boss_mal_ganis() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_mal_ganis"; + newscript->GetAI = &GetAI_boss_mal_ganis; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp new file mode 100644 index 00000000000..eba9733c745 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_meathook.cpp @@ -0,0 +1,140 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + +/* Script Data Start +SDName: Boss meathook +SDAuthor: Tartalo +SD%Complete: 100 +SDComment: It may need timer adjustment +SDCategory: +Script Data End */ + +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CONSTRICTING_CHAINS = 52696, //Encases the targets in chains, dealing 1800 Physical damage every 1 sec. and stunning the target for 5 sec. + H_SPELL_CONSTRICTING_CHAINS = 58823, + SPELL_DISEASE_EXPULSION = 52666, //Meathook belches out a cloud of disease, dealing 1710 to 1890 Nature damage and interrupting the spell casting of nearby enemy targets for 4 sec. + H_SPELL_DISEASE_EXPULSION = 58824, + SPELL_FRENZY = 58841 //Increases the caster's Physical damage by 10% for 30 sec. +}; + +enum Yells +{ + SAY_AGGRO = -1595026, + SAY_SLAY_1 = -1595027, + SAY_SLAY_2 = -1595028, + SAY_SLAY_3 = -1595029, + SAY_SPAWN = -1595030, + SAY_DEATH = -1595031 +}; + +struct boss_meathookAI : public ScriptedAI +{ + boss_meathookAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + if (pInstance) + DoScriptText(SAY_SPAWN,me); + } + + uint32 uiChainTimer; + uint32 uiDiseaseTimer; + uint32 uiFrenzyTimer; + + ScriptedInstance* pInstance; + + void Reset() + { + uiChainTimer = urand(12000,17000); //seen on video 13, 17, 15, 12, 16 + uiDiseaseTimer = urand(2000,4000); //approx 3s + uiFrenzyTimer = urand(21000,26000); //made it up + + if (pInstance) + pInstance->SetData(DATA_MEATHOOK_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + DoScriptText(SAY_AGGRO, me); + + if (pInstance) + pInstance->SetData(DATA_MEATHOOK_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + if (uiDiseaseTimer <= diff) + { + DoCastAOE(SPELL_DISEASE_EXPULSION); + uiDiseaseTimer = urand(1500,4000); + } else uiDiseaseTimer -= diff; + + if (uiFrenzyTimer <= diff) + { + DoCast(me, SPELL_FRENZY); + uiFrenzyTimer = urand(21000,26000); + } else uiFrenzyTimer -= diff; + + if (uiChainTimer <= diff) + { + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(pTarget, SPELL_CONSTRICTING_CHAINS); //anyone but the tank + uiChainTimer = urand(2000,4000); + } else uiChainTimer -= diff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance) + pInstance->SetData(DATA_MEATHOOK_EVENT, DONE); + } + + void KilledUnit(Unit * victim) + { + if (victim == me) + return; + + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me); + } +}; + +CreatureAI* GetAI_boss_meathook(Creature* pCreature) +{ + return new boss_meathookAI (pCreature); +} + +void AddSC_boss_meathook() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_meathook"; + newscript->GetAI = &GetAI_boss_meathook; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp new file mode 100644 index 00000000000..da1c8098517 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_salramm.cpp @@ -0,0 +1,170 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + +/* Script Data Start +SDName: Boss salramm +SDAuthor: Tartalo +SD%Complete: 80 +SDComment: TODO: Intro +SDCategory: +Script Data End */ + +/*** SQL START *** +update creature_template set scriptname = 'boss_salramm' where entry = ''; +*** SQL END ***/ +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" + +enum Spells +{ + SPELL_CURSE_OF_TWISTED_FLESH = 58845, + SPELL_EXPLODE_GHOUL = 52480, + H_SPELL_EXPLODE_GHOUL = 58825, + SPELL_SHADOW_BOLT = 57725, + H_SPELL_SHADOW_BOLT = 58828, + SPELL_STEAL_FLESH = 52708, + SPELL_SUMMON_GHOULS = 52451 +}; + +enum Yells +{ + SAY_AGGRO = -1595032, + SAY_SPAWN = -1595033, + SAY_SLAY_1 = -1595034, + SAY_SLAY_2 = -1595035, + SAY_SLAY_3 = -1595036, + SAY_DEATH = -1595037, + SAY_EXPLODE_GHOUL_1 = -1595038, + SAY_EXPLODE_GHOUL_2 = -1595039, + SAY_STEAL_FLESH_1 = -1595040, + SAY_STEAL_FLESH_2 = -1595041, + SAY_STEAL_FLESH_3 = -1595042, + SAY_SUMMON_GHOULS_1 = -1595043, + SAY_SUMMON_GHOULS_2 = -1595044 +}; + +struct boss_salrammAI : public ScriptedAI +{ + boss_salrammAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + if (pInstance) + DoScriptText(SAY_SPAWN,me); + } + + uint32 uiCurseFleshTimer; + uint32 uiExplodeGhoulTimer; + uint32 uiShadowBoltTimer; + uint32 uiStealFleshTimer; + uint32 uiSummonGhoulsTimer; + + ScriptedInstance* pInstance; + + void Reset() + { + uiCurseFleshTimer = 30000; //30s DBM + uiExplodeGhoulTimer = urand(25000,28000); //approx 6 sec after summon ghouls + uiShadowBoltTimer = urand(8000,12000); // approx 10s + uiStealFleshTimer = 12345; + uiSummonGhoulsTimer = urand(19000,24000); //on a video approx 24s after aggro + + if (pInstance) + pInstance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED); + } + + void EnterCombat(Unit* /*who*/) + { + DoScriptText(SAY_AGGRO, me); + + if (pInstance) + pInstance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Curse of twisted flesh timer + if (uiCurseFleshTimer <= diff) + { + DoCast(me->getVictim(), SPELL_CURSE_OF_TWISTED_FLESH); + uiCurseFleshTimer = 37000; + } else uiCurseFleshTimer -= diff; + + //Shadow bolt timer + if (uiShadowBoltTimer <= diff) + { + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_SHADOW_BOLT); + uiShadowBoltTimer = urand(8000,12000); + } else uiShadowBoltTimer -= diff; + + //Steal Flesh timer + if (uiStealFleshTimer <= diff) + { + DoScriptText(RAND(SAY_STEAL_FLESH_1,SAY_STEAL_FLESH_2,SAY_STEAL_FLESH_3), me); + if (Unit* random_pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(random_pTarget, SPELL_STEAL_FLESH); + uiStealFleshTimer = 10000; + } else uiStealFleshTimer -= diff; + + //Summon ghouls timer + if (uiSummonGhoulsTimer <= diff) + { + DoScriptText(RAND(SAY_SUMMON_GHOULS_1,SAY_SUMMON_GHOULS_2), me); + if (Unit* random_pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(random_pTarget, SPELL_SUMMON_GHOULS); + uiSummonGhoulsTimer = 10000; + } else uiSummonGhoulsTimer -= diff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance) + pInstance->SetData(DATA_SALRAMM_EVENT, DONE); + } + + void KilledUnit(Unit * victim) + { + if (victim == me) + return; + + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me); + } +}; + +CreatureAI* GetAI_boss_salramm(Creature* pCreature) +{ + return new boss_salrammAI (pCreature); +} + +void AddSC_boss_salramm() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_salramm"; + newscript->GetAI = &GetAI_boss_salramm; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp new file mode 100644 index 00000000000..faaed2eb6db --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp @@ -0,0 +1,1210 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" +#include "ScriptedEscortAI.h" + +enum Says +{ + //First Act - Uther and Jaina Dialog + SAY_PHASE101 = -1595070, //Arthas + SAY_PHASE102 = -1595071, //Uther + SAY_PHASE103 = -1595072, //Arthas + SAY_PHASE104 = -1595073, //Arthas + SAY_PHASE105 = -1595074, //Uther + SAY_PHASE106 = -1595075, //Arthas + SAY_PHASE107 = -1595076, //Uther + SAY_PHASE108 = -1595077, //Arthas + SAY_PHASE109 = -1595078, //Arthas + SAY_PHASE110 = -1595079, //Uther + SAY_PHASE111 = -1595080, //Arthas + SAY_PHASE112 = -1595081, //Uther + SAY_PHASE113 = -1595082, //Jaina + SAY_PHASE114 = -1595083, //Arthas + SAY_PHASE115 = -1595084, //Uther + SAY_PHASE116 = -1595085, //Arthas + SAY_PHASE117 = -1595086, //Jaina + SAY_PHASE118 = -1595087, //Arthas + //Second Act - City Streets + SAY_PHASE201 = -1595088, //Arthas + SAY_PHASE202 = -1595089, //Cityman + SAY_PHASE203 = -1595090, //Arthas + SAY_PHASE204 = -1595091, //Crazyman + SAY_PHASE205 = -1595092, //Arthas + SAY_PHASE206 = -1595009, //Malganis + SAY_PHASE207 = -1595010, //Malganis + SAY_PHASE208 = -1595093, //Arthas + SAY_PHASE209 = -1595094, //Arthas + SAY_PHASE210 = -1595095, //Arthas + //Third Act - Town Hall + SAY_PHASE301 = -1595096, //Arthas + SAY_PHASE302 = -1595097, //Drakonian + SAY_PHASE303 = -1595098, //Arthas + SAY_PHASE304 = -1595099, //Arthas + SAY_PHASE305 = -1595100, //Drakonian + SAY_PHASE306 = -1595101, //Arthas + SAY_PHASE307 = -1595102, //Arthas + SAY_PHASE308 = -1595103, //Arthas + SAY_PHASE309 = -1595104, //Arthas + SAY_PHASE310 = -1595105, //Arthas + SAY_PHASE311 = -1595106, //Arthas + SAY_PHASE312 = -1595107, //Arthas + SAY_PHASE313 = -1595108, //Arthas + SAY_PHASE314 = -1595000, //Epoch + SAY_PHASE315 = -1595109, //Arthas + //Fourth Act - Fire Corridor + SAY_PHASE401 = -1595110, //Arthas + SAY_PHASE402 = -1595111, //Arthas + SAY_PHASE403 = -1595112, //Arthas + SAY_PHASE404 = -1595113, //Arthas + SAY_PHASE405 = -1595114, //Arthas + SAY_PHASE406 = -1595115, //Arthas + SAY_PHASE407 = -1595116, //Arthas + //Fifth Act - Mal'Ganis Fight + SAY_PHASE501 = -1595117, //Arthas + SAY_PHASE502 = -1595118, //Arthas + SAY_PHASE503 = -1595119, //Arthas + SAY_PHASE504 = -1595120, //Arthas +}; + +enum NPCs +{ + NPC_INFINITE_ADVERSARY = 27742, + NPC_INFINITE_HUNTER = 27743, + NPC_INFINITE_AGENT = 27744, + NPC_TIME_RIFT = 28409, + NPC_ZOMBIE = 27737, + NPC_GHOUL = 28249, + NPC_NECROMANCER = 28200, + NPC_STALKER = 28199, + NPC_FIEND = 27734, + NPC_GOLEM = 28201, + NPC_EGHOUL = 27729, + NPC_CONSTRUCT = 27736, + + NPC_INVIS_TARGET = 20562, + + NPC_KNIGHT_ESCORT = 27745, + NPC_PRIEST_ESCORT = 27747, + NPC_CITY_MAN = 28167, + NPC_CITY_MAN2 = 28169, + NPC_CITY_MAN3 = 31126, + NPC_CITY_MAN4 = 31127, +}; + +enum Spells +{ + SPELL_FEAR = 39176, + SPELL_ARTHAS_AURA = 52442, + SPELL_EXORCISM_N = 52445, + SPELL_EXORCISM_H = 58822, + SPELL_HOLY_LIGHT = 52444, +}; + +enum GossipMenuArthas +{ + GOSSIP_MENU_ARTHAS_1 = 100001, + GOSSIP_MENU_ARTHAS_2 = 100002, + GOSSIP_MENU_ARTHAS_3 = 100003, + GOSSIP_MENU_ARTHAS_4 = 100004, + GOSSIP_MENU_ARTHAS_5 = 100005 +}; + +enum +{ + ENCOUNTER_WAVES_NUMBER = 8, + ENCOUNTER_WAVES_MAX_SPAWNS = 5, + ENCOUNTER_DRACONIAN_NUMBER = 4, + ENCOUNTER_CHRONO_SPAWNS = 19 +}; + +// Locations for necromancers and add to spawn +float WavesLocations[ENCOUNTER_WAVES_NUMBER][ENCOUNTER_WAVES_MAX_SPAWNS][5]= +{ + { + {NPC_ZOMBIE, 2164.698975, 1255.392944, 135.040878, 0.490202}, + {NPC_ZOMBIE, 2183.501465, 1263.079102, 134.859055, 3.169981}, + {NPC_GHOUL, 2177.512939, 1247.313843, 135.846695, 1.696574}, + {NPC_GHOUL, 2171.991943, 1246.615845, 135.745026, 1.696574}, + {0, 0, 0, 0, 0} + }, + { + {NPC_GHOUL, 2254.434326, 1163.427612, 138.055038, 2.077358}, + {NPC_GHOUL, 2254.703613, 1158.867798, 138.212234, 2.345532}, + {NPC_GHOUL, 2257.615723, 1162.310913, 138.091202, 2.077358}, + {NPC_NECROMANCER, 2258.258057, 1157.250732, 138.272873, 2.387766}, + {0, 0, 0, 0, 0} + }, + { + {NPC_STALKER, 2348.120117, 1202.302490, 130.491104, 4.698538}, + {NPC_GHOUL, 2352.863525, 1207.819092, 130.424271, 4.949865}, + {NPC_GHOUL, 2343.593750, 1207.915039, 130.781311, 4.321547}, + {NPC_NECROMANCER, 2348.257324, 1212.202515, 130.670135, 4.450352}, + {0, 0, 0, 0, 0} + }, + { + {NPC_STALKER, 2139.825195, 1356.277100, 132.199615, 5.820131}, + {NPC_GHOUL, 2137.073486, 1362.464844, 132.271637, 5.820131}, + {NPC_GHOUL, 2134.075684, 1354.148071, 131.885864, 5.820131}, + {NPC_NECROMANCER, 2133.302246, 1358.907837, 132.037689, 5.820131}, + {0, 0, 0, 0, 0} + }, + { + {NPC_NECROMANCER, 2264.013428, 1174.055908, 138.093094, 2.860481}, + {NPC_GHOUL, 2264.207764, 1170.892700, 138.034973, 2.860481}, + {NPC_GHOUL, 2266.948975, 1176.898926, 137.976929, 2.860481}, + {NPC_STALKER, 2269.215576, 1170.109253, 137.742691, 2.860481}, + {NPC_FIEND, 2273.106689, 1176.101074, 137.880508, 2.860481} + }, + { + {NPC_GOLEM, 2349.701660, 1188.436646, 130.428864, 3.908642}, + {NPC_GHOUL, 2349.909180, 1194.582642, 130.417816, 3.577001}, + {NPC_EGHOUL, 2354.662598, 1185.692017, 130.552032, 3.577001}, + {NPC_EGHOUL, 2354.716797, 1191.614380, 130.539810, 3.577001}, + {0, 0, 0, 0, 0} + }, + { + {NPC_CONSTRUCT, 2145.212891, 1355.288086, 132.288773, 6.004838}, + {NPC_NECROMANCER, 2137.078613, 1357.612671, 132.173340, 6.004838}, + {NPC_EGHOUL, 2139.402100, 1352.541626, 132.127518, 5.812850}, + {NPC_EGHOUL, 2142.408447, 1360.760620, 132.321564, 5.812850}, + {0, 0, 0, 0, 0} + }, + { + {NPC_GHOUL, 2172.686279, 1259.618164, 134.391754, 1.865499}, + {NPC_FIEND, 2177.649170, 1256.061157, 135.096512, 1.849572}, + {NPC_CONSTRUCT, 2170.782959, 1253.594849, 134.973022, 1.849572}, + {NPC_NECROMANCER, 2175.595703, 1249.041992, 135.603531, 1.849572}, + {0, 0, 0, 0, 0} + } +}; + +// Locations for rifts to spawn and draconians to go +float RiftAndSpawnsLocations[ENCOUNTER_CHRONO_SPAWNS][5]= +{ + {NPC_TIME_RIFT, 2431.790039, 1190.670044, 148.076004, 0.187923}, + {NPC_INFINITE_ADVERSARY, 2433.857910, 1185.612061, 148.075974, 4.566168}, + {NPC_INFINITE_ADVERSARY, 2437.577881, 1188.241089, 148.075974, 0.196999}, + {NPC_INFINITE_AGENT, 2437.165527, 1192.294922, 148.075974, 0.169247}, + {NPC_INFINITE_HUNTER, 2434.989990, 1197.679565, 148.075974, 0.715971}, + {NPC_TIME_RIFT, 2403.954834, 1178.815430, 148.075943, 4.966126}, + {NPC_INFINITE_AGENT, 2403.676758, 1171.495850, 148.075607, 4.902797}, + {NPC_INFINITE_HUNTER, 2407.691162, 1172.162720, 148.075607, 4.963010}, + {NPC_TIME_RIFT, 2414.217041, 1133.446167, 148.076050, 1.706972}, + {NPC_INFINITE_ADVERSARY, 2416.024658, 1139.456177, 148.076431, 1.752129}, + {NPC_INFINITE_HUNTER, 2410.866699, 1139.680542, 148.076431, 1.752129}, + {NPC_TIME_RIFT, 2433.081543, 1099.869751, 148.076157, 1.809509}, + {NPC_INFINITE_ADVERSARY, 2426.947998, 1107.471680, 148.076019, 1.877580}, + {NPC_INFINITE_HUNTER, 2432.944580, 1108.896362, 148.208160, 2.199241}, + {NPC_TIME_RIFT, 2444.077637, 1114.366089, 148.076157, 3.049565}, + {NPC_INFINITE_ADVERSARY, 2438.190674, 1118.368164, 148.076172, 3.139232}, + {NPC_INFINITE_AGENT, 2435.861328, 1113.402954, 148.169327, 2.390271}, + {NPC_TIME_RIFT, 2463.131592, 1115.391724, 152.473129, 3.409651}, + {NPC_EPOCH, 2451.809326, 1112.901245, 149.220459, 3.363617} +}; + +struct npc_arthasAI : public npc_escortAI +{ + npc_arthasAI(Creature *pCreature) : npc_escortAI(pCreature) + { + pInstance = pCreature->GetInstanceData(); + Reset(); + } + + ScriptedInstance* pInstance; + + bool bStepping; + uint32 uiStep; + uint32 uiPhaseTimer; + uint32 uiGossipStep; + uint32 uiPlayerFaction; + uint32 uiBossEvent; + uint32 uiWave; + + uint64 uiUtherGUID; + uint64 uiJainaGUID; + uint64 uiCitymenGUID[2]; + uint64 uiWaveGUID[ENCOUNTER_WAVES_MAX_SPAWNS]; + uint64 uiInfiniteDraconianGUID[ENCOUNTER_DRACONIAN_NUMBER]; + uint64 uiStalkerGUID; + + uint64 uiBossGUID; //uiMeathookGUID || uiSalrammGUID + uint64 uiEpochGUID; + uint64 uiMalganisGUID; + uint64 uiInfiniteGUID; + + uint32 uiExorcismTimer; + + void Reset() + { + uiUtherGUID = 0; + uiJainaGUID = 0; + + for (uint8 i = 0; i < 2; ++i) + uiCitymenGUID[i] = 0; + + for (uint8 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i) + uiWaveGUID[i] = 0; + + for (uint8 i = 0; i < ENCOUNTER_DRACONIAN_NUMBER; ++i) + uiInfiniteDraconianGUID[i] = 0; + + uiStalkerGUID = 0; + uiBossGUID = 0; + uiEpochGUID = 0; + uiMalganisGUID = 0; + uiInfiniteGUID = 0; + + if (pInstance) { + pInstance->SetData(DATA_ARTHAS_EVENT, NOT_STARTED); + switch(pInstance->GetData(DATA_ARTHAS_EVENT)) + { + case NOT_STARTED: + bStepping = true; + uiStep = 0; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + uiBossEvent = DATA_MEATHOOK_EVENT; + uiGossipStep = 0; + break; + } + uiPhaseTimer = 1000; + uiExorcismTimer = 7300; + uiWave = 0; + } + } + + void EnterCombat(Unit* /*who*/) + { + DoCast(me, SPELL_ARTHAS_AURA); + } + + void JustDied(Unit * /*killer*/) + { + if (pInstance) + pInstance->SetData(DATA_ARTHAS_EVENT, FAIL); + } + + void SpawnTimeRift(uint32 timeRiftID, uint64* guidVector) + { + me->SummonCreature((uint32)RiftAndSpawnsLocations[timeRiftID][0],RiftAndSpawnsLocations[timeRiftID][1],RiftAndSpawnsLocations[timeRiftID][2],RiftAndSpawnsLocations[timeRiftID][3],RiftAndSpawnsLocations[timeRiftID][4],TEMPSUMMON_TIMED_DESPAWN,11000); + + for (uint32 i = timeRiftID+1; i < ENCOUNTER_CHRONO_SPAWNS; ++i) + { + if ((uint32)RiftAndSpawnsLocations[i][0] == NPC_TIME_RIFT) break; + if (Creature* pTemp = me->SummonCreature((uint32)RiftAndSpawnsLocations[i][0],RiftAndSpawnsLocations[timeRiftID][1],RiftAndSpawnsLocations[timeRiftID][2],RiftAndSpawnsLocations[timeRiftID][3],RiftAndSpawnsLocations[timeRiftID][4],TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) + { + guidVector[i-timeRiftID-1] = pTemp->GetGUID(); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); + pTemp->SetReactState(REACT_PASSIVE); + pTemp->GetMotionMaster()->MovePoint(0, RiftAndSpawnsLocations[i][1],RiftAndSpawnsLocations[i][2],RiftAndSpawnsLocations[i][3]); + if ((uint32)RiftAndSpawnsLocations[i][0] == NPC_EPOCH) + uiEpochGUID = pTemp->GetGUID(); + } + } + } + + void SpawnWaveGroup(uint32 waveID, uint64* guidVector) + { + for (uint32 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i) + { + if ((uint32)WavesLocations[waveID][i][0] == 0) break; + if (Creature* pTemp = me->SummonCreature((uint32)WavesLocations[waveID][i][0],WavesLocations[waveID][i][1],WavesLocations[waveID][i][2],WavesLocations[waveID][i][3],WavesLocations[waveID][i][4],TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) + { + guidVector[i] = pTemp->GetGUID(); + } + } + } + + void SetHoldState(bool bOnHold) + { + SetEscortPaused(bOnHold); + } + + void JumpToNextStep(uint32 uiTimer) + { + uiPhaseTimer = uiTimer; + ++uiStep; + } + + void WaypointReached(uint32 uiPointId) + { + switch(uiPointId) + { + case 0: + case 1: + case 3: + case 9: + case 10: + case 11: + case 22: + case 23: + case 26: + case 55: + case 56: + SetHoldState(true); + bStepping = true; + break; + case 7: + if (Unit* pCityman0 = me->SummonCreature(NPC_CITY_MAN,2091.977f,1275.021f,140.757f,0.558f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,60000)) + uiCitymenGUID[0] = pCityman0->GetGUID(); + if (Unit* pCityman1 = me->SummonCreature(NPC_CITY_MAN2,2093.514f,1275.842f,140.408f,3.801f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,60000)) + uiCitymenGUID[1] = pCityman1->GetGUID(); + break; + case 8: + uiGossipStep = 1; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetHoldState(true); + break; + case 12: + SetRun(true); + DoScriptText(SAY_PHASE210, me); + if (Unit* pDisguised0 = me->SummonCreature(NPC_CITY_MAN3,2398.14f,1207.81f,134.04f,5.155249f,TEMPSUMMON_DEAD_DESPAWN,180000)) + { + uiInfiniteDraconianGUID[0] = pDisguised0->GetGUID(); + if (Unit* pDisguised1 = me->SummonCreature(NPC_CITY_MAN4,2403.22f,1205.54f,134.04f,3.311264f,TEMPSUMMON_DEAD_DESPAWN,180000)) + { + uiInfiniteDraconianGUID[1] = pDisguised1->GetGUID(); + + if (Unit* pDisguised2 = me->SummonCreature(NPC_CITY_MAN,2400.82f,1201.69f,134.01f,1.534082f,TEMPSUMMON_DEAD_DESPAWN,180000)) + { + uiInfiniteDraconianGUID[2] = pDisguised2->GetGUID(); + pDisguised0->SetUInt64Value(UNIT_FIELD_TARGET, uiInfiniteDraconianGUID[1]); + pDisguised1->SetUInt64Value(UNIT_FIELD_TARGET, uiInfiniteDraconianGUID[0]); + pDisguised2->SetUInt64Value(UNIT_FIELD_TARGET, uiInfiniteDraconianGUID[1]); + } + } + } + break; + case 20: + uiGossipStep = 2; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetRun(false); + SetHoldState(true); + break; + case 21: + DoScriptText(SAY_PHASE301, me); + break; + case 25: + SetRun(false); + SpawnTimeRift(0,&uiInfiniteDraconianGUID[0]); + DoScriptText(SAY_PHASE307,me); + break; + case 29: + SetRun(false); + SpawnTimeRift(5,&uiInfiniteDraconianGUID[0]); + SpawnTimeRift(8,&uiInfiniteDraconianGUID[2]); + DoScriptText(SAY_PHASE309,me); + SetHoldState(true); + bStepping = true; + break; + case 31: + SetRun(false); + SpawnTimeRift(11,&uiInfiniteDraconianGUID[0]); + SpawnTimeRift(14,&uiInfiniteDraconianGUID[2]); + DoScriptText(SAY_PHASE311,me); + SetHoldState(true); + bStepping = true; + break; + case 32: + DoScriptText(SAY_PHASE401,me); + break; + case 34: + DoScriptText(SAY_PHASE402,me); + break; + case 35: + DoScriptText(SAY_PHASE403,me); + break; + case 36: + if (pInstance) + { + GameObject* pGate = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_SHKAF_GATE)); + pGate->SetGoState(GO_STATE_ACTIVE); + } + break; + case 45: + SetRun(true); + SetDespawnAtFar(false); + uiGossipStep = 4; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetHoldState(true); + break; + case 47: + SetRun(false); + DoScriptText(SAY_PHASE405,me); + break; + case 48: + SetRun(true); + DoScriptText(SAY_PHASE406,me); + break; + case 53: + DoScriptText(SAY_PHASE407,me); + break; + case 54: + uiGossipStep = 5; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetHoldState(true); + break; + } + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + + DoMeleeAttackIfReady(); + + if (bStepping) + { + if (uiPhaseTimer <= diff) + { + switch(uiStep) + { + //After reset + case 0: + if (Unit* pJaina = GetClosestCreatureWithEntry(me, NPC_JAINA, 50.0f)) + uiJainaGUID = pJaina->GetGUID(); + else if (Unit* pJaina = me->SummonCreature(NPC_JAINA,1895.48f,1292.66f,143.706f,0.023475f,TEMPSUMMON_DEAD_DESPAWN,180000)) + uiJainaGUID = pJaina->GetGUID(); + bStepping = false; + JumpToNextStep(0); + break; + //After waypoint 0 + case 1: + me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + if (Unit* pUther = me->SummonCreature(NPC_UTHER,1794.357f,1272.183f,140.558f,1.37f,TEMPSUMMON_DEAD_DESPAWN,180000)) + { + uiUtherGUID = pUther->GetGUID(); + pUther->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + pUther->GetMotionMaster()->MovePoint(0, 1897.018f, 1287.487f, 143.481f); + pUther->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiUtherGUID); + } + JumpToNextStep(17000); + break; + case 2: + DoScriptText(SAY_PHASE101, me); + JumpToNextStep(2000); + break; + case 3: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + { + DoScriptText(SAY_PHASE102, pUther); + } + JumpToNextStep(8000); + break; + case 4: + SetEscortPaused(false); + bStepping = false; + SetRun(false); + DoScriptText(SAY_PHASE103, me); + JumpToNextStep(0); + break; + //After waypoint 1 + case 5: + if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) + pJaina->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + DoScriptText(SAY_PHASE104, me); + JumpToNextStep(10000); + break; + case 6: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + DoScriptText(SAY_PHASE105, pUther); + JumpToNextStep(1000); + break; + case 7: + DoScriptText(SAY_PHASE106, me); + JumpToNextStep(4000); + break; + case 8: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + DoScriptText(SAY_PHASE107, pUther); + JumpToNextStep(6000); + break; + case 9: + DoScriptText(SAY_PHASE108, me); + JumpToNextStep(4000); + break; + case 10: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + DoScriptText(SAY_PHASE109, pUther); + JumpToNextStep(8000); + break; + case 11: + DoScriptText(SAY_PHASE110, me); + JumpToNextStep(4000); + break; + case 12: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + DoScriptText(SAY_PHASE111, pUther); + JumpToNextStep(4000); + break; + case 13: + DoScriptText(SAY_PHASE112, me); + JumpToNextStep(11000); + break; + case 14: + if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) + DoScriptText(SAY_PHASE113, pJaina); + JumpToNextStep(3000); + break; + case 15: + DoScriptText(SAY_PHASE114, me); + JumpToNextStep(9000); + break; + case 16: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + DoScriptText(SAY_PHASE115, pUther); + JumpToNextStep(4000); + break; + case 17: + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + { + pUther->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + pUther->GetMotionMaster()->MovePoint(0, 1794.357f,1272.183f,140.558f); + } + JumpToNextStep(1000); + break; + case 18: + if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) + { + me->SetUInt64Value(UNIT_FIELD_TARGET, uiJainaGUID); + pJaina->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + pJaina->GetMotionMaster()->MovePoint(0, 1794.357f,1272.183f,140.558f); + } + JumpToNextStep(1000); + break; + case 19: + DoScriptText(SAY_PHASE116, me); + JumpToNextStep(1000); + break; + case 20: + if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) + DoScriptText(SAY_PHASE117, pJaina); + JumpToNextStep(3000); + break; + case 21: + SetEscortPaused(false); + bStepping = false; + me->SetUInt64Value(UNIT_FIELD_TARGET, 0); + JumpToNextStep(0); + break; + //After waypoint 3 + case 22: + DoScriptText(SAY_PHASE118, me); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiJainaGUID); + JumpToNextStep(10000); + break; + case 23: + SetEscortPaused(false); + bStepping = false; + SetRun(true); + + if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) + pJaina->DisappearAndDie(); + + if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) + pUther->DisappearAndDie(); + + me->SetUInt64Value(UNIT_FIELD_TARGET, 0); + JumpToNextStep(0); + break; + //After Gossip 1 (waypoint 8) + case 24: + if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET,2026.469f,1287.088f,143.596f,1.37f,TEMPSUMMON_TIMED_DESPAWN,14000)) + { + uiStalkerGUID = pStalker->GetGUID(); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); + } + JumpToNextStep(1000); + break; + case 25: + DoScriptText(SAY_PHASE201, me); + JumpToNextStep(12000); + break; + case 26: + SetEscortPaused(false); + bStepping = false; + SetRun(false); + me->SetUInt64Value(UNIT_FIELD_TARGET, 0); + JumpToNextStep(0); + break; + //After waypoint 9 + case 27: + me->SetUInt64Value(UNIT_FIELD_TARGET, uiCitymenGUID[0]); + if (Creature* pCityman = Unit::GetCreature(*me, uiCitymenGUID[0])) + { + pCityman->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + pCityman->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + pCityman->GetMotionMaster()->MovePoint(0, 2088.625f,1279.191f,140.743f); + } + JumpToNextStep(2000); + break; + case 28: + if (Creature* pCityman = Unit::GetCreature(*me, uiCitymenGUID[0])) + DoScriptText(SAY_PHASE202, pCityman); + JumpToNextStep(4000); + break; + case 29: + SetEscortPaused(false); + bStepping = false; + DoScriptText(SAY_PHASE203, me); + JumpToNextStep(0); + break; + //After waypoint 10 + case 30: + me->HandleEmoteCommand(37); + JumpToNextStep(1000); + break; + case 31: + SetEscortPaused(false); + bStepping = false; + if (Creature* pCityman1 = Unit::GetCreature(*me, uiCitymenGUID[1])) + { + DoScriptText(SAY_PHASE204, pCityman1); + pCityman1->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + if (Creature* pCityman0 = Unit::GetCreature(*me, uiCitymenGUID[0])) + pCityman0->Kill(pCityman0); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiCitymenGUID[1]); + } + JumpToNextStep(0); + break; + //After waypoint 11 + case 32: + me->HandleEmoteCommand(37); + JumpToNextStep(1000); + break; + case 33: + if (Creature* pCityman1 = Unit::GetCreature(*me, uiCitymenGUID[1])) + pCityman1->Kill(pCityman1); + JumpToNextStep(1000); + break; + case 34: + if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET,2081.447f,1287.770f,141.3241f,1.37f,TEMPSUMMON_TIMED_DESPAWN,10000)) + { + uiStalkerGUID = pStalker->GetGUID(); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); + } + DoScriptText(SAY_PHASE205, me); + JumpToNextStep(3000); + break; + case 35: + if (Unit* pStalkerM = me->SummonCreature(NPC_INVIS_TARGET,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,60000)) + { + uiStalkerGUID = pStalkerM->GetGUID(); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); + } + JumpToNextStep(1000); + break; + case 36: + if (Creature* pMalganis = me->SummonCreature(NPC_MAL_GANIS,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,60000)) + { + if (Creature* pStalkerM = Unit::GetCreature(*me, uiStalkerGUID)) + pMalganis->CastSpell(pStalkerM,63793,false); + + uiMalganisGUID = pMalganis->GetGUID(); + DoScriptText(SAY_PHASE206, pMalganis); + pMalganis->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + pMalganis->SetReactState(REACT_PASSIVE); + } + JumpToNextStep(11000); + break; + case 37: + if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) + { + if (Creature* pZombie = GetClosestCreatureWithEntry(pMalganis, NPC_CITY_MAN, 100.0f)) + pZombie->UpdateEntry(NPC_ZOMBIE, 0); + else if (Creature* pZombie = GetClosestCreatureWithEntry(pMalganis, NPC_CITY_MAN2, 100.0f)) + pZombie->UpdateEntry(NPC_ZOMBIE, 0); + else //There's no one else to transform + uiStep++; + } + else + uiStep++; + uiPhaseTimer = 500; + break; + case 38: + if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) + DoScriptText(SAY_PHASE207, pMalganis); + JumpToNextStep(17000); + break; + case 39: + if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) + pMalganis->SetVisibility(VISIBILITY_OFF); + DoScriptText(SAY_PHASE208, me); + JumpToNextStep(7000); + break; + case 40: + if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET,2081.447f,1287.770f,141.3241f,1.37f,TEMPSUMMON_TIMED_DESPAWN,10000)) + { + uiStalkerGUID = pStalker->GetGUID(); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); + } + DoScriptText(SAY_PHASE209, me); + + uiBossEvent = DATA_MEATHOOK_EVENT; + if (pInstance) + pInstance->SetData(DATA_ARTHAS_EVENT, IN_PROGRESS); + + me->SetReactState(REACT_DEFENSIVE); + SetDespawnAtFar(false); + JumpToNextStep(5000); + break; + case 41: //Summon wave group + case 43: + case 45: + case 47: + case 51: + case 53: + case 55: + case 57: + if (pInstance->GetData(uiBossEvent) != DONE) + { + SpawnWaveGroup(uiWave, uiWaveGUID); + uiWave++; + } + JumpToNextStep(500); + break; + case 42: //Wait group to die + case 44: + case 46: + case 48: + case 52: + case 54: + case 56: + case 58: + if (pInstance->GetData(uiBossEvent) != DONE) + { + uint32 mobCounter = 0; + uint32 deadCounter = 0; + for (uint8 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i) + { + if (uiWaveGUID[i] == 0) + break; + ++mobCounter; + Unit* pTemp = Unit::GetCreature(*me, uiWaveGUID[i]); + if (!pTemp || pTemp->isDead()) + ++deadCounter; + } + + if (mobCounter <= deadCounter) //If group is dead + JumpToNextStep(1000); + else + uiPhaseTimer = 1000; + } + else + JumpToNextStep(500); + break; + case 49: //Summon Boss + case 59: + if (pInstance->GetData(uiBossEvent) != DONE) + { + uint32 uiBossID = 0; + if (uiBossEvent == DATA_MEATHOOK_EVENT) + uiBossID = NPC_MEATHOOK; + else if (uiBossEvent == DATA_SALRAMM_EVENT) + uiBossID = NPC_SALRAMM; + + if (Unit* pBoss = me->SummonCreature(uiBossID,2232.19f,1331.933f,126.662f,3.15f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) + { + uiBossGUID = pBoss->GetGUID(); + pBoss->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + pBoss->GetMotionMaster()->MovePoint(0, 2194.110f,1332.00f,130.00f); + } + } + JumpToNextStep(30000); + break; + case 50: //Wait Boss death + case 60: + if (pInstance) + { + if (pInstance->GetData(uiBossEvent) == DONE) + { + JumpToNextStep(1000); + if (uiBossEvent == DATA_MEATHOOK_EVENT) + uiBossEvent = DATA_SALRAMM_EVENT; + else if (uiBossEvent == DATA_SALRAMM_EVENT) + { + SetHoldState(false); + bStepping = false; + uiBossEvent = DATA_EPOCH_EVENT; + } + } + else if (pInstance->GetData(uiBossEvent) == FAIL) + npc_escortAI::EnterEvadeMode(); + else + uiPhaseTimer = 10000; + } + break; + //After Gossip 2 (waypoint 22) + case 61: + me->SetReactState(REACT_AGGRESSIVE); + if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) + pDisguised0->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + if (Creature* pDisguised1 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[1])) + pDisguised1->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + if (Creature* pDisguised2 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[2])) + pDisguised2->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); + JumpToNextStep(1000); + break; + case 62: + if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) + DoScriptText(SAY_PHASE302, pDisguised0); + JumpToNextStep(7000); + break; + case 63: + DoScriptText(SAY_PHASE303, me); + SetHoldState(false); + bStepping = false; + JumpToNextStep(0); + break; + //After waypoint 23 + case 64: + me->HandleEmoteCommand(54); + JumpToNextStep(1000); + break; + case 65: + if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) + pDisguised0->HandleEmoteCommand(11); + JumpToNextStep(1000); + break; + case 66: + DoScriptText(SAY_PHASE304,me); + JumpToNextStep(2000); + break; + case 67: + if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) + DoScriptText(SAY_PHASE305,pDisguised0); + JumpToNextStep(1000); + break; + case 68: + if (Creature* pDisguised2 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[2])) + { + pDisguised2->UpdateEntry(NPC_INFINITE_HUNTER, 0); + //Make them unattackable + pDisguised2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); + pDisguised2->SetReactState(REACT_PASSIVE); + } + JumpToNextStep(2000); + break; + case 69: + if (Creature* pDisguised1 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[1])) + { + pDisguised1->UpdateEntry(NPC_INFINITE_AGENT, 0); + //Make them unattackable + pDisguised1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); + pDisguised1->SetReactState(REACT_PASSIVE); + } + JumpToNextStep(2000); + break; + case 70: + if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) + { + pDisguised0->UpdateEntry(NPC_INFINITE_ADVERSARY, 0); + //Make them unattackable + pDisguised0->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); + pDisguised0->SetReactState(REACT_PASSIVE); + } + JumpToNextStep(2000); + break; + case 71: + //After waypoint 26,29,31 + case 73: + case 75: + case 77: + //Make cratures attackable + for (uint32 i = 0; i< ENCOUNTER_DRACONIAN_NUMBER; ++i) + if (Creature* pTemp = Unit::GetCreature(*me, uiInfiniteDraconianGUID[i])) + { + pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); + pTemp->SetReactState(REACT_AGGRESSIVE); + } + JumpToNextStep(5000); + break; + case 72: + case 74: + case 76: + if (me->isInCombat()) + uiPhaseTimer = 1000; + else + { + if (uiStep == 72) DoScriptText(SAY_PHASE308,me); + if (uiStep == 74) DoScriptText(SAY_PHASE308,me); + if (uiStep == 76) DoScriptText(SAY_PHASE310,me); + SetHoldState(false); + bStepping = false; + SetRun(true); + JumpToNextStep(2000); + } + break; + case 78: + if (me->isInCombat()) + uiPhaseTimer = 1000; + else + { + DoScriptText(SAY_PHASE312,me); + JumpToNextStep(5000); + } + break; + case 79: + DoScriptText(SAY_PHASE313,me); + JumpToNextStep(1000); + break; + case 80: + if (pInstance) + if (pInstance->GetData(DATA_EPOCH_EVENT) != DONE) + { + SpawnTimeRift(17,&uiEpochGUID); + if (Creature* pEpoch = Unit::GetCreature(*me, uiEpochGUID)) + DoScriptText(SAY_PHASE314,pEpoch); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiEpochGUID); + } + JumpToNextStep(18000); + break; + case 81: + if (pInstance) + if (pInstance->GetData(DATA_EPOCH_EVENT) != DONE) + DoScriptText(SAY_PHASE315, me); + JumpToNextStep(6000); + break; + case 82: + if (pInstance) + if (pInstance->GetData(DATA_EPOCH_EVENT) != DONE) + { + if (Creature* pEpoch = Unit::GetCreature(*me, uiEpochGUID)) + { + //Make Epoch attackable + pEpoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); + pEpoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pEpoch->SetReactState(REACT_AGGRESSIVE); + } + + } + JumpToNextStep(1000); + break; + case 83: + if (pInstance) + { + if (pInstance->GetData(DATA_EPOCH_EVENT) == DONE) + { + uiGossipStep = 3; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + bStepping = false; + uiBossEvent = DATA_MAL_GANIS_EVENT; + JumpToNextStep(15000); + } + else if (pInstance->GetData(DATA_EPOCH_EVENT) == FAIL) + npc_escortAI::EnterEvadeMode(); + else + uiPhaseTimer = 10000; + } + break; + //After Gossip 4 + case 84: + DoScriptText(SAY_PHASE404,me); + SetHoldState(false); + bStepping = false; + break; + //After Gossip 5 + case 85: + DoScriptText(SAY_PHASE501, me); + if (Creature* pMalganis = me->SummonCreature(NPC_MAL_GANIS,2296.665f,1502.362f,128.362f,4.961f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) + { + uiMalganisGUID = pMalganis->GetGUID(); + pMalganis->SetReactState(REACT_PASSIVE); + } + if (pInstance) + { + GameObject* pGate = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_MAL_GANIS_GATE_1)); + pGate->SetGoState(GO_STATE_ACTIVE); + } + SetHoldState(false); + bStepping = false; + JumpToNextStep(0); + break; + //After waypoint 55 + case 86: + DoScriptText(SAY_PHASE502, me); + JumpToNextStep(6000); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiMalganisGUID); + break; + case 87: + if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) + { + pMalganis->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_6 | UNIT_FLAG_UNK_9 | UNIT_FLAG_UNK_15); + pMalganis->SetReactState(REACT_AGGRESSIVE); + } + JumpToNextStep(1000); + break; + case 88: + if (pInstance) + { + if (pInstance->GetData(DATA_MAL_GANIS_EVENT) == DONE) + { + SetHoldState(false); + JumpToNextStep(1000); + } + else if (pInstance->GetData(DATA_MAL_GANIS_EVENT) == FAIL) + npc_escortAI::EnterEvadeMode(); + else + uiPhaseTimer = 10000; + } + break; + //After waypoint 56 + case 89: + SetRun(true); + me->SetUInt64Value(UNIT_FIELD_TARGET, uiMalganisGUID); + DoScriptText(SAY_PHASE503, me); + JumpToNextStep(7000); + break; + case 90: + if (pInstance) + { + pInstance->SetData(DATA_ARTHAS_EVENT, DONE); //Rewards: Achiev & Chest ;D + me->SetUInt64Value(UNIT_FIELD_TARGET, pInstance->GetData64(DATA_MAL_GANIS_GATE_2)); //Look behind + } + DoScriptText(SAY_PHASE504, me); + bStepping = false; + break; + } + } else uiPhaseTimer -= diff; + } + + //Battling skills + if (!me->getVictim()) + return; + + if (uiExorcismTimer < diff) + { + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) + DoCast(target, SPELL_EXORCISM_N); + uiExorcismTimer = 7300; + } else uiExorcismTimer -= diff; + + if (HealthBelowPct(40)) + DoCast(me, SPELL_HOLY_LIGHT); + } +}; + +CreatureAI* GetAI_npc_arthas(Creature* pCreature) +{ + return new npc_arthasAI(pCreature); +} + +#define GOSSIP_ITEM_ARTHAS_0 "I'm ready to start Culling of Stratholme." +#define GOSSIP_ITEM_ARTHAS_1 "Yes, my Prince. We're ready." +#define GOSSIP_ITEM_ARTHAS_2 "We're only doing what is best for Loarderon your Highness." +#define GOSSIP_ITEM_ARTHAS_3 "I'm ready." +#define GOSSIP_ITEM_ARTHAS_4 "For Lordaeron!" +#define GOSSIP_ITEM_ARTHAS_5 "I'm ready to battle the dreadlord, sire." + +bool GossipHello_npc_arthas(Player* pPlayer, Creature* pCreature) +{ + npc_arthasAI* pAI = CAST_AI(npc_arthasAI,pCreature->AI()); + + if (pAI && pAI->bStepping == false) + { + switch (pAI->uiGossipStep) + { + case 0: //This one is a workaround since the very beggining of the script is wrong. + if (pPlayer->GetQuestStatus(13149) != QUEST_STATUS_COMPLETE) + return false; + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); + break; + case 1: + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_1, pCreature->GetGUID()); + break; + case 2: + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_2, pCreature->GetGUID()); + break; + case 3: + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_3, pCreature->GetGUID()); + break; + case 4: + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_4, pCreature->GetGUID()); + break; + case 5: + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_5, pCreature->GetGUID()); + break; + default: + return false; + } + } + return true; +} + + +bool GossipSelect_npc_arthas(Player *pPlayer, Creature *pCreature, uint32 /*sender*/, uint32 action) +{ + npc_arthasAI* pAI = CAST_AI(npc_arthasAI,pCreature->AI()); + + if (!pAI) + return false; + + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + pAI->Start(true,true,pPlayer->GetGUID(),0,false,false); + pAI->SetDespawnAtEnd(false); + pAI->bStepping = false; + pAI->uiStep = 1; + break; + case GOSSIP_ACTION_INFO_DEF+1: + pAI->bStepping = true; + pAI->uiStep = 24; + break; + case GOSSIP_ACTION_INFO_DEF+2: + pAI->SetHoldState(false); + pAI->bStepping = false; + pAI->uiStep = 61; + break; + case GOSSIP_ACTION_INFO_DEF+3: + pAI->SetHoldState(false); + break; + case GOSSIP_ACTION_INFO_DEF+4: + pAI->bStepping = true; + pAI->uiStep = 84; + break; + case GOSSIP_ACTION_INFO_DEF+5: + pAI->bStepping = true; + pAI->uiStep = 85; + break; + } + pPlayer->CLOSE_GOSSIP_MENU(); + pAI->SetDespawnAtFar(true); + pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + return true; +} + +void AddSC_culling_of_stratholme() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_arthas"; + newscript->GetAI = &GetAI_npc_arthas; + newscript->pGossipHello = &GossipHello_npc_arthas; + newscript->pGossipSelect = &GossipSelect_npc_arthas; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h new file mode 100644 index 00000000000..4278ad46500 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h @@ -0,0 +1,68 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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_CULLING_OF_STRATHOLME_H +#define DEF_CULLING_OF_STRATHOLME_H + +enum Data +{ + DATA_MEATHOOK_EVENT, + DATA_SALRAMM_EVENT, + DATA_EPOCH_EVENT, + DATA_MAL_GANIS_EVENT, + DATA_INFINITE_EVENT, + DATA_ARTHAS_EVENT +}; + +enum Data64 +{ + DATA_ARTHAS, + DATA_MEATHOOK, + DATA_SALRAMM, + DATA_EPOCH, + DATA_MAL_GANIS, + DATA_INFINITE, + DATA_SHKAF_GATE, + DATA_MAL_GANIS_GATE_1, + DATA_MAL_GANIS_GATE_2, + DATA_EXIT_GATE, + DATA_MAL_GANIS_CHEST +}; + +enum Creatures +{ + NPC_MEATHOOK = 26529, + NPC_SALRAMM = 26530, + NPC_EPOCH = 26532, + NPC_MAL_GANIS = 26533, + NPC_INFINITE = 32273, + NPC_ARTHAS = 26499, + NPC_JAINA = 26497, + NPC_UTHER = 26528 +}; + +enum GameObjects +{ + GO_SHKAF_GATE = 188686, + GO_MALGANIS_GATE_1 = 187711, + GO_MALGANIS_GATE_2 = 187723, + GO_EXIT_GATE = 191788, + GO_MALGANIS_CHEST_N = 190663, + GO_MALGANIS_CHEST_H = 193597 +}; +#endif diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp new file mode 100644 index 00000000000..73742a1e748 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp @@ -0,0 +1,244 @@ +/* +* Copyright (C) 2008-2010 Trinity +* +* 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 +*/ + +#include "ScriptedPch.h" +#include "culling_of_stratholme.h" + +#define MAX_ENCOUNTER 5 + +/* Culling of Stratholme encounters: +0 - Meathook +1 - Salramm the Fleshcrafter +2 - Chrono-Lord Epoch +3 - Mal'Ganis +4 - Infinite Corruptor (Heroic only) +*/ + +struct instance_culling_of_stratholme : public ScriptedInstance +{ + instance_culling_of_stratholme(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint64 uiArthas; + uint64 uiMeathook; + uint64 uiSalramm; + uint64 uiEpoch; + uint64 uiMalGanis; + uint64 uiInfinite; + + uint64 uiShkafGate; + uint64 uiMalGanisGate1; + uint64 uiMalGanisGate2; + uint64 uiExitGate; + uint64 uiMalGanisChest; + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string str_data; + + 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 NPC_ARTHAS: + uiArthas = pCreature->GetGUID(); + break; + case NPC_MEATHOOK: + uiMeathook = pCreature->GetGUID(); + break; + case NPC_SALRAMM: + uiSalramm = pCreature->GetGUID(); + break; + case NPC_EPOCH: + uiEpoch = pCreature->GetGUID(); + break; + case NPC_MAL_GANIS: + uiMalGanis = pCreature->GetGUID(); + break; + case NPC_INFINITE: + uiInfinite = pCreature->GetGUID(); + break; + } + } + + void OnGameObjectCreate(GameObject* pGo, bool /*add*/) + { + switch(pGo->GetEntry()) + { + case GO_SHKAF_GATE: + uiShkafGate = pGo->GetGUID(); + break; + case GO_MALGANIS_GATE_1: + uiMalGanisGate1 = pGo->GetGUID(); + break; + case GO_MALGANIS_GATE_2: + uiMalGanisGate2 = pGo->GetGUID(); + break; + case GO_EXIT_GATE: + uiExitGate = pGo->GetGUID(); + if (m_auiEncounter[3] == DONE) + HandleGameObject(uiExitGate,true); + break; + case GO_MALGANIS_CHEST_N: + case GO_MALGANIS_CHEST_H: + uiMalGanisChest = pGo->GetGUID(); + if (m_auiEncounter[3] == DONE) + pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND); + break; + } + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case DATA_MEATHOOK_EVENT: + m_auiEncounter[0] = data; + break; + case DATA_SALRAMM_EVENT: + m_auiEncounter[1] = data; + break; + case DATA_EPOCH_EVENT: + m_auiEncounter[2] = data; + break; + case DATA_MAL_GANIS_EVENT: + m_auiEncounter[3] = data; + + switch(m_auiEncounter[3]) + { + case NOT_STARTED: + HandleGameObject(uiMalGanisGate2,true); + break; + case IN_PROGRESS: + HandleGameObject(uiMalGanisGate2,false); + break; + case DONE: + HandleGameObject(uiExitGate, true); + if (GameObject *pGo = instance->GetGameObject(uiMalGanisChest)) + pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND); + break; + } + break; + case DATA_INFINITE_EVENT: + m_auiEncounter[4] = data; + break; + } + + if (data == DONE) + SaveToDB(); + } + + uint32 GetData(uint32 type) + { + switch(type) + { + case DATA_MEATHOOK_EVENT: return m_auiEncounter[0]; + case DATA_SALRAMM_EVENT: return m_auiEncounter[1]; + case DATA_EPOCH_EVENT: return m_auiEncounter[2]; + case DATA_MAL_GANIS_EVENT: return m_auiEncounter[3]; + case DATA_INFINITE_EVENT: return m_auiEncounter[4]; + } + return 0; + } + + uint64 GetData64(uint32 identifier) + { + switch(identifier) + { + case DATA_ARTHAS: return uiArthas; + case DATA_MEATHOOK: return uiMeathook; + case DATA_SALRAMM: return uiSalramm; + case DATA_EPOCH: return uiEpoch; + case DATA_MAL_GANIS: return uiMalGanis; + case DATA_INFINITE: return uiInfinite; + case DATA_SHKAF_GATE: return uiShkafGate; + case DATA_MAL_GANIS_GATE_1: return uiMalGanisGate1; + case DATA_MAL_GANIS_GATE_2: return uiMalGanisGate2; + case DATA_EXIT_GATE: return uiExitGate; + case DATA_MAL_GANIS_CHEST: return uiMalGanisChest; + } + return 0; + } + + std::string GetSaveData() + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "C S " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " + << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4]; + + 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, data4; + + std::istringstream loadStream(in); + loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4; + + if (dataHead1 == 'C' && dataHead2 == 'S') + { + m_auiEncounter[0] = data0; + m_auiEncounter[1] = data1; + m_auiEncounter[2] = data2; + m_auiEncounter[3] = data3; + m_auiEncounter[4] = data4; + + 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_culling_of_stratholme(Map* pMap) +{ + return new instance_culling_of_stratholme(pMap); +} + +void AddSC_instance_culling_of_stratholme() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_culling_of_stratholme"; + newscript->GetInstanceData = &GetInstanceData_instance_culling_of_stratholme; + newscript->RegisterSelf(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp new file mode 100644 index 00000000000..49cf7cd4433 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp @@ -0,0 +1,145 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Aeonus +SD%Complete: 80 +SDComment: Some spells not implemented +SDCategory: Caverns of Time, The Dark Portal +EndScriptData */ + +#include "ScriptedPch.h" +#include "dark_portal.h" + +enum eEnums +{ + SAY_ENTER = -1269012, + SAY_AGGRO = -1269013, + SAY_BANISH = -1269014, + SAY_SLAY1 = -1269015, + SAY_SLAY2 = -1269016, + SAY_DEATH = -1269017, + EMOTE_FRENZY = -1269018, + + SPELL_CLEAVE = 40504, + SPELL_TIME_STOP = 31422, + SPELL_ENRAGE = 37605, + SPELL_SAND_BREATH = 31473, + H_SPELL_SAND_BREATH = 39049 +}; + +struct boss_aeonusAI : public ScriptedAI +{ + boss_aeonusAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 SandBreath_Timer; + uint32 TimeStop_Timer; + uint32 Frenzy_Timer; + + void Reset() + { + SandBreath_Timer = 15000+rand()%15000; + TimeStop_Timer = 10000+rand()%5000; + Frenzy_Timer = 30000+rand()%15000; + } + + void EnterCombat(Unit * /*who*/) + { + DoScriptText(SAY_AGGRO, me); + } + + void MoveInLineOfSight(Unit *who) + { + //Despawn Time Keeper + if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == C_TIME_KEEPER) + { + if (me->IsWithinDistInMap(who,20.0f)) + { + DoScriptText(SAY_BANISH, me); + me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance) + { + pInstance->SetData(TYPE_RIFT,DONE); + pInstance->SetData(TYPE_MEDIVH,DONE);//FIXME: later should be removed + } + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Sand Breath + if (SandBreath_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_SAND_BREATH); + SandBreath_Timer = 15000+rand()%10000; + } else SandBreath_Timer -= diff; + + //Time Stop + if (TimeStop_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_TIME_STOP); + TimeStop_Timer = 20000+rand()%15000; + } else TimeStop_Timer -= diff; + + //Frenzy + if (Frenzy_Timer <= diff) + { + DoScriptText(EMOTE_FRENZY, me); + DoCast(me, SPELL_ENRAGE); + Frenzy_Timer = 20000+rand()%15000; + } else Frenzy_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_aeonus(Creature* pCreature) +{ + return new boss_aeonusAI (pCreature); +} + +void AddSC_boss_aeonus() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_aeonus"; + newscript->GetAI = &GetAI_boss_aeonus; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp new file mode 100644 index 00000000000..1f2b4a80612 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp @@ -0,0 +1,154 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Chrono_Lord_Deja +SD%Complete: 65 +SDComment: All abilities not implemented +SDCategory: Caverns of Time, The Dark Portal +EndScriptData */ + +#include "ScriptedPch.h" +#include "dark_portal.h" + +enum eEnums +{ + SAY_ENTER = -1269006, + SAY_AGGRO = -1269007, + SAY_BANISH = -1269008, + SAY_SLAY1 = -1269009, + SAY_SLAY2 = -1269010, + SAY_DEATH = -1269011, + + SPELL_ARCANE_BLAST = 31457, + H_SPELL_ARCANE_BLAST = 38538, + SPELL_ARCANE_DISCHARGE = 31472, + H_SPELL_ARCANE_DISCHARGE = 38539, + SPELL_TIME_LAPSE = 31467, + SPELL_ATTRACTION = 38540 //Not Implemented (Heroic mode) +}; + +struct boss_chrono_lord_dejaAI : public ScriptedAI +{ + boss_chrono_lord_dejaAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 ArcaneBlast_Timer; + uint32 TimeLapse_Timer; + uint32 Attraction_Timer; + uint32 ArcaneDischarge_Timer; + + void Reset() + { + ArcaneBlast_Timer = 18000+rand()%5000; + TimeLapse_Timer = 10000+rand()%5000; + ArcaneDischarge_Timer = 20000+rand()%10000; + Attraction_Timer = 25000+rand()%10000; + } + + void EnterCombat(Unit * /*who*/) + { + DoScriptText(SAY_AGGRO, me); + } + + void MoveInLineOfSight(Unit *who) + { + //Despawn Time Keeper + if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == C_TIME_KEEPER) + { + if (me->IsWithinDistInMap(who,20.0f)) + { + DoScriptText(SAY_BANISH, me); + me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance) + pInstance->SetData(TYPE_RIFT,SPECIAL); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Arcane Blast + if (ArcaneBlast_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_ARCANE_BLAST); + ArcaneBlast_Timer = 15000+rand()%10000; + } else ArcaneBlast_Timer -= diff; + + //Arcane Discharge + if (ArcaneDischarge_Timer <= diff) + { + Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + DoCast(pTarget, SPELL_ARCANE_DISCHARGE); + ArcaneDischarge_Timer = 20000+rand()%10000; + } else ArcaneDischarge_Timer -= diff; + + //Time Lapse + if (TimeLapse_Timer <= diff) + { + DoScriptText(SAY_BANISH, me); + DoCast(me, SPELL_TIME_LAPSE); + TimeLapse_Timer = 15000+rand()%10000; + } else TimeLapse_Timer -= diff; + + if (IsHeroic()) + { + if (Attraction_Timer <= diff) + { + DoCast(me, SPELL_ATTRACTION); + Attraction_Timer = 25000+rand()%10000; + } else Attraction_Timer -= diff; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_chrono_lord_deja(Creature* pCreature) +{ + return new boss_chrono_lord_dejaAI (pCreature); +} + +void AddSC_boss_chrono_lord_deja() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_chrono_lord_deja"; + newscript->GetAI = &GetAI_boss_chrono_lord_deja; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp new file mode 100644 index 00000000000..04b4b020ead --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp @@ -0,0 +1,152 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Temporus +SD%Complete: 75 +SDComment: More abilities need to be implemented +SDCategory: Caverns of Time, The Dark Portal +EndScriptData */ + +#include "ScriptedPch.h" +#include "dark_portal.h" + +enum eEnums +{ + SAY_ENTER = -1269000, + SAY_AGGRO = -1269001, + SAY_BANISH = -1269002, + SAY_SLAY1 = -1269003, + SAY_SLAY2 = -1269004, + SAY_DEATH = -1269005, + + SPELL_HASTE = 31458, + SPELL_MORTAL_WOUND = 31464, + SPELL_WING_BUFFET = 31475, + H_SPELL_WING_BUFFET = 38593, + SPELL_REFLECT = 38592 //Not Implemented (Heroic mod) +}; + +struct boss_temporusAI : public ScriptedAI +{ + boss_temporusAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 Haste_Timer; + uint32 SpellReflection_Timer; + uint32 MortalWound_Timer; + uint32 WingBuffet_Timer; + + void Reset() + { + Haste_Timer = 15000+rand()%8000; + SpellReflection_Timer = 30000; + MortalWound_Timer = 8000; + WingBuffet_Timer = 25000+rand()%10000; + } + + void EnterCombat(Unit * /*who*/) + { + DoScriptText(SAY_AGGRO, me); + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance) + pInstance->SetData(TYPE_RIFT,SPECIAL); + } + + void MoveInLineOfSight(Unit *who) + { + //Despawn Time Keeper + if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == C_TIME_KEEPER) + { + if (me->IsWithinDistInMap(who,20.0f)) + { + DoScriptText(SAY_BANISH, me); + + me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Attack Haste + if (Haste_Timer <= diff) + { + DoCast(me, SPELL_HASTE); + Haste_Timer = 20000+rand()%5000; + } else Haste_Timer -= diff; + + //MortalWound_Timer + if (MortalWound_Timer <= diff) + { + DoCast(me, SPELL_MORTAL_WOUND); + MortalWound_Timer = 10000+rand()%10000; + } else MortalWound_Timer -= diff; + + //Wing ruffet + if (WingBuffet_Timer <= diff) + { + DoCast(me, SPELL_WING_BUFFET); + WingBuffet_Timer = 20000+rand()%10000; + } else WingBuffet_Timer -= diff; + + if (IsHeroic()) + { + if (SpellReflection_Timer <= diff) + { + DoCast(me, SPELL_REFLECT); + SpellReflection_Timer = 25000+rand()%10000; + } else SpellReflection_Timer -= diff; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_temporus(Creature* pCreature) +{ + return new boss_temporusAI (pCreature); +} + +void AddSC_boss_temporus() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_temporus"; + newscript->GetAI = &GetAI_boss_temporus; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp new file mode 100644 index 00000000000..b0432a9b57c --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp @@ -0,0 +1,404 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 +* 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: Dark_Portal +SD%Complete: 30 +SDComment: Misc NPC's and mobs for instance. Most here far from complete. +SDCategory: Caverns of Time, The Dark Portal +EndScriptData */ + +/* ContentData +npc_medivh_bm +npc_time_rift +npc_saat +EndContentData */ + +#include "ScriptedPch.h" +#include "dark_portal.h" + +#define SAY_ENTER -1269020 //where does this belong? +#define SAY_INTRO -1269021 +#define SAY_WEAK75 -1269022 +#define SAY_WEAK50 -1269023 +#define SAY_WEAK25 -1269024 +#define SAY_DEATH -1269025 +#define SAY_WIN -1269026 +#define SAY_ORCS_ENTER -1269027 +#define SAY_ORCS_ANSWER -1269028 + +#define SPELL_CHANNEL 31556 +#define SPELL_PORTAL_RUNE 32570 //aura(portal on ground effect) + +#define SPELL_BLACK_CRYSTAL 32563 //aura +#define SPELL_PORTAL_CRYSTAL 32564 //summon + +#define SPELL_BANISH_PURPLE 32566 //aura +#define SPELL_BANISH_GREEN 32567 //aura + +#define SPELL_CORRUPT 31326 +#define SPELL_CORRUPT_AEONUS 37853 + +#define C_COUNCIL_ENFORCER 17023 + +struct npc_medivh_bmAI : public ScriptedAI +{ + npc_medivh_bmAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 SpellCorrupt_Timer; + uint32 Check_Timer; + + bool Life75; + bool Life50; + bool Life25; + + void Reset() + { + SpellCorrupt_Timer = 0; + + if (!pInstance) + return; + + if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS) + DoCast(me, SPELL_CHANNEL, true); + else if (me->HasAura(SPELL_CHANNEL)) + me->RemoveAura(SPELL_CHANNEL); + + DoCast(me, SPELL_PORTAL_RUNE, true); + } + + void MoveInLineOfSight(Unit *who) + { + if (!pInstance) + return; + + if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 10.0f)) + { + if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS || pInstance->GetData(TYPE_MEDIVH) == DONE) + return; + + DoScriptText(SAY_INTRO, me); + pInstance->SetData(TYPE_MEDIVH,IN_PROGRESS); + DoCast(me, SPELL_CHANNEL, false); + Check_Timer = 5000; + } + else if (who->GetTypeId() == TYPEID_UNIT && me->IsWithinDistInMap(who, 15.0f)) + { + if (pInstance->GetData(TYPE_MEDIVH) != IN_PROGRESS) + return; + + uint32 entry = who->GetEntry(); + if (entry == C_ASSAS || entry == C_WHELP || entry == C_CHRON || entry == C_EXECU || entry == C_VANQU) + { + who->StopMoving(); + who->CastSpell(me,SPELL_CORRUPT,false); + } + else if (entry == C_AEONUS) + { + who->StopMoving(); + who->CastSpell(me,SPELL_CORRUPT_AEONUS,false); + } + } + } + + void AttackStart(Unit * /*who*/) + { + //if (pInstance && pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS) + //return; + + //ScriptedAI::AttackStart(who); + } + + void EnterCombat(Unit * /*who*/) {} + + void SpellHit(Unit* /*caster*/, const SpellEntry* spell) + { + if (SpellCorrupt_Timer) + return; + + if (spell->Id == SPELL_CORRUPT_AEONUS) + SpellCorrupt_Timer = 1000; + + if (spell->Id == SPELL_CORRUPT) + SpellCorrupt_Timer = 3000; + } + + void JustDied(Unit* Killer) + { + if (Killer->GetEntry() == me->GetEntry()) + return; + + DoScriptText(SAY_DEATH, me); + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance) + return; + + if (SpellCorrupt_Timer) + { + if (SpellCorrupt_Timer <= diff) + { + pInstance->SetData(TYPE_MEDIVH,SPECIAL); + + if (me->HasAura(SPELL_CORRUPT_AEONUS)) + SpellCorrupt_Timer = 1000; + else if (me->HasAura(SPELL_CORRUPT)) + SpellCorrupt_Timer = 3000; + else + SpellCorrupt_Timer = 0; + } else SpellCorrupt_Timer -= diff; + } + + if (Check_Timer) + { + if (Check_Timer <= diff) + { + uint32 pct = pInstance->GetData(DATA_SHIELD); + + Check_Timer = 5000; + + if (Life25 && pct <= 25) + { + DoScriptText(SAY_WEAK25, me); + Life25 = false; + } + else if (Life50 && pct <= 50) + { + DoScriptText(SAY_WEAK50, me); + Life50 = false; + } + else if (Life75 && pct <= 75) + { + DoScriptText(SAY_WEAK75, me); + Life75 = false; + } + + //if we reach this it means event was running but at some point reset. + if (pInstance->GetData(TYPE_MEDIVH) == NOT_STARTED) + { + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + me->RemoveCorpse(); + me->Respawn(); + return; + } + + if (pInstance->GetData(TYPE_RIFT) == DONE) + { + DoScriptText(SAY_WIN, me); + Check_Timer = 0; + + if (me->HasAura(SPELL_CHANNEL)) + me->RemoveAura(SPELL_CHANNEL); + + //TODO: start the post-event here + pInstance->SetData(TYPE_MEDIVH,DONE); + } + } else Check_Timer -= diff; + } + + //if (!UpdateVictim()) + //return; + + //DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_npc_medivh_bm(Creature* pCreature) +{ + return new npc_medivh_bmAI (pCreature); +} + +struct Wave +{ + uint32 PortalMob[4]; //spawns for portal waves (in order) +}; + +static Wave PortalWaves[]= +{ + {C_ASSAS, C_WHELP, C_CHRON, 0}, + {C_EXECU, C_CHRON, C_WHELP, C_ASSAS}, + {C_EXECU, C_VANQU, C_CHRON, C_ASSAS} +}; + +struct npc_time_riftAI : public ScriptedAI +{ + npc_time_riftAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 TimeRiftWave_Timer; + uint8 mRiftWaveCount; + uint8 mPortalCount; + uint8 mWaveId; + + void Reset() + { + + TimeRiftWave_Timer = 15000; + mRiftWaveCount = 0; + + if (!pInstance) + return; + + mPortalCount = pInstance->GetData(DATA_PORTAL_COUNT); + + if (mPortalCount < 6) + mWaveId = 0; + else if (mPortalCount > 12) + mWaveId = 2; + else mWaveId = 1; + + } + void EnterCombat(Unit * /*who*/) {} + + void DoSummonAtRift(uint32 creature_entry) + { + if (!creature_entry) + return; + + if (pInstance && pInstance->GetData(TYPE_MEDIVH) != IN_PROGRESS) + { + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + return; + } + + Position pos; + me->GetRandomNearPosition(pos, 10.0f); + + //normalize Z-level if we can, if rift is not at ground level. + pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + + if (Unit *Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) + if (Unit *temp = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_MEDIVH) : 0)) + Summon->AddThreat(temp,0.0f); + } + + void DoSelectSummon() + { + uint32 entry = 0; + + if ((mRiftWaveCount > 2 && mWaveId < 1) || mRiftWaveCount > 3) + mRiftWaveCount = 0; + + entry = PortalWaves[mWaveId].PortalMob[mRiftWaveCount]; + debug_log("TSCR: npc_time_rift: summoning wave Creature (Wave %u, Entry %u).",mRiftWaveCount,entry); + + ++mRiftWaveCount; + + if (entry == C_WHELP) + { + for (uint8 i = 0; i < 3; ++i) + DoSummonAtRift(entry); + } else DoSummonAtRift(entry); + } + + void UpdateAI(const uint32 diff) + { + if (!pInstance) + return; + + if (TimeRiftWave_Timer <= diff) + { + DoSelectSummon(); + TimeRiftWave_Timer = 15000; + } else TimeRiftWave_Timer -= diff; + + if (me->IsNonMeleeSpellCasted(false)) + return; + + debug_log("TSCR: npc_time_rift: not casting anylonger, i need to die."); + me->setDeathState(JUST_DIED); + + if (pInstance->GetData(TYPE_RIFT) == IN_PROGRESS) + pInstance->SetData(TYPE_RIFT,SPECIAL); + } +}; + +CreatureAI* GetAI_npc_time_rift(Creature* pCreature) +{ + return new npc_time_riftAI (pCreature); +} + +#define SAY_SAAT_WELCOME -1269019 + +#define GOSSIP_ITEM_OBTAIN "[PH] Obtain Chrono-Beacon" +#define SPELL_CHRONO_BEACON 34975 +#define ITEM_CHRONO_BEACON 24289 + +bool GossipHello_npc_saat(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + + if (pPlayer->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE && !pPlayer->HasItemCount(ITEM_CHRONO_BEACON,1)) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_ITEM_OBTAIN,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(10000, pCreature->GetGUID()); + return true; + } + else if (pPlayer->GetQuestRewardStatus(QUEST_OPENING_PORTAL) && !pPlayer->HasItemCount(ITEM_CHRONO_BEACON,1)) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_ITEM_OBTAIN,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(10001, pCreature->GetGUID()); + return true; + } + + pPlayer->SEND_GOSSIP_MENU(10002, pCreature->GetGUID()); + return true; +} + +bool GossipSelect_npc_saat(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + pPlayer->CLOSE_GOSSIP_MENU(); + pCreature->CastSpell(pPlayer,SPELL_CHRONO_BEACON,false); + } + return true; +} + +void AddSC_dark_portal() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_medivh_bm"; + newscript->GetAI = &GetAI_npc_medivh_bm; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_time_rift"; + newscript->GetAI = &GetAI_npc_time_rift; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_saat"; + newscript->pGossipHello = &GossipHello_npc_saat; + newscript->pGossipSelect = &GossipSelect_npc_saat; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h new file mode 100644 index 00000000000..7bfd8c917d7 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 +* This program is free software licensed under GPL version 2 +* Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_DARKPORTAL_H +#define DEF_DARKPORTAL_H + +#define TYPE_MEDIVH 1 +#define TYPE_RIFT 2 + +#define DATA_MEDIVH 10 +#define DATA_PORTAL_COUNT 11 +#define DATA_SHIELD 12 + +#define WORLD_STATE_BM 2541 +#define WORLD_STATE_BM_SHIELD 2540 +#define WORLD_STATE_BM_RIFT 2784 + +#define QUEST_OPENING_PORTAL 10297 +#define QUEST_MASTER_TOUCH 9836 + +#define C_TIME_KEEPER 17918 +#define C_RKEEP 21104 +#define C_RLORD 17839 +#define C_DEJA 17879 +#define C_TEMPO 17880 +#define C_AEONUS 17881 +#define C_ASSAS 17835 +#define C_WHELP 21818 +#define C_CHRON 17892 +#define C_EXECU 18994 +#define C_VANQU 18995 + +#endif + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp new file mode 100644 index 00000000000..d1280230808 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp @@ -0,0 +1,346 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 +* 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_Dark_Portal +SD%Complete: 50 +SDComment: Quest support: 9836, 10297. Currently in progress. +SDCategory: Caverns of Time, The Dark Portal +EndScriptData */ + +#include "ScriptedPch.h" +#include "dark_portal.h" + +#define MAX_ENCOUNTER 2 + +#define C_MEDIVH 15608 +#define C_TIME_RIFT 17838 + +#define SPELL_RIFT_CHANNEL 31387 + +#define RIFT_BOSS 1 + +inline uint32 RandRiftBoss() { return ((rand()%2) ? C_RKEEP : C_RLORD); } + +float PortalLocation[4][4]= +{ + {-2041.06, 7042.08, 29.99, 1.30}, + {-1968.18, 7042.11, 21.93, 2.12}, + {-1885.82, 7107.36, 22.32, 3.07}, + {-1928.11, 7175.95, 22.11, 3.44} +}; + +struct Wave +{ + uint32 PortalBoss; //protector of current portal + uint32 NextPortalTime; //time to next portal, or 0 if portal boss need to be killed +}; + +static Wave RiftWaves[]= +{ + {RIFT_BOSS, 0}, + {C_DEJA, 0}, + {RIFT_BOSS, 120000}, + {C_TEMPO, 140000}, + {RIFT_BOSS, 120000}, + {C_AEONUS, 0} +}; + +struct instance_dark_portal : public ScriptedInstance +{ + instance_dark_portal(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + + uint32 mRiftPortalCount; + uint32 mShieldPercent; + uint8 mRiftWaveCount; + uint8 mRiftWaveId; + + uint32 NextPortal_Timer; + + uint64 MedivhGUID; + uint8 CurrentRiftId; + + void Initialize() + { + MedivhGUID = 0; + Clear(); + } + + void Clear() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + mRiftPortalCount = 0; + mShieldPercent = 100; + mRiftWaveCount = 0; + mRiftWaveId = 0; + + CurrentRiftId = 0; + + NextPortal_Timer = 0; + } + + void InitWorldState(bool Enable = true) + { + DoUpdateWorldState(WORLD_STATE_BM,Enable ? 1 : 0); + DoUpdateWorldState(WORLD_STATE_BM_SHIELD, 100); + DoUpdateWorldState(WORLD_STATE_BM_RIFT, 0); + } + + bool IsEncounterInProgress() + { + if (GetData(TYPE_MEDIVH) == IN_PROGRESS) + return true; + + return false; + } + + void OnPlayerEnter(Player* pPlayer) + { + if (GetData(TYPE_MEDIVH) == IN_PROGRESS) + return; + + pPlayer->SendUpdateWorldState(WORLD_STATE_BM,0); + } + + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + if (pCreature->GetEntry() == C_MEDIVH) + MedivhGUID = pCreature->GetGUID(); + } + + //what other conditions to check? + bool CanProgressEvent() + { + if (instance->GetPlayers().isEmpty()) + return false; + + return true; + } + + uint8 GetRiftWaveId() + { + switch(mRiftPortalCount) + { + case 6: + mRiftWaveId = 2; + return 1; + case 12: + mRiftWaveId = 4; + return 3; + case 18: + return 5; + default: + return mRiftWaveId; + } + } + + void SetData(uint32 type, uint32 data) + { + switch(type) + { + case TYPE_MEDIVH: + if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS) + { + --mShieldPercent; + + DoUpdateWorldState(WORLD_STATE_BM_SHIELD, mShieldPercent); + + if (!mShieldPercent) + { + if (Creature* pMedivh = instance->GetCreature(MedivhGUID)) + { + if (pMedivh->isAlive()) + { + pMedivh->DealDamage(pMedivh, pMedivh->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_auiEncounter[0] = FAIL; + m_auiEncounter[1] = NOT_STARTED; + } + } + } + } + else + { + if (data == IN_PROGRESS) + { + debug_log("TSCR: Instance Dark Portal: Starting event."); + InitWorldState(); + m_auiEncounter[1] = IN_PROGRESS; + NextPortal_Timer = 15000; + } + + if (data == DONE) + { + //this may be completed further out in the post-event + debug_log("TSCR: Instance Dark Portal: Event completed."); + Map::PlayerList const& players = instance->GetPlayers(); + + if (!players.isEmpty()) + { + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + { + if (pPlayer->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE) + pPlayer->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL); + + if (pPlayer->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE) + pPlayer->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH); + } + } + } + } + + m_auiEncounter[0] = data; + } + break; + case TYPE_RIFT: + if (data == SPECIAL) + { + if (mRiftPortalCount < 7) + NextPortal_Timer = 5000; + } + else + m_auiEncounter[1] = data; + break; + } + } + + uint32 GetData(uint32 type) + { + switch(type) + { + case TYPE_MEDIVH: + return m_auiEncounter[0]; + case TYPE_RIFT: + return m_auiEncounter[1]; + case DATA_PORTAL_COUNT: + return mRiftPortalCount; + case DATA_SHIELD: + return mShieldPercent; + } + return 0; + } + + uint64 GetData64(uint32 data) + { + if (data == DATA_MEDIVH) + return MedivhGUID; + + return 0; + } + + Creature* SummonedPortalBoss(Creature* me) + { + uint32 entry = RiftWaves[GetRiftWaveId()].PortalBoss; + + if (entry == RIFT_BOSS) + entry = RandRiftBoss(); + + debug_log("TSCR: Instance Dark Portal: Summoning rift boss entry %u.",entry); + + Position pos; + me->GetRandomNearPosition(pos, 10.0f); + + //normalize Z-level if we can, if rift is not at ground level. + pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + + if (Creature *summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) + return summon; + + debug_log("TSCR: Instance Dark Portal: What just happened there? No boss, no loot, no fun..."); + return NULL; + } + + void DoSpawnPortal() + { + if (Creature* pMedivh = instance->GetCreature(MedivhGUID)) + { + uint8 tmp = urand(0,2); + + if (tmp >= CurrentRiftId) + ++tmp; + + debug_log("TSCR: Instance Dark Portal: Creating Time Rift at locationId %i (old locationId was %u).",tmp,CurrentRiftId); + + CurrentRiftId = tmp; + + Creature *pTemp = pMedivh->SummonCreature(C_TIME_RIFT, + PortalLocation[tmp][0],PortalLocation[tmp][1],PortalLocation[tmp][2],PortalLocation[tmp][3], + TEMPSUMMON_CORPSE_DESPAWN,0); + if (pTemp) + { + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + if (Creature *pBoss = SummonedPortalBoss(pTemp)) + { + if (pBoss->GetEntry() == C_AEONUS) + pBoss->AddThreat(pMedivh,0.0f); + else + { + pBoss->AddThreat(pTemp,0.0f); + pTemp->CastSpell(pBoss,SPELL_RIFT_CHANNEL,false); + } + } + } + } + } + + void Update(uint32 diff) + { + if (m_auiEncounter[1] != IN_PROGRESS) + return; + + //add delay timer? + if (!CanProgressEvent()) + { + Clear(); + return; + } + + if (NextPortal_Timer) + { + if (NextPortal_Timer <= diff) + { + ++mRiftPortalCount; + + DoUpdateWorldState(WORLD_STATE_BM_RIFT, mRiftPortalCount); + + DoSpawnPortal(); + NextPortal_Timer = RiftWaves[GetRiftWaveId()].NextPortalTime; + } else NextPortal_Timer -= diff; + } + } +}; + +InstanceData* GetInstanceData_instance_dark_portal(Map* pMap) +{ + return new instance_dark_portal(pMap); +} + +void AddSC_instance_dark_portal() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "instance_dark_portal"; + newscript->GetInstanceData = &GetInstanceData_instance_dark_portal; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp new file mode 100644 index 00000000000..91c9e274b83 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp @@ -0,0 +1,152 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Captain_Skarloc +SD%Complete: 75 +SDComment: Missing adds, missing waypoints to move up to Thrall once spawned + speech before enter combat. +SDCategory: Caverns of Time, Old Hillsbrad Foothills +EndScriptData */ + +#include "ScriptedPch.h" +#include "old_hillsbrad.h" + +#define SAY_ENTER -1560000 +#define SAY_TAUNT1 -1560001 +#define SAY_TAUNT2 -1560002 +#define SAY_SLAY1 -1560003 +#define SAY_SLAY2 -1560004 +#define SAY_DEATH -1560005 + +#define SPELL_HOLY_LIGHT 29427 +#define SPELL_CLEANSE 29380 +#define SPELL_HAMMER_OF_JUSTICE 13005 +#define SPELL_HOLY_SHIELD 31904 +#define SPELL_DEVOTION_AURA 8258 +#define SPELL_CONSECRATION 38385 + +struct boss_captain_skarlocAI : public ScriptedAI +{ + boss_captain_skarlocAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 Holy_Light_Timer; + uint32 Cleanse_Timer; + uint32 HammerOfJustice_Timer; + uint32 HolyShield_Timer; + uint32 DevotionAura_Timer; + uint32 Consecration_Timer; + + void Reset() + { + Holy_Light_Timer = 20000 + rand()%10000; + Cleanse_Timer = 10000; + HammerOfJustice_Timer = 20000 + rand()%15000; + HolyShield_Timer = 240000; + DevotionAura_Timer = 3000; + Consecration_Timer = 8000; + } + + void EnterCombat(Unit * /*who*/) + { + //This is not correct. Should taunt Thrall before engage in combat + DoScriptText(SAY_TAUNT1, me); + DoScriptText(SAY_TAUNT2, me); + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance && pInstance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) + pInstance->SetData(TYPE_THRALL_PART1, DONE); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Holy_Light + if (Holy_Light_Timer <= diff) + { + DoCast(me, SPELL_HOLY_LIGHT); + Holy_Light_Timer = 30000; + } else Holy_Light_Timer -= diff; + + //Cleanse + if (Cleanse_Timer <= diff) + { + DoCast(me, SPELL_CLEANSE); + Cleanse_Timer = 10000; + } else Cleanse_Timer -= diff; + + //Hammer of Justice + if (HammerOfJustice_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_HAMMER_OF_JUSTICE); + HammerOfJustice_Timer = 60000; + } else HammerOfJustice_Timer -= diff; + + //Holy Shield + if (HolyShield_Timer <= diff) + { + DoCast(me, SPELL_HOLY_SHIELD); + HolyShield_Timer = 240000; + } else HolyShield_Timer -= diff; + + //Devotion_Aura + if (DevotionAura_Timer <= diff) + { + DoCast(me, SPELL_DEVOTION_AURA); + DevotionAura_Timer = 45000 + rand()%10000; + } else DevotionAura_Timer -= diff; + + //Consecration + if (Consecration_Timer <= diff) + { + //DoCast(me->getVictim(), SPELL_CONSECRATION); + Consecration_Timer = 5000 + rand()%5000; + } else Consecration_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_captain_skarloc(Creature* pCreature) +{ + return new boss_captain_skarlocAI (pCreature); +} + +void AddSC_boss_captain_skarloc() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_captain_skarloc"; + newscript->GetAI = &GetAI_boss_captain_skarloc; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp new file mode 100644 index 00000000000..2c2ad96ddb7 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp @@ -0,0 +1,138 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Epoch_Hunter +SD%Complete: 60 +SDComment: Missing spawns pre-event, missing speech to be coordinated with rest of escort event. +SDCategory: Caverns of Time, Old Hillsbrad Foothills +EndScriptData */ + +#include "ScriptedPch.h" +#include "old_hillsbrad.h" + +#define SAY_ENTER1 -1560013 +#define SAY_ENTER2 -1560014 +#define SAY_ENTER3 -1560015 +#define SAY_AGGRO1 -1560016 +#define SAY_AGGRO2 -1560017 +#define SAY_SLAY1 -1560018 +#define SAY_SLAY2 -1560019 +#define SAY_BREATH1 -1560020 +#define SAY_BREATH2 -1560021 +#define SAY_DEATH -1560022 + +#define SPELL_SAND_BREATH 31914 +#define SPELL_IMPENDING_DEATH 31916 +#define SPELL_MAGIC_DISRUPTION_AURA 33834 +#define SPELL_WING_BUFFET 31475 + +struct boss_epoch_hunterAI : public ScriptedAI +{ + boss_epoch_hunterAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + uint32 SandBreath_Timer; + uint32 ImpendingDeath_Timer; + uint32 WingBuffet_Timer; + uint32 Mda_Timer; + + void Reset() + { + SandBreath_Timer = 8000 + rand()%8000; + ImpendingDeath_Timer = 25000 + rand()%5000; + WingBuffet_Timer = 35000; + Mda_Timer = 40000; + } + + void EnterCombat(Unit * /*who*/) + { + DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2), me); + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + + if (pInstance && pInstance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) + pInstance->SetData(TYPE_THRALL_PART4, DONE); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + //Sand Breath + if (SandBreath_Timer <= diff) + { + if (me->IsNonMeleeSpellCasted(false)) + me->InterruptNonMeleeSpells(false); + + DoCast(me->getVictim(), SPELL_SAND_BREATH); + + DoScriptText(RAND(SAY_BREATH1,SAY_BREATH2), me); + + SandBreath_Timer = 10000 + rand()%10000; + } else SandBreath_Timer -= diff; + + if (ImpendingDeath_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_IMPENDING_DEATH); + ImpendingDeath_Timer = 25000+rand()%5000; + } else ImpendingDeath_Timer -= diff; + + if (WingBuffet_Timer <= diff) + { + if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) + DoCast(pTarget, SPELL_WING_BUFFET); + WingBuffet_Timer = 25000+rand()%10000; + } else WingBuffet_Timer -= diff; + + if (Mda_Timer <= diff) + { + DoCast(me, SPELL_MAGIC_DISRUPTION_AURA); + Mda_Timer = 15000; + } else Mda_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_epoch_hunter(Creature* pCreature) +{ + return new boss_epoch_hunterAI (pCreature); +} + +void AddSC_boss_epoch_hunter() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_epoch_hunter"; + newscript->GetAI = &GetAI_boss_epoch_hunter; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp new file mode 100644 index 00000000000..dae0f5390b1 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp @@ -0,0 +1,190 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Luetenant_Drake +SD%Complete: 70 +SDComment: Missing proper code for patrolling area after being spawned. Script for GO (barrels) quest 10283 +SDCategory: Caverns of Time, Old Hillsbrad Foothills +EndScriptData */ + +#include "ScriptedPch.h" +#include "old_hillsbrad.h" +#include "ScriptedEscortAI.h" + +/*###### +## go_barrel_old_hillsbrad +######*/ + +bool GOHello_go_barrel_old_hillsbrad(Player* /*pPlayer*/, GameObject* pGO) +{ + if (ScriptedInstance* pInstance = pGO->GetInstanceData()) + { + if (pInstance->GetData(TYPE_BARREL_DIVERSION) == DONE) + return false; + + pInstance->SetData(TYPE_BARREL_DIVERSION, IN_PROGRESS); + } + + return false; +} + +/*###### +## boss_lieutenant_drake +######*/ + +#define SAY_ENTER -1560006 +#define SAY_AGGRO -1560007 +#define SAY_SLAY1 -1560008 +#define SAY_SLAY2 -1560009 +#define SAY_MORTAL -1560010 +#define SAY_SHOUT -1560011 +#define SAY_DEATH -1560012 + +#define SPELL_WHIRLWIND 31909 +#define SPELL_HAMSTRING 9080 +#define SPELL_MORTAL_STRIKE 31911 +#define SPELL_FRIGHTENING_SHOUT 33789 + +struct Location +{ + uint32 wpId; + float x; + float y; + float z; +}; + +static Location DrakeWP[]= +{ + {0, 2125.84, 88.2535, 54.8830}, + {1, 2111.01, 93.8022, 52.6356}, + {2, 2106.70, 114.753, 53.1965}, + {3, 2107.76, 138.746, 52.5109}, + {4, 2114.83, 160.142, 52.4738}, + {5, 2125.24, 178.909, 52.7283}, + {6, 2151.02, 208.901, 53.1551}, + {7, 2177.00, 233.069, 52.4409}, + {8, 2190.71, 227.831, 53.2742}, + {9, 2178.14, 214.219, 53.0779}, + {10, 2154.99, 202.795, 52.6446}, + {11, 2132.00, 191.834, 52.5709}, + {12, 2117.59, 166.708, 52.7686}, + {13, 2093.61, 139.441, 52.7616}, + {14, 2086.29, 104.950, 52.9246}, + {15, 2094.23, 81.2788, 52.6946}, + {16, 2108.70, 85.3075, 53.3294}, + {17, 2125.50, 88.9481, 54.7953}, + {18, 2128.20, 70.9763, 64.4221} +}; + +struct boss_lieutenant_drakeAI : public ScriptedAI +{ + boss_lieutenant_drakeAI(Creature *c) : ScriptedAI(c) {} + + bool CanPatrol; + uint32 wpId; + + uint32 Whirlwind_Timer; + uint32 Fear_Timer; + uint32 MortalStrike_Timer; + uint32 ExplodingShout_Timer; + + void Reset() + { + CanPatrol = true; + wpId = 0; + + Whirlwind_Timer = 20000; + Fear_Timer = 30000; + MortalStrike_Timer = 45000; + ExplodingShout_Timer = 25000; + } + + void EnterCombat(Unit * /*who*/) + { + DoScriptText(SAY_AGGRO, me); + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); + } + + void JustDied(Unit * /*victim*/) + { + DoScriptText(SAY_DEATH, me); + } + + void UpdateAI(const uint32 diff) + { + //TODO: make this work + if (CanPatrol && wpId == 0) + { + me->GetMotionMaster()->MovePoint(DrakeWP[0].wpId, DrakeWP[0].x, DrakeWP[0].y, DrakeWP[0].z); + ++wpId; + } + + //Return since we have no target + if (!UpdateVictim()) + return; + + //Whirlwind + if (Whirlwind_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_WHIRLWIND); + Whirlwind_Timer = 20000+rand()%5000; + } else Whirlwind_Timer -= diff; + + //Fear + if (Fear_Timer <= diff) + { + DoScriptText(SAY_SHOUT, me); + DoCast(me->getVictim(), SPELL_FRIGHTENING_SHOUT); + Fear_Timer = 25000+rand()%10000; + } else Fear_Timer -= diff; + + //Mortal Strike + if (MortalStrike_Timer <= diff) + { + DoScriptText(SAY_MORTAL, me); + DoCast(me->getVictim(), SPELL_MORTAL_STRIKE); + MortalStrike_Timer = 20000+rand()%10000; + } else MortalStrike_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_lieutenant_drake(Creature* pCreature) +{ + return new boss_lieutenant_drakeAI (pCreature); +} + +void AddSC_boss_lieutenant_drake() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "go_barrel_old_hillsbrad"; + newscript->pGOHello = &GOHello_go_barrel_old_hillsbrad; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "boss_lieutenant_drake"; + newscript->GetAI = &GetAI_boss_lieutenant_drake; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp new file mode 100644 index 00000000000..fa0b7c14595 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp @@ -0,0 +1,238 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * 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_Old_Hillsbrad +SD%Complete: 75 +SDComment: If thrall escort fail, all parts will reset. In future, save sub-parts and continue from last known. +SDCategory: Caverns of Time, Old Hillsbrad Foothills +EndScriptData */ + +#include "ScriptedPch.h" +#include "old_hillsbrad.h" + +#define MAX_ENCOUNTER 6 + +#define THRALL_ENTRY 17876 +#define TARETHA_ENTRY 18887 +#define EPOCH_ENTRY 18096 + +#define DRAKE_ENTRY 17848 + +#define QUEST_ENTRY_DIVERSION 10283 +#define LODGE_QUEST_TRIGGER 20155 + +struct instance_old_hillsbrad : public ScriptedInstance +{ + instance_old_hillsbrad(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; + + uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint32 mBarrelCount; + uint32 mThrallEventCount; + + uint64 ThrallGUID; + uint64 TarethaGUID; + uint64 EpochGUID; + + void Initialize() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + mBarrelCount = 0; + mThrallEventCount = 0; + ThrallGUID = 0; + TarethaGUID = 0; + EpochGUID = 0; + } + + Player* GetPlayerInMap() + { + Map::PlayerList const& players = instance->GetPlayers(); + + if (!players.isEmpty()) + { + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* plr = itr->getSource()) + return plr; + } + } + + debug_log("TSCR: Instance Old Hillsbrad: GetPlayerInMap, but PlayerList is empty!"); + return NULL; + } + + void UpdateQuestCredit() + { + Map::PlayerList const& players = instance->GetPlayers(); + + if (!players.isEmpty()) + { + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + pPlayer->KilledMonsterCredit(LODGE_QUEST_TRIGGER,0); + } + } + } + + void OnCreatureCreate(Creature* pCreature, bool /*add*/) + { + switch(pCreature->GetEntry()) + { + case THRALL_ENTRY: + ThrallGUID = pCreature->GetGUID(); + break; + case TARETHA_ENTRY: + TarethaGUID = pCreature->GetGUID(); + break; + case EPOCH_ENTRY: + EpochGUID = pCreature->GetGUID(); + break; + } + } + + void SetData(uint32 type, uint32 data) + { + Player* pPlayer = GetPlayerInMap(); + + if (!pPlayer) + { + debug_log("TSCR: Instance Old Hillsbrad: SetData (Type: %u Data %u) cannot find any player.", type, data); + return; + } + + switch(type) + { + case TYPE_BARREL_DIVERSION: + { + if (data == IN_PROGRESS) + { + if (mBarrelCount >= 5) + return; + + ++mBarrelCount; + DoUpdateWorldState(WORLD_STATE_OH, mBarrelCount); + + debug_log("TSCR: Instance Old Hillsbrad: go_barrel_old_hillsbrad count %u",mBarrelCount); + + m_auiEncounter[0] = IN_PROGRESS; + + if (mBarrelCount == 5) + { + UpdateQuestCredit(); + pPlayer->SummonCreature(DRAKE_ENTRY, 2128.43, 71.01, 64.42, 1.74, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 1800000); + m_auiEncounter[0] = DONE; + } + } + break; + } + case TYPE_THRALL_EVENT: + { + if (data == FAIL) + { + if (mThrallEventCount <= 20) + { + ++mThrallEventCount; + m_auiEncounter[1] = NOT_STARTED; + debug_log("TSCR: Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.",mThrallEventCount); + m_auiEncounter[2] = NOT_STARTED; + m_auiEncounter[3] = NOT_STARTED; + m_auiEncounter[4] = NOT_STARTED; + m_auiEncounter[5] = NOT_STARTED; + } + else if (mThrallEventCount > 20) + { + m_auiEncounter[1] = data; + m_auiEncounter[2] = data; + m_auiEncounter[3] = data; + m_auiEncounter[4] = data; + m_auiEncounter[5] = data; + debug_log("TSCR: Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.",mThrallEventCount); + } + } + else + m_auiEncounter[1] = data; + debug_log("TSCR: Instance Old Hillsbrad: Thrall escort event adjusted to data %u.",data); + break; + } + case TYPE_THRALL_PART1: + m_auiEncounter[2] = data; + debug_log("TSCR: Instance Old Hillsbrad: Thrall event part I adjusted to data %u.",data); + break; + case TYPE_THRALL_PART2: + m_auiEncounter[3] = data; + debug_log("TSCR: Instance Old Hillsbrad: Thrall event part II adjusted to data %u.",data); + break; + case TYPE_THRALL_PART3: + m_auiEncounter[4] = data; + debug_log("TSCR: Instance Old Hillsbrad: Thrall event part III adjusted to data %u.",data); + break; + case TYPE_THRALL_PART4: + m_auiEncounter[5] = data; + debug_log("TSCR: Instance Old Hillsbrad: Thrall event part IV adjusted to data %u.",data); + break; + } + } + + uint32 GetData(uint32 data) + { + switch(data) + { + case TYPE_BARREL_DIVERSION: + return m_auiEncounter[0]; + case TYPE_THRALL_EVENT: + return m_auiEncounter[1]; + case TYPE_THRALL_PART1: + return m_auiEncounter[2]; + case TYPE_THRALL_PART2: + return m_auiEncounter[3]; + case TYPE_THRALL_PART3: + return m_auiEncounter[4]; + case TYPE_THRALL_PART4: + return m_auiEncounter[5]; + } + return 0; + } + + uint64 GetData64(uint32 data) + { + switch(data) + { + case DATA_THRALL: + return ThrallGUID; + case DATA_TARETHA: + return TarethaGUID; + case DATA_EPOCH: + return EpochGUID; + } + return 0; + } +}; +InstanceData* GetInstanceData_instance_old_hillsbrad(Map* pMap) +{ + return new instance_old_hillsbrad(pMap); +} + +void AddSC_instance_old_hillsbrad() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "instance_old_hillsbrad"; + newscript->GetInstanceData = &GetInstanceData_instance_old_hillsbrad; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp new file mode 100644 index 00000000000..08c63954db5 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -0,0 +1,658 @@ + /* Copyright (C) 2006 - 2009 ScriptDev2 + * 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: Old_Hillsbrad +SD%Complete: 40 +SDComment: Quest support: 10283, 10284. All friendly NPC's. Thrall waypoints fairly complete, missing many details, but possible to complete escort. +SDCategory: Caverns of Time, Old Hillsbrad Foothills +EndScriptData */ + +/* ContentData +npc_erozion +npc_thrall_old_hillsbrad +npc_taretha +EndContentData */ + +#include "ScriptedPch.h" +#include "ScriptedEscortAI.h" +#include "old_hillsbrad.h" + +#define QUEST_ENTRY_HILLSBRAD 10282 +#define QUEST_ENTRY_DIVERSION 10283 +#define QUEST_ENTRY_ESCAPE 10284 +#define QUEST_ENTRY_RETURN 10285 +#define ITEM_ENTRY_BOMBS 25853 + +#define GOSSIP_HELLO_EROZION1 "I need a pack of Incendiary Bombs." +#define GOSSIP_HELLO_EROZION2 "[PH] Teleport please, i'm tired." + +/*###### +## npc_erozion +######*/ + +bool GossipHello_npc_erozion(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + + ScriptedInstance* pInstance = pCreature->GetInstanceData(); + if (pInstance && pInstance->GetData(TYPE_BARREL_DIVERSION) != DONE && !pPlayer->HasItemCount(ITEM_ENTRY_BOMBS,1)) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + if (!pPlayer->GetQuestRewardStatus(QUEST_ENTRY_RETURN) && pPlayer->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE) + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + pPlayer->SEND_GOSSIP_MENU(9778, pCreature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_erozion(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + ItemPosCountVec dest; + uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_ENTRY_BOMBS, 1); + if (msg == EQUIP_ERR_OK) + { + pPlayer->StoreNewItem(dest, ITEM_ENTRY_BOMBS, true); + } + pPlayer->SEND_GOSSIP_MENU(9515, pCreature->GetGUID()); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + pPlayer->CLOSE_GOSSIP_MENU(); + } + return true; +} + +/*###### +## npc_thrall_old_hillsbrad +######*/ + +//Thrall texts +#define SAY_TH_START_EVENT_PART1 -1560023 +#define SAY_TH_ARMORY -1560024 +#define SAY_TH_SKARLOC_MEET -1560025 +#define SAY_TH_SKARLOC_TAUNT -1560026 +#define SAY_TH_START_EVENT_PART2 -1560027 +#define SAY_TH_MOUNTS_UP -1560028 +#define SAY_TH_CHURCH_END -1560029 +#define SAY_TH_MEET_TARETHA -1560030 +#define SAY_TH_EPOCH_WONDER -1560031 +#define SAY_TH_EPOCH_KILL_TARETHA -1560032 +#define SAY_TH_EVENT_COMPLETE -1560033 + +#define SAY_TH_RANDOM_LOW_HP1 -1560034 +#define SAY_TH_RANDOM_LOW_HP2 -1560035 + +#define SAY_TH_RANDOM_DIE1 -1560036 +#define SAY_TH_RANDOM_DIE2 -1560037 + +#define SAY_TH_RANDOM_AGGRO1 -1560038 +#define SAY_TH_RANDOM_AGGRO2 -1560039 +#define SAY_TH_RANDOM_AGGRO3 -1560040 +#define SAY_TH_RANDOM_AGGRO4 -1560041 + +#define SAY_TH_RANDOM_KILL1 -1560042 +#define SAY_TH_RANDOM_KILL2 -1560043 +#define SAY_TH_RANDOM_KILL3 -1560044 + +#define SAY_TH_LEAVE_COMBAT1 -1560045 +#define SAY_TH_LEAVE_COMBAT2 -1560046 +#define SAY_TH_LEAVE_COMBAT3 -1560047 + +//Taretha texts +#define SAY_TA_FREE -1560048 +#define SAY_TA_ESCAPED -1560049 + +//Misc for Thrall +#define SPELL_STRIKE 14516 +#define SPELL_SHIELD_BLOCK 12169 +#define SPELL_SUMMON_EROZION_IMAGE 33954 //if thrall dies during escort? + +#define SPEED_WALK (0.5f) +#define SPEED_RUN (1.0f) +#define SPEED_MOUNT (1.6f) + +#define THRALL_WEAPON_MODEL 22106 +#define THRALL_WEAPON_INFO 218169346 +#define THRALL_SHIELD_MODEL 18662 +#define THRALL_SHIELD_INFO 234948100 +#define THRALL_MODEL_UNEQUIPPED 17292 +#define THRALL_MODEL_EQUIPPED 18165 + +//Misc Creature entries +#define ENTRY_ARMORER 18764 +#define ENTRY_SCARLOC 17862 + +#define MOB_ENTRY_RIFLE 17820 +#define MOB_ENTRY_WARDEN 17833 +#define MOB_ENTRY_VETERAN 17860 +#define MOB_ENTRY_WATCHMAN 17814 +#define MOB_ENTRY_SENTRY 17815 + +#define MOB_ENTRY_BARN_GUARDSMAN 18092 +#define MOB_ENTRY_BARN_PROTECTOR 18093 +#define MOB_ENTRY_BARN_LOOKOUT 18094 + +#define MOB_ENTRY_CHURCH_GUARDSMAN 23175 +#define MOB_ENTRY_CHURCH_PROTECTOR 23179 +#define MOB_ENTRY_CHURCH_LOOKOUT 23177 + +#define MOB_ENTRY_INN_GUARDSMAN 23176 +#define MOB_ENTRY_INN_PROTECTOR 23180 +#define MOB_ENTRY_INN_LOOKOUT 23178 + +#define SKARLOC_MOUNT 18798 +#define SKARLOC_MOUNT_MODEL 18223 +#define EROZION_ENTRY 18723 +#define ENTRY_EPOCH 18096 + +//gossip items +#define GOSSIP_ID_START 9568 +#define GOSSIP_ID_SKARLOC1 9614 //I'm glad Taretha is alive. We now must find a way to free her... +#define GOSSIP_ITEM_SKARLOC1 "Taretha cannot see you, Thrall." +#define GOSSIP_ID_SKARLOC2 9579 //What do you mean by this? Is Taretha in danger? +#define GOSSIP_ITEM_SKARLOC2 "The situation is rather complicated, Thrall. It would be best for you to head into the mountains now, before more of Blackmoore's men show up. We'll make sure Taretha is safe." +#define GOSSIP_ID_SKARLOC3 9580 + +#define GOSSIP_ID_TARREN 9597 //tarren mill is beyond these trees +#define GOSSIP_ITEM_TARREN "We're ready, Thrall." + +#define GOSSIP_ID_COMPLETE 9578 //Thank you friends, I owe my freedom to you. Where is Taretha? I hoped to see her + +#define GOSSIP_ITEM_WALKING "[PH] Start walking." + +struct npc_thrall_old_hillsbradAI : public npc_escortAI +{ + npc_thrall_old_hillsbradAI(Creature *c) : npc_escortAI(c) + { + pInstance = c->GetInstanceData(); + HadMount = false; + me->setActive(true); + } + + ScriptedInstance *pInstance; + + uint64 TarethaGUID; + + bool LowHp; + bool HadMount; + + void WaypointReached(uint32 i) + { + if (!pInstance) + return; + + switch(i) + { + case 8: + SetRun(false); + me->SummonCreature(18764,2181.87,112.46,89.45,0.26,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 9: + DoScriptText(SAY_TH_ARMORY, me); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL); + //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); + //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL); + //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); + //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); + break; + case 10: + me->SetDisplayId(THRALL_MODEL_EQUIPPED); + break; + case 11: + SetRun(); + break; + case 15: + me->SummonCreature(MOB_ENTRY_RIFLE,2200.28,137.37,87.93,5.07,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_WARDEN,2197.44,131.83,87.93,0.78,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_VETERAN,2203.62,135.40,87.93,3.70,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_VETERAN,2200.75,130.13,87.93,1.48,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 21: + me->SummonCreature(MOB_ENTRY_RIFLE,2135.80,154.01,67.45,4.98,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_WARDEN,2144.36,151.87,67.74,4.46,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_VETERAN,2142.12,154.41,67.12,4.56,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_VETERAN,2138.08,155.38,67.24,4.60,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 25: + me->SummonCreature(MOB_ENTRY_RIFLE,2102.98,192.17,65.24,6.02,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_WARDEN,2108.48,198.75,65.18,5.15,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_VETERAN,2106.11,197.29,65.18,5.63,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_VETERAN,2104.18,194.82,65.18,5.75,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 29: + DoScriptText(SAY_TH_SKARLOC_MEET, me); + me->SummonCreature(ENTRY_SCARLOC,2036.48,271.22,63.43,5.27,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); + //temporary,skarloc should rather be triggered to walk up to thrall + break; + case 30: + SetEscortPaused(true); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetRun(false); + break; + case 31: + DoScriptText(SAY_TH_MOUNTS_UP, me); + DoMount(); + SetRun(); + break; + case 37: + //possibly regular patrollers? If so, remove this and let database handle them + me->SummonCreature(MOB_ENTRY_WATCHMAN,2124.26,522.16,56.87,3.99,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_WATCHMAN,2121.69,525.37,57.11,4.01,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_SENTRY,2124.65,524.55,56.63,3.98,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 59: + me->SummonCreature(SKARLOC_MOUNT,2488.64,625.77,58.26,4.71,TEMPSUMMON_TIMED_DESPAWN,10000); + DoUnmount(); + HadMount = false; + SetRun(false); + break; + case 60: + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + //make horsie run off + SetEscortPaused(true); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + pInstance->SetData(TYPE_THRALL_PART2, DONE); + SetRun(); + break; + case 64: + SetRun(false); + break; + case 68: + me->SummonCreature(MOB_ENTRY_BARN_PROTECTOR,2500.22,692.60,55.50,2.84,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_BARN_LOOKOUT,2500.13,696.55,55.51,3.38,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN,2500.55,693.64,55.50,3.14,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN,2500.94,695.81,55.50,3.14,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 71: + SetRun(); + break; + case 81: + SetRun(false); + break; + case 83: + me->SummonCreature(MOB_ENTRY_CHURCH_PROTECTOR,2627.33,646.82,56.03,4.28,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); + me->SummonCreature(MOB_ENTRY_CHURCH_LOOKOUT,2624.14,648.03,56.03,4.50,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); + me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN,2625.32,649.60,56.03,4.38,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); + me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN,2627.22,649.00,56.03,4.34,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); + break; + case 84: + DoScriptText(SAY_TH_CHURCH_END, me); + SetRun(); + break; + case 91: + me->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); + SetRun(false); + break; + case 93: + me->SummonCreature(MOB_ENTRY_INN_PROTECTOR,2652.71,660.31,61.93,1.67,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_INN_LOOKOUT,2648.96,662.59,61.93,0.79,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN,2657.36,662.34,61.93,2.68,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN,2656.39,659.77,61.93,2.61,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); + break; + case 94: + if (uint64 TarethaGUID = pInstance->GetData64(DATA_TARETHA)) + { + if (Unit* Taretha = Unit::GetUnit((*me), TarethaGUID)) + DoScriptText(SAY_TA_ESCAPED, Taretha, me); + } + break; + case 95: + DoScriptText(SAY_TH_MEET_TARETHA, me); + pInstance->SetData(TYPE_THRALL_PART3,DONE); + SetEscortPaused(true); + break; + case 96: + DoScriptText(SAY_TH_EPOCH_WONDER, me); + break; + case 97: + DoScriptText(SAY_TH_EPOCH_KILL_TARETHA, me); + SetRun(); + break; + case 98: + //trigger epoch Yell("Thrall! Come outside and face your fate! ....") + //from here, thrall should not never be allowed to move to point 106 which he currently does. + break; + + case 106: + { + //trigger taretha to run down outside + if (Creature* Taretha = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TARETHA))) + { + if (Player* pPlayer = GetPlayerForEscort()) + CAST_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, pPlayer->GetGUID()); + } + + //kill credit Creature for quest + Map* pMap = me->GetMap(); + Map::PlayerList const& players = pMap->GetPlayers(); + if (!players.isEmpty() && pMap->IsDungeon()) + { + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* pPlayer = itr->getSource()) + pPlayer->KilledMonsterCredit(20156,me->GetGUID()); + } + } + + //alot will happen here, thrall and taretha talk, erozion appear at spot to explain + me->SummonCreature(EROZION_ENTRY,2646.47,680.416,55.38,4.16,TEMPSUMMON_TIMED_DESPAWN,120000); + } + break; + case 108: + //last waypoint, just set Thrall invisible, respawn is turned off + me->SetVisibility(VISIBILITY_OFF); + break; + } + } + + void Reset() + { + LowHp = false; + + if (HadMount) + DoMount(); + + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + DoUnmount(); + HadMount = false; + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + me->SetDisplayId(THRALL_MODEL_UNEQUIPPED); + } + if (HasEscortState(STATE_ESCORT_ESCORTING)) + { + DoScriptText(RAND(SAY_TH_LEAVE_COMBAT1,SAY_TH_LEAVE_COMBAT2,SAY_TH_LEAVE_COMBAT3), me); + } + } + void StartWP() + { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + SetEscortPaused(false); + } + void DoMount() + { + me->Mount(SKARLOC_MOUNT_MODEL); + me->SetSpeed(MOVE_RUN,SPEED_MOUNT); + } + void DoUnmount() + { + me->Unmount(); + me->SetSpeed(MOVE_RUN,SPEED_RUN); + } + void EnterCombat(Unit* /*who*/) + { + DoScriptText(RAND(SAY_TH_RANDOM_AGGRO1,SAY_TH_RANDOM_AGGRO2,SAY_TH_RANDOM_AGGRO3,SAY_TH_RANDOM_AGGRO4), me); + if (me->IsMounted()) + { + DoUnmount(); + HadMount = true; + } + } + + void JustSummoned(Creature* summoned) + { + switch(summoned->GetEntry()) + { + //TODO: make Scarloc start into event instead, and not start attack directly + case MOB_ENTRY_BARN_GUARDSMAN: + case MOB_ENTRY_BARN_PROTECTOR: + case MOB_ENTRY_BARN_LOOKOUT: + case SKARLOC_MOUNT: + case EROZION_ENTRY: + break; + default: + summoned->AI()->AttackStart(me); + break; + } + } + + void KilledUnit(Unit * /*victim*/) + { + DoScriptText(RAND(SAY_TH_RANDOM_KILL1,SAY_TH_RANDOM_KILL2,SAY_TH_RANDOM_KILL3), me); + } + void JustDied(Unit *slayer) + { + if (pInstance) + pInstance->SetData(TYPE_THRALL_EVENT,FAIL); + + // Don't do a yell if he kills self (if player goes too far or at the end). + if (slayer == me) + return; + + DoScriptText(RAND(SAY_TH_RANDOM_DIE1,SAY_TH_RANDOM_DIE2), me); + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + + if (!UpdateVictim()) + return; + + //TODO: add his abilities'n-crap here + if (!LowHp && ((me->GetHealth()*100 / me->GetMaxHealth()) < 20)) + { + DoScriptText(RAND(SAY_TH_RANDOM_LOW_HP1,SAY_TH_RANDOM_LOW_HP2), me); + LowHp = true; + } + } +}; + +CreatureAI* GetAI_npc_thrall_old_hillsbrad(Creature* pCreature) +{ + return new npc_thrall_old_hillsbradAI(pCreature); +} + +bool GossipHello_npc_thrall_old_hillsbrad(Player* pPlayer, Creature* pCreature) +{ + if (pCreature->isQuestGiver()) + { + pPlayer->PrepareQuestMenu(pCreature->GetGUID()); + pPlayer->SendPreparedQuest(pCreature->GetGUID()); + } + + ScriptedInstance* pInstance = pCreature->GetInstanceData(); + if (pInstance) + { + if (pInstance->GetData(TYPE_BARREL_DIVERSION) == DONE && !pInstance->GetData(TYPE_THRALL_EVENT)) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WALKING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_START, pCreature->GetGUID()); + } + + if (pInstance->GetData(TYPE_THRALL_PART1) == DONE && !pInstance->GetData(TYPE_THRALL_PART2)) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SKARLOC1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_SKARLOC1, pCreature->GetGUID()); + } + + if (pInstance->GetData(TYPE_THRALL_PART2) == DONE && !pInstance->GetData(TYPE_THRALL_PART3)) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TARREN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_TARREN, pCreature->GetGUID()); + } + } + return true; +} + +bool GossipSelect_npc_thrall_old_hillsbrad(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + ScriptedInstance* pInstance = pCreature->GetInstanceData(); + switch(uiAction) + { + case GOSSIP_ACTION_INFO_DEF+1: + pPlayer->CLOSE_GOSSIP_MENU(); + if (pInstance) + { + pInstance->SetData(TYPE_THRALL_EVENT,IN_PROGRESS); + pInstance->SetData(TYPE_THRALL_PART1,IN_PROGRESS); + } + + DoScriptText(SAY_TH_START_EVENT_PART1, pCreature); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI())) + pEscortAI->Start(true, true, pPlayer->GetGUID()); + + CAST_AI(npc_escortAI, (pCreature->AI()))->SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far + CAST_AI(npc_escortAI, (pCreature->AI()))->SetDespawnAtEnd(false); + CAST_AI(npc_escortAI, (pCreature->AI()))->SetDespawnAtFar(false); + break; + + case GOSSIP_ACTION_INFO_DEF+2: + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SKARLOC2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+20); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_SKARLOC2, pCreature->GetGUID()); + break; + + case GOSSIP_ACTION_INFO_DEF+20: + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_SKARLOC3, pCreature->GetGUID()); + pCreature->SummonCreature(SKARLOC_MOUNT,2038.81,270.26,63.20,5.41,TEMPSUMMON_TIMED_DESPAWN,12000); + if (pInstance) + pInstance->SetData(TYPE_THRALL_PART2,IN_PROGRESS); + + DoScriptText(SAY_TH_START_EVENT_PART2, pCreature); + + CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI())->StartWP(); + break; + + case GOSSIP_ACTION_INFO_DEF+3: + pPlayer->CLOSE_GOSSIP_MENU(); + if (pInstance) + pInstance->SetData(TYPE_THRALL_PART3,IN_PROGRESS); + CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI())->StartWP(); + break; + } + return true; +} + +/*###### +## npc_taretha +######*/ + +#define GOSSIP_ID_EPOCH1 9610 //Thank you for helping Thrall escape, friends. Now I only hope +#define GOSSIP_ITEM_EPOCH1 "Strange wizard?" +#define GOSSIP_ID_EPOCH2 9613 //Yes, friends. This man was no wizard of +#define GOSSIP_ITEM_EPOCH2 "We'll get you out. Taretha. Don't worry. I doubt the wizard would wander too far away." + +struct npc_tarethaAI : public npc_escortAI +{ + npc_tarethaAI(Creature *c) : npc_escortAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance *pInstance; + + void WaypointReached(uint32 i) + { + switch(i) + { + case 6: + DoScriptText(SAY_TA_FREE, me); + break; + case 7: + me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); + break; + } + } + void Reset() {} + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; +CreatureAI* GetAI_npc_taretha(Creature* pCreature) +{ + return new npc_tarethaAI(pCreature); +} + +bool GossipHello_npc_taretha(Player* pPlayer, Creature* pCreature) +{ + ScriptedInstance* pInstance = pCreature->GetInstanceData(); + if (pInstance && pInstance->GetData(TYPE_THRALL_PART3) == DONE && pInstance->GetData(TYPE_THRALL_PART4) == NOT_STARTED) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_EPOCH1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_EPOCH1, pCreature->GetGUID()); + } + return true; +} + +bool GossipSelect_npc_taretha(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) +{ + ScriptedInstance* pInstance = pCreature->GetInstanceData(); + if (uiAction == GOSSIP_ACTION_INFO_DEF+1) + { + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_EPOCH2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_EPOCH2, pCreature->GetGUID()); + } + if (uiAction == GOSSIP_ACTION_INFO_DEF+2) + { + pPlayer->CLOSE_GOSSIP_MENU(); + + if (pInstance && pInstance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) + { + pInstance->SetData(TYPE_THRALL_PART4,IN_PROGRESS); + if (pInstance->GetData64(DATA_EPOCH) == 0) + pCreature->SummonCreature(ENTRY_EPOCH,2639.13,698.55,65.43,4.59,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,120000); + + if (uint64 ThrallGUID = pInstance->GetData64(DATA_THRALL)) + { + Creature* Thrall = (Unit::GetCreature((*pCreature), ThrallGUID)); + if (Thrall) + CAST_AI(npc_thrall_old_hillsbradAI, Thrall->AI())->StartWP(); + } + } + } + return true; +} + +/*###### +## AddSC +######*/ + +void AddSC_old_hillsbrad() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "npc_erozion"; + newscript->pGossipHello = &GossipHello_npc_erozion; + newscript->pGossipSelect = &GossipSelect_npc_erozion; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_thrall_old_hillsbrad"; + newscript->pGossipHello = &GossipHello_npc_thrall_old_hillsbrad; + newscript->pGossipSelect = &GossipSelect_npc_thrall_old_hillsbrad; + newscript->GetAI = &GetAI_npc_thrall_old_hillsbrad; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "npc_taretha"; + newscript->pGossipHello = &GossipHello_npc_taretha; + newscript->pGossipSelect = &GossipSelect_npc_taretha; + newscript->GetAI = &GetAI_npc_taretha; + newscript->RegisterSelf(); +} + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h new file mode 100644 index 00000000000..5c398cc2647 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h @@ -0,0 +1,19 @@ +/* Copyright (C) 2006 - 2009 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ + +#ifndef DEF_OLD_HILLSBRAD_H +#define DEF_OLD_HILLSBRAD_H + +#define TYPE_BARREL_DIVERSION 1 +#define TYPE_THRALL_EVENT 2 +#define TYPE_THRALL_PART1 3 +#define TYPE_THRALL_PART2 4 +#define TYPE_THRALL_PART3 5 +#define TYPE_THRALL_PART4 6 +#define DATA_THRALL 7 +#define DATA_TARETHA 8 +#define DATA_EPOCH 9 +#define WORLD_STATE_OH 2436 +#endif + diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_epoch.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_epoch.cpp deleted file mode 100644 index 287d3cf8e9b..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_epoch.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - - -/* Script Data Start -SDName: Boss epoch -SDAuthor: Tartalo -SD%Complete: 80 -SDComment: TODO: Intro, consecutive attacks to a random target durin time wrap, adjust timers -SDCategory: -Script Data End */ - -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CURSE_OF_EXERTION = 52772, - SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec. - SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec. - SPELL_WOUNDING_STRIKE = 52771, //Used only on the tank - H_SPELL_WOUNDING_STRIKE = 58830 -}; - -enum Yells -{ - SAY_INTRO = -1595000, //"Prince Arthas Menethil, on this day, a powerful darkness has taken hold of your soul. The death you are destined to visit upon others will this day be your own." - SAY_AGGRO = -1595001, //"We'll see about that, young prince." - SAY_TIME_WARP_1 = -1595002, //"Tick tock, tick tock..." - SAY_TIME_WARP_2 = -1595003, //"Not quick enough!" - SAY_TIME_WARP_3 = -1595004, //"Let's get this over with. " - SAY_SLAY_1 = -1595005, //"There is no future for you." - SAY_SLAY_2 = -1595006, //"This is the hour of our greatest triumph!" - SAY_SLAY_3 = -1595007, //"You were destined to fail. " - SAY_DEATH = -1595008 //"*gurgles*" -}; - -struct boss_epochAI : public ScriptedAI -{ - boss_epochAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - uint8 uiStep; - - uint32 uiStepTimer; - uint32 uiWoundingStrikeTimer; - uint32 uiTimeWarpTimer; - uint32 uiTimeStopTimer; - uint32 uiCurseOfExertionTimer; - - ScriptedInstance* pInstance; - - void Reset() - { - uiStep = 1; - uiStepTimer = 26000; - uiCurseOfExertionTimer = 9300; - uiTimeWarpTimer = 25300; - uiTimeStopTimer = 21300; - uiWoundingStrikeTimer = 5300; - - if (pInstance) - pInstance->SetData(DATA_EPOCH_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - DoScriptText(SAY_AGGRO, me); - - if (pInstance) - pInstance->SetData(DATA_EPOCH_EVENT, IN_PROGRESS); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiCurseOfExertionTimer < diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(pTarget, SPELL_CURSE_OF_EXERTION); - uiCurseOfExertionTimer = 9300; - } else uiCurseOfExertionTimer -= diff; - - if (uiWoundingStrikeTimer < diff) - { - DoCastVictim(SPELL_WOUNDING_STRIKE); - uiWoundingStrikeTimer = 5300; - } else uiWoundingStrikeTimer -= diff; - - if (uiTimeStopTimer < diff) - { - DoCastAOE(SPELL_TIME_STOP); - uiTimeStopTimer = 21300; - } else uiTimeStopTimer -= diff; - - if (uiTimeWarpTimer < diff) - { - DoScriptText(RAND(SAY_TIME_WARP_1,SAY_TIME_WARP_2,SAY_TIME_WARP_3), me); - DoCastAOE(SPELL_TIME_WARP); - uiTimeWarpTimer = 25300; - } else uiTimeWarpTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(DATA_EPOCH_EVENT, DONE); - } - - void KilledUnit(Unit * victim) - { - if (victim == me) - return; - - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me); - } -}; - -CreatureAI* GetAI_boss_epoch(Creature* pCreature) -{ - return new boss_epochAI (pCreature); -} - -void AddSC_boss_epoch() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_epoch"; - newscript->GetAI = &GetAI_boss_epoch; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_infinite.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_infinite.cpp deleted file mode 100644 index 12cdf00f2a5..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_infinite.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CORRUPTING_BLIGHT = 60588, - SPELL_VOID_STRIKE = 60590 -}; - -enum Yells -{ - SAY_AGGRO = -1595045, - SAY_FAIL = -1595046, - SAY_DEATH = -1595047 -}; - - -struct boss_infinite_corruptorAI : public ScriptedAI -{ - boss_infinite_corruptorAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance* pInstance; - - void Reset() - { - if (pInstance) - pInstance->SetData(DATA_INFINITE_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - if (pInstance) - pInstance->SetData(DATA_INFINITE_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; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - if (pInstance) - pInstance->SetData(DATA_INFINITE_EVENT, DONE); - } -}; - -CreatureAI* GetAI_boss_infinite_corruptor(Creature* pCreature) -{ - return new boss_infinite_corruptorAI(pCreature); -} - -void AddSC_boss_infinite_corruptor() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_infinite_corruptor"; - newscript->GetAI = &GetAI_boss_infinite_corruptor; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_mal_ganis.cpp deleted file mode 100644 index a39f3289a5a..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_mal_ganis.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - -/* Script Data Start -SDName: Boss mal_ganis -SDAuthor: Tartalo -SD%Complete: 80 -SDComment: TODO: Intro & outro -SDCategory: -Script Data End */ - -/*** SQL START *** -update creature_template set scriptname = 'boss_mal_ganis' where entry = ''; -*** SQL END ***/ -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CARRION_SWARM = 52720, //A cresting wave of chaotic magic splashes over enemies in front of the caster, dealing 3230 to 3570 Shadow damage and 380 to 420 Shadow damage every 3 sec. for 15 sec. - H_SPELL_CARRION_SWARM = 58852, - SPELL_MIND_BLAST = 52722, //Inflicts 4163 to 4837 Shadow damage to an enemy. - H_SPELL_MIND_BLAST = 58850, - SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target. - H_SPELL_SLEEP = 58849, - SPELL_VAMPIRIC_TOUCH = 52723 //Heals the caster for half the damage dealt by a melee attack. -}; - -enum Yells -{ - SAY_INTRO_1 = -1595009, - SAY_INTRO_2 = -1595010, - SAY_AGGRO = -1595011, - SAY_KILL_1 = -1595012, - SAY_KILL_2 = -1595013, - SAY_KILL_3 = -1595014, - SAY_SLAY_1 = -1595015, - SAY_SLAY_2 = -1595016, - SAY_SLAY_3 = -1595017, - SAY_SLAY_4 = -1595018, - SAY_SLEEP_1 = -1595019, - SAY_SLEEP_2 = -1595020, - SAY_30HEALTH = -1595021, - SAY_15HEALTH = -1595022, - SAY_ESCAPE_SPEECH_1 = -1595023, - SAY_ESCAPE_SPEECH_2 = -1595024, - SAY_OUTRO = -1595025, -}; - -enum CombatPhases -{ - COMBAT, - OUTRO -}; - -struct boss_mal_ganisAI : public ScriptedAI -{ - boss_mal_ganisAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - uint32 uiCarrionSwarmTimer; - uint32 uiMindBlastTimer; - uint32 uiVampiricTouchTimer; - uint32 uiSleepTimer; - - uint8 uiOutroStep; - uint32 uiOutroTimer; - - bool bYelled; - bool bYelled2; - - CombatPhases Phase; - - ScriptedInstance* pInstance; - - void Reset() - { - bYelled = false; - bYelled2 = false; - Phase = COMBAT; - uiCarrionSwarmTimer = 6000; - uiMindBlastTimer = 11000; - uiVampiricTouchTimer = urand(10000,15000); - uiSleepTimer = urand(15000,20000); - uiOutroTimer = 1000; - - if (pInstance) - pInstance->SetData(DATA_MAL_GANIS_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - DoScriptText(SAY_AGGRO, me); - if (pInstance) - pInstance->SetData(DATA_MAL_GANIS_EVENT, IN_PROGRESS); - } - - void DamageTaken(Unit *done_by, uint32 &damage) - { - if (damage >= me->GetHealth() && done_by != me) - damage = me->GetHealth()-1; - } - - void UpdateAI(const uint32 diff) - { - switch(Phase) - { - case COMBAT: - //Return since we have no target - if (!UpdateVictim()) - return; - - if (!bYelled && HealthBelowPct(30)) - { - DoScriptText(SAY_30HEALTH, me); - bYelled = true; - } - - if (!bYelled2 && HealthBelowPct(15)) - { - DoScriptText(SAY_15HEALTH, me); - bYelled2 = true; - } - - if (HealthBelowPct(1)) - { - //Handle Escape Event: Don't forget to add Player::RewardPlayerAndGroupAtEvent - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - uiOutroStep = 1; - Phase = OUTRO; - return; - } - - if (Creature* pArthas = me->GetCreature(*me, pInstance ? pInstance->GetData64(DATA_ARTHAS) : 0)) - if (pArthas->isDead()) - { - EnterEvadeMode(); - me->DisappearAndDie(); - if (pInstance) - pInstance->SetData(DATA_MAL_GANIS_EVENT, FAIL); - } - - if (uiCarrionSwarmTimer < diff) - { - DoCastVictim(SPELL_CARRION_SWARM); - uiCarrionSwarmTimer = 7000; - } else uiCarrionSwarmTimer -= diff; - - if (uiMindBlastTimer < diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(pTarget, SPELL_MIND_BLAST); - uiMindBlastTimer = 6000; - } else uiMindBlastTimer -= diff; - - if (uiVampiricTouchTimer < diff) - { - DoCast(me, SPELL_VAMPIRIC_TOUCH); - uiVampiricTouchTimer = 32000; - } else uiVampiricTouchTimer -= diff; - - if (uiSleepTimer < diff) - { - DoScriptText(RAND(SAY_SLEEP_1,SAY_SLEEP_2), me); - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(pTarget, SPELL_SLEEP); - uiSleepTimer = urand(15000,20000); - } else uiSleepTimer -= diff; - - DoMeleeAttackIfReady(); - break; - case OUTRO: - if (uiOutroTimer < diff) - { - switch(uiOutroStep) - { - case 1: - DoScriptText(SAY_ESCAPE_SPEECH_1, me); - me->GetMotionMaster()->MoveTargetedHome(); - ++uiOutroStep; - uiOutroTimer = 8000; - break; - case 2: - me->SetUInt64Value(UNIT_FIELD_TARGET, pInstance ? pInstance->GetData64(DATA_ARTHAS) : 0); - me->HandleEmoteCommand(29); - DoScriptText(SAY_ESCAPE_SPEECH_2, me); - ++uiOutroStep; - uiOutroTimer = 9000; - break; - case 3: - DoScriptText(SAY_OUTRO, me); - ++uiOutroStep; - uiOutroTimer = 16000; - break; - case 4: - me->HandleEmoteCommand(33); - ++uiOutroStep; - uiOutroTimer = 500; - break; - case 5: - me->SetVisibility(VISIBILITY_OFF); - me->Kill(me); - break; - - } - } else uiOutroTimer -= diff; - break; - } - } - - void JustDied(Unit* /*killer*/) - { - if (pInstance) - { - pInstance->SetData(DATA_MAL_GANIS_EVENT, DONE); - - // give achievement credit to players. criteria use spell 58630 which doesn't exist. - if (pInstance) - pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58630); - } - } - - void KilledUnit(Unit * victim) - { - if (victim == me) - return; - - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), me); - } -}; - -CreatureAI* GetAI_boss_mal_ganis(Creature* pCreature) -{ - return new boss_mal_ganisAI (pCreature); -} - -void AddSC_boss_mal_ganis() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_mal_ganis"; - newscript->GetAI = &GetAI_boss_mal_ganis; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_meathook.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_meathook.cpp deleted file mode 100644 index eba9733c745..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_meathook.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - -/* Script Data Start -SDName: Boss meathook -SDAuthor: Tartalo -SD%Complete: 100 -SDComment: It may need timer adjustment -SDCategory: -Script Data End */ - -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CONSTRICTING_CHAINS = 52696, //Encases the targets in chains, dealing 1800 Physical damage every 1 sec. and stunning the target for 5 sec. - H_SPELL_CONSTRICTING_CHAINS = 58823, - SPELL_DISEASE_EXPULSION = 52666, //Meathook belches out a cloud of disease, dealing 1710 to 1890 Nature damage and interrupting the spell casting of nearby enemy targets for 4 sec. - H_SPELL_DISEASE_EXPULSION = 58824, - SPELL_FRENZY = 58841 //Increases the caster's Physical damage by 10% for 30 sec. -}; - -enum Yells -{ - SAY_AGGRO = -1595026, - SAY_SLAY_1 = -1595027, - SAY_SLAY_2 = -1595028, - SAY_SLAY_3 = -1595029, - SAY_SPAWN = -1595030, - SAY_DEATH = -1595031 -}; - -struct boss_meathookAI : public ScriptedAI -{ - boss_meathookAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - if (pInstance) - DoScriptText(SAY_SPAWN,me); - } - - uint32 uiChainTimer; - uint32 uiDiseaseTimer; - uint32 uiFrenzyTimer; - - ScriptedInstance* pInstance; - - void Reset() - { - uiChainTimer = urand(12000,17000); //seen on video 13, 17, 15, 12, 16 - uiDiseaseTimer = urand(2000,4000); //approx 3s - uiFrenzyTimer = urand(21000,26000); //made it up - - if (pInstance) - pInstance->SetData(DATA_MEATHOOK_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - DoScriptText(SAY_AGGRO, me); - - if (pInstance) - pInstance->SetData(DATA_MEATHOOK_EVENT, IN_PROGRESS); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiDiseaseTimer <= diff) - { - DoCastAOE(SPELL_DISEASE_EXPULSION); - uiDiseaseTimer = urand(1500,4000); - } else uiDiseaseTimer -= diff; - - if (uiFrenzyTimer <= diff) - { - DoCast(me, SPELL_FRENZY); - uiFrenzyTimer = urand(21000,26000); - } else uiFrenzyTimer -= diff; - - if (uiChainTimer <= diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(pTarget, SPELL_CONSTRICTING_CHAINS); //anyone but the tank - uiChainTimer = urand(2000,4000); - } else uiChainTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(DATA_MEATHOOK_EVENT, DONE); - } - - void KilledUnit(Unit * victim) - { - if (victim == me) - return; - - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me); - } -}; - -CreatureAI* GetAI_boss_meathook(Creature* pCreature) -{ - return new boss_meathookAI (pCreature); -} - -void AddSC_boss_meathook() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_meathook"; - newscript->GetAI = &GetAI_boss_meathook; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_salramm.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_salramm.cpp deleted file mode 100644 index da1c8098517..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/boss_salramm.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - -/* Script Data Start -SDName: Boss salramm -SDAuthor: Tartalo -SD%Complete: 80 -SDComment: TODO: Intro -SDCategory: -Script Data End */ - -/*** SQL START *** -update creature_template set scriptname = 'boss_salramm' where entry = ''; -*** SQL END ***/ -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" - -enum Spells -{ - SPELL_CURSE_OF_TWISTED_FLESH = 58845, - SPELL_EXPLODE_GHOUL = 52480, - H_SPELL_EXPLODE_GHOUL = 58825, - SPELL_SHADOW_BOLT = 57725, - H_SPELL_SHADOW_BOLT = 58828, - SPELL_STEAL_FLESH = 52708, - SPELL_SUMMON_GHOULS = 52451 -}; - -enum Yells -{ - SAY_AGGRO = -1595032, - SAY_SPAWN = -1595033, - SAY_SLAY_1 = -1595034, - SAY_SLAY_2 = -1595035, - SAY_SLAY_3 = -1595036, - SAY_DEATH = -1595037, - SAY_EXPLODE_GHOUL_1 = -1595038, - SAY_EXPLODE_GHOUL_2 = -1595039, - SAY_STEAL_FLESH_1 = -1595040, - SAY_STEAL_FLESH_2 = -1595041, - SAY_STEAL_FLESH_3 = -1595042, - SAY_SUMMON_GHOULS_1 = -1595043, - SAY_SUMMON_GHOULS_2 = -1595044 -}; - -struct boss_salrammAI : public ScriptedAI -{ - boss_salrammAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - if (pInstance) - DoScriptText(SAY_SPAWN,me); - } - - uint32 uiCurseFleshTimer; - uint32 uiExplodeGhoulTimer; - uint32 uiShadowBoltTimer; - uint32 uiStealFleshTimer; - uint32 uiSummonGhoulsTimer; - - ScriptedInstance* pInstance; - - void Reset() - { - uiCurseFleshTimer = 30000; //30s DBM - uiExplodeGhoulTimer = urand(25000,28000); //approx 6 sec after summon ghouls - uiShadowBoltTimer = urand(8000,12000); // approx 10s - uiStealFleshTimer = 12345; - uiSummonGhoulsTimer = urand(19000,24000); //on a video approx 24s after aggro - - if (pInstance) - pInstance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) - { - DoScriptText(SAY_AGGRO, me); - - if (pInstance) - pInstance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Curse of twisted flesh timer - if (uiCurseFleshTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CURSE_OF_TWISTED_FLESH); - uiCurseFleshTimer = 37000; - } else uiCurseFleshTimer -= diff; - - //Shadow bolt timer - if (uiShadowBoltTimer <= diff) - { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_SHADOW_BOLT); - uiShadowBoltTimer = urand(8000,12000); - } else uiShadowBoltTimer -= diff; - - //Steal Flesh timer - if (uiStealFleshTimer <= diff) - { - DoScriptText(RAND(SAY_STEAL_FLESH_1,SAY_STEAL_FLESH_2,SAY_STEAL_FLESH_3), me); - if (Unit* random_pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(random_pTarget, SPELL_STEAL_FLESH); - uiStealFleshTimer = 10000; - } else uiStealFleshTimer -= diff; - - //Summon ghouls timer - if (uiSummonGhoulsTimer <= diff) - { - DoScriptText(RAND(SAY_SUMMON_GHOULS_1,SAY_SUMMON_GHOULS_2), me); - if (Unit* random_pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(random_pTarget, SPELL_SUMMON_GHOULS); - uiSummonGhoulsTimer = 10000; - } else uiSummonGhoulsTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(DATA_SALRAMM_EVENT, DONE); - } - - void KilledUnit(Unit * victim) - { - if (victim == me) - return; - - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me); - } -}; - -CreatureAI* GetAI_boss_salramm(Creature* pCreature) -{ - return new boss_salrammAI (pCreature); -} - -void AddSC_boss_salramm() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_salramm"; - newscript->GetAI = &GetAI_boss_salramm; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.cpp deleted file mode 100644 index faaed2eb6db..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.cpp +++ /dev/null @@ -1,1210 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" -#include "ScriptedEscortAI.h" - -enum Says -{ - //First Act - Uther and Jaina Dialog - SAY_PHASE101 = -1595070, //Arthas - SAY_PHASE102 = -1595071, //Uther - SAY_PHASE103 = -1595072, //Arthas - SAY_PHASE104 = -1595073, //Arthas - SAY_PHASE105 = -1595074, //Uther - SAY_PHASE106 = -1595075, //Arthas - SAY_PHASE107 = -1595076, //Uther - SAY_PHASE108 = -1595077, //Arthas - SAY_PHASE109 = -1595078, //Arthas - SAY_PHASE110 = -1595079, //Uther - SAY_PHASE111 = -1595080, //Arthas - SAY_PHASE112 = -1595081, //Uther - SAY_PHASE113 = -1595082, //Jaina - SAY_PHASE114 = -1595083, //Arthas - SAY_PHASE115 = -1595084, //Uther - SAY_PHASE116 = -1595085, //Arthas - SAY_PHASE117 = -1595086, //Jaina - SAY_PHASE118 = -1595087, //Arthas - //Second Act - City Streets - SAY_PHASE201 = -1595088, //Arthas - SAY_PHASE202 = -1595089, //Cityman - SAY_PHASE203 = -1595090, //Arthas - SAY_PHASE204 = -1595091, //Crazyman - SAY_PHASE205 = -1595092, //Arthas - SAY_PHASE206 = -1595009, //Malganis - SAY_PHASE207 = -1595010, //Malganis - SAY_PHASE208 = -1595093, //Arthas - SAY_PHASE209 = -1595094, //Arthas - SAY_PHASE210 = -1595095, //Arthas - //Third Act - Town Hall - SAY_PHASE301 = -1595096, //Arthas - SAY_PHASE302 = -1595097, //Drakonian - SAY_PHASE303 = -1595098, //Arthas - SAY_PHASE304 = -1595099, //Arthas - SAY_PHASE305 = -1595100, //Drakonian - SAY_PHASE306 = -1595101, //Arthas - SAY_PHASE307 = -1595102, //Arthas - SAY_PHASE308 = -1595103, //Arthas - SAY_PHASE309 = -1595104, //Arthas - SAY_PHASE310 = -1595105, //Arthas - SAY_PHASE311 = -1595106, //Arthas - SAY_PHASE312 = -1595107, //Arthas - SAY_PHASE313 = -1595108, //Arthas - SAY_PHASE314 = -1595000, //Epoch - SAY_PHASE315 = -1595109, //Arthas - //Fourth Act - Fire Corridor - SAY_PHASE401 = -1595110, //Arthas - SAY_PHASE402 = -1595111, //Arthas - SAY_PHASE403 = -1595112, //Arthas - SAY_PHASE404 = -1595113, //Arthas - SAY_PHASE405 = -1595114, //Arthas - SAY_PHASE406 = -1595115, //Arthas - SAY_PHASE407 = -1595116, //Arthas - //Fifth Act - Mal'Ganis Fight - SAY_PHASE501 = -1595117, //Arthas - SAY_PHASE502 = -1595118, //Arthas - SAY_PHASE503 = -1595119, //Arthas - SAY_PHASE504 = -1595120, //Arthas -}; - -enum NPCs -{ - NPC_INFINITE_ADVERSARY = 27742, - NPC_INFINITE_HUNTER = 27743, - NPC_INFINITE_AGENT = 27744, - NPC_TIME_RIFT = 28409, - NPC_ZOMBIE = 27737, - NPC_GHOUL = 28249, - NPC_NECROMANCER = 28200, - NPC_STALKER = 28199, - NPC_FIEND = 27734, - NPC_GOLEM = 28201, - NPC_EGHOUL = 27729, - NPC_CONSTRUCT = 27736, - - NPC_INVIS_TARGET = 20562, - - NPC_KNIGHT_ESCORT = 27745, - NPC_PRIEST_ESCORT = 27747, - NPC_CITY_MAN = 28167, - NPC_CITY_MAN2 = 28169, - NPC_CITY_MAN3 = 31126, - NPC_CITY_MAN4 = 31127, -}; - -enum Spells -{ - SPELL_FEAR = 39176, - SPELL_ARTHAS_AURA = 52442, - SPELL_EXORCISM_N = 52445, - SPELL_EXORCISM_H = 58822, - SPELL_HOLY_LIGHT = 52444, -}; - -enum GossipMenuArthas -{ - GOSSIP_MENU_ARTHAS_1 = 100001, - GOSSIP_MENU_ARTHAS_2 = 100002, - GOSSIP_MENU_ARTHAS_3 = 100003, - GOSSIP_MENU_ARTHAS_4 = 100004, - GOSSIP_MENU_ARTHAS_5 = 100005 -}; - -enum -{ - ENCOUNTER_WAVES_NUMBER = 8, - ENCOUNTER_WAVES_MAX_SPAWNS = 5, - ENCOUNTER_DRACONIAN_NUMBER = 4, - ENCOUNTER_CHRONO_SPAWNS = 19 -}; - -// Locations for necromancers and add to spawn -float WavesLocations[ENCOUNTER_WAVES_NUMBER][ENCOUNTER_WAVES_MAX_SPAWNS][5]= -{ - { - {NPC_ZOMBIE, 2164.698975, 1255.392944, 135.040878, 0.490202}, - {NPC_ZOMBIE, 2183.501465, 1263.079102, 134.859055, 3.169981}, - {NPC_GHOUL, 2177.512939, 1247.313843, 135.846695, 1.696574}, - {NPC_GHOUL, 2171.991943, 1246.615845, 135.745026, 1.696574}, - {0, 0, 0, 0, 0} - }, - { - {NPC_GHOUL, 2254.434326, 1163.427612, 138.055038, 2.077358}, - {NPC_GHOUL, 2254.703613, 1158.867798, 138.212234, 2.345532}, - {NPC_GHOUL, 2257.615723, 1162.310913, 138.091202, 2.077358}, - {NPC_NECROMANCER, 2258.258057, 1157.250732, 138.272873, 2.387766}, - {0, 0, 0, 0, 0} - }, - { - {NPC_STALKER, 2348.120117, 1202.302490, 130.491104, 4.698538}, - {NPC_GHOUL, 2352.863525, 1207.819092, 130.424271, 4.949865}, - {NPC_GHOUL, 2343.593750, 1207.915039, 130.781311, 4.321547}, - {NPC_NECROMANCER, 2348.257324, 1212.202515, 130.670135, 4.450352}, - {0, 0, 0, 0, 0} - }, - { - {NPC_STALKER, 2139.825195, 1356.277100, 132.199615, 5.820131}, - {NPC_GHOUL, 2137.073486, 1362.464844, 132.271637, 5.820131}, - {NPC_GHOUL, 2134.075684, 1354.148071, 131.885864, 5.820131}, - {NPC_NECROMANCER, 2133.302246, 1358.907837, 132.037689, 5.820131}, - {0, 0, 0, 0, 0} - }, - { - {NPC_NECROMANCER, 2264.013428, 1174.055908, 138.093094, 2.860481}, - {NPC_GHOUL, 2264.207764, 1170.892700, 138.034973, 2.860481}, - {NPC_GHOUL, 2266.948975, 1176.898926, 137.976929, 2.860481}, - {NPC_STALKER, 2269.215576, 1170.109253, 137.742691, 2.860481}, - {NPC_FIEND, 2273.106689, 1176.101074, 137.880508, 2.860481} - }, - { - {NPC_GOLEM, 2349.701660, 1188.436646, 130.428864, 3.908642}, - {NPC_GHOUL, 2349.909180, 1194.582642, 130.417816, 3.577001}, - {NPC_EGHOUL, 2354.662598, 1185.692017, 130.552032, 3.577001}, - {NPC_EGHOUL, 2354.716797, 1191.614380, 130.539810, 3.577001}, - {0, 0, 0, 0, 0} - }, - { - {NPC_CONSTRUCT, 2145.212891, 1355.288086, 132.288773, 6.004838}, - {NPC_NECROMANCER, 2137.078613, 1357.612671, 132.173340, 6.004838}, - {NPC_EGHOUL, 2139.402100, 1352.541626, 132.127518, 5.812850}, - {NPC_EGHOUL, 2142.408447, 1360.760620, 132.321564, 5.812850}, - {0, 0, 0, 0, 0} - }, - { - {NPC_GHOUL, 2172.686279, 1259.618164, 134.391754, 1.865499}, - {NPC_FIEND, 2177.649170, 1256.061157, 135.096512, 1.849572}, - {NPC_CONSTRUCT, 2170.782959, 1253.594849, 134.973022, 1.849572}, - {NPC_NECROMANCER, 2175.595703, 1249.041992, 135.603531, 1.849572}, - {0, 0, 0, 0, 0} - } -}; - -// Locations for rifts to spawn and draconians to go -float RiftAndSpawnsLocations[ENCOUNTER_CHRONO_SPAWNS][5]= -{ - {NPC_TIME_RIFT, 2431.790039, 1190.670044, 148.076004, 0.187923}, - {NPC_INFINITE_ADVERSARY, 2433.857910, 1185.612061, 148.075974, 4.566168}, - {NPC_INFINITE_ADVERSARY, 2437.577881, 1188.241089, 148.075974, 0.196999}, - {NPC_INFINITE_AGENT, 2437.165527, 1192.294922, 148.075974, 0.169247}, - {NPC_INFINITE_HUNTER, 2434.989990, 1197.679565, 148.075974, 0.715971}, - {NPC_TIME_RIFT, 2403.954834, 1178.815430, 148.075943, 4.966126}, - {NPC_INFINITE_AGENT, 2403.676758, 1171.495850, 148.075607, 4.902797}, - {NPC_INFINITE_HUNTER, 2407.691162, 1172.162720, 148.075607, 4.963010}, - {NPC_TIME_RIFT, 2414.217041, 1133.446167, 148.076050, 1.706972}, - {NPC_INFINITE_ADVERSARY, 2416.024658, 1139.456177, 148.076431, 1.752129}, - {NPC_INFINITE_HUNTER, 2410.866699, 1139.680542, 148.076431, 1.752129}, - {NPC_TIME_RIFT, 2433.081543, 1099.869751, 148.076157, 1.809509}, - {NPC_INFINITE_ADVERSARY, 2426.947998, 1107.471680, 148.076019, 1.877580}, - {NPC_INFINITE_HUNTER, 2432.944580, 1108.896362, 148.208160, 2.199241}, - {NPC_TIME_RIFT, 2444.077637, 1114.366089, 148.076157, 3.049565}, - {NPC_INFINITE_ADVERSARY, 2438.190674, 1118.368164, 148.076172, 3.139232}, - {NPC_INFINITE_AGENT, 2435.861328, 1113.402954, 148.169327, 2.390271}, - {NPC_TIME_RIFT, 2463.131592, 1115.391724, 152.473129, 3.409651}, - {NPC_EPOCH, 2451.809326, 1112.901245, 149.220459, 3.363617} -}; - -struct npc_arthasAI : public npc_escortAI -{ - npc_arthasAI(Creature *pCreature) : npc_escortAI(pCreature) - { - pInstance = pCreature->GetInstanceData(); - Reset(); - } - - ScriptedInstance* pInstance; - - bool bStepping; - uint32 uiStep; - uint32 uiPhaseTimer; - uint32 uiGossipStep; - uint32 uiPlayerFaction; - uint32 uiBossEvent; - uint32 uiWave; - - uint64 uiUtherGUID; - uint64 uiJainaGUID; - uint64 uiCitymenGUID[2]; - uint64 uiWaveGUID[ENCOUNTER_WAVES_MAX_SPAWNS]; - uint64 uiInfiniteDraconianGUID[ENCOUNTER_DRACONIAN_NUMBER]; - uint64 uiStalkerGUID; - - uint64 uiBossGUID; //uiMeathookGUID || uiSalrammGUID - uint64 uiEpochGUID; - uint64 uiMalganisGUID; - uint64 uiInfiniteGUID; - - uint32 uiExorcismTimer; - - void Reset() - { - uiUtherGUID = 0; - uiJainaGUID = 0; - - for (uint8 i = 0; i < 2; ++i) - uiCitymenGUID[i] = 0; - - for (uint8 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i) - uiWaveGUID[i] = 0; - - for (uint8 i = 0; i < ENCOUNTER_DRACONIAN_NUMBER; ++i) - uiInfiniteDraconianGUID[i] = 0; - - uiStalkerGUID = 0; - uiBossGUID = 0; - uiEpochGUID = 0; - uiMalganisGUID = 0; - uiInfiniteGUID = 0; - - if (pInstance) { - pInstance->SetData(DATA_ARTHAS_EVENT, NOT_STARTED); - switch(pInstance->GetData(DATA_ARTHAS_EVENT)) - { - case NOT_STARTED: - bStepping = true; - uiStep = 0; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - uiBossEvent = DATA_MEATHOOK_EVENT; - uiGossipStep = 0; - break; - } - uiPhaseTimer = 1000; - uiExorcismTimer = 7300; - uiWave = 0; - } - } - - void EnterCombat(Unit* /*who*/) - { - DoCast(me, SPELL_ARTHAS_AURA); - } - - void JustDied(Unit * /*killer*/) - { - if (pInstance) - pInstance->SetData(DATA_ARTHAS_EVENT, FAIL); - } - - void SpawnTimeRift(uint32 timeRiftID, uint64* guidVector) - { - me->SummonCreature((uint32)RiftAndSpawnsLocations[timeRiftID][0],RiftAndSpawnsLocations[timeRiftID][1],RiftAndSpawnsLocations[timeRiftID][2],RiftAndSpawnsLocations[timeRiftID][3],RiftAndSpawnsLocations[timeRiftID][4],TEMPSUMMON_TIMED_DESPAWN,11000); - - for (uint32 i = timeRiftID+1; i < ENCOUNTER_CHRONO_SPAWNS; ++i) - { - if ((uint32)RiftAndSpawnsLocations[i][0] == NPC_TIME_RIFT) break; - if (Creature* pTemp = me->SummonCreature((uint32)RiftAndSpawnsLocations[i][0],RiftAndSpawnsLocations[timeRiftID][1],RiftAndSpawnsLocations[timeRiftID][2],RiftAndSpawnsLocations[timeRiftID][3],RiftAndSpawnsLocations[timeRiftID][4],TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) - { - guidVector[i-timeRiftID-1] = pTemp->GetGUID(); - pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); - pTemp->SetReactState(REACT_PASSIVE); - pTemp->GetMotionMaster()->MovePoint(0, RiftAndSpawnsLocations[i][1],RiftAndSpawnsLocations[i][2],RiftAndSpawnsLocations[i][3]); - if ((uint32)RiftAndSpawnsLocations[i][0] == NPC_EPOCH) - uiEpochGUID = pTemp->GetGUID(); - } - } - } - - void SpawnWaveGroup(uint32 waveID, uint64* guidVector) - { - for (uint32 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i) - { - if ((uint32)WavesLocations[waveID][i][0] == 0) break; - if (Creature* pTemp = me->SummonCreature((uint32)WavesLocations[waveID][i][0],WavesLocations[waveID][i][1],WavesLocations[waveID][i][2],WavesLocations[waveID][i][3],WavesLocations[waveID][i][4],TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) - { - guidVector[i] = pTemp->GetGUID(); - } - } - } - - void SetHoldState(bool bOnHold) - { - SetEscortPaused(bOnHold); - } - - void JumpToNextStep(uint32 uiTimer) - { - uiPhaseTimer = uiTimer; - ++uiStep; - } - - void WaypointReached(uint32 uiPointId) - { - switch(uiPointId) - { - case 0: - case 1: - case 3: - case 9: - case 10: - case 11: - case 22: - case 23: - case 26: - case 55: - case 56: - SetHoldState(true); - bStepping = true; - break; - case 7: - if (Unit* pCityman0 = me->SummonCreature(NPC_CITY_MAN,2091.977f,1275.021f,140.757f,0.558f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,60000)) - uiCitymenGUID[0] = pCityman0->GetGUID(); - if (Unit* pCityman1 = me->SummonCreature(NPC_CITY_MAN2,2093.514f,1275.842f,140.408f,3.801f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,60000)) - uiCitymenGUID[1] = pCityman1->GetGUID(); - break; - case 8: - uiGossipStep = 1; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SetHoldState(true); - break; - case 12: - SetRun(true); - DoScriptText(SAY_PHASE210, me); - if (Unit* pDisguised0 = me->SummonCreature(NPC_CITY_MAN3,2398.14f,1207.81f,134.04f,5.155249f,TEMPSUMMON_DEAD_DESPAWN,180000)) - { - uiInfiniteDraconianGUID[0] = pDisguised0->GetGUID(); - if (Unit* pDisguised1 = me->SummonCreature(NPC_CITY_MAN4,2403.22f,1205.54f,134.04f,3.311264f,TEMPSUMMON_DEAD_DESPAWN,180000)) - { - uiInfiniteDraconianGUID[1] = pDisguised1->GetGUID(); - - if (Unit* pDisguised2 = me->SummonCreature(NPC_CITY_MAN,2400.82f,1201.69f,134.01f,1.534082f,TEMPSUMMON_DEAD_DESPAWN,180000)) - { - uiInfiniteDraconianGUID[2] = pDisguised2->GetGUID(); - pDisguised0->SetUInt64Value(UNIT_FIELD_TARGET, uiInfiniteDraconianGUID[1]); - pDisguised1->SetUInt64Value(UNIT_FIELD_TARGET, uiInfiniteDraconianGUID[0]); - pDisguised2->SetUInt64Value(UNIT_FIELD_TARGET, uiInfiniteDraconianGUID[1]); - } - } - } - break; - case 20: - uiGossipStep = 2; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SetRun(false); - SetHoldState(true); - break; - case 21: - DoScriptText(SAY_PHASE301, me); - break; - case 25: - SetRun(false); - SpawnTimeRift(0,&uiInfiniteDraconianGUID[0]); - DoScriptText(SAY_PHASE307,me); - break; - case 29: - SetRun(false); - SpawnTimeRift(5,&uiInfiniteDraconianGUID[0]); - SpawnTimeRift(8,&uiInfiniteDraconianGUID[2]); - DoScriptText(SAY_PHASE309,me); - SetHoldState(true); - bStepping = true; - break; - case 31: - SetRun(false); - SpawnTimeRift(11,&uiInfiniteDraconianGUID[0]); - SpawnTimeRift(14,&uiInfiniteDraconianGUID[2]); - DoScriptText(SAY_PHASE311,me); - SetHoldState(true); - bStepping = true; - break; - case 32: - DoScriptText(SAY_PHASE401,me); - break; - case 34: - DoScriptText(SAY_PHASE402,me); - break; - case 35: - DoScriptText(SAY_PHASE403,me); - break; - case 36: - if (pInstance) - { - GameObject* pGate = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_SHKAF_GATE)); - pGate->SetGoState(GO_STATE_ACTIVE); - } - break; - case 45: - SetRun(true); - SetDespawnAtFar(false); - uiGossipStep = 4; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SetHoldState(true); - break; - case 47: - SetRun(false); - DoScriptText(SAY_PHASE405,me); - break; - case 48: - SetRun(true); - DoScriptText(SAY_PHASE406,me); - break; - case 53: - DoScriptText(SAY_PHASE407,me); - break; - case 54: - uiGossipStep = 5; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SetHoldState(true); - break; - } - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - - DoMeleeAttackIfReady(); - - if (bStepping) - { - if (uiPhaseTimer <= diff) - { - switch(uiStep) - { - //After reset - case 0: - if (Unit* pJaina = GetClosestCreatureWithEntry(me, NPC_JAINA, 50.0f)) - uiJainaGUID = pJaina->GetGUID(); - else if (Unit* pJaina = me->SummonCreature(NPC_JAINA,1895.48f,1292.66f,143.706f,0.023475f,TEMPSUMMON_DEAD_DESPAWN,180000)) - uiJainaGUID = pJaina->GetGUID(); - bStepping = false; - JumpToNextStep(0); - break; - //After waypoint 0 - case 1: - me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - if (Unit* pUther = me->SummonCreature(NPC_UTHER,1794.357f,1272.183f,140.558f,1.37f,TEMPSUMMON_DEAD_DESPAWN,180000)) - { - uiUtherGUID = pUther->GetGUID(); - pUther->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - pUther->GetMotionMaster()->MovePoint(0, 1897.018f, 1287.487f, 143.481f); - pUther->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiUtherGUID); - } - JumpToNextStep(17000); - break; - case 2: - DoScriptText(SAY_PHASE101, me); - JumpToNextStep(2000); - break; - case 3: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - { - DoScriptText(SAY_PHASE102, pUther); - } - JumpToNextStep(8000); - break; - case 4: - SetEscortPaused(false); - bStepping = false; - SetRun(false); - DoScriptText(SAY_PHASE103, me); - JumpToNextStep(0); - break; - //After waypoint 1 - case 5: - if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) - pJaina->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - DoScriptText(SAY_PHASE104, me); - JumpToNextStep(10000); - break; - case 6: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - DoScriptText(SAY_PHASE105, pUther); - JumpToNextStep(1000); - break; - case 7: - DoScriptText(SAY_PHASE106, me); - JumpToNextStep(4000); - break; - case 8: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - DoScriptText(SAY_PHASE107, pUther); - JumpToNextStep(6000); - break; - case 9: - DoScriptText(SAY_PHASE108, me); - JumpToNextStep(4000); - break; - case 10: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - DoScriptText(SAY_PHASE109, pUther); - JumpToNextStep(8000); - break; - case 11: - DoScriptText(SAY_PHASE110, me); - JumpToNextStep(4000); - break; - case 12: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - DoScriptText(SAY_PHASE111, pUther); - JumpToNextStep(4000); - break; - case 13: - DoScriptText(SAY_PHASE112, me); - JumpToNextStep(11000); - break; - case 14: - if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) - DoScriptText(SAY_PHASE113, pJaina); - JumpToNextStep(3000); - break; - case 15: - DoScriptText(SAY_PHASE114, me); - JumpToNextStep(9000); - break; - case 16: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - DoScriptText(SAY_PHASE115, pUther); - JumpToNextStep(4000); - break; - case 17: - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - { - pUther->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - pUther->GetMotionMaster()->MovePoint(0, 1794.357f,1272.183f,140.558f); - } - JumpToNextStep(1000); - break; - case 18: - if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) - { - me->SetUInt64Value(UNIT_FIELD_TARGET, uiJainaGUID); - pJaina->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - pJaina->GetMotionMaster()->MovePoint(0, 1794.357f,1272.183f,140.558f); - } - JumpToNextStep(1000); - break; - case 19: - DoScriptText(SAY_PHASE116, me); - JumpToNextStep(1000); - break; - case 20: - if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) - DoScriptText(SAY_PHASE117, pJaina); - JumpToNextStep(3000); - break; - case 21: - SetEscortPaused(false); - bStepping = false; - me->SetUInt64Value(UNIT_FIELD_TARGET, 0); - JumpToNextStep(0); - break; - //After waypoint 3 - case 22: - DoScriptText(SAY_PHASE118, me); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiJainaGUID); - JumpToNextStep(10000); - break; - case 23: - SetEscortPaused(false); - bStepping = false; - SetRun(true); - - if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID)) - pJaina->DisappearAndDie(); - - if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID)) - pUther->DisappearAndDie(); - - me->SetUInt64Value(UNIT_FIELD_TARGET, 0); - JumpToNextStep(0); - break; - //After Gossip 1 (waypoint 8) - case 24: - if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET,2026.469f,1287.088f,143.596f,1.37f,TEMPSUMMON_TIMED_DESPAWN,14000)) - { - uiStalkerGUID = pStalker->GetGUID(); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); - } - JumpToNextStep(1000); - break; - case 25: - DoScriptText(SAY_PHASE201, me); - JumpToNextStep(12000); - break; - case 26: - SetEscortPaused(false); - bStepping = false; - SetRun(false); - me->SetUInt64Value(UNIT_FIELD_TARGET, 0); - JumpToNextStep(0); - break; - //After waypoint 9 - case 27: - me->SetUInt64Value(UNIT_FIELD_TARGET, uiCitymenGUID[0]); - if (Creature* pCityman = Unit::GetCreature(*me, uiCitymenGUID[0])) - { - pCityman->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - pCityman->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - pCityman->GetMotionMaster()->MovePoint(0, 2088.625f,1279.191f,140.743f); - } - JumpToNextStep(2000); - break; - case 28: - if (Creature* pCityman = Unit::GetCreature(*me, uiCitymenGUID[0])) - DoScriptText(SAY_PHASE202, pCityman); - JumpToNextStep(4000); - break; - case 29: - SetEscortPaused(false); - bStepping = false; - DoScriptText(SAY_PHASE203, me); - JumpToNextStep(0); - break; - //After waypoint 10 - case 30: - me->HandleEmoteCommand(37); - JumpToNextStep(1000); - break; - case 31: - SetEscortPaused(false); - bStepping = false; - if (Creature* pCityman1 = Unit::GetCreature(*me, uiCitymenGUID[1])) - { - DoScriptText(SAY_PHASE204, pCityman1); - pCityman1->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - if (Creature* pCityman0 = Unit::GetCreature(*me, uiCitymenGUID[0])) - pCityman0->Kill(pCityman0); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiCitymenGUID[1]); - } - JumpToNextStep(0); - break; - //After waypoint 11 - case 32: - me->HandleEmoteCommand(37); - JumpToNextStep(1000); - break; - case 33: - if (Creature* pCityman1 = Unit::GetCreature(*me, uiCitymenGUID[1])) - pCityman1->Kill(pCityman1); - JumpToNextStep(1000); - break; - case 34: - if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET,2081.447f,1287.770f,141.3241f,1.37f,TEMPSUMMON_TIMED_DESPAWN,10000)) - { - uiStalkerGUID = pStalker->GetGUID(); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); - } - DoScriptText(SAY_PHASE205, me); - JumpToNextStep(3000); - break; - case 35: - if (Unit* pStalkerM = me->SummonCreature(NPC_INVIS_TARGET,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,60000)) - { - uiStalkerGUID = pStalkerM->GetGUID(); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); - } - JumpToNextStep(1000); - break; - case 36: - if (Creature* pMalganis = me->SummonCreature(NPC_MAL_GANIS,2117.349f,1288.624f,136.271f,1.37f,TEMPSUMMON_TIMED_DESPAWN,60000)) - { - if (Creature* pStalkerM = Unit::GetCreature(*me, uiStalkerGUID)) - pMalganis->CastSpell(pStalkerM,63793,false); - - uiMalganisGUID = pMalganis->GetGUID(); - DoScriptText(SAY_PHASE206, pMalganis); - pMalganis->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - pMalganis->SetReactState(REACT_PASSIVE); - } - JumpToNextStep(11000); - break; - case 37: - if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) - { - if (Creature* pZombie = GetClosestCreatureWithEntry(pMalganis, NPC_CITY_MAN, 100.0f)) - pZombie->UpdateEntry(NPC_ZOMBIE, 0); - else if (Creature* pZombie = GetClosestCreatureWithEntry(pMalganis, NPC_CITY_MAN2, 100.0f)) - pZombie->UpdateEntry(NPC_ZOMBIE, 0); - else //There's no one else to transform - uiStep++; - } - else - uiStep++; - uiPhaseTimer = 500; - break; - case 38: - if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) - DoScriptText(SAY_PHASE207, pMalganis); - JumpToNextStep(17000); - break; - case 39: - if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) - pMalganis->SetVisibility(VISIBILITY_OFF); - DoScriptText(SAY_PHASE208, me); - JumpToNextStep(7000); - break; - case 40: - if (Unit* pStalker = me->SummonCreature(NPC_INVIS_TARGET,2081.447f,1287.770f,141.3241f,1.37f,TEMPSUMMON_TIMED_DESPAWN,10000)) - { - uiStalkerGUID = pStalker->GetGUID(); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiStalkerGUID); - } - DoScriptText(SAY_PHASE209, me); - - uiBossEvent = DATA_MEATHOOK_EVENT; - if (pInstance) - pInstance->SetData(DATA_ARTHAS_EVENT, IN_PROGRESS); - - me->SetReactState(REACT_DEFENSIVE); - SetDespawnAtFar(false); - JumpToNextStep(5000); - break; - case 41: //Summon wave group - case 43: - case 45: - case 47: - case 51: - case 53: - case 55: - case 57: - if (pInstance->GetData(uiBossEvent) != DONE) - { - SpawnWaveGroup(uiWave, uiWaveGUID); - uiWave++; - } - JumpToNextStep(500); - break; - case 42: //Wait group to die - case 44: - case 46: - case 48: - case 52: - case 54: - case 56: - case 58: - if (pInstance->GetData(uiBossEvent) != DONE) - { - uint32 mobCounter = 0; - uint32 deadCounter = 0; - for (uint8 i = 0; i < ENCOUNTER_WAVES_MAX_SPAWNS; ++i) - { - if (uiWaveGUID[i] == 0) - break; - ++mobCounter; - Unit* pTemp = Unit::GetCreature(*me, uiWaveGUID[i]); - if (!pTemp || pTemp->isDead()) - ++deadCounter; - } - - if (mobCounter <= deadCounter) //If group is dead - JumpToNextStep(1000); - else - uiPhaseTimer = 1000; - } - else - JumpToNextStep(500); - break; - case 49: //Summon Boss - case 59: - if (pInstance->GetData(uiBossEvent) != DONE) - { - uint32 uiBossID = 0; - if (uiBossEvent == DATA_MEATHOOK_EVENT) - uiBossID = NPC_MEATHOOK; - else if (uiBossEvent == DATA_SALRAMM_EVENT) - uiBossID = NPC_SALRAMM; - - if (Unit* pBoss = me->SummonCreature(uiBossID,2232.19f,1331.933f,126.662f,3.15f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) - { - uiBossGUID = pBoss->GetGUID(); - pBoss->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - pBoss->GetMotionMaster()->MovePoint(0, 2194.110f,1332.00f,130.00f); - } - } - JumpToNextStep(30000); - break; - case 50: //Wait Boss death - case 60: - if (pInstance) - { - if (pInstance->GetData(uiBossEvent) == DONE) - { - JumpToNextStep(1000); - if (uiBossEvent == DATA_MEATHOOK_EVENT) - uiBossEvent = DATA_SALRAMM_EVENT; - else if (uiBossEvent == DATA_SALRAMM_EVENT) - { - SetHoldState(false); - bStepping = false; - uiBossEvent = DATA_EPOCH_EVENT; - } - } - else if (pInstance->GetData(uiBossEvent) == FAIL) - npc_escortAI::EnterEvadeMode(); - else - uiPhaseTimer = 10000; - } - break; - //After Gossip 2 (waypoint 22) - case 61: - me->SetReactState(REACT_AGGRESSIVE); - if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) - pDisguised0->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - if (Creature* pDisguised1 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[1])) - pDisguised1->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - if (Creature* pDisguised2 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[2])) - pDisguised2->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID()); - JumpToNextStep(1000); - break; - case 62: - if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) - DoScriptText(SAY_PHASE302, pDisguised0); - JumpToNextStep(7000); - break; - case 63: - DoScriptText(SAY_PHASE303, me); - SetHoldState(false); - bStepping = false; - JumpToNextStep(0); - break; - //After waypoint 23 - case 64: - me->HandleEmoteCommand(54); - JumpToNextStep(1000); - break; - case 65: - if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) - pDisguised0->HandleEmoteCommand(11); - JumpToNextStep(1000); - break; - case 66: - DoScriptText(SAY_PHASE304,me); - JumpToNextStep(2000); - break; - case 67: - if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) - DoScriptText(SAY_PHASE305,pDisguised0); - JumpToNextStep(1000); - break; - case 68: - if (Creature* pDisguised2 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[2])) - { - pDisguised2->UpdateEntry(NPC_INFINITE_HUNTER, 0); - //Make them unattackable - pDisguised2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); - pDisguised2->SetReactState(REACT_PASSIVE); - } - JumpToNextStep(2000); - break; - case 69: - if (Creature* pDisguised1 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[1])) - { - pDisguised1->UpdateEntry(NPC_INFINITE_AGENT, 0); - //Make them unattackable - pDisguised1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); - pDisguised1->SetReactState(REACT_PASSIVE); - } - JumpToNextStep(2000); - break; - case 70: - if (Creature* pDisguised0 = Unit::GetCreature(*me, uiInfiniteDraconianGUID[0])) - { - pDisguised0->UpdateEntry(NPC_INFINITE_ADVERSARY, 0); - //Make them unattackable - pDisguised0->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); - pDisguised0->SetReactState(REACT_PASSIVE); - } - JumpToNextStep(2000); - break; - case 71: - //After waypoint 26,29,31 - case 73: - case 75: - case 77: - //Make cratures attackable - for (uint32 i = 0; i< ENCOUNTER_DRACONIAN_NUMBER; ++i) - if (Creature* pTemp = Unit::GetCreature(*me, uiInfiniteDraconianGUID[i])) - { - pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); - pTemp->SetReactState(REACT_AGGRESSIVE); - } - JumpToNextStep(5000); - break; - case 72: - case 74: - case 76: - if (me->isInCombat()) - uiPhaseTimer = 1000; - else - { - if (uiStep == 72) DoScriptText(SAY_PHASE308,me); - if (uiStep == 74) DoScriptText(SAY_PHASE308,me); - if (uiStep == 76) DoScriptText(SAY_PHASE310,me); - SetHoldState(false); - bStepping = false; - SetRun(true); - JumpToNextStep(2000); - } - break; - case 78: - if (me->isInCombat()) - uiPhaseTimer = 1000; - else - { - DoScriptText(SAY_PHASE312,me); - JumpToNextStep(5000); - } - break; - case 79: - DoScriptText(SAY_PHASE313,me); - JumpToNextStep(1000); - break; - case 80: - if (pInstance) - if (pInstance->GetData(DATA_EPOCH_EVENT) != DONE) - { - SpawnTimeRift(17,&uiEpochGUID); - if (Creature* pEpoch = Unit::GetCreature(*me, uiEpochGUID)) - DoScriptText(SAY_PHASE314,pEpoch); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiEpochGUID); - } - JumpToNextStep(18000); - break; - case 81: - if (pInstance) - if (pInstance->GetData(DATA_EPOCH_EVENT) != DONE) - DoScriptText(SAY_PHASE315, me); - JumpToNextStep(6000); - break; - case 82: - if (pInstance) - if (pInstance->GetData(DATA_EPOCH_EVENT) != DONE) - { - if (Creature* pEpoch = Unit::GetCreature(*me, uiEpochGUID)) - { - //Make Epoch attackable - pEpoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_9); - pEpoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - pEpoch->SetReactState(REACT_AGGRESSIVE); - } - - } - JumpToNextStep(1000); - break; - case 83: - if (pInstance) - { - if (pInstance->GetData(DATA_EPOCH_EVENT) == DONE) - { - uiGossipStep = 3; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - bStepping = false; - uiBossEvent = DATA_MAL_GANIS_EVENT; - JumpToNextStep(15000); - } - else if (pInstance->GetData(DATA_EPOCH_EVENT) == FAIL) - npc_escortAI::EnterEvadeMode(); - else - uiPhaseTimer = 10000; - } - break; - //After Gossip 4 - case 84: - DoScriptText(SAY_PHASE404,me); - SetHoldState(false); - bStepping = false; - break; - //After Gossip 5 - case 85: - DoScriptText(SAY_PHASE501, me); - if (Creature* pMalganis = me->SummonCreature(NPC_MAL_GANIS,2296.665f,1502.362f,128.362f,4.961f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,900000)) - { - uiMalganisGUID = pMalganis->GetGUID(); - pMalganis->SetReactState(REACT_PASSIVE); - } - if (pInstance) - { - GameObject* pGate = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_MAL_GANIS_GATE_1)); - pGate->SetGoState(GO_STATE_ACTIVE); - } - SetHoldState(false); - bStepping = false; - JumpToNextStep(0); - break; - //After waypoint 55 - case 86: - DoScriptText(SAY_PHASE502, me); - JumpToNextStep(6000); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiMalganisGUID); - break; - case 87: - if (Creature* pMalganis = Unit::GetCreature(*me, uiMalganisGUID)) - { - pMalganis->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_UNK_6 | UNIT_FLAG_UNK_9 | UNIT_FLAG_UNK_15); - pMalganis->SetReactState(REACT_AGGRESSIVE); - } - JumpToNextStep(1000); - break; - case 88: - if (pInstance) - { - if (pInstance->GetData(DATA_MAL_GANIS_EVENT) == DONE) - { - SetHoldState(false); - JumpToNextStep(1000); - } - else if (pInstance->GetData(DATA_MAL_GANIS_EVENT) == FAIL) - npc_escortAI::EnterEvadeMode(); - else - uiPhaseTimer = 10000; - } - break; - //After waypoint 56 - case 89: - SetRun(true); - me->SetUInt64Value(UNIT_FIELD_TARGET, uiMalganisGUID); - DoScriptText(SAY_PHASE503, me); - JumpToNextStep(7000); - break; - case 90: - if (pInstance) - { - pInstance->SetData(DATA_ARTHAS_EVENT, DONE); //Rewards: Achiev & Chest ;D - me->SetUInt64Value(UNIT_FIELD_TARGET, pInstance->GetData64(DATA_MAL_GANIS_GATE_2)); //Look behind - } - DoScriptText(SAY_PHASE504, me); - bStepping = false; - break; - } - } else uiPhaseTimer -= diff; - } - - //Battling skills - if (!me->getVictim()) - return; - - if (uiExorcismTimer < diff) - { - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(target, SPELL_EXORCISM_N); - uiExorcismTimer = 7300; - } else uiExorcismTimer -= diff; - - if (HealthBelowPct(40)) - DoCast(me, SPELL_HOLY_LIGHT); - } -}; - -CreatureAI* GetAI_npc_arthas(Creature* pCreature) -{ - return new npc_arthasAI(pCreature); -} - -#define GOSSIP_ITEM_ARTHAS_0 "I'm ready to start Culling of Stratholme." -#define GOSSIP_ITEM_ARTHAS_1 "Yes, my Prince. We're ready." -#define GOSSIP_ITEM_ARTHAS_2 "We're only doing what is best for Loarderon your Highness." -#define GOSSIP_ITEM_ARTHAS_3 "I'm ready." -#define GOSSIP_ITEM_ARTHAS_4 "For Lordaeron!" -#define GOSSIP_ITEM_ARTHAS_5 "I'm ready to battle the dreadlord, sire." - -bool GossipHello_npc_arthas(Player* pPlayer, Creature* pCreature) -{ - npc_arthasAI* pAI = CAST_AI(npc_arthasAI,pCreature->AI()); - - if (pAI && pAI->bStepping == false) - { - switch (pAI->uiGossipStep) - { - case 0: //This one is a workaround since the very beggining of the script is wrong. - if (pPlayer->GetQuestStatus(13149) != QUEST_STATUS_COMPLETE) - return false; - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); - break; - case 1: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_1, pCreature->GetGUID()); - break; - case 2: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_2, pCreature->GetGUID()); - break; - case 3: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_3, pCreature->GetGUID()); - break; - case 4: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_4, pCreature->GetGUID()); - break; - case 5: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ARTHAS_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_MENU_ARTHAS_5, pCreature->GetGUID()); - break; - default: - return false; - } - } - return true; -} - - -bool GossipSelect_npc_arthas(Player *pPlayer, Creature *pCreature, uint32 /*sender*/, uint32 action) -{ - npc_arthasAI* pAI = CAST_AI(npc_arthasAI,pCreature->AI()); - - if (!pAI) - return false; - - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - pAI->Start(true,true,pPlayer->GetGUID(),0,false,false); - pAI->SetDespawnAtEnd(false); - pAI->bStepping = false; - pAI->uiStep = 1; - break; - case GOSSIP_ACTION_INFO_DEF+1: - pAI->bStepping = true; - pAI->uiStep = 24; - break; - case GOSSIP_ACTION_INFO_DEF+2: - pAI->SetHoldState(false); - pAI->bStepping = false; - pAI->uiStep = 61; - break; - case GOSSIP_ACTION_INFO_DEF+3: - pAI->SetHoldState(false); - break; - case GOSSIP_ACTION_INFO_DEF+4: - pAI->bStepping = true; - pAI->uiStep = 84; - break; - case GOSSIP_ACTION_INFO_DEF+5: - pAI->bStepping = true; - pAI->uiStep = 85; - break; - } - pPlayer->CLOSE_GOSSIP_MENU(); - pAI->SetDespawnAtFar(true); - pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - return true; -} - -void AddSC_culling_of_stratholme() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "npc_arthas"; - newscript->GetAI = &GetAI_npc_arthas; - newscript->pGossipHello = &GossipHello_npc_arthas; - newscript->pGossipSelect = &GossipSelect_npc_arthas; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.h b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.h deleted file mode 100644 index 4278ad46500..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/culling_of_stratholme.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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_CULLING_OF_STRATHOLME_H -#define DEF_CULLING_OF_STRATHOLME_H - -enum Data -{ - DATA_MEATHOOK_EVENT, - DATA_SALRAMM_EVENT, - DATA_EPOCH_EVENT, - DATA_MAL_GANIS_EVENT, - DATA_INFINITE_EVENT, - DATA_ARTHAS_EVENT -}; - -enum Data64 -{ - DATA_ARTHAS, - DATA_MEATHOOK, - DATA_SALRAMM, - DATA_EPOCH, - DATA_MAL_GANIS, - DATA_INFINITE, - DATA_SHKAF_GATE, - DATA_MAL_GANIS_GATE_1, - DATA_MAL_GANIS_GATE_2, - DATA_EXIT_GATE, - DATA_MAL_GANIS_CHEST -}; - -enum Creatures -{ - NPC_MEATHOOK = 26529, - NPC_SALRAMM = 26530, - NPC_EPOCH = 26532, - NPC_MAL_GANIS = 26533, - NPC_INFINITE = 32273, - NPC_ARTHAS = 26499, - NPC_JAINA = 26497, - NPC_UTHER = 26528 -}; - -enum GameObjects -{ - GO_SHKAF_GATE = 188686, - GO_MALGANIS_GATE_1 = 187711, - GO_MALGANIS_GATE_2 = 187723, - GO_EXIT_GATE = 191788, - GO_MALGANIS_CHEST_N = 190663, - GO_MALGANIS_CHEST_H = 193597 -}; -#endif diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/instance_culling_of_stratholme.cpp deleted file mode 100644 index 73742a1e748..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/culling_of_stratholme/instance_culling_of_stratholme.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -* Copyright (C) 2008-2010 Trinity -* -* 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 -*/ - -#include "ScriptedPch.h" -#include "culling_of_stratholme.h" - -#define MAX_ENCOUNTER 5 - -/* Culling of Stratholme encounters: -0 - Meathook -1 - Salramm the Fleshcrafter -2 - Chrono-Lord Epoch -3 - Mal'Ganis -4 - Infinite Corruptor (Heroic only) -*/ - -struct instance_culling_of_stratholme : public ScriptedInstance -{ - instance_culling_of_stratholme(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint64 uiArthas; - uint64 uiMeathook; - uint64 uiSalramm; - uint64 uiEpoch; - uint64 uiMalGanis; - uint64 uiInfinite; - - uint64 uiShkafGate; - uint64 uiMalGanisGate1; - uint64 uiMalGanisGate2; - uint64 uiExitGate; - uint64 uiMalGanisChest; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string str_data; - - 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 NPC_ARTHAS: - uiArthas = pCreature->GetGUID(); - break; - case NPC_MEATHOOK: - uiMeathook = pCreature->GetGUID(); - break; - case NPC_SALRAMM: - uiSalramm = pCreature->GetGUID(); - break; - case NPC_EPOCH: - uiEpoch = pCreature->GetGUID(); - break; - case NPC_MAL_GANIS: - uiMalGanis = pCreature->GetGUID(); - break; - case NPC_INFINITE: - uiInfinite = pCreature->GetGUID(); - break; - } - } - - void OnGameObjectCreate(GameObject* pGo, bool /*add*/) - { - switch(pGo->GetEntry()) - { - case GO_SHKAF_GATE: - uiShkafGate = pGo->GetGUID(); - break; - case GO_MALGANIS_GATE_1: - uiMalGanisGate1 = pGo->GetGUID(); - break; - case GO_MALGANIS_GATE_2: - uiMalGanisGate2 = pGo->GetGUID(); - break; - case GO_EXIT_GATE: - uiExitGate = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE) - HandleGameObject(uiExitGate,true); - break; - case GO_MALGANIS_CHEST_N: - case GO_MALGANIS_CHEST_H: - uiMalGanisChest = pGo->GetGUID(); - if (m_auiEncounter[3] == DONE) - pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND); - break; - } - } - - void SetData(uint32 type, uint32 data) - { - switch(type) - { - case DATA_MEATHOOK_EVENT: - m_auiEncounter[0] = data; - break; - case DATA_SALRAMM_EVENT: - m_auiEncounter[1] = data; - break; - case DATA_EPOCH_EVENT: - m_auiEncounter[2] = data; - break; - case DATA_MAL_GANIS_EVENT: - m_auiEncounter[3] = data; - - switch(m_auiEncounter[3]) - { - case NOT_STARTED: - HandleGameObject(uiMalGanisGate2,true); - break; - case IN_PROGRESS: - HandleGameObject(uiMalGanisGate2,false); - break; - case DONE: - HandleGameObject(uiExitGate, true); - if (GameObject *pGo = instance->GetGameObject(uiMalGanisChest)) - pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND); - break; - } - break; - case DATA_INFINITE_EVENT: - m_auiEncounter[4] = data; - break; - } - - if (data == DONE) - SaveToDB(); - } - - uint32 GetData(uint32 type) - { - switch(type) - { - case DATA_MEATHOOK_EVENT: return m_auiEncounter[0]; - case DATA_SALRAMM_EVENT: return m_auiEncounter[1]; - case DATA_EPOCH_EVENT: return m_auiEncounter[2]; - case DATA_MAL_GANIS_EVENT: return m_auiEncounter[3]; - case DATA_INFINITE_EVENT: return m_auiEncounter[4]; - } - return 0; - } - - uint64 GetData64(uint32 identifier) - { - switch(identifier) - { - case DATA_ARTHAS: return uiArthas; - case DATA_MEATHOOK: return uiMeathook; - case DATA_SALRAMM: return uiSalramm; - case DATA_EPOCH: return uiEpoch; - case DATA_MAL_GANIS: return uiMalGanis; - case DATA_INFINITE: return uiInfinite; - case DATA_SHKAF_GATE: return uiShkafGate; - case DATA_MAL_GANIS_GATE_1: return uiMalGanisGate1; - case DATA_MAL_GANIS_GATE_2: return uiMalGanisGate2; - case DATA_EXIT_GATE: return uiExitGate; - case DATA_MAL_GANIS_CHEST: return uiMalGanisChest; - } - return 0; - } - - std::string GetSaveData() - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << "C S " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " - << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4]; - - 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, data4; - - std::istringstream loadStream(in); - loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4; - - if (dataHead1 == 'C' && dataHead2 == 'S') - { - m_auiEncounter[0] = data0; - m_auiEncounter[1] = data1; - m_auiEncounter[2] = data2; - m_auiEncounter[3] = data3; - m_auiEncounter[4] = data4; - - 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_culling_of_stratholme(Map* pMap) -{ - return new instance_culling_of_stratholme(pMap); -} - -void AddSC_instance_culling_of_stratholme() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "instance_culling_of_stratholme"; - newscript->GetInstanceData = &GetInstanceData_instance_culling_of_stratholme; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_aeonus.cpp deleted file mode 100644 index 49cf7cd4433..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_aeonus.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Aeonus -SD%Complete: 80 -SDComment: Some spells not implemented -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptedPch.h" -#include "dark_portal.h" - -enum eEnums -{ - SAY_ENTER = -1269012, - SAY_AGGRO = -1269013, - SAY_BANISH = -1269014, - SAY_SLAY1 = -1269015, - SAY_SLAY2 = -1269016, - SAY_DEATH = -1269017, - EMOTE_FRENZY = -1269018, - - SPELL_CLEAVE = 40504, - SPELL_TIME_STOP = 31422, - SPELL_ENRAGE = 37605, - SPELL_SAND_BREATH = 31473, - H_SPELL_SAND_BREATH = 39049 -}; - -struct boss_aeonusAI : public ScriptedAI -{ - boss_aeonusAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 SandBreath_Timer; - uint32 TimeStop_Timer; - uint32 Frenzy_Timer; - - void Reset() - { - SandBreath_Timer = 15000+rand()%15000; - TimeStop_Timer = 10000+rand()%5000; - Frenzy_Timer = 30000+rand()%15000; - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(SAY_AGGRO, me); - } - - void MoveInLineOfSight(Unit *who) - { - //Despawn Time Keeper - if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == C_TIME_KEEPER) - { - if (me->IsWithinDistInMap(who,20.0f)) - { - DoScriptText(SAY_BANISH, me); - me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance) - { - pInstance->SetData(TYPE_RIFT,DONE); - pInstance->SetData(TYPE_MEDIVH,DONE);//FIXME: later should be removed - } - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Sand Breath - if (SandBreath_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SAND_BREATH); - SandBreath_Timer = 15000+rand()%10000; - } else SandBreath_Timer -= diff; - - //Time Stop - if (TimeStop_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_TIME_STOP); - TimeStop_Timer = 20000+rand()%15000; - } else TimeStop_Timer -= diff; - - //Frenzy - if (Frenzy_Timer <= diff) - { - DoScriptText(EMOTE_FRENZY, me); - DoCast(me, SPELL_ENRAGE); - Frenzy_Timer = 20000+rand()%15000; - } else Frenzy_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_aeonus(Creature* pCreature) -{ - return new boss_aeonusAI (pCreature); -} - -void AddSC_boss_aeonus() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_aeonus"; - newscript->GetAI = &GetAI_boss_aeonus; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_chrono_lord_deja.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_chrono_lord_deja.cpp deleted file mode 100644 index 1f2b4a80612..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_chrono_lord_deja.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Chrono_Lord_Deja -SD%Complete: 65 -SDComment: All abilities not implemented -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptedPch.h" -#include "dark_portal.h" - -enum eEnums -{ - SAY_ENTER = -1269006, - SAY_AGGRO = -1269007, - SAY_BANISH = -1269008, - SAY_SLAY1 = -1269009, - SAY_SLAY2 = -1269010, - SAY_DEATH = -1269011, - - SPELL_ARCANE_BLAST = 31457, - H_SPELL_ARCANE_BLAST = 38538, - SPELL_ARCANE_DISCHARGE = 31472, - H_SPELL_ARCANE_DISCHARGE = 38539, - SPELL_TIME_LAPSE = 31467, - SPELL_ATTRACTION = 38540 //Not Implemented (Heroic mode) -}; - -struct boss_chrono_lord_dejaAI : public ScriptedAI -{ - boss_chrono_lord_dejaAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 ArcaneBlast_Timer; - uint32 TimeLapse_Timer; - uint32 Attraction_Timer; - uint32 ArcaneDischarge_Timer; - - void Reset() - { - ArcaneBlast_Timer = 18000+rand()%5000; - TimeLapse_Timer = 10000+rand()%5000; - ArcaneDischarge_Timer = 20000+rand()%10000; - Attraction_Timer = 25000+rand()%10000; - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(SAY_AGGRO, me); - } - - void MoveInLineOfSight(Unit *who) - { - //Despawn Time Keeper - if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == C_TIME_KEEPER) - { - if (me->IsWithinDistInMap(who,20.0f)) - { - DoScriptText(SAY_BANISH, me); - me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(TYPE_RIFT,SPECIAL); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Arcane Blast - if (ArcaneBlast_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_ARCANE_BLAST); - ArcaneBlast_Timer = 15000+rand()%10000; - } else ArcaneBlast_Timer -= diff; - - //Arcane Discharge - if (ArcaneDischarge_Timer <= diff) - { - Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - DoCast(pTarget, SPELL_ARCANE_DISCHARGE); - ArcaneDischarge_Timer = 20000+rand()%10000; - } else ArcaneDischarge_Timer -= diff; - - //Time Lapse - if (TimeLapse_Timer <= diff) - { - DoScriptText(SAY_BANISH, me); - DoCast(me, SPELL_TIME_LAPSE); - TimeLapse_Timer = 15000+rand()%10000; - } else TimeLapse_Timer -= diff; - - if (IsHeroic()) - { - if (Attraction_Timer <= diff) - { - DoCast(me, SPELL_ATTRACTION); - Attraction_Timer = 25000+rand()%10000; - } else Attraction_Timer -= diff; - } - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_chrono_lord_deja(Creature* pCreature) -{ - return new boss_chrono_lord_dejaAI (pCreature); -} - -void AddSC_boss_chrono_lord_deja() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_chrono_lord_deja"; - newscript->GetAI = &GetAI_boss_chrono_lord_deja; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_temporus.cpp deleted file mode 100644 index 04b4b020ead..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/boss_temporus.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Temporus -SD%Complete: 75 -SDComment: More abilities need to be implemented -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptedPch.h" -#include "dark_portal.h" - -enum eEnums -{ - SAY_ENTER = -1269000, - SAY_AGGRO = -1269001, - SAY_BANISH = -1269002, - SAY_SLAY1 = -1269003, - SAY_SLAY2 = -1269004, - SAY_DEATH = -1269005, - - SPELL_HASTE = 31458, - SPELL_MORTAL_WOUND = 31464, - SPELL_WING_BUFFET = 31475, - H_SPELL_WING_BUFFET = 38593, - SPELL_REFLECT = 38592 //Not Implemented (Heroic mod) -}; - -struct boss_temporusAI : public ScriptedAI -{ - boss_temporusAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 Haste_Timer; - uint32 SpellReflection_Timer; - uint32 MortalWound_Timer; - uint32 WingBuffet_Timer; - - void Reset() - { - Haste_Timer = 15000+rand()%8000; - SpellReflection_Timer = 30000; - MortalWound_Timer = 8000; - WingBuffet_Timer = 25000+rand()%10000; - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(SAY_AGGRO, me); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(TYPE_RIFT,SPECIAL); - } - - void MoveInLineOfSight(Unit *who) - { - //Despawn Time Keeper - if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == C_TIME_KEEPER) - { - if (me->IsWithinDistInMap(who,20.0f)) - { - DoScriptText(SAY_BANISH, me); - - me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Attack Haste - if (Haste_Timer <= diff) - { - DoCast(me, SPELL_HASTE); - Haste_Timer = 20000+rand()%5000; - } else Haste_Timer -= diff; - - //MortalWound_Timer - if (MortalWound_Timer <= diff) - { - DoCast(me, SPELL_MORTAL_WOUND); - MortalWound_Timer = 10000+rand()%10000; - } else MortalWound_Timer -= diff; - - //Wing ruffet - if (WingBuffet_Timer <= diff) - { - DoCast(me, SPELL_WING_BUFFET); - WingBuffet_Timer = 20000+rand()%10000; - } else WingBuffet_Timer -= diff; - - if (IsHeroic()) - { - if (SpellReflection_Timer <= diff) - { - DoCast(me, SPELL_REFLECT); - SpellReflection_Timer = 25000+rand()%10000; - } else SpellReflection_Timer -= diff; - } - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_temporus(Creature* pCreature) -{ - return new boss_temporusAI (pCreature); -} - -void AddSC_boss_temporus() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_temporus"; - newscript->GetAI = &GetAI_boss_temporus; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.cpp deleted file mode 100644 index b0432a9b57c..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 -* 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: Dark_Portal -SD%Complete: 30 -SDComment: Misc NPC's and mobs for instance. Most here far from complete. -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -/* ContentData -npc_medivh_bm -npc_time_rift -npc_saat -EndContentData */ - -#include "ScriptedPch.h" -#include "dark_portal.h" - -#define SAY_ENTER -1269020 //where does this belong? -#define SAY_INTRO -1269021 -#define SAY_WEAK75 -1269022 -#define SAY_WEAK50 -1269023 -#define SAY_WEAK25 -1269024 -#define SAY_DEATH -1269025 -#define SAY_WIN -1269026 -#define SAY_ORCS_ENTER -1269027 -#define SAY_ORCS_ANSWER -1269028 - -#define SPELL_CHANNEL 31556 -#define SPELL_PORTAL_RUNE 32570 //aura(portal on ground effect) - -#define SPELL_BLACK_CRYSTAL 32563 //aura -#define SPELL_PORTAL_CRYSTAL 32564 //summon - -#define SPELL_BANISH_PURPLE 32566 //aura -#define SPELL_BANISH_GREEN 32567 //aura - -#define SPELL_CORRUPT 31326 -#define SPELL_CORRUPT_AEONUS 37853 - -#define C_COUNCIL_ENFORCER 17023 - -struct npc_medivh_bmAI : public ScriptedAI -{ - npc_medivh_bmAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 SpellCorrupt_Timer; - uint32 Check_Timer; - - bool Life75; - bool Life50; - bool Life25; - - void Reset() - { - SpellCorrupt_Timer = 0; - - if (!pInstance) - return; - - if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS) - DoCast(me, SPELL_CHANNEL, true); - else if (me->HasAura(SPELL_CHANNEL)) - me->RemoveAura(SPELL_CHANNEL); - - DoCast(me, SPELL_PORTAL_RUNE, true); - } - - void MoveInLineOfSight(Unit *who) - { - if (!pInstance) - return; - - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 10.0f)) - { - if (pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS || pInstance->GetData(TYPE_MEDIVH) == DONE) - return; - - DoScriptText(SAY_INTRO, me); - pInstance->SetData(TYPE_MEDIVH,IN_PROGRESS); - DoCast(me, SPELL_CHANNEL, false); - Check_Timer = 5000; - } - else if (who->GetTypeId() == TYPEID_UNIT && me->IsWithinDistInMap(who, 15.0f)) - { - if (pInstance->GetData(TYPE_MEDIVH) != IN_PROGRESS) - return; - - uint32 entry = who->GetEntry(); - if (entry == C_ASSAS || entry == C_WHELP || entry == C_CHRON || entry == C_EXECU || entry == C_VANQU) - { - who->StopMoving(); - who->CastSpell(me,SPELL_CORRUPT,false); - } - else if (entry == C_AEONUS) - { - who->StopMoving(); - who->CastSpell(me,SPELL_CORRUPT_AEONUS,false); - } - } - } - - void AttackStart(Unit * /*who*/) - { - //if (pInstance && pInstance->GetData(TYPE_MEDIVH) == IN_PROGRESS) - //return; - - //ScriptedAI::AttackStart(who); - } - - void EnterCombat(Unit * /*who*/) {} - - void SpellHit(Unit* /*caster*/, const SpellEntry* spell) - { - if (SpellCorrupt_Timer) - return; - - if (spell->Id == SPELL_CORRUPT_AEONUS) - SpellCorrupt_Timer = 1000; - - if (spell->Id == SPELL_CORRUPT) - SpellCorrupt_Timer = 3000; - } - - void JustDied(Unit* Killer) - { - if (Killer->GetEntry() == me->GetEntry()) - return; - - DoScriptText(SAY_DEATH, me); - } - - void UpdateAI(const uint32 diff) - { - if (!pInstance) - return; - - if (SpellCorrupt_Timer) - { - if (SpellCorrupt_Timer <= diff) - { - pInstance->SetData(TYPE_MEDIVH,SPECIAL); - - if (me->HasAura(SPELL_CORRUPT_AEONUS)) - SpellCorrupt_Timer = 1000; - else if (me->HasAura(SPELL_CORRUPT)) - SpellCorrupt_Timer = 3000; - else - SpellCorrupt_Timer = 0; - } else SpellCorrupt_Timer -= diff; - } - - if (Check_Timer) - { - if (Check_Timer <= diff) - { - uint32 pct = pInstance->GetData(DATA_SHIELD); - - Check_Timer = 5000; - - if (Life25 && pct <= 25) - { - DoScriptText(SAY_WEAK25, me); - Life25 = false; - } - else if (Life50 && pct <= 50) - { - DoScriptText(SAY_WEAK50, me); - Life50 = false; - } - else if (Life75 && pct <= 75) - { - DoScriptText(SAY_WEAK75, me); - Life75 = false; - } - - //if we reach this it means event was running but at some point reset. - if (pInstance->GetData(TYPE_MEDIVH) == NOT_STARTED) - { - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - me->RemoveCorpse(); - me->Respawn(); - return; - } - - if (pInstance->GetData(TYPE_RIFT) == DONE) - { - DoScriptText(SAY_WIN, me); - Check_Timer = 0; - - if (me->HasAura(SPELL_CHANNEL)) - me->RemoveAura(SPELL_CHANNEL); - - //TODO: start the post-event here - pInstance->SetData(TYPE_MEDIVH,DONE); - } - } else Check_Timer -= diff; - } - - //if (!UpdateVictim()) - //return; - - //DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_npc_medivh_bm(Creature* pCreature) -{ - return new npc_medivh_bmAI (pCreature); -} - -struct Wave -{ - uint32 PortalMob[4]; //spawns for portal waves (in order) -}; - -static Wave PortalWaves[]= -{ - {C_ASSAS, C_WHELP, C_CHRON, 0}, - {C_EXECU, C_CHRON, C_WHELP, C_ASSAS}, - {C_EXECU, C_VANQU, C_CHRON, C_ASSAS} -}; - -struct npc_time_riftAI : public ScriptedAI -{ - npc_time_riftAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 TimeRiftWave_Timer; - uint8 mRiftWaveCount; - uint8 mPortalCount; - uint8 mWaveId; - - void Reset() - { - - TimeRiftWave_Timer = 15000; - mRiftWaveCount = 0; - - if (!pInstance) - return; - - mPortalCount = pInstance->GetData(DATA_PORTAL_COUNT); - - if (mPortalCount < 6) - mWaveId = 0; - else if (mPortalCount > 12) - mWaveId = 2; - else mWaveId = 1; - - } - void EnterCombat(Unit * /*who*/) {} - - void DoSummonAtRift(uint32 creature_entry) - { - if (!creature_entry) - return; - - if (pInstance && pInstance->GetData(TYPE_MEDIVH) != IN_PROGRESS) - { - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - return; - } - - Position pos; - me->GetRandomNearPosition(pos, 10.0f); - - //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); - - if (Unit *Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) - if (Unit *temp = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_MEDIVH) : 0)) - Summon->AddThreat(temp,0.0f); - } - - void DoSelectSummon() - { - uint32 entry = 0; - - if ((mRiftWaveCount > 2 && mWaveId < 1) || mRiftWaveCount > 3) - mRiftWaveCount = 0; - - entry = PortalWaves[mWaveId].PortalMob[mRiftWaveCount]; - debug_log("TSCR: npc_time_rift: summoning wave Creature (Wave %u, Entry %u).",mRiftWaveCount,entry); - - ++mRiftWaveCount; - - if (entry == C_WHELP) - { - for (uint8 i = 0; i < 3; ++i) - DoSummonAtRift(entry); - } else DoSummonAtRift(entry); - } - - void UpdateAI(const uint32 diff) - { - if (!pInstance) - return; - - if (TimeRiftWave_Timer <= diff) - { - DoSelectSummon(); - TimeRiftWave_Timer = 15000; - } else TimeRiftWave_Timer -= diff; - - if (me->IsNonMeleeSpellCasted(false)) - return; - - debug_log("TSCR: npc_time_rift: not casting anylonger, i need to die."); - me->setDeathState(JUST_DIED); - - if (pInstance->GetData(TYPE_RIFT) == IN_PROGRESS) - pInstance->SetData(TYPE_RIFT,SPECIAL); - } -}; - -CreatureAI* GetAI_npc_time_rift(Creature* pCreature) -{ - return new npc_time_riftAI (pCreature); -} - -#define SAY_SAAT_WELCOME -1269019 - -#define GOSSIP_ITEM_OBTAIN "[PH] Obtain Chrono-Beacon" -#define SPELL_CHRONO_BEACON 34975 -#define ITEM_CHRONO_BEACON 24289 - -bool GossipHello_npc_saat(Player* pPlayer, Creature* pCreature) -{ - if (pCreature->isQuestGiver()) - pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - - if (pPlayer->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE && !pPlayer->HasItemCount(ITEM_CHRONO_BEACON,1)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_ITEM_OBTAIN,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(10000, pCreature->GetGUID()); - return true; - } - else if (pPlayer->GetQuestRewardStatus(QUEST_OPENING_PORTAL) && !pPlayer->HasItemCount(ITEM_CHRONO_BEACON,1)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_ITEM_OBTAIN,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(10001, pCreature->GetGUID()); - return true; - } - - pPlayer->SEND_GOSSIP_MENU(10002, pCreature->GetGUID()); - return true; -} - -bool GossipSelect_npc_saat(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - if (uiAction == GOSSIP_ACTION_INFO_DEF+1) - { - pPlayer->CLOSE_GOSSIP_MENU(); - pCreature->CastSpell(pPlayer,SPELL_CHRONO_BEACON,false); - } - return true; -} - -void AddSC_dark_portal() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "npc_medivh_bm"; - newscript->GetAI = &GetAI_npc_medivh_bm; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_time_rift"; - newscript->GetAI = &GetAI_npc_time_rift; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_saat"; - newscript->pGossipHello = &GossipHello_npc_saat; - newscript->pGossipSelect = &GossipSelect_npc_saat; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.h b/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.h deleted file mode 100644 index 7bfd8c917d7..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/dark_portal.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 -* This program is free software licensed under GPL version 2 -* Please see the included DOCS/LICENSE.TXT for more information */ - -#ifndef DEF_DARKPORTAL_H -#define DEF_DARKPORTAL_H - -#define TYPE_MEDIVH 1 -#define TYPE_RIFT 2 - -#define DATA_MEDIVH 10 -#define DATA_PORTAL_COUNT 11 -#define DATA_SHIELD 12 - -#define WORLD_STATE_BM 2541 -#define WORLD_STATE_BM_SHIELD 2540 -#define WORLD_STATE_BM_RIFT 2784 - -#define QUEST_OPENING_PORTAL 10297 -#define QUEST_MASTER_TOUCH 9836 - -#define C_TIME_KEEPER 17918 -#define C_RKEEP 21104 -#define C_RLORD 17839 -#define C_DEJA 17879 -#define C_TEMPO 17880 -#define C_AEONUS 17881 -#define C_ASSAS 17835 -#define C_WHELP 21818 -#define C_CHRON 17892 -#define C_EXECU 18994 -#define C_VANQU 18995 - -#endif - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/instance_dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/instance_dark_portal.cpp deleted file mode 100644 index d1280230808..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/dark_portal/instance_dark_portal.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 -* 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_Dark_Portal -SD%Complete: 50 -SDComment: Quest support: 9836, 10297. Currently in progress. -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptedPch.h" -#include "dark_portal.h" - -#define MAX_ENCOUNTER 2 - -#define C_MEDIVH 15608 -#define C_TIME_RIFT 17838 - -#define SPELL_RIFT_CHANNEL 31387 - -#define RIFT_BOSS 1 - -inline uint32 RandRiftBoss() { return ((rand()%2) ? C_RKEEP : C_RLORD); } - -float PortalLocation[4][4]= -{ - {-2041.06, 7042.08, 29.99, 1.30}, - {-1968.18, 7042.11, 21.93, 2.12}, - {-1885.82, 7107.36, 22.32, 3.07}, - {-1928.11, 7175.95, 22.11, 3.44} -}; - -struct Wave -{ - uint32 PortalBoss; //protector of current portal - uint32 NextPortalTime; //time to next portal, or 0 if portal boss need to be killed -}; - -static Wave RiftWaves[]= -{ - {RIFT_BOSS, 0}, - {C_DEJA, 0}, - {RIFT_BOSS, 120000}, - {C_TEMPO, 140000}, - {RIFT_BOSS, 120000}, - {C_AEONUS, 0} -}; - -struct instance_dark_portal : public ScriptedInstance -{ - instance_dark_portal(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - - uint32 mRiftPortalCount; - uint32 mShieldPercent; - uint8 mRiftWaveCount; - uint8 mRiftWaveId; - - uint32 NextPortal_Timer; - - uint64 MedivhGUID; - uint8 CurrentRiftId; - - void Initialize() - { - MedivhGUID = 0; - Clear(); - } - - void Clear() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - mRiftPortalCount = 0; - mShieldPercent = 100; - mRiftWaveCount = 0; - mRiftWaveId = 0; - - CurrentRiftId = 0; - - NextPortal_Timer = 0; - } - - void InitWorldState(bool Enable = true) - { - DoUpdateWorldState(WORLD_STATE_BM,Enable ? 1 : 0); - DoUpdateWorldState(WORLD_STATE_BM_SHIELD, 100); - DoUpdateWorldState(WORLD_STATE_BM_RIFT, 0); - } - - bool IsEncounterInProgress() - { - if (GetData(TYPE_MEDIVH) == IN_PROGRESS) - return true; - - return false; - } - - void OnPlayerEnter(Player* pPlayer) - { - if (GetData(TYPE_MEDIVH) == IN_PROGRESS) - return; - - pPlayer->SendUpdateWorldState(WORLD_STATE_BM,0); - } - - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - if (pCreature->GetEntry() == C_MEDIVH) - MedivhGUID = pCreature->GetGUID(); - } - - //what other conditions to check? - bool CanProgressEvent() - { - if (instance->GetPlayers().isEmpty()) - return false; - - return true; - } - - uint8 GetRiftWaveId() - { - switch(mRiftPortalCount) - { - case 6: - mRiftWaveId = 2; - return 1; - case 12: - mRiftWaveId = 4; - return 3; - case 18: - return 5; - default: - return mRiftWaveId; - } - } - - void SetData(uint32 type, uint32 data) - { - switch(type) - { - case TYPE_MEDIVH: - if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS) - { - --mShieldPercent; - - DoUpdateWorldState(WORLD_STATE_BM_SHIELD, mShieldPercent); - - if (!mShieldPercent) - { - if (Creature* pMedivh = instance->GetCreature(MedivhGUID)) - { - if (pMedivh->isAlive()) - { - pMedivh->DealDamage(pMedivh, pMedivh->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - m_auiEncounter[0] = FAIL; - m_auiEncounter[1] = NOT_STARTED; - } - } - } - } - else - { - if (data == IN_PROGRESS) - { - debug_log("TSCR: Instance Dark Portal: Starting event."); - InitWorldState(); - m_auiEncounter[1] = IN_PROGRESS; - NextPortal_Timer = 15000; - } - - if (data == DONE) - { - //this may be completed further out in the post-event - debug_log("TSCR: Instance Dark Portal: Event completed."); - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) - { - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* pPlayer = itr->getSource()) - { - if (pPlayer->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE) - pPlayer->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL); - - if (pPlayer->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE) - pPlayer->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH); - } - } - } - } - - m_auiEncounter[0] = data; - } - break; - case TYPE_RIFT: - if (data == SPECIAL) - { - if (mRiftPortalCount < 7) - NextPortal_Timer = 5000; - } - else - m_auiEncounter[1] = data; - break; - } - } - - uint32 GetData(uint32 type) - { - switch(type) - { - case TYPE_MEDIVH: - return m_auiEncounter[0]; - case TYPE_RIFT: - return m_auiEncounter[1]; - case DATA_PORTAL_COUNT: - return mRiftPortalCount; - case DATA_SHIELD: - return mShieldPercent; - } - return 0; - } - - uint64 GetData64(uint32 data) - { - if (data == DATA_MEDIVH) - return MedivhGUID; - - return 0; - } - - Creature* SummonedPortalBoss(Creature* me) - { - uint32 entry = RiftWaves[GetRiftWaveId()].PortalBoss; - - if (entry == RIFT_BOSS) - entry = RandRiftBoss(); - - debug_log("TSCR: Instance Dark Portal: Summoning rift boss entry %u.",entry); - - Position pos; - me->GetRandomNearPosition(pos, 10.0f); - - //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); - - if (Creature *summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) - return summon; - - debug_log("TSCR: Instance Dark Portal: What just happened there? No boss, no loot, no fun..."); - return NULL; - } - - void DoSpawnPortal() - { - if (Creature* pMedivh = instance->GetCreature(MedivhGUID)) - { - uint8 tmp = urand(0,2); - - if (tmp >= CurrentRiftId) - ++tmp; - - debug_log("TSCR: Instance Dark Portal: Creating Time Rift at locationId %i (old locationId was %u).",tmp,CurrentRiftId); - - CurrentRiftId = tmp; - - Creature *pTemp = pMedivh->SummonCreature(C_TIME_RIFT, - PortalLocation[tmp][0],PortalLocation[tmp][1],PortalLocation[tmp][2],PortalLocation[tmp][3], - TEMPSUMMON_CORPSE_DESPAWN,0); - if (pTemp) - { - pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - if (Creature *pBoss = SummonedPortalBoss(pTemp)) - { - if (pBoss->GetEntry() == C_AEONUS) - pBoss->AddThreat(pMedivh,0.0f); - else - { - pBoss->AddThreat(pTemp,0.0f); - pTemp->CastSpell(pBoss,SPELL_RIFT_CHANNEL,false); - } - } - } - } - } - - void Update(uint32 diff) - { - if (m_auiEncounter[1] != IN_PROGRESS) - return; - - //add delay timer? - if (!CanProgressEvent()) - { - Clear(); - return; - } - - if (NextPortal_Timer) - { - if (NextPortal_Timer <= diff) - { - ++mRiftPortalCount; - - DoUpdateWorldState(WORLD_STATE_BM_RIFT, mRiftPortalCount); - - DoSpawnPortal(); - NextPortal_Timer = RiftWaves[GetRiftWaveId()].NextPortalTime; - } else NextPortal_Timer -= diff; - } - } -}; - -InstanceData* GetInstanceData_instance_dark_portal(Map* pMap) -{ - return new instance_dark_portal(pMap); -} - -void AddSC_instance_dark_portal() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "instance_dark_portal"; - newscript->GetInstanceData = &GetInstanceData_instance_dark_portal; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_anetheron.cpp deleted file mode 100644 index 14ce4a59b37..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_anetheron.cpp +++ /dev/null @@ -1,309 +0,0 @@ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "hyjal_trash.h" - -#define SPELL_CARRION_SWARM 31306 -#define SPELL_SLEEP 31298 -#define SPELL_VAMPIRIC_AURA 38196 -#define SPELL_INFERNO 31299 - -#define SAY_ONDEATH "The clock... is still... ticking." -#define SOUND_ONDEATH 10982 - -#define SAY_ONSLAY1 "Your hopes are lost!" -#define SAY_ONSLAY2 "Scream for me!" -#define SAY_ONSLAY3 "Pity, no time for a slow death!" -#define SOUND_ONSLAY1 10981 -#define SOUND_ONSLAY2 11038 -#define SOUND_ONSLAY3 11039 - -#define SAY_SWARM1 "The swarm is eager to feed!" -#define SAY_SWARM2 "Pestilence upon you!" -#define SOUND_SWARM1 10979 -#define SOUND_SWARM2 11037 - -#define SAY_SLEEP1 "You look tired..." -#define SAY_SLEEP2 "Sweet dreams..." -#define SOUND_SLEEP1 10978 -#define SOUND_SLEEP2 11545 - -#define SAY_INFERNO1 "Let fire rain from above!" -#define SAY_INFERNO2 "Earth and sky shall burn!" -#define SOUND_INFERNO1 10980 -#define SOUND_INFERNO2 11036 - -#define SAY_ONAGGRO "You are defenders of a doomed world! Flee here, and perhaps you will prolong your pathetic lives!" -#define SOUND_ONAGGRO 10977 - -struct boss_anetheronAI : public hyjal_trashAI -{ - boss_anetheronAI(Creature *c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - SpellEntry *TempSpell = GET_SPELL(SPELL_SLEEP); - if (TempSpell && TempSpell->EffectImplicitTargetA[0] != 1) - { - TempSpell->EffectImplicitTargetA[0] = 1; - TempSpell->EffectImplicitTargetB[0] = 0; - } - } - - uint32 SwarmTimer; - uint32 SleepTimer; - uint32 AuraTimer; - uint32 InfernoTimer; - bool pGo; - uint32 pos; - - void Reset() - { - damageTaken = 0; - SwarmTimer = 45000; - SleepTimer = 60000; - AuraTimer = 5000; - InfernoTimer = 45000; - - if (pInstance && IsEvent) - pInstance->SetData(DATA_ANETHERONEVENT, NOT_STARTED); - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance && IsEvent) - pInstance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS); - DoPlaySoundToSet(me, SOUND_ONAGGRO); - me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); - } - - void KilledUnit(Unit * /*victim*/) - { - switch (urand(0,2)) - { - case 0: - DoPlaySoundToSet(me, SOUND_ONSLAY1); - me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0); - break; - case 1: - DoPlaySoundToSet(me, SOUND_ONSLAY2); - me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0); - break; - case 2: - DoPlaySoundToSet(me, SOUND_ONSLAY3); - me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0); - break; - } - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - - void JustDied(Unit *victim) - { - hyjal_trashAI::JustDied(victim); - if (pInstance && IsEvent) - pInstance->SetData(DATA_ANETHERONEVENT, DONE); - DoPlaySoundToSet(me, SOUND_ONDEATH); - me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0); - } - - void UpdateAI(const uint32 diff) - { - if (IsEvent) - { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); - if (!pGo) - { - pGo = true; - if (pInstance) - { - AddWaypoint(0, 4896.08, -1576.35, 1333.65); - AddWaypoint(1, 4898.68, -1615.02, 1329.48); - AddWaypoint(2, 4907.12, -1667.08, 1321.00); - AddWaypoint(3, 4963.18, -1699.35, 1340.51); - AddWaypoint(4, 4989.16, -1716.67, 1335.74); - AddWaypoint(5, 5026.27, -1736.89, 1323.02); - AddWaypoint(6, 5037.77, -1770.56, 1324.36); - AddWaypoint(7, 5067.23, -1789.95, 1321.17); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - if (SwarmTimer <= diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(pTarget, SPELL_CARRION_SWARM); - - SwarmTimer = urand(45000,60000); - switch (urand(0,1)) - { - case 0: - DoPlaySoundToSet(me, SOUND_SWARM1); - me->MonsterYell(SAY_SWARM1, LANG_UNIVERSAL, 0); - break; - case 1: - DoPlaySoundToSet(me, SOUND_SWARM2); - me->MonsterYell(SAY_SWARM2, LANG_UNIVERSAL, 0); - break; - } - } else SwarmTimer -= diff; - - if (SleepTimer <= diff) - { - for (uint8 i = 0; i < 3; ++i) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - pTarget->CastSpell(pTarget,SPELL_SLEEP,true); - } - SleepTimer = 60000; - switch (urand(0,1)) - { - case 0: - DoPlaySoundToSet(me, SOUND_SLEEP1); - me->MonsterYell(SAY_SLEEP1, LANG_UNIVERSAL, 0); - break; - case 1: - DoPlaySoundToSet(me, SOUND_SLEEP2); - me->MonsterYell(SAY_SLEEP2, LANG_UNIVERSAL, 0); - break; - } - } else SleepTimer -= diff; - if (AuraTimer <= diff) - { - DoCast(me, SPELL_VAMPIRIC_AURA, true); - AuraTimer = urand(10000,20000); - } else AuraTimer -= diff; - if (InfernoTimer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO); - InfernoTimer = 45000; - switch (urand(0,1)) - { - case 0: - DoPlaySoundToSet(me, SOUND_INFERNO1); - me->MonsterYell(SAY_INFERNO1, LANG_UNIVERSAL, 0); - break; - case 1: - DoPlaySoundToSet(me, SOUND_INFERNO2); - me->MonsterYell(SAY_INFERNO2, LANG_UNIVERSAL, 0); - break; - } - } else InfernoTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_anetheron(Creature* pCreature) -{ - return new boss_anetheronAI (pCreature); -} - -#define SPELL_IMMOLATION 31303 -#define SPELL_INFERNO_EFFECT 31302 - -struct mob_towering_infernalAI : public ScriptedAI -{ - mob_towering_infernalAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - if (pInstance) - AnetheronGUID = pInstance->GetData64(DATA_ANETHERON); - } - - uint32 ImmolationTimer; - uint32 CheckTimer; - uint64 AnetheronGUID; - ScriptedInstance* pInstance; - - void Reset() - { - DoCast(me, SPELL_INFERNO_EFFECT); - ImmolationTimer = 5000; - CheckTimer = 5000; - } - - void EnterCombat(Unit * /*who*/) - { - } - - void KilledUnit(Unit * /*victim*/) - { - } - - void JustDied(Unit * /*victim*/) - { - } - - void MoveInLineOfSight(Unit *who) - { - if (me->IsWithinDist(who, 50) && !me->isInCombat() && me->IsHostileTo(who)) - AttackStart(who); - } - - void UpdateAI(const uint32 diff) - { - if (CheckTimer <= diff) - { - if (AnetheronGUID) - { - Creature* boss = Unit::GetCreature((*me),AnetheronGUID); - if (!boss || (boss && boss->isDead())) - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - return; - } - } - CheckTimer = 5000; - } else CheckTimer -= diff; - - //Return since we have no target - if (!UpdateVictim()) - return; - - if (ImmolationTimer <= diff) - { - DoCast(me, SPELL_IMMOLATION); - ImmolationTimer = 5000; - } else ImmolationTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_towering_infernal(Creature* pCreature) -{ - return new mob_towering_infernalAI (pCreature); -} - -void AddSC_boss_anetheron() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_anetheron"; - newscript->GetAI = &GetAI_boss_anetheron; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_towering_infernal"; - newscript->GetAI = &GetAI_mob_towering_infernal; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_archimonde.cpp deleted file mode 100644 index 8e1fa378e07..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_archimonde.cpp +++ /dev/null @@ -1,635 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Archimonde -SD%Complete: 85 -SDComment: Doomfires not completely offlike due to core limitations for random moving. Tyrande and second phase not fully implemented. -SDCategory: Caverns of Time, Mount Hyjal -EndScriptData */ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "SpellAuras.h" -#include "hyjal_trash.h" - -//text id -1534018 are the text used when previous events complete. Not part of this script. -#define SAY_AGGRO -1534019 -#define SAY_DOOMFIRE1 -1534020 -#define SAY_DOOMFIRE2 -1534021 -#define SAY_AIR_BURST1 -1534022 -#define SAY_AIR_BURST2 -1534023 -#define SAY_SLAY1 -1534024 -#define SAY_SLAY2 -1534025 -#define SAY_SLAY3 -1534026 -#define SAY_ENRAGE -1534027 -#define SAY_DEATH -1534028 -#define SAY_SOUL_CHARGE1 -1534029 -#define SAY_SOUL_CHARGE2 -1534030 - -#define SPELL_DENOUEMENT_WISP 32124 -#define SPELL_ANCIENT_SPARK 39349 -#define SPELL_PROTECTION_OF_ELUNE 38528 - -#define SPELL_DRAIN_WORLD_TREE 39140 -#define SPELL_DRAIN_WORLD_TREE_2 39141 - -#define SPELL_FINGER_OF_DEATH 31984 -#define SPELL_HAND_OF_DEATH 35354 -#define SPELL_AIR_BURST 32014 -#define SPELL_GRIP_OF_THE_LEGION 31972 -#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures -#define SPELL_DOOMFIRE_SPAWN 32074 -#define SPELL_DOOMFIRE 31945 -#define SPELL_SOUL_CHARGE_YELLOW 32045 -#define SPELL_SOUL_CHARGE_GREEN 32051 -#define SPELL_SOUL_CHARGE_RED 32052 -#define SPELL_UNLEASH_SOUL_YELLOW 32054 -#define SPELL_UNLEASH_SOUL_GREEN 32057 -#define SPELL_UNLEASH_SOUL_RED 32053 -#define SPELL_FEAR 31970 - -#define CREATURE_ARCHIMONDE 17968 -#define CREATURE_DOOMFIRE 18095 -#define CREATURE_DOOMFIRE_SPIRIT 18104 -#define CREATURE_ANCIENT_WISP 17946 -#define CREATURE_CHANNEL_TARGET 22418 - -#define NORDRASSIL_X 5503.713 -#define NORDRASSIL_Y -3523.436 -#define NORDRASSIL_Z 1608.781 - -struct mob_ancient_wispAI : public ScriptedAI -{ - mob_ancient_wispAI(Creature* c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - ArchimondeGUID = 0; - } - - ScriptedInstance* pInstance; - uint64 ArchimondeGUID; - uint32 CheckTimer; - - void Reset() - { - CheckTimer = 1000; - - if (pInstance) - ArchimondeGUID = pInstance->GetData64(DATA_ARCHIMONDE); - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - - void EnterCombat(Unit* /*who*/) {} - - void DamageTaken(Unit* /*done_by*/, uint32 &damage) { damage = 0; } - - void UpdateAI(const uint32 diff) - { - if (CheckTimer <= diff) - { - if (Unit* Archimonde = Unit::GetUnit((*me), ArchimondeGUID)) - { - if ((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive()) - DoCast(me, SPELL_DENOUEMENT_WISP); - else - DoCast(Archimonde, SPELL_ANCIENT_SPARK); - } - CheckTimer = 1000; - } else CheckTimer -= diff; - } -}; - -/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will - MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */ -struct mob_doomfireAI : public ScriptedAI -{ - mob_doomfireAI(Creature* c) : ScriptedAI(c) {} - - void Reset() { } - - void MoveInLineOfSight(Unit* /*who*/) {} - void EnterCombat(Unit* /*who*/) {} - void DamageTaken(Unit * /*done_by*/, uint32 &damage) { damage = 0; } -}; - -/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or - travels in random directions if pTarget cannot be found. */ -struct mob_doomfire_targettingAI : public ScriptedAI -{ - mob_doomfire_targettingAI(Creature* c) : ScriptedAI(c) {} - - uint64 TargetGUID; - uint32 ChangeTargetTimer; - - void Reset() - { - TargetGUID = 0; - ChangeTargetTimer = 5000; - } - - void MoveInLineOfSight(Unit* who) - { - //will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0 - //when UpdateAI needs it, it will be forced to select randomPoint - if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER) - TargetGUID = who->GetGUID(); - } - - void EnterCombat(Unit* /*who*/) {} - - void DamageTaken(Unit * /*done_by*/, uint32 &damage) { damage = 0; } - - void UpdateAI(const uint32 diff) - { - if (ChangeTargetTimer <= diff) - { - if (Unit *temp = Unit::GetUnit(*me,TargetGUID)) - { - me->GetMotionMaster()->MoveFollow(temp,0.0f,0.0f); - TargetGUID = 0; - } - else - { - Position pos; - me->GetRandomNearPosition(pos, 40); - me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ); - } - - ChangeTargetTimer = 5000; - } else ChangeTargetTimer -= diff; - } -}; - -/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers. - The only complicated aspect of the battle is Finger of Death and Doomfire, with Doomfire being the - hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then - select a random pTarget and cast the spell on them. However, if someone IS in melee range, and this - is NOT the main tank (creature's victim), then we aggro that player and they become the new victim. - For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will - randomly select it's pTarget to follow and then we create the random movement making it unpredictable. */ - -struct boss_archimondeAI : public hyjal_trashAI -{ - boss_archimondeAI(Creature *c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance* pInstance; - - uint64 DoomfireSpiritGUID; - uint64 WorldTreeGUID; - - uint32 DrainNordrassilTimer; - uint32 FearTimer; - uint32 AirBurstTimer; - uint32 GripOfTheLegionTimer; - uint32 DoomfireTimer; - uint32 SoulChargeTimer; - uint32 SoulChargeCount; - uint32 MeleeRangeCheckTimer; - uint32 HandOfDeathTimer; - uint32 SummonWispTimer; - uint32 WispCount; - uint32 EnrageTimer; - uint32 CheckDistanceTimer; - - bool Enraged; - bool BelowTenPercent; - bool HasProtected; - bool IsChanneling; - - void Reset() - { - if (pInstance) - pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED); - - DoomfireSpiritGUID = 0; - damageTaken = 0; - WorldTreeGUID = 0; - - DrainNordrassilTimer = 0; - FearTimer = 42000; - AirBurstTimer = 30000; - GripOfTheLegionTimer = urand(5000,25000); - DoomfireTimer = 20000; - SoulChargeTimer = urand(2000,30000); - SoulChargeCount = 0; - MeleeRangeCheckTimer = 15000; - HandOfDeathTimer = 2000; - WispCount = 0; // When ~30 wisps are summoned, Archimonde dies - EnrageTimer = 600000; // 10 minutes - CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage - SummonWispTimer = 0; - - Enraged = false; - BelowTenPercent = false; - HasProtected = false; - IsChanneling = false; - } - - void EnterCombat(Unit * /*who*/) - { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); - - if (pInstance) - pInstance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS); - } - - void KilledUnit(Unit * victim) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me); - - if (victim && (victim->GetTypeId() == TYPEID_PLAYER)) - GainSoulCharge(CAST_PLR(victim)); - } - - void GainSoulCharge(Player* victim) - { - switch(victim->getClass()) - { - case CLASS_PRIEST: - case CLASS_PALADIN: - case CLASS_WARLOCK: - victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true); - break; - case CLASS_MAGE: - case CLASS_ROGUE: - case CLASS_WARRIOR: - victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true); - break; - case CLASS_DRUID: - case CLASS_SHAMAN: - case CLASS_HUNTER: - victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true); - break; - } - - SoulChargeTimer = urand(2000,30000); - ++SoulChargeCount; - } - - void JustDied(Unit *victim) - { - hyjal_trashAI::JustDied(victim); - DoScriptText(SAY_DEATH, me); - - if (pInstance) - pInstance->SetData(DATA_ARCHIMONDEEVENT, DONE); - } - - bool CanUseFingerOfDeath() - { - // First we check if our current victim is in melee range or not. - Unit* victim = me->getVictim(); - if (victim && me->IsWithinDistInMap(victim, me->GetAttackDistance(victim))) - return false; - - std::list& m_threatlist = me->getThreatManager().getThreatList(); - if (m_threatlist.empty()) - return false; - - std::list targets; - std::list::const_iterator itr = m_threatlist.begin(); - for (; itr != m_threatlist.end(); ++itr) - { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && pUnit->isAlive()) - targets.push_back(pUnit); - } - - if (targets.empty()) - return false; - - targets.sort(Trinity::ObjectDistanceOrderPred(me)); - Unit *pTarget = targets.front(); - if (pTarget) - { - if (!me->IsWithinDistInMap(pTarget, me->GetAttackDistance(pTarget))) - return true; // Cast Finger of Death - else // This target is closest, he is our new tank - me->AddThreat(pTarget, me->getThreatManager().getThreat(me->getVictim())); - } - - return false; - } - - void JustSummoned(Creature *summoned) - { - if (summoned->GetEntry() == CREATURE_ANCIENT_WISP) - summoned->AI()->AttackStart(me); - else - { - summoned->setFaction(me->getFaction()); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - - if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT) - { - DoomfireSpiritGUID = summoned->GetGUID(); - } - - if (summoned->GetEntry() == CREATURE_DOOMFIRE) - { - summoned->CastSpell(summoned,SPELL_DOOMFIRE_SPAWN,false); - summoned->CastSpell(summoned,SPELL_DOOMFIRE,true,0,0,me->GetGUID()); - - if (Unit *DoomfireSpirit = Unit::GetUnit(*me, DoomfireSpiritGUID)) - { - summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit,0.0f,0.0f); - DoomfireSpiritGUID = 0; - } - } - } - - //this is code doing close to what the summoning spell would do (spell 31903) - void SummonDoomfire(Unit *pTarget) - { - me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT, - pTarget->GetPositionX()+15.0,pTarget->GetPositionY()+15.0,pTarget->GetPositionZ(),0, - TEMPSUMMON_TIMED_DESPAWN, 27000); - - me->SummonCreature(CREATURE_DOOMFIRE, - pTarget->GetPositionX()-15.0,pTarget->GetPositionY()-15.0,pTarget->GetPositionZ(),0, - TEMPSUMMON_TIMED_DESPAWN, 27000); - } - - void UnleashSoulCharge() - { - me->InterruptNonMeleeSpells(false); - - bool HasCast = false; - uint32 chargeSpell = 0; - uint32 unleashSpell = 0; - - switch (urand(0,2)) - { - case 0: - chargeSpell = SPELL_SOUL_CHARGE_RED; - unleashSpell = SPELL_UNLEASH_SOUL_RED; - break; - case 1: - chargeSpell = SPELL_SOUL_CHARGE_YELLOW; - unleashSpell = SPELL_UNLEASH_SOUL_YELLOW; - break; - case 2: - chargeSpell = SPELL_SOUL_CHARGE_GREEN; - unleashSpell = SPELL_UNLEASH_SOUL_GREEN; - break; - } - - if (me->HasAura(chargeSpell)) - { - me->RemoveAuraFromStack(chargeSpell); - DoCast(me->getVictim(), unleashSpell); - HasCast = true; - SoulChargeCount--; - } - - if (HasCast) - SoulChargeTimer = urand(2000,30000); - } - - void UpdateAI(const uint32 diff) - { - if (!me->isInCombat()) - { - if (pInstance) - { - // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. - if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((me->GetVisibility() != VISIBILITY_OFF) || (me->getFaction() != 35))) - { - me->SetVisibility(VISIBILITY_OFF); - me->setFaction(35); - } - else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((me->GetVisibility() != VISIBILITY_ON) || (me->getFaction() == 35))) - { - me->setFaction(1720); - me->SetVisibility(VISIBILITY_ON); - } - } - - if (DrainNordrassilTimer <= diff) - { - if (!IsChanneling) - { - Creature *temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000); - - if (temp) - WorldTreeGUID = temp->GetGUID(); - - if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) - { - Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Nordrassil->SetDisplayId(11686); - DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); - IsChanneling = true; - } - } - - if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID)) - { - Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); - DrainNordrassilTimer = 1000; - } - } else DrainNordrassilTimer -= diff; - } - - if (!UpdateVictim()) - return; - - if (((me->GetHealth()*100 / me->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged) - BelowTenPercent = true; - - if (!Enraged) - { - if (EnrageTimer <= diff) - { - if ((me->GetHealth()*100 / me->GetMaxHealth()) > 10) - { - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MoveIdle(); - Enraged = true; - DoScriptText(SAY_ENRAGE, me); - } - } else EnrageTimer -= diff; - - if (CheckDistanceTimer <= diff) - { - // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature - Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000); - if (Check) - { - Check->SetVisibility(VISIBILITY_OFF); - - if (me->IsWithinDistInMap(Check, 75)) - { - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MoveIdle(); - Enraged = true; - DoScriptText(SAY_ENRAGE, me); - } - } - CheckDistanceTimer = 5000; - } else CheckDistanceTimer -= diff; - } - - if (BelowTenPercent) - { - if (!HasProtected) - { - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MoveIdle(); - - //all members of raid must get this buff - DoCast(me->getVictim(), SPELL_PROTECTION_OF_ELUNE); - HasProtected = true; - Enraged = true; - } - - if (SummonWispTimer <= diff) - { - DoSpawnCreature(CREATURE_ANCIENT_WISP, rand()%40, rand()%40, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - SummonWispTimer = 1500; - ++WispCount; - } else SummonWispTimer -= diff; - - if (WispCount >= 30) - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - - if (Enraged) - { - if (HandOfDeathTimer <= diff) - { - DoCast(me->getVictim(), SPELL_HAND_OF_DEATH); - HandOfDeathTimer = 2000; - } else HandOfDeathTimer -= diff; - return; // Don't do anything after this point. - } - - if (SoulChargeCount) - { - if (SoulChargeTimer <= diff) - UnleashSoulCharge(); - else SoulChargeTimer -= diff; - } - - if (GripOfTheLegionTimer <= diff) - { - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); - GripOfTheLegionTimer = urand(5000,25000); - } else GripOfTheLegionTimer -= diff; - - if (AirBurstTimer <= diff) - { - if (urand(0,1)) - DoScriptText(SAY_AIR_BURST1, me); - else - DoScriptText(SAY_AIR_BURST2, me); - - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank - AirBurstTimer = urand(25000,40000); - } else AirBurstTimer -= diff; - - if (FearTimer <= diff) - { - DoCast(me->getVictim(), SPELL_FEAR); - FearTimer = 42000; - } else FearTimer -= diff; - - if (DoomfireTimer <= diff) - { - if (urand(0,1)) - DoScriptText(SAY_DOOMFIRE1, me); - else - DoScriptText(SAY_DOOMFIRE2, me); - - Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1); - if (!temp) - temp = me->getVictim(); - - //replace with spell cast 31903 once implicitTarget 73 implemented - SummonDoomfire(temp); - - //supposedly three doomfire can be up at the same time - DoomfireTimer = 20000; - } else DoomfireTimer -= diff; - - if (MeleeRangeCheckTimer <= diff) - { - if (CanUseFingerOfDeath()) - { - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); - MeleeRangeCheckTimer = 1000; - } - - MeleeRangeCheckTimer = 5000; - } else MeleeRangeCheckTimer -= diff; - - DoMeleeAttackIfReady(); - } - void WaypointReached(uint32 /*i*/){} -}; - -CreatureAI* GetAI_boss_archimonde(Creature* pCreature) -{ - return new boss_archimondeAI (pCreature); -} - -CreatureAI* GetAI_mob_doomfire(Creature* pCreature) -{ - return new mob_doomfireAI(pCreature); -} - -CreatureAI* GetAI_mob_doomfire_targetting(Creature* pCreature) -{ - return new mob_doomfire_targettingAI(pCreature); -} - -CreatureAI* GetAI_mob_ancient_wisp(Creature* pCreature) -{ - return new mob_ancient_wispAI(pCreature); -} - -void AddSC_boss_archimonde() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_archimonde"; - newscript->GetAI = &GetAI_boss_archimonde; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_doomfire"; - newscript->GetAI = &GetAI_mob_doomfire; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_doomfire_targetting"; - newscript->GetAI = &GetAI_mob_doomfire_targetting; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_ancient_wisp"; - newscript->GetAI = &GetAI_mob_ancient_wisp; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_azgalor.cpp deleted file mode 100644 index 69e37f7f740..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_azgalor.cpp +++ /dev/null @@ -1,285 +0,0 @@ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "hyjal_trash.h" - -#define SPELL_RAIN_OF_FIRE 31340 -#define SPELL_DOOM 31347 -#define SPELL_HOWL_OF_AZGALOR 31344 -#define SPELL_CLEAVE 31345 -#define SPELL_BERSERK 26662 - -#define SAY_ONDEATH "Your time is almost... up" -#define SOUND_ONDEATH 11002 - -#define SAY_ONSLAY1 "Reesh, hokta!" -#define SAY_ONSLAY2 "Don't fight it" -#define SAY_ONSLAY3 "No one is going to save you" -#define SOUND_ONSLAY1 11001 -#define SOUND_ONSLAY2 11048 -#define SOUND_ONSLAY3 11047 - -#define SAY_DOOM1 "Just a taste... of what awaits you" -#define SAY_DOOM2 "Suffer you despicable insect!" -#define SOUND_DOOM1 11046 -#define SOUND_DOOM2 11000 - -#define SAY_ONAGGRO "Abandon all hope! The legion has returned to finish what was begun so many years ago. This time there will be no escape!" -#define SOUND_ONAGGRO 10999 - -struct boss_azgalorAI : public hyjal_trashAI -{ - boss_azgalorAI(Creature *c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - SpellEntry *TempSpell = GET_SPELL(SPELL_HOWL_OF_AZGALOR); - if (TempSpell) - TempSpell->EffectRadiusIndex[0] = 12;//100yards instead of 50000?! - } - - uint32 RainTimer; - uint32 DoomTimer; - uint32 HowlTimer; - uint32 CleaveTimer; - uint32 EnrageTimer; - bool enraged; - - bool pGo; - uint32 pos; - - void Reset() - { - damageTaken = 0; - RainTimer = 20000; - DoomTimer = 50000; - HowlTimer = 30000; - CleaveTimer = 10000; - EnrageTimer = 600000; - enraged = false; - - if (pInstance && IsEvent) - pInstance->SetData(DATA_AZGALOREVENT, NOT_STARTED); - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance && IsEvent) - pInstance->SetData(DATA_AZGALOREVENT, IN_PROGRESS); - DoPlaySoundToSet(me, SOUND_ONAGGRO); - me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, NULL); - } - - void KilledUnit(Unit * /*victim*/) - { - switch (urand(0,2)) - { - case 0: - DoPlaySoundToSet(me, SOUND_ONSLAY1); - me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, NULL); - break; - case 1: - DoPlaySoundToSet(me, SOUND_ONSLAY2); - me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, NULL); - break; - case 2: - DoPlaySoundToSet(me, SOUND_ONSLAY3); - me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, NULL); - break; - } - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - - void JustDied(Unit *victim) - { - hyjal_trashAI::JustDied(victim); - if (pInstance && IsEvent) - pInstance->SetData(DATA_AZGALOREVENT, DONE); - DoPlaySoundToSet(me, SOUND_ONDEATH); - } - - void UpdateAI(const uint32 diff) - { - if (IsEvent) - { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); - if (!pGo) - { - pGo = true; - if (pInstance) - { - AddWaypoint(0, 5492.91, -2404.61, 1462.63); - AddWaypoint(1, 5531.76, -2460.87, 1469.55); - AddWaypoint(2, 5554.58, -2514.66, 1476.12); - AddWaypoint(3, 5554.16, -2567.23, 1479.90); - AddWaypoint(4, 5540.67, -2625.99, 1480.89); - AddWaypoint(5, 5508.16, -2659.2, 1480.15); - AddWaypoint(6, 5489.62, -2704.05, 1482.18); - AddWaypoint(7, 5457.04, -2726.26, 1485.10); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - if (RainTimer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,30,true), SPELL_RAIN_OF_FIRE); - RainTimer = 20000+rand()%15000; - } else RainTimer -= diff; - - if (DoomTimer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM,1,100,true), SPELL_DOOM);//never on tank - DoomTimer = 45000+rand()%5000; - } else DoomTimer -= diff; - - if (HowlTimer <= diff) - { - DoCast(me, SPELL_HOWL_OF_AZGALOR); - HowlTimer = 30000; - } else HowlTimer -= diff; - - if (CleaveTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CLEAVE); - CleaveTimer = 10000+rand()%5000; - } else CleaveTimer -= diff; - - if (EnrageTimer < diff && !enraged) - { - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_BERSERK, true); - enraged = true; - EnrageTimer = 600000; - } else EnrageTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_azgalor(Creature* pCreature) -{ - return new boss_azgalorAI (pCreature); -} - -#define SPELL_THRASH 12787 -#define SPELL_CRIPPLE 31406 -#define SPELL_WARSTOMP 31408 - -struct mob_lesser_doomguardAI : public hyjal_trashAI -{ - mob_lesser_doomguardAI(Creature *c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - if (pInstance) - AzgalorGUID = pInstance->GetData64(DATA_AZGALOR); - } - - uint32 CrippleTimer; - uint32 WarstompTimer; - uint32 CheckTimer; - uint64 AzgalorGUID; - ScriptedInstance* pInstance; - - void Reset() - { - CrippleTimer = 50000; - WarstompTimer = 10000; - DoCast(me, SPELL_THRASH); - CheckTimer = 5000; - } - - void EnterCombat(Unit * /*who*/) - { - } - - void KilledUnit(Unit * /*victim*/) - { - } - - void WaypointReached(uint32 /*i*/) - { - } - - void MoveInLineOfSight(Unit *who) - { - if (me->IsWithinDist(who, 50) && !me->isInCombat() && me->IsHostileTo(who)) - AttackStart(who); - } - - void JustDied(Unit * /*victim*/) - { - } - - void UpdateAI(const uint32 diff) - { - if (CheckTimer <= diff) - { - if (AzgalorGUID) - { - Creature* boss = Unit::GetCreature((*me),AzgalorGUID); - if (!boss || (boss && boss->isDead())) - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - return; - } - } - CheckTimer = 5000; - } else CheckTimer -= diff; - - //Return since we have no target - if (!UpdateVictim()) - return; - - if (WarstompTimer <= diff) - { - DoCast(me, SPELL_WARSTOMP); - WarstompTimer = 10000+rand()%5000; - } else WarstompTimer -= diff; - - if (CrippleTimer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CRIPPLE); - CrippleTimer = 25000+rand()%5000; - } else CrippleTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_lesser_doomguard(Creature* pCreature) -{ - return new mob_lesser_doomguardAI (pCreature); -} - -void AddSC_boss_azgalor() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_azgalor"; - newscript->GetAI = &GetAI_boss_azgalor; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_lesser_doomguard"; - newscript->GetAI = &GetAI_mob_lesser_doomguard; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_kazrogal.cpp deleted file mode 100644 index b52d22842e3..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_kazrogal.cpp +++ /dev/null @@ -1,197 +0,0 @@ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "hyjal_trash.h" - -#define SPELL_CLEAVE 31436 -#define SPELL_WARSTOMP 31480 -#define SPELL_MARK 31447 - -#define SOUND_ONDEATH 11018 - -#define SAY_ONSLAY1 "Shaza-Kiel!" -#define SAY_ONSLAY2 "You... are nothing!" -#define SAY_ONSLAY3 "Miserable nuisance!" -#define SOUND_ONSLAY1 11017 -#define SOUND_ONSLAY2 11053 -#define SOUND_ONSLAY3 11054 - -#define SAY_MARK1 "Your death will be a painful one." -#define SAY_MARK2 "You... are marked." -#define SOUND_MARK1 11016 -#define SOUND_MARK2 11052 - -#define SAY_ONAGGRO "Cry for mercy! Your meaningless lives will soon be forfeit." -#define SOUND_ONAGGRO 11015 - -struct boss_kazrogalAI : public hyjal_trashAI -{ - boss_kazrogalAI(Creature *c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - SpellEntry *TempSpell = GET_SPELL(SPELL_MARK); - if (TempSpell && TempSpell->EffectImplicitTargetA[0] != 1) - { - TempSpell->EffectImplicitTargetA[0] = 1; - TempSpell->EffectImplicitTargetB[0] = 0; - } - } - - uint32 CleaveTimer; - uint32 WarStompTimer; - uint32 MarkTimer; - uint32 MarkTimerBase; - bool pGo; - uint32 pos; - - void Reset() - { - damageTaken = 0; - CleaveTimer = 5000; - WarStompTimer = 15000; - MarkTimer = 45000; - MarkTimerBase = 45000; - - if (pInstance && IsEvent) - pInstance->SetData(DATA_KAZROGALEVENT, NOT_STARTED); - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance && IsEvent) - pInstance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS); - DoPlaySoundToSet(me, SOUND_ONAGGRO); - me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, NULL); - } - - void KilledUnit(Unit * /*victim*/) - { - switch (urand(0,2)) - { - case 0: - DoPlaySoundToSet(me, SOUND_ONSLAY1); - me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, NULL); - break; - case 1: - DoPlaySoundToSet(me, SOUND_ONSLAY2); - me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, NULL); - break; - case 2: - DoPlaySoundToSet(me, SOUND_ONSLAY3); - me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, NULL); - break; - } - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - - void JustDied(Unit *victim) - { - hyjal_trashAI::JustDied(victim); - if (pInstance && IsEvent) - pInstance->SetData(DATA_KAZROGALEVENT, DONE); - DoPlaySoundToSet(me, SOUND_ONDEATH); - } - - void UpdateAI(const uint32 diff) - { - if (IsEvent) - { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); - if (!pGo) - { - pGo = true; - if (pInstance) - { - AddWaypoint(0, 5492.91, -2404.61, 1462.63); - AddWaypoint(1, 5531.76, -2460.87, 1469.55); - AddWaypoint(2, 5554.58, -2514.66, 1476.12); - AddWaypoint(3, 5554.16, -2567.23, 1479.90); - AddWaypoint(4, 5540.67, -2625.99, 1480.89); - AddWaypoint(5, 5508.16, -2659.2, 1480.15); - AddWaypoint(6, 5489.62, -2704.05, 1482.18); - AddWaypoint(7, 5457.04, -2726.26, 1485.10); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - if (CleaveTimer <= diff) - { - DoCast(me, SPELL_CLEAVE); - CleaveTimer = 6000+rand()%15000; - } else CleaveTimer -= diff; - - if (WarStompTimer <= diff) - { - DoCast(me, SPELL_WARSTOMP); - WarStompTimer = 60000; - } else WarStompTimer -= diff; - - if (me->HasAura(SPELL_MARK)) - me->RemoveAurasDueToSpell(SPELL_MARK); - if (MarkTimer <= diff) - { - //cast dummy, useful for bos addons - me->CastCustomSpell(me, SPELL_MARK, NULL, NULL, NULL, false, NULL, NULL, me->GetGUID()); - - std::list t_list = me->getThreatManager().getThreatList(); - for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) - { - Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->getPowerType() == POWER_MANA) - { - pTarget->CastSpell(pTarget, SPELL_MARK,true);//only cast on mana users - } - } - MarkTimerBase -= 5000; - if (MarkTimerBase < 5500) - MarkTimerBase = 5500; - MarkTimer = MarkTimerBase; - switch (urand(0,2)) - { - case 0: - DoPlaySoundToSet(me, SOUND_MARK1); - me->MonsterYell(SAY_MARK1, LANG_UNIVERSAL, NULL); - break; - case 1: - DoPlaySoundToSet(me, SOUND_MARK2); - me->MonsterYell(SAY_MARK2, LANG_UNIVERSAL, NULL); - break; - } - } else MarkTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_kazrogal(Creature* pCreature) -{ - return new boss_kazrogalAI (pCreature); -} - -void AddSC_boss_kazrogal() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_kazrogal"; - newscript->GetAI = &GetAI_boss_kazrogal; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_rage_winterchill.cpp deleted file mode 100644 index 7465b997117..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/boss_rage_winterchill.cpp +++ /dev/null @@ -1,192 +0,0 @@ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "hyjal_trash.h" - -#define SPELL_FROST_ARMOR 31256 -#define SPELL_DEATH_AND_DECAY 31258 - -#define SPELL_FROST_NOVA 31250 -#define SPELL_ICEBOLT 31249 - -#define SAY_ONDEATH "You have won this battle, but not... the... war" -#define SOUND_ONDEATH 11026 - -#define SAY_ONSLAY1 "All life must perish!" -#define SAY_ONSLAY2 "Victory to the Legion!" -#define SOUND_ONSLAY1 11025 -#define SOUND_ONSLAY2 11057 - -#define SAY_DECAY1 "Crumble and rot!" -#define SAY_DECAY2 "Ashes to ashes, dust to dust" -#define SOUND_DECAY1 11023 -#define SOUND_DECAY2 11055 - -#define SAY_NOVA1 "Succumb to the icy chill... of death!" -#define SAY_NOVA2 "It will be much colder in your grave" -#define SOUND_NOVA1 11024 -#define SOUND_NOVA2 11058 - -#define SAY_ONAGGRO "The Legion's final conquest has begun! Once again the subjugation of this world is within our grasp. Let none survive!" -#define SOUND_ONAGGRO 11022 - -struct boss_rage_winterchillAI : public hyjal_trashAI -{ - boss_rage_winterchillAI(Creature *c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - } - - uint32 FrostArmorTimer; - uint32 DecayTimer; - uint32 NovaTimer; - uint32 IceboltTimer; - bool pGo; - uint32 pos; - - void Reset() - { - damageTaken = 0; - FrostArmorTimer = 37000; - DecayTimer = 45000; - NovaTimer = 15000; - IceboltTimer = 10000; - - if (pInstance && IsEvent) - pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED); - } - - void EnterCombat(Unit * /*who*/) - { - if (pInstance && IsEvent) - pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS); - DoPlaySoundToSet(me, SOUND_ONAGGRO); - me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0); - } - - void KilledUnit(Unit * /*victim*/) - { - switch (urand(0,1)) - { - case 0: - DoPlaySoundToSet(me, SOUND_ONSLAY1); - me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, NULL); - break; - case 1: - DoPlaySoundToSet(me, SOUND_ONSLAY2); - me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, NULL); - break; - } - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0f); - } - } - - void JustDied(Unit *victim) - { - hyjal_trashAI::JustDied(victim); - if (pInstance && IsEvent) - pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE); - DoPlaySoundToSet(me, SOUND_ONDEATH); - me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, NULL); - } - - void UpdateAI(const uint32 diff) - { - if (IsEvent) - { - //Must update npc_escortAI - npc_escortAI::UpdateAI(diff); - if (!pGo) - { - pGo = true; - if (pInstance) - { - AddWaypoint(0, 4896.08, -1576.35, 1333.65); - AddWaypoint(1, 4898.68, -1615.02, 1329.48); - AddWaypoint(2, 4907.12, -1667.08, 1321.00); - AddWaypoint(3, 4963.18, -1699.35, 1340.51); - AddWaypoint(4, 4989.16, -1716.67, 1335.74); - AddWaypoint(5, 5026.27, -1736.89, 1323.02); - AddWaypoint(6, 5037.77, -1770.56, 1324.36); - AddWaypoint(7, 5067.23, -1789.95, 1321.17); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - if (FrostArmorTimer <= diff) - { - DoCast(me, SPELL_FROST_ARMOR); - FrostArmorTimer = 40000+rand()%20000; - } else FrostArmorTimer -= diff; - if (DecayTimer <= diff) - { - DoCast(me->getVictim(), SPELL_DEATH_AND_DECAY); - DecayTimer = 60000+rand()%20000; - switch (urand(0,1)) - { - case 0: - DoPlaySoundToSet(me, SOUND_DECAY1); - me->MonsterYell(SAY_DECAY1, LANG_UNIVERSAL, NULL); - break; - case 1: - DoPlaySoundToSet(me, SOUND_DECAY2); - me->MonsterYell(SAY_DECAY2, LANG_UNIVERSAL, NULL); - break; - } - } else DecayTimer -= diff; - if (NovaTimer <= diff) - { - DoCast(me->getVictim(), SPELL_FROST_NOVA); - NovaTimer = 30000+rand()%15000; - switch (urand(0,1)) - { - case 0: - DoPlaySoundToSet(me, SOUND_NOVA1); - me->MonsterYell(SAY_NOVA1, LANG_UNIVERSAL, NULL); - break; - case 1: - DoPlaySoundToSet(me, SOUND_NOVA2); - me->MonsterYell(SAY_NOVA2, LANG_UNIVERSAL, NULL); - break; - } - } else NovaTimer -= diff; - if (IceboltTimer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,40,true), SPELL_ICEBOLT); - IceboltTimer = 11000+rand()%20000; - } else IceboltTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_rage_winterchill(Creature* pCreature) -{ - return new boss_rage_winterchillAI (pCreature); -} - -void AddSC_boss_rage_winterchill() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_rage_winterchill"; - newscript->GetAI = &GetAI_boss_rage_winterchill; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.cpp deleted file mode 100644 index 16a050939cc..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.cpp +++ /dev/null @@ -1,247 +0,0 @@ - /* Copyright (C) 2006 - 2009 ScriptDev2 - * 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: Hyjal -SD%Complete: 80 -SDComment: gossip text id's unknown -SDCategory: Caverns of Time, Mount Hyjal -EndScriptData */ - -/* ContentData -npc_jaina_proudmoore -npc_thrall -npc_tyrande_whisperwind -EndContentData */ - -#include "ScriptedPch.h" -#include "hyjalAI.h" - -#define GOSSIP_ITEM_BEGIN_ALLY "My companions and I are with you, Lady Proudmoore." -#define GOSSIP_ITEM_ANETHERON "We are ready for whatever Archimonde might send our way, Lady Proudmoore." - -#define GOSSIP_ITEM_BEGIN_HORDE "I am with you, Thrall." -#define GOSSIP_ITEM_AZGALOR "We have nothing to fear." - -#define GOSSIP_ITEM_RETREAT "We can't keep this up. Let's retreat!" - -#define GOSSIP_ITEM_TYRANDE "Aid us in defending Nordrassil" -#define ITEM_TEAR_OF_GODDESS 24494 - -#define GOSSIP_ITEM_GM1 "[GM] Toggle Debug Timers" - -CreatureAI* GetAI_npc_jaina_proudmoore(Creature* pCreature) -{ - hyjalAI* ai = new hyjalAI(pCreature); - - ai->Reset(); - ai->EnterEvadeMode(); - - ai->Spell[0].SpellId = SPELL_BLIZZARD; - ai->Spell[0].Cooldown = 15000 + rand()%20000; - ai->Spell[0].TargetType = TARGETTYPE_RANDOM; - - ai->Spell[1].SpellId = SPELL_PYROBLAST; - ai->Spell[1].Cooldown = 5500 + rand()%4000; - ai->Spell[1].TargetType = TARGETTYPE_RANDOM; - - ai->Spell[2].SpellId = SPELL_SUMMON_ELEMENTALS; - ai->Spell[2].Cooldown = 15000 + rand()%30000; - ai->Spell[2].TargetType = TARGETTYPE_SELF; - - return ai; -} - -bool GossipHello_npc_jaina_proudmoore(Player* pPlayer, Creature* pCreature) -{ - hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); - if (ai->EventBegun) - return false; - - uint32 RageEncounter = ai->GetInstanceData(DATA_RAGEWINTERCHILLEVENT); - uint32 AnetheronEncounter = ai->GetInstanceData(DATA_ANETHERONEVENT); - if (RageEncounter == NOT_STARTED) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_ALLY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - else if (RageEncounter == DONE && AnetheronEncounter == NOT_STARTED) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ANETHERON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - else if (RageEncounter == DONE && AnetheronEncounter == DONE) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - if (pPlayer->isGameMaster()) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); - return true; -} - -bool GossipSelect_npc_jaina_proudmoore(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); - switch(uiAction) - { - case GOSSIP_ACTION_INFO_DEF + 1: - ai->StartEvent(pPlayer); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - ai->FirstBossDead = true; - ai->WaveCount = 9; - ai->StartEvent(pPlayer); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - ai->Retreat(); - break; - case GOSSIP_ACTION_INFO_DEF: - ai->Debug = !ai->Debug; - debug_log("TSCR: HyjalAI - Debug mode has been toggled"); - break; - } - return true; -} - -CreatureAI* GetAI_npc_thrall(Creature* pCreature) -{ - hyjalAI* ai = new hyjalAI(pCreature); - - ai->Reset(); - ai->EnterEvadeMode(); - - ai->Spell[0].SpellId = SPELL_CHAIN_LIGHTNING; - ai->Spell[0].Cooldown = 3000 + rand()%5000; - ai->Spell[0].TargetType = TARGETTYPE_VICTIM; - - ai->Spell[1].SpellId = SPELL_SUMMON_DIRE_WOLF; - ai->Spell[1].Cooldown = 6000 + rand()%35000; - ai->Spell[1].TargetType = TARGETTYPE_RANDOM; - - return ai; -} - -bool GossipHello_npc_thrall(Player* pPlayer, Creature* pCreature) -{ - hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); - if (ai->EventBegun) - return false; - - uint32 AnetheronEvent = ai->GetInstanceData(DATA_ANETHERONEVENT); - // Only let them start the Horde phases if Anetheron is dead. - if (AnetheronEvent == DONE && ai->GetInstanceData(DATA_ALLIANCE_RETREAT)) - { - uint32 KazrogalEvent = ai->GetInstanceData(DATA_KAZROGALEVENT); - uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT); - if (KazrogalEvent == NOT_STARTED) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_HORDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - else if (KazrogalEvent == DONE && AzgalorEvent == NOT_STARTED) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AZGALOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - else if (AzgalorEvent == DONE) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - } - - if (pPlayer->isGameMaster()) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); - return true; -} - -bool GossipSelect_npc_thrall(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); - ai->DeSpawnVeins();//despawn the alliance veins - switch(uiAction) - { - case GOSSIP_ACTION_INFO_DEF + 1: - ai->StartEvent(pPlayer); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - ai->FirstBossDead = true; - ai->WaveCount = 9; - ai->StartEvent(pPlayer); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - ai->Retreat(); - break; - case GOSSIP_ACTION_INFO_DEF: - ai->Debug = !ai->Debug; - debug_log("TSCR: HyjalAI - Debug mode has been toggled"); - break; - } - return true; -} - -CreatureAI* GetAI_npc_tyrande_whisperwind(Creature* pCreature) -{ - hyjalAI* ai = new hyjalAI(pCreature); - ai->Reset(); - ai->EnterEvadeMode(); - return ai; -} - -bool GossipHello_npc_tyrande_whisperwind(Player* pPlayer, Creature* pCreature) -{ - hyjalAI* ai = CAST_AI(hyjalAI, pCreature->AI()); - uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT); - - // Only let them get item if Azgalor is dead. - if (AzgalorEvent == DONE && !pPlayer->HasItemCount(ITEM_TEAR_OF_GODDESS,1)) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TYRANDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); - return true; -} - -bool GossipSelect_npc_tyrande_whisperwind(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - if (uiAction == GOSSIP_ACTION_INFO_DEF) - { - ItemPosCountVec dest; - uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_TEAR_OF_GODDESS, 1); - if (msg == EQUIP_ERR_OK) - { - Item* item = pPlayer->StoreNewItem(dest, ITEM_TEAR_OF_GODDESS, true); - if (item && pPlayer) - pPlayer->SendNewItem(item,1,true,false,true); - } - pPlayer->SEND_GOSSIP_MENU(907, pCreature->GetGUID()); - CAST_AI(hyjalAI, pCreature->AI()); - } - return true; -} - -void AddSC_hyjal() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "npc_jaina_proudmoore"; - newscript->GetAI = &GetAI_npc_jaina_proudmoore; - newscript->pGossipHello = &GossipHello_npc_jaina_proudmoore; - newscript->pGossipSelect = &GossipSelect_npc_jaina_proudmoore; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_thrall"; - newscript->GetAI = &GetAI_npc_thrall; - newscript->pGossipHello = &GossipHello_npc_thrall; - newscript->pGossipSelect = &GossipSelect_npc_thrall; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_tyrande_whisperwind"; - newscript->pGossipHello = &GossipHello_npc_tyrande_whisperwind; - newscript->pGossipSelect = &GossipSelect_npc_tyrande_whisperwind; - newscript->GetAI = &GetAI_npc_tyrande_whisperwind; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.h deleted file mode 100644 index bfc9a54dfd9..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software licensed under GPL version 2 - * Please see the included DOCS/LICENSE.TXT for more information */ - -#ifndef DEF_HYJAL_H -#define DEF_HYJAL_H - -#define ERROR_INST_DATA "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy." - -enum eTypes -{ - WORLD_STATE_WAVES = 2842, - WORLD_STATE_ENEMY = 2453, - WORLD_STATE_ENEMYCOUNT = 2454, - - DATA_ANETHERON = 1, - DATA_ANETHERONEVENT = 2, - DATA_ARCHIMONDE = 3, - DATA_ARCHIMONDEEVENT = 4, - DATA_AZGALOR = 5, - DATA_AZGALOREVENT = 6, - DATA_JAINAPROUDMOORE = 7, - DATA_KAZROGAL = 8, - DATA_KAZROGALEVENT = 9, - DATA_RAGEWINTERCHILL = 10, - DATA_RAGEWINTERCHILLEVENT = 11, - DATA_THRALL = 12, - DATA_TYRANDEWHISPERWIND = 13, - DATA_TRASH = 14, - DATA_RESET_TRASH_COUNT = 15, - DATA_ALLIANCE_RETREAT = 16, - DATA_HORDE_RETREAT = 17, - DATA_RAIDDAMAGE = 18, - DATA_RESET_RAIDDAMAGE = 19, - TYPE_RETREAT = 20 -}; -#endif - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.cpp deleted file mode 100644 index 3c12b54f3f4..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.cpp +++ /dev/null @@ -1,1157 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * 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: HyjalAI -SD%Complete: 90 -SDComment: -SDCategory: Caverns of Time, Mount Hyjal -EndScriptData */ - -#include "ScriptedPch.h" -#include "hyjalAI.h" -#include "hyjal_trash.h" -#include "MapManager.h" -#include "Language.h" -#include "Chat.h" -#include "Object.h" - -#define SPAWN_GARG_GATE 0 -#define SPAWN_WYRM_GATE 1 -#define SPAWN_NEAR_TOWER 2 - -#define YELL_HURRY "Hurry, we don't have much time" - -// Locations for summoning gargoyls and frost wyrms in special cases -float SpawnPointSpecial[3][3]= -{ - {5497.08, -2493.23, 1535.72}, //spawn point for the gargoyles near the horde gate - {5624.53, -2548.12, 1551.54}, //spawn point for the frost wyrm near the horde gate - {5604.41, -2811.98, 1547.77} //spawn point for the gargoyles and wyrms near the horde tower -}; - -// Locations for summoning waves in Alliance base -float AllianceBase[4][3]= -{ - {4928.48, -1526.38, 1326.83}, - {4923.54, -1514.29, 1327.98}, - {4928.41, -1510.35, 1327.99}, - {4938.35, -1521.00, 1326.69} -}; - -float JainaDummySpawn[2][4]= -{ - {5497.01, -2719.03, 1483.08, 2.90426}, - {5484.98, -2721.69, 1483.39, 6.00656} -}; - -// Locations for summoning waves in Horde base -float HordeBase[4][3]= -{ - {5458.01, -2340.27, 1459.60}, - {5466.01, -2334.69, 1460.06}, - {5468.45, -2355.13, 1459.99}, - {5479.06, -2344.16, 1461.74} -}; - -// Lady Jaina's waypoints when retreathing -float JainaWPs[2][3]= -{ - {5078.56, -1789.79, 1320.73},//next to the small stairs - {5037.38, -1778.39, 1322.61},//center of alliance base -}; - -float InfernalPos[8][3]=//spawn points for the infernals in the horde base -{ - {5453.59, -2764.52, 1493.50}, - {5478.4, -2781.77, 1497.52}, - {5506.09, -2780.53, 1496.32}, - {5532.1, -2763.42, 1492.37}, - {5544.16, -2733.99, 1487.14}, - {5536.19, -2708.18, 1480.01}, - {5510.16, -2691.75, 1479.66}, - {5482.39, -2689.19, 1481.09} -}; - -float InfernalSPWP[26][4]=//spawn points for the infernals in the horde base used in the cleaning wave -{ - {5490.96, -2718.72, 1482.96, 0.49773}, - {5449.51, -2723.32, 1485.69, 2.69685}, - {5520.83, -2624.68, 1483.82, 1.20459}, - {5558.28, -2629.26, 1485.76, 0.37992}, - {5567.97, -2758.69, 1494.10, 5.04125}, - {5384.90, -2793.47, 1503.90, 5.55412}, - {5495.33, -2814.06, 1501.56, 1.12055}, - {5472.63, -2929.39, 1538.31, 1.95777}, - {5334.72, -2952.29, 1534.34, 0.50869}, - {5398.36, -2872.46, 1512.38, 0.76787}, - {5514.39, -2768.63, 1492.30, 1.55721}, - {5598.91, -2703.75, 1495.64, 2.56644}, - {5467.80, -2655.93, 1482.27, 0.85819}, - {5399.83, -2985.24, 1545.04, 5.92559}, - {5232.13, -2967.05, 1553.09, 5.41351}, - {5272.02, -3082.52, 1567.09, 3.40681}, - {5343.26, -3120.71, 1582.92, 3.16727}, - {5371.26, -3175.24, 1587.41, 6.10466}, - {5434.67, -3177.91, 1579.25, 2.77850}, - {5237.39, -3149.25, 1593.59, 0.83855}, - {5202.15, -3016.64, 1566.28, 3.31256}, - {5302.54, -2914.37, 1528.53, 3.37146}, - {5439.04, -2834.81, 1508.80, 2.14231}, - {5421.33, -2771.04, 1494.28, 6.06223}, - {5549.76, -2692.93, 1482.68, 2.19414}, - {5459.78, -2755.71, 1490.68, 1.05139} -}; - -float VeinPos[14][8]=//spawn points of the ancient gem veins -{ - {5184.84, -1982.59, 1382.66, 2.58079, 0, 0, 0.960944, 0.276742}, //alliance - {5107.66, -2071.16, 1368.37, 2.65148, 0, 0, 0.970124, 0.242611}, //alliance - {5040.53, -2227.65, 1403.17, 3.35049, 0, 0, 0.99455, -0.104257}, //alliance - {5187.59, -2453.12, 1455.51, 5.87943, 0, 0, 0.20051, -0.979692}, //alliance - {5429.43, -2340.65, 1465.38, 4.7681, 0, 0, 0.687138, -0.726527}, //alliance - {5463.99, -2315.95, 1470.29, 1.52045, 0, 0, 0.689084, 0.724682}, //alliance - {5624.65, -2495.09, 1510.11, 0.0124869, 0, 0, 0.00624342, 0.999981}, //alliance - {5285.41, -3348.32, 1663.01, 1.57152, 0, 0, 0.707362, 0.706852}, //horde - {5417.69, -3372.52, 1656.31, 0.361993, 0, 0, 0.18001, 0.983665}, //horde - {5315.34, -3238.32, 1622.88, 3.03627, 0, 0, 0.998614, 0.0526347}, //horde - {5303.4, -3096.44, 1596.41, 1.72073, 0, 0, 0.758081, 0.65216}, //horde - {5265.13, -3177.27, 1616.22, 0.813604, 0, 0, 0.395674, 0.918391}, //horde - {5374.3, -3420.59, 1653.43, 1.45762, 0, 0, 0.665981, 0.745969}, //horde - {5441.54, -3321.59, 1651.55, 0.258306, 0, 0, 0.128794, 0.991671} //horde -}; - -float AllianceOverrunGargPos[5][4]=//gargoyle spawn points in the alliance overrun -{ - {5279.94, -2049.68, 1311.38, 0},//garg1 - {5289.15, -2219.06, 1291.12, 0},//garg2 - {5202.07, -2136.10, 1305.07, 2.8},//garg3 - {5071.52, -2425.63, 1454.48, 5.54},//garg4 - {5120.65, -2467.92, 1463.93, 2.54}//garg5 -}; - -float AllianceFirePos[92][8]=//spawn points for the fire visuals (GO) in the alliance base -{ - {5039.9, -1796.84, 1323.88, 2.59222, 0, 0, 0.962511, 0.271243}, - {5087.2, -1795.2, 1320.68, 1.03946, 0, 0, 0.496644, 0.867954}, - {5112.68, -1806.66, 1359.93, 1.37799, 0, 0, 0.63576, 0.771887}, - {5095.61, -1793.27, 1359.78, 0.580806, 0, 0, 0.286338, 0.958129}, - {5090.43, -1784.45, 1360.44, 0.796784, 0, 0, 0.387937, 0.921686}, - {5139.25, -1783.11, 1359.39, 3.30849, 0, 0, 0.99652, -0.0833509}, - {5112.16, -1763.72, 1361.35, 5.10312, 0, 0, 0.556388, -0.830922}, - {4981.18, -1793.98, 1335.7, 3.23072, 0, 0, 0.999007, -0.0445498}, - {4996.57, -1766.75, 1341.62, 3.5331, 0, 0, 0.980902, -0.194505}, - {4983.74, -1769.25, 1345.75, 3.79228, 0, 0, 0.947541, -0.319635}, - {4996.01, -1774.43, 1330.71, 3.07364, 0, 0, 0.999423, 0.0339693}, - {5094.2, -1726.13, 1330.55, 1.56175, 0, 0, 0.703901, 0.710298}, - {5079.82, -1721.24, 1336.26, 1.18868, 0, 0, 0.559964, 0.828517}, - {5077.68, -1717.15, 1327.78, 0.0145145, 0, 0, 0.00725717, 0.999974}, - {5122.27, -1738.22, 1341.67, 0.835256, 0, 0, 0.405593, 0.914054}, - {5131.88, -1741.15, 1335.25, 2.15472, 0, 0, 0.880712, 0.473653}, - {5196.93, -1772.99, 1345.2, 0.128397, 0, 0, 0.0641544, 0.99794}, - {5225.33, -1756.06, 1344.17, 3.04223, 0, 0, 0.998766, 0.0496599}, - {5224.84, -1767.05, 1360.06, 3.19538, 0, 0, 0.999638, -0.0268922}, - {5202.05, -1763.47, 1361.68, 2.59455, 0, 0, 0.962826, 0.270122}, - {5194.74, -1766.66, 1356.94, 0.0734191, 0, 0, 0.0367013, 0.999326}, - {5159.67, -1832.97, 1344.5, 5.17457, 0, 0, 0.526356, -0.850264}, - {5096.17, -1858.73, 1332.46, 5.30021, 0, 0, 0.471939, -0.881631}, - {5110.7, -1856.59, 1342.84, 5.97564, 0, 0, 0.153167, -0.9882}, - {5109.76, -1855.3, 1332.38, 4.89572, 0, 0, 0.639411, -0.768865}, - {5068.95, -1837.37, 1328.81, 2.61569, 0, 0, 0.965628, 0.25993}, - {5064.4, -1824.77, 1329.02, 2.16409, 0, 0, 0.88292, 0.469524}, - {5059.89, -1848.79, 1329.59, 0.0709955, 0, 0, 0.0354903, 0.99937}, - {5014.37, -1851.39, 1322.56, 4.66949, 0, 0, 0.722111, -0.691777}, - {5025.1, -1848.27, 1323.39, 4.44565, 0, 0, 0.794854, -0.606801}, - {4942.63, -1890.13, 1326.59, 3.28719, 0, 0, 0.997351, -0.0727343}, - {4937.95, -1888.71, 1352.41, 3.41678, 0, 0, 0.990549, -0.13716}, - {4922.48, -1881.92, 1352.41, 5.03077, 0, 0, 0.586075, -0.810257}, - {4915.35, -1894.32, 1351.24, 6.22457, 0, 0, 0.0293048, -0.999571}, - {4922.71, -1904.84, 1352.56, 1.37866, 0, 0, 0.63602, 0.771672}, - {4932.89, -1905.49, 1352.56, 1.89702, 0, 0, 0.812549, 0.582893}, - {5011.83, -1861.05, 1345.86, 4.43777, 0, 0, 0.797239, -0.603664}, - {5011.83, -1861.05, 1363.26, 4.748, 0, 0, 0.694406, -0.719583}, - {5021.46, -1858.35, 1342.17, 4.86188, 0, 0, 0.652329, -0.757936}, - {4995.02, -1698.3, 1370.38, 6.15779, 0, 0, 0.0626579, -0.998035}, - {5119.85, -1728.9, 1336.04, 5.87112, 0, 0, 0.204579, -0.97885}, - {5214.75, -1751.02, 1342.5, 5.08965, 0, 0, 0.561972, -0.827156}, - {5075.04, -1822.43, 1328.87, 3.99951, 0, 0, 0.9094, -0.415924}, - {5057.09, -1823.32, 1350.35, 3.88169, 0, 0, 0.93231, -0.361659}, - {4984.6, -1816.99, 1329.21, 3.05308, 0, 0, 0.999021, 0.0442417}, - {4983.35, -1811.55, 1356.82, 3.33975, 0, 0, 0.995096, -0.098917}, - {4984.11, -1825.73, 1350.76, 2.26375, 0, 0, 0.905211, 0.424962}, - {4968.47, -1786.46, 1354.09, 3.07663, 0, 0, 0.999473, 0.0324733}, - {5061.82, -1751.16, 1339.07, 5.94727, 0, 0, 0.167171, -0.985928}, - {5063.75, -1763, 1351.91, 0.759707, 0, 0, 0.370784, 0.928719}, - {5078.65, -1708.26, 1353.9, 1.27022, 0, 0, 0.593264, 0.805008}, - {4983.19, -1755.96, 1331.13, 4.28221, 0, 0, 0.841733, -0.539894}, - {4972.76, -1755.3, 1332.5, 4.21938, 0, 0, 0.858276, -0.513188}, - {4961.65, -1760.82, 1351.69, 3.56515, 0, 0, 0.977659, -0.210198}, - {5086.45, -1779.83, 1321.62, 6.23157, 0, 0, 0.0258051, -0.999667}, - {5063.15, -1756.74, 1328.56, 0.886926, 0, 0, 0.42907, 0.903271}, - {5042.45, -1800.61, 1323.88, 2.50093, 0, 0, 0.949131, 0.31488}, - {5084.74, -1725.35, 1327.89, 1.65034, 0, 0, 0.734663, 0.678432}, - {4993.25, -1758.1, 1331.07, 3.49995, 0, 0, 0.98399, -0.178223}, - {5078.53, -1867.85, 1348.91, 5.85612, 0, 0, 0.211913, -0.977288}, - {5080.74, -1869.73, 1333.18, 6.18206, 0, 0, 0.0505424, -0.998722}, - {5089.55, -1894.13, 1356.08, 1.52072, 0, 0, 0.689181, 0.724589}, - {5113.24, -1899.49, 1363.77, 1.50108, 0, 0, 0.682034, 0.731321}, - {4984.18, -1907.69, 1325.62, 3.82193, 0, 0, 0.942698, -0.333646}, - {5094.14, -2432.08, 1429.38, 4.70083, 0, 0, 0.711182, -0.703007}, - {5329.89, -2113.30, 1281.06, 5.60560, 0, 0, 0.332347, -0.943157}, - {5170.87, -2148.13, 1278.32, 1.63540, 0, 0, 0.729573, 0.683903 }, - {5132.94, -1960.25, 1367.8, 3.69787, 0, 0, 0.961568, -0.274566}, - {5280.82, -2351.55, 1431.57, 4.46913, 0, 0, 0.787677, -0.616088}, - {5176.78, -2121.43, 1295.27, 3.24153, 0, 0, 0.998752, -0.04995}, - {5332.75, -2101.41, 1296.37, 5.50350, 0, 0, 0.380043, -0.924969}, - {5265.70, -2050.27, 1287.57, 0.50051, 0, 0, 0.247655, 0.968848 }, - {5194.21, -2129.89, 1274.04, 3.08053, 0, 0, 0.999534, 0.0305272}, - {5225.81, -1985.50, 1364.15, 0.37247, 0, 0, 0.185163, 0.982708 }, - {5339.46, -2204.47, 1280.45, 0.99921, 0, 0, 0.479081, 0.877771 }, - {5269.63, -2020.57, 1299.62, 3.00201, 0, 0, 0.997566, 0.0697332}, - {5111.54, -2445.70, 1435.31, 2.70983, 0, 0, 0.976788, 0.214207 }, - {5111.24, -1901.14, 1355.33, 1.61028, 0, 0, 0.720929, 0.693009 }, - {5310.42, -2207.82, 1277.46, 0.50441, 0, 0, 0.249544, 0.968363 }, - {5150.81, -2042.13, 1394.3, 2.21031, 0, 0, 0.893534, 0.448995 }, - {5224.84, -2376.61, 1366.33, 5.0621, 0, 0, 0.573311, -0.819338}, - {5105.41, -2454.86, 1446.16, 4.64584, 0, 0, 0.730239, -0.683191}, - {5309.65, -2188.28, 1266.84, 5.56631, 0, 0, 0.350811, -0.936446}, - {5281.46, -2047.82, 1287.67, 2.44909, 0, 0, 0.940652, 0.339373 }, - {5325.45, -2189.41, 1309.6, 6.23783, 0, 0, 0.0226771, -0.999743}, - {5190.96, -2142.54, 1293.03, 6.25668, 0, 0, 0.0132544, -0.999912}, - {5089.99, -2467.49, 1441.8, 0.77381, 0, 0, 0.377326, 0.92608 }, - {5195.08, -2129.01, 1285.36, 3.55727, 0, 0, 0.978480, -0.206344}, - {5353.76, -2116.28, 1299.27, 6.17894, 0, 0, 0.0521006, -0.998642}, - {5271.14, -2037.38, 1299.24, 4.07879, 0, 0, 0.892201, -0.451638}, - {5332.5 , -2181.28, 1279.95, 4.6906, 0, 0, 0.714768, -0.699362}, - {5108.2 , -2429.84, 1427.73, 4.5194, 0, 0, 0.771943, -0.635691} -}; - -float HordeFirePos[65][8]=//spawn points for the fire visuals (GO) in the horde base -{ - {5524.11, -2612.73, 1483.38, 1.96198, 0, 0, 0.831047, 0.556202}, - {5514.42, -2617.19, 1505.77, 1.82453, 0, 0, 0.790892, 0.611956}, - {5510.21, -2624.77, 1485.34, 1.71065, 0, 0, 0.754783, 0.655974}, - {5570.72, -2619.04, 1487.62, 0.728898, 0, 0, 0.356435, 0.93432}, - {5570.29, -2639.37, 1487.31, 1.49308, 0, 0, 0.679104, 0.734042}, - {5583.56, -2637.2, 1503.78, 1.46559, 0, 0, 0.668951, 0.743307}, - {5571.53, -2626.81, 1510.99, 0.362107, 0, 0, 0.180066, 0.983654}, - {5545.97, -2659.62, 1489.64, 5.07055, 0, 0, 0.569845, -0.821752}, - {5557.44, -2675.91, 1482.58, 1.70118, 0, 0, 0.751671, 0.659539}, - {5594.98, -2742.31, 1495.51, 4.5993, 0, 0, 0.74594, -0.666013}, - {5599.65, -2755.6, 1505.05, 1.66896, 0, 0, 0.740947, 0.671564}, - {5565.95, -2774.75, 1499.48, 6.22425, 0, 0, 0.0294611, -0.999566}, - {5567.1, -2769.7, 1511.17, 5.99257, 0, 0, 0.144799, -0.989461}, - {5572.84, -2774.16, 1527.06, 0.836428, 0, 0, 0.406129, 0.913816}, - {5538.32, -2805.94, 1498.87, 4.30082, 0, 0, 0.836674, -0.547701}, - {5515.66, -2801.74, 1503.53, 5.57316, 0, 0, 0.347602, -0.937642}, - {5516.76, -2827.14, 1501.15, 0.35026, 0, 0, 0.174236, 0.984704}, - {5536.13, -2813.51, 1537.21, 4.51681, 0, 0, 0.772765, -0.634692}, - {5525.05, -2825.16, 1538.53, 0.489275, 0, 0, 0.242205, 0.970225}, - {5534.42, -2815.45, 1562.84, 4.62834, 0, 0, 0.736191, -0.676774}, - {5519.64, -2831.12, 1526.46, 0.611008, 0, 0, 0.300774, 0.953696}, - {5551.04, -2827.55, 1523.5, 3.35206, 0, 0, 0.994468, -0.10504}, - {5469.22, -2802.87, 1503.5, 4.99509, 0, 0, 0.600436, -0.799673}, - {5427.8, -2737.26, 1487.12, 1.78673, 0, 0, 0.779186, 0.626793}, - {5454.1, -2709.1, 1485.92, 3.03552, 0, 0, 0.998594, 0.0530137}, - {5436.3, -2718.2, 1506.02, 2.7567, 0, 0, 0.981539, 0.191261}, - {5412.6, -2740.55, 1510.79, 2.98446, 0, 0, 0.996915, 0.0784832}, - {5406.12, -2752.48, 1521.01, 2.05769, 0, 0, 0.856705, 0.515807}, - {5445.24, -2676.35, 1521.89, 2.91378, 0, 0, 0.99352, 0.113661}, - {5481.4, -2665.08, 1482.23, 4.30001, 0, 0, 0.836895, -0.547363}, - {5443.51, -2675.44, 1487.12, 2.90986, 0, 0, 0.993295, 0.115606}, - {5391.72, -2647.3, 1528.9, 3.76987, 0, 0, 0.951063, -0.308997}, - {5421.09, -2734.12, 1521.01, 2.70567, 0, 0, 0.97634, 0.216242}, - {5405.39, -2710.33, 1533.77, 2.51324, 0, 0, 0.951052, 0.309032}, - {5423.96, -2703.76, 1516.34, 2.79206, 0, 0, 0.984767, 0.173879}, - {5444.75, -2735.23, 1486.37, 2.22657, 0, 0, 0.897155, 0.441715}, - {5570.98, -2747.91, 1495.7, 5.14433, 0, 0, 0.53915, -0.84221}, - {5567.79, -2673.9, 1484.66, 2.72529, 0, 0, 0.978415, 0.20665}, - {5600.71, -2696.8, 1500.42, 0.443704, 0, 0, 0.220036, 0.975492}, - {5600.7, -2693.04, 1515.2, 5.16003, 0, 0, 0.532522, -0.846416}, - {5627.56, -2839.66, 1510.53, 5.41527, 0, 0, 0.420463, -0.907309}, - {5622.02, -2868.71, 1516.22, 2.25482, 0, 0, 0.903303, 0.429002}, - {5586.61, -2878.97, 1510.34, 4.55604, 0, 0, 0.76017, -0.649724}, - {5583.78, -2843.71, 1509.54, 5.35715, 0, 0, 0.44665, -0.894709}, - {5580.95, -2811.3, 1513.3, 3.57587, 0, 0, 0.976518, -0.215434}, - {5542.52, -2869.31, 1523.13, 5.23304, 0, 0, 0.501275, -0.865288}, - {5557.35, -2866.36, 1518.76, 4.48299, 0, 0, 0.783388, -0.621533}, - {5380.91, -2849.36, 1512.81, 3.90962, 0, 0, 0.927168, -0.374646}, - {5395.76, -2881.41, 1521.11, 4.28426, 0, 0, 0.84118, -0.540755}, - {5374.87, -2859.63, 1528.98, 3.30252, 0, 0, 0.996765, -0.0803745}, - {5356.07, -2854.66, 1520.34, 5.83933, 0, 0, 0.220108, -0.975475}, - {5363.01, -2975.72, 1539.02, 4.13738, 0, 0, 0.87859, -0.477576}, - {5336.85, -2980.74, 1561.24, 5.11126, 0, 0, 0.553001, -0.83318}, - {5335.23, -2974.62, 1540.05, 5.04451, 0, 0, 0.580496, -0.814263}, - {5422.37, -2998.87, 1549.98, 4.51831, 0, 0, 0.772288, -0.635272}, - {5405.54, -3014.6, 1562.16, 5.86761, 0, 0, 0.206298, -0.978489}, - {5427.96, -3019.4, 1561.58, 3.53498, 0, 0, 0.980718, -0.19543}, - {5348.12, -2977.84, 1582.47, 3.94025, 0, 0, 0.921323, -0.388799}, - {5331.12, -2993.71, 1576.14, 0.0642734, 0, 0, 0.0321311, 0.999484}, - {5321.63, -2986.55, 1552.2, 5.29503, 0, 0, 0.474219, -0.880407}, - {5292.1, -2914.36, 1529.52, 2.9742, 0, 0, 0.996499, 0.083601}, - {5281.77, -2926.5, 1530.62, 1.67829, 0, 0, 0.744071, 0.6681}, - {5287.19, -2909.94, 1543.49, 3.31192, 0, 0, 0.996376, -0.0850591}, - {5534.15, -2679.35, 1483.61, 0.428685, 0, 0, 0.212705, 0.977116}, - {5545.43, -2647.82, 1483.05, 5.38848, 0, 0, 0.432578, -0.901596} -}; - -hyjalAI::hyjalAI(Creature *c) : npc_escortAI(c), Summons(me) -{ - pInstance = c->GetInstanceData(); - VeinsSpawned[0] = false; - VeinsSpawned[1] = false; - for (uint8 i=0; i<14; ++i) - VeinGUID[i] = 0; - InfernalCount = 0; - TeleportTimer = 1000; - Overrun = false; - Teleported = false; - WaitForTeleport = false; - OverrunCounter = 0; - OverrunCounter2 = 0; - InfernalPoint = 0; - RespawnTimer = 10000; - DoRespawn = false; - DoHide = false; - MassTeleportTimer = 0; - DoMassTeleport = false; -} - -void hyjalAI::JustSummoned(Creature *summoned) -{ - Summons.Summon(summoned); -} - -void hyjalAI::SummonedCreatureDespawn(Creature* summoned) -{ - Summons.Despawn(summoned); -} - -void hyjalAI::Reset() -{ - IsDummy = false; - me->setActive(true); - // GUIDs - PlayerGUID = 0; - BossGUID[0] = 0; - BossGUID[1] = 0; - - // Timers - NextWaveTimer = 10000; - CheckTimer = 0; - RetreatTimer = 1000; - - // Misc - WaveCount = 0; - EnemyCount = 0; - - // Set faction properly based on Creature entry - switch(me->GetEntry()) - { - case JAINA: - Faction = 0; - DoCast(me, SPELL_BRILLIANCE_AURA, true); - break; - - case THRALL: - Faction = 1; - break; - - case TYRANDE: - Faction = 2; - break; - } - - //Bools - EventBegun = false; - FirstBossDead = false; - SecondBossDead = false; - Summon = false; - bRetreat = false; - Debug = false; - - //Flags - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - //Initialize spells - memset(Spell, 0, sizeof(Spell)); - - //Reset Instance Data for trash count - if (pInstance) - { - if ((!pInstance->GetData(DATA_ALLIANCE_RETREAT) && me->GetEntry() == JAINA) || (pInstance->GetData(DATA_ALLIANCE_RETREAT) && me->GetEntry() == THRALL)) - { - //Reset World States - pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, 0); - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, 0); - pInstance->SetData(DATA_RESET_TRASH_COUNT, 0); - } - } else error_log(ERROR_INST_DATA); - - //Visibility - DoHide = true; -} - -void hyjalAI::EnterEvadeMode() -{ - if (me->GetEntry() != JAINA) - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(true); - me->LoadCreaturesAddon(); - - if (me->isAlive()) - me->GetMotionMaster()->MoveTargetedHome(); - - me->SetLootRecipient(NULL); -} - -void hyjalAI::EnterCombat(Unit * /*who*/) -{ - if (IsDummy)return; - for (uint8 i = 0; i < 3; ++i) - if (Spell[i].Cooldown) - SpellTimer[i] = Spell[i].Cooldown; - - Talk(ATTACKED); -} - -void hyjalAI::MoveInLineOfSight(Unit *who) -{ - if (IsDummy) - return; - - npc_escortAI::MoveInLineOfSight(who); -} - -void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) -{ - uint32 random = rand()%4; - float SpawnLoc[3]; - - for (uint8 i = 0; i < 3; ++i) - { - SpawnLoc[i] = Base[random][i]; - } - Creature* pCreature = NULL; - switch(entry) - { - case 17906: //GARGOYLE - - if (!FirstBossDead && (WaveCount == 1 || WaveCount == 3)) - {//summon at tower - pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0]+irand(-20,20), SpawnPointSpecial[SPAWN_NEAR_TOWER][1]+irand(-20,20), SpawnPointSpecial[SPAWN_NEAR_TOWER][2]+irand(-10,10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - if (pCreature) - CAST_AI(hyjal_trashAI, pCreature->AI())->useFlyPath = true; - }else{//summon at gate - pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_GARG_GATE][0]+irand(-10,10), SpawnPointSpecial[SPAWN_GARG_GATE][1]+irand(-10,10), SpawnPointSpecial[SPAWN_GARG_GATE][2]+irand(-10,10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - } - break; - case 17907: //FROST_WYRM , - if (FirstBossDead && WaveCount == 1) //summon at gate - pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_WYRM_GATE][0],SpawnPointSpecial[SPAWN_WYRM_GATE][1],SpawnPointSpecial[SPAWN_WYRM_GATE][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - else - { - pCreature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0], SpawnPointSpecial[SPAWN_NEAR_TOWER][1],SpawnPointSpecial[SPAWN_NEAR_TOWER][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - if (pCreature) - CAST_AI(hyjal_trashAI, pCreature->AI())->useFlyPath = true; - } - break; - case 17908: //GIANT_INFERNAL - ++InfernalCount; - if (InfernalCount > 7) - InfernalCount = 0; - pCreature = me->SummonCreature(entry, InfernalPos[InfernalCount][0], InfernalPos[InfernalCount][1], InfernalPos[InfernalCount][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - break; - default: - pCreature = me->SummonCreature(entry, SpawnLoc[0], SpawnLoc[1], SpawnLoc[2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - break; - - } - - if (pCreature) - { - // Increment Enemy Count to be used in World States and instance script - ++EnemyCount; - - pCreature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - pCreature->setActive(true); - switch(entry) - { - case NECROMANCER: - case ABOMINATION: - case GHOUL: - case BANSHEE: - case CRYPT_FIEND: - case GARGOYLE: - case FROST_WYRM: - case GIANT_INFERNAL: - case FEL_STALKER: - case RAGE_WINTERCHILL: - case ANETHERON: - case KAZROGAL: - case AZGALOR: - CAST_AI(hyjal_trashAI, pCreature->AI())->IsEvent = true; - break; - } - if (pInstance) - { - if (pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE) - pCreature->SetDisableReputationGain(true);//no repu for solo farming - } - // Check if Creature is a boss. - if (pCreature->isWorldBoss()) - { - if (!FirstBossDead) BossGUID[0] = pCreature->GetGUID(); - else BossGUID[1] = pCreature->GetGUID(); - CheckTimer = 5000; - } - } -} - -void hyjalAI::SummonNextWave(Wave wave[18], uint32 Count, float Base[4][3]) -{ - // 1 in 4 chance we give a rally yell. Not sure if the chance is offilike. - if (rand()%4 == 0) - Talk(RALLY); - - if (!pInstance) - { - error_log(ERROR_INST_DATA); - return; - } - InfernalCount = 0;//reset infernal count every new wave - - EnemyCount = pInstance->GetData(DATA_TRASH); - for (uint8 i = 0; i < 18; ++i) - { - if (wave[Count].Mob[i]) - SummonCreature(wave[Count].Mob[i], Base); - } - - if (!wave[Count].IsBoss) - { - uint32 stateValue = Count+1; - if (FirstBossDead) - stateValue -= 9; // Subtract 9 from it to give the proper wave number if we are greater than 8 - - // Set world state to our current wave number - pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, stateValue); // Set world state to our current wave number - // Enable world state - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 1); // Enable world state - - pInstance->SetData(DATA_TRASH, EnemyCount); // Send data for instance script to update count - - if (!Debug) - NextWaveTimer = wave[Count].WaveTimer; - else - { - NextWaveTimer = 15000; - debug_log("TSCR: HyjalAI: debug mode is enabled. Next Wave in 15 seconds"); - } - } - else - { - // Set world state for waves to 0 to disable it. - pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, 0); - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 1); - - // Set World State for enemies invading to 1. - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, 1); - - Summon = false; - } - CheckTimer = 5000; -} - -void hyjalAI::StartEvent(Player* pPlayer) -{ - if (!pPlayer || IsDummy || !pInstance) - return; - - Talk(BEGIN); - - EventBegun = true; - Summon = true; - - NextWaveTimer = 15000; - CheckTimer = 5000; - PlayerGUID = pPlayer->GetGUID(); - - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - pInstance->DoUpdateWorldState(WORLD_STATE_WAVES, 0); - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, 0); - - DeSpawnVeins(); -} - -uint32 hyjalAI::GetInstanceData(uint32 Event) -{ - if (pInstance) - return pInstance->GetData(Event); - else error_log(ERROR_INST_DATA); - - return 0; -} - -void hyjalAI::Talk(uint32 id) -{ - std::list index; - for (uint8 i = 0; i < 9; ++i) - { - if (Faction == 0) // Alliance - { - if (JainaQuotes[i].id == id) - index.push_back(i); - } - else if (Faction == 1) // Horde - { - if (ThrallQuotes[i].id == id) - index.push_back(i); - } - } - - if (index.empty()) - return; // No quotes found, no use to continue - - uint8 ind = *(index.begin()) + rand()%index.size(); - - int32 YellId = 0; - if (Faction == 0) // Alliance - { - YellId = JainaQuotes[ind].textid; - } - else if (Faction == 1) // Horde - { - YellId = ThrallQuotes[ind].textid; - } - - if (YellId) - DoScriptText(YellId, me); -} - -void hyjalAI::Retreat() -{ - if (pInstance) - { - pInstance->SetData(TYPE_RETREAT,SPECIAL); - - if (Faction == 0) - { - pInstance->SetData(DATA_ALLIANCE_RETREAT, 1); - AddWaypoint(0,JainaWPs[0][0],JainaWPs[0][1],JainaWPs[0][2]); - AddWaypoint(1,JainaWPs[1][0],JainaWPs[1][1],JainaWPs[1][2]); - Start(false, false); - SetDespawnAtEnd(false);//move to center of alliance base - } - if (Faction == 1) - { - pInstance->SetData(DATA_HORDE_RETREAT, 1); - Creature* JainaDummy = me->SummonCreature(JAINA,JainaDummySpawn[0][0],JainaDummySpawn[0][1],JainaDummySpawn[0][2],JainaDummySpawn[0][3],TEMPSUMMON_TIMED_DESPAWN,60000); - if (JainaDummy) - { - JainaDummy->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - CAST_AI(hyjalAI, JainaDummy->AI())->IsDummy = true; - DummyGuid = JainaDummy->GetGUID(); - } - AddWaypoint(0,JainaDummySpawn[1][0],JainaDummySpawn[1][1],JainaDummySpawn[1][2]); - Start(false, false); - SetDespawnAtEnd(false);//move to center of alliance base - } - } - SpawnVeins(); - Overrun = true; - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);//cant talk after overrun event started -} - -void hyjalAI::SpawnVeins() -{ - if (Faction == 0) - { - if (VeinsSpawned[0])//prevent any buggers - return; - for (uint8 i = 0; i<7; ++i) - { - GameObject* gem = me->SummonGameObject(ANCIENT_VEIN,VeinPos[i][0],VeinPos[i][1],VeinPos[i][2],VeinPos[i][3],VeinPos[i][4],VeinPos[i][5],VeinPos[i][6],VeinPos[i][7],0); - if (gem) - VeinGUID[i]=gem->GetGUID(); - } - VeinsSpawned[0] = true; - }else{ - if (VeinsSpawned[1]) - return; - for (uint8 i = 7; i<14; ++i) - { - GameObject* gem = me->SummonGameObject(ANCIENT_VEIN,VeinPos[i][0],VeinPos[i][1],VeinPos[i][2],VeinPos[i][3],VeinPos[i][4],VeinPos[i][5],VeinPos[i][6],VeinPos[i][7],0); - if (gem) - VeinGUID[i]=gem->GetGUID(); - } - VeinsSpawned[1] = true; - } -} - -void hyjalAI::DeSpawnVeins() -{ - if (!pInstance) - return; - if (Faction == 1) - { - Creature* pUnit=Unit::GetCreature((*me),pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (!pUnit)return; - hyjalAI* ai = CAST_AI(hyjalAI, pUnit->AI()); - if (!ai)return; - for (uint8 i = 0; i<7; ++i) - { - if (GameObject* gem = pInstance->instance->GetGameObject(pInstance->GetData64(ai->VeinGUID[i]))) - gem->Delete(); - } - } else if (Faction) - { - Creature* pUnit=Unit::GetCreature((*me),pInstance->GetData64(DATA_THRALL)); - if (!pUnit)return; - hyjalAI* ai = CAST_AI(hyjalAI, pUnit->AI()); - if (!ai)return; - for (uint8 i = 7; i<14; ++i) - { - if (GameObject* gem = pInstance->instance->GetGameObject(pInstance->GetData64(ai->VeinGUID[i]))) - gem->Delete(); - } - } -} - -void hyjalAI::UpdateAI(const uint32 diff) -{ - if (IsDummy) - { - if (MassTeleportTimer < diff && DoMassTeleport) - { - DoCast(me, SPELL_MASS_TELEPORT, false); - DoMassTeleport = false; - } else MassTeleportTimer -= diff; - return; - } - if (DoHide) - { - DoHide = false; - switch(me->GetEntry()) - { - case JAINA: - if (pInstance && pInstance->GetData(DATA_ALLIANCE_RETREAT)) - { - me->SetVisibility(VISIBILITY_OFF); - HideNearPos(me->GetPositionX(), me->GetPositionY()); - HideNearPos(5037.76, -1889.71); - for (uint8 i = 0; i < 92; ++i)//summon fires - me->SummonGameObject(FLAMEOBJECT,AllianceFirePos[i][0],AllianceFirePos[i][1],AllianceFirePos[i][2],AllianceFirePos[i][3],AllianceFirePos[i][4],AllianceFirePos[i][5],AllianceFirePos[i][6],AllianceFirePos[i][7],0); - - } - else me->SetVisibility(VISIBILITY_ON); - break; - case THRALL: //thrall - if (pInstance && pInstance->GetData(DATA_HORDE_RETREAT)) - { - me->SetVisibility(VISIBILITY_OFF); - HideNearPos(me->GetPositionX(), me->GetPositionY()); - HideNearPos(5563, -2763.19); - HideNearPos(5542.2, -2629.36); - for (uint8 i = 0; i < 65; ++i)//summon fires - me->SummonGameObject(FLAMEOBJECT,HordeFirePos[i][0],HordeFirePos[i][1],HordeFirePos[i][2],HordeFirePos[i][3],HordeFirePos[i][4],HordeFirePos[i][5],HordeFirePos[i][6],HordeFirePos[i][7],0); - - } - else me->SetVisibility(VISIBILITY_ON); - break; - } - } - if (DoRespawn) - { - if (RespawnTimer <= diff) - { - DoRespawn = false; - RespawnNearPos(me->GetPositionX(), me->GetPositionY()); - if (Faction == 0) - { - RespawnNearPos(5037.76, -1889.71); - } else if (Faction == 1) - { - RespawnNearPos(5563, -2763.19); - RespawnNearPos(5542.2, -2629.36); - } - me->SetVisibility(VISIBILITY_ON); - }else{ - RespawnTimer -= diff; - me->SetVisibility(VISIBILITY_OFF); - } - return; - } - if (Overrun) - DoOverrun(Faction, diff); - if (bRetreat) - { - if (RetreatTimer <= diff) - { - IsDummy = true; - bRetreat = false; - HideNearPos(me->GetPositionX(), me->GetPositionY()); - switch(me->GetEntry()) - { - case JAINA://jaina - HideNearPos(5037.76, -1889.71); - break; - case THRALL://thrall - HideNearPos(5563, -2763.19); - HideNearPos(5542.2, -2629.36); - HideNearPos(5603.75, -2853.12); - break; - } - me->SetVisibility(VISIBILITY_OFF); - } else RetreatTimer -= diff; - } - - if (!EventBegun) - return; - - if (Summon) - { - if (pInstance && EnemyCount) - { - EnemyCount = pInstance->GetData(DATA_TRASH); - if (!EnemyCount) - NextWaveTimer = 5000; - } - - if (NextWaveTimer <= diff) - { - if (Faction == 0) - SummonNextWave(AllianceWaves, WaveCount, AllianceBase); - else if (Faction == 1) - SummonNextWave(HordeWaves, WaveCount, HordeBase); - ++WaveCount; - } else NextWaveTimer -= diff; - } - - if (CheckTimer <= diff) - { - for (uint8 i = 0; i < 2; ++i) - { - if (BossGUID[i]) - { - Unit* pUnit = Unit::GetUnit((*me), BossGUID[i]); - if (pUnit && (!pUnit->isAlive())) - { - if (BossGUID[i] == BossGUID[0]) - { - Talk(INCOMING); - FirstBossDead = true; - } - else if (BossGUID[i] == BossGUID[1]) - { - Talk(SUCCESS); - SecondBossDead = true; - } - EventBegun = false; - CheckTimer = 0; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - BossGUID[i] = 0; - if (pInstance) - pInstance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); // Reset world state for enemies to disable it - } - } - } - CheckTimer = 5000; - } else CheckTimer -= diff; - - if (!UpdateVictim()) - return; - - for (uint8 i = 0; i < 3; ++i) - { - if (Spell[i].SpellId) - { - if (SpellTimer[i] <= diff) - { - if (me->IsNonMeleeSpellCasted(false)) - me->InterruptNonMeleeSpells(false); - - Unit *pTarget = NULL; - - switch(Spell[i].TargetType) - { - case TARGETTYPE_SELF: pTarget = me; break; - case TARGETTYPE_RANDOM: pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); break; - case TARGETTYPE_VICTIM: pTarget = me->getVictim(); break; - } - - if (pTarget && pTarget->isAlive()) - { - DoCast(pTarget, Spell[i].SpellId); - SpellTimer[i] = Spell[i].Cooldown; - } - } else SpellTimer[i] -= diff; - } - } - - DoMeleeAttackIfReady(); -} -void hyjalAI::JustDied(Unit* /*killer*/) -{ - if (IsDummy)return; - me->Respawn(); - me->SetVisibility(VISIBILITY_OFF); - DoRespawn = true; - RespawnTimer = 120000; - Talk(DEATH); - Summons.DespawnAll();//despawn all wave's summons - if (pInstance) - {//reset encounter if boss is despawned (ex: thrall is killed, boss despawns, event stucks at inprogress) - if (pInstance->GetData(DATA_RAGEWINTERCHILLEVENT) == IN_PROGRESS) - pInstance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED); - if (pInstance->GetData(DATA_ANETHERONEVENT) == IN_PROGRESS) - pInstance->SetData(DATA_ANETHERONEVENT, NOT_STARTED); - if (pInstance->GetData(DATA_KAZROGALEVENT) == IN_PROGRESS) - pInstance->SetData(DATA_KAZROGALEVENT, NOT_STARTED); - if (pInstance->GetData(DATA_AZGALOREVENT) == IN_PROGRESS) - pInstance->SetData(DATA_AZGALOREVENT, NOT_STARTED); - pInstance->SetData(DATA_RESET_RAIDDAMAGE, NULL);//reset damage on die - } -} -void hyjalAI::HideNearPos(float x, float y) -{ - CellPair pair(Trinity::ComputeCellPair(x, y)); - Cell cell(pair); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - // First get all creatures. - std::list creatures; - Trinity::AllFriendlyCreaturesInGrid creature_check(me); - Trinity::CreatureListSearcher creature_searcher(me, creatures, creature_check); - TypeContainerVisitor - , - GridTypeMapContainer> creature_visitor(creature_searcher); - - // Get Creatures - cell.Visit(pair, creature_visitor, *(me->GetMap())); - - if (!creatures.empty()) - { - for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) - { - (*itr)->SetVisibility(VISIBILITY_OFF); - (*itr)->setFaction(35);//make them friendly so mobs won't attack them - } - } -} -void hyjalAI::RespawnNearPos(float x, float y) -{ - CellPair p(Trinity::ComputeCellPair(x, y)); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - Trinity::RespawnDo u_do; - Trinity::WorldObjectWorker worker(me, u_do); - TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); - cell.Visit(p, obj_worker, *me->GetMap()); -} -void hyjalAI::WaypointReached(uint32 i) -{ - if (i == 1 || (i == 0 && me->GetEntry() == THRALL)) - { - me->MonsterYell(YELL_HURRY,0,0); - WaitForTeleport = true; - TeleportTimer = 20000; - if (me->GetEntry() == JAINA) - DoCast(me, SPELL_MASS_TELEPORT, false); - if (me->GetEntry() == THRALL && DummyGuid) - { - Unit* Dummy = Unit::GetUnit((*me),DummyGuid); - if (Dummy) - { - CAST_AI(hyjalAI, CAST_CRE(Dummy)->AI())->DoMassTeleport = true; - CAST_AI(hyjalAI, CAST_CRE(Dummy)->AI())->MassTeleportTimer = 20000; - Dummy->CastSpell(me, SPELL_MASS_TELEPORT, false); - } - } - //do some talking - //all alive guards walk near here - CellPair pair(Trinity::ComputeCellPair(me->GetPositionX(), me->GetPositionY())); - Cell cell(pair); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - // First get all creatures. - std::list creatures; - Trinity::AllFriendlyCreaturesInGrid creature_check(me); - Trinity::CreatureListSearcher creature_searcher(me, creatures, creature_check); - TypeContainerVisitor - , - GridTypeMapContainer> creature_visitor(creature_searcher); - - cell.Visit(pair, creature_visitor, *(me->GetMap())); - - if (!creatures.empty()) - { - for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) - { - if ((*itr) && (*itr)->isAlive() && (*itr) != me && (*itr)->GetEntry() != JAINA) - { - if (!(*itr)->IsWithinDist(me, 60)) - (*itr)->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - float x, y, z; - (*itr)->SetDefaultMovementType(IDLE_MOTION_TYPE); - (*itr)->GetMotionMaster()->Initialize(); - float range = 10; - if (me->GetEntry() == THRALL)range = 20; - me->GetNearPoint(me, x, y, z, range, 0, me->GetAngle((*itr))); - (*itr)->GetMotionMaster()->MovePoint(0, x+irand(-5,5), y+irand(-5,5), me->GetPositionZ()); - } - } - } - } -} -void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) -{ - npc_escortAI::UpdateAI(diff); - if (WaitForTeleport) - { - if (TeleportTimer <= diff) - { - CellPair pair(Trinity::ComputeCellPair(me->GetPositionX(), me->GetPositionY())); - Cell cell(pair); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - - std::list creatures; - Trinity::AllFriendlyCreaturesInGrid creature_check(me); - Trinity::CreatureListSearcher creature_searcher(me, creatures, creature_check); - TypeContainerVisitor - , - GridTypeMapContainer> creature_visitor(creature_searcher); - - cell.Visit(pair, creature_visitor, *(me->GetMap())); - - if (!creatures.empty()) - { - for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) - { - if ((*itr) && (*itr)->isAlive()) - { - (*itr)->CastSpell(*itr, SPELL_TELEPORT_VISUAL, true); - (*itr)->setFaction(35);//make them friendly so mobs won't attack them - (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - } - DoCast(me, SPELL_TELEPORT_VISUAL); - bRetreat = true; - RetreatTimer = 1000; - } - - WaitForTeleport = false; - Teleported = true; - }TeleportTimer -= diff; - } - if (!Teleported) - return; - Overrun = false;//execute once - switch(faction) - { - case 0://alliance - for (uint8 i = 0; i < 92; ++i)//summon fires - me->SummonGameObject(FLAMEOBJECT,AllianceFirePos[i][0],AllianceFirePos[i][1],AllianceFirePos[i][2],AllianceFirePos[i][3],AllianceFirePos[i][4],AllianceFirePos[i][5],AllianceFirePos[i][6],AllianceFirePos[i][7],0); - - for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls - { - uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(GHOUL, AllianceBase[r][0]+irand(-15,15), AllianceBase[r][1]+irand(-15,15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) - { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); - } - } - for (uint8 i = 0; i < 3; ++i)//summon 3 abominations - { - uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15,15), AllianceBase[r][1]+irand(-15,15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) - { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); - } - } - for (uint8 i = 0; i < 5; ++i)//summon 5 gargoyles - { - Creature* pUnit = me->SummonCreature(GARGOYLE, AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) - { - pUnit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]); - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); - } - } - break; - case 1://horde - for (uint8 i = 0; i < 65; ++i)//summon fires - me->SummonGameObject(FLAMEOBJECT,HordeFirePos[i][0],HordeFirePos[i][1],HordeFirePos[i][2],HordeFirePos[i][3],HordeFirePos[i][4],HordeFirePos[i][5],HordeFirePos[i][6],HordeFirePos[i][7],0); - - for (uint8 i = 0; i < 26; ++i)//summon infernals - { - Creature* pUnit = me->SummonCreature(GIANT_INFERNAL, InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) - { - pUnit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]); - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); - } - } - for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls - { - uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15,15), HordeBase[r][1]+irand(-15,15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) - { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); - } - } - for (uint8 i = 0; i < 5; ++i)//summon 5 abominations - { - uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15,15), HordeBase[r][1]+irand(-15,15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) - { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); - } - } - break; - } -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.h deleted file mode 100644 index 5c75465b7b4..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjalAI.h +++ /dev/null @@ -1,248 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software licensed under GPL version 2 - * Please see the included DOCS/LICENSE.TXT for more information */ - -#ifndef SC_HYJALAI_H -#define SC_HYJALAI_H - -#include "hyjal.h" -#include "ScriptedEscortAI.h" - -// Trash Mobs summoned in waves -#define NECROMANCER 17899//done -#define ABOMINATION 17898//done -#define GHOUL 17895//done -#define BANSHEE 17905//done -#define CRYPT_FIEND 17897//done -#define GARGOYLE 17906//done -#define FROST_WYRM 17907//done -#define GIANT_INFERNAL 17908//done -#define FEL_STALKER 17916//done - -#define JAINA 17772 -#define THRALL 17852 -#define TYRANDE 17948 - -#define ANCIENT_VEIN 185557 -#define FLAMEOBJECT 182592 - -// Bosses summoned after every 8 waves -#define RAGE_WINTERCHILL 17767 -#define ANETHERON 17808 -#define KAZROGAL 17888 -#define AZGALOR 17842 -#define ARCHIMONDE 17968 - -#define SPELL_TELEPORT_VISUAL 41232 -#define SPELL_MASS_TELEPORT 16807 - -//Spells for Jaina -#define SPELL_BRILLIANCE_AURA 31260 // The database must handle this spell via creature_addon(it should, but is removed in evade..) -#define SPELL_BLIZZARD 31266 -#define SPELL_PYROBLAST 31263 -#define SPELL_SUMMON_ELEMENTALS 31264 - -//Thrall spells -#define SPELL_CHAIN_LIGHTNING 31330 -#define SPELL_SUMMON_DIRE_WOLF 31331 - -struct Wave -{ - uint32 Mob[18]; // Stores Creature Entries to be summoned in Waves - uint32 WaveTimer; // The timer before the next wave is summoned - bool IsBoss; // Simply used to inform the wave summoner that the next wave contains a boss to halt all waves after that -}; - -static Wave AllianceWaves[]= // Waves that will be summoned in the Alliance Base -{ // Rage Winterchill Wave 1-8 - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, - // All 8 Waves are summoned, summon Rage Winterchill, next few waves are for Anetheron - {RAGE_WINTERCHILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true}, - // Anetheron Wave 1-8 - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, - {NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 120000, false}, - {CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, BANSHEE, BANSHEE, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, GHOUL, GHOUL, 0, 0, 0, 0, 120000, false}, - {GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, - // All 8 Waves are summoned, summon Anatheron - {ANETHERON, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true} -}; - -static Wave HordeWaves[]= // Waves that are summoned in the Horde base -{ // Kaz'Rogal Wave 1-8 - {GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, - {CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, - {GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 240000, false}, - // All 8 Waves are summoned, summon Kaz'Rogal, next few waves are for Azgalor - {KAZROGAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true}, - // Azgalor Wave 1-8 - {ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, FROST_WYRM, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0, 180000, false}, - {GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, 0, 0, 0, 0, 180000, false}, - {FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 180000, false}, - {NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0, 180000, false}, - {GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0, 180000, false}, - {CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 240000, false}, - // All 8 Waves are summoned, summon Azgalor - {AZGALOR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true} -}; - -enum TargetType // Used in the spell cast system for the AI -{ - TARGETTYPE_SELF = 0, - TARGETTYPE_RANDOM = 1, - TARGETTYPE_VICTIM = 2, -}; - -struct Yells -{ - uint32 id; // Used to determine the type of yell (attack, rally, etc) - int32 textid; // The text id to be yelled -}; - -enum YellId -{ - ATTACKED = 0, // Used when attacked and set in combat - BEGIN = 1, // Used when the event is begun - INCOMING = 2, // Used to warn the raid that another wave phase is coming - RALLY = 3, // Used to rally the raid and warn that the next wave has been summoned - FAILURE = 4, // Used when raid has failed (unsure where to place) - SUCCESS = 5, // Used when the raid has sucessfully defeated a wave phase - DEATH = 6, // Used on death -}; - -static Yells JainaQuotes[]= -{ - {ATTACKED, -1534000}, - {ATTACKED, -1534001}, - {INCOMING, -1534002}, - {BEGIN, -1534003}, - {RALLY, -1534004}, - {RALLY, -1534005}, - {FAILURE, -1534006}, - {SUCCESS, -1534007}, - {DEATH, -1534008}, -}; - -static Yells ThrallQuotes[]= -{ - {ATTACKED, -1534009}, - {ATTACKED, -1534010}, - {INCOMING, -1534011}, - {BEGIN, -1534012}, - {RALLY, -1534013}, - {RALLY, -1534014}, - {FAILURE, -1534015}, - {SUCCESS, -1534016}, - {DEATH, -1534017}, -}; - -struct hyjalAI : public npc_escortAI -{ - hyjalAI(Creature *c); - - void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat - - void EnterEvadeMode(); // Send creature back to spawn location and evade. - - void EnterCombat(Unit * /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack - - void UpdateAI(const uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells. - - void JustDied(Unit* /*killer*/); // Called on death, informs the raid that they have failed. - - void SetFaction(uint32 _faction) // Set the faction to either Alliance or Horde in Hyjal - { - Faction = _faction; - } - - void Retreat(); // "Teleport" (teleport visual + set invisible) all friendly creatures away from the base. - - void SpawnVeins(); - void DeSpawnVeins(); - void JustSummoned(Creature *summoned); - void SummonedCreatureDespawn(Creature* summoned); - void HideNearPos(float x, float y); - void RespawnNearPos(float x, float y); - void WaypointReached(uint32 i); - void DoOverrun(uint32 faction, const uint32 diff); - void MoveInLineOfSight(Unit *who); - - void SummonCreature(uint32 entry, float Base[4][3]); // Summons a creature for that wave in that base - - // Summons the next wave, calls SummonCreature - void SummonNextWave(Wave wave[18], uint32 Count, float Base[4][3]); - - void StartEvent(Player* player); // Begins the event by gossip click - - uint32 GetInstanceData(uint32 Event); // Gets instance data for this instance, used to check if raid has gotten past a certain point and can access the next phase - - void Talk(uint32 id); // Searches for the appropriate yell and sound and uses it to inform the raid of various things - - public: - ScriptedInstance* pInstance; - - uint64 PlayerGUID; - uint64 BossGUID[2]; - uint64 VeinGUID[14]; - - uint32 NextWaveTimer; - uint32 WaveCount; - uint32 CheckTimer; - uint32 Faction; - uint32 EnemyCount; - uint32 RetreatTimer; - - bool EventBegun; - bool FirstBossDead; - bool SecondBossDead; - bool Summon; - bool bRetreat; - bool Debug; - bool VeinsSpawned[2]; - uint8 InfernalCount; - SummonList Summons; - bool Overrun; - bool Teleported; - bool WaitForTeleport; - uint32 TeleportTimer; - uint32 OverrunCounter; - uint32 OverrunCounter2; - uint32 InfernalPoint; - uint32 RespawnTimer; - bool DoRespawn; - bool DoHide; - bool IsDummy; - uint32 MassTeleportTimer; - bool DoMassTeleport; - uint64 DummyGuid; - - struct Spell - { - uint32 SpellId; - uint32 Cooldown; - uint32 TargetType; - }Spell[3]; - - private: - uint32 SpellTimer[3]; - //std::list CreatureList; -}; -#endif - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.cpp deleted file mode 100644 index c4cf9ede397..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.cpp +++ /dev/null @@ -1,1440 +0,0 @@ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "hyjal_trash.h" -#include "hyjalAI.h" - -#define SPELL_METEOR 33814 //infernal visual -#define SPELL_IMMOLATION 37059 -#define SPELL_FLAME_BUFFET 31724 -#define NPC_TRIGGER 21987 //World Trigger (Tiny) -#define MODEL_INVIS 11686 //invisible model - -float HordeWPs[8][3]=//basic waypoints from spawn to leader -{ - {5492.91, -2404.61, 1462.63}, - {5531.76, -2460.87, 1469.55}, - {5554.58, -2514.66, 1476.12}, - {5554.16, -2567.23, 1479.90}, - {5540.67, -2625.99, 1480.89}, - {5508.16, -2659.20, 1480.15},//random rush starts from here - {5489.62, -2704.05, 1482.18}, - {5457.04, -2726.26, 1485.10} -}; -float AllianceWPs[8][3]=//basic waypoints from spawn to leader -{ - {4896.08, -1576.35, 1333.65}, - {4898.68, -1615.02, 1329.48}, - {4907.12, -1667.08, 1321.00}, - {4963.18, -1699.35, 1340.51}, - {4989.16, -1716.67, 1335.74},//first WP in the base, after the gate - {5026.27, -1736.89, 1323.02}, - {5037.77, -1770.56, 1324.36}, - {5067.23, -1789.95, 1321.17} -}; - -float FrostWyrmWPs[3][3]=//waypoints for the frost wyrms in horde base -{ - {5580.82, -2628.83, 1528.28}, - {5550.90, -2667.16, 1505.45}, - {5459.64, -2725.91, 1484.83} -}; - -float GargoyleWPs[3][3]=//waypoints for the gargoyles in horde base -{ - {5533.66, -2634.32, 1495.33}, - {5517.88, -2712.05, 1490.54}, - {5459.64, -2725.91, 1484.83} -}; - -float FlyPathWPs[3][3]=//waypoints for the gargoyls and frost wyrms in horde base in wave 1/3 -{ - {5531.96, -2772.83, 1516.68}, - {5498.32, -2734.84, 1497.01}, - {5456.67, -2725.48, 1493.08} -}; - -float AllianceOverrunWP[55][3]=//waypoints in the alliance base used in the end in the cleaning wave -{ - {4976.37,-1708.02,1339.43},//0spawn - {4994.83,-1725.52,1333.25},//1 start - {4982.92,-1753.7,1330.69},//2 end - {4996.75,-1721.47,1332.95},//3 start - {5015.74,-1755.05,1322.49},//4 - {4998.68,-1773.44,1329.59},//5 - {4994.83,-1725.52,1333.25},//6 start - {5022.8,-1735.46,1323.53},//7 - {5052.15,-1729.02,1320.88},//8 - {5082.43,-1726.29,1327.87},//9 - {4994.83,-1725.52,1333.25},//10 start - {5018.92,-1751.14,1322.19},//11 - {5040.09,-1792.09,1322.1},//12 - {4994.83,-1725.52,1333.25},//13 start - {5023.47,-1748.1,1322.51},//14 - {5013.43,-1842.39,1322.07},//15 - {4994.83,-1725.52,1333.25},//16 start - {5020.8,-1756.86,1322.2},//17 - {5019.53,-1824.6,1321.96},//18 - {5043.42,-1853.75,1324.52},//19 - {5053.02,-1864.13,1330.36},//20 - {5062.49,-1852.47,1330.49},//21 - {5015.27, -1738.77, 1324.83},//35//start 22 - {5027.97, -1775.25, 1321.87},//34 23 - {5015.94, -1821.24, 1321.86},//33 24 - {4983.25, -1857.4, 1320.48},//32 25 - {4981.51, -1883.7, 1322.34},//31 26 - {5002.33, -1893.98, 1325.88},//30 27 - {5049.32, -1886.54, 1331.69},//29 28 - {5089.68, -1846.88, 1328.99},//28 29 - {5127.90, -1825.14, 1335.58},//27 30 - {5163.27, -1789.08, 1337.04},//26 31 - {5138.97, -1755.88, 1334.57},//25 32 - {5096.63, -1742.22, 1329.61},//24 33 - {5065.81, -1729.43, 1325.66},//23 34 - {5049.32, -1726.31, 1320.64},//22 start - {5081.07, -1902.10, 1346.36},//36 abo start - {5107.65, -1912.03, 1356.49},//37 - {5132.83, -1927.07, 1362.42},//38 - {5147.78, -1954.41, 1365.98},//39 - {5164.96, -1966.48, 1367.04},//40 - {5189.04, -1961.06, 1367.90},//41 - {5212.27, -1975.30, 1365.58},//42 - {5221.82, -1994.18, 1364.97},//43 end1 - {5202.23, -1994.94, 1367.59},//44 end2 - {5279.94, -2049.68, 1311.38},//45 garg1 - {5289.15, -2219.06, 1291.12},//46 garg2 - {5202.07, -2136.10, 1305.07},//47 garg3 - {5071.52, -2425.63, 1454.48},//48 garg4 - {5120.65, -2467.92, 1463.93},//49 garg5 - {5283.04, -2043.26, 1300.11},//50 garg target1 - {5313.22, -2207.60, 1290.06},//51 garg target2 - {5180.41, -2121.87, 1292.62},//52 garg target3 - {5088.68, -2432.04, 1441.73},//53 garg target4 - {5111.26, -2454.73, 1449.63}//54 garg target5 - -}; - -float HordeOverrunWP[21][3]=//waypoints in the horde base used in the end in the cleaning wave -{ - {5490.72,-2702.94,1482.14},//0 start - {5469.77,-2741.34,1486.95}, - {5439.47,-2771.02,1494.59}, - {5408.85,-2811.92,1505.68}, - {5423.87,-2857.80,1515.55}, - {5428.19,-2898.15,1524.61}, - {5394.59,-2930.05,1528.23}, - {5351.11,-2935.80,1532.24}, - {5312.37,-2959.06,1536.21}, - {5264.93,-2989.80,1545.70}, - {5256.63,-3056.16,1559.24}, - {5267.32,-3119.55,1575.36}, - {5305.61,-3139.88,1586.38}, - {5330.56,-3135.37,1588.58}, - {5365.87,-3139.78,1583.96}, - {5389.39,-3163.57,1582.57},//15 end - {5500.86,-2669.89,1481.04},//16 start - {5472.08,-2715.14,1483.55}, - {5450.11,-2721.47,1485.61}, - {5433.25,-2712.93,1493.02},//19 end 1 - {5429.91,-2718.44,1493.42}//20 end 2 -}; - -hyjal_trashAI::hyjal_trashAI(Creature *c) : npc_escortAI(c) -{ - pInstance = c->GetInstanceData(); - IsEvent = false; - Delay = 0; - LastOverronPos = 0; - IsOverrun = false; - OverrunType = 0; - SetupOverrun = false; - faction = 0; - useFlyPath = false; - damageTaken = 0; - Reset(); -} - -void hyjal_trashAI::DamageTaken(Unit *done_by, uint32 &damage) -{ - if (done_by->GetTypeId() == TYPEID_PLAYER || (done_by->GetTypeId() == TYPEID_UNIT && CAST_CRE(done_by)->isPet())) - { - damageTaken += damage; - if (pInstance) - pInstance->SetData(DATA_RAIDDAMAGE,damage);//store raid's damage - } -} - -void hyjal_trashAI::UpdateAI(const uint32 /*diff*/) -{ - if (IsOverrun && !SetupOverrun) - { - SetupOverrun = true; - if (faction == 0) - { - if (me->GetEntry() == GARGOYLE) - { - DummyTarget[0] = AllianceOverrunWP[50+OverrunType][0]; //+OverrunType 0 - 4 - DummyTarget[1] = AllianceOverrunWP[50+OverrunType][1]; - DummyTarget[2] = AllianceOverrunWP[50+OverrunType][2]; - } - if (me->GetEntry() == ABOMINATION) - { - for (uint8 i = 0; i < 4; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - switch(OverrunType) - { - case 0: - AddWaypoint(4, AllianceOverrunWP[22][0]+irand(-3,3), AllianceOverrunWP[22][1]+irand(-3,3), AllianceOverrunWP[22][2]); - AddWaypoint(5, AllianceOverrunWP[23][0]+irand(-3,3), AllianceOverrunWP[23][1]+irand(-3,3), AllianceOverrunWP[23][2]); - AddWaypoint(6, AllianceOverrunWP[24][0]+irand(-3,3), AllianceOverrunWP[24][1]+irand(-3,3), AllianceOverrunWP[24][2]); - AddWaypoint(7, AllianceOverrunWP[25][0]+irand(-3,3), AllianceOverrunWP[25][1]+irand(-3,3), AllianceOverrunWP[25][2]); - AddWaypoint(8, AllianceOverrunWP[26][0]+irand(-3,3), AllianceOverrunWP[26][1]+irand(-3,3), AllianceOverrunWP[26][2]); - AddWaypoint(9, AllianceOverrunWP[27][0]+irand(-3,3), AllianceOverrunWP[27][1]+irand(-3,3), AllianceOverrunWP[27][2]); - AddWaypoint(10, AllianceOverrunWP[28][0]+irand(-3,3), AllianceOverrunWP[28][1]+irand(-3,3), AllianceOverrunWP[28][2]); - - AddWaypoint(11, AllianceOverrunWP[36][0]+irand(-3,3), AllianceOverrunWP[36][1]+irand(-3,3), AllianceOverrunWP[36][2]); - AddWaypoint(12, AllianceOverrunWP[37][0]+irand(-3,3), AllianceOverrunWP[37][1]+irand(-3,3), AllianceOverrunWP[37][2]); - AddWaypoint(13, AllianceOverrunWP[38][0]+irand(-3,3), AllianceOverrunWP[38][1]+irand(-3,3), AllianceOverrunWP[38][2]); - AddWaypoint(14, AllianceOverrunWP[39][0]+irand(-3,3), AllianceOverrunWP[39][1]+irand(-3,3), AllianceOverrunWP[39][2]); - AddWaypoint(15, AllianceOverrunWP[40][0]+irand(-3,3), AllianceOverrunWP[40][1]+irand(-3,3), AllianceOverrunWP[40][2]); - AddWaypoint(16, AllianceOverrunWP[41][0]+irand(-3,3), AllianceOverrunWP[41][1]+irand(-3,3), AllianceOverrunWP[41][2]); - AddWaypoint(17, AllianceOverrunWP[42][0]+irand(-3,3), AllianceOverrunWP[42][1]+irand(-3,3), AllianceOverrunWP[42][2]); - AddWaypoint(18, AllianceOverrunWP[43][0]+irand(-3,3), AllianceOverrunWP[43][1]+irand(-3,3), AllianceOverrunWP[43][2]); - me->SetHomePosition(AllianceOverrunWP[43][0]+irand(-3,3), AllianceOverrunWP[43][1]+irand(-3,3), AllianceOverrunWP[43][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 18; - Start(true, true); - break; - case 1: - AddWaypoint(4, AllianceOverrunWP[22][0]+irand(-3,3), AllianceOverrunWP[22][1]+irand(-3,3), AllianceOverrunWP[22][2]); - AddWaypoint(5, AllianceOverrunWP[23][0]+irand(-3,3), AllianceOverrunWP[23][1]+irand(-3,3), AllianceOverrunWP[23][2]); - AddWaypoint(6, AllianceOverrunWP[24][0]+irand(-3,3), AllianceOverrunWP[24][1]+irand(-3,3), AllianceOverrunWP[24][2]); - AddWaypoint(7, AllianceOverrunWP[25][0]+irand(-3,3), AllianceOverrunWP[25][1]+irand(-3,3), AllianceOverrunWP[25][2]); - AddWaypoint(8, AllianceOverrunWP[26][0]+irand(-3,3), AllianceOverrunWP[26][1]+irand(-3,3), AllianceOverrunWP[26][2]); - AddWaypoint(9, AllianceOverrunWP[27][0]+irand(-3,3), AllianceOverrunWP[27][1]+irand(-3,3), AllianceOverrunWP[27][2]); - AddWaypoint(10, AllianceOverrunWP[28][0]+irand(-3,3), AllianceOverrunWP[28][1]+irand(-3,3), AllianceOverrunWP[28][2]); - - AddWaypoint(11, AllianceOverrunWP[36][0]+irand(-3,3), AllianceOverrunWP[36][1]+irand(-3,3), AllianceOverrunWP[36][2]); - AddWaypoint(12, AllianceOverrunWP[37][0]+irand(-3,3), AllianceOverrunWP[37][1]+irand(-3,3), AllianceOverrunWP[37][2]); - AddWaypoint(13, AllianceOverrunWP[38][0]+irand(-3,3), AllianceOverrunWP[38][1]+irand(-3,3), AllianceOverrunWP[38][2]); - AddWaypoint(14, AllianceOverrunWP[39][0]+irand(-3,3), AllianceOverrunWP[39][1]+irand(-3,3), AllianceOverrunWP[39][2]); - AddWaypoint(15, AllianceOverrunWP[40][0]+irand(-3,3), AllianceOverrunWP[40][1]+irand(-3,3), AllianceOverrunWP[40][2]); - AddWaypoint(16, AllianceOverrunWP[41][0]+irand(-3,3), AllianceOverrunWP[41][1]+irand(-3,3), AllianceOverrunWP[41][2]); - AddWaypoint(17, AllianceOverrunWP[42][0]+irand(-3,3), AllianceOverrunWP[42][1]+irand(-3,3), AllianceOverrunWP[42][2]); - AddWaypoint(18, AllianceOverrunWP[44][0]+irand(-3,3), AllianceOverrunWP[44][1]+irand(-3,3), AllianceOverrunWP[44][2]); - me->SetHomePosition(AllianceOverrunWP[44][0]+irand(-3,3), AllianceOverrunWP[44][1]+irand(-3,3), AllianceOverrunWP[44][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 18; - Start(true, true); - break; - default: - for (uint8 i = 22; i < 36; ++i) - AddWaypoint(i-18, AllianceOverrunWP[i][0]+irand(-3,3), AllianceOverrunWP[i][1]+irand(-3,3), AllianceOverrunWP[i][2]); - - SetDespawnAtEnd(true); - LastOverronPos = 17; - Start(true, true); - break; - } - } - if (me->GetEntry() == GHOUL) - { - for (uint8 i = 0; i < 4; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - switch(OverrunType) - { - case 0: - AddWaypoint(4, AllianceOverrunWP[1][0]+irand(-3,3), AllianceOverrunWP[1][1]+irand(-3,3), AllianceOverrunWP[1][2]); - AddWaypoint(5, AllianceOverrunWP[2][0]+irand(-3,3), AllianceOverrunWP[2][1]+irand(-3,3), AllianceOverrunWP[2][2]); - me->SetHomePosition(AllianceOverrunWP[2][0]+irand(-3,3), AllianceOverrunWP[2][1]+irand(-3,3), AllianceOverrunWP[2][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 5; - Start(true, true); - break; - case 1: - AddWaypoint(4, AllianceOverrunWP[3][0]+irand(-3,3), AllianceOverrunWP[3][1]+irand(-3,3), AllianceOverrunWP[3][2]); - AddWaypoint(5, AllianceOverrunWP[4][0]+irand(-3,3), AllianceOverrunWP[4][1]+irand(-3,3), AllianceOverrunWP[4][2]); - AddWaypoint(6, AllianceOverrunWP[5][0]+irand(-3,3), AllianceOverrunWP[5][1]+irand(-3,3), AllianceOverrunWP[5][2]); - me->SetHomePosition(AllianceOverrunWP[5][0]+irand(-3,3), AllianceOverrunWP[5][1]+irand(-3,3), AllianceOverrunWP[5][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 6; - Start(true, true); - break; - case 2: - AddWaypoint(4, AllianceOverrunWP[6][0]+irand(-3,3), AllianceOverrunWP[6][1]+irand(-3,3), AllianceOverrunWP[6][2]); - AddWaypoint(5, AllianceOverrunWP[7][0]+irand(-3,3), AllianceOverrunWP[7][1]+irand(-3,3), AllianceOverrunWP[7][2]); - AddWaypoint(6, AllianceOverrunWP[8][0]+irand(-3,3), AllianceOverrunWP[8][1]+irand(-3,3), AllianceOverrunWP[8][2]); - AddWaypoint(7, AllianceOverrunWP[9][0]+irand(-3,3), AllianceOverrunWP[9][1]+irand(-3,3), AllianceOverrunWP[9][2]); - me->SetHomePosition(AllianceOverrunWP[9][0]+irand(-3,3), AllianceOverrunWP[9][1]+irand(-3,3), AllianceOverrunWP[9][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 7; - Start(true, true); - break; - case 3: - AddWaypoint(4, AllianceOverrunWP[10][0]+irand(-3,3), AllianceOverrunWP[10][1]+irand(-3,3), AllianceOverrunWP[10][2]); - AddWaypoint(5, AllianceOverrunWP[11][0]+irand(-3,3), AllianceOverrunWP[11][1]+irand(-3,3), AllianceOverrunWP[11][2]); - AddWaypoint(6, AllianceOverrunWP[12][0]+irand(-3,3), AllianceOverrunWP[12][1]+irand(-3,3), AllianceOverrunWP[12][2]); - me->SetHomePosition(AllianceOverrunWP[12][0]+irand(-3,3), AllianceOverrunWP[12][1]+irand(-3,3), AllianceOverrunWP[12][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 6; - Start(true, true); - break; - case 4: - AddWaypoint(4, AllianceOverrunWP[13][0]+irand(-3,3), AllianceOverrunWP[13][1]+irand(-3,3), AllianceOverrunWP[13][2]); - AddWaypoint(5, AllianceOverrunWP[14][0]+irand(-3,3), AllianceOverrunWP[14][1]+irand(-3,3), AllianceOverrunWP[14][2]); - AddWaypoint(6, AllianceOverrunWP[15][0]+irand(-3,3), AllianceOverrunWP[15][1]+irand(-3,3), AllianceOverrunWP[15][2]); - me->SetHomePosition(AllianceOverrunWP[15][0]+irand(-3,3), AllianceOverrunWP[15][1]+irand(-3,3), AllianceOverrunWP[15][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 6; - Start(true, true); - break; - case 5: - AddWaypoint(4, AllianceOverrunWP[16][0]+irand(-3,3), AllianceOverrunWP[16][1]+irand(-3,3), AllianceOverrunWP[16][2]); - AddWaypoint(5, AllianceOverrunWP[17][0]+irand(-3,3), AllianceOverrunWP[17][1]+irand(-3,3), AllianceOverrunWP[17][2]); - AddWaypoint(6, AllianceOverrunWP[18][0]+irand(-3,3), AllianceOverrunWP[18][1]+irand(-3,3), AllianceOverrunWP[18][2]); - AddWaypoint(7, AllianceOverrunWP[19][0]+irand(-3,3), AllianceOverrunWP[19][1]+irand(-3,3), AllianceOverrunWP[19][2]); - AddWaypoint(8, AllianceOverrunWP[20][0]+irand(-3,3), AllianceOverrunWP[20][1]+irand(-3,3), AllianceOverrunWP[20][2]); - AddWaypoint(9, AllianceOverrunWP[21][0]+irand(-3,3), AllianceOverrunWP[21][1]+irand(-3,3), AllianceOverrunWP[21][2]); - me->SetHomePosition(AllianceOverrunWP[21][0]+irand(-3,3), AllianceOverrunWP[21][1]+irand(-3,3), AllianceOverrunWP[21][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 9; - Start(true, true); - break; - default: - for (uint8 i = 22; i < 36; ++i) - AddWaypoint(i-18, AllianceOverrunWP[i][0]+irand(-3,3), AllianceOverrunWP[i][1]+irand(-3,3), AllianceOverrunWP[i][2]); - SetDespawnAtEnd(true); - LastOverronPos = 17; - Start(true, true); - break; - } - } - } - if (faction == 1) - { - if (me->GetEntry() == GHOUL) - { - for (uint8 i = 0; i < 6; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - switch(OverrunType) - { - case 0: - AddWaypoint(5, HordeOverrunWP[16][0]+irand(-10,10), HordeOverrunWP[16][1]+irand(-10,10), HordeOverrunWP[16][2]); - AddWaypoint(6, HordeOverrunWP[17][0]+irand(-10,10), HordeOverrunWP[17][1]+irand(-10,10), HordeOverrunWP[17][2]); - AddWaypoint(7, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]); - AddWaypoint(8, HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2]); - me->SetHomePosition(HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 8; - Start(true, true); - break; - case 1: - AddWaypoint(5, HordeOverrunWP[16][0]+irand(-10,10), HordeOverrunWP[16][1]+irand(-10,10), HordeOverrunWP[16][2]); - AddWaypoint(6, HordeOverrunWP[17][0]+irand(-10,10), HordeOverrunWP[17][1]+irand(-10,10), HordeOverrunWP[17][2]); - AddWaypoint(7, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]); - AddWaypoint(8, HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2]); - me->SetHomePosition(HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2],0); - SetDespawnAtEnd(false); - LastOverronPos = 8; - Start(true, true); - break; - default: - for (uint8 i = 0; i < 16; ++i) - AddWaypoint(i+6, HordeOverrunWP[i][0]+irand(-10,10), HordeOverrunWP[i][1]+irand(-10,10), HordeOverrunWP[i][2]); - SetDespawnAtEnd(true); - LastOverronPos = 21; - Start(true, true); - break; - } - } - if (me->GetEntry() == ABOMINATION) - { - for (uint8 i = 0; i < 6; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-10,10), HordeWPs[i][1]+irand(-10,10), HordeWPs[i][2]); - for (uint8 i = 0; i < 16; ++i) - AddWaypoint(i+6, HordeOverrunWP[i][0]+irand(-10,10), HordeOverrunWP[i][1]+irand(-10,10), HordeOverrunWP[i][2]); - SetDespawnAtEnd(true); - LastOverronPos = 21; - Start(true, true); - } - } - } -} - -void hyjal_trashAI::JustDied(Unit * /*victim*/) -{ - if (!pInstance) - return; - if (IsEvent && !me->isWorldBoss()) - pInstance->SetData(DATA_TRASH, 0);//signal trash is dead - - if ((pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE && !me->isWorldBoss()) || (damageTaken < me->GetMaxHealth()/4 && me->isWorldBoss())) - me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);//no loot -} - -struct mob_giant_infernalAI : public hyjal_trashAI -{ - mob_giant_infernalAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - meteor = false;//call once! - CanMove = false; - Delay = rand()%30000; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetDisplayId(MODEL_INVIS); - pGo = false; - pos = 0; - Reset(); - } - - bool meteor; - bool CanMove; - bool WpEnabled; - bool pGo; - uint32 pos; - uint32 spawnTimer; - uint32 FlameBuffetTimer; - bool imol; - - void Reset() - { - spawnTimer = 2000; - FlameBuffetTimer= 2000; - imol = false; - } - - void EnterCombat(Unit* /*who*/) {} - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 0 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - } - - void UpdateAI(const uint32 diff) - { - if (Delay <= diff) - { - Delay=0; - }else{ - Delay-=diff; - return; - } - if (!meteor) - { - float x,y,z; - me->GetPosition(x,y,z); - Creature* trigger = me->SummonCreature(NPC_TRIGGER,x+8,y+8,z+25+rand()%10,me->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,1000); - if (trigger) - { - trigger->SetVisibility(VISIBILITY_OFF); - trigger->setFaction(me->getFaction()); - trigger->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - trigger->CastSpell(me,SPELL_METEOR,true); - } - me->GetMotionMaster()->Clear(); - meteor = true; - } else if (!CanMove){ - if (spawnTimer <= diff) - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetDisplayId(me->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID)); - CanMove = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT) && !pInstance->GetData(DATA_HORDE_RETREAT)) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } else if (pInstance->GetData(DATA_ALLIANCE_RETREAT) && pInstance->GetData(DATA_HORDE_RETREAT)){ - //do overrun - } - } - } else spawnTimer -= diff; - } - if (!CanMove)return; - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - AddWaypoint(0, HordeWPs[7][0]+irand(-3,3), HordeWPs[7][1]+irand(-3,3), HordeWPs[7][2]);//HordeWPs[7] infront of thrall - Start(true, true); - SetDespawnAtEnd(false); - } - } - } - - if (!UpdateVictim()) - return; - if (!imol) - { - DoCast(me, SPELL_IMMOLATION); - imol=true; - } - if (FlameBuffetTimer <= diff) - { - DoCast(me->getVictim(), SPELL_FLAME_BUFFET, true); - FlameBuffetTimer = 7000; - } else FlameBuffetTimer -= diff; - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_giant_infernal(Creature* pCreature) -{ - return new mob_giant_infernalAI(pCreature); -} - -#define SPELL_DISEASE_CLOUD 31607 -#define SPELL_KNOCKDOWN 31610 - -struct mob_abominationAI : public hyjal_trashAI -{ - mob_abominationAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - - bool pGo; - uint32 KnockDownTimer; - uint32 pos; - void Reset() - { - KnockDownTimer = 10000; - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - }else{ - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - if (i == LastOverronPos && IsOverrun) - { - if ((faction == 0 && LastOverronPos == 17) || (faction == 1 && LastOverronPos == 21)) - { - me->setDeathState(DEAD); - me->RemoveCorpse(); - } - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else//use alliance WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - } - if (!me->HasAura(SPELL_DISEASE_CLOUD)) - DoCast(me, SPELL_DISEASE_CLOUD); - if (!UpdateVictim()) - return; - if (KnockDownTimer <= diff) - { - DoCast(me->getVictim(), SPELL_KNOCKDOWN); - KnockDownTimer = 15000+rand()%10000; - } else KnockDownTimer -= diff; - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_abomination(Creature* pCreature) -{ - return new mob_abominationAI(pCreature); -} - -#define SPELL_FRENZY 31540 - -struct mob_ghoulAI : public hyjal_trashAI -{ - mob_ghoulAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - - bool pGo; - uint32 FrenzyTimer; - uint32 pos; - uint32 MoveTimer; - bool RandomMove; - void Reset() - { - FrenzyTimer = 5000+rand()%5000; - MoveTimer = 2000; - RandomMove = false; - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - }else{ - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - if (i == LastOverronPos && IsOverrun) - { - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACKUNARMED); - if ((faction == 0 && LastOverronPos == 17) || (faction == 1 && LastOverronPos == 21)) - { - me->setDeathState(DEAD); - me->RemoveCorpse(); - } - - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else//use alliance WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - } - if (FrenzyTimer <= diff) - { - DoCast(me, SPELL_FRENZY); - FrenzyTimer = 15000+rand()%15000; - } else FrenzyTimer -= diff; - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_ghoul(Creature* pCreature) -{ - return new mob_ghoulAI(pCreature); -} - -#define SPELL_RAISE_DEAD_1 31617 -#define SPELL_RAISE_DEAD_2 31624 -#define SPELL_RAISE_DEAD_3 31625 -#define SPELL_SHADOW_BOLT 31627 - -struct mob_necromancerAI : public hyjal_trashAI -{ - mob_necromancerAI(Creature* c) : hyjal_trashAI(c), summons(me) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - SummonList summons; - bool pGo; - uint32 ShadowBoltTimer; - uint32 pos; - void Reset() - { - ShadowBoltTimer = 1000+rand()%5000; - summons.DespawnAll(); - } - - void JustSummoned(Creature* summon) - { - Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0,30,true); - if (pTarget && summon) - summon->Attack(pTarget,false); - summons.Summon(summon); - } - void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - }else{ - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - } - - void KilledUnit(Unit* /*victim*/) - { - switch (urand(0,2)) - { - case 0: - DoSpawnCreature(17902,3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); - DoSpawnCreature(17902,-3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); - break; - case 1: - DoSpawnCreature(17903,3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); - DoSpawnCreature(17903,-3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); - break; - case 2: - DoSpawnCreature(RAND(17902,17903),3,0,0,0,TEMPSUMMON_TIMED_DESPAWN, 60000); - break; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - Start(true, true); - SetDespawnAtEnd(false); - }else//use alliance WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - Start(true, true); - SetDespawnAtEnd(false); - } - } - } - } - if (!UpdateVictim()) - return; - if (ShadowBoltTimer <= diff) - { - DoCast(me->getVictim(), SPELL_SHADOW_BOLT); - ShadowBoltTimer = 20000+rand()%10000; - } else ShadowBoltTimer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_necromancer(Creature* pCreature) -{ - return new mob_necromancerAI(pCreature); -} - -#define SPELL_BANSHEE_CURSE 31651 -#define SPELL_BANSHEE_WAIL 38183 -#define SPELL_ANTI_MAGIC_SHELL 31662 - -struct mob_bansheeAI : public hyjal_trashAI -{ - mob_bansheeAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - - bool pGo; - uint32 CourseTimer; - uint32 WailTimer; - uint32 ShellTimer; - uint32 pos; - void Reset() - { - CourseTimer = 20000+rand()%5000; - WailTimer = 15000+rand()%5000; - ShellTimer = 50000+rand()%10000; - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - }else{ - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else//use alliance WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - } - if (!UpdateVictim()) - return; - if (CourseTimer <= diff) - { - DoCast(me->getVictim(), SPELL_BANSHEE_CURSE); - CourseTimer = 20000+rand()%5000; - } else CourseTimer -= diff; - if (WailTimer <= diff) - { - DoCast(me->getVictim(), SPELL_BANSHEE_WAIL); - WailTimer = 15000+rand()%5000; - } else WailTimer -= diff; - if (ShellTimer <= diff) - { - DoCast(me, SPELL_ANTI_MAGIC_SHELL); - ShellTimer = 50000+rand()%10000; - } else ShellTimer -= diff; - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_banshee(Creature* pCreature) -{ - return new mob_bansheeAI(pCreature); -} - -#define SPELL_WEB 28991 - -struct mob_crypt_fiendAI : public hyjal_trashAI -{ - mob_crypt_fiendAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - - bool pGo; - uint32 WebTimer; - uint32 pos; - void Reset() - { - WebTimer = 20000+rand()%5000; - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - }else{ - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else//use alliance WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - - } - } - } - if (!UpdateVictim()) - return; - if (WebTimer <= diff) - { - DoCast(me->getVictim(), SPELL_WEB); - WebTimer = 20000+rand()%5000; - } else WebTimer -= diff; - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_crypt_fiend(Creature* pCreature) -{ - return new mob_crypt_fiendAI(pCreature); -} - -#define SPELL_MANA_BURN 31729 - -struct mob_fel_stalkerAI : public hyjal_trashAI -{ - mob_fel_stalkerAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - - bool pGo; - uint32 ManaBurnTimer; - uint32 pos; - void Reset() - { - ManaBurnTimer = 9000+rand()%5000; - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 7 && pInstance && !IsOverrun) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - }else{ - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (pTarget && pTarget->isAlive()) - me->AddThreat(pTarget,0.0); - } - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - npc_escortAI::UpdateAI(diff); - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (pInstance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, use horde WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else//use alliance WPs - { - for (uint8 i = 0; i < 8; ++i) - AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - - } - } - } - if (!UpdateVictim()) - return; - if (ManaBurnTimer <= diff) - { - DoCast(me->getVictim(), SPELL_MANA_BURN); - ManaBurnTimer = 9000+rand()%5000; - } else ManaBurnTimer -= diff; - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_mob_fel_stalker(Creature* pCreature) -{ - return new mob_fel_stalkerAI(pCreature); -} - -#define SPELL_FROST_BREATH 31688 - -struct mob_frost_wyrmAI : public hyjal_trashAI -{ - mob_frost_wyrmAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - Reset(); - } - - bool pGo; - uint32 FrostBreathTimer; - uint32 pos; - uint32 MoveTimer; - - void Reset() - { - FrostBreathTimer = 5000; - MoveTimer = 0; - me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 2 && pInstance && !IsOverrun) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - { - me->AddThreat(pTarget,0.0); - DoCast(pTarget, SPELL_FROST_BREATH, true); - } - } - } - - void JustDied(Unit * /*victim*/) - { - if (pInstance && IsEvent) - pInstance->SetData(DATA_TRASH, 0);//signal trash is dead - - float x,y,z; - me->GetPosition(x,y,z); - z = me->GetMap()->GetHeight(x, y, z); - me->GetMotionMaster()->MovePoint(0,x,y,z); - me->GetMap()->CreatureRelocation(me, x,y,z,0); - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - { - CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); - npc_escortAI::UpdateAI(diff); - } - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (!useFlyPath) - { - for (uint8 i = 0; i < 3; ++i) - AddWaypoint(i, FrostWyrmWPs[i][0], FrostWyrmWPs[i][1], FrostWyrmWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else{//fly path FlyPathWPs - for (uint8 i = 0; i < 3; ++i) - AddWaypoint(i, FlyPathWPs[i][0]+irand(-10,10), FlyPathWPs[i][1]+irand(-10,10), FlyPathWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - } - if (!UpdateVictim()) - return; - if (!me->IsWithinDist(me->getVictim(), 25)){ - if (MoveTimer <= diff) - { - me->GetMotionMaster()->MoveChase(me->getVictim()); - MoveTimer = 2000; - } else MoveTimer-=diff; - } - - if (FrostBreathTimer <= diff) - { - if (!me->IsWithinDist(me->getVictim(), 25)) - { - DoCast(me->getVictim(), SPELL_FROST_BREATH); - me->StopMoving(); - me->GetMotionMaster()->Clear(); - FrostBreathTimer = 4000; - } - } else FrostBreathTimer -= diff; - } -}; - -CreatureAI* GetAI_mob_frost_wyrm(Creature* pCreature) -{ - return new mob_frost_wyrmAI(pCreature); -} - -#define SPELL_GARGOYLE_STRIKE 31664 - -struct mob_gargoyleAI : public hyjal_trashAI -{ - mob_gargoyleAI(Creature* c) : hyjal_trashAI(c) - { - pInstance = c->GetInstanceData(); - pGo = false; - pos = 0; - DummyTarget[0] = 0;DummyTarget[1] = 0;DummyTarget[2] = 0; - Reset(); - } - - bool pGo; - uint32 StrikeTimer; - uint32 pos; - uint32 MoveTimer; - float Zpos; - bool forcemove; - - void Reset() - { - forcemove = true; - Zpos = 10.0; - StrikeTimer = 2000+rand()%5000; - MoveTimer = 0; - me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); - } - - void WaypointReached(uint32 i) - { - pos = i; - if (i == 2 && pInstance && !IsOverrun) - { - Unit *pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_THRALL)); - if (pTarget && pTarget->isAlive()) - { - me->AddThreat(pTarget,0.0); - DoCast(pTarget, SPELL_GARGOYLE_STRIKE, true); - } - } - } - - void JustDied(Unit *victim) - { - float x,y,z; - me->GetPosition(x,y,z); - z = me->GetMap()->GetHeight(x, y, z); - me->GetMotionMaster()->MovePoint(0,x,y,z); - me->GetMap()->CreatureRelocation(me, x,y,z,0); - hyjal_trashAI::JustDied(victim); - } - - void UpdateAI(const uint32 diff) - { - hyjal_trashAI::UpdateAI(diff); - if (IsEvent || IsOverrun) - { - CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); - npc_escortAI::UpdateAI(diff); - } - if (IsEvent) - { - if (!pGo) - { - pGo = true; - if (pInstance) - { - if (!useFlyPath) - { - for (uint8 i = 0; i < 3; ++i) - AddWaypoint(i, GargoyleWPs[i][0]+irand(-10,10), GargoyleWPs[i][1]+irand(-10,10), GargoyleWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - }else{//fly path FlyPathWPs - for (uint8 i = 0; i < 3; ++i) - AddWaypoint(i, FlyPathWPs[i][0]+irand(-10,10), FlyPathWPs[i][1]+irand(-10,10), FlyPathWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); - } - } - } - } - if (IsOverrun && !UpdateVictim()) - { - if (faction == 0)//alliance - { - if (StrikeTimer <= diff) - { - me->CastSpell(DummyTarget[0],DummyTarget[1],DummyTarget[2],SPELL_GARGOYLE_STRIKE,false); - StrikeTimer = 2000+rand()%1000; - } else StrikeTimer -= diff; - } - } - if (!UpdateVictim()) - return; - if (!me->IsWithinDist(me->getVictim(), 20) || forcemove) - { - forcemove = false; - if (forcemove) - { - Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); - if (pTarget) - me->Attack(pTarget,false); - } - if (MoveTimer <= diff) - { - float x,y,z; - me->getVictim()->GetPosition(x,y,z); - me->GetMotionMaster()->MovePoint(0,x,y,z+Zpos); - Zpos-=1.0; - if (Zpos <= 0)Zpos=0; - MoveTimer = 2000; - } else MoveTimer-=diff; - } - if (StrikeTimer <= diff) - { - if (me->IsWithinDist(me->getVictim(), 20)) - { - DoCast(me->getVictim(), SPELL_GARGOYLE_STRIKE); - me->StopMoving(); - me->GetMotionMaster()->Clear(); - StrikeTimer = 2000+rand()%1000; - } else StrikeTimer=0; - } else StrikeTimer -= diff; - } -}; - -CreatureAI* GetAI_mob_gargoyle(Creature* pCreature) -{ - return new mob_gargoyleAI(pCreature); -} - -#define SPELL_EXPLODING_SHOT 7896 - -struct alliance_riflemanAI : public Scripted_NoMovementAI -{ - alliance_riflemanAI(Creature *c) : Scripted_NoMovementAI(c) - { - Reset(); - } - - uint32 ExplodeTimer; - - void JustDied(Unit* /*who*/) - { - } - - void Reset() - { - ExplodeTimer = 5000+rand()%5000; - } - - void MoveInLineOfSight(Unit *who) - { - if (!who || me->getVictim()) - return; - - if (who->isTargetableForAttack() && me->IsHostileTo(who)) - { - //float attackRadius = me->GetAttackDistance(who); - if (me->IsWithinDistInMap(who, 30)) - AttackStart(who); - } - } - - void EnterCombat(Unit * /*who*/) - { - } - - void UpdateAI(const uint32 diff) - { - //Check if we have a target - if (!UpdateVictim()) - return; - if (ExplodeTimer <= diff) - { - if (!me->IsWithinDistInMap(me->getVictim(), 30)) - { - EnterEvadeMode(); - return; - } - int dmg = 500+rand()%700; - me->CastCustomSpell(me->getVictim(), SPELL_EXPLODING_SHOT, &dmg, 0, 0, false); - ExplodeTimer = 5000+rand()%5000; - } else ExplodeTimer -= diff; - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_alliance_rifleman(Creature* pCreature) -{ - return new alliance_riflemanAI(pCreature); -} - -void AddSC_hyjal_trash() -{ - Script *newscript = new Script; - newscript->Name = "mob_giant_infernal"; - newscript->GetAI = &GetAI_mob_giant_infernal; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_abomination"; - newscript->GetAI = &GetAI_mob_abomination; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_ghoul"; - newscript->GetAI = &GetAI_mob_ghoul; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_necromancer"; - newscript->GetAI = &GetAI_mob_necromancer; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_banshee"; - newscript->GetAI = &GetAI_mob_banshee; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_crypt_fiend"; - newscript->GetAI = &GetAI_mob_crypt_fiend; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_fel_stalker"; - newscript->GetAI = &GetAI_mob_fel_stalker; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_frost_wyrm"; - newscript->GetAI = &GetAI_mob_frost_wyrm; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "mob_gargoyle"; - newscript->GetAI = &GetAI_mob_gargoyle; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "alliance_rifleman"; - newscript->GetAI = &GetAI_alliance_rifleman; - newscript->RegisterSelf(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.h deleted file mode 100644 index 21ee4bc06cc..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/hyjal_trash.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef SC_HYJAL_TRASH_AI_H -#define SC_HYJAL_TRASH_AI_H - -#include "hyjal.h" -#include "ScriptedEscortAI.h" - -#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies - -struct hyjal_trashAI : public npc_escortAI -{ - hyjal_trashAI(Creature *c); - - void UpdateAI(const uint32 diff); - - void JustDied(Unit* /*killer*/); - - void DamageTaken(Unit *done_by, uint32 &damage); - - public: - ScriptedInstance* pInstance; - bool IsEvent; - uint32 Delay; - uint32 LastOverronPos; - bool IsOverrun; - bool SetupOverrun; - uint32 OverrunType; - uint8 faction; - bool useFlyPath; - uint32 damageTaken; - float DummyTarget[3]; - - //private: -}; -#endif diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/instance_hyjal.cpp deleted file mode 100644 index e89d518c5bc..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/hyjal/instance_hyjal.cpp +++ /dev/null @@ -1,324 +0,0 @@ - /* Copyright (C) 2006 - 2009 ScriptDev2 - * 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_Mount_Hyjal -SD%Complete: 100 -SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Hyjal Scripts -SDCategory: Caverns of Time, Mount Hyjal -EndScriptData */ - -#include "ScriptedPch.h" -#include "hyjal.h" -#include "hyjal_trash.h" - -enum eEnums -{ - MAX_ENCOUNTER = 5, - - GO_ANCIENT_GEM = 185557 -}; -/* Battle of Mount Hyjal encounters: -0 - Rage Winterchill event -1 - Anetheron event -2 - Kaz'rogal event -3 - Azgalor event -4 - Archimonde event -*/ - -struct instance_mount_hyjal : public ScriptedInstance -{ - instance_mount_hyjal(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string str_data; - - std::list m_uiAncientGemGUID; - - uint64 RageWinterchill; - uint64 Anetheron; - uint64 Kazrogal; - uint64 Azgalor; - uint64 Archimonde; - uint64 JainaProudmoore; - uint64 Thrall; - uint64 TyrandeWhisperwind; - uint64 HordeGate; - uint64 ElfGate; - - uint32 Trash; - - uint32 hordeRetreat; - uint32 allianceRetreat; - bool ArchiYell; - - uint32 RaidDamage; - - #define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more." - #define YELL_EFFORTS_NAME "Archimonde" - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiAncientGemGUID.clear(); - - RageWinterchill = 0; - Anetheron = 0; - Kazrogal = 0; - Azgalor = 0; - Archimonde = 0; - JainaProudmoore = 0; - Thrall = 0; - TyrandeWhisperwind = 0; - HordeGate = 0; - ElfGate = 0; - ArchiYell = false; - RaidDamage = 0; - - Trash = 0; - - hordeRetreat = 0; - allianceRetreat = 0; - } - - bool IsEncounterInProgress() const - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) return true; - - return false; - } - - void OnGameObjectCreate(GameObject* pGo, bool /*add*/) - { - switch(pGo->GetEntry()) - { - case 182060: - HordeGate = pGo->GetGUID(); - if (allianceRetreat) - HandleGameObject(0, true, pGo); - else - HandleGameObject(0, false, pGo); - break; - case 182061: - ElfGate = pGo->GetGUID(); - if (hordeRetreat) - HandleGameObject(0, true, pGo); - else - HandleGameObject(0, false, pGo); - break; - case GO_ANCIENT_GEM: - m_uiAncientGemGUID.push_back(pGo->GetGUID()); - break; - } - } - - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - switch(pCreature->GetEntry()) - { - case 17767: RageWinterchill = pCreature->GetGUID(); break; - case 17808: Anetheron = pCreature->GetGUID(); break; - case 17888: Kazrogal = pCreature->GetGUID(); break; - case 17842: Azgalor = pCreature->GetGUID(); break; - case 17968: Archimonde = pCreature->GetGUID(); break; - case 17772: JainaProudmoore = pCreature->GetGUID(); break; - case 17852: Thrall = pCreature->GetGUID(); break; - case 17948: TyrandeWhisperwind = pCreature->GetGUID(); break; - } - } - - uint64 GetData64(uint32 identifier) - { - switch(identifier) - { - case DATA_RAGEWINTERCHILL: return RageWinterchill; - case DATA_ANETHERON: return Anetheron; - case DATA_KAZROGAL: return Kazrogal; - case DATA_AZGALOR: return Azgalor; - case DATA_ARCHIMONDE: return Archimonde; - case DATA_JAINAPROUDMOORE: return JainaProudmoore; - case DATA_THRALL: return Thrall; - case DATA_TYRANDEWHISPERWIND: return TyrandeWhisperwind; - } - - return 0; - } - - void SetData(uint32 type, uint32 data) - { - switch(type) - { - case DATA_RAGEWINTERCHILLEVENT: m_auiEncounter[0] = data; break; - case DATA_ANETHERONEVENT: - m_auiEncounter[1] = data; - break; - case DATA_KAZROGALEVENT: m_auiEncounter[2] = data; break; - case DATA_AZGALOREVENT: - { - m_auiEncounter[3] = data; - if (data == DONE) - { - if (ArchiYell)break; - ArchiYell = true; - - Creature* pCreature = instance->GetCreature(Azgalor); - if (pCreature) - { - Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); - - Map* pMap = pCreature->GetMap(); - if (pMap->IsDungeon() && pUnit) - { - pUnit->SetVisibility(VISIBILITY_OFF); - Map::PlayerList const &PlayerList = pMap->GetPlayers(); - if (PlayerList.isEmpty()) - return; - - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - { - if (i->getSource()) - { - WorldPacket data(SMSG_MESSAGECHAT, 200); - pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,YELL_EFFORTS,0,YELL_EFFORTS_NAME,i->getSource()->GetGUID()); - i->getSource()->GetSession()->SendPacket(&data); - - WorldPacket data2(SMSG_PLAY_SOUND, 4); - data2 << 10986; - i->getSource()->GetSession()->SendPacket(&data2); - } - } - } - } - } - } - break; - case DATA_ARCHIMONDEEVENT: m_auiEncounter[4] = data; break; - case DATA_RESET_TRASH_COUNT: Trash = 0; break; - - case DATA_TRASH: - if (data) Trash = data; - else Trash--; - DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); - break; - case TYPE_RETREAT: - if (data == SPECIAL) - { - if (!m_uiAncientGemGUID.empty()) - { - for (std::list::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr) - { - //don't know how long it expected - DoRespawnGameObject(*itr,DAY); - } - } - } - break; - case DATA_ALLIANCE_RETREAT: - allianceRetreat = data; - HandleGameObject(HordeGate, true); - SaveToDB(); - break; - case DATA_HORDE_RETREAT: - hordeRetreat = data; - HandleGameObject(ElfGate, true); - SaveToDB(); - break; - case DATA_RAIDDAMAGE: - RaidDamage += data; - if (RaidDamage >= MINRAIDDAMAGE) - RaidDamage = MINRAIDDAMAGE; - break; - case DATA_RESET_RAIDDAMAGE: - RaidDamage = 0; - break; - } - - debug_log("TSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); - - if (data == DONE) - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " - << m_auiEncounter[3] << " " << m_auiEncounter[4] - << " " << allianceRetreat << " " << hordeRetreat - << " " << RaidDamage; - - str_data = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; - } - - } - - uint32 GetData(uint32 type) - { - switch(type) - { - case DATA_RAGEWINTERCHILLEVENT: return m_auiEncounter[0]; - case DATA_ANETHERONEVENT: return m_auiEncounter[1]; - case DATA_KAZROGALEVENT: return m_auiEncounter[2]; - case DATA_AZGALOREVENT: return m_auiEncounter[3]; - case DATA_ARCHIMONDEEVENT: return m_auiEncounter[4]; - case DATA_TRASH: return Trash; - case DATA_ALLIANCE_RETREAT: return allianceRetreat; - case DATA_HORDE_RETREAT: return hordeRetreat; - case DATA_RAIDDAMAGE: return RaidDamage; - } - return 0; - } - - std::string GetSaveData() - { - return str_data; - } - - void Load(const char* in) - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4] >> allianceRetreat >> hordeRetreat >> RaidDamage; - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as IN_PROGRESS - reset it instead. - m_auiEncounter[i] = NOT_STARTED; - OUT_LOAD_INST_DATA_COMPLETE; - } -}; - -InstanceData* GetInstanceData_instance_mount_hyjal(Map* pMap) -{ - return new instance_mount_hyjal(pMap); -} - -void AddSC_instance_mount_hyjal() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "instance_hyjal"; - newscript->GetInstanceData = &GetInstanceData_instance_mount_hyjal; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_captain_skarloc.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_captain_skarloc.cpp deleted file mode 100644 index 91c9e274b83..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_captain_skarloc.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Captain_Skarloc -SD%Complete: 75 -SDComment: Missing adds, missing waypoints to move up to Thrall once spawned + speech before enter combat. -SDCategory: Caverns of Time, Old Hillsbrad Foothills -EndScriptData */ - -#include "ScriptedPch.h" -#include "old_hillsbrad.h" - -#define SAY_ENTER -1560000 -#define SAY_TAUNT1 -1560001 -#define SAY_TAUNT2 -1560002 -#define SAY_SLAY1 -1560003 -#define SAY_SLAY2 -1560004 -#define SAY_DEATH -1560005 - -#define SPELL_HOLY_LIGHT 29427 -#define SPELL_CLEANSE 29380 -#define SPELL_HAMMER_OF_JUSTICE 13005 -#define SPELL_HOLY_SHIELD 31904 -#define SPELL_DEVOTION_AURA 8258 -#define SPELL_CONSECRATION 38385 - -struct boss_captain_skarlocAI : public ScriptedAI -{ - boss_captain_skarlocAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 Holy_Light_Timer; - uint32 Cleanse_Timer; - uint32 HammerOfJustice_Timer; - uint32 HolyShield_Timer; - uint32 DevotionAura_Timer; - uint32 Consecration_Timer; - - void Reset() - { - Holy_Light_Timer = 20000 + rand()%10000; - Cleanse_Timer = 10000; - HammerOfJustice_Timer = 20000 + rand()%15000; - HolyShield_Timer = 240000; - DevotionAura_Timer = 3000; - Consecration_Timer = 8000; - } - - void EnterCombat(Unit * /*who*/) - { - //This is not correct. Should taunt Thrall before engage in combat - DoScriptText(SAY_TAUNT1, me); - DoScriptText(SAY_TAUNT2, me); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance && pInstance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) - pInstance->SetData(TYPE_THRALL_PART1, DONE); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Holy_Light - if (Holy_Light_Timer <= diff) - { - DoCast(me, SPELL_HOLY_LIGHT); - Holy_Light_Timer = 30000; - } else Holy_Light_Timer -= diff; - - //Cleanse - if (Cleanse_Timer <= diff) - { - DoCast(me, SPELL_CLEANSE); - Cleanse_Timer = 10000; - } else Cleanse_Timer -= diff; - - //Hammer of Justice - if (HammerOfJustice_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_HAMMER_OF_JUSTICE); - HammerOfJustice_Timer = 60000; - } else HammerOfJustice_Timer -= diff; - - //Holy Shield - if (HolyShield_Timer <= diff) - { - DoCast(me, SPELL_HOLY_SHIELD); - HolyShield_Timer = 240000; - } else HolyShield_Timer -= diff; - - //Devotion_Aura - if (DevotionAura_Timer <= diff) - { - DoCast(me, SPELL_DEVOTION_AURA); - DevotionAura_Timer = 45000 + rand()%10000; - } else DevotionAura_Timer -= diff; - - //Consecration - if (Consecration_Timer <= diff) - { - //DoCast(me->getVictim(), SPELL_CONSECRATION); - Consecration_Timer = 5000 + rand()%5000; - } else Consecration_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_captain_skarloc(Creature* pCreature) -{ - return new boss_captain_skarlocAI (pCreature); -} - -void AddSC_boss_captain_skarloc() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_captain_skarloc"; - newscript->GetAI = &GetAI_boss_captain_skarloc; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_epoch_hunter.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_epoch_hunter.cpp deleted file mode 100644 index 2c2ad96ddb7..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_epoch_hunter.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Epoch_Hunter -SD%Complete: 60 -SDComment: Missing spawns pre-event, missing speech to be coordinated with rest of escort event. -SDCategory: Caverns of Time, Old Hillsbrad Foothills -EndScriptData */ - -#include "ScriptedPch.h" -#include "old_hillsbrad.h" - -#define SAY_ENTER1 -1560013 -#define SAY_ENTER2 -1560014 -#define SAY_ENTER3 -1560015 -#define SAY_AGGRO1 -1560016 -#define SAY_AGGRO2 -1560017 -#define SAY_SLAY1 -1560018 -#define SAY_SLAY2 -1560019 -#define SAY_BREATH1 -1560020 -#define SAY_BREATH2 -1560021 -#define SAY_DEATH -1560022 - -#define SPELL_SAND_BREATH 31914 -#define SPELL_IMPENDING_DEATH 31916 -#define SPELL_MAGIC_DISRUPTION_AURA 33834 -#define SPELL_WING_BUFFET 31475 - -struct boss_epoch_hunterAI : public ScriptedAI -{ - boss_epoch_hunterAI(Creature *c) : ScriptedAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - uint32 SandBreath_Timer; - uint32 ImpendingDeath_Timer; - uint32 WingBuffet_Timer; - uint32 Mda_Timer; - - void Reset() - { - SandBreath_Timer = 8000 + rand()%8000; - ImpendingDeath_Timer = 25000 + rand()%5000; - WingBuffet_Timer = 35000; - Mda_Timer = 40000; - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2), me); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - - if (pInstance && pInstance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) - pInstance->SetData(TYPE_THRALL_PART4, DONE); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Sand Breath - if (SandBreath_Timer <= diff) - { - if (me->IsNonMeleeSpellCasted(false)) - me->InterruptNonMeleeSpells(false); - - DoCast(me->getVictim(), SPELL_SAND_BREATH); - - DoScriptText(RAND(SAY_BREATH1,SAY_BREATH2), me); - - SandBreath_Timer = 10000 + rand()%10000; - } else SandBreath_Timer -= diff; - - if (ImpendingDeath_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_IMPENDING_DEATH); - ImpendingDeath_Timer = 25000+rand()%5000; - } else ImpendingDeath_Timer -= diff; - - if (WingBuffet_Timer <= diff) - { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_WING_BUFFET); - WingBuffet_Timer = 25000+rand()%10000; - } else WingBuffet_Timer -= diff; - - if (Mda_Timer <= diff) - { - DoCast(me, SPELL_MAGIC_DISRUPTION_AURA); - Mda_Timer = 15000; - } else Mda_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_epoch_hunter(Creature* pCreature) -{ - return new boss_epoch_hunterAI (pCreature); -} - -void AddSC_boss_epoch_hunter() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "boss_epoch_hunter"; - newscript->GetAI = &GetAI_boss_epoch_hunter; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_leutenant_drake.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_leutenant_drake.cpp deleted file mode 100644 index dae0f5390b1..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/boss_leutenant_drake.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* ScriptData -SDName: Boss_Luetenant_Drake -SD%Complete: 70 -SDComment: Missing proper code for patrolling area after being spawned. Script for GO (barrels) quest 10283 -SDCategory: Caverns of Time, Old Hillsbrad Foothills -EndScriptData */ - -#include "ScriptedPch.h" -#include "old_hillsbrad.h" -#include "ScriptedEscortAI.h" - -/*###### -## go_barrel_old_hillsbrad -######*/ - -bool GOHello_go_barrel_old_hillsbrad(Player* /*pPlayer*/, GameObject* pGO) -{ - if (ScriptedInstance* pInstance = pGO->GetInstanceData()) - { - if (pInstance->GetData(TYPE_BARREL_DIVERSION) == DONE) - return false; - - pInstance->SetData(TYPE_BARREL_DIVERSION, IN_PROGRESS); - } - - return false; -} - -/*###### -## boss_lieutenant_drake -######*/ - -#define SAY_ENTER -1560006 -#define SAY_AGGRO -1560007 -#define SAY_SLAY1 -1560008 -#define SAY_SLAY2 -1560009 -#define SAY_MORTAL -1560010 -#define SAY_SHOUT -1560011 -#define SAY_DEATH -1560012 - -#define SPELL_WHIRLWIND 31909 -#define SPELL_HAMSTRING 9080 -#define SPELL_MORTAL_STRIKE 31911 -#define SPELL_FRIGHTENING_SHOUT 33789 - -struct Location -{ - uint32 wpId; - float x; - float y; - float z; -}; - -static Location DrakeWP[]= -{ - {0, 2125.84, 88.2535, 54.8830}, - {1, 2111.01, 93.8022, 52.6356}, - {2, 2106.70, 114.753, 53.1965}, - {3, 2107.76, 138.746, 52.5109}, - {4, 2114.83, 160.142, 52.4738}, - {5, 2125.24, 178.909, 52.7283}, - {6, 2151.02, 208.901, 53.1551}, - {7, 2177.00, 233.069, 52.4409}, - {8, 2190.71, 227.831, 53.2742}, - {9, 2178.14, 214.219, 53.0779}, - {10, 2154.99, 202.795, 52.6446}, - {11, 2132.00, 191.834, 52.5709}, - {12, 2117.59, 166.708, 52.7686}, - {13, 2093.61, 139.441, 52.7616}, - {14, 2086.29, 104.950, 52.9246}, - {15, 2094.23, 81.2788, 52.6946}, - {16, 2108.70, 85.3075, 53.3294}, - {17, 2125.50, 88.9481, 54.7953}, - {18, 2128.20, 70.9763, 64.4221} -}; - -struct boss_lieutenant_drakeAI : public ScriptedAI -{ - boss_lieutenant_drakeAI(Creature *c) : ScriptedAI(c) {} - - bool CanPatrol; - uint32 wpId; - - uint32 Whirlwind_Timer; - uint32 Fear_Timer; - uint32 MortalStrike_Timer; - uint32 ExplodingShout_Timer; - - void Reset() - { - CanPatrol = true; - wpId = 0; - - Whirlwind_Timer = 20000; - Fear_Timer = 30000; - MortalStrike_Timer = 45000; - ExplodingShout_Timer = 25000; - } - - void EnterCombat(Unit * /*who*/) - { - DoScriptText(SAY_AGGRO, me); - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me); - } - - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - } - - void UpdateAI(const uint32 diff) - { - //TODO: make this work - if (CanPatrol && wpId == 0) - { - me->GetMotionMaster()->MovePoint(DrakeWP[0].wpId, DrakeWP[0].x, DrakeWP[0].y, DrakeWP[0].z); - ++wpId; - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - //Whirlwind - if (Whirlwind_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_WHIRLWIND); - Whirlwind_Timer = 20000+rand()%5000; - } else Whirlwind_Timer -= diff; - - //Fear - if (Fear_Timer <= diff) - { - DoScriptText(SAY_SHOUT, me); - DoCast(me->getVictim(), SPELL_FRIGHTENING_SHOUT); - Fear_Timer = 25000+rand()%10000; - } else Fear_Timer -= diff; - - //Mortal Strike - if (MortalStrike_Timer <= diff) - { - DoScriptText(SAY_MORTAL, me); - DoCast(me->getVictim(), SPELL_MORTAL_STRIKE); - MortalStrike_Timer = 20000+rand()%10000; - } else MortalStrike_Timer -= diff; - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_lieutenant_drake(Creature* pCreature) -{ - return new boss_lieutenant_drakeAI (pCreature); -} - -void AddSC_boss_lieutenant_drake() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "go_barrel_old_hillsbrad"; - newscript->pGOHello = &GOHello_go_barrel_old_hillsbrad; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "boss_lieutenant_drake"; - newscript->GetAI = &GetAI_boss_lieutenant_drake; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/instance_old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/instance_old_hillsbrad.cpp deleted file mode 100644 index fa0b7c14595..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/instance_old_hillsbrad.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * 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_Old_Hillsbrad -SD%Complete: 75 -SDComment: If thrall escort fail, all parts will reset. In future, save sub-parts and continue from last known. -SDCategory: Caverns of Time, Old Hillsbrad Foothills -EndScriptData */ - -#include "ScriptedPch.h" -#include "old_hillsbrad.h" - -#define MAX_ENCOUNTER 6 - -#define THRALL_ENTRY 17876 -#define TARETHA_ENTRY 18887 -#define EPOCH_ENTRY 18096 - -#define DRAKE_ENTRY 17848 - -#define QUEST_ENTRY_DIVERSION 10283 -#define LODGE_QUEST_TRIGGER 20155 - -struct instance_old_hillsbrad : public ScriptedInstance -{ - instance_old_hillsbrad(Map* pMap) : ScriptedInstance(pMap) {Initialize();}; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint32 mBarrelCount; - uint32 mThrallEventCount; - - uint64 ThrallGUID; - uint64 TarethaGUID; - uint64 EpochGUID; - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - mBarrelCount = 0; - mThrallEventCount = 0; - ThrallGUID = 0; - TarethaGUID = 0; - EpochGUID = 0; - } - - Player* GetPlayerInMap() - { - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) - { - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* plr = itr->getSource()) - return plr; - } - } - - debug_log("TSCR: Instance Old Hillsbrad: GetPlayerInMap, but PlayerList is empty!"); - return NULL; - } - - void UpdateQuestCredit() - { - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) - { - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* pPlayer = itr->getSource()) - pPlayer->KilledMonsterCredit(LODGE_QUEST_TRIGGER,0); - } - } - } - - void OnCreatureCreate(Creature* pCreature, bool /*add*/) - { - switch(pCreature->GetEntry()) - { - case THRALL_ENTRY: - ThrallGUID = pCreature->GetGUID(); - break; - case TARETHA_ENTRY: - TarethaGUID = pCreature->GetGUID(); - break; - case EPOCH_ENTRY: - EpochGUID = pCreature->GetGUID(); - break; - } - } - - void SetData(uint32 type, uint32 data) - { - Player* pPlayer = GetPlayerInMap(); - - if (!pPlayer) - { - debug_log("TSCR: Instance Old Hillsbrad: SetData (Type: %u Data %u) cannot find any player.", type, data); - return; - } - - switch(type) - { - case TYPE_BARREL_DIVERSION: - { - if (data == IN_PROGRESS) - { - if (mBarrelCount >= 5) - return; - - ++mBarrelCount; - DoUpdateWorldState(WORLD_STATE_OH, mBarrelCount); - - debug_log("TSCR: Instance Old Hillsbrad: go_barrel_old_hillsbrad count %u",mBarrelCount); - - m_auiEncounter[0] = IN_PROGRESS; - - if (mBarrelCount == 5) - { - UpdateQuestCredit(); - pPlayer->SummonCreature(DRAKE_ENTRY, 2128.43, 71.01, 64.42, 1.74, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 1800000); - m_auiEncounter[0] = DONE; - } - } - break; - } - case TYPE_THRALL_EVENT: - { - if (data == FAIL) - { - if (mThrallEventCount <= 20) - { - ++mThrallEventCount; - m_auiEncounter[1] = NOT_STARTED; - debug_log("TSCR: Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.",mThrallEventCount); - m_auiEncounter[2] = NOT_STARTED; - m_auiEncounter[3] = NOT_STARTED; - m_auiEncounter[4] = NOT_STARTED; - m_auiEncounter[5] = NOT_STARTED; - } - else if (mThrallEventCount > 20) - { - m_auiEncounter[1] = data; - m_auiEncounter[2] = data; - m_auiEncounter[3] = data; - m_auiEncounter[4] = data; - m_auiEncounter[5] = data; - debug_log("TSCR: Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.",mThrallEventCount); - } - } - else - m_auiEncounter[1] = data; - debug_log("TSCR: Instance Old Hillsbrad: Thrall escort event adjusted to data %u.",data); - break; - } - case TYPE_THRALL_PART1: - m_auiEncounter[2] = data; - debug_log("TSCR: Instance Old Hillsbrad: Thrall event part I adjusted to data %u.",data); - break; - case TYPE_THRALL_PART2: - m_auiEncounter[3] = data; - debug_log("TSCR: Instance Old Hillsbrad: Thrall event part II adjusted to data %u.",data); - break; - case TYPE_THRALL_PART3: - m_auiEncounter[4] = data; - debug_log("TSCR: Instance Old Hillsbrad: Thrall event part III adjusted to data %u.",data); - break; - case TYPE_THRALL_PART4: - m_auiEncounter[5] = data; - debug_log("TSCR: Instance Old Hillsbrad: Thrall event part IV adjusted to data %u.",data); - break; - } - } - - uint32 GetData(uint32 data) - { - switch(data) - { - case TYPE_BARREL_DIVERSION: - return m_auiEncounter[0]; - case TYPE_THRALL_EVENT: - return m_auiEncounter[1]; - case TYPE_THRALL_PART1: - return m_auiEncounter[2]; - case TYPE_THRALL_PART2: - return m_auiEncounter[3]; - case TYPE_THRALL_PART3: - return m_auiEncounter[4]; - case TYPE_THRALL_PART4: - return m_auiEncounter[5]; - } - return 0; - } - - uint64 GetData64(uint32 data) - { - switch(data) - { - case DATA_THRALL: - return ThrallGUID; - case DATA_TARETHA: - return TarethaGUID; - case DATA_EPOCH: - return EpochGUID; - } - return 0; - } -}; -InstanceData* GetInstanceData_instance_old_hillsbrad(Map* pMap) -{ - return new instance_old_hillsbrad(pMap); -} - -void AddSC_instance_old_hillsbrad() -{ - Script *newscript; - newscript = new Script; - newscript->Name = "instance_old_hillsbrad"; - newscript->GetInstanceData = &GetInstanceData_instance_old_hillsbrad; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.cpp deleted file mode 100644 index 08c63954db5..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.cpp +++ /dev/null @@ -1,658 +0,0 @@ - /* Copyright (C) 2006 - 2009 ScriptDev2 - * 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: Old_Hillsbrad -SD%Complete: 40 -SDComment: Quest support: 10283, 10284. All friendly NPC's. Thrall waypoints fairly complete, missing many details, but possible to complete escort. -SDCategory: Caverns of Time, Old Hillsbrad Foothills -EndScriptData */ - -/* ContentData -npc_erozion -npc_thrall_old_hillsbrad -npc_taretha -EndContentData */ - -#include "ScriptedPch.h" -#include "ScriptedEscortAI.h" -#include "old_hillsbrad.h" - -#define QUEST_ENTRY_HILLSBRAD 10282 -#define QUEST_ENTRY_DIVERSION 10283 -#define QUEST_ENTRY_ESCAPE 10284 -#define QUEST_ENTRY_RETURN 10285 -#define ITEM_ENTRY_BOMBS 25853 - -#define GOSSIP_HELLO_EROZION1 "I need a pack of Incendiary Bombs." -#define GOSSIP_HELLO_EROZION2 "[PH] Teleport please, i'm tired." - -/*###### -## npc_erozion -######*/ - -bool GossipHello_npc_erozion(Player* pPlayer, Creature* pCreature) -{ - if (pCreature->isQuestGiver()) - pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - - ScriptedInstance* pInstance = pCreature->GetInstanceData(); - if (pInstance && pInstance->GetData(TYPE_BARREL_DIVERSION) != DONE && !pPlayer->HasItemCount(ITEM_ENTRY_BOMBS,1)) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - if (!pPlayer->GetQuestRewardStatus(QUEST_ENTRY_RETURN) && pPlayer->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE) - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - pPlayer->SEND_GOSSIP_MENU(9778, pCreature->GetGUID()); - - return true; -} - -bool GossipSelect_npc_erozion(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - if (uiAction == GOSSIP_ACTION_INFO_DEF+1) - { - ItemPosCountVec dest; - uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_ENTRY_BOMBS, 1); - if (msg == EQUIP_ERR_OK) - { - pPlayer->StoreNewItem(dest, ITEM_ENTRY_BOMBS, true); - } - pPlayer->SEND_GOSSIP_MENU(9515, pCreature->GetGUID()); - } - if (uiAction == GOSSIP_ACTION_INFO_DEF+2) - { - pPlayer->CLOSE_GOSSIP_MENU(); - } - return true; -} - -/*###### -## npc_thrall_old_hillsbrad -######*/ - -//Thrall texts -#define SAY_TH_START_EVENT_PART1 -1560023 -#define SAY_TH_ARMORY -1560024 -#define SAY_TH_SKARLOC_MEET -1560025 -#define SAY_TH_SKARLOC_TAUNT -1560026 -#define SAY_TH_START_EVENT_PART2 -1560027 -#define SAY_TH_MOUNTS_UP -1560028 -#define SAY_TH_CHURCH_END -1560029 -#define SAY_TH_MEET_TARETHA -1560030 -#define SAY_TH_EPOCH_WONDER -1560031 -#define SAY_TH_EPOCH_KILL_TARETHA -1560032 -#define SAY_TH_EVENT_COMPLETE -1560033 - -#define SAY_TH_RANDOM_LOW_HP1 -1560034 -#define SAY_TH_RANDOM_LOW_HP2 -1560035 - -#define SAY_TH_RANDOM_DIE1 -1560036 -#define SAY_TH_RANDOM_DIE2 -1560037 - -#define SAY_TH_RANDOM_AGGRO1 -1560038 -#define SAY_TH_RANDOM_AGGRO2 -1560039 -#define SAY_TH_RANDOM_AGGRO3 -1560040 -#define SAY_TH_RANDOM_AGGRO4 -1560041 - -#define SAY_TH_RANDOM_KILL1 -1560042 -#define SAY_TH_RANDOM_KILL2 -1560043 -#define SAY_TH_RANDOM_KILL3 -1560044 - -#define SAY_TH_LEAVE_COMBAT1 -1560045 -#define SAY_TH_LEAVE_COMBAT2 -1560046 -#define SAY_TH_LEAVE_COMBAT3 -1560047 - -//Taretha texts -#define SAY_TA_FREE -1560048 -#define SAY_TA_ESCAPED -1560049 - -//Misc for Thrall -#define SPELL_STRIKE 14516 -#define SPELL_SHIELD_BLOCK 12169 -#define SPELL_SUMMON_EROZION_IMAGE 33954 //if thrall dies during escort? - -#define SPEED_WALK (0.5f) -#define SPEED_RUN (1.0f) -#define SPEED_MOUNT (1.6f) - -#define THRALL_WEAPON_MODEL 22106 -#define THRALL_WEAPON_INFO 218169346 -#define THRALL_SHIELD_MODEL 18662 -#define THRALL_SHIELD_INFO 234948100 -#define THRALL_MODEL_UNEQUIPPED 17292 -#define THRALL_MODEL_EQUIPPED 18165 - -//Misc Creature entries -#define ENTRY_ARMORER 18764 -#define ENTRY_SCARLOC 17862 - -#define MOB_ENTRY_RIFLE 17820 -#define MOB_ENTRY_WARDEN 17833 -#define MOB_ENTRY_VETERAN 17860 -#define MOB_ENTRY_WATCHMAN 17814 -#define MOB_ENTRY_SENTRY 17815 - -#define MOB_ENTRY_BARN_GUARDSMAN 18092 -#define MOB_ENTRY_BARN_PROTECTOR 18093 -#define MOB_ENTRY_BARN_LOOKOUT 18094 - -#define MOB_ENTRY_CHURCH_GUARDSMAN 23175 -#define MOB_ENTRY_CHURCH_PROTECTOR 23179 -#define MOB_ENTRY_CHURCH_LOOKOUT 23177 - -#define MOB_ENTRY_INN_GUARDSMAN 23176 -#define MOB_ENTRY_INN_PROTECTOR 23180 -#define MOB_ENTRY_INN_LOOKOUT 23178 - -#define SKARLOC_MOUNT 18798 -#define SKARLOC_MOUNT_MODEL 18223 -#define EROZION_ENTRY 18723 -#define ENTRY_EPOCH 18096 - -//gossip items -#define GOSSIP_ID_START 9568 -#define GOSSIP_ID_SKARLOC1 9614 //I'm glad Taretha is alive. We now must find a way to free her... -#define GOSSIP_ITEM_SKARLOC1 "Taretha cannot see you, Thrall." -#define GOSSIP_ID_SKARLOC2 9579 //What do you mean by this? Is Taretha in danger? -#define GOSSIP_ITEM_SKARLOC2 "The situation is rather complicated, Thrall. It would be best for you to head into the mountains now, before more of Blackmoore's men show up. We'll make sure Taretha is safe." -#define GOSSIP_ID_SKARLOC3 9580 - -#define GOSSIP_ID_TARREN 9597 //tarren mill is beyond these trees -#define GOSSIP_ITEM_TARREN "We're ready, Thrall." - -#define GOSSIP_ID_COMPLETE 9578 //Thank you friends, I owe my freedom to you. Where is Taretha? I hoped to see her - -#define GOSSIP_ITEM_WALKING "[PH] Start walking." - -struct npc_thrall_old_hillsbradAI : public npc_escortAI -{ - npc_thrall_old_hillsbradAI(Creature *c) : npc_escortAI(c) - { - pInstance = c->GetInstanceData(); - HadMount = false; - me->setActive(true); - } - - ScriptedInstance *pInstance; - - uint64 TarethaGUID; - - bool LowHp; - bool HadMount; - - void WaypointReached(uint32 i) - { - if (!pInstance) - return; - - switch(i) - { - case 8: - SetRun(false); - me->SummonCreature(18764,2181.87,112.46,89.45,0.26,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 9: - DoScriptText(SAY_TH_ARMORY, me); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); - break; - case 10: - me->SetDisplayId(THRALL_MODEL_EQUIPPED); - break; - case 11: - SetRun(); - break; - case 15: - me->SummonCreature(MOB_ENTRY_RIFLE,2200.28,137.37,87.93,5.07,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_WARDEN,2197.44,131.83,87.93,0.78,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_VETERAN,2203.62,135.40,87.93,3.70,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_VETERAN,2200.75,130.13,87.93,1.48,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 21: - me->SummonCreature(MOB_ENTRY_RIFLE,2135.80,154.01,67.45,4.98,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_WARDEN,2144.36,151.87,67.74,4.46,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_VETERAN,2142.12,154.41,67.12,4.56,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_VETERAN,2138.08,155.38,67.24,4.60,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 25: - me->SummonCreature(MOB_ENTRY_RIFLE,2102.98,192.17,65.24,6.02,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_WARDEN,2108.48,198.75,65.18,5.15,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_VETERAN,2106.11,197.29,65.18,5.63,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_VETERAN,2104.18,194.82,65.18,5.75,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 29: - DoScriptText(SAY_TH_SKARLOC_MEET, me); - me->SummonCreature(ENTRY_SCARLOC,2036.48,271.22,63.43,5.27,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000); - //temporary,skarloc should rather be triggered to walk up to thrall - break; - case 30: - SetEscortPaused(true); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SetRun(false); - break; - case 31: - DoScriptText(SAY_TH_MOUNTS_UP, me); - DoMount(); - SetRun(); - break; - case 37: - //possibly regular patrollers? If so, remove this and let database handle them - me->SummonCreature(MOB_ENTRY_WATCHMAN,2124.26,522.16,56.87,3.99,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_WATCHMAN,2121.69,525.37,57.11,4.01,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_SENTRY,2124.65,524.55,56.63,3.98,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 59: - me->SummonCreature(SKARLOC_MOUNT,2488.64,625.77,58.26,4.71,TEMPSUMMON_TIMED_DESPAWN,10000); - DoUnmount(); - HadMount = false; - SetRun(false); - break; - case 60: - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - //make horsie run off - SetEscortPaused(true); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - pInstance->SetData(TYPE_THRALL_PART2, DONE); - SetRun(); - break; - case 64: - SetRun(false); - break; - case 68: - me->SummonCreature(MOB_ENTRY_BARN_PROTECTOR,2500.22,692.60,55.50,2.84,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_BARN_LOOKOUT,2500.13,696.55,55.51,3.38,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN,2500.55,693.64,55.50,3.14,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_BARN_GUARDSMAN,2500.94,695.81,55.50,3.14,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 71: - SetRun(); - break; - case 81: - SetRun(false); - break; - case 83: - me->SummonCreature(MOB_ENTRY_CHURCH_PROTECTOR,2627.33,646.82,56.03,4.28,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); - me->SummonCreature(MOB_ENTRY_CHURCH_LOOKOUT,2624.14,648.03,56.03,4.50,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); - me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN,2625.32,649.60,56.03,4.38,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); - me->SummonCreature(MOB_ENTRY_CHURCH_GUARDSMAN,2627.22,649.00,56.03,4.34,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,5000); - break; - case 84: - DoScriptText(SAY_TH_CHURCH_END, me); - SetRun(); - break; - case 91: - me->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - SetRun(false); - break; - case 93: - me->SummonCreature(MOB_ENTRY_INN_PROTECTOR,2652.71,660.31,61.93,1.67,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_INN_LOOKOUT,2648.96,662.59,61.93,0.79,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN,2657.36,662.34,61.93,2.68,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - me->SummonCreature(MOB_ENTRY_INN_GUARDSMAN,2656.39,659.77,61.93,2.61,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000); - break; - case 94: - if (uint64 TarethaGUID = pInstance->GetData64(DATA_TARETHA)) - { - if (Unit* Taretha = Unit::GetUnit((*me), TarethaGUID)) - DoScriptText(SAY_TA_ESCAPED, Taretha, me); - } - break; - case 95: - DoScriptText(SAY_TH_MEET_TARETHA, me); - pInstance->SetData(TYPE_THRALL_PART3,DONE); - SetEscortPaused(true); - break; - case 96: - DoScriptText(SAY_TH_EPOCH_WONDER, me); - break; - case 97: - DoScriptText(SAY_TH_EPOCH_KILL_TARETHA, me); - SetRun(); - break; - case 98: - //trigger epoch Yell("Thrall! Come outside and face your fate! ....") - //from here, thrall should not never be allowed to move to point 106 which he currently does. - break; - - case 106: - { - //trigger taretha to run down outside - if (Creature* Taretha = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TARETHA))) - { - if (Player* pPlayer = GetPlayerForEscort()) - CAST_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, pPlayer->GetGUID()); - } - - //kill credit Creature for quest - Map* pMap = me->GetMap(); - Map::PlayerList const& players = pMap->GetPlayers(); - if (!players.isEmpty() && pMap->IsDungeon()) - { - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* pPlayer = itr->getSource()) - pPlayer->KilledMonsterCredit(20156,me->GetGUID()); - } - } - - //alot will happen here, thrall and taretha talk, erozion appear at spot to explain - me->SummonCreature(EROZION_ENTRY,2646.47,680.416,55.38,4.16,TEMPSUMMON_TIMED_DESPAWN,120000); - } - break; - case 108: - //last waypoint, just set Thrall invisible, respawn is turned off - me->SetVisibility(VISIBILITY_OFF); - break; - } - } - - void Reset() - { - LowHp = false; - - if (HadMount) - DoMount(); - - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - { - DoUnmount(); - HadMount = false; - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); - me->SetDisplayId(THRALL_MODEL_UNEQUIPPED); - } - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - DoScriptText(RAND(SAY_TH_LEAVE_COMBAT1,SAY_TH_LEAVE_COMBAT2,SAY_TH_LEAVE_COMBAT3), me); - } - } - void StartWP() - { - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - SetEscortPaused(false); - } - void DoMount() - { - me->Mount(SKARLOC_MOUNT_MODEL); - me->SetSpeed(MOVE_RUN,SPEED_MOUNT); - } - void DoUnmount() - { - me->Unmount(); - me->SetSpeed(MOVE_RUN,SPEED_RUN); - } - void EnterCombat(Unit* /*who*/) - { - DoScriptText(RAND(SAY_TH_RANDOM_AGGRO1,SAY_TH_RANDOM_AGGRO2,SAY_TH_RANDOM_AGGRO3,SAY_TH_RANDOM_AGGRO4), me); - if (me->IsMounted()) - { - DoUnmount(); - HadMount = true; - } - } - - void JustSummoned(Creature* summoned) - { - switch(summoned->GetEntry()) - { - //TODO: make Scarloc start into event instead, and not start attack directly - case MOB_ENTRY_BARN_GUARDSMAN: - case MOB_ENTRY_BARN_PROTECTOR: - case MOB_ENTRY_BARN_LOOKOUT: - case SKARLOC_MOUNT: - case EROZION_ENTRY: - break; - default: - summoned->AI()->AttackStart(me); - break; - } - } - - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(RAND(SAY_TH_RANDOM_KILL1,SAY_TH_RANDOM_KILL2,SAY_TH_RANDOM_KILL3), me); - } - void JustDied(Unit *slayer) - { - if (pInstance) - pInstance->SetData(TYPE_THRALL_EVENT,FAIL); - - // Don't do a yell if he kills self (if player goes too far or at the end). - if (slayer == me) - return; - - DoScriptText(RAND(SAY_TH_RANDOM_DIE1,SAY_TH_RANDOM_DIE2), me); - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - //TODO: add his abilities'n-crap here - if (!LowHp && ((me->GetHealth()*100 / me->GetMaxHealth()) < 20)) - { - DoScriptText(RAND(SAY_TH_RANDOM_LOW_HP1,SAY_TH_RANDOM_LOW_HP2), me); - LowHp = true; - } - } -}; - -CreatureAI* GetAI_npc_thrall_old_hillsbrad(Creature* pCreature) -{ - return new npc_thrall_old_hillsbradAI(pCreature); -} - -bool GossipHello_npc_thrall_old_hillsbrad(Player* pPlayer, Creature* pCreature) -{ - if (pCreature->isQuestGiver()) - { - pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - pPlayer->SendPreparedQuest(pCreature->GetGUID()); - } - - ScriptedInstance* pInstance = pCreature->GetInstanceData(); - if (pInstance) - { - if (pInstance->GetData(TYPE_BARREL_DIVERSION) == DONE && !pInstance->GetData(TYPE_THRALL_EVENT)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WALKING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_START, pCreature->GetGUID()); - } - - if (pInstance->GetData(TYPE_THRALL_PART1) == DONE && !pInstance->GetData(TYPE_THRALL_PART2)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SKARLOC1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_SKARLOC1, pCreature->GetGUID()); - } - - if (pInstance->GetData(TYPE_THRALL_PART2) == DONE && !pInstance->GetData(TYPE_THRALL_PART3)) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TARREN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_TARREN, pCreature->GetGUID()); - } - } - return true; -} - -bool GossipSelect_npc_thrall_old_hillsbrad(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - ScriptedInstance* pInstance = pCreature->GetInstanceData(); - switch(uiAction) - { - case GOSSIP_ACTION_INFO_DEF+1: - pPlayer->CLOSE_GOSSIP_MENU(); - if (pInstance) - { - pInstance->SetData(TYPE_THRALL_EVENT,IN_PROGRESS); - pInstance->SetData(TYPE_THRALL_PART1,IN_PROGRESS); - } - - DoScriptText(SAY_TH_START_EVENT_PART1, pCreature); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI())) - pEscortAI->Start(true, true, pPlayer->GetGUID()); - - CAST_AI(npc_escortAI, (pCreature->AI()))->SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far - CAST_AI(npc_escortAI, (pCreature->AI()))->SetDespawnAtEnd(false); - CAST_AI(npc_escortAI, (pCreature->AI()))->SetDespawnAtFar(false); - break; - - case GOSSIP_ACTION_INFO_DEF+2: - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_SKARLOC2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+20); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_SKARLOC2, pCreature->GetGUID()); - break; - - case GOSSIP_ACTION_INFO_DEF+20: - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_SKARLOC3, pCreature->GetGUID()); - pCreature->SummonCreature(SKARLOC_MOUNT,2038.81,270.26,63.20,5.41,TEMPSUMMON_TIMED_DESPAWN,12000); - if (pInstance) - pInstance->SetData(TYPE_THRALL_PART2,IN_PROGRESS); - - DoScriptText(SAY_TH_START_EVENT_PART2, pCreature); - - CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI())->StartWP(); - break; - - case GOSSIP_ACTION_INFO_DEF+3: - pPlayer->CLOSE_GOSSIP_MENU(); - if (pInstance) - pInstance->SetData(TYPE_THRALL_PART3,IN_PROGRESS); - CAST_AI(npc_thrall_old_hillsbradAI, pCreature->AI())->StartWP(); - break; - } - return true; -} - -/*###### -## npc_taretha -######*/ - -#define GOSSIP_ID_EPOCH1 9610 //Thank you for helping Thrall escape, friends. Now I only hope -#define GOSSIP_ITEM_EPOCH1 "Strange wizard?" -#define GOSSIP_ID_EPOCH2 9613 //Yes, friends. This man was no wizard of -#define GOSSIP_ITEM_EPOCH2 "We'll get you out. Taretha. Don't worry. I doubt the wizard would wander too far away." - -struct npc_tarethaAI : public npc_escortAI -{ - npc_tarethaAI(Creature *c) : npc_escortAI(c) - { - pInstance = c->GetInstanceData(); - } - - ScriptedInstance *pInstance; - - void WaypointReached(uint32 i) - { - switch(i) - { - case 6: - DoScriptText(SAY_TA_FREE, me); - break; - case 7: - me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); - break; - } - } - void Reset() {} - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - } -}; -CreatureAI* GetAI_npc_taretha(Creature* pCreature) -{ - return new npc_tarethaAI(pCreature); -} - -bool GossipHello_npc_taretha(Player* pPlayer, Creature* pCreature) -{ - ScriptedInstance* pInstance = pCreature->GetInstanceData(); - if (pInstance && pInstance->GetData(TYPE_THRALL_PART3) == DONE && pInstance->GetData(TYPE_THRALL_PART4) == NOT_STARTED) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_EPOCH1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_EPOCH1, pCreature->GetGUID()); - } - return true; -} - -bool GossipSelect_npc_taretha(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) -{ - ScriptedInstance* pInstance = pCreature->GetInstanceData(); - if (uiAction == GOSSIP_ACTION_INFO_DEF+1) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_EPOCH2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_ID_EPOCH2, pCreature->GetGUID()); - } - if (uiAction == GOSSIP_ACTION_INFO_DEF+2) - { - pPlayer->CLOSE_GOSSIP_MENU(); - - if (pInstance && pInstance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) - { - pInstance->SetData(TYPE_THRALL_PART4,IN_PROGRESS); - if (pInstance->GetData64(DATA_EPOCH) == 0) - pCreature->SummonCreature(ENTRY_EPOCH,2639.13,698.55,65.43,4.59,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,120000); - - if (uint64 ThrallGUID = pInstance->GetData64(DATA_THRALL)) - { - Creature* Thrall = (Unit::GetCreature((*pCreature), ThrallGUID)); - if (Thrall) - CAST_AI(npc_thrall_old_hillsbradAI, Thrall->AI())->StartWP(); - } - } - } - return true; -} - -/*###### -## AddSC -######*/ - -void AddSC_old_hillsbrad() -{ - Script *newscript; - - newscript = new Script; - newscript->Name = "npc_erozion"; - newscript->pGossipHello = &GossipHello_npc_erozion; - newscript->pGossipSelect = &GossipSelect_npc_erozion; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_thrall_old_hillsbrad"; - newscript->pGossipHello = &GossipHello_npc_thrall_old_hillsbrad; - newscript->pGossipSelect = &GossipSelect_npc_thrall_old_hillsbrad; - newscript->GetAI = &GetAI_npc_thrall_old_hillsbrad; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "npc_taretha"; - newscript->pGossipHello = &GossipHello_npc_taretha; - newscript->pGossipSelect = &GossipSelect_npc_taretha; - newscript->GetAI = &GetAI_npc_taretha; - newscript->RegisterSelf(); -} - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.h b/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.h deleted file mode 100644 index 5c398cc2647..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/old_hillsbrad/old_hillsbrad.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 - * This program is free software licensed under GPL version 2 - * Please see the included DOCS/LICENSE.TXT for more information */ - -#ifndef DEF_OLD_HILLSBRAD_H -#define DEF_OLD_HILLSBRAD_H - -#define TYPE_BARREL_DIVERSION 1 -#define TYPE_THRALL_EVENT 2 -#define TYPE_THRALL_PART1 3 -#define TYPE_THRALL_PART2 4 -#define TYPE_THRALL_PART3 5 -#define TYPE_THRALL_PART4 6 -#define DATA_THRALL 7 -#define DATA_TARETHA 8 -#define DATA_EPOCH 9 -#define WORLD_STATE_OH 2436 -#endif - -- cgit v1.2.3