You've already forked OpenRCT2-Unity
mirror of
https://github.com/izzy2lost/OpenRCT2-Unity.git
synced 2026-03-10 12:38:22 -07:00
Merge pull request #21122 from ZehMatt/gamestate
Start centralizing all save related data in GameState_t
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
# include <memory>
|
||||
# include <openrct2/Context.h>
|
||||
# include <openrct2/Game.h>
|
||||
# include <openrct2/GameState.h>
|
||||
# include <openrct2/OpenRCT2.h>
|
||||
# include <openrct2/ParkImporter.h>
|
||||
# include <openrct2/core/String.hpp>
|
||||
@@ -253,7 +254,10 @@ namespace OpenRCT2::Scripting
|
||||
auto parkImporter = ParkImporter::Create(handle->HintPath);
|
||||
auto result = parkImporter->LoadFromStream(handle->Stream.get(), isScenario);
|
||||
objectMgr.LoadObjects(result.RequiredObjects);
|
||||
parkImporter->Import();
|
||||
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = GetGameState();
|
||||
parkImporter->Import(gameState);
|
||||
|
||||
auto old = gLoadKeepWindowsOpen;
|
||||
|
||||
|
||||
@@ -304,7 +304,9 @@ namespace OpenRCT2::Title
|
||||
auto& objectManager = GetContext()->GetObjectManager();
|
||||
objectManager.LoadObjects(result.RequiredObjects);
|
||||
|
||||
parkImporter->Import();
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = GetGameState();
|
||||
parkImporter->Import(gameState);
|
||||
MapAnimationAutoCreate();
|
||||
}
|
||||
PrepareParkForPlayback();
|
||||
@@ -343,7 +345,10 @@ namespace OpenRCT2::Title
|
||||
auto& objectManager = GetContext()->GetObjectManager();
|
||||
objectManager.LoadObjects(result.RequiredObjects);
|
||||
|
||||
parkImporter->Import();
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = GetGameState();
|
||||
|
||||
parkImporter->Import(gameState);
|
||||
}
|
||||
PrepareParkForPlayback();
|
||||
success = true;
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <openrct2/world/Footpath.h>
|
||||
#include <openrct2/world/Park.h>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
static constexpr StringId WINDOW_TITLE = STR_STRINGID;
|
||||
static constexpr int32_t WH = 157;
|
||||
static constexpr int32_t WW = 192;
|
||||
@@ -1146,7 +1148,7 @@ private:
|
||||
int32_t guestEntryTime = peep->GetParkEntryTime();
|
||||
if (guestEntryTime != -1)
|
||||
{
|
||||
int32_t timeInPark = (gCurrentTicks - guestEntryTime) >> 11;
|
||||
int32_t timeInPark = (GetGameState().CurrentTicks - guestEntryTime) >> 11;
|
||||
auto ft = Formatter();
|
||||
ft.Add<uint16_t>(timeInPark & 0xFFFF);
|
||||
DrawTextBasic(dpi, screenCoords, STR_GUEST_STAT_TIME_IN_PARK, ft);
|
||||
@@ -1233,7 +1235,7 @@ private:
|
||||
}
|
||||
|
||||
// Every 2048 ticks do a full window_invalidate
|
||||
int32_t numTicks = gCurrentTicks - guest->GetParkEntryTime();
|
||||
int32_t numTicks = GetGameState().CurrentTicks - guest->GetParkEntryTime();
|
||||
if (!(numTicks & 0x7FF))
|
||||
Invalidate();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/GameState.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/entity/EntityRegistry.h>
|
||||
@@ -28,6 +29,8 @@
|
||||
#include <openrct2/world/Park.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
static constexpr StringId WINDOW_TITLE = STR_GUESTS;
|
||||
static constexpr int32_t WH = 330;
|
||||
static constexpr int32_t WW = 350;
|
||||
@@ -812,7 +815,7 @@ private:
|
||||
|
||||
bool IsRefreshOfGroupsRequired()
|
||||
{
|
||||
uint32_t tick256 = Floor2(gCurrentTicks, 256);
|
||||
uint32_t tick256 = Floor2(GetGameState().CurrentTicks, 256);
|
||||
if (_selectedView == _lastFindGroupsSelectedView)
|
||||
{
|
||||
if (_lastFindGroupsWait != 0 || _lastFindGroupsTick == tick256)
|
||||
@@ -839,7 +842,7 @@ private:
|
||||
|
||||
void RefreshGroups()
|
||||
{
|
||||
_lastFindGroupsTick = Floor2(gCurrentTicks, 256);
|
||||
_lastFindGroupsTick = Floor2(GetGameState().CurrentTicks, 256);
|
||||
_lastFindGroupsSelectedView = _selectedView;
|
||||
_lastFindGroupsWait = 320;
|
||||
_groups.clear();
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
#pragma region Widgets
|
||||
|
||||
static constexpr StringId WINDOW_TITLE = STR_NONE;
|
||||
@@ -264,6 +266,8 @@ static void Select(const char* path)
|
||||
char pathBuffer[MAX_PATH];
|
||||
SafeStrCpy(pathBuffer, path, sizeof(pathBuffer));
|
||||
|
||||
auto& gameState = GetGameState();
|
||||
|
||||
switch (_type & 0x0F)
|
||||
{
|
||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME):
|
||||
@@ -284,7 +288,7 @@ static void Select(const char* path)
|
||||
|
||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME):
|
||||
SetAndSaveConfigPath(gConfigGeneral.LastSaveGameDirectory, pathBuffer);
|
||||
if (ScenarioSave(pathBuffer, gConfigGeneral.SavePluginData ? 1 : 0))
|
||||
if (ScenarioSave(gameState, pathBuffer, gConfigGeneral.SavePluginData ? 1 : 0))
|
||||
{
|
||||
gScenarioSavePath = pathBuffer;
|
||||
gCurrentLoadedPath = pathBuffer;
|
||||
@@ -322,7 +326,7 @@ static void Select(const char* path)
|
||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE):
|
||||
SetAndSaveConfigPath(gConfigGeneral.LastSaveLandscapeDirectory, pathBuffer);
|
||||
gScenarioFileName = std::string(String::ToStringView(pathBuffer, std::size(pathBuffer)));
|
||||
if (ScenarioSave(pathBuffer, gConfigGeneral.SavePluginData ? 3 : 2))
|
||||
if (ScenarioSave(gameState, pathBuffer, gConfigGeneral.SavePluginData ? 3 : 2))
|
||||
{
|
||||
gCurrentLoadedPath = pathBuffer;
|
||||
WindowCloseByClass(WindowClass::Loadsave);
|
||||
@@ -343,7 +347,7 @@ static void Select(const char* path)
|
||||
gParkFlags &= ~PARK_FLAGS_SPRITES_INITIALISED;
|
||||
gEditorStep = EditorStep::Invalid;
|
||||
gScenarioFileName = std::string(String::ToStringView(pathBuffer, std::size(pathBuffer)));
|
||||
int32_t success = ScenarioSave(pathBuffer, gConfigGeneral.SavePluginData ? 3 : 2);
|
||||
int32_t success = ScenarioSave(gameState, pathBuffer, gConfigGeneral.SavePluginData ? 3 : 2);
|
||||
gParkFlags = parkFlagsBackup;
|
||||
|
||||
if (success)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <openrct2/Cheats.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/GameState.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/Limits.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
@@ -4661,7 +4662,7 @@ private:
|
||||
{
|
||||
colour_t spriteColour = COLOUR_BLACK;
|
||||
// Limit update rate of preview to avoid making people dizzy.
|
||||
if ((gCurrentTicks % 64) == 0)
|
||||
if ((GetGameState().CurrentTicks % 64) == 0)
|
||||
{
|
||||
spriteColour++;
|
||||
if (spriteColour >= COLOUR_NUM_NORMAL)
|
||||
|
||||
@@ -647,7 +647,11 @@ namespace OpenRCT2
|
||||
|
||||
GameUnloadScripts();
|
||||
_objectManager->LoadObjects(result.RequiredObjects);
|
||||
parkImporter->Import();
|
||||
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = ::GetGameState();
|
||||
parkImporter->Import(gameState);
|
||||
|
||||
gScenarioSavePath = path;
|
||||
gCurrentLoadedPath = path;
|
||||
gFirstTimeSaving = true;
|
||||
|
||||
@@ -282,7 +282,10 @@ namespace Editor
|
||||
auto importer = ParkImporter::CreateParkFile(context->GetObjectRepository());
|
||||
auto loadResult = importer->Load(path);
|
||||
objManager.LoadObjects(loadResult.RequiredObjects);
|
||||
importer->Import();
|
||||
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = GetGameState();
|
||||
importer->Import(gameState);
|
||||
|
||||
AfterLoadCleanup(true);
|
||||
return true;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Context.h"
|
||||
#include "Editor.h"
|
||||
#include "FileClassifier.h"
|
||||
#include "GameState.h"
|
||||
#include "GameStateSnapshots.h"
|
||||
#include "Input.h"
|
||||
#include "OpenRCT2.h"
|
||||
@@ -74,6 +75,8 @@
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
uint16_t gCurrentDeltaTime;
|
||||
uint8_t gGamePaused = 0;
|
||||
int32_t gGameSpeed = 1;
|
||||
@@ -87,7 +90,6 @@ bool gIsAutosaveLoaded = false;
|
||||
|
||||
bool gLoadKeepWindowsOpen = false;
|
||||
|
||||
uint32_t gCurrentTicks;
|
||||
uint32_t gCurrentRealTimeTicks;
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
@@ -639,7 +641,9 @@ void SaveGameCmd(u8string_view name /* = {} */)
|
||||
void SaveGameWithName(u8string_view name)
|
||||
{
|
||||
LOG_VERBOSE("Saving to %s", u8string(name).c_str());
|
||||
if (ScenarioSave(name, gConfigGeneral.SavePluginData ? 1 : 0))
|
||||
|
||||
auto& gameState = GetGameState();
|
||||
if (ScenarioSave(gameState, name, gConfigGeneral.SavePluginData ? 1 : 0))
|
||||
{
|
||||
LOG_VERBOSE("Saved to %s", u8string(name).c_str());
|
||||
gCurrentLoadedPath = name;
|
||||
@@ -761,7 +765,9 @@ void GameAutosave()
|
||||
File::Copy(path, backupPath, true);
|
||||
}
|
||||
|
||||
if (!ScenarioSave(path, saveFlags))
|
||||
auto& gameState = GetGameState();
|
||||
|
||||
if (!ScenarioSave(gameState, path, saveFlags))
|
||||
Console::Error::WriteLine("Could not autosave the scenario. Is the save folder writeable?");
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,6 @@ enum
|
||||
ERROR_TYPE_FILE_LOAD = 255
|
||||
};
|
||||
|
||||
extern uint32_t gCurrentTicks;
|
||||
extern uint32_t gCurrentRealTimeTicks;
|
||||
|
||||
extern uint16_t gCurrentDeltaTime;
|
||||
|
||||
@@ -50,6 +50,16 @@
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Scripting;
|
||||
|
||||
static GameState_t _gameState{};
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
GameState_t& GetGameState()
|
||||
{
|
||||
return _gameState;
|
||||
}
|
||||
} // namespace OpenRCT2
|
||||
|
||||
GameState::GameState()
|
||||
{
|
||||
_park = std::make_unique<Park>();
|
||||
@@ -63,7 +73,7 @@ void GameState::InitAll(const TileCoordsXY& mapSize)
|
||||
PROFILED_FUNCTION();
|
||||
|
||||
gInMapInitCode = true;
|
||||
gCurrentTicks = 0;
|
||||
GetGameState().CurrentTicks = 0;
|
||||
|
||||
MapInit(mapSize);
|
||||
_park->Initialise();
|
||||
@@ -130,7 +140,7 @@ void GameState::Tick()
|
||||
if (NetworkGetMode() == NETWORK_MODE_CLIENT && NetworkGetStatus() == NETWORK_STATUS_CONNECTED
|
||||
&& NetworkGetAuthstatus() == NetworkAuth::Ok)
|
||||
{
|
||||
numUpdates = std::clamp<uint32_t>(NetworkGetServerTick() - gCurrentTicks, 0, 10);
|
||||
numUpdates = std::clamp<uint32_t>(NetworkGetServerTick() - GetGameState().CurrentTicks, 0, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -280,7 +290,7 @@ void GameState::UpdateLogic()
|
||||
else if (NetworkGetMode() == NETWORK_MODE_CLIENT)
|
||||
{
|
||||
// Don't run past the server, this condition can happen during map changes.
|
||||
if (NetworkGetServerTick() == gCurrentTicks)
|
||||
if (NetworkGetServerTick() == GetGameState().CurrentTicks)
|
||||
{
|
||||
gInUpdateCode = false;
|
||||
return;
|
||||
@@ -352,7 +362,7 @@ void GameState::UpdateLogic()
|
||||
NetworkProcessPending();
|
||||
NetworkFlush();
|
||||
|
||||
gCurrentTicks++;
|
||||
GetGameState().CurrentTicks++;
|
||||
gSavedAge++;
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
@@ -376,7 +386,7 @@ void GameState::CreateStateSnapshot()
|
||||
|
||||
auto& snapshot = snapshots->CreateSnapshot();
|
||||
snapshots->Capture(snapshot);
|
||||
snapshots->LinkSnapshot(snapshot, gCurrentTicks, ScenarioRandState().s0);
|
||||
snapshots->LinkSnapshot(snapshot, GetGameState().CurrentTicks, ScenarioRandState().s0);
|
||||
}
|
||||
|
||||
void GameState::SetDate(Date newDate)
|
||||
|
||||
@@ -21,6 +21,13 @@ namespace OpenRCT2
|
||||
{
|
||||
class Park;
|
||||
|
||||
struct GameState_t
|
||||
{
|
||||
uint32_t CurrentTicks{};
|
||||
};
|
||||
|
||||
GameState_t& GetGameState();
|
||||
|
||||
/**
|
||||
* Class to update the state of the map and park.
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,8 @@ struct IObjectRepository;
|
||||
namespace OpenRCT2
|
||||
{
|
||||
struct IStream;
|
||||
}
|
||||
struct GameState_t;
|
||||
} // namespace OpenRCT2
|
||||
|
||||
struct ScenarioIndexEntry;
|
||||
|
||||
@@ -56,7 +57,7 @@ public:
|
||||
virtual ParkLoadResult LoadFromStream(
|
||||
OpenRCT2::IStream* stream, bool isScenario, bool skipObjectCheck = false, const u8string& path = {}) abstract;
|
||||
|
||||
virtual void Import() abstract;
|
||||
virtual void Import(OpenRCT2::GameState_t& gameState) abstract;
|
||||
virtual bool GetDetails(ScenarioIndexEntry* dst) abstract;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "Context.h"
|
||||
#include "Game.h"
|
||||
#include "GameState.h"
|
||||
#include "GameStateSnapshots.h"
|
||||
#include "OpenRCT2.h"
|
||||
#include "ParkImporter.h"
|
||||
@@ -145,7 +146,7 @@ namespace OpenRCT2
|
||||
|
||||
auto ga = GameActions::Clone(action);
|
||||
|
||||
_currentRecording->commands.emplace(gCurrentTicks, std::move(ga), _commandId++);
|
||||
_currentRecording->commands.emplace(tick, std::move(ga), _commandId++);
|
||||
}
|
||||
|
||||
void AddChecksum(uint32_t tick, EntitiesChecksum&& checksum)
|
||||
@@ -159,17 +160,19 @@ namespace OpenRCT2
|
||||
if (_mode == ReplayMode::NONE)
|
||||
return;
|
||||
|
||||
if ((_mode == ReplayMode::RECORDING || _mode == ReplayMode::NORMALISATION) && gCurrentTicks == _nextChecksumTick)
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
if ((_mode == ReplayMode::RECORDING || _mode == ReplayMode::NORMALISATION) && currentTicks == _nextChecksumTick)
|
||||
{
|
||||
EntitiesChecksum checksum = GetAllEntitiesChecksum();
|
||||
AddChecksum(gCurrentTicks, std::move(checksum));
|
||||
AddChecksum(currentTicks, std::move(checksum));
|
||||
|
||||
_nextChecksumTick = gCurrentTicks + ChecksumTicksDelta();
|
||||
_nextChecksumTick = currentTicks + ChecksumTicksDelta();
|
||||
}
|
||||
|
||||
if (_mode == ReplayMode::RECORDING)
|
||||
{
|
||||
if (gCurrentTicks >= _currentRecording->tickEnd)
|
||||
if (currentTicks >= _currentRecording->tickEnd)
|
||||
{
|
||||
StopRecording();
|
||||
return;
|
||||
@@ -185,7 +188,7 @@ namespace OpenRCT2
|
||||
ReplayCommands();
|
||||
|
||||
// Normal playback will always end at the specific tick.
|
||||
if (gCurrentTicks >= _currentReplay->tickEnd)
|
||||
if (currentTicks >= _currentReplay->tickEnd)
|
||||
{
|
||||
StopPlayback();
|
||||
return;
|
||||
@@ -214,7 +217,7 @@ namespace OpenRCT2
|
||||
|
||||
auto& snapshot = snapshots->CreateSnapshot();
|
||||
snapshots->Capture(snapshot);
|
||||
snapshots->LinkSnapshot(snapshot, gCurrentTicks, ScenarioRandState().s0);
|
||||
snapshots->LinkSnapshot(snapshot, GetGameState().CurrentTicks, ScenarioRandState().s0);
|
||||
DataSerialiser snapShotDs(true, snapshotStream);
|
||||
snapshots->SerialiseSnapshot(snapshot, snapShotDs);
|
||||
}
|
||||
@@ -230,14 +233,16 @@ namespace OpenRCT2
|
||||
if (_mode != ReplayMode::NONE && _mode != ReplayMode::NORMALISATION)
|
||||
return false;
|
||||
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
auto replayData = std::make_unique<ReplayRecordData>();
|
||||
replayData->magic = ReplayMagic;
|
||||
replayData->version = ReplayVersion;
|
||||
replayData->networkId = NetworkGetVersion();
|
||||
replayData->name = name;
|
||||
replayData->tickStart = gCurrentTicks;
|
||||
replayData->tickStart = currentTicks;
|
||||
if (maxTicks != k_MaxReplayTicks)
|
||||
replayData->tickEnd = gCurrentTicks + maxTicks;
|
||||
replayData->tickEnd = currentTicks + maxTicks;
|
||||
else
|
||||
replayData->tickEnd = k_MaxReplayTicks;
|
||||
|
||||
@@ -247,9 +252,10 @@ namespace OpenRCT2
|
||||
auto& objManager = context->GetObjectManager();
|
||||
auto objects = objManager.GetPackableObjects();
|
||||
|
||||
auto& gameState = GetGameState();
|
||||
auto exporter = std::make_unique<ParkFileExporter>();
|
||||
exporter->ExportObjectsList = objects;
|
||||
exporter->Export(replayData->parkData);
|
||||
exporter->Export(gameState, replayData->parkData);
|
||||
|
||||
replayData->timeRecorded = std::chrono::seconds(std::time(nullptr)).count();
|
||||
|
||||
@@ -266,7 +272,7 @@ namespace OpenRCT2
|
||||
|
||||
_currentRecording = std::move(replayData);
|
||||
_recordType = rt;
|
||||
_nextChecksumTick = gCurrentTicks + 1;
|
||||
_nextChecksumTick = currentTicks + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -283,11 +289,13 @@ namespace OpenRCT2
|
||||
return true;
|
||||
}
|
||||
|
||||
_currentRecording->tickEnd = gCurrentTicks;
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
_currentRecording->tickEnd = currentTicks;
|
||||
|
||||
{
|
||||
EntitiesChecksum checksum = GetAllEntitiesChecksum();
|
||||
AddChecksum(gCurrentTicks, std::move(checksum));
|
||||
AddChecksum(currentTicks, std::move(checksum));
|
||||
}
|
||||
|
||||
TakeGameStateSnapshot(_currentRecording->gameStateSnapshots);
|
||||
@@ -366,7 +374,7 @@ namespace OpenRCT2
|
||||
info.Version = data->version;
|
||||
info.TimeRecorded = data->timeRecorded;
|
||||
if (_mode == ReplayMode::RECORDING)
|
||||
info.Ticks = gCurrentTicks - data->tickStart;
|
||||
info.Ticks = GetGameState().CurrentTicks - data->tickStart;
|
||||
else if (_mode == ReplayMode::PLAYING)
|
||||
info.Ticks = data->tickEnd - data->tickStart;
|
||||
info.NumCommands = static_cast<uint32_t>(data->commands.size());
|
||||
@@ -384,9 +392,11 @@ namespace OpenRCT2
|
||||
GameStateSnapshot_t& replaySnapshot = snapshots->CreateSnapshot();
|
||||
snapshots->SerialiseSnapshot(replaySnapshot, ds);
|
||||
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
auto& localSnapshot = snapshots->CreateSnapshot();
|
||||
snapshots->Capture(localSnapshot);
|
||||
snapshots->LinkSnapshot(localSnapshot, gCurrentTicks, ScenarioRandState().s0);
|
||||
snapshots->LinkSnapshot(localSnapshot, currentTicks, ScenarioRandState().s0);
|
||||
try
|
||||
{
|
||||
GameStateCompareData cmpData = snapshots->Compare(replaySnapshot, localSnapshot);
|
||||
@@ -402,7 +412,7 @@ namespace OpenRCT2
|
||||
std::string outputPath = GetContext()->GetPlatformEnvironment()->GetDirectoryPath(
|
||||
DIRBASE::USER, DIRID::LOG_DESYNCS);
|
||||
char uniqueFileName[128] = {};
|
||||
snprintf(uniqueFileName, sizeof(uniqueFileName), "replay_desync_%u.txt", gCurrentTicks);
|
||||
snprintf(uniqueFileName, sizeof(uniqueFileName), "replay_desync_%u.txt", currentTicks);
|
||||
|
||||
std::string outputFile = Path::Combine(outputPath, uniqueFileName);
|
||||
snapshots->LogCompareDataToFile(outputFile, cmpData);
|
||||
@@ -433,7 +443,7 @@ namespace OpenRCT2
|
||||
return false;
|
||||
}
|
||||
|
||||
gCurrentTicks = replayData->tickStart;
|
||||
GetGameState().CurrentTicks = replayData->tickStart;
|
||||
|
||||
LoadAndCompareSnapshot(replayData->gameStateSnapshots);
|
||||
|
||||
@@ -495,7 +505,7 @@ namespace OpenRCT2
|
||||
return false;
|
||||
}
|
||||
|
||||
_nextReplayTick = gCurrentTicks + 1;
|
||||
_nextReplayTick = GetGameState().CurrentTicks + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -526,7 +536,9 @@ namespace OpenRCT2
|
||||
auto loadResult = importer->LoadFromStream(&data.parkData, false);
|
||||
objManager.LoadObjects(loadResult.RequiredObjects);
|
||||
|
||||
importer->Import();
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = GetGameState();
|
||||
importer->Import(gameState);
|
||||
|
||||
EntityTweener::Get().Reset();
|
||||
|
||||
@@ -788,19 +800,21 @@ namespace OpenRCT2
|
||||
if (checksumIndex >= _currentReplay->checksums.size())
|
||||
return;
|
||||
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
const auto& savedChecksum = _currentReplay->checksums[checksumIndex];
|
||||
if (_currentReplay->checksums[checksumIndex].first == gCurrentTicks)
|
||||
if (_currentReplay->checksums[checksumIndex].first == currentTicks)
|
||||
{
|
||||
_currentReplay->checksumIndex++;
|
||||
|
||||
EntitiesChecksum checksum = GetAllEntitiesChecksum();
|
||||
if (savedChecksum.second.raw != checksum.raw)
|
||||
{
|
||||
uint32_t replayTick = gCurrentTicks - _currentReplay->tickStart;
|
||||
uint32_t replayTick = currentTicks - _currentReplay->tickStart;
|
||||
|
||||
// Detected different game state.
|
||||
LOG_WARNING(
|
||||
"Different sprite checksum at tick %u (Replay Tick: %u) ; Saved: %s, Current: %s", gCurrentTicks,
|
||||
"Different sprite checksum at tick %u (Replay Tick: %u) ; Saved: %s, Current: %s", currentTicks,
|
||||
replayTick, savedChecksum.second.ToString().c_str(), checksum.ToString().c_str());
|
||||
|
||||
_faultyChecksumIndex = checksumIndex;
|
||||
@@ -809,8 +823,8 @@ namespace OpenRCT2
|
||||
{
|
||||
// Good state.
|
||||
LOG_VERBOSE(
|
||||
"Good state at tick %u ; Saved: %s, Current: %s", gCurrentTicks,
|
||||
savedChecksum.second.ToString().c_str(), checksum.ToString().c_str());
|
||||
"Good state at tick %u ; Saved: %s, Current: %s", currentTicks, savedChecksum.second.ToString().c_str(),
|
||||
checksum.ToString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -820,6 +834,8 @@ namespace OpenRCT2
|
||||
{
|
||||
auto& replayQueue = _currentReplay->commands;
|
||||
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
while (replayQueue.begin() != replayQueue.end())
|
||||
{
|
||||
const ReplayCommand& command = (*replayQueue.begin());
|
||||
@@ -827,16 +843,16 @@ namespace OpenRCT2
|
||||
if (_mode == ReplayMode::PLAYING)
|
||||
{
|
||||
// If this is a normal playback wait for the correct tick.
|
||||
if (command.tick != gCurrentTicks)
|
||||
if (command.tick != currentTicks)
|
||||
break;
|
||||
}
|
||||
else if (_mode == ReplayMode::NORMALISATION)
|
||||
{
|
||||
// Allow one entry per tick.
|
||||
if (gCurrentTicks != _nextReplayTick)
|
||||
if (currentTicks != _nextReplayTick)
|
||||
break;
|
||||
|
||||
_nextReplayTick = gCurrentTicks + 1;
|
||||
_nextReplayTick = currentTicks + 1;
|
||||
}
|
||||
|
||||
bool isPositionValid = false;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "GameAction.h"
|
||||
|
||||
#include "../Context.h"
|
||||
#include "../GameState.h"
|
||||
#include "../ReplayManager.h"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../core/Memory.hpp"
|
||||
@@ -101,7 +102,7 @@ namespace GameActions
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t currentTick = gCurrentTicks;
|
||||
const uint32_t currentTick = GetGameState().CurrentTicks;
|
||||
|
||||
while (_actionQueue.begin() != _actionQueue.end())
|
||||
{
|
||||
@@ -251,7 +252,7 @@ namespace GameActions
|
||||
|
||||
char temp[128] = {};
|
||||
snprintf(
|
||||
temp, sizeof(temp), "[%s] Tick: %u, GA: %s (%08X) (", GetRealm(), gCurrentTicks, action->GetName(),
|
||||
temp, sizeof(temp), "[%s] Tick: %u, GA: %s (%08X) (", GetRealm(), GetGameState().CurrentTicks, action->GetName(),
|
||||
EnumValue(action->GetType()));
|
||||
|
||||
output.Write(temp, strlen(temp));
|
||||
@@ -345,7 +346,7 @@ namespace GameActions
|
||||
if (!(actionFlags & GameActions::Flags::ClientOnly) && !(flags & GAME_COMMAND_FLAG_NETWORKED))
|
||||
{
|
||||
LOG_VERBOSE("[%s] GameAction::Execute %s (Queue)", GetRealm(), action->GetName());
|
||||
Enqueue(action, gCurrentTicks);
|
||||
Enqueue(action, GetGameState().CurrentTicks);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -415,7 +416,7 @@ namespace GameActions
|
||||
}
|
||||
if (recordAction)
|
||||
{
|
||||
replayManager->AddGameAction(gCurrentTicks, action);
|
||||
replayManager->AddGameAction(GetGameState().CurrentTicks, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "../Context.h"
|
||||
#include "../FileClassifier.h"
|
||||
#include "../GameState.h"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "../ParkImporter.h"
|
||||
#include "../common.h"
|
||||
@@ -22,6 +23,8 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
static void WriteConvertFromAndToMessage(FileExtension sourceFileType, FileExtension destinationFileType);
|
||||
static u8string GetFileTypeFriendlyName(FileExtension fileType);
|
||||
|
||||
@@ -98,7 +101,9 @@ exitcode_t CommandLine::HandleCommandConvert(CommandLineArgEnumerator* enumerato
|
||||
|
||||
objManager.LoadObjects(loadResult.RequiredObjects);
|
||||
|
||||
importer->Import();
|
||||
// TODO: Have a separate GameState and exchange once loaded.
|
||||
auto& gameState = GetGameState();
|
||||
importer->Import(gameState);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
@@ -120,7 +125,9 @@ exitcode_t CommandLine::HandleCommandConvert(CommandLineArgEnumerator* enumerato
|
||||
// correct initial view
|
||||
WindowCloseByClass(WindowClass::MainWindow);
|
||||
|
||||
exporter->Export(destinationPath);
|
||||
auto& gameState = GetGameState();
|
||||
|
||||
exporter->Export(gameState, destinationPath);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Weather.h"
|
||||
|
||||
#include "../Game.h"
|
||||
#include "../GameState.h"
|
||||
#include "../config/Config.h"
|
||||
#include "../interface/Viewport.h"
|
||||
#include "../ride/TrackDesign.h"
|
||||
@@ -83,15 +84,17 @@ void DrawWeather(DrawPixelInfo& dpi, IWeatherDrawer* weatherDrawer)
|
||||
static void DrawLightRain(
|
||||
DrawPixelInfo& dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
|
||||
{
|
||||
int32_t x_start = -static_cast<int32_t>(gCurrentTicks) + 8;
|
||||
int32_t y_start = (gCurrentTicks * 3) + 7;
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
int32_t x_start = -static_cast<int32_t>(currentTicks) + 8;
|
||||
int32_t y_start = (currentTicks * 3) + 7;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks) + 0x18;
|
||||
y_start = (gCurrentTicks * 4) + 0x0D;
|
||||
x_start = -static_cast<int32_t>(currentTicks) + 0x18;
|
||||
y_start = (currentTicks * 4) + 0x0D;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
@@ -105,29 +108,31 @@ static void DrawLightRain(
|
||||
static void DrawHeavyRain(
|
||||
DrawPixelInfo& dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
|
||||
{
|
||||
int32_t x_start = -static_cast<int32_t>(gCurrentTicks);
|
||||
int32_t y_start = gCurrentTicks * 5;
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
int32_t x_start = -static_cast<int32_t>(currentTicks);
|
||||
int32_t y_start = currentTicks * 5;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks) + 0x10;
|
||||
y_start = (gCurrentTicks * 6) + 5;
|
||||
x_start = -static_cast<int32_t>(currentTicks) + 0x10;
|
||||
y_start = (currentTicks * 6) + 5;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks) + 8;
|
||||
y_start = (gCurrentTicks * 3) + 7;
|
||||
x_start = -static_cast<int32_t>(currentTicks) + 8;
|
||||
y_start = (currentTicks * 3) + 7;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks) + 0x18;
|
||||
y_start = (gCurrentTicks * 4) + 0x0D;
|
||||
x_start = -static_cast<int32_t>(currentTicks) + 0x18;
|
||||
y_start = (currentTicks * 4) + 0x0D;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
@@ -137,9 +142,11 @@ static void DrawHeavyRain(
|
||||
static void DrawLightSnow(
|
||||
DrawPixelInfo& dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
|
||||
{
|
||||
const uint32_t t = gCurrentTicks / 2;
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
const uint32_t t = currentTicks / 2;
|
||||
const int32_t negT = -static_cast<int32_t>(t);
|
||||
const double cosTick = static_cast<double>(gCurrentTicks) * 0.05;
|
||||
const double cosTick = static_cast<double>(currentTicks) * 0.05;
|
||||
|
||||
int32_t x_start = negT + 1 + (cos(1.0 + cosTick) * 6);
|
||||
int32_t y_start = t + 1;
|
||||
@@ -159,29 +166,31 @@ static void DrawLightSnow(
|
||||
static void DrawHeavySnow(
|
||||
DrawPixelInfo& dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
|
||||
{
|
||||
int32_t x_start = -static_cast<int32_t>(gCurrentTicks * 3) + 1;
|
||||
int32_t y_start = gCurrentTicks + 23;
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
int32_t x_start = -static_cast<int32_t>(currentTicks * 3) + 1;
|
||||
int32_t y_start = currentTicks + 23;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks * 4) + 6;
|
||||
y_start = gCurrentTicks + 5;
|
||||
x_start = -static_cast<int32_t>(currentTicks * 4) + 6;
|
||||
y_start = currentTicks + 5;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks * 2) + 11;
|
||||
y_start = gCurrentTicks + 18;
|
||||
x_start = -static_cast<int32_t>(currentTicks * 2) + 11;
|
||||
y_start = currentTicks + 18;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
|
||||
|
||||
x_start = -static_cast<int32_t>(gCurrentTicks * 3) + 17;
|
||||
y_start = gCurrentTicks + 11;
|
||||
x_start = -static_cast<int32_t>(currentTicks * 3) + 17;
|
||||
y_start = currentTicks + 11;
|
||||
y_start = -y_start;
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Duck.h"
|
||||
|
||||
#include "../Game.h"
|
||||
#include "../GameState.h"
|
||||
#include "../audio/audio.h"
|
||||
#include "../core/DataSerialiser.h"
|
||||
#include "../localisation/Date.h"
|
||||
@@ -23,6 +24,8 @@
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
constexpr int32_t DUCK_MAX_STATES = 5;
|
||||
|
||||
// clang-format off
|
||||
@@ -88,7 +91,9 @@ void Duck::Remove()
|
||||
|
||||
void Duck::UpdateFlyToWater()
|
||||
{
|
||||
if ((gCurrentTicks & 3) != 0)
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
if ((currentTicks & 3) != 0)
|
||||
return;
|
||||
|
||||
frame++;
|
||||
@@ -150,7 +155,9 @@ void Duck::UpdateFlyToWater()
|
||||
|
||||
void Duck::UpdateSwim()
|
||||
{
|
||||
if (((gCurrentTicks + Id.ToUnderlying()) & 3) != 0)
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
if (((currentTicks + Id.ToUnderlying()) & 3) != 0)
|
||||
return;
|
||||
|
||||
uint32_t randomNumber = ScenarioRand();
|
||||
@@ -246,7 +253,7 @@ void Duck::UpdateDoubleDrink()
|
||||
|
||||
void Duck::UpdateFlyAway()
|
||||
{
|
||||
if ((gCurrentTicks & 3) == 0)
|
||||
if ((GetGameState().CurrentTicks & 3) == 0)
|
||||
{
|
||||
frame++;
|
||||
if (frame >= std::size(DuckAnimationFlyAway))
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Fountain.h"
|
||||
|
||||
#include "../Game.h"
|
||||
#include "../GameState.h"
|
||||
#include "../core/DataSerialiser.h"
|
||||
#include "../object/PathAdditionEntry.h"
|
||||
#include "../paint/Paint.h"
|
||||
@@ -21,6 +22,8 @@
|
||||
#include "../world/Scenery.h"
|
||||
#include "EntityRegistry.h"
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
enum class PATTERN
|
||||
{
|
||||
CYCLIC_SQUARES,
|
||||
@@ -86,11 +89,13 @@ template<> bool EntityBase::Is<JumpingFountain>() const
|
||||
|
||||
void JumpingFountain::StartAnimation(const JumpingFountainType newType, const CoordsXY& newLoc, const TileElement* tileElement)
|
||||
{
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
int32_t randomIndex;
|
||||
auto newZ = tileElement->GetBaseZ();
|
||||
|
||||
// Change pattern approximately every 51 seconds
|
||||
uint32_t pattern = (gCurrentTicks >> 11) & 7;
|
||||
uint32_t pattern = (currentTicks >> 11) & 7;
|
||||
switch (static_cast<PATTERN>(pattern))
|
||||
{
|
||||
case PATTERN::CYCLIC_SQUARES:
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "../Context.h"
|
||||
#include "../Game.h"
|
||||
#include "../GameState.h"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "../audio/audio.h"
|
||||
#include "../config/Config.h"
|
||||
@@ -899,7 +900,9 @@ void Guest::Loc68FA89()
|
||||
|
||||
void Guest::Tick128UpdateGuest(int32_t index)
|
||||
{
|
||||
if (static_cast<uint32_t>(index & 0x1FF) == (gCurrentTicks & 0x1FF))
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
if (static_cast<uint32_t>(index & 0x1FF) == (currentTicks & 0x1FF))
|
||||
{
|
||||
/* Effect of masking with 0x1FF here vs mask 0x7F,
|
||||
* which is the condition for calling this function, is
|
||||
@@ -1009,7 +1012,7 @@ void Guest::Tick128UpdateGuest(int32_t index)
|
||||
if (State == PeepState::Walking && !OutsideOfPark && !(PeepFlags & PEEP_FLAGS_LEAVING_PARK) && GuestNumRides == 0
|
||||
&& GuestHeadingToRideId.IsNull())
|
||||
{
|
||||
uint32_t time_duration = gCurrentTicks - ParkEntryTime;
|
||||
uint32_t time_duration = currentTicks - ParkEntryTime;
|
||||
time_duration /= 2048;
|
||||
|
||||
if (time_duration >= 5)
|
||||
@@ -1033,7 +1036,7 @@ void Guest::Tick128UpdateGuest(int32_t index)
|
||||
PickRideToGoOn();
|
||||
}
|
||||
|
||||
if (static_cast<uint32_t>(index & 0x3FF) == (gCurrentTicks & 0x3FF))
|
||||
if (static_cast<uint32_t>(index & 0x3FF) == (currentTicks & 0x3FF))
|
||||
{
|
||||
/* Effect of masking with 0x3FF here vs mask 0x1FF,
|
||||
* which is used in the encompassing conditional, is
|
||||
@@ -3559,12 +3562,14 @@ void PeepUpdateRideLeaveEntranceSpiralSlide(Guest* peep, Ride& ride, CoordsXYZD&
|
||||
|
||||
void PeepUpdateRideLeaveEntranceDefault(Guest* peep, Ride& ride, CoordsXYZD& entrance_loc)
|
||||
{
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
// If the ride type was changed guests will become stuck.
|
||||
// Inform the player about this if its a new issue or hasn't been addressed within 120 seconds.
|
||||
if ((ride.current_issues & RIDE_ISSUE_GUESTS_STUCK) == 0 || gCurrentTicks - ride.last_issue_time > 3000)
|
||||
if ((ride.current_issues & RIDE_ISSUE_GUESTS_STUCK) == 0 || currentTicks - ride.last_issue_time > 3000)
|
||||
{
|
||||
ride.current_issues |= RIDE_ISSUE_GUESTS_STUCK;
|
||||
ride.last_issue_time = gCurrentTicks;
|
||||
ride.last_issue_time = currentTicks;
|
||||
|
||||
auto ft = Formatter();
|
||||
ride.FormatNameTo(ft);
|
||||
@@ -5281,6 +5286,8 @@ void Guest::UpdateWalking()
|
||||
if (!CheckForPath())
|
||||
return;
|
||||
|
||||
const auto currentTicks = GetGameState().CurrentTicks;
|
||||
|
||||
if (!IsOnLevelCrossing())
|
||||
{
|
||||
if (PeepFlags & PEEP_FLAGS_WAVING && IsActionInterruptable() && (0xFFFF & ScenarioRand()) < 936)
|
||||
@@ -5335,7 +5342,7 @@ void Guest::UpdateWalking()
|
||||
}
|
||||
else if (HasEmptyContainer())
|
||||
{
|
||||
if ((!GetNextIsSurface()) && (static_cast<uint32_t>(Id.ToUnderlying() & 0x1FF) == (gCurrentTicks & 0x1FF))
|
||||
if ((!GetNextIsSurface()) && (static_cast<uint32_t>(Id.ToUnderlying() & 0x1FF) == (currentTicks & 0x1FF))
|
||||
&& ((0xFFFF & ScenarioRand()) <= 4096))
|
||||
{
|
||||
int32_t container = UtilBitScanForward(GetEmptyContainerFlags());
|
||||
@@ -5699,7 +5706,7 @@ void Guest::UpdateEnteringPark()
|
||||
SetState(PeepState::Falling);
|
||||
|
||||
OutsideOfPark = false;
|
||||
ParkEntryTime = gCurrentTicks;
|
||||
ParkEntryTime = GetGameState().CurrentTicks;
|
||||
IncrementGuestsInPark();
|
||||
DecrementGuestsHeadingForPark();
|
||||
auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user