2017-07-23 01:19:09 +02:00
|
|
|
/*****************************************************************************
|
2024-01-01 12:52:28 +01:00
|
|
|
* Copyright (c) 2014-2024 OpenRCT2 developers
|
2018-06-15 14:07:34 +02:00
|
|
|
*
|
|
|
|
* For a complete list of all authors, please refer to contributors.md
|
|
|
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
|
|
|
*
|
|
|
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
|
|
|
*****************************************************************************/
|
2017-07-23 01:19:09 +02:00
|
|
|
|
|
|
|
#include "GameState.h"
|
2018-06-22 23:25:16 +02:00
|
|
|
|
2022-05-14 01:59:47 +02:00
|
|
|
#include "./peep/GuestPathfinding.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "Context.h"
|
2023-04-02 10:25:41 +02:00
|
|
|
#include "Date.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "Editor.h"
|
2018-11-19 23:10:54 +01:00
|
|
|
#include "Game.h"
|
2020-08-29 22:47:37 +02:00
|
|
|
#include "GameState.h"
|
2019-05-11 21:31:34 +02:00
|
|
|
#include "GameStateSnapshots.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "Input.h"
|
2018-06-22 23:25:16 +02:00
|
|
|
#include "OpenRCT2.h"
|
2018-12-06 06:34:27 +01:00
|
|
|
#include "ReplayManager.h"
|
2019-08-20 23:51:12 +02:00
|
|
|
#include "actions/GameAction.h"
|
2019-05-11 21:31:34 +02:00
|
|
|
#include "config/Config.h"
|
2021-11-24 15:58:01 +01:00
|
|
|
#include "entity/EntityRegistry.h"
|
2023-05-22 03:31:48 +02:00
|
|
|
#include "entity/EntityTweener.h"
|
2022-03-08 01:14:52 +01:00
|
|
|
#include "entity/PatrolArea.h"
|
2021-11-25 22:47:24 +01:00
|
|
|
#include "entity/Staff.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "interface/Screenshot.h"
|
2017-07-23 17:10:09 +02:00
|
|
|
#include "localisation/Date.h"
|
2018-05-27 17:11:54 +02:00
|
|
|
#include "localisation/Localisation.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "management/NewsItem.h"
|
|
|
|
#include "network/network.h"
|
2022-02-18 21:57:00 +01:00
|
|
|
#include "platform/Platform.h"
|
2022-01-18 19:21:20 +01:00
|
|
|
#include "profiling/Profiling.h"
|
2021-05-29 07:01:32 +02:00
|
|
|
#include "ride/Vehicle.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "scenario/Scenario.h"
|
2024-04-23 21:31:05 +02:00
|
|
|
#include "scenes/title/TitleScene.h"
|
|
|
|
#include "scenes/title/TitleSequencePlayer.h"
|
2018-03-19 00:35:58 +01:00
|
|
|
#include "scripting/ScriptEngine.h"
|
2018-06-22 23:25:16 +02:00
|
|
|
#include "ui/UiContext.h"
|
2018-05-27 17:11:54 +02:00
|
|
|
#include "windows/Intent.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
#include "world/Climate.h"
|
|
|
|
#include "world/MapAnimation.h"
|
|
|
|
#include "world/Park.h"
|
2018-05-27 17:11:54 +02:00
|
|
|
#include "world/Scenery.h"
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2018-08-12 13:50:40 +02:00
|
|
|
#include <algorithm>
|
2020-08-29 22:47:37 +02:00
|
|
|
#include <chrono>
|
2018-08-12 13:50:40 +02:00
|
|
|
|
2017-07-23 01:19:09 +02:00
|
|
|
using namespace OpenRCT2;
|
2018-03-19 00:35:58 +01:00
|
|
|
using namespace OpenRCT2::Scripting;
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2023-12-27 22:57:53 +01:00
|
|
|
static GameState_t _gameState{};
|
|
|
|
|
2023-12-27 23:53:43 +01:00
|
|
|
namespace OpenRCT2
|
2023-12-27 22:57:53 +01:00
|
|
|
{
|
2023-12-27 23:53:43 +01:00
|
|
|
GameState_t& GetGameState()
|
|
|
|
{
|
|
|
|
return _gameState;
|
|
|
|
}
|
2017-07-23 02:06:24 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
/**
|
|
|
|
* Initialises the map, park etc. basically all S6 data.
|
|
|
|
*/
|
|
|
|
void gameStateInitAll(GameState_t& gameState, const TileCoordsXY& mapSize)
|
|
|
|
{
|
|
|
|
PROFILED_FUNCTION();
|
2022-01-18 19:21:20 +01:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
gInMapInitCode = true;
|
|
|
|
gameState.CurrentTicks = 0;
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
MapInit(mapSize);
|
2024-03-26 21:35:55 +01:00
|
|
|
Park::Initialise(gameState);
|
2024-03-26 15:08:17 +01:00
|
|
|
FinanceInit();
|
|
|
|
BannerInit(gameState);
|
|
|
|
RideInitAll();
|
|
|
|
ResetAllEntities();
|
|
|
|
UpdateConsolidatedPatrolAreas();
|
|
|
|
ResetDate();
|
|
|
|
ClimateReset(ClimateType::CoolAndWet);
|
|
|
|
News::InitQueue();
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
gInMapInitCode = false;
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
GetGameState().NextGuestNumber = 1;
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
ContextInit();
|
|
|
|
ScenerySetDefaultPlacementConfiguration();
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
auto intent = Intent(INTENT_ACTION_CLEAR_TILE_INSPECTOR_CLIPBOARD);
|
|
|
|
ContextBroadcastIntent(&intent);
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
LoadPalette();
|
2021-10-27 14:21:14 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
CheatsReset();
|
|
|
|
ClearRestrictedScenery();
|
2022-02-19 17:32:08 +01:00
|
|
|
|
|
|
|
#ifdef ENABLE_SCRIPTING
|
2024-03-26 15:08:17 +01:00
|
|
|
auto& scriptEngine = GetContext()->GetScriptEngine();
|
|
|
|
scriptEngine.ClearParkStorage();
|
2022-02-19 17:32:08 +01:00
|
|
|
#endif
|
2023-05-22 03:31:48 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
EntityTweener::Get().Reset();
|
|
|
|
}
|
2018-05-27 17:11:54 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
/**
|
|
|
|
* Function will be called every kGameUpdateTimeMS.
|
|
|
|
* 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,
|
|
|
|
* another influence can be the game speed setting.
|
|
|
|
*/
|
|
|
|
void gameStateTick()
|
|
|
|
{
|
|
|
|
PROFILED_FUNCTION();
|
2022-01-18 19:21:20 +01:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Normal game play will update only once every kGameUpdateTimeMS
|
|
|
|
uint32_t numUpdates = 1;
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// 0x006E3AEC // screen_game_process_mouse_input();
|
|
|
|
ScreenshotCheck();
|
|
|
|
GameHandleKeyboardInput();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
if (GameIsNotPaused() && gPreviewingTitleSequenceInGame)
|
2018-06-02 13:33:20 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
auto player = GetContext()->GetUiContext()->GetTitleSequencePlayer();
|
|
|
|
if (player != nullptr)
|
|
|
|
{
|
|
|
|
player->Update();
|
|
|
|
}
|
2018-06-02 13:33:20 +02:00
|
|
|
}
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
NetworkUpdate();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
if (NetworkGetMode() == NETWORK_MODE_CLIENT && NetworkGetStatus() == NETWORK_STATUS_CONNECTED
|
|
|
|
&& NetworkGetAuthstatus() == NetworkAuth::Ok)
|
2019-08-06 00:28:45 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
numUpdates = std::clamp<uint32_t>(NetworkGetServerTick() - GetGameState().CurrentTicks, 0, 10);
|
2019-08-06 00:28:45 +02:00
|
|
|
}
|
2024-03-26 15:08:17 +01:00
|
|
|
else
|
2017-07-23 01:19:09 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
// Determine how many times we need to update the game
|
|
|
|
if (gGameSpeed > 1)
|
|
|
|
{
|
|
|
|
// Update more often if game speed is above normal.
|
|
|
|
numUpdates = 1 << (gGameSpeed - 1);
|
|
|
|
}
|
2017-07-23 01:19:09 +02:00
|
|
|
}
|
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
bool isPaused = GameIsPaused();
|
|
|
|
if (NetworkGetMode() == NETWORK_MODE_SERVER && gConfigNetwork.PauseServerIfNoClients)
|
2018-09-23 23:40:47 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
// If we are headless we always have 1 player (host), pause if no one else is around.
|
|
|
|
if (gOpenRCT2Headless && NetworkGetNumPlayers() == 1)
|
|
|
|
{
|
|
|
|
isPaused |= true;
|
|
|
|
}
|
2018-09-23 23:40:47 +02:00
|
|
|
}
|
2021-06-30 20:51:04 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
bool didRunSingleFrame = false;
|
|
|
|
if (isPaused)
|
|
|
|
{
|
|
|
|
if (gDoSingleUpdate && NetworkGetMode() == NETWORK_MODE_NONE)
|
2021-06-30 20:51:04 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
didRunSingleFrame = true;
|
|
|
|
PauseToggle();
|
|
|
|
numUpdates = 1;
|
2021-06-30 20:51:04 +02:00
|
|
|
}
|
2024-03-26 15:08:17 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// 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();
|
|
|
|
}
|
2021-06-30 20:51:04 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Keep updating the money effect even when paused.
|
|
|
|
UpdateMoneyEffect();
|
2023-12-23 15:04:25 +01:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Update the animation list. Note this does not
|
|
|
|
// increment the map animation.
|
|
|
|
MapAnimationInvalidateAll();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Post-tick network update
|
|
|
|
NetworkProcessPending();
|
2019-08-20 23:51:12 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Post-tick game actions.
|
|
|
|
GameActions::ProcessQueue();
|
|
|
|
}
|
2018-09-23 23:40:47 +02:00
|
|
|
}
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Update the game one or more times
|
|
|
|
for (uint32_t i = 0; i < numUpdates; i++)
|
2017-07-23 01:19:09 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
gameStateUpdateLogic();
|
|
|
|
if (gGameSpeed == 1)
|
2017-07-23 01:19:09 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
if (InputGetState() == InputState::Reset || InputGetState() == InputState::Normal)
|
|
|
|
{
|
|
|
|
if (InputTestFlag(INPUT_FLAG_VIEWPORT_SCROLLING))
|
|
|
|
{
|
|
|
|
InputSetFlag(INPUT_FLAG_VIEWPORT_SCROLLING, false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2017-07-23 01:19:09 +02:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-03-26 15:08:17 +01:00
|
|
|
// Don't call UpdateLogic again if the game was just paused.
|
|
|
|
isPaused |= GameIsPaused();
|
|
|
|
if (isPaused)
|
2017-07-23 01:19:09 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
NetworkFlush();
|
2021-05-16 13:14:29 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
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;
|
2017-07-23 01:19:09 +02:00
|
|
|
}
|
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
static void gameStateCreateStateSnapshot()
|
2017-07-23 01:19:09 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
PROFILED_FUNCTION();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
IGameStateSnapshots* snapshots = GetContext()->GetGameStateSnapshots();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
auto& snapshot = snapshots->CreateSnapshot();
|
|
|
|
snapshots->Capture(snapshot);
|
|
|
|
snapshots->LinkSnapshot(snapshot, GetGameState().CurrentTicks, ScenarioRandState().s0);
|
2018-09-23 23:40:47 +02:00
|
|
|
}
|
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
void gameStateUpdateLogic()
|
|
|
|
{
|
|
|
|
PROFILED_FUNCTION();
|
2022-01-18 19:21:20 +01:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
gInUpdateCode = true;
|
2023-06-01 00:25:07 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
gScreenAge++;
|
|
|
|
if (gScreenAge == 0)
|
|
|
|
gScreenAge--;
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
GetContext()->GetReplayManager()->Update();
|
2018-12-06 06:34:27 +01:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
NetworkUpdate();
|
2019-08-08 17:49:30 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
if (NetworkGetMode() == NETWORK_MODE_SERVER)
|
2019-05-11 21:31:34 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
if (NetworkGamestateSnapshotsEnabled())
|
|
|
|
{
|
|
|
|
gameStateCreateStateSnapshot();
|
|
|
|
}
|
2019-05-11 21:31:34 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Send current tick out.
|
|
|
|
NetworkSendTick();
|
2019-11-17 23:26:32 +01:00
|
|
|
}
|
2024-03-26 15:08:17 +01:00
|
|
|
else if (NetworkGetMode() == NETWORK_MODE_CLIENT)
|
2019-05-11 21:31:34 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
// Don't run past the server, this condition can happen during map changes.
|
|
|
|
if (NetworkGetServerTick() == GetGameState().CurrentTicks)
|
2019-05-11 21:31:34 +02:00
|
|
|
{
|
2024-03-26 15:08:17 +01:00
|
|
|
gInUpdateCode = false;
|
|
|
|
return;
|
|
|
|
}
|
2019-05-11 21:31:34 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// 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();
|
|
|
|
}
|
2019-05-11 21:31:34 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
auto& gameState = GetGameState();
|
2020-04-24 16:58:01 +02:00
|
|
|
#ifdef ENABLE_SCRIPTING
|
2024-03-26 15:08:17 +01:00
|
|
|
// Stash the current day number before updating the date so that we
|
|
|
|
// know if the day number changes on this tick.
|
|
|
|
auto day = gameState.Date.GetDay();
|
2020-02-23 13:55:48 +01:00
|
|
|
#endif
|
2020-02-18 23:31:54 +01:00
|
|
|
|
2024-03-26 17:32:36 +01:00
|
|
|
DateUpdate(gameState);
|
2024-03-26 15:08:17 +01:00
|
|
|
|
|
|
|
ScenarioUpdate(gameState);
|
|
|
|
ClimateUpdate();
|
|
|
|
MapUpdateTiles();
|
|
|
|
// Temporarily remove provisional paths to prevent peep from interacting with them
|
|
|
|
MapRemoveProvisionalElements();
|
|
|
|
MapUpdatePathWideFlags();
|
|
|
|
PeepUpdateAll();
|
|
|
|
MapRestoreProvisionalElements();
|
|
|
|
VehicleUpdateAll();
|
|
|
|
UpdateAllMiscEntities();
|
|
|
|
Ride::UpdateAll();
|
|
|
|
|
|
|
|
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR))
|
|
|
|
{
|
2024-03-26 21:35:55 +01:00
|
|
|
Park::Update(gameState, gameState.Date);
|
2024-03-26 15:08:17 +01:00
|
|
|
}
|
2017-07-23 02:06:24 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
ResearchUpdate();
|
|
|
|
RideRatingsUpdateAll();
|
|
|
|
RideMeasurementsUpdate();
|
|
|
|
News::UpdateCurrentItem();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
MapAnimationInvalidateAll();
|
|
|
|
VehicleSoundsUpdate();
|
|
|
|
PeepUpdateCrowdNoise();
|
|
|
|
ClimateUpdateSound();
|
|
|
|
EditorOpenWindowsForCurrentStep();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Update windows
|
|
|
|
// WindowDispatchUpdateAll();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
// Start autosave timer after update
|
2024-04-04 18:18:25 +02:00
|
|
|
if (gLastAutoSaveUpdate == kAutosavePause)
|
2024-03-26 15:08:17 +01:00
|
|
|
{
|
|
|
|
gLastAutoSaveUpdate = Platform::GetTicks();
|
|
|
|
}
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
GameActions::ProcessQueue();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
NetworkProcessPending();
|
|
|
|
NetworkFlush();
|
2017-07-23 01:19:09 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
gameState.CurrentTicks++;
|
2020-05-11 04:24:15 +02:00
|
|
|
|
|
|
|
#ifdef ENABLE_SCRIPTING
|
2024-03-26 15:08:17 +01:00
|
|
|
auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine();
|
|
|
|
hookEngine.Call(HOOK_TYPE::INTERVAL_TICK, true);
|
2020-05-11 04:24:15 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
if (day != gameState.Date.GetDay())
|
|
|
|
{
|
|
|
|
hookEngine.Call(HOOK_TYPE::INTERVAL_DAY, true);
|
|
|
|
}
|
2020-05-11 04:24:15 +02:00
|
|
|
#endif
|
2020-08-29 22:47:37 +02:00
|
|
|
|
2024-03-26 15:08:17 +01:00
|
|
|
gInUpdateCode = false;
|
|
|
|
}
|
|
|
|
} // namespace OpenRCT2
|