mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-22 06:23:04 +01:00
Change _GBP to money64, migrate a few usages to money64 as well
This commit is contained in:
committed by
GitHub
parent
438c0f642b
commit
18d9e72173
@@ -356,7 +356,7 @@ class CheatsWindow final : public Window
|
||||
{
|
||||
private:
|
||||
char _moneySpinnerText[MONEY_STRING_MAXLENGTH]{};
|
||||
money32 _moneySpinnerValue = CHEATS_MONEY_DEFAULT;
|
||||
money64 _moneySpinnerValue = CHEATS_MONEY_DEFAULT;
|
||||
int32_t _selectedStaffSpeed = 1;
|
||||
int32_t _parkRatingSpinnerValue{};
|
||||
int32_t _yearSpinnerValue = 1;
|
||||
@@ -589,7 +589,7 @@ public:
|
||||
if (page == WINDOW_CHEATS_PAGE_MONEY && widgetIndex == WIDX_MONEY_SPINNER)
|
||||
{
|
||||
auto val = string_to_money(std::string(text).c_str());
|
||||
if (val != MONEY32_UNDEFINED)
|
||||
if (val != MONEY64_UNDEFINED)
|
||||
{
|
||||
_moneySpinnerValue = val;
|
||||
}
|
||||
|
||||
@@ -6423,14 +6423,13 @@ static void WindowRideIncomeDecreasePrimaryPrice(rct_window* w)
|
||||
WindowRideIncomeSetPrimaryPrice(w, price);
|
||||
}
|
||||
|
||||
static money16 WindowRideIncomeGetSecondaryPrice(rct_window* w)
|
||||
static money64 WindowRideIncomeGetSecondaryPrice(rct_window* w)
|
||||
{
|
||||
auto ride = get_ride(w->rideId);
|
||||
if (ride == nullptr)
|
||||
return 0;
|
||||
|
||||
money16 price = ride->price[1];
|
||||
return price;
|
||||
return ride->price[1];
|
||||
}
|
||||
|
||||
static void WindowRideIncomeSetSecondaryPrice(rct_window* w, money16 price)
|
||||
@@ -6457,7 +6456,7 @@ static bool WindowRideIncomeCanModifyPrimaryPrice(rct_window* w)
|
||||
*/
|
||||
static void WindowRideIncomeIncreaseSecondaryPrice(rct_window* w)
|
||||
{
|
||||
money16 price = WindowRideIncomeGetSecondaryPrice(w);
|
||||
auto price = WindowRideIncomeGetSecondaryPrice(w);
|
||||
|
||||
if (price < 20.00_GBP)
|
||||
price++;
|
||||
@@ -6471,7 +6470,7 @@ static void WindowRideIncomeIncreaseSecondaryPrice(rct_window* w)
|
||||
*/
|
||||
static void WindowRideIncomeDecreaseSecondaryPrice(rct_window* w)
|
||||
{
|
||||
money16 price = WindowRideIncomeGetSecondaryPrice(w);
|
||||
auto price = WindowRideIncomeGetSecondaryPrice(w);
|
||||
|
||||
if (price > 0.00_GBP)
|
||||
price--;
|
||||
@@ -6510,7 +6509,7 @@ static void WindowRideIncomeMouseup(rct_window* w, WidgetIndex widgetIndex)
|
||||
auto ride = get_ride(w->rideId);
|
||||
if (ride != nullptr)
|
||||
{
|
||||
money_to_string(static_cast<money32>(ride->price[0]), _moneyInputText, MONEY_STRING_MAXLENGTH, true);
|
||||
money_to_string(static_cast<money64>(ride->price[0]), _moneyInputText, MONEY_STRING_MAXLENGTH, true);
|
||||
WindowTextInputRawOpen(
|
||||
w, WIDX_PRIMARY_PRICE, STR_ENTER_NEW_VALUE, STR_ENTER_NEW_VALUE, {}, _moneyInputText,
|
||||
MONEY_STRING_MAXLENGTH);
|
||||
@@ -6522,9 +6521,9 @@ static void WindowRideIncomeMouseup(rct_window* w, WidgetIndex widgetIndex)
|
||||
break;
|
||||
case WIDX_SECONDARY_PRICE:
|
||||
{
|
||||
money32 price32 = static_cast<money32>(WindowRideIncomeGetSecondaryPrice(w));
|
||||
auto price64 = WindowRideIncomeGetSecondaryPrice(w);
|
||||
|
||||
money_to_string(price32, _moneyInputText, MONEY_STRING_MAXLENGTH, true);
|
||||
money_to_string(price64, _moneyInputText, MONEY_STRING_MAXLENGTH, true);
|
||||
WindowTextInputRawOpen(
|
||||
w, WIDX_SECONDARY_PRICE, STR_ENTER_NEW_VALUE, STR_ENTER_NEW_VALUE, {}, _moneyInputText, MONEY_STRING_MAXLENGTH);
|
||||
}
|
||||
@@ -6590,8 +6589,8 @@ static void WindowRideIncomeTextinput(rct_window* w, WidgetIndex widgetIndex, ch
|
||||
if ((widgetIndex != WIDX_PRIMARY_PRICE && widgetIndex != WIDX_SECONDARY_PRICE) || text == nullptr)
|
||||
return;
|
||||
|
||||
money32 price = string_to_money(text);
|
||||
if (price == MONEY32_UNDEFINED)
|
||||
money64 price = string_to_money(text);
|
||||
if (price == MONEY64_UNDEFINED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,18 +92,17 @@ using money64 = fixed64_1dp;
|
||||
#define FIXED_1DP(whole, fraction) FIXED_XDP(1, whole, fraction)
|
||||
#define FIXED_2DP(whole, fraction) FIXED_XDP(10, whole, fraction)
|
||||
|
||||
// User defined literal to convert money literal to money32
|
||||
constexpr money32 operator"" _GBP(long double money) noexcept
|
||||
constexpr money64 operator"" _GBP(long double money) noexcept
|
||||
{
|
||||
return money * 10;
|
||||
}
|
||||
|
||||
constexpr money32 ToMoney32FromGBP(int32_t money) noexcept
|
||||
constexpr money64 ToMoney64FromGBP(int32_t money) noexcept
|
||||
{
|
||||
return money * 10;
|
||||
}
|
||||
|
||||
constexpr money32 ToMoney32FromGBP(double money) noexcept
|
||||
constexpr money64 ToMoney64FromGBP(int64_t money) noexcept
|
||||
{
|
||||
return money * 10;
|
||||
}
|
||||
@@ -127,16 +126,6 @@ constexpr money64 ToMoney64(money16 value)
|
||||
return value == MONEY16_UNDEFINED ? MONEY64_UNDEFINED : value;
|
||||
}
|
||||
|
||||
constexpr money32 ToMoney32(money64 value)
|
||||
{
|
||||
return value == MONEY64_UNDEFINED ? MONEY32_UNDEFINED : static_cast<money32>(value);
|
||||
}
|
||||
|
||||
constexpr money16 ToMoney16(money64 value)
|
||||
{
|
||||
return value == MONEY64_UNDEFINED ? MONEY16_UNDEFINED : static_cast<money16>(value);
|
||||
}
|
||||
|
||||
using StringId = uint16_t;
|
||||
|
||||
#define SafeFree(x) \
|
||||
|
||||
@@ -781,7 +781,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
|
||||
else if (argv[0] == "scenario_initial_cash" && invalidArguments(&invalidArgs, int_valid[0]))
|
||||
{
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(
|
||||
ScenarioSetSetting::InitialCash, std::clamp(ToMoney32FromGBP(int_val[0]), 0.00_GBP, 1000000.00_GBP));
|
||||
ScenarioSetSetting::InitialCash, std::clamp(ToMoney64FromGBP(int_val[0]), 0.00_GBP, 1000000.00_GBP));
|
||||
scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) {
|
||||
if (res->Error != GameActions::Status::Ok)
|
||||
console.WriteLineError("set scenario_initial_cash command failed, likely due to permissions.");
|
||||
@@ -792,10 +792,9 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
|
||||
}
|
||||
else if (argv[0] == "current_loan" && invalidArguments(&invalidArgs, int_valid[0]))
|
||||
{
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(
|
||||
ScenarioSetSetting::InitialLoan,
|
||||
std::clamp<money64>(
|
||||
ToMoney64FromGBP(int_val[0]) - ToMoney64FromGBP(int_val[0] % 1000), 0.00_GBP, gMaxBankLoan));
|
||||
auto amount = std::clamp(
|
||||
ToMoney64FromGBP(int_val[0]) - ToMoney64FromGBP(int_val[0] % 1000), 0.00_GBP, gMaxBankLoan);
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::InitialLoan, amount);
|
||||
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.");
|
||||
@@ -806,9 +805,9 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
|
||||
}
|
||||
else if (argv[0] == "max_loan" && invalidArguments(&invalidArgs, int_valid[0]))
|
||||
{
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(
|
||||
ScenarioSetSetting::MaximumLoanSize,
|
||||
std::clamp(ToMoney32FromGBP(int_val[0]) - ToMoney32FromGBP(int_val[0] % 1000), 0.00_GBP, 5000000.00_GBP));
|
||||
auto amount = std::clamp(
|
||||
ToMoney64FromGBP(int_val[0]) - ToMoney64FromGBP(int_val[0] % 1000), 0.00_GBP, 5000000.00_GBP);
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::MaximumLoanSize, amount);
|
||||
scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) {
|
||||
if (res->Error != GameActions::Status::Ok)
|
||||
console.WriteLineError("set max_loan command failed, likely due to permissions.");
|
||||
@@ -820,7 +819,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
|
||||
else if (argv[0] == "guest_initial_cash" && invalidArguments(&invalidArgs, double_valid[0]))
|
||||
{
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(
|
||||
ScenarioSetSetting::AverageCashPerGuest, std::clamp(ToMoney32FromGBP(double_val[0]), 0.00_GBP, 1000.00_GBP));
|
||||
ScenarioSetSetting::AverageCashPerGuest, std::clamp(ToMoney64FromGBP(double_val[0]), 0.00_GBP, 1000.00_GBP));
|
||||
scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) {
|
||||
if (res->Error != GameActions::Status::Ok)
|
||||
console.WriteLineError("set guest_initial_cash command failed, likely due to permissions.");
|
||||
@@ -984,7 +983,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
|
||||
else if (argv[0] == "land_rights_cost" && invalidArguments(&invalidArgs, double_valid[0]))
|
||||
{
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(
|
||||
ScenarioSetSetting::CostToBuyLand, std::clamp(ToMoney32FromGBP(double_val[0]), 0.00_GBP, 200.00_GBP));
|
||||
ScenarioSetSetting::CostToBuyLand, std::clamp(ToMoney64FromGBP(double_val[0]), 0.00_GBP, 200.00_GBP));
|
||||
scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) {
|
||||
if (res->Error != GameActions::Status::Ok)
|
||||
console.WriteLineError("set land_rights_cost command failed, likely due to permissions.");
|
||||
@@ -997,7 +996,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
|
||||
{
|
||||
auto scenarioSetSetting = ScenarioSetSettingAction(
|
||||
ScenarioSetSetting::CostToBuyConstructionRights,
|
||||
std::clamp(ToMoney32FromGBP(double_val[0]), 0.00_GBP, 200.00_GBP));
|
||||
std::clamp(ToMoney64FromGBP(double_val[0]), 0.00_GBP, 200.00_GBP));
|
||||
scenarioSetSetting.SetCallback([&console](const GameAction*, const GameActions::Result* res) {
|
||||
if (res->Error != GameActions::Status::Ok)
|
||||
console.WriteLineError("set construction_rights_cost command failed, likely due to permissions.");
|
||||
|
||||
@@ -421,7 +421,7 @@ void format_readable_speed(char* buf, size_t bufSize, uint64_t sizeBytes)
|
||||
format_string(buf, bufSize, STR_NETWORK_SPEED_SEC, args);
|
||||
}
|
||||
|
||||
money32 string_to_money(const char* string_to_monetise)
|
||||
money64 string_to_money(const char* string_to_monetise)
|
||||
{
|
||||
const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
const currency_descriptor* currencyDesc = &CurrencyDescriptors[EnumValue(gConfigGeneral.CurrencyFormat)];
|
||||
@@ -445,7 +445,7 @@ money32 string_to_money(const char* string_to_monetise)
|
||||
else if (*src_ptr == decimal_char[0])
|
||||
{
|
||||
if (hasDecSep)
|
||||
return MONEY32_UNDEFINED;
|
||||
return MONEY64_UNDEFINED;
|
||||
hasDecSep = true;
|
||||
|
||||
// Replace localised decimal separator with an English one.
|
||||
@@ -456,7 +456,7 @@ money32 string_to_money(const char* string_to_monetise)
|
||||
else if (*src_ptr == '-')
|
||||
{
|
||||
if (hasMinus)
|
||||
return MONEY32_UNDEFINED;
|
||||
return MONEY64_UNDEFINED;
|
||||
hasMinus = true;
|
||||
}
|
||||
else
|
||||
@@ -475,16 +475,16 @@ money32 string_to_money(const char* string_to_monetise)
|
||||
*dst_ptr = '\0';
|
||||
|
||||
if (numNumbers == 0)
|
||||
return MONEY32_UNDEFINED;
|
||||
return MONEY64_UNDEFINED;
|
||||
|
||||
int32_t sign = 1;
|
||||
int64_t sign = 1;
|
||||
if (hasMinus)
|
||||
{
|
||||
// If there is a minus sign, it has to be at position 0 in order to be valid.
|
||||
if (processedString[0] == '-')
|
||||
sign = -1;
|
||||
else
|
||||
return MONEY32_UNDEFINED;
|
||||
return MONEY64_UNDEFINED;
|
||||
}
|
||||
|
||||
// Due to the nature of strstr and strtok, decimals at the very beginning will be ignored, causing
|
||||
@@ -499,10 +499,7 @@ money32 string_to_money(const char* string_to_monetise)
|
||||
auto number = std::stod(processedString, nullptr);
|
||||
number /= (currencyDesc->rate / 10.0);
|
||||
|
||||
// Check if MONEY resulted in overflow
|
||||
uint64_t result = std::min<uint64_t>(ToMoney32FromGBP(number), (std::numeric_limits<uint32_t>::max)());
|
||||
result *= sign;
|
||||
return static_cast<uint32_t>(result);
|
||||
return ToMoney64FromGBP(number) * sign;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -513,39 +510,40 @@ money32 string_to_money(const char* string_to_monetise)
|
||||
* @param forceDecimals Show decimals, even if the amount does not have them. Will be ignored if the current exchange
|
||||
* rate is too big to have decimals.
|
||||
*/
|
||||
void money_to_string(money32 amount, char* buffer_to_put_value_to, size_t buffer_len, bool forceDecimals)
|
||||
void money_to_string(money64 amount, char* buffer_to_put_value_to, size_t buffer_len, bool forceDecimals)
|
||||
{
|
||||
if (amount == MONEY32_UNDEFINED)
|
||||
if (amount == MONEY64_UNDEFINED)
|
||||
{
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "0");
|
||||
return;
|
||||
}
|
||||
|
||||
const currency_descriptor* currencyDesc = &CurrencyDescriptors[EnumValue(gConfigGeneral.CurrencyFormat)];
|
||||
const currency_descriptor& currencyDesc = CurrencyDescriptors[EnumValue(gConfigGeneral.CurrencyFormat)];
|
||||
|
||||
int sign = amount >= 0 ? 1 : -1;
|
||||
int a = abs(amount) * currencyDesc->rate;
|
||||
const char* sign = amount >= 0 ? "" : "-";
|
||||
const uint64_t a = std::abs(amount) * currencyDesc.rate;
|
||||
const unsigned long long whole = a / 100;
|
||||
const unsigned long long decimal = a % 100;
|
||||
|
||||
bool amountIsInteger = (a / 100 > 0) && (a % 100 == 0);
|
||||
bool amountIsInteger = (whole > 0) && decimal == 0;
|
||||
|
||||
// If whole and decimal exist
|
||||
if ((a / 100 > 0 && a % 100 > 0) || (amountIsInteger && forceDecimals && currencyDesc->rate < 100))
|
||||
if ((whole > 0 && decimal > 0) || (amountIsInteger && forceDecimals && currencyDesc.rate < 100))
|
||||
{
|
||||
const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
auto decimalPart = a % 100;
|
||||
auto precedingZero = (decimalPart < 10) ? "0" : "";
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "%d%s%s%d", (a / 100) * sign, decimal_char, precedingZero, decimalPart);
|
||||
const char* decimalChar = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
auto precedingZero = (decimal < 10) ? "0" : "";
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "%s%llu%s%s%llu", sign, whole, decimalChar, precedingZero, decimal);
|
||||
}
|
||||
// If whole exists, but not decimal
|
||||
else if (amountIsInteger)
|
||||
{
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "%d", (a / 100) * sign);
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "%s%llu", sign, whole);
|
||||
}
|
||||
// If decimal exists, but not whole
|
||||
else if (a / 100 == 0 && a % 100 > 0)
|
||||
else if (whole == 0 && decimal > 0)
|
||||
{
|
||||
const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "%s0%s%d", sign < 0 ? "-" : "", decimal_char, a % 100);
|
||||
const char* decimalChar = language_get_string(STR_LOCALE_DECIMAL_POINT);
|
||||
snprintf(buffer_to_put_value_to, buffer_len, "%s0%s%llu", sign, decimalChar, decimal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -38,8 +38,8 @@ size_t get_string_size(const utf8* text);
|
||||
|
||||
// The maximum number of characters allowed for string/money conversions (anything above will risk integer overflow issues)
|
||||
#define MONEY_STRING_MAXLENGTH 14
|
||||
money32 string_to_money(const char* string_to_monetise);
|
||||
void money_to_string(money32 amount, char* buffer_to_put_value_to, size_t buffer_len, bool forceDecimals);
|
||||
money64 string_to_money(const char* string_to_monetise);
|
||||
void money_to_string(money64 amount, char* buffer_to_put_value_to, size_t buffer_len, bool forceDecimals);
|
||||
|
||||
bool is_user_string_id(StringId stringId);
|
||||
|
||||
|
||||
@@ -500,7 +500,7 @@ money64 Park::CalculateRideValue(const Ride& ride) const
|
||||
if (ride.value != RIDE_VALUE_UNDEFINED)
|
||||
{
|
||||
const auto& rtd = ride.GetRideTypeDescriptor();
|
||||
result = ToMoney32FromGBP(static_cast<int32_t>(ride.value))
|
||||
result = ToMoney64FromGBP(ride.value)
|
||||
* (static_cast<money64>(ride_customers_in_last_5_minutes(ride)) + rtd.BonusValue * 4LL);
|
||||
}
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user