diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 2eeb90605d..0f82efe2c3 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3766,6 +3766,9 @@ STR_6315 :{WINDOW_COLOUR_2}Pathfind Goal: {BLACK}{INT32}, {INT32}, {INT32} di STR_6316 :{WINDOW_COLOUR_2}Pathfind history: STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} STR_6318 :Network desync detected.{NEWLINE}Log file: {STRING} +STR_6319 :{WINDOW_COLOUR_2}Block Brake Closed +STR_6320 :{WINDOW_COLOUR_2}Indestructible +STR_6321 :{WINDOW_COLOUR_2}Addition is broken ############# # Scenarios # diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 151425bcb3..989bc5daca 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Feature: [#8558] Guest debugging tab. - Feature: [#8659] Banner and sign texts are now shown in tooltips. - Feature: [#8687] New multiplayer toolbar icon showing network status with reconnect option. +- Feature: [#8791] Improved tile element flag manipulation in Tile Inspector. - Feature: [#8919] Allow setting ride price from console. - Feature: [#8963] Add missing Czech letters to sprite font, use sprite font for Czech. - Feature: [#9154] Change map toolbar icon with current viewport rotation. diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 1b1ebbbc09..69b79b6755 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -110,7 +110,6 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { WIDX_COLUMN_BASEHEIGHT, WIDX_COLUMN_CLEARANCEHEIGHT, WIDX_COLUMN_GHOSTFLAG, - WIDX_COLUMN_BROKENFLAG, WIDX_COLUMN_LASTFLAG, WIDX_GROUPBOX_DETAILS, WIDX_GROUPBOX_PROPERTIES, @@ -133,6 +132,7 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { WIDX_PATH_SPINNER_HEIGHT = PAGE_WIDGETS, WIDX_PATH_SPINNER_HEIGHT_INCREASE, WIDX_PATH_SPINNER_HEIGHT_DECREASE, + WIDX_PATH_CHECK_BROKEN, WIDX_PATH_CHECK_SLOPED, WIDX_PATH_CHECK_EDGE_NE, // Note: This is NOT named after the world orientation, but after the way WIDX_PATH_CHECK_EDGE_E, // it looks in the window (top corner is north). Their order is important, @@ -149,6 +149,8 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { WIDX_TRACK_SPINNER_HEIGHT_INCREASE, WIDX_TRACK_SPINNER_HEIGHT_DECREASE, WIDX_TRACK_CHECK_CHAIN_LIFT, + WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED, + WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE, // Scenery WIDX_SCENERY_SPINNER_HEIGHT = PAGE_WIDGETS, @@ -214,11 +216,10 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { // Column offsets for the table headers #define COL_X_TYPE 3 // Type -#define COL_X_BH (COL_X_TYPE + 300) // Base height +#define COL_X_BH (COL_X_TYPE + 312) // Base height #define COL_X_CH (COL_X_BH + 20) // Clearance height #define COL_X_GF (COL_X_CH + 20) // Ghost flag -#define COL_X_BF (COL_X_GF + 12) // Broken flag -#define COL_X_LF (COL_X_BF + 12) // Last for tile flag +#define COL_X_LF (COL_X_GF + 12) // Last for tile flag #define PADDING_BOTTOM 15 #define GROUPBOX_PADDING 6 @@ -263,8 +264,7 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { { WWT_TABLE_HEADER, 1, COL_X_TYPE, COL_X_BH - 1, 42, 42 + 13, STR_NONE, STR_NONE }, /* Type */ \ { WWT_TABLE_HEADER, 1, COL_X_BH, COL_X_CH - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_BASE_HEIGHT }, /* Base height */ \ { WWT_TABLE_HEADER, 1, COL_X_CH, COL_X_GF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_CLEARANCE_HEIGHT }, /* Clearance height */ \ - { WWT_TABLE_HEADER, 1, COL_X_GF, COL_X_BF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_GHOST }, /* Ghost flag */ \ - { WWT_TABLE_HEADER, 1, COL_X_BF, COL_X_LF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_BROKEN }, /* Broken flag */ \ + { WWT_TABLE_HEADER, 1, COL_X_GF, COL_X_LF - 1, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_GHOST }, /* Ghost flag */ \ { WWT_TABLE_HEADER, 1, COL_X_LF, WW - 3, 42, 42 + 13, STR_NONE, STR_TILE_INSPECTOR_FLAG_LAST }, /* Last of tile flag */ \ { WWT_GROUPBOX, 1, 6, WW - 6, -1, -1, STR_NONE, STR_NONE }, /* Details group box */ \ { WWT_GROUPBOX, 1, 6, WW - 6, -1, -1, STR_TILE_INSPECTOR_GROUPBOX_PROPERTIES, STR_NONE } /* Properties group box */ @@ -293,13 +293,14 @@ static rct_widget SurfaceWidgets[] = { }; #define PAT_GBPB PADDING_BOTTOM // Path group box properties bottom -#define PAT_GBPT (PAT_GBPB + 16 + 4 * 21) // Path group box properties top +#define PAT_GBPT (PAT_GBPB + 16 + 5 * 21) // Path group box properties top #define PAT_GBDB (PAT_GBPT + GROUPBOX_PADDING) // Path group box info bottom #define PAT_GBDT (PAT_GBDB + 20 + 2 * 11) // Path group box info top static rct_widget PathWidgets[] = { MAIN_TILE_INSPECTOR_WIDGETS, SPINNER_WIDGETS (1, GBBL(1), GBBR(1), GBBT(WH - PAT_GBPT, 0) + 3, GBBB(WH - PAT_GBPT, 0) - 3, STR_NONE, STR_NONE), // WIDX_PATH_SPINNER_HEIGHT{,_INCREASE,_DECREASE} - { WWT_CHECKBOX, 1, GBBF(WH - PAT_GBPT, 0, 1), STR_TILE_INSPECTOR_PATH_SLOPED, STR_NONE }, // WIDX_PATH_CHECK_SLOPED + { WWT_CHECKBOX, 1, GBBF(WH - PAT_GBPT, 0, 1), STR_TILE_INSPECTOR_PATH_BROKEN, STR_NONE }, // WIDX_PATH_CHECK_BROKEN + { WWT_CHECKBOX, 1, GBBF(WH - PAT_GBPT, 0, 2), STR_TILE_INSPECTOR_PATH_SLOPED, STR_NONE }, // WIDX_PATH_CHECK_SLOPED { WWT_CHECKBOX, 1, CHK(GBBL(1) + 14 * 3, GBBT(WH - PAT_GBPT, 2) + 7 * 1), STR_NONE, STR_NONE }, // WIDX_PATH_CHECK_EDGE_NE { WWT_CHECKBOX, 1, CHK(GBBL(1) + 14 * 4, GBBT(WH - PAT_GBPT, 2) + 7 * 2), STR_NONE, STR_NONE }, // WIDX_PATH_CHECK_EDGE_E { WWT_CHECKBOX, 1, CHK(GBBL(1) + 14 * 3, GBBT(WH - PAT_GBPT, 2) + 7 * 3), STR_NONE, STR_NONE }, // WIDX_PATH_CHECK_EDGE_SE @@ -312,7 +313,7 @@ static rct_widget PathWidgets[] = { }; #define TRA_GBPB PADDING_BOTTOM // Track group box properties bottom -#define TRA_GBPT (TRA_GBPB + 16 + 3 * 21) // Track group box properties top +#define TRA_GBPT (TRA_GBPB + 16 + 5 * 21) // Track group box properties top #define TRA_GBDB (TRA_GBPT + GROUPBOX_PADDING) // Track group box info bottom #define TRA_GBDT (TRA_GBDB + 20 + 7 * 11) // Track group box info top static rct_widget TrackWidgets[] = { @@ -320,6 +321,8 @@ static rct_widget TrackWidgets[] = { { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 0), STR_TILE_INSPECTOR_TRACK_ENTIRE_TRACK_PIECE, STR_NONE }, // WIDX_TRACK_CHECK_APPLY_TO_ALL SPINNER_WIDGETS (1, GBBL(1), GBBR(1), GBBT(WH - TRA_GBPT, 1) + 3, GBBB(WH - TRA_GBPT, 1) - 3, STR_NONE, STR_NONE), // WIDX_TRACK_SPINNER_HEIGHT{,_INCREASE,_DECREASE} { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 2), STR_TILE_INSPECTOR_TRACK_CHAIN_LIFT, STR_NONE }, // WIDX_TRACK_CHECK_CHAIN_LIFT + { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 3), STR_TILE_INSPECTOR_TRACK_BLOCK_BRAKE, STR_NONE }, // WIDX_PATH_CHECK_BLOCK_BRAKE_CLOSED + { WWT_CHECKBOX, 1, GBBF(WH - TRA_GBPT, 0, 4), STR_TILE_INSPECTOR_TRACK_IS_INDESTRUCTIBLE, STR_NONE }, // WIDX_PATH_CHECK_IS_INDESTRUCTIBLE { WIDGETS_END }, }; @@ -501,8 +504,8 @@ static rct_window_event_list TileInspectorWindowEvents = { static uint64_t PageEnabledWidgets[] = { (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_SURFACE_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_SURFACE_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_SURFACE_BUTTON_REMOVE_FENCES) | (1ULL << WIDX_SURFACE_BUTTON_RESTORE_FENCES) | (1ULL << WIDX_SURFACE_CHECK_CORNER_N) | (1ULL << WIDX_SURFACE_CHECK_CORNER_E) | (1ULL << WIDX_SURFACE_CHECK_CORNER_S) | (1ULL << WIDX_SURFACE_CHECK_CORNER_W) | (1ULL << WIDX_SURFACE_CHECK_DIAGONAL), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_PATH_CHECK_SLOPED) | (1ULL << WIDX_PATH_CHECK_EDGE_N) | (1ULL << WIDX_PATH_CHECK_EDGE_NE) | (1ULL << WIDX_PATH_CHECK_EDGE_E) | (1ULL << WIDX_PATH_CHECK_EDGE_SE) | (1ULL << WIDX_PATH_CHECK_EDGE_S) | (1ULL << WIDX_PATH_CHECK_EDGE_SW) | (1ULL << WIDX_PATH_CHECK_EDGE_W) | (1ULL << WIDX_PATH_CHECK_EDGE_NW), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_TRACK_CHECK_APPLY_TO_ALL) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_TRACK_CHECK_CHAIN_LIFT), + (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_PATH_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_PATH_CHECK_SLOPED) | (1ULL << WIDX_PATH_CHECK_BROKEN) | (1ULL << WIDX_PATH_CHECK_EDGE_N) | (1ULL << WIDX_PATH_CHECK_EDGE_NE) | (1ULL << WIDX_PATH_CHECK_EDGE_E) | (1ULL << WIDX_PATH_CHECK_EDGE_SE) | (1ULL << WIDX_PATH_CHECK_EDGE_S) | (1ULL << WIDX_PATH_CHECK_EDGE_SW) | (1ULL << WIDX_PATH_CHECK_EDGE_W) | (1ULL << WIDX_PATH_CHECK_EDGE_NW), + (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_TRACK_CHECK_APPLY_TO_ALL) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_TRACK_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_TRACK_CHECK_CHAIN_LIFT) | (1ULL << WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED) | (1ULL << WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_SCENERY_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_SCENERY_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_N) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_E) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_S) | (1ULL << WIDX_SCENERY_CHECK_QUARTER_W) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_N) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_E) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_S) | (1ULL << WIDX_SCENERY_CHECK_COLLISION_W), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_ENTRANCE_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_ENTRANCE_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_ENTRANCE_BUTTON_MAKE_USABLE), (1ULL << WIDX_CLOSE) | (1ULL << WIDX_BUTTON_CORRUPT) | (1ULL << WIDX_BUTTON_REMOVE) | (1ULL << WIDX_BUTTON_ROTATE) | (1ULL << WIDX_BUTTON_COPY) | (1ULL << WIDX_WALL_SPINNER_HEIGHT_INCREASE) | (1ULL << WIDX_WALL_SPINNER_HEIGHT_DECREASE) | (1ULL << WIDX_WALL_DROPDOWN_SLOPE) | (1ULL << WIDX_WALL_DROPDOWN_SLOPE_BUTTON), @@ -710,6 +713,13 @@ static void window_tile_inspector_path_set_sloped(int32_t elementIndex, bool slo elementIndex, GAME_COMMAND_MODIFY_TILE, sloped, 0); } +static void window_tile_inspector_path_set_broken(int32_t elementIndex, bool broken) +{ + game_do_command( + TILE_INSPECTOR_PATH_SET_BROKEN, GAME_COMMAND_FLAG_APPLY, windowTileInspectorTileX | (windowTileInspectorTileY << 8), + elementIndex, GAME_COMMAND_MODIFY_TILE, broken, 0); +} + static void window_tile_inspector_path_toggle_edge(int32_t elementIndex, int32_t cornerIndex) { openrct2_assert(elementIndex >= 0 && elementIndex < windowTileInspectorElementCount, "elementIndex out of range"); @@ -751,6 +761,21 @@ static void window_tile_inspector_track_block_set_lift(int32_t elementIndex, boo elementIndex, GAME_COMMAND_MODIFY_TILE, entireTrackBlock, chain); } +static void window_tile_inspector_track_set_block_brake(int32_t elementIndex, bool blockBrake) +{ + game_do_command( + TILE_INSPECTOR_TRACK_SET_BLOCK_BRAKE, GAME_COMMAND_FLAG_APPLY, + windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, blockBrake, 0); +} + +static void window_tile_inspector_track_set_indestructible(int32_t elementIndex, bool isIndestructible) +{ + game_do_command( + TILE_INSPECTOR_TRACK_SET_INDESTRUCTIBLE, GAME_COMMAND_FLAG_APPLY, + windowTileInspectorTileX | (windowTileInspectorTileY << 8), elementIndex, GAME_COMMAND_MODIFY_TILE, isIndestructible, + 0); +} + static void window_tile_inspector_quarter_tile_set(int32_t elementIndex, const int32_t quarterIndex) { // quarterIndex is widget index relative to WIDX_SCENERY_CHECK_QUARTER_N, so a value from 0-3 @@ -867,6 +892,9 @@ static void window_tile_inspector_mouseup(rct_window* w, rct_widgetindex widgetI case WIDX_PATH_CHECK_SLOPED: window_tile_inspector_path_set_sloped(windowTileInspectorSelectedIndex, !tileElement->AsPath()->IsSloped()); break; + case WIDX_PATH_CHECK_BROKEN: + window_tile_inspector_path_set_broken(windowTileInspectorSelectedIndex, !tileElement->AsPath()->IsBroken()); + break; case WIDX_PATH_CHECK_EDGE_E: case WIDX_PATH_CHECK_EDGE_S: case WIDX_PATH_CHECK_EDGE_W: @@ -910,6 +938,14 @@ static void window_tile_inspector_mouseup(rct_window* w, rct_widgetindex widgetI window_tile_inspector_track_block_set_lift(windowTileInspectorSelectedIndex, entireTrackBlock, newLift); break; } + case WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED: + window_tile_inspector_track_set_block_brake( + windowTileInspectorSelectedIndex, !tileElement->AsTrack()->BlockBrakeClosed()); + break; + case WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE: + window_tile_inspector_track_set_indestructible( + windowTileInspectorSelectedIndex, !tileElement->AsTrack()->IsIndestructible()); + break; } // switch widget index break; @@ -1495,25 +1531,28 @@ static void window_tile_inspector_invalidate(rct_window* w) w->widgets[WIDX_PATH_SPINNER_HEIGHT_INCREASE].bottom = GBBB(propertiesAnchor, 0) - 4; w->widgets[WIDX_PATH_SPINNER_HEIGHT_DECREASE].top = GBBT(propertiesAnchor, 0) + 4; w->widgets[WIDX_PATH_SPINNER_HEIGHT_DECREASE].bottom = GBBB(propertiesAnchor, 0) - 4; - w->widgets[WIDX_PATH_CHECK_SLOPED].top = GBBT(propertiesAnchor, 1) + 2; - w->widgets[WIDX_PATH_CHECK_SLOPED].bottom = GBBT(propertiesAnchor, 1) + 15; - w->widgets[WIDX_PATH_CHECK_EDGE_N].top = GBBT(propertiesAnchor, 2) + 7 * 0; + w->widgets[WIDX_PATH_CHECK_BROKEN].top = GBBT(propertiesAnchor, 1); + w->widgets[WIDX_PATH_CHECK_BROKEN].bottom = GBBB(propertiesAnchor, 1); + w->widgets[WIDX_PATH_CHECK_SLOPED].top = GBBT(propertiesAnchor, 2); + w->widgets[WIDX_PATH_CHECK_SLOPED].bottom = GBBB(propertiesAnchor, 2); + w->widgets[WIDX_PATH_CHECK_EDGE_N].top = GBBT(propertiesAnchor, 3) + 7 * 0; w->widgets[WIDX_PATH_CHECK_EDGE_N].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_N].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_NE].top = GBBT(propertiesAnchor, 2) + 7 * 1; + w->widgets[WIDX_PATH_CHECK_EDGE_NE].top = GBBT(propertiesAnchor, 3) + 7 * 1; w->widgets[WIDX_PATH_CHECK_EDGE_NE].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_NE].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_E].top = GBBT(propertiesAnchor, 2) + 7 * 2; + w->widgets[WIDX_PATH_CHECK_EDGE_E].top = GBBT(propertiesAnchor, 3) + 7 * 2; w->widgets[WIDX_PATH_CHECK_EDGE_E].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_E].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_SE].top = GBBT(propertiesAnchor, 2) + 7 * 3; + w->widgets[WIDX_PATH_CHECK_EDGE_SE].top = GBBT(propertiesAnchor, 3) + 7 * 3; w->widgets[WIDX_PATH_CHECK_EDGE_SE].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_SE].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_S].top = GBBT(propertiesAnchor, 2) + 7 * 4; + w->widgets[WIDX_PATH_CHECK_EDGE_S].top = GBBT(propertiesAnchor, 3) + 7 * 4; w->widgets[WIDX_PATH_CHECK_EDGE_S].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_S].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_SW].top = GBBT(propertiesAnchor, 2) + 7 * 3; + w->widgets[WIDX_PATH_CHECK_EDGE_SW].top = GBBT(propertiesAnchor, 3) + 7 * 3; w->widgets[WIDX_PATH_CHECK_EDGE_SW].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_SW].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_W].top = GBBT(propertiesAnchor, 2) + 7 * 2; + w->widgets[WIDX_PATH_CHECK_EDGE_W].top = GBBT(propertiesAnchor, 3) + 7 * 2; w->widgets[WIDX_PATH_CHECK_EDGE_W].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_W].top + 13; - w->widgets[WIDX_PATH_CHECK_EDGE_NW].top = GBBT(propertiesAnchor, 2) + 7 * 1; + w->widgets[WIDX_PATH_CHECK_EDGE_NW].top = GBBT(propertiesAnchor, 3) + 7 * 1; w->widgets[WIDX_PATH_CHECK_EDGE_NW].bottom = w->widgets[WIDX_PATH_CHECK_EDGE_NW].top + 13; widget_set_checkbox_value(w, WIDX_PATH_CHECK_SLOPED, tileElement->AsPath()->IsSloped()); + widget_set_checkbox_value(w, WIDX_PATH_CHECK_BROKEN, tileElement->AsPath()->IsBroken()); widget_set_checkbox_value( w, WIDX_PATH_CHECK_EDGE_NE, tileElement->AsPath()->GetEdges() & (1 << ((0 - get_current_rotation()) & 3))); widget_set_checkbox_value( @@ -1542,8 +1581,14 @@ static void window_tile_inspector_invalidate(rct_window* w) w->widgets[WIDX_TRACK_SPINNER_HEIGHT_DECREASE].bottom = GBBB(propertiesAnchor, 1) - 4; w->widgets[WIDX_TRACK_CHECK_CHAIN_LIFT].top = GBBT(propertiesAnchor, 2); w->widgets[WIDX_TRACK_CHECK_CHAIN_LIFT].bottom = GBBB(propertiesAnchor, 2); + w->widgets[WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED].top = GBBT(propertiesAnchor, 3); + w->widgets[WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED].bottom = GBBB(propertiesAnchor, 3); + w->widgets[WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE].top = GBBT(propertiesAnchor, 4); + w->widgets[WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE].bottom = GBBB(propertiesAnchor, 4); widget_set_checkbox_value(w, WIDX_TRACK_CHECK_APPLY_TO_ALL, windowTileInspectorApplyToAll); widget_set_checkbox_value(w, WIDX_TRACK_CHECK_CHAIN_LIFT, tileElement->AsTrack()->HasChain()); + widget_set_checkbox_value(w, WIDX_TRACK_CHECK_BLOCK_BRAKE_CLOSED, tileElement->AsTrack()->BlockBrakeClosed()); + widget_set_checkbox_value(w, WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE, tileElement->AsTrack()->IsIndestructible()); break; case TILE_INSPECTOR_PAGE_SCENERY: { @@ -1711,12 +1756,6 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) dpi, STR_TILE_INSPECTOR_FLAG_GHOST_SHORT, gCommonFormatArgs, w->colours[1], w->x + widget->left + 1, w->y + widget->top + 1, widget->right - widget->left); } - if ((widget = &w->widgets[WIDX_COLUMN_BROKENFLAG])->type != WWT_EMPTY) - { - gfx_draw_string_left_clipped( - dpi, STR_TILE_INSPECTOR_FLAG_BROKEN_SHORT, gCommonFormatArgs, w->colours[1], w->x + widget->left + 1, - w->y + widget->top + 1, widget->right - widget->left); - } if ((widget = &w->widgets[WIDX_COLUMN_LASTFLAG])->type != WWT_EMPTY) { gfx_draw_string_left_clipped( @@ -2200,7 +2239,6 @@ static void window_tile_inspector_scrollpaint(rct_window* w, rct_drawpixelinfo* const int32_t baseHeight = tileElement->base_height; const int32_t clearanceHeight = tileElement->clearance_height; const bool ghost = tileElement->IsGhost(); - const bool broken = tileElement->AsPath() == nullptr ? false : tileElement->AsPath()->IsBroken(); const bool last = tileElement->IsLastForTile(); const rct_string_id stringFormat = (selectedRow || hoveredRow) ? STR_WHITE_STRING : STR_WINDOW_COLOUR_2_STRINGID; @@ -2222,17 +2260,13 @@ static void window_tile_inspector_scrollpaint(rct_window* w, rct_drawpixelinfo* set_format_arg(2, int32_t, clearanceHeight); gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_CH, y); - // Checkmarks for ghost, broken en last for tile + // Checkmarks for ghost and last for tile set_format_arg(0, rct_string_id, STR_STRING); set_format_arg(2, char*, CheckBoxMarkString); if (ghost) { gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_GF, y); } - if (broken) - { - gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_BF, y); - } if (last) { gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_LF, y); diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 9764813223..d0fa8b27ca 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -3939,6 +3939,9 @@ enum STR_MULTITHREADING_TIP = 6306, STR_TILE_INSPECTOR_COLOUR_SCHEME = 6307, + STR_TILE_INSPECTOR_TRACK_BLOCK_BRAKE = 6319, + STR_TILE_INSPECTOR_TRACK_IS_INDESTRUCTIBLE = 6320, + STR_TILE_INSPECTOR_PATH_BROKEN = 6321, STR_MAP_TOOLTIP_BANNER_STRINGID_STRINGID = 6308, diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 88d59b0a14..8117a00413 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -2323,6 +2323,13 @@ void game_command_modify_tile( *ebx = tile_inspector_path_set_sloped(x, y, elementIndex, sloped, flags); break; } + case TILE_INSPECTOR_PATH_SET_BROKEN: + { + const int32_t elementIndex = *edx; + const bool broken = *edi; + *ebx = tile_inspector_path_set_broken(x, y, elementIndex, broken, flags); + break; + } case TILE_INSPECTOR_PATH_TOGGLE_EDGE: { const int32_t elementIndex = *edx; @@ -2358,6 +2365,20 @@ void game_command_modify_tile( *ebx = tile_inspector_track_set_chain(x, y, elementIndex, entireTrackBlock, setChain, flags); break; } + case TILE_INSPECTOR_TRACK_SET_BLOCK_BRAKE: + { + const int32_t elementIndex = *edx; + const bool blockBrake = *edi; + *ebx = tile_inspector_track_set_block_brake(x, y, elementIndex, blockBrake, flags); + break; + } + case TILE_INSPECTOR_TRACK_SET_INDESTRUCTIBLE: + { + const int32_t elementIndex = *edx; + const bool isIndestructible = *edi; + *ebx = tile_inspector_track_set_indestructible(x, y, elementIndex, isIndestructible, flags); + break; + } case TILE_INSPECTOR_SCENERY_SET_QUARTER_LOCATION: { const int32_t elementIndex = *edx; diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 20f67bb87b..630389d180 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -625,6 +625,30 @@ int32_t tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementInde return 0; } +int32_t tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, int32_t flags) +{ + TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); + + if (pathElement == nullptr || pathElement->GetType() != TILE_ELEMENT_TYPE_PATH) + return MONEY32_UNDEFINED; + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + pathElement->AsPath()->SetIsBroken(broken); + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); + if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX + && (uint32_t)y == windowTileInspectorTileY) + { + window_invalidate(tileInspectorWindow); + } + } + + return 0; +} + int32_t tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t edgeIndex, int32_t flags) { TileElement* const pathElement = map_get_nth_element_at(x, y, elementIndex); @@ -973,6 +997,55 @@ int32_t tile_inspector_track_set_chain( return 0; } +int32_t tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, int32_t flags) +{ + TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + + if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) + return MONEY32_UNDEFINED; + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + trackElement->AsTrack()->SetBlockBrakeClosed(blockBrake); + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); + if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX + && (uint32_t)y == windowTileInspectorTileY) + { + window_invalidate(tileInspectorWindow); + } + } + + return 0; +} + +int32_t tile_inspector_track_set_indestructible( + int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, int32_t flags) +{ + TileElement* const trackElement = map_get_nth_element_at(x, y, elementIndex); + + if (trackElement == nullptr || trackElement->GetType() != TILE_ELEMENT_TYPE_TRACK) + return MONEY32_UNDEFINED; + + if (flags & GAME_COMMAND_FLAG_APPLY) + { + trackElement->AsTrack()->SetIsIndestructible(isIndestructible); + + map_invalidate_tile_full(x << 5, y << 5); + + rct_window* const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); + if (tileInspectorWindow != nullptr && (uint32_t)x == windowTileInspectorTileX + && (uint32_t)y == windowTileInspectorTileY) + { + window_invalidate(tileInspectorWindow); + } + } + + return 0; +} + int32_t tile_inspector_scenery_set_quarter_location( int32_t x, int32_t y, int32_t elementIndex, int32_t quarterIndex, int32_t flags) { diff --git a/src/openrct2/world/TileInspector.h b/src/openrct2/world/TileInspector.h index ab759f963f..90262a2959 100644 --- a/src/openrct2/world/TileInspector.h +++ b/src/openrct2/world/TileInspector.h @@ -39,6 +39,7 @@ enum TILE_INSPECTOR_INSTRUCTION_TYPE TILE_INSPECTOR_SURFACE_TOGGLE_CORNER, TILE_INSPECTOR_SURFACE_TOGGLE_DIAGONAL, TILE_INSPECTOR_PATH_SET_SLOPE, + TILE_INSPECTOR_PATH_SET_BROKEN, TILE_INSPECTOR_PATH_TOGGLE_EDGE, TILE_INSPECTOR_ENTRANCE_MAKE_USABLE, TILE_INSPECTOR_WALL_SET_SLOPE, @@ -48,6 +49,8 @@ enum TILE_INSPECTOR_INSTRUCTION_TYPE TILE_INSPECTOR_SCENERY_SET_QUARTER_COLLISION, TILE_INSPECTOR_BANNER_TOGGLE_BLOCKING_EDGE, TILE_INSPECTOR_CORRUPT_CLAMP, + TILE_INSPECTOR_TRACK_SET_BLOCK_BRAKE, + TILE_INSPECTOR_TRACK_SET_INDESTRUCTIBLE, }; int32_t tile_inspector_insert_corrupt_at(int32_t x, int32_t y, int16_t elementIndex, int32_t flags); @@ -61,10 +64,14 @@ int32_t tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool enabl int32_t tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t cornerIndex, int32_t flags); int32_t tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, int32_t flags); int32_t tile_inspector_path_set_sloped(int32_t x, int32_t y, int32_t elementIndex, bool sloped, int32_t flags); +int32_t tile_inspector_path_set_broken(int32_t x, int32_t y, int32_t elementIndex, bool broken, int32_t flags); int32_t tile_inspector_path_toggle_edge(int32_t x, int32_t y, int32_t elementIndex, int32_t cornerIndex, int32_t flags); int32_t tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elementIndex, int32_t flags); int32_t tile_inspector_wall_set_slope(int32_t x, int32_t y, int32_t elementIndex, int32_t slopeValue, int32_t flags); int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t elementIndex, int8_t offset, int32_t flags); +int32_t tile_inspector_track_set_block_brake(int32_t x, int32_t y, int32_t elementIndex, bool blockBrake, int32_t flags); +int32_t tile_inspector_track_set_indestructible( + int32_t x, int32_t y, int32_t elementIndex, bool isIndestructible, int32_t flags); int32_t tile_inspector_track_set_chain( int32_t x, int32_t y, int32_t elementIndex, bool entireTrackBlock, bool setChain, int32_t flags); int32_t tile_inspector_scenery_set_quarter_location(