mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
Remove union from window internal (#20429)
* Remove campaign vars from union * Remove error union * Remove new_ride union * Remove Unknown5 * Update changelog
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
- Fix: [#20361] Crash when using random map generation.
|
||||
- Fix: [#20413] Crash when attempting to navigate an empty console history.
|
||||
- Fix: [#20417] Plugin/custom windows are missing the left border in the title bar.
|
||||
- Fix: [#20429] Error window tooltip not closing after 8 seconds.
|
||||
|
||||
0.4.5 (2023-05-08)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
@@ -34,6 +34,7 @@ class ErrorWindow final : public Window
|
||||
private:
|
||||
std::string _text;
|
||||
uint16_t _numLines;
|
||||
uint8_t _staleCount;
|
||||
|
||||
public:
|
||||
ErrorWindow(std::string text, uint16_t numLines)
|
||||
@@ -48,7 +49,7 @@ public:
|
||||
window_error_widgets[WIDX_BACKGROUND].bottom = height;
|
||||
|
||||
widgets = window_error_widgets;
|
||||
error.var_480 = 0;
|
||||
_staleCount = 0;
|
||||
if (!gDisableErrorWindowSound)
|
||||
{
|
||||
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Error, 0, windowPos.x + (width / 2));
|
||||
@@ -97,10 +98,11 @@ public:
|
||||
dpi, { leftTop + ScreenCoordsXY{ (width + 1) / 2 - 1, 1 } }, _numLines, _text.data(), FontStyle::Medium);
|
||||
}
|
||||
|
||||
void OnUnknown5() override
|
||||
void OnPeriodicUpdate() override
|
||||
{
|
||||
error.var_480++;
|
||||
if (error.var_480 >= 8)
|
||||
// Close the window after 8 seconds of showing
|
||||
_staleCount++;
|
||||
if (_staleCount >= 8)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -654,7 +654,7 @@ public:
|
||||
return cursorId;
|
||||
}
|
||||
|
||||
void OnUnknown5() override
|
||||
void OnPeriodicUpdate() override
|
||||
{
|
||||
InvalidateDirtyWidgets();
|
||||
}
|
||||
|
||||
@@ -61,6 +61,16 @@ class NewCampaignWindow final : public Window
|
||||
private:
|
||||
std::vector<RideId> RideList;
|
||||
std::vector<ShopItem> ShopItems;
|
||||
struct CampaignVariables
|
||||
{
|
||||
int16_t campaign_type;
|
||||
int16_t no_weeks; // 0x482
|
||||
union
|
||||
{
|
||||
::RideId RideId;
|
||||
ObjectEntryIndex ShopItemId;
|
||||
};
|
||||
} Campaign;
|
||||
|
||||
static bool RideValueCompare(const RideId& a, const RideId& b)
|
||||
{
|
||||
@@ -164,13 +174,13 @@ public:
|
||||
widgets[WIDX_TITLE].text = MarketingCampaignNames[campaignType][0];
|
||||
|
||||
// Campaign type
|
||||
campaign.campaign_type = campaignType;
|
||||
Campaign.campaign_type = campaignType;
|
||||
|
||||
// Number of weeks
|
||||
campaign.no_weeks = 2;
|
||||
Campaign.no_weeks = 2;
|
||||
|
||||
// Currently selected ride
|
||||
campaign.RideId = RideId::GetNull();
|
||||
Campaign.RideId = RideId::GetNull();
|
||||
|
||||
RefreshRides();
|
||||
}
|
||||
@@ -185,7 +195,7 @@ public:
|
||||
case WIDX_RIDE_DROPDOWN_BUTTON:
|
||||
dropdownWidget = widget - 1;
|
||||
|
||||
if (campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE)
|
||||
if (Campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE)
|
||||
{
|
||||
GetShopItems();
|
||||
if (!ShopItems.empty())
|
||||
@@ -236,11 +246,11 @@ public:
|
||||
break;
|
||||
// In RCT2, the maximum was 6 weeks
|
||||
case WIDX_WEEKS_INCREASE_BUTTON:
|
||||
campaign.no_weeks = std::min(campaign.no_weeks + 1, 12);
|
||||
Campaign.no_weeks = std::min(Campaign.no_weeks + 1, 12);
|
||||
Invalidate();
|
||||
break;
|
||||
case WIDX_WEEKS_DECREASE_BUTTON:
|
||||
campaign.no_weeks = std::max(campaign.no_weeks - 1, 2);
|
||||
Campaign.no_weeks = std::max(Campaign.no_weeks - 1, 2);
|
||||
Invalidate();
|
||||
break;
|
||||
}
|
||||
@@ -256,7 +266,7 @@ public:
|
||||
case WIDX_START_BUTTON:
|
||||
{
|
||||
auto gameAction = ParkMarketingAction(
|
||||
campaign.campaign_type, campaign.RideId.ToUnderlying(), campaign.no_weeks);
|
||||
Campaign.campaign_type, Campaign.RideId.ToUnderlying(), Campaign.no_weeks);
|
||||
gameAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
|
||||
if (result->Error == GameActions::Status::Ok)
|
||||
{
|
||||
@@ -277,19 +287,19 @@ public:
|
||||
if (dropdownIndex < 0)
|
||||
return;
|
||||
|
||||
if (campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE)
|
||||
if (Campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE)
|
||||
{
|
||||
if (static_cast<size_t>(dropdownIndex) >= ShopItems.size())
|
||||
return;
|
||||
|
||||
campaign.ShopItemId = EnumValue(ShopItems[dropdownIndex]);
|
||||
Campaign.ShopItemId = EnumValue(ShopItems[dropdownIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (static_cast<size_t>(dropdownIndex) >= RideList.size())
|
||||
return;
|
||||
|
||||
campaign.RideId = RideList[dropdownIndex];
|
||||
Campaign.RideId = RideList[dropdownIndex];
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
@@ -301,7 +311,7 @@ public:
|
||||
widgets[WIDX_RIDE_DROPDOWN].type = WindowWidgetType::Empty;
|
||||
widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WindowWidgetType::Empty;
|
||||
widgets[WIDX_RIDE_DROPDOWN].text = STR_MARKETING_NOT_SELECTED;
|
||||
switch (campaign.campaign_type)
|
||||
switch (Campaign.campaign_type)
|
||||
{
|
||||
case ADVERTISING_CAMPAIGN_RIDE_FREE:
|
||||
case ADVERTISING_CAMPAIGN_RIDE:
|
||||
@@ -309,9 +319,9 @@ public:
|
||||
widgets[WIDX_RIDE_DROPDOWN].type = WindowWidgetType::DropdownMenu;
|
||||
widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WindowWidgetType::Button;
|
||||
widgets[WIDX_RIDE_LABEL].text = STR_MARKETING_RIDE;
|
||||
if (campaign.RideId != RideId::GetNull())
|
||||
if (Campaign.RideId != RideId::GetNull())
|
||||
{
|
||||
auto curRide = GetRide(campaign.RideId);
|
||||
auto curRide = GetRide(Campaign.RideId);
|
||||
if (curRide != nullptr)
|
||||
{
|
||||
widgets[WIDX_RIDE_DROPDOWN].text = STR_STRINGID;
|
||||
@@ -326,9 +336,9 @@ public:
|
||||
widgets[WIDX_RIDE_DROPDOWN].type = WindowWidgetType::DropdownMenu;
|
||||
widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WindowWidgetType::Button;
|
||||
widgets[WIDX_RIDE_LABEL].text = STR_MARKETING_ITEM;
|
||||
if (campaign.ShopItemId != SELECTED_ITEM_UNDEFINED)
|
||||
if (Campaign.ShopItemId != SELECTED_ITEM_UNDEFINED)
|
||||
{
|
||||
widgets[WIDX_RIDE_DROPDOWN].text = GetShopItemDescriptor(ShopItem(campaign.ShopItemId)).Naming.Plural;
|
||||
widgets[WIDX_RIDE_DROPDOWN].text = GetShopItemDescriptor(ShopItem(Campaign.ShopItemId)).Naming.Plural;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -338,7 +348,7 @@ public:
|
||||
|
||||
// Enable / disable start button based on ride dropdown
|
||||
WidgetSetDisabled(*this, WIDX_START_BUTTON, false);
|
||||
if (widgets[WIDX_RIDE_DROPDOWN].type == WindowWidgetType::DropdownMenu && campaign.RideId == RideId::GetNull())
|
||||
if (widgets[WIDX_RIDE_DROPDOWN].type == WindowWidgetType::DropdownMenu && Campaign.RideId == RideId::GetNull())
|
||||
WidgetSetDisabled(*this, WIDX_START_BUTTON, true);
|
||||
}
|
||||
|
||||
@@ -351,22 +361,22 @@ public:
|
||||
// Number of weeks
|
||||
Widget* spinnerWidget = &widgets[WIDX_WEEKS_SPINNER];
|
||||
auto ft = Formatter();
|
||||
ft.Add<int16_t>(campaign.no_weeks);
|
||||
ft.Add<int16_t>(Campaign.no_weeks);
|
||||
DrawTextBasic(
|
||||
dpi, windowPos + ScreenCoordsXY{ spinnerWidget->left + 1, spinnerWidget->top },
|
||||
campaign.no_weeks == 1 ? STR_MARKETING_1_WEEK : STR_X_WEEKS, ft, { colours[0] });
|
||||
Campaign.no_weeks == 1 ? STR_MARKETING_1_WEEK : STR_X_WEEKS, ft, { colours[0] });
|
||||
|
||||
screenCoords = windowPos + ScreenCoordsXY{ 14, 60 };
|
||||
|
||||
// Price per week
|
||||
ft = Formatter();
|
||||
ft.Add<money64>(AdvertisingCampaignPricePerWeek[campaign.campaign_type]);
|
||||
ft.Add<money64>(AdvertisingCampaignPricePerWeek[Campaign.campaign_type]);
|
||||
DrawTextBasic(dpi, screenCoords, STR_MARKETING_COST_PER_WEEK, ft);
|
||||
screenCoords.y += 13;
|
||||
|
||||
// Total price
|
||||
ft = Formatter();
|
||||
ft.Add<money64>(AdvertisingCampaignPricePerWeek[campaign.campaign_type] * campaign.no_weeks);
|
||||
ft.Add<money64>(AdvertisingCampaignPricePerWeek[Campaign.campaign_type] * Campaign.no_weeks);
|
||||
DrawTextBasic(dpi, screenCoords, STR_MARKETING_TOTAL_COST, ft);
|
||||
}
|
||||
|
||||
@@ -374,6 +384,11 @@ public:
|
||||
{
|
||||
ResizeFrame();
|
||||
}
|
||||
|
||||
int16_t GetCampaignType() const
|
||||
{
|
||||
return Campaign.campaign_type;
|
||||
}
|
||||
};
|
||||
|
||||
WindowBase* WindowNewCampaignOpen(int16_t campaignType)
|
||||
@@ -381,7 +396,7 @@ WindowBase* WindowNewCampaignOpen(int16_t campaignType)
|
||||
auto w = static_cast<NewCampaignWindow*>(WindowBringToFrontByClass(WindowClass::NewCampaign));
|
||||
if (w != nullptr)
|
||||
{
|
||||
if (w->campaign.campaign_type == campaignType)
|
||||
if (w->GetCampaignType() == campaignType)
|
||||
return w;
|
||||
|
||||
WindowClose(*w);
|
||||
|
||||
@@ -274,6 +274,12 @@ private:
|
||||
RideSelection _lastTrackDesignCountRideType{};
|
||||
int32_t _lastTrackDesignCount{};
|
||||
RideSelection _windowNewRideListItems[RideListItemsMax]{};
|
||||
struct NewRideVariables
|
||||
{
|
||||
RideSelection SelectedRide;
|
||||
RideSelection HighlightedRide;
|
||||
uint16_t SelectedRideCountdown;
|
||||
} _newRideVars{};
|
||||
|
||||
public:
|
||||
static void SetOpeningPage(NewRideTabId tab)
|
||||
@@ -294,7 +300,7 @@ public:
|
||||
_filter.clear();
|
||||
|
||||
frame_no = 0;
|
||||
new_ride.SelectedRide = { RIDE_TYPE_NULL, OBJECT_ENTRY_INDEX_NULL };
|
||||
_newRideVars.SelectedRide = { RIDE_TYPE_NULL, OBJECT_ENTRY_INDEX_NULL };
|
||||
_lastTrackDesignCountRideType.Type = RIDE_TYPE_NULL;
|
||||
_lastTrackDesignCountRideType.EntryIndex = OBJECT_ENTRY_INDEX_NULL;
|
||||
|
||||
@@ -322,7 +328,7 @@ public:
|
||||
WidgetInvalidate(*this, WIDX_FILTER_TEXT_BOX);
|
||||
}
|
||||
|
||||
if (new_ride.SelectedRide.Type != RIDE_TYPE_NULL && new_ride.selected_ride_countdown-- == 0)
|
||||
if (_newRideVars.SelectedRide.Type != RIDE_TYPE_NULL && _newRideVars.SelectedRideCountdown-- == 0)
|
||||
{
|
||||
RideSelect();
|
||||
}
|
||||
@@ -336,7 +342,7 @@ public:
|
||||
// Remove highlight when mouse leaves rides list
|
||||
if (!WidgetIsHighlighted(*this, WIDX_RIDE_LIST))
|
||||
{
|
||||
new_ride.HighlightedRide = { RIDE_TYPE_NULL, OBJECT_ENTRY_INDEX_NULL };
|
||||
_newRideVars.HighlightedRide = { RIDE_TYPE_NULL, OBJECT_ENTRY_INDEX_NULL };
|
||||
WidgetInvalidate(*this, WIDX_RIDE_LIST);
|
||||
}
|
||||
}
|
||||
@@ -414,7 +420,7 @@ public:
|
||||
|
||||
if (_currentTab != RESEARCH_TAB)
|
||||
{
|
||||
RideSelection item = new_ride.HighlightedRide;
|
||||
RideSelection item = _newRideVars.HighlightedRide;
|
||||
if (item.Type != RIDE_TYPE_NULL || item.EntryIndex != OBJECT_ENTRY_INDEX_NULL)
|
||||
DrawRideInformation(dpi, item, windowPos + ScreenCoordsXY{ 3, height - 64 }, width - 6);
|
||||
}
|
||||
@@ -440,12 +446,12 @@ public:
|
||||
void OnScrollMouseOver(int32_t scrollIndex, const ScreenCoordsXY& screenCoords) override
|
||||
{
|
||||
RideSelection item = ScrollGetRideListItemAt(screenCoords);
|
||||
if (new_ride.HighlightedRide == item)
|
||||
if (_newRideVars.HighlightedRide == item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new_ride.HighlightedRide = item;
|
||||
_newRideVars.HighlightedRide = item;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@@ -457,10 +463,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
new_ride.SelectedRide = item;
|
||||
_newRideVars.SelectedRide = item;
|
||||
|
||||
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, windowPos.x + (width / 2));
|
||||
new_ride.selected_ride_countdown = 8;
|
||||
_newRideVars.SelectedRideCountdown = 8;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@@ -479,9 +485,9 @@ public:
|
||||
{
|
||||
// Draw flat button rectangle
|
||||
int32_t buttonFlags = 0;
|
||||
if (new_ride.SelectedRide == *listItem)
|
||||
if (_newRideVars.SelectedRide == *listItem)
|
||||
buttonFlags |= INSET_RECT_FLAG_BORDER_INSET;
|
||||
if (new_ride.HighlightedRide == *listItem || buttonFlags != 0)
|
||||
if (_newRideVars.HighlightedRide == *listItem || buttonFlags != 0)
|
||||
GfxFillRectInset(
|
||||
dpi, { coords, coords + ScreenCoordsXY{ 115, 115 } }, colours[1],
|
||||
INSET_RECT_FLAG_FILL_MID_LIGHT | buttonFlags);
|
||||
@@ -530,8 +536,8 @@ public:
|
||||
{
|
||||
_currentTab = tab;
|
||||
frame_no = 0;
|
||||
new_ride.HighlightedRide = { RIDE_TYPE_NULL, OBJECT_ENTRY_INDEX_NULL };
|
||||
new_ride.selected_ride_countdown = std::numeric_limits<uint16_t>::max();
|
||||
_newRideVars.HighlightedRide = { RIDE_TYPE_NULL, OBJECT_ENTRY_INDEX_NULL };
|
||||
_newRideVars.SelectedRideCountdown = std::numeric_limits<uint16_t>::max();
|
||||
PopulateRideList();
|
||||
RefreshWidgetSizing();
|
||||
Invalidate();
|
||||
@@ -545,7 +551,7 @@ public:
|
||||
private:
|
||||
void RideSelect()
|
||||
{
|
||||
RideSelection item = new_ride.SelectedRide;
|
||||
RideSelection item = _newRideVars.SelectedRide;
|
||||
if (item.Type == RIDE_TYPE_NULL)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -111,16 +111,6 @@ public:
|
||||
pressed_widgets = 0;
|
||||
}
|
||||
|
||||
void OnClose() override
|
||||
{
|
||||
switch (page)
|
||||
{
|
||||
case WINDOW_PLAYER_PAGE_STATISTICS:
|
||||
OnCloseStatistics();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnResize() override
|
||||
{
|
||||
switch (page)
|
||||
@@ -589,14 +579,6 @@ private:
|
||||
|
||||
#pragma region Statistics
|
||||
|
||||
void OnCloseStatistics()
|
||||
{
|
||||
if (error.var_480)
|
||||
{
|
||||
error.var_480 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OnResizeStatistics()
|
||||
{
|
||||
WindowSetResize(*this, 210, 80, 210, 80);
|
||||
|
||||
@@ -1436,11 +1436,6 @@ void WindowEventDropdownCall(WindowBase* w, WidgetIndex widgetIndex, int32_t dro
|
||||
w->OnDropdown(widgetIndex, dropdownIndex);
|
||||
}
|
||||
|
||||
void WindowEventUnknown05Call(WindowBase* w)
|
||||
{
|
||||
w->OnUnknown5();
|
||||
}
|
||||
|
||||
void WindowEventUpdateCall(WindowBase* w)
|
||||
{
|
||||
w->OnUpdate();
|
||||
|
||||
@@ -259,38 +259,12 @@ struct WindowEventList
|
||||
}
|
||||
};
|
||||
|
||||
struct CampaignVariables
|
||||
{
|
||||
int16_t campaign_type;
|
||||
int16_t no_weeks; // 0x482
|
||||
union
|
||||
{
|
||||
::RideId RideId;
|
||||
ObjectEntryIndex ShopItemId;
|
||||
};
|
||||
uint32_t Pad486;
|
||||
};
|
||||
|
||||
struct NewRideVariables
|
||||
{
|
||||
RideSelection SelectedRide; // 0x480
|
||||
RideSelection HighlightedRide; // 0x482
|
||||
uint16_t Pad484;
|
||||
uint16_t Pad486;
|
||||
uint16_t selected_ride_countdown; // 488
|
||||
};
|
||||
|
||||
struct TrackListVariables
|
||||
{
|
||||
bool track_list_being_updated;
|
||||
bool reload_track_designs;
|
||||
};
|
||||
|
||||
struct ErrorVariables
|
||||
{
|
||||
uint16_t var_480;
|
||||
};
|
||||
|
||||
struct WindowCloseModifier
|
||||
{
|
||||
WindowIdentifier window;
|
||||
|
||||
@@ -56,10 +56,7 @@ struct WindowBase
|
||||
std::optional<Focus> focus;
|
||||
union
|
||||
{
|
||||
CampaignVariables campaign;
|
||||
NewRideVariables new_ride;
|
||||
TrackListVariables track_list;
|
||||
ErrorVariables error;
|
||||
void* custom_info;
|
||||
};
|
||||
union
|
||||
@@ -187,9 +184,6 @@ struct WindowBase
|
||||
{
|
||||
}
|
||||
virtual CursorID OnCursor(WidgetIndex, const ScreenCoordsXY&, CursorID);
|
||||
virtual void OnUnknown5()
|
||||
{
|
||||
}
|
||||
|
||||
void ResizeFrame();
|
||||
void ResizeFrameWithPage();
|
||||
|
||||
Reference in New Issue
Block a user