diff --git a/src/openrct2-ui/windows/EditorScenarioOptions.cpp b/src/openrct2-ui/windows/EditorScenarioOptions.cpp index 61a3f2c8cac6..287594f52c6d 100644 --- a/src/openrct2-ui/windows/EditorScenarioOptions.cpp +++ b/src/openrct2-ui/windows/EditorScenarioOptions.cpp @@ -465,10 +465,10 @@ class EditorScenarioOptionsWindow final : public Window Invalidate(); break; case WIDX_INITIAL_LOAN_INCREASE: - if (gBankLoan < 5000000.00_GBP) + if (gameState.BankLoan < 5000000.00_GBP) { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::InitialLoan, gBankLoan + 1000.00_GBP); + ScenarioSetSetting::InitialLoan, gameState.BankLoan + 1000.00_GBP); GameActions::Execute(&scenarioSetSetting); } else @@ -478,10 +478,10 @@ class EditorScenarioOptionsWindow final : public Window Invalidate(); break; case WIDX_INITIAL_LOAN_DECREASE: - if (gBankLoan > 0.00_GBP) + if (gameState.BankLoan > 0.00_GBP) { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::InitialLoan, gBankLoan - 1000.00_GBP); + ScenarioSetSetting::InitialLoan, gameState.BankLoan - 1000.00_GBP); GameActions::Execute(&scenarioSetSetting); } else @@ -517,10 +517,10 @@ class EditorScenarioOptionsWindow final : public Window Invalidate(); break; case WIDX_INTEREST_RATE_INCREASE: - if (gBankLoanInterestRate < MaxBankLoanInterestRate) + if (gameState.BankLoanInterestRate < MaxBankLoanInterestRate) { auto scenarioSetSetting = ScenarioSetSettingAction( - ScenarioSetSetting::AnnualInterestRate, gBankLoanInterestRate + 1); + ScenarioSetSetting::AnnualInterestRate, gameState.BankLoanInterestRate + 1); GameActions::Execute(&scenarioSetSetting); } else @@ -530,9 +530,9 @@ class EditorScenarioOptionsWindow final : public Window Invalidate(); break; case WIDX_INTEREST_RATE_DECREASE: - if (gBankLoanInterestRate > 0) + if (gameState.BankLoanInterestRate > 0) { - auto interest = std::min(MaxBankLoanInterestRate, gBankLoanInterestRate - 1); + auto interest = std::min(MaxBankLoanInterestRate, gameState.BankLoanInterestRate - 1); auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::AnnualInterestRate, interest); GameActions::Execute(&scenarioSetSetting); } @@ -622,6 +622,8 @@ class EditorScenarioOptionsWindow final : public Window WindowDrawWidgets(*this, dpi); DrawTabImages(dpi); + auto& gameState = GetGameState(); + const auto& initialCashWidget = widgets[WIDX_INITIAL_CASH]; if (initialCashWidget.type != WindowWidgetType::Empty) { @@ -642,7 +644,7 @@ class EditorScenarioOptionsWindow final : public Window screenCoords = windowPos + ScreenCoordsXY{ initialLoanWidget.left + 1, initialLoanWidget.top }; auto ft = Formatter(); - ft.Add(gBankLoan); + ft.Add(gameState.BankLoan); DrawTextBasic(dpi, screenCoords, STR_CURRENCY_FORMAT_LABEL, ft); } @@ -667,7 +669,7 @@ class EditorScenarioOptionsWindow final : public Window screenCoords = windowPos + ScreenCoordsXY{ interestRateWidget.left + 1, interestRateWidget.top }; auto ft = Formatter(); - ft.Add(std::clamp(static_cast(gBankLoanInterestRate), INT16_MIN, INT16_MAX)); + ft.Add(std::clamp(static_cast(gameState.BankLoanInterestRate), INT16_MIN, INT16_MAX)); DrawTextBasic(dpi, screenCoords, STR_PERCENT_FORMAT_LABEL, ft); } } diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 18eb409b318e..a8a83c8ba045 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -491,8 +491,8 @@ class FinancesWindow final : public Window { // If loan can be increased, do so. // If not, action shows error message. - auto newLoan = gBankLoan + 1000.00_GBP; - if (gBankLoan < gameState.MaxBankLoan) + auto newLoan = gameState.BankLoan + 1000.00_GBP; + if (gameState.BankLoan < gameState.MaxBankLoan) { newLoan = std::min(gameState.MaxBankLoan, newLoan); } @@ -505,10 +505,10 @@ class FinancesWindow final : public Window // If loan is positive, decrease it. // If loan is negative, action shows error message. // If loan is exactly 0, prevent error message. - if (gBankLoan != 0) + if (gameState.BankLoan != 0) { - auto newLoan = gBankLoan - 1000.00_GBP; - if (gBankLoan > 0) + auto newLoan = gameState.BankLoan - 1000.00_GBP; + if (gameState.BankLoan > 0) { newLoan = std::max(static_cast(0LL), newLoan); } @@ -527,7 +527,7 @@ class FinancesWindow final : public Window // drawing has completed. auto ft = Formatter::Common(); ft.Increment(6); - ft.Add(gBankLoan); + ft.Add(GetGameState().BankLoan); // Keep up with new months being added in the first two years. if (GetDate().GetMonthsElapsed() != _lastPaintedMonth) @@ -569,7 +569,7 @@ class FinancesWindow final : public Window if (!(gameState.ParkFlags & PARK_FLAGS_RCT1_INTEREST)) { auto ft = Formatter(); - ft.Add(gBankLoanInterestRate); + ft.Add(gameState.BankLoanInterestRate); DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ 167, 279 }, STR_FINANCES_SUMMARY_AT_X_PER_YEAR, ft); } @@ -615,8 +615,10 @@ class FinancesWindow final : public Window auto graphTopLeft = windowPos + ScreenCoordsXY{ pageWidget->left + 4, pageWidget->top + 15 }; auto graphBottomRight = windowPos + ScreenCoordsXY{ pageWidget->right - 4, pageWidget->bottom - 4 }; + const auto& gameState = GetGameState(); + // Cash (less loan) - auto cashLessLoan = GetGameState().Cash - gBankLoan; + auto cashLessLoan = gameState.Cash - gameState.BankLoan; auto ft = Formatter(); ft.Add(cashLessLoan); diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 31c76d9463aa..f69693c7a2be 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -344,11 +344,11 @@ namespace Editor gameState.InitialCash = std::min(GetGameState().InitialCash, 100000); FinanceResetCashToInitial(); - gBankLoan = std::clamp(gBankLoan, 0.00_GBP, 5000000.00_GBP); + gameState.BankLoan = std::clamp(gameState.BankLoan, 0.00_GBP, 5000000.00_GBP); gameState.MaxBankLoan = std::clamp(gameState.MaxBankLoan, 0.00_GBP, 5000000.00_GBP); - gBankLoanInterestRate = std::clamp(gBankLoanInterestRate, 5, MaxBankLoanInterestRate); + gameState.BankLoanInterestRate = std::clamp(gameState.BankLoanInterestRate, 5, MaxBankLoanInterestRate); } ClimateReset(gameState.Climate); diff --git a/src/openrct2/GameState.h b/src/openrct2/GameState.h index e2b6754a5073..e1229b3a95fb 100644 --- a/src/openrct2/GameState.h +++ b/src/openrct2/GameState.h @@ -62,6 +62,8 @@ namespace OpenRCT2 uint16_t ScenarioParkRatingWarningDays; money64 ScenarioCompletedCompanyValue; money64 ScenarioCompanyValueRecord; + money64 BankLoan; + uint8_t BankLoanInterestRate; money64 MaxBankLoan; random_engine_t ScenarioRand; int32_t MapBaseZ; diff --git a/src/openrct2/actions/CheatSetAction.cpp b/src/openrct2/actions/CheatSetAction.cpp index 149be4ae499b..3b1e98362fa4 100644 --- a/src/openrct2/actions/CheatSetAction.cpp +++ b/src/openrct2/actions/CheatSetAction.cpp @@ -591,7 +591,7 @@ void CheatSetAction::AddMoney(money64 amount) const void CheatSetAction::ClearLoan() const { // First give money - AddMoney(gBankLoan); + AddMoney(GetGameState().BankLoan); // Then pay the loan auto gameAction = ParkSetLoanAction(0.00_GBP); diff --git a/src/openrct2/actions/ParkSetLoanAction.cpp b/src/openrct2/actions/ParkSetLoanAction.cpp index b52e67221fbf..9e2671001c8c 100644 --- a/src/openrct2/actions/ParkSetLoanAction.cpp +++ b/src/openrct2/actions/ParkSetLoanAction.cpp @@ -44,18 +44,18 @@ void ParkSetLoanAction::Serialise(DataSerialiser& stream) GameActions::Result ParkSetLoanAction::Query() const { auto& gameState = GetGameState(); - if (_value > gBankLoan && _value > gameState.MaxBankLoan) + if (_value > gameState.BankLoan && _value > gameState.MaxBankLoan) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BORROW_ANY_MORE_MONEY, STR_BANK_REFUSES_TO_INCREASE_LOAN); } - if (_value < gBankLoan && _value < 0.00_GBP) + if (_value < gameState.BankLoan && _value < 0.00_GBP) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_PAY_BACK_LOAN, STR_LOAN_CANT_BE_NEGATIVE); } // The “isPayingBack” check is needed to allow increasing the loan when the player is in debt. - const auto isPayingBack = gBankLoan > _value; - const auto amountToPayBack = gBankLoan - _value; + const auto isPayingBack = gameState.BankLoan > _value; + const auto amountToPayBack = gameState.BankLoan - _value; if (isPayingBack && amountToPayBack > gameState.Cash) { return GameActions::Result( @@ -66,8 +66,10 @@ GameActions::Result ParkSetLoanAction::Query() const GameActions::Result ParkSetLoanAction::Execute() const { - GetGameState().Cash -= (gBankLoan - _value); - gBankLoan = _value; + auto& gameState = GetGameState(); + + gameState.Cash -= (gameState.BankLoan - _value); + gameState.BankLoan = _value; auto windowManager = OpenRCT2::GetContext()->GetUiContext()->GetWindowManager(); windowManager->BroadcastIntent(Intent(INTENT_ACTION_UPDATE_CASH)); diff --git a/src/openrct2/actions/ScenarioSetSettingAction.cpp b/src/openrct2/actions/ScenarioSetSettingAction.cpp index da901da05e9a..75befc3f7011 100644 --- a/src/openrct2/actions/ScenarioSetSettingAction.cpp +++ b/src/openrct2/actions/ScenarioSetSettingAction.cpp @@ -90,17 +90,17 @@ GameActions::Result ScenarioSetSettingAction::Execute() const WindowInvalidateByClass(WindowClass::BottomToolbar); break; case ScenarioSetSetting::InitialLoan: - gBankLoan = std::clamp(_value, 0.00_GBP, 5000000.00_GBP); - gameState.MaxBankLoan = std::max(gBankLoan, gameState.MaxBankLoan); + gameState.BankLoan = std::clamp(_value, 0.00_GBP, 5000000.00_GBP); + gameState.MaxBankLoan = std::max(gameState.BankLoan, gameState.MaxBankLoan); WindowInvalidateByClass(WindowClass::Finances); break; case ScenarioSetSetting::MaximumLoanSize: gameState.MaxBankLoan = std::clamp(_value, 0.00_GBP, 5000000.00_GBP); - gBankLoan = std::min(gBankLoan, gameState.MaxBankLoan); + gameState.BankLoan = std::min(gameState.BankLoan, gameState.MaxBankLoan); WindowInvalidateByClass(WindowClass::Finances); break; case ScenarioSetSetting::AnnualInterestRate: - gBankLoanInterestRate = std::clamp(_value, 0, MaxBankLoanInterestRate); + gameState.BankLoanInterestRate = std::clamp(_value, 0, MaxBankLoanInterestRate); WindowInvalidateByClass(WindowClass::Finances); break; case ScenarioSetSetting::ForbidMarketingCampaigns: diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 654e1901c3d0..92e82f22d172 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -577,7 +577,7 @@ static int32_t ConsoleCommandGet(InteractiveConsole& console, const arguments_t& } else if (argv[0] == "current_loan") { - console.WriteFormatLine("current_loan %d", gBankLoan / 10); + console.WriteFormatLine("current_loan %d", gameState.BankLoan / 10); } else if (argv[0] == "max_loan") { diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index 627f244f48a6..de6fc7abc679 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -39,8 +39,6 @@ static constexpr int32_t dword_988E60[static_cast(ExpenditureType::Coun 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, }; -money64 gBankLoan; -uint8_t gBankLoanInterestRate; money64 gCurrentExpenditure; money64 gCurrentProfit; money64 gHistoricalProfit; @@ -138,16 +136,18 @@ void FinancePayResearch() */ void FinancePayInterest() { - if (GetGameState().ParkFlags & PARK_FLAGS_NO_MONEY) + const auto& gameState = GetGameState(); + + if (gameState.ParkFlags & PARK_FLAGS_NO_MONEY) { return; } // This variable uses the 64-bit type as the computation below can involve multiplying very large numbers // that will overflow money64 if the loan is greater than (1 << 31) / (5 * current_interest_rate) - const money64 current_loan = gBankLoan; - const auto current_interest_rate = gBankLoanInterestRate; - const money64 interest_to_pay = (GetGameState().ParkFlags & PARK_FLAGS_RCT1_INTEREST) + const money64 current_loan = gameState.BankLoan; + const auto current_interest_rate = gameState.BankLoanInterestRate; + const money64 interest_to_pay = (gameState.ParkFlags & PARK_FLAGS_RCT1_INTEREST) ? (current_loan / 2400) : (current_loan * 5 * current_interest_rate) >> 14; @@ -229,12 +229,12 @@ void FinanceInit() gameState.InitialCash = 10000.00_GBP; // Cheat detection gameState.Cash = 10000.00_GBP; - gBankLoan = 10000.00_GBP; + gameState.BankLoan = 10000.00_GBP; gameState.MaxBankLoan = 20000.00_GBP; gHistoricalProfit = 0; - gBankLoanInterestRate = 10; + gameState.BankLoanInterestRate = 10; gameState.ParkValue = 0; gCompanyValue = 0; gameState.ScenarioCompletedCompanyValue = MONEY64_UNDEFINED; @@ -270,7 +270,7 @@ void FinanceUpdateDailyProfit() current_profit -= research_cost_table[level]; // Loan costs - auto current_loan = gBankLoan; + auto current_loan = gameState.BankLoan; current_profit -= current_loan / 600; // Ride costs @@ -302,7 +302,7 @@ money64 FinanceGetInitialCash() money64 FinanceGetCurrentLoan() { - return gBankLoan; + return GetGameState().BankLoan; } money64 FinanceGetMaximumLoan() diff --git a/src/openrct2/management/Finance.h b/src/openrct2/management/Finance.h index 8543b3da05fa..b49f84cfde0e 100644 --- a/src/openrct2/management/Finance.h +++ b/src/openrct2/management/Finance.h @@ -38,8 +38,6 @@ constexpr uint8_t MaxBankLoanInterestRate = 255; extern const money64 research_cost_table[RESEARCH_FUNDING_COUNT]; -extern money64 gBankLoan; -extern uint8_t gBankLoanInterestRate; extern money64 gCurrentExpenditure; extern money64 gCurrentProfit; diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 3a5b520b83fe..7328e1317a3d 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -803,9 +803,9 @@ namespace OpenRCT2 auto& park = GetContext()->GetGameState()->GetPark(); cs.ReadWrite(park.Name); cs.ReadWrite(gameState.Cash); - cs.ReadWrite(gBankLoan); + cs.ReadWrite(gameState.BankLoan); cs.ReadWrite(gameState.MaxBankLoan); - cs.ReadWrite(gBankLoanInterestRate); + cs.ReadWrite(gameState.BankLoanInterestRate); cs.ReadWrite(gameState.ParkFlags); if (version <= 18) { diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index e53ca5fa7cf8..f1a896458f08 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1396,10 +1396,10 @@ namespace RCT1 gConstructionRightsPrice = ToMoney64(_s4.ConstructionRightsPrice); gameState.Cash = ToMoney64(_s4.Cash); - gBankLoan = ToMoney64(_s4.Loan); + gameState.BankLoan = ToMoney64(_s4.Loan); gameState.MaxBankLoan = ToMoney64(_s4.MaxLoan); // It's more like 1.33%, but we can only use integers. Can be fixed once we have our own save format. - gBankLoanInterestRate = 1; + gameState.BankLoanInterestRate = 1; gameState.InitialCash = ToMoney64(_s4.Cash); gCompanyValue = ToMoney64(_s4.CompanyValue); diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 38f4ab915f5c..58cdcbb10be4 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -261,7 +261,7 @@ namespace RCT2 ImportEntities(); gameState.InitialCash = ToMoney64(_s6.InitialCash); - gBankLoan = ToMoney64(_s6.CurrentLoan); + gameState.BankLoan = ToMoney64(_s6.CurrentLoan); gameState.ParkFlags = _s6.ParkFlags & ~PARK_FLAGS_NO_MONEY_SCENARIO; @@ -411,7 +411,7 @@ namespace RCT2 // Pad01358842 ImportResearchList(gameState); gameState.MapBaseZ = _s6.MapBaseZ; - gBankLoanInterestRate = _s6.CurrentInterestRate; + gameState.BankLoanInterestRate = _s6.CurrentInterestRate; // Pad0135934B // Preserve compatibility with vanilla RCT2's save format. gameState.ParkEntrances.clear(); diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 33f51b4f3ed9..459fa121af2b 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -105,7 +105,7 @@ void ScenarioReset(GameState_t& gameState) gameState.ParkRating = park.CalculateParkRating(); gameState.ParkValue = park.CalculateParkValue(); gCompanyValue = park.CalculateCompanyValue(); - gHistoricalProfit = gameState.InitialCash - gBankLoan; + gHistoricalProfit = gameState.InitialCash - gameState.BankLoan; gameState.Cash = gameState.InitialCash; { @@ -820,7 +820,7 @@ ObjectiveStatus Objective::CheckRepayLoanAndParkValue() const { const auto& gameState = GetGameState(); money64 parkValue = gameState.ParkValue; - money64 currentLoan = gBankLoan; + 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 045744f8550f..08a44a99eb39 100644 --- a/src/openrct2/scripting/bindings/world/ScPark.cpp +++ b/src/openrct2/scripting/bindings/world/ScPark.cpp @@ -86,15 +86,17 @@ namespace OpenRCT2::Scripting money64 ScPark::bankLoan_get() const { - return gBankLoan; + return GetGameState().BankLoan; } void ScPark::bankLoan_set(money64 value) { ThrowIfGameStateNotMutable(); - if (gBankLoan != value) + auto& gameState = GetGameState(); + + if (gameState.BankLoan != value) { - gBankLoan = value; + gameState.BankLoan = value; auto intent = Intent(INTENT_ACTION_UPDATE_CASH); ContextBroadcastIntent(&intent); } diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 203817ec23e1..6fe4965969a9 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -496,7 +496,9 @@ money64 Park::CalculateRideValue(const Ride& ride) const money64 Park::CalculateCompanyValue() const { - auto result = GetGameState().ParkValue - gBankLoan; + const auto& gameState = GetGameState(); + + auto result = gameState.ParkValue - gameState.BankLoan; // Clamp addition to prevent overflow result = AddClamp_money64(result, FinanceGetCurrentCash()); @@ -753,7 +755,7 @@ void Park::UpdateHistories() // Update park rating, guests in park and current cash history HistoryPushRecord(gameState.ParkRatingHistory, gameState.ParkRating / 4); HistoryPushRecord(gGuestsInParkHistory, gameState.NumGuestsInPark); - HistoryPushRecord(gCashHistory, FinanceGetCurrentCash() - gBankLoan); + HistoryPushRecord(gCashHistory, FinanceGetCurrentCash() - gameState.BankLoan); // Update weekly profit history auto currentWeeklyProfit = gameState.WeeklyProfitAverageDividend;