fix(Scripts/BlackMorass): Improved Opening the Dark portal encounter. (#14861)

This commit is contained in:
UltraNix
2023-02-19 05:48:12 +01:00
committed by GitHub
parent 195c99124c
commit 6e7aec3b95
3 changed files with 138 additions and 31 deletions
@@ -23,7 +23,8 @@
#include "TemporarySummon.h" #include "TemporarySummon.h"
#include "the_black_morass.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 }, { -2030.8318f, 7024.9443f, 23.071817f, 3.14159f },
{ -1961.7335f, 7029.5280f, 21.811401f, 2.12931f }, { -1961.7335f, 7029.5280f, 21.811401f, 2.12931f },
@@ -58,6 +59,7 @@ public:
_currentRift = 0; _currentRift = 0;
_shieldPercent = 100; _shieldPercent = 100;
encounterNPCs.clear(); encounterNPCs.clear();
_timerToNextBoss = 0;
} }
void CleanupInstance() void CleanupInstance()
@@ -66,6 +68,8 @@ public:
_currentRift = 0; _currentRift = 0;
_shieldPercent = 100; _shieldPercent = 100;
_usedRiftPostions.fill(ObjectGuid::Empty);
instance->LoadGrid(-2023.0f, 7121.0f); instance->LoadGrid(-2023.0f, 7121.0f);
if (Creature* medivh = instance->GetCreature(_medivhGUID)) if (Creature* medivh = instance->GetCreature(_medivhGUID))
{ {
@@ -183,21 +187,48 @@ public:
} }
case TYPE_CHRONO_LORD_DEJA: case TYPE_CHRONO_LORD_DEJA:
case TYPE_TEMPORUS: 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; 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); Events.SetPhase(1);
SaveToDB(); SaveToDB();
_timerToNextBoss = (instance->IsHeroic() ? 300 : 150) * IN_MILLISECONDS;
break; break;
case DATA_RIFT_KILLED: }
if (!Events.IsInPhase(1))
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 4000);
break;
case DATA_MEDIVH: case DATA_MEDIVH:
{ {
DoUpdateWorldState(WORLD_STATE_BM, 1); DoUpdateWorldState(WORLD_STATE_BM, 1);
DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent); DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift); DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 3000); Events.RescheduleEvent(EVENT_NEXT_PORTAL, 3000);
_timerToNextBoss = (instance->IsHeroic() ? 300 : 150) * IN_MILLISECONDS;
for (ObjectGuid const& guid : encounterNPCs) for (ObjectGuid const& guid : encounterNPCs)
{ {
@@ -285,6 +316,34 @@ public:
encounterNPCs.insert(data); encounterNPCs.insert(data);
else if (type == DATA_DELETED_NPC) else if (type == DATA_DELETED_NPC)
encounterNPCs.erase(data); 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 ObjectGuid GetGuidData(uint32 data) const override
@@ -295,17 +354,11 @@ public:
return ObjectGuid::Empty; return ObjectGuid::Empty;
} }
void SummonPortalKeeper() void SummonPortalKeeper(uint32 eventId)
{ {
Creature* rift = nullptr; uint8 riftPosition = eventId - EVENT_SUMMON_KEEPER_1;
for (ObjectGuid const& guid : encounterNPCs) ObjectGuid const& riftGUID = _usedRiftPostions[riftPosition];
if (Creature* summon = instance->GetCreature(guid)) Creature* rift = instance->GetCreature(riftGUID);
if (summon->GetEntry() == NPC_TIME_RIFT)
{
rift = summon;
break;
}
if (!rift) if (!rift)
return; return;
@@ -348,23 +401,72 @@ public:
void Update(uint32 diff) override void Update(uint32 diff) override
{ {
if (_timerToNextBoss)
{
if (_timerToNextBoss <= diff)
{
_timerToNextBoss = 0;
}
else
{
_timerToNextBoss -= diff;
}
}
Events.Update(diff); Events.Update(diff);
switch (Events.ExecuteEvent())
uint32 eventId = Events.ExecuteEvent();
switch (eventId)
{ {
case EVENT_NEXT_PORTAL: case EVENT_NEXT_PORTAL:
++_currentRift; {
DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
Events.ScheduleEvent(EVENT_SUMMON_KEEPER, 6000);
Events.SetPhase(0);
if (instance->GetCreature(_medivhGUID)) if (instance->GetCreature(_medivhGUID))
{ {
uint8 position = (_currentRift - 1) % 4; uint8 position = MAX_PORTAL_LOCATIONS;
instance->SummonCreature(NPC_TIME_RIFT, PortalLocation[position]);
std::vector<uint8> 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; 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; break;
case EVENT_WIPE_1: case EVENT_WIPE_1:
if (Creature* medivh = instance->GetCreature(_medivhGUID)) if (Creature* medivh = instance->GetCreature(_medivhGUID))
@@ -433,6 +535,8 @@ public:
protected: protected:
EventMap Events; EventMap Events;
std::array<ObjectGuid, MAX_PORTAL_LOCATIONS> _usedRiftPostions;
uint32 _timerToNextBoss;
}; };
}; };
@@ -326,7 +326,7 @@ struct npc_time_rift : public NullCreatureAI
Creature* riftKeeper = ObjectAccessor::GetCreature(*me, _riftKeeperGUID); Creature* riftKeeper = ObjectAccessor::GetCreature(*me, _riftKeeperGUID);
if (!riftKeeper || !riftKeeper->IsAlive()) if (!riftKeeper || !riftKeeper->IsAlive())
{ {
_instance->SetData(DATA_RIFT_KILLED, 1); _instance->SetGuidData(DATA_RIFT_KILLED, me->GetGUID());
me->DespawnOrUnsummon(0); me->DespawnOrUnsummon(0);
break; break;
@@ -90,10 +90,13 @@ enum Misc
SPELL_TELEPORT_VISUAL = 7791, SPELL_TELEPORT_VISUAL = 7791,
EVENT_NEXT_PORTAL = 1, EVENT_NEXT_PORTAL = 1,
EVENT_SUMMON_KEEPER = 2, EVENT_SUMMON_KEEPER_1 = 2,
EVENT_WIPE_1 = 3, EVENT_SUMMON_KEEPER_2 = 3,
EVENT_WIPE_2 = 4, EVENT_SUMMON_KEEPER_3 = 4,
EVENT_WIPE_3 = 5, EVENT_SUMMON_KEEPER_4 = 5,
EVENT_WIPE_1 = 6,
EVENT_WIPE_2 = 7,
EVENT_WIPE_3 = 8,
ACTION_OUTRO = 1 ACTION_OUTRO = 1
}; };