mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-19 11:55:43 +00:00
fix(Scripts/BlackMorass): Improved Opening the Dark portal encounter. (#14861)
This commit is contained in:
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user