diff --git a/data/sql/updates/db_world/2023_06_07_00.sql b/data/sql/updates/db_world/2023_06_07_00.sql
new file mode 100644
index 000000000..47f3539c1
--- /dev/null
+++ b/data/sql/updates/db_world/2023_06_07_00.sql
@@ -0,0 +1,7 @@
+-- DB update 2023_06_05_01 -> 2023_06_07_00
+--
+UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_porung' WHERE `entry` = 20923;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (20923, 17461) AND `source_type` = 0;
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN (2092300, 1746100) AND `source_type` = 9;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(17461, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 45, 2, 0, 0, 0, 0, 0, 19, 17693, 100, 0, 0, 0, 0, 0, 0, 'Shattered Hand Blood Guard - On Just Died - Set Data 2 0');
diff --git a/data/sql/updates/db_world/2023_06_07_01.sql b/data/sql/updates/db_world/2023_06_07_01.sql
new file mode 100644
index 000000000..ab02f3b21
--- /dev/null
+++ b/data/sql/updates/db_world/2023_06_07_01.sql
@@ -0,0 +1,3 @@
+-- DB update 2023_06_07_00 -> 2023_06_07_01
+--
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|256|4194304 WHERE `entry` IN (17839, 20744, 21140, 22172, 21104, 21148, 22170, 22171);
diff --git a/data/sql/updates/db_world/2023_06_07_02.sql b/data/sql/updates/db_world/2023_06_07_02.sql
new file mode 100644
index 000000000..0eb5c1750
--- /dev/null
+++ b/data/sql/updates/db_world/2023_06_07_02.sql
@@ -0,0 +1,3 @@
+-- DB update 2023_06_07_01 -> 2023_06_07_02
+--
+UPDATE `gameobject` SET `spawnMask`=2 WHERE `guid` = 30237 AND `id` = 184174;
diff --git a/data/sql/updates/db_world/2023_06_07_03.sql b/data/sql/updates/db_world/2023_06_07_03.sql
new file mode 100644
index 000000000..828e314bd
--- /dev/null
+++ b/data/sql/updates/db_world/2023_06_07_03.sql
@@ -0,0 +1,7 @@
+-- DB update 2023_06_07_02 -> 2023_06_07_03
+DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-151090,-151091,-151092,-151093)) AND (`source_type` = 0) AND (`id` IN (1000));
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(-151090, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All'),
+(-151091, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All'),
+(-151092, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All'),
+(-151093, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All');
diff --git a/data/sql/updates/db_world/2023_06_07_04.sql b/data/sql/updates/db_world/2023_06_07_04.sql
new file mode 100644
index 000000000..163149fa0
--- /dev/null
+++ b/data/sql/updates/db_world/2023_06_07_04.sql
@@ -0,0 +1,9 @@
+-- DB update 2023_06_07_03 -> 2023_06_07_04
+UPDATE `creature_template` SET `mechanic_immune_mask` = 0 WHERE `entry` IN (16507, 16700, 17465, 17670, 17671, 20593, 20589, 20583, 20588, 20584, 20582, 20590, 20587, 20586); -- setting to 0
+
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1|2|8|16|64|128|1024|2048|4096|8192|65536|8388608|536870912 WHERE `entry` IN (17671, 20584); -- full cc
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1|1024|65536 WHERE `entry` IN (17465, 20583); -- MC/charm, snare and poly
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|65536 WHERE `entry` IN (16700, 20589); -- poly
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|536870912 WHERE `entry` IN (16507, 20593); -- sap
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|65536 WHERE `entry` = 20588; -- houndmaster HC only immune to poly
+UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1 WHERE `entry` IN (20588, 20584, 20582, 20586, 20587, 20589, 20590, 20593); -- HC only houndmaster, champion, brawler, gladiator, heathen, legionnaire, reaver and sentry MC immune
diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp
index cc3db3b01..bff534f0a 100644
--- a/src/server/game/Spells/SpellInfoCorrections.cpp
+++ b/src/server/game/Spells/SpellInfoCorrections.cpp
@@ -4541,6 +4541,12 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->MaxAffectedTargets = 1;
});
+ // Acid Spit
+ ApplySpellFix({ 34290 }, [](SpellInfo* spellInfo)
+ {
+ spellInfo->MaxAffectedTargets = 1;
+ });
+
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
SpellInfo* spellInfo = mSpellInfoMap[i];
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_porung.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_porung.cpp
new file mode 100644
index 000000000..3f1f78624
--- /dev/null
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_porung.cpp
@@ -0,0 +1,318 @@
+/*
+ * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by the
+ * Free Software Foundation; either version 3 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 Affero 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 "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "TaskScheduler.h"
+#include "shattered_halls.h"
+
+enum Spells
+{
+ SPELL_CLEAR_ALL = 28471,
+ SPELL_SUMMON_ZEALOTS = 30976,
+ SPELL_SHOOT_FLAME_ARROW = 30952,
+ SPELL_CLEAVE = 15496
+};
+
+enum Says
+{
+ SAY_INVADERS_BREACHED = 0,
+
+ SAY_PORUNG_ARCHERS = 0,
+ SAY_PORUNG_READY = 1,
+ SAY_PORUNG_AIM = 2,
+ SAY_PORUNG_FIRE = 3,
+ SAY_PORUNG_AGGRO = 4
+};
+
+enum Misc
+{
+ POINT_SCOUT_WP_END = 3,
+
+ SET_DATA_ARBITRARY_VALUE = 1,
+ SET_DATA_ENCOUNTER_DONE = 2
+};
+
+struct boss_porung : public BossAI
+{
+ boss_porung(Creature* creature) : BossAI(creature, DATA_PORUNG) { }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+
+ Talk(SAY_PORUNG_AGGRO);
+ scheduler.Schedule(2s, 4s, [this](TaskContext context)
+ {
+ DoCastVictim(SPELL_CLEAVE);
+ context.Repeat(8s, 10s);
+ });
+ }
+
+ void JustDied(Unit* killer) override
+ {
+ BossAI::JustDied(killer);
+
+ if (Creature* scout = me->FindNearestCreature(NPC_SH_SCOUT, 250.f))
+ scout->AI()->SetData(SET_DATA_ENCOUNTER_DONE, 0);
+ }
+};
+
+struct npc_shattered_hand_scout : public ScriptedAI
+{
+ npc_shattered_hand_scout(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() override
+ {
+ me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void SetData(uint32 type, uint32 /*data*/) override
+ {
+ if (type != SET_DATA_ENCOUNTER_DONE)
+ return;
+
+ _scheduler.CancelAll();
+ }
+
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && me->IsWithinDist2d(who, 50.0f) && who->GetPositionZ() > -3.0f
+ && who->IsPlayer())
+ {
+ me->SetReactState(REACT_PASSIVE);
+ DoCastSelf(SPELL_CLEAR_ALL);
+ me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ Talk(SAY_INVADERS_BREACHED);
+ me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);
+
+ _firstZealots.clear();
+ std::list creatureList;
+ GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 15.0f);
+ for (Creature* creature : creatureList)
+ {
+ if (creature)
+ {
+ _firstZealots.insert(creature->GetGUID());
+ }
+ }
+ }
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
+ {
+ if (damage >= me->GetHealth())
+ {
+ // Let creature fall to 1 HP but prevent it from dying.
+ damage = me->GetHealth() - 1;
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 point) override
+ {
+ if (type == WAYPOINT_MOTION_TYPE && point == POINT_SCOUT_WP_END)
+ {
+ me->SetVisible(false);
+
+ if (Creature* porung = GetPorung())
+ {
+ porung->setActive(true);
+ porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
+ porung->AI()->Talk(SAY_PORUNG_ARCHERS);
+
+ _scheduler.Schedule(45s, [this](TaskContext context)
+ {
+ if (Creature* porung = GetPorung())
+ {
+ porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
+ }
+
+ context.Repeat();
+ });
+ }
+
+ _scheduler.Schedule(1s, [this](TaskContext /*context*/)
+ {
+ _zealotGUIDs.clear();
+ std::list creatureList;
+ GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 100.0f);
+ for (Creature* creature : creatureList)
+ {
+ if (creature)
+ {
+ creature->AI()->SetData(SET_DATA_ARBITRARY_VALUE, SET_DATA_ARBITRARY_VALUE);
+ _zealotGUIDs.insert(creature->GetGUID());
+ }
+ }
+
+ for (auto const& guid : _firstZealots)
+ {
+ if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
+ {
+ zealot->SetInCombatWithZone();
+ }
+ }
+
+ if (Creature* porung = GetPorung())
+ {
+ porung->AI()->Talk(SAY_PORUNG_READY, 3600ms);
+ porung->AI()->Talk(SAY_PORUNG_AIM, 4800ms);
+ }
+
+ _scheduler.Schedule(5800ms, [this](TaskContext /*context*/)
+ {
+ std::list creatureList;
+ GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
+ for (Creature* creature : creatureList)
+ {
+ if (creature)
+ {
+ creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
+ }
+ }
+
+ if (Creature* porung = GetPorung())
+ {
+ porung->AI()->Talk(SAY_PORUNG_FIRE, 200ms);
+ }
+
+ _scheduler.Schedule(2s, 9750ms, [this](TaskContext context)
+ {
+ if (FireArrows())
+ {
+ context.Repeat();
+ }
+
+ if (!me->SelectNearestPlayer(250.0f))
+ {
+ me->SetVisible(true);
+ me->DespawnOrUnsummon(5s, 5s);
+
+ for (auto const& guid : _zealotGUIDs)
+ {
+ if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
+ {
+ if (zealot->IsAlive())
+ {
+ zealot->DespawnOrUnsummon(5s, 5s);
+ }
+ else
+ {
+ zealot->Respawn(true);
+ }
+ }
+ }
+
+ for (auto const& guid : _firstZealots)
+ {
+ if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
+ {
+ if (zealot->IsAlive())
+ {
+ zealot->DespawnOrUnsummon(5s, 5s);
+ }
+ else
+ {
+ zealot->Respawn(true);
+ }
+ }
+ }
+
+ _scheduler.CancelAll();
+ }
+ });
+ });
+ });
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+ bool FireArrows()
+ {
+ std::list creatureList;
+ GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
+
+ if (creatureList.empty())
+ {
+ return false;
+ }
+
+ for (Creature* creature : creatureList)
+ {
+ if (creature)
+ {
+ creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
+ }
+ }
+
+ return true;
+ }
+
+ Creature* GetPorung()
+ {
+ return me->FindNearestCreature(IsHeroic() ? NPC_PORUNG : NPC_BLOOD_GUARD, 100.0f);
+ }
+
+private:
+ TaskScheduler _scheduler;
+ GuidSet _zealotGUIDs;
+ GuidSet _firstZealots;
+};
+
+class spell_tsh_shoot_flame_arrow : public SpellScript
+{
+ PrepareSpellScript(spell_tsh_shoot_flame_arrow);
+
+ void FilterTargets(std::list& unitList)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ unitList.remove_if([&](WorldObject* target) -> bool
+ {
+ return !target->SelectNearestPlayer(15.0f);
+ });
+
+ Acore::Containers::RandomResize(unitList, 1);
+ }
+
+ void HandleScriptEffect(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(target, 30953, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tsh_shoot_flame_arrow::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_tsh_shoot_flame_arrow::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+void AddSC_boss_porung()
+{
+ RegisterShatteredHallsCreatureAI(boss_porung);
+ RegisterShatteredHallsCreatureAI(npc_shattered_hand_scout);
+ RegisterSpellScript(spell_tsh_shoot_flame_arrow);
+}
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
index 0996c4f65..ffaf806d9 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
@@ -182,264 +182,6 @@ public:
};
};
-enum ScoutMisc
-{
- SAY_INVADERS_BREACHED = 0,
-
- SAY_PORUNG_ARCHERS = 0,
- SAY_PORUNG_READY = 1,
- SAY_PORUNG_AIM = 2,
- SAY_PORUNG_FIRE = 3,
-
- SPELL_CLEAR_ALL = 28471,
- SPELL_SUMMON_ZEALOTS = 30976,
- SPELL_SHOOT_FLAME_ARROW = 30952,
-
- POINT_SCOUT_WP_END = 3,
-
- SET_DATA_ARBITRARY_VALUE = 1
-};
-
-struct npc_shattered_hand_scout : public ScriptedAI
-{
- npc_shattered_hand_scout(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void MoveInLineOfSight(Unit* who) override
- {
- if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && me->IsWithinDist2d(who, 50.0f) && who->GetPositionZ() > -3.0f
- && who->IsPlayer())
- {
- me->SetReactState(REACT_PASSIVE);
- DoCastSelf(SPELL_CLEAR_ALL);
- me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- Talk(SAY_INVADERS_BREACHED);
- me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);
-
- _firstZealots.clear();
- std::list creatureList;
- GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 15.0f);
- for (Creature* creature : creatureList)
- {
- if (creature)
- {
- _firstZealots.insert(creature->GetGUID());
- }
- }
- }
- }
-
- void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
- {
- if (damage >= me->GetHealth())
- {
- // Let creature fall to 1 HP but prevent it from dying.
- damage = me->GetHealth() - 1;
- }
- }
-
- void MovementInform(uint32 type, uint32 point) override
- {
- if (type == WAYPOINT_MOTION_TYPE && point == POINT_SCOUT_WP_END)
- {
- me->SetVisible(false);
-
- if (Creature* porung = GetPorung())
- {
- porung->setActive(true);
- porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
- porung->AI()->Talk(SAY_PORUNG_ARCHERS);
-
- _scheduler.Schedule(45s, [this](TaskContext context)
- {
- if (Creature* porung = GetPorung())
- {
- porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
- }
-
- context.Repeat();
- });
- }
-
- _scheduler.Schedule(1s, [this](TaskContext /*context*/)
- {
- _zealotGUIDs.clear();
- std::list creatureList;
- GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 100.0f);
- for (Creature* creature : creatureList)
- {
- if (creature)
- {
- creature->AI()->SetData(SET_DATA_ARBITRARY_VALUE, SET_DATA_ARBITRARY_VALUE);
- _zealotGUIDs.insert(creature->GetGUID());
- }
- }
-
- for (auto const& guid : _firstZealots)
- {
- if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
- {
- zealot->SetInCombatWithZone();
- }
- }
-
- if (Creature* porung = GetPorung())
- {
- porung->AI()->Talk(SAY_PORUNG_READY, 3600ms);
- porung->AI()->Talk(SAY_PORUNG_AIM, 4800ms);
- }
-
- _scheduler.Schedule(5800ms, [this](TaskContext /*context*/)
- {
- std::list creatureList;
- GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
- for (Creature* creature : creatureList)
- {
- if (creature)
- {
- creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
- }
- }
-
- if (Creature* porung = GetPorung())
- {
- porung->AI()->Talk(SAY_PORUNG_FIRE, 200ms);
- }
-
- _scheduler.Schedule(2s, 9750ms, [this](TaskContext context)
- {
- if (FireArrows())
- {
- context.Repeat();
- }
-
- if (!me->SelectNearestPlayer(250.0f))
- {
- me->SetVisible(true);
- me->DespawnOrUnsummon(5s, 5s);
-
- for (auto const& guid : _zealotGUIDs)
- {
- if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
- {
- if (zealot->IsAlive())
- {
- zealot->DespawnOrUnsummon(5s, 5s);
- }
- else
- {
- zealot->Respawn(true);
- }
- }
- }
-
- for (auto const& guid : _firstZealots)
- {
- if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
- {
- if (zealot->IsAlive())
- {
- zealot->DespawnOrUnsummon(5s, 5s);
- }
- else
- {
- zealot->Respawn(true);
- }
- }
- }
-
- _scheduler.CancelAll();
- }
- });
- });
- });
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- _scheduler.Update(diff);
- }
-
- bool FireArrows()
- {
- std::list creatureList;
- GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
-
- if (creatureList.empty())
- {
- return false;
- }
-
- for (Creature* creature : creatureList)
- {
- if (creature)
- {
- creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
- }
- }
-
- return true;
- }
-
- Creature* GetPorung()
- {
- return me->FindNearestCreature(IsHeroic() ? NPC_PORUNG : NPC_BLOOD_GUARD, 100.0f);
- }
-
-private:
- TaskScheduler _scheduler;
- GuidSet _zealotGUIDs;
- GuidSet _firstZealots;
-};
-
-class spell_tsh_shoot_flame_arrow : public SpellScriptLoader
-{
-public:
- spell_tsh_shoot_flame_arrow() : SpellScriptLoader("spell_tsh_shoot_flame_arrow") { }
-
- class spell_tsh_shoot_flame_arrow_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_tsh_shoot_flame_arrow_SpellScript);
-
- void FilterTargets(std::list& unitList)
- {
- Unit* caster = GetCaster();
- if (!caster)
- return;
-
- unitList.remove_if([&](WorldObject* target) -> bool
- {
- return !target->SelectNearestPlayer(15.0f);
- });
-
- Acore::Containers::RandomResize(unitList, 1);
- }
-
- void HandleScriptEffect(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- if (Unit* target = GetHitUnit())
- target->CastSpell(target, 30953, true);
- }
-
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tsh_shoot_flame_arrow_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
- OnEffectHitTarget += SpellEffectFn(spell_tsh_shoot_flame_arrow_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_tsh_shoot_flame_arrow_SpellScript();
- }
-};
-
class at_shattered_halls_execution : public AreaTriggerScript
{
public:
@@ -462,7 +204,5 @@ public:
void AddSC_instance_shattered_halls()
{
new instance_shattered_halls();
- RegisterShatteredHallsCreatureAI(npc_shattered_hand_scout);
- new spell_tsh_shoot_flame_arrow();
new at_shattered_halls_execution();
}
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h
index 7f46320b4..07c31a3ba 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h
@@ -29,7 +29,8 @@ enum DataTypes
DATA_NETHEKURSE = 0,
DATA_OMROGG = 1,
DATA_KARGATH = 2,
- ENCOUNTER_COUNT = 3,
+ DATA_PORUNG = 3,
+ ENCOUNTER_COUNT = 4,
DATA_ENTERED_ROOM = 10,
DATA_PRISONER_1 = 11,
@@ -49,6 +50,7 @@ enum CreatureIds
NPC_BLOOD_GUARD = 17461,
NPC_SH_ZEALOT = 17462,
NPC_SH_ARCHER = 17427,
+ NPC_SH_SCOUT = 17693,
// Warchief Kargath
NPC_WARCHIEF_KARGATH = 16808,
diff --git a/src/server/scripts/Outland/outland_script_loader.cpp b/src/server/scripts/Outland/outland_script_loader.cpp
index ced2b80f4..5b4cefba9 100644
--- a/src/server/scripts/Outland/outland_script_loader.cpp
+++ b/src/server/scripts/Outland/outland_script_loader.cpp
@@ -75,6 +75,7 @@ void AddSC_instance_blood_furnace();
void AddSC_boss_magtheridon(); //HC Magtheridon's Lair
void AddSC_instance_magtheridons_lair();
void AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
+void AddSC_boss_porung();
void AddSC_boss_warbringer_omrogg();
void AddSC_boss_warchief_kargath_bladefist();
void AddSC_instance_shattered_halls();
@@ -179,6 +180,7 @@ void AddOutlandScripts()
AddSC_boss_magtheridon(); //HC Magtheridon's Lair
AddSC_instance_magtheridons_lair();
AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
+ AddSC_boss_porung();
AddSC_boss_warbringer_omrogg();
AddSC_boss_warchief_kargath_bladefist();
AddSC_instance_shattered_halls();
@@ -219,4 +221,4 @@ void AddOutlandScripts()
AddSC_shattrath_city();
AddSC_terokkar_forest();
//AddSC_zangarmarsh();
-}
\ No newline at end of file
+}