Change most things and formatting to money64

This commit is contained in:
Ted John 2021-04-10 16:00:50 +01:00 committed by Gymnasiast
parent 9ba19689d7
commit 70d9c1438e
No known key found for this signature in database
GPG Key ID: DBFFF47AB2CA3EDD
45 changed files with 264 additions and 214 deletions

View File

@ -104,7 +104,7 @@ namespace Graph
struct FinancialTooltipInfo
{
const ScreenCoordsXY coords;
const money32 money{};
const money64 money{};
};
static constexpr auto ChartMaxDataCount = 64;
@ -122,21 +122,22 @@ static int32_t IndexForCursorAndHistory(const int32_t historyCount, const int32_
}
static const ScreenCoordsXY ScreenCoordsForHistoryIndex(
const int32_t index, const money32* history, const int32_t chartX, const int32_t chartY, const int32_t modifier,
const int32_t index, const money64* history, const int32_t chartX, const int32_t chartY, const int32_t modifier,
const int32_t offset)
{
auto coords = ScreenCoordsXY{ chartX + ChartDataWidth * (ChartMaxIndex - index),
chartY + ChartMaxHeight - ((((history[index] >> modifier) + offset) * 170) / 256) };
chartY + ChartMaxHeight
- (((static_cast<int32_t>(history[index] >> modifier) + offset) * 170) / 256) };
return coords;
}
static const FinancialTooltipInfo finance_tooltip_info_from_money(
const money32* history, const int32_t historyCount, const int32_t modifier, const int32_t offset,
const money64* history, const int32_t historyCount, const int32_t modifier, const int32_t offset,
const ScreenRect& chartFrame, const ScreenCoordsXY& cursorPosition)
{
if (!chartFrame.Contains(cursorPosition))
{
return { {}, MONEY32_UNDEFINED };
return { {}, MONEY64_UNDEFINED };
}
const auto historyIndex = IndexForCursorAndHistory(historyCount, cursorPosition.x, chartFrame.GetLeft());
@ -148,7 +149,7 @@ static const FinancialTooltipInfo finance_tooltip_info_from_money(
namespace Graph
{
static void DrawMonths(rct_drawpixelinfo* dpi, const money32* history, int32_t count, const ScreenCoordsXY& origCoords)
static void DrawMonths(rct_drawpixelinfo* dpi, const money64* history, int32_t count, const ScreenCoordsXY& origCoords)
{
int32_t i, yearOver32, currentMonth, currentDay;
@ -158,7 +159,7 @@ namespace Graph
auto screenCoords = origCoords;
for (i = count - 1; i >= 0; i--)
{
if (history[i] != MONEY32_UNDEFINED && yearOver32 % 4 == 0)
if (history[i] != MONEY64_UNDEFINED && yearOver32 % 4 == 0)
{
// Draw month text
int32_t monthFormat = DateGameShortMonthNames[date_get_month((yearOver32 / 4) + MONTH_COUNT)];
@ -176,14 +177,14 @@ namespace Graph
}
static void DrawLineA(
rct_drawpixelinfo* dpi, const money32* history, int32_t count, const ScreenCoordsXY& origCoords, int32_t modifier,
rct_drawpixelinfo* dpi, const money64* history, int32_t count, const ScreenCoordsXY& origCoords, int32_t modifier,
int32_t offset)
{
auto lastCoords = ScreenCoordsXY{ -1, -1 };
auto coords = origCoords;
for (int32_t i = count - 1; i >= 0; i--)
{
if (history[i] != MONEY32_UNDEFINED)
if (history[i] != MONEY64_UNDEFINED)
{
coords.y = origCoords.y + 170 - 6 - ((((history[i] >> modifier) + offset) * 170) / 256);
@ -206,14 +207,14 @@ namespace Graph
}
static void DrawLineB(
rct_drawpixelinfo* dpi, const money32* history, int32_t count, const ScreenCoordsXY& origCoords, int32_t modifier,
rct_drawpixelinfo* dpi, const money64* history, int32_t count, const ScreenCoordsXY& origCoords, int32_t modifier,
int32_t offset)
{
auto lastCoords = ScreenCoordsXY{ -1, -1 };
auto coords = origCoords;
for (int32_t i = count - 1; i >= 0; i--)
{
if (history[i] != MONEY32_UNDEFINED)
if (history[i] != MONEY64_UNDEFINED)
{
coords.y = origCoords.y + 170 - 6 - ((((history[i] >> modifier) + offset) * 170) / 256);
@ -233,7 +234,7 @@ namespace Graph
}
static void DrawHoveredValue(
rct_drawpixelinfo* dpi, const money32* history, const int32_t historyCount, const ScreenCoordsXY& screenCoords,
rct_drawpixelinfo* dpi, const money64* history, const int32_t historyCount, const ScreenCoordsXY& screenCoords,
const int32_t modifier, const int32_t offset)
{
const auto cursorPosition = context_get_cursor_position_scaled();
@ -247,7 +248,7 @@ namespace Graph
const auto info = finance_tooltip_info_from_money(
history, ChartMaxDataCount, modifier, offset, chartFrame, cursorPosition);
if (info.money == MONEY32_UNDEFINED)
if (info.money == MONEY64_UNDEFINED)
{
return;
}
@ -270,7 +271,7 @@ namespace Graph
}
void Draw(
rct_drawpixelinfo* dpi, const money32* history, const int32_t count, const ScreenCoordsXY& screenCoords,
rct_drawpixelinfo* dpi, const money64* history, const int32_t count, const ScreenCoordsXY& screenCoords,
const int32_t modifier, const int32_t offset)
{
DrawMonths(dpi, history, count, screenCoords);

View File

@ -18,7 +18,7 @@ namespace Graph
{
void Draw(rct_drawpixelinfo* dpi, uint8_t* history, int32_t count, const ScreenCoordsXY& screenPos);
void Draw(
rct_drawpixelinfo* dpi, const money32* history, const int32_t count, const ScreenCoordsXY& coords,
rct_drawpixelinfo* dpi, const money64* history, const int32_t count, const ScreenCoordsXY& coords,
const int32_t modifier, const int32_t offset);
} // namespace Graph

View File

@ -616,7 +616,7 @@ public:
{
auto colour = colours[1];
auto ft = Formatter();
ft.Add<money32>(_moneySpinnerValue);
ft.Add<money64>(_moneySpinnerValue);
if (IsWidgetDisabled(WIDX_MONEY_SPINNER))
{
colour |= COLOUR_FLAG_INSET;

View File

@ -167,7 +167,7 @@ static void window_ride_demolish_paint(rct_window* w, rct_drawpixelinfo* dpi)
auto stringId = (gParkFlags & PARK_FLAGS_NO_MONEY) ? STR_DEMOLISH_RIDE_ID : STR_DEMOLISH_RIDE_ID_MONEY;
auto ft = Formatter();
ride->FormatNameTo(ft);
ft.Add<money32>(_demolishRideCost);
ft.Add<money64>(_demolishRideCost);
ScreenCoordsXY stringCoords(w->windowPos.x + WW / 2, w->windowPos.y + (WH / 2) - 3);
DrawTextWrapped(dpi, stringCoords, WW - 4, stringId, ft, { TextAlignment::CENTRE });
@ -184,7 +184,7 @@ static void window_ride_refurbish_paint(rct_window* w, rct_drawpixelinfo* dpi)
auto stringId = (gParkFlags & PARK_FLAGS_NO_MONEY) ? STR_REFURBISH_RIDE_ID_NO_MONEY : STR_REFURBISH_RIDE_ID_MONEY;
auto ft = Formatter();
ride->FormatNameTo(ft);
ft.Add<money32>(_demolishRideCost / 2);
ft.Add<money64>(_demolishRideCost / 2);
ScreenCoordsXY stringCoords(w->windowPos.x + WW / 2, w->windowPos.y + (WH / 2) - 3);
DrawTextWrapped(dpi, stringCoords, WW - 4, stringId, ft, { TextAlignment::CENTRE });

View File

@ -515,7 +515,7 @@ static void window_finances_summary_invalidate(rct_window* w)
window_finances_set_pressed_tab(w);
auto ft = Formatter::Common();
ft.Increment(6);
ft.Add<money32>(gBankLoan);
ft.Add<money64>(gBankLoan);
}
/**
@ -566,9 +566,9 @@ static void window_finances_summary_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Objective related financial information
if (gScenarioObjective.Type == OBJECTIVE_MONTHLY_FOOD_INCOME)
{
money32 lastMonthProfit = finance_get_last_month_shop_profit();
auto lastMonthProfit = finance_get_last_month_shop_profit();
ft = Formatter();
ft.Add<money32>(lastMonthProfit);
ft.Add<money64>(lastMonthProfit);
DrawTextBasic(
dpi, w->windowPos + ScreenCoordsXY{ 280, 279 }, STR_LAST_MONTH_PROFIT_FROM_FOOD_DRINK_MERCHANDISE_SALES_LABEL, ft);
}
@ -621,17 +621,17 @@ static void window_finances_summary_scrollpaint(rct_window* w, rct_drawpixelinfo
screenCoords.y += 14;
// Month expenditures
money32 profit = 0;
money64 profit = 0;
for (int32_t j = 0; j < static_cast<int32_t>(ExpenditureType::Count); j++)
{
money32 expenditure = gExpenditureTable[i][j];
auto expenditure = gExpenditureTable[i][j];
if (expenditure != 0)
{
profit += expenditure;
const rct_string_id format = expenditure >= 0 ? STR_FINANCES_SUMMARY_INCOME_VALUE
: STR_FINANCES_SUMMARY_EXPENDITURE_VALUE;
ft = Formatter();
ft.Add<money32>(expenditure);
ft.Add<money64>(expenditure);
DrawTextBasic(
dpi, screenCoords + ScreenCoordsXY{ EXPENDITURE_COLUMN_WIDTH, 0 }, format, ft, { TextAlignment::RIGHT });
}
@ -642,7 +642,7 @@ static void window_finances_summary_scrollpaint(rct_window* w, rct_drawpixelinfo
// Month profit
const rct_string_id format = profit >= 0 ? STR_FINANCES_SUMMARY_INCOME_VALUE : STR_FINANCES_SUMMARY_LOSS_VALUE;
ft = Formatter();
ft.Add<money32>(profit);
ft.Add<money64>(profit);
DrawTextBasic(dpi, screenCoords + ScreenCoordsXY{ EXPENDITURE_COLUMN_WIDTH, 0 }, format, ft, { TextAlignment::RIGHT });
gfx_fill_rect(
@ -713,7 +713,7 @@ static void window_finances_financial_graph_paint(rct_window* w, rct_drawpixelin
auto graphBottomRight = w->windowPos + ScreenCoordsXY{ pageWidget->right - 4, pageWidget->bottom - 4 };
// Cash (less loan)
money32 cashLessLoan = gCash - gBankLoan;
auto cashLessLoan = gCash - gBankLoan;
DrawTextBasic(
dpi, graphTopLeft - ScreenCoordsXY{ 0, 11 },
@ -728,8 +728,8 @@ static void window_finances_financial_graph_paint(rct_window* w, rct_drawpixelin
int32_t yAxisScale = 0;
for (int32_t i = 0; i < 64; i++)
{
money32 balance = gCashHistory[i];
if (balance == MONEY32_UNDEFINED)
auto balance = gCashHistory[i];
if (balance == MONEY64_UNDEFINED)
continue;
// Modifier balance then keep halving until less than 127 pixels
@ -743,12 +743,12 @@ static void window_finances_financial_graph_paint(rct_window* w, rct_drawpixelin
// Y axis labels
auto coords = graphTopLeft + ScreenCoordsXY{ 18, 14 };
money32 axisBase;
money64 axisBase;
for (axisBase = MONEY(12, 00); axisBase >= MONEY(-12, 00); axisBase -= MONEY(6, 00))
{
money32 axisValue = axisBase << yAxisScale;
auto axisValue = axisBase << yAxisScale;
auto ft = Formatter();
ft.Add<money32>(axisValue);
ft.Add<money64>(axisValue);
DrawTextBasic(
dpi, coords + ScreenCoordsXY{ 70, 0 }, STR_FINANCES_FINANCIAL_GRAPH_CASH_VALUE, ft,
{ FontSpriteBase::SMALL, TextAlignment::RIGHT });
@ -821,7 +821,7 @@ static void window_finances_park_value_graph_paint(rct_window* w, rct_drawpixeli
auto graphBottomRight = w->windowPos + ScreenCoordsXY{ pageWidget->right - 4, pageWidget->bottom - 4 };
// Park value
money32 parkValue = gParkValue;
auto parkValue = gParkValue;
DrawTextBasic(dpi, graphTopLeft - ScreenCoordsXY{ 0, 11 }, STR_FINANCES_PARK_VALUE, &parkValue);
// Graph
@ -831,8 +831,8 @@ static void window_finances_park_value_graph_paint(rct_window* w, rct_drawpixeli
int32_t yAxisScale = 0;
for (int32_t i = 0; i < 64; i++)
{
money32 balance = gParkValueHistory[i];
if (balance == MONEY32_UNDEFINED)
auto balance = gParkValueHistory[i];
if (balance == MONEY64_UNDEFINED)
continue;
// Modifier balance then keep halving until less than 255 pixels
@ -846,12 +846,12 @@ static void window_finances_park_value_graph_paint(rct_window* w, rct_drawpixeli
// Y axis labels
auto coords = graphTopLeft + ScreenCoordsXY{ 18, 14 };
money32 axisBase;
money64 axisBase;
for (axisBase = MONEY(24, 00); axisBase >= MONEY(0, 00); axisBase -= MONEY(6, 00))
{
money32 axisValue = axisBase << yAxisScale;
auto axisValue = axisBase << yAxisScale;
auto ft = Formatter();
ft.Add<money32>(axisValue);
ft.Add<money64>(axisValue);
DrawTextBasic(
dpi, coords + ScreenCoordsXY{ 70, 0 }, STR_FINANCES_FINANCIAL_GRAPH_CASH_VALUE, ft,
{ FontSpriteBase::SMALL, TextAlignment::RIGHT });
@ -923,7 +923,7 @@ static void window_finances_profit_graph_paint(rct_window* w, rct_drawpixelinfo*
auto graphBottomRight = w->windowPos + ScreenCoordsXY{ pageWidget->right - 4, pageWidget->bottom - 4 };
// Weekly profit
money32 weeklyPofit = gCurrentProfit;
auto weeklyPofit = gCurrentProfit;
DrawTextBasic(
dpi, graphTopLeft - ScreenCoordsXY{ 0, 11 },
weeklyPofit >= 0 ? STR_FINANCES_WEEKLY_PROFIT_POSITIVE : STR_FINANCES_WEEKLY_PROFIT_LOSS, &weeklyPofit);
@ -935,8 +935,8 @@ static void window_finances_profit_graph_paint(rct_window* w, rct_drawpixelinfo*
int32_t yAxisScale = 0;
for (int32_t i = 0; i < 64; i++)
{
money32 balance = gWeeklyProfitHistory[i];
if (balance == MONEY32_UNDEFINED)
auto balance = gWeeklyProfitHistory[i];
if (balance == MONEY64_UNDEFINED)
continue;
// Modifier balance then keep halving until less than 127 pixels
@ -950,12 +950,12 @@ static void window_finances_profit_graph_paint(rct_window* w, rct_drawpixelinfo*
// Y axis labels
auto screenPos = graphTopLeft + ScreenCoordsXY{ 18, 14 };
money32 axisBase;
money64 axisBase;
for (axisBase = MONEY(12, 00); axisBase >= MONEY(-12, 00); axisBase -= MONEY(6, 00))
{
money32 axisValue = axisBase << yAxisScale;
money64 axisValue = axisBase << yAxisScale;
auto ft = Formatter();
ft.Add<money32>(axisValue);
ft.Add<money64>(axisValue);
DrawTextBasic(
dpi, screenPos + ScreenCoordsXY{ 70, 0 }, STR_FINANCES_FINANCIAL_GRAPH_CASH_VALUE, ft,
{ FontSpriteBase::SMALL, TextAlignment::RIGHT });
@ -1117,7 +1117,7 @@ static void window_finances_marketing_paint(rct_window* w, rct_drawpixelinfo* dp
if (campaignButton->type != WindowWidgetType::Empty)
{
// Draw button text
money32 pricePerWeek = AdvertisingCampaignPricePerWeek[i];
money64 pricePerWeek = AdvertisingCampaignPricePerWeek[i];
DrawTextBasic(dpi, screenCoords + ScreenCoordsXY{ 4, 0 }, MarketingCampaignNames[i][0]);
DrawTextBasic(dpi, screenCoords + ScreenCoordsXY{ WH_SUMMARY, 0 }, STR_MARKETING_PER_WEEK, &pricePerWeek);

View File

@ -633,7 +633,8 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
{
DrawTextBasic(dpi, screenCoords, STR_COST_LABEL, &_window_footpath_cost, { TextAlignment::CENTRE });
money64 cost = _window_footpath_cost;
DrawTextBasic(dpi, screenCoords, STR_COST_LABEL, &cost, { TextAlignment::CENTRE });
}
}
}

View File

@ -414,7 +414,7 @@ static void window_game_bottom_toolbar_draw_left_panel(rct_drawpixelinfo* dpi, r
: NOT_TRANSLUCENT(w->colours[0]));
rct_string_id stringId = gCash < 0 ? STR_BOTTOM_TOOLBAR_CASH_NEGATIVE : STR_BOTTOM_TOOLBAR_CASH;
auto ft = Formatter();
ft.Add<money32>(gCash);
ft.Add<money64>(gCash);
DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE });
}

View File

@ -1657,7 +1657,7 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Cash in pocket
{
auto ft = Formatter();
ft.Add<money32>(peep->CashInPocket);
ft.Add<money64>(peep->CashInPocket);
DrawTextBasic(dpi, screenCoords, STR_GUEST_STAT_CASH_IN_POCKET, ft);
screenCoords.y += LIST_ROW_HEIGHT;
}
@ -1665,7 +1665,7 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Cash spent
{
auto ft = Formatter();
ft.Add<money32>(peep->CashSpent);
ft.Add<money64>(peep->CashSpent);
DrawTextBasic(dpi, screenCoords, STR_GUEST_STAT_CASH_SPENT, ft);
screenCoords.y += LIST_ROW_HEIGHT * 2;
}
@ -1677,14 +1677,14 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Paid to enter
{
auto ft = Formatter();
ft.Add<money32>(peep->PaidToEnter);
ft.Add<money64>(peep->PaidToEnter);
DrawTextBasic(dpi, screenCoords, STR_GUEST_EXPENSES_ENTRANCE_FEE, ft);
screenCoords.y += LIST_ROW_HEIGHT;
}
// Paid on rides
{
auto ft = Formatter();
ft.Add<money32>(peep->PaidOnRides);
ft.Add<money64>(peep->PaidOnRides);
ft.Add<uint16_t>(peep->GuestNumRides);
if (peep->GuestNumRides != 1)
{
@ -1699,7 +1699,7 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Paid on food
{
auto ft = Formatter();
ft.Add<money32>(peep->PaidOnFood);
ft.Add<money64>(peep->PaidOnFood);
ft.Add<uint16_t>(peep->AmountOfFood);
if (peep->AmountOfFood != 1)
{
@ -1715,7 +1715,7 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Paid on drinks
{
auto ft = Formatter();
ft.Add<money32>(peep->PaidOnDrink);
ft.Add<money64>(peep->PaidOnDrink);
ft.Add<uint16_t>(peep->AmountOfDrinks);
if (peep->AmountOfDrinks != 1)
{
@ -1730,7 +1730,7 @@ void window_guest_finance_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Paid on souvenirs
{
auto ft = Formatter();
ft.Add<money32>(peep->PaidOnSouvenirs);
ft.Add<money64>(peep->PaidOnSouvenirs);
ft.Add<uint16_t>(peep->AmountOfSouvenirs);
if (peep->AmountOfSouvenirs != 1)
{

View File

@ -256,7 +256,7 @@ public:
{
ScreenCoordsXY screenCoords;
int32_t numTiles;
money32 price;
money64 price;
rct_widget* previewWidget = &widgets[WIDX_PREVIEW];
DrawWidgets(dpi);
@ -284,12 +284,18 @@ public:
{
// Draw raise cost amount
if (gLandToolRaiseCost != MONEY32_UNDEFINED && gLandToolRaiseCost != 0)
DrawTextBasic(&dpi, screenCoords, STR_RAISE_COST_AMOUNT, &gLandToolRaiseCost, { TextAlignment::CENTRE });
{
price = gLandToolRaiseCost;
DrawTextBasic(&dpi, screenCoords, STR_RAISE_COST_AMOUNT, &price, { TextAlignment::CENTRE });
}
screenCoords.y += 10;
// Draw lower cost amount
if (gLandToolLowerCost != MONEY32_UNDEFINED && gLandToolLowerCost != 0)
DrawTextBasic(&dpi, screenCoords, STR_LOWER_COST_AMOUNT, &gLandToolLowerCost, { TextAlignment::CENTRE });
{
price = gLandToolLowerCost;
DrawTextBasic(&dpi, screenCoords, STR_LOWER_COST_AMOUNT, &price, { TextAlignment::CENTRE });
}
screenCoords.y += 50;
// Draw paint price
@ -302,17 +308,17 @@ public:
objManager.GetLoadedObject(ObjectType::TerrainSurface, gLandToolTerrainSurface));
if (surfaceObj != nullptr)
{
price += numTiles * surfaceObj->Price;
price += numTiles * static_cast<money64>(surfaceObj->Price);
}
}
if (gLandToolTerrainEdge != OBJECT_ENTRY_INDEX_NULL)
price += numTiles * 100;
price += numTiles * 100LL;
if (price != 0)
{
auto ft = Formatter();
ft.Add<money32>(price);
ft.Add<money64>(price);
DrawTextBasic(&dpi, screenCoords, STR_COST_AMOUNT, ft.Data(), { TextAlignment::CENTRE });
}
}

View File

@ -353,12 +353,12 @@ public:
screenCoords = windowPos + ScreenCoordsXY{ 14, 60 };
// Price per week
money32 pricePerWeek = AdvertisingCampaignPricePerWeek[campaign.campaign_type];
money64 pricePerWeek = AdvertisingCampaignPricePerWeek[campaign.campaign_type];
DrawTextBasic(&dpi, screenCoords, STR_MARKETING_COST_PER_WEEK, &pricePerWeek);
screenCoords.y += 13;
// Total price
money32 totalPrice = AdvertisingCampaignPricePerWeek[campaign.campaign_type] * campaign.no_weeks;
money64 totalPrice = AdvertisingCampaignPricePerWeek[campaign.campaign_type] * campaign.no_weeks;
DrawTextBasic(&dpi, screenCoords, STR_MARKETING_TOTAL_COST, &totalPrice);
}
};

View File

@ -942,7 +942,7 @@ static void window_new_ride_paint_ride_information(
{
// Get price of ride
int32_t unk2 = GetRideTypeDescriptor(item.Type).StartTrackPiece;
money32 price = GetRideTypeDescriptor(item.Type).BuildCosts.TrackPrice;
money64 price = GetRideTypeDescriptor(item.Type).BuildCosts.TrackPrice;
price *= TrackPricing[unk2];
price = (price >> 17) * 10 * GetRideTypeDescriptor(item.Type).BuildCosts.PriceEstimateMultiplier;
@ -952,7 +952,7 @@ static void window_new_ride_paint_ride_information(
stringId = STR_NEW_RIDE_COST_FROM;
ft = Formatter();
ft.Add<money32>(price);
ft.Add<money64>(price);
DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ width, 51 }, stringId, ft, { TextAlignment::RIGHT });
}
}

View File

@ -1183,7 +1183,7 @@ static void window_park_price_paint(rct_window* w, rct_drawpixelinfo* dpi)
+ ScreenCoordsXY{ w->widgets[WIDX_PAGE_BACKGROUND].left + 4, w->widgets[WIDX_PAGE_BACKGROUND].top + 30 };
DrawTextBasic(dpi, screenCoords, STR_INCOME_FROM_ADMISSIONS, &gTotalIncomeFromAdmissions);
money32 parkEntranceFee = park_get_entrance_fee();
money64 parkEntranceFee = park_get_entrance_fee();
auto stringId = parkEntranceFee == 0 ? STR_FREE : STR_BOTTOM_TOOLBAR_CASH;
screenCoords = w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_PRICE].left + 1, w->widgets[WIDX_PRICE].top + 1 };
DrawTextBasic(dpi, screenCoords, stringId, &parkEntranceFee, { w->colours[1] });
@ -1489,14 +1489,14 @@ static void window_park_objective_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (gScenarioObjective.Type == OBJECTIVE_FINISH_5_ROLLERCOASTERS)
ft.Add<uint16_t>(gScenarioObjective.MinimumExcitement);
else
ft.Add<money32>(gScenarioObjective.Currency);
ft.Add<money64>(gScenarioObjective.Currency);
}
screenCoords.y += DrawTextWrapped(dpi, screenCoords, 221, ObjectiveNames[gScenarioObjective.Type], ft);
screenCoords.y += 5;
// Objective outcome
if (gScenarioCompletedCompanyValue != MONEY32_UNDEFINED)
if (gScenarioCompletedCompanyValue != MONEY64_UNDEFINED)
{
if (gScenarioCompletedCompanyValue == COMPANY_VALUE_ON_FAILED_OBJECTIVE)
{
@ -1507,7 +1507,7 @@ static void window_park_objective_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
// Objective completed
ft = Formatter();
ft.Add<money32>(gScenarioCompletedCompanyValue);
ft.Add<money64>(gScenarioCompletedCompanyValue);
DrawTextWrapped(dpi, screenCoords, 222, STR_OBJECTIVE_ACHIEVED, ft);
}
}

View File

@ -561,7 +561,7 @@ void window_research_funding_page_paint(rct_window* w, rct_drawpixelinfo* dpi, r
return;
int32_t currentResearchLevel = gResearchFundingLevel;
money32 currentResearchCostPerWeek = research_cost_table[currentResearchLevel];
money64 currentResearchCostPerWeek = research_cost_table[currentResearchLevel];
DrawTextBasic(dpi, w->windowPos + ScreenCoordsXY{ 10, 77 }, STR_RESEARCH_COST_PER_MONTH, &currentResearchCostPerWeek);
}

View File

@ -6507,10 +6507,10 @@ static void window_ride_income_invalidate(rct_window* w)
if (ride == nullptr)
return;
w->widgets[WIDX_TITLE].text = STR_ARG_14_STRINGID;
w->widgets[WIDX_TITLE].text = STR_ARG_18_STRINGID;
auto ft = Formatter::Common();
ft.Increment(14);
ft.Increment(18);
ride->FormatNameTo(ft);
auto rideEntry = ride->GetRideEntry();
@ -6536,11 +6536,10 @@ static void window_ride_income_invalidate(rct_window* w)
window_ride_income_widgets[WIDX_SECONDARY_PRICE_LABEL].text = STR_SHOP_ITEM_PRICE_LABEL_ON_RIDE_PHOTO;
window_ride_income_widgets[WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK].type = WindowWidgetType::Empty;
window_ride_income_widgets[WIDX_PRIMARY_PRICE].text = STR_ARG_6_CURRENCY2DP;
window_ride_income_widgets[WIDX_PRIMARY_PRICE].text = STR_BOTTOM_TOOLBAR_CASH;
money16 ridePrimaryPrice = ride_get_price(ride);
ft.Rewind();
ft.Increment(6);
ft.Add<money32>(ridePrimaryPrice);
ft.Add<money64>(ridePrimaryPrice);
if (ridePrimaryPrice == 0)
window_ride_income_widgets[WIDX_PRIMARY_PRICE].text = STR_FREE;
@ -6591,7 +6590,9 @@ static void window_ride_income_invalidate(rct_window* w)
// Set secondary item price
window_ride_income_widgets[WIDX_SECONDARY_PRICE].text = STR_RIDE_SECONDARY_PRICE_VALUE;
ft.Add<money32>(ride->price[1]);
ft.Rewind();
ft.Increment(10);
ft.Add<money64>(ride->price[1]);
if (ride->price[1] == 0)
window_ride_income_widgets[WIDX_SECONDARY_PRICE].text = STR_FREE;
}
@ -6607,7 +6608,7 @@ static void window_ride_income_invalidate(rct_window* w)
static void window_ride_income_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
rct_string_id stringId;
money32 profit, costPerHour;
money64 profit, costPerHour;
ShopItem primaryItem, secondaryItem;
WindowDrawWidgets(w, dpi);
@ -6665,7 +6666,7 @@ static void window_ride_income_paint(rct_window* w, rct_drawpixelinfo* dpi)
screenCoords.y += 18;
// Income per hour
if (ride->income_per_hour != MONEY32_UNDEFINED)
if (ride->income_per_hour != MONEY64_UNDEFINED)
{
DrawTextBasic(dpi, screenCoords, STR_INCOME_PER_HOUR, &ride->income_per_hour);
screenCoords.y += LIST_ROW_HEIGHT;
@ -6678,7 +6679,7 @@ static void window_ride_income_paint(rct_window* w, rct_drawpixelinfo* dpi)
screenCoords.y += LIST_ROW_HEIGHT;
// Profit per hour
if (ride->profit != MONEY32_UNDEFINED)
if (ride->profit != MONEY64_UNDEFINED)
{
DrawTextBasic(dpi, screenCoords, STR_PROFIT_PER_HOUR, &ride->profit);
screenCoords.y += LIST_ROW_HEIGHT;

View File

@ -632,7 +632,7 @@ static void window_ride_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi,
break;
case INFORMATION_TYPE_PROFIT:
formatSecondary = 0;
if (ride->profit != MONEY32_UNDEFINED)
if (ride->profit != MONEY64_UNDEFINED)
{
formatSecondary = STR_PROFIT_LABEL;
ft.Add<int32_t>(ride->profit);
@ -644,7 +644,7 @@ static void window_ride_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi,
break;
case INFORMATION_TYPE_TOTAL_PROFIT:
formatSecondary = 0;
if (ride->total_profit != MONEY32_UNDEFINED)
if (ride->total_profit != MONEY64_UNDEFINED)
{
formatSecondary = STR_RIDE_LIST_TOTAL_PROFIT_LABEL;
ft.Add<int32_t>(ride->total_profit);
@ -674,7 +674,7 @@ static void window_ride_list_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi,
}
case INFORMATION_TYPE_INCOME:
formatSecondary = 0;
if (ride->income_per_hour != MONEY32_UNDEFINED)
if (ride->income_per_hour != MONEY64_UNDEFINED)
{
formatSecondary = STR_RIDE_LIST_INCOME_LABEL;
ft.Add<int32_t>(ride->income_per_hour);

View File

@ -535,7 +535,7 @@ static void window_scenarioselect_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (scenario->objective_type == OBJECTIVE_FINISH_5_ROLLERCOASTERS)
ft.Add<uint16_t>(scenario->objective_arg_2);
else
ft.Add<money32>(scenario->objective_arg_2);
ft.Add<money64>(scenario->objective_arg_2);
}
screenPos.y += DrawTextWrapped(dpi, screenPos, 170, STR_OBJECTIVE, ft) + 5;
@ -551,7 +551,7 @@ static void window_scenarioselect_paint(rct_window* w, rct_drawpixelinfo* dpi)
ft = Formatter();
ft.Add<rct_string_id>(STR_STRING);
ft.Add<const char*>(completedByName);
ft.Add<money32>(scenario->highscore->company_value);
ft.Add<money64>(scenario->highscore->company_value);
screenPos.y += DrawTextWrapped(dpi, screenPos, 170, STR_COMPLETED_BY_WITH_COMPANY_VALUE, ft);
}
}

View File

@ -1071,7 +1071,7 @@ void window_staff_stats_paint(rct_window* w, rct_drawpixelinfo* dpi)
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
{
auto ft = Formatter();
ft.Add<money32>(GetStaffWage(peep->AssignedStaffType));
ft.Add<money64>(GetStaffWage(peep->AssignedStaffType));
DrawTextBasic(dpi, screenCoords, STR_STAFF_STAT_WAGES, ft);
screenCoords.y += LIST_ROW_HEIGHT;
}

View File

@ -286,7 +286,7 @@ public:
if (!(gParkFlags & PARK_FLAGS_NO_MONEY))
{
auto ft = Formatter();
ft.Add<money32>(GetStaffWage(GetSelectedStaffType()));
ft.Add<money64>(GetStaffWage(GetSelectedStaffType()));
DrawTextBasic(&dpi, windowPos + ScreenCoordsXY{ width - 155, 32 }, STR_COST_PER_MONTH, ft);
}

View File

@ -345,12 +345,12 @@ namespace Editor
gGuestInitialCash = std::clamp(
gGuestInitialCash, static_cast<money16>(MONEY(10, 00)), static_cast<money16>(MAX_ENTRANCE_FEE));
gInitialCash = std::min(gInitialCash, 100000);
gInitialCash = std::min<money64>(gInitialCash, 100000);
finance_reset_cash_to_initial();
gBankLoan = std::clamp(gBankLoan, MONEY(0, 00), MONEY(5000000, 00));
gBankLoan = std::clamp<money64>(gBankLoan, MONEY(0, 00), MONEY(5000000, 00));
gMaxBankLoan = std::clamp(gMaxBankLoan, MONEY(0, 00), MONEY(5000000, 00));
gMaxBankLoan = std::clamp<money64>(gMaxBankLoan, MONEY(0, 00), MONEY(5000000, 00));
gBankLoanInterestRate = std::clamp<uint8_t>(gBankLoanInterestRate, 5, 80);
}

View File

@ -283,8 +283,8 @@ GameActions::Result::Ptr RideCreateAction::Execute() const
ride->no_primary_items_sold = 0;
ride->no_secondary_items_sold = 0;
ride->last_crash_type = RIDE_CRASH_TYPE_NONE;
ride->income_per_hour = MONEY32_UNDEFINED;
ride->profit = MONEY32_UNDEFINED;
ride->income_per_hour = MONEY64_UNDEFINED;
ride->profit = MONEY64_UNDEFINED;
ride->connected_message_throttle = 0;
ride->entrance_style = 0;
ride->num_block_brakes = 0;

View File

@ -73,18 +73,18 @@ GameActions::Result::Ptr ScenarioSetSettingAction::Execute() const
}
break;
case ScenarioSetSetting::InitialCash:
gInitialCash = std::clamp<money32>(_value, MONEY(0, 00), MONEY(1000000, 00));
gInitialCash = std::clamp<money64>(_value, MONEY(0, 00), MONEY(1000000, 00));
gCash = gInitialCash;
window_invalidate_by_class(WC_FINANCES);
window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
break;
case ScenarioSetSetting::InitialLoan:
gBankLoan = std::clamp<money32>(_value, MONEY(0, 00), MONEY(5000000, 00));
gBankLoan = std::clamp<money64>(_value, MONEY(0, 00), MONEY(5000000, 00));
gMaxBankLoan = std::max(gBankLoan, gMaxBankLoan);
window_invalidate_by_class(WC_FINANCES);
break;
case ScenarioSetSetting::MaximumLoanSize:
gMaxBankLoan = std::clamp<money32>(_value, MONEY(0, 00), MONEY(5000000, 00));
gMaxBankLoan = std::clamp<money64>(_value, MONEY(0, 00), MONEY(5000000, 00));
gBankLoan = std::min(gBankLoan, gMaxBankLoan);
window_invalidate_by_class(WC_FINANCES);
break;
@ -103,7 +103,7 @@ GameActions::Result::Ptr ScenarioSetSettingAction::Execute() const
}
break;
case ScenarioSetSetting::AverageCashPerGuest:
gGuestInitialCash = std::clamp<money32>(_value, MONEY(0, 00), MONEY(1000, 00));
gGuestInitialCash = std::clamp<money64>(_value, MONEY(0, 00), MONEY(1000, 00));
break;
case ScenarioSetSetting::GuestInitialHappiness:
gGuestInitialHappiness = std::clamp<uint8_t>(_value, 40, 250);

View File

@ -141,6 +141,12 @@ using money64 = fixed64_1dp;
#define MONEY_FREE MONEY(0, 00)
#define MONEY16_UNDEFINED static_cast<money16>(static_cast<uint16_t>(0xFFFF))
#define MONEY32_UNDEFINED (static_cast<money32>(0x80000000))
#define MONEY64_UNDEFINED (static_cast<money64>(0x8000000000000000))
static constexpr money64 ToMoney64(money32 value)
{
return value == MONEY32_UNDEFINED ? MONEY64_UNDEFINED : value;
}
using EMPTY_ARGS_VOID_POINTER = void();
using rct_string_id = uint16_t;

View File

@ -774,7 +774,7 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv)
}
else if (argv[0] == "current_loan" && invalidArguments(&invalidArgs, int_valid[0]))
{
gBankLoan = std::clamp(MONEY(int_val[0] - (int_val[0] % 1000), 0), MONEY(0, 0), gMaxBankLoan);
gBankLoan = std::clamp<money64>(MONEY(int_val[0] - (int_val[0] % 1000), 0), MONEY(0, 0), gMaxBankLoan);
console.Execute("get current_loan");
}
else if (argv[0] == "max_loan" && invalidArguments(&invalidArgs, int_valid[0]))

View File

@ -82,6 +82,7 @@ public:
std::is_same_v<typename std::remove_cv<TSpecified>::type, int16_t> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, int32_t> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, money32> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, money64> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, rct_string_id> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, uint16_t> ||
std::is_same_v<typename std::remove_cv<TSpecified>::type, uint32_t> ||

View File

@ -657,6 +657,10 @@ namespace OpenRCT2
{
FormatArgument(ss, token, std::get<int32_t>(value));
}
else if (std::holds_alternative<int64_t>(value))
{
FormatArgument(ss, token, std::get<int64_t>(value));
}
else if (std::holds_alternative<const char*>(value))
{
FormatArgument(ss, token, std::get<const char*>(value));
@ -755,11 +759,13 @@ namespace OpenRCT2
case FormatToken::Comma32:
case FormatToken::Int32:
case FormatToken::Comma2dp32:
case FormatToken::Currency2dp:
case FormatToken::Currency:
case FormatToken::Sprite:
anyArgs.push_back(ReadFromArgs<int32_t>(args));
break;
case FormatToken::Currency2dp:
case FormatToken::Currency:
anyArgs.push_back(ReadFromArgs<int64_t>(args));
break;
case FormatToken::UInt16:
case FormatToken::MonthYear:
case FormatToken::Month:

View File

@ -145,7 +145,7 @@ namespace OpenRCT2
using FormatBuffer = FormatBufferBase<char>;
using FormatArg_t = std::variant<uint16_t, int32_t, const char*, std::string>;
using FormatArg_t = std::variant<uint16_t, int32_t, int64_t, const char*, std::string>;
class FmtString
{

View File

@ -35,20 +35,20 @@ static constexpr const int32_t dword_988E60[static_cast<int32_t>(ExpenditureType
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
};
money32 gInitialCash;
money32 gCash;
money32 gBankLoan;
money64 gInitialCash;
money64 gCash;
money64 gBankLoan;
uint8_t gBankLoanInterestRate;
money32 gMaxBankLoan;
money32 gCurrentExpenditure;
money32 gCurrentProfit;
money32 gHistoricalProfit;
money32 gWeeklyProfitAverageDividend;
money64 gMaxBankLoan;
money64 gCurrentExpenditure;
money64 gCurrentProfit;
money64 gHistoricalProfit;
money64 gWeeklyProfitAverageDividend;
uint16_t gWeeklyProfitAverageDivisor;
money32 gCashHistory[FINANCE_GRAPH_SIZE];
money32 gWeeklyProfitHistory[FINANCE_GRAPH_SIZE];
money32 gParkValueHistory[FINANCE_GRAPH_SIZE];
money32 gExpenditureTable[EXPENDITURE_TABLE_MONTH_COUNT][static_cast<int32_t>(ExpenditureType::Count)];
money64 gCashHistory[FINANCE_GRAPH_SIZE];
money64 gWeeklyProfitHistory[FINANCE_GRAPH_SIZE];
money64 gParkValueHistory[FINANCE_GRAPH_SIZE];
money64 gExpenditureTable[EXPENDITURE_TABLE_MONTH_COUNT][static_cast<int32_t>(ExpenditureType::Count)];
/**
* Checks the condition if the game is required to use money.
@ -186,9 +186,9 @@ void finance_reset_history()
{
for (int32_t i = 0; i < FINANCE_GRAPH_SIZE; i++)
{
gCashHistory[i] = MONEY32_UNDEFINED;
gWeeklyProfitHistory[i] = MONEY32_UNDEFINED;
gParkValueHistory[i] = MONEY32_UNDEFINED;
gCashHistory[i] = MONEY64_UNDEFINED;
gWeeklyProfitHistory[i] = MONEY64_UNDEFINED;
gParkValueHistory[i] = MONEY64_UNDEFINED;
}
}
@ -221,7 +221,7 @@ void finance_init()
gBankLoanInterestRate = 10;
gParkValue = 0;
gCompanyValue = 0;
gScenarioCompletedCompanyValue = MONEY32_UNDEFINED;
gScenarioCompletedCompanyValue = MONEY64_UNDEFINED;
gTotalAdmissions = 0;
gTotalIncomeFromAdmissions = 0;
gScenarioCompletedBy = "?";
@ -276,22 +276,22 @@ void finance_update_daily_profit()
window_invalidate_by_class(WC_FINANCES);
}
money32 finance_get_initial_cash()
money64 finance_get_initial_cash()
{
return gInitialCash;
}
money32 finance_get_current_loan()
money64 finance_get_current_loan()
{
return gBankLoan;
}
money32 finance_get_maximum_loan()
money64 finance_get_maximum_loan()
{
return gMaxBankLoan;
}
money32 finance_get_current_cash()
money64 finance_get_current_cash()
{
return gCash;
}
@ -306,7 +306,7 @@ void finance_shift_expenditure_table()
// If EXPENDITURE_TABLE_MONTH_COUNT months have passed then is full, sum the oldest month
if (gDateMonthsElapsed >= EXPENDITURE_TABLE_MONTH_COUNT)
{
money32 sum = 0;
money64 sum = 0;
for (uint32_t i = 0; i < static_cast<int32_t>(ExpenditureType::Count); i++)
{
sum += gExpenditureTable[EXPENDITURE_TABLE_MONTH_COUNT - 1][i];
@ -344,12 +344,12 @@ void finance_reset_cash_to_initial()
/**
* Gets the last month's profit from food, drink and merchandise.
*/
money32 finance_get_last_month_shop_profit()
money64 finance_get_last_month_shop_profit()
{
money32 profit = 0;
money64 profit = 0;
if (gDateMonthsElapsed != 0)
{
money32* lastMonthExpenditure = gExpenditureTable[1];
const auto* lastMonthExpenditure = gExpenditureTable[1];
profit += lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::ShopSales)];
profit += lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::ShopStock)];

View File

@ -36,26 +36,26 @@ enum class ExpenditureType : int32_t
extern const money32 research_cost_table[RESEARCH_FUNDING_COUNT];
extern money32 gInitialCash;
extern money32 gCash;
extern money32 gBankLoan;
extern money64 gInitialCash;
extern money64 gCash;
extern money64 gBankLoan;
extern uint8_t gBankLoanInterestRate;
extern money32 gMaxBankLoan;
extern money32 gCurrentExpenditure;
extern money32 gCurrentProfit;
extern money64 gMaxBankLoan;
extern money64 gCurrentExpenditure;
extern money64 gCurrentProfit;
/**
* The total profit for the entire scenario that precedes
* the current financial table.
*/
extern money32 gHistoricalProfit;
extern money64 gHistoricalProfit;
extern money32 gWeeklyProfitAverageDividend;
extern money64 gWeeklyProfitAverageDividend;
extern uint16_t gWeeklyProfitAverageDivisor;
extern money32 gCashHistory[FINANCE_GRAPH_SIZE];
extern money32 gWeeklyProfitHistory[FINANCE_GRAPH_SIZE];
extern money32 gParkValueHistory[FINANCE_GRAPH_SIZE];
extern money32 gExpenditureTable[EXPENDITURE_TABLE_MONTH_COUNT][static_cast<int32_t>(ExpenditureType::Count)];
extern money64 gCashHistory[FINANCE_GRAPH_SIZE];
extern money64 gWeeklyProfitHistory[FINANCE_GRAPH_SIZE];
extern money64 gParkValueHistory[FINANCE_GRAPH_SIZE];
extern money64 gExpenditureTable[EXPENDITURE_TABLE_MONTH_COUNT][static_cast<int32_t>(ExpenditureType::Count)];
bool finance_check_money_required(uint32_t flags);
bool finance_check_affordability(money32 cost, uint32_t flags);
@ -70,9 +70,9 @@ void finance_update_daily_profit();
void finance_shift_expenditure_table();
void finance_reset_cash_to_initial();
money32 finance_get_initial_cash();
money32 finance_get_current_loan();
money32 finance_get_maximum_loan();
money32 finance_get_current_cash();
money64 finance_get_initial_cash();
money64 finance_get_current_loan();
money64 finance_get_maximum_loan();
money64 finance_get_current_cash();
money32 finance_get_last_month_shop_profit();
money64 finance_get_last_month_shop_profit();

View File

@ -920,7 +920,7 @@ bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int16_t
* @param rotation (ebp)
*/
void PaintFloatingMoneyEffect(
paint_session* session, money32 amount, rct_string_id string_id, int16_t y, int16_t z, int8_t y_offsets[], int16_t offset_x,
paint_session* session, money64 amount, rct_string_id string_id, int16_t y, int16_t z, int8_t y_offsets[], int16_t offset_x,
uint32_t rotation)
{
auto* ps = session->AllocateStringPaintEntry();
@ -938,8 +938,7 @@ void PaintFloatingMoneyEffect(
ps->string_id = string_id;
ps->next = nullptr;
ps->args[0] = amount;
ps->args[1] = y;
std::memcpy(ps->args, &amount, sizeof(amount));
ps->args[2] = 0;
ps->args[3] = 0;
ps->y_offsets = reinterpret_cast<uint8_t*>(y_offsets);

View File

@ -330,7 +330,7 @@ void paint_util_push_tunnel_rotated(paint_session* session, uint8_t direction, u
bool PaintAttachToPreviousAttach(paint_session* session, uint32_t image_id, int16_t x, int16_t y);
bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int16_t x, int16_t y);
void PaintFloatingMoneyEffect(
paint_session* session, money32 amount, rct_string_id string_id, int16_t y, int16_t z, int8_t y_offsets[], int16_t offset_x,
paint_session* session, money64 amount, rct_string_id string_id, int16_t y, int16_t z, int8_t y_offsets[], int16_t offset_x,
uint32_t rotation);
paint_session* PaintSessionAlloc(rct_drawpixelinfo* dpi, uint32_t viewFlags);

View File

@ -280,7 +280,7 @@ public:
return true;
}
int32_t CorrectRCT1ParkValue(money32 oldParkValue)
money32 CorrectRCT1ParkValue(money32 oldParkValue)
{
if (oldParkValue == MONEY32_UNDEFINED)
{
@ -1327,13 +1327,13 @@ private:
gInitialCash = _s4.cash;
gCompanyValue = _s4.company_value;
gParkValue = CorrectRCT1ParkValue(_s4.park_value);
gParkValue = ToMoney64(CorrectRCT1ParkValue(_s4.park_value));
gCurrentProfit = _s4.profit;
for (size_t i = 0; i < RCT12_FINANCE_GRAPH_SIZE; i++)
{
gCashHistory[i] = _s4.cash_history[i];
gParkValueHistory[i] = CorrectRCT1ParkValue(_s4.park_value_history[i]);
gParkValueHistory[i] = ToMoney64(CorrectRCT1ParkValue(_s4.park_value_history[i]));
gWeeklyProfitHistory[i] = _s4.weekly_profit_history[i];
}
@ -2300,7 +2300,7 @@ private:
// This is corrected here, but since scenario_objective_currency doubles as minimum excitement rating,
// we need to check the goal to avoid affecting scenarios like Volcania.
if (_s4.scenario_objective_type == OBJECTIVE_PARK_VALUE_BY)
gScenarioObjective.Currency = CorrectRCT1ParkValue(_s4.scenario_objective_currency);
gScenarioObjective.Currency = ToMoney64(CorrectRCT1ParkValue(_s4.scenario_objective_currency));
else
gScenarioObjective.Currency = _s4.scenario_objective_currency;

View File

@ -321,7 +321,7 @@ public:
{
gCashHistory[i] = _s6.balance_history[i];
gWeeklyProfitHistory[i] = _s6.weekly_profit_history[i];
gParkValueHistory[i] = _s6.park_value_history[i];
gParkValueHistory[i] = ToMoney64(_s6.park_value_history[i]);
}
gScenarioCompletedCompanyValue = _s6.completed_company_value;

View File

@ -309,7 +309,7 @@ public:
// Various flags stating whether a window needs to be refreshed
uint8_t window_invalidate_flags;
uint32_t total_customers;
money32 total_profit;
money64 total_profit;
uint8_t popularity;
uint8_t popularity_time_out; // Updated every purchase and ?possibly by time?
uint8_t popularity_next; // When timeout reached this will be the next popularity
@ -359,8 +359,8 @@ public:
uint8_t not_fixed_timeout;
uint8_t last_crash_type;
uint8_t connected_message_throttle;
money32 income_per_hour;
money32 profit;
money64 income_per_hour;
money64 profit;
TrackColour track_colour[NUM_COLOUR_SCHEMES];
uint8_t music;
uint8_t entrance_style;

View File

@ -75,8 +75,8 @@ Objective gScenarioObjective;
bool gAllowEarlyCompletionInNetworkPlay;
uint16_t gScenarioParkRatingWarningDays;
money32 gScenarioCompletedCompanyValue;
money32 gScenarioCompanyValueRecord;
money64 gScenarioCompletedCompanyValue;
money64 gScenarioCompanyValueRecord;
char gScenarioFileName[MAX_PATH];
@ -144,7 +144,7 @@ void scenario_begin()
gCurrentProfit = 0;
gWeeklyProfitAverageDividend = 0;
gWeeklyProfitAverageDivisor = 0;
gScenarioCompletedCompanyValue = MONEY32_UNDEFINED;
gScenarioCompletedCompanyValue = MONEY64_UNDEFINED;
gTotalAdmissions = 0;
gTotalIncomeFromAdmissions = 0;
gScenarioCompletedBy = "?";
@ -197,7 +197,7 @@ void scenario_failure()
*/
void scenario_success()
{
const money32 companyValue = gCompanyValue;
auto companyValue = gCompanyValue;
gScenarioCompletedCompanyValue = companyValue;
peep_applause();
@ -928,8 +928,8 @@ ObjectiveStatus Objective::CheckRepayLoanAndParkValue() const
ObjectiveStatus Objective::CheckMonthlyFoodIncome() const
{
money32* lastMonthExpenditure = gExpenditureTable[1];
int32_t lastMonthProfit = lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::ShopSales)]
const auto* lastMonthExpenditure = gExpenditureTable[1];
auto lastMonthProfit = lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::ShopSales)]
+ lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::ShopStock)]
+ lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::FoodDrinkSales)]
+ lastMonthExpenditure[static_cast<int32_t>(ExpenditureType::FoodDrinkStock)];
@ -978,7 +978,7 @@ static void scenario_objective_check()
*/
ObjectiveStatus Objective::Check() const
{
if (gScenarioCompletedCompanyValue != MONEY32_UNDEFINED)
if (gScenarioCompletedCompanyValue != MONEY64_UNDEFINED)
{
return ObjectiveStatus::Undecided;
}

View File

@ -373,7 +373,7 @@ struct Objective
};
union
{
money32 Currency;
money64 Currency;
uint16_t MinimumExcitement; // For the "Finish 5 coaster with a minimum excitement rating" objective.
};
@ -423,7 +423,7 @@ enum
#define AUTOSAVE_PAUSE 0
#define DEFAULT_NUM_AUTOSAVES_TO_KEEP 10
static constexpr money32 COMPANY_VALUE_ON_FAILED_OBJECTIVE = 0x80000001;
static constexpr money64 COMPANY_VALUE_ON_FAILED_OBJECTIVE = 0x8000000000000001;
extern const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT];
@ -433,8 +433,8 @@ extern random_engine_t gScenarioRand;
extern Objective gScenarioObjective;
extern bool gAllowEarlyCompletionInNetworkPlay;
extern uint16_t gScenarioParkRatingWarningDays;
extern money32 gScenarioCompletedCompanyValue;
extern money32 gScenarioCompanyValueRecord;
extern money64 gScenarioCompletedCompanyValue;
extern money64 gScenarioCompanyValueRecord;
extern rct_s6_info gS6Info;
extern std::string gScenarioName;

View File

@ -318,7 +318,7 @@ private:
class ScenarioRepository final : public IScenarioRepository
{
private:
static constexpr uint32_t HighscoreFileVersion = 1;
static constexpr uint32_t HighscoreFileVersion = 2;
std::shared_ptr<IPlatformEnvironment> const _env;
ScenarioFileIndex const _fileIndex;
@ -416,7 +416,7 @@ public:
return nullptr;
}
bool TryRecordHighscore(int32_t language, const utf8* scenarioFileName, money32 companyValue, const utf8* name) override
bool TryRecordHighscore(int32_t language, const utf8* scenarioFileName, money64 companyValue, const utf8* name) override
{
// Scan the scenarios so we have a fresh list to query. This is to prevent the issue of scenario completions
// not getting recorded, see #4951.
@ -598,7 +598,7 @@ private:
{
auto fs = FileStream(path, FILE_MODE_OPEN);
uint32_t fileVersion = fs.ReadValue<uint32_t>();
if (fileVersion != 1)
if (fileVersion != 1 && fileVersion != 2)
{
Console::Error::WriteLine("Invalid or incompatible highscores file.");
return;
@ -612,7 +612,7 @@ private:
scenario_highscore_entry* highscore = InsertHighscore();
highscore->fileName = fs.ReadString();
highscore->name = fs.ReadString();
highscore->company_value = fs.ReadValue<money32>();
highscore->company_value = fileVersion == 1 ? fs.ReadValue<money32>() : fs.ReadValue<money64>();
highscore->timestamp = fs.ReadValue<datetime64>();
}
}
@ -784,7 +784,7 @@ const scenario_index_entry* scenario_repository_get_by_index(size_t index)
return repo->GetByIndex(index);
}
bool scenario_repository_try_record_highscore(const utf8* scenarioFileName, money32 companyValue, const utf8* name)
bool scenario_repository_try_record_highscore(const utf8* scenarioFileName, money64 companyValue, const utf8* name)
{
IScenarioRepository* repo = GetScenarioRepository();
return repo->TryRecordHighscore(LocalisationService_GetCurrentLanguage(), scenarioFileName, companyValue, name);

View File

@ -20,7 +20,7 @@ struct scenario_highscore_entry
{
utf8* fileName;
utf8* name;
money32 company_value;
money64 company_value;
datetime64 timestamp;
};
@ -38,7 +38,7 @@ struct scenario_index_entry
// Objective
uint8_t objective_type;
uint8_t objective_arg_1;
int32_t objective_arg_2;
int64_t objective_arg_2;
int16_t objective_arg_3;
scenario_highscore_entry* highscore = nullptr;
@ -71,7 +71,7 @@ struct IScenarioRepository
virtual const scenario_index_entry* GetByPath(const utf8* path) const abstract;
virtual bool TryRecordHighscore(
int32_t language, const utf8* scenarioFileName, money32 companyValue, const utf8* name) abstract;
int32_t language, const utf8* scenarioFileName, money64 companyValue, const utf8* name) abstract;
};
std::unique_ptr<IScenarioRepository> CreateScenarioRepository(const std::shared_ptr<OpenRCT2::IPlatformEnvironment>& env);
@ -80,5 +80,5 @@ IScenarioRepository* GetScenarioRepository();
void scenario_repository_scan();
size_t scenario_repository_get_count();
const scenario_index_entry* scenario_repository_get_by_index(size_t index);
bool scenario_repository_try_record_highscore(const utf8* scenarioFileName, money32 companyValue, const utf8* name);
bool scenario_repository_try_record_highscore(const utf8* scenarioFileName, money64 companyValue, const utf8* name);
void scenario_translate(scenario_index_entry* scenarioEntry);

View File

@ -123,6 +123,13 @@ namespace OpenRCT2::Scripting
duk_put_prop_string(_ctx, _idx, name);
}
void Set(const char* name, int64_t value)
{
EnsureObjectPushed();
duk_push_number(_ctx, value);
duk_put_prop_string(_ctx, _idx, name);
}
void Set(const char* name, uint64_t value)
{
EnsureObjectPushed();
@ -280,6 +287,12 @@ namespace OpenRCT2::Scripting
return DukValue::take_from_stack(ctx);
}
template<> inline DukValue ToDuk(duk_context* ctx, const int64_t& value)
{
duk_push_number(ctx, value);
return DukValue::take_from_stack(ctx);
}
template<> inline DukValue ToDuk(duk_context* ctx, const std::string_view& value)
{
duk_push_lstring(ctx, value.data(), value.size());

View File

@ -247,11 +247,11 @@ namespace OpenRCT2::Scripting
class ScPark
{
public:
money32 cash_get() const
money64 cash_get() const
{
return gCash;
}
void cash_set(money32 value)
void cash_set(money64 value)
{
ThrowIfGameStateNotMutable();
@ -280,11 +280,11 @@ namespace OpenRCT2::Scripting
}
}
money32 bankLoan_get() const
money64 bankLoan_get() const
{
return gBankLoan;
}
void bankLoan_set(money32 value)
void bankLoan_set(money64 value)
{
ThrowIfGameStateNotMutable();
@ -296,11 +296,11 @@ namespace OpenRCT2::Scripting
}
}
money32 maxBankLoan_get() const
money64 maxBankLoan_get() const
{
return gMaxBankLoan;
}
void maxBankLoan_set(money32 value)
void maxBankLoan_set(money64 value)
{
ThrowIfGameStateNotMutable();
@ -362,11 +362,11 @@ namespace OpenRCT2::Scripting
return gGuestInitialThirst;
}
money32 value_get() const
money64 value_get() const
{
return gParkValue;
}
void value_set(money32 value)
void value_set(money64 value)
{
ThrowIfGameStateNotMutable();
@ -378,11 +378,11 @@ namespace OpenRCT2::Scripting
}
}
money32 companyValue_get() const
money64 companyValue_get() const
{
return gCompanyValue;
}
void companyValue_set(money32 value)
void companyValue_set(money64 value)
{
ThrowIfGameStateNotMutable();
@ -414,11 +414,11 @@ namespace OpenRCT2::Scripting
}
}
money32 totalIncomeFromAdmissions_get() const
money64 totalIncomeFromAdmissions_get() const
{
return gTotalIncomeFromAdmissions;
}
void totalIncomeFromAdmissions_set(money32 value)
void totalIncomeFromAdmissions_set(money64 value)
{
ThrowIfGameStateNotMutable();

View File

@ -107,7 +107,7 @@ namespace OpenRCT2::Scripting
}
}
money32 excitement_get()
money64 excitement_get()
{
if (gScenarioObjective.Type == OBJECTIVE_FINISH_5_ROLLERCOASTERS)
{
@ -116,7 +116,7 @@ namespace OpenRCT2::Scripting
return 0;
}
void excitement_set(money32 value)
void excitement_set(money64 value)
{
ThrowIfGameStateNotMutable();
if (gScenarioObjective.Type == OBJECTIVE_FINISH_5_ROLLERCOASTERS)
@ -125,7 +125,7 @@ namespace OpenRCT2::Scripting
}
}
money32 parkValue_get()
money64 parkValue_get()
{
if (gScenarioObjective.Type == OBJECTIVE_PARK_VALUE_BY
|| gScenarioObjective.Type == OBJECTIVE_REPAY_LOAN_AND_PARK_VALUE)
@ -135,7 +135,7 @@ namespace OpenRCT2::Scripting
return 0;
}
void parkValue_set(money32 value)
void parkValue_set(money64 value)
{
ThrowIfGameStateNotMutable();
if (gScenarioObjective.Type == OBJECTIVE_PARK_VALUE_BY
@ -145,7 +145,7 @@ namespace OpenRCT2::Scripting
}
}
money32 monthlyIncome_get()
money64 monthlyIncome_get()
{
if (gScenarioObjective.Type == OBJECTIVE_MONTHLY_RIDE_INCOME
|| gScenarioObjective.Type == OBJECTIVE_MONTHLY_FOOD_INCOME)
@ -155,7 +155,7 @@ namespace OpenRCT2::Scripting
return 0;
}
void monthlyIncome_set(money32 value)
void monthlyIncome_set(money64 value)
{
ThrowIfGameStateNotMutable();
if (gScenarioObjective.Type == OBJECTIVE_PARK_VALUE_BY
@ -246,7 +246,7 @@ namespace OpenRCT2::Scripting
DukValue completedCompanyValue_get() const
{
auto ctx = GetContext()->GetScriptEngine().GetContext();
if (gScenarioCompletedCompanyValue == MONEY32_UNDEFINED
if (gScenarioCompletedCompanyValue == MONEY64_UNDEFINED
|| gScenarioCompletedCompanyValue == COMPANY_VALUE_ON_FAILED_OBJECTIVE)
{
return ToDuk(ctx, nullptr);
@ -261,7 +261,7 @@ namespace OpenRCT2::Scripting
std::string status_get() const
{
if (gScenarioCompletedCompanyValue == MONEY32_UNDEFINED)
if (gScenarioCompletedCompanyValue == MONEY64_UNDEFINED)
return "inProgress";
else if (gScenarioCompletedCompanyValue == COMPANY_VALUE_ON_FAILED_OBJECTIVE)
return "failed";
@ -271,18 +271,18 @@ namespace OpenRCT2::Scripting
{
ThrowIfGameStateNotMutable();
if (value == "inProgress")
gScenarioCompletedCompanyValue = MONEY32_UNDEFINED;
gScenarioCompletedCompanyValue = MONEY64_UNDEFINED;
else if (value == "failed")
gScenarioCompletedCompanyValue = COMPANY_VALUE_ON_FAILED_OBJECTIVE;
else if (value == "completed")
gScenarioCompletedCompanyValue = gCompanyValue;
}
money32 companyValueRecord_get() const
money64 companyValueRecord_get() const
{
return gScenarioCompanyValueRecord;
}
void companyValueRecord_set(money32 value)
void companyValueRecord_set(money64 value)
{
ThrowIfGameStateNotMutable();
gScenarioCompanyValueRecord = value;

View File

@ -729,6 +729,12 @@ int32_t add_clamp_int32_t(int32_t value, int32_t value_to_add)
return value;
}
int64_t add_clamp_int64_t(int64_t value, int64_t value_to_add)
{
add_clamp_body(value, value_to_add, INT64_MIN, INT64_MAX);
return value;
}
money32 add_clamp_money32(money32 value, money32 value_to_add)
{
// This function is intended only for clarity, as money32
@ -737,6 +743,14 @@ money32 add_clamp_money32(money32 value, money32 value_to_add)
return add_clamp_int32_t(value, value_to_add);
}
money32 add_clamp_money64(money64 value, money64 value_to_add)
{
// This function is intended only for clarity, as money64
// is technically the same as int64_t
assert_struct_size(money64, sizeof(int64_t));
return add_clamp_int64_t(value, value_to_add);
}
#undef add_clamp_body
uint8_t lerp(uint8_t a, uint8_t b, float t)

View File

@ -63,7 +63,9 @@ bool util_gzip_compress(FILE* source, FILE* dest);
int8_t add_clamp_int8_t(int8_t value, int8_t value_to_add);
int16_t add_clamp_int16_t(int16_t value, int16_t value_to_add);
int32_t add_clamp_int32_t(int32_t value, int32_t value_to_add);
int64_t add_clamp_int64_t(int64_t value, int64_t value_to_add);
money32 add_clamp_money32(money32 value, money32 value_to_add);
money32 add_clamp_money64(money64 value, money64 value_to_add);
uint8_t lerp(uint8_t a, uint8_t b, float t);
float flerp(float a, float b, float t);

View File

@ -133,12 +133,12 @@ void MoneyEffect::Update()
sprite_remove(this);
}
std::pair<rct_string_id, money32> MoneyEffect::GetStringId() const
std::pair<rct_string_id, money64> MoneyEffect::GetStringId() const
{
rct_string_id spentStringId = Vertical ? STR_MONEY_EFFECT_SPEND_HIGHP : STR_MONEY_EFFECT_SPEND;
rct_string_id receiveStringId = Vertical ? STR_MONEY_EFFECT_RECEIVE_HIGHP : STR_MONEY_EFFECT_RECEIVE;
rct_string_id stringId = receiveStringId;
money32 outValue = Value;
money64 outValue = Value;
if (Value < 0)
{
outValue *= -1;

View File

@ -246,12 +246,12 @@ uint16_t Park::GetParkRating() const
return gParkRating;
}
money32 Park::GetParkValue() const
money64 Park::GetParkValue() const
{
return gParkValue;
}
money32 Park::GetCompanyValue() const
money64 Park::GetCompanyValue() const
{
return gCompanyValue;
}
@ -482,10 +482,10 @@ int32_t Park::CalculateParkRating() const
return result;
}
money32 Park::CalculateParkValue() const
money64 Park::CalculateParkValue() const
{
// Sum ride values
money32 result = 0;
money64 result = 0;
for (const auto& ride : GetRideManager())
{
result += CalculateRideValue(&ride);
@ -497,23 +497,23 @@ money32 Park::CalculateParkValue() const
return result;
}
money32 Park::CalculateRideValue(const Ride* ride) const
money64 Park::CalculateRideValue(const Ride* ride) const
{
money32 result = 0;
money64 result = 0;
if (ride != nullptr && ride->value != RIDE_VALUE_UNDEFINED)
{
const auto& rtd = ride->GetRideTypeDescriptor();
result = (ride->value * 10) * (ride_customers_in_last_5_minutes(ride) + rtd.BonusValue * 4);
result = (ride->value * 10LL) * (static_cast<money64>(ride_customers_in_last_5_minutes(ride)) + rtd.BonusValue * 4);
}
return result;
}
money32 Park::CalculateCompanyValue() const
money64 Park::CalculateCompanyValue() const
{
money32 result = gParkValue - gBankLoan;
auto result = gParkValue - gBankLoan;
// Clamp addition to prevent overflow
result = add_clamp_money32(result, finance_get_current_cash());
result = add_clamp_money64(result, finance_get_current_cash());
return result;
}
@ -767,20 +767,20 @@ void Park::UpdateHistories()
// Update park rating, guests in park and current cash history
HistoryPushRecord<uint8_t, 32>(gParkRatingHistory, CalculateParkRating() / 4);
HistoryPushRecord<uint8_t, 32>(gGuestsInParkHistory, std::min<uint16_t>(gNumGuestsInPark, 5000) / 20);
HistoryPushRecord<money32, 128>(gCashHistory, finance_get_current_cash() - gBankLoan);
HistoryPushRecord<money64, std::size(gCashHistory)>(gCashHistory, finance_get_current_cash() - gBankLoan);
// Update weekly profit history
money32 currentWeeklyProfit = gWeeklyProfitAverageDividend;
auto currentWeeklyProfit = gWeeklyProfitAverageDividend;
if (gWeeklyProfitAverageDivisor != 0)
{
currentWeeklyProfit /= gWeeklyProfitAverageDivisor;
}
HistoryPushRecord<money32, 128>(gWeeklyProfitHistory, currentWeeklyProfit);
HistoryPushRecord<money64, std::size(gWeeklyProfitHistory)>(gWeeklyProfitHistory, currentWeeklyProfit);
gWeeklyProfitAverageDividend = 0;
gWeeklyProfitAverageDivisor = 0;
// Update park value history
HistoryPushRecord<money32, 128>(gParkValueHistory, gParkValue);
HistoryPushRecord<money64, std::size(gParkValueHistory)>(gParkValueHistory, gParkValue);
// Invalidate relevant windows
auto intent = Intent(INTENT_ACTION_UPDATE_GUEST_COUNT);

View File

@ -59,16 +59,16 @@ namespace OpenRCT2
bool IsOpen() const;
uint16_t GetParkRating() const;
money32 GetParkValue() const;
money32 GetCompanyValue() const;
money64 GetParkValue() const;
money64 GetCompanyValue() const;
void Initialise();
void Update(const Date& date);
int32_t CalculateParkSize() const;
int32_t CalculateParkRating() const;
money32 CalculateParkValue() const;
money32 CalculateCompanyValue() const;
money64 CalculateParkValue() const;
money64 CalculateCompanyValue() const;
static uint8_t CalculateGuestInitialHappiness(uint8_t percentage);
Guest* GenerateGuest();
@ -77,7 +77,7 @@ namespace OpenRCT2
void UpdateHistories();
private:
money32 CalculateRideValue(const Ride* ride) const;
money64 CalculateRideValue(const Ride* ride) const;
money16 CalculateTotalRideValueForMoney() const;
uint32_t CalculateSuggestedMaxGuests() const;
uint32_t CalculateGuestGenerationProbability() const;