From a0dd6a3aa6c39bc517885ed3cae6b8a48b3e465f Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Wed, 28 Sep 2022 12:20:44 +0200 Subject: [PATCH] Fix #18087: gCash clamped to 32-bit integer every transaction --- distribution/changelog.txt | 1 + src/openrct2/actions/ParkSetLoanAction.cpp | 2 +- src/openrct2/actions/ParkSetLoanAction.h | 2 +- src/openrct2/actions/SetCheatAction.cpp | 6 +++--- src/openrct2/actions/SetCheatAction.h | 4 ++-- src/openrct2/common.h | 5 +++++ src/openrct2/interface/InteractiveConsole.cpp | 4 ++-- src/openrct2/management/Finance.cpp | 6 +++--- src/openrct2/management/Finance.h | 4 ++-- src/openrct2/network/NetworkBase.cpp | 2 +- 10 files changed, 21 insertions(+), 15 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 6dbe6a9a2a..03af2fbf1d 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -83,6 +83,7 @@ - Fix: [#18035] Favourited servers don’t get their online status updated. - Fix: [#18051] Visual glitch with Mine Ride's large unbanked turn (original bug). - Fix: [#18059] [Plugin] Width and height of custom window not changeable via script. +- Fix: [#18087] Bank balance is clamped to a 32-bit integer every transaction. 0.4.1 (2022-07-04) ------------------------------------------------------------------------ diff --git a/src/openrct2/actions/ParkSetLoanAction.cpp b/src/openrct2/actions/ParkSetLoanAction.cpp index 27be2e8f1a..62d784b38d 100644 --- a/src/openrct2/actions/ParkSetLoanAction.cpp +++ b/src/openrct2/actions/ParkSetLoanAction.cpp @@ -17,7 +17,7 @@ #include "../ui/WindowManager.h" #include "../windows/Intent.h" -ParkSetLoanAction::ParkSetLoanAction(money32 value) +ParkSetLoanAction::ParkSetLoanAction(money64 value) : _value(value) { } diff --git a/src/openrct2/actions/ParkSetLoanAction.h b/src/openrct2/actions/ParkSetLoanAction.h index 6f91dca101..025332d753 100644 --- a/src/openrct2/actions/ParkSetLoanAction.h +++ b/src/openrct2/actions/ParkSetLoanAction.h @@ -18,7 +18,7 @@ private: public: ParkSetLoanAction() = default; - ParkSetLoanAction(money32 value); + ParkSetLoanAction(money64 value); void AcceptParameters(GameActionParameterVisitor& visitor) override; diff --git a/src/openrct2/actions/SetCheatAction.cpp b/src/openrct2/actions/SetCheatAction.cpp index de1df804da..d24e28b194 100644 --- a/src/openrct2/actions/SetCheatAction.cpp +++ b/src/openrct2/actions/SetCheatAction.cpp @@ -517,7 +517,7 @@ void SetCheatAction::SetScenarioNoMoney(bool enabled) const window_invalidate_by_class(WindowClass::Cheats); } -void SetCheatAction::SetMoney(money32 amount) const +void SetCheatAction::SetMoney(money64 amount) const { gCash = amount; @@ -525,9 +525,9 @@ void SetCheatAction::SetMoney(money32 amount) const window_invalidate_by_class(WindowClass::BottomToolbar); } -void SetCheatAction::AddMoney(money32 amount) const +void SetCheatAction::AddMoney(money64 amount) const { - gCash = add_clamp_money32(gCash, amount); + gCash = add_clamp_money64(gCash, amount); window_invalidate_by_class(WindowClass::Finances); window_invalidate_by_class(WindowClass::BottomToolbar); diff --git a/src/openrct2/actions/SetCheatAction.h b/src/openrct2/actions/SetCheatAction.h index 81843be1ad..aa8ec22392 100644 --- a/src/openrct2/actions/SetCheatAction.h +++ b/src/openrct2/actions/SetCheatAction.h @@ -44,8 +44,8 @@ private: void ResetRideCrashStatus() const; void Set10MinuteInspection() const; void SetScenarioNoMoney(bool enabled) const; - void SetMoney(money32 amount) const; - void AddMoney(money32 amount) const; + void SetMoney(money64 amount) const; + void AddMoney(money64 amount) const; void ClearLoan() const; void GenerateGuests(int32_t count) const; void SetGuestParameter(int32_t parameter, int32_t value) const; diff --git a/src/openrct2/common.h b/src/openrct2/common.h index ea56c38499..60d9990d43 100644 --- a/src/openrct2/common.h +++ b/src/openrct2/common.h @@ -108,6 +108,11 @@ constexpr money32 ToMoney32FromGBP(double money) noexcept return money * 10; } +constexpr money64 ToMoney64FromGBP(double money) noexcept +{ + return money * 10; +} + #define MONEY16_UNDEFINED static_cast(static_cast(0xFFFF)) #define MONEY32_UNDEFINED (static_cast(0x80000000)) #define MONEY64_UNDEFINED (static_cast(0x8000000000000000)) diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index c0cd0bfd07..a449fd2707 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -762,7 +762,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) if (argv[0] == "money" && invalidArguments(&invalidArgs, double_valid[0])) { - money32 money = ToMoney32FromGBP(double_val[0]); + money32 money = ToMoney64FromGBP(double_val[0]); if (gCash != money) { auto setCheatAction = SetCheatAction(CheatType::SetMoney, money); @@ -796,7 +796,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) auto scenarioSetSetting = ScenarioSetSettingAction( ScenarioSetSetting::InitialLoan, std::clamp( - ToMoney32FromGBP(int_val[0]) - ToMoney32FromGBP(int_val[0] % 1000), 0.00_GBP, gMaxBankLoan)); + ToMoney64FromGBP(int_val[0]) - ToMoney64FromGBP(int_val[0] % 1000), 0.00_GBP, gMaxBankLoan)); scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) { if (res->Error != GameActions::Status::Ok) console.WriteLineError("set current_loan command failed, likely due to permissions."); diff --git a/src/openrct2/management/Finance.cpp b/src/openrct2/management/Finance.cpp index eda249249e..bab619fb57 100644 --- a/src/openrct2/management/Finance.cpp +++ b/src/openrct2/management/Finance.cpp @@ -73,7 +73,7 @@ bool finance_check_money_required(uint32_t flags) * @param cost. * @param flags game command flags. */ -bool finance_check_affordability(money32 cost, uint32_t flags) +bool finance_check_affordability(money64 cost, uint32_t flags) { return !finance_check_money_required(flags) || cost <= 0 || cost <= gCash; } @@ -84,10 +84,10 @@ bool finance_check_affordability(money32 cost, uint32_t flags) * @param amount (eax) * @param type passed via global var 0x0141F56C (RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE), our type is that var/4. */ -void finance_payment(money32 amount, ExpenditureType type) +void finance_payment(money64 amount, ExpenditureType type) { // overflow check - gCash = add_clamp_money32(gCash, -amount); + gCash = add_clamp_money64(gCash, -amount); gExpenditureTable[0][static_cast(type)] -= amount; if (dword_988E60[static_cast(type)] & 1) diff --git a/src/openrct2/management/Finance.h b/src/openrct2/management/Finance.h index 61f3a1a0ac..de26222090 100644 --- a/src/openrct2/management/Finance.h +++ b/src/openrct2/management/Finance.h @@ -60,8 +60,8 @@ extern money64 gParkValueHistory[FINANCE_GRAPH_SIZE]; extern money64 gExpenditureTable[EXPENDITURE_TABLE_MONTH_COUNT][static_cast(ExpenditureType::Count)]; bool finance_check_money_required(uint32_t flags); -bool finance_check_affordability(money32 cost, uint32_t flags); -void finance_payment(money32 amount, ExpenditureType type); +bool finance_check_affordability(money64 cost, uint32_t flags); +void finance_payment(money64 amount, ExpenditureType type); void finance_pay_wages(); void finance_pay_research(); void finance_pay_interest(); diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 00c4afb846..77d1d26e19 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -42,7 +42,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "20" +#define NETWORK_STREAM_VERSION "21" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr;