diff --git a/src/openrct2/windows/tile_inspector.c b/src/openrct2/windows/tile_inspector.c index 4756a01f7d..c77ea68bcf 100644 --- a/src/openrct2/windows/tile_inspector.c +++ b/src/openrct2/windows/tile_inspector.c @@ -693,24 +693,26 @@ static void window_tile_inspector_copy_element(rct_window *w) static void window_tile_inspector_paste_element(rct_window *w) { - rct_map_element *const pastedElement = map_element_insert(windowTileInspectorTileX, windowTileInspectorTileY, tileInspectorCopiedElement.base_height, 0); - if (pastedElement == NULL) { - // map_element_insert displays an error message on failure - window_error_open(STR_CANT_PASTE, STR_MAP_ELEMENT_LIMIT_REACHED); - return; - } + // Construct the data to send using the surface's properties + sint32 bytes[2] = { 0 }; + bytes[0] |= tileInspectorCopiedElement.type << 24; + bytes[0] |= tileInspectorCopiedElement.flags << 16; + bytes[0] |= tileInspectorCopiedElement.base_height << 8; + bytes[0] |= tileInspectorCopiedElement.clearance_height; + bytes[1] |= tileInspectorCopiedElement.properties.surface.slope << 24; + bytes[1] |= tileInspectorCopiedElement.properties.surface.terrain << 16; + bytes[1] |= tileInspectorCopiedElement.properties.surface.grass_length << 8; + bytes[1] |= tileInspectorCopiedElement.properties.surface.ownership; - windowTileInspectorElementCount++; - bool lastForTile = map_element_is_last_for_tile(pastedElement); - *pastedElement = tileInspectorCopiedElement; - pastedElement->flags &= ~MAP_ELEMENT_FLAG_LAST_TILE; - if (lastForTile) { - pastedElement->flags |= MAP_ELEMENT_FLAG_LAST_TILE; - } - - // Make pasted element selected - const rct_map_element *mapElement = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); - w->selected_list_item = (sint16)(pastedElement - mapElement); + game_do_command( + TILE_INSPECTOR_ANY_PASTE, + GAME_COMMAND_FLAG_APPLY, + windowTileInspectorTileX | (windowTileInspectorTileY << 8), + bytes[0], + GAME_COMMAND_MODIFY_TILE, + bytes[1], + 0 + ); } static void window_tile_inspector_surface_toggle_corner(rct_map_element *mapElement, sint32 cornerIndex) @@ -1018,8 +1020,6 @@ static void window_tile_inspector_mouseup(rct_window *w, sint32 widgetIndex) break; case WIDX_BUTTON_PASTE: window_tile_inspector_paste_element(w); - map_invalidate_tile_full(windowTileInspectorTileX << 5, windowTileInspectorTileY << 5); - widget_invalidate(w, WIDX_LIST); break; case WIDX_BUTTON_MOVE_DOWN: window_tile_inspector_swap_elements(w->selected_list_item, w->selected_list_item + 1); diff --git a/src/openrct2/world/map.c b/src/openrct2/world/map.c index 73947f368e..db34fb48c2 100644 --- a/src/openrct2/world/map.c +++ b/src/openrct2/world/map.c @@ -5639,6 +5639,20 @@ void game_command_modify_tile(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx *ebx = tile_inspector_rotate_element_at(x, y, index, flags); return; } + case TILE_INSPECTOR_ANY_PASTE: + { + rct_map_element element_to_paste; + element_to_paste.type = *edx >> 24; + element_to_paste.flags = *edx >> 16; + element_to_paste.base_height = *edx >> 8; + element_to_paste.clearance_height = *edx; + element_to_paste.properties.surface.slope = *edi >> 24; + element_to_paste.properties.surface.terrain = *edi >> 16; + element_to_paste.properties.surface.grass_length = *edi >> 8; + element_to_paste.properties.surface.ownership = *edi; + *ebx = tile_inspector_paste_element_at(x, y, element_to_paste, flags); + return; + } default: log_error("invalid instruction"); *ebx = MONEY32_UNDEFINED; diff --git a/src/openrct2/world/tile_inspector.c b/src/openrct2/world/tile_inspector.c index 61d8608817..f36da86306 100644 --- a/src/openrct2/world/tile_inspector.c +++ b/src/openrct2/world/tile_inspector.c @@ -217,7 +217,53 @@ sint32 tile_inspector_rotate_element_at(sint32 x, sint32 y, sint32 element_index } map_invalidate_tile_full(x << 5, y << 5); - window_invalidate_by_class(WC_TILE_INSPECTOR); + + if ((uint32)x == windowTileInspectorTileX && (uint32)y == windowTileInspectorTileY) + { + window_invalidate_by_class(WC_TILE_INSPECTOR); + } + } + + return 0; +} + +sint32 tile_inspector_paste_element_at(sint32 x, sint32 y, rct_map_element element, sint32 flags) +{ + // Make sure there is enough space for the new element + if (!map_check_free_elements_and_reorganise(1)) + { + return MONEY32_UNDEFINED; + } + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + rct_map_element *const pastedElement = map_element_insert(x, y, element.base_height, 0); + + bool lastForTile = map_element_is_last_for_tile(pastedElement); + *pastedElement = element; + pastedElement->flags &= ~MAP_ELEMENT_FLAG_LAST_TILE; + if (lastForTile) + { + pastedElement->flags |= MAP_ELEMENT_FLAG_LAST_TILE; + } + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window *const tile_inspector_window = window_find_by_class(WC_TILE_INSPECTOR); + if (tile_inspector_window != NULL && (uint32)x == windowTileInspectorTileX && (uint32)y == windowTileInspectorTileY) + { + windowTileInspectorElementCount++; + + // Select new element if there was none selected already + sint16 new_index = (sint16)(pastedElement - map_get_first_element_at(x, y)); + if (tile_inspector_window->selected_list_item == -1) + tile_inspector_window->selected_list_item = new_index; + else if (tile_inspector_window->selected_list_item >= new_index) + tile_inspector_window->selected_list_item++; + + window_tile_inspector_auto_set_buttons(tile_inspector_window); + window_invalidate(tile_inspector_window); + } } return 0; diff --git a/src/openrct2/world/tile_inspector.h b/src/openrct2/world/tile_inspector.h index ffb8dd0ba5..aa984c63e7 100644 --- a/src/openrct2/world/tile_inspector.h +++ b/src/openrct2/world/tile_inspector.h @@ -36,9 +36,11 @@ typedef enum { TILE_INSPECTOR_ANY_SWAP, TILE_INSPECTOR_ANY_INSERT_CORRUPT, TILE_INSPECTOR_ANY_ROTATE, + TILE_INSPECTOR_ANY_PASTE, } tile_inspector_instruction; sint32 tile_inspector_insert_corrupt_at(sint32 x, sint32 y, sint16 element_index, sint32 flags); sint32 tile_inspector_remove_element_at(sint32 x, sint32 y, sint16 element_index, sint32 flags); sint32 tile_inspector_swap_elements(sint32 x, sint32 y, sint16 first, sint16 second, sint32 flags); -sint32 tile_inspector_rotate_element_at(sint32 x, sint32 y, sint32 element_index, sint32 flags); \ No newline at end of file +sint32 tile_inspector_rotate_element_at(sint32 x, sint32 y, sint32 element_index, sint32 flags); +sint32 tile_inspector_paste_element_at(sint32 x, sint32 y, rct_map_element element, sint32 flags);