diff --git a/sql/custom/world/EG_2026_02_13_00_misc.sql b/sql/custom/world/EG_2026_02_13_00_misc.sql new file mode 100644 index 00000000..561c474a --- /dev/null +++ b/sql/custom/world/EG_2026_02_13_00_misc.sql @@ -0,0 +1,49 @@ + -- The Exorcism Bubbling Slimer Bunny (DND) smart ai +SET @ENTRY := 22505; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +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`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 11, 39300, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On just summoned - Self: Cast spell Quest - The Exorcism Bubbling Slimer (39300) on Self'), +(@ENTRY, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 146, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On just summoned - Self: Set uninteractable'), +(@ENTRY, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On just summoned - Self: Set react state to Passive'), +(@ENTRY, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On just summoned - Self: Set rooted'), +(@ENTRY, 0, 4, 0, 60, 0, 100, 0, 5000, 10000, 15000, 30000, 11, 39302, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Every 15 - 30 seconds (5 - 10s initially) - Self: Cast spell Quest - The Exorcism, Summon Foul Purge (39302) on Self'); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 22505 AND `SourceId` = 0; + +-- Correct condition set, because previously you could start the event again even though the quest was finished. +DELETE FROM `gossip_menu_option` WHERE `MenuID` = 8539; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(8539, 1, 0, 'I am ready, Anchorite. Let us begin the exorcism.', 20396, 1, 3, 0, 0, 0, 0, NULL, 0, 0); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` IN (8539)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUES +(15, 8539, 1, 0, 0, 9, 0, 10935, 0, 0, 0, 'Player for which gossip text is shown has quest The Exorcism of Colonel Jules (10935) active'); + +-- Sleeping is not necessary here because a spell takes care of that +UPDATE `creature_template_addon` SET `StandState` = 0 WHERE `entry` = 22432; + +-- Delete non-working Linked spell entry +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = 39371; + + -- Darkness Released smart ai +SET @ENTRY := 22507; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +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`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(@ENTRY, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 89, 15, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On just summoned - Self: Move randomly in radius 15 yards'), +(@ENTRY, 0, 1, 0, 8, 0, 100, 0, 39371, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On spell Prayer Beads (39371) hit - Self: Die'); + + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` = 22507 AND `SourceId` = 0; + +-- Spellscript Entry +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'EG_spell_prayer_beads'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(39371, 'EG_spell_prayer_beads'); + +UPDATE `creature` SET `orientation` = 4.79 WHERE (`guid` = 78786); + +DELETE FROM `creature_template_movement` WHERE `CreatureId`= 22507; +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES +(22507, 0, 0, 1, 0, 0, 0, 0); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 3edf72df..6722427c 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -36,6 +36,7 @@ #include #include #include +#include class Corpse; class Creature; @@ -298,6 +299,7 @@ class FlaggedValuesArray32 struct FindCreatureOptions { Optional CreatureId; + std::unordered_set CreatureIds; Optional StringId; Optional IsAlive; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 3a2cf3d2..6634844e 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1417,6 +1417,9 @@ namespace Trinity if (i_args.CreatureId && u->GetEntry() != i_args.CreatureId) return false; + if (!i_args.CreatureIds.contains(u->GetEntry())) + return false; + if (i_args.StringId && !u->HasStringId(*i_args.StringId)) return false; diff --git a/src/server/scripts/Custom/Spells/EG_gen_spell_scripts.cpp b/src/server/scripts/Custom/Spells/EG_gen_spell_scripts.cpp index 9621bc7d..78e277d3 100644 --- a/src/server/scripts/Custom/Spells/EG_gen_spell_scripts.cpp +++ b/src/server/scripts/Custom/Spells/EG_gen_spell_scripts.cpp @@ -1,4 +1,5 @@ #include "ScriptMgr.h" +#include "Creature.h" #include "Spell.h" #include "SpellInfo.h" #include "SpellMgr.h" @@ -167,6 +168,35 @@ class EG_spell_charm_drakuru_servant : public AuraScript } }; +enum SpellRitualPrayerBeads +{ + SPELL_HEAL_BARADA = 39322, + NPC_ANCHORITE_BARADA = 22431 +}; + +// 39371 - Prayer Beads +class EG_spell_prayer_beads : public SpellScript +{ + PrepareSpellScript(EG_spell_prayer_beads); + + void HandleHit() + { + Unit* caster = GetCaster(); + Creature* target = GetHitCreature(); + if (!caster || !target) + return; + + uint32 entry = target->GetEntry(); + if (entry == NPC_ANCHORITE_BARADA) + caster->CastSpell(target, SPELL_HEAL_BARADA, true); + } + + void Register() override + { + OnHit += SpellHitFn(EG_spell_prayer_beads::HandleHit); + } +}; + void AddSC_EG_gen_spell_scripts() { RegisterSpellScript(EG_spell_Cosmetic___Divine_Shield_Blue); @@ -175,4 +205,5 @@ void AddSC_EG_gen_spell_scripts() RegisterSpellScript(EG_spell_fel_reaver_controller); RegisterSpellScript(EG_spell_charm_channel); RegisterSpellScript(EG_spell_charm_drakuru_servant); + RegisterSpellScript(EG_spell_prayer_beads); } diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index e387477f..5c046117 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -31,13 +31,14 @@ enum ExorcismSpells { - SPELL_JULES_GOES_PRONE = 39283, + SPELL_JULES_GOES_PRONE = 39283, SPELL_JULES_THREATENS_AURA = 39284, - SPELL_JULES_GOES_UPRIGHT = 39294, - SPELL_JULES_VOMITS_AURA = 39295, + SPELL_JULES_GOES_UPRIGHT = 39294, + SPELL_JULES_VOMITS_AURA = 39295, - SPELL_BARADAS_COMMAND = 39277, - SPELL_BARADA_FALTERS = 39278, + SPELL_BARADAS_COMMAND = 39277, + SPELL_BARADA_FALTERS = 39278, + SPELL_HEAL_SELF = 39321, }; enum ExorcismTexts @@ -50,471 +51,367 @@ enum ExorcismTexts SAY_BARADA_6 = 5, SAY_BARADA_7 = 6, SAY_BARADA_8 = 7, - - SAY_JULES_1 = 0, - SAY_JULES_2 = 1, - SAY_JULES_3 = 2, - SAY_JULES_4 = 3, - SAY_JULES_5 = 4, + SAY_JULES_1 = 0, + SAY_JULES_2 = 1, + SAY_JULES_3 = 2, + SAY_JULES_4 = 3, + SAY_JULES_5 = 4, }; -Position const exorcismPos[11] = +Position const exorcismPos[12] = { - { -707.123f, 2751.686f, 101.592f, 4.577416f }, //Barada Waypoint-1 0 - { -710.731f, 2749.075f, 101.592f, 1.513286f }, //Barada Cast position 1 - { -710.332f, 2754.394f, 102.948f, 3.207566f }, //Jules 2 - { -714.261f, 2747.754f, 103.391f, 0.0f }, //Jules Waypoint-1 3 - { -713.113f, 2750.194f, 103.391f, 0.0f }, //Jules Waypoint-2 4 - { -710.385f, 2750.896f, 103.391f, 0.0f }, //Jules Waypoint-3 5 - { -708.309f, 2750.062f, 103.391f, 0.0f }, //Jules Waypoint-4 6 - { -707.401f, 2747.696f, 103.391f, 0.0f }, //Jules Waypoint-5 7 - { -708.591f, 2745.266f, 103.391f, 0.0f }, //Jules Waypoint-6 8 - { -710.597f, 2744.035f, 103.391f, 0.0f }, //Jules Waypoint-7 9 - { -713.089f, 2745.302f, 103.391f, 0.0f }, //Jules Waypoint-8 10 + { -707.42f, 2747.98f, 101.59f, 4.577416f }, + { -711.20f, 2747.75f, 101.59f, 1.51f }, + { -710.84f, 2749.55f, 101.59f, 1.63f }, + { -710.332f, 2754.394f, 102.948f, 3.207566f }, + { -714.261f, 2747.754f, 103.391f, 0.0f }, + { -713.113f, 2750.194f, 103.391f, 0.0f }, + { -710.385f, 2750.896f, 103.391f, 0.0f }, + { -708.309f, 2750.062f, 103.391f, 0.0f }, + { -707.401f, 2747.696f, 103.391f, 0.0f }, + { -708.591f, 2745.266f, 103.391f, 0.0f }, + { -710.597f, 2744.035f, 103.391f, 0.0f }, + { -713.089f, 2745.302f, 103.391f, 0.0f }, }; enum ExorcismMisc { - NPC_DARKNESS_RELEASED = 22507, - NPC_FOUL_PURGE = 22506, - NPC_COLONEL_JULES = 22432, - - BARADAS_GOSSIP_MESSAGE = 10683, - - QUEST_THE_EXORCISM_OF_COLONEL_JULES = 10935, - - ACTION_START_EVENT = 1, - ACTION_JULES_HOVER = 2, - ACTION_JULES_FLIGHT = 3, - ACTION_JULES_MOVE_HOME = 4, + NPC_COLONEL_JULES = 22432, + NPC_DARKNESS_RELEASED = 22507, + NPC_FOUL_PURGE = 22506, + NPC_THE_EXORCISM_BUBBLING_SLIMER_BUNNY = 22505, + + ACTION_START_EVENT = 1, + ACTION_JULES_HOVER = 2, + ACTION_JULES_FLIGHT = 3, + ACTION_JULES_MOVE_HOME = 4 }; enum ExorcismEvents { - EVENT_BARADAS_TALK = 1, - EVENT_RESET = 2, - - //Colonel Jules - EVENT_SUMMON_SKULL = 1, + EVENT_BARADAS_1 = 1, + EVENT_BARADAS_2 = 2, + EVENT_BARADAS_3 = 3, + EVENT_BARADAS_4 = 4, + EVENT_BARADAS_5 = 5, + EVENT_BARADAS_6 = 6, + EVENT_BARADAS_7 = 7, + EVENT_BARADAS_8 = 8, + EVENT_BARADAS_9 = 9, + EVENT_BARADAS_10 = 10, + EVENT_BARADAS_11 = 11, + EVENT_BARADAS_12 = 12, + EVENT_BARADAS_13 = 13, + EVENT_BARADAS_14 = 14, + EVENT_BARADAS_15 = 15, + EVENT_BARADAS_16 = 16, + EVENT_BARADAS_17 = 17, + EVENT_BARADAS_18 = 18, + EVENT_BARADAS_19 = 19, + EVENT_BARADAS_20 = 20, + EVENT_BARADAS_21 = 21, + EVENT_BARADAS_22 = 22, + EVENT_RESET = 23 }; /*###### ## npc_colonel_jules ######*/ - -class npc_colonel_jules : public CreatureScript +struct npc_colonel_jules : public ScriptedAI { -public: - npc_colonel_jules() : CreatureScript("npc_colonel_jules") { } + npc_colonel_jules(Creature* creature) : ScriptedAI(creature) {} - struct npc_colonel_julesAI : public ScriptedAI + void Reset() override { - npc_colonel_julesAI(Creature* creature) : ScriptedAI(creature), summons(me) - { - Initialize(); - } - - void Initialize() - { - point = 3; - wpreached = false; - success = false; - } - - void Reset() override - { - events.Reset(); - - summons.DespawnAll(); - Initialize(); - } - - bool success; + _point = 4; + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->CastSpell(me, SPELL_JULES_GOES_PRONE); + } - void DoAction(int32 action) override + void DoAction(int32 action) override + { + switch (action) { - switch (action) - { case ACTION_JULES_HOVER: - me->AddAura(SPELL_JULES_GOES_PRONE, me); - me->AddAura(SPELL_JULES_THREATENS_AURA, me); - + DoCastSelf(SPELL_JULES_THREATENS_AURA); me->SetCanFly(true); - me->SetSpeedRate(MOVE_RUN, 0.2f); - + me->SetWalk(true); me->SetFacingTo(3.207566f); - me->GetMotionMaster()->MoveJump(exorcismPos[2], 2.0f, 2.0f); - - success = false; - - events.ScheduleEvent(EVENT_SUMMON_SKULL, 10s); + me->GetMotionMaster()->MoveJump(exorcismPos[3], 2.0f, 2.0f); break; case ACTION_JULES_FLIGHT: - me->RemoveAura(SPELL_JULES_GOES_PRONE); - - me->AddAura(SPELL_JULES_GOES_UPRIGHT, me); - me->AddAura(SPELL_JULES_VOMITS_AURA, me); - - wpreached = true; - me->GetMotionMaster()->MovePoint(point, exorcismPos[point]); + me->RemoveAurasDueToSpell(SPELL_JULES_GOES_PRONE); + me->RemoveAurasDueToSpell(SPELL_JULES_THREATENS_AURA); + DoCastSelf(SPELL_JULES_GOES_UPRIGHT, true); + DoCastSelf(SPELL_JULES_VOMITS_AURA); + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(4, exorcismPos[4]); break; case ACTION_JULES_MOVE_HOME: - wpreached = false; - me->SetSpeedRate(MOVE_RUN, 1.0f); - me->GetMotionMaster()->MovePoint(11, exorcismPos[2]); - - events.CancelEvent(EVENT_SUMMON_SKULL); - break; - } - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - summon->GetMotionMaster()->MoveRandom(10.0f); - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (id < 10) - wpreached = true; - - if (id == 8) { - for (uint8 i = 0; i < 2; i++) - DoSummon(NPC_FOUL_PURGE, exorcismPos[8]); - } - - if (id == 10) - { - wpreached = true; - point = 3; + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(10, me->GetHomePosition(), true, me->GetHomePosition().GetOrientation()); + me->RemoveAurasDueToSpell(SPELL_JULES_VOMITS_AURA); + me->RemoveAurasDueToSpell(SPELL_JULES_THREATENS_AURA); + std::list npcs; + me->GetCreatureListWithOptionsInGrid(npcs, 40.f, FindCreatureOptions{ .CreatureIds = { NPC_DARKNESS_RELEASED, NPC_FOUL_PURGE, NPC_THE_EXORCISM_BUBBLING_SLIMER_BUNNY } }); + for (Creature* npc : npcs) + npc->DespawnOrUnsummon(); + break; } + default: + break; } + } - void UpdateAI(uint32 diff) override - { - if (wpreached) - { - me->GetMotionMaster()->MovePoint(point, exorcismPos[point]); - point++; - wpreached = false; - } - - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SUMMON_SKULL: - uint8 summonCount = urand(1, 3); - - for (uint8 i = 0; i < summonCount; i++) - me->SummonCreature(NPC_DARKNESS_RELEASED, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 1.5f, 0, TEMPSUMMON_MANUAL_DESPAWN); - - events.ScheduleEvent(EVENT_SUMMON_SKULL, 10s, 15s); - break; - } - } - } + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; - bool OnGossipHello(Player* player) override + if (id == 10) { - if (success) - player->KilledMonsterCredit(NPC_COLONEL_JULES, ObjectGuid::Empty); - - SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); - return true; + me->SetCanFly(false); + me->SetDisableGravity(false); + me->RemoveAllAuras(); + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->HandleEmoteCommand(EMOTE_STATE_STAND); + return; } - private: - EventMap events; - SummonList summons; - - uint8 point; - - bool wpreached; - }; + if (id == 9) + _point = 4; + if (_point) + me->GetMotionMaster()->MovePoint(_point++, exorcismPos[_point]); + } - CreatureAI* GetAI(Creature* creature) const override + bool OnGossipHello(Player* player) override { - return new npc_colonel_julesAI(creature); + player->KilledMonsterCredit(NPC_COLONEL_JULES, ObjectGuid::Empty); + SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID()); + return true; } + + void EnterEvadeMode(EvadeReason /*why*/) override { } + +private: + uint8 _point = 4; }; /*###### ## npc_barada ######*/ - -class npc_barada : public CreatureScript +struct npc_barada : public ScriptedAI { -public: - npc_barada() : CreatureScript("npc_barada") { } + npc_barada(Creature* creature) : ScriptedAI(creature) {} - struct npc_baradaAI : public ScriptedAI + void Reset() override { - npc_baradaAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - step = 0; - } + _events.Reset(); + _playerGUID.Clear(); + me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + } - void Reset() override + bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + ClearGossipMenuFor(player); + if (gossipListId == 1) { - events.Reset(); - Initialize(); - - playerGUID.Clear(); - me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + player->PlayerTalkClass->SendCloseGossip(); + me->AI()->Talk(SAY_BARADA_1); + me->AI()->DoAction(ACTION_START_EVENT); } + return false; + } - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + void DoAction(int32 action) override + { + if (action == ACTION_START_EVENT) { - ClearGossipMenuFor(player); - switch (gossipListId) + if (Creature* jules = me->FindNearestCreature(NPC_COLONEL_JULES, 20.0f)) { - case 1: - player->PlayerTalkClass->SendCloseGossip(); - me->AI()->Talk(SAY_BARADA_1); - me->AI()->DoAction(ACTION_START_EVENT); - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - break; - default: - break; + _julesGUID = jules->GetGUID(); + jules->AI()->Talk(SAY_JULES_1); } - return false; + me->SetWalk(true); + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + Talk(SAY_BARADA_2); + me->SetUnitFlag(UNIT_FLAG_PACIFIED); + me->GetMotionMaster()->MovePoint(0, exorcismPos[0]); } + } - void DoAction(int32 action) override - { - if (action == ACTION_START_EVENT) - { - if (Creature* jules = me->FindNearestCreature(NPC_COLONEL_JULES, 20.0f, true)) - { - julesGUID = jules->GetGUID(); - jules->AI()->Talk(SAY_JULES_1); - } - - me->GetMotionMaster()->MovePoint(0, exorcismPos[1]); - Talk(SAY_BARADA_2); - - me->SetUnitFlag(UNIT_FLAG_PACIFIED); - } - } + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; - void MovementInform(uint32 type, uint32 id) override + if (id == 0) + me->GetMotionMaster()->MovePoint(1, exorcismPos[1]); + else if (id == 1) + me->GetMotionMaster()->MovePoint(2, exorcismPos[2]); + else if (id == 2) { - if (type != POINT_MOTION_TYPE) - return; + me->HandleEmoteCommand(EMOTE_STATE_STAND); + _events.ScheduleEvent(EVENT_BARADAS_1, 2s); + } + } - if (id == 0) - me->GetMotionMaster()->MovePoint(1, exorcismPos[1]); + void JustDied(Unit* /*killer*/) override + { + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->DespawnOrUnsummon(5s, 10s); + me->DespawnOrUnsummon(5s, 10s); + + std::list npcs; + me->GetCreatureListWithOptionsInGrid(npcs, 40.f, FindCreatureOptions{ .CreatureIds = { NPC_DARKNESS_RELEASED, NPC_FOUL_PURGE, NPC_THE_EXORCISM_BUBBLING_SLIMER_BUNNY } }); + for (Creature* npc : npcs) + npc->DespawnOrUnsummon(); + } - if (id == 1) - events.ScheduleEvent(EVENT_BARADAS_TALK, 2s); - } + void EnterEvadeMode(EvadeReason /*why*/) override { } - void JustDied(Unit* /*killer*/) override - { - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - { - jules->AI()->DoAction(ACTION_JULES_MOVE_HOME); - jules->RemoveAllAuras(); - } - } + void UpdateAI(uint32 diff) override + { + _events.Update(diff); - void UpdateAI(uint32 diff) override + while (uint32 eventId = _events.ExecuteEvent()) { - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) + switch (eventId) { - switch (eventId) + case EVENT_BARADAS_1: + me->SetFacingTo(1.513286f); + me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + _events.ScheduleEvent(EVENT_BARADAS_2, 3s); + break; + case EVENT_BARADAS_2: + DoCast(SPELL_BARADAS_COMMAND); + _events.ScheduleEvent(EVENT_BARADAS_3, 5s); + break; + case EVENT_BARADAS_3: + Talk(SAY_BARADA_3); + _events.ScheduleEvent(EVENT_BARADAS_4, 7s); + break; + case EVENT_BARADAS_4: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_2); + _events.ScheduleEvent(EVENT_BARADAS_5, 18s); + break; + case EVENT_BARADAS_5: + DoCast(SPELL_BARADA_FALTERS); + me->HandleEmoteCommand(EMOTE_STAND_STATE_NONE); + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->DoAction(ACTION_JULES_HOVER); + _events.ScheduleEvent(EVENT_BARADAS_6, 11s); + break; + case EVENT_BARADAS_6: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_3); + _events.ScheduleEvent(EVENT_BARADAS_7, 13s); + break; + case EVENT_BARADAS_7: + Talk(SAY_BARADA_4); + _events.ScheduleEvent(EVENT_BARADAS_8, 5s); + break; + case EVENT_BARADAS_8: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_3); + _events.ScheduleEvent(EVENT_BARADAS_9, 13s); + break; + case EVENT_BARADAS_9: + Talk(SAY_BARADA_4); + _events.ScheduleEvent(EVENT_BARADAS_10, 12s); + break; + case EVENT_BARADAS_10: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_4); + _events.ScheduleEvent(EVENT_BARADAS_11, 12s); + break; + case EVENT_BARADAS_11: + Talk(SAY_BARADA_4); + _events.ScheduleEvent(EVENT_BARADAS_12, 5s); + break; + case EVENT_BARADAS_12: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->DoAction(ACTION_JULES_FLIGHT); + _events.ScheduleEvent(EVENT_BARADAS_13, 10s); + break; + case EVENT_BARADAS_13: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_4); + _events.ScheduleEvent(EVENT_BARADAS_14, 8s); + break; + case EVENT_BARADAS_14: + Talk(SAY_BARADA_5); + _events.ScheduleEvent(EVENT_BARADAS_15, 10s); + break; + case EVENT_BARADAS_15: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_4); + _events.ScheduleEvent(EVENT_BARADAS_16, 10s); + break; + case EVENT_BARADAS_16: + Talk(SAY_BARADA_6); + _events.ScheduleEvent(EVENT_BARADAS_17, 10s); + break; + case EVENT_BARADAS_17: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_5); + _events.ScheduleEvent(EVENT_BARADAS_18, 10s); + break; + case EVENT_BARADAS_18: + Talk(SAY_BARADA_7); + _events.ScheduleEvent(EVENT_BARADAS_19, 10s); + break; + case EVENT_BARADAS_19: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->Talk(SAY_JULES_3); + _events.ScheduleEvent(EVENT_BARADAS_20, 10s); + break; + case EVENT_BARADAS_20: + Talk(SAY_BARADA_7); + _events.ScheduleEvent(EVENT_BARADAS_21, 10s); + break; + case EVENT_BARADAS_21: { - case EVENT_BARADAS_TALK: - switch (step) - { - case 0: - me->SetFacingTo(1.513286f); - - me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); - events.ScheduleEvent(EVENT_BARADAS_TALK, 3s); - step++; - break; - case 1: - DoCast(SPELL_BARADAS_COMMAND); - events.ScheduleEvent(EVENT_BARADAS_TALK, 5s); - step++; - break; - case 2: - Talk(SAY_BARADA_3); - events.ScheduleEvent(EVENT_BARADAS_TALK, 7s); - step++; - break; - case 3: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_2); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 18s); - step++; - break; - case 4: - DoCast(SPELL_BARADA_FALTERS); - me->HandleEmoteCommand(EMOTE_STAND_STATE_NONE); - - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->DoAction(ACTION_JULES_HOVER); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 11s); - step++; - break; - case 5: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_3); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 13s); - step++; - break; - case 6: - Talk(SAY_BARADA_4); - events.ScheduleEvent(EVENT_BARADAS_TALK, 5s); - step++; - break; - case 7: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_3); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 13s); - step++; - break; - case 8: - Talk(SAY_BARADA_4); - events.ScheduleEvent(EVENT_BARADAS_TALK, 12s); - step++; - break; - case 9: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_4); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 12s); - step++; - break; - case 10: - Talk(SAY_BARADA_4); - events.ScheduleEvent(EVENT_BARADAS_TALK, 5s); - step++; - break; - case 11: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->DoAction(ACTION_JULES_FLIGHT); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 12: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_4); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 8s); - step++; - break; - case 13: - Talk(SAY_BARADA_5); - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 14: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_4); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 15: - Talk(SAY_BARADA_6); - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 16: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_5); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 17: - Talk(SAY_BARADA_7); - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 18: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - jules->AI()->Talk(SAY_JULES_3); - - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 19: - Talk(SAY_BARADA_7); - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 20: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - { - jules->AI()->DoAction(ACTION_JULES_MOVE_HOME); - jules->RemoveAura(SPELL_JULES_VOMITS_AURA); - } - - events.ScheduleEvent(EVENT_BARADAS_TALK, 10s); - step++; - break; - case 21: - //End - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - { - ENSURE_AI(npc_colonel_jules::npc_colonel_julesAI, jules->AI())->success = true; - jules->RemoveAllAuras(); - } - - me->RemoveAura(SPELL_BARADAS_COMMAND); - me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); - - Talk(SAY_BARADA_8); - me->GetMotionMaster()->MoveTargetedHome(); - EnterEvadeMode(); - events.ScheduleEvent(EVENT_RESET, 2min); - break; - } - break; - case EVENT_RESET: - if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) - ENSURE_AI(npc_colonel_jules::npc_colonel_julesAI, jules->AI())->success = false; - break; + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + jules->AI()->DoAction(ACTION_JULES_MOVE_HOME); + std::list npcs; + me->GetCreatureListWithOptionsInGrid(npcs, 40.f, FindCreatureOptions{ .CreatureIds = { NPC_DARKNESS_RELEASED, NPC_FOUL_PURGE, NPC_THE_EXORCISM_BUBBLING_SLIMER_BUNNY } }); + for (Creature* npc : npcs) + npc->DespawnOrUnsummon(); + _events.ScheduleEvent(EVENT_BARADAS_22, 2s); + break; } + case EVENT_BARADAS_22: + me->HandleEmoteCommand(EMOTE_STATE_STAND); + DoCastSelf(SPELL_HEAL_SELF); + me->RemoveAllAuras(); + me->RemoveUnitFlag(UNIT_FLAG_PACIFIED); + Talk(SAY_BARADA_8); + _events.ScheduleEvent(EVENT_RESET, 60s); + break; + case EVENT_RESET: + if (Creature* jules = ObjectAccessor::GetCreature(*me, _julesGUID)) + { + jules->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + jules->DespawnOrUnsummon(1s, 10s); + } + me->DespawnOrUnsummon(1s, 10s); + break; + default: + break; } } - - private: - EventMap events; - uint8 step; - ObjectGuid julesGUID; - ObjectGuid playerGUID; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_baradaAI(creature); } + +private: + EventMap _events; + ObjectGuid _julesGUID; + ObjectGuid _playerGUID; }; enum Aledis @@ -986,8 +883,8 @@ class spell_hellfire_peninsula_demonaic_visitation : public AuraScript void AddSC_hellfire_peninsula() { - new npc_colonel_jules(); - new npc_barada(); + RegisterCreatureAI(npc_colonel_jules); + RegisterCreatureAI(npc_barada); new npc_magister_aledis(); RegisterCreatureAI(npc_watch_commander_leonus); RegisterCreatureAI(npc_infernal_rain_hellfire);