|
|
|
|
@@ -15,9 +15,11 @@
|
|
|
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "GameEventMgr.h"
|
|
|
|
|
#include "MapMgr.h"
|
|
|
|
|
#include "Player.h"
|
|
|
|
|
#include "SharedDefines.h"
|
|
|
|
|
#include "Weather.h"
|
|
|
|
|
#include "WorldState.h"
|
|
|
|
|
|
|
|
|
|
WorldState* WorldState::instance()
|
|
|
|
|
@@ -37,6 +39,82 @@ WorldState::~WorldState()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::Load()
|
|
|
|
|
{
|
|
|
|
|
QueryResult result = CharacterDatabase.Query("SELECT Id, Data FROM world_state");
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
Field* fields = result->Fetch();
|
|
|
|
|
uint32 id = fields[0].Get<uint32>();
|
|
|
|
|
std::string data = fields[1].Get<std::string>();
|
|
|
|
|
std::istringstream loadStream(data);
|
|
|
|
|
|
|
|
|
|
switch (id)
|
|
|
|
|
{
|
|
|
|
|
case SAVE_ID_QUEL_DANAS:
|
|
|
|
|
{
|
|
|
|
|
if (data.size())
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
loadStream >> m_sunsReachData.m_phase >> m_sunsReachData.m_subphaseMask;
|
|
|
|
|
for (uint32 i = 0; i < COUNTERS_MAX; ++i)
|
|
|
|
|
loadStream >> m_sunsReachData.m_sunsReachReclamationCounters[i];
|
|
|
|
|
loadStream >> m_sunsReachData.m_gate;
|
|
|
|
|
for (uint32 i = 0; i < COUNTERS_MAX_GATES; ++i)
|
|
|
|
|
loadStream >> m_sunsReachData.m_gateCounters[i];
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
LOG_ERROR("scripts", "WorldState::Load: Exception reading SunsReach data {}", e.what());
|
|
|
|
|
m_sunsReachData.m_phase = 0;
|
|
|
|
|
m_sunsReachData.m_subphaseMask = 0;
|
|
|
|
|
memset(m_sunsReachData.m_sunsReachReclamationCounters, 0, sizeof(m_sunsReachData.m_sunsReachReclamationCounters));
|
|
|
|
|
m_sunsReachData.m_gate = SUNWELL_ALL_GATES_CLOSED;
|
|
|
|
|
memset(m_sunsReachData.m_gateCounters, 0, sizeof(m_sunsReachData.m_gateCounters));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_sunsReachData.m_phase = 0;
|
|
|
|
|
m_sunsReachData.m_subphaseMask = 0;
|
|
|
|
|
memset(m_sunsReachData.m_sunsReachReclamationCounters, 0, sizeof(m_sunsReachData.m_sunsReachReclamationCounters));
|
|
|
|
|
m_sunsReachData.m_gate = SUNWELL_ALL_GATES_CLOSED;
|
|
|
|
|
memset(m_sunsReachData.m_gateCounters, 0, sizeof(m_sunsReachData.m_gateCounters));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (result->NextRow());
|
|
|
|
|
}
|
|
|
|
|
StartSunsReachPhase(true);
|
|
|
|
|
StartSunwellGatePhase();
|
|
|
|
|
HandleSunsReachSubPhaseTransition(m_sunsReachData.m_subphaseMask, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::Save(WorldStateSaveIds saveId)
|
|
|
|
|
{
|
|
|
|
|
switch (saveId)
|
|
|
|
|
{
|
|
|
|
|
case SAVE_ID_QUEL_DANAS:
|
|
|
|
|
{
|
|
|
|
|
std::string expansionData = m_sunsReachData.GetData();
|
|
|
|
|
SaveHelper(expansionData, SAVE_ID_QUEL_DANAS);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::SaveHelper(std::string& stringToSave, WorldStateSaveIds saveId)
|
|
|
|
|
{
|
|
|
|
|
CharacterDatabase.Execute("DELETE FROM world_state WHERE Id='{}'", saveId);
|
|
|
|
|
CharacterDatabase.Execute("INSERT INTO world_state(Id,Data) VALUES('{}','{}')", saveId, stringToSave.data());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WorldState::IsConditionFulfilled(WorldStateCondition conditionId, WorldStateConditionState state) const
|
|
|
|
|
{
|
|
|
|
|
switch (conditionId)
|
|
|
|
|
@@ -140,6 +218,16 @@ void WorldState::HandlePlayerEnterZone(Player* player, WorldStateZoneId zoneId)
|
|
|
|
|
else if (_isMagtheridonHeadSpawnedHorde && player->GetTeamId() == TEAM_HORDE)
|
|
|
|
|
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
|
|
|
|
break;
|
|
|
|
|
case ZONEID_ISLE_OF_QUEL_DANAS:
|
|
|
|
|
case ZONEID_MAGISTERS_TERRACE:
|
|
|
|
|
case ZONEID_SUNWELL_PLATEAU:
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> guard(m_sunsReachData.m_sunsReachReclamationMutex);
|
|
|
|
|
m_sunsReachData.m_sunsReachReclamationPlayers.push_back(player->GetGUID());
|
|
|
|
|
if (m_sunsReachData.m_subphaseMask == SUBPHASE_ALL)
|
|
|
|
|
player->CastSpell(player, SPELL_KIRU_SONG_OF_VICTORY, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -167,6 +255,17 @@ void WorldState::HandlePlayerLeaveZone(Player* player, WorldStateZoneId zoneId)
|
|
|
|
|
else if (player->GetTeamId() == TEAM_HORDE)
|
|
|
|
|
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
|
|
|
|
break;
|
|
|
|
|
case ZONEID_ISLE_OF_QUEL_DANAS:
|
|
|
|
|
case ZONEID_MAGISTERS_TERRACE:
|
|
|
|
|
case ZONEID_SUNWELL_PLATEAU:
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> guard(m_sunsReachData.m_sunsReachReclamationMutex);
|
|
|
|
|
player->RemoveAurasDueToSpell(SPELL_KIRU_SONG_OF_VICTORY);
|
|
|
|
|
auto position = std::find(m_sunsReachData.m_sunsReachReclamationPlayers.begin(), m_sunsReachData.m_sunsReachReclamationPlayers.end(), player->GetGUID());
|
|
|
|
|
if (position != m_sunsReachData.m_sunsReachReclamationPlayers.end())
|
|
|
|
|
m_sunsReachData.m_sunsReachReclamationPlayers.erase(position);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -291,3 +390,699 @@ void WorldState::DispelAdalsSongOfBattle()
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::SendWorldstateUpdate(std::mutex& mutex, GuidVector const& guids, uint32 value, uint32 worldStateId)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> guard(mutex);
|
|
|
|
|
for (ObjectGuid const& guid : guids)
|
|
|
|
|
if (Player* player = ObjectAccessor::FindPlayer(guid))
|
|
|
|
|
player->SendUpdateWorldState(worldStateId, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum WorldStateSunsReachQuests
|
|
|
|
|
{
|
|
|
|
|
QUEST_ERRATIC_BEHAVIOR = 11524,
|
|
|
|
|
QUEST_SANCTUM_WARDS = 11496,
|
|
|
|
|
QUEST_BATTLE_FOR_THE_SUNS_REACH_ARMORY = 11538,
|
|
|
|
|
QUEST_DISTRACTION_AT_THE_DEAD_SCAR = 11532,
|
|
|
|
|
QUEST_INTERCEPTING_THE_MANA_CELLS = 11513,
|
|
|
|
|
QUEST_INTERCEPT_THE_REINFORCEMENTS = 11542,
|
|
|
|
|
QUEST_TAKING_THE_HARBOR = 11539,
|
|
|
|
|
QUEST_MAKING_READY = 11535,
|
|
|
|
|
QUEST_DISCOVERING_YOUR_ROOTS = 11520,
|
|
|
|
|
QUEST_A_CHARITABLE_DONATION = 11545,
|
|
|
|
|
QUEST_A_MAGNANIMOUS_BENEFACTOR = 11549,
|
|
|
|
|
COUNTER_MAX_VAL_REQ = 10000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void WorldState::AddSunsReachProgress(uint32 questId)
|
|
|
|
|
{
|
|
|
|
|
uint32 counter = 0;
|
|
|
|
|
int32 otherCounter = -1;
|
|
|
|
|
int32 worldState = 0;
|
|
|
|
|
uint32 subPhaseMask = 0;
|
|
|
|
|
uint32 addedValue = 1;
|
|
|
|
|
switch (questId)
|
|
|
|
|
{
|
|
|
|
|
case QUEST_ERRATIC_BEHAVIOR:
|
|
|
|
|
counter = COUNTER_ERRATIC_BEHAVIOR;
|
|
|
|
|
otherCounter = COUNTER_SANCTUM_WARDS;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_SANCTUM;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_SANCTUM_WARDS:
|
|
|
|
|
counter = COUNTER_SANCTUM_WARDS;
|
|
|
|
|
otherCounter = COUNTER_SANCTUM_WARDS;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_SANCTUM;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_BATTLE_FOR_THE_SUNS_REACH_ARMORY:
|
|
|
|
|
counter = COUNTER_BATTLE_FOR_THE_SUNS_REACH_ARMORY;
|
|
|
|
|
otherCounter = COUNTER_DISTRACTION_AT_THE_DEAD_SCAR;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_ARMORY;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_DISTRACTION_AT_THE_DEAD_SCAR:
|
|
|
|
|
counter = COUNTER_DISTRACTION_AT_THE_DEAD_SCAR;
|
|
|
|
|
otherCounter = COUNTER_BATTLE_FOR_THE_SUNS_REACH_ARMORY;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_ARMORY;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_INTERCEPTING_THE_MANA_CELLS:
|
|
|
|
|
counter = COUNTER_INTERCEPTING_THE_MANA_CELLS;
|
|
|
|
|
subPhaseMask = SUBPHASE_PORTAL;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_PORTAL;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_INTERCEPT_THE_REINFORCEMENTS:
|
|
|
|
|
counter = COUNTER_INTERCEPT_THE_REINFORCEMENTS;
|
|
|
|
|
otherCounter = COUNTER_TAKING_THE_HARBOR;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_HARBOR;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_TAKING_THE_HARBOR:
|
|
|
|
|
counter = COUNTER_TAKING_THE_HARBOR;
|
|
|
|
|
otherCounter = COUNTER_INTERCEPT_THE_REINFORCEMENTS;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_HARBOR;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_MAKING_READY:
|
|
|
|
|
counter = COUNTER_MAKING_READY;
|
|
|
|
|
subPhaseMask = SUBPHASE_ANVIL;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_ANVIL;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_DISCOVERING_YOUR_ROOTS:
|
|
|
|
|
counter = COUNTER_DISCOVERING_YOUR_ROOTS;
|
|
|
|
|
subPhaseMask = SUBPHASE_ALCHEMY_LAB;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_ALCHEMY_LAB;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_A_CHARITABLE_DONATION:
|
|
|
|
|
counter = COUNTER_A_CHARITABLE_DONATION;
|
|
|
|
|
subPhaseMask = SUBPHASE_MONUMENT;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_MONUMENT;
|
|
|
|
|
break;
|
|
|
|
|
case QUEST_A_MAGNANIMOUS_BENEFACTOR:
|
|
|
|
|
counter = COUNTER_A_CHARITABLE_DONATION;
|
|
|
|
|
subPhaseMask = SUBPHASE_MONUMENT;
|
|
|
|
|
worldState = WORLD_STATE_QUEL_DANAS_MONUMENT;
|
|
|
|
|
addedValue = 150;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32 previousValue = 0;
|
|
|
|
|
uint32 newValue = 0;
|
|
|
|
|
|
|
|
|
|
if (!subPhaseMask)
|
|
|
|
|
previousValue = m_sunsReachData.GetPhasePercentage(m_sunsReachData.m_phase);
|
|
|
|
|
else
|
|
|
|
|
previousValue = m_sunsReachData.GetSubPhasePercentage(subPhaseMask);
|
|
|
|
|
m_sunsReachData.m_sunsReachReclamationCounters[counter] += addedValue;
|
|
|
|
|
if (!subPhaseMask)
|
|
|
|
|
newValue = m_sunsReachData.GetPhasePercentage(m_sunsReachData.m_phase);
|
|
|
|
|
else
|
|
|
|
|
newValue = m_sunsReachData.GetSubPhasePercentage(subPhaseMask);
|
|
|
|
|
if (previousValue != newValue)
|
|
|
|
|
SendWorldstateUpdate(m_sunsReachData.m_sunsReachReclamationMutex, m_sunsReachData.m_sunsReachReclamationPlayers, newValue, worldState);
|
|
|
|
|
|
|
|
|
|
bool save = true;
|
|
|
|
|
uint32 counterValue = m_sunsReachData.m_sunsReachReclamationCounters[counter];
|
|
|
|
|
uint32 modifier = 1;
|
|
|
|
|
if (otherCounter != -1)
|
|
|
|
|
{
|
|
|
|
|
modifier = 2;
|
|
|
|
|
counterValue += m_sunsReachData.m_sunsReachReclamationCounters[otherCounter];
|
|
|
|
|
}
|
|
|
|
|
if (counterValue >= sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX) * modifier)
|
|
|
|
|
{
|
|
|
|
|
save = false;
|
|
|
|
|
switch (questId)
|
|
|
|
|
{
|
|
|
|
|
case QUEST_ERRATIC_BEHAVIOR:
|
|
|
|
|
case QUEST_SANCTUM_WARDS:
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_phase == SUNS_REACH_PHASE_1_STAGING_AREA)
|
|
|
|
|
HandleSunsReachPhaseTransition(SUNS_REACH_PHASE_2_SANCTUM);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_BATTLE_FOR_THE_SUNS_REACH_ARMORY:
|
|
|
|
|
case QUEST_DISTRACTION_AT_THE_DEAD_SCAR:
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_phase == SUNS_REACH_PHASE_2_SANCTUM)
|
|
|
|
|
HandleSunsReachPhaseTransition(SUNS_REACH_PHASE_3_ARMORY);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_INTERCEPTING_THE_MANA_CELLS:
|
|
|
|
|
{
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_PORTAL) == 0)
|
|
|
|
|
HandleSunsReachSubPhaseTransition(SUBPHASE_PORTAL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_INTERCEPT_THE_REINFORCEMENTS:
|
|
|
|
|
case QUEST_TAKING_THE_HARBOR:
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_phase == SUNS_REACH_PHASE_3_ARMORY)
|
|
|
|
|
HandleSunsReachPhaseTransition(SUNS_REACH_PHASE_4_HARBOR);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_MAKING_READY:
|
|
|
|
|
{
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ANVIL) == 0)
|
|
|
|
|
HandleSunsReachSubPhaseTransition(SUBPHASE_ANVIL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_DISCOVERING_YOUR_ROOTS:
|
|
|
|
|
{
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ALCHEMY_LAB) == 0)
|
|
|
|
|
HandleSunsReachSubPhaseTransition(SUBPHASE_ALCHEMY_LAB);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_A_CHARITABLE_DONATION:
|
|
|
|
|
case QUEST_A_MAGNANIMOUS_BENEFACTOR:
|
|
|
|
|
{
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_MONUMENT) == 0)
|
|
|
|
|
HandleSunsReachSubPhaseTransition(SUBPHASE_MONUMENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (save)
|
|
|
|
|
Save(SAVE_ID_QUEL_DANAS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::HandleSunsReachPhaseTransition(uint32 newPhase)
|
|
|
|
|
{
|
|
|
|
|
if (newPhase < m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
while (newPhase != m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
StopSunsReachPhase(newPhase > m_sunsReachData.m_phase);
|
|
|
|
|
--m_sunsReachData.m_phase;
|
|
|
|
|
}
|
|
|
|
|
StartSunsReachPhase();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
StopSunsReachPhase(newPhase > m_sunsReachData.m_phase);
|
|
|
|
|
bool moreThanOne = newPhase > m_sunsReachData.m_phase + 1; // custom command case
|
|
|
|
|
m_sunsReachData.m_phase = newPhase;
|
|
|
|
|
StartSunsReachPhase(moreThanOne);
|
|
|
|
|
}
|
|
|
|
|
switch (m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
case SUNS_REACH_PHASE_2_SANCTUM: if ((m_sunsReachData.m_subphaseMask & SUBPHASE_PORTAL) == 0) sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_NO_PORTAL); break;
|
|
|
|
|
case SUNS_REACH_PHASE_3_ARMORY: if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ANVIL) == 0) sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_NO_ANVIL); break;
|
|
|
|
|
case SUNS_REACH_PHASE_4_HARBOR:
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ALCHEMY_LAB) == 0) sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_4_NO_MONUMENT);
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_MONUMENT) == 0) sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_4_NO_ALCHEMY_LAB);
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
SendWorldstateUpdate(m_sunsReachData.m_sunsReachReclamationMutex, m_sunsReachData.m_sunsReachReclamationPlayers, m_sunsReachData.m_phase, WORLD_STATE_QUEL_DANAS_MUSIC);
|
|
|
|
|
Save(SAVE_ID_QUEL_DANAS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::HandleSunsReachSubPhaseTransition(int32 subPhaseMask, bool initial)
|
|
|
|
|
{
|
|
|
|
|
bool start = true;
|
|
|
|
|
if (subPhaseMask < 0)
|
|
|
|
|
{
|
|
|
|
|
start = false;
|
|
|
|
|
subPhaseMask = -subPhaseMask;
|
|
|
|
|
}
|
|
|
|
|
bool all = false;
|
|
|
|
|
if (start)
|
|
|
|
|
{
|
|
|
|
|
m_sunsReachData.m_subphaseMask |= subPhaseMask;
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ALL) == SUBPHASE_ALL)
|
|
|
|
|
all = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ALL) == SUBPHASE_ALL)
|
|
|
|
|
all = true;
|
|
|
|
|
m_sunsReachData.m_subphaseMask &= ~subPhaseMask;
|
|
|
|
|
}
|
|
|
|
|
if (initial)
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_phase >= SUNS_REACH_PHASE_2_SANCTUM)
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_PORTAL) == 0)
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_NO_PORTAL);
|
|
|
|
|
if (m_sunsReachData.m_phase >= SUNS_REACH_PHASE_3_ARMORY)
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_ANVIL) == 0)
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_NO_ANVIL);
|
|
|
|
|
if (m_sunsReachData.m_phase >= SUNS_REACH_PHASE_4_HARBOR)
|
|
|
|
|
{
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_ALCHEMY_LAB) == 0)
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_4_NO_ALCHEMY_LAB);
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_MONUMENT) == 0)
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_4_NO_MONUMENT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_PORTAL))
|
|
|
|
|
{
|
|
|
|
|
uint32 first = GAME_EVENT_QUEL_DANAS_PHASE_2_NO_PORTAL;
|
|
|
|
|
uint32 second = GAME_EVENT_QUEL_DANAS_PHASE_2_PORTAL;
|
|
|
|
|
if (start)
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(first);
|
|
|
|
|
sGameEventMgr->StartEvent(second);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(second);
|
|
|
|
|
sGameEventMgr->StartEvent(first);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_ANVIL))
|
|
|
|
|
{
|
|
|
|
|
uint32 first = GAME_EVENT_QUEL_DANAS_PHASE_3_NO_ANVIL;
|
|
|
|
|
uint32 second = GAME_EVENT_QUEL_DANAS_PHASE_3_ANVIL;
|
|
|
|
|
if (start)
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(first);
|
|
|
|
|
sGameEventMgr->StartEvent(second);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(second);
|
|
|
|
|
sGameEventMgr->StartEvent(first);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_ALCHEMY_LAB))
|
|
|
|
|
{
|
|
|
|
|
uint32 first = GAME_EVENT_QUEL_DANAS_PHASE_4_NO_ALCHEMY_LAB;
|
|
|
|
|
uint32 second = GAME_EVENT_QUEL_DANAS_PHASE_4_ALCHEMY_LAB;
|
|
|
|
|
if (start)
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(first);
|
|
|
|
|
sGameEventMgr->StartEvent(second);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(second);
|
|
|
|
|
sGameEventMgr->StartEvent(first);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((subPhaseMask & SUBPHASE_MONUMENT))
|
|
|
|
|
{
|
|
|
|
|
uint32 first = GAME_EVENT_QUEL_DANAS_PHASE_4_NO_MONUMENT;
|
|
|
|
|
uint32 second = GAME_EVENT_QUEL_DANAS_PHASE_4_MONUMENT;
|
|
|
|
|
if (start)
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(first);
|
|
|
|
|
sGameEventMgr->StartEvent(second);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StopEvent(second);
|
|
|
|
|
sGameEventMgr->StartEvent(first);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (all)
|
|
|
|
|
{
|
|
|
|
|
if (start)
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_4_KIRU);
|
|
|
|
|
else
|
|
|
|
|
sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_4_KIRU);
|
|
|
|
|
|
|
|
|
|
if (!initial)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> guard(m_sunsReachData.m_sunsReachReclamationMutex);
|
|
|
|
|
for (ObjectGuid& guid : m_sunsReachData.m_sunsReachReclamationPlayers)
|
|
|
|
|
if (Player* player = ObjectAccessor::FindPlayer(guid))
|
|
|
|
|
{
|
|
|
|
|
if (start)
|
|
|
|
|
player->CastSpell(player, SPELL_KIRU_SONG_OF_VICTORY, true);
|
|
|
|
|
else
|
|
|
|
|
player->RemoveAurasDueToSpell(SPELL_KIRU_SONG_OF_VICTORY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!initial)
|
|
|
|
|
Save(SAVE_ID_QUEL_DANAS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::HandleSunwellGateTransition(uint32 newGate)
|
|
|
|
|
{
|
|
|
|
|
if (newGate < m_sunsReachData.m_gate)
|
|
|
|
|
{
|
|
|
|
|
while (newGate != m_sunsReachData.m_gate)
|
|
|
|
|
{
|
|
|
|
|
StopSunwellGatePhase();
|
|
|
|
|
--m_sunsReachData.m_gate;
|
|
|
|
|
}
|
|
|
|
|
StartSunwellGatePhase();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
StopSunwellGatePhase();
|
|
|
|
|
m_sunsReachData.m_gate = newGate;
|
|
|
|
|
StartSunwellGatePhase();
|
|
|
|
|
}
|
|
|
|
|
int32 worldState = 0;
|
|
|
|
|
switch (newGate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN: worldState = WORLD_STATE_AGAMATH_THE_FIRST_GATE_HEALTH; break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN: worldState = WORLD_STATE_ROHENDOR_THE_SECOND_GATE_HEALTH; break;
|
|
|
|
|
case SUNWELL_ARCHONISUS_GATE3_OPEN: worldState = WORLD_STATE_ARCHONISUS_THE_FINAL_GATE_HEALTH; break;
|
|
|
|
|
}
|
|
|
|
|
if (worldState)
|
|
|
|
|
SendWorldstateUpdate(m_sunsReachData.m_sunsReachReclamationMutex, m_sunsReachData.m_sunsReachReclamationPlayers, m_sunsReachData.m_gate, worldState);
|
|
|
|
|
|
|
|
|
|
Save(SAVE_ID_QUEL_DANAS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::SetSunsReachCounter(SunsReachCounters index, uint32 value)
|
|
|
|
|
{
|
|
|
|
|
m_sunsReachData.m_sunsReachReclamationCounters[index] = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::StopSunsReachPhase(bool forward)
|
|
|
|
|
{
|
|
|
|
|
switch (m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
case SUNS_REACH_PHASE_1_STAGING_AREA: sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_1); break;
|
|
|
|
|
case SUNS_REACH_PHASE_2_SANCTUM: sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_ONLY); if (!forward) sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_PERMANENT); break;
|
|
|
|
|
case SUNS_REACH_PHASE_3_ARMORY: sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_ONLY); if (!forward) sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_PERMANENT); break;
|
|
|
|
|
case SUNS_REACH_PHASE_4_HARBOR: sGameEventMgr->StopEvent(GAME_EVENT_QUEL_DANAS_PHASE_4); break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::StartSunsReachPhase(bool initial)
|
|
|
|
|
{
|
|
|
|
|
switch (m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
case SUNS_REACH_PHASE_1_STAGING_AREA:
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_1);
|
|
|
|
|
if (Map* map = sMapMgr->FindBaseNonInstanceMap(530))
|
|
|
|
|
map->SetZoneWeather(ZONEID_ISLE_OF_QUEL_DANAS, WEATHER_STATE_MEDIUM_RAIN, 0.75f);
|
|
|
|
|
break;
|
|
|
|
|
case SUNS_REACH_PHASE_2_SANCTUM:
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_ONLY);
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_PERMANENT);
|
|
|
|
|
if (Map* map = sMapMgr->FindBaseNonInstanceMap(530))
|
|
|
|
|
map->SetZoneWeather(ZONEID_ISLE_OF_QUEL_DANAS, WEATHER_STATE_LIGHT_RAIN, 0.5f);
|
|
|
|
|
break;
|
|
|
|
|
case SUNS_REACH_PHASE_3_ARMORY:
|
|
|
|
|
if (initial)
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_PERMANENT);
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_ONLY); sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_PERMANENT);
|
|
|
|
|
// TODO: Should be id 2 0.25f?
|
|
|
|
|
if (Map* map = sMapMgr->FindBaseNonInstanceMap(530))
|
|
|
|
|
map->SetZoneWeather(ZONEID_ISLE_OF_QUEL_DANAS, WEATHER_STATE_LIGHT_RAIN, 0.25f);
|
|
|
|
|
break;
|
|
|
|
|
case SUNS_REACH_PHASE_4_HARBOR:
|
|
|
|
|
if (initial)
|
|
|
|
|
{
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_2_PERMANENT);
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_3_PERMANENT);
|
|
|
|
|
}
|
|
|
|
|
sGameEventMgr->StartEvent(GAME_EVENT_QUEL_DANAS_PHASE_4);
|
|
|
|
|
if (Map* map = sMapMgr->FindBaseNonInstanceMap(530))
|
|
|
|
|
map->SetZoneWeather(ZONEID_ISLE_OF_QUEL_DANAS, WEATHER_STATE_FINE, 0.0f);
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string WorldState::GetSunsReachPrintout()
|
|
|
|
|
{
|
|
|
|
|
auto formatPhase = [this]() -> std::string {
|
|
|
|
|
std::string name;
|
|
|
|
|
switch (m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
case SUNS_REACH_PHASE_1_STAGING_AREA: name = "Phase 1: Staging Area"; break;
|
|
|
|
|
case SUNS_REACH_PHASE_2_SANCTUM: name = "Phase 2: Sanctum"; break;
|
|
|
|
|
case SUNS_REACH_PHASE_3_ARMORY: name = "Phase 3: Armory"; break;
|
|
|
|
|
case SUNS_REACH_PHASE_4_HARBOR: name = "Phase 4: Harbor"; break;
|
|
|
|
|
default: name = "Unknown"; break;
|
|
|
|
|
}
|
|
|
|
|
return "Phase: " + std::to_string(m_sunsReachData.m_phase) + " (" + name + ") " + std::to_string(m_sunsReachData.GetPhasePercentage(m_sunsReachData.m_phase)) + "%\n";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto formatSubPhase = [this](uint32 subPhase) -> std::string {
|
|
|
|
|
std::string name;
|
|
|
|
|
switch (subPhase)
|
|
|
|
|
{
|
|
|
|
|
case SUBPHASE_PORTAL: name = "Portal"; break;
|
|
|
|
|
case SUBPHASE_ANVIL: name = "Anvil"; break;
|
|
|
|
|
case SUBPHASE_ALCHEMY_LAB: name = "Alchemy Lab"; break;
|
|
|
|
|
case SUBPHASE_MONUMENT: name = "Monument"; break;
|
|
|
|
|
default: name = "Unknown"; break;
|
|
|
|
|
}
|
|
|
|
|
return name + ": " + (m_sunsReachData.m_subphaseMask & subPhase ? "100%" : std::to_string(m_sunsReachData.GetSubPhasePercentage(subPhase)) + "%");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto formatCounter = [](uint32 counter, uint32 value) -> std::string {
|
|
|
|
|
switch (counter)
|
|
|
|
|
{
|
|
|
|
|
case COUNTER_ERRATIC_BEHAVIOR:
|
|
|
|
|
return "Erratic Behavior: " + std::to_string(value) + " (counts towards Phase 2: Sanctum)";
|
|
|
|
|
case COUNTER_SANCTUM_WARDS:
|
|
|
|
|
return "Sanctum Wards: " + std::to_string(value) + " (counts towards Phase 2: Sanctum)";
|
|
|
|
|
case COUNTER_BATTLE_FOR_THE_SUNS_REACH_ARMORY:
|
|
|
|
|
return "Battle for the Sun's Reach Armory: " + std::to_string(value) + " (counts towards Phase 3: Armory)";
|
|
|
|
|
case COUNTER_DISTRACTION_AT_THE_DEAD_SCAR:
|
|
|
|
|
return "Distraction at the Dead Scar: " + std::to_string(value) + " (counts towards Phase 3: Armory)";
|
|
|
|
|
case COUNTER_INTERCEPTING_THE_MANA_CELLS:
|
|
|
|
|
return "Intercepting the Mana Cells: " + std::to_string(value) + " (counts towards Subphase: Portal)";
|
|
|
|
|
case COUNTER_INTERCEPT_THE_REINFORCEMENTS:
|
|
|
|
|
return "Intercept the Reinforcements: " + std::to_string(value) + " (counts towards Phase 4: Harbor)";
|
|
|
|
|
case COUNTER_TAKING_THE_HARBOR:
|
|
|
|
|
return "Taking the Harbor: " + std::to_string(value) + " (counts towards Phase 4: Harbor)";
|
|
|
|
|
case COUNTER_MAKING_READY:
|
|
|
|
|
return "Making Ready: " + std::to_string(value) + " (counts towards Subphase: Anvil)";
|
|
|
|
|
case COUNTER_DISCOVERING_YOUR_ROOTS:
|
|
|
|
|
return "Discovering Your Roots: " + std::to_string(value) + " (counts towards Subphase: Alchemy Lab)";
|
|
|
|
|
case COUNTER_A_CHARITABLE_DONATION:
|
|
|
|
|
return "A Charitable Donation: " + std::to_string(value) + " (counts towards Subphase: Monument)";
|
|
|
|
|
default:
|
|
|
|
|
return "Unknown: " + std::to_string(value) + " (Unknown goal)";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string output = formatPhase();
|
|
|
|
|
output += "Subphase mask: " + std::to_string(m_sunsReachData.m_subphaseMask) + "\n";
|
|
|
|
|
for (uint32 i = 0; i < 4; ++i)
|
|
|
|
|
{
|
|
|
|
|
uint32 subPhaseMask = 1 << i;
|
|
|
|
|
output += " " + formatSubPhase(subPhaseMask) + "\n";
|
|
|
|
|
}
|
|
|
|
|
output += "Counters:\n";
|
|
|
|
|
output += " Sunsreach.CounterMax = " + std::to_string(sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX)) + "\n";
|
|
|
|
|
for (uint32 i = 0; i < COUNTERS_MAX; ++i)
|
|
|
|
|
output += " " + std::to_string(i) + ". " + formatCounter(i, m_sunsReachData.m_sunsReachReclamationCounters[i]) + "\n";
|
|
|
|
|
|
|
|
|
|
// Sunwell Gates
|
|
|
|
|
auto formatGatePhase = [](uint32 gate) -> std::string {
|
|
|
|
|
switch (gate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_ALL_GATES_CLOSED: return "All Gates Closed"; break;
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN: return "Gate 1 Agamath Open"; break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN: return "Gate 2 Rohendar Open"; break;
|
|
|
|
|
case SUNWELL_ARCHONISUS_GATE3_OPEN: return "Gate 3 Archonisus Open"; break;
|
|
|
|
|
default: return "Unknown"; break;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
output += "Sunwell Plateau Gate Phase " + std::to_string(m_sunsReachData.m_gate) + " (" + formatGatePhase(m_sunsReachData.m_gate) + ")" + ":\n";
|
|
|
|
|
output += " 0. Gate 1 (Agamath): " + std::string(m_sunsReachData.m_gate >= SUNWELL_AGAMATH_GATE1_OPEN ? "Open " : "Closed ") + std::to_string(m_sunsReachData.m_sunsReachReclamationCounters[COUNTER_AGAMATH_THE_FIRST_GATE]) + " (" + std::to_string(m_sunsReachData.GetSunwellGatePercentage(SUNWELL_ALL_GATES_CLOSED)) + "%)\n";
|
|
|
|
|
output += " 1. Gate 2 (Rohendor): " + std::string(m_sunsReachData.m_gate >= SUNWELL_ROHENDOR_GATE2_OPEN ? "Open " : "Closed ") + std::to_string(m_sunsReachData.m_sunsReachReclamationCounters[COUNTER_ROHENDOR_THE_SECOND_GATE]) + " (" + std::to_string(m_sunsReachData.GetSunwellGatePercentage(SUNWELL_AGAMATH_GATE1_OPEN)) + "%)\n";
|
|
|
|
|
output += " 2. Gate 3 (Archonisus): " + std::string(m_sunsReachData.m_gate >= SUNWELL_ARCHONISUS_GATE3_OPEN ? "Open " : "Closed ") + std::to_string(m_sunsReachData.m_sunsReachReclamationCounters[COUNTER_ARCHONISUS_THE_FINAL_GATE]) + " (" + std::to_string(m_sunsReachData.GetSunwellGatePercentage(SUNWELL_ROHENDOR_GATE2_OPEN)) + "%)\n";
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string SunsReachReclamationData::GetData()
|
|
|
|
|
{
|
|
|
|
|
std::string output = std::to_string(m_phase) + " " + std::to_string(m_subphaseMask);
|
|
|
|
|
for (uint32 value : m_sunsReachReclamationCounters)
|
|
|
|
|
output += " " + std::to_string(value);
|
|
|
|
|
output += " " + std::to_string(m_gate);
|
|
|
|
|
for (uint32 value : m_gateCounters)
|
|
|
|
|
output += " " + std::to_string(value);
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32 SunsReachReclamationData::GetPhasePercentage(uint32 phase)
|
|
|
|
|
{
|
|
|
|
|
switch (phase)
|
|
|
|
|
{
|
|
|
|
|
case SUNS_REACH_PHASE_1_STAGING_AREA: return uint32((m_sunsReachReclamationCounters[COUNTER_ERRATIC_BEHAVIOR] + m_sunsReachReclamationCounters[COUNTER_SANCTUM_WARDS]) * 100 / (2 * sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX)));
|
|
|
|
|
case SUNS_REACH_PHASE_2_SANCTUM: return uint32((m_sunsReachReclamationCounters[COUNTER_BATTLE_FOR_THE_SUNS_REACH_ARMORY] + m_sunsReachReclamationCounters[COUNTER_DISTRACTION_AT_THE_DEAD_SCAR]) * 100 / (2 * sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX)));
|
|
|
|
|
case SUNS_REACH_PHASE_3_ARMORY: return uint32((m_sunsReachReclamationCounters[COUNTER_INTERCEPT_THE_REINFORCEMENTS] + m_sunsReachReclamationCounters[COUNTER_TAKING_THE_HARBOR]) * 100 / (2 * sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX)));
|
|
|
|
|
default: return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32 SunsReachReclamationData::GetSubPhasePercentage(uint32 subPhase)
|
|
|
|
|
{
|
|
|
|
|
switch (subPhase)
|
|
|
|
|
{
|
|
|
|
|
case SUBPHASE_PORTAL: return uint32(m_sunsReachReclamationCounters[COUNTER_INTERCEPTING_THE_MANA_CELLS] * 100 / sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX));
|
|
|
|
|
case SUBPHASE_ANVIL: return uint32(m_sunsReachReclamationCounters[COUNTER_MAKING_READY] * 100 / sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX));
|
|
|
|
|
case SUBPHASE_ALCHEMY_LAB: return uint32(m_sunsReachReclamationCounters[COUNTER_DISCOVERING_YOUR_ROOTS] * 100 / sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX));
|
|
|
|
|
case SUBPHASE_MONUMENT: return uint32(m_sunsReachReclamationCounters[COUNTER_A_CHARITABLE_DONATION] * 100 / sWorld->getIntConfig(CONFIG_SUNSREACH_COUNTER_MAX));
|
|
|
|
|
default: return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum WorldStateSunwellGateQuests
|
|
|
|
|
{
|
|
|
|
|
// Sunwell Plateau PTR progressive release gates
|
|
|
|
|
QUEST_AGAMATH_THE_FIRST_GATE = 11551,
|
|
|
|
|
QUEST_ROHENDOR_THE_SECOND_GATE = 11552,
|
|
|
|
|
QUEST_ARCHONISUS_THE_FINAL_GATE = 11553,
|
|
|
|
|
COUNTER_MAX_VAL_REQ_SWP_GATES = 80,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void WorldState::AddSunwellGateProgress(uint32 questId)
|
|
|
|
|
{
|
|
|
|
|
uint32 counter = 0;
|
|
|
|
|
int32 worldState = 0;
|
|
|
|
|
uint32 addedValue = 1;
|
|
|
|
|
switch (questId)
|
|
|
|
|
{
|
|
|
|
|
case QUEST_AGAMATH_THE_FIRST_GATE:
|
|
|
|
|
case QUEST_ROHENDOR_THE_SECOND_GATE:
|
|
|
|
|
case QUEST_ARCHONISUS_THE_FINAL_GATE:
|
|
|
|
|
break;
|
|
|
|
|
default: return;
|
|
|
|
|
}
|
|
|
|
|
switch (m_sunsReachData.m_gate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_ALL_GATES_CLOSED: counter = COUNTER_AGAMATH_THE_FIRST_GATE; worldState = WORLD_STATE_AGAMATH_THE_FIRST_GATE_HEALTH; break;
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN: counter = COUNTER_ROHENDOR_THE_SECOND_GATE; worldState = WORLD_STATE_ROHENDOR_THE_SECOND_GATE_HEALTH; break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN: counter = COUNTER_ARCHONISUS_THE_FINAL_GATE; worldState = WORLD_STATE_ARCHONISUS_THE_FINAL_GATE_HEALTH; break;
|
|
|
|
|
default: return;
|
|
|
|
|
}
|
|
|
|
|
uint32 previousValue = m_sunsReachData.GetSunwellGatePercentage(m_sunsReachData.m_gate);
|
|
|
|
|
uint32 newValue = 0;
|
|
|
|
|
m_sunsReachData.m_gateCounters[counter] += addedValue;
|
|
|
|
|
newValue = m_sunsReachData.GetSunwellGatePercentage(m_sunsReachData.m_gate);
|
|
|
|
|
if (previousValue != newValue)
|
|
|
|
|
SendWorldstateUpdate(m_sunsReachData.m_sunsReachReclamationMutex, m_sunsReachData.m_sunsReachReclamationPlayers, newValue, worldState);
|
|
|
|
|
bool save = true;
|
|
|
|
|
if (m_sunsReachData.m_gateCounters[counter] >= COUNTER_MAX_VAL_REQ_SWP_GATES)
|
|
|
|
|
{
|
|
|
|
|
save = false;
|
|
|
|
|
switch (questId)
|
|
|
|
|
{
|
|
|
|
|
case QUEST_AGAMATH_THE_FIRST_GATE:
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_gate == SUNWELL_ALL_GATES_CLOSED)
|
|
|
|
|
HandleSunwellGateTransition(SUNWELL_AGAMATH_GATE1_OPEN);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_ROHENDOR_THE_SECOND_GATE:
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_gate == SUNWELL_AGAMATH_GATE1_OPEN)
|
|
|
|
|
HandleSunwellGateTransition(SUNWELL_ROHENDOR_GATE2_OPEN);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case QUEST_ARCHONISUS_THE_FINAL_GATE:
|
|
|
|
|
{
|
|
|
|
|
if (m_sunsReachData.m_gate == SUNWELL_ROHENDOR_GATE2_OPEN)
|
|
|
|
|
HandleSunwellGateTransition(SUNWELL_ARCHONISUS_GATE3_OPEN);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (save)
|
|
|
|
|
Save(SAVE_ID_QUEL_DANAS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::SetSunwellGateCounter(SunwellGateCounters index, uint32 value)
|
|
|
|
|
{
|
|
|
|
|
m_sunsReachData.m_gateCounters[index] = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::StartSunwellGatePhase()
|
|
|
|
|
{
|
|
|
|
|
switch (m_sunsReachData.m_gate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_ALL_GATES_CLOSED: sGameEventMgr->StartEvent(GAME_EVENT_SWP_GATES_PHASE_0); break;
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN: sGameEventMgr->StartEvent(GAME_EVENT_SWP_GATES_PHASE_1); break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN: sGameEventMgr->StartEvent(GAME_EVENT_SWP_GATES_PHASE_2); break;
|
|
|
|
|
case SUNWELL_ARCHONISUS_GATE3_OPEN: sGameEventMgr->StartEvent(GAME_EVENT_SWP_GATES_PHASE_3); break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::StopSunwellGatePhase()
|
|
|
|
|
{
|
|
|
|
|
switch (m_sunsReachData.m_gate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_ALL_GATES_CLOSED: sGameEventMgr->StopEvent(GAME_EVENT_SWP_GATES_PHASE_0); break;
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN: sGameEventMgr->StopEvent(GAME_EVENT_SWP_GATES_PHASE_1); break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN: sGameEventMgr->StopEvent(GAME_EVENT_SWP_GATES_PHASE_2); break;
|
|
|
|
|
case SUNWELL_ARCHONISUS_GATE3_OPEN: sGameEventMgr->StopEvent(GAME_EVENT_SWP_GATES_PHASE_3); break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32 SunsReachReclamationData::GetSunwellGatePercentage(uint32 gate)
|
|
|
|
|
{
|
|
|
|
|
int32 percentage = 0;
|
|
|
|
|
switch (gate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_ALL_GATES_CLOSED:
|
|
|
|
|
percentage = 100 - int32(m_gateCounters[COUNTER_AGAMATH_THE_FIRST_GATE] * 100 / COUNTER_MAX_VAL_REQ_SWP_GATES);
|
|
|
|
|
break;
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN:
|
|
|
|
|
percentage = 100 - int32(m_gateCounters[COUNTER_ROHENDOR_THE_SECOND_GATE] * 100 / COUNTER_MAX_VAL_REQ_SWP_GATES);
|
|
|
|
|
break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN:
|
|
|
|
|
percentage = 100 - int32(m_gateCounters[COUNTER_ARCHONISUS_THE_FINAL_GATE] * 100 / COUNTER_MAX_VAL_REQ_SWP_GATES);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return percentage < 0 ? 0 : uint32(percentage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorldState::FillInitialWorldStates(ByteBuffer& data, uint32 zoneId, uint32 /*areaId*/)
|
|
|
|
|
{
|
|
|
|
|
switch (zoneId)
|
|
|
|
|
{
|
|
|
|
|
case ZONEID_ISLE_OF_QUEL_DANAS:
|
|
|
|
|
case ZONEID_MAGISTERS_TERRACE:
|
|
|
|
|
case ZONEID_SUNWELL_PLATEAU:
|
|
|
|
|
case ZONEID_SHATTRATH:
|
|
|
|
|
{
|
|
|
|
|
// Sunwell Reclamation
|
|
|
|
|
switch (m_sunsReachData.m_phase)
|
|
|
|
|
{
|
|
|
|
|
case SUNS_REACH_PHASE_1_STAGING_AREA:
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_SANCTUM << m_sunsReachData.GetPhasePercentage(m_sunsReachData.m_phase);
|
|
|
|
|
break;
|
|
|
|
|
case SUNS_REACH_PHASE_2_SANCTUM:
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_ARMORY << m_sunsReachData.GetPhasePercentage(m_sunsReachData.m_phase);
|
|
|
|
|
break;
|
|
|
|
|
case SUNS_REACH_PHASE_3_ARMORY:
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_HARBOR << m_sunsReachData.GetPhasePercentage(m_sunsReachData.m_phase);
|
|
|
|
|
break;
|
|
|
|
|
case SUNS_REACH_PHASE_4_HARBOR:
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_ALCHEMY_LAB) == 0)
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_ALCHEMY_LAB << m_sunsReachData.GetSubPhasePercentage(SUBPHASE_ALCHEMY_LAB);
|
|
|
|
|
if ((m_sunsReachData.m_subphaseMask & SUBPHASE_MONUMENT) == 0)
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_MONUMENT << m_sunsReachData.GetSubPhasePercentage(SUBPHASE_MONUMENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (m_sunsReachData.m_phase >= SUNS_REACH_PHASE_2_SANCTUM && (m_sunsReachData.m_subphaseMask & SUBPHASE_PORTAL) == 0)
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_PORTAL << m_sunsReachData.GetSubPhasePercentage(SUBPHASE_PORTAL);
|
|
|
|
|
if (m_sunsReachData.m_phase >= SUNS_REACH_PHASE_3_ARMORY && (m_sunsReachData.m_subphaseMask & SUBPHASE_ANVIL) == 0)
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_ANVIL << m_sunsReachData.GetSubPhasePercentage(SUBPHASE_ANVIL);
|
|
|
|
|
data << WORLD_STATE_QUEL_DANAS_MUSIC << m_sunsReachData.m_phase;
|
|
|
|
|
|
|
|
|
|
// Sunwell Gates
|
|
|
|
|
switch (m_sunsReachData.m_gate)
|
|
|
|
|
{
|
|
|
|
|
case SUNWELL_ALL_GATES_CLOSED:
|
|
|
|
|
data << WORLD_STATE_AGAMATH_THE_FIRST_GATE_HEALTH << m_sunsReachData.GetSunwellGatePercentage(m_sunsReachData.m_gate);
|
|
|
|
|
break;
|
|
|
|
|
case SUNWELL_AGAMATH_GATE1_OPEN:
|
|
|
|
|
data << WORLD_STATE_ROHENDOR_THE_SECOND_GATE_HEALTH << m_sunsReachData.GetSunwellGatePercentage(m_sunsReachData.m_gate);
|
|
|
|
|
break;
|
|
|
|
|
case SUNWELL_ROHENDOR_GATE2_OPEN:
|
|
|
|
|
data << WORLD_STATE_ARCHONISUS_THE_FINAL_GATE_HEALTH << m_sunsReachData.GetSunwellGatePercentage(m_sunsReachData.m_gate);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|