diff --git a/sql/updates/world/4.3.4/2017_12_27_00_world.sql b/sql/updates/world/4.3.4/2017_12_27_00_world.sql
new file mode 100644
index 00000000000..d3c5399ac37
--- /dev/null
+++ b/sql/updates/world/4.3.4/2017_12_27_00_world.sql
@@ -0,0 +1,41 @@
+-- Lockmaw
+UPDATE `creature_template` SET `difficulty_entry_1`= 49043, `mechanic_immune_mask`= 667893759, `scriptname`= 'boss_lockmaw' WHERE `entry`= 43614;
+UPDATE `creature_template` SET `minlevel`= 87, `maxlevel`= 87, `faction`= 16, `exp`= 3, `mechanic_immune_mask`= 667893759 WHERE `entry`= 49043;
+-- Dust Flail Front
+UPDATE `creature_template` SET `minlevel`= 80, `maxlevel`= 80, `faction`= 14, `unit_flags`= 33554944, `flags_extra`= 128 WHERE `entry`= 43655;
+-- Dust Flail Back
+UPDATE `creature_template` SET `minlevel`= 85, `maxlevel`= 85, `faction`= 14, `unit_flags`= 33554944, `flags_extra`= 128 WHERE `entry`= 43650;
+-- Frenzied Crocolisk
+UPDATE `creature_template` SET `minlevel`= 84, `maxlevel`= 84, `difficulty_entry_1`= 49311, `flags_extra`= 256, `scriptname`= 'npc_lockmaw_frenzied_crocolisk' WHERE `entry`= 43658;
+UPDATE `creature_template` SET `minlevel`= 85, `maxlevel`= 85, `faction`= 16, `exp`= 3, `flags_extra`= 256 WHERE `entry`= 49311;
+-- Augh 1 and 2
+UPDATE `creature_template` SET `unit_flags`= 32832, `mechanic_immune_mask`= 667893759, `scriptname`= 'npc_lockmaw_augh' WHERE `entry` IN (45379, 45378);
+-- Augh
+UPDATE `creature_template` SET `mechanic_immune_mask`= 667893759, `scriptname`= 'boss_augh' WHERE `entry`= 49045;
+-- Add Stalker
+UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 131 WHERE `entry`= 45124;
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN
+('spell_lockmaw_paralytic_blow_dart',
+'spell_lockmaw_scent_of_blood',
+'spell_lockmaw_random_aggro_taunt');
+
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(84799, 'spell_lockmaw_paralytic_blow_dart'),
+(89989, 'spell_lockmaw_paralytic_blow_dart'),
+(81690, 'spell_lockmaw_scent_of_blood'),
+(89998, 'spell_lockmaw_scent_of_blood'),
+(50230, 'spell_lockmaw_random_aggro_taunt');
+
+DELETE FROM `creature_template_addon` WHERE `entry`= 43650;
+INSERT INTO `creature_template_addon` (`entry`, `Auras`) VALUES
+(43650, '81646');
+
+DELETE FROM `creature_text` WHERE `CreatureID`= 49045;
+INSERT INTO `creature_text` (`CreatureID`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `comment`) VALUES
+(49045, 0, 0, 'Augh appears from the distance!', 41, 0, 0, 0, 0, 0, 50638, 'Augh - Intro 1'),
+(49045, 1, 0, 'GAAAH! How you kill croc?!', 12, 0, 0, 53, 0, 0, 49169, 'Augh - Intro 2'),
+(49045, 2, 0, 'Augh smart! Augh already steal treasure while you no looking!', 12, 0, 0, 1, 0, 0, 49170, 'Augh - Intro 3'),
+(49045, 3, 0, 'Augh da boss! Oh yeah!', 12, 0, 0, 0, 0, 0, 49171, 'Augh Taunt'),
+(49045, 4, 0, 'Augh steal your treasure. Uhn uhn uhnnn!', 12, 0, 0, 0, 0, 0, 49173, 'Augh Taunt'),
+(49045, 5, 0, 'Who bad?! Augh bad!! Ugn!', 12, 0, 0, 0, 0, 0, 49172, 'Augh Taunt');
diff --git a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_lockmaw_and_augh.cpp b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_lockmaw_and_augh.cpp
new file mode 100644
index 00000000000..937b30df057
--- /dev/null
+++ b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/boss_lockmaw_and_augh.cpp
@@ -0,0 +1,619 @@
+/*
+* Copyright (C) 2008-2017 TrinityCore
+*
+* 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, see .
+*/
+
+#include "ScriptMgr.h"
+#include "lost_city_of_the_tolvir.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "ScriptedCreature.h"
+#include "SpellAuraEffects.h"
+#include "SpellScript.h"
+
+enum Texts
+{
+ // Augh Boss
+ SAY_ANNOUNCE_AUGH_APPEAR = 0,
+ SAY_AUGH_INTRO_1 = 1,
+ SAY_AUGH_INTRO_2 = 2,
+ SAY_AUGH_TAUNT_1 = 3,
+ SAY_AUGH_TAUNT_2 = 4,
+ SAY_AUGH_TAUNT_3 = 5
+};
+
+enum Spells
+{
+ // Lockmaw
+ SPELL_VISCOUS_POISON = 81630,
+ SPELL_SCENT_OF_BLOOD = 81690,
+ SPELL_SCENT_OF_BLOOD_HC = 89998,
+ SPELL_DUST_FLAIL_DUMMY = 81652,
+ SPELL_DUST_FLAIL = 81642,
+ SPELL_VENOMOUS_RAGE = 81706,
+
+ // Frenzied Crocolisk
+ SPELL_STEALTHED = 84244,
+
+ // Augh (Combat Assistance)
+ SPELL_PARALYTIC_BLOW_DART = 84799,
+ SPELL_SMOKE_BOMB = 84768,
+ SPELL_RANDOM_AGGRO_TAUNT = 50230,
+ SPELL_WHIRLWIND = 84784,
+
+ // Augh (Heroic Boss)
+ SPELL_DRAGONS_BREATH = 83776,
+ SPELL_FRENZY = 91415,
+ SPELL_WHIRLWIND_BOSS = 91408
+};
+
+enum Events
+{
+ // Lockmaw
+ EVENT_VISCOUS_POISON = 1,
+ EVENT_SCENT_OF_BLOOD,
+ EVENT_DUST_FLAIL,
+ EVENT_MAKE_AGGRESSIVE,
+ EVENT_SUMMON_CROCOLISK,
+ EVENT_SUMMON_AUGH,
+
+ // Frenzied Crocolisk
+ EVENT_FIND_PLAYER_TARGET,
+
+ // Augh (Assistance)
+ EVENT_ROAR_EMOTE,
+ EVENT_PARALYTIC_BLOW_DART,
+ EVENT_SMOKE_BOMB,
+ EVENT_WHIRLWIND,
+ EVENT_RANDOM_AGGRO,
+ EVENT_ATTACK_STOP,
+
+ // Augh Boss
+ EVENT_MOVE_HOME_POS,
+ EVENT_TALK_INTRO_1,
+ EVENT_TALK_INTRO_2,
+ EVENT_PLAY_EMOTE,
+ EVENT_MAKE_ATTACKABLE,
+ EVENT_TALK_TAUNT_1,
+ EVENT_TALK_TAUNT_2,
+ EVENT_TALK_TAUNT_3,
+ EVENT_DRAGONS_BREATH
+
+};
+
+enum Phases
+{
+ PHASE_INTRO = 1,
+ PHASE_COMBAT
+};
+
+enum Actions
+{
+ ACTION_AUGH_INTRO = 1,
+ ACTION_AUGH_ATTACKABLE = 2
+};
+
+Position const AughMovePoint = { -11062.5f, -1662.39f, 0.7606202f, 0.8028514f };
+
+class ScentOfBloodTargetSelector : public std::unary_function
+{
+public:
+ ScentOfBloodTargetSelector() { }
+
+ bool operator()(Unit* unit) const
+ {
+ return (!unit->HasAura(SPELL_SCENT_OF_BLOOD) || !unit->HasAura(SPELL_SCENT_OF_BLOOD_HC));
+ }
+};
+
+class boss_lockmaw : public CreatureScript
+{
+ public:
+ boss_lockmaw() : CreatureScript("boss_lockmaw") { }
+
+ struct boss_lockmawAI : public BossAI
+ {
+ boss_lockmawAI(Creature* creature) : BossAI(creature, DATA_LOCKMAW)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ _enraged = false;
+ _lastSpellID = 0;
+ }
+
+ void Reset() override
+ {
+ instance->SetBossState(DATA_LOCKMAW_AND_AUGH, NOT_STARTED);
+ instance->SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_NONE);
+ _Reset();
+ Initialize();
+ }
+
+ void EnterCombat(Unit* /*victim*/) override
+ {
+ _EnterCombat();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
+ events.ScheduleEvent(EVENT_VISCOUS_POISON, Seconds(6));
+ events.ScheduleEvent(EVENT_SCENT_OF_BLOOD, Seconds(6));
+ events.ScheduleEvent(EVENT_DUST_FLAIL, Seconds(8));
+ events.ScheduleEvent(EVENT_SUMMON_AUGH, Seconds(6));
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ _EnterEvadeMode();
+ summons.DespawnAll();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ _DespawnAtEvade();
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ summons.Summon(summon);
+
+ if (summon->GetEntry() == NPC_DUST_FLAIL_FRONT_STALKER)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->StopMoving();
+ me->AttackStop();
+ me->SetFacingToObject(summon);
+ DoCastSelf(SPELL_DUST_FLAIL);
+ events.ScheduleEvent(EVENT_MAKE_AGGRESSIVE, Seconds(5));
+ }
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
+ {
+ if (me->HealthBelowPct(30) && !_enraged)
+ {
+ DoCastSelf(SPELL_VENOMOUS_RAGE, true);
+ _enraged = true;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_VISCOUS_POISON:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true, 0))
+ DoCast(target, SPELL_VISCOUS_POISON);
+ events.Repeat(Seconds(26));
+ break;
+ case EVENT_SCENT_OF_BLOOD:
+ DoCastAOE(SPELL_SCENT_OF_BLOOD, true);
+ events.ScheduleEvent(EVENT_SCENT_OF_BLOOD, Seconds(30));
+ events.ScheduleEvent(EVENT_SUMMON_CROCOLISK, Milliseconds(100));
+ break;
+ case EVENT_SUMMON_CROCOLISK:
+ instance->SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_SUMMON_CROCOLISKS);
+ break;
+ case EVENT_DUST_FLAIL:
+ DoCastAOE(SPELL_DUST_FLAIL_DUMMY, true);
+ events.Repeat(Seconds(39));
+ break;
+ case EVENT_MAKE_AGGRESSIVE:
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ case EVENT_SUMMON_AUGH:
+ if (_lastSpellID != SPELL_SUMMON_AUGH_DART)
+ {
+ _lastSpellID = SPELL_SUMMON_AUGH_DART;
+ instance->SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_SUMMON_AUGH_DART);
+ events.Repeat(Seconds(20));
+ }
+ else
+ {
+ _lastSpellID = SPELL_SUMMON_AUGH_WHIRLWIND;
+ instance->SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_SUMMON_AUGH_WHIRLWIND);
+ events.Repeat(Seconds(40));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+ private:
+ bool _enraged;
+ uint32 _lastSpellID;
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetLostCityOfTheTolvirAI(creature);
+ }
+};
+
+class boss_augh : public CreatureScript
+{
+ public:
+ boss_augh() : CreatureScript("boss_augh") { }
+
+ struct boss_aughAI : public BossAI
+ {
+ boss_aughAI(Creature* creature) : BossAI(creature, DATA_AUGH) { }
+
+ void EnterCombat(Unit* /*victim*/) override
+ {
+ _EnterCombat();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_NONE);
+ events.SetPhase(PHASE_COMBAT);
+ DoCastSelf(SPELL_FRENZY);
+ events.ScheduleEvent(EVENT_PARALYTIC_BLOW_DART, Seconds(8));
+ events.ScheduleEvent(EVENT_WHIRLWIND, Seconds(9));
+ events.ScheduleEvent(EVENT_DRAGONS_BREATH, Seconds(6));
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ _EnterEvadeMode();
+ instance->SetBossState(DATA_AUGH, FAIL);
+ _DespawnAtEvade();
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_AUGH_INTRO:
+ me->SetReactState(REACT_PASSIVE);
+ Talk(SAY_ANNOUNCE_AUGH_APPEAR);
+ events.SetPhase(PHASE_INTRO);
+ events.ScheduleEvent(EVENT_MOVE_HOME_POS, Seconds(1));
+ break;
+ case ACTION_AUGH_ATTACKABLE:
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO))
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MOVE_HOME_POS:
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(0, AughMovePoint, true);
+ events.ScheduleEvent(EVENT_TALK_INTRO_1, Seconds(10) + Milliseconds(500), 0, PHASE_INTRO);
+ break;
+ case EVENT_TALK_INTRO_1:
+ me->SetFacingTo(AughMovePoint.GetOrientation());
+ Talk(SAY_AUGH_INTRO_1);
+ events.ScheduleEvent(EVENT_TALK_INTRO_2, Seconds(4), 0, PHASE_INTRO);
+ break;
+ case EVENT_TALK_INTRO_2:
+ Talk(SAY_AUGH_INTRO_2);
+ events.ScheduleEvent(EVENT_PLAY_EMOTE, Seconds(3), 0, PHASE_INTRO);
+ break;
+ case EVENT_PLAY_EMOTE:
+ me->HandleEmoteCommand(EMOTE_STATE_SPELL_CHANNEL_OMNI);
+ events.ScheduleEvent(EVENT_MAKE_ATTACKABLE, Seconds(4), 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_TALK_TAUNT_1, Seconds(5), PHASE_INTRO);
+ break;
+ case EVENT_MAKE_ATTACKABLE:
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ case EVENT_TALK_TAUNT_1:
+ Talk(SAY_AUGH_TAUNT_1);
+ events.ScheduleEvent(EVENT_TALK_TAUNT_2, Seconds(5), 0, PHASE_INTRO);
+ break;
+ case EVENT_TALK_TAUNT_2:
+ Talk(SAY_AUGH_TAUNT_2);
+ events.ScheduleEvent(EVENT_TALK_TAUNT_3, Seconds(5), 0, PHASE_INTRO);
+ break;
+ case EVENT_TALK_TAUNT_3:
+ Talk(SAY_AUGH_TAUNT_3);
+ break;
+ case EVENT_PARALYTIC_BLOW_DART:
+ DoCastAOE(SPELL_PARALYTIC_BLOW_DART);
+ events.Repeat(Seconds(10), Seconds(15));
+ break;
+ case EVENT_WHIRLWIND:
+ DoCastAOE(SPELL_RANDOM_AGGRO_TAUNT, true);
+ DoCastSelf(SPELL_WHIRLWIND_BOSS);
+ events.Repeat(Seconds(29));
+ break;
+ case EVENT_DRAGONS_BREATH:
+ DoCastAOE(SPELL_DRAGONS_BREATH);
+ events.Repeat(Seconds(28));
+ break;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetLostCityOfTheTolvirAI(creature);
+ }
+};
+
+class npc_lockmaw_frenzied_crocolisk : public CreatureScript
+{
+ public:
+ npc_lockmaw_frenzied_crocolisk() : CreatureScript("npc_lockmaw_frenzied_crocolisk") { }
+
+ struct npc_lockmaw_frenzied_crocoliskAI : public ScriptedAI
+ {
+ npc_lockmaw_frenzied_crocoliskAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ me->DespawnOrUnsummon(Seconds(5));
+ }
+
+ void IsSummonedBy(Unit* summoner) override
+ {
+ if (Creature* lockmaw = _instance->GetCreature(DATA_LOCKMAW))
+ lockmaw->AI()->JustSummoned(me);
+ me->SetReactState(REACT_PASSIVE);
+ DoZoneInCombat();
+ _events.ScheduleEvent(EVENT_FIND_PLAYER_TARGET, Seconds(1));
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FIND_PLAYER_TARGET:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, ScentOfBloodTargetSelector()))
+ {
+ DoCastSelf(SPELL_STEALTHED);
+ me->AI()->AttackStart(target);
+ me->AddThreat(target, 50000000.0f);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetLostCityOfTheTolvirAI(creature);
+ }
+};
+
+class npc_lockmaw_augh : public CreatureScript
+{
+ public:
+ npc_lockmaw_augh() : CreatureScript("npc_lockmaw_augh") { }
+
+ struct npc_lockmaw_aughAI : public ScriptedAI
+ {
+ npc_lockmaw_aughAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void IsSummonedBy(Unit* /*summoner*/) override
+ {
+ if (Creature* lockmaw = _instance->GetCreature(DATA_LOCKMAW))
+ lockmaw->AI()->JustSummoned(me);
+
+ DoCastSelf(SPELL_STEALTHED, true);
+
+ if (me->GetEntry() == NPC_AUGH_DART)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ _events.ScheduleEvent(EVENT_ROAR_EMOTE, Seconds(7));
+ _events.ScheduleEvent(EVENT_PARALYTIC_BLOW_DART, Seconds(8));
+ _events.ScheduleEvent(EVENT_SMOKE_BOMB, Seconds(12));
+ }
+ else
+ _events.ScheduleEvent(EVENT_WHIRLWIND, Seconds(4));
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ // There is indeed now immunity aura...
+ damage = 0;
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ROAR_EMOTE:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_BATTLE_ROAR);
+ break;
+ case EVENT_PARALYTIC_BLOW_DART:
+ DoCastAOE(SPELL_PARALYTIC_BLOW_DART);
+ break;
+ case EVENT_SMOKE_BOMB:
+ DoCastSelf(SPELL_SMOKE_BOMB);
+ me->DespawnOrUnsummon(Seconds(3));
+ break;
+ case EVENT_WHIRLWIND:
+ DoCastAOE(SPELL_RANDOM_AGGRO_TAUNT, true);
+ DoCastSelf(SPELL_WHIRLWIND);
+ _events.ScheduleEvent(EVENT_RANDOM_AGGRO, Seconds(10));
+ break;
+ case EVENT_RANDOM_AGGRO:
+ DoCastAOE(SPELL_RANDOM_AGGRO_TAUNT, true);
+ _events.ScheduleEvent(EVENT_ATTACK_STOP, Seconds(10));
+ break;
+ case EVENT_ATTACK_STOP:
+ me->AttackStop();
+ me->SetReactState(REACT_PASSIVE);
+ me->DespawnOrUnsummon(Seconds(6));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetLostCityOfTheTolvirAI(creature);
+ }
+};
+
+class spell_lockmaw_scent_of_blood : public SpellScriptLoader
+{
+ public:
+ spell_lockmaw_scent_of_blood() : SpellScriptLoader("spell_lockmaw_scent_of_blood") { }
+
+ class spell_lockmaw_scent_of_blood_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_lockmaw_scent_of_blood_SpellScript);
+
+ void FilterTargets(std::list& targets)
+ {
+ if (targets.empty())
+ return;
+
+ Trinity::Containers::RandomResize(targets, 1);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_lockmaw_scent_of_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_lockmaw_scent_of_blood_SpellScript();
+ }
+};
+
+class spell_lockmaw_paralytic_blow_dart : public SpellScriptLoader
+{
+ public:
+ spell_lockmaw_paralytic_blow_dart() : SpellScriptLoader("spell_lockmaw_paralytic_blow_dart") { }
+
+ class spell_lockmaw_paralytic_blow_dart_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_lockmaw_paralytic_blow_dart_SpellScript);
+
+ void FilterTargets(std::list& targets)
+ {
+ if (targets.empty())
+ return;
+
+ Trinity::Containers::RandomResize(targets, 1);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_lockmaw_paralytic_blow_dart_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_lockmaw_paralytic_blow_dart_SpellScript();
+ }
+};
+
+class spell_lockmaw_random_aggro_taunt : public SpellScriptLoader
+{
+ public:
+ spell_lockmaw_random_aggro_taunt() : SpellScriptLoader("spell_lockmaw_random_aggro_taunt") { }
+
+ class spell_lockmaw_random_aggro_taunt_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_lockmaw_random_aggro_taunt_SpellScript);
+
+ void FilterTargets(std::list& targets)
+ {
+ if (targets.empty())
+ return;
+
+ Trinity::Containers::RandomResize(targets, 1);
+ }
+
+ void EffectScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ GetHitPlayer()->CastSpell(GetCaster(), GetSpellInfo()->Effects[EFFECT_0].BasePoints, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_lockmaw_random_aggro_taunt_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_lockmaw_random_aggro_taunt_SpellScript::EffectScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_lockmaw_random_aggro_taunt_SpellScript();
+ }
+};
+
+void AddSC_boss_lockmaw_and_augh()
+{
+ new boss_lockmaw();
+ new boss_augh();
+ new npc_lockmaw_frenzied_crocolisk();
+ new npc_lockmaw_augh();
+ new spell_lockmaw_scent_of_blood();
+ new spell_lockmaw_paralytic_blow_dart();
+ new spell_lockmaw_random_aggro_taunt();
+}
diff --git a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/instance_lost_city_of_the_tolvir.cpp b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/instance_lost_city_of_the_tolvir.cpp
index ea3be9c72c2..992b482dca6 100644
--- a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/instance_lost_city_of_the_tolvir.cpp
+++ b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/instance_lost_city_of_the_tolvir.cpp
@@ -19,6 +19,26 @@
#include "InstanceScript.h"
#include "lost_city_of_the_tolvir.h"
+enum TimedEvents
+{
+ EVENT_SPAWN_AUGH = 1
+};
+
+enum SummonGroups
+{
+ SUMMON_GROUP_WIND_TUNNEL = 0
+};
+
+enum Actions
+{
+ // Lockmaw and Augh
+ ACTION_AUGH_INTRO = 1,
+ ACTION_AUGH_ATTACKABLE = 2
+};
+
+Position const AughSpawnPos = { -11058.91f, -1625.342f, -0.1304993f, 4.782202f };
+Position const AughHomePos = { -11062.5f, -1662.39f, 0.7606202f, 0.8028514f };
+
ObjectData const creatureData[] =
{
{ BOSS_GENERAL_HUSAM, DATA_GENERAL_HUSAM },
@@ -28,7 +48,7 @@ ObjectData const creatureData[] =
{ BOSS_SIAMAT, DATA_SIAMAT },
{ NPC_BLAZE_OF_THE_HEAVENS, DATA_BLAZE_OF_THE_HEAVENS },
{ NPC_HARBINGER_OF_DARKNESS, DATA_HARBINGER_OF_DARKNESS },
- { 0, 0 } // End
+ { 0, 0 } // End
};
ObjectData const gameObjectData[] =
@@ -39,31 +59,155 @@ ObjectData const gameObjectData[] =
class instance_lost_city_of_the_tolvir : public InstanceMapScript
{
-public:
- instance_lost_city_of_the_tolvir() : InstanceMapScript(LCTScriptName, 755) { }
+ public:
+ instance_lost_city_of_the_tolvir() : InstanceMapScript(LCTScriptName, 755) { }
- struct instance_lost_city_of_the_tolvir_InstanceMapScript : public InstanceScript
- {
- instance_lost_city_of_the_tolvir_InstanceMapScript(Map* map) : InstanceScript(map)
+ struct instance_lost_city_of_the_tolvir_InstanceMapScript : public InstanceScript
{
- SetHeaders(DataHeader);
- SetBossNumber(EncounterCount);
- LoadObjectData(creatureData, gameObjectData);
- }
+ instance_lost_city_of_the_tolvir_InstanceMapScript(Map* map) : InstanceScript(map)
+ {
+ SetHeaders(DataHeader);
+ SetBossNumber(EncounterCount);
+ LoadObjectData(creatureData, gameObjectData);
+ Initialize();
+ }
- bool SetBossState(uint32 type, EncounterState state) override
+ void Initialize()
+ {
+ _heroicAughSpawned = false;
+ }
+
+ void OnCreatureCreate(Creature* creature) override
+ {
+ InstanceScript::OnCreatureCreate(creature);
+
+ if (creature->GetEntry() == NPC_ADD_STALKER)
+ addStalkerGUIDs.push_back(creature->GetGUID());
+ }
+
+ bool SetBossState(uint32 type, EncounterState state) override
+ {
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ switch (type)
+ {
+ case DATA_LOCKMAW:
+ if (!instance->IsHeroic() && state == DONE)
+ SetBossState(DATA_LOCKMAW_AND_AUGH, DONE);
+ else if (instance->IsHeroic() && state == DONE && !_heroicAughSpawned)
+ _events.ScheduleEvent(EVENT_SPAWN_AUGH, Seconds(4));
+ break;
+ case DATA_AUGH: // Since Augh is summoned, we need to handle his respawn here
+ if (state == DONE)
+ SetBossState(DATA_LOCKMAW_AND_AUGH, DONE);
+ else if (state == FAIL)
+ _events.ScheduleEvent(EVENT_SPAWN_AUGH, Seconds(30));
+ break;
+ case DATA_GENERAL_HUSAM:
+ case DATA_LOCKMAW_AND_AUGH:
+ case DATA_HIGH_PROPHET_BARIM:
+ if (state == DONE && CheckSiamatsPlatform())
+ {
+ if (GameObject* platform = GetGameObject(DATA_SIAMAT_PLATFORM))
+ {
+ platform->setActive(true);
+ platform->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED);
+ platform->EnableCollision(true);
+ }
+
+ instance->SetZoneWeather(ZONE_ID_LOST_CITY, WEATHER_STATE_HEAVY_RAIN, 1.0f);
+ instance->SummonCreatureGroup(SUMMON_GROUP_WIND_TUNNEL);
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ void SetData(uint32 data, uint32 value) override
+ {
+ switch (data)
+ {
+ case DATA_LOCKMAW_COMBAT_ASSISTANCE:
+ switch (value)
+ {
+ case ASSISTANCE_SUMMON_AUGH_DART:
+ if (Unit* stalker = instance->GetCreature(Trinity::Containers::SelectRandomContainerElement(addStalkerGUIDs)))
+ stalker->CastSpell(stalker, SPELL_SUMMON_AUGH_DART);
+ SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_NONE);
+ break;
+ case ASSISTANCE_SUMMON_AUGH_WHIRLWIND:
+ if (Unit* stalker = instance->GetCreature(Trinity::Containers::SelectRandomContainerElement(addStalkerGUIDs)))
+ stalker->CastSpell(stalker, SPELL_SUMMON_AUGH_WHIRLWIND);
+ SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_NONE);
+ break;
+ case ASSISTANCE_SUMMON_CROCOLISKS:
+ {
+ GuidVector tempList = addStalkerGUIDs;
+ if (!tempList.empty())
+ {
+ Trinity::Containers::RandomResize(tempList, 4);
+ for (auto itr = tempList.begin(); itr != tempList.end(); itr++)
+ if (Unit* stalker = instance->GetCreature(*itr))
+ stalker->CastSpell(stalker, SPELL_SUMMON_CROCOLISK);
+ }
+ SetData(DATA_LOCKMAW_COMBAT_ASSISTANCE, ASSISTANCE_NONE);
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ bool CheckSiamatsPlatform()
+ {
+ for (LCTDataTypes boss : { DATA_GENERAL_HUSAM, DATA_LOCKMAW_AND_AUGH, DATA_HIGH_PROPHET_BARIM })
+ if (GetBossState(boss) != DONE)
+ return false;
+ return true;
+ }
+
+ void Update(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SPAWN_AUGH:
+ if (!_heroicAughSpawned)
+ {
+ if (Creature* augh = instance->SummonCreature(BOSS_AUGH, AughSpawnPos))
+ augh->AI()->DoAction(ACTION_AUGH_INTRO);
+ _heroicAughSpawned = true;
+ }
+ else if (_heroicAughSpawned)
+ if (Creature* augh = instance->SummonCreature(BOSS_AUGH, AughHomePos))
+ augh->AI()->DoAction(ACTION_AUGH_ATTACKABLE);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ protected:
+ EventMap events;
+ bool heroicAughSpawned;
+ GuidVector addStalkerGUIDs;
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
- if (!InstanceScript::SetBossState(type, state))
- return false;
-
- return true;
+ return new instance_lost_city_of_the_tolvir_InstanceMapScript(map);
}
- };
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const override
- {
- return new instance_lost_city_of_the_tolvir_InstanceMapScript(map);
- }
};
void AddSC_instance_lost_city_of_the_tolvir()
diff --git a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/lost_city_of_the_tolvir.h b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/lost_city_of_the_tolvir.h
index 1107ed69346..db66b5c2038 100644
--- a/src/server/scripts/Kalimdor/LostCityOfTheTolvir/lost_city_of_the_tolvir.h
+++ b/src/server/scripts/Kalimdor/LostCityOfTheTolvir/lost_city_of_the_tolvir.h
@@ -21,21 +21,23 @@
#define LCTScriptName "instance_lost_city_of_the_tolvir"
#define DataHeader "LCT"
-uint32 const EncounterCount = 4;
+uint32 const EncounterCount = 6;
enum LCTDataTypes
{
// Encounter States
- DATA_GENERAL_HUSAM = 1,
- DATA_LOCKMAW = 2,
- DATA_AUGH = 3,
- DATA_HIGH_PROPHET_BARIM = 4,
- DATA_SIAMAT = 5,
+ DATA_GENERAL_HUSAM = 0,
+ DATA_LOCKMAW_AND_AUGH = 1,
+ DATA_HIGH_PROPHET_BARIM = 2,
+ DATA_SIAMAT = 3,
+ DATA_LOCKMAW = 4,
+ DATA_AUGH = 5,
// Additional Data
- DATA_SIAMAT_PLATFORM = 6,
- DATA_BLAZE_OF_THE_HEAVENS = 7,
- DATA_HARBINGER_OF_DARKNESS = 8,
+ DATA_SIAMAT_PLATFORM = 6,
+ DATA_BLAZE_OF_THE_HEAVENS = 7,
+ DATA_HARBINGER_OF_DARKNESS = 8,
+ DATA_LOCKMAW_COMBAT_ASSISTANCE = 9
};
enum LCTCreatureIds
@@ -56,6 +58,9 @@ enum LCTCreatureIds
NPC_BLAZE_OF_THE_HEAVENS = 48906,
NPC_SOUL_FRAGMENT = 43934,
NPC_HARBINGER_OF_DARKNESS = 43927,
+ NPC_DUST_FLAIL_FRONT_STALKER = 43655,
+ NPC_ADD_STALKER = 45124,
+ NPC_AUGH_DART = 45379
};
enum LCTGameObjectIds
@@ -63,6 +68,23 @@ enum LCTGameObjectIds
GO_SIAMAT_PLATFORM = 205365
};
+enum LCTSpells
+{
+ SPELL_SUMMON_CROCOLISK = 84242,
+ SPELL_SUMMON_AUGH_DART = 84809,
+ SPELL_SUMMON_AUGH_WHIRLWIND = 84808
+};
+
+enum LCTMisc
+{
+ ZONE_ID_LOST_CITY = 5396,
+
+ ASSISTANCE_NONE = 0,
+ ASSISTANCE_SUMMON_AUGH_DART = 1,
+ ASSISTANCE_SUMMON_AUGH_WHIRLWIND = 2,
+ ASSISTANCE_SUMMON_CROCOLISKS = 3
+};
+
template
AI* GetLostCityOfTheTolvirAI(Creature* creature)
{