From 6e7aec3b958d91b7ecd135e700530c8437acb3d5 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sun, 19 Feb 2023 05:48:12 +0100 Subject: [PATCH] fix(Scripts/BlackMorass): Improved Opening the Dark portal encounter. (#14861) --- .../instance_the_black_morass.cpp | 156 +++++++++++++++--- .../TheBlackMorass/the_black_morass.cpp | 2 +- .../TheBlackMorass/the_black_morass.h | 11 +- 3 files changed, 138 insertions(+), 31 deletions(-) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp index a1539a192..aa80861ad 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp @@ -23,7 +23,8 @@ #include "TemporarySummon.h" #include "the_black_morass.h" -const Position PortalLocation[4] = +#define MAX_PORTAL_LOCATIONS 4 +const Position PortalLocation[MAX_PORTAL_LOCATIONS] = { { -2030.8318f, 7024.9443f, 23.071817f, 3.14159f }, { -1961.7335f, 7029.5280f, 21.811401f, 2.12931f }, @@ -58,6 +59,7 @@ public: _currentRift = 0; _shieldPercent = 100; encounterNPCs.clear(); + _timerToNextBoss = 0; } void CleanupInstance() @@ -66,6 +68,8 @@ public: _currentRift = 0; _shieldPercent = 100; + _usedRiftPostions.fill(ObjectGuid::Empty); + instance->LoadGrid(-2023.0f, 7121.0f); if (Creature* medivh = instance->GetCreature(_medivhGUID)) { @@ -183,21 +187,48 @@ public: } case TYPE_CHRONO_LORD_DEJA: case TYPE_TEMPORUS: + { + GuidSet eCopy = encounterNPCs; + for (ObjectGuid const& guid : eCopy) + { + if (Creature* creature = instance->GetCreature(guid)) + { + switch (creature->GetEntry()) + { + case NPC_RIFT_KEEPER_WARLOCK: + case NPC_RIFT_KEEPER_MAGE: + case NPC_RIFT_LORD: + case NPC_RIFT_LORD_2: + case NPC_TIME_RIFT: + creature->DespawnOrUnsummon(); + break; + default: + break; + } + } + } encounters[type] = DONE; - Events.RescheduleEvent(EVENT_NEXT_PORTAL, 60000); + + if (!_timerToNextBoss || _timerToNextBoss > 30 * IN_MILLISECONDS) + { + Events.RescheduleEvent(EVENT_NEXT_PORTAL, 30 * IN_MILLISECONDS); + } + else + { + Events.RescheduleEvent(EVENT_NEXT_PORTAL, _timerToNextBoss); + } Events.SetPhase(1); SaveToDB(); + _timerToNextBoss = (instance->IsHeroic() ? 300 : 150) * IN_MILLISECONDS; break; - case DATA_RIFT_KILLED: - if (!Events.IsInPhase(1)) - Events.RescheduleEvent(EVENT_NEXT_PORTAL, 4000); - break; + } case DATA_MEDIVH: { DoUpdateWorldState(WORLD_STATE_BM, 1); DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent); DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift); Events.RescheduleEvent(EVENT_NEXT_PORTAL, 3000); + _timerToNextBoss = (instance->IsHeroic() ? 300 : 150) * IN_MILLISECONDS; for (ObjectGuid const& guid : encounterNPCs) { @@ -285,6 +316,34 @@ public: encounterNPCs.insert(data); else if (type == DATA_DELETED_NPC) encounterNPCs.erase(data); + else if (type == DATA_RIFT_KILLED) + { + if (!Events.IsInPhase(1)) + { + uint8 emptySpots = 0; + for (uint8 i = 0; i < MAX_PORTAL_LOCATIONS; ++i) + { + if (!_usedRiftPostions[i]) + { + ++emptySpots; + } + + if (_usedRiftPostions[i] == data) + { + _usedRiftPostions[i].Clear(); + } + } + + if (emptySpots >= MAX_PORTAL_LOCATIONS - 1) + { + Events.RescheduleEvent(EVENT_NEXT_PORTAL, 4000); + } + else if (!emptySpots) + { + Events.RescheduleEvent(EVENT_NEXT_PORTAL, (_currentRift >= 13 ? 120 : 90) * IN_MILLISECONDS); + } + } + } } ObjectGuid GetGuidData(uint32 data) const override @@ -295,17 +354,11 @@ public: return ObjectGuid::Empty; } - void SummonPortalKeeper() + void SummonPortalKeeper(uint32 eventId) { - Creature* rift = nullptr; - for (ObjectGuid const& guid : encounterNPCs) - if (Creature* summon = instance->GetCreature(guid)) - if (summon->GetEntry() == NPC_TIME_RIFT) - { - rift = summon; - break; - } - + uint8 riftPosition = eventId - EVENT_SUMMON_KEEPER_1; + ObjectGuid const& riftGUID = _usedRiftPostions[riftPosition]; + Creature* rift = instance->GetCreature(riftGUID); if (!rift) return; @@ -348,23 +401,72 @@ public: void Update(uint32 diff) override { + if (_timerToNextBoss) + { + if (_timerToNextBoss <= diff) + { + _timerToNextBoss = 0; + } + else + { + _timerToNextBoss -= diff; + } + } + Events.Update(diff); - switch (Events.ExecuteEvent()) + + uint32 eventId = Events.ExecuteEvent(); + switch (eventId) { case EVENT_NEXT_PORTAL: - ++_currentRift; - DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift); - Events.ScheduleEvent(EVENT_SUMMON_KEEPER, 6000); - Events.SetPhase(0); - + { if (instance->GetCreature(_medivhGUID)) { - uint8 position = (_currentRift - 1) % 4; - instance->SummonCreature(NPC_TIME_RIFT, PortalLocation[position]); + uint8 position = MAX_PORTAL_LOCATIONS; + + std::vector possibleSpots; + for (uint8 i = 0; i < MAX_PORTAL_LOCATIONS; ++i) + { + if (!_usedRiftPostions[i]) + { + possibleSpots.push_back(i); + } + } + + if (!possibleSpots.empty()) + { + position = Acore::Containers::SelectRandomContainerElement(possibleSpots); + } + + if (position < MAX_PORTAL_LOCATIONS) + { + ++_currentRift; + DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift); + Events.ScheduleEvent(EVENT_SUMMON_KEEPER_1 + position, 6000); + Events.SetPhase(0); + + if (Creature* rift = instance->SummonCreature(NPC_TIME_RIFT, PortalLocation[position])) + { + _usedRiftPostions[position] = rift->GetGUID(); + + for (uint8 i = 0; i < MAX_PORTAL_LOCATIONS; ++i) + { + if (!_usedRiftPostions[i]) + { + Events.RescheduleEvent(EVENT_NEXT_PORTAL, (_currentRift >= 13 ? 120 : 90) * IN_MILLISECONDS); + break; + } + } + } + } } break; - case EVENT_SUMMON_KEEPER: - SummonPortalKeeper(); + } + case EVENT_SUMMON_KEEPER_1: + case EVENT_SUMMON_KEEPER_2: + case EVENT_SUMMON_KEEPER_3: + case EVENT_SUMMON_KEEPER_4: + SummonPortalKeeper(eventId); break; case EVENT_WIPE_1: if (Creature* medivh = instance->GetCreature(_medivhGUID)) @@ -433,6 +535,8 @@ public: protected: EventMap Events; + std::array _usedRiftPostions; + uint32 _timerToNextBoss; }; }; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp index cb4abba8f..873411b44 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -326,7 +326,7 @@ struct npc_time_rift : public NullCreatureAI Creature* riftKeeper = ObjectAccessor::GetCreature(*me, _riftKeeperGUID); if (!riftKeeper || !riftKeeper->IsAlive()) { - _instance->SetData(DATA_RIFT_KILLED, 1); + _instance->SetGuidData(DATA_RIFT_KILLED, me->GetGUID()); me->DespawnOrUnsummon(0); break; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h index 1d5325122..6d895c210 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h @@ -90,10 +90,13 @@ enum Misc SPELL_TELEPORT_VISUAL = 7791, EVENT_NEXT_PORTAL = 1, - EVENT_SUMMON_KEEPER = 2, - EVENT_WIPE_1 = 3, - EVENT_WIPE_2 = 4, - EVENT_WIPE_3 = 5, + EVENT_SUMMON_KEEPER_1 = 2, + EVENT_SUMMON_KEEPER_2 = 3, + EVENT_SUMMON_KEEPER_3 = 4, + EVENT_SUMMON_KEEPER_4 = 5, + EVENT_WIPE_1 = 6, + EVENT_WIPE_2 = 7, + EVENT_WIPE_3 = 8, ACTION_OUTRO = 1 };