1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 08:12:53 +01:00

fix filtering on object selection

This commit is contained in:
Ted John
2016-06-29 22:15:38 +01:00
parent 840179299c
commit db304cdfcb
8 changed files with 84 additions and 61 deletions

View File

@@ -26,6 +26,7 @@ extern "C"
}
interface IStream;
struct ObjectRepositoryItem;
class Object
{
@@ -52,4 +53,6 @@ public:
virtual uint8 GetObjectType() { return _objectEntry.flags & 0x0F; }
virtual const utf8 * GetName() abstract;
virtual void SetRepositoryItem(ObjectRepositoryItem * item) const { }
};

View File

@@ -273,6 +273,7 @@ private:
item.ObjectEntry = *object->GetObjectEntry();
item.Path = String::Duplicate(path);
item.Name = String::Duplicate(object->GetName());
object->SetRepositoryItem(&item);
AddItem(&item);
delete object;

View File

@@ -54,6 +54,8 @@ typedef struct ObjectRepositoryItem
#ifdef __cplusplus
class Object;
interface IObjectRepository
{
virtual ~IObjectRepository() { }

View File

@@ -17,6 +17,7 @@
#include "../core/IStream.hpp"
#include "../core/Memory.hpp"
#include "../core/Util.hpp"
#include "ObjectRepository.h"
#include "RideObject.h"
extern "C"
@@ -317,15 +318,6 @@ void RideObject::Load()
}
}
}
// TODO sort out this filter stuff
int di = _legacyType.ride_type[0] | (_legacyType.ride_type[1] << 8) | (_legacyType.ride_type[2] << 16);
if ((_legacyType.flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) &&
!rideTypeShouldLoseSeparateFlag(&_legacyType))
{
di |= 0x1000000;
}
RCT2_GLOBAL(0xF433DD, uint32) = di;
}
void RideObject::Unload()
@@ -352,3 +344,23 @@ const utf8 * RideObject::GetCapacity()
const utf8 * capacity = GetStringTable()->GetString(OBJ_STRING_ID_CAPACITY);
return capacity != nullptr ? capacity : "";
}
void RideObject::SetRepositoryItem(ObjectRepositoryItem * item) const
{
for (int i = 0; i < 3; i++)
{
item->RideType[i] = _legacyType.ride_type[i];
}
for (int i = 0; i < 2; i++)
{
item->RideCategory[i] = _legacyType.category[i];
}
uint8 flags = 0;
if ((_legacyType.flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE_NAME) &&
!rideTypeShouldLoseSeparateFlag(&_legacyType))
{
flags |= 0x1000000;
}
item->RideFlags = flags;
}

View File

@@ -44,6 +44,8 @@ public:
const utf8 * GetDescription();
const utf8 * GetCapacity();
void SetRepositoryItem(ObjectRepositoryItem * item) const;
private:
};

View File

@@ -78,7 +78,7 @@ bool rct1_read_sv4(const char *path, rct1_s4 *s4)
return success;
}
bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry)
bool rideTypeShouldLoseSeparateFlag(const rct_ride_entry *rideEntry)
{
if (!gConfigInterface.select_by_track_type) {
return false;

View File

@@ -745,7 +745,7 @@ bool rct1_read_sv4(const char *path, rct1_s4 *s4);
void rct1_import_s4(rct1_s4 *s4);
void rct1_fix_landscape();
int vehicle_preference_compare(uint8 rideType, const char * a, const char * b);
bool rideTypeShouldLoseSeparateFlag(rct_ride_entry *rideEntry);
bool rideTypeShouldLoseSeparateFlag(const rct_ride_entry *rideEntry);
bool rct1_load_saved_game(const char *path);
bool rct1_load_scenario(const char *path);

View File

@@ -27,6 +27,7 @@
#include "../management/research.h"
#include "../object.h"
#include "../object_list.h"
#include "../object/ObjectRepository.h"
#include "../rct1.h"
#include "../ride/ride.h"
#include "../ride/ride_data.h"
@@ -224,9 +225,9 @@ static int get_object_from_object_selection(uint8 object_type, int y, uint8 *obj
static void window_editor_object_selection_manage_tracks();
static void editor_load_selected_objects();
static bool filter_selected(uint8* objectFlags);
static bool filter_string(rct_object_entry *entry, rct_object_filters *filter);
static bool filter_source(rct_object_entry *entry);
static bool filter_chunks(rct_object_entry *entry, rct_object_filters *filter);
static bool filter_string(const ObjectRepositoryItem * item);
static bool filter_source(const ObjectRepositoryItem * item);
static bool filter_chunks(const ObjectRepositoryItem * item);
static void filter_update_counts();
void reset_selected_object_count_and_size();
@@ -282,6 +283,7 @@ enum {
};
typedef struct list_item {
const ObjectRepositoryItem * repositoryItem;
rct_object_entry *entry;
rct_object_filters *filter;
uint8 *flags;
@@ -305,8 +307,8 @@ static int visible_list_sort_ride_name(const void *rawA, const void *rawB)
list_item *a = (list_item*)rawA;
list_item *b = (list_item*)rawB;
const char *nameA = object_get_name(a->entry);
const char *nameB = object_get_name(b->entry);
const char *nameA = a->repositoryItem->Name;
const char *nameB = b->repositoryItem->Name;
return strcmp(nameA, nameB);
}
@@ -315,8 +317,8 @@ static int visible_list_sort_ride_type(const void *rawA, const void *rawB)
list_item *a = (list_item*)rawA;
list_item *b = (list_item*)rawB;
const char *rideTypeA = language_get_string(2 + a->filter->ride.ride_type);
const char *rideTypeB = language_get_string(2 + b->filter->ride.ride_type);
const char *rideTypeA = language_get_string(2 + a->repositoryItem->RideType[0]);
const char *rideTypeB = language_get_string(2 + b->repositoryItem->RideType[0]);
int result = strcmp(rideTypeA, rideTypeB);
if (result != 0)
return result;
@@ -326,31 +328,32 @@ static int visible_list_sort_ride_type(const void *rawA, const void *rawB)
static void visible_list_refresh(rct_window *w)
{
int numObjects = gInstalledObjectsCount;
int numObjects = (int)object_repository_get_items_count();
visible_list_dispose();
_listItems = malloc(numObjects * sizeof(list_item));
_numListItems = 0;
list_item *currentListItem = &_listItems[0];
rct_object_entry *entry = gInstalledObjects;
const ObjectRepositoryItem *items = object_repository_get_items();
uint8 *itemFlags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
for (int i = 0; i < numObjects; i++) {
rct_object_filters *filter = get_object_filter(i);
int type = entry->flags & 0x0F;
if (type == w->selected_tab && !(*itemFlags & OBJECT_SELECTION_FLAG_6)
&& filter_source(entry)
&& filter_string(entry, filter)
&& filter_chunks(entry, filter)
&& filter_selected(itemFlags)) {
currentListItem->entry = entry;
currentListItem->filter = filter;
currentListItem->flags = itemFlags;
currentListItem++;
_numListItems++;
const ObjectRepositoryItem * item = &items[i];
uint8 objectType = item->ObjectEntry.flags & 0x0F;
if (objectType == w->selected_tab && !(*itemFlags & OBJECT_SELECTION_FLAG_6) &&
filter_source(item) &&
filter_string(item) &&
filter_chunks(item) &&
filter_selected(itemFlags)
) {
rct_object_filters * filter = calloc(1, sizeof(rct_object_filters));
currentListItem->repositoryItem = item;
currentListItem->entry = (rct_object_entry *)&item->ObjectEntry;
currentListItem->filter = filter;
currentListItem->flags = itemFlags;
currentListItem++;
_numListItems++;
}
entry = object_get_next(entry);
itemFlags++;
}
@@ -1534,13 +1537,13 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
if (ridePage) {
// Draw ride type
strcpy(buffer, language_get_string(2 + listItem->filter->ride.ride_type));
strcpy(buffer, language_get_string(2 + listItem->repositoryItem->RideType[0]));
gfx_draw_string(dpi, bufferWithColour, colour, x, y);
x = w->widgets[WIDX_LIST_SORT_RIDE].left - w->widgets[WIDX_LIST].left;
}
// Draw text
strcpy(buffer, object_get_name(listItem->entry));
strcpy(buffer, listItem->repositoryItem->Name);
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
while (*buffer != 0 && *buffer != 9)
buffer++;
@@ -2115,26 +2118,26 @@ static bool filter_selected(uint8* objectFlag) {
}
}
static bool filter_string(rct_object_entry *entry, rct_object_filters *filter)
static bool filter_string(const ObjectRepositoryItem * item)
{
// Nothing to search for
if (_filter_string[0] == '\0')
return true;
// Object doesn't have a name
char *name = object_get_name(entry);
if (name[0] == '\0')
utf8 *name = item->Name;
if (name == NULL || name[0] == '\0')
return false;
// Get ride type
const char *ride_type = language_get_string(2 + filter->ride.ride_type);
const char *rideTypeName = language_get_string(2 + item->RideType[0]);
// Get object name (ride/vehicle for rides) and type name (rides only)
char name_lower[MAX_PATH];
char type_lower[MAX_PATH];
char filter_lower[sizeof(_filter_string)];
safe_strcpy(name_lower, name, MAX_PATH);
safe_strcpy(type_lower, ride_type, MAX_PATH);
safe_strcpy(type_lower, rideTypeName, MAX_PATH);
safe_strcpy(filter_lower, _filter_string, sizeof(_filter_string));
// Make use of lowercase characters only
@@ -2145,30 +2148,30 @@ static bool filter_string(rct_object_entry *entry, rct_object_filters *filter)
for (int i = 0; filter_lower[i] != '\0'; i++)
filter_lower[i] = (char)tolower(filter_lower[i]);
return strstr(name_lower, filter_lower) != NULL || (((entry->flags & 0x0F) == OBJECT_TYPE_RIDE) && strstr(type_lower, filter_lower) != NULL);
return strstr(name_lower, filter_lower) != NULL || (((item->ObjectEntry.flags & 0x0F) == OBJECT_TYPE_RIDE) && strstr(type_lower, filter_lower) != NULL);
}
static bool filter_source(rct_object_entry *entry)
static bool filter_source(const ObjectRepositoryItem * item)
{
if (_FILTER_ALL)
return true;
uint8 source = (entry->flags & 0xF0) >> 4;
uint8 source = (item->ObjectEntry.flags & 0xF0) >> 4;
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)
static bool filter_chunks(const ObjectRepositoryItem * item)
{
switch (entry->flags & 0x0F) {
switch (item->ObjectEntry.flags & 0x0F) {
case OBJECT_TYPE_RIDE:
if(!gConfigInterface.select_by_track_type) {
if (_filter_flags & (1 << (filter->ride.category[0] + 5)))
if (_filter_flags & (1 << (item->RideCategory[0] + 5)))
return true;
if (_filter_flags & (1 << (filter->ride.category[1] + 5)))
if (_filter_flags & (1 << (item->RideCategory[1] + 5)))
return true;
}
else {
if (_filter_flags & (1 << (gRideCategories[filter->ride.ride_type] + 5)))
if (_filter_flags & (1 << (gRideCategories[item->RideType[0]] + 5)))
return true;
}
return false;
@@ -2179,23 +2182,23 @@ static bool filter_chunks(rct_object_entry *entry, rct_object_filters *filter)
static void filter_update_counts()
{
if (!_FILTER_ALL || strlen(_filter_string) > 0) {
rct_object_entry *installed_entry = gInstalledObjects;
rct_object_filters *filter;
uint8 *objectFlag = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
uint8 type;
for (int i = 0; i < 11; i++) {
_filter_object_counts[i] = 0;
}
for (uint32 i = 0; i < gInstalledObjectsCount; i++) {
filter = get_object_filter(i);
type = installed_entry->flags & 0xF;
if (filter_source(installed_entry)
&& filter_string(installed_entry, filter)
&& filter_chunks(installed_entry, filter)
&& filter_selected(objectFlag)) {
_filter_object_counts[type]++;
size_t numObjects = object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items();
for (size_t i = 0; i < numObjects; i++) {
const ObjectRepositoryItem * item = &items[i];
if (filter_source(item) &&
filter_string(item) &&
filter_chunks(item) &&
filter_selected(objectFlag)
) {
uint8 objectType = item->ObjectEntry.flags & 0xF;
_filter_object_counts[objectType]++;
}
installed_entry = object_get_next(installed_entry);
objectFlag++;
}
}