diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 97749a8dcc..42fa301cb6 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -118,6 +118,67 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t case DDSP_DEMOLISH_AREA: DoCommandP(end_tile, start_tile, _ctrl_pressed ? 1 : 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); break; + case DDSP_DEMOLISH_TREES: + // loop through every tile and send a demolish command for each tree + // orthogonal area + TileIndex tree_start_tile, prev_tile; + tree_start_tile = prev_tile = 0; + if (!_ctrl_pressed) { + OrthogonalTileArea square_area = OrthogonalTileArea(start_tile, end_tile); + TILE_AREA_LOOP(curr_tile, square_area) + { + // if we're on a consecutive tile + if (curr_tile == prev_tile + 1) { + if (GetTileType(prev_tile) != MP_TREES && GetTileType(curr_tile) == MP_TREES) { + tree_start_tile = curr_tile; + } else if (GetTileType(prev_tile) == MP_TREES && GetTileType(curr_tile) != MP_TREES) { + DoCommandP(tree_start_tile, prev_tile, 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + } + // remaining cases include: both prev and curr are trees, or both prev and curr are not trees + /** + * first tile of the search, or we've just jumped to a new row + * (so prev_tile is last tile of previous row and curr_tile is first tile of new row) + */ + } else { + if (GetTileType(prev_tile) == MP_TREES) { + DoCommandP(tree_start_tile, prev_tile, 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + } + if (GetTileType(curr_tile) == MP_TREES) { + tree_start_tile = curr_tile; + } + } + prev_tile = curr_tile; + } + // at this point prev_tile is the last tile of the selection + + // diagonal area (not working optimally yet) + } + //*/ + else { + DiagonalTileArea diagonal_area = DiagonalTileArea(start_tile, end_tile); + DIAGONAL_TILE_AREA_LOOP(curr_tile, diagonal_area) + { + // same as above but with a different criteria for consecutive tiles + TileIndexDiffC tile_diff = TileIndexToTileIndexDiffC(curr_tile, prev_tile); + if ((tile_diff.x == 1 && tile_diff.y == 1) || (tile_diff.x == -1 && tile_diff.y == -1)){ + if (GetTileType(prev_tile) != MP_TREES && GetTileType(curr_tile) == MP_TREES) { + tree_start_tile = curr_tile; + } else if (GetTileType(prev_tile) == MP_TREES && GetTileType(curr_tile) != MP_TREES) { + DoCommandP(tree_start_tile, prev_tile, 1, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + } + } else { + if (GetTileType(prev_tile) == MP_TREES) { + DoCommandP(tree_start_tile, prev_tile, 1, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + } + if (GetTileType(curr_tile) == MP_TREES) { + tree_start_tile = curr_tile; + } + } + prev_tile = curr_tile; + } + } + //*/ + break; case DDSP_RAISE_AND_LEVEL_AREA: DoCommandP(end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_RAISE_LAND_HERE), CcTerraform); break; @@ -197,6 +258,11 @@ struct TerraformToolbarWindow : Window { this->last_user_action = widget; break; + case WID_TT_DEMOLISH_TREES: // Demolish aka dynamite button + HandlePlacePushButton(this, WID_TT_DEMOLISH_TREES, ANIMCURSOR_DEMOLISH, HT_RECT | HT_DIAGONAL); + this->last_user_action = widget; + break; + case WID_TT_BUY_LAND: // Buy land button HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT); this->last_user_action = widget; @@ -238,6 +304,10 @@ struct TerraformToolbarWindow : Window { PlaceProc_DemolishArea(tile); break; + case WID_TT_DEMOLISH_TREES: // Demolish trees only + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_TREES); + break; + case WID_TT_BUY_LAND: // Buy land button DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound_SPLAT_RAIL); break; @@ -268,6 +338,7 @@ struct TerraformToolbarWindow : Window { switch (select_proc) { default: NOT_REACHED(); case DDSP_DEMOLISH_AREA: + case DDSP_DEMOLISH_TREES: case DDSP_RAISE_AND_LEVEL_AREA: case DDSP_LOWER_AND_LEVEL_AREA: case DDSP_LEVEL_AREA: @@ -329,6 +400,8 @@ static const NWidgetPart _nested_terraform_widgets[] = { NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_DEMOLISH), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_DEMOLISH_TREES), SetMinimalSize(22, 22), + SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_BUY_LAND), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_BUY_LAND, STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND), NWidget(WWT_PUSHIMGBTN, COLOUR_DARK_GREEN, WID_TT_PLANT_TREES), SetMinimalSize(22, 22), diff --git a/src/tilearea_type.h b/src/tilearea_type.h index 45bfb3d4c0..36bb89f3c9 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -231,4 +231,6 @@ public: */ #define TILE_AREA_LOOP(var, ta) for (OrthogonalTileIterator var(ta); var != INVALID_TILE; ++var) +#define DIAGONAL_TILE_AREA_LOOP(var, ta) for (DiagonalTileIterator var(ta); var != INVALID_TILE; ++var) + #endif /* TILEAREA_TYPE_H */ diff --git a/src/viewport_type.h b/src/viewport_type.h index f2942298ad..bfaa67e1ad 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -96,6 +96,7 @@ DECLARE_ENUM_AS_BIT_SET(ViewportPlaceMethod) */ enum ViewportDragDropSelectionProcess { DDSP_DEMOLISH_AREA, ///< Clear area + DDSP_DEMOLISH_TREES, ///< Clear trees DDSP_RAISE_AND_LEVEL_AREA, ///< Raise / level area DDSP_LOWER_AND_LEVEL_AREA, ///< Lower / level area DDSP_LEVEL_AREA, ///< Level area diff --git a/src/widgets/terraform_widget.h b/src/widgets/terraform_widget.h index 7f8a4c4d1b..60e5a9fbd6 100644 --- a/src/widgets/terraform_widget.h +++ b/src/widgets/terraform_widget.h @@ -20,6 +20,7 @@ enum TerraformToolbarWidgets { WID_TT_RAISE_LAND, ///< Raise land button. WID_TT_LEVEL_LAND, ///< Level land button. WID_TT_DEMOLISH, ///< Demolish aka dynamite button. + WID_TT_DEMOLISH_TREES, ///< Demolish trees only WID_TT_BUY_LAND, ///< Buy land button. WID_TT_PLANT_TREES, ///< Plant trees button (note: opens separate window, no place-push-button). WID_TT_PLACE_SIGN, ///< Place sign button.