mirror of https://github.com/OpenRCT2/OpenRCT2.git
Remove GameState class
This commit is contained in:
parent
28451027b1
commit
fef1a27342
|
@ -714,9 +714,7 @@ public:
|
||||||
{
|
{
|
||||||
if (_titleSequencePlayer == nullptr)
|
if (_titleSequencePlayer == nullptr)
|
||||||
{
|
{
|
||||||
auto context = GetContext();
|
_titleSequencePlayer = OpenRCT2::Title::CreateTitleSequencePlayer();
|
||||||
auto gameState = context->GetGameState();
|
|
||||||
_titleSequencePlayer = OpenRCT2::Title::CreateTitleSequencePlayer(*gameState);
|
|
||||||
}
|
}
|
||||||
return _titleSequencePlayer.get();
|
return _titleSequencePlayer.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,6 @@ namespace OpenRCT2::Title
|
||||||
class TitleSequencePlayer final : public ITitleSequencePlayer
|
class TitleSequencePlayer final : public ITitleSequencePlayer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
GameState& _gameState;
|
|
||||||
|
|
||||||
std::unique_ptr<TitleSequence> _sequence;
|
std::unique_ptr<TitleSequence> _sequence;
|
||||||
int32_t _position = 0;
|
int32_t _position = 0;
|
||||||
int32_t _waitCounter = 0;
|
int32_t _waitCounter = 0;
|
||||||
|
@ -57,8 +55,7 @@ namespace OpenRCT2::Title
|
||||||
ScreenCoordsXY _previousViewPosition = {};
|
ScreenCoordsXY _previousViewPosition = {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TitleSequencePlayer(GameState& gameState)
|
explicit TitleSequencePlayer()
|
||||||
: _gameState(gameState)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +245,7 @@ namespace OpenRCT2::Title
|
||||||
{
|
{
|
||||||
if (Update())
|
if (Update())
|
||||||
{
|
{
|
||||||
_gameState.UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -431,8 +428,8 @@ namespace OpenRCT2::Title
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ITitleSequencePlayer> CreateTitleSequencePlayer(GameState& gameState)
|
std::unique_ptr<ITitleSequencePlayer> CreateTitleSequencePlayer()
|
||||||
{
|
{
|
||||||
return std::make_unique<TitleSequencePlayer>(gameState);
|
return std::make_unique<TitleSequencePlayer>();
|
||||||
}
|
}
|
||||||
} // namespace OpenRCT2::Title
|
} // namespace OpenRCT2::Title
|
||||||
|
|
|
@ -17,10 +17,8 @@ struct IScenarioRepository;
|
||||||
|
|
||||||
namespace OpenRCT2
|
namespace OpenRCT2
|
||||||
{
|
{
|
||||||
class GameState;
|
|
||||||
|
|
||||||
namespace Title
|
namespace Title
|
||||||
{
|
{
|
||||||
[[nodiscard]] std::unique_ptr<ITitleSequencePlayer> CreateTitleSequencePlayer(GameState& gameState);
|
[[nodiscard]] std::unique_ptr<ITitleSequencePlayer> CreateTitleSequencePlayer();
|
||||||
} // namespace Title
|
} // namespace Title
|
||||||
} // namespace OpenRCT2
|
} // namespace OpenRCT2
|
||||||
|
|
|
@ -123,7 +123,6 @@ namespace OpenRCT2
|
||||||
|
|
||||||
// Game states
|
// Game states
|
||||||
std::unique_ptr<TitleScreen> _titleScreen;
|
std::unique_ptr<TitleScreen> _titleScreen;
|
||||||
std::unique_ptr<GameState> _gameState;
|
|
||||||
|
|
||||||
DrawingEngine _drawingEngineType = DrawingEngine::Software;
|
DrawingEngine _drawingEngineType = DrawingEngine::Software;
|
||||||
std::unique_ptr<IDrawingEngine> _drawingEngine;
|
std::unique_ptr<IDrawingEngine> _drawingEngine;
|
||||||
|
@ -221,11 +220,6 @@ namespace OpenRCT2
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GameState* GetGameState() override
|
|
||||||
{
|
|
||||||
return _gameState.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<IPlatformEnvironment> GetPlatformEnvironment() override
|
std::shared_ptr<IPlatformEnvironment> GetPlatformEnvironment() override
|
||||||
{
|
{
|
||||||
return _env;
|
return _env;
|
||||||
|
@ -477,14 +471,13 @@ namespace OpenRCT2
|
||||||
InputResetPlaceObjModifier();
|
InputResetPlaceObjModifier();
|
||||||
ViewportInitAll();
|
ViewportInitAll();
|
||||||
|
|
||||||
_gameState = std::make_unique<GameState>();
|
gameStateInitAll(GetGameState(), DEFAULT_MAP_SIZE);
|
||||||
_gameState->InitAll(DEFAULT_MAP_SIZE);
|
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
_scriptEngine.Initialise();
|
_scriptEngine.Initialise();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_titleScreen = std::make_unique<TitleScreen>(*_gameState);
|
_titleScreen = std::make_unique<TitleScreen>();
|
||||||
_uiContext->Initialise();
|
_uiContext->Initialise();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1199,7 +1192,7 @@ namespace OpenRCT2
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_gameState->Tick();
|
gameStateTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ENABLE_DISCORD__
|
#ifdef __ENABLE_DISCORD__
|
||||||
|
|
|
@ -81,7 +81,6 @@ class NetworkBase;
|
||||||
namespace OpenRCT2
|
namespace OpenRCT2
|
||||||
{
|
{
|
||||||
class AssetPackManager;
|
class AssetPackManager;
|
||||||
class GameState;
|
|
||||||
|
|
||||||
struct IPlatformEnvironment;
|
struct IPlatformEnvironment;
|
||||||
struct IReplayManager;
|
struct IReplayManager;
|
||||||
|
@ -125,7 +124,6 @@ namespace OpenRCT2
|
||||||
|
|
||||||
[[nodiscard]] virtual std::shared_ptr<Audio::IAudioContext> GetAudioContext() abstract;
|
[[nodiscard]] virtual std::shared_ptr<Audio::IAudioContext> GetAudioContext() abstract;
|
||||||
[[nodiscard]] virtual std::shared_ptr<Ui::IUiContext> GetUiContext() abstract;
|
[[nodiscard]] virtual std::shared_ptr<Ui::IUiContext> GetUiContext() abstract;
|
||||||
virtual GameState* GetGameState() abstract;
|
|
||||||
[[nodiscard]] virtual std::shared_ptr<IPlatformEnvironment> GetPlatformEnvironment() abstract;
|
[[nodiscard]] virtual std::shared_ptr<IPlatformEnvironment> GetPlatformEnvironment() abstract;
|
||||||
virtual Localisation::LocalisationService& GetLocalisationService() abstract;
|
virtual Localisation::LocalisationService& GetLocalisationService() abstract;
|
||||||
virtual IObjectManager& GetObjectManager() abstract;
|
virtual IObjectManager& GetObjectManager() abstract;
|
||||||
|
|
|
@ -105,7 +105,7 @@ namespace Editor
|
||||||
auto& gameState = GetGameState();
|
auto& gameState = GetGameState();
|
||||||
Audio::StopAll();
|
Audio::StopAll();
|
||||||
ObjectListLoad();
|
ObjectListLoad();
|
||||||
GetContext()->GetGameState()->InitAll(DEFAULT_MAP_SIZE);
|
gameStateInitAll(gameState, DEFAULT_MAP_SIZE);
|
||||||
gScreenFlags = SCREEN_FLAGS_SCENARIO_EDITOR;
|
gScreenFlags = SCREEN_FLAGS_SCENARIO_EDITOR;
|
||||||
gameState.EditorStep = EditorStep::ObjectSelection;
|
gameState.EditorStep = EditorStep::ObjectSelection;
|
||||||
gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES;
|
gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES;
|
||||||
|
@ -167,7 +167,7 @@ namespace Editor
|
||||||
|
|
||||||
ObjectManagerUnloadAllObjects();
|
ObjectManagerUnloadAllObjects();
|
||||||
ObjectListLoad();
|
ObjectListLoad();
|
||||||
GetContext()->GetGameState()->InitAll(DEFAULT_MAP_SIZE);
|
gameStateInitAll(GetGameState(), DEFAULT_MAP_SIZE);
|
||||||
SetAllLandOwned();
|
SetAllLandOwned();
|
||||||
GetGameState().EditorStep = EditorStep::ObjectSelection;
|
GetGameState().EditorStep = EditorStep::ObjectSelection;
|
||||||
ViewportInitAll();
|
ViewportInitAll();
|
||||||
|
@ -188,7 +188,7 @@ namespace Editor
|
||||||
|
|
||||||
ObjectManagerUnloadAllObjects();
|
ObjectManagerUnloadAllObjects();
|
||||||
ObjectListLoad();
|
ObjectListLoad();
|
||||||
GetContext()->GetGameState()->InitAll(DEFAULT_MAP_SIZE);
|
gameStateInitAll(GetGameState(), DEFAULT_MAP_SIZE);
|
||||||
SetAllLandOwned();
|
SetAllLandOwned();
|
||||||
GetGameState().EditorStep = EditorStep::ObjectSelection;
|
GetGameState().EditorStep = EditorStep::ObjectSelection;
|
||||||
ViewportInitAll();
|
ViewportInitAll();
|
||||||
|
|
|
@ -58,338 +58,332 @@ namespace OpenRCT2
|
||||||
{
|
{
|
||||||
return _gameState;
|
return _gameState;
|
||||||
}
|
}
|
||||||
} // namespace OpenRCT2
|
|
||||||
|
|
||||||
GameState::GameState()
|
/**
|
||||||
{
|
* Initialises the map, park etc. basically all S6 data.
|
||||||
}
|
*/
|
||||||
|
void gameStateInitAll(GameState_t& gameState, const TileCoordsXY& mapSize)
|
||||||
|
{
|
||||||
|
PROFILED_FUNCTION();
|
||||||
|
|
||||||
/**
|
gInMapInitCode = true;
|
||||||
* Initialises the map, park etc. basically all S6 data.
|
gameState.CurrentTicks = 0;
|
||||||
*/
|
|
||||||
void GameState::InitAll(const TileCoordsXY& mapSize)
|
|
||||||
{
|
|
||||||
PROFILED_FUNCTION();
|
|
||||||
|
|
||||||
auto& gameState = GetGameState();
|
MapInit(mapSize);
|
||||||
gInMapInitCode = true;
|
gameState.Park.Initialise();
|
||||||
gameState.CurrentTicks = 0;
|
FinanceInit();
|
||||||
|
BannerInit(gameState);
|
||||||
|
RideInitAll();
|
||||||
|
ResetAllEntities();
|
||||||
|
UpdateConsolidatedPatrolAreas();
|
||||||
|
ResetDate();
|
||||||
|
ClimateReset(ClimateType::CoolAndWet);
|
||||||
|
News::InitQueue();
|
||||||
|
|
||||||
MapInit(mapSize);
|
gInMapInitCode = false;
|
||||||
gameState.Park.Initialise();
|
|
||||||
FinanceInit();
|
|
||||||
BannerInit(gameState);
|
|
||||||
RideInitAll();
|
|
||||||
ResetAllEntities();
|
|
||||||
UpdateConsolidatedPatrolAreas();
|
|
||||||
ResetDate();
|
|
||||||
ClimateReset(ClimateType::CoolAndWet);
|
|
||||||
News::InitQueue();
|
|
||||||
|
|
||||||
gInMapInitCode = false;
|
GetGameState().NextGuestNumber = 1;
|
||||||
|
|
||||||
GetGameState().NextGuestNumber = 1;
|
ContextInit();
|
||||||
|
ScenerySetDefaultPlacementConfiguration();
|
||||||
|
|
||||||
ContextInit();
|
auto intent = Intent(INTENT_ACTION_CLEAR_TILE_INSPECTOR_CLIPBOARD);
|
||||||
ScenerySetDefaultPlacementConfiguration();
|
ContextBroadcastIntent(&intent);
|
||||||
|
|
||||||
auto intent = Intent(INTENT_ACTION_CLEAR_TILE_INSPECTOR_CLIPBOARD);
|
LoadPalette();
|
||||||
ContextBroadcastIntent(&intent);
|
|
||||||
|
|
||||||
LoadPalette();
|
CheatsReset();
|
||||||
|
ClearRestrictedScenery();
|
||||||
CheatsReset();
|
|
||||||
ClearRestrictedScenery();
|
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||||
scriptEngine.ClearParkStorage();
|
scriptEngine.ClearParkStorage();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EntityTweener::Get().Reset();
|
EntityTweener::Get().Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function will be called every kGameUpdateTimeMS.
|
* Function will be called every kGameUpdateTimeMS.
|
||||||
* It has its own loop which might run multiple updates per call such as
|
* It has its own loop which might run multiple updates per call such as
|
||||||
* when operating as a client it may run multiple updates to catch up with the server tick,
|
* when operating as a client it may run multiple updates to catch up with the server tick,
|
||||||
* another influence can be the game speed setting.
|
* another influence can be the game speed setting.
|
||||||
*/
|
*/
|
||||||
void GameState::Tick()
|
void gameStateTick()
|
||||||
{
|
|
||||||
PROFILED_FUNCTION();
|
|
||||||
|
|
||||||
// Normal game play will update only once every kGameUpdateTimeMS
|
|
||||||
uint32_t numUpdates = 1;
|
|
||||||
|
|
||||||
// 0x006E3AEC // screen_game_process_mouse_input();
|
|
||||||
ScreenshotCheck();
|
|
||||||
GameHandleKeyboardInput();
|
|
||||||
|
|
||||||
if (GameIsNotPaused() && gPreviewingTitleSequenceInGame)
|
|
||||||
{
|
{
|
||||||
auto player = GetContext()->GetUiContext()->GetTitleSequencePlayer();
|
PROFILED_FUNCTION();
|
||||||
if (player != nullptr)
|
|
||||||
|
// Normal game play will update only once every kGameUpdateTimeMS
|
||||||
|
uint32_t numUpdates = 1;
|
||||||
|
|
||||||
|
// 0x006E3AEC // screen_game_process_mouse_input();
|
||||||
|
ScreenshotCheck();
|
||||||
|
GameHandleKeyboardInput();
|
||||||
|
|
||||||
|
if (GameIsNotPaused() && gPreviewingTitleSequenceInGame)
|
||||||
{
|
{
|
||||||
player->Update();
|
auto player = GetContext()->GetUiContext()->GetTitleSequencePlayer();
|
||||||
|
if (player != nullptr)
|
||||||
|
{
|
||||||
|
player->Update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NetworkUpdate();
|
NetworkUpdate();
|
||||||
|
|
||||||
if (NetworkGetMode() == NETWORK_MODE_CLIENT && NetworkGetStatus() == NETWORK_STATUS_CONNECTED
|
if (NetworkGetMode() == NETWORK_MODE_CLIENT && NetworkGetStatus() == NETWORK_STATUS_CONNECTED
|
||||||
&& NetworkGetAuthstatus() == NetworkAuth::Ok)
|
&& NetworkGetAuthstatus() == NetworkAuth::Ok)
|
||||||
{
|
|
||||||
numUpdates = std::clamp<uint32_t>(NetworkGetServerTick() - GetGameState().CurrentTicks, 0, 10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Determine how many times we need to update the game
|
|
||||||
if (gGameSpeed > 1)
|
|
||||||
{
|
{
|
||||||
// Update more often if game speed is above normal.
|
numUpdates = std::clamp<uint32_t>(NetworkGetServerTick() - GetGameState().CurrentTicks, 0, 10);
|
||||||
numUpdates = 1 << (gGameSpeed - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPaused = GameIsPaused();
|
|
||||||
if (NetworkGetMode() == NETWORK_MODE_SERVER && gConfigNetwork.PauseServerIfNoClients)
|
|
||||||
{
|
|
||||||
// If we are headless we always have 1 player (host), pause if no one else is around.
|
|
||||||
if (gOpenRCT2Headless && NetworkGetNumPlayers() == 1)
|
|
||||||
{
|
|
||||||
isPaused |= true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool didRunSingleFrame = false;
|
|
||||||
if (isPaused)
|
|
||||||
{
|
|
||||||
if (gDoSingleUpdate && NetworkGetMode() == NETWORK_MODE_NONE)
|
|
||||||
{
|
|
||||||
didRunSingleFrame = true;
|
|
||||||
PauseToggle();
|
|
||||||
numUpdates = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// NOTE: Here are a few special cases that would be normally handled in UpdateLogic.
|
// Determine how many times we need to update the game
|
||||||
// If the game is paused it will not call UpdateLogic at all.
|
if (gGameSpeed > 1)
|
||||||
numUpdates = 0;
|
|
||||||
|
|
||||||
if (NetworkGetMode() == NETWORK_MODE_SERVER)
|
|
||||||
{
|
{
|
||||||
// Make sure the client always knows about what tick the host is on.
|
// Update more often if game speed is above normal.
|
||||||
NetworkSendTick();
|
numUpdates = 1 << (gGameSpeed - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep updating the money effect even when paused.
|
|
||||||
UpdateMoneyEffect();
|
|
||||||
|
|
||||||
// Update the animation list. Note this does not
|
|
||||||
// increment the map animation.
|
|
||||||
MapAnimationInvalidateAll();
|
|
||||||
|
|
||||||
// Post-tick network update
|
|
||||||
NetworkProcessPending();
|
|
||||||
|
|
||||||
// Post-tick game actions.
|
|
||||||
GameActions::ProcessQueue();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update the game one or more times
|
bool isPaused = GameIsPaused();
|
||||||
for (uint32_t i = 0; i < numUpdates; i++)
|
if (NetworkGetMode() == NETWORK_MODE_SERVER && gConfigNetwork.PauseServerIfNoClients)
|
||||||
{
|
|
||||||
UpdateLogic();
|
|
||||||
if (gGameSpeed == 1)
|
|
||||||
{
|
{
|
||||||
if (InputGetState() == InputState::Reset || InputGetState() == InputState::Normal)
|
// If we are headless we always have 1 player (host), pause if no one else is around.
|
||||||
|
if (gOpenRCT2Headless && NetworkGetNumPlayers() == 1)
|
||||||
{
|
{
|
||||||
if (InputTestFlag(INPUT_FLAG_VIEWPORT_SCROLLING))
|
isPaused |= true;
|
||||||
{
|
}
|
||||||
InputSetFlag(INPUT_FLAG_VIEWPORT_SCROLLING, false);
|
}
|
||||||
break;
|
|
||||||
}
|
bool didRunSingleFrame = false;
|
||||||
|
if (isPaused)
|
||||||
|
{
|
||||||
|
if (gDoSingleUpdate && NetworkGetMode() == NETWORK_MODE_NONE)
|
||||||
|
{
|
||||||
|
didRunSingleFrame = true;
|
||||||
|
PauseToggle();
|
||||||
|
numUpdates = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
// NOTE: Here are a few special cases that would be normally handled in UpdateLogic.
|
||||||
|
// If the game is paused it will not call UpdateLogic at all.
|
||||||
|
numUpdates = 0;
|
||||||
|
|
||||||
|
if (NetworkGetMode() == NETWORK_MODE_SERVER)
|
||||||
|
{
|
||||||
|
// Make sure the client always knows about what tick the host is on.
|
||||||
|
NetworkSendTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep updating the money effect even when paused.
|
||||||
|
UpdateMoneyEffect();
|
||||||
|
|
||||||
|
// Update the animation list. Note this does not
|
||||||
|
// increment the map animation.
|
||||||
|
MapAnimationInvalidateAll();
|
||||||
|
|
||||||
|
// Post-tick network update
|
||||||
|
NetworkProcessPending();
|
||||||
|
|
||||||
|
// Post-tick game actions.
|
||||||
|
GameActions::ProcessQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Don't call UpdateLogic again if the game was just paused.
|
|
||||||
isPaused |= GameIsPaused();
|
|
||||||
if (isPaused)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkFlush();
|
// Update the game one or more times
|
||||||
|
for (uint32_t i = 0; i < numUpdates; i++)
|
||||||
if (!gOpenRCT2Headless)
|
|
||||||
{
|
|
||||||
InputSetFlag(INPUT_FLAG_VIEWPORT_SCROLLING, false);
|
|
||||||
|
|
||||||
// the flickering frequency is reduced by 4, compared to the original
|
|
||||||
// it was done due to inability to reproduce original frequency
|
|
||||||
// and decision that the original one looks too fast
|
|
||||||
if (gCurrentRealTimeTicks % 4 == 0)
|
|
||||||
gWindowMapFlashingFlags ^= MapFlashingFlags::SwitchColour;
|
|
||||||
|
|
||||||
// Handle guest map flashing
|
|
||||||
gWindowMapFlashingFlags &= ~MapFlashingFlags::FlashGuests;
|
|
||||||
if (gWindowMapFlashingFlags & MapFlashingFlags::GuestListOpen)
|
|
||||||
gWindowMapFlashingFlags |= MapFlashingFlags::FlashGuests;
|
|
||||||
gWindowMapFlashingFlags &= ~MapFlashingFlags::GuestListOpen;
|
|
||||||
|
|
||||||
// Handle staff map flashing
|
|
||||||
gWindowMapFlashingFlags &= ~MapFlashingFlags::FlashStaff;
|
|
||||||
if (gWindowMapFlashingFlags & MapFlashingFlags::StaffListOpen)
|
|
||||||
gWindowMapFlashingFlags |= MapFlashingFlags::FlashStaff;
|
|
||||||
gWindowMapFlashingFlags &= ~MapFlashingFlags::StaffListOpen;
|
|
||||||
|
|
||||||
ContextUpdateMapTooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always perform autosave check, even when paused
|
|
||||||
if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !(gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
|
|
||||||
&& !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER))
|
|
||||||
{
|
|
||||||
ScenarioAutosaveCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowDispatchUpdateAll();
|
|
||||||
|
|
||||||
if (didRunSingleFrame && GameIsNotPaused() && !(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO))
|
|
||||||
{
|
|
||||||
PauseToggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
gDoSingleUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameState::UpdateLogic()
|
|
||||||
{
|
|
||||||
PROFILED_FUNCTION();
|
|
||||||
|
|
||||||
gInUpdateCode = true;
|
|
||||||
|
|
||||||
gScreenAge++;
|
|
||||||
if (gScreenAge == 0)
|
|
||||||
gScreenAge--;
|
|
||||||
|
|
||||||
GetContext()->GetReplayManager()->Update();
|
|
||||||
|
|
||||||
NetworkUpdate();
|
|
||||||
|
|
||||||
if (NetworkGetMode() == NETWORK_MODE_SERVER)
|
|
||||||
{
|
|
||||||
if (NetworkGamestateSnapshotsEnabled())
|
|
||||||
{
|
{
|
||||||
CreateStateSnapshot();
|
gameStateUpdateLogic();
|
||||||
}
|
if (gGameSpeed == 1)
|
||||||
|
|
||||||
// Send current tick out.
|
|
||||||
NetworkSendTick();
|
|
||||||
}
|
|
||||||
else if (NetworkGetMode() == NETWORK_MODE_CLIENT)
|
|
||||||
{
|
|
||||||
// Don't run past the server, this condition can happen during map changes.
|
|
||||||
if (NetworkGetServerTick() == GetGameState().CurrentTicks)
|
|
||||||
{
|
|
||||||
gInUpdateCode = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check desync.
|
|
||||||
bool desynced = NetworkCheckDesynchronisation();
|
|
||||||
if (desynced)
|
|
||||||
{
|
|
||||||
// If desync debugging is enabled and we are still connected request the specific game state from server.
|
|
||||||
if (NetworkGamestateSnapshotsEnabled() && NetworkGetStatus() == NETWORK_STATUS_CONNECTED)
|
|
||||||
{
|
{
|
||||||
// Create snapshot from this tick so we can compare it later
|
if (InputGetState() == InputState::Reset || InputGetState() == InputState::Normal)
|
||||||
// as we won't pause the game on this event.
|
{
|
||||||
CreateStateSnapshot();
|
if (InputTestFlag(INPUT_FLAG_VIEWPORT_SCROLLING))
|
||||||
|
{
|
||||||
|
InputSetFlag(INPUT_FLAG_VIEWPORT_SCROLLING, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't call UpdateLogic again if the game was just paused.
|
||||||
|
isPaused |= GameIsPaused();
|
||||||
|
if (isPaused)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
NetworkRequestGamestateSnapshot();
|
NetworkFlush();
|
||||||
|
|
||||||
|
if (!gOpenRCT2Headless)
|
||||||
|
{
|
||||||
|
InputSetFlag(INPUT_FLAG_VIEWPORT_SCROLLING, false);
|
||||||
|
|
||||||
|
// the flickering frequency is reduced by 4, compared to the original
|
||||||
|
// it was done due to inability to reproduce original frequency
|
||||||
|
// and decision that the original one looks too fast
|
||||||
|
if (gCurrentRealTimeTicks % 4 == 0)
|
||||||
|
gWindowMapFlashingFlags ^= MapFlashingFlags::SwitchColour;
|
||||||
|
|
||||||
|
// Handle guest map flashing
|
||||||
|
gWindowMapFlashingFlags &= ~MapFlashingFlags::FlashGuests;
|
||||||
|
if (gWindowMapFlashingFlags & MapFlashingFlags::GuestListOpen)
|
||||||
|
gWindowMapFlashingFlags |= MapFlashingFlags::FlashGuests;
|
||||||
|
gWindowMapFlashingFlags &= ~MapFlashingFlags::GuestListOpen;
|
||||||
|
|
||||||
|
// Handle staff map flashing
|
||||||
|
gWindowMapFlashingFlags &= ~MapFlashingFlags::FlashStaff;
|
||||||
|
if (gWindowMapFlashingFlags & MapFlashingFlags::StaffListOpen)
|
||||||
|
gWindowMapFlashingFlags |= MapFlashingFlags::FlashStaff;
|
||||||
|
gWindowMapFlashingFlags &= ~MapFlashingFlags::StaffListOpen;
|
||||||
|
|
||||||
|
ContextUpdateMapTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always perform autosave check, even when paused
|
||||||
|
if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !(gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
|
||||||
|
&& !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER))
|
||||||
|
{
|
||||||
|
ScenarioAutosaveCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowDispatchUpdateAll();
|
||||||
|
|
||||||
|
if (didRunSingleFrame && GameIsNotPaused() && !(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO))
|
||||||
|
{
|
||||||
|
PauseToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
gDoSingleUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gameStateCreateStateSnapshot()
|
||||||
|
{
|
||||||
|
PROFILED_FUNCTION();
|
||||||
|
|
||||||
|
IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots();
|
||||||
|
|
||||||
|
auto& snapshot = snapshots->CreateSnapshot();
|
||||||
|
snapshots->Capture(snapshot);
|
||||||
|
snapshots->LinkSnapshot(snapshot, GetGameState().CurrentTicks, ScenarioRandState().s0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gameStateUpdateLogic()
|
||||||
|
{
|
||||||
|
PROFILED_FUNCTION();
|
||||||
|
|
||||||
|
gInUpdateCode = true;
|
||||||
|
|
||||||
|
gScreenAge++;
|
||||||
|
if (gScreenAge == 0)
|
||||||
|
gScreenAge--;
|
||||||
|
|
||||||
|
GetContext()->GetReplayManager()->Update();
|
||||||
|
|
||||||
|
NetworkUpdate();
|
||||||
|
|
||||||
|
if (NetworkGetMode() == NETWORK_MODE_SERVER)
|
||||||
|
{
|
||||||
|
if (NetworkGamestateSnapshotsEnabled())
|
||||||
|
{
|
||||||
|
gameStateCreateStateSnapshot();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send current tick out.
|
||||||
|
NetworkSendTick();
|
||||||
|
}
|
||||||
|
else if (NetworkGetMode() == NETWORK_MODE_CLIENT)
|
||||||
|
{
|
||||||
|
// Don't run past the server, this condition can happen during map changes.
|
||||||
|
if (NetworkGetServerTick() == GetGameState().CurrentTicks)
|
||||||
|
{
|
||||||
|
gInUpdateCode = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check desync.
|
||||||
|
bool desynced = NetworkCheckDesynchronisation();
|
||||||
|
if (desynced)
|
||||||
|
{
|
||||||
|
// If desync debugging is enabled and we are still connected request the specific game state from server.
|
||||||
|
if (NetworkGamestateSnapshotsEnabled() && NetworkGetStatus() == NETWORK_STATUS_CONNECTED)
|
||||||
|
{
|
||||||
|
// Create snapshot from this tick so we can compare it later
|
||||||
|
// as we won't pause the game on this event.
|
||||||
|
gameStateCreateStateSnapshot();
|
||||||
|
|
||||||
|
NetworkRequestGamestateSnapshot();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auto& gameState = GetGameState();
|
auto& gameState = GetGameState();
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
// Stash the current day number before updating the date so that we
|
// Stash the current day number before updating the date so that we
|
||||||
// know if the day number changes on this tick.
|
// know if the day number changes on this tick.
|
||||||
auto day = gameState.Date.GetDay();
|
auto day = gameState.Date.GetDay();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gameState.Date.Update();
|
gameState.Date.Update();
|
||||||
|
|
||||||
ScenarioUpdate(gameState);
|
ScenarioUpdate(gameState);
|
||||||
ClimateUpdate();
|
ClimateUpdate();
|
||||||
MapUpdateTiles();
|
MapUpdateTiles();
|
||||||
// Temporarily remove provisional paths to prevent peep from interacting with them
|
// Temporarily remove provisional paths to prevent peep from interacting with them
|
||||||
MapRemoveProvisionalElements();
|
MapRemoveProvisionalElements();
|
||||||
MapUpdatePathWideFlags();
|
MapUpdatePathWideFlags();
|
||||||
PeepUpdateAll();
|
PeepUpdateAll();
|
||||||
MapRestoreProvisionalElements();
|
MapRestoreProvisionalElements();
|
||||||
VehicleUpdateAll();
|
VehicleUpdateAll();
|
||||||
UpdateAllMiscEntities();
|
UpdateAllMiscEntities();
|
||||||
Ride::UpdateAll();
|
Ride::UpdateAll();
|
||||||
|
|
||||||
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR))
|
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR))
|
||||||
{
|
{
|
||||||
gameState.Park.Update(gameState.Date);
|
gameState.Park.Update(gameState.Date);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResearchUpdate();
|
ResearchUpdate();
|
||||||
RideRatingsUpdateAll();
|
RideRatingsUpdateAll();
|
||||||
RideMeasurementsUpdate();
|
RideMeasurementsUpdate();
|
||||||
News::UpdateCurrentItem();
|
News::UpdateCurrentItem();
|
||||||
|
|
||||||
MapAnimationInvalidateAll();
|
MapAnimationInvalidateAll();
|
||||||
VehicleSoundsUpdate();
|
VehicleSoundsUpdate();
|
||||||
PeepUpdateCrowdNoise();
|
PeepUpdateCrowdNoise();
|
||||||
ClimateUpdateSound();
|
ClimateUpdateSound();
|
||||||
EditorOpenWindowsForCurrentStep();
|
EditorOpenWindowsForCurrentStep();
|
||||||
|
|
||||||
// Update windows
|
// Update windows
|
||||||
// WindowDispatchUpdateAll();
|
// WindowDispatchUpdateAll();
|
||||||
|
|
||||||
// Start autosave timer after update
|
// Start autosave timer after update
|
||||||
if (gLastAutoSaveUpdate == kAutosavePause)
|
if (gLastAutoSaveUpdate == kAutosavePause)
|
||||||
{
|
{
|
||||||
gLastAutoSaveUpdate = Platform::GetTicks();
|
gLastAutoSaveUpdate = Platform::GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
GameActions::ProcessQueue();
|
GameActions::ProcessQueue();
|
||||||
|
|
||||||
NetworkProcessPending();
|
NetworkProcessPending();
|
||||||
NetworkFlush();
|
NetworkFlush();
|
||||||
|
|
||||||
gameState.CurrentTicks++;
|
gameState.CurrentTicks++;
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine();
|
auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine();
|
||||||
hookEngine.Call(HOOK_TYPE::INTERVAL_TICK, true);
|
hookEngine.Call(HOOK_TYPE::INTERVAL_TICK, true);
|
||||||
|
|
||||||
if (day != gameState.Date.GetDay())
|
if (day != gameState.Date.GetDay())
|
||||||
{
|
{
|
||||||
hookEngine.Call(HOOK_TYPE::INTERVAL_DAY, true);
|
hookEngine.Call(HOOK_TYPE::INTERVAL_DAY, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gInUpdateCode = false;
|
gInUpdateCode = false;
|
||||||
}
|
}
|
||||||
|
} // namespace OpenRCT2
|
||||||
void GameState::CreateStateSnapshot()
|
|
||||||
{
|
|
||||||
PROFILED_FUNCTION();
|
|
||||||
|
|
||||||
IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots();
|
|
||||||
|
|
||||||
auto& snapshot = snapshots->CreateSnapshot();
|
|
||||||
snapshots->Capture(snapshot);
|
|
||||||
snapshots->LinkSnapshot(snapshot, GetGameState().CurrentTicks, ScenarioRandState().s0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -158,20 +158,8 @@ namespace OpenRCT2
|
||||||
|
|
||||||
GameState_t& GetGameState();
|
GameState_t& GetGameState();
|
||||||
|
|
||||||
/**
|
void gameStateInitAll(GameState_t& gameState, const TileCoordsXY& mapSize);
|
||||||
* Class to update the state of the map and park.
|
void gameStateTick();
|
||||||
*/
|
void gameStateUpdateLogic();
|
||||||
class GameState final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GameState();
|
|
||||||
GameState(const GameState&) = delete;
|
|
||||||
|
|
||||||
void InitAll(const TileCoordsXY& mapSize);
|
|
||||||
void Tick();
|
|
||||||
void UpdateLogic();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void CreateStateSnapshot();
|
|
||||||
};
|
|
||||||
} // namespace OpenRCT2
|
} // namespace OpenRCT2
|
||||||
|
|
|
@ -59,7 +59,7 @@ static exitcode_t HandleSimulate(CommandLineArgEnumerator* argEnumerator)
|
||||||
Console::WriteLine("Running %d ticks...", ticks);
|
Console::WriteLine("Running %d ticks...", ticks);
|
||||||
for (uint32_t i = 0; i < ticks; i++)
|
for (uint32_t i = 0; i < ticks; i++)
|
||||||
{
|
{
|
||||||
context->GetGameState()->UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
Console::WriteLine("Completed: %s", GetAllEntitiesChecksum().ToString().c_str());
|
Console::WriteLine("Completed: %s", GetAllEntitiesChecksum().ToString().c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1063,8 +1063,7 @@ namespace OpenRCT2
|
||||||
|
|
||||||
if (cs.GetMode() == OrcaStream::Mode::READING)
|
if (cs.GetMode() == OrcaStream::Mode::READING)
|
||||||
{
|
{
|
||||||
// TODO: Use the passed gameState instead of the global one.
|
gameStateInitAll(gameState, gameState.MapSize);
|
||||||
OpenRCT2::GetContext()->GetGameState()->InitAll(gameState.MapSize);
|
|
||||||
|
|
||||||
auto numElements = cs.Read<uint32_t>();
|
auto numElements = cs.Read<uint32_t>();
|
||||||
|
|
||||||
|
|
|
@ -326,8 +326,7 @@ namespace RCT1
|
||||||
gScenarioFileName = GetRCT1ScenarioName();
|
gScenarioFileName = GetRCT1ScenarioName();
|
||||||
|
|
||||||
// Do map initialisation, same kind of stuff done when loading scenario editor
|
// Do map initialisation, same kind of stuff done when loading scenario editor
|
||||||
auto context = OpenRCT2::GetContext();
|
gameStateInitAll(gameState, { mapSize, mapSize });
|
||||||
context->GetGameState()->InitAll({ mapSize, mapSize });
|
|
||||||
gameState.EditorStep = EditorStep::ObjectSelection;
|
gameState.EditorStep = EditorStep::ObjectSelection;
|
||||||
gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES;
|
gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES;
|
||||||
gameState.ScenarioCategory = SCENARIO_CATEGORY_OTHER;
|
gameState.ScenarioCategory = SCENARIO_CATEGORY_OTHER;
|
||||||
|
|
|
@ -229,7 +229,7 @@ namespace RCT2
|
||||||
|
|
||||||
void Import(GameState_t& gameState) override
|
void Import(GameState_t& gameState) override
|
||||||
{
|
{
|
||||||
Initialise();
|
Initialise(gameState);
|
||||||
|
|
||||||
gameState.EditorStep = _s6.Info.EditorStep;
|
gameState.EditorStep = _s6.Info.EditorStep;
|
||||||
gameState.ScenarioCategory = static_cast<SCENARIO_CATEGORY>(_s6.Info.Category);
|
gameState.ScenarioCategory = static_cast<SCENARIO_CATEGORY>(_s6.Info.Category);
|
||||||
|
@ -1719,9 +1719,9 @@ namespace RCT2
|
||||||
dst->position.y = src->y;
|
dst->position.y = src->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialise()
|
void Initialise(GameState_t& gameState)
|
||||||
{
|
{
|
||||||
OpenRCT2::GetContext()->GetGameState()->InitAll({ _s6.MapSize, _s6.MapSize });
|
gameStateInitAll(gameState, { _s6.MapSize, _s6.MapSize });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,8 +39,7 @@ using namespace OpenRCT2;
|
||||||
bool gPreviewingTitleSequenceInGame;
|
bool gPreviewingTitleSequenceInGame;
|
||||||
static TitleScreen* _singleton = nullptr;
|
static TitleScreen* _singleton = nullptr;
|
||||||
|
|
||||||
TitleScreen::TitleScreen(GameState& gameState)
|
TitleScreen::TitleScreen()
|
||||||
: _gameState(gameState)
|
|
||||||
{
|
{
|
||||||
_singleton = this;
|
_singleton = this;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +128,7 @@ void TitleScreen::Load()
|
||||||
GetContext()->GetNetwork().Close();
|
GetContext()->GetNetwork().Close();
|
||||||
#endif
|
#endif
|
||||||
OpenRCT2::Audio::StopAll();
|
OpenRCT2::Audio::StopAll();
|
||||||
GetContext()->GetGameState()->InitAll(DEFAULT_MAP_SIZE);
|
gameStateInitAll(GetGameState(), DEFAULT_MAP_SIZE);
|
||||||
ViewportInitAll();
|
ViewportInitAll();
|
||||||
ContextOpenWindow(WindowClass::MainWindow);
|
ContextOpenWindow(WindowClass::MainWindow);
|
||||||
CreateWindows();
|
CreateWindows();
|
||||||
|
@ -173,7 +172,7 @@ void TitleScreen::Tick()
|
||||||
}
|
}
|
||||||
for (int32_t i = 0; i < numUpdates; i++)
|
for (int32_t i = 0; i < numUpdates; i++)
|
||||||
{
|
{
|
||||||
_gameState.UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
UpdatePaletteEffects();
|
UpdatePaletteEffects();
|
||||||
// update_weather_animation();
|
// update_weather_animation();
|
||||||
|
@ -336,7 +335,7 @@ bool TitleScreen::TryLoadSequence(bool loadPreview)
|
||||||
_loadedTitleSequenceId = SIZE_MAX;
|
_loadedTitleSequenceId = SIZE_MAX;
|
||||||
if (!loadPreview)
|
if (!loadPreview)
|
||||||
{
|
{
|
||||||
GetContext()->GetGameState()->InitAll(DEFAULT_MAP_SIZE);
|
gameStateInitAll(GetGameState(), DEFAULT_MAP_SIZE);
|
||||||
GameNotifyMapChanged();
|
GameNotifyMapChanged();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,12 +16,10 @@ struct ITitleSequencePlayer;
|
||||||
|
|
||||||
namespace OpenRCT2
|
namespace OpenRCT2
|
||||||
{
|
{
|
||||||
class GameState;
|
|
||||||
|
|
||||||
class TitleScreen final
|
class TitleScreen final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TitleScreen(GameState& gameState);
|
TitleScreen();
|
||||||
~TitleScreen();
|
~TitleScreen();
|
||||||
|
|
||||||
ITitleSequencePlayer* GetSequencePlayer();
|
ITitleSequencePlayer* GetSequencePlayer();
|
||||||
|
@ -38,8 +36,6 @@ namespace OpenRCT2
|
||||||
void ChangePresetSequence(size_t preset);
|
void ChangePresetSequence(size_t preset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GameState& _gameState;
|
|
||||||
|
|
||||||
ITitleSequencePlayer* _sequencePlayer = nullptr;
|
ITitleSequencePlayer* _sequencePlayer = nullptr;
|
||||||
size_t _loadedTitleSequenceId = SIZE_MAX;
|
size_t _loadedTitleSequenceId = SIZE_MAX;
|
||||||
size_t _currentSequence = SIZE_MAX;
|
size_t _currentSequence = SIZE_MAX;
|
||||||
|
|
|
@ -45,8 +45,6 @@ TEST(MultiLaunchTest, all)
|
||||||
|
|
||||||
// Check ride count to check load was successful
|
// Check ride count to check load was successful
|
||||||
ASSERT_EQ(RideGetCount(), 134);
|
ASSERT_EQ(RideGetCount(), 134);
|
||||||
auto gs = context->GetGameState();
|
|
||||||
ASSERT_NE(gs, nullptr);
|
|
||||||
|
|
||||||
auto& date = GetGameState().Date;
|
auto& date = GetGameState().Date;
|
||||||
// NOTE: This value is saved in the SV6 file, after the import this will be the current state.
|
// NOTE: This value is saved in the SV6 file, after the import this will be the current state.
|
||||||
|
@ -55,7 +53,7 @@ TEST(MultiLaunchTest, all)
|
||||||
|
|
||||||
for (int j = 0; j < updatesToTest; j++)
|
for (int j = 0; j < updatesToTest; j++)
|
||||||
{
|
{
|
||||||
gs->UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_EQ(date.GetMonthTicks(), 7862 + updatesToTest);
|
ASSERT_EQ(date.GetMonthTicks(), 7862 + updatesToTest);
|
||||||
|
|
|
@ -68,11 +68,11 @@ static std::unique_ptr<IContext> localStartGame(const std::string& parkPath)
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Fn> static bool updateUntil(GameState& gs, int maxSteps, Fn&& fn)
|
template<class Fn> static bool updateUntil(int maxSteps, Fn&& fn)
|
||||||
{
|
{
|
||||||
while (maxSteps-- && !fn())
|
while (maxSteps-- && !fn())
|
||||||
{
|
{
|
||||||
gs.UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
return maxSteps > 0;
|
return maxSteps > 0;
|
||||||
}
|
}
|
||||||
|
@ -96,9 +96,6 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds)
|
||||||
auto context = localStartGame(initStateFile);
|
auto context = localStartGame(initStateFile);
|
||||||
ASSERT_NE(context.get(), nullptr);
|
ASSERT_NE(context.get(), nullptr);
|
||||||
|
|
||||||
auto gs = context->GetGameState();
|
|
||||||
ASSERT_NE(gs, nullptr);
|
|
||||||
|
|
||||||
auto& gameState = GetGameState();
|
auto& gameState = GetGameState();
|
||||||
|
|
||||||
// Open park for free but charging for rides
|
// Open park for free but charging for rides
|
||||||
|
@ -125,7 +122,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds)
|
||||||
richGuest->CashInPocket = 3000;
|
richGuest->CashInPocket = 3000;
|
||||||
|
|
||||||
// Wait for rich guest to get in queue
|
// Wait for rich guest to get in queue
|
||||||
bool matched = updateUntil(*gs, 1000, [&]() { return richGuest->State == PeepState::Queuing; });
|
bool matched = updateUntil(1000, [&]() { return richGuest->State == PeepState::Queuing; });
|
||||||
ASSERT_TRUE(matched);
|
ASSERT_TRUE(matched);
|
||||||
|
|
||||||
// Insert poor guest
|
// Insert poor guest
|
||||||
|
@ -133,7 +130,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds)
|
||||||
poorGuest->CashInPocket = 5;
|
poorGuest->CashInPocket = 5;
|
||||||
|
|
||||||
// Wait for poor guest to get in queue
|
// Wait for poor guest to get in queue
|
||||||
matched = updateUntil(*gs, 1000, [&]() { return poorGuest->State == PeepState::Queuing; });
|
matched = updateUntil(1000, [&]() { return poorGuest->State == PeepState::Queuing; });
|
||||||
ASSERT_TRUE(matched);
|
ASSERT_TRUE(matched);
|
||||||
|
|
||||||
// Raise the price of the ride to a value poor guest can't pay
|
// Raise the price of the ride to a value poor guest can't pay
|
||||||
|
@ -142,7 +139,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds)
|
||||||
// Verify that the poor guest goes back to walking without riding
|
// Verify that the poor guest goes back to walking without riding
|
||||||
// since it doesn't have enough money to pay for it
|
// since it doesn't have enough money to pay for it
|
||||||
bool enteredTheRide = false;
|
bool enteredTheRide = false;
|
||||||
matched = updateUntil(*gs, 10000, [&]() {
|
matched = updateUntil(10000, [&]() {
|
||||||
enteredTheRide |= poorGuest->State == PeepState::OnRide;
|
enteredTheRide |= poorGuest->State == PeepState::OnRide;
|
||||||
return poorGuest->State == PeepState::Walking || enteredTheRide;
|
return poorGuest->State == PeepState::Walking || enteredTheRide;
|
||||||
});
|
});
|
||||||
|
@ -159,9 +156,6 @@ TEST_F(PlayTests, CarRideWithOneCarOnlyAcceptsTwoGuests)
|
||||||
auto context = localStartGame(initStateFile);
|
auto context = localStartGame(initStateFile);
|
||||||
ASSERT_NE(context.get(), nullptr);
|
ASSERT_NE(context.get(), nullptr);
|
||||||
|
|
||||||
auto gs = context->GetGameState();
|
|
||||||
ASSERT_NE(gs, nullptr);
|
|
||||||
|
|
||||||
auto& gameState = GetGameState();
|
auto& gameState = GetGameState();
|
||||||
|
|
||||||
// Open park for free but charging for rides
|
// Open park for free but charging for rides
|
||||||
|
@ -191,7 +185,7 @@ TEST_F(PlayTests, CarRideWithOneCarOnlyAcceptsTwoGuests)
|
||||||
|
|
||||||
// Wait until one of them is riding
|
// Wait until one of them is riding
|
||||||
auto guestIsOnRide = [](auto* g) { return g->State == PeepState::OnRide; };
|
auto guestIsOnRide = [](auto* g) { return g->State == PeepState::OnRide; };
|
||||||
bool matched = updateUntil(*gs, 10000, [&]() { return std::any_of(guests.begin(), guests.end(), guestIsOnRide); });
|
bool matched = updateUntil(10000, [&]() { return std::any_of(guests.begin(), guests.end(), guestIsOnRide); });
|
||||||
ASSERT_TRUE(matched);
|
ASSERT_TRUE(matched);
|
||||||
|
|
||||||
// For the next few ticks at most two guests can be on the ride
|
// For the next few ticks at most two guests can be on the ride
|
||||||
|
@ -199,6 +193,6 @@ TEST_F(PlayTests, CarRideWithOneCarOnlyAcceptsTwoGuests)
|
||||||
{
|
{
|
||||||
int numRiding = std::count_if(guests.begin(), guests.end(), guestIsOnRide);
|
int numRiding = std::count_if(guests.begin(), guests.end(), guestIsOnRide);
|
||||||
ASSERT_LE(numRiding, 2);
|
ASSERT_LE(numRiding, 2);
|
||||||
gs->UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,6 @@ TEST_P(ReplayTests, RunReplay)
|
||||||
bool initialised = context->Initialise();
|
bool initialised = context->Initialise();
|
||||||
ASSERT_TRUE(initialised);
|
ASSERT_TRUE(initialised);
|
||||||
|
|
||||||
auto gs = context->GetGameState();
|
|
||||||
ASSERT_NE(gs, nullptr);
|
|
||||||
|
|
||||||
IReplayManager* replayManager = context->GetReplayManager();
|
IReplayManager* replayManager = context->GetReplayManager();
|
||||||
ASSERT_NE(replayManager, nullptr);
|
ASSERT_NE(replayManager, nullptr);
|
||||||
|
|
||||||
|
@ -92,7 +89,7 @@ TEST_P(ReplayTests, RunReplay)
|
||||||
|
|
||||||
while (replayManager->IsReplaying())
|
while (replayManager->IsReplaying())
|
||||||
{
|
{
|
||||||
gs->UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
if (replayManager->IsPlaybackStateMismatching())
|
if (replayManager->IsPlaybackStateMismatching())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,10 +138,9 @@ static void RecordGameStateSnapshot(std::unique_ptr<IContext>& context, MemorySt
|
||||||
|
|
||||||
static void AdvanceGameTicks(uint32_t ticks, std::unique_ptr<IContext>& context)
|
static void AdvanceGameTicks(uint32_t ticks, std::unique_ptr<IContext>& context)
|
||||||
{
|
{
|
||||||
auto* gameState = context->GetGameState();
|
|
||||||
for (uint32_t i = 0; i < ticks; i++)
|
for (uint32_t i = 0; i < ticks; i++)
|
||||||
{
|
{
|
||||||
gameState->UpdateLogic();
|
gameStateUpdateLogic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue