From 97f303702108ee57063c53ce094569faad372380 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Sun, 28 May 2023 15:50:50 -0300 Subject: [PATCH] fix(Scripts/ShatteredHalls): Implement the Flame Gauntlet event (#16383) Co-authored-by: Gultask <100873791+Gultask@users.noreply.github.com> --- .../rev_1684108506441826000.sql | 23 ++ .../instance_shattered_halls.cpp | 226 ++++++++++++++++++ .../ShatteredHalls/shattered_halls.h | 5 + 3 files changed, 254 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1684108506441826000.sql diff --git a/data/sql/updates/pending_db_world/rev_1684108506441826000.sql b/data/sql/updates/pending_db_world/rev_1684108506441826000.sql new file mode 100644 index 000000000..7ddeaf240 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1684108506441826000.sql @@ -0,0 +1,23 @@ +UPDATE `creature_template` SET `ScriptName` = 'npc_shattered_hand_scout' WHERE `entry` = 17693; + +SET @PATH := 17693 * 10; +DELETE FROM `waypoint_data` WHERE `id` = @PATH; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(@PATH,1,389.98074,315.4098,1.9338964,NULL,0,1,0,100,0), +(@PATH,2,419.4097,315.15308,1.940825,NULL,0,1,0,100,0), +(@PATH,3,460.31537,316.02213,1.9368871,NULL,0,1,0,100,0), +(@PATH,4,488.62424,315.73007,1.9498857,NULL,0,1,0,100,0); + +DELETE FROM `spell_target_position` WHERE `ID` = 30976; +INSERT INTO `spell_target_position` (`ID`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `VerifiedBuild`) VALUES +(30976, 540, 520.062, 255.486, 2.0333333, 48999); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 30952); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 30952, 0, 0, 31, 0, 3, 17687, 0, 0, 0, 0, '', 'Shoot Flame Arrow (30952) only hit Flame Arrow (17687)'); + +DELETE FROM `creature_formations` WHERE `memberGUID` IN (151094,151095,151096,151097); +INSERT INTO `creature_formations` (`memberGUID`, `leaderGUID`, `groupAI`) VALUES +(151095,151095,3), +(151096,151095,3), +(151097,151095,3); 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 5df8630d0..bb484cefb 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp @@ -17,6 +17,7 @@ #include "CreatureTextMgr.h" #include "InstanceScript.h" +#include "ScriptedCreature.h" #include "ScriptMgr.h" #include "shattered_halls.h" @@ -181,6 +182,221 @@ 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: @@ -192,6 +408,15 @@ public: 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); } @@ -232,6 +457,7 @@ 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 089c0d2d2..7f46320b4 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h @@ -45,6 +45,11 @@ enum CreatureIds { NPC_GRAND_WARLOCK_NETHEKURSE = 16807, NPC_FEL_ORC_CONVERT = 17083, + NPC_PORUNG = 20923, + NPC_BLOOD_GUARD = 17461, + NPC_SH_ZEALOT = 17462, + NPC_SH_ARCHER = 17427, + // Warchief Kargath NPC_WARCHIEF_KARGATH = 16808, NPC_WARCHIEF_PORTAL = 17611,