1
0
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:
Michael Steenbeek
2023-01-08 15:10:22 +01:00
committed by GitHub
parent 438c0f642b
commit 18d9e72173
7 changed files with 50 additions and 65 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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) \

View File

@@ -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.");

View File

@@ -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
{

View File

@@ -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);

View File

@@ -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;