1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-28 09:14:58 +01:00

Draw park graphs with new method.

Also clean up constants and includes.
This commit is contained in:
Michael Bernardi
2024-07-31 01:45:06 +10:00
parent 9e2eb73aa7
commit f4a1d22662
11 changed files with 142 additions and 215 deletions

View File

@@ -13,103 +13,33 @@
#include <openrct2/Date.h>
#include <openrct2/localisation/Formatter.h>
#include <openrct2/localisation/Localisation.Date.h>
using namespace OpenRCT2;
namespace OpenRCT2::Graph
{
static void DrawMonths(DrawPixelInfo& dpi, const uint8_t* history, int32_t count, const ScreenCoordsXY& origCoords)
{
auto& date = GetDate();
int32_t currentMonth = date.GetMonth();
int32_t currentDay = date.GetMonthTicks();
int32_t yearOver32 = (currentMonth * 4) + (currentDay >> 14) - 31;
auto screenCoords = origCoords;
for (int32_t i = count - 1; i >= 0; i--)
{
if (history[i] != 255 && yearOver32 % 4 == 0)
{
// Draw month text
auto ft = Formatter();
ft.Add<uint32_t>(DateGameShortMonthNames[DateGetMonth((yearOver32 / 4) + MONTH_COUNT)]);
DrawTextBasic(
dpi, screenCoords - ScreenCoordsXY{ 0, 10 }, STR_GRAPH_LABEL, ft,
{ FontStyle::Small, TextAlignment::CENTRE });
// Draw month mark
GfxFillRect(dpi, { screenCoords, screenCoords + ScreenCoordsXY{ 0, 3 } }, PALETTE_INDEX_10);
}
yearOver32 = (yearOver32 + 1) % 32;
screenCoords.x += 6;
}
}
static void DrawLineA(DrawPixelInfo& dpi, const uint8_t* history, int32_t count, const ScreenCoordsXY& origCoords)
{
auto lastCoords = ScreenCoordsXY{ -1, -1 };
auto coords = origCoords;
for (int32_t i = count - 1; i >= 0; i--)
{
if (history[i] != 255)
{
coords.y = origCoords.y + ((255 - history[i]) * 100) / 256;
if (lastCoords.x != -1)
{
auto leftTop1 = lastCoords + ScreenCoordsXY{ 1, 1 };
auto rightBottom1 = coords + ScreenCoordsXY{ 1, 1 };
auto leftTop2 = lastCoords + ScreenCoordsXY{ 0, 1 };
auto rightBottom2 = coords + ScreenCoordsXY{ 0, 1 };
GfxDrawLine(dpi, { leftTop1, rightBottom1 }, PALETTE_INDEX_10);
GfxDrawLine(dpi, { leftTop2, rightBottom2 }, PALETTE_INDEX_10);
}
if (i == 0)
GfxFillRect(dpi, { coords, coords + ScreenCoordsXY{ 2, 2 } }, PALETTE_INDEX_10);
lastCoords = coords;
}
coords.x += 6;
}
}
static void DrawLineB(DrawPixelInfo& dpi, const uint8_t* history, int32_t count, const ScreenCoordsXY& origCoords)
{
auto lastCoords = ScreenCoordsXY{ -1, -1 };
auto coords = origCoords;
for (int32_t i = count - 1; i >= 0; i--)
{
if (history[i] != 255)
{
coords.y = origCoords.y + ((255 - history[i]) * 100) / 256;
if (lastCoords.x != -1)
{
auto leftTop = lastCoords;
auto rightBottom = coords;
GfxDrawLine(dpi, { leftTop, rightBottom }, PALETTE_INDEX_21);
}
if (i == 0)
GfxFillRect(dpi, { coords - ScreenCoordsXY{ 1, 1 }, coords + ScreenCoordsXY{ 1, 1 } }, PALETTE_INDEX_21);
lastCoords = coords;
}
coords.x += 6;
}
}
void Draw(DrawPixelInfo& dpi, uint8_t* history, int32_t count, const ScreenCoordsXY& screenPos)
{
DrawMonths(dpi, history, count, screenPos);
DrawLineA(dpi, history, count, screenPos);
DrawLineB(dpi, history, count, screenPos);
}
} // namespace OpenRCT2::Graph
#include <openrct2/world/Park.h>
namespace OpenRCT2::Graph
{
constexpr int32_t kDashLength = 2;
template<typename T>
static void DrawYLabels(
DrawPixelInfo& dpi, const ScreenRect& internalBounds, const T min, const T max, const int32_t numYLabels,
const int32_t yLabelStepPx, const StringId fmt, const ColourWithFlags lineCol)
{
T curLabel = max;
int32_t curScreenPos = internalBounds.GetTop() - 5;
const T yLabelStep = (max - min) / (numYLabels - 1);
for (int32_t i = 0; i < numYLabels; i++)
{
Formatter ft;
ft.Add<T>(curLabel);
DrawTextBasic(dpi, { internalBounds.GetLeft(), curScreenPos }, fmt, ft, { FontStyle::Small, TextAlignment::RIGHT });
GfxFillRectInset(
dpi, { { internalBounds.GetLeft(), curScreenPos + 5 }, { internalBounds.GetRight(), curScreenPos + 5 } },
lineCol, INSET_RECT_FLAG_BORDER_INSET);
curScreenPos += yLabelStepPx;
curLabel -= yLabelStep;
}
}
template<typename T, T TkNoValue>
static void DrawMonths(DrawPixelInfo& dpi, const T* series, int32_t count, const ScreenRect& bounds, const int32_t xStep)
{
@@ -126,11 +56,12 @@ namespace OpenRCT2::Graph
auto ft = Formatter();
ft.Add<StringId>(DateGameShortMonthNames[DateGetMonth((yearOver32 / 4) + MONTH_COUNT)]);
DrawTextBasic(
dpi, screenCoords - ScreenCoordsXY{ 0, 13 }, STR_GRAPH_LABEL, ft,
dpi, screenCoords - ScreenCoordsXY{ 0, 14 }, STR_GRAPH_LABEL, ft,
{ FontStyle::Small, TextAlignment::CENTRE });
// Draw month mark
GfxFillRect(dpi, { screenCoords - ScreenCoordsXY{ 0, 3 }, screenCoords }, PALETTE_INDEX_10);
GfxFillRect(
dpi, { screenCoords - ScreenCoordsXY{ 0, 4 }, screenCoords - ScreenCoordsXY{ 0, 1 } }, PALETTE_INDEX_10);
}
yearOver32 = (yearOver32 + 1) % 32;
@@ -148,12 +79,15 @@ namespace OpenRCT2::Graph
const int32_t yPosition = bounds.GetBottom() - ((value - minValue) * screenRange) / valueRange;
ScreenCoordsXY coords = { bounds.GetRight() - hoverIdx * xStep, yPosition };
// Line needs to be shifted over 1 pixel to match with the month ticks.
ScreenCoordsXY lineCoords = { coords.x + 1, coords.y };
GfxDrawDashedLine(
dpi, { { lineCoords.x, bounds.GetTop() }, { lineCoords.x, bounds.GetBottom() } }, kDashLength, PALETTE_INDEX_10);
GfxDrawDashedLine(dpi, { { bounds.GetLeft(), lineCoords.y }, lineCoords }, kDashLength, PALETTE_INDEX_10);
dpi,
{
{ coords.x, bounds.GetTop() },
{ coords.x, bounds.GetBottom() },
},
kDashLength, PALETTE_INDEX_10);
GfxDrawDashedLine(dpi, { { bounds.GetLeft(), coords.y }, coords }, kDashLength, PALETTE_INDEX_10);
auto ft = Formatter();
ft.Add<money64>(value);
@@ -222,39 +156,49 @@ namespace OpenRCT2::Graph
void DrawFinanceGraph(DrawPixelInfo& dpi, const GraphProperties<money64>& p)
{
money64 curLabel = p.max;
int32_t curScreenPos = p.internalBounds.GetTop() - 5;
const money64 yLabelStep = (p.max - p.min) / (p.numYLabels - 1);
for (int32_t i = 0; i < p.numYLabels; i++)
{
Formatter ft;
ft.Add<money64>(curLabel);
DrawTextBasic(
dpi, { p.internalBounds.GetLeft(), curScreenPos }, STR_FINANCES_FINANCIAL_GRAPH_CASH_VALUE, ft,
{ FontStyle::Small, TextAlignment::RIGHT });
GfxFillRectInset(
dpi, { { p.internalBounds.GetLeft(), curScreenPos + 5 }, { p.internalBounds.GetRight(), curScreenPos + 5 } },
p.lineCol, INSET_RECT_FLAG_BORDER_INSET);
curScreenPos += p.yLabelStepPx;
curLabel -= yLabelStep;
}
constexpr StringId fmt = STR_FINANCES_FINANCIAL_GRAPH_CASH_VALUE;
DrawYLabels<money64>(dpi, p.internalBounds, p.min, p.max, p.numYLabels, p.yLabelStepPx, fmt, p.lineCol);
DrawMonths<money64, kMoney64Undefined>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx);
DrawLine<money64, kMoney64Undefined, true>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx, p.min, p.max);
DrawLine<money64, kMoney64Undefined, false>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx, p.min, p.max);
if (p.hoverIdx >= 0 && p.hoverIdx < p.numPoints)
{
money64 value = p.series[p.hoverIdx];
const money64 value = p.series[p.hoverIdx];
if (value != kMoney64Undefined)
DrawHoveredValue<money64>(dpi, value, p.hoverIdx, p.internalBounds, p.xStepPx, p.min, p.max);
}
}
// todo debug code.
ScreenCoordsXY bottomLeft{ p.internalBounds.Point1.x, p.internalBounds.Point2.y };
ScreenCoordsXY topRight{ p.internalBounds.Point2.x, p.internalBounds.Point1.y };
GfxDrawLine(dpi, { p.internalBounds.Point1, topRight }, 33);
GfxDrawLine(dpi, { p.internalBounds.Point1, bottomLeft }, 33);
GfxDrawLine(dpi, { bottomLeft, p.internalBounds.Point2 }, 33);
GfxDrawLine(dpi, { topRight, p.internalBounds.Point2 }, 33);
void DrawRatingGraph(DrawPixelInfo& dpi, const GraphProperties<uint8_t>& p)
{
constexpr uint8_t noValue = ParkRatingHistoryUndefined;
constexpr StringId fmt = STR_GRAPH_AXIS_LABEL;
// Since the park rating rating history is divided by 4, we have to fudge the max number here.
DrawYLabels<uint16_t>(dpi, p.internalBounds, p.min, 1000, p.numYLabels, p.yLabelStepPx, fmt, p.lineCol);
DrawMonths<uint8_t, noValue>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx);
DrawLine<uint8_t, noValue, true>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx, p.min, p.max);
DrawLine<uint8_t, noValue, false>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx, p.min, p.max);
if (p.hoverIdx >= 0 && p.hoverIdx < p.numPoints)
{
const uint8_t value = p.series[p.hoverIdx];
if (value != noValue)
DrawHoveredValue<uint8_t>(dpi, value, p.hoverIdx, p.internalBounds, p.xStepPx, p.min, p.max);
}
}
void DrawGuestGraph(DrawPixelInfo& dpi, const GraphProperties<uint32_t>& p)
{
constexpr uint32_t noValue = GuestsInParkHistoryUndefined;
constexpr StringId fmt = STR_GRAPH_AXIS_LABEL;
DrawYLabels<uint32_t>(dpi, p.internalBounds, p.min, p.max, p.numYLabels, p.yLabelStepPx, fmt, p.lineCol);
DrawMonths<uint32_t, noValue>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx);
DrawLine<uint32_t, noValue, true>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx, p.min, p.max);
DrawLine<uint32_t, noValue, false>(dpi, p.series, p.numPoints, p.internalBounds, p.xStepPx, p.min, p.max);
if (p.hoverIdx >= 0 && p.hoverIdx < p.numPoints)
{
const uint32_t value = p.series[p.hoverIdx];
if (value != noValue)
DrawHoveredValue<uint32_t>(dpi, value, p.hoverIdx, p.internalBounds, p.xStepPx, p.min, p.max);
}
}
} // namespace OpenRCT2::Graph

View File

@@ -19,7 +19,7 @@ namespace OpenRCT2::Graph
template<typename T> struct GraphProperties
{
ScreenRect internalBounds;
T* series;
const T* series;
T min;
T max;
int32_t hoverIdx;
@@ -41,7 +41,7 @@ namespace OpenRCT2::Graph
numYLabels = newNumYLabels;
}
bool UpdateHoverIdx()
bool UpdateHoverIndex()
{
const ScreenCoordsXY cursorPos = ContextGetCursorPositionScaled();
@@ -64,7 +64,7 @@ namespace OpenRCT2::Graph
}
};
void Draw(DrawPixelInfo& dpi, uint8_t* history, int32_t count, const ScreenCoordsXY& screenPos);
void DrawFinanceGraph(DrawPixelInfo& dpi, const GraphProperties<money64>& p);
void DrawRatingGraph(DrawPixelInfo& dpi, const GraphProperties<uint8_t>& p);
void DrawGuestGraph(DrawPixelInfo& dpi, const GraphProperties<uint32_t>& p);
} // namespace OpenRCT2::Graph

View File

@@ -256,7 +256,7 @@ static Widget _windowFinancesResearchWidgets[] =
if (page == WINDOW_FINANCES_PAGE_VALUE_GRAPH || page == WINDOW_FINANCES_PAGE_PROFIT_GRAPH
|| page == WINDOW_FINANCES_PAGE_FINANCIAL_GRAPH)
{
if (_graphProps.UpdateHoverIdx())
if (_graphProps.UpdateHoverIndex())
{
InvalidateWidget(WIDX_BACKGROUND);
}
@@ -839,19 +839,18 @@ static Widget _windowFinancesResearchWidgets[] =
}
void OnDrawGraph(
DrawPixelInfo& dpi, const money64 currentValue, money64 (&series)[kFinanceGraphSize], const StringId fmt, const bool centred)
DrawPixelInfo& dpi, const money64 currentValue, money64 (&series)[kFinanceHistorySize], const StringId fmt,
const bool centred)
{
auto ft = Formatter();
Formatter ft;
ft.Add<money64>(currentValue);
DrawTextBasic(dpi, _graphBounds.Point1 - ScreenCoordsXY{ 0, 11 }, fmt, ft);
// Graph
GfxFillRectInset(dpi, _graphBounds, colours[1], INSET_RECT_F_30);
for (int i = 0; i < 128; i++) // TODO debug
series[i] = i % 2 * 96.00_GBP;
// series[i] = 0;
// Calculate Y axis max and min.
// This is how the original code does it. Could be improved.
money64 max = centred ? 12.00_GBP : 24.00_GBP;
for (int32_t i = 0; i < kGraphNumPoints; i++)
{

View File

@@ -15,7 +15,6 @@
#include <openrct2-ui/interface/Graph.h>
#include <openrct2-ui/interface/LandTool.h>
#include <openrct2-ui/interface/Objective.h>
#include <openrct2-ui/interface/Viewport.h>
#include <openrct2-ui/interface/Widget.h>
#include <openrct2-ui/windows/Window.h>
#include <openrct2/Context.h>
@@ -27,13 +26,11 @@
#include <openrct2/config/Config.h>
#include <openrct2/localisation/Currency.h>
#include <openrct2/localisation/Formatting.h>
#include <openrct2/localisation/Localisation.Date.h>
#include <openrct2/management/Award.h>
#include <openrct2/peep/PeepAnimationData.h>
#include <openrct2/ride/RideData.h>
#include <openrct2/scenario/Scenario.h>
#include <openrct2/util/Util.h>
#include <openrct2/world/Entrance.h>
#include <openrct2/world/Park.h>
namespace OpenRCT2::Ui::Windows
@@ -41,6 +38,10 @@ namespace OpenRCT2::Ui::Windows
static constexpr StringId WINDOW_TITLE = STR_STRINGID;
static constexpr int32_t WH = 224;
static constexpr ScreenCoordsXY kGraphTopLeftPadding{ 35, 15 };
static constexpr ScreenCoordsXY kGraphBottomRightPadding{ 5, 5 };
static constexpr uint8_t kGraphNumYLabels = 6;
// clang-format off
enum WindowParkPage {
WINDOW_PARK_PAGE_ENTRANCE,
@@ -197,6 +198,12 @@ static constexpr WindowParkAward _parkAwards[] = {
int32_t _numberOfRides = -1;
uint8_t _peepAnimationFrame = 0;
Graph::GraphProperties<uint8_t> _ratingProps{};
Graph::GraphProperties<uint32_t> _guestProps{};
ScreenRect _ratingGraphBounds;
ScreenRect _guestGraphBounds;
public:
void OnOpen() override
{
@@ -206,6 +213,11 @@ static constexpr WindowParkAward _parkAwards[] = {
_numberOfStaff = -1;
_peepAnimationFrame = 0;
SetPage(0);
_ratingProps.lineCol = colours[2];
_guestProps.lineCol = colours[2];
_ratingProps.hoverIdx = -1;
_guestProps.hoverIdx = -1;
}
void OnClose() override
@@ -692,6 +704,13 @@ static constexpr WindowParkAward _parkAwards[] = {
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_7);
AnchorBorderWidgets();
const Widget* background = &widgets[WIDX_PAGE_BACKGROUND];
_ratingGraphBounds = { windowPos + ScreenCoordsXY{ background->left + 4, background->top + 15 },
windowPos + ScreenCoordsXY{ background->right - 4, background->bottom - 4 } };
_ratingProps.RecalculateLayout(
{ _ratingGraphBounds.Point1 + kGraphTopLeftPadding, _ratingGraphBounds.Point2 - kGraphBottomRightPadding },
kGraphNumYLabels, kParkRatingHistorySize);
}
void OnDrawRating(DrawPixelInfo& dpi)
@@ -699,41 +718,21 @@ static constexpr WindowParkAward _parkAwards[] = {
DrawWidgets(dpi);
DrawTabImages(dpi);
auto screenPos = windowPos;
Widget* widget = &widgets[WIDX_PAGE_BACKGROUND];
const auto& gameState = OpenRCT2::GetGameState();
// Current value
auto ft = Formatter();
ft.Add<uint16_t>(GetGameState().Park.Rating);
DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ widget->left + 3, widget->top + 2 }, STR_PARK_RATING_LABEL, ft);
Formatter ft;
ft.Add<uint16_t>(gameState.Park.Rating);
DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ widget->left + 3, widget->top + 2 }, STR_PARK_RATING_LABEL, ft);
// Graph border
GfxFillRectInset(
dpi,
{ screenPos + ScreenCoordsXY{ widget->left + 4, widget->top + 15 },
screenPos + ScreenCoordsXY{ widget->right - 4, widget->bottom - 4 } },
colours[1], INSET_RECT_F_30);
GfxFillRectInset(dpi, _ratingGraphBounds, colours[1], INSET_RECT_F_30);
// Y axis labels
screenPos = screenPos + ScreenCoordsXY{ widget->left + 27, widget->top + 23 };
for (int i = 5; i >= 0; i--)
{
uint32_t axisValue = i * 200;
ft = Formatter();
ft.Add<uint32_t>(axisValue);
DrawTextBasic(
dpi, screenPos + ScreenCoordsXY{ 10, 0 }, STR_GRAPH_AXIS_LABEL, ft,
{ FontStyle::Small, TextAlignment::RIGHT });
GfxFillRectInset(
dpi, { screenPos + ScreenCoordsXY{ 15, 5 }, screenPos + ScreenCoordsXY{ width - 32, 5 } }, colours[2],
INSET_RECT_FLAG_BORDER_INSET);
screenPos.y += 20;
}
// Graph
screenPos = windowPos + ScreenCoordsXY{ widget->left + 47, widget->top + 26 };
Graph::Draw(dpi, GetGameState().Park.RatingHistory, kParkRatingHistorySize, screenPos);
_ratingProps.min = 0;
_ratingProps.max = 250;
_ratingProps.series = gameState.Park.RatingHistory;
Graph::DrawRatingGraph(dpi, _ratingProps);
}
#pragma endregion
@@ -765,6 +764,13 @@ static constexpr WindowParkAward _parkAwards[] = {
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_7);
AnchorBorderWidgets();
const Widget* background = &widgets[WIDX_PAGE_BACKGROUND];
_guestGraphBounds = { windowPos + ScreenCoordsXY{ background->left + 4, background->top + 15 },
windowPos + ScreenCoordsXY{ background->right - 4, background->bottom - 4 } };
_guestProps.RecalculateLayout(
{ _guestGraphBounds.Point1 + kGraphTopLeftPadding, _guestGraphBounds.Point2 - kGraphBottomRightPadding },
kGraphNumYLabels, kGuestsInParkHistorySize);
}
void OnDrawGuests(DrawPixelInfo& dpi)
@@ -772,56 +778,30 @@ static constexpr WindowParkAward _parkAwards[] = {
DrawWidgets(dpi);
DrawTabImages(dpi);
auto screenPos = windowPos;
Widget* widget = &widgets[WIDX_PAGE_BACKGROUND];
const auto& gameState = OpenRCT2::GetGameState();
// Current value
auto ft = Formatter();
Formatter ft;
ft.Add<uint32_t>(gameState.NumGuestsInPark);
DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ widget->left + 3, widget->top + 2 }, STR_GUESTS_IN_PARK_LABEL, ft);
DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ widget->left + 3, widget->top + 2 }, STR_GUESTS_IN_PARK_LABEL, ft);
// Graph border
GfxFillRectInset(
dpi,
{ screenPos + ScreenCoordsXY{ widget->left + 4, widget->top + 15 },
screenPos + ScreenCoordsXY{ widget->right - 4, widget->bottom - 4 } },
colours[1], INSET_RECT_F_30);
GfxFillRectInset(dpi, _guestGraphBounds, colours[1], INSET_RECT_F_30);
// Y axis labels
screenPos = screenPos + ScreenCoordsXY{ widget->left + 27, widget->top + 23 };
for (int i = 5; i >= 0; i--)
{
uint32_t axisValue = i * 1000;
ft = Formatter();
ft.Add<uint32_t>(axisValue);
DrawTextBasic(
dpi, screenPos + ScreenCoordsXY{ 10, 0 }, STR_GRAPH_AXIS_LABEL, ft,
{ FontStyle::Small, TextAlignment::RIGHT });
GfxFillRectInset(
dpi, { screenPos + ScreenCoordsXY{ 15, 5 }, screenPos + ScreenCoordsXY{ width - 32, 5 } }, colours[2],
INSET_RECT_FLAG_BORDER_INSET);
screenPos.y += 20;
}
// Graph
screenPos = windowPos + ScreenCoordsXY{ widget->left + 47, widget->top + 26 };
uint8_t cappedHistory[32];
for (size_t i = 0; i < std::size(cappedHistory); i++)
// Calculate Y axis max and min
_guestProps.min = 0;
_guestProps.max = 5000;
for (size_t i = 0; i < std::size(gameState.GuestsInParkHistory); i++)
{
auto value = gameState.GuestsInParkHistory[i];
if (value != std::numeric_limits<uint32_t>::max())
{
cappedHistory[i] = static_cast<uint8_t>(std::min<uint32_t>(value, 5000) / 20);
}
else
{
cappedHistory[i] = std::numeric_limits<uint8_t>::max();
}
if (value == GuestsInParkHistoryUndefined)
continue;
while (value > _guestProps.max)
_guestProps.max += 5000;
}
Graph::Draw(dpi, cappedHistory, static_cast<int32_t>(std::size(cappedHistory)), screenPos);
_guestProps.series = gameState.GuestsInParkHistory;
Graph::DrawGuestGraph(dpi, _guestProps);
}
#pragma endregion
@@ -1315,6 +1295,7 @@ static constexpr WindowParkAward _parkAwards[] = {
windowPos + ScreenCoordsXY{ widgets[WIDX_TAB_7].left, widgets[WIDX_TAB_7].top });
}
}
#pragma endregion
};
static ParkWindow* ParkWindowOpen(uint8_t page)

View File

@@ -47,13 +47,13 @@ namespace OpenRCT2
money64 ConstructionRightsPrice;
money64 CurrentExpenditure;
money64 CurrentProfit;
uint32_t GuestsInParkHistory[32];
uint32_t GuestsInParkHistory[kGuestsInParkHistorySize];
ClimateType Climate;
ClimateState ClimateCurrent;
ClimateState ClimateNext;
uint16_t ClimateUpdateTimer;
money64 Cash;
money64 CashHistory[kFinanceGraphSize];
money64 CashHistory[kFinanceHistorySize];
money64 InitialCash;
money64 GuestInitialCash;
uint8_t GuestInitialHappiness;
@@ -69,7 +69,7 @@ namespace OpenRCT2
money64 TotalIncomeFromAdmissions;
money64 TotalRideValueForMoney;
uint16_t WeeklyProfitAverageDivisor;
money64 WeeklyProfitHistory[kFinanceGraphSize];
money64 WeeklyProfitHistory[kFinanceHistorySize];
Objective ScenarioObjective;
uint16_t ScenarioParkRatingWarningDays;
money64 ScenarioCompletedCompanyValue;

View File

@@ -185,7 +185,7 @@ void FinancePayRideUpkeep()
void FinanceResetHistory()
{
auto& gameState = GetGameState();
for (auto i = 0; i < kFinanceGraphSize; i++)
for (auto i = 0; i < kFinanceHistorySize; i++)
{
gameState.CashHistory[i] = kMoney64Undefined;
gameState.WeeklyProfitHistory[i] = kMoney64Undefined;

View File

@@ -32,7 +32,7 @@ enum class ExpenditureType : int32_t
};
constexpr uint8_t kExpenditureTableMonthCount = 16;
constexpr uint8_t kFinanceGraphSize = 128;
constexpr uint8_t kFinanceHistorySize = 128;
constexpr uint8_t MaxBankLoanInterestRate = 255;

View File

@@ -769,7 +769,7 @@ namespace OpenRCT2::RCT1
uint8_t Unk1990AA[94];
uint16_t ParkRating;
uint8_t ParkRatingHistory[kParkRatingHistorySize];
uint8_t GuestsInParkHistory[32];
uint8_t GuestsInParkHistory[kGuestsInParkHistorySize];
uint8_t ResearchPriority;
uint8_t ResearchProgressStage;
uint8_t LastResearchItem;

View File

@@ -862,7 +862,7 @@ namespace OpenRCT2::RCT2
// Ignored in scenario
uint8_t ParkRatingHistory[kParkRatingHistorySize];
uint8_t GuestsInParkHistory[32];
uint8_t GuestsInParkHistory[kGuestsInParkHistorySize];
// SC6[10]
uint8_t ActiveResearchTypes;

View File

@@ -586,8 +586,10 @@ namespace OpenRCT2::Park
gameState.NumGuestsInParkLastWeek = gameState.NumGuestsInPark;
// Update park rating, guests in park and current cash history
HistoryPushRecord<uint8_t, 32>(gameState.Park.RatingHistory, gameState.Park.Rating / 4);
HistoryPushRecord<uint32_t, 32>(gameState.GuestsInParkHistory, gameState.NumGuestsInPark);
constexpr auto ratingHistorySize = std::extent_v<decltype(ParkData::RatingHistory)>;
HistoryPushRecord<uint8_t, ratingHistorySize>(gameState.Park.RatingHistory, gameState.Park.Rating / 4);
constexpr auto numGuestsHistorySize = std::extent_v<decltype(GameState_t::GuestsInParkHistory)>;
HistoryPushRecord<uint32_t, numGuestsHistorySize>(gameState.GuestsInParkHistory, gameState.NumGuestsInPark);
constexpr auto cashHistorySize = std::extent_v<decltype(GameState_t::CashHistory)>;
HistoryPushRecord<money64, cashHistorySize>(gameState.CashHistory, FinanceGetCurrentCash() - gameState.BankLoan);

View File

@@ -17,6 +17,7 @@ constexpr auto MAX_ENTRANCE_FEE = 999.00_GBP;
constexpr uint8_t ParkRatingHistoryUndefined = std::numeric_limits<uint8_t>::max();
constexpr uint32_t GuestsInParkHistoryUndefined = std::numeric_limits<uint32_t>::max();
constexpr uint8_t kParkRatingHistorySize = 32;
constexpr uint8_t kGuestsInParkHistorySize = 32;
constexpr uint8_t ParkNameMaxLength = 128;
constexpr uint8_t ScenarioNameMaxLength = 128;
constexpr uint16_t ScenarioDetailsNameMaxLength = 256;
@@ -65,7 +66,7 @@ namespace OpenRCT2
std::vector<CoordsXYZD> Entrances;
uint32_t Size;
money64 Value;
money64 ValueHistory[kFinanceGraphSize];
money64 ValueHistory[kFinanceHistorySize];
bool IsOpen() const;
};