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

View File

@@ -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<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;
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<ObjectGuid, MAX_PORTAL_LOCATIONS> _usedRiftPostions;
uint32 _timerToNextBoss;
};
};

View File

@@ -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;

View File

@@ -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
};