Use Fn modifier to flatten land for the polyrail

This commit is contained in:
dP
2021-10-16 04:44:44 +03:00
parent c9e1b3eff1
commit e7c6f27931
4 changed files with 110 additions and 1 deletions

View File

@@ -74,6 +74,12 @@ This is usable for any OpenTTD servers
== CHANGELOG ==
*** 12.0 (?? Oct 2021) ***
- Automatically search servers when opening multiplayer window.
- Added TeamGame server filtering button.
- Show town population instead of name in IMBA minimap mode.
- In polyrail mode placing rail while holding Fn modifier will automatically flatten the land for it.
*** 12.0-RC1 (5 Oct 2021) ***
- Added experimental rail copy-paste tool.
- Added client list overlay (toggleable with a button in the regular client list window title).

View File

@@ -399,6 +399,93 @@ static CommandContainer DoRailroadTrackCmd(TileIndex start_tile, TileIndex end_t
return ret;
}
namespace citymania {
static void DoAutodirTerraform(bool diagonal, TileIndex s1, TileIndex e1, TileIndex s2, TileIndex e2) {
auto h1 = TileHeight(s1);
auto h2 = TileHeight(s2);
int diag_flag = (int)diagonal;
DoCommandP(e1, s1, ((h1 < h2 ? LM_RAISE : LM_LEVEL) << 1) | diag_flag, CMD_LEVEL_LAND, CcTerraform);
DoCommandP(e2, s2, ((h2 < h1 ? LM_RAISE : LM_LEVEL) << 1) | diag_flag, CMD_LEVEL_LAND, CcTerraform);
}
static void HandleAutodirTerraform(TileIndex start_tile, TileIndex end_tile) {
bool eq = (TileX(end_tile) - TileY(end_tile) == TileX(start_tile) - TileY(start_tile));
bool ez = (TileX(end_tile) + TileY(end_tile) == TileX(start_tile) + TileY(start_tile));
switch (_thd.cm_poly_dir) {
case TRACKDIR_X_NE:
DoAutodirTerraform(false,
TILE_ADDXY(start_tile, 1, 0), end_tile,
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 0, 1));
break;
case TRACKDIR_X_SW:
DoAutodirTerraform(false,
start_tile, TILE_ADDXY(end_tile, 1, 0),
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, 1, 1));
break;
case TRACKDIR_Y_SE:
DoAutodirTerraform(false,
start_tile, TILE_ADDXY(end_tile, 0, 1),
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, 1, 1));
break;
case TRACKDIR_Y_NW:
DoAutodirTerraform(false,
TILE_ADDXY(start_tile, 0, 1), end_tile,
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 1, 0));
break;
case TRACKDIR_LEFT_N: {
DoAutodirTerraform(true,
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, eq, 0),
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 0, !eq));
break;
}
case TRACKDIR_RIGHT_N: {
DoAutodirTerraform(true,
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, 0, eq),
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, !eq, 0));
break;
}
case TRACKDIR_LEFT_S: {
DoAutodirTerraform(true,
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, 1, !eq),
start_tile, TILE_ADDXY(end_tile, eq, 1));
break;
}
case TRACKDIR_RIGHT_S: {
DoAutodirTerraform(true,
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, !eq, 1),
start_tile, TILE_ADDXY(end_tile, 1, eq));
break;
}
case TRACKDIR_UPPER_E: {
DoAutodirTerraform(true,
start_tile, TILE_ADDXY(end_tile, 0, !ez),
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, !ez, 1));
break;
}
case TRACKDIR_LOWER_E: {
DoAutodirTerraform(true,
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, ez, 1),
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, 0, ez));
break;
}
case TRACKDIR_UPPER_W: {
DoAutodirTerraform(true,
start_tile, TILE_ADDXY(end_tile, !ez, 0),
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, 1, !ez));
break;
}
case TRACKDIR_LOWER_W: {
DoAutodirTerraform(true,
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 1, ez),
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, ez, 0));
break;
}
}
}
} // namespace citymania
static void HandleAutodirPlacement()
{
Track track = (Track)(_thd.drawstyle & HT_DIR_MASK); // 0..5
@@ -416,6 +503,7 @@ static void HandleAutodirPlacement()
if (citymania::_estimate_mod || !(_thd.place_mode & HT_POLY) ||
DoCommand(&cmd, DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
_rail_track_endtile == INVALID_TILE) {
if (_thd.cm_poly_terra) citymania::HandleAutodirTerraform(start_tile, end_tile);
/* Execute. */
if (!DoCommandP(&cmd)) return;
}
@@ -976,6 +1064,14 @@ struct BuildRailToolbarWindow : Window {
return ES_NOT_HANDLED;
}
EventState CM_OnFnModStateChange() override
{
if (this->IsWidgetLowered(WID_RAT_POLYRAIL)) {
return ES_HANDLED;
}
return ES_NOT_HANDLED;
}
static HotkeyList hotkeys;
};

View File

@@ -91,6 +91,9 @@ struct TileHighlightData {
citymania::ObjectHighlight cm;
citymania::ObjectHighlight cm_new;
bool cm_poly_terra;
bool cm_new_poly_terra;
Trackdir cm_poly_dir;
void Reset();

View File

@@ -1181,7 +1181,7 @@ static void DrawTileSelection(const TileInfo *ti)
case HT_LINE: {
HighLightStyle type = GetPartOfAutoLine(ti->x, ti->y, _thd.selstart, _thd.selend, _thd.drawstyle & HT_DIR_MASK);
if (type < HT_DIR_END) {
DrawAutorailSelection(ti, type);
DrawAutorailSelection(ti, type, _thd.cm_poly_terra ? CM_SPR_PALETTE_ZONING_YELLOW : PAL_NONE);
} else if (_thd.dir2 < HT_DIR_END) {
type = GetPartOfAutoLine(ti->x, ti->y, _thd.selstart2, _thd.selend2, _thd.dir2);
if (type < HT_DIR_END) DrawAutorailSelection(ti, type, PALETTE_SEL_TILE_BLUE);
@@ -2695,6 +2695,7 @@ void UpdateTileSelection()
_thd.new_size.y = y2 - y1 + TILE_SIZE;
}
}
_thd.cm_new_poly_terra = citymania::_fn_mod;
break;
}
/* HT_RAIL */
@@ -2744,6 +2745,7 @@ void UpdateTileSelection()
_thd.offs.x != _thd.new_offs.x || _thd.offs.y != _thd.new_offs.y ||
_thd.outersize.x != _thd.new_outersize.x ||
_thd.outersize.y != _thd.new_outersize.y ||
_thd.cm_poly_terra != _thd.cm_new_poly_terra ||
_thd.diagonal != new_diagonal) {
/* Clear the old tile selection? */
if ((_thd.drawstyle & HT_DRAG_MASK) != HT_NONE) SetSelectionTilesDirty();
@@ -2753,6 +2755,7 @@ void UpdateTileSelection()
_thd.size = _thd.new_size;
_thd.offs = _thd.new_offs;
_thd.outersize = _thd.new_outersize;
_thd.cm_poly_terra = _thd.cm_new_poly_terra;
_thd.diagonal = new_diagonal;
_thd.dirty = 0xff;
@@ -3519,6 +3522,7 @@ static HighLightStyle CalcPolyrailDrawstyle(Point pt, bool dragging)
_thd.selend.x -= first_dir.x;
_thd.selend.y -= first_dir.y;
Trackdir seldir = PointDirToTrackdir(_thd.selstart, line.first_dir);
_thd.cm_poly_dir = seldir;
_thd.selstart.x &= ~TILE_UNIT_MASK;
_thd.selstart.y &= ~TILE_UNIT_MASK;