From fd80b4c82254e455d05c2d01b70842a3a8b23d58 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 2 Apr 2023 10:25:41 +0200 Subject: [PATCH] Refactor and clean up date handling (#19666) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor and clean up date handling * Remove gDate, remove direct access to days_in_month * Adjust the MultiLaunch test * Bump network version --------- Co-authored-by: ζeh Matt <5415177+ZehMatt@users.noreply.github.com> --- src/openrct2-ui/interface/Graph.cpp | 17 +-- src/openrct2-ui/windows/Cheats.cpp | 18 ++- src/openrct2-ui/windows/Finances.cpp | 10 +- src/openrct2-ui/windows/GameBottomToolbar.cpp | 15 +-- src/openrct2/Date.cpp | 52 +++++++- src/openrct2/Date.h | 48 ++++++++ src/openrct2/GameState.cpp | 21 +++- src/openrct2/GameState.h | 2 + src/openrct2/actions/ParkSetDateAction.cpp | 5 +- src/openrct2/actions/RideCreateAction.cpp | 2 +- src/openrct2/actions/StaffHireNewAction.cpp | 2 +- src/openrct2/entity/Duck.cpp | 2 +- src/openrct2/entity/Staff.cpp | 2 +- src/openrct2/interface/InteractiveConsole.cpp | 13 +- src/openrct2/localisation/Date.h | 53 +------- .../localisation/Localisation.Date.cpp | 115 +++--------------- src/openrct2/localisation/Localisation.cpp | 56 --------- src/openrct2/localisation/Localisation.h | 3 - src/openrct2/management/Finance.cpp | 4 +- src/openrct2/management/NewsItem.cpp | 5 +- src/openrct2/management/Research.cpp | 9 +- src/openrct2/network/NetworkBase.cpp | 2 +- .../network/NetworkServerAdvertiser.cpp | 3 +- src/openrct2/park/ParkFile.cpp | 16 ++- src/openrct2/platform/Platform.Linux.cpp | 1 + src/openrct2/platform/Platform.Posix.cpp | 2 +- src/openrct2/platform/Platform.Win32.cpp | 1 + src/openrct2/platform/Platform.h | 8 +- src/openrct2/platform/Platform.macOS.mm | 4 +- src/openrct2/platform/Shared.cpp | 1 + src/openrct2/rct1/S4Importer.cpp | 3 +- src/openrct2/rct2/S6Importer.cpp | 3 +- src/openrct2/ride/Ride.cpp | 6 +- src/openrct2/scenario/Scenario.cpp | 22 ++-- .../scripting/bindings/world/ScDate.hpp | 6 +- src/openrct2/world/Climate.cpp | 6 +- test/tests/MultiLaunch.cpp | 5 +- 37 files changed, 241 insertions(+), 302 deletions(-) diff --git a/src/openrct2-ui/interface/Graph.cpp b/src/openrct2-ui/interface/Graph.cpp index 007d5a3279..d64299ce1f 100644 --- a/src/openrct2-ui/interface/Graph.cpp +++ b/src/openrct2-ui/interface/Graph.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -17,8 +18,9 @@ namespace Graph { static void DrawMonths(DrawPixelInfo* dpi, const uint8_t* history, int32_t count, const ScreenCoordsXY& origCoords) { - int32_t currentMonth = DateGetMonth(gDateMonthsElapsed); - int32_t currentDay = gDateMonthTicks; + auto& date = GetDate(); + int32_t currentMonth = date.GetMonth(); + int32_t currentDay = date.GetMonthTicks(); int32_t yearOver32 = (currentMonth * 4) + (currentDay >> 14) - 31; auto screenCoords = origCoords; for (int32_t i = count - 1; i >= 0; i--) @@ -152,13 +154,12 @@ namespace Graph { static void DrawMonths(DrawPixelInfo* dpi, const money64* history, int32_t count, const ScreenCoordsXY& origCoords) { - int32_t i, yearOver32, currentMonth, currentDay; - - currentMonth = DateGetMonth(gDateMonthsElapsed); - currentDay = gDateMonthTicks; - yearOver32 = (currentMonth * 4) + (currentDay >> 14) - 31; + auto& date = GetDate(); + int32_t currentMonth = date.GetMonth(); + int32_t currentDay = date.GetMonthTicks(); + int32_t yearOver32 = (currentMonth * 4) + (currentDay >> 14) - 31; auto screenCoords = origCoords; - for (i = count - 1; i >= 0; i--) + for (int32_t i = count - 1; i >= 0; i--) { if (history[i] != MONEY64_UNDEFINED && yearOver32 % 4 == 0) { diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index c050ee1fd4..39a1280e9a 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -31,6 +31,8 @@ constexpr auto CHEATS_MONEY_DEFAULT = 10000.00_GBP; constexpr auto CHEATS_MONEY_INCREMENT_DIV = 5000.00_GBP; +using OpenRCT2::Date; + // clang-format off enum { @@ -724,37 +726,41 @@ private: case WIDX_MONTH_UP: _monthSpinnerValue++; _monthSpinnerValue = std::clamp(_monthSpinnerValue, 1, static_cast(MONTH_COUNT)); - _daySpinnerValue = std::clamp(_daySpinnerValue, 1, static_cast(days_in_month[_monthSpinnerValue - 1])); + _daySpinnerValue = std::clamp( + _daySpinnerValue, 1, static_cast(Date::GetDaysInMonth(_monthSpinnerValue - 1))); InvalidateWidget(WIDX_MONTH_BOX); InvalidateWidget(WIDX_DAY_BOX); break; case WIDX_MONTH_DOWN: _monthSpinnerValue--; _monthSpinnerValue = std::clamp(_monthSpinnerValue, 1, static_cast(MONTH_COUNT)); - _daySpinnerValue = std::clamp(_daySpinnerValue, 1, static_cast(days_in_month[_monthSpinnerValue - 1])); + _daySpinnerValue = std::clamp( + _daySpinnerValue, 1, static_cast(Date::GetDaysInMonth(_monthSpinnerValue - 1))); InvalidateWidget(WIDX_MONTH_BOX); InvalidateWidget(WIDX_DAY_BOX); break; case WIDX_DAY_UP: _daySpinnerValue++; - _daySpinnerValue = std::clamp(_daySpinnerValue, 1, static_cast(days_in_month[_monthSpinnerValue - 1])); + _daySpinnerValue = std::clamp( + _daySpinnerValue, 1, static_cast(Date::GetDaysInMonth(_monthSpinnerValue - 1))); InvalidateWidget(WIDX_DAY_BOX); break; case WIDX_DAY_DOWN: _daySpinnerValue--; - _daySpinnerValue = std::clamp(_daySpinnerValue, 1, static_cast(days_in_month[_monthSpinnerValue - 1])); + _daySpinnerValue = std::clamp( + _daySpinnerValue, 1, static_cast(Date::GetDaysInMonth(_monthSpinnerValue - 1))); InvalidateWidget(WIDX_DAY_BOX); break; case WIDX_DATE_SET: { - auto setDateAction = ParkSetDateAction(_yearSpinnerValue, _monthSpinnerValue, _daySpinnerValue); + auto setDateAction = ParkSetDateAction(_yearSpinnerValue - 1, _monthSpinnerValue - 1, _daySpinnerValue - 1); GameActions::Execute(&setDateAction); WindowInvalidateByClass(WindowClass::BottomToolbar); break; } case WIDX_DATE_RESET: { - auto setDateAction = ParkSetDateAction(1, 1, 1); + auto setDateAction = ParkSetDateAction(0, 0, 0); GameActions::Execute(&setDateAction); WindowInvalidateByClass(WindowClass::BottomToolbar); InvalidateWidget(WIDX_YEAR_BOX); diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 7818028718..23d3067a97 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -224,13 +224,13 @@ static_assert(std::size(_windowFinancesPageHoldDownWidgets) == WINDOW_FINANCES_P class FinancesWindow final : public Window { private: - int32_t _lastPaintedMonth; + uint32_t _lastPaintedMonth; public: void OnOpen() override { SetPage(WINDOW_FINANCES_PAGE_SUMMARY); - _lastPaintedMonth = std::numeric_limits::max(); + _lastPaintedMonth = std::numeric_limits::max(); ResearchUpdateUncompletedTypes(); } @@ -381,7 +381,7 @@ public: } // Expenditure / Income values for each month - uint16_t currentMonthYear = static_cast(gDateMonthsElapsed); + auto currentMonthYear = GetDate().GetMonthsElapsed(); for (int32_t i = SummaryMaxAvailableMonth(); i >= 0; i--) { screenCoords.y = 0; @@ -522,7 +522,7 @@ public: ft.Add(gBankLoan); // Keep up with new months being added in the first two years. - if (gDateMonthsElapsed != _lastPaintedMonth) + if (GetDate().GetMonthsElapsed() != _lastPaintedMonth) InitialiseScrollPosition(WIDX_SUMMARY_SCROLL, 0); } @@ -593,7 +593,7 @@ public: uint16_t SummaryMaxAvailableMonth() { - return std::min(gDateMonthsElapsed, EXPENDITURE_TABLE_MONTH_COUNT - 1); + return std::min(GetDate().GetMonthsElapsed(), EXPENDITURE_TABLE_MONTH_COUNT - 1); } #pragma endregion diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index c036abf6e4..913f12e953 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -190,7 +190,6 @@ static void WindowGameBottomToolbarMouseup(WindowBase* w, WidgetIndex widgetInde static OpenRCT2String WindowGameBottomToolbarTooltip(WindowBase* w, const WidgetIndex widgetIndex, const StringId fallback) { - int32_t month, day; auto ft = Formatter(); switch (widgetIndex) @@ -202,13 +201,6 @@ static OpenRCT2String WindowGameBottomToolbarTooltip(WindowBase* w, const Widget case WIDX_PARK_RATING: ft.Add(gParkRating); break; - case WIDX_DATE: - month = DateGetMonth(gDateMonthsElapsed); - day = ((gDateMonthTicks * days_in_month[month]) >> 16) & 0xFF; - - ft.Add(DateDayNames[day]); - ft.Add(DateGameMonthNames[month]); - break; } return { fallback, ft }; } @@ -496,9 +488,10 @@ static void WindowGameBottomToolbarDrawRightPanel(DrawPixelInfo* dpi, WindowBase window_game_bottom_toolbar_widgets[WIDX_RIGHT_OUTSET].top + w->windowPos.y + 2 }; // Date - int32_t year = DateGetYear(gDateMonthsElapsed) + 1; - int32_t month = DateGetMonth(gDateMonthsElapsed); - int32_t day = ((gDateMonthTicks * days_in_month[month]) >> 16) & 0xFF; + auto& date = GetDate(); + int32_t year = date.GetYear() + 1; + int32_t month = date.GetMonth(); + int32_t day = date.GetDay(); colour_t colour = (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_DATE diff --git a/src/openrct2/Date.cpp b/src/openrct2/Date.cpp index d3743e7b36..e2f7771aa0 100644 --- a/src/openrct2/Date.cpp +++ b/src/openrct2/Date.cpp @@ -9,7 +9,10 @@ #include "localisation/Date.h" +#include "Context.h" #include "Date.h" +#include "Game.h" +#include "GameState.h" #include "core/Guard.hpp" #include @@ -21,6 +24,13 @@ constexpr int32_t MASK_WEEK_TICKS = 0x3FFF; constexpr int32_t MASK_FORTNIGHT_TICKS = 0x7FFF; constexpr int32_t MASK_MONTH_TICKS = 0xFFFF; +// rct2: 0x00993988 +static const int16_t days_in_month[MONTH_COUNT] = { + 31, 30, 31, 30, 31, 31, 30, 31, +}; + +RealWorldTime gRealTimeOfDay; + Date::Date(uint32_t monthsElapsed, uint16_t monthTicks) : _monthTicks(monthTicks) , _monthsElapsed(monthsElapsed) @@ -29,17 +39,17 @@ Date::Date(uint32_t monthsElapsed, uint16_t monthTicks) Date Date::FromYMD(int32_t year, int32_t month, int32_t day) { - // Year, months - Guard::ArgumentInRange(month, 0, MONTH_COUNT - 1); - int32_t monthsElapsed = (year * MONTH_COUNT) + month; + year = std::clamp(year, 0, MAX_YEAR - 1); + month = std::clamp(month, 0, static_cast(MONTH_COUNT) - 1); + auto daysInMonth = days_in_month[month]; + day = std::clamp(day, 0, daysInMonth - 1); + int32_t monthsElapsed = (year * MONTH_COUNT) + month; // Day int32_t monthTicks = 0; if (day != 0) { - auto daysInMonth = GetDaysInMonth(month); - day = std::clamp(day, 0, daysInMonth - 1); - monthTicks = (day << 16) / daysInMonth; + monthTicks = ((day << 16) / daysInMonth) + MONTH_TICKS_INCREMENT; } return Date(monthsElapsed, monthTicks); @@ -119,3 +129,33 @@ int32_t Date::GetDaysInMonth(int32_t month) return days_in_month[month]; } + +int32_t DateGetMonth(int32_t months) +{ + return months % MONTH_COUNT; +} + +int32_t DateGetYear(int32_t months) +{ + return months / MONTH_COUNT; +} + +int32_t DateGetTotalMonths(int32_t month, int32_t year) +{ + return (year - 1) * MONTH_COUNT + month; +} + +void DateUpdateRealTimeOfDay() +{ + time_t timestamp = time(nullptr); + struct tm* now = localtime(×tamp); + + gRealTimeOfDay.second = now->tm_sec; + gRealTimeOfDay.minute = now->tm_min; + gRealTimeOfDay.hour = now->tm_hour; +} + +Date& GetDate() +{ + return OpenRCT2::GetContext()->GetGameState()->GetDate(); +} diff --git a/src/openrct2/Date.h b/src/openrct2/Date.h index 6942760456..33c6c1e0b2 100644 --- a/src/openrct2/Date.h +++ b/src/openrct2/Date.h @@ -11,6 +11,31 @@ #include "common.h" +constexpr int32_t MAX_YEAR = 8192; +constexpr int32_t TICKS_PER_MONTH = 0x10000; + +enum +{ + MONTH_MARCH, + MONTH_APRIL, + MONTH_MAY, + MONTH_JUNE, + MONTH_JULY, + MONTH_AUGUST, + MONTH_SEPTEMBER, + MONTH_OCTOBER, + + MONTH_COUNT +}; + +enum +{ + DATE_FORMAT_DAY_MONTH_YEAR, + DATE_FORMAT_MONTH_DAY_YEAR, + DATE_FORMAT_YEAR_MONTH_DAY, + DATE_FORMAT_YEAR_DAY_MONTH +}; + namespace OpenRCT2 { /** @@ -44,3 +69,26 @@ namespace OpenRCT2 static int32_t GetDaysInMonth(int32_t month); }; } // namespace OpenRCT2 + +struct RealWorldDate +{ + uint8_t day; + uint8_t month; + int16_t year; + uint8_t day_of_week; +}; + +struct RealWorldTime +{ + uint8_t second; + uint8_t minute; + uint8_t hour; +}; + +OpenRCT2::Date& GetDate(); +extern RealWorldTime gRealTimeOfDay; + +int32_t DateGetMonth(int32_t months); +int32_t DateGetYear(int32_t months); +int32_t DateGetTotalMonths(int32_t month, int32_t year); +void DateUpdateRealTimeOfDay(); diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index a3670dc24a..e42246cc45 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -11,6 +11,7 @@ #include "./peep/GuestPathfinding.h" #include "Context.h" +#include "Date.h" #include "Editor.h" #include "Game.h" #include "GameState.h" @@ -70,7 +71,7 @@ void GameState::InitAll(const TileCoordsXY& mapSize) RideInitAll(); ResetAllEntities(); UpdateConsolidatedPatrolAreas(); - DateReset(); + ResetDate(); ClimateReset(ClimateType::CoolAndWet); News::InitQueue(); @@ -313,8 +314,7 @@ void GameState::UpdateLogic(LogicTimings* timings) auto day = _date.GetDay(); #endif - DateUpdate(); - _date = Date(static_cast(gDateMonthsElapsed), gDateMonthTicks); + _date.Update(); report_time(LogicTimePart::Date); ScenarioUpdate(); @@ -408,3 +408,18 @@ void GameState::CreateStateSnapshot() snapshots->Capture(snapshot); snapshots->LinkSnapshot(snapshot, gCurrentTicks, ScenarioRandState().s0); } + +void GameState::SetDate(Date newDate) +{ + _date = newDate; +} + +/** + * + * rct2: 0x006C4494 + */ +void GameState::ResetDate() +{ + _date = OpenRCT2::Date(); + gCurrentRealTimeTicks = 0; +} diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index 1ad0cb7d5e..3cc2d29b40 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -86,6 +86,8 @@ namespace OpenRCT2 void InitAll(const TileCoordsXY& mapSize); void Tick(); void UpdateLogic(LogicTimings* timings = nullptr); + void SetDate(Date newDate); + void ResetDate(); private: void CreateStateSnapshot(); diff --git a/src/openrct2/actions/ParkSetDateAction.cpp b/src/openrct2/actions/ParkSetDateAction.cpp index c0a0367596..31d6abe7f6 100644 --- a/src/openrct2/actions/ParkSetDateAction.cpp +++ b/src/openrct2/actions/ParkSetDateAction.cpp @@ -10,6 +10,7 @@ #include "ParkSetDateAction.h" #include "../Context.h" +#include "../GameState.h" #include "../core/MemoryStream.h" #include "../localisation/StringIds.h" #include "../management/Finance.h" @@ -44,7 +45,7 @@ void ParkSetDateAction::Serialise(DataSerialiser& stream) GameActions::Result ParkSetDateAction::Query() const { - if (_year <= 0 || _year > MAX_YEAR || _month <= 0 || _month > MONTH_COUNT || _day <= 0 || _day > 31) + if (_year < 0 || _year >= MAX_YEAR || _month < 0 || _month >= MONTH_COUNT || _day < 0 || _day >= 31) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); } @@ -54,6 +55,6 @@ GameActions::Result ParkSetDateAction::Query() const GameActions::Result ParkSetDateAction::Execute() const { - DateSet(_year, _month, _day); + OpenRCT2::GetContext()->GetGameState()->SetDate(OpenRCT2::Date::FromYMD(_year, _month, _day)); return GameActions::Result(); } diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 0d70ab429b..eff9a6507a 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -286,7 +286,7 @@ GameActions::Result RideCreateAction::Execute() const ride->num_riders = 0; ride->slide_in_use = 0; ride->maze_tiles = 0; - ride->build_date = gDateMonthsElapsed; + ride->build_date = GetDate().GetMonthsElapsed(); ride->music_tune_id = TUNE_ID_NULL; ride->breakdown_reason = 255; diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index 10a979c03c..2eaeda3407 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -190,7 +190,7 @@ GameActions::Result StaffHireNewAction::QueryExecute(bool execute) const } // Staff uses this - newPeep->As()->SetHireDate(gDateMonthsElapsed); + newPeep->As()->SetHireDate(GetDate().GetMonthsElapsed()); newPeep->PathfindGoal.x = 0xFF; newPeep->PathfindGoal.y = 0xFF; newPeep->PathfindGoal.z = 0xFF; diff --git a/src/openrct2/entity/Duck.cpp b/src/openrct2/entity/Duck.cpp index ab2d06b21d..59fd138158 100644 --- a/src/openrct2/entity/Duck.cpp +++ b/src/openrct2/entity/Duck.cpp @@ -171,7 +171,7 @@ void Duck::UpdateSwim() } else { - int32_t currentMonth = DateGetMonth(gDateMonthsElapsed); + int32_t currentMonth = GetDate().GetMonth(); if (currentMonth >= MONTH_SEPTEMBER && (randomNumber >> 16) < 218) { state = DuckState::FlyAway; diff --git a/src/openrct2/entity/Staff.cpp b/src/openrct2/entity/Staff.cpp index eae925d0f1..868c18d642 100644 --- a/src/openrct2/entity/Staff.cpp +++ b/src/openrct2/entity/Staff.cpp @@ -265,7 +265,7 @@ void Staff::ResetStats() { for (auto peep : EntityList()) { - peep->SetHireDate(gDateMonthsElapsed); + peep->SetHireDate(GetDate().GetMonthsElapsed()); peep->StaffLawnsMown = 0; peep->StaffRidesFixed = 0; peep->StaffGardensWatered = 0; diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 0d10c88ab0..289d2be8b9 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -10,6 +10,7 @@ #include "InteractiveConsole.h" #include "../Context.h" +#include "../Date.h" #include "../EditorObjectSelectionSession.h" #include "../Game.h" #include "../OpenRCT2.h" @@ -18,6 +19,7 @@ #include "../Version.h" #include "../actions/CheatSetAction.h" #include "../actions/ClimateSetAction.h" +#include "../actions/ParkSetDateAction.h" #include "../actions/ParkSetParameterAction.h" #include "../actions/RideFreezeRatingAction.h" #include "../actions/RideSetPriceAction.h" @@ -76,6 +78,7 @@ #endif using arguments_t = std::vector; +using OpenRCT2::Date; static constexpr const char* ClimateNames[] = { "cool_and_wet", @@ -1452,7 +1455,7 @@ static int32_t ConsoleCommandForceDate([[maybe_unused]] InteractiveConsole& cons // YYYY (no month provided, preserve existing month) if (argv.size() == 1) { - month = gDateMonthsElapsed % MONTH_COUNT + 1; + month = GetDate().GetMonth() + 1; } // YYYY MM or YYYY MM DD (month provided) @@ -1469,21 +1472,21 @@ static int32_t ConsoleCommandForceDate([[maybe_unused]] InteractiveConsole& cons // YYYY OR YYYY MM (no day provided, preserve existing day) if (argv.size() <= 2) { - day = std::clamp( - gDateMonthTicks / (TICKS_PER_MONTH / days_in_month[month - 1]) + 1, 1, static_cast(days_in_month[month - 1])); + day = std::clamp(GetDate().GetDay() + 1, 1, static_cast(Date::GetDaysInMonth(month - 1))); } // YYYY MM DD (year, month, and day provided) if (argv.size() == 3) { day = atoi(argv[2].c_str()); - if (day < 1 || day > days_in_month[month - 1]) + if (day < 1 || day > Date::GetDaysInMonth(month - 1)) { return -1; } } - DateSet(year, month, day); + auto setDateAction = ParkSetDateAction(year - 1, month - 1, day - 1); + GameActions::Execute(&setDateAction); WindowInvalidateByClass(WindowClass::BottomToolbar); return 1; diff --git a/src/openrct2/localisation/Date.h b/src/openrct2/localisation/Date.h index 406b831571..32ce07d607 100644 --- a/src/openrct2/localisation/Date.h +++ b/src/openrct2/localisation/Date.h @@ -9,57 +9,12 @@ #pragma once +#include "../Date.h" #include "../common.h" -constexpr int32_t MAX_YEAR = 8192; -constexpr int32_t TICKS_PER_MONTH = 0x10000; - -enum -{ - MONTH_MARCH, - MONTH_APRIL, - MONTH_MAY, - MONTH_JUNE, - MONTH_JULY, - MONTH_AUGUST, - MONTH_SEPTEMBER, - MONTH_OCTOBER, - - MONTH_COUNT -}; - -enum -{ - DATE_FORMAT_DAY_MONTH_YEAR, - DATE_FORMAT_MONTH_DAY_YEAR, - DATE_FORMAT_YEAR_MONTH_DAY, - DATE_FORMAT_YEAR_DAY_MONTH -}; - -struct RealWorldTime -{ - uint8_t second; - uint8_t minute; - uint8_t hour; -}; - -extern const int16_t days_in_month[MONTH_COUNT]; extern const StringId DateFormatStringIDs[]; extern const StringId DateFormatStringFormatIds[]; -extern uint16_t gDateMonthTicks; -extern int32_t gDateMonthsElapsed; - -extern RealWorldTime gRealTimeOfDay; - -int32_t DateGetMonth(int32_t months); -int32_t DateGetYear(int32_t months); -int32_t DateGetTotalMonths(int32_t month, int32_t year); -void DateReset(); -void DateUpdate(); -void DateSet(int32_t year, int32_t month, int32_t day); -void DateUpdateRealTimeOfDay(); -bool DateIsDayStart(int32_t monthTicks); -bool DateIsWeekStart(int32_t monthTicks); -bool DateIsFortnightStart(int32_t monthTicks); -bool DateIsMonthStart(int32_t monthTicks); +extern const StringId DateDayNames[31]; +extern const StringId DateGameMonthNames[MONTH_COUNT]; +extern const StringId DateGameShortMonthNames[MONTH_COUNT]; diff --git a/src/openrct2/localisation/Localisation.Date.cpp b/src/openrct2/localisation/Localisation.Date.cpp index 6b95029501..1fcab7f2ae 100644 --- a/src/openrct2/localisation/Localisation.Date.cpp +++ b/src/openrct2/localisation/Localisation.Date.cpp @@ -7,21 +7,26 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "../Game.h" -#include "../profiling/Profiling.h" -#include "../util/Math.hpp" +#include "../common.h" #include "Date.h" #include "StringIds.h" -#include -#include +const StringId DateDayNames[] = { + STR_DATE_DAY_1, STR_DATE_DAY_2, STR_DATE_DAY_3, STR_DATE_DAY_4, STR_DATE_DAY_5, STR_DATE_DAY_6, STR_DATE_DAY_7, + STR_DATE_DAY_8, STR_DATE_DAY_9, STR_DATE_DAY_10, STR_DATE_DAY_11, STR_DATE_DAY_12, STR_DATE_DAY_13, STR_DATE_DAY_14, + STR_DATE_DAY_15, STR_DATE_DAY_16, STR_DATE_DAY_17, STR_DATE_DAY_18, STR_DATE_DAY_19, STR_DATE_DAY_20, STR_DATE_DAY_21, + STR_DATE_DAY_22, STR_DATE_DAY_23, STR_DATE_DAY_24, STR_DATE_DAY_25, STR_DATE_DAY_26, STR_DATE_DAY_27, STR_DATE_DAY_28, + STR_DATE_DAY_29, STR_DATE_DAY_30, STR_DATE_DAY_31, +}; -uint16_t gDateMonthTicks; -int32_t gDateMonthsElapsed; +const StringId DateGameMonthNames[MONTH_COUNT] = { + STR_MONTH_MARCH, STR_MONTH_APRIL, STR_MONTH_MAY, STR_MONTH_JUNE, + STR_MONTH_JULY, STR_MONTH_AUGUST, STR_MONTH_SEPTEMBER, STR_MONTH_OCTOBER, +}; -// rct2: 0x00993988 -const int16_t days_in_month[MONTH_COUNT] = { - 31, 30, 31, 30, 31, 31, 30, 31, +const StringId DateGameShortMonthNames[MONTH_COUNT] = { + STR_MONTH_SHORT_MAR, STR_MONTH_SHORT_APR, STR_MONTH_SHORT_MAY, STR_MONTH_SHORT_JUN, + STR_MONTH_SHORT_JUL, STR_MONTH_SHORT_AUG, STR_MONTH_SHORT_SEP, STR_MONTH_SHORT_OCT, }; const StringId DateFormatStringIDs[] = { @@ -37,93 +42,3 @@ const StringId DateFormatStringFormatIds[] = { STR_DATE_FORMAT_YMD, STR_DATE_FORMAT_YDM, }; - -RealWorldTime gRealTimeOfDay; - -int32_t DateGetMonth(int32_t months) -{ - return months % MONTH_COUNT; -} - -int32_t DateGetYear(int32_t months) -{ - return months / MONTH_COUNT; -} - -int32_t DateGetTotalMonths(int32_t month, int32_t year) -{ - return (year - 1) * MONTH_COUNT + month; -} - -/** - * - * rct2: 0x006C4494 - */ -void DateReset() -{ - gDateMonthsElapsed = 0; - gDateMonthTicks = 0; - gCurrentRealTimeTicks = 0; -} - -void DateSet(int32_t year, int32_t month, int32_t day) -{ - year = std::clamp(year, 1, MAX_YEAR); - month = std::clamp(month, 1, static_cast(MONTH_COUNT)); - day = std::clamp(day, 1, static_cast(days_in_month[month - 1])); - gDateMonthsElapsed = (year - 1) * MONTH_COUNT + month - 1; - gDateMonthTicks = TICKS_PER_MONTH / days_in_month[month - 1] * (day - 1) + 4; -} - -void DateUpdate() -{ - PROFILED_FUNCTION(); - - int32_t monthTicks = gDateMonthTicks + 4; - if (monthTicks >= TICKS_PER_MONTH) - { - gDateMonthTicks = 0; - gDateMonthsElapsed++; - } - else - { - gDateMonthTicks = Floor2(static_cast(monthTicks), 4); - } -} - -void DateUpdateRealTimeOfDay() -{ - time_t timestamp = time(nullptr); - struct tm* now = localtime(×tamp); - - gRealTimeOfDay.second = now->tm_sec; - gRealTimeOfDay.minute = now->tm_min; - gRealTimeOfDay.hour = now->tm_hour; -} - -bool DateIsDayStart(int32_t monthTicks) -{ - if (monthTicks < 4) - { - return false; - } - int32_t prevMonthTick = monthTicks - 4; - int32_t currentMonth = DateGetMonth(gDateMonthsElapsed); - int32_t currentDaysInMonth = days_in_month[currentMonth]; - return ((currentDaysInMonth * monthTicks) >> 16 != (currentDaysInMonth * prevMonthTick) >> 16); -} - -bool DateIsWeekStart(int32_t monthTicks) -{ - return (monthTicks & 0x3FFF) == 0; -} - -bool DateIsFortnightStart(int32_t monthTicks) -{ - return (monthTicks & 0x7FFF) == 0; -} - -bool DateIsMonthStart(int32_t monthTicks) -{ - return (monthTicks == 0); -} diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index 83aae3d3de..46dd4e1a1a 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -263,62 +263,6 @@ const StringId PeepThoughts[] = { STR_PEEP_THOUGHT_TYPE_EXCITED_DEPRECATED, STR_PEEP_THOUGHT_TYPE_HERE_WE_ARE, }; - -const StringId DateDayNames[] = { - STR_DATE_DAY_1, - STR_DATE_DAY_2, - STR_DATE_DAY_3, - STR_DATE_DAY_4, - STR_DATE_DAY_5, - STR_DATE_DAY_6, - STR_DATE_DAY_7, - STR_DATE_DAY_8, - STR_DATE_DAY_9, - STR_DATE_DAY_10, - STR_DATE_DAY_11, - STR_DATE_DAY_12, - STR_DATE_DAY_13, - STR_DATE_DAY_14, - STR_DATE_DAY_15, - STR_DATE_DAY_16, - STR_DATE_DAY_17, - STR_DATE_DAY_18, - STR_DATE_DAY_19, - STR_DATE_DAY_20, - STR_DATE_DAY_21, - STR_DATE_DAY_22, - STR_DATE_DAY_23, - STR_DATE_DAY_24, - STR_DATE_DAY_25, - STR_DATE_DAY_26, - STR_DATE_DAY_27, - STR_DATE_DAY_28, - STR_DATE_DAY_29, - STR_DATE_DAY_30, - STR_DATE_DAY_31, -}; - -const StringId DateGameMonthNames[MONTH_COUNT] = { - STR_MONTH_MARCH, - STR_MONTH_APRIL, - STR_MONTH_MAY, - STR_MONTH_JUNE, - STR_MONTH_JULY, - STR_MONTH_AUGUST, - STR_MONTH_SEPTEMBER, - STR_MONTH_OCTOBER, -}; - -const StringId DateGameShortMonthNames[MONTH_COUNT] = { - STR_MONTH_SHORT_MAR, - STR_MONTH_SHORT_APR, - STR_MONTH_SHORT_MAY, - STR_MONTH_SHORT_JUN, - STR_MONTH_SHORT_JUL, - STR_MONTH_SHORT_AUG, - STR_MONTH_SHORT_SEP, - STR_MONTH_SHORT_OCT, -}; // clang-format on std::string FormatStringID(StringId format, const void* args) diff --git a/src/openrct2/localisation/Localisation.h b/src/openrct2/localisation/Localisation.h index 3a250d3649..9f8be0b0a0 100644 --- a/src/openrct2/localisation/Localisation.h +++ b/src/openrct2/localisation/Localisation.h @@ -63,6 +63,3 @@ extern const StringId ResearchFundingLevelNames[4]; extern const StringId MarketingCampaignNames[ADVERTISING_CAMPAIGN_COUNT][3]; extern const StringId RideInspectionIntervalNames[]; extern const StringId PeepThoughts[174]; -extern const StringId DateDayNames[31]; -extern const StringId DateGameMonthNames[MONTH_COUNT]; -extern const StringId DateGameShortMonthNames[MONTH_COUNT]; diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index 2d5d872510..a66f9bd8b8 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -320,7 +320,7 @@ money64 FinanceGetCurrentCash() void FinanceShiftExpenditureTable() { // If EXPENDITURE_TABLE_MONTH_COUNT months have passed then is full, sum the oldest month - if (gDateMonthsElapsed >= EXPENDITURE_TABLE_MONTH_COUNT) + if (GetDate().GetMonthsElapsed() >= EXPENDITURE_TABLE_MONTH_COUNT) { money64 sum = 0; for (uint32_t i = 0; i < static_cast(ExpenditureType::Count); i++) @@ -363,7 +363,7 @@ void FinanceResetCashToInitial() money64 FinanceGetLastMonthShopProfit() { money64 profit = 0; - if (gDateMonthsElapsed != 0) + if (GetDate().GetMonthsElapsed() != 0) { const auto* lastMonthExpenditure = gExpenditureTable[1]; diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 0e6d3ec3d4..5bc950c452 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -323,13 +323,14 @@ News::Item* News::AddItemToQueue(ItemType type, StringId string_id, EntityId ass News::Item* News::AddItemToQueue(News::ItemType type, const utf8* text, uint32_t assoc) { + auto& date = GetDate(); News::Item* newsItem = gNewsItems.FirstOpenOrNewSlot(); newsItem->Type = type; newsItem->Flags = 0; newsItem->Assoc = assoc; // Make optional for Award, Money, Graph and Null newsItem->Ticks = 0; - newsItem->MonthYear = static_cast(gDateMonthsElapsed); - newsItem->Day = ((days_in_month[DateGetMonth(newsItem->MonthYear)] * gDateMonthTicks) >> 16) + 1; + newsItem->MonthYear = static_cast(date.GetMonthsElapsed()); + newsItem->Day = date.GetDay() + 1; newsItem->Text = text; return newsItem; diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 229cecb9e2..4295fbe42a 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -9,6 +9,7 @@ #include "Research.h" +#include "../Date.h" #include "../Game.h" #include "../OpenRCT2.h" #include "../actions/ParkSetResearchFundingAction.h" @@ -108,16 +109,18 @@ static void ResearchCalculateExpectedDate() } else { + auto& date = GetDate(); + int32_t progressRemaining = gResearchProgressStage == RESEARCH_STAGE_COMPLETING_DESIGN ? 0x10000 : 0x20000; progressRemaining -= gResearchProgress; int32_t daysRemaining = (progressRemaining / _researchRate[gResearchFundingLevel]) * 128; - int32_t expectedDay = gDateMonthTicks + (daysRemaining & 0xFFFF); + int32_t expectedDay = date.GetMonthTicks() + (daysRemaining & 0xFFFF); int32_t dayQuotient = expectedDay / 0x10000; int32_t dayRemainder = expectedDay % 0x10000; - int32_t expectedMonth = DateGetMonth(gDateMonthsElapsed + dayQuotient + (daysRemaining >> 16)); - expectedDay = (dayRemainder * days_in_month[expectedMonth]) >> 16; + int32_t expectedMonth = DateGetMonth(date.GetMonthsElapsed() + dayQuotient + (daysRemaining >> 16)); + expectedDay = (dayRemainder * Date::GetDaysInMonth(expectedMonth)) >> 16; gResearchExpectedDay = expectedDay; gResearchExpectedMonth = expectedMonth; diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 2649d94272..f7cbb8ed99 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -43,7 +43,7 @@ // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "0" +#define NETWORK_STREAM_VERSION "1" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index 10d107dc80..ed18f6752a 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -297,9 +297,10 @@ private: { "players", numPlayers }, }; + auto& date = GetDate(); json_t mapSize = { { "x", gMapSize.x - 2 }, { "y", gMapSize.y - 2 } }; json_t gameInfo = { - { "mapSize", mapSize }, { "day", gDateMonthTicks }, { "month", gDateMonthsElapsed }, + { "mapSize", mapSize }, { "day", date.GetMonthTicks() }, { "month", date.GetMonthsElapsed() }, { "guests", gNumGuestsInPark }, { "parkValue", gParkValue }, }; if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index e0a5a3b9b8..435bb6c562 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -479,8 +479,20 @@ namespace OpenRCT2 cs.Write(isPaused); } cs.ReadWrite(gCurrentTicks); - cs.ReadWrite(gDateMonthTicks); - cs.ReadWrite(gDateMonthsElapsed); + if (cs.GetMode() == OrcaStream::Mode::READING) + { + uint16_t monthTicks; + uint32_t monthsElapsed; + cs.ReadWrite(monthTicks); + cs.ReadWrite(monthsElapsed); + GetContext()->GetGameState()->SetDate(Date(monthsElapsed, monthTicks)); + } + else + { + auto& date = GetDate(); + cs.Write(date.GetMonthTicks()); + cs.Write(date.GetMonthsElapsed()); + } if (cs.GetMode() == OrcaStream::Mode::READING) { diff --git a/src/openrct2/platform/Platform.Linux.cpp b/src/openrct2/platform/Platform.Linux.cpp index c3366fe11c..c86c36e9a6 100644 --- a/src/openrct2/platform/Platform.Linux.cpp +++ b/src/openrct2/platform/Platform.Linux.cpp @@ -28,6 +28,7 @@ # include # endif // NO_TTF +# include "../Date.h" # include "../OpenRCT2.h" # include "../core/Path.hpp" # include "../localisation/Language.h" diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index f0420831e6..449e2146a0 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -11,10 +11,10 @@ # include "Platform.h" +# include "../Date.h" # include "../core/Memory.hpp" # include "../core/Path.hpp" # include "../core/String.hpp" -# include "../localisation/Date.h" # include "../util/Util.h" # include diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 2000727629..9eea08e3d3 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -21,6 +21,7 @@ # include # undef GetEnvironmentVariable +# include "../Date.h" # include "../OpenRCT2.h" # include "../common.h" # include "../core/Path.hpp" diff --git a/src/openrct2/platform/Platform.h b/src/openrct2/platform/Platform.h index 1a6e8da5cf..c5527d63b9 100644 --- a/src/openrct2/platform/Platform.h +++ b/src/openrct2/platform/Platform.h @@ -40,13 +40,7 @@ enum class SPECIAL_FOLDER RCT2_DISCORD, }; -struct RealWorldDate -{ - uint8_t day; - uint8_t month; - int16_t year; - uint8_t day_of_week; -}; +struct RealWorldDate; struct RealWorldTime; namespace Platform diff --git a/src/openrct2/platform/Platform.macOS.mm b/src/openrct2/platform/Platform.macOS.mm index cee15ba715..c30619c3cf 100644 --- a/src/openrct2/platform/Platform.macOS.mm +++ b/src/openrct2/platform/Platform.macOS.mm @@ -9,11 +9,13 @@ #if defined(__APPLE__) && defined(__MACH__) +# include "Platform.h" + +# include "../Date.h" # include "../OpenRCT2.h" # include "../core/Path.hpp" # include "../core/String.hpp" # include "../localisation/Language.h" -# include "Platform.h" // undefine `interface` and `abstract`, because it's causing conflicts with Objective-C's keywords # undef interface diff --git a/src/openrct2/platform/Shared.cpp b/src/openrct2/platform/Shared.cpp index 7e96da47a9..661f9aebf3 100644 --- a/src/openrct2/platform/Shared.cpp +++ b/src/openrct2/platform/Shared.cpp @@ -7,6 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "../Date.h" #include "../common.h" #ifdef _WIN32 diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index f8951077cc..ec92fd7426 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2121,8 +2121,7 @@ namespace RCT1 // Date and srand gCurrentTicks = _s4.Ticks; ScenarioRandSeed(_s4.RandomA, _s4.RandomB); - gDateMonthsElapsed = static_cast(_s4.Month); - gDateMonthTicks = _s4.Day; + GetContext()->GetGameState()->SetDate(Date(_s4.Month, _s4.Day)); // Park rating gParkRating = _s4.ParkRating; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index e47482ae28..97e2eaa33c 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -249,8 +249,7 @@ namespace RCT2 gScenarioDetails = loadMaybeUTF8(_s6.ScenarioDescription); } - gDateMonthsElapsed = static_cast(_s6.ElapsedMonths); - gDateMonthTicks = _s6.CurrentDay; + OpenRCT2::GetContext()->GetGameState()->SetDate(OpenRCT2::Date(_s6.ElapsedMonths, _s6.CurrentDay)); gCurrentTicks = _s6.GameTicks1; ScenarioRandSeed(_s6.ScenarioSrand0, _s6.ScenarioSrand1); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index bdedbe61d6..500734f95e 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -307,7 +307,7 @@ size_t Ride::GetNumPrices() const int32_t Ride::GetAge() const { - return gDateMonthsElapsed - build_date; + return GetDate().GetMonthsElapsed() - build_date; } int32_t Ride::GetTotalQueueLength() const @@ -953,7 +953,7 @@ void ResetAllRideBuildDates() { for (auto& ride : GetRideManager()) { - ride.build_date -= gDateMonthsElapsed; + ride.build_date -= GetDate().GetMonthsElapsed(); } } @@ -5162,7 +5162,7 @@ void Ride::Delete() void Ride::Renew() { // Set build date to current date (so the ride is brand new) - build_date = gDateMonthsElapsed; + build_date = GetDate().GetMonthsElapsed(); reliability = RIDE_INITIAL_RELIABILITY; } diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index c12712f6a6..749310cea0 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -11,6 +11,7 @@ #include "../Cheats.h" #include "../Context.h" +#include "../Date.h" #include "../FileClassifier.h" #include "../Game.h" #include "../GameState.h" @@ -158,7 +159,7 @@ void ScenarioReset() FinanceResetHistory(); AwardReset(); ResetAllRideBuildDates(); - DateReset(); + GetContext()->GetGameState()->ResetDate(); Duck::RemoveAll(); ParkCalculateSize(); MapCountRemainingLandRights(); @@ -326,7 +327,7 @@ static void ScenarioDayUpdate() static void ScenarioWeekUpdate() { - int32_t month = DateGetMonth(gDateMonthsElapsed); + int32_t month = GetDate().GetMonth(); FinancePayWages(); FinancePayResearch(); @@ -369,7 +370,7 @@ static void ScenarioUpdateDayNightCycle() if (gScreenFlags == SCREEN_FLAGS_PLAYING && gConfigGeneral.DayNightCycle) { - float monthFraction = gDateMonthTicks / static_cast(TICKS_PER_MONTH); + float monthFraction = GetDate().GetMonthTicks() / static_cast(TICKS_PER_MONTH); if (monthFraction < (1 / 8.0f)) { gDayNightCycle = 0.0f; @@ -409,19 +410,20 @@ void ScenarioUpdate() if (gScreenFlags == SCREEN_FLAGS_PLAYING) { - if (DateIsDayStart(gDateMonthTicks)) + auto& date = GetDate(); + if (date.IsDayStart()) { ScenarioDayUpdate(); } - if (DateIsWeekStart(gDateMonthTicks)) + if (date.IsWeekStart()) { ScenarioWeekUpdate(); } - if (DateIsFortnightStart(gDateMonthTicks)) + if (date.IsFortnightStart()) { ScenarioFortnightUpdate(); } - if (DateIsMonthStart(gDateMonthTicks)) + if (date.IsMonthStart()) { ScenarioMonthUpdate(); } @@ -617,7 +619,7 @@ ResultWithMessage ScenarioPrepareForSave() ObjectiveStatus Objective::CheckGuestsBy() const { auto parkRating = gParkRating; - auto currentMonthYear = gDateMonthsElapsed; + int32_t currentMonthYear = GetDate().GetMonthsElapsed(); if (currentMonthYear == MONTH_COUNT * Year || AllowEarlyCompletion()) { @@ -637,7 +639,7 @@ ObjectiveStatus Objective::CheckGuestsBy() const ObjectiveStatus Objective::CheckParkValueBy() const { - int32_t currentMonthYear = gDateMonthsElapsed; + int32_t currentMonthYear = GetDate().GetMonthsElapsed(); money64 objectiveParkValue = Currency; money64 parkValue = gParkValue; @@ -695,7 +697,7 @@ ObjectiveStatus Objective::Check10RollerCoasters() const */ ObjectiveStatus Objective::CheckGuestsAndRating() const { - if (gParkRating < 700 && gDateMonthsElapsed >= 1) + if (gParkRating < 700 && GetDate().GetMonthsElapsed() >= 1) { gScenarioParkRatingWarningDays++; if (gScenarioParkRatingWarningDays == 1) diff --git a/src/openrct2/scripting/bindings/world/ScDate.hpp b/src/openrct2/scripting/bindings/world/ScDate.hpp index f1f38f34fb..0d1e3b8c76 100644 --- a/src/openrct2/scripting/bindings/world/ScDate.hpp +++ b/src/openrct2/scripting/bindings/world/ScDate.hpp @@ -46,7 +46,7 @@ namespace OpenRCT2::Scripting void monthsElapsed_set(int32_t value) { ThrowIfGameStateNotMutable(); - gDateMonthsElapsed = static_cast(value); + GetContext()->GetGameState()->SetDate(Date(value, GetDate().GetMonthTicks())); } uint32_t monthProgress_get() const @@ -58,13 +58,13 @@ namespace OpenRCT2::Scripting void monthProgress_set(int32_t value) { ThrowIfGameStateNotMutable(); - gDateMonthTicks = value; + GetContext()->GetGameState()->SetDate(Date(GetDate().GetMonthsElapsed(), value)); } uint32_t yearsElapsed_get() const { const auto& date = GetDate(); - return date.GetMonthsElapsed() / 8; + return date.GetYear(); } uint32_t ticksElapsed_get() const diff --git a/src/openrct2/world/Climate.cpp b/src/openrct2/world/Climate.cpp index 12f96a7ebb..5d61d449cb 100644 --- a/src/openrct2/world/Climate.cpp +++ b/src/openrct2/world/Climate.cpp @@ -91,7 +91,7 @@ int32_t ClimateCelsiusToFahrenheit(int32_t celsius) void ClimateReset(ClimateType climate) { auto weather = WeatherType::PartiallyCloudy; - int32_t month = DateGetMonth(gDateMonthsElapsed); + int32_t month = GetDate().GetMonth(); const WeatherTransition* transition = &ClimateTransitions[static_cast(climate)][month]; const WeatherState* weatherState = &ClimateWeatherData[EnumValue(weather)]; @@ -197,7 +197,7 @@ void ClimateUpdate() void ClimateForceWeather(WeatherType weather) { - int32_t month = DateGetMonth(gDateMonthsElapsed); + int32_t month = GetDate().GetMonth(); const WeatherTransition* transition = &ClimateTransitions[static_cast(gClimate)][month]; const auto weatherState = &ClimateWeatherData[EnumValue(weather)]; @@ -295,7 +295,7 @@ static int8_t ClimateStepWeatherLevel(int8_t currentWeatherLevel, int8_t nextWea */ static void ClimateDetermineFutureWeather(int32_t randomDistribution) { - int32_t month = DateGetMonth(gDateMonthsElapsed); + int32_t month = GetDate().GetMonth(); // Generate a random variable with values 0 up to DistributionSize-1 and chose weather from the distribution table // accordingly diff --git a/test/tests/MultiLaunch.cpp b/test/tests/MultiLaunch.cpp index 70bbab819b..fc1146bca3 100644 --- a/test/tests/MultiLaunch.cpp +++ b/test/tests/MultiLaunch.cpp @@ -48,8 +48,11 @@ TEST(MultiLaunchTest, all) ASSERT_EQ(RideGetCount(), 134); auto gs = context->GetGameState(); ASSERT_NE(gs, nullptr); + auto& date = gs->GetDate(); - ASSERT_EQ(date.GetMonthTicks(), 0); + // NOTE: This value is saved in the SV6 file, after the import this will be the current state. + // In case the save file gets replaced this needs to be adjusted. + ASSERT_EQ(date.GetMonthTicks(), 0x1e98); for (int j = 0; j < updatesToTest; j++) {