From 155bacb8dd068e31604ad5e7e5249bc8837a8306 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sun, 9 Apr 2023 20:10:53 +0200 Subject: [PATCH] fix(Scripts/ShadowLabirynth): Ambassador Hellmaw: (#15761) * fix(Scripts/ShadowLabirynth): Ambassador Hellmaw: Properly handle Banish intro event. Ambassadow Hellmaw can attack while casting Corrosive Acid. Added missing paths. Fixes #15638 * buildfix. --- .../rev_1680357334133098700.sql | 40 +++++ .../boss_ambassador_hellmaw.cpp | 144 ++++++++++++++---- .../instance_shadow_labyrinth.cpp | 37 +++-- .../ShadowLabyrinth/shadow_labyrinth.h | 4 +- 4 files changed, 180 insertions(+), 45 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1680357334133098700.sql diff --git a/data/sql/updates/pending_db_world/rev_1680357334133098700.sql b/data/sql/updates/pending_db_world/rev_1680357334133098700.sql new file mode 100644 index 000000000..c59706e8f --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1680357334133098700.sql @@ -0,0 +1,40 @@ +-- +DELETE FROM `smart_scripts` WHERE `entryorguid`=18794 AND `source_type`=0 AND `id`=16; + +DELETE FROM `script_waypoint` WHERE `entry`=18731; +DELETE FROM `waypoint_data` WHERE `id` IN (1873100,1873101); +INSERT INTO `waypoint_data` VALUES +(1873100,1,-159.51387,-2.139098,8.073091,NULL,0,0,0,100,0), +(1873100,2,-163.44856,-7.553354,8.073133,NULL,0,0,0,100,0), +(1873100,3,-168.17548,-9.746803,8.073169,NULL,0,0,0,100,0), +(1873100,4,-171.3253,-13.198364,8.073106,NULL,0,0,0,100,0), +(1873100,5,-172.78348,-25.986193,8.073088,NULL,0,0,0,100,0), +(1873100,6,-173.66841,-54.100628,8.073081,NULL,0,0,0,100,0), +(1873100,7,-168.93939,-66.52654,8.073219,NULL,0,0,0,100,0), +(1873100,8,-157.49812,-73.04389,8.077904,NULL,0,0,0,100,0), +(1873100,9,-145.8215,-67.855865,8.063689,NULL,0,0,0,100,0), +(1873100,10,-141.28224,-56.002922,8.073066,NULL,0,0,0,100,0), +(1873100,11,-142.33768,-25.135996,8.073035,NULL,0,0,0,100,0), +(1873100,12,-143.23366,-14.373271,8.073031,NULL,0,0,0,100,0), +(1873100,13,-147.05266,-10.097949,8.0730295,NULL,0,0,0,100,0), +(1873100,14,-152.87035,-5.490992,8.073108,NULL,0,0,0,100,0), +(1873100,15,-156.7587,4.856207,8.073061,4.660028934478759765,0,0,0,100,0), + +(1873101,16,-156.31073,24.4289,8.072962,NULL,0,0,0,100,0), +(1873101,17,-153.34592,40.90819,6.877141,NULL,0,0,0,100,0), +(1873101,18,-144.48116,52.74748,5.6318674,NULL,0,0,0,100,0), +(1873101,19,-130.80013,60.605686,4.2999473,NULL,0,0,0,100,0), +(1873101,20,-91.258835,61.131367,3.2408845,NULL,0,0,0,100,0), +(1873101,22,-73.11457,51.921284,1.4783795,2.705260276794433593,30000,0,0,100,0), +(1873101,23,-89.108116,61.20221,3.026778,NULL,0,0,0,100,0), +(1873101,24,-108.00966,63.536663,3.4476438,NULL,0,0,0,100,0), +(1873101,25,-130.86102,60.57378,4.3055944,NULL,0,0,0,100,0), +(1873101,26,-143.99977,52.971825,5.5921054,NULL,0,0,0,100,0), +(1873101,27,-152.94989,41.38679,6.888551,NULL,0,0,0,100,0), +(1873101,28,-156.86404,25.838596,8.125509,NULL,30000,0,0,100,0), +(1873101,29,-156.68945,2.408526,8.073063,NULL,20000,0,0,100,0); + +UPDATE `creature_text` SET `Emote`=15 WHERE `CreatureID`=18731 AND `GroupID`=0; + +UPDATE `creature_template` SET `unit_flags`=32832 WHERE `entry` IN (18731,20636); +DELETE FROM `creature_template_addon` WHERE `entry`=18731; diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp index 893a31715..d9c359f15 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp @@ -17,7 +17,6 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" #include "shadow_labyrinth.h" enum eEnums @@ -35,7 +34,12 @@ enum eEnums EVENT_SPELL_CORROSIVE = 1, EVENT_SPELL_FEAR = 2, - EVENT_SPELL_ENRAGE = 3 + EVENT_SPELL_ENRAGE = 3, + + PATH_ID_START = 1873100, + PATH_ID_PATHING = 1873101, + + SOUND_INTRO = 9349 }; class boss_ambassador_hellmaw : public CreatureScript @@ -48,9 +52,9 @@ public: return GetShadowLabyrinthAI(creature); } - struct boss_ambassador_hellmawAI : public npc_escortAI + struct boss_ambassador_hellmawAI : public ScriptedAI { - boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature) + boss_ambassador_hellmawAI(Creature* creature) : ScriptedAI(creature) { instance = creature->GetInstanceScript(); } @@ -59,64 +63,102 @@ public: EventMap events; bool isBanished; - void DoAction(int32 param) override + void InitializeAI() override { - if (param != 1) - return; + Reset(); - me->RemoveAurasDueToSpell(SPELL_BANISH); - Talk(SAY_INTRO); - Start(true, false, ObjectGuid::Empty, nullptr, false, true); - isBanished = false; + if (instance && instance->GetData(TYPE_RITUALISTS) != DONE) + { + isBanished = true; + me->SetImmuneToAll(true); + + me->m_Events.AddEventAtOffset([this]() + { + DoCastSelf(SPELL_BANISH, true); + }, 500ms); + } + else + { + me->GetMotionMaster()->MovePath(PATH_ID_START, false); + } } void Reset() override { events.Reset(); isBanished = false; + me->SetImmuneToAll(false); if (instance) { instance->SetData(TYPE_HELLMAW, NOT_STARTED); - if (instance->GetData(TYPE_OVERSEER) != DONE) - { - isBanished = true; - me->CastSpell(me, SPELL_BANISH, true); - } - else - Start(true, false, ObjectGuid::Empty, nullptr, false, true); } } + void DoAction(int32 param) override + { + if (param != 1) + { + return; + } + + me->RemoveAurasDueToSpell(SPELL_BANISH); + Talk(SAY_INTRO); + DoPlaySoundToSet(me, SOUND_INTRO); + isBanished = false; + me->SetImmuneToAll(false); + me->GetMotionMaster()->MovePath(PATH_ID_START, false); + } + void JustEngagedWith(Unit*) override { if (isBanished) + { return; + } + Talk(SAY_AGGRO); events.ScheduleEvent(EVENT_SPELL_CORROSIVE, urand(5000, 10000)); events.ScheduleEvent(EVENT_SPELL_FEAR, urand(15000, 20000)); if (IsHeroic()) + { events.ScheduleEvent(EVENT_SPELL_ENRAGE, 180000); + } if (instance) + { instance->SetData(TYPE_HELLMAW, IN_PROGRESS); + } } void MoveInLineOfSight(Unit* who) override { if (isBanished) + { return; - npc_escortAI::MoveInLineOfSight(who); + } + + ScriptedAI::MoveInLineOfSight(who); } void AttackStart(Unit* who) override { if (isBanished) + { return; - npc_escortAI::AttackStart(who); + } + + ScriptedAI::AttackStart(who); } - void WaypointReached(uint32 /*waypointId*/) override + void PathEndReached(uint32 pathId) override { + if (pathId == PATH_ID_START) + { + me->m_Events.AddEventAtOffset([this]() + { + me->GetMotionMaster()->MovePath(PATH_ID_PATHING, true); + }, 20s); + } } void KilledUnit(Unit* victim) override @@ -132,19 +174,63 @@ public: instance->SetData(TYPE_HELLMAW, DONE); } - void UpdateAI(uint32 diff) override + bool CanAIAttack(Unit const* /*unit*/) const override { - npc_escortAI::UpdateAI(diff); + return !isBanished; + } - if (!UpdateVictim()) - return; - - if (isBanished) + void DoMeleeAttackIfReady(bool ignoreCasting) + { + if (!ignoreCasting && me->HasUnitState(UNIT_STATE_CASTING)) { - EnterEvadeMode(); return; } + Unit* victim = me->GetVictim(); + if (!victim || !victim->IsInWorld()) + { + return; + } + + if (!me->IsWithinMeleeRange(victim)) + { + return; + } + + //Make sure our attack is ready and we aren't currently casting before checking distance + if (me->isAttackReady()) + { + // xinef: prevent base and off attack in same time, delay attack at 0.2 sec + if (me->haveOffhandWeapon()) + { + if (me->getAttackTimer(OFF_ATTACK) < ATTACK_DISPLAY_DELAY) + { + me->setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY); + } + } + + me->AttackerStateUpdate(victim, BASE_ATTACK, false, ignoreCasting); + me->resetAttackTimer(); + } + + if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK)) + { + // xinef: delay main hand attack if both will hit at the same time (players code) + if (me->getAttackTimer(BASE_ATTACK) < ATTACK_DISPLAY_DELAY) + { + me->setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY); + } + + me->AttackerStateUpdate(victim, OFF_ATTACK, false, ignoreCasting); + me->resetAttackTimer(OFF_ATTACK); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + events.Update(diff); switch (events.ExecuteEvent()) { @@ -161,7 +247,7 @@ public: break; } - DoMeleeAttackIfReady(); + DoMeleeAttackIfReady(me->FindCurrentSpellBySpellId(SPELL_CORROSIVE_ACID) != nullptr); } }; }; diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp index 2e88a620c..f05b3e2eb 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp @@ -39,13 +39,13 @@ public: ObjectGuid m_uiRefectoryDoorGUID; ObjectGuid m_uiScreamingHallDoorGUID; - uint32 m_uiFelOverseerCount; + uint32 _ritualistsAliveCount; void Initialize() override { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - m_uiFelOverseerCount = 0; + _ritualistsAliveCount = 0; } bool IsEncounterInProgress() const override @@ -76,11 +76,13 @@ public: void OnCreatureCreate(Creature* creature) override { + InstanceScript::OnCreatureCreate(creature); + switch (creature->GetEntry()) { - case NPC_FEL_OVERSEER: + case NPC_CABAL_RITUALIST: if (creature->IsAlive()) - ++m_uiFelOverseerCount; + ++_ritualistsAliveCount; break; case NPC_HELLMAW: m_uiHellmawGUID = creature->GetGUID(); @@ -88,19 +90,26 @@ public: } } + void OnUnitDeath(Unit* unit) override + { + InstanceScript::OnUnitDeath(unit); + + if (unit->GetEntry() == NPC_CABAL_RITUALIST) + if (!--_ritualistsAliveCount) + { + m_auiEncounter[TYPE_RITUALISTS] = DONE; + SaveToDB(); + if (Creature* cr = instance->GetCreature(m_uiHellmawGUID)) + { + cr->AI()->DoAction(1); + } + } + } + void SetData(uint32 type, uint32 uiData) override { switch (type) { - case TYPE_OVERSEER: - if (!--m_uiFelOverseerCount) - { - m_auiEncounter[type] = DONE; - if (Creature* cr = instance->GetCreature(m_uiHellmawGUID)) - cr->AI()->DoAction(1); - } - break; - case DATA_BLACKHEARTTHEINCITEREVENT: if (uiData == DONE) DoUseDoorOrButton(m_uiRefectoryDoorGUID); @@ -125,7 +134,7 @@ public: uint32 GetData(uint32 type) const override { - if (type == TYPE_OVERSEER) + if (type == TYPE_RITUALISTS) return m_auiEncounter[0]; return 0; } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h index 7b54d4514..c8bed78e9 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h @@ -27,7 +27,7 @@ enum slData { - TYPE_OVERSEER = 0, + TYPE_RITUALISTS = 0, TYPE_HELLMAW = 1, DATA_BLACKHEARTTHEINCITEREVENT = 2, DATA_GRANDMASTERVORPILEVENT = 3, @@ -37,7 +37,7 @@ enum slData enum slNPCandGO { - NPC_FEL_OVERSEER = 18796, + NPC_CABAL_RITUALIST = 18794, NPC_HELLMAW = 18731, REFECTORY_DOOR = 183296, //door opened when blackheart the inciter dies