fix basic object selection

This commit is contained in:
Ted John 2016-07-02 14:59:13 +01:00
parent aa62c3f03f
commit 4bed693344
5 changed files with 160 additions and 192 deletions

View File

@ -99,7 +99,6 @@
#define RCT2_ADDRESS_SCENARIO_TEXT_ENTRIES 0x009ADAE4 #define RCT2_ADDRESS_SCENARIO_TEXT_ENTRIES 0x009ADAE4
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8 #define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
#define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC
#define RCT2_ADDRESS_TOTAL_NO_IMAGES 0x009ADAF0 #define RCT2_ADDRESS_TOTAL_NO_IMAGES 0x009ADAF0
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280 #define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
@ -479,6 +478,8 @@
#define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319 #define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319
#define RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS 0x009AC861 #define RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS 0x009AC861
#define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC
#define RCT2_ADDRESS_TOOL_WINDOWNUMBER 0x009DE542 #define RCT2_ADDRESS_TOOL_WINDOWNUMBER 0x009DE542
#define RCT2_ADDRESS_TOOL_WINDOWCLASS 0x009DE544 #define RCT2_ADDRESS_TOOL_WINDOWCLASS 0x009DE544
#define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545 #define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545

View File

@ -559,21 +559,6 @@ static void editor_finalise_main_view()
gfx_invalidate_screen(); gfx_invalidate_screen();
} }
static bool editor_check_object_group_at_least_one_selected(int objectType)
{
uint32 numObjects = gInstalledObjectsCount;
rct_object_entry *entry = gInstalledObjects;
uint8 *objectFlag = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
for (uint32 i = 0; i < numObjects; i++) {
if ((entry->flags & 0x0F) == objectType && (*objectFlag & OBJECT_SELECTION_FLAG_SELECTED)) {
return true;
}
entry = object_get_next(entry);
objectFlag++;
}
return false;
}
/** /**
* *
* rct2: 0x006AB9B8 * rct2: 0x006AB9B8

View File

@ -42,4 +42,6 @@ void editor_open_windows_for_current_step();
bool editor_check_park(); bool editor_check_park();
int editor_check_object_selection(); int editor_check_object_selection();
bool editor_check_object_group_at_least_one_selected(int objectType);
#endif #endif

View File

@ -866,29 +866,6 @@ static int cc_twitch(const utf8 **argv, int argc)
return 0; return 0;
} }
static void editor_load_selected_objects_console()
{
uint8 *selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
rct_object_entry *installed_entry = gInstalledObjects;
if (gInstalledObjectsCount == 0)
return;
for (int i = gInstalledObjectsCount; i != 0; i--, selection_flags++) {
if (*selection_flags & 1) {
uint8 entry_index, entry_type;
if (!find_object_in_entry_group(installed_entry, &entry_type, &entry_index)){
int chunk_size;
if (!object_load_chunk(-1, installed_entry, &chunk_size)) {
log_error("Failed to load entry %.8s", installed_entry->name);
}
}
}
installed_entry = object_get_next(installed_entry);
}
}
static int cc_load_object(const utf8 **argv, int argc) { static int cc_load_object(const utf8 **argv, int argc) {
if (argc > 0) { if (argc > 0) {
utf8 path[MAX_PATH]; utf8 path[MAX_PATH];

View File

@ -220,11 +220,11 @@ static void window_editor_object_set_page(rct_window *w, int page);
static void window_editor_object_selection_set_pressed_tab(rct_window *w); static void window_editor_object_selection_set_pressed_tab(rct_window *w);
static void window_editor_object_selection_select_default_objects(); static void window_editor_object_selection_select_default_objects();
static void window_editor_object_selection_select_required_objects(); static void window_editor_object_selection_select_required_objects();
static int window_editor_object_selection_select_object(uint8 bh, int flags, rct_object_entry *entry); static int window_editor_object_selection_select_object(uint8 bh, int flags, const rct_object_entry *entry);
static int get_object_from_object_selection(uint8 object_type, int y); static int get_object_from_object_selection(uint8 object_type, int y);
static void window_editor_object_selection_manage_tracks(); static void window_editor_object_selection_manage_tracks();
static void editor_load_selected_objects(); static void editor_load_selected_objects();
static bool filter_selected(uint8* objectFlags); static bool filter_selected(uint8 objectFlags);
static bool filter_string(const ObjectRepositoryItem * item); static bool filter_string(const ObjectRepositoryItem * item);
static bool filter_source(const ObjectRepositoryItem * item); static bool filter_source(const ObjectRepositoryItem * item);
static bool filter_chunks(const ObjectRepositoryItem * item); static bool filter_chunks(const ObjectRepositoryItem * item);
@ -308,6 +308,10 @@ static list_item *_listItems = NULL;
static int _listSortType = RIDE_SORT_TYPE; static int _listSortType = RIDE_SORT_TYPE;
static bool _listSortDescending = false; static bool _listSortDescending = false;
static void * _loadedObject = NULL; static void * _loadedObject = NULL;
static uint8 * _objectSelectionFlags = NULL;
static int _numSelectedObjectsForType[11];
static int _numAvailableObjectsForType[11];
static bool _maxObjectsWasHit;
static void visible_list_dispose() static void visible_list_dispose()
{ {
@ -349,25 +353,24 @@ static void visible_list_refresh(rct_window *w)
list_item *currentListItem = &_listItems[0]; list_item *currentListItem = &_listItems[0];
const ObjectRepositoryItem *items = object_repository_get_items(); 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++) { for (int i = 0; i < numObjects; i++) {
uint8 selectionFlags = _objectSelectionFlags[i];
const ObjectRepositoryItem * item = &items[i]; const ObjectRepositoryItem * item = &items[i];
uint8 objectType = item->ObjectEntry.flags & 0x0F; uint8 objectType = item->ObjectEntry.flags & 0x0F;
if (objectType == w->selected_tab && !(*itemFlags & OBJECT_SELECTION_FLAG_6) && if (objectType == w->selected_tab && !(selectionFlags & OBJECT_SELECTION_FLAG_6) &&
filter_source(item) && filter_source(item) &&
filter_string(item) && filter_string(item) &&
filter_chunks(item) && filter_chunks(item) &&
filter_selected(itemFlags) filter_selected(selectionFlags)
) { ) {
rct_object_filters * filter = calloc(1, sizeof(rct_object_filters)); rct_object_filters * filter = calloc(1, sizeof(rct_object_filters));
currentListItem->repositoryItem = item; currentListItem->repositoryItem = item;
currentListItem->entry = (rct_object_entry *)&item->ObjectEntry; currentListItem->entry = (rct_object_entry *)&item->ObjectEntry;
currentListItem->filter = filter; currentListItem->filter = filter;
currentListItem->flags = itemFlags; currentListItem->flags = &_objectSelectionFlags[i];
currentListItem++; currentListItem++;
_numListItems++; _numListItems++;
} }
itemFlags++;
} }
_listItems = realloc(_listItems, _numListItems * sizeof(list_item)); _listItems = realloc(_listItems, _numListItems * sizeof(list_item));
@ -461,36 +464,35 @@ void window_editor_object_selection_open()
static void setup_track_manager_objects() static void setup_track_manager_objects()
{ {
uint8 ride_list[128] = { 0 }; uint8 ride_list[128] = { 0 };
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
int numObjects = object_repository_get_items_count(); int numObjects = object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numObjects; i > 0; --i) { for (int i = 0; i < numObjects; i++) {
uint8 * selectionFlags = &_objectSelectionFlags[i];
const ObjectRepositoryItem * item = &items[i]; const ObjectRepositoryItem * item = &items[i];
uint8 object_type = item->ObjectEntry.flags & 0xF; uint8 object_type = item->ObjectEntry.flags & 0xF;
if (object_type == OBJECT_TYPE_RIDE){ if (object_type == OBJECT_TYPE_RIDE){
*selection_flags |= OBJECT_SELECTION_FLAG_6; *selectionFlags |= OBJECT_SELECTION_FLAG_6;
for (uint8 j = 0; j < 3; j++) { for (uint8 j = 0; j < 3; j++) {
uint8 ride_type = item->RideType[j]; uint8 rideType = item->RideType[j];
if (ride_type == 0xFF) if (rideType == 0xFF)
continue; continue;
if (!ride_type_has_flag(ride_type, RIDE_TYPE_FLAG_HAS_TRACK)) if (!ride_type_has_flag(rideType, RIDE_TYPE_FLAG_HAS_TRACK))
continue; continue;
if (item->RideType[3] & (1 << 0)) { if (item->RideType[3] & (1 << 0)) {
*selection_flags &= ~OBJECT_SELECTION_FLAG_6; *selectionFlags &= ~OBJECT_SELECTION_FLAG_6;
} else if (ride_list[ride_type] & (1 << 0)) { } else if (ride_list[rideType] & (1 << 0)) {
continue; continue;
} else { } else {
ride_list[ride_type] |= (1 << 0); ride_list[rideType] |= (1 << 0);
*selection_flags &= ~OBJECT_SELECTION_FLAG_6; *selectionFlags &= ~OBJECT_SELECTION_FLAG_6;
} }
break; break;
} }
} }
selection_flags++;
} }
} }
@ -500,28 +502,25 @@ static void setup_track_manager_objects()
*/ */
static void setup_track_designer_objects() static void setup_track_designer_objects()
{ {
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
int numObjects = object_repository_get_items_count(); int numObjects = object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numObjects; i > 0; --i) { for (int i = 0; i < numObjects; i++) {
uint8 * selectionFlags = &_objectSelectionFlags[i];
const ObjectRepositoryItem * item = &items[i]; const ObjectRepositoryItem * item = &items[i];
uint8 object_type = item->ObjectEntry.flags & 0xF; uint8 objectType = item->ObjectEntry.flags & 0xF;
if (object_type == OBJECT_TYPE_RIDE){ if (objectType == OBJECT_TYPE_RIDE){
*selection_flags |= OBJECT_SELECTION_FLAG_6; *selectionFlags |= OBJECT_SELECTION_FLAG_6;
for (uint8 j = 0; j < 3; j++) { for (uint8 j = 0; j < 3; j++) {
uint8 ride_type = item->RideType[j]; uint8 rideType = item->RideType[j];
if (ride_type == 0xFF) if (rideType != 0xFF) {
continue; if (RideData4[rideType].flags & RIDE_TYPE_FLAG4_11) {
*selectionFlags &= ~OBJECT_SELECTION_FLAG_6;
if (!(RideData4[ride_type].flags & RIDE_TYPE_FLAG4_11)) break;
continue; }
}
*selection_flags &= ~OBJECT_SELECTION_FLAG_6;
break;
} }
} }
selection_flags++;
} }
} }
@ -529,8 +528,8 @@ static void setup_track_designer_objects()
* *
* rct2: 0x006AA82B * rct2: 0x006AA82B
*/ */
static void setup_in_use_selection_flags(){ static void setup_in_use_selection_flags()
{
for (uint8 object_type = 0; object_type < 11; object_type++){ for (uint8 object_type = 0; object_type < 11; object_type++){
for (uint16 i = 0; i < object_entry_group_counts[object_type]; i++){ for (uint16 i = 0; i < object_entry_group_counts[object_type]; i++){
RCT2_ADDRESS(0x0098DA38, uint8*)[object_type][i] = 0; RCT2_ADDRESS(0x0098DA38, uint8*)[object_type][i] = 0;
@ -601,35 +600,32 @@ static void setup_in_use_selection_flags(){
} }
} while (map_element_iterator_next(&iter)); } while (map_element_iterator_next(&iter));
for (uint8 ride_index = 0; ride_index < 0xFF; ride_index++){ for (uint8 ride_index = 0; ride_index < 0xFF; ride_index++) {
rct_ride* ride = get_ride(ride_index); rct_ride* ride = get_ride(ride_index);
if (ride->type == RIDE_TYPE_NULL) if (ride->type != RIDE_TYPE_NULL) {
continue; uint8 type = ride->subtype;
RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_RIDE][type] |= (1 << 0);
uint8 type = ride->subtype; }
RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_RIDE][type] |= (1 << 0);
} }
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
int numObjects = (int)object_repository_get_items_count(); int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numObjects; i > 0; --i) { for (int i = 0; i < numObjects; i++) {
uint8 *selectionFlags = &_objectSelectionFlags[i];
const ObjectRepositoryItem * item = &items[i]; const ObjectRepositoryItem * item = &items[i];
*selection_flags &= ~OBJECT_SELECTION_FLAG_IN_USE; *selectionFlags &= ~OBJECT_SELECTION_FLAG_IN_USE;
uint8 entry_type, entry_index; uint8 entryType, entryIndex;
if (find_object_in_entry_group(&item->ObjectEntry, &entry_type, &entry_index)) { if (find_object_in_entry_group(&item->ObjectEntry, &entryType, &entryIndex)) {
if (RCT2_ADDRESS(0x0098DA38, uint8*)[entry_type][entry_index] & (1 << 0)){ if (RCT2_ADDRESS(0x0098DA38, uint8*)[entryType][entryIndex] & (1 << 0)) {
*selection_flags |= *selectionFlags |=
OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_IN_USE |
OBJECT_SELECTION_FLAG_SELECTED; OBJECT_SELECTION_FLAG_SELECTED;
} }
if (RCT2_ADDRESS(0x0098DA38, uint8*)[entry_type][entry_index] & (1 << 1)){ if (RCT2_ADDRESS(0x0098DA38, uint8*)[entryType][entryIndex] & (1 << 1)) {
*selection_flags |= OBJECT_SELECTION_FLAG_SELECTED; *selectionFlags |= OBJECT_SELECTION_FLAG_SELECTED;
} }
} }
selection_flags++;
} }
} }
@ -640,43 +636,41 @@ static void setup_in_use_selection_flags(){
static int sub_6AB211() static int sub_6AB211()
{ {
int numObjects = (int)object_repository_get_items_count(); int numObjects = (int)object_repository_get_items_count();
_objectSelectionFlags = (uint8*)calloc(numObjects, sizeof(uint8));
RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) = malloc(numObjects); if (_objectSelectionFlags == NULL){
if (RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) == NULL){
log_error("Failed to allocate memory for object flag list."); log_error("Failed to allocate memory for object flag list.");
return 0; return 0;
} }
memset(RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*), 0, numObjects); for (uint8 objectType = 0; objectType < 11; objectType++) {
for (uint8 object_type = 0; object_type < 11; object_type++){ _numSelectedObjectsForType[objectType] = 0;
RCT2_ADDRESS(0x00F433F7, uint16)[object_type] = 0; _numAvailableObjectsForType[objectType] = 0;
RCT2_ADDRESS(0x00F433E1, uint16)[object_type] = 0;
} }
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numObjects; i > 0; --i) { for (int i = 0; i < numObjects; i++) {
uint8 object_type = items[i].ObjectEntry.flags & 0xF; uint8 objectType = items[i].ObjectEntry.flags & 0xF;
RCT2_ADDRESS(0x00F433E1, uint16)[object_type]++; _numAvailableObjectsForType[objectType]++;
} }
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER){ if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) {
setup_track_designer_objects(); setup_track_designer_objects();
} }
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER){ if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
setup_track_manager_objects(); setup_track_manager_objects();
} }
setup_in_use_selection_flags(); setup_in_use_selection_flags();
reset_selected_object_count_and_size(); reset_selected_object_count_and_size();
if (!(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))){ if (!(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) {
window_editor_object_selection_select_required_objects(); window_editor_object_selection_select_required_objects();
// To prevent it breaking in scenario mode. // To prevent it breaking in scenario mode.
if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) {
window_editor_object_selection_select_default_objects(); window_editor_object_selection_select_default_objects();
}
} }
reset_required_object_flags(); reset_required_object_flags();
@ -690,7 +684,7 @@ static int sub_6AB211()
*/ */
static void editor_object_flags_free() static void editor_object_flags_free()
{ {
SafeFree(RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*)); SafeFree(_objectSelectionFlags);
} }
/** /**
@ -719,16 +713,13 @@ void remove_selected_objects_from_research(const rct_object_entry* installedObje
*/ */
void unload_unselected_objects() void unload_unselected_objects()
{ {
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
int numItems = object_repository_get_items_count(); int numItems = object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numItems; i > 0; --i) { for (int i = 0; i < numItems; i++) {
if (!(*selection_flags & OBJECT_SELECTION_FLAG_SELECTED)){ if (!(_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)) {
remove_selected_objects_from_research(&items[i].ObjectEntry); remove_selected_objects_from_research(&items[i].ObjectEntry);
object_repository_unload(i); object_repository_unload(i);
} }
selection_flags++;
} }
} }
@ -1008,7 +999,7 @@ static void window_editor_object_selection_scroll_mousedown(rct_window *w, int s
if (!(object_selection_flags & OBJECT_SELECTION_FLAG_SELECTED)) if (!(object_selection_flags & OBJECT_SELECTION_FLAG_SELECTED))
ebx = 7; ebx = 7;
RCT2_GLOBAL(0xF43411, uint8) = 0; _maxObjectsWasHit = false;
if (!window_editor_object_selection_select_object(0, ebx, listItem->entry)) { if (!window_editor_object_selection_select_object(0, ebx, listItem->entry)) {
rct_string_id error_title = ebx & 1 ? rct_string_id error_title = ebx & 1 ?
STR_UNABLE_TO_SELECT_THIS_OBJECT : STR_UNABLE_TO_SELECT_THIS_OBJECT :
@ -1024,10 +1015,9 @@ static void window_editor_object_selection_scroll_mousedown(rct_window *w, int s
window_invalidate(w); window_invalidate(w);
} }
if (!RCT2_GLOBAL(0xF43411, uint8) & 1) if (_maxObjectsWasHit) {
return; window_error_open(STR_WARNING_TOO_MANY_OBJECTS_SELECTED, STR_NOT_ALL_OBJECTS_IN_THIS_SCENERY_GROUP_COULD_BE_SELECTED);
}
window_error_open(STR_WARNING_TOO_MANY_OBJECTS_SELECTED, STR_NOT_ALL_OBJECTS_IN_THIS_SCENERY_GROUP_COULD_BE_SELECTED);
} }
/** /**
@ -1299,7 +1289,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf
x = w->x + 3; x = w->x + 3;
y = w->y + w->height - 13; y = w->y + w->height - 13;
numSelected = RCT2_ADDRESS(0x00F433F7, uint16)[w->selected_tab]; numSelected = _numSelectedObjectsForType[w->selected_tab];
totalSelectable = object_entry_group_counts[w->selected_tab]; totalSelectable = object_entry_group_counts[w->selected_tab];
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
totalSelectable = 4; totalSelectable = 4;
@ -1508,13 +1498,11 @@ static void window_editor_object_selection_set_pressed_tab(rct_window *w)
*/ */
static void window_editor_object_selection_select_default_objects() static void window_editor_object_selection_select_default_objects()
{ {
int i; if (_numSelectedObjectsForType[0] == 0) {
for (int i = 0; i < countof(DefaultSelectedObjects); i++) {
if (RCT2_GLOBAL(0x00F433F7, uint16) != 0) window_editor_object_selection_select_object(0, 7, &DefaultSelectedObjects[i]);
return; }
}
for (i = 0; i < countof(DefaultSelectedObjects); i++)
window_editor_object_selection_select_object(0, 7, &DefaultSelectedObjects[i]);
} }
/** /**
@ -1535,8 +1523,17 @@ static void window_editor_object_selection_select_required_objects()
*/ */
void reset_selected_object_count_and_size() void reset_selected_object_count_and_size()
{ {
for (uint8 object_type = 0; object_type < 11; object_type++) { for (uint8 objectType = 0; objectType < 11; objectType++) {
RCT2_ADDRESS(0x00F433F7, uint16)[object_type] = 0; _numSelectedObjectsForType[objectType] = 0;
}
int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = 0; i < numObjects; i++) {
uint8 objectType = items[i].ObjectEntry.flags & 0xF;
if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED) {
_numSelectedObjectsForType[objectType]++;
}
} }
} }
@ -1546,21 +1543,19 @@ void reset_selected_object_count_and_size()
*/ */
void set_required_object_flags(rct_object_entry* required_object) void set_required_object_flags(rct_object_entry* required_object)
{ {
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
int numObjects = (int)object_repository_get_items_count(); int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numObjects; i > 0; --i) { for (int i = 0; i < numObjects; i++) {
const ObjectRepositoryItem * item = &items[i]; const ObjectRepositoryItem * item = &items[i];
if (object_entry_compare(required_object, &item->ObjectEntry)) { if (object_entry_compare(required_object, &item->ObjectEntry)) {
*selection_flags |= OBJECT_SELECTION_FLAG_REQUIRED; _objectSelectionFlags[i] |= OBJECT_SELECTION_FLAG_REQUIRED;
uint16 no_required_objects = item->NumRequiredObjects; uint16 numRequiredObjects = item->NumRequiredObjects;
for (; no_required_objects > 0; no_required_objects--) { for (uint16 j = 0; j < numRequiredObjects; j++) {
set_required_object_flags(&item->RequiredObjects[i]); set_required_object_flags(&item->RequiredObjects[j]);
} }
return; break;
} }
selection_flags++;
} }
} }
@ -1573,24 +1568,19 @@ void reset_required_object_flags()
int numObjects = (int)object_repository_get_items_count(); int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); for (int i = 0; i < numObjects; i++) {
for (int i = numObjects; i > 0; --i) { _objectSelectionFlags[i] &= ~OBJECT_SELECTION_FLAG_REQUIRED;
*selection_flags &= ~OBJECT_SELECTION_FLAG_REQUIRED;
selection_flags++;
} }
selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); for (int i = 0; i < numObjects; i++) {
for (int i = numObjects; i > 0; --i){
const ObjectRepositoryItem * item = &items[i]; const ObjectRepositoryItem * item = &items[i];
if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED){
uint16 no_required_objects = item->NumRequiredObjects; if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED) {
for (; no_required_objects > 0; no_required_objects--){ uint16 numRequiredObjects = item->NumRequiredObjects;
set_required_object_flags(&item->RequiredObjects[i]); for (uint16 j = 0; j < numRequiredObjects; j++) {
set_required_object_flags(&item->RequiredObjects[j]);
} }
} }
selection_flags++;
} }
} }
@ -1610,7 +1600,7 @@ void set_object_selection_error(uint8 is_master_object, rct_string_id error_msg)
* *
* rct2: 0x006AB54F * rct2: 0x006AB54F
*/ */
static int window_editor_object_selection_select_object(uint8 bh, int flags, rct_object_entry *entry) static int window_editor_object_selection_select_object(uint8 bh, int flags, const rct_object_entry *entry)
{ {
int numObjects = (int)object_repository_get_items_count(); int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * item = object_repository_find_object_by_entry(entry); const ObjectRepositoryItem * item = object_repository_find_object_by_entry(entry);
@ -1619,29 +1609,33 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct
return 0; return 0;
} }
uint8 * selection_flags; // Get repository item index
selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); int index = -1;
for (int i = numObjects; i > 0; --i) { const ObjectRepositoryItem * items = object_repository_get_items();
selection_flags++; for (int i = 0; i < numObjects; i++) {
if (&items[i] == item) {
index = i;
}
} }
if (!(flags & 1)){ uint8 * selectionFlags = &_objectSelectionFlags[index];
if (!(*selection_flags & OBJECT_SELECTION_FLAG_SELECTED)) if (!(flags & 1)) {
if (!(*selectionFlags & OBJECT_SELECTION_FLAG_SELECTED))
{ {
if (bh == 0){ if (bh == 0){
reset_required_object_flags(); reset_required_object_flags();
} }
return 1; return 1;
} }
else if (*selection_flags & OBJECT_SELECTION_FLAG_IN_USE){ else if (*selectionFlags & OBJECT_SELECTION_FLAG_IN_USE){
set_object_selection_error(bh, 3173); set_object_selection_error(bh, 3173);
return 0; return 0;
} }
else if (*selection_flags & OBJECT_SELECTION_FLAG_REQUIRED){ else if (*selectionFlags & OBJECT_SELECTION_FLAG_REQUIRED){
set_object_selection_error(bh, 3174); set_object_selection_error(bh, 3174);
return 0; return 0;
} }
else if (*selection_flags & OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED){ else if (*selectionFlags & OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED){
set_object_selection_error(bh, 3175); set_object_selection_error(bh, 3175);
return 0; return 0;
} }
@ -1655,9 +1649,9 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct
} }
} }
uint8 object_type = item->ObjectEntry.flags & 0xF; uint8 objectType = item->ObjectEntry.flags & 0xF;
RCT2_ADDRESS(0x00F433F7, uint16)[object_type]--; _numSelectedObjectsForType[objectType]--;
*selection_flags &= ~OBJECT_SELECTION_FLAG_SELECTED; *selectionFlags &= ~OBJECT_SELECTION_FLAG_SELECTED;
if (bh == 0) { if (bh == 0) {
reset_required_object_flags(); reset_required_object_flags();
} }
@ -1665,48 +1659,44 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct
} else { } else {
if (bh == 0) { if (bh == 0) {
if (flags & (1 << 3)) { if (flags & (1 << 3)) {
*selection_flags |= OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED; *selectionFlags |= OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED;
} }
} }
if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED) { if (*selectionFlags & OBJECT_SELECTION_FLAG_SELECTED) {
if (bh == 0) { if (bh == 0) {
reset_required_object_flags(); reset_required_object_flags();
} }
return 1; return 1;
} }
uint8 object_type = item->ObjectEntry.flags & 0xF; uint8 objectType = item->ObjectEntry.flags & 0xF;
uint16 no_objects = object_entry_group_counts[object_type]; uint16 maxObjects = object_entry_group_counts[objectType];
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) { if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) {
no_objects = 4; maxObjects = 4;
} }
if (no_objects <= RCT2_ADDRESS(0x00F433F7, uint16)[object_type]) { if (maxObjects <= _numSelectedObjectsForType[objectType]) {
set_object_selection_error(bh, 3171); set_object_selection_error(bh, 3171);
return 0; return 0;
} }
uint16 numRequiredObjects = item->NumRequiredObjects; for (uint16 j = 0; j < item->NumRequiredObjects; j++) {
rct_object_entry * required_objects = item->RequiredObjects; if (!window_editor_object_selection_select_object(++bh, flags, &item->RequiredObjects[j])) {
for (; numRequiredObjects != 0; numRequiredObjects--) {
if (!window_editor_object_selection_select_object(++bh, flags, required_objects)) {
if (bh != 0) { if (bh != 0) {
reset_selected_object_count_and_size(); reset_selected_object_count_and_size();
} }
return 0; return 0;
} }
required_objects++;
} }
uint16 numThemeObjects = item->NumThemeObjects; if (objectType == OBJECT_TYPE_SCENERY_SETS) {
rct_object_entry * theme_object = item->RequiredObjects; for (uint16 j = 0; j < item->NumThemeObjects; j++) {
for (; numThemeObjects != 0; numThemeObjects--) { if (flags & (1 << 2)) {
if (flags & (1 << 2)) { if (!window_editor_object_selection_select_object(++bh, flags, &item->ThemeObjects[j])) {
if (!window_editor_object_selection_select_object(++bh, flags, theme_object)) { _maxObjectsWasHit = true;
RCT2_GLOBAL(0x00F43411, uint8) |= 1; }
} }
} }
theme_object++;
} }
if (bh != 0 && !(flags & (1 << 1))) { if (bh != 0 && !(flags & (1 << 1))) {
@ -1716,14 +1706,14 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct
return 0; return 0;
} }
if (no_objects <= RCT2_ADDRESS(0x00F433F7, uint16)[object_type]) { if (maxObjects <= _numSelectedObjectsForType[objectType]) {
set_object_selection_error(bh, 3171); set_object_selection_error(bh, 3171);
return 0; return 0;
} }
RCT2_ADDRESS(0x00F433F7, uint16)[object_type]++; _numSelectedObjectsForType[objectType]++;
*selection_flags |= OBJECT_SELECTION_FLAG_SELECTED; *selectionFlags |= OBJECT_SELECTION_FLAG_SELECTED;
if (bh == 0) { if (bh == 0) {
reset_required_object_flags(); reset_required_object_flags();
} }
@ -1798,12 +1788,10 @@ static void window_editor_object_selection_manage_tracks()
*/ */
static void editor_load_selected_objects() static void editor_load_selected_objects()
{ {
uint8 *selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
int numObjects = (int)object_repository_get_items_count(); int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items(); const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = numObjects; i != 0; i--, selection_flags++) { for (int i = 0; i < numObjects; i++) {
if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED) { if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED) {
uint8 entry_index, entry_type; uint8 entry_index, entry_type;
if (!find_object_in_entry_group(&items[i].ObjectEntry, &entry_type, &entry_index)) { if (!find_object_in_entry_group(&items[i].ObjectEntry, &entry_type, &entry_index)) {
int chunk_size; int chunk_size;
@ -1874,14 +1862,15 @@ static void window_editor_object_selection_textinput(rct_window *w, int widgetIn
window_invalidate(w); window_invalidate(w);
} }
static bool filter_selected(uint8* objectFlag) { static bool filter_selected(uint8 objectFlag)
{
if (_FILTER_SELECTED == _FILTER_NONSELECTED) { if (_FILTER_SELECTED == _FILTER_NONSELECTED) {
return true; return true;
} }
if (_FILTER_SELECTED && *objectFlag & OBJECT_SELECTION_FLAG_SELECTED) { if (_FILTER_SELECTED && objectFlag & OBJECT_SELECTION_FLAG_SELECTED) {
return true; return true;
} }
else if (_FILTER_NONSELECTED && !(*objectFlag & OBJECT_SELECTION_FLAG_SELECTED)) { else if (_FILTER_NONSELECTED && !(objectFlag & OBJECT_SELECTION_FLAG_SELECTED)) {
return true; return true;
} }
else { else {
@ -1960,7 +1949,7 @@ static bool filter_chunks(const ObjectRepositoryItem * item)
static void filter_update_counts() static void filter_update_counts()
{ {
if (!_FILTER_ALL || strlen(_filter_string) > 0) { if (!_FILTER_ALL || strlen(_filter_string) > 0) {
uint8 *objectFlag = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); uint8 *selectionFlags = _objectSelectionFlags;
for (int i = 0; i < 11; i++) { for (int i = 0; i < 11; i++) {
_filter_object_counts[i] = 0; _filter_object_counts[i] = 0;
} }
@ -1972,12 +1961,12 @@ static void filter_update_counts()
if (filter_source(item) && if (filter_source(item) &&
filter_string(item) && filter_string(item) &&
filter_chunks(item) && filter_chunks(item) &&
filter_selected(objectFlag) filter_selected(*selectionFlags)
) { ) {
uint8 objectType = item->ObjectEntry.flags & 0xF; uint8 objectType = item->ObjectEntry.flags & 0xF;
_filter_object_counts[objectType]++; _filter_object_counts[objectType]++;
} }
objectFlag++; selectionFlags++;
} }
} }
} }
@ -1994,3 +1983,17 @@ static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem * item)
} }
return result; return result;
} }
bool editor_check_object_group_at_least_one_selected(int objectType)
{
int numObjects = (int)object_repository_get_items_count();
const ObjectRepositoryItem * items = object_repository_get_items();
for (int i = 0; i < numObjects; i++) {
uint8 objectType = items[i].ObjectEntry.flags & 0x0F;
if (objectType == objectType && (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)) {
return true;
}
}
return false;
}