diff options
author | Shauren <shauren.trinity@gmail.com> | 2022-09-27 00:08:16 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-09-30 20:47:31 +0200 |
commit | 0f15d74ffc29b3ba39303fe03b70d9542393772b (patch) | |
tree | 43a42b90c847608c3f4ced6cd7b070ca7a189003 | |
parent | bc7b14b1c6e1a72c9cb2a73f93c2e4e07fa18c0e (diff) |
Scripts/The Escape From Durnholde: Minor improvements
* Converted to BossAI
* Prevent repeating boss kills on Thrall event wipe
(cherry picked from commit 2d027e56ad3d4531300559e46151153032e7e63d)
6 files changed, 692 insertions, 773 deletions
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp index f52f408aa88..9992806e628 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp @@ -47,123 +47,110 @@ enum CaptainSkarloc SPELL_CONSECRATION = 38385 }; -class boss_captain_skarloc : public CreatureScript +struct boss_captain_skarloc : public BossAI { -public: - boss_captain_skarloc() : CreatureScript("boss_captain_skarloc") { } + boss_captain_skarloc(Creature* creature) : BossAI(creature, DATA_CAPTAIN_SKARLOC) + { + Initialize(); + } - CreatureAI* GetAI(Creature* creature) const override + void Initialize() { - return GetOldHillsbradAI<boss_captain_skarlocAI>(creature); + Holy_Light_Timer = urand(20000, 30000); + Cleanse_Timer = 10000; + HammerOfJustice_Timer = urand(20000, 35000); + HolyShield_Timer = 240000; + DevotionAura_Timer = 3000; + Consecration_Timer = 8000; } - struct boss_captain_skarlocAI : public ScriptedAI + uint32 Holy_Light_Timer; + uint32 Cleanse_Timer; + uint32 HammerOfJustice_Timer; + uint32 HolyShield_Timer; + uint32 DevotionAura_Timer; + uint32 Consecration_Timer; + + void Reset() override { - boss_captain_skarlocAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + BossAI::Reset(); + Initialize(); + } - void Initialize() - { - Holy_Light_Timer = urand(20000, 30000); - Cleanse_Timer = 10000; - HammerOfJustice_Timer = urand(20000, 35000); - HolyShield_Timer = 240000; - DevotionAura_Timer = 3000; - Consecration_Timer = 8000; - } + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + //This is not correct. Should taunt Thrall before engage in combat + Talk(SAY_TAUNT1); + Talk(SAY_TAUNT2); + } - InstanceScript* instance; + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_SLAY); + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(SAY_DEATH); + + instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_HORSE_RIDE); + } - uint32 Holy_Light_Timer; - uint32 Cleanse_Timer; - uint32 HammerOfJustice_Timer; - uint32 HolyShield_Timer; - uint32 DevotionAura_Timer; - uint32 Consecration_Timer; + void UpdateAI(uint32 diff) override + { + //Return since we have no target + if (!UpdateVictim()) + return; - void Reset() override + //Holy_Light + if (Holy_Light_Timer <= diff) { - Initialize(); - } + DoCast(me, SPELL_HOLY_LIGHT); + Holy_Light_Timer = 30000; + } else Holy_Light_Timer -= diff; - void JustEngagedWith(Unit* /*who*/) override + //Cleanse + if (Cleanse_Timer <= diff) { - //This is not correct. Should taunt Thrall before engage in combat - Talk(SAY_TAUNT1); - Talk(SAY_TAUNT2); - } + DoCast(me, SPELL_CLEANSE); + Cleanse_Timer = 10000; + } else Cleanse_Timer -= diff; - void KilledUnit(Unit* /*victim*/) override + //Hammer of Justice + if (HammerOfJustice_Timer <= diff) { - Talk(SAY_SLAY); - } + DoCastVictim(SPELL_HAMMER_OF_JUSTICE); + HammerOfJustice_Timer = 60000; + } else HammerOfJustice_Timer -= diff; - void JustDied(Unit* /*killer*/) override + //Holy Shield + if (HolyShield_Timer <= diff) { - Talk(SAY_DEATH); + DoCast(me, SPELL_HOLY_SHIELD); + HolyShield_Timer = 240000; + } else HolyShield_Timer -= diff; - if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) - instance->SetData(TYPE_THRALL_PART1, DONE); - } + //Devotion_Aura + if (DevotionAura_Timer <= diff) + { + DoCast(me, SPELL_DEVOTION_AURA); + DevotionAura_Timer = urand(45000, 55000); + } else DevotionAura_Timer -= diff; - void UpdateAI(uint32 diff) override + //Consecration + if (Consecration_Timer <= 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) - { - DoCastVictim(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 = urand(45000, 55000); - } else DevotionAura_Timer -= diff; - - //Consecration - if (Consecration_Timer <= diff) - { - //DoCastVictim(SPELL_CONSECRATION); - Consecration_Timer = urand(5000, 10000); - } else Consecration_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; + //DoCastVictim(SPELL_CONSECRATION); + Consecration_Timer = urand(5000, 10000); + } else Consecration_Timer -= diff; + DoMeleeAttackIfReady(); + } }; void AddSC_boss_captain_skarloc() { - new boss_captain_skarloc(); + RegisterOldHillsbradCreatureAI(boss_captain_skarloc); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp index 93c035c5e89..25c5b0345f0 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp @@ -45,107 +45,94 @@ enum EpochHunter SPELL_WING_BUFFET = 31475 }; -class boss_epoch_hunter : public CreatureScript +struct boss_epoch_hunter : public BossAI { -public: - boss_epoch_hunter() : CreatureScript("boss_epoch_hunter") { } + boss_epoch_hunter(Creature* creature) : BossAI(creature, DATA_EPOCH_HUNTER) + { + Initialize(); + } - CreatureAI* GetAI(Creature* creature) const override + void Initialize() { - return GetOldHillsbradAI<boss_epoch_hunterAI>(creature); + SandBreath_Timer = urand(8000, 16000); + ImpendingDeath_Timer = urand(25000, 30000); + WingBuffet_Timer = 35000; + Mda_Timer = 40000; } - struct boss_epoch_hunterAI : public ScriptedAI + uint32 SandBreath_Timer; + uint32 ImpendingDeath_Timer; + uint32 WingBuffet_Timer; + uint32 Mda_Timer; + + void Reset() override { - boss_epoch_hunterAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + BossAI::Reset(); + Initialize(); + } - void Initialize() - { - SandBreath_Timer = urand(8000, 16000); - ImpendingDeath_Timer = urand(25000, 30000); - WingBuffet_Timer = 35000; - Mda_Timer = 40000; - } + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + } + + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_SLAY); + } - InstanceScript* instance; + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(SAY_DEATH); - uint32 SandBreath_Timer; - uint32 ImpendingDeath_Timer; - uint32 WingBuffet_Timer; - uint32 Mda_Timer; + instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_FINISHED); + } - void Reset() override - { - Initialize(); - } + void UpdateAI(uint32 diff) override + { + //Return since we have no target + if (!UpdateVictim()) + return; - void JustEngagedWith(Unit* /*who*/) override + //Sand Breath + if (SandBreath_Timer <= diff) { - Talk(SAY_AGGRO); - } + if (me->IsNonMeleeSpellCast(false)) + me->InterruptNonMeleeSpells(false); - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_SLAY); - } + DoCastVictim(SPELL_SAND_BREATH); + + Talk(SAY_BREATH); + + SandBreath_Timer = urand(10000, 20000); + } else SandBreath_Timer -= diff; - void JustDied(Unit* /*killer*/) override + if (ImpendingDeath_Timer <= diff) { - Talk(SAY_DEATH); + DoCastVictim(SPELL_IMPENDING_DEATH); + ImpendingDeath_Timer = 25000 + rand32() % 5000; + } else ImpendingDeath_Timer -= diff; - if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) - instance->SetData(TYPE_THRALL_PART4, DONE); - } + if (WingBuffet_Timer <= diff) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(target, SPELL_WING_BUFFET); + WingBuffet_Timer = 25000 + rand32() % 10000; + } else WingBuffet_Timer -= diff; - void UpdateAI(uint32 diff) override + if (Mda_Timer <= diff) { - //Return since we have no target - if (!UpdateVictim()) - return; - - //Sand Breath - if (SandBreath_Timer <= diff) - { - if (me->IsNonMeleeSpellCast(false)) - me->InterruptNonMeleeSpells(false); - - DoCastVictim(SPELL_SAND_BREATH); - - Talk(SAY_BREATH); - - SandBreath_Timer = urand(10000, 20000); - } else SandBreath_Timer -= diff; - - if (ImpendingDeath_Timer <= diff) - { - DoCastVictim(SPELL_IMPENDING_DEATH); - ImpendingDeath_Timer = 25000 + rand32() % 5000; - } else ImpendingDeath_Timer -= diff; - - if (WingBuffet_Timer <= diff) - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(target, SPELL_WING_BUFFET); - WingBuffet_Timer = 25000 + rand32() % 10000; - } else WingBuffet_Timer -= diff; - - if (Mda_Timer <= diff) - { - DoCast(me, SPELL_MAGIC_DISRUPTION_AURA); - Mda_Timer = 15000; - } else Mda_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; + DoCast(me, SPELL_MAGIC_DISRUPTION_AURA); + Mda_Timer = 15000; + } else Mda_Timer -= diff; + DoMeleeAttackIfReady(); + } }; void AddSC_boss_epoch_hunter() { - new boss_epoch_hunter(); + RegisterOldHillsbradCreatureAI(boss_epoch_hunter); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp index b5ffc37d724..77fbb20f084 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp @@ -31,37 +31,6 @@ EndScriptData */ #include "ScriptedCreature.h" /*###### -## go_barrel_old_hillsbrad -######*/ - -class go_barrel_old_hillsbrad : public GameObjectScript -{ -public: - go_barrel_old_hillsbrad() : GameObjectScript("go_barrel_old_hillsbrad") { } - - struct go_barrel_old_hillsbradAI : public GameObjectAI - { - go_barrel_old_hillsbradAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } - - InstanceScript* instance; - - bool OnGossipHello(Player* /*player*/) override - { - if (instance->GetData(TYPE_BARREL_DIVERSION) == DONE) - return false; - - instance->SetData(TYPE_BARREL_DIVERSION, IN_PROGRESS); - return false; - } - }; - - GameObjectAI* GetAI(GameObject* go) const override - { - return GetOldHillsbradAI<go_barrel_old_hillsbradAI>(go); - } -}; - -/*###### ## boss_lieutenant_drake ######*/ @@ -103,106 +72,117 @@ Position const DrakeWP[]= { 2128.20f, 70.9763f, 64.4221f } }; -class boss_lieutenant_drake : public CreatureScript +struct boss_lieutenant_drake : public BossAI { -public: - boss_lieutenant_drake() : CreatureScript("boss_lieutenant_drake") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_lieutenant_drake(Creature* creature) : BossAI(creature, DATA_LIEUTENANT_DRAKE) { - return GetOldHillsbradAI<boss_lieutenant_drakeAI>(creature); + Initialize(); } - struct boss_lieutenant_drakeAI : public ScriptedAI + void Initialize() { - boss_lieutenant_drakeAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + CanPatrol = true; + wpId = 0; - void Initialize() - { - CanPatrol = true; - wpId = 0; + Whirlwind_Timer = 20000; + Fear_Timer = 30000; + MortalStrike_Timer = 45000; + ExplodingShout_Timer = 25000; + } - Whirlwind_Timer = 20000; - Fear_Timer = 30000; - MortalStrike_Timer = 45000; - ExplodingShout_Timer = 25000; - } + bool CanPatrol; + uint32 wpId; - bool CanPatrol; - uint32 wpId; + uint32 Whirlwind_Timer; + uint32 Fear_Timer; + uint32 MortalStrike_Timer; + uint32 ExplodingShout_Timer; - uint32 Whirlwind_Timer; - uint32 Fear_Timer; - uint32 MortalStrike_Timer; - uint32 ExplodingShout_Timer; + void Reset() override + { + BossAI::Reset(); + Initialize(); + } - void Reset() override - { - Initialize(); - } + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + } + + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_SLAY); + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(SAY_DEATH); + } - void JustEngagedWith(Unit* /*who*/) override + void UpdateAI(uint32 diff) override + { + /// @todo make this work + if (CanPatrol && wpId == 0) { - Talk(SAY_AGGRO); + me->GetMotionMaster()->MovePoint(wpId, DrakeWP[wpId]); + ++wpId; } - void KilledUnit(Unit* /*victim*/) override + //Return since we have no target + if (!UpdateVictim()) + return; + + //Whirlwind + if (Whirlwind_Timer <= diff) { - Talk(SAY_SLAY); - } + DoCastVictim(SPELL_WHIRLWIND); + Whirlwind_Timer = 20000 + rand32() % 5000; + } else Whirlwind_Timer -= diff; - void JustDied(Unit* /*killer*/) override + //Fear + if (Fear_Timer <= diff) { - Talk(SAY_DEATH); - } + Talk(SAY_SHOUT); + DoCastVictim(SPELL_FRIGHTENING_SHOUT); + Fear_Timer = 25000 + rand32() % 10000; + } else Fear_Timer -= diff; - void UpdateAI(uint32 diff) override + //Mortal Strike + if (MortalStrike_Timer <= diff) { - /// @todo make this work - if (CanPatrol && wpId == 0) - { - me->GetMotionMaster()->MovePoint(wpId, DrakeWP[wpId]); - ++wpId; - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - //Whirlwind - if (Whirlwind_Timer <= diff) - { - DoCastVictim(SPELL_WHIRLWIND); - Whirlwind_Timer = 20000 + rand32() % 5000; - } else Whirlwind_Timer -= diff; - - //Fear - if (Fear_Timer <= diff) - { - Talk(SAY_SHOUT); - DoCastVictim(SPELL_FRIGHTENING_SHOUT); - Fear_Timer = 25000 + rand32() % 10000; - } else Fear_Timer -= diff; - - //Mortal Strike - if (MortalStrike_Timer <= diff) - { - Talk(SAY_MORTAL); - DoCastVictim(SPELL_MORTAL_STRIKE); - MortalStrike_Timer = 20000 + rand32() % 10000; - } else MortalStrike_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; + Talk(SAY_MORTAL); + DoCastVictim(SPELL_MORTAL_STRIKE); + MortalStrike_Timer = 20000 + rand32() % 10000; + } else MortalStrike_Timer -= diff; + DoMeleeAttackIfReady(); + } +}; + +/*###### +## go_barrel_old_hillsbrad +######*/ + +struct go_barrel_old_hillsbrad : public GameObjectAI +{ + go_barrel_old_hillsbrad(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } + + InstanceScript* instance; + + bool OnGossipHello(Player* /*player*/) override + { + if (instance->GetData(TYPE_BARREL_DIVERSION) == DONE) + return false; + + instance->SetData(TYPE_BARREL_DIVERSION, IN_PROGRESS); + return false; + } }; void AddSC_boss_lieutenant_drake() { - new go_barrel_old_hillsbrad(); - new boss_lieutenant_drake(); + RegisterOldHillsbradCreatureAI(boss_lieutenant_drake); + RegisterOldHillsbradGameObjectAI(go_barrel_old_hillsbrad); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp index 6deaa484bfe..cef1bc9ad92 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/instance_old_hillsbrad.cpp @@ -23,14 +23,12 @@ SDCategory: Caverns of Time, Old Hillsbrad Foothills EndScriptData */ #include "ScriptMgr.h" -#include "Creature.h" #include "InstanceScript.h" #include "Log.h" #include "Map.h" #include "old_hillsbrad.h" #include "Player.h" - -#define MAX_ENCOUNTER 6 +#include "TemporarySummon.h" #define THRALL_ENTRY 17876 #define TARETHA_ENTRY 18887 @@ -56,13 +54,14 @@ public: instance_old_hillsbrad_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { SetHeaders(DataHeader); - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + SetBossNumber(OldHillsbradFoothillsBossCount); + ThrallEscortState = OH_ESCORT_PRISON_TO_SKARLOC; mBarrelCount = 0; mThrallEventCount = 0; } - uint32 m_auiEncounter[MAX_ENCOUNTER]; + OHThrallEscortStates ThrallEscortState; uint32 mBarrelCount; uint32 mThrallEventCount; @@ -70,18 +69,6 @@ public: ObjectGuid TarethaGUID; ObjectGuid EpochGUID; - Player* GetPlayerInMap() - { - Map::PlayerList const& players = instance->GetPlayers(); - - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (Player* player = itr->GetSource()) - return player; - - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: GetPlayerInMap, but PlayerList is empty!"); - return nullptr; - } - void UpdateQuestCredit() { Map::PlayerList const& players = instance->GetPlayers(); @@ -109,14 +96,6 @@ public: void SetData(uint32 type, uint32 data) override { - Player* player = GetPlayerInMap(); - - if (!player) - { - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: SetData (Type: %u Data %u) cannot find any player.", type, data); - return; - } - switch (type) { case TYPE_BARREL_DIVERSION: @@ -131,62 +110,34 @@ public: TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: go_barrel_old_hillsbrad count %u", mBarrelCount); - m_auiEncounter[0] = IN_PROGRESS; - if (mBarrelCount == 5) { UpdateQuestCredit(); - player->SummonCreature(DRAKE_ENTRY, 2128.43f, 71.01f, 64.42f, 1.74f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30min); - m_auiEncounter[0] = DONE; + if (TempSummon* drake = instance->SummonCreature(DRAKE_ENTRY, { 2128.43f, 71.01f, 64.42f, 1.74f }, nullptr, Milliseconds(30min).count())) + drake->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN); } } break; } case TYPE_THRALL_EVENT: { - if (data == FAIL) + if (data != OH_ESCORT_DEATH_EVENT) { - if (mThrallEventCount <= 20) - { - ++mThrallEventCount; - m_auiEncounter[1] = NOT_STARTED; - TC_LOG_DEBUG("scripts", "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 - { - m_auiEncounter[1] = data; - m_auiEncounter[2] = data; - m_auiEncounter[3] = data; - m_auiEncounter[4] = data; - m_auiEncounter[5] = data; - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.", mThrallEventCount); - } + ThrallEscortState = OHThrallEscortStates(data); + if (Creature* thrall = instance->GetCreature(ThrallGUID)) + thrall->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); } else - m_auiEncounter[1] = data; + { + ++mThrallEventCount; + if (mThrallEventCount >= 20) + ThrallEscortState = OH_ESCORT_FINISHED; // wipe limit reached + else + ThrallEscortState = OH_ESCORT_PRISON_TO_SKARLOC; // not correct, see npc_thrall_old_hillsbrad::InitializeAI for details + } TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall escort event adjusted to data %u.", data); break; } - case TYPE_THRALL_PART1: - m_auiEncounter[2] = data; - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part I adjusted to data %u.", data); - break; - case TYPE_THRALL_PART2: - m_auiEncounter[3] = data; - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part II adjusted to data %u.", data); - break; - case TYPE_THRALL_PART3: - m_auiEncounter[4] = data; - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part III adjusted to data %u.", data); - break; - case TYPE_THRALL_PART4: - m_auiEncounter[5] = data; - TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part IV adjusted to data %u.", data); - break; } } @@ -195,17 +146,9 @@ public: switch (data) { case TYPE_BARREL_DIVERSION: - return m_auiEncounter[0]; + return mBarrelCount >= 5 ? DONE : IN_PROGRESS; 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 ThrallEscortState; } return 0; } @@ -218,13 +161,24 @@ public: return ThrallGUID; case DATA_TARETHA: return TarethaGUID; - case DATA_EPOCH: + case DATA_EPOCH_HUNTER: return EpochGUID; } return ObjectGuid::Empty; } - }; + void ReadSaveDataMore(std::istringstream&) override + { + if (GetBossState(DATA_LIEUTENANT_DRAKE) == DONE) + mBarrelCount = 5; + /* TODO not correct, see npc_thrall_old_hillsbrad::InitializeAI for details + if (GetBossState(DATA_CAPTAIN_SKARLOC) == DONE) + ThrallEscortState = OH_ESCORT_HORSE_RIDE; + if (GetBossState(DATA_EPOCH_HUNTER) == DONE) + ThrallEscortState = OH_ESCORT_FINISHED; + */ + } + }; }; void AddSC_instance_old_hillsbrad() diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 951d3bf60b3..ef1b1377458 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -49,60 +49,53 @@ enum Erozion }; #define GOSSIP_HELLO_EROZION2 "[PH] Teleport please, i'm tired." //not in DB,maybe incorrect? +Position const ThrallRespawnPositionAfterSkarloc(2062.934f, 229.14508f, 64.57113f, 2.338741064071655273); +Position const ThrallRespawnPositionAfterHorseRide(2486.5637f, 624.09796f, 57.95088f, 4.136430263519287109); +Position const ThrallRespawnPositionAfterMeetingTaretha(2660.0847f, 659.54816f, 62.020317f, 5.864306449890136718); + /*###### ## npc_erozion ######*/ -class npc_erozion : public CreatureScript +struct npc_erozion : public ScriptedAI { -public: - npc_erozion() : CreatureScript("npc_erozion") { } - - struct npc_erozionAI : public ScriptedAI - { - npc_erozionAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { } + npc_erozion(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { } - InstanceScript* instance; + InstanceScript* instance; - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); + ClearGossipMenuFor(player); + if (action == GOSSIP_ACTION_INFO_DEF + 1) { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF + 1) + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_ENTRY_BOMBS, 1); + if (msg == EQUIP_ERR_OK) { - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_ENTRY_BOMBS, 1); - if (msg == EQUIP_ERR_OK) - { - player->StoreNewItem(dest, ITEM_ENTRY_BOMBS, true); - } - SendGossipMenuFor(player, 9515, me->GetGUID()); + player->StoreNewItem(dest, ITEM_ENTRY_BOMBS, true); } - if (action == GOSSIP_ACTION_INFO_DEF + 2) - CloseGossipMenuFor(player); - return true; + SendGossipMenuFor(player, 9515, me->GetGUID()); } + if (action == GOSSIP_ACTION_INFO_DEF + 2) + CloseGossipMenuFor(player); + return true; + } - bool OnGossipHello(Player* player) override - { - if (me->IsQuestGiver()) - player->PrepareQuestMenu(me->GetGUID()); - - if (instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS)) - AddGossipItemFor(player, GOSSIP_MENU_EROZION, GOSSIP_OPTION_BOMB, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + bool OnGossipHello(Player* player) override + { + if (me->IsQuestGiver()) + player->PrepareQuestMenu(me->GetGUID()); - if (player->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE) - AddGossipItemFor(player, GossipOptionNpc::None, GOSSIP_HELLO_EROZION2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + if (instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS)) + AddGossipItemFor(player, GOSSIP_MENU_EROZION, GOSSIP_OPTION_BOMB, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, 9778, me->GetGUID()); + if (player->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE) + AddGossipItemFor(player, GossipOptionNpc::None, GOSSIP_HELLO_EROZION2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - return true; - } - }; + SendGossipMenuFor(player, 9778, me->GetGUID()); - CreatureAI* GetAI(Creature* creature) const override - { - return GetOldHillsbradAI<npc_erozionAI>(creature); + return true; } }; @@ -191,359 +184,381 @@ enum ThrallOldHillsbrad #define SPEED_RUN (1.0f) #define SPEED_MOUNT (1.6f) -class npc_thrall_old_hillsbrad : public CreatureScript +struct npc_thrall_old_hillsbrad : public EscortAI { -public: - npc_thrall_old_hillsbrad() : CreatureScript("npc_thrall_old_hillsbrad") { } + npc_thrall_old_hillsbrad(Creature* creature) : EscortAI(creature) + { + Initialize(); + instance = creature->GetInstanceScript(); + HadMount = false; + me->setActive(true); + me->SetFarVisible(true); + } + + void Initialize() + { + LowHp = false; + } - struct npc_thrall_old_hillsbradAI : public EscortAI + void InitializeAI() override { - npc_thrall_old_hillsbradAI(Creature* creature) : EscortAI(creature) + /* correct respawn positions after wipe cannot be used because of how waypoints are set up for this creature + * it would require splitting the path into 4 segments, moving it out of script_waypoint table and changing + * all waypoint ids in WaypointReached function + switch (instance->GetData(TYPE_THRALL_EVENT)) { - Initialize(); - instance = creature->GetInstanceScript(); - HadMount = false; - me->setActive(true); - me->SetFarVisible(true); + case OH_ESCORT_HORSE_RIDE: + me->Relocate(ThrallRespawnPositionAfterSkarloc); + break; + case OH_ESCORT_BARN_TO_TARETHA: + me->Relocate(ThrallRespawnPositionAfterHorseRide); + break; + case OH_ESCORT_EPOCH_HUNTER: + me->Relocate(ThrallRespawnPositionAfterMeetingTaretha); + break; + default: + break; } - void Initialize() + if (instance->GetData(TYPE_THRALL_EVENT) != OH_ESCORT_PRISON_TO_SKARLOC) { - LowHp = false; + me->SetVirtualItem(0, THRALL_WEAPON_ITEM); + me->SetVirtualItem(1, THRALL_SHIELD_ITEM); + me->SetDisplayId(THRALL_MODEL_EQUIPPED); } + */ - InstanceScript* instance; + EscortAI::InitializeAI(); + me->SetRespawnCompatibilityMode(true); + } - bool LowHp; - bool HadMount; + InstanceScript* instance; - void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override + bool LowHp; + bool HadMount; + + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override + { + switch (waypointId) { - switch (waypointId) - { - case 8: - SetRun(false); - me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 9: - Talk(SAY_TH_ARMORY); - me->SetVirtualItem(0, THRALL_WEAPON_ITEM); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); - me->SetVirtualItem(1, THRALL_SHIELD_ITEM); - //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(NPC_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 21: - me->SummonCreature(NPC_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 25: - me->SummonCreature(NPC_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 29: - Talk(SAY_TH_SKARLOC_MEET); + case 8: + SetRun(false); + me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 9: + Talk(SAY_TH_ARMORY); + me->SetVirtualItem(0, THRALL_WEAPON_ITEM); + me->SetVirtualItem(1, THRALL_SHIELD_ITEM); + break; + case 10: + me->SetDisplayId(THRALL_MODEL_EQUIPPED); + break; + case 11: + SetRun(); + break; + case 15: + me->SummonCreature(NPC_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 21: + me->SummonCreature(NPC_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 25: + me->SummonCreature(NPC_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 29: + Talk(SAY_TH_SKARLOC_MEET); + if (instance->GetBossState(DATA_CAPTAIN_SKARLOC) != DONE) me->SummonCreature(ENTRY_SCARLOC, 2036.48f, 271.22f, 63.43f, 5.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s); - //temporary, skarloc should rather be triggered to walk up to thrall - break; - case 30: - SetEscortPaused(true); - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - SetRun(false); - break; - case 31: - Talk(SAY_TH_MOUNTS_UP); - DoMount(); - SetRun(); - break; - case 37: - //possibly regular patrollers? If so, remove this and let database handle them - me->SummonCreature(NPC_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 59: - me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10s); - DoUnmount(); - HadMount = false; - SetRun(false); - break; - case 60: - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - //make horsie run off - SetEscortPaused(true); - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); - instance->SetData(TYPE_THRALL_PART2, DONE); - SetRun(); - break; - case 64: - SetRun(false); - break; - case 68: - me->SummonCreature(NPC_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 71: - SetRun(); - break; - case 81: - SetRun(false); - break; - case 83: - me->SummonCreature(NPC_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); - me->SummonCreature(NPC_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); - me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); - me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); - break; - case 84: - Talk(SAY_TH_CHURCH_END); - SetRun(); - break; - case 91: - me->SetWalk(true); - SetRun(false); - break; - case 93: - me->SummonCreature(NPC_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); - break; - case 94: + else + { + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); // wipe recovery, prevent repeatedly farming the boss + instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_HORSE_RIDE); + } + SetEscortPaused(true); + //temporary, skarloc should rather be triggered to walk up to thrall + break; + case 30: + SetRun(false); + break; + case 31: + Talk(SAY_TH_MOUNTS_UP); + HadMount = true; + DoMount(); + SetRun(); + break; + case 37: + //possibly regular patrollers? If so, remove this and let database handle them + me->SummonCreature(NPC_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 59: + me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10s); + DoUnmount(); + HadMount = false; + SetRun(false); + break; + case 60: + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + //make horsie run off + SetEscortPaused(true); + instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_BARN_TO_TARETHA); + SetRun(); + break; + case 64: + SetRun(false); + break; + case 68: + me->SummonCreature(NPC_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 71: + SetRun(); + break; + case 81: + SetRun(false); + break; + case 83: + me->SummonCreature(NPC_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); + me->SummonCreature(NPC_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); + me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); + me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s); + break; + case 84: + Talk(SAY_TH_CHURCH_END); + SetRun(); + break; + case 91: + me->SetWalk(true); + SetRun(false); + break; + case 93: + me->SummonCreature(NPC_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s); + break; + case 94: + if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA))) + Taretha->AI()->Talk(SAY_TA_ESCAPED, me); + break; + case 95: + Talk(SAY_TH_MEET_TARETHA); + instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_EPOCH_HUNTER); + SetEscortPaused(true); + break; + case 96: + Talk(SAY_TH_EPOCH_WONDER); + break; + case 97: + Talk(SAY_TH_EPOCH_KILL_TARETHA); + 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 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA))) - Taretha->AI()->Talk(SAY_TA_ESCAPED, me); - break; - case 95: - Talk(SAY_TH_MEET_TARETHA); - instance->SetData(TYPE_THRALL_PART3, DONE); - SetEscortPaused(true); - break; - case 96: - Talk(SAY_TH_EPOCH_WONDER); - break; - case 97: - Talk(SAY_TH_EPOCH_KILL_TARETHA); - 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 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA))) - { - if (Player* player = GetPlayerForEscort()) - ENSURE_AI(EscortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); - } - - //kill credit Creature for quest - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* player = itr->GetSource()) - player->KilledMonsterCredit(20156); - } - - //alot will happen here, thrall and taretha talk, erozion appear at spot to explain - me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 2min); + if (Player* player = GetPlayerForEscort()) + ENSURE_AI(EscortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); } - break; - case 108: - //last waypoint, just set Thrall invisible, respawn is turned off - me->SetVisible(false); - break; - } + + //kill credit Creature for quest + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* player = itr->GetSource()) + player->KilledMonsterCredit(20156); + } + + //alot will happen here, thrall and taretha talk, erozion appear at spot to explain + me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 2min); + } + break; + case 108: + //last waypoint, just set Thrall invisible, respawn is turned off + me->SetVisible(false); + break; } + } - void Reset() override - { - Initialize(); + void Reset() override + { + Initialize(); - if (HadMount) - DoMount(); + if (HadMount) + DoMount(); - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - { - DoUnmount(); - HadMount = false; - me->SetVirtualItem(0, 0); - me->SetVirtualItem(1, 0); - me->SetDisplayId(THRALL_MODEL_UNEQUIPPED); - } - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - Talk(SAY_TH_LEAVE_COMBAT); - } - } - void StartWP() - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - SetEscortPaused(false); - } - void DoMount() - { - me->Mount(SKARLOC_MOUNT_MODEL); - me->SetSpeedRate(MOVE_RUN, SPEED_MOUNT); - } - void DoUnmount() + if (!HasEscortState(STATE_ESCORT_ESCORTING)) { - me->Dismount(); - me->SetSpeedRate(MOVE_RUN, SPEED_RUN); + DoUnmount(); + HadMount = false; + me->SetVirtualItem(0, 0); + me->SetVirtualItem(1, 0); + me->SetDisplayId(THRALL_MODEL_UNEQUIPPED); } - void JustEngagedWith(Unit* /*who*/) override + if (HasEscortState(STATE_ESCORT_ESCORTING)) { - Talk(SAY_TH_RANDOM_AGGRO); - if (me->IsMounted()) - { - DoUnmount(); - HadMount = true; - } + Talk(SAY_TH_LEAVE_COMBAT); } + } + void StartWP() + { + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + SetEscortPaused(false); + } + void DoMount() + { + me->Mount(SKARLOC_MOUNT_MODEL); + me->SetSpeedRate(MOVE_RUN, SPEED_MOUNT); + } + void DoUnmount() + { + me->Dismount(); + me->SetSpeedRate(MOVE_RUN, SPEED_RUN); + } + void JustEngagedWith(Unit* /*who*/) override + { + Talk(SAY_TH_RANDOM_AGGRO); + if (me->IsMounted()) + DoUnmount(); + } - void JustSummoned(Creature* summoned) override - { - switch (summoned->GetEntry()) - { - /// @todo make Scarloc start into event instead, and not start attack directly - case NPC_BARN_GUARDSMAN: - case NPC_BARN_PROTECTOR: - case NPC_BARN_LOOKOUT: - case SKARLOC_MOUNT: - case EROZION_ENTRY: - break; - default: - summoned->AI()->AttackStart(me); - break; - } - } + void JustReachedHome() override + { + EscortAI::JustReachedHome(); + if (HadMount) + DoMount(); + } - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_TH_RANDOM_KILL); - } - void JustDied(Unit* killer) override - { - instance->SetData(TYPE_THRALL_EVENT, FAIL); + void JustSummoned(Creature* summoned) override + { + switch (summoned->GetEntry()) + { + /// @todo make Scarloc start into event instead, and not start attack directly + case NPC_BARN_GUARDSMAN: + case NPC_BARN_PROTECTOR: + case NPC_BARN_LOOKOUT: + case SKARLOC_MOUNT: + case EROZION_ENTRY: + break; + default: + summoned->AI()->AttackStart(me); + break; + } + } - // Don't do a yell if he kills self (if player goes too far or at the end). - if (killer == me) - return; + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_TH_RANDOM_KILL); + } + void JustDied(Unit* killer) override + { + instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_DEATH_EVENT); - Talk(SAY_TH_RANDOM_DIE); - } + // Don't do a yell if he kills self (if player goes too far or at the end). + if (killer == me) + return; - void UpdateAI(uint32 diff) override - { - EscortAI::UpdateAI(diff); + Talk(SAY_TH_RANDOM_DIE); + } - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + EscortAI::UpdateAI(diff); - /// @todo add his abilities'n-crap here - if (!LowHp && HealthBelowPct(20)) - { - Talk(SAY_TH_RANDOM_LOW_HP); - LowHp = true; - } + if (!UpdateVictim()) + return; + + /// @todo add his abilities'n-crap here + if (!LowHp && HealthBelowPct(20)) + { + Talk(SAY_TH_RANDOM_LOW_HP); + LowHp = true; } + } - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); + ClearGossipMenuFor(player); + switch (action) { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - CloseGossipMenuFor(player); - instance->SetData(TYPE_THRALL_EVENT, IN_PROGRESS); - instance->SetData(TYPE_THRALL_PART1, IN_PROGRESS); + case GOSSIP_ACTION_INFO_DEF + 1: + CloseGossipMenuFor(player); - Talk(SAY_TH_START_EVENT_PART1); + Talk(SAY_TH_START_EVENT_PART1); - Start(true, true, player->GetGUID()); + Start(true, true, player->GetGUID()); - SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far - SetDespawnAtEnd(false); - SetDespawnAtFar(false); - break; + SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far + SetDespawnAtEnd(false); + SetDespawnAtFar(false); + break; - case GOSSIP_ACTION_INFO_DEF + 2: - AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC2_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20); - SendGossipMenuFor(player, GOSSIP_ID_SKARLOC2, me->GetGUID()); - break; + case GOSSIP_ACTION_INFO_DEF + 2: + AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC2_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20); + SendGossipMenuFor(player, GOSSIP_ID_SKARLOC2, me->GetGUID()); + break; - case GOSSIP_ACTION_INFO_DEF + 20: - SendGossipMenuFor(player, GOSSIP_ID_SKARLOC3, me->GetGUID()); - me->SummonCreature(SKARLOC_MOUNT, 2038.81f, 270.26f, 63.20f, 5.41f, TEMPSUMMON_TIMED_DESPAWN, 12s); - instance->SetData(TYPE_THRALL_PART2, IN_PROGRESS); + case GOSSIP_ACTION_INFO_DEF + 20: + SendGossipMenuFor(player, GOSSIP_ID_SKARLOC3, me->GetGUID()); + me->SummonCreature(SKARLOC_MOUNT, 2038.81f, 270.26f, 63.20f, 5.41f, TEMPSUMMON_TIMED_DESPAWN, 12s); - Talk(SAY_TH_START_EVENT_PART2); + Talk(SAY_TH_START_EVENT_PART2); - StartWP(); - break; + StartWP(); + break; - case GOSSIP_ACTION_INFO_DEF + 3: - CloseGossipMenuFor(player); - instance->SetData(TYPE_THRALL_PART3, IN_PROGRESS); - StartWP(); - break; - } - return true; + case GOSSIP_ACTION_INFO_DEF + 3: + CloseGossipMenuFor(player); + StartWP(); + break; } + return true; + } - bool OnGossipHello(Player* player) override + bool OnGossipHello(Player* player) override + { + if (me->IsQuestGiver()) { - if (me->IsQuestGiver()) - { - player->PrepareQuestMenu(me->GetGUID()); - player->SendPreparedQuest(me); - } - - if (instance->GetData(TYPE_BARREL_DIVERSION) == DONE && !instance->GetData(TYPE_THRALL_EVENT)) - { - AddGossipItemFor(player, GOSSIP_ITEM_WALKING_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, GOSSIP_ID_START, me->GetGUID()); - } + player->PrepareQuestMenu(me->GetGUID()); + player->SendPreparedQuest(me); + } - if (instance->GetData(TYPE_THRALL_PART1) == DONE && !instance->GetData(TYPE_THRALL_PART2)) - { - AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC1_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - SendGossipMenuFor(player, GOSSIP_ID_SKARLOC1, me->GetGUID()); - } + if (instance->GetBossState(DATA_LIEUTENANT_DRAKE) == DONE && instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_PRISON_TO_SKARLOC) + { + AddGossipItemFor(player, GOSSIP_ITEM_WALKING_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + SendGossipMenuFor(player, GOSSIP_ID_START, me->GetGUID()); + } - if (instance->GetData(TYPE_THRALL_PART2) == DONE && !instance->GetData(TYPE_THRALL_PART3)) - { - AddGossipItemFor(player, GOSSIP_ITEM_TARREN_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - SendGossipMenuFor(player, GOSSIP_ID_TARREN, me->GetGUID()); - } - return true; + if (instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_HORSE_RIDE) + { + AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC1_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + SendGossipMenuFor(player, GOSSIP_ID_SKARLOC1, me->GetGUID()); } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetOldHillsbradAI<npc_thrall_old_hillsbradAI>(creature); + if (instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_BARN_TO_TARETHA) + { + AddGossipItemFor(player, GOSSIP_ITEM_TARREN_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + SendGossipMenuFor(player, GOSSIP_ID_TARREN, me->GetGUID()); + } + return true; } }; @@ -560,82 +575,64 @@ enum Taretha GOSSIP_ITEM_EPOCH2_OID = 0 //We'll get you out, Taretha. Don't worry. I doubt the wizard would wander too far away. }; -class npc_taretha : public CreatureScript +struct npc_taretha : public EscortAI { -public: - npc_taretha() : CreatureScript("npc_taretha") { } - - struct npc_tarethaAI : public EscortAI + npc_taretha(Creature* creature) : EscortAI(creature) { - npc_tarethaAI(Creature* creature) : EscortAI(creature) - { - instance = creature->GetInstanceScript(); - } + instance = creature->GetInstanceScript(); + } - InstanceScript* instance; + InstanceScript* instance; - void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override + { + switch (waypointId) { - switch (waypointId) - { - case 6: - Talk(SAY_TA_FREE); - break; - case 7: - me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); - break; - } + case 6: + Talk(SAY_TA_FREE); + break; + case 7: + me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); + break; } + } - void Reset() override { } - void JustEngagedWith(Unit* /*who*/) override { } + void Reset() override { } + void JustEngagedWith(Unit* /*who*/) override { } - void UpdateAI(uint32 diff) override + bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); + ClearGossipMenuFor(player); + + if (action == GOSSIP_ACTION_INFO_DEF + 1) { - EscortAI::UpdateAI(diff); + AddGossipItemFor(player, GOSSIP_ITEM_EPOCH2_MID, GOSSIP_ITEM_EPOCH2_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + SendGossipMenuFor(player, GOSSIP_ID_EPOCH2, me->GetGUID()); } - - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + if (action == GOSSIP_ACTION_INFO_DEF + 2) { - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); - ClearGossipMenuFor(player); + CloseGossipMenuFor(player); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - AddGossipItemFor(player, GOSSIP_ITEM_EPOCH2_MID, GOSSIP_ITEM_EPOCH2_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - SendGossipMenuFor(player, GOSSIP_ID_EPOCH2, me->GetGUID()); - } - if (action == GOSSIP_ACTION_INFO_DEF + 2) - { - CloseGossipMenuFor(player); + if (instance->GetGuidData(DATA_EPOCH_HUNTER).IsEmpty()) + me->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 2min); - if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) - { - instance->SetData(TYPE_THRALL_PART4, IN_PROGRESS); - if (instance->GetGuidData(DATA_EPOCH).IsEmpty()) - me->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 2min); + if (Creature* thrall = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THRALL))) + ENSURE_AI(npc_thrall_old_hillsbrad, thrall->AI())->StartWP(); - if (Creature* thrall = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THRALL))) - ENSURE_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, thrall->AI())->StartWP(); - } - } - return true; + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); } + return true; + } - bool OnGossipHello(Player* player) override + bool OnGossipHello(Player* player) override + { + if (instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_EPOCH_HUNTER && instance->GetBossState(DATA_EPOCH_HUNTER) != DONE) { - if (instance->GetData(TYPE_THRALL_PART3) == DONE && instance->GetData(TYPE_THRALL_PART4) == NOT_STARTED) - { - AddGossipItemFor(player, GOSSIP_ITEM_EPOCH1_MID, GOSSIP_ITEM_EPOCH1_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, GOSSIP_ID_EPOCH1, me->GetGUID()); - } - return true; + AddGossipItemFor(player, GOSSIP_ITEM_EPOCH1_MID, GOSSIP_ITEM_EPOCH1_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + SendGossipMenuFor(player, GOSSIP_ID_EPOCH1, me->GetGUID()); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetOldHillsbradAI<npc_tarethaAI>(creature); + return true; } }; @@ -645,7 +642,7 @@ public: void AddSC_old_hillsbrad() { - new npc_erozion(); - new npc_thrall_old_hillsbrad(); - new npc_taretha(); + RegisterOldHillsbradCreatureAI(npc_erozion); + RegisterOldHillsbradCreatureAI(npc_thrall_old_hillsbrad); + RegisterOldHillsbradCreatureAI(npc_taretha); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h index 882b2e398bf..c43d0ca1a24 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h @@ -23,19 +23,19 @@ #define OHScriptName "instance_old_hillsbrad" #define DataHeader "OH" +constexpr uint32 OldHillsbradFoothillsBossCount = 3; + enum OHDataTypes { - TYPE_BARREL_DIVERSION = 1, - TYPE_THRALL_EVENT = 2, - TYPE_THRALL_PART1 = 3, - TYPE_THRALL_PART2 = 4, - TYPE_THRALL_PART3 = 5, - TYPE_THRALL_PART4 = 6, + DATA_LIEUTENANT_DRAKE = 0, + DATA_CAPTAIN_SKARLOC = 1, + DATA_EPOCH_HUNTER = 2, - DATA_THRALL = 7, - DATA_TARETHA = 8, - DATA_EPOCH = 9 + TYPE_BARREL_DIVERSION = 3, + TYPE_THRALL_EVENT = 4, + DATA_THRALL = 5, + DATA_TARETHA = 6 }; enum OHWorldStateIds @@ -43,10 +43,24 @@ enum OHWorldStateIds WORLD_STATE_OH = 2436 }; +enum OHThrallEscortStates +{ + OH_ESCORT_PRISON_TO_SKARLOC, + OH_ESCORT_HORSE_RIDE, + OH_ESCORT_BARN_TO_TARETHA, + OH_ESCORT_EPOCH_HUNTER, + OH_ESCORT_FINISHED, + + OH_ESCORT_DEATH_EVENT // increment wipe counter +}; + template <class AI, class T> inline AI* GetOldHillsbradAI(T* obj) { return GetInstanceAI<AI>(obj, OHScriptName); } +#define RegisterOldHillsbradCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetOldHillsbradAI) +#define RegisterOldHillsbradGameObjectAI(ai_name) RegisterGameObjectAIWithFactory(ai_name, GetOldHillsbradAI) + #endif |