diff --git a/src/openrct2-ui/input/Shortcuts.cpp b/src/openrct2-ui/input/Shortcuts.cpp index 386a7f34e1..6921a59f17 100644 --- a/src/openrct2-ui/input/Shortcuts.cpp +++ b/src/openrct2-ui/input/Shortcuts.cpp @@ -278,7 +278,7 @@ static void ShortcutShowFinancialInformation() return; if (!(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) ContextOpenWindow(WindowClass::Finances); } diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 3291f90931..349d312b7b 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -371,7 +371,7 @@ static StringId window_cheats_page_titles[] = { void OnOpen() override { SetPage(WINDOW_CHEATS_PAGE_MONEY); - _parkRatingSpinnerValue = ParkGetForcedRating() >= 0 ? ParkGetForcedRating() : 999; + _parkRatingSpinnerValue = Park::GetForcedRating() >= 0 ? Park::GetForcedRating() : 999; } void OnUpdate() override @@ -459,7 +459,7 @@ static StringId window_cheats_page_titles[] = { { case WINDOW_CHEATS_PAGE_MONEY: { - auto moneyDisabled = (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) != 0; + auto moneyDisabled = (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) != 0; SetCheckboxValue(WIDX_NO_MONEY, moneyDisabled); SetWidgetDisabled(WIDX_ADD_SET_MONEY_GROUP, moneyDisabled); SetWidgetDisabled(WIDX_MONEY_SPINNER, moneyDisabled); @@ -480,9 +480,9 @@ static StringId window_cheats_page_titles[] = { break; } case WINDOW_CHEATS_PAGE_MISC: - widgets[WIDX_OPEN_CLOSE_PARK].text = (gameState.ParkFlags & PARK_FLAGS_PARK_OPEN) ? STR_CHEAT_CLOSE_PARK - : STR_CHEAT_OPEN_PARK; - SetCheckboxValue(WIDX_FORCE_PARK_RATING, ParkGetForcedRating() >= 0); + widgets[WIDX_OPEN_CLOSE_PARK].text = (gameState.Park.Flags & PARK_FLAGS_PARK_OPEN) ? STR_CHEAT_CLOSE_PARK + : STR_CHEAT_OPEN_PARK; + SetCheckboxValue(WIDX_FORCE_PARK_RATING, Park::GetForcedRating() >= 0); SetCheckboxValue(WIDX_FREEZE_WEATHER, gameState.Cheats.FreezeWeather); SetCheckboxValue(WIDX_NEVERENDING_MARKETING, gameState.Cheats.NeverendingMarketing); SetCheckboxValue(WIDX_DISABLE_PLANT_AGING, gameState.Cheats.DisablePlantAging); @@ -788,7 +788,7 @@ static StringId window_cheats_page_titles[] = { switch (widgetIndex) { case WIDX_NO_MONEY: - CheatsSet(CheatType::NoMoney, GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY ? 0 : 1); + CheatsSet(CheatType::NoMoney, GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY ? 0 : 1); break; case WIDX_MONEY_SPINNER: MoneyToString(_moneySpinnerValue, _moneySpinnerText, MONEY_STRING_MAXLENGTH, false); @@ -814,7 +814,7 @@ static StringId window_cheats_page_titles[] = { case WIDX_INCREASE_PARK_RATING: _parkRatingSpinnerValue = std::min(999, 10 * (_parkRatingSpinnerValue / 10 + 1)); InvalidateWidget(WIDX_PARK_RATING_SPINNER); - if (ParkGetForcedRating() >= 0) + if (Park::GetForcedRating() >= 0) { auto cheatSetAction = CheatSetAction(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); GameActions::Execute(&cheatSetAction); @@ -823,7 +823,7 @@ static StringId window_cheats_page_titles[] = { case WIDX_DECREASE_PARK_RATING: _parkRatingSpinnerValue = std::max(0, 10 * (_parkRatingSpinnerValue / 10 - 1)); InvalidateWidget(WIDX_PARK_RATING_SPINNER); - if (ParkGetForcedRating() >= 0) + if (Park::GetForcedRating() >= 0) { CheatsSet(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); } @@ -913,7 +913,7 @@ static StringId window_cheats_page_titles[] = { CheatsSet(CheatType::NeverEndingMarketing, !gameState.Cheats.NeverendingMarketing); break; case WIDX_FORCE_PARK_RATING: - if (ParkGetForcedRating() >= 0) + if (Park::GetForcedRating() >= 0) { CheatsSet(CheatType::SetForcedParkRating, -1); } diff --git a/src/openrct2-ui/windows/ClearScenery.cpp b/src/openrct2-ui/windows/ClearScenery.cpp index 7efe3ae5a7..5589f8a3ea 100644 --- a/src/openrct2-ui/windows/ClearScenery.cpp +++ b/src/openrct2-ui/windows/ClearScenery.cpp @@ -192,7 +192,7 @@ namespace OpenRCT2::Ui::Windows // Draw cost amount if (gClearSceneryCost != kMoney64Undefined && gClearSceneryCost != 0 - && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(gClearSceneryCost); diff --git a/src/openrct2-ui/windows/DemolishRidePrompt.cpp b/src/openrct2-ui/windows/DemolishRidePrompt.cpp index e9ab8914f4..7aaf995c03 100644 --- a/src/openrct2-ui/windows/DemolishRidePrompt.cpp +++ b/src/openrct2-ui/windows/DemolishRidePrompt.cpp @@ -84,8 +84,8 @@ static Widget window_ride_demolish_widgets[] = auto currentRide = GetRide(rideId); if (currentRide != nullptr) { - auto stringId = (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) ? STR_DEMOLISH_RIDE_ID - : STR_DEMOLISH_RIDE_ID_MONEY; + auto stringId = (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) ? STR_DEMOLISH_RIDE_ID + : STR_DEMOLISH_RIDE_ID_MONEY; auto ft = Formatter(); currentRide->FormatNameTo(ft); ft.Add(_demolishRideCost); diff --git a/src/openrct2-ui/windows/EditorBottomToolbar.cpp b/src/openrct2-ui/windows/EditorBottomToolbar.cpp index b8b3adb368..2fe2cda019 100644 --- a/src/openrct2-ui/windows/EditorBottomToolbar.cpp +++ b/src/openrct2-ui/windows/EditorBottomToolbar.cpp @@ -105,7 +105,7 @@ static Widget _editorBottomToolbarWidgets[] = { } else if (!(gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)) { - if (GetNumFreeEntities() != MAX_ENTITIES || GetGameState().ParkFlags & PARK_FLAGS_SPRITES_INITIALISED) + if (GetNumFreeEntities() != MAX_ENTITIES || GetGameState().Park.Flags & PARK_FLAGS_SPRITES_INITIALISED) { HidePreviousStepButton(); } @@ -141,7 +141,7 @@ static Widget _editorBottomToolbarWidgets[] = { if (widgetIndex == WIDX_PREVIOUS_STEP_BUTTON) { if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - || (GetNumFreeEntities() == MAX_ENTITIES && !(GetGameState().ParkFlags & PARK_FLAGS_SPRITES_INITIALISED))) + || (GetNumFreeEntities() == MAX_ENTITIES && !(GetGameState().Park.Flags & PARK_FLAGS_SPRITES_INITIALISED))) { ((this)->*(_previousButtonMouseUp[EnumValue(gameState.EditorStep)]))(); } diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index ee1d1c6e5f..99b7795ccb 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -446,10 +446,11 @@ static uint64_t window_editor_objective_options_page_hold_down_widgets[] = { if (i == OBJECTIVE_NONE || i == OBJECTIVE_BUILD_THE_BEST) continue; - const bool objectiveAllowedByMoneyUsage = !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + const bool objectiveAllowedByMoneyUsage = !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) || !ObjectiveNeedsMoney(i); // This objective can only work if the player can ask money for rides. - const bool objectiveAllowedByPaymentSettings = (i != OBJECTIVE_MONTHLY_RIDE_INCOME) || ParkRidePricesUnlocked(); + const bool objectiveAllowedByPaymentSettings = (i != OBJECTIVE_MONTHLY_RIDE_INCOME) + || Park::RidePricesUnlocked(); if (objectiveAllowedByMoneyUsage && objectiveAllowedByPaymentSettings) { gDropdownItems[numItems].Format = STR_DROPDOWN_MENU_LABEL; @@ -763,11 +764,11 @@ static uint64_t window_editor_objective_options_page_hold_down_widgets[] = { objectiveType = GetGameState().ScenarioObjective.Type; // Check if objective is allowed by money and pay-per-ride settings. - const bool objectiveAllowedByMoneyUsage = !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + const bool objectiveAllowedByMoneyUsage = !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) || !ObjectiveNeedsMoney(objectiveType); // This objective can only work if the player can ask money for rides. const bool objectiveAllowedByPaymentSettings = (objectiveType != OBJECTIVE_MONTHLY_RIDE_INCOME) - || ParkRidePricesUnlocked(); + || Park::RidePricesUnlocked(); if (!objectiveAllowedByMoneyUsage || !objectiveAllowedByPaymentSettings) { // Reset objective diff --git a/src/openrct2-ui/windows/EditorScenarioOptions.cpp b/src/openrct2-ui/windows/EditorScenarioOptions.cpp index bd98594969..c029f7c247 100644 --- a/src/openrct2-ui/windows/EditorScenarioOptions.cpp +++ b/src/openrct2-ui/windows/EditorScenarioOptions.cpp @@ -385,7 +385,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { break; case WIDX_NO_MONEY: { - auto newMoneySetting = (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) ? 0 : 1; + auto newMoneySetting = (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) ? 0 : 1; auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::NoMoney, newMoneySetting); GameActions::Execute(&scenarioSetSetting); Invalidate(); @@ -395,7 +395,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::ForbidMarketingCampaigns, - gameState.ParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -403,7 +403,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { case WIDX_RCT1_INTEREST: { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::UseRCT1Interest, gameState.ParkFlags & PARK_FLAGS_RCT1_INTEREST ? 0 : 1); + ScenarioSetSetting::UseRCT1Interest, gameState.Park.Flags & PARK_FLAGS_RCT1_INTEREST ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -570,7 +570,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { SetPressedTab(); auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { SetWidgetPressed(WIDX_NO_MONEY, true); for (int32_t i = WIDX_INITIAL_CASH; i <= WIDX_RCT1_INTEREST; i++) @@ -590,7 +590,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { widgets[WIDX_MAXIMUM_LOAN_DECREASE].type = WindowWidgetType::Button; widgets[WIDX_FORBID_MARKETING].type = WindowWidgetType::Checkbox; - if (gameState.ParkFlags & PARK_FLAGS_RCT1_INTEREST) + if (gameState.Park.Flags & PARK_FLAGS_RCT1_INTEREST) { widgets[WIDX_INTEREST_RATE].type = WindowWidgetType::Empty; widgets[WIDX_INTEREST_RATE_INCREASE].type = WindowWidgetType::Empty; @@ -607,7 +607,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { } } - SetWidgetPressed(WIDX_FORBID_MARKETING, gameState.ParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN); + SetWidgetPressed(WIDX_FORBID_MARKETING, gameState.Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN); widgets[WIDX_CLOSE].type = (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) ? WindowWidgetType::Empty : WindowWidgetType::CloseBox; @@ -696,7 +696,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::GuestsPreferLessIntenseRides, - gameState.ParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -705,7 +705,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::GuestsPreferMoreIntenseRides, - gameState.ParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -850,7 +850,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { SetPressedTab(); auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { widgets[WIDX_CASH_PER_GUEST].type = WindowWidgetType::Empty; widgets[WIDX_CASH_PER_GUEST_INCREASE].type = WindowWidgetType::Empty; @@ -863,8 +863,8 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { widgets[WIDX_CASH_PER_GUEST_DECREASE].type = WindowWidgetType::Button; } - SetWidgetPressed(WIDX_GUEST_PREFER_LESS_INTENSE_RIDES, gameState.ParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES); - SetWidgetPressed(WIDX_GUEST_PREFER_MORE_INTENSE_RIDES, gameState.ParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES); + SetWidgetPressed(WIDX_GUEST_PREFER_LESS_INTENSE_RIDES, gameState.Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES); + SetWidgetPressed(WIDX_GUEST_PREFER_MORE_INTENSE_RIDES, gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES); widgets[WIDX_CLOSE].type = (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) ? WindowWidgetType::Empty : WindowWidgetType::CloseBox; @@ -948,7 +948,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { case WIDX_FORBID_TREE_REMOVAL: { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::ForbidTreeRemoval, gameState.ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL ? 0 : 1); + ScenarioSetSetting::ForbidTreeRemoval, gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -957,7 +957,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::ForbidLandscapeChanges, - gameState.ParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -966,7 +966,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::ForbidHighConstruction, - gameState.ParkFlags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -975,7 +975,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::ParkRatingHigherDifficultyLevel, - gameState.ParkFlags & PARK_FLAGS_DIFFICULT_PARK_RATING ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -984,7 +984,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::GuestGenerationHigherDifficultyLevel, - gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION ? 0 : 1); + gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION ? 0 : 1); GameActions::Execute(&scenarioSetSetting); Invalidate(); break; @@ -1058,10 +1058,10 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { Invalidate(); break; case WIDX_ENTRY_PRICE_INCREASE: - if (gameState.ParkEntranceFee < MAX_ENTRANCE_FEE) + if (gameState.Park.EntranceFee < MAX_ENTRANCE_FEE) { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::ParkChargeEntryFee, gameState.ParkEntranceFee + 1.00_GBP); + ScenarioSetSetting::ParkChargeEntryFee, gameState.Park.EntranceFee + 1.00_GBP); GameActions::Execute(&scenarioSetSetting); } else @@ -1071,10 +1071,10 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { Invalidate(); break; case WIDX_ENTRY_PRICE_DECREASE: - if (gameState.ParkEntranceFee > 0.00_GBP) + if (gameState.Park.EntranceFee > 0.00_GBP) { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::ParkChargeEntryFee, gameState.ParkEntranceFee - 1.00_GBP); + ScenarioSetSetting::ParkChargeEntryFee, gameState.Park.EntranceFee - 1.00_GBP); GameActions::Execute(&scenarioSetSetting); } else @@ -1097,9 +1097,9 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { { windowPos.x + dropdownWidget->left, windowPos.y + dropdownWidget->top }, dropdownWidget->height() - 1, colours[1], 0, Dropdown::Flag::StayOpen, 3, dropdownWidget->width() - 3); - if (gameState.ParkFlags & PARK_FLAGS_UNLOCK_ALL_PRICES) + if (gameState.Park.Flags & PARK_FLAGS_UNLOCK_ALL_PRICES) Dropdown::SetChecked(2, true); - else if (gameState.ParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) + else if (gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY) Dropdown::SetChecked(0, true); else Dropdown::SetChecked(1, true); @@ -1156,7 +1156,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { SetPressedTab(); auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { for (int32_t i = WIDX_LAND_COST; i <= WIDX_ENTRY_PRICE_DECREASE; i++) widgets[i].type = WindowWidgetType::Empty; @@ -1172,7 +1172,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { widgets[WIDX_PAY_FOR_PARK_OR_RIDES].type = WindowWidgetType::DropdownMenu; widgets[WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN].type = WindowWidgetType::Button; - if (!ParkEntranceFeeUnlocked()) + if (!Park::EntranceFeeUnlocked()) { widgets[WIDX_ENTRY_PRICE].type = WindowWidgetType::Empty; widgets[WIDX_ENTRY_PRICE_INCREASE].type = WindowWidgetType::Empty; @@ -1186,11 +1186,11 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { } } - SetWidgetPressed(WIDX_FORBID_TREE_REMOVAL, gameState.ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL); - SetWidgetPressed(WIDX_FORBID_LANDSCAPE_CHANGES, gameState.ParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES); - SetWidgetPressed(WIDX_FORBID_HIGH_CONSTRUCTION, gameState.ParkFlags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION); - SetWidgetPressed(WIDX_HARD_PARK_RATING, gameState.ParkFlags & PARK_FLAGS_DIFFICULT_PARK_RATING); - SetWidgetPressed(WIDX_HARD_GUEST_GENERATION, gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION); + SetWidgetPressed(WIDX_FORBID_TREE_REMOVAL, gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL); + SetWidgetPressed(WIDX_FORBID_LANDSCAPE_CHANGES, gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES); + SetWidgetPressed(WIDX_FORBID_HIGH_CONSTRUCTION, gameState.Park.Flags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION); + SetWidgetPressed(WIDX_HARD_PARK_RATING, gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING); + SetWidgetPressed(WIDX_HARD_GUEST_GENERATION, gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION); widgets[WIDX_CLOSE].type = (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) ? WindowWidgetType::Empty : WindowWidgetType::CloseBox; @@ -1243,9 +1243,9 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { auto ft = Formatter(); // Pay for park and/or rides value - if (gameState.ParkFlags & PARK_FLAGS_UNLOCK_ALL_PRICES) + if (gameState.Park.Flags & PARK_FLAGS_UNLOCK_ALL_PRICES) ft.Add(STR_PAID_ENTRY_PAID_RIDES); - else if (gameState.ParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) + else if (gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY) ft.Add(STR_FREE_PARK_ENTER); else ft.Add(STR_PAY_PARK_ENTER); @@ -1263,7 +1263,7 @@ static uint32_t window_editor_scenario_options_page_hold_down_widgets[] = { // Entry price value screenCoords = windowPos + ScreenCoordsXY{ entryPriceWidget.left + 1, entryPriceWidget.top }; auto ft = Formatter(); - ft.Add(gameState.ParkEntranceFee); + ft.Add(gameState.Park.EntranceFee); DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft); } diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 4d38dec47b..04453ade98 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -230,7 +230,7 @@ static Widget _windowFinancesResearchWidgets[] = void SetDisabledTabs() { - disabled_widgets = (GetGameState().ParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) ? (1uLL << WIDX_TAB_5) : 0; + disabled_widgets = (GetGameState().Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) ? (1uLL << WIDX_TAB_5) : 0; } public: @@ -569,7 +569,7 @@ static Widget _windowFinancesResearchWidgets[] = // Loan and interest rate DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ 8, 279 }, STR_FINANCES_SUMMARY_LOAN); - if (!(gameState.ParkFlags & PARK_FLAGS_RCT1_INTEREST)) + if (!(gameState.Park.Flags & PARK_FLAGS_RCT1_INTEREST)) { auto ft = Formatter(); ft.Add(gameState.BankLoanInterestRate); @@ -596,7 +596,7 @@ static Widget _windowFinancesResearchWidgets[] = { // Park value and company value ft = Formatter(); - ft.Add(gameState.ParkValue); + ft.Add(gameState.Park.Value); DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ 280, 279 }, STR_PARK_VALUE_LABEL, ft); ft = Formatter(); ft.Add(gameState.CompanyValue); @@ -688,7 +688,7 @@ static Widget _windowFinancesResearchWidgets[] = // Park value auto ft = Formatter(); - ft.Add(gameState.ParkValue); + ft.Add(gameState.Park.Value); DrawTextBasic(dpi, graphTopLeft - ScreenCoordsXY{ 0, 11 }, STR_FINANCES_PARK_VALUE, ft); // Graph @@ -698,7 +698,7 @@ static Widget _windowFinancesResearchWidgets[] = int32_t yAxisScale = 0; for (int32_t i = 0; i < 64; i++) { - auto balance = gameState.ParkValueHistory[i]; + auto balance = gameState.Park.ValueHistory[i]; if (balance == kMoney64Undefined) continue; @@ -730,7 +730,7 @@ static Widget _windowFinancesResearchWidgets[] = // X axis labels and values coords = graphTopLeft + ScreenCoordsXY{ 98, 17 }; - Graph::Draw(dpi, gameState.ParkValueHistory, 64, coords, yAxisScale, 0); + Graph::Draw(dpi, gameState.Park.ValueHistory, 64, coords, yAxisScale, 0); } #pragma endregion diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 31b63b6115..08474f4ba1 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -500,7 +500,7 @@ static constexpr uint8_t ConstructionPreviewImages[][4] = { window_footpath_widgets[WIDX_CONSTRUCT].bottom - 12 }; if (_windowFootpathCost != kMoney64Undefined) { - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(_windowFootpathCost); diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index ee2e5461d1..dd68c4ef64 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -92,7 +92,7 @@ static Widget window_game_bottom_toolbar_widgets[] = auto& gameState = GetGameState(); // Draw money - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { Widget widget = window_game_bottom_toolbar_widgets[WIDX_MONEY]; auto screenCoords = ScreenCoordsXY{ windowPos.x + widget.midX(), @@ -143,7 +143,7 @@ static Widget window_game_bottom_toolbar_widgets[] = Widget widget = window_game_bottom_toolbar_widgets[WIDX_PARK_RATING]; auto screenCoords = windowPos + ScreenCoordsXY{ widget.left + 11, widget.midY() - 5 }; - DrawParkRating(dpi, colours[3], screenCoords, std::max(10, ((gameState.ParkRating / 4) * 263) / 256)); + DrawParkRating(dpi, colours[3], screenCoords, std::max(10, ((gameState.Park.Rating / 4) * 263) / 256)); } } @@ -422,7 +422,7 @@ static Widget window_game_bottom_toolbar_widgets[] = { case WIDX_LEFT_OUTSET: case WIDX_MONEY: - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) ContextOpenWindow(WindowClass::Finances); break; case WIDX_GUESTS: @@ -478,10 +478,10 @@ static Widget window_game_bottom_toolbar_widgets[] = { case WIDX_MONEY: ft.Add(gameState.CurrentProfit); - ft.Add(gameState.ParkValue); + ft.Add(gameState.Park.Value); break; case WIDX_PARK_RATING: - ft.Add(gameState.ParkRating); + ft.Add(gameState.Park.Rating); break; } return { fallback, ft }; @@ -504,7 +504,7 @@ static Widget window_game_bottom_toolbar_widgets[] = + 1; // Reposition left widgets in accordance with line height... depending on whether there is money in play. - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) { widgets[WIDX_MONEY].type = WindowWidgetType::Empty; widgets[WIDX_GUESTS].top = 1; diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 268d998158..1226feaa97 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -468,7 +468,7 @@ static_assert(_guestWindowPageWidgets.size() == WINDOW_GUEST_PAGE_COUNT); if (!WidgetIsDisabled(*this, WIDX_PICKUP)) Invalidate(); } - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) { newDisabledWidgets |= (1uLL << WIDX_TAB_4); // Disable finance tab if no money } diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index 423f0161c1..ee66044506 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -960,8 +960,8 @@ static Widget window_guest_list_widgets[] = { static GuestItem::CompareFunc GetGuestCompareFunc() { - return GetGameState().ParkFlags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES ? CompareGuestItem - : CompareGuestItem; + return GetGameState().Park.Flags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES ? CompareGuestItem + : CompareGuestItem; } }; diff --git a/src/openrct2-ui/windows/Land.cpp b/src/openrct2-ui/windows/Land.cpp index d019d2c3df..fffa262959 100644 --- a/src/openrct2-ui/windows/Land.cpp +++ b/src/openrct2-ui/windows/Land.cpp @@ -264,7 +264,7 @@ static Widget window_land_widgets[] = { screenCoords = { windowPos.x + previewWidget->midX(), windowPos.y + previewWidget->bottom + 5 }; - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { // Draw raise cost amount if (gLandToolRaiseCost != kMoney64Undefined && gLandToolRaiseCost != 0) diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index 9bdc0fb49e..b4201b2591 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -230,7 +230,7 @@ static Widget window_land_rights_widgets[] = { // Draw cost amount if (_landRightsCost != kMoney64Undefined && _landRightsCost != 0 - && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(_landRightsCost); diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index a231941fad..743d5b90ca 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -343,12 +343,12 @@ static Widget window_loadsave_widgets[] = case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO): { SetAndSaveConfigPath(gConfigGeneral.LastSaveScenarioDirectory, pathBuffer); - int32_t parkFlagsBackup = gameState.ParkFlags; - gameState.ParkFlags &= ~PARK_FLAGS_SPRITES_INITIALISED; + int32_t parkFlagsBackup = gameState.Park.Flags; + gameState.Park.Flags &= ~PARK_FLAGS_SPRITES_INITIALISED; gameState.EditorStep = EditorStep::Invalid; gScenarioFileName = std::string(String::ToStringView(pathBuffer, std::size(pathBuffer))); int32_t success = ScenarioSave(gameState, pathBuffer, gConfigGeneral.SavePluginData ? 3 : 2); - gameState.ParkFlags = parkFlagsBackup; + gameState.Park.Flags = parkFlagsBackup; if (success) { diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 2f43010cff..f56ee24f69 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -846,7 +846,7 @@ static Widget window_new_ride_widgets[] = { widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP].type = WindowWidgetType::Groupbox; widgets[WIDX_LAST_DEVELOPMENT_GROUP].type = WindowWidgetType::Groupbox; widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::FlatBtn; - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) widgets[WIDX_RESEARCH_FUNDING_BUTTON].type = WindowWidgetType::FlatBtn; newWidth = 300; @@ -954,7 +954,7 @@ static Widget window_new_ride_widgets[] = { DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ 0, 51 }, designCountStringId, ft); // Price - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { // Get price of ride int32_t startPieceId = GetRideTypeDescriptor(item.Type).StartTrackPiece; diff --git a/src/openrct2-ui/windows/Park.cpp b/src/openrct2-ui/windows/Park.cpp index 9c769c0c19..dc384e173c 100644 --- a/src/openrct2-ui/windows/Park.cpp +++ b/src/openrct2-ui/windows/Park.cpp @@ -397,7 +397,7 @@ static constexpr WindowParkAward _parkAwards[] = { void SetDisabledTabs() { // Disable price tab if money is disabled - disabled_widgets = (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) ? (1uLL << WIDX_TAB_4) : 0; + disabled_widgets = (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) ? (1uLL << WIDX_TAB_4) : 0; } void PrepareWindowTitleText() @@ -428,10 +428,10 @@ static constexpr WindowParkAward _parkAwards[] = { break; } case WIDX_CLOSE_LIGHT: - ParkSetOpen(false); + Park::SetOpen(false); break; case WIDX_OPEN_LIGHT: - ParkSetOpen(true); + Park::SetOpen(true); break; } } @@ -477,11 +477,11 @@ static constexpr WindowParkAward _parkAwards[] = { if (dropdownIndex != 0) { - ParkSetOpen(true); + Park::SetOpen(true); } else { - ParkSetOpen(false); + Park::SetOpen(false); } } } @@ -532,7 +532,7 @@ static constexpr WindowParkAward _parkAwards[] = { disabled_widgets &= ~((1uLL << WIDX_OPEN_OR_CLOSE) | (1uLL << WIDX_CLOSE_LIGHT) | (1uLL << WIDX_OPEN_LIGHT)); // Only allow purchase of land when there is money - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) widgets[WIDX_BUY_LAND_RIGHTS].type = WindowWidgetType::Empty; else widgets[WIDX_BUY_LAND_RIGHTS].type = WindowWidgetType::FlatBtn; @@ -620,9 +620,9 @@ static constexpr WindowParkAward _parkAwards[] = { const auto& gameState = GetGameState(); std::optional newFocus = std::nullopt; - if (!gameState.ParkEntrances.empty()) + if (!gameState.Park.Entrances.empty()) { - const auto& entrance = gameState.ParkEntrances[0]; + const auto& entrance = gameState.Park.Entrances[0]; newFocus = Focus(CoordsXYZ{ entrance.x + 16, entrance.y + 16, entrance.z + 32 }); } @@ -701,7 +701,7 @@ static constexpr WindowParkAward _parkAwards[] = { // Current value auto ft = Formatter(); - ft.Add(GetGameState().ParkRating); + ft.Add(GetGameState().Park.Rating); DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ widget->left + 3, widget->top + 2 }, STR_PARK_RATING_LABEL, ft); // Graph border @@ -730,7 +730,7 @@ static constexpr WindowParkAward _parkAwards[] = { // Graph screenPos = windowPos + ScreenCoordsXY{ widget->left + 47, widget->top + 26 }; - Graph::Draw(dpi, GetGameState().ParkRatingHistory, kParkRatingHistorySize, screenPos); + Graph::Draw(dpi, GetGameState().Park.RatingHistory, kParkRatingHistorySize, screenPos); } #pragma endregion @@ -836,14 +836,14 @@ static constexpr WindowParkAward _parkAwards[] = { { case WIDX_INCREASE_PRICE: { - const auto newFee = std::min(MAX_ENTRANCE_FEE, gameState.ParkEntranceFee + 1.00_GBP); + const auto newFee = std::min(MAX_ENTRANCE_FEE, gameState.Park.EntranceFee + 1.00_GBP); auto gameAction = ParkSetEntranceFeeAction(newFee); GameActions::Execute(&gameAction); break; } case WIDX_DECREASE_PRICE: { - const auto newFee = std::max(0.00_GBP, gameState.ParkEntranceFee - 1.00_GBP); + const auto newFee = std::max(0.00_GBP, gameState.Park.EntranceFee - 1.00_GBP); auto gameAction = ParkSetEntranceFeeAction(newFee); GameActions::Execute(&gameAction); break; @@ -873,14 +873,14 @@ static constexpr WindowParkAward _parkAwards[] = { widgets[WIDX_PRICE_LABEL].tooltip = STR_NONE; widgets[WIDX_PRICE].tooltip = STR_NONE; - if (!ParkEntranceFeeUnlocked()) + if (!Park::EntranceFeeUnlocked()) { widgets[WIDX_PRICE_LABEL].tooltip = STR_ADMISSION_PRICE_PAY_PER_RIDE_TIP; widgets[WIDX_PRICE].tooltip = STR_ADMISSION_PRICE_PAY_PER_RIDE_TIP; } // If the entry price is locked at free, disable the widget, unless the unlock_all_prices cheat is active. - if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) || !ParkEntranceFeeUnlocked()) + if ((GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) || !Park::EntranceFeeUnlocked()) { widgets[WIDX_PRICE].type = WindowWidgetType::LabelCentred; widgets[WIDX_INCREASE_PRICE].type = WindowWidgetType::Empty; @@ -908,7 +908,7 @@ static constexpr WindowParkAward _parkAwards[] = { ft.Add(GetGameState().TotalIncomeFromAdmissions); DrawTextBasic(dpi, screenCoords, STR_INCOME_FROM_ADMISSIONS, ft); - money64 parkEntranceFee = ParkGetEntranceFee(); + money64 parkEntranceFee = Park::GetEntranceFee(); auto stringId = parkEntranceFee == 0 ? STR_FREE : STR_BOTTOM_TOOLBAR_CASH; screenCoords = windowPos + ScreenCoordsXY{ widgets[WIDX_PRICE].left + 1, widgets[WIDX_PRICE].top + 1 }; ft = Formatter(); @@ -971,7 +971,7 @@ static constexpr WindowParkAward _parkAwards[] = { auto& gameState = GetGameState(); // Draw park size - auto parkSize = gameState.ParkSize * 10; + auto parkSize = gameState.Park.Size * 10; auto stringIndex = STR_PARK_SIZE_METRIC_LABEL; if (gConfigGeneral.MeasurementFormat == MeasurementFormat::Imperial) { @@ -1058,7 +1058,7 @@ static constexpr WindowParkAward _parkAwards[] = { PrepareWindowTitleText(); // Show name input button on scenario completion. - if (GetGameState().ParkFlags & PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT) + if (GetGameState().Park.Flags & PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT) { widgets[WIDX_ENTER_NAME].type = WindowWidgetType::Button; widgets[WIDX_ENTER_NAME].top = height - 19; diff --git a/src/openrct2-ui/windows/RefurbishRidePrompt.cpp b/src/openrct2-ui/windows/RefurbishRidePrompt.cpp index 1afb893d01..9ded71dc47 100644 --- a/src/openrct2-ui/windows/RefurbishRidePrompt.cpp +++ b/src/openrct2-ui/windows/RefurbishRidePrompt.cpp @@ -83,8 +83,8 @@ static Widget window_ride_refurbish_widgets[] = auto currentRide = GetRide(rideId); if (currentRide != nullptr) { - auto stringId = (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) ? STR_REFURBISH_RIDE_ID_NO_MONEY - : STR_REFURBISH_RIDE_ID_MONEY; + auto stringId = (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) ? STR_REFURBISH_RIDE_ID_NO_MONEY + : STR_REFURBISH_RIDE_ID_MONEY; auto ft = Formatter(); currentRide->FormatNameTo(ft); ft.Add(_demolishRideCost / 2); diff --git a/src/openrct2-ui/windows/Research.cpp b/src/openrct2-ui/windows/Research.cpp index 73a0e23a68..1d7144d7d0 100644 --- a/src/openrct2-ui/windows/Research.cpp +++ b/src/openrct2-ui/windows/Research.cpp @@ -547,7 +547,7 @@ static Widget *window_research_page_widgets[] = { const auto& gameState = GetGameState(); auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING); - if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) || gameState.ResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL) + if ((GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) || gameState.ResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL) { w->widgets[WIDX_RESEARCH_FUNDING + widgetOffset].type = WindowWidgetType::Empty; w->widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset].type = WindowWidgetType::Empty; @@ -591,7 +591,7 @@ static Widget *window_research_page_widgets[] = { void WindowResearchFundingDraw(WindowBase* w, DrawPixelInfo& dpi) { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) return; const auto& gameState = GetGameState(); diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 93f2cfdd03..d39afd4b54 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1281,7 +1281,7 @@ static_assert(std::size(RatingNames) == 6); } if (rtd.HasFlag(RIDE_TYPE_FLAG_IS_CASH_MACHINE) || rtd.HasFlag(RIDE_TYPE_FLAG_IS_FIRST_AID) - || (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) != 0) + || (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) != 0) disabledTabs |= (1uLL << WIDX_TAB_9); // 0x1000 if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) != 0) @@ -6070,7 +6070,7 @@ static_assert(std::size(RatingNames) == 6); auto rideEntry = ride->GetRideEntry(); const auto& rtd = ride->GetRideTypeDescriptor(); - return ParkRidePricesUnlocked() || rtd.HasFlag(RIDE_TYPE_FLAG_IS_TOILET) + return Park::RidePricesUnlocked() || rtd.HasFlag(RIDE_TYPE_FLAG_IS_TOILET) || (rideEntry != nullptr && rideEntry->shop_item[0] != ShopItem::None); } @@ -6245,7 +6245,7 @@ static_assert(std::size(RatingNames) == 6); // If ride prices are locked, do not allow setting the price, unless we're dealing with a shop or toilet. const auto& rtd = ride->GetRideTypeDescriptor(); - if (!ParkRidePricesUnlocked() && rideEntry->shop_item[0] == ShopItem::None + if (!Park::RidePricesUnlocked() && rideEntry->shop_item[0] == ShopItem::None && !rtd.HasFlag(RIDE_TYPE_FLAG_IS_TOILET)) { disabled_widgets |= (1uLL << WIDX_PRIMARY_PRICE); diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 0cae52afd7..9e73c90cf1 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1575,7 +1575,7 @@ static Widget _rideConstructionWidgets[] = { DrawTextBasic(dpi, screenCoords, STR_BUILD_THIS, {}, { TextAlignment::CENTRE }); screenCoords.y += 11; - if (_currentTrackPrice != kMoney64Undefined && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (_currentTrackPrice != kMoney64Undefined && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(_currentTrackPrice); diff --git a/src/openrct2-ui/windows/RideList.cpp b/src/openrct2-ui/windows/RideList.cpp index 23604fcce9..24ae36bb92 100644 --- a/src/openrct2-ui/windows/RideList.cpp +++ b/src/openrct2-ui/windows/RideList.cpp @@ -301,7 +301,7 @@ static Widget _rideListWidgets[] = { int32_t selectedIndex = -1; for (int32_t type = INFORMATION_TYPE_STATUS; type <= lastType; type++) { - if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if ((GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { if (ride_info_type_money_mapping[type]) { diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 755f40e25b..c1c566be51 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -803,7 +803,7 @@ static Widget WindowSceneryBaseWidgets[] = { } auto [name, price] = GetNameAndPrice(selectedSceneryEntry); - if (price != kMoney64Undefined && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (price != kMoney64Undefined && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(price); diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index b743ae7090..0919b44d35 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -931,7 +931,7 @@ static Widget _staffOptionsWidgets[] = { auto screenCoords = windowPos + ScreenCoordsXY{ widgets[WIDX_RESIZE].left + 4, widgets[WIDX_RESIZE].top + 4 }; - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(GetStaffWage(staff->AssignedStaffType)); diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index 6493660c19..263eebf289 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -290,7 +290,7 @@ static Widget _staffListWidgets[] = { DrawWidgets(dpi); DrawTabImages(dpi); - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto ft = Formatter(); ft.Add(GetStaffWage(GetSelectedStaffType())); diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index cff7c067d2..7c3a925784 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 28cc31f993..6e97466227 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3036,7 +3036,7 @@ static Widget _topToolbarWidgets[] = { widgets[WIDX_PAUSE].type = WindowWidgetType::Empty; } - if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) || !gConfigInterface.ToolbarShowFinances) + if ((GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) || !gConfigInterface.ToolbarShowFinances) widgets[WIDX_FINANCES].type = WindowWidgetType::Empty; if (gScreenFlags & SCREEN_FLAGS_EDITOR) diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 83b47a8ce3..27416bf4ea 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -306,7 +306,7 @@ static Widget _trackPlaceWidgets[] = { } // Price - if (_placementCost != kMoney64Undefined && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (_placementCost != kMoney64Undefined && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { ft = Formatter(); ft.Add(_placementCost); diff --git a/src/openrct2-ui/windows/Water.cpp b/src/openrct2-ui/windows/Water.cpp index 838e74a087..c2d145da40 100644 --- a/src/openrct2-ui/windows/Water.cpp +++ b/src/openrct2-ui/windows/Water.cpp @@ -156,7 +156,7 @@ static Widget _waterWidgets[] = { dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, ft, { TextAlignment::CENTRE }); } - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { // Draw raise cost amount screenCoords = { widgets[WIDX_PREVIEW].midX() + windowPos.x, widgets[WIDX_PREVIEW].bottom + windowPos.y + 5 }; diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 5e7380db34..bd20e98d1e 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -108,7 +108,7 @@ namespace Editor gameStateInitAll(gameState, DEFAULT_MAP_SIZE); gScreenFlags = SCREEN_FLAGS_SCENARIO_EDITOR; gameState.EditorStep = EditorStep::ObjectSelection; - gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; + gameState.Park.Flags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; gameState.ScenarioCategory = SCENARIO_CATEGORY_OTHER; ViewportInitAll(); WindowBase* mainWindow = OpenEditorWindows(); @@ -324,18 +324,18 @@ namespace Editor gameState.GuestChangeModifier = 0; if (fromSave) { - gameState.ParkFlags |= PARK_FLAGS_NO_MONEY; + gameState.Park.Flags |= PARK_FLAGS_NO_MONEY; - if (gameState.ParkEntranceFee == 0) + if (gameState.Park.EntranceFee == 0) { - gameState.ParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags |= PARK_FLAGS_PARK_FREE_ENTRY; } else { - gameState.ParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags &= ~PARK_FLAGS_PARK_FREE_ENTRY; } - gameState.ParkFlags &= ~PARK_FLAGS_SPRITES_INITIALISED; + gameState.Park.Flags &= ~PARK_FLAGS_SPRITES_INITIALISED; gameState.GuestInitialCash = std::clamp(gameState.GuestInitialCash, 10.00_GBP, MAX_ENTRANCE_FEE); @@ -500,18 +500,18 @@ namespace Editor ResultWithMessage CheckPark() { auto& gameState = GetGameState(); - int32_t parkSize = ParkUpdateSize(gameState); + int32_t parkSize = Park::UpdateSize(gameState); if (parkSize == 0) { return { false, STR_PARK_MUST_OWN_SOME_LAND }; } - if (gameState.ParkEntrances.empty()) + if (gameState.Park.Entrances.empty()) { return { false, STR_NO_PARK_ENTRANCES }; } - for (const auto& parkEntrance : gameState.ParkEntrances) + for (const auto& parkEntrance : gameState.Park.Entrances) { int32_t direction = DirectionReverse(parkEntrance.direction); diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp index 1363b9197f..ec25c62349 100644 --- a/src/openrct2/GameState.cpp +++ b/src/openrct2/GameState.cpp @@ -70,7 +70,7 @@ namespace OpenRCT2 gameState.CurrentTicks = 0; MapInit(mapSize); - ParkInitialise(gameState); + Park::Initialise(gameState); FinanceInit(); BannerInit(gameState); RideInitAll(); @@ -344,7 +344,7 @@ namespace OpenRCT2 if (!(gScreenFlags & SCREEN_FLAGS_EDITOR)) { - ParkUpdate(gameState, gameState.Date); + Park::Update(gameState, gameState.Date); } ResearchUpdate(); diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index 94cdbbb4c8..564166c58a 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -34,29 +34,18 @@ namespace OpenRCT2 { - struct Park; - struct GameState_t { - ::OpenRCT2::Park Park{}; + ::OpenRCT2::Park::ParkData Park{}; std::string PluginStorage; uint32_t CurrentTicks{}; ::OpenRCT2::Date Date; - uint64_t ParkFlags; - uint16_t ParkRating; - money64 ParkEntranceFee; - std::vector ParkEntrances; - uint32_t ParkSize; - int16_t ParkRatingCasualtyPenalty; - money64 ParkValue; - money64 ParkValueHistory[FINANCE_GRAPH_SIZE]; money64 CompanyValue; // The total profit for the entire scenario that precedes the current financial table. money64 HistoricalProfit; money64 ConstructionRightsPrice; money64 CurrentExpenditure; money64 CurrentProfit; - uint8_t ParkRatingHistory[kParkRatingHistorySize]; uint32_t GuestsInParkHistory[32]; ClimateType Climate; ClimateState ClimateCurrent; diff --git a/src/openrct2/actions/CheatSetAction.cpp b/src/openrct2/actions/CheatSetAction.cpp index 5d9ef410c0..a119a1089b 100644 --- a/src/openrct2/actions/CheatSetAction.cpp +++ b/src/openrct2/actions/CheatSetAction.cpp @@ -228,7 +228,7 @@ GameActions::Result CheatSetAction::Execute() const gameState.ScenarioObjective.Type = OBJECTIVE_HAVE_FUN; break; case CheatType::SetForcedParkRating: - ParkSetForcedRating(_param1); + Park::SetForcedRating(_param1); break; case CheatType::AllowArbitraryRideTypeChanges: GetGameState().Cheats.AllowArbitraryRideTypeChanges = _param1 != 0; @@ -562,11 +562,11 @@ void CheatSetAction::SetScenarioNoMoney(bool enabled) const auto& gameState = GetGameState(); if (enabled) { - gameState.ParkFlags |= PARK_FLAGS_NO_MONEY; + gameState.Park.Flags |= PARK_FLAGS_NO_MONEY; } else { - gameState.ParkFlags &= ~PARK_FLAGS_NO_MONEY; + gameState.Park.Flags &= ~PARK_FLAGS_NO_MONEY; } // Invalidate all windows that have anything to do with finance @@ -609,7 +609,7 @@ void CheatSetAction::GenerateGuests(int32_t count) const { for (int32_t i = 0; i < count; i++) { - GenerateGuest(); + Park::GenerateGuest(); } WindowInvalidateByClass(WindowClass::BottomToolbar); } @@ -766,7 +766,7 @@ void CheatSetAction::OwnAllLand() const if (destOwnership != OWNERSHIP_UNOWNED) { surfaceElement->SetOwnership(destOwnership); - ParkUpdateFencesAroundTile(coords); + Park::UpdateFencesAroundTile(coords); MapInvalidateTile({ coords, baseZ, baseZ + 16 }); } } @@ -779,7 +779,7 @@ void CheatSetAction::OwnAllLand() const if (surfaceElement != nullptr) { surfaceElement->SetOwnership(OWNERSHIP_UNOWNED); - ParkUpdateFencesAroundTile(spawn); + Park::UpdateFencesAroundTile(spawn); uint16_t baseZ = surfaceElement->GetBaseZ(); MapInvalidateTile({ spawn, baseZ, baseZ + 16 }); } diff --git a/src/openrct2/actions/LandBuyRightsAction.cpp b/src/openrct2/actions/LandBuyRightsAction.cpp index 4f486ecfd2..2d206e9dcb 100644 --- a/src/openrct2/actions/LandBuyRightsAction.cpp +++ b/src/openrct2/actions/LandBuyRightsAction.cpp @@ -143,7 +143,7 @@ GameActions::Result LandBuyRightsAction::MapBuyLandRightsForTile(const CoordsXY& if (isExecuting) { surfaceElement->SetOwnership(OWNERSHIP_OWNED); - ParkUpdateFencesAroundTile(loc); + Park::UpdateFencesAroundTile(loc); } res.Cost = GetGameState().LandPrice; return res; diff --git a/src/openrct2/actions/LandSetHeightAction.cpp b/src/openrct2/actions/LandSetHeightAction.cpp index 11ae1abaa2..64a9edebbe 100644 --- a/src/openrct2/actions/LandSetHeightAction.cpp +++ b/src/openrct2/actions/LandSetHeightAction.cpp @@ -56,7 +56,7 @@ void LandSetHeightAction::Serialise(DataSerialiser& stream) GameActions::Result LandSetHeightAction::Query() const { auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) + if (gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) { return GameActions::Result(GameActions::Status::Disallowed, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY, STR_NONE); } @@ -78,7 +78,7 @@ GameActions::Result LandSetHeightAction::Query() const money64 sceneryRemovalCost = 0; if (!GetGameState().Cheats.DisableClearanceChecks) { - if (gameState.ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) + if (gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) { // Check for obstructing large trees TileElement* tileElement = CheckTreeObstructions(); diff --git a/src/openrct2/actions/LandSetRightsAction.cpp b/src/openrct2/actions/LandSetRightsAction.cpp index 4c46710c6f..813277a402 100644 --- a/src/openrct2/actions/LandSetRightsAction.cpp +++ b/src/openrct2/actions/LandSetRightsAction.cpp @@ -129,7 +129,7 @@ GameActions::Result LandSetRightsAction::MapBuyLandRightsForTile(const CoordsXY& { surfaceElement->SetOwnership( surfaceElement->GetOwnership() & ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)); - ParkUpdateFencesAroundTile(loc); + Park::UpdateFencesAroundTile(loc); } return res; case LandSetRightSetting::UnownConstructionRights: @@ -199,7 +199,7 @@ GameActions::Result LandSetRightsAction::MapBuyLandRightsForTile(const CoordsXY& gameState.PeepSpawns.end()); } surfaceElement->SetOwnership(_ownership); - ParkUpdateFencesAroundTile(loc); + Park::UpdateFencesAroundTile(loc); gMapLandRightsUpdateSuccess = true; } return res; diff --git a/src/openrct2/actions/LargeSceneryRemoveAction.cpp b/src/openrct2/actions/LargeSceneryRemoveAction.cpp index ff8bb62ee1..899a327875 100644 --- a/src/openrct2/actions/LargeSceneryRemoveAction.cpp +++ b/src/openrct2/actions/LargeSceneryRemoveAction.cpp @@ -97,7 +97,7 @@ GameActions::Result LargeSceneryRemoveAction::Query() const if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) { - if (GetGameState().ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) + if (GetGameState().Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) { if (sceneryEntry->HasFlag(LARGE_SCENERY_FLAG_IS_TREE)) { diff --git a/src/openrct2/actions/MapChangeSizeAction.cpp b/src/openrct2/actions/MapChangeSizeAction.cpp index d8e7eca10b..04e28ac200 100644 --- a/src/openrct2/actions/MapChangeSizeAction.cpp +++ b/src/openrct2/actions/MapChangeSizeAction.cpp @@ -73,7 +73,7 @@ GameActions::Result MapChangeSizeAction::Execute() const auto* ctx = OpenRCT2::GetContext(); auto uiContext = ctx->GetUiContext(); auto* windowManager = uiContext->GetWindowManager(); - ParkUpdateSize(gameState); + OpenRCT2::Park::UpdateSize(gameState); windowManager->BroadcastIntent(Intent(INTENT_ACTION_MAP)); GfxInvalidateScreen(); diff --git a/src/openrct2/actions/ParkEntrancePlaceAction.cpp b/src/openrct2/actions/ParkEntrancePlaceAction.cpp index 50e3b7619f..8cfdf87d27 100644 --- a/src/openrct2/actions/ParkEntrancePlaceAction.cpp +++ b/src/openrct2/actions/ParkEntrancePlaceAction.cpp @@ -75,7 +75,7 @@ GameActions::Result ParkEntrancePlaceAction::Query() const } const auto& gameState = GetGameState(); - if (gameState.ParkEntrances.size() >= OpenRCT2::Limits::MaxParkEntrances) + if (gameState.Park.Entrances.size() >= OpenRCT2::Limits::MaxParkEntrances) { return GameActions::Result( GameActions::Status::InvalidParameters, STR_CANT_BUILD_THIS_HERE, STR_ERR_TOO_MANY_PARK_ENTRANCES); @@ -121,7 +121,7 @@ GameActions::Result ParkEntrancePlaceAction::Execute() const uint32_t flags = GetFlags(); - GetGameState().ParkEntrances.push_back(_loc); + GetGameState().Park.Entrances.push_back(_loc); auto zLow = _loc.z; auto zHigh = zLow + ParkEntranceHeight; @@ -170,11 +170,11 @@ GameActions::Result ParkEntrancePlaceAction::Execute() const FootpathConnectEdges(entranceLoc, entranceElement->as(), GAME_COMMAND_FLAG_APPLY); } - ParkUpdateFences(entranceLoc); - ParkUpdateFences({ entranceLoc.x - COORDS_XY_STEP, entranceLoc.y }); - ParkUpdateFences({ entranceLoc.x + COORDS_XY_STEP, entranceLoc.y }); - ParkUpdateFences({ entranceLoc.x, entranceLoc.y - COORDS_XY_STEP }); - ParkUpdateFences({ entranceLoc.x, entranceLoc.y + COORDS_XY_STEP }); + Park::UpdateFences(entranceLoc); + Park::UpdateFences({ entranceLoc.x - COORDS_XY_STEP, entranceLoc.y }); + Park::UpdateFences({ entranceLoc.x + COORDS_XY_STEP, entranceLoc.y }); + Park::UpdateFences({ entranceLoc.x, entranceLoc.y - COORDS_XY_STEP }); + Park::UpdateFences({ entranceLoc.x, entranceLoc.y + COORDS_XY_STEP }); MapInvalidateTile({ entranceLoc, entranceElement->GetBaseZ(), entranceElement->GetClearanceZ() }); diff --git a/src/openrct2/actions/ParkEntranceRemoveAction.cpp b/src/openrct2/actions/ParkEntranceRemoveAction.cpp index 8aeaa39793..d47f15f0ef 100644 --- a/src/openrct2/actions/ParkEntranceRemoveAction.cpp +++ b/src/openrct2/actions/ParkEntranceRemoveAction.cpp @@ -78,7 +78,7 @@ GameActions::Result ParkEntranceRemoveAction::Execute() const } auto& gameState = GetGameState(); - auto direction = (gameState.ParkEntrances[entranceIndex].direction - 1) & 3; + auto direction = (gameState.Park.Entrances[entranceIndex].direction - 1) & 3; // Centre (sign) ParkEntranceRemoveSegment(_loc); @@ -91,7 +91,7 @@ GameActions::Result ParkEntranceRemoveAction::Execute() const ParkEntranceRemoveSegment( { _loc.x - CoordsDirectionDelta[direction].x, _loc.y - CoordsDirectionDelta[direction].y, _loc.z }); - gameState.ParkEntrances.erase(gameState.ParkEntrances.begin() + entranceIndex); + gameState.Park.Entrances.erase(gameState.Park.Entrances.begin() + entranceIndex); return res; } @@ -105,5 +105,5 @@ void ParkEntranceRemoveAction::ParkEntranceRemoveSegment(const CoordsXYZ& loc) c MapInvalidateTile({ loc, entranceElement->GetBaseZ(), entranceElement->GetClearanceZ() }); entranceElement->Remove(); - ParkUpdateFences({ loc.x, loc.y }); + Park::UpdateFences({ loc.x, loc.y }); } diff --git a/src/openrct2/actions/ParkMarketingAction.cpp b/src/openrct2/actions/ParkMarketingAction.cpp index 1912dd663d..9d64090eca 100644 --- a/src/openrct2/actions/ParkMarketingAction.cpp +++ b/src/openrct2/actions/ParkMarketingAction.cpp @@ -56,7 +56,7 @@ GameActions::Result ParkMarketingAction::Query() const return GameActions::Result( GameActions::Status::InvalidParameters, STR_CANT_START_MARKETING_CAMPAIGN, STR_ERR_VALUE_OUT_OF_RANGE); } - if (GetGameState().ParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) + if (GetGameState().Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_START_MARKETING_CAMPAIGN, diff --git a/src/openrct2/actions/ParkSetEntranceFeeAction.cpp b/src/openrct2/actions/ParkSetEntranceFeeAction.cpp index 89c235745c..da155eb316 100644 --- a/src/openrct2/actions/ParkSetEntranceFeeAction.cpp +++ b/src/openrct2/actions/ParkSetEntranceFeeAction.cpp @@ -42,12 +42,12 @@ void ParkSetEntranceFeeAction::Serialise(DataSerialiser& stream) GameActions::Result ParkSetEntranceFeeAction::Query() const { - if ((GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) != 0) + if ((GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) != 0) { LOG_ERROR("Can't set park entrance fee because the park has no money"); return GameActions::Result(GameActions::Status::Disallowed, STR_ERR_CANT_CHANGE_PARK_ENTRANCE_FEE, STR_NONE); } - else if (!ParkEntranceFeeUnlocked()) + else if (!Park::EntranceFeeUnlocked()) { LOG_ERROR("Park entrance fee is locked"); return GameActions::Result(GameActions::Status::Disallowed, STR_ERR_CANT_CHANGE_PARK_ENTRANCE_FEE, STR_NONE); @@ -64,7 +64,7 @@ GameActions::Result ParkSetEntranceFeeAction::Query() const GameActions::Result ParkSetEntranceFeeAction::Execute() const { - GetGameState().ParkEntranceFee = _fee; + GetGameState().Park.EntranceFee = _fee; WindowInvalidateByClass(WindowClass::ParkInformation); return GameActions::Result(); } diff --git a/src/openrct2/actions/ParkSetParameterAction.cpp b/src/openrct2/actions/ParkSetParameterAction.cpp index 83d4ad1030..a113238ed3 100644 --- a/src/openrct2/actions/ParkSetParameterAction.cpp +++ b/src/openrct2/actions/ParkSetParameterAction.cpp @@ -60,16 +60,16 @@ GameActions::Result ParkSetParameterAction::Execute() const switch (_parameter) { case ParkParameter::Close: - if (gameState.ParkFlags & PARK_FLAGS_PARK_OPEN) + if (gameState.Park.Flags & PARK_FLAGS_PARK_OPEN) { - gameState.ParkFlags &= ~PARK_FLAGS_PARK_OPEN; + gameState.Park.Flags &= ~PARK_FLAGS_PARK_OPEN; WindowInvalidateByClass(WindowClass::ParkInformation); } break; case ParkParameter::Open: - if (!(gameState.ParkFlags & PARK_FLAGS_PARK_OPEN)) + if (!(gameState.Park.Flags & PARK_FLAGS_PARK_OPEN)) { - gameState.ParkFlags |= PARK_FLAGS_PARK_OPEN; + gameState.Park.Flags |= PARK_FLAGS_PARK_OPEN; WindowInvalidateByClass(WindowClass::ParkInformation); } break; diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 7512bc69a8..9eafd8009e 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -207,7 +207,7 @@ GameActions::Result RideCreateAction::Execute() const ride->excitement = kRideRatingUndefined; auto& gameState = GetGameState(); - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { for (auto i = 0; i < RCT2::ObjectLimits::MaxShopItemsPerRideEntry; i++) { @@ -216,7 +216,7 @@ GameActions::Result RideCreateAction::Execute() const if (rideEntry->shop_item[0] == ShopItem::None) { - if (!ParkRidePricesUnlocked() || gameState.ParkEntranceFee > 0) + if (!Park::RidePricesUnlocked() || gameState.Park.EntranceFee > 0) { ride->price[0] = 0; } diff --git a/src/openrct2/actions/RideDemolishAction.cpp b/src/openrct2/actions/RideDemolishAction.cpp index 81654fdb2e..4e7e3f9ed7 100644 --- a/src/openrct2/actions/RideDemolishAction.cpp +++ b/src/openrct2/actions/RideDemolishAction.cpp @@ -156,7 +156,7 @@ GameActions::Result RideDemolishAction::DemolishRide(Ride& ride) const } ride.Delete(); - GetGameState().ParkValue = CalculateParkValue(); + GetGameState().Park.Value = Park::CalculateParkValue(); // Close windows related to the demolished ride WindowCloseByNumber(WindowClass::RideConstruction, rideId.ToUnderlying()); diff --git a/src/openrct2/actions/ScenarioSetSettingAction.cpp b/src/openrct2/actions/ScenarioSetSettingAction.cpp index 87043377e8..3e972ae68d 100644 --- a/src/openrct2/actions/ScenarioSetSettingAction.cpp +++ b/src/openrct2/actions/ScenarioSetSettingAction.cpp @@ -57,22 +57,22 @@ GameActions::Result ScenarioSetSettingAction::Execute() const { if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_NO_MONEY; + gameState.Park.Flags |= PARK_FLAGS_NO_MONEY; } else { - gameState.ParkFlags &= ~PARK_FLAGS_NO_MONEY; + gameState.Park.Flags &= ~PARK_FLAGS_NO_MONEY; } } else { if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_NO_MONEY; + gameState.Park.Flags |= PARK_FLAGS_NO_MONEY; } else { - gameState.ParkFlags &= ~PARK_FLAGS_NO_MONEY; + gameState.Park.Flags &= ~PARK_FLAGS_NO_MONEY; } // Invalidate all windows that have anything to do with finance WindowInvalidateByClass(WindowClass::Ride); @@ -106,11 +106,11 @@ GameActions::Result ScenarioSetSettingAction::Execute() const case ScenarioSetSetting::ForbidMarketingCampaigns: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; + gameState.Park.Flags |= PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; } else { - gameState.ParkFlags &= ~PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; + gameState.Park.Flags &= ~PARK_FLAGS_FORBID_MARKETING_CAMPAIGN; } break; case ScenarioSetSetting::AverageCashPerGuest: @@ -128,21 +128,21 @@ GameActions::Result ScenarioSetSettingAction::Execute() const case ScenarioSetSetting::GuestsPreferLessIntenseRides: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_PREF_LESS_INTENSE_RIDES; + gameState.Park.Flags |= PARK_FLAGS_PREF_LESS_INTENSE_RIDES; } else { - gameState.ParkFlags &= ~PARK_FLAGS_PREF_LESS_INTENSE_RIDES; + gameState.Park.Flags &= ~PARK_FLAGS_PREF_LESS_INTENSE_RIDES; } break; case ScenarioSetSetting::GuestsPreferMoreIntenseRides: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_PREF_MORE_INTENSE_RIDES; + gameState.Park.Flags |= PARK_FLAGS_PREF_MORE_INTENSE_RIDES; } else { - gameState.ParkFlags &= ~PARK_FLAGS_PREF_MORE_INTENSE_RIDES; + gameState.Park.Flags &= ~PARK_FLAGS_PREF_MORE_INTENSE_RIDES; } break; case ScenarioSetSetting::CostToBuyLand: @@ -156,96 +156,96 @@ GameActions::Result ScenarioSetSettingAction::Execute() const { if (_value == 0) { - gameState.ParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gameState.ParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; - gameState.ParkEntranceFee = 0.00_GBP; + gameState.Park.Flags |= PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.EntranceFee = 0.00_GBP; } else if (_value == 1) { - gameState.ParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; - gameState.ParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; - gameState.ParkEntranceFee = 10.00_GBP; + gameState.Park.Flags &= ~PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.EntranceFee = 10.00_GBP; } else { - gameState.ParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gameState.ParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; - gameState.ParkEntranceFee = 10.00_GBP; + gameState.Park.Flags |= PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.EntranceFee = 10.00_GBP; } } else { if (_value == 0) { - gameState.ParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gameState.ParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.Flags |= PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; } else if (_value == 1) { - gameState.ParkFlags &= ~PARK_FLAGS_PARK_FREE_ENTRY; - gameState.ParkFlags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.Flags &= ~PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags &= ~PARK_FLAGS_UNLOCK_ALL_PRICES; } else { - gameState.ParkFlags |= PARK_FLAGS_PARK_FREE_ENTRY; - gameState.ParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.Flags |= PARK_FLAGS_PARK_FREE_ENTRY; + gameState.Park.Flags |= PARK_FLAGS_UNLOCK_ALL_PRICES; } WindowInvalidateByClass(WindowClass::ParkInformation); WindowInvalidateByClass(WindowClass::Ride); } break; case ScenarioSetSetting::ParkChargeEntryFee: - gameState.ParkEntranceFee = std::clamp(_value, 0.00_GBP, MAX_ENTRANCE_FEE); + gameState.Park.EntranceFee = std::clamp(_value, 0.00_GBP, MAX_ENTRANCE_FEE); WindowInvalidateByClass(WindowClass::ParkInformation); break; case ScenarioSetSetting::ForbidTreeRemoval: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_FORBID_TREE_REMOVAL; + gameState.Park.Flags |= PARK_FLAGS_FORBID_TREE_REMOVAL; } else { - gameState.ParkFlags &= ~PARK_FLAGS_FORBID_TREE_REMOVAL; + gameState.Park.Flags &= ~PARK_FLAGS_FORBID_TREE_REMOVAL; } break; case ScenarioSetSetting::ForbidLandscapeChanges: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; + gameState.Park.Flags |= PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; } else { - gameState.ParkFlags &= ~PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; + gameState.Park.Flags &= ~PARK_FLAGS_FORBID_LANDSCAPE_CHANGES; } break; case ScenarioSetSetting::ForbidHighConstruction: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; + gameState.Park.Flags |= PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; } else { - gameState.ParkFlags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; + gameState.Park.Flags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; } break; case ScenarioSetSetting::ParkRatingHigherDifficultyLevel: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_DIFFICULT_PARK_RATING; + gameState.Park.Flags |= PARK_FLAGS_DIFFICULT_PARK_RATING; } else { - gameState.ParkFlags &= ~PARK_FLAGS_DIFFICULT_PARK_RATING; + gameState.Park.Flags &= ~PARK_FLAGS_DIFFICULT_PARK_RATING; } break; case ScenarioSetSetting::GuestGenerationHigherDifficultyLevel: if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_DIFFICULT_GUEST_GENERATION; + gameState.Park.Flags |= PARK_FLAGS_DIFFICULT_GUEST_GENERATION; } else { - gameState.ParkFlags &= ~PARK_FLAGS_DIFFICULT_GUEST_GENERATION; + gameState.Park.Flags &= ~PARK_FLAGS_DIFFICULT_GUEST_GENERATION; } break; case ScenarioSetSetting::AllowEarlyCompletion: @@ -255,11 +255,11 @@ GameActions::Result ScenarioSetSettingAction::Execute() const { if (_value != 0) { - gameState.ParkFlags |= PARK_FLAGS_RCT1_INTEREST; + gameState.Park.Flags |= PARK_FLAGS_RCT1_INTEREST; } else { - gameState.ParkFlags &= ~PARK_FLAGS_RCT1_INTEREST; + gameState.Park.Flags &= ~PARK_FLAGS_RCT1_INTEREST; } break; } diff --git a/src/openrct2/actions/SmallSceneryRemoveAction.cpp b/src/openrct2/actions/SmallSceneryRemoveAction.cpp index b52f741923..77ca81964b 100644 --- a/src/openrct2/actions/SmallSceneryRemoveAction.cpp +++ b/src/openrct2/actions/SmallSceneryRemoveAction.cpp @@ -79,7 +79,7 @@ GameActions::Result SmallSceneryRemoveAction::Query() const && !GetGameState().Cheats.SandboxMode) { // Check if allowed to remove item - if (GetGameState().ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) + if (GetGameState().Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) { if (entry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE)) { diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index 27708f73b2..09e740c119 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -288,10 +288,10 @@ void StaffHireNewAction::AutoPositionNewStaff(Peep* newPeep) const { // No walking guests; pick random park entrance const auto& gameState = GetGameState(); - if (!gameState.ParkEntrances.empty()) + if (!gameState.Park.Entrances.empty()) { - auto rand = ScenarioRandMax(static_cast(gameState.ParkEntrances.size())); - const auto& entrance = gameState.ParkEntrances[rand]; + auto rand = ScenarioRandMax(static_cast(gameState.Park.Entrances.size())); + const auto& entrance = gameState.Park.Entrances[rand]; auto dir = entrance.direction; newLocation = entrance; // TODO: Replace with CoordsDirectionDelta diff --git a/src/openrct2/actions/SurfaceSetStyleAction.cpp b/src/openrct2/actions/SurfaceSetStyleAction.cpp index 658f38f2ea..a9151787e7 100644 --- a/src/openrct2/actions/SurfaceSetStyleAction.cpp +++ b/src/openrct2/actions/SurfaceSetStyleAction.cpp @@ -86,7 +86,7 @@ GameActions::Result SurfaceSetStyleAction::Query() const // Do nothing if not in editor, sandbox mode or landscaping is forbidden if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode - && (GetGameState().ParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)) + && (GetGameState().Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_CHANGE_LAND_TYPE, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY); diff --git a/src/openrct2/actions/WaterSetHeightAction.cpp b/src/openrct2/actions/WaterSetHeightAction.cpp index ab472abb02..418f67874a 100644 --- a/src/openrct2/actions/WaterSetHeightAction.cpp +++ b/src/openrct2/actions/WaterSetHeightAction.cpp @@ -49,7 +49,7 @@ GameActions::Result WaterSetHeightAction::Query() const res.Position = { _coords, _height * COORDS_Z_STEP }; if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode - && GetGameState().ParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) + && GetGameState().Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) { return GameActions::Result(GameActions::Status::Disallowed, STR_NONE, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY); } diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index 0dee7da7cd..77d65b6887 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -1075,7 +1075,7 @@ void Guest::Tick128UpdateGuest(uint32_t index) possible_thoughts[num_thoughts++] = PeepThoughtType::Toilet; } - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) && CashInPocket <= 9.00_GBP && Happiness >= 105 + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) && CashInPocket <= 9.00_GBP && Happiness >= 105 && Energy >= 70) { /* The energy check was originally a second check on happiness. @@ -1539,7 +1539,7 @@ bool Guest::DecideAndBuyItem(Ride& ride, const ShopItem shopItem, money64 price) if (!hasVoucher) { - if (price != 0 && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (price != 0 && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { if (CashInPocket == 0) { @@ -1586,7 +1586,7 @@ bool Guest::DecideAndBuyItem(Ride& ride, const ShopItem shopItem, money64 price) itemValue -= price; itemValue = std::max(0.80_GBP, itemValue); - if (!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { if (itemValue >= static_cast(ScenarioRand() & 0x07)) { @@ -1694,7 +1694,7 @@ bool Guest::DecideAndBuyItem(Ride& ride, const ShopItem shopItem, money64 price) expenditure = ExpenditureType::FoodDrinkStock; } - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) FinancePayment(shopItemDescriptor.Cost, expenditure); // Sets the expenditure type to *_FOODDRINK_SALES or *_SHOP_SALES appropriately. @@ -1704,7 +1704,7 @@ bool Guest::DecideAndBuyItem(Ride& ride, const ShopItem shopItem, money64 price) RemoveItem(ShopItem::Voucher); WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_INVENTORY; } - else if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + else if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { SpendMoney(*expend_type, price, expenditure); } @@ -2006,7 +2006,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b auto& gameState = GetGameState(); // Basic price checks - if (ridePrice != 0 && !PeepHasVoucherForFreeRide(this, ride) && !(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (ridePrice != 0 && !PeepHasVoucherForFreeRide(this, ride) && !(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { if (ridePrice > CashInPocket) { @@ -2155,7 +2155,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b // If the value of the ride hasn't yet been calculated, peeps will be willing to pay any amount for the ride. if (value != RIDE_VALUE_UNDEFINED && !PeepHasVoucherForFreeRide(this, ride) - && !(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + && !(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { // The amount peeps are willing to pay is decreased by 75% if they had to pay to enter the park. if (PeepFlags & PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY) @@ -2181,7 +2181,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b // A ride is good value if the price is 50% or less of the ride value and the peep didn't pay to enter the park. if (ridePrice <= (value / 2) && peepAtRide) { - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { if (!(PeepFlags & PEEP_FLAGS_HAS_PAID_FOR_PARK_ENTRY)) { @@ -2300,7 +2300,7 @@ void Guest::SpendMoney(money64 amount, ExpenditureType expenditure) */ void Guest::SpendMoney(money64& peep_expend_type, money64 amount, ExpenditureType expenditure) { - assert(!(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)); + assert(!(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)); CashInPocket = std::max(0.00_GBP, static_cast(CashInPocket) - amount); CashSpent += amount; @@ -2615,7 +2615,7 @@ static bool PeepCheckRidePriceAtEntrance(Guest* peep, const Ride& ride, money64 && peep->VoucherRideId == peep->CurrentRide) return true; - if (peep->CashInPocket <= 0 && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (peep->CashInPocket <= 0 && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { peep->InsertNewThought(PeepThoughtType::SpentMoney); PeepUpdateRideAtEntranceTryLeave(peep); @@ -2709,7 +2709,7 @@ static void PeepUpdateFavouriteRide(Guest* peep, const Ride& ride) /* rct2: 0x00695555 */ static int16_t PeepCalculateRideValueSatisfaction(Guest* peep, const Ride& ride) { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) { return -30; } @@ -2883,7 +2883,7 @@ static bool PeepShouldGoOnRideAgain(Guest* peep, const Ride& ride) static bool PeepShouldPreferredIntensityIncrease(Guest* peep) { - if (GetGameState().ParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) + if (GetGameState().Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) return false; if (peep->Happiness < 200) return false; @@ -3068,7 +3068,7 @@ static void PeepDecideWhetherToLeavePark(Guest* peep) * in the park. */ if (!(peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK)) { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) { if (peep->Energy >= 70 && peep->Happiness >= 60) { @@ -3298,7 +3298,7 @@ void Guest::StopPurchaseThought(ride_type_t rideType) */ static bool PeepShouldUseCashMachine(Guest* peep, RideId rideIndex) { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) return false; if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) return false; @@ -7141,9 +7141,9 @@ Guest* Guest::Generate(const CoordsXYZ& coords) /* Check which intensity boxes are enabled * and apply the appropriate intensity settings. */ - if (gameState.ParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) + if (gameState.Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) { - if (gameState.ParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) + if (gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) { intensityLowest = 0; intensityHighest = 15; @@ -7154,7 +7154,7 @@ Guest* Guest::Generate(const CoordsXYZ& coords) intensityHighest = 4; } } - else if (gameState.ParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) + else if (gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) { intensityLowest = 9; intensityHighest = 15; @@ -7163,7 +7163,7 @@ Guest* Guest::Generate(const CoordsXYZ& coords) peep->Intensity = IntensityRange(intensityLowest, intensityHighest); uint8_t nauseaTolerance = ScenarioRand() & 0x7; - if (gameState.ParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) + if (gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) { nauseaTolerance += 4; } @@ -7220,7 +7220,7 @@ Guest* Guest::Generate(const CoordsXYZ& coords) cash = 500; } - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { cash = 0; } diff --git a/src/openrct2/entity/Peep.cpp b/src/openrct2/entity/Peep.cpp index 9b91f94ca8..99f2c110af 100644 --- a/src/openrct2/entity/Peep.cpp +++ b/src/openrct2/entity/Peep.cpp @@ -718,7 +718,7 @@ void Peep::UpdateFalling() } auto& gameState = GetGameState(); - gameState.ParkRatingCasualtyPenalty = std::min(gameState.ParkRatingCasualtyPenalty + 25, 1000); + gameState.Park.RatingCasualtyPenalty = std::min(gameState.Park.RatingCasualtyPenalty + 25, 1000); Remove(); return; } @@ -1538,7 +1538,7 @@ void Peep::FormatNameTo(Formatter& ft) const ft.Add(_staffNames[staffNameIndex]); ft.Add(PeepId); } - else if (GetGameState().ParkFlags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES) + else if (GetGameState().Park.Flags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES) { auto realNameStringId = GetRealNameStringIDFromPeepID(PeepId); ft.Add(realNameStringId); @@ -1805,7 +1805,7 @@ static bool PeepInteractWithEntrance(Peep* peep, const CoordsXYE& coords, uint8_ if (!(guest->PeepFlags & PEEP_FLAGS_LEAVING_PARK)) { // If the park is open and leaving flag isn't set return to centre - if (gameState.ParkFlags & PARK_FLAGS_PARK_OPEN) + if (gameState.Park.Flags & PARK_FLAGS_PARK_OPEN) { PeepReturnToCentreOfTile(guest); return true; @@ -1838,7 +1838,7 @@ static bool PeepInteractWithEntrance(Peep* peep, const CoordsXYE& coords, uint8_ return true; } - if (!(gameState.ParkFlags & PARK_FLAGS_PARK_OPEN)) + if (!(gameState.Park.Flags & PARK_FLAGS_PARK_OPEN)) { guest->State = PeepState::LeavingPark; guest->Var37 = 1; @@ -1849,10 +1849,10 @@ static bool PeepInteractWithEntrance(Peep* peep, const CoordsXYE& coords, uint8_ } bool found = false; - auto entrance = std::find_if(gameState.ParkEntrances.begin(), gameState.ParkEntrances.end(), [coords](const auto& e) { + auto entrance = std::find_if(gameState.Park.Entrances.begin(), gameState.Park.Entrances.end(), [coords](const auto& e) { return coords.ToTileStart() == e; }); - if (entrance != gameState.ParkEntrances.end()) + if (entrance != gameState.Park.Entrances.end()) { int16_t z = entrance->z / 8; entranceDirection = entrance->direction; @@ -1911,7 +1911,7 @@ static bool PeepInteractWithEntrance(Peep* peep, const CoordsXYE& coords, uint8_ return true; } - auto entranceFee = ParkGetEntranceFee(); + auto entranceFee = Park::GetEntranceFee(); if (entranceFee != 0) { if (guest->HasItem(ShopItem::Voucher)) @@ -2287,7 +2287,7 @@ static bool PeepInteractWithShop(Peep* peep, const CoordsXYE& coords) } auto cost = ride->price[0]; - if (cost != 0 && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (cost != 0 && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { ride->total_profit += cost; ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; @@ -2552,7 +2552,7 @@ int32_t PeepCompare(const EntityId sprite_index_a, const EntityId sprite_index_b if (peep_a->Name == nullptr && peep_b->Name == nullptr) { - if (GetGameState().ParkFlags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES) + if (GetGameState().Park.Flags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES) { // Potentially could find a more optional way of sorting dynamic real names } @@ -2585,12 +2585,12 @@ void PeepUpdateNames(bool realNames) auto& gameState = GetGameState(); if (realNames) { - gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; + gameState.Park.Flags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; // Peep names are now dynamic } else { - gameState.ParkFlags &= ~PARK_FLAGS_SHOW_REAL_GUEST_NAMES; + gameState.Park.Flags &= ~PARK_FLAGS_SHOW_REAL_GUEST_NAMES; // Peep names are now dynamic } diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 3692ce8ba4..84562cd63d 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -557,11 +557,11 @@ static int32_t ConsoleCommandGet(InteractiveConsole& console, const arguments_t& { if (argv[0] == "park_rating") { - console.WriteFormatLine("park_rating %d", gameState.ParkRating); + console.WriteFormatLine("park_rating %d", gameState.Park.Rating); } else if (argv[0] == "park_value") { - console.WriteFormatLine("park_value %d", gameState.ParkValue / 10); + console.WriteFormatLine("park_value %d", gameState.Park.Value / 10); } else if (argv[0] == "company_value") { @@ -597,7 +597,7 @@ static int32_t ConsoleCommandGet(InteractiveConsole& console, const arguments_t& { console.WriteFormatLine("guest_initial_happiness %d%% (%d)", 15, gameState.GuestInitialHappiness); } - else if (current_happiness == CalculateGuestInitialHappiness(i)) + else if (current_happiness == Park::CalculateGuestInitialHappiness(i)) { console.WriteFormatLine("guest_initial_happiness %d%% (%d)", i, gameState.GuestInitialHappiness); break; @@ -619,52 +619,52 @@ static int32_t ConsoleCommandGet(InteractiveConsole& console, const arguments_t& else if (argv[0] == "guest_prefer_less_intense_rides") { console.WriteFormatLine( - "guest_prefer_less_intense_rides %d", (gameState.ParkFlags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) != 0); + "guest_prefer_less_intense_rides %d", (gameState.Park.Flags & PARK_FLAGS_PREF_LESS_INTENSE_RIDES) != 0); } else if (argv[0] == "guest_prefer_more_intense_rides") { console.WriteFormatLine( - "guest_prefer_more_intense_rides %d", (gameState.ParkFlags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) != 0); + "guest_prefer_more_intense_rides %d", (gameState.Park.Flags & PARK_FLAGS_PREF_MORE_INTENSE_RIDES) != 0); } else if (argv[0] == "forbid_marketing_campaigns") { console.WriteFormatLine( - "forbid_marketing_campaigns %d", (gameState.ParkFlags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) != 0); + "forbid_marketing_campaigns %d", (gameState.Park.Flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) != 0); } else if (argv[0] == "forbid_landscape_changes") { console.WriteFormatLine( - "forbid_landscape_changes %d", (gameState.ParkFlags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) != 0); + "forbid_landscape_changes %d", (gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) != 0); } else if (argv[0] == "forbid_tree_removal") { - console.WriteFormatLine("forbid_tree_removal %d", (gameState.ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) != 0); + console.WriteFormatLine("forbid_tree_removal %d", (gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) != 0); } else if (argv[0] == "forbid_high_construction") { console.WriteFormatLine( - "forbid_high_construction %d", (gameState.ParkFlags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION) != 0); + "forbid_high_construction %d", (gameState.Park.Flags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION) != 0); } else if (argv[0] == "pay_for_rides") { - console.WriteFormatLine("pay_for_rides %d", (gameState.ParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) != 0); + console.WriteFormatLine("pay_for_rides %d", (gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY) != 0); } else if (argv[0] == "no_money") { - console.WriteFormatLine("no_money %d", (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) != 0); + console.WriteFormatLine("no_money %d", (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) != 0); } else if (argv[0] == "difficult_park_rating") { - console.WriteFormatLine("difficult_park_rating %d", (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_PARK_RATING) != 0); + console.WriteFormatLine("difficult_park_rating %d", (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING) != 0); } else if (argv[0] == "difficult_guest_generation") { console.WriteFormatLine( - "difficult_guest_generation %d", (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0); + "difficult_guest_generation %d", (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0); } else if (argv[0] == "park_open") { - console.WriteFormatLine("park_open %d", (gameState.ParkFlags & PARK_FLAGS_PARK_OPEN) != 0); + console.WriteFormatLine("park_open %d", (gameState.Park.Flags & PARK_FLAGS_PARK_OPEN) != 0); } else if (argv[0] == "land_rights_cost") { @@ -850,7 +850,8 @@ static int32_t ConsoleCommandSet(InteractiveConsole& console, const arguments_t& else if (argv[0] == "guest_initial_happiness" && InvalidArguments(&invalidArgs, int_valid[0])) { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::GuestInitialHappiness, CalculateGuestInitialHappiness(static_cast(int_val[0]))); + ScenarioSetSetting::GuestInitialHappiness, + Park::CalculateGuestInitialHappiness(static_cast(int_val[0]))); scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) { if (res->Error != GameActions::Status::Ok) console.WriteLineError("set guest_initial_happiness command failed, likely due to permissions."); @@ -951,7 +952,7 @@ static int32_t ConsoleCommandSet(InteractiveConsole& console, const arguments_t& } else if (argv[0] == "pay_for_rides" && InvalidArguments(&invalidArgs, int_valid[0])) { - SET_FLAG(gameState.ParkFlags, PARK_FLAGS_PARK_FREE_ENTRY, int_val[0]); + SET_FLAG(gameState.Park.Flags, PARK_FLAGS_PARK_FREE_ENTRY, int_val[0]); console.Execute("get pay_for_rides"); } else if (argv[0] == "no_money" && InvalidArguments(&invalidArgs, int_valid[0])) diff --git a/src/openrct2/management/Award.cpp b/src/openrct2/management/Award.cpp index 146fe49403..0904b7b451 100644 --- a/src/openrct2/management/Award.cpp +++ b/src/openrct2/management/Award.cpp @@ -176,13 +176,13 @@ static bool AwardIsDeservedBestValue(int32_t activeAwardTypes) if (activeAwardTypes & EnumToFlag(AwardType::MostDisappointing)) return false; - if ((gameState.ParkFlags & PARK_FLAGS_NO_MONEY) || !ParkEntranceFeeUnlocked()) + if ((gameState.Park.Flags & PARK_FLAGS_NO_MONEY) || !Park::EntranceFeeUnlocked()) return false; if (gameState.TotalRideValueForMoney < 10.00_GBP) return false; - if (ParkGetEntranceFee() + 0.10_GBP >= gameState.TotalRideValueForMoney / 2) + if (Park::GetEntranceFee() + 0.10_GBP >= gameState.TotalRideValueForMoney / 2) return false; return true; @@ -228,10 +228,10 @@ static bool AwardIsDeservedWorstValue(int32_t activeAwardTypes) if (activeAwardTypes & EnumToFlag(AwardType::BestValue)) return false; - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) return false; - const auto parkEntranceFee = ParkGetEntranceFee(); + const auto parkEntranceFee = Park::GetEntranceFee(); if (parkEntranceFee == 0.00_GBP) return false; if (parkEntranceFee <= gameState.TotalRideValueForMoney) @@ -407,7 +407,7 @@ static bool AwardIsDeservedMostDisappointing(int32_t activeAwardTypes) { if (activeAwardTypes & EnumToFlag(AwardType::BestValue)) return false; - if (GetGameState().ParkRating > 650) + if (GetGameState().Park.Rating > 650) return false; // Count the number of disappointing rides @@ -622,7 +622,7 @@ void AwardUpdateAll() } // Only add new awards if park is open - if (GetGameState().ParkFlags & PARK_FLAGS_PARK_OPEN) + if (GetGameState().Park.Flags & PARK_FLAGS_PARK_OPEN) { // Set active award types as flags int32_t activeAwardTypes = 0; diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index cd0abc8660..7e9f429800 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -47,7 +47,7 @@ static constexpr int32_t dword_988E60[EnumValue(ExpenditureType::Count)] = { */ bool FinanceCheckMoneyRequired(uint32_t flags) { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) return false; if (gScreenFlags & SCREEN_FLAGS_EDITOR) return false; @@ -99,7 +99,7 @@ void FinancePayWages() { PROFILED_FUNCTION(); - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) { return; } @@ -117,7 +117,7 @@ void FinancePayWages() void FinancePayResearch() { const auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { return; } @@ -134,7 +134,7 @@ void FinancePayInterest() { const auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { return; } @@ -143,7 +143,7 @@ void FinancePayInterest() // that will overflow money64 if the loan is greater than (1 << 31) / (5 * current_interest_rate) const money64 current_loan = gameState.BankLoan; const auto current_interest_rate = gameState.BankLoanInterestRate; - const money64 interest_to_pay = (gameState.ParkFlags & PARK_FLAGS_RCT1_INTEREST) + const money64 interest_to_pay = (gameState.Park.Flags & PARK_FLAGS_RCT1_INTEREST) ? (current_loan / 2400) : (current_loan * 5 * current_interest_rate) >> 14; @@ -165,7 +165,7 @@ void FinancePayRideUpkeep() ride.Renew(); } - if (ride.status != RideStatus::Closed && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY)) + if (ride.status != RideStatus::Closed && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY)) { auto upkeep = ride.upkeep_cost; if (upkeep != kMoney64Undefined) @@ -190,7 +190,7 @@ void FinanceResetHistory() { gameState.CashHistory[i] = kMoney64Undefined; gameState.WeeklyProfitHistory[i] = kMoney64Undefined; - gameState.ParkValueHistory[i] = kMoney64Undefined; + gameState.Park.ValueHistory[i] = kMoney64Undefined; } for (uint32_t i = 0; i < EXPENDITURE_TABLE_MONTH_COUNT; ++i) @@ -229,7 +229,7 @@ void FinanceInit() gameState.MaxBankLoan = 20000.00_GBP; gameState.BankLoanInterestRate = 10; - gameState.ParkValue = 0; + gameState.Park.Value = 0; gameState.CompanyValue = 0; gameState.HistoricalProfit = 0; gameState.ScenarioCompletedCompanyValue = kMoney64Undefined; @@ -252,7 +252,7 @@ void FinanceUpdateDailyProfit() money64 current_profit = 0; - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { // Staff costs for (auto peep : EntityList()) @@ -372,4 +372,4 @@ money64 FinanceGetLastMonthShopProfit() profit += lastMonthExpenditure[EnumValue(ExpenditureType::FoodDrinkStock)]; } return profit; -} \ No newline at end of file +} diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 8cda9cb79a..718ff9e9e7 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -53,11 +53,11 @@ uint16_t MarketingGetCampaignGuestGenerationProbability(int32_t campaignType) switch (campaign->Type) { case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: - if (ParkGetEntranceFee() < 4.00_GBP) + if (Park::GetEntranceFee() < 4.00_GBP) probability /= 8; break; case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: - if (ParkGetEntranceFee() < 6.00_GBP) + if (Park::GetEntranceFee() < 6.00_GBP) probability /= 8; break; case ADVERTISING_CAMPAIGN_RIDE_FREE: @@ -177,12 +177,12 @@ bool MarketingIsCampaignTypeApplicable(int32_t campaignType) { case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE: case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE: - if (!ParkEntranceFeeUnlocked()) + if (!Park::EntranceFeeUnlocked()) return false; return true; case ADVERTISING_CAMPAIGN_RIDE_FREE: - if (!ParkRidePricesUnlocked()) + if (!Park::RidePricesUnlocked()) return false; // fall-through diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index ae3919dae1..34544c8066 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -315,7 +315,7 @@ void ResearchUpdate() return; } - if ((gameState.ParkFlags & PARK_FLAGS_NO_MONEY) && gameState.ResearchFundingLevel == RESEARCH_FUNDING_NONE) + if ((gameState.Park.Flags & PARK_FLAGS_NO_MONEY) && gameState.ResearchFundingLevel == RESEARCH_FUNDING_NONE) { researchLevel = RESEARCH_FUNDING_NORMAL; } diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index eea3c50f11..c0b2290cb9 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -309,10 +309,10 @@ private: { "day", date.GetMonthTicks() }, { "month", date.GetMonthsElapsed() }, { "guests", gameState.NumGuestsInPark }, - { "parkValue", gameState.ParkValue }, + { "parkValue", gameState.Park.Value }, }; - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY)) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY)) { gameInfo["cash"] = gameState.Cash; } diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 7be70b9f3b..40a3ac289b 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -220,7 +220,7 @@ static void PaintParkEntranceScrollingText( return; auto ft = Formatter(); - if (GetGameState().ParkFlags & PARK_FLAGS_PARK_OPEN) + if (GetGameState().Park.Flags & PARK_FLAGS_PARK_OPEN) { const auto& park = OpenRCT2::GetGameState().Park; auto name = park.Name.c_str(); diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 2712fabb2d..dd3ef855f4 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -798,16 +798,16 @@ namespace OpenRCT2 cs.ReadWrite(gameState.BankLoan); cs.ReadWrite(gameState.MaxBankLoan); cs.ReadWrite(gameState.BankLoanInterestRate); - cs.ReadWrite(gameState.ParkFlags); + cs.ReadWrite(gameState.Park.Flags); if (version <= 18) { money16 tempParkEntranceFee{}; cs.ReadWrite(tempParkEntranceFee); - gameState.ParkEntranceFee = ToMoney64(tempParkEntranceFee); + gameState.Park.EntranceFee = ToMoney64(tempParkEntranceFee); } else { - cs.ReadWrite(gameState.ParkEntranceFee); + cs.ReadWrite(gameState.Park.EntranceFee); } cs.ReadWrite(gameState.StaffHandymanColour); @@ -877,13 +877,13 @@ namespace OpenRCT2 cs.ReadWrite(award.Type); }); } - cs.ReadWrite(gameState.ParkValue); + cs.ReadWrite(gameState.Park.Value); cs.ReadWrite(gameState.CompanyValue); - cs.ReadWrite(gameState.ParkSize); + cs.ReadWrite(gameState.Park.Size); cs.ReadWrite(gameState.NumGuestsInPark); cs.ReadWrite(gameState.NumGuestsHeadingForPark); - cs.ReadWrite(gameState.ParkRating); - cs.ReadWrite(gameState.ParkRatingCasualtyPenalty); + cs.ReadWrite(gameState.Park.Rating); + cs.ReadWrite(gameState.Park.RatingCasualtyPenalty); cs.ReadWrite(gameState.CurrentExpenditure); cs.ReadWrite(gameState.CurrentProfit); cs.ReadWrite(gameState.WeeklyProfitAverageDividend); @@ -910,7 +910,7 @@ namespace OpenRCT2 return true; }); - cs.ReadWriteArray(gameState.ParkRatingHistory, [&cs](uint8_t& value) { + cs.ReadWriteArray(gameState.Park.RatingHistory, [&cs](uint8_t& value) { cs.ReadWrite(value); return true; }); @@ -928,7 +928,7 @@ namespace OpenRCT2 cs.ReadWrite(value); return true; }); - cs.ReadWriteArray(gameState.ParkValueHistory, [&cs](money64& value) { + cs.ReadWriteArray(gameState.Park.ValueHistory, [&cs](money64& value) { cs.ReadWrite(value); return true; }); diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index 51512b06d9..e9e8ce5ec3 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -1548,7 +1548,7 @@ namespace OpenRCT2::PathFinding { std::optional chosenEntrance = std::nullopt; uint16_t nearestDist = 0xFFFF; - for (const auto& parkEntrance : GetGameState().ParkEntrances) + for (const auto& parkEntrance : GetGameState().Park.Entrances) { auto dist = abs(parkEntrance.x - loc.x) + abs(parkEntrance.y - loc.y); if (dist < nearestDist) diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 33fb4fd68e..55505ae292 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -275,7 +275,7 @@ namespace RCT1 { // Use the ratio between the old and new park value to calcute the ratio to // use for the park value history and the goal. - _parkValueConversionFactor = (CalculateParkValue() * 10) / _s4.ParkValue; + _parkValueConversionFactor = (Park::CalculateParkValue() * 10) / _s4.ParkValue; } else { @@ -327,7 +327,7 @@ namespace RCT1 // Do map initialisation, same kind of stuff done when loading scenario editor gameStateInitAll(gameState, { mapSize, mapSize }); gameState.EditorStep = EditorStep::ObjectSelection; - gameState.ParkFlags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; + gameState.Park.Flags |= PARK_FLAGS_SHOW_REAL_GUEST_NAMES; gameState.ScenarioCategory = SCENARIO_CATEGORY_OTHER; } @@ -1423,7 +1423,7 @@ namespace RCT1 void ImportFinance(GameState_t& gameState) { - gameState.ParkEntranceFee = _s4.ParkEntranceFee; + gameState.Park.EntranceFee = _s4.ParkEntranceFee; gameState.LandPrice = ToMoney64(_s4.LandPrice); gameState.ConstructionRightsPrice = ToMoney64(_s4.ConstructionRightsPrice); @@ -1435,13 +1435,13 @@ namespace RCT1 gameState.InitialCash = ToMoney64(_s4.Cash); gameState.CompanyValue = ToMoney64(_s4.CompanyValue); - gameState.ParkValue = CorrectRCT1ParkValue(_s4.ParkValue); + gameState.Park.Value = CorrectRCT1ParkValue(_s4.ParkValue); gameState.CurrentProfit = ToMoney64(_s4.Profit); for (size_t i = 0; i < Limits::FinanceGraphSize; i++) { gameState.CashHistory[i] = ToMoney64(_s4.CashHistory[i]); - gameState.ParkValueHistory[i] = CorrectRCT1ParkValue(_s4.ParkValueHistory[i]); + gameState.Park.ValueHistory[i] = CorrectRCT1ParkValue(_s4.ParkValueHistory[i]); gameState.WeeklyProfitHistory[i] = ToMoney64(_s4.WeeklyProfitHistory[i]); } @@ -2146,10 +2146,10 @@ namespace RCT1 gameState.Date = Date{ _s4.Month, _s4.Day }; // Park rating - gameState.ParkRating = _s4.ParkRating; + gameState.Park.Rating = _s4.ParkRating; - ResetParkHistories(gameState); - std::copy(std::begin(_s4.ParkRatingHistory), std::end(_s4.ParkRatingHistory), gameState.ParkRatingHistory); + Park::ResetHistories(gameState); + std::copy(std::begin(_s4.ParkRatingHistory), std::end(_s4.ParkRatingHistory), gameState.Park.RatingHistory); for (size_t i = 0; i < std::size(_s4.GuestsInParkHistory); i++) { if (_s4.GuestsInParkHistory[i] != RCT12ParkHistoryUndefined) @@ -2222,17 +2222,17 @@ namespace RCT1 gameState.StaffSecurityColour = RCT1::GetColour(_s4.SecurityGuardColour); // Flags - gameState.ParkFlags = _s4.ParkFlags; - gameState.ParkFlags &= ~PARK_FLAGS_ANTI_CHEAT_DEPRECATED; - gameState.ParkFlags |= PARK_FLAGS_RCT1_INTEREST; + gameState.Park.Flags = _s4.ParkFlags; + gameState.Park.Flags &= ~PARK_FLAGS_ANTI_CHEAT_DEPRECATED; + gameState.Park.Flags |= PARK_FLAGS_RCT1_INTEREST; // Loopy Landscape parks can set a flag to lock the entry price to free. // If this flag is not set, the player can ask money for both rides and entry. if (!(_s4.ParkFlags & RCT1_PARK_FLAGS_PARK_ENTRY_LOCKED_AT_FREE)) { - gameState.ParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.Flags |= PARK_FLAGS_UNLOCK_ALL_PRICES; } - gameState.ParkSize = _s4.ParkSize; + gameState.Park.Size = _s4.ParkSize; gameState.TotalRideValueForMoney = _s4.TotalRideValueForMoney; gameState.SamePriceThroughoutPark = 0; if (_gameVersion == FILE_VERSION_RCT1_LL) @@ -2444,10 +2444,10 @@ namespace RCT1 void FixEntrancePositions() { auto& gameState = GetGameState(); - gameState.ParkEntrances.clear(); + gameState.Park.Entrances.clear(); TileElementIterator it; TileElementIteratorBegin(&it); - while (TileElementIteratorNext(&it) && gameState.ParkEntrances.size() < Limits::MaxParkEntrances) + while (TileElementIteratorNext(&it) && gameState.Park.Entrances.size() < Limits::MaxParkEntrances) { TileElement* element = it.element; @@ -2459,7 +2459,7 @@ namespace RCT1 continue; CoordsXYZD entrance = { TileCoordsXY(it.x, it.y).ToCoordsXY(), element->GetBaseZ(), element->GetDirection() }; - gameState.ParkEntrances.push_back(entrance); + gameState.Park.Entrances.push_back(entrance); } } diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index da73742fe9..5be87cebeb 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -263,18 +263,18 @@ namespace RCT2 gameState.InitialCash = ToMoney64(_s6.InitialCash); gameState.BankLoan = ToMoney64(_s6.CurrentLoan); - gameState.ParkFlags = _s6.ParkFlags & ~PARK_FLAGS_NO_MONEY_SCENARIO; + gameState.Park.Flags = _s6.ParkFlags & ~PARK_FLAGS_NO_MONEY_SCENARIO; // RCT2 used a different flag for `no money` when the park is a scenario if (_s6.Header.Type == S6_TYPE_SCENARIO) { if (_s6.ParkFlags & PARK_FLAGS_NO_MONEY_SCENARIO) - gameState.ParkFlags |= PARK_FLAGS_NO_MONEY; + gameState.Park.Flags |= PARK_FLAGS_NO_MONEY; else - gameState.ParkFlags &= ~PARK_FLAGS_NO_MONEY; + gameState.Park.Flags &= ~PARK_FLAGS_NO_MONEY; } - gameState.ParkEntranceFee = _s6.ParkEntranceFee; + gameState.Park.EntranceFee = _s6.ParkEntranceFee; // rct1_park_entranceX // rct1_park_entrance_y // Pad013573EE @@ -305,10 +305,10 @@ namespace RCT2 gameState.StaffMechanicColour = _s6.MechanicColour; gameState.StaffSecurityColour = _s6.SecurityColour; - gameState.ParkRating = _s6.ParkRating; + gameState.Park.Rating = _s6.ParkRating; - ResetParkHistories(gameState); - std::copy(std::begin(_s6.ParkRatingHistory), std::end(_s6.ParkRatingHistory), gameState.ParkRatingHistory); + Park::ResetHistories(gameState); + std::copy(std::begin(_s6.ParkRatingHistory), std::end(_s6.ParkRatingHistory), gameState.Park.RatingHistory); for (size_t i = 0; i < std::size(_s6.GuestsInParkHistory); i++) { if (_s6.GuestsInParkHistory[i] != RCT12ParkHistoryUndefined) @@ -336,7 +336,7 @@ namespace RCT2 gameState.ResearchExpectedDay = _s6.NextResearchExpectedDay; gameState.ResearchExpectedMonth = _s6.NextResearchExpectedMonth; gameState.GuestInitialHappiness = _s6.GuestInitialHappiness; - gameState.ParkSize = _s6.ParkSize; + gameState.Park.Size = _s6.ParkSize; gameState.GuestGenerationProbability = _s6.GuestGenerationProbability; gameState.TotalRideValueForMoney = _s6.TotalRideValueForMoney; gameState.MaxBankLoan = ToMoney64(_s6.MaximumLoan); @@ -361,13 +361,13 @@ namespace RCT2 gameState.WeeklyProfitAverageDivisor = _s6.WeeklyProfitAverageDivisor; // Pad0135833A - gameState.ParkValue = ToMoney64(_s6.ParkValue); + gameState.Park.Value = ToMoney64(_s6.ParkValue); for (size_t i = 0; i < Limits::FinanceGraphSize; i++) { gameState.CashHistory[i] = ToMoney64(_s6.BalanceHistory[i]); gameState.WeeklyProfitHistory[i] = ToMoney64(_s6.WeeklyProfitHistory[i]); - gameState.ParkValueHistory[i] = ToMoney64(_s6.ParkValueHistory[i]); + gameState.Park.ValueHistory[i] = ToMoney64(_s6.ParkValueHistory[i]); } gameState.ScenarioCompletedCompanyValue = RCT12CompletedCompanyValueToOpenRCT2(_s6.CompletedCompanyValue); @@ -400,7 +400,7 @@ namespace RCT2 gameState.ScenarioCompletedBy = std::string_view(_s6.ScenarioCompletedName, sizeof(_s6.ScenarioCompletedName)); gameState.Cash = ToMoney64(DECRYPT_MONEY(_s6.Cash)); // Pad013587FC - gameState.ParkRatingCasualtyPenalty = _s6.ParkRatingCasualtyPenalty; + gameState.Park.RatingCasualtyPenalty = _s6.ParkRatingCasualtyPenalty; gameState.MapSize = { _s6.MapSize, _s6.MapSize }; gameState.SamePriceThroughoutPark = _s6.SamePriceThroughout | (static_cast(_s6.SamePriceThroughoutExtended) << 32); @@ -413,7 +413,7 @@ namespace RCT2 gameState.BankLoanInterestRate = _s6.CurrentInterestRate; // Pad0135934B // Preserve compatibility with vanilla RCT2's save format. - gameState.ParkEntrances.clear(); + gameState.Park.Entrances.clear(); for (uint8_t i = 0; i < Limits::MaxParkEntrances; i++) { if (_s6.ParkEntranceX[i] != LOCATION_NULL) @@ -423,7 +423,7 @@ namespace RCT2 entrance.y = _s6.ParkEntranceY[i]; entrance.z = _s6.ParkEntranceZ[i]; entrance.direction = _s6.ParkEntranceDirection[i]; - gameState.ParkEntrances.push_back(entrance); + gameState.Park.Entrances.push_back(entrance); } } if (_s6.Header.Type == S6_TYPE_SCENARIO) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index d0300a5cf3..c878043db5 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -5321,11 +5321,11 @@ bool Ride::IsRide() const money64 RideGetPrice(const Ride& ride) { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + if (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) return 0; if (ride.IsRide()) { - if (!ParkRidePricesUnlocked()) + if (!Park::RidePricesUnlocked()) { return 0; } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index e852fb6e17..5da07840a9 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1942,8 +1942,8 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon _trackDesignDrawingPreview = true; uint8_t backup_rotation = _currentTrackPieceDirection; - uint32_t backup_park_flags = gameState.ParkFlags; - gameState.ParkFlags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; + uint32_t backup_park_flags = gameState.Park.Flags; + gameState.Park.Flags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; auto mapSize = TileCoordsXY{ gameState.MapSize.x * 16, gameState.MapSize.y * 16 }; _currentTrackPieceDirection = 0; @@ -1967,7 +1967,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon auto res = TrackDesignPlaceVirtual( tds, td6, PTD_OPERATION_PLACE_TRACK_PREVIEW, placeScenery, *ride, { mapSize.x, mapSize.y, z, _currentTrackPieceDirection }); - gameState.ParkFlags = backup_park_flags; + gameState.Park.Flags = backup_park_flags; if (res.Error == GameActions::Status::Ok) { diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 462038b032..46fd05fba5 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -4530,9 +4530,9 @@ static void ride_train_crash(Ride& ride, uint16_t numFatalities) } auto& gameState = GetGameState(); - if (gameState.ParkRatingCasualtyPenalty < 500) + if (gameState.Park.RatingCasualtyPenalty < 500) { - gameState.ParkRatingCasualtyPenalty += 200; + gameState.Park.RatingCasualtyPenalty += 200; } } } diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 5976ceaf5a..490bf766e7 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -100,9 +100,9 @@ void ScenarioReset(GameState_t& gameState) ScenerySetDefaultPlacementConfiguration(); News::InitQueue(); - gameState.ParkRating = CalculateParkRating(); - gameState.ParkValue = CalculateParkValue(); - gameState.CompanyValue = CalculateCompanyValue(); + gameState.Park.Rating = Park::CalculateParkRating(); + gameState.Park.Value = Park::CalculateParkValue(); + gameState.CompanyValue = Park::CalculateCompanyValue(); gameState.HistoricalProfit = gameState.InitialCash - gameState.BankLoan; gameState.Cash = gameState.InitialCash; @@ -140,17 +140,17 @@ void ScenarioReset(GameState_t& gameState) gameState.TotalAdmissions = 0; gameState.TotalIncomeFromAdmissions = 0; - gameState.ParkFlags &= ~PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; + gameState.Park.Flags &= ~PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; gameState.ScenarioCompletedCompanyValue = kMoney64Undefined; gameState.ScenarioCompletedBy = "?"; - ResetParkHistories(gameState); + Park::ResetHistories(gameState); FinanceResetHistory(); AwardReset(); ResetAllRideBuildDates(); ResetDate(); Duck::RemoveAll(); - ParkUpdateSize(gameState); + Park::UpdateSize(gameState); MapCountRemainingLandRights(); Staff::ResetStats(); @@ -163,16 +163,16 @@ void ScenarioReset(GameState_t& gameState) } gMarketingCampaigns.clear(); - gameState.ParkRatingCasualtyPenalty = 0; + gameState.Park.RatingCasualtyPenalty = 0; // Open park with free entry when there is no money - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { - gameState.ParkFlags |= PARK_FLAGS_PARK_OPEN; - gameState.ParkEntranceFee = 0; + gameState.Park.Flags |= PARK_FLAGS_PARK_OPEN; + gameState.Park.EntranceFee = 0; } - gameState.ParkFlags |= PARK_FLAGS_SPRITES_INITIALISED; + gameState.Park.Flags |= PARK_FLAGS_SPRITES_INITIALISED; gGamePaused = false; } @@ -208,7 +208,7 @@ void ScenarioSuccess(GameState_t& gameState) if (ScenarioRepositoryTryRecordHighscore(gScenarioFileName.c_str(), companyValue, nullptr)) { // Allow name entry - GetGameState().ParkFlags |= PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; + GetGameState().Park.Flags |= PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; gameState.ScenarioCompanyValueRecord = companyValue; } ScenarioEnd(); @@ -224,7 +224,7 @@ void ScenarioSuccessSubmitName(GameState_t& gameState, const char* name) { gameState.ScenarioCompletedBy = name; } - gameState.ParkFlags &= ~PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; + gameState.Park.Flags &= ~PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; } /** @@ -236,11 +236,11 @@ static void ScenarioCheckEntranceFeeTooHigh() const auto& gameState = GetGameState(); const auto max_fee = AddClamp_money64(gameState.TotalRideValueForMoney, gameState.TotalRideValueForMoney / 2); - if ((gameState.ParkFlags & PARK_FLAGS_PARK_OPEN) && ParkGetEntranceFee() > max_fee) + if ((gameState.Park.Flags & PARK_FLAGS_PARK_OPEN) && Park::GetEntranceFee() > max_fee) { - if (!gameState.ParkEntrances.empty()) + if (!gameState.Park.Entrances.empty()) { - const auto& entrance = gameState.ParkEntrances[0]; + const auto& entrance = gameState.Park.Entrances[0]; auto x = entrance.x + 16; auto y = entrance.y + 16; @@ -308,8 +308,8 @@ static void ScenarioDayUpdate(GameState_t& gameState) } // Lower the casualty penalty - uint16_t casualtyPenaltyModifier = (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) ? 40 : 7; - gameState.ParkRatingCasualtyPenalty = std::max(0, gameState.ParkRatingCasualtyPenalty - casualtyPenaltyModifier); + uint16_t casualtyPenaltyModifier = (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) ? 40 : 7; + gameState.Park.RatingCasualtyPenalty = std::max(0, gameState.Park.RatingCasualtyPenalty - casualtyPenaltyModifier); auto intent = Intent(INTENT_ACTION_UPDATE_DATE); ContextBroadcastIntent(&intent); @@ -600,7 +600,7 @@ ResultWithMessage ScenarioPrepareForSave(GameState_t& gameState) } if (gameState.ScenarioObjective.Type == OBJECTIVE_GUESTS_AND_RATING) - GetGameState().ParkFlags |= PARK_FLAGS_PARK_OPEN; + GetGameState().Park.Flags |= PARK_FLAGS_PARK_OPEN; ScenarioReset(gameState); @@ -609,7 +609,7 @@ ResultWithMessage ScenarioPrepareForSave(GameState_t& gameState) ObjectiveStatus Objective::CheckGuestsBy() const { - auto parkRating = GetGameState().ParkRating; + auto parkRating = GetGameState().Park.Rating; int32_t currentMonthYear = GetDate().GetMonthsElapsed(); if (currentMonthYear == MONTH_COUNT * Year || AllowEarlyCompletion()) @@ -632,7 +632,7 @@ ObjectiveStatus Objective::CheckParkValueBy() const { int32_t currentMonthYear = GetDate().GetMonthsElapsed(); money64 objectiveParkValue = Currency; - money64 parkValue = GetGameState().ParkValue; + money64 parkValue = GetGameState().Park.Value; if (currentMonthYear == MONTH_COUNT * Year || AllowEarlyCompletion()) { @@ -689,7 +689,7 @@ ObjectiveStatus Objective::Check10RollerCoasters() const ObjectiveStatus Objective::CheckGuestsAndRating() const { auto& gameState = GetGameState(); - if (gameState.ParkRating < 700 && GetDate().GetMonthsElapsed() >= 1) + if (gameState.Park.Rating < 700 && GetDate().GetMonthsElapsed() >= 1) { gameState.ScenarioParkRatingWarningDays++; if (gameState.ScenarioParkRatingWarningDays == 1) @@ -723,7 +723,7 @@ ObjectiveStatus Objective::CheckGuestsAndRating() const else if (gameState.ScenarioParkRatingWarningDays == 29) { News::AddItemToQueue(News::ItemType::Graph, STR_PARK_HAS_BEEN_CLOSED_DOWN, 0, {}); - gameState.ParkFlags &= ~PARK_FLAGS_PARK_OPEN; + gameState.Park.Flags &= ~PARK_FLAGS_PARK_OPEN; gameState.GuestInitialHappiness = 50; return ObjectiveStatus::Failure; } @@ -733,7 +733,7 @@ ObjectiveStatus Objective::CheckGuestsAndRating() const gameState.ScenarioParkRatingWarningDays = 0; } - if (gameState.ParkRating >= 700) + if (gameState.Park.Rating >= 700) if (gameState.NumGuestsInPark >= NumGuests) return ObjectiveStatus::Success; @@ -817,7 +817,7 @@ ObjectiveStatus Objective::CheckFinish5RollerCoasters() const ObjectiveStatus Objective::CheckRepayLoanAndParkValue() const { const auto& gameState = GetGameState(); - money64 parkValue = gameState.ParkValue; + money64 parkValue = gameState.Park.Value; money64 currentLoan = gameState.BankLoan; if (currentLoan <= 0 && parkValue >= Currency) diff --git a/src/openrct2/scripting/bindings/world/ScPark.cpp b/src/openrct2/scripting/bindings/world/ScPark.cpp index bac2a9adc0..79c6eb7e2a 100644 --- a/src/openrct2/scripting/bindings/world/ScPark.cpp +++ b/src/openrct2/scripting/bindings/world/ScPark.cpp @@ -68,7 +68,7 @@ namespace OpenRCT2::Scripting int32_t ScPark::rating_get() const { - return GetGameState().ParkRating; + return GetGameState().Park.Rating; } void ScPark::rating_set(int32_t value) { @@ -76,9 +76,9 @@ namespace OpenRCT2::Scripting auto valueClamped = std::min(std::max(0, value), 999); auto& gameState = GetGameState(); - if (gameState.ParkRating != valueClamped) + if (gameState.Park.Rating != valueClamped) { - gameState.ParkRating = std::min(std::max(0, value), 999); + gameState.Park.Rating = std::min(std::max(0, value), 999); auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); ContextBroadcastIntent(&intent); } @@ -121,16 +121,16 @@ namespace OpenRCT2::Scripting money64 ScPark::entranceFee_get() const { - return GetGameState().ParkEntranceFee; + return GetGameState().Park.EntranceFee; } void ScPark::entranceFee_set(money64 value) { ThrowIfGameStateNotMutable(); auto& gameState = GetGameState(); - if (gameState.ParkEntranceFee != value) + if (gameState.Park.EntranceFee != value) { - gameState.ParkEntranceFee = value; + gameState.Park.EntranceFee = value; WindowInvalidateByClass(WindowClass::ParkInformation); } } @@ -172,16 +172,16 @@ namespace OpenRCT2::Scripting money64 ScPark::value_get() const { - return GetGameState().ParkValue; + return GetGameState().Park.Value; } void ScPark::value_set(money64 value) { ThrowIfGameStateNotMutable(); auto& gameState = GetGameState(); - if (gameState.ParkValue != value) + if (gameState.Park.Value != value) { - gameState.ParkValue = value; + gameState.Park.Value = value; auto intent = Intent(INTENT_ACTION_UPDATE_CASH); ContextBroadcastIntent(&intent); } @@ -263,17 +263,17 @@ namespace OpenRCT2::Scripting int16_t ScPark::casualtyPenalty_get() const { - return GetGameState().ParkRatingCasualtyPenalty; + return GetGameState().Park.RatingCasualtyPenalty; } void ScPark::casualtyPenalty_set(int16_t value) { ThrowIfGameStateNotMutable(); - GetGameState().ParkRatingCasualtyPenalty = value; + GetGameState().Park.RatingCasualtyPenalty = value; } uint16_t ScPark::parkSize_get() const { - return GetGameState().ParkSize; + return GetGameState().Park.Size; } std::string ScPark::name_get() const @@ -295,7 +295,7 @@ namespace OpenRCT2::Scripting bool ScPark::getFlag(const std::string& key) const { auto mask = ParkFlagMap[key]; - return (GetGameState().ParkFlags & mask) != 0; + return (GetGameState().Park.Flags & mask) != 0; } void ScPark::setFlag(const std::string& key, bool value) @@ -304,9 +304,9 @@ namespace OpenRCT2::Scripting auto mask = ParkFlagMap[key]; auto& gameState = GetGameState(); if (value) - gameState.ParkFlags |= mask; + gameState.Park.Flags |= mask; else - gameState.ParkFlags &= ~mask; + gameState.Park.Flags &= ~mask; GfxInvalidateScreen(); } diff --git a/src/openrct2/world/ConstructionClearance.cpp b/src/openrct2/world/ConstructionClearance.cpp index 8fc716aaaa..58e572eaff 100644 --- a/src/openrct2/world/ConstructionClearance.cpp +++ b/src/openrct2/world/ConstructionClearance.cpp @@ -36,13 +36,13 @@ static int32_t MapPlaceClearFunc( auto* scenery = (*tile_element)->AsSmallScenery()->GetEntry(); auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_FORBID_TREE_REMOVAL) + if (gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) { if (scenery != nullptr && scenery->HasFlag(SMALL_SCENERY_FLAG_IS_TREE)) return 1; } - if (!(gameState.ParkFlags & PARK_FLAGS_NO_MONEY) && scenery != nullptr) + if (!(gameState.Park.Flags & PARK_FLAGS_NO_MONEY) && scenery != nullptr) *price += scenery->removal_price; if (flags & GAME_COMMAND_FLAG_GHOST) @@ -189,7 +189,7 @@ GameActions::Result MapCanConstructWithClearAt( } } - if (GetGameState().ParkFlags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION && !isTree) + if (GetGameState().Park.Flags & PARK_FLAGS_FORBID_HIGH_CONSTRUCTION && !isTree) { const auto heightFromGround = pos.clearanceZ - tileElement->GetBaseZ(); diff --git a/src/openrct2/world/Entrance.cpp b/src/openrct2/world/Entrance.cpp index c33dfb1fe2..a05a8e55b5 100644 --- a/src/openrct2/world/Entrance.cpp +++ b/src/openrct2/world/Entrance.cpp @@ -70,7 +70,7 @@ void ParkEntranceRemoveGhost() int32_t ParkEntranceGetIndex(const CoordsXYZ& entrancePos) { int32_t i = 0; - for (const auto& entrance : GetGameState().ParkEntrances) + for (const auto& entrance : GetGameState().Park.Entrances) { if (entrancePos == entrance) { @@ -83,7 +83,7 @@ int32_t ParkEntranceGetIndex(const CoordsXYZ& entrancePos) void ParkEntranceReset() { - GetGameState().ParkEntrances.clear(); + GetGameState().Park.Entrances.clear(); } void RideEntranceExitPlaceProvisionalGhost() @@ -214,17 +214,17 @@ void ParkEntranceFixLocations(void) { auto& gameState = GetGameState(); // Fix ParkEntrance locations for which the tile_element no longer exists - gameState.ParkEntrances.erase( + gameState.Park.Entrances.erase( std::remove_if( - gameState.ParkEntrances.begin(), gameState.ParkEntrances.end(), + gameState.Park.Entrances.begin(), gameState.Park.Entrances.end(), [](const auto& entrance) { return MapGetParkEntranceElementAt(entrance, false) == nullptr; }), - gameState.ParkEntrances.end()); + gameState.Park.Entrances.end()); } void ParkEntranceUpdateLocations() { auto& gameState = GetGameState(); - gameState.ParkEntrances.clear(); + gameState.Park.Entrances.clear(); TileElementIterator it; TileElementIteratorBegin(&it); while (TileElementIteratorNext(&it)) @@ -234,7 +234,7 @@ void ParkEntranceUpdateLocations() && entranceElement->GetSequenceIndex() == 0 && !entranceElement->IsGhost()) { auto entrance = TileCoordsXYZD(it.x, it.y, it.element->BaseHeight, it.element->GetDirection()).ToCoordsXYZD(); - gameState.ParkEntrances.push_back(entrance); + gameState.Park.Entrances.push_back(entrance); } } } diff --git a/src/openrct2/world/Entrance.h b/src/openrct2/world/Entrance.h index d89ae0dc38..8bb4de0b9c 100644 --- a/src/openrct2/world/Entrance.h +++ b/src/openrct2/world/Entrance.h @@ -41,6 +41,7 @@ extern CoordsXYZD gRideEntranceExitGhostPosition; extern StationIndex gRideEntranceExitGhostStationIndex; void ParkEntranceRemoveGhost(); +int32_t ParkEntranceGetIndex(const CoordsXYZ& entrancePos); void ParkEntranceReset(); void MazeEntranceHedgeReplacement(const CoordsXYE& entrance); diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 048420be30..5fdb731da7 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1366,7 +1366,7 @@ void MapRemoveOutOfRangeElements() if (surfaceElement != nullptr) { surfaceElement->SetOwnership(OWNERSHIP_UNOWNED); - ParkUpdateFencesAroundTile({ x, y }); + Park::UpdateFencesAroundTile({ x, y }); } ClearElementsAt({ x, y }); } @@ -1430,7 +1430,7 @@ void MapExtendBoundarySurfaceY() MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement); } - ParkUpdateFences({ x << 5, y << 5 }); + Park::UpdateFences({ x << 5, y << 5 }); } } @@ -1448,7 +1448,7 @@ void MapExtendBoundarySurfaceX() { MapExtendBoundarySurfaceExtendTile(*existingTileElement, *newTileElement); } - ParkUpdateFences({ x << 5, y << 5 }); + Park::UpdateFences({ x << 5, y << 5 }); } } @@ -2229,7 +2229,7 @@ void FixLandOwnershipTilesWithOwnership(std::initializer_list tile continue; surfaceElement->SetOwnership(ownership); - ParkUpdateFencesAroundTile({ (*tile).x * 32, (*tile).y * 32 }); + Park::UpdateFencesAroundTile({ (*tile).x * 32, (*tile).y * 32 }); } } } diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index f6a9579f31..fd83c022f3 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -47,725 +47,729 @@ using namespace OpenRCT2; -// If this value is more than or equal to 0, the park rating is forced to this value. Used for cheat -static int32_t _forcedParkRating = -1; - -static money64 calculateRideValue(const Ride& ride); -static money64 calculateTotalRideValueForMoney(); -static uint32_t calculateSuggestedMaxGuests(); -static uint32_t calculateGuestGenerationProbability(); - -static void generateGuests(GameState_t& gameState); -static Guest* generateGuestFromCampaign(int32_t campaign); - -/** - * Choose a random peep spawn and iterates through until defined spawn is found. - */ -static PeepSpawn* GetRandomPeepSpawn() +namespace OpenRCT2::Park { - auto& gameState = GetGameState(); - if (!gameState.PeepSpawns.empty()) + // If this value is more than or equal to 0, the park rating is forced to this value. Used for cheat + static int32_t _forcedParkRating = -1; + + static money64 calculateRideValue(const Ride& ride); + static money64 calculateTotalRideValueForMoney(); + static uint32_t calculateSuggestedMaxGuests(); + static uint32_t calculateGuestGenerationProbability(); + + static void generateGuests(GameState_t& gameState); + static Guest* generateGuestFromCampaign(int32_t campaign); + + /** + * Choose a random peep spawn and iterates through until defined spawn is found. + */ + static PeepSpawn* GetRandomPeepSpawn() { - return &gameState.PeepSpawns[ScenarioRand() % gameState.PeepSpawns.size()]; + auto& gameState = GetGameState(); + if (!gameState.PeepSpawns.empty()) + { + return &gameState.PeepSpawns[ScenarioRand() % gameState.PeepSpawns.size()]; + } + + return nullptr; } - return nullptr; -} - -void ParkSetOpen(bool open) -{ - auto parkSetParameter = ParkSetParameterAction(open ? ParkParameter::Open : ParkParameter::Close); - GameActions::Execute(&parkSetParameter); -} - -/** - * - * rct2: 0x00664D05 - */ -void ParkUpdateFences(const CoordsXY& coords) -{ - if (MapIsEdge(coords)) - return; - - auto surfaceElement = MapGetSurfaceElementAt(coords); - if (surfaceElement == nullptr) - return; - - uint8_t newFences = 0; - if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) == 0) + static money64 calculateRideValue(const Ride& ride) { - bool fenceRequired = true; - - TileElement* tileElement = MapGetFirstElementAt(coords); - if (tileElement == nullptr) - return; - // If an entrance element do not place flags around surface - do + money64 result = 0; + if (ride.value != RIDE_VALUE_UNDEFINED) { - if (tileElement->GetType() != TileElementType::Entrance) + const auto& rtd = ride.GetRideTypeDescriptor(); + result = (ride.value * 10) * (static_cast(RideCustomersInLast5Minutes(ride)) + rtd.BonusValue * 4LL); + } + return result; + } + + static money64 calculateTotalRideValueForMoney() + { + money64 totalRideValue = 0; + bool ridePricesUnlocked = RidePricesUnlocked() && !(GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY); + for (auto& ride : GetRideManager()) + { + if (ride.status != RideStatus::Open) + continue; + if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + continue; + if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) continue; - if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE) + // Add ride value + if (ride.value != RIDE_VALUE_UNDEFINED) + { + money64 rideValue = ride.value; + if (ridePricesUnlocked) + { + rideValue -= ride.price[0]; + } + if (rideValue > 0) + { + totalRideValue += rideValue * 2; + } + } + } + return totalRideValue; + } + + static uint32_t calculateSuggestedMaxGuests() + { + uint32_t suggestedMaxGuests = 0; + uint32_t difficultGenerationBonus = 0; + + auto& gameState = GetGameState(); + + for (auto& ride : GetRideManager()) + { + if (ride.status != RideStatus::Open) + continue; + if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + continue; + if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) continue; - if (!(tileElement->IsGhost())) - { - fenceRequired = false; - break; - } - } while (!(tileElement++)->IsLastForTile()); + // Add guest score for ride type + suggestedMaxGuests += ride.GetRideTypeDescriptor().BonusValue; - if (fenceRequired) + // If difficult guest generation, extra guests are available for good rides + if (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) + { + if (!(ride.lifecycle_flags & RIDE_LIFECYCLE_TESTED)) + continue; + if (!ride.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_HAS_TRACK)) + continue; + if (!ride.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_HAS_DATA_LOGGING)) + continue; + if (ride.GetStation().SegmentLength < (600 << 16)) + continue; + if (ride.excitement < RIDE_RATING(6, 00)) + continue; + + // Bonus guests for good ride + difficultGenerationBonus += ride.GetRideTypeDescriptor().BonusValue * 2; + } + } + + if (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) { - if (MapIsLocationInPark({ coords.x - COORDS_XY_STEP, coords.y })) - { - newFences |= 0x8; - } + suggestedMaxGuests = std::min(suggestedMaxGuests, 1000); + suggestedMaxGuests += difficultGenerationBonus; + } - if (MapIsLocationInPark({ coords.x, coords.y - COORDS_XY_STEP })) - { - newFences |= 0x4; - } + suggestedMaxGuests = std::min(suggestedMaxGuests, 65535); + return suggestedMaxGuests; + } - if (MapIsLocationInPark({ coords.x + COORDS_XY_STEP, coords.y })) - { - newFences |= 0x2; - } + static uint32_t calculateGuestGenerationProbability() + { + auto& gameState = GetGameState(); - if (MapIsLocationInPark({ coords.x, coords.y + COORDS_XY_STEP })) + // Begin with 50 + park rating + uint32_t probability = 50 + std::clamp(gameState.Park.Rating - 200, 0, 650); + + // The more guests, the lower the chance of a new one + uint32_t numGuests = gameState.NumGuestsInPark + gameState.NumGuestsHeadingForPark; + if (numGuests > gameState.SuggestedGuestMaximum) + { + probability /= 4; + // Even lower for difficult guest generation + if (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) { - newFences |= 0x1; + probability /= 4; + } + } + + // Reduces chance for any more than 7000 guests + if (numGuests > 7000) + { + probability /= 4; + } + + // Penalty for overpriced entrance fee relative to total ride value + auto entranceFee = GetEntranceFee(); + if (entranceFee > gameState.TotalRideValueForMoney) + { + probability /= 4; + // Extra penalty for very overpriced entrance fee + if (entranceFee / 2 > gameState.TotalRideValueForMoney) + { + probability /= 4; + } + } + + // Reward or penalties for park awards + for (const auto& award : GetGameState().CurrentAwards) + { + // +/- 0.25% of the probability + if (AwardIsPositive(award.Type)) + { + probability += probability / 4; + } + else + { + probability -= probability / 4; + } + } + + return probability; + } + + static void generateGuests(GameState_t& gameState) + { + // Generate a new guest for some probability + if (static_cast(ScenarioRand() & 0xFFFF) < gameState.GuestGenerationProbability) + { + bool difficultGeneration = (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0; + if (!difficultGeneration || gameState.SuggestedGuestMaximum + 150 >= gameState.NumGuestsInPark) + { + GenerateGuest(); + } + } + + // Extra guests generated by advertising campaigns + for (const auto& campaign : gMarketingCampaigns) + { + // Random chance of guest generation + auto probability = MarketingGetCampaignGuestGenerationProbability(campaign.Type); + auto random = ScenarioRandMax(std::numeric_limits::max()); + if (random < probability) + { + generateGuestFromCampaign(campaign.Type); } } } - if (surfaceElement->GetParkFences() != newFences) + static Guest* generateGuestFromCampaign(int32_t campaign) { - int32_t baseZ = surfaceElement->GetBaseZ(); - int32_t clearZ = baseZ + 16; - MapInvalidateTile({ coords, baseZ, clearZ }); - surfaceElement->SetParkFences(newFences); - } -} - -void ParkUpdateFencesAroundTile(const CoordsXY& coords) -{ - ParkUpdateFences(coords); - ParkUpdateFences({ coords.x + COORDS_XY_STEP, coords.y }); - ParkUpdateFences({ coords.x - COORDS_XY_STEP, coords.y }); - ParkUpdateFences({ coords.x, coords.y + COORDS_XY_STEP }); - ParkUpdateFences({ coords.x, coords.y - COORDS_XY_STEP }); -} - -void ParkSetForcedRating(int32_t rating) -{ - _forcedParkRating = rating; - GetGameState().ParkRating = CalculateParkRating(); - auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); - ContextBroadcastIntent(&intent); -} - -int32_t ParkGetForcedRating() -{ - return _forcedParkRating; -} - -money64 ParkGetEntranceFee() -{ - const auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) - { - return 0; - } - if (!ParkEntranceFeeUnlocked()) - { - return 0; - } - return gameState.ParkEntranceFee; -} - -bool ParkRidePricesUnlocked() -{ - const auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_UNLOCK_ALL_PRICES) - { - return true; - } - if (gameState.ParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) - { - return true; - } - return false; -} - -bool ParkEntranceFeeUnlocked() -{ - const auto& gameState = GetGameState(); - if (gameState.ParkFlags & PARK_FLAGS_UNLOCK_ALL_PRICES) - { - return true; - } - if (!(gameState.ParkFlags & PARK_FLAGS_PARK_FREE_ENTRY)) - { - return true; - } - return false; -} - -bool Park::IsOpen() const -{ - return (GetGameState().ParkFlags & PARK_FLAGS_PARK_OPEN) != 0; -} - -void ParkInitialise(GameState_t& gameState) -{ - gameState.Park.Name = LanguageGetString(STR_UNNAMED_PARK); - gameState.PluginStorage = {}; - gameState.StaffHandymanColour = COLOUR_BRIGHT_RED; - gameState.StaffMechanicColour = COLOUR_LIGHT_BLUE; - gameState.StaffSecurityColour = COLOUR_YELLOW; - gameState.NumGuestsInPark = 0; - gameState.NumGuestsInParkLastWeek = 0; - gameState.NumGuestsHeadingForPark = 0; - gameState.GuestChangeModifier = 0; - gameState.ParkRating = 0; - gameState.GuestGenerationProbability = 0; - gameState.TotalRideValueForMoney = 0; - gameState.SuggestedGuestMaximum = 0; - gameState.ResearchLastItem = std::nullopt; - gMarketingCampaigns.clear(); - - ResearchResetItems(gameState); - FinanceInit(); - - SetEveryRideTypeNotInvented(); - - SetAllSceneryItemsInvented(); - - gameState.ParkEntranceFee = 10.00_GBP; - - gameState.PeepSpawns.clear(); - ParkEntranceReset(); - - gameState.ResearchPriorities = EnumsToFlags( - ResearchCategory::Transport, ResearchCategory::Gentle, ResearchCategory::Rollercoaster, ResearchCategory::Thrill, - ResearchCategory::Water, ResearchCategory::Shop, ResearchCategory::SceneryGroup); - gameState.ResearchFundingLevel = RESEARCH_FUNDING_NORMAL; - - gameState.GuestInitialCash = 50.00_GBP; - gameState.GuestInitialHappiness = CalculateGuestInitialHappiness(50); - gameState.GuestInitialHunger = 200; - gameState.GuestInitialThirst = 200; - gameState.ScenarioObjective.Type = OBJECTIVE_GUESTS_BY; - gameState.ScenarioObjective.Year = 4; - gameState.ScenarioObjective.NumGuests = 1000; - gameState.LandPrice = 90.00_GBP; - gameState.ConstructionRightsPrice = 40.00_GBP; - gameState.ParkFlags = PARK_FLAGS_NO_MONEY | PARK_FLAGS_SHOW_REAL_GUEST_NAMES; - ResetParkHistories(gameState); - FinanceResetHistory(); - AwardReset(); - - gameState.ScenarioName.clear(); - gameState.ScenarioDetails = String::ToStd(LanguageGetString(STR_NO_DETAILS_YET)); -} - -void ParkUpdate(GameState_t& gameState, const Date& date) -{ - PROFILED_FUNCTION(); - - // Every new week - if (date.IsWeekStart()) - { - UpdateParkHistories(gameState); + auto peep = GenerateGuest(); + if (peep != nullptr) + { + MarketingSetGuestCampaign(peep, campaign); + } + return peep; } - const auto currentTicks = gameState.CurrentTicks; - - // Every ~13 seconds - if (currentTicks % 512 == 0) + template static void HistoryPushRecord(T history[TSize], T newItem) { - gameState.ParkRating = CalculateParkRating(); - gameState.ParkValue = CalculateParkValue(); - gameState.CompanyValue = CalculateCompanyValue(); - gameState.TotalRideValueForMoney = calculateTotalRideValueForMoney(); - gameState.SuggestedGuestMaximum = calculateSuggestedMaxGuests(); - gameState.GuestGenerationProbability = calculateGuestGenerationProbability(); + for (size_t i = TSize - 1; i > 0; i--) + { + history[i] = history[i - 1]; + } + history[0] = newItem; + } + void Initialise(GameState_t& gameState) + { + gameState.Park.Name = LanguageGetString(STR_UNNAMED_PARK); + gameState.PluginStorage = {}; + gameState.StaffHandymanColour = COLOUR_BRIGHT_RED; + gameState.StaffMechanicColour = COLOUR_LIGHT_BLUE; + gameState.StaffSecurityColour = COLOUR_YELLOW; + gameState.NumGuestsInPark = 0; + gameState.NumGuestsInParkLastWeek = 0; + gameState.NumGuestsHeadingForPark = 0; + gameState.GuestChangeModifier = 0; + gameState.Park.Rating = 0; + gameState.GuestGenerationProbability = 0; + gameState.TotalRideValueForMoney = 0; + gameState.SuggestedGuestMaximum = 0; + gameState.ResearchLastItem = std::nullopt; + gMarketingCampaigns.clear(); + + ResearchResetItems(gameState); + FinanceInit(); + + SetEveryRideTypeNotInvented(); + + SetAllSceneryItemsInvented(); + + gameState.Park.EntranceFee = 10.00_GBP; + + gameState.PeepSpawns.clear(); + ParkEntranceReset(); + + gameState.ResearchPriorities = EnumsToFlags( + ResearchCategory::Transport, ResearchCategory::Gentle, ResearchCategory::Rollercoaster, ResearchCategory::Thrill, + ResearchCategory::Water, ResearchCategory::Shop, ResearchCategory::SceneryGroup); + gameState.ResearchFundingLevel = RESEARCH_FUNDING_NORMAL; + + gameState.GuestInitialCash = 50.00_GBP; + gameState.GuestInitialHappiness = Park::CalculateGuestInitialHappiness(50); + gameState.GuestInitialHunger = 200; + gameState.GuestInitialThirst = 200; + gameState.ScenarioObjective.Type = OBJECTIVE_GUESTS_BY; + gameState.ScenarioObjective.Year = 4; + gameState.ScenarioObjective.NumGuests = 1000; + gameState.LandPrice = 90.00_GBP; + gameState.ConstructionRightsPrice = 40.00_GBP; + gameState.Park.Flags = PARK_FLAGS_NO_MONEY | PARK_FLAGS_SHOW_REAL_GUEST_NAMES; + ResetHistories(gameState); + FinanceResetHistory(); + AwardReset(); + + gameState.ScenarioName.clear(); + gameState.ScenarioDetails = String::ToStd(LanguageGetString(STR_NO_DETAILS_YET)); + } + + void Update(GameState_t& gameState, const Date& date) + { + PROFILED_FUNCTION(); + + // Every new week + if (date.IsWeekStart()) + { + UpdateHistories(gameState); + } + + const auto currentTicks = gameState.CurrentTicks; + + // Every ~13 seconds + if (currentTicks % 512 == 0) + { + gameState.Park.Rating = CalculateParkRating(); + gameState.Park.Value = Park::CalculateParkValue(); + gameState.CompanyValue = CalculateCompanyValue(); + gameState.TotalRideValueForMoney = calculateTotalRideValueForMoney(); + gameState.SuggestedGuestMaximum = calculateSuggestedMaxGuests(); + gameState.GuestGenerationProbability = calculateGuestGenerationProbability(); + + WindowInvalidateByClass(WindowClass::Finances); + auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); + ContextBroadcastIntent(&intent); + } + + // Every ~102 seconds + if (currentTicks % 4096 == 0) + { + gameState.Park.Size = CalculateParkSize(); + WindowInvalidateByClass(WindowClass::ParkInformation); + } + + generateGuests(gameState); + } + + uint32_t CalculateParkSize() + { + uint32_t tiles = 0; + TileElementIterator it; + TileElementIteratorBegin(&it); + do + { + if (it.element->GetType() == TileElementType::Surface) + { + if (it.element->AsSurface()->GetOwnership() & (OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED | OWNERSHIP_OWNED)) + { + tiles++; + } + } + } while (TileElementIteratorNext(&it)); + + auto& gameState = GetGameState(); + if (tiles != gameState.Park.Size) + { + gameState.Park.Size = tiles; + WindowInvalidateByClass(WindowClass::ParkInformation); + } + + return tiles; + } + + int32_t CalculateParkRating() + { + if (_forcedParkRating >= 0) + { + return _forcedParkRating; + } + + auto& gameState = GetGameState(); + int32_t result = 1150; + if (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING) + { + result = 1050; + } + + // Guests + { + // -150 to +3 based on a range of guests from 0 to 2000 + result -= 150 - (std::min(2000, gameState.NumGuestsInPark) / 13); + + // Find the number of happy peeps and the number of peeps who can't find the park exit + uint32_t happyGuestCount = 0; + uint32_t lostGuestCount = 0; + for (auto peep : EntityList()) + { + if (!peep->OutsideOfPark) + { + if (peep->Happiness > 128) + { + happyGuestCount++; + } + if ((peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) && (peep->GuestIsLostCountdown < 90)) + { + lostGuestCount++; + } + } + } + + // Peep happiness -500 to +0 + result -= 500; + if (gameState.NumGuestsInPark > 0) + { + result += 2 * std::min(250u, (happyGuestCount * 300) / gameState.NumGuestsInPark); + } + + // Up to 25 guests can be lost without affecting the park rating. + if (lostGuestCount > 25) + { + result -= (lostGuestCount - 25) * 7; + } + } + + // Rides + { + int32_t rideCount = 0; + int32_t excitingRideCount = 0; + int32_t totalRideUptime = 0; + int32_t totalRideIntensity = 0; + int32_t totalRideExcitement = 0; + for (auto& ride : GetRideManager()) + { + totalRideUptime += 100 - ride.downtime; + if (RideHasRatings(ride)) + { + totalRideExcitement += ride.excitement / 8; + totalRideIntensity += ride.intensity / 8; + excitingRideCount++; + } + rideCount++; + } + result -= 200; + if (rideCount > 0) + { + result += (totalRideUptime / rideCount) * 2; + } + result -= 100; + if (excitingRideCount > 0) + { + int32_t averageExcitement = totalRideExcitement / excitingRideCount; + int32_t averageIntensity = totalRideIntensity / excitingRideCount; + + averageExcitement -= 46; + if (averageExcitement < 0) + { + averageExcitement = -averageExcitement; + } + + averageIntensity -= 65; + if (averageIntensity < 0) + { + averageIntensity = -averageIntensity; + } + + averageExcitement = std::min(averageExcitement / 2, 50); + averageIntensity = std::min(averageIntensity / 2, 50); + result += 100 - averageExcitement - averageIntensity; + } + + totalRideExcitement = std::min(1000, totalRideExcitement); + totalRideIntensity = std::min(1000, totalRideIntensity); + result -= 200 - ((totalRideExcitement + totalRideIntensity) / 10); + } + + // Litter + { + // Counts the amount of litter whose age is min. 7680 ticks (5~ min) old. + const auto litterList = EntityList(); + const auto litterCount = std::count_if( + litterList.begin(), litterList.end(), [](auto* litter) { return litter->GetAge() >= 7680; }); + + result -= 600 - (4 * (150 - std::min(150, litterCount))); + } + + result -= gameState.Park.RatingCasualtyPenalty; + result = std::clamp(result, 0, 999); + return result; + } + + money64 CalculateParkValue() + { + // Sum ride values + money64 result = 0; + for (const auto& ride : GetRideManager()) + { + result += calculateRideValue(ride); + } + + // +7.00 per guest + result += static_cast(GetGameState().NumGuestsInPark) * 7.00_GBP; + + return result; + } + + money64 CalculateCompanyValue() + { + const auto& gameState = GetGameState(); + + auto result = gameState.Park.Value - gameState.BankLoan; + + // Clamp addition to prevent overflow + result = AddClamp_money64(result, FinanceGetCurrentCash()); + + return result; + } + + uint8_t CalculateGuestInitialHappiness(uint8_t percentage) + { + percentage = std::clamp(percentage, 15, 98); + + // The percentages follow this sequence: + // 15 17 18 20 21 23 25 26 28 29 31 32 34 36 37 39 40 42 43 45 47 48 50 51 53... + // This sequence can be defined as PI*(9+n)/2 (the value is floored) + for (uint8_t n = 1; n < 55; n++) + { + // Avoid floating point math by rescaling PI up. + constexpr int32_t SCALE = 100000; + constexpr int32_t PI_SCALED = 314159; // PI * SCALE; + if (((PI_SCALED * (9 + n)) / SCALE) / 2 >= percentage) + { + return (9 + n) * 4; + } + } + + // This is the lowest possible value: + return 40; + } + + Guest* GenerateGuest() + { + Guest* peep = nullptr; + const auto spawn = GetRandomPeepSpawn(); + if (spawn != nullptr) + { + auto direction = DirectionReverse(spawn->direction); + peep = Guest::Generate({ spawn->x, spawn->y, spawn->z }); + if (peep != nullptr) + { + peep->Orientation = direction << 3; + + auto destination = peep->GetLocation().ToTileCentre(); + peep->SetDestination(destination, 5); + peep->PeepDirection = direction; + peep->Var37 = 0; + peep->State = PeepState::EnteringPark; + } + } + return peep; + } + + void ResetHistories(GameState_t& gameState) + { + std::fill(std::begin(gameState.Park.RatingHistory), std::end(gameState.Park.RatingHistory), ParkRatingHistoryUndefined); + std::fill( + std::begin(gameState.GuestsInParkHistory), std::end(gameState.GuestsInParkHistory), GuestsInParkHistoryUndefined); + } + + void UpdateHistories(GameState_t& gameState) + { + uint8_t guestChangeModifier = 1; + int32_t changeInGuestsInPark = static_cast(gameState.NumGuestsInPark) + - static_cast(gameState.NumGuestsInParkLastWeek); + if (changeInGuestsInPark > -20) + { + guestChangeModifier++; + if (changeInGuestsInPark < 20) + { + guestChangeModifier = 0; + } + } + gameState.GuestChangeModifier = guestChangeModifier; + gameState.NumGuestsInParkLastWeek = gameState.NumGuestsInPark; + + // Update park rating, guests in park and current cash history + HistoryPushRecord(gameState.Park.RatingHistory, gameState.Park.Rating / 4); + HistoryPushRecord(gameState.GuestsInParkHistory, gameState.NumGuestsInPark); + + constexpr auto cashHistorySize = std::extent_v; + HistoryPushRecord(gameState.CashHistory, FinanceGetCurrentCash() - gameState.BankLoan); + + // Update weekly profit history + auto currentWeeklyProfit = gameState.WeeklyProfitAverageDividend; + if (gameState.WeeklyProfitAverageDivisor != 0) + { + currentWeeklyProfit /= gameState.WeeklyProfitAverageDivisor; + } + constexpr auto profitHistorySize = std::extent_v; + HistoryPushRecord(gameState.WeeklyProfitHistory, currentWeeklyProfit); + gameState.WeeklyProfitAverageDividend = 0; + gameState.WeeklyProfitAverageDivisor = 0; + + // Update park value history + constexpr auto parkValueHistorySize = std::extent_v; + HistoryPushRecord(gameState.Park.ValueHistory, gameState.Park.Value); + + // Invalidate relevant windows + auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT); + ContextBroadcastIntent(&intent); + WindowInvalidateByClass(WindowClass::ParkInformation); WindowInvalidateByClass(WindowClass::Finances); + } + + uint32_t UpdateSize(GameState_t& gameState) + { + auto tiles = CalculateParkSize(); + if (tiles != gameState.Park.Size) + { + gameState.Park.Size = tiles; + WindowInvalidateByClass(WindowClass::ParkInformation); + } + return tiles; + } + + void SetOpen(bool open) + { + auto parkSetParameter = ParkSetParameterAction(open ? ParkParameter::Open : ParkParameter::Close); + GameActions::Execute(&parkSetParameter); + } + + /** + * + * rct2: 0x00664D05 + */ + void UpdateFences(const CoordsXY& coords) + { + if (MapIsEdge(coords)) + return; + + auto surfaceElement = MapGetSurfaceElementAt(coords); + if (surfaceElement == nullptr) + return; + + uint8_t newFences = 0; + if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) == 0) + { + bool fenceRequired = true; + + TileElement* tileElement = MapGetFirstElementAt(coords); + if (tileElement == nullptr) + return; + // If an entrance element do not place flags around surface + do + { + if (tileElement->GetType() != TileElementType::Entrance) + continue; + + if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_PARK_ENTRANCE) + continue; + + if (!(tileElement->IsGhost())) + { + fenceRequired = false; + break; + } + } while (!(tileElement++)->IsLastForTile()); + + if (fenceRequired) + { + if (MapIsLocationInPark({ coords.x - COORDS_XY_STEP, coords.y })) + { + newFences |= 0x8; + } + + if (MapIsLocationInPark({ coords.x, coords.y - COORDS_XY_STEP })) + { + newFences |= 0x4; + } + + if (MapIsLocationInPark({ coords.x + COORDS_XY_STEP, coords.y })) + { + newFences |= 0x2; + } + + if (MapIsLocationInPark({ coords.x, coords.y + COORDS_XY_STEP })) + { + newFences |= 0x1; + } + } + } + + if (surfaceElement->GetParkFences() != newFences) + { + int32_t baseZ = surfaceElement->GetBaseZ(); + int32_t clearZ = baseZ + 16; + MapInvalidateTile({ coords, baseZ, clearZ }); + surfaceElement->SetParkFences(newFences); + } + } + + void UpdateFencesAroundTile(const CoordsXY& coords) + { + UpdateFences(coords); + UpdateFences({ coords.x + COORDS_XY_STEP, coords.y }); + UpdateFences({ coords.x - COORDS_XY_STEP, coords.y }); + UpdateFences({ coords.x, coords.y + COORDS_XY_STEP }); + UpdateFences({ coords.x, coords.y - COORDS_XY_STEP }); + } + + void SetForcedRating(int32_t rating) + { + _forcedParkRating = rating; + GetGameState().Park.Rating = CalculateParkRating(); auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); ContextBroadcastIntent(&intent); } - // Every ~102 seconds - if (currentTicks % 4096 == 0) - { - gameState.ParkSize = CalculateParkSize(); - WindowInvalidateByClass(WindowClass::ParkInformation); - } - - generateGuests(gameState); -} - -uint32_t CalculateParkSize() -{ - uint32_t tiles = 0; - TileElementIterator it; - TileElementIteratorBegin(&it); - do - { - if (it.element->GetType() == TileElementType::Surface) - { - if (it.element->AsSurface()->GetOwnership() & (OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED | OWNERSHIP_OWNED)) - { - tiles++; - } - } - } while (TileElementIteratorNext(&it)); - - auto& gameState = GetGameState(); - if (tiles != gameState.ParkSize) - { - gameState.ParkSize = tiles; - WindowInvalidateByClass(WindowClass::ParkInformation); - } - - return tiles; -} - -int32_t CalculateParkRating() -{ - if (_forcedParkRating >= 0) + int32_t GetForcedRating() { return _forcedParkRating; } - auto& gameState = GetGameState(); - int32_t result = 1150; - if (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_PARK_RATING) + money64 GetEntranceFee() { - result = 1050; - } - - // Guests - { - // -150 to +3 based on a range of guests from 0 to 2000 - result -= 150 - (std::min(2000, gameState.NumGuestsInPark) / 13); - - // Find the number of happy peeps and the number of peeps who can't find the park exit - uint32_t happyGuestCount = 0; - uint32_t lostGuestCount = 0; - for (auto peep : EntityList()) + const auto& gameState = GetGameState(); + if (gameState.Park.Flags & PARK_FLAGS_NO_MONEY) { - if (!peep->OutsideOfPark) - { - if (peep->Happiness > 128) - { - happyGuestCount++; - } - if ((peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK) && (peep->GuestIsLostCountdown < 90)) - { - lostGuestCount++; - } - } + return 0; } - - // Peep happiness -500 to +0 - result -= 500; - if (gameState.NumGuestsInPark > 0) + if (!EntranceFeeUnlocked()) { - result += 2 * std::min(250u, (happyGuestCount * 300) / gameState.NumGuestsInPark); + return 0; } + return gameState.Park.EntranceFee; + } - // Up to 25 guests can be lost without affecting the park rating. - if (lostGuestCount > 25) + bool RidePricesUnlocked() + { + const auto& gameState = GetGameState(); + if (gameState.Park.Flags & PARK_FLAGS_UNLOCK_ALL_PRICES) { - result -= (lostGuestCount - 25) * 7; + return true; } - } - - // Rides - { - int32_t rideCount = 0; - int32_t excitingRideCount = 0; - int32_t totalRideUptime = 0; - int32_t totalRideIntensity = 0; - int32_t totalRideExcitement = 0; - for (auto& ride : GetRideManager()) + if (gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY) { - totalRideUptime += 100 - ride.downtime; - if (RideHasRatings(ride)) - { - totalRideExcitement += ride.excitement / 8; - totalRideIntensity += ride.intensity / 8; - excitingRideCount++; - } - rideCount++; + return true; } - result -= 200; - if (rideCount > 0) + return false; + } + + bool EntranceFeeUnlocked() + { + const auto& gameState = GetGameState(); + if (gameState.Park.Flags & PARK_FLAGS_UNLOCK_ALL_PRICES) { - result += (totalRideUptime / rideCount) * 2; + return true; } - result -= 100; - if (excitingRideCount > 0) + if (!(gameState.Park.Flags & PARK_FLAGS_PARK_FREE_ENTRY)) { - int32_t averageExcitement = totalRideExcitement / excitingRideCount; - int32_t averageIntensity = totalRideIntensity / excitingRideCount; - - averageExcitement -= 46; - if (averageExcitement < 0) - { - averageExcitement = -averageExcitement; - } - - averageIntensity -= 65; - if (averageIntensity < 0) - { - averageIntensity = -averageIntensity; - } - - averageExcitement = std::min(averageExcitement / 2, 50); - averageIntensity = std::min(averageIntensity / 2, 50); - result += 100 - averageExcitement - averageIntensity; + return true; } - - totalRideExcitement = std::min(1000, totalRideExcitement); - totalRideIntensity = std::min(1000, totalRideIntensity); - result -= 200 - ((totalRideExcitement + totalRideIntensity) / 10); + return false; } - // Litter + bool ParkData::IsOpen() const { - // Counts the amount of litter whose age is min. 7680 ticks (5~ min) old. - const auto litterList = EntityList(); - const auto litterCount = std::count_if( - litterList.begin(), litterList.end(), [](auto* litter) { return litter->GetAge() >= 7680; }); - - result -= 600 - (4 * (150 - std::min(150, litterCount))); + return (Flags & PARK_FLAGS_PARK_OPEN) != 0; } - - result -= gameState.ParkRatingCasualtyPenalty; - result = std::clamp(result, 0, 999); - return result; -} - -money64 CalculateParkValue() -{ - // Sum ride values - money64 result = 0; - for (const auto& ride : GetRideManager()) - { - result += calculateRideValue(ride); - } - - // +7.00 per guest - result += static_cast(GetGameState().NumGuestsInPark) * 7.00_GBP; - - return result; -} - -static money64 calculateRideValue(const Ride& ride) -{ - money64 result = 0; - if (ride.value != RIDE_VALUE_UNDEFINED) - { - const auto& rtd = ride.GetRideTypeDescriptor(); - result = (ride.value * 10) * (static_cast(RideCustomersInLast5Minutes(ride)) + rtd.BonusValue * 4LL); - } - return result; -} - -money64 CalculateCompanyValue() -{ - const auto& gameState = GetGameState(); - - auto result = gameState.ParkValue - gameState.BankLoan; - - // Clamp addition to prevent overflow - result = AddClamp_money64(result, FinanceGetCurrentCash()); - - return result; -} - -static money64 calculateTotalRideValueForMoney() -{ - money64 totalRideValue = 0; - bool ridePricesUnlocked = ParkRidePricesUnlocked() && !(GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY); - for (auto& ride : GetRideManager()) - { - if (ride.status != RideStatus::Open) - continue; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) - continue; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - continue; - - // Add ride value - if (ride.value != RIDE_VALUE_UNDEFINED) - { - money64 rideValue = ride.value; - if (ridePricesUnlocked) - { - rideValue -= ride.price[0]; - } - if (rideValue > 0) - { - totalRideValue += rideValue * 2; - } - } - } - return totalRideValue; -} - -static uint32_t calculateSuggestedMaxGuests() -{ - uint32_t suggestedMaxGuests = 0; - uint32_t difficultGenerationBonus = 0; - - auto& gameState = GetGameState(); - - for (auto& ride : GetRideManager()) - { - if (ride.status != RideStatus::Open) - continue; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) - continue; - if (ride.lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - continue; - - // Add guest score for ride type - suggestedMaxGuests += ride.GetRideTypeDescriptor().BonusValue; - - // If difficult guest generation, extra guests are available for good rides - if (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) - { - if (!(ride.lifecycle_flags & RIDE_LIFECYCLE_TESTED)) - continue; - if (!ride.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_HAS_TRACK)) - continue; - if (!ride.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_HAS_DATA_LOGGING)) - continue; - if (ride.GetStation().SegmentLength < (600 << 16)) - continue; - if (ride.excitement < RIDE_RATING(6, 00)) - continue; - - // Bonus guests for good ride - difficultGenerationBonus += ride.GetRideTypeDescriptor().BonusValue * 2; - } - } - - if (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) - { - suggestedMaxGuests = std::min(suggestedMaxGuests, 1000); - suggestedMaxGuests += difficultGenerationBonus; - } - - suggestedMaxGuests = std::min(suggestedMaxGuests, 65535); - return suggestedMaxGuests; -} - -static uint32_t calculateGuestGenerationProbability() -{ - auto& gameState = GetGameState(); - - // Begin with 50 + park rating - uint32_t probability = 50 + std::clamp(gameState.ParkRating - 200, 0, 650); - - // The more guests, the lower the chance of a new one - uint32_t numGuests = gameState.NumGuestsInPark + gameState.NumGuestsHeadingForPark; - if (numGuests > gameState.SuggestedGuestMaximum) - { - probability /= 4; - // Even lower for difficult guest generation - if (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) - { - probability /= 4; - } - } - - // Reduces chance for any more than 7000 guests - if (numGuests > 7000) - { - probability /= 4; - } - - // Penalty for overpriced entrance fee relative to total ride value - auto entranceFee = ParkGetEntranceFee(); - if (entranceFee > gameState.TotalRideValueForMoney) - { - probability /= 4; - // Extra penalty for very overpriced entrance fee - if (entranceFee / 2 > gameState.TotalRideValueForMoney) - { - probability /= 4; - } - } - - // Reward or penalties for park awards - for (const auto& award : GetGameState().CurrentAwards) - { - // +/- 0.25% of the probability - if (AwardIsPositive(award.Type)) - { - probability += probability / 4; - } - else - { - probability -= probability / 4; - } - } - - return probability; -} - -uint8_t CalculateGuestInitialHappiness(uint8_t percentage) -{ - percentage = std::clamp(percentage, 15, 98); - - // The percentages follow this sequence: - // 15 17 18 20 21 23 25 26 28 29 31 32 34 36 37 39 40 42 43 45 47 48 50 51 53... - // This sequence can be defined as PI*(9+n)/2 (the value is floored) - for (uint8_t n = 1; n < 55; n++) - { - // Avoid floating point math by rescaling PI up. - constexpr int32_t SCALE = 100000; - constexpr int32_t PI_SCALED = 314159; // PI * SCALE; - if (((PI_SCALED * (9 + n)) / SCALE) / 2 >= percentage) - { - return (9 + n) * 4; - } - } - - // This is the lowest possible value: - return 40; -} - -static void generateGuests(GameState_t& gameState) -{ - // Generate a new guest for some probability - if (static_cast(ScenarioRand() & 0xFFFF) < gameState.GuestGenerationProbability) - { - bool difficultGeneration = (gameState.ParkFlags & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0; - if (!difficultGeneration || gameState.SuggestedGuestMaximum + 150 >= gameState.NumGuestsInPark) - { - GenerateGuest(); - } - } - - // Extra guests generated by advertising campaigns - for (const auto& campaign : gMarketingCampaigns) - { - // Random chance of guest generation - auto probability = MarketingGetCampaignGuestGenerationProbability(campaign.Type); - auto random = ScenarioRandMax(std::numeric_limits::max()); - if (random < probability) - { - generateGuestFromCampaign(campaign.Type); - } - } -} - -static Guest* generateGuestFromCampaign(int32_t campaign) -{ - auto peep = GenerateGuest(); - if (peep != nullptr) - { - MarketingSetGuestCampaign(peep, campaign); - } - return peep; -} - -Guest* GenerateGuest() -{ - Guest* peep = nullptr; - const auto spawn = GetRandomPeepSpawn(); - if (spawn != nullptr) - { - auto direction = DirectionReverse(spawn->direction); - peep = Guest::Generate({ spawn->x, spawn->y, spawn->z }); - if (peep != nullptr) - { - peep->Orientation = direction << 3; - - auto destination = peep->GetLocation().ToTileCentre(); - peep->SetDestination(destination, 5); - peep->PeepDirection = direction; - peep->Var37 = 0; - peep->State = PeepState::EnteringPark; - } - } - return peep; -} - -template static void HistoryPushRecord(T history[TSize], T newItem) -{ - for (size_t i = TSize - 1; i > 0; i--) - { - history[i] = history[i - 1]; - } - history[0] = newItem; -} - -void ResetParkHistories(GameState_t& gameState) -{ - std::fill(std::begin(gameState.ParkRatingHistory), std::end(gameState.ParkRatingHistory), ParkRatingHistoryUndefined); - std::fill(std::begin(gameState.GuestsInParkHistory), std::end(gameState.GuestsInParkHistory), GuestsInParkHistoryUndefined); -} - -void UpdateParkHistories(GameState_t& gameState) -{ - uint8_t guestChangeModifier = 1; - int32_t changeInGuestsInPark = static_cast(gameState.NumGuestsInPark) - - static_cast(gameState.NumGuestsInParkLastWeek); - if (changeInGuestsInPark > -20) - { - guestChangeModifier++; - if (changeInGuestsInPark < 20) - { - guestChangeModifier = 0; - } - } - gameState.GuestChangeModifier = guestChangeModifier; - gameState.NumGuestsInParkLastWeek = gameState.NumGuestsInPark; - - // Update park rating, guests in park and current cash history - HistoryPushRecord(gameState.ParkRatingHistory, gameState.ParkRating / 4); - HistoryPushRecord(gameState.GuestsInParkHistory, gameState.NumGuestsInPark); - - constexpr auto cashHistorySize = std::extent_v; - HistoryPushRecord(gameState.CashHistory, FinanceGetCurrentCash() - gameState.BankLoan); - - // Update weekly profit history - auto currentWeeklyProfit = gameState.WeeklyProfitAverageDividend; - if (gameState.WeeklyProfitAverageDivisor != 0) - { - currentWeeklyProfit /= gameState.WeeklyProfitAverageDivisor; - } - constexpr auto profitHistorySize = std::extent_v; - HistoryPushRecord(gameState.WeeklyProfitHistory, currentWeeklyProfit); - gameState.WeeklyProfitAverageDividend = 0; - gameState.WeeklyProfitAverageDivisor = 0; - - // Update park value history - constexpr auto parkValueHistorySize = std::extent_v; - HistoryPushRecord(gameState.ParkValueHistory, gameState.ParkValue); - - // Invalidate relevant windows - auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT); - ContextBroadcastIntent(&intent); - WindowInvalidateByClass(WindowClass::ParkInformation); - WindowInvalidateByClass(WindowClass::Finances); -} - -uint32_t ParkUpdateSize(GameState_t& gameState) -{ - auto tiles = CalculateParkSize(); - if (tiles != gameState.ParkSize) - { - gameState.ParkSize = tiles; - WindowInvalidateByClass(WindowClass::ParkInformation); - } - return tiles; -} +} // namespace OpenRCT2::Park diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index df73e3ccc6..28d491433e 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -10,6 +10,7 @@ #pragma once #include "../common.h" +#include "../management/Finance.h" #include "Map.h" constexpr auto MAX_ENTRANCE_FEE = 999.00_GBP; @@ -52,39 +53,51 @@ namespace OpenRCT2 { struct Date; - struct Park final + namespace Park { - std::string Name; + struct ParkData final + { + std::string Name; + uint64_t Flags; + uint16_t Rating; + uint8_t RatingHistory[kParkRatingHistorySize]; + int16_t RatingCasualtyPenalty; + money64 EntranceFee; + std::vector Entrances; + uint32_t Size; + money64 Value; + money64 ValueHistory[FINANCE_GRAPH_SIZE]; + + bool IsOpen() const; + }; + + void Initialise(OpenRCT2::GameState_t& gameState); + void Update(OpenRCT2::GameState_t& gameState, const OpenRCT2::Date& date); + + uint32_t CalculateParkSize(); + int32_t CalculateParkRating(); + money64 CalculateParkValue(); + money64 CalculateCompanyValue(); + + Guest* GenerateGuest(); + + void ResetHistories(OpenRCT2::GameState_t& gameState); + void UpdateHistories(OpenRCT2::GameState_t& gameState); + void SetForcedRating(int32_t rating); + int32_t GetForcedRating(); + + uint32_t UpdateSize(OpenRCT2::GameState_t& gameState); + + void UpdateFences(const CoordsXY& coords); + void UpdateFencesAroundTile(const CoordsXY& coords); + + uint8_t CalculateGuestInitialHappiness(uint8_t percentage); + + void SetOpen(bool open); + money64 GetEntranceFee(); + + bool RidePricesUnlocked(); + bool EntranceFeeUnlocked(); + } // namespace Park - bool IsOpen() const; - }; } // namespace OpenRCT2 - -void ParkInitialise(OpenRCT2::GameState_t& gameState); -void ParkUpdate(OpenRCT2::GameState_t& gameState, const OpenRCT2::Date& date); - -uint32_t CalculateParkSize(); -int32_t CalculateParkRating(); -money64 CalculateParkValue(); -money64 CalculateCompanyValue(); - -Guest* GenerateGuest(); - -void ResetParkHistories(OpenRCT2::GameState_t& gameState); -void UpdateParkHistories(OpenRCT2::GameState_t& gameState); -void ParkSetForcedRating(int32_t rating); -int32_t ParkGetForcedRating(); - -uint32_t ParkUpdateSize(OpenRCT2::GameState_t& gameState); - -void ParkUpdateFences(const CoordsXY& coords); -void ParkUpdateFencesAroundTile(const CoordsXY& coords); - -uint8_t CalculateGuestInitialHappiness(uint8_t percentage); - -void ParkSetOpen(bool open); -int32_t ParkEntranceGetIndex(const CoordsXYZ& entrancePos); -money64 ParkGetEntranceFee(); - -bool ParkRidePricesUnlocked(); -bool ParkEntranceFeeUnlocked(); diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index ecbb9f6a31..2de34811c4 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -503,7 +503,7 @@ namespace OpenRCT2::TileInspector if (!showFences) surfaceelement->SetParkFences(0); else - ParkUpdateFences(loc); + Park::UpdateFences(loc); } return GameActions::Result(); diff --git a/test/tests/PlayTests.cpp b/test/tests/PlayTests.cpp index 655ab02450..45a36f6ec8 100644 --- a/test/tests/PlayTests.cpp +++ b/test/tests/PlayTests.cpp @@ -101,7 +101,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds) // Open park for free but charging for rides execute(ParkParameter::Open); execute(0); - gameState.ParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.Flags |= PARK_FLAGS_UNLOCK_ALL_PRICES; // Find ferris wheel auto rideManager = GetRideManager(); @@ -118,7 +118,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds) gameState.Cheats.IgnoreRideIntensity = true; // Insert a rich guest - auto richGuest = gameState.Park.GenerateGuest(); + auto richGuest = Park::GenerateGuest(); richGuest->CashInPocket = 3000; // Wait for rich guest to get in queue @@ -126,7 +126,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds) ASSERT_TRUE(matched); // Insert poor guest - auto poorGuest = gameState.Park.GenerateGuest(); + auto poorGuest = Park::GenerateGuest(); poorGuest->CashInPocket = 5; // Wait for poor guest to get in queue @@ -161,7 +161,7 @@ TEST_F(PlayTests, CarRideWithOneCarOnlyAcceptsTwoGuests) // Open park for free but charging for rides execute(ParkParameter::Open); execute(0); - gameState.ParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; + gameState.Park.Flags |= PARK_FLAGS_UNLOCK_ALL_PRICES; // Find car ride auto rideManager = GetRideManager(); @@ -180,7 +180,7 @@ TEST_F(PlayTests, CarRideWithOneCarOnlyAcceptsTwoGuests) std::vector guests; for (int i = 0; i < 25; i++) { - guests.push_back(gameState.Park.GenerateGuest()); + guests.push_back(Park::GenerateGuest()); } // Wait until one of them is riding