mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #7608 from AaronVanGeffen/vehicle_type_dropdown
Order vehicle type dropdown orthographically
This commit is contained in:
commit
f03fe46b83
|
@ -49,6 +49,7 @@
|
||||||
- Improved: [#7555] Allow setting the Twitch API URL, allowing custom API servers.
|
- Improved: [#7555] Allow setting the Twitch API URL, allowing custom API servers.
|
||||||
- Improved: [#7567] Improve the performance of loading parks and the title sequence.
|
- Improved: [#7567] Improve the performance of loading parks and the title sequence.
|
||||||
- Improved: [#7577] Allow fine-tuning the virtual floor style.
|
- Improved: [#7577] Allow fine-tuning the virtual floor style.
|
||||||
|
- Improved: [#7608] The vehicle selection dropdown is now sorted orthographically.
|
||||||
|
|
||||||
0.1.2 (2018-03-18)
|
0.1.2 (2018-03-18)
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
|
@ -1236,6 +1236,19 @@ struct RideTypeLabel
|
||||||
static sint32 RideDropdownDataLanguage = LANGUAGE_UNDEFINED;
|
static sint32 RideDropdownDataLanguage = LANGUAGE_UNDEFINED;
|
||||||
static std::vector<RideTypeLabel> RideDropdownData;
|
static std::vector<RideTypeLabel> RideDropdownData;
|
||||||
|
|
||||||
|
// Used for sorting the vehicle type dropdown.
|
||||||
|
struct VehicleTypeLabel
|
||||||
|
{
|
||||||
|
sint32 subtype_id;
|
||||||
|
rct_string_id label_id;
|
||||||
|
const char* label_string;
|
||||||
|
};
|
||||||
|
|
||||||
|
static sint32 VehicleDropdownDataLanguage = LANGUAGE_UNDEFINED;
|
||||||
|
static rct_ride_entry *VehicleDropdownRideType = nullptr;
|
||||||
|
static bool VehicleDropdownExpanded = false;
|
||||||
|
static std::vector<VehicleTypeLabel> VehicleDropdownData;
|
||||||
|
|
||||||
static void window_ride_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, sint32 page, sint32 spriteIndex)
|
static void window_ride_draw_tab_image(rct_drawpixelinfo *dpi, rct_window *w, sint32 page, sint32 spriteIndex)
|
||||||
{
|
{
|
||||||
rct_widgetindex widgetIndex = WIDX_TAB_1 + page;
|
rct_widgetindex widgetIndex = WIDX_TAB_1 + page;
|
||||||
|
@ -2183,6 +2196,8 @@ static void populate_ride_type_dropdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(RideDropdownData.begin(), RideDropdownData.end(), [](auto& a, auto& b) { return std::strcmp(a.label_string, b.label_string) < 0; });
|
std::sort(RideDropdownData.begin(), RideDropdownData.end(), [](auto& a, auto& b) { return std::strcmp(a.label_string, b.label_string) < 0; });
|
||||||
|
|
||||||
|
RideDropdownDataLanguage = ls.GetCurrentLanguage();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_ride_show_ride_type_dropdown(rct_window *w, rct_widget *widget)
|
static void window_ride_show_ride_type_dropdown(rct_window *w, rct_widget *widget)
|
||||||
|
@ -2223,6 +2238,115 @@ static void window_ride_show_ride_type_dropdown(rct_window *w, rct_widget *widge
|
||||||
dropdown_set_checked(pos, true);
|
dropdown_set_checked(pos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void populate_vehicle_type_dropdown(Ride *ride)
|
||||||
|
{
|
||||||
|
rct_ride_entry *rideEntry = get_ride_entry_by_ride(ride);
|
||||||
|
|
||||||
|
bool selectionShouldBeExpanded;
|
||||||
|
sint32 rideTypeIterator, rideTypeIteratorMax;
|
||||||
|
if (gCheatsShowVehiclesFromOtherTrackTypes && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE || ride->type == RIDE_TYPE_MINI_GOLF))
|
||||||
|
{
|
||||||
|
selectionShouldBeExpanded = true;
|
||||||
|
rideTypeIterator = 0;
|
||||||
|
rideTypeIteratorMax = RIDE_TYPE_COUNT - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selectionShouldBeExpanded = false;
|
||||||
|
rideTypeIterator = ride->type;
|
||||||
|
rideTypeIteratorMax = ride->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't repopulate the list if we just did.
|
||||||
|
auto& ls = OpenRCT2::GetContext()->GetLocalisationService();
|
||||||
|
if (VehicleDropdownExpanded == selectionShouldBeExpanded &&
|
||||||
|
VehicleDropdownRideType == rideEntry &&
|
||||||
|
VehicleDropdownDataLanguage == ls.GetCurrentLanguage())
|
||||||
|
return;
|
||||||
|
|
||||||
|
VehicleDropdownData.clear();
|
||||||
|
|
||||||
|
for (; rideTypeIterator <= rideTypeIteratorMax; rideTypeIterator++)
|
||||||
|
{
|
||||||
|
if (selectionShouldBeExpanded && ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE))
|
||||||
|
continue;
|
||||||
|
if (selectionShouldBeExpanded && (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint8 *rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator);
|
||||||
|
|
||||||
|
for (uint8 *currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL; currentRideEntryIndex++)
|
||||||
|
{
|
||||||
|
sint32 rideEntryIndex = *currentRideEntryIndex;
|
||||||
|
rct_ride_entry *currentRideEntry = get_ride_entry(rideEntryIndex);
|
||||||
|
|
||||||
|
// Skip if vehicle type has not been invented yet
|
||||||
|
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Skip if vehicle does not belong to the same ride group
|
||||||
|
if (RideGroupManager::RideTypeHasRideGroups(ride->type) && !selectionShouldBeExpanded)
|
||||||
|
{
|
||||||
|
const RideGroup *rideGroup = RideGroupManager::GetRideGroup(ride->type, rideEntry);
|
||||||
|
const RideGroup *currentRideGroup = RideGroupManager::GetRideGroup(ride->type, currentRideEntry);
|
||||||
|
|
||||||
|
if (!rideGroup->Equals(currentRideGroup))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleTypeLabel label = { rideEntryIndex, currentRideEntry->naming.name, ls.GetString(currentRideEntry->naming.name) };
|
||||||
|
VehicleDropdownData.push_back(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(VehicleDropdownData.begin(), VehicleDropdownData.end(), [](auto& a, auto& b) { return std::strcmp(a.label_string, b.label_string) < 0; });
|
||||||
|
|
||||||
|
VehicleDropdownExpanded = selectionShouldBeExpanded;
|
||||||
|
VehicleDropdownRideType = rideEntry;
|
||||||
|
VehicleDropdownDataLanguage = ls.GetCurrentLanguage();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void window_ride_show_vehicle_type_dropdown(rct_window *w, rct_widget *widget)
|
||||||
|
{
|
||||||
|
Ride *ride = get_ride(w->number);
|
||||||
|
populate_vehicle_type_dropdown(ride);
|
||||||
|
|
||||||
|
size_t numItems = std::min<size_t>(VehicleDropdownData.size(), DROPDOWN_ITEMS_MAX_SIZE);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
|
||||||
|
gDropdownItemsArgs[i] = VehicleDropdownData[i].label_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
rct_widget *dropdownWidget = widget - 1;
|
||||||
|
window_dropdown_show_text_custom_width(
|
||||||
|
w->x + dropdownWidget->left,
|
||||||
|
w->y + dropdownWidget->top,
|
||||||
|
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||||
|
w->colours[1],
|
||||||
|
0,
|
||||||
|
DROPDOWN_FLAG_STAY_OPEN,
|
||||||
|
numItems,
|
||||||
|
widget->right - dropdownWidget->left
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the current vehicle type in the ordered list.
|
||||||
|
uint8 pos = 0;
|
||||||
|
for (uint8 i = 0; i < VehicleDropdownData.size(); i++)
|
||||||
|
{
|
||||||
|
if (VehicleDropdownData[i].subtype_id == ride->subtype)
|
||||||
|
{
|
||||||
|
pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gDropdownHighlightedIndex = pos;
|
||||||
|
gDropdownDefaultIndex = pos;
|
||||||
|
dropdown_set_checked(pos, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x006AF1BD
|
* rct2: 0x006AF1BD
|
||||||
|
@ -2702,83 +2826,11 @@ static void window_ride_vehicle_resize(rct_window *w)
|
||||||
*/
|
*/
|
||||||
static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget)
|
||||||
{
|
{
|
||||||
rct_widget *dropdownWidget = widget - 1;
|
Ride *ride = get_ride(w->number);
|
||||||
Ride *ride;
|
|
||||||
rct_ride_entry *rideEntry, *currentRideEntry;
|
|
||||||
const RideGroup * rideGroup, * currentRideGroup;
|
|
||||||
sint32 numItems, rideEntryIndex, selectedIndex, rideTypeIterator, rideTypeIteratorMax;
|
|
||||||
uint8 *rideEntryIndexPtr;
|
|
||||||
bool selectionShouldBeExpanded;
|
|
||||||
|
|
||||||
ride = get_ride(w->number);
|
|
||||||
rideEntry = get_ride_entry_by_ride(ride);
|
|
||||||
|
|
||||||
if(gCheatsShowVehiclesFromOtherTrackTypes && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type==RIDE_TYPE_MAZE || ride->type==RIDE_TYPE_MINI_GOLF)) {
|
|
||||||
selectionShouldBeExpanded = true;
|
|
||||||
rideTypeIterator = 0;
|
|
||||||
rideTypeIteratorMax = RIDE_TYPE_COUNT - 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
selectionShouldBeExpanded = false;
|
|
||||||
rideTypeIterator = ride->type;
|
|
||||||
rideTypeIteratorMax = ride->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (widgetIndex) {
|
switch (widgetIndex) {
|
||||||
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
||||||
selectedIndex = -1;
|
window_ride_show_vehicle_type_dropdown(w, &w->widgets[widgetIndex]);
|
||||||
numItems = 0;
|
|
||||||
|
|
||||||
// Dropdowns with more items start acting weird, so cap it.
|
|
||||||
for (; rideTypeIterator <= rideTypeIteratorMax && numItems < DROPDOWN_ITEMS_MAX_SIZE; rideTypeIterator++) {
|
|
||||||
|
|
||||||
if(selectionShouldBeExpanded && ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE))
|
|
||||||
continue;
|
|
||||||
if(selectionShouldBeExpanded && (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator);
|
|
||||||
|
|
||||||
for (uint8 *currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL && numItems < DROPDOWN_ITEMS_MAX_SIZE; currentRideEntryIndex++) {
|
|
||||||
rideEntryIndex = *currentRideEntryIndex;
|
|
||||||
currentRideEntry = get_ride_entry(rideEntryIndex);
|
|
||||||
|
|
||||||
// Skip if vehicle type is not invented yet
|
|
||||||
if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Skip if vehicle does not belong to the same ride group
|
|
||||||
if (RideGroupManager::RideTypeHasRideGroups(ride->type) && !selectionShouldBeExpanded)
|
|
||||||
{
|
|
||||||
rideGroup = RideGroupManager::GetRideGroup(ride->type, rideEntry);
|
|
||||||
currentRideGroup = RideGroupManager::GetRideGroup(ride->type, currentRideEntry);
|
|
||||||
|
|
||||||
if (!rideGroup->Equals(currentRideGroup))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ride->subtype == rideEntryIndex)
|
|
||||||
selectedIndex = numItems;
|
|
||||||
|
|
||||||
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
|
|
||||||
gDropdownItemsArgs[numItems] = (rideEntryIndex << 16) | currentRideEntry->naming.name;
|
|
||||||
|
|
||||||
numItems++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window_dropdown_show_text_custom_width(
|
|
||||||
w->x + dropdownWidget->left,
|
|
||||||
w->y + dropdownWidget->top,
|
|
||||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
|
||||||
w->colours[1],
|
|
||||||
0,
|
|
||||||
DROPDOWN_FLAG_STAY_OPEN,
|
|
||||||
numItems,
|
|
||||||
widget->right - dropdownWidget->left
|
|
||||||
);
|
|
||||||
|
|
||||||
dropdown_set_checked(selectedIndex, true);
|
|
||||||
break;
|
break;
|
||||||
case WIDX_VEHICLE_TRAINS_INCREASE:
|
case WIDX_VEHICLE_TRAINS_INCREASE:
|
||||||
if (ride->num_vehicles < 32)
|
if (ride->num_vehicles < 32)
|
||||||
|
@ -2793,6 +2845,7 @@ static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetI
|
||||||
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train + 1);
|
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train + 1);
|
||||||
break;
|
break;
|
||||||
case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE:
|
case WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE:
|
||||||
|
rct_ride_entry * rideEntry = get_ride_entry_by_ride(ride);
|
||||||
if (ride->num_cars_per_train > rideEntry->zero_cars + 1)
|
if (ride->num_cars_per_train > rideEntry->zero_cars + 1)
|
||||||
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train - 1);
|
ride_set_num_cars_per_vehicle(w->number, ride->num_cars_per_train - 1);
|
||||||
break;
|
break;
|
||||||
|
@ -2810,8 +2863,8 @@ static void window_ride_vehicle_dropdown(rct_window *w, rct_widgetindex widgetIn
|
||||||
|
|
||||||
switch (widgetIndex) {
|
switch (widgetIndex) {
|
||||||
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
||||||
dropdownIndex = (gDropdownItemsArgs[dropdownIndex] >> 16) & 0xFFFF;
|
sint32 newRideType = VehicleDropdownData[dropdownIndex].subtype_id;
|
||||||
ride_set_ride_entry(w->number, dropdownIndex);
|
ride_set_ride_entry(w->number, newRideType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue