diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 97d2608ed6..323c2e331c 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3681,4 +3681,11 @@ STR_5344 :Changelog STR_5345 :Financial cheats STR_5346 :Guest cheats STR_5347 :Ride cheats -STR_5348 :Park cheats \ No newline at end of file +STR_5348 :Park cheats +STR_5349 :{SMALLFONT}{BLACK}All Rides +STR_5350 :{SMALLFONT}{BLACK}Transport Rides +STR_5351 :{SMALLFONT}{BLACK}Gentle Rides +STR_5352 :{SMALLFONT}{BLACK}Roller Coasters +STR_5353 :{SMALLFONT}{BLACK}Thrill Rides +STR_5354 :{SMALLFONT}{BLACK}Water Rides +STR_5355 :{SMALLFONT}{BLACK}Shops & Stalls \ No newline at end of file diff --git a/src/object.h b/src/object.h index 0a846f140c..cfe41692d6 100644 --- a/src/object.h +++ b/src/object.h @@ -67,6 +67,17 @@ typedef struct { rct_object_entry_extended *entries; } rct_object_entry_group; +typedef struct { + uint8 category[2]; + +} rct_ride_filters; + +typedef struct { + union { + rct_ride_filters ride; + }; +} rct_object_filters; + extern rct_object_entry_group object_entry_groups[]; int object_load_entry(const char *path, rct_object_entry *outEntry); @@ -95,4 +106,6 @@ rct_object_entry *object_list_find(rct_object_entry *entry); char *object_get_name(rct_object_entry *entry); +rct_object_filters *get_object_filter(int index); + #endif \ No newline at end of file diff --git a/src/object_list.c b/src/object_list.c index 0b566bc384..43bd1fee0d 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -28,6 +28,7 @@ #define OBJECT_ENTRY_GROUP_COUNT 11 #define OBJECT_ENTRY_COUNT 721 +#define FILTER_VERSION 1 typedef struct { uint32 total_files; @@ -86,7 +87,10 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file static int object_list_cache_save(int fileCount, uint64 totalFileSize, int fileDateModifiedChecksum, int currentItemOffset); void object_list_create_hash_table(); -static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* installed_entry, const char* path); +static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* installed_entry, const char* path, rct_object_filters* filter); +static void load_object_filter(rct_object_entry* entry, uint8* chunk, rct_object_filters* filter); + +static rct_object_filters *_installedObjectFilters = NULL; static void get_plugin_path(char *outPath) { @@ -97,6 +101,7 @@ static void get_plugin_path(char *outPath) static void object_list_sort() { rct_object_entry **objectBuffer, *newBuffer, *entry, *destEntry, *lowestEntry; + rct_object_filters *newFilters, *destFilter; int numObjects, i, j, bufferSize, entrySize, lowestIndex; char *objectName, *lowestString; uint8 *copied; @@ -104,7 +109,7 @@ static void object_list_sort() objectBuffer = &RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); numObjects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32); copied = calloc(numObjects, sizeof(uint8)); - + // Get buffer size entry = *objectBuffer; for (i = 0; i < numObjects; i++) @@ -114,6 +119,10 @@ static void object_list_sort() // Create new buffer newBuffer = rct2_malloc(bufferSize); destEntry = newBuffer; + if (_installedObjectFilters) { + newFilters = malloc(numObjects * sizeof(rct_object_filters)); + destFilter = newFilters; + } // Copy over sorted objects for (i = 0; i < numObjects; i++) { @@ -134,12 +143,18 @@ static void object_list_sort() entrySize = object_get_length(lowestEntry); memcpy(destEntry, lowestEntry, entrySize); destEntry = (rct_object_entry*)((int)destEntry + entrySize); + if (_installedObjectFilters) + destFilter[i] = _installedObjectFilters[lowestIndex]; copied[lowestIndex] = 1; } // Replace old buffer rct2_free(*objectBuffer); *objectBuffer = newBuffer; + if (_installedObjectFilters) { + free(_installedObjectFilters); + _installedObjectFilters = newFilters; + } free(copied); } @@ -264,6 +279,11 @@ void object_list_load() log_verbose("building cache of available objects..."); + if (_installedObjectFilters) { + free(_installedObjectFilters); + _installedObjectFilters = NULL; + } + enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char)); if (enumFileHandle != INVALID_HANDLE) { uint32 installed_buffer_size = 0x1000; @@ -288,9 +308,16 @@ void object_list_load() if (!object_load_entry(path, &entry)) continue; - rct_object_entry* installed_entry = (rct_object_entry*)(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset); + if (_installedObjectFilters) + _installedObjectFilters = realloc(_installedObjectFilters, sizeof(rct_object_filters) * fileCount); + else + _installedObjectFilters = malloc(sizeof(rct_object_filters) * fileCount); - current_item_offset += install_object_entry(&entry, installed_entry, enumFileInfo.path); + rct_object_entry* installed_entry = (rct_object_entry*)(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset); + rct_object_filters filter; + + current_item_offset += install_object_entry(&entry, installed_entry, enumFileInfo.path, &filter); + _installedObjectFilters[fileCount - 1] = filter; } platform_enumerate_files_end(enumFileHandle); } @@ -313,6 +340,7 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file char path[MAX_PATH]; FILE *file; rct_plugin_header pluginHeader; + uint32 filterVersion = 0; log_verbose("loading object list cache (plugin.dat)"); @@ -344,10 +372,21 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file if (pluginHeader.object_list_no_items != (pluginHeader.total_files & 0xFFFFFF)) log_error("Potential mismatch in file numbers. Possible corrupt file. Consider deleting plugin.dat."); - fclose(file); - reset_loaded_objects(); - object_list_examine(); - return 1; + if (fread(&filterVersion, sizeof(filterVersion), 1, file)) { + if (filterVersion == FILTER_VERSION) { + if (_installedObjectFilters) + free(_installedObjectFilters); + _installedObjectFilters = malloc(sizeof(rct_object_filters) * pluginHeader.object_list_no_items); + if (fread(_installedObjectFilters, sizeof(rct_object_filters) * pluginHeader.object_list_no_items, 1, file)) { + + fclose(file); + reset_loaded_objects(); + object_list_examine(); + return 1; + } + } + } + } } else if (pluginHeader.total_files != totalFiles) { @@ -378,6 +417,7 @@ static int object_list_cache_save(int fileCount, uint64 totalFileSize, int fileD char path[MAX_PATH]; FILE *file; rct_plugin_header pluginHeader; + uint32 filterVersion = FILTER_VERSION; log_verbose("saving object list cache (plugin.dat)"); @@ -396,6 +436,8 @@ static int object_list_cache_save(int fileCount, uint64 totalFileSize, int fileD fwrite(&pluginHeader, sizeof(rct_plugin_header), 1, file); fwrite(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*), pluginHeader.object_list_size, 1, file); + fwrite(&filterVersion, sizeof(filterVersion), 1, file); + fwrite(_installedObjectFilters, sizeof(rct_object_filters) * RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32), 1, file); fclose(file); return 1; } @@ -511,6 +553,7 @@ void object_unload_all() uint32 _installedObjectHashTableSize; rct_object_entry ** _installedObjectHashTable = NULL; + uint32 _installedObjectHashTableCollisions; uint32 object_get_hash_code(rct_object_entry *object) @@ -551,7 +594,7 @@ void object_list_create_hash_table() // Set hash table slot _installedObjectHashTable[index] = installedObject; - + // Next installed object installedObject = object_get_next(installedObject); } @@ -600,7 +643,7 @@ rct_object_entry *object_list_find(rct_object_entry *entry) /* Installs an object_entry at the desired installed_entry address * Returns the size of the new entry. Will return 0 on failure. */ -static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* installed_entry, const char* path){ +static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* installed_entry, const char* path, rct_object_filters* filter){ uint8* installed_entry_pointer = (uint8*) installed_entry; /** Copy all known information into the install entry **/ @@ -661,6 +704,9 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in uint8* chunk = RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER, uint8*); // Loaded in object_load + load_object_filter(entry, chunk, filter); + + // When made of two parts i.e Wooden Roller Coaster (Dream Woodie Cars) if ((objectType == OBJECT_TYPE_RIDE) && !((((rct_ride_type*)chunk)->flags) & RIDE_ENTRY_FLAG_SEPERATE_RIDE_NAME)) { rct_ride_type* ride_type = (rct_ride_type*)chunk; @@ -712,4 +758,30 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in object_unload(objectType, (rct_object_entry_extended*)entry); return size_of_object; -} \ No newline at end of file +} + +static void load_object_filter(rct_object_entry* entry, uint8* chunk, rct_object_filters* filter) +{ + switch (entry->flags & 0xF) { + case OBJECT_TYPE_RIDE: + filter->ride.category[0] = ((rct_ride_type*)chunk)->category[0]; + filter->ride.category[1] = ((rct_ride_type*)chunk)->category[1]; + break; + case OBJECT_TYPE_SMALL_SCENERY: + case OBJECT_TYPE_LARGE_SCENERY: + case OBJECT_TYPE_WALLS: + case OBJECT_TYPE_BANNERS: + case OBJECT_TYPE_PATHS: + case OBJECT_TYPE_PATH_BITS: + case OBJECT_TYPE_SCENERY_SETS: + case OBJECT_TYPE_PARK_ENTRANCE: + case OBJECT_TYPE_WATER: + case OBJECT_TYPE_SCENARIO_TEXT: + break; + } +} + +rct_object_filters *get_object_filter(int index) +{ + return &_installedObjectFilters[index]; +} diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index cee5bef0be..b25ccec702 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -38,11 +38,21 @@ enum { FILTER_WW = (1 << 1), FILTER_TT = (1 << 2), FILTER_CUSTOM = (1 << 3), - FILTER_ALL = 0xF + + FILTER_RIDE_TRANSPORT = (1 << 5), + FILTER_RIDE_GENTLE = (1 << 6), + FILTER_RIDE_COASTER = (1 << 7), + FILTER_RIDE_THRILL = (1 << 8), + FILTER_RIDE_WATER = (1 << 9), + FILTER_RIDE_STALL = (1 << 10), + + + FILTER_ALL = 0x7EF, } FILTER_FLAGS; uint32 _filter_flags; uint16 _filter_object_counts[11]; +uint8 _filter_ride_tab; char _filter_string[41]; @@ -91,7 +101,15 @@ enum WINDOW_STAFF_LIST_WIDGET_IDX { WIDX_DROPDOWN2, // 18, 40000 WIDX_FILTER_DROPDOWN, // 19, 80000 WIDX_FILTER_STRING_BUTTON, // 20, 100000 - WIDX_FILTER_CLEAR_BUTTON // 21, 200000 + WIDX_FILTER_CLEAR_BUTTON, // 21, 200000 + WIDX_FILTER_RIDE_TAB_FRAME, + WIDX_FILTER_RIDE_TAB_ALL, + WIDX_FILTER_RIDE_TAB_TRANSPORT, + WIDX_FILTER_RIDE_TAB_GENTLE, + WIDX_FILTER_RIDE_TAB_COASTER, + WIDX_FILTER_RIDE_TAB_THRILL, + WIDX_FILTER_RIDE_TAB_WATER, + WIDX_FILTER_RIDE_TAB_STALL }; static rct_widget window_editor_object_selection_widgets[] = { @@ -117,6 +135,14 @@ static rct_widget window_editor_object_selection_widgets[] = { { WWT_DROPDOWN_BUTTON, 0, 350, 463, 23, 34, 5261, 5265 }, { WWT_TEXT_BOX, 1, 4, 214, 46, 57, (uint32)_filter_string, STR_NONE }, { WWT_DROPDOWN_BUTTON, 1, 218, 287, 46, 57, 5277, STR_NONE }, + { WWT_RESIZE, 1, 3, 287, 73, 76, 0xFFFFFFFF, STR_NONE }, + { WWT_TAB, 1, 3, 33, 47, 73, 0x2000144E, 5349 }, + { WWT_TAB, 1, 34, 64, 47, 73, 0x2000144E, 5350 }, + { WWT_TAB, 1, 65, 95, 47, 73, 0x2000144E, 5351 }, + { WWT_TAB, 1, 96, 126, 47, 73, 0x2000144E, 5352 }, + { WWT_TAB, 1, 127, 157, 47, 73, 0x2000144E, 5353 }, + { WWT_TAB, 1, 158, 188, 47, 73, 0x2000144E, 5354 }, + { WWT_TAB, 1, 189, 219, 47, 73, 0x2000144E, 5355 }, { WIDGETS_END } }; @@ -182,6 +208,7 @@ static void window_editor_object_selection_manage_tracks(); static void editor_load_selected_objects(); static bool filter_string(rct_object_entry *entry); static bool filter_source(rct_object_entry *entry); +static bool filter_chunks(rct_object_entry *entry, rct_object_filters *filter); static void filter_update_counts(); static rct_object_entry DefaultSelectedObjects[] = { @@ -341,6 +368,28 @@ static void window_editor_object_selection_mouseup() case WIDX_TAB_11: window_editor_object_set_page(w, widgetIndex - WIDX_TAB_1); break; + case WIDX_FILTER_RIDE_TAB_ALL: + _filter_flags |= 0x7E0; + filter_update_counts(); + w->scrolls->v_top = 0; + + window_invalidate(w); + break; + case WIDX_FILTER_RIDE_TAB_TRANSPORT: + case WIDX_FILTER_RIDE_TAB_GENTLE: + case WIDX_FILTER_RIDE_TAB_COASTER: + case WIDX_FILTER_RIDE_TAB_THRILL: + case WIDX_FILTER_RIDE_TAB_WATER: + case WIDX_FILTER_RIDE_TAB_STALL: + _filter_flags &= ~0x7E0; + + _filter_flags |= (1 << (widgetIndex - WIDX_FILTER_RIDE_TAB_TRANSPORT + 5)); + + filter_update_counts(); + w->scrolls->v_top = 0; + + window_invalidate(w); + break; case WIDX_DROPDOWN1: w->list_information_type ^= 1; @@ -380,10 +429,10 @@ void window_editor_object_selection_mousedown(int widgetIndex, rct_window*w, rct case WIDX_FILTER_DROPDOWN: num_items = 4; - gDropdownItemsFormat[0] = 1142; - gDropdownItemsFormat[1] = 1142; - gDropdownItemsFormat[2] = 1142; - gDropdownItemsFormat[3] = 1142; + gDropdownItemsFormat[0] = 1156; + gDropdownItemsFormat[1] = 1156; + gDropdownItemsFormat[2] = 1156; + gDropdownItemsFormat[3] = 1156; gDropdownItemsArgs[0] = 2741; gDropdownItemsArgs[1] = 5262; gDropdownItemsArgs[2] = 5263; @@ -398,8 +447,9 @@ void window_editor_object_selection_mousedown(int widgetIndex, rct_window*w, rct num_items ); - gDropdownItemsChecked = _filter_flags; + gDropdownItemsChecked = _filter_flags & 0xF; break; + } } @@ -415,7 +465,6 @@ static void window_editor_object_selection_dropdown() return; switch (widgetIndex) { case WIDX_FILTER_DROPDOWN: - _filter_flags ^= (1 << dropdownIndex); filter_update_counts(); @@ -640,6 +689,39 @@ static void window_editor_object_selection_invalidate() w->widgets[WIDX_LIST].right = 587 - x; w->widgets[WIDX_PREVIEW].left = 537 - (x >> 1); w->widgets[WIDX_PREVIEW].right = w->widgets[WIDX_PREVIEW].left + 113; + + bool ridePage = (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS); + w->widgets[WIDX_LIST].top = (ridePage ? 94 : 60); + w->widgets[WIDX_FILTER_STRING_BUTTON].top = (ridePage ? 80 : 46); + w->widgets[WIDX_FILTER_STRING_BUTTON].bottom = (ridePage ? 91 : 57); + w->widgets[WIDX_FILTER_CLEAR_BUTTON].top = (ridePage ? 80 : 46); + w->widgets[WIDX_FILTER_CLEAR_BUTTON].bottom = (ridePage ? 91 : 57); + + if (ridePage) { + w->enabled_widgets |= (1 << WIDX_FILTER_RIDE_TAB_ALL) | (1 << WIDX_FILTER_RIDE_TAB_TRANSPORT) | + (1 << WIDX_FILTER_RIDE_TAB_GENTLE) | (1 << WIDX_FILTER_RIDE_TAB_COASTER) | (1 << WIDX_FILTER_RIDE_TAB_THRILL) | + (1 << WIDX_FILTER_RIDE_TAB_WATER) | (1 << WIDX_FILTER_RIDE_TAB_STALL); + for (i = 0; i < 7; i++) + w->pressed_widgets &= ~(1 << (WIDX_FILTER_RIDE_TAB_ALL + i)); + if ((_filter_flags & 0x7E0) == 0x7E0) + w->pressed_widgets |= (1 << WIDX_FILTER_RIDE_TAB_ALL); + else { + for (int i = 0; i < 6; i++) { + if (_filter_flags & (1 << (5 + i))) + w->pressed_widgets |= (uint64)(1 << (WIDX_FILTER_RIDE_TAB_TRANSPORT + i)); + } + } + w->widgets[WIDX_FILTER_RIDE_TAB_FRAME].type = WWT_RESIZE; + for (int i = WIDX_FILTER_RIDE_TAB_ALL; i <= WIDX_FILTER_RIDE_TAB_STALL; i++) + w->widgets[i].type = WWT_TAB; + } + else { + w->enabled_widgets &= ~((1 << WIDX_FILTER_RIDE_TAB_ALL) | (1 << WIDX_FILTER_RIDE_TAB_TRANSPORT) | + (1 << WIDX_FILTER_RIDE_TAB_GENTLE) | (1 << WIDX_FILTER_RIDE_TAB_COASTER) | (1 << WIDX_FILTER_RIDE_TAB_THRILL) | + (1 << WIDX_FILTER_RIDE_TAB_WATER) | (1 << WIDX_FILTER_RIDE_TAB_STALL)); + for (int i = WIDX_FILTER_RIDE_TAB_FRAME; i <= WIDX_FILTER_RIDE_TAB_STALL; i++) + w->widgets[i].type = WWT_EMPTY; + } } /** @@ -659,6 +741,17 @@ static void window_editor_object_selection_paint() window_paint_get_registers(w, dpi); + /*if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) { + gfx_fill_rect_inset(dpi, + w->x + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].left - 1, + w->y + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].bottom, + w->x + w->widgets[WIDX_FILTER_RIDE_TAB_STALL].right + 1, + w->y + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].bottom + 2, + w->colours[1], + 0x10 + ); + }*/ + window_draw_widgets(w, dpi); // Draw tabs @@ -672,6 +765,22 @@ static void window_editor_object_selection_paint() gfx_draw_sprite(dpi, 5458 + i, x, y, 0); } + const int ride_tabs[] = { 5458, 0x200015A1, 5542, 0x200015AA, 5557 + 5, 5551, 5530, 5327 }; + + // Draw ride tabs + if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) { + for (i = 0; i < 7; i++) { + widget = &w->widgets[WIDX_FILTER_RIDE_TAB_ALL + i]; + if (widget->type == WWT_EMPTY) + continue; + + x = w->x + widget->left; + y = w->y + widget->top; + gfx_draw_sprite(dpi, ride_tabs[i] | (w->colours[1] << 19), x, y, 0); + } + + } + // Preview background widget = &w->widgets[WIDX_PREVIEW]; gfx_fill_rect( @@ -823,6 +932,7 @@ static void window_editor_object_selection_scrollpaint() int x, y, i, colour, colour2, numObjects, type; short scrollIndex; rct_object_entry *entry; + rct_object_filters *filter; rct_window *w; rct_drawpixelinfo *dpi; uint8 *itemFlags; @@ -839,9 +949,10 @@ static void window_editor_object_selection_scrollpaint() itemFlags = RCT2_GLOBAL(0x009ADAEC, uint8*); y = 0; for (i = 0; i < numObjects; i++) { + filter = get_object_filter(i); type = entry->flags & 0x0F; source = (entry->flags & 0xF0) >> 4; - if (type == w->selected_tab && !(*itemFlags & 0x20) && filter_source(entry) && filter_string(entry)) { + if (type == w->selected_tab && !(*itemFlags & 0x20) && filter_source(entry) && filter_string(entry) && filter_chunks(entry, filter)) { if (y + 12 >= dpi->y && y <= dpi->y + dpi->height) { // Draw checkbox if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && !(*itemFlags & 0x20)) @@ -949,13 +1060,15 @@ static int window_editor_object_selection_select_object(int flags, rct_object_en */ static int get_object_from_object_selection(uint8 object_type, int y, uint8 *object_selection_flags, rct_object_entry **installed_entry) { + rct_object_filters *filter; *installed_entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); uint8 source; int object_count = 0; for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + filter = get_object_filter(RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) - i); source = ((*installed_entry)->flags & 0xF0) >> 4; - if (((*installed_entry)->flags & 0xF) == object_type && filter_source(*installed_entry) && filter_string(*installed_entry)){ + if (((*installed_entry)->flags & 0xF) == object_type && filter_source(*installed_entry) && filter_string(*installed_entry) && filter_chunks(*installed_entry, filter)){ if (!(*selection_flags & 0x20)){ y -= 12; *object_selection_flags = *selection_flags; @@ -1106,17 +1219,33 @@ static bool filter_source(rct_object_entry *entry) return (_FILTER_RCT2 && source == 8) || (_FILTER_WW && source == 1) || (_FILTER_TT && source == 2) || (_FILTER_CUSTOM && source != 8 && source != 1 && source != 2); } +static bool filter_chunks(rct_object_entry *entry, rct_object_filters *filter) +{ + switch (entry->flags & 0x0F) { + case OBJECT_TYPE_RIDE: + if (_filter_flags & (1 << (filter->ride.category[0] + 5))) + return true; + if (_filter_flags & (1 << (filter->ride.category[1] + 5))) + return true; + + return false; + } + return true; +} + static void filter_update_counts() { if (!_FILTER_ALL || strlen(_filter_string) > 0) { rct_object_entry *installed_entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + rct_object_filters *filter; uint8 type; for (int i = 0; i < 11; i++) { _filter_object_counts[i] = 0; } for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i) { + filter = get_object_filter(RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) - i); type = installed_entry->flags & 0xF; - if (filter_source(installed_entry) && filter_string(installed_entry)) { + if (filter_source(installed_entry) && filter_string(installed_entry) && filter_chunks(installed_entry, filter)) { _filter_object_counts[type]++; } installed_entry = object_get_next(installed_entry);