diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index d3a1bdd0cd..2e145c2c6e 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -1677,6 +1677,9 @@ enum { STR_TUTORIAL_CUSTOM_RIDES = 3386, STR_TUTORIAL_ROLLER_COASTER = 3387, + STR_SAVE_TRACK_SCENERY_UNABLE_TO_SELECT_ADDITIONAL_ITEM_OF_SCENERY = 3389, + STR_SAVE_TRACK_SCENERY_TOO_MANY_ITEMS_SELECTED = 3390, + STR_OBJECTIVE_2_NONE = 2397, STR_OBJECTIVE_2_NUMBER_OF_GUESTS_AT_A_GIVEN_DATE = STR_OBJECTIVE_2_NONE + 1, STR_OBJECTIVE_2_PARK_VALUE_AT_A_GIVEN_DATE = STR_OBJECTIVE_2_NONE + 2, diff --git a/src/ride/track.c b/src/ride/track.c index 22fe6ab0d5..8bcf72593f 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -239,9 +239,11 @@ const rct_trackdefinition gTrackDefinitions_INCORRECT[] = { { TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_LEFT_LARGE_HALF_LOOP_DOWN }; +rct_map_element **gTrackSavedMapElements = (rct_map_element**)0x00F63674; + static bool track_save_should_select_scenery_around(int rideIndex, rct_map_element *mapElement); static void track_save_select_nearby_scenery_for_tile(int rideIndex, int cx, int cy); -static void track_save_add_map_element(int mapElementSelectType, int x, int y, rct_map_element *mapElement); +static bool track_save_add_map_element(int interactionType, int x, int y, rct_map_element *mapElement); uint32* sub_6AB49A(rct_object_entry* entry){ rct_object_entry* object_list_entry = object_list_find(entry); @@ -3323,13 +3325,60 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int */ void track_save_reset_scenery() { - rct_map_element **savedMapElements = (rct_map_element**)0x00F63674; - RCT2_GLOBAL(0x009DA193, uint8) = 255; - savedMapElements[0] = (rct_map_element*)0xFFFFFFFF; + gTrackSavedMapElements[0] = (rct_map_element*)0xFFFFFFFF; gfx_invalidate_screen(); } +static bool track_save_contains_map_element(rct_map_element *mapElement) +{ + rct_map_element **savedMapElement; + + savedMapElement = gTrackSavedMapElements; + do { + if (*savedMapElement == mapElement) { + return true; + } + } while (*savedMapElement++ != (rct_map_element*)-1); + return false; +} + +/** + * + * rct2: 0x006D2B3C + */ +static bool track_save_add_map_element(int interactionType, int x, int y, rct_map_element *mapElement) +{ + return !(RCT2_CALLPROC_X(0x006D2B3C, x, interactionType | (0 << 8), y, (int)mapElement, 0, 0, 0) & 0x100); +} + +/** + * + * rct2: 0x006D2B3C + */ +static void track_save_remove_map_element(int interactionType, int x, int y, rct_map_element *mapElement) +{ + RCT2_CALLPROC_X(0x006D2B3C, x, interactionType | (1 << 8), y, (int)mapElement, 0, 0, 0); +} + +/** + * + * rct2: 0x006D2B07 + */ +void track_save_toggle_map_element(int interactionType, int x, int y, rct_map_element *mapElement) +{ + if (track_save_contains_map_element(mapElement)) { + track_save_remove_map_element(interactionType, x, y, mapElement); + } else { + if (!track_save_add_map_element(interactionType, x, y, mapElement)) { + window_error_open( + STR_SAVE_TRACK_SCENERY_UNABLE_TO_SELECT_ADDITIONAL_ITEM_OF_SCENERY, + STR_SAVE_TRACK_SCENERY_TOO_MANY_ITEMS_SELECTED + ); + } + } +} + /** * * rct2: 0x006D303D @@ -3383,53 +3432,35 @@ static void track_save_select_nearby_scenery_for_tile(int rideIndex, int cx, int for (int x = cx - 1; x <= cx + 1; x++) { mapElement = map_get_first_element_at(x, y); do { - int mapElementSelectType = 0; + int interactionType = VIEWPORT_INTERACTION_ITEM_NONE; switch (map_element_get_type(mapElement)) { case MAP_ELEMENT_TYPE_PATH: if (!(mapElement->type & 1)) - mapElementSelectType = 6; + interactionType = VIEWPORT_INTERACTION_ITEM_FOOTPATH; else if (mapElement->properties.path.addition_status == rideIndex) - mapElementSelectType = 6; + interactionType = VIEWPORT_INTERACTION_ITEM_FOOTPATH; break; case MAP_ELEMENT_TYPE_SCENERY: - mapElementSelectType = 5; + interactionType = VIEWPORT_INTERACTION_ITEM_SCENERY; break; case MAP_ELEMENT_TYPE_FENCE: - mapElementSelectType = 9; + interactionType = VIEWPORT_INTERACTION_ITEM_WALL; break; case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: - mapElementSelectType = 10; + interactionType = VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY; break; } - if (mapElementSelectType != 0) { - bool mapElementAlreadySelected = false; - rct_map_element **savedMapElement = (rct_map_element**)0x00F63674; - while (*savedMapElement != (rct_map_element*)0xFFFFFFFF) { - if (*savedMapElement == mapElement) { - mapElementAlreadySelected = true; - break; - } - savedMapElement++; + if (interactionType != VIEWPORT_INTERACTION_ITEM_NONE) { + if (!track_save_contains_map_element(mapElement)) { + track_save_add_map_element(interactionType, x * 32, y * 32, mapElement); } - - if (!mapElementAlreadySelected) - track_save_add_map_element(mapElementSelectType, x * 32, y * 32, mapElement); } } while (!map_element_is_last_for_tile(mapElement++)); } } } -/** - * - * rct2: 0x006D2B3C - */ -static void track_save_add_map_element(int mapElementSelectType, int x, int y, rct_map_element *mapElement) -{ - RCT2_CALLPROC_X(0x006D2B3C, x, mapElementSelectType, y, (int)mapElement, 0, 0, 0); -} - const rct_preview_track *get_track_def_from_ride(rct_ride *ride, int trackType) { return ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) ? diff --git a/src/ride/track.h b/src/ride/track.h index df71a307c7..89a302f241 100644 --- a/src/ride/track.h +++ b/src/ride/track.h @@ -493,6 +493,8 @@ typedef struct { extern const rct_trackdefinition *gFlatRideTrackDefinitions; extern const rct_trackdefinition *gTrackDefinitions; +extern rct_map_element **gTrackSavedMapElements; + void track_load_list(ride_list_item item); int sub_67726A(const char *path); rct_track_design *track_get_info(int index, uint8** preview); @@ -511,6 +513,7 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int void track_save_reset_scenery(); void track_save_select_nearby_scenery(int rideIndex); +void track_save_toggle_map_element(int interactionType, int x, int y, rct_map_element *mapElement); const rct_preview_track *get_track_def_from_ride(rct_ride *ride, int trackType); const rct_preview_track *get_track_def_from_ride_index(int rideIndex, int trackType); diff --git a/src/windows/ride.c b/src/windows/ride.c index 3981ffa009..0620dd2c4b 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -4539,7 +4539,7 @@ static void setup_scenery_selection(rct_window* w){ RCT2_GLOBAL(0x00F64DE8, uint8) = (uint8)w->number; RCT2_GLOBAL(0x009DA193, uint8) = 0xFF; - RCT2_GLOBAL(0x00F63674, sint32) = -1; + gTrackSavedMapElements[0] = (rct_map_element*)-1; RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) |= (1 << 2); RCT2_GLOBAL(0x009DEA6F, uint8) |= 1; @@ -4706,11 +4706,23 @@ static void window_ride_measurements_update(rct_window *w) /** * - * rct2: 0x006AD4EB + * rct2: 0x006D2AE7 */ static void window_ride_measurements_tooldown(rct_window *w, int widgetIndex, int x, int y) { - RCT2_CALLPROC_X(0x006D2AE7, x, y, 0, widgetIndex, (int)w, 0, 0); + rct_map_element *mapElement; + sint16 mapX, mapY; + int interactionType; + + get_map_coordinates_from_pos(x, y, 0xFCCF, &mapX, &mapY, &interactionType, &mapElement, NULL); + switch (interactionType) { + case VIEWPORT_INTERACTION_ITEM_SCENERY: + case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY: + case VIEWPORT_INTERACTION_ITEM_WALL: + case VIEWPORT_INTERACTION_ITEM_FOOTPATH: + track_save_toggle_map_element(interactionType, mapX, mapY, mapElement); + break; + } } /**