src/rail_cmd.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6877 889301acc299
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "bridge_map.h"
     7 #include "bridge_map.h"
     8 #include "bridge.h"
     8 #include "bridge.h"
     9 #include "cmd_helper.h"
     9 #include "cmd_helper.h"
    10 #include "debug.h"
    10 #include "debug.h"
    11 #include "functions.h"
    11 #include "tile_cmd.h"
    12 #include "rail_map.h"
    12 #include "rail_map.h"
    13 #include "road_map.h"
    13 #include "road_map.h"
    14 #include "table/sprites.h"
       
    15 #include "table/strings.h"
       
    16 #include "map.h"
       
    17 #include "landscape.h"
    14 #include "landscape.h"
    18 #include "tile.h"
       
    19 #include "town_map.h"
    15 #include "town_map.h"
    20 #include "tunnel_map.h"
    16 #include "tunnel_map.h"
    21 #include "vehicle.h"
    17 #include "viewport_func.h"
    22 #include "viewport.h"
    18 #include "command_func.h"
    23 #include "command.h"
       
    24 #include "pathfind.h"
    19 #include "pathfind.h"
    25 #include "engine.h"
    20 #include "engine.h"
    26 #include "town.h"
    21 #include "town.h"
    27 #include "sound.h"
       
    28 #include "station.h"
    22 #include "station.h"
    29 #include "sprite.h"
    23 #include "sprite.h"
    30 #include "depot.h"
    24 #include "depot.h"
    31 #include "waypoint.h"
    25 #include "waypoint.h"
    32 #include "window.h"
       
    33 #include "rail.h"
    26 #include "rail.h"
    34 #include "railtypes.h" // include table for railtypes
       
    35 #include "newgrf.h"
    27 #include "newgrf.h"
    36 #include "yapf/yapf.h"
    28 #include "yapf/yapf.h"
    37 #include "newgrf_engine.h"
    29 #include "newgrf_engine.h"
    38 #include "newgrf_callbacks.h"
    30 #include "newgrf_callbacks.h"
    39 #include "newgrf_station.h"
    31 #include "newgrf_station.h"
    40 #include "train.h"
    32 #include "train.h"
    41 #include "misc/autoptr.hpp"
    33 #include "misc/autoptr.hpp"
       
    34 #include "variables.h"
    42 #include "autoslope.h"
    35 #include "autoslope.h"
    43 #include "transparency.h"
    36 #include "transparency.h"
    44 #include "water.h"
    37 #include "water.h"
       
    38 #include "tunnelbridge_map.h"
       
    39 #include "window_func.h"
       
    40 #include "vehicle_func.h"
       
    41 #include "sound_func.h"
       
    42 #include "signal_func.h"
       
    43 
       
    44 #include "table/sprites.h"
       
    45 #include "table/strings.h"
       
    46 #include "table/railtypes.h"
    45 
    47 
    46 const byte _track_sloped_sprites[14] = {
    48 const byte _track_sloped_sprites[14] = {
    47 	14, 15, 22, 13,
    49 	14, 15, 22, 13,
    48 	 0, 21, 17, 12,
    50 	 0, 21, 17, 12,
    49 	23,  0, 18, 20,
    51 	23,  0, 18, 20,
    80  *               01abcdef => rail w/ signals
    82  *               01abcdef => rail w/ signals
    81  *               10uuuuuu => unused
    83  *               10uuuuuu => unused
    82  *               11uuuudd => rail depot
    84  *               11uuuudd => rail depot
    83  */
    85  */
    84 
    86 
    85 /** Struct used in EnsureNoTrainOnTrack() */
    87 
    86 struct TrainOnTrackData {
    88 void *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
    87 	TileIndex tile;       ///< tile to check
    89 {
    88 	uint z;               ///< tile max Z
    90 	TrackBits rail_bits = *(TrackBits *)data;
    89 	TrackBits rail_bits;  ///< trackbits of interest
    91 
    90 };
    92 	if (v->type != VEH_TRAIN) return NULL;
    91 
    93 
    92 static void *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
    94 	if ((v->u.rail.track != rail_bits) && !TracksOverlap(v->u.rail.track | rail_bits)) return NULL;
    93 {
       
    94 	const TrainOnTrackData *info = (const TrainOnTrackData *)data;
       
    95 
       
    96 	if (v->tile != info->tile || v->type != VEH_TRAIN) return NULL;
       
    97 	if (v->z_pos > info->z) return NULL;
       
    98 
       
    99 	if ((v->u.rail.track != info->rail_bits) && !TracksOverlap(v->u.rail.track | info->rail_bits)) return NULL;
       
   100 
    95 
   101 	_error_message = VehicleInTheWayErrMsg(v);
    96 	_error_message = VehicleInTheWayErrMsg(v);
   102 	return v;
    97 	return v;
   103 }
    98 }
   104 
    99 
   109  * @param tile The tile.
   104  * @param tile The tile.
   110  * @param track The track.
   105  * @param track The track.
   111  */
   106  */
   112 static bool EnsureNoTrainOnTrack(TileIndex tile, Track track)
   107 static bool EnsureNoTrainOnTrack(TileIndex tile, Track track)
   113 {
   108 {
   114 	TrainOnTrackData info;
   109 	TrackBits rail_bits = TrackToTrackBits(track);
   115 
   110 
   116 	info.tile = tile;
   111 	return VehicleFromPos(tile, &rail_bits, &EnsureNoTrainOnTrackProc) == NULL;
   117 	info.z = GetTileMaxZ(tile);
       
   118 	info.rail_bits = TrackToTrackBits(track);
       
   119 
       
   120 	return VehicleFromPos(tile, &info, EnsureNoTrainOnTrackProc) == NULL;
       
   121 }
   112 }
   122 
   113 
   123 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
   114 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
   124 {
   115 {
   125 	TrackBits current; // The current track layout
   116 	TrackBits current; // The current track layout
   296 	if ((f_new == FOUNDATION_INVALID) ||
   287 	if ((f_new == FOUNDATION_INVALID) ||
   297 	    ((f_new != FOUNDATION_NONE) && (!_patches.build_on_slopes || _is_old_ai_player))
   288 	    ((f_new != FOUNDATION_NONE) && (!_patches.build_on_slopes || _is_old_ai_player))
   298 	   ) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   289 	   ) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   299 
   290 
   300 	Foundation f_old = GetRailFoundation(tileh, existing);
   291 	Foundation f_old = GetRailFoundation(tileh, existing);
   301 	return CommandCost(f_new != f_old ? _price.terraform : (Money)0);
   292 	return CommandCost(EXPENSES_CONSTRUCTION, f_new != f_old ? _price.terraform : (Money)0);
   302 }
   293 }
   303 
   294 
   304 /* Validate functions for rail building */
   295 /* Validate functions for rail building */
   305 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
   296 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
   306 
   297 
   311  * @param p2 rail track to build
   302  * @param p2 rail track to build
   312  */
   303  */
   313 CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   304 CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   314 {
   305 {
   315 	Slope tileh;
   306 	Slope tileh;
   316 	RailType railtype;
   307 	RailType railtype = (RailType)p1;
   317 	Track track;
   308 	Track track = (Track)p2;
   318 	TrackBits trackbit;
   309 	TrackBits trackbit;
   319 	CommandCost cost;
   310 	CommandCost cost(EXPENSES_CONSTRUCTION);
   320 	CommandCost ret;
   311 	CommandCost ret;
   321 
   312 
   322 	if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   313 	if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
   323 	railtype = (RailType)p1;
       
   324 	track = (Track)p2;
       
   325 
   314 
   326 	tileh = GetTileSlope(tile, NULL);
   315 	tileh = GetTileSlope(tile, NULL);
   327 	trackbit = TrackToTrackBits(track);
   316 	trackbit = TrackToTrackBits(track);
   328 
       
   329 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   330 
   317 
   331 	switch (GetTileType(tile)) {
   318 	switch (GetTileType(tile)) {
   332 		case MP_RAILWAY:
   319 		case MP_RAILWAY:
   333 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   320 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   334 					!EnsureNoTrainOnTrack(tile, track)) {
   321 					!EnsureNoTrainOnTrack(tile, track)) {
   394 
   381 
   395 				if ((track == TRACK_X && road == ROAD_Y) ||
   382 				if ((track == TRACK_X && road == ROAD_Y) ||
   396 						(track == TRACK_Y && road == ROAD_X)) {
   383 						(track == TRACK_Y && road == ROAD_X)) {
   397 					if (flags & DC_EXEC) {
   384 					if (flags & DC_EXEC) {
   398 						MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile));
   385 						MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile));
       
   386 						UpdateLevelCrossing(tile, false);
   399 					}
   387 					}
   400 					break;
   388 					break;
   401 				}
   389 				}
   402 			}
   390 			}
   403 
   391 
   429 			break;
   417 			break;
   430 	}
   418 	}
   431 
   419 
   432 	if (flags & DC_EXEC) {
   420 	if (flags & DC_EXEC) {
   433 		MarkTileDirtyByTile(tile);
   421 		MarkTileDirtyByTile(tile);
   434 		SetSignalsOnBothDir(tile, track);
   422 		AddTrackToSignalBuffer(tile, track, _current_player);
   435 		YapfNotifyTrackLayoutChange(tile, track);
   423 		YapfNotifyTrackLayoutChange(tile, track);
   436 	}
   424 	}
   437 
   425 
   438 	return cost.AddCost(RailBuildCost(railtype));
   426 	return cost.AddCost(RailBuildCost(railtype));
   439 }
   427 }
   446  */
   434  */
   447 CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   435 CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   448 {
   436 {
   449 	Track track = (Track)p2;
   437 	Track track = (Track)p2;
   450 	TrackBits trackbit;
   438 	TrackBits trackbit;
   451 	CommandCost cost(_price.remove_rail);
   439 	CommandCost cost(EXPENSES_CONSTRUCTION, _price.remove_rail );
   452 	bool crossing = false;
   440 	bool crossing = false;
   453 
   441 
   454 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   442 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
   455 	trackbit = TrackToTrackBits(track);
   443 	trackbit = TrackToTrackBits(track);
   456 
   444 
   457 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   445 	/* Need to read tile owner now because it may change when the rail is removed
       
   446 	 * Also, in case of floods, _current_player != owner
       
   447 	 * There may be invalid tiletype even in exec run (when removing long track),
       
   448 	 * so do not call GetTileOwner(tile) in any case here */
       
   449 	Owner owner = INVALID_OWNER;
   458 
   450 
   459 	switch (GetTileType(tile)) {
   451 	switch (GetTileType(tile)) {
   460 		case MP_ROAD: {
   452 		case MP_ROAD: {
   461 			if (!IsLevelCrossing(tile) ||
   453 			if (!IsLevelCrossing(tile) ||
   462 					GetCrossingRailBits(tile) != trackbit ||
   454 					GetCrossingRailBits(tile) != trackbit ||
   464 					!EnsureNoVehicleOnGround(tile)) {
   456 					!EnsureNoVehicleOnGround(tile)) {
   465 				return CMD_ERROR;
   457 				return CMD_ERROR;
   466 			}
   458 			}
   467 
   459 
   468 			if (flags & DC_EXEC) {
   460 			if (flags & DC_EXEC) {
       
   461 				owner = GetTileOwner(tile);
   469 				MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY));
   462 				MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY));
   470 			}
   463 			}
   471 			break;
   464 			break;
   472 		}
   465 		}
   473 
   466 
   487 			/* Charge extra to remove signals on the track, if they are there */
   480 			/* Charge extra to remove signals on the track, if they are there */
   488 			if (HasSignalOnTrack(tile, track))
   481 			if (HasSignalOnTrack(tile, track))
   489 				cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
   482 				cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
   490 
   483 
   491 			if (flags & DC_EXEC) {
   484 			if (flags & DC_EXEC) {
       
   485 				owner = GetTileOwner(tile);
   492 				present ^= trackbit;
   486 				present ^= trackbit;
   493 				if (present == 0) {
   487 				if (present == 0) {
   494 					if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
   488 					if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
   495 						MakeShore(tile);
   489 						MakeShore(tile);
   496 					} else {
   490 					} else {
   505 
   499 
   506 		default: return CMD_ERROR;
   500 		default: return CMD_ERROR;
   507 	}
   501 	}
   508 
   502 
   509 	if (flags & DC_EXEC) {
   503 	if (flags & DC_EXEC) {
       
   504 		/* if we got that far, 'owner' variable is set correctly */
       
   505 		assert(IsValidPlayer(owner));
       
   506 
   510 		MarkTileDirtyByTile(tile);
   507 		MarkTileDirtyByTile(tile);
   511 		if (crossing) {
   508 		if (crossing) {
   512 			/* crossing is set when only TRACK_BIT_X and TRACK_BIT_Y are set. As we
   509 			/* crossing is set when only TRACK_BIT_X and TRACK_BIT_Y are set. As we
   513 			 * are removing one of these pieces, we'll need to update signals for
   510 			 * are removing one of these pieces, we'll need to update signals for
   514 			 * both directions explicitly, as after the track is removed it won't
   511 			 * both directions explicitly, as after the track is removed it won't
   515 			 * 'connect' with the other piece. */
   512 			 * 'connect' with the other piece. */
   516 			SetSignalsOnBothDir(tile, TRACK_X);
   513 			AddTrackToSignalBuffer(tile, TRACK_X, owner);
   517 			SetSignalsOnBothDir(tile, TRACK_Y);
   514 			AddTrackToSignalBuffer(tile, TRACK_Y, owner);
   518 			YapfNotifyTrackLayoutChange(tile, TRACK_X);
   515 			YapfNotifyTrackLayoutChange(tile, TRACK_X);
   519 			YapfNotifyTrackLayoutChange(tile, TRACK_Y);
   516 			YapfNotifyTrackLayoutChange(tile, TRACK_Y);
   520 		} else {
   517 		} else {
   521 			SetSignalsOnBothDir(tile, track);
   518 			AddTrackToSignalBuffer(tile, track, owner);
   522 			YapfNotifyTrackLayoutChange(tile, track);
   519 			YapfNotifyTrackLayoutChange(tile, track);
   523 		}
   520 		}
   524 	}
   521 	}
   525 
   522 
   526 	return cost;
   523 	return cost;
   530 /**
   527 /**
   531  * Called from water_cmd if a non-flat rail-tile gets flooded and should be converted to shore.
   528  * Called from water_cmd if a non-flat rail-tile gets flooded and should be converted to shore.
   532  * The function floods the lower halftile, if the tile has a halftile foundation.
   529  * The function floods the lower halftile, if the tile has a halftile foundation.
   533  *
   530  *
   534  * @param t The tile to flood.
   531  * @param t The tile to flood.
   535  */
   532  * @return true if something was flooded.
   536 void FloodHalftile(TileIndex t)
   533  */
   537 {
   534 bool FloodHalftile(TileIndex t)
   538 	if (GetRailGroundType(t) == RAIL_GROUND_WATER) return;
   535 {
       
   536 	bool flooded = false;
       
   537 	if (GetRailGroundType(t) == RAIL_GROUND_WATER) return flooded;
   539 
   538 
   540 	Slope tileh = GetTileSlope(t, NULL);
   539 	Slope tileh = GetTileSlope(t, NULL);
   541 	TrackBits rail_bits = GetTrackBits(t);
   540 	TrackBits rail_bits = GetTrackBits(t);
   542 
   541 
   543 	if (!IsSteepSlope(tileh) && HasSlopeHighestCorner(tileh)) {
   542 	if (!IsSteepSlope(tileh) && HasSlopeHighestCorner(tileh)) {
   544 		TrackBits lower_track = CornerToTrackBits(OppositeCorner(GetHighestSlopeCorner(tileh)));
   543 		TrackBits lower_track = CornerToTrackBits(OppositeCorner(GetHighestSlopeCorner(tileh)));
   545 
   544 
   546 		TrackBits to_remove = lower_track & rail_bits;
   545 		TrackBits to_remove = lower_track & rail_bits;
   547 		if (to_remove != 0) {
   546 		if (to_remove != 0) {
   548 			_current_player = OWNER_WATER;
   547 			_current_player = OWNER_WATER;
   549 			if (CmdFailed(DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL))) return; // not yet floodable
   548 			if (CmdFailed(DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL))) return flooded; // not yet floodable
       
   549 			flooded = true;
   550 			rail_bits = rail_bits & ~to_remove;
   550 			rail_bits = rail_bits & ~to_remove;
   551 			if (rail_bits == 0) {
   551 			if (rail_bits == 0) {
   552 				MakeShore(t);
   552 				MakeShore(t);
   553 				MarkTileDirtyByTile(t);
   553 				MarkTileDirtyByTile(t);
   554 				return;
   554 				return flooded;
   555 			}
   555 			}
   556 		}
   556 		}
   557 
   557 
   558 		if (IsNonContinuousFoundation(GetRailFoundation(tileh, rail_bits))) {
   558 		if (IsNonContinuousFoundation(GetRailFoundation(tileh, rail_bits))) {
       
   559 			flooded = true;
   559 			SetRailGroundType(t, RAIL_GROUND_WATER);
   560 			SetRailGroundType(t, RAIL_GROUND_WATER);
   560 			MarkTileDirtyByTile(t);
   561 			MarkTileDirtyByTile(t);
   561 		}
   562 		}
   562 	}
   563 	}
       
   564 	return flooded;
   563 }
   565 }
   564 
   566 
   565 static const TileIndexDiffC _trackdelta[] = {
   567 static const TileIndexDiffC _trackdelta[] = {
   566 	{ -1,  0 }, {  0,  1 }, { -1,  0 }, {  0,  1 }, {  1,  0 }, {  0,  1 },
   568 	{ -1,  0 }, {  0,  1 }, { -1,  0 }, {  0,  1 }, {  1,  0 }, {  0,  1 },
   567 	{  0,  0 },
   569 	{  0,  0 },
   632  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   634  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   633  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   635  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   634  */
   636  */
   635 static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   637 static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   636 {
   638 {
   637 	CommandCost ret, total_cost;
   639 	CommandCost ret, total_cost(EXPENSES_CONSTRUCTION);
   638 	Track track = (Track)GB(p2, 4, 3);
   640 	Track track = (Track)GB(p2, 4, 3);
   639 	Trackdir trackdir;
   641 	Trackdir trackdir;
   640 	byte mode = HasBit(p2, 7);
   642 	byte mode = HasBit(p2, 7);
   641 	RailType railtype = (RailType)GB(p2, 0, 4);
   643 	RailType railtype = (RailType)GB(p2, 0, 4);
   642 	TileIndex end_tile;
   644 	TileIndex end_tile;
   643 
   645 
   644 	if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
   646 	if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
   645 	if (p1 >= MapSize()) return CMD_ERROR;
   647 	if (p1 >= MapSize()) return CMD_ERROR;
   646 	end_tile = p1;
   648 	end_tile = p1;
   647 	trackdir = TrackToTrackdir(track);
   649 	trackdir = TrackToTrackdir(track);
   648 
       
   649 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   650 
   650 
   651 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
   651 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
   652 
   652 
   653 	if (flags & DC_EXEC) SndPlayTileFx(SND_20_SPLAT_2, tile);
   653 	if (flags & DC_EXEC) SndPlayTileFx(SND_20_SPLAT_2, tile);
   654 
   654 
   714  * @todo When checking for the tile slope,
   714  * @todo When checking for the tile slope,
   715  * distingush between "Flat land required" and "land sloped in wrong direction"
   715  * distingush between "Flat land required" and "land sloped in wrong direction"
   716  */
   716  */
   717 CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   717 CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   718 {
   718 {
   719 	CommandCost cost;
       
   720 	Slope tileh;
   719 	Slope tileh;
   721 
   720 
   722 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   723 
       
   724 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
   721 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
   725 	if (!ValParamRailtype(p1)) return CMD_ERROR;
   722 	if (!ValParamRailtype((RailType)p1)) return CMD_ERROR;
   726 
   723 
   727 	tileh = GetTileSlope(tile, NULL);
   724 	tileh = GetTileSlope(tile, NULL);
   728 
   725 
   729 	DiagDirection dir = Extract<DiagDirection, 0>(p2);
   726 	DiagDirection dir = Extract<DiagDirection, 0>(p2);
   730 
   727 
   743 				!CanBuildDepotByTileh(dir, tileh)
   740 				!CanBuildDepotByTileh(dir, tileh)
   744 			)) {
   741 			)) {
   745 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
   742 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
   746 	}
   743 	}
   747 
   744 
   748 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   745 	CommandCost cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   749 	if (CmdFailed(cost)) return CMD_ERROR;
   746 	if (CmdFailed(cost)) return CMD_ERROR;
   750 
   747 
   751 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
   748 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
   752 
   749 
   753 	Depot *d = new Depot(tile);
   750 	Depot *d = new Depot(tile);
   759 		MakeRailDepot(tile, _current_player, dir, (RailType)p1);
   756 		MakeRailDepot(tile, _current_player, dir, (RailType)p1);
   760 		MarkTileDirtyByTile(tile);
   757 		MarkTileDirtyByTile(tile);
   761 
   758 
   762 		d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
   759 		d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
   763 
   760 
   764 		UpdateSignalsOnSegment(tile, dir);
   761 		AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_player);
   765 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
   762 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
   766 		d_auto_delete.Detach();
   763 		d_auto_delete.Detach();
   767 	}
   764 	}
   768 
   765 
   769 	return cost.AddCost(_price.build_train_depot);
   766 	return cost.AddCost(_price.build_train_depot);
   814 	}
   811 	}
   815 
   812 
   816 	/* you can not convert a signal if no signal is on track */
   813 	/* you can not convert a signal if no signal is on track */
   817 	if (convert_signal && !HasSignalOnTrack(tile, track)) return CMD_ERROR;
   814 	if (convert_signal && !HasSignalOnTrack(tile, track)) return CMD_ERROR;
   818 
   815 
   819 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   820 
       
   821 	if (!HasSignalOnTrack(tile, track)) {
   816 	if (!HasSignalOnTrack(tile, track)) {
   822 		/* build new signals */
   817 		/* build new signals */
   823 		cost = CommandCost(_price.build_signals);
   818 		cost = CommandCost(EXPENSES_CONSTRUCTION, _price.build_signals);
   824 	} else {
   819 	} else {
   825 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
   820 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
   826 			/* convert signals <-> semaphores */
   821 			/* convert signals <-> semaphores */
   827 			cost = CommandCost(_price.build_signals + _price.remove_signals);
   822 			cost = CommandCost(EXPENSES_CONSTRUCTION, _price.build_signals + _price.remove_signals);
   828 
   823 
   829 		} else if (convert_signal) {
   824 		} else if (convert_signal) {
   830 			/* convert button pressed */
   825 			/* convert button pressed */
   831 			if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) {
   826 			if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) {
   832 				/* convert electric <-> semaphore */
   827 				/* convert electric <-> semaphore */
   833 				cost = CommandCost(_price.build_signals + _price.remove_signals);
   828 				cost = CommandCost(EXPENSES_CONSTRUCTION, _price.build_signals + _price.remove_signals);
   834 			} else {
   829 			} else {
   835 				/* it is free to change signal type: normal-pre-exit-combo */
   830 				/* it is free to change signal type: normal-pre-exit-combo */
   836 				cost = CommandCost();
   831 				cost = CommandCost();
   837 			}
   832 			}
   838 
   833 
   887 			SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
   882 			SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
   888 			SetSignalVariant(tile, track, sigvar);
   883 			SetSignalVariant(tile, track, sigvar);
   889 		}
   884 		}
   890 
   885 
   891 		MarkTileDirtyByTile(tile);
   886 		MarkTileDirtyByTile(tile);
   892 		SetSignalsOnBothDir(tile, track);
   887 		AddTrackToSignalBuffer(tile, track, _current_player);
   893 		YapfNotifyTrackLayoutChange(tile, track);
   888 		YapfNotifyTrackLayoutChange(tile, track);
   894 	}
   889 	}
   895 
   890 
   896 	return cost;
   891 	return cost;
   897 }
   892 }
   933 			if (!IsLevelCrossing(tile)) return false;
   928 			if (!IsLevelCrossing(tile)) return false;
   934 			signal_ctr += 2;
   929 			signal_ctr += 2;
   935 			return true;
   930 			return true;
   936 
   931 
   937 		case MP_TUNNELBRIDGE: {
   932 		case MP_TUNNELBRIDGE: {
   938 			TileIndex orig_tile = tile;
   933 			TileIndex orig_tile = tile; // backup old value
   939 			/* Skip to end of tunnel or bridge */
   934 
   940 			if (IsBridge(tile)) {
   935 			if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
   941 				if (GetBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
   936 			if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(trackdir)) return false;
   942 				if (GetBridgeRampDirection(tile) != TrackdirToExitdir(trackdir)) return false;
   937 
   943 				tile = GetOtherBridgeEnd(tile);
   938 			/* Skip to end of tunnel or bridge
   944 			} else {
   939 			 * note that tile is a parameter by reference, so it must be updated */
   945 				if (GetTunnelTransportType(tile) != TRANSPORT_RAIL) return false;
   940 			tile = GetOtherTunnelBridgeEnd(tile);
   946 				if (GetTunnelDirection(tile) != TrackdirToExitdir(trackdir)) return false;
   941 
   947 				tile = GetOtherTunnelEnd(tile);
       
   948 			}
       
   949 			signal_ctr += 2 + DistanceMax(orig_tile, tile) * 2;
   942 			signal_ctr += 2 + DistanceMax(orig_tile, tile) * 2;
   950 			return true;
   943 			return true;
   951 		}
   944 		}
   952 
   945 
   953 		default: return false;
   946 		default: return false;
   966  * - p2 = (bit  6)    - 0 = selected stretch, 1 = auto fill
   959  * - p2 = (bit  6)    - 0 = selected stretch, 1 = auto fill
   967  * - p2 = (bit 24-31) - user defined signals_density
   960  * - p2 = (bit 24-31) - user defined signals_density
   968  */
   961  */
   969 static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   962 static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   970 {
   963 {
   971 	CommandCost ret, total_cost;
   964 	CommandCost ret, total_cost(EXPENSES_CONSTRUCTION);
   972 	int signal_ctr;
   965 	int signal_ctr;
   973 	byte signals;
   966 	byte signals;
   974 	bool error = true;
   967 	bool error = true;
   975 	TileIndex end_tile;
   968 	TileIndex end_tile;
   976 	TileIndex start_tile = tile;
   969 	TileIndex start_tile = tile;
   986 	if (p1 >= MapSize()) return CMD_ERROR;
   979 	if (p1 >= MapSize()) return CMD_ERROR;
   987 	end_tile = p1;
   980 	end_tile = p1;
   988 	if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
   981 	if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
   989 
   982 
   990 	if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
   983 	if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
   991 
       
   992 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   993 
   984 
   994 	/* for vertical/horizontal tracks, double the given signals density
   985 	/* for vertical/horizontal tracks, double the given signals density
   995 	 * since the original amount will be too dense (shorter tracks) */
   986 	 * since the original amount will be too dense (shorter tracks) */
   996 	signal_density *= 2;
   987 	signal_density *= 2;
   997 
   988 
  1111 	}
  1102 	}
  1112 
  1103 
  1113 	/* Only water can remove signals from anyone */
  1104 	/* Only water can remove signals from anyone */
  1114 	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
  1105 	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
  1115 
  1106 
  1116 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
  1117 
       
  1118 	/* Do it? */
  1107 	/* Do it? */
  1119 	if (flags & DC_EXEC) {
  1108 	if (flags & DC_EXEC) {
  1120 		SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track));
  1109 		SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track));
  1121 
  1110 
  1122 		/* removed last signal from tile? */
  1111 		/* removed last signal from tile? */
  1124 			SetSignalStates(tile, 0);
  1113 			SetSignalStates(tile, 0);
  1125 			SetHasSignals(tile, false);
  1114 			SetHasSignals(tile, false);
  1126 			SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
  1115 			SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
  1127 		}
  1116 		}
  1128 
  1117 
  1129 		SetSignalsOnBothDir(tile, track);
  1118 		AddTrackToSignalBuffer(tile, track, GetTileOwner(tile));
  1130 		YapfNotifyTrackLayoutChange(tile, track);
  1119 		YapfNotifyTrackLayoutChange(tile, track);
  1131 
  1120 
  1132 		MarkTileDirtyByTile(tile);
  1121 		MarkTileDirtyByTile(tile);
  1133 	}
  1122 	}
  1134 
  1123 
  1135 	return CommandCost(_price.remove_signals);
  1124 	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_signals);
  1136 }
  1125 }
  1137 
  1126 
  1138 /** Remove signals on a stretch of track.
  1127 /** Remove signals on a stretch of track.
  1139  * Stub for the unified signal builder/remover
  1128  * Stub for the unified signal builder/remover
  1140  * @param tile start tile of drag
  1129  * @param tile start tile of drag
  1152 CommandCost CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1141 CommandCost CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1153 {
  1142 {
  1154 	return CmdSignalTrackHelper(tile, flags, p1, SetBit(p2, 5)); // bit 5 is remove bit
  1143 	return CmdSignalTrackHelper(tile, flags, p1, SetBit(p2, 5)); // bit 5 is remove bit
  1155 }
  1144 }
  1156 
  1145 
  1157 typedef CommandCost DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
  1146 /** Update power of train under which is the railtype being converted */
  1158 
       
  1159 void *UpdateTrainPowerProc(Vehicle *v, void *data)
  1147 void *UpdateTrainPowerProc(Vehicle *v, void *data)
  1160 {
  1148 {
  1161 	/* Similiar checks as in TrainPowerChanged() */
  1149 	/* Similiar checks as in TrainPowerChanged() */
  1162 
  1150 
  1163 	if (v->type == VEH_TRAIN && v->tile == *(TileIndex*)data && !IsArticulatedPart(v)) {
  1151 	if (v->type == VEH_TRAIN && !IsArticulatedPart(v)) {
  1164 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  1152 		const RailVehicleInfo *rvi = RailVehInfo(v->engine_type);
  1165 		if (GetVehicleProperty(v, 0x0B, rvi->power) != 0) TrainPowerChanged(v->First());
  1153 		if (GetVehicleProperty(v, 0x0B, rvi->power) != 0) TrainPowerChanged(v->First());
  1166 	}
  1154 	}
  1167 
  1155 
  1168 	return NULL;
  1156 	return NULL;
  1169 }
  1157 }
  1170 
       
  1171 /**
       
  1172  * Switches the rail type.
       
  1173  * Railtypes are stored on a per-tile basis, not on a per-track basis, so
       
  1174  * all the tracks in the given tile will be converted.
       
  1175  * @param tile        The tile on which the railtype is to be convert.
       
  1176  * @param totype      The railtype we want to convert to
       
  1177  * @param exec        Switches between test and execute mode
       
  1178  * @return            The cost and state of the operation
       
  1179  * @retval CMD_ERROR  An error occured during the operation.
       
  1180  */
       
  1181 static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec)
       
  1182 {
       
  1183 	/* change type. */
       
  1184 	if (exec) {
       
  1185 		SetRailType(tile, totype);
       
  1186 		MarkTileDirtyByTile(tile);
       
  1187 
       
  1188 		/* notify YAPF about the track layout change */
       
  1189 		TrackBits tracks = GetTrackBits(tile);
       
  1190 		while (tracks != TRACK_BIT_NONE) {
       
  1191 			YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
       
  1192 		}
       
  1193 
       
  1194 		if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
       
  1195 			/* Update build vehicle window related to this depot */
       
  1196 			InvalidateWindowData(WC_VEHICLE_DEPOT, tile);
       
  1197 			InvalidateWindowData(WC_BUILD_VEHICLE, tile);
       
  1198 		}
       
  1199 
       
  1200 		/* update power of train engines on this tile */
       
  1201 		VehicleFromPos(tile, &tile, UpdateTrainPowerProc);
       
  1202 	}
       
  1203 
       
  1204 	return CommandCost(RailBuildCost(totype) / 2);
       
  1205 }
       
  1206 
       
  1207 extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
       
  1208 extern CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec);
       
  1209 extern CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
       
  1210 
  1158 
  1211 /** Convert one rail type to the other. You can convert normal rail to
  1159 /** Convert one rail type to the other. You can convert normal rail to
  1212  * monorail/maglev easily or vice-versa.
  1160  * monorail/maglev easily or vice-versa.
  1213  * @param tile end tile of rail conversion drag
  1161  * @param tile end tile of rail conversion drag
  1214  * @param flags operation to perform
  1162  * @param flags operation to perform
  1215  * @param p1 start tile of drag
  1163  * @param p1 start tile of drag
  1216  * @param p2 new railtype to convert to
  1164  * @param p2 new railtype to convert to
  1217  */
  1165  */
  1218 CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1166 CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1219 {
  1167 {
  1220 	CommandCost ret, cost;
  1168 	CommandCost cost(EXPENSES_CONSTRUCTION);
  1221 	Money money;
  1169 	RailType totype = (RailType)p2;
  1222 	int ex;
  1170 
  1223 	int ey;
  1171 	if (!ValParamRailtype(totype)) return CMD_ERROR;
  1224 	int sx, sy, x, y;
       
  1225 
       
  1226 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
  1227 
       
  1228 	if (!ValParamRailtype(p2)) return CMD_ERROR;
       
  1229 	if (p1 >= MapSize()) return CMD_ERROR;
  1172 	if (p1 >= MapSize()) return CMD_ERROR;
  1230 
  1173 
       
  1174 	uint ex = TileX(tile);
       
  1175 	uint ey = TileY(tile);
       
  1176 	uint sx = TileX(p1);
       
  1177 	uint sy = TileY(p1);
       
  1178 
  1231 	/* make sure sx,sy are smaller than ex,ey */
  1179 	/* make sure sx,sy are smaller than ex,ey */
  1232 	ex = TileX(tile);
       
  1233 	ey = TileY(tile);
       
  1234 	sx = TileX(p1);
       
  1235 	sy = TileY(p1);
       
  1236 	if (ex < sx) Swap(ex, sx);
  1180 	if (ex < sx) Swap(ex, sx);
  1237 	if (ey < sy) Swap(ey, sy);
  1181 	if (ey < sy) Swap(ey, sy);
  1238 
  1182 
  1239 	money = GetAvailableMoneyForCommand();
  1183 	_error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK; // by default, there is no track to convert
  1240 
  1184 
  1241 	for (x = sx; x <= ex; ++x) {
  1185 	for (uint x = sx; x <= ex; ++x) {
  1242 		for (y = sy; y <= ey; ++y) {
  1186 		for (uint y = sy; y <= ey; ++y) {
  1243 			TileIndex tile = TileXY(x, y);
  1187 			TileIndex tile = TileXY(x, y);
  1244 			DoConvertRailProc *proc;
  1188 			TileType tt = GetTileType(tile);
  1245 			RailType totype = (RailType)p2;
  1189 
  1246 
  1190 			/* Check if there is any track on tile */
  1247 			switch (GetTileType(tile)) {
  1191 			switch (tt) {
  1248 				case MP_RAILWAY:      proc = DoConvertRail;             break;
  1192 				case MP_RAILWAY:
  1249 				case MP_STATION:      proc = DoConvertStationRail;      break;
  1193 					break;
  1250 				case MP_ROAD:         proc = DoConvertStreetRail;       break;
  1194 				case MP_STATION:
  1251 				case MP_TUNNELBRIDGE: proc = DoConvertTunnelBridgeRail; break;
  1195 					if (!IsRailwayStation(tile)) continue;
       
  1196 					break;
       
  1197 				case MP_ROAD:
       
  1198 					if (!IsLevelCrossing(tile)) continue;
       
  1199 					break;
       
  1200 				case MP_TUNNELBRIDGE:
       
  1201 					if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
       
  1202 					break;
  1252 				default: continue;
  1203 				default: continue;
  1253 			}
  1204 			}
  1254 
  1205 
  1255 			/* It is possible that 'type' is invalid when there is no rail on the tile,
  1206 			/* Original railtype we are converting from */
  1256 			 * but this situation will be detected in proc()
       
  1257 			 */
       
  1258 			RailType type = GetRailType(tile);
  1207 			RailType type = GetRailType(tile);
  1259 
  1208 
  1260 			/* Not own tile or track is already converted */
  1209 			/* Converting to the same type or converting 'hidden' elrail -> rail */
  1261 			if ((!CheckTileOwnership(tile) || type == totype) ||
  1210 			if (type == totype || (_patches.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
  1262 				/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
  1211 
  1263 				(_patches.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC) ||
  1212 			/* Trying to convert other's rail */
  1264 				/* Vehicle on a tile while not converting Rail <-> ElRail */
  1213 			if (!CheckTileOwnership(tile)) continue;
  1265 				(!IsCompatibleRail(type, totype) && !EnsureNoVehicleOnGround(tile))) {
  1214 
  1266 					ret = CMD_ERROR;
  1215 			/* Vehicle on the tile when not converting Rail <-> ElRail
  1267 					continue;
  1216 			 * Tunnels and bridges have special check later */
  1268 			}
  1217 			if (tt != MP_TUNNELBRIDGE) {
  1269 
  1218 				if (!IsCompatibleRail(type, totype) && !EnsureNoVehicleOnGround(tile)) continue;
  1270 			ret = proc(tile, totype, false);
  1219 				if (flags & DC_EXEC) { // we can safely convert, too
  1271 			if (CmdFailed(ret)) continue;
  1220 					SetRailType(tile, totype);
  1272 
  1221 					MarkTileDirtyByTile(tile);
  1273 			if (flags & DC_EXEC) {
  1222 					/* update power of train engines on this tile */
  1274 				money -= ret.GetCost();
  1223 					VehicleFromPos(tile, NULL, &UpdateTrainPowerProc);
  1275 				if (money < 0) {
       
  1276 					_additional_cash_required = ret.GetCost();
       
  1277 					return cost;
       
  1278 				}
  1224 				}
  1279 				proc(tile, totype, true);
  1225 			}
  1280 			}
  1226 
  1281 			cost.AddCost(ret);
  1227 			switch (tt) {
  1282 		}
  1228 				case MP_RAILWAY:
  1283 	}
  1229 					switch (GetRailTileType(tile)) {
  1284 
  1230 						case RAIL_TILE_WAYPOINT:
  1285 	return (cost.GetCost() == 0) ? ret : cost;
  1231 							if (flags & DC_EXEC) {
       
  1232 								/* notify YAPF about the track layout change */
       
  1233 								YapfNotifyTrackLayoutChange(tile, AxisToTrack(GetWaypointAxis(tile)));
       
  1234 							}
       
  1235 							cost.AddCost(RailConvertCost(type, totype));
       
  1236 							break;
       
  1237 
       
  1238 						case RAIL_TILE_DEPOT:
       
  1239 							if (flags & DC_EXEC) {
       
  1240 								/* notify YAPF about the track layout change */
       
  1241 								YapfNotifyTrackLayoutChange(tile, AxisToTrack(DiagDirToAxis(GetRailDepotDirection(tile))));
       
  1242 
       
  1243 								/* Update build vehicle window related to this depot */
       
  1244 								InvalidateWindowData(WC_VEHICLE_DEPOT, tile);
       
  1245 								InvalidateWindowData(WC_BUILD_VEHICLE, tile);
       
  1246 							}
       
  1247 							cost.AddCost(RailConvertCost(type, totype));
       
  1248 							break;
       
  1249 
       
  1250 						default: // RAIL_TILE_NORMAL, RAIL_TILE_SIGNALS
       
  1251 							if (flags & DC_EXEC) {
       
  1252 								/* notify YAPF about the track layout change */
       
  1253 								TrackBits tracks = GetTrackBits(tile);
       
  1254 								while (tracks != TRACK_BIT_NONE) {
       
  1255 									YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
       
  1256 								}
       
  1257 							}
       
  1258 							cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile)));
       
  1259 							break;
       
  1260 					}
       
  1261 					break;
       
  1262 
       
  1263 				case MP_TUNNELBRIDGE: {
       
  1264 					TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
       
  1265 
       
  1266 					/* If both ends of tunnel/bridge are in the range, do not try to convert twice -
       
  1267 					 * it would cause assert because of different test and exec runs */
       
  1268 					if (endtile < tile && TileX(endtile) >= sx && TileX(endtile) <= ex &&
       
  1269 							TileY(endtile) >= sy && TileY(endtile) <= ey) continue;
       
  1270 
       
  1271 					/* When not coverting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */
       
  1272 					if (!IsCompatibleRail(GetRailType(tile), totype) &&
       
  1273 							GetVehicleTunnelBridge(tile, endtile) != NULL) continue;
       
  1274 
       
  1275 					if (flags & DC_EXEC) {
       
  1276 						SetRailType(tile, totype);
       
  1277 						SetRailType(endtile, totype);
       
  1278 
       
  1279 						VehicleFromPos(tile, NULL, &UpdateTrainPowerProc);
       
  1280 						VehicleFromPos(endtile, NULL, &UpdateTrainPowerProc);
       
  1281 
       
  1282 						Track track = AxisToTrack(DiagDirToAxis(GetTunnelBridgeDirection(tile)));
       
  1283 
       
  1284 						YapfNotifyTrackLayoutChange(tile, track);
       
  1285 						YapfNotifyTrackLayoutChange(endtile, track);
       
  1286 
       
  1287 						MarkTileDirtyByTile(tile);
       
  1288 						MarkTileDirtyByTile(endtile);
       
  1289 
       
  1290 						if (IsBridge(tile)) {
       
  1291 							TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
       
  1292 							TileIndex t = tile + delta;
       
  1293 							for (; t != endtile; t += delta) MarkTileDirtyByTile(t); // TODO encapsulate this into a function
       
  1294 						}
       
  1295 					}
       
  1296 
       
  1297 					cost.AddCost((DistanceManhattan(tile, endtile) + 1) * RailConvertCost(type, totype));
       
  1298 				} break;
       
  1299 
       
  1300 				default: // MP_STATION, MP_ROAD
       
  1301 					if (flags & DC_EXEC) {
       
  1302 						Track track = (tt == MP_STATION) ? GetRailStationTrack(tile) : AxisToTrack(OtherAxis(GetCrossingRoadAxis(tile)));
       
  1303 						YapfNotifyTrackLayoutChange(tile, track);
       
  1304 					}
       
  1305 
       
  1306 					cost.AddCost(RailConvertCost(type, totype));
       
  1307 					break;
       
  1308 			}
       
  1309 		}
       
  1310 	}
       
  1311 
       
  1312 	return (cost.GetCost() == 0) ? CMD_ERROR : cost;
  1286 }
  1313 }
  1287 
  1314 
  1288 static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
  1315 static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
  1289 {
  1316 {
  1290 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
  1317 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
  1292 
  1319 
  1293 	if (!EnsureNoVehicleOnGround(tile))
  1320 	if (!EnsureNoVehicleOnGround(tile))
  1294 		return CMD_ERROR;
  1321 		return CMD_ERROR;
  1295 
  1322 
  1296 	if (flags & DC_EXEC) {
  1323 	if (flags & DC_EXEC) {
       
  1324 		/* read variables before the depot is removed */
  1297 		DiagDirection dir = GetRailDepotDirection(tile);
  1325 		DiagDirection dir = GetRailDepotDirection(tile);
       
  1326 		Owner owner = GetTileOwner(tile);
  1298 
  1327 
  1299 		DoClearSquare(tile);
  1328 		DoClearSquare(tile);
  1300 		delete GetDepotByTile(tile);
  1329 		delete GetDepotByTile(tile);
  1301 		UpdateSignalsOnSegment(tile, dir);
  1330 		AddSideToSignalBuffer(tile, dir, owner);
  1302 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
  1331 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
  1303 	}
  1332 	}
  1304 
  1333 
  1305 	return CommandCost(_price.remove_train_depot);
  1334 	return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot);
  1306 }
  1335 }
  1307 
  1336 
  1308 static CommandCost ClearTile_Track(TileIndex tile, byte flags)
  1337 static CommandCost ClearTile_Track(TileIndex tile, byte flags)
  1309 {
  1338 {
  1310 	CommandCost cost;
  1339 	CommandCost cost(EXPENSES_CONSTRUCTION);
  1311 	CommandCost ret;
  1340 	CommandCost ret;
  1312 
  1341 
  1313 	if (flags & DC_AUTO) {
  1342 	if (flags & DC_AUTO) {
  1314 		if (!IsTileOwner(tile, _current_player))
  1343 		if (!IsTileOwner(tile, _current_player))
  1315 			return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
  1344 			return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
  1781 				image += rti->total_offset;
  1810 				image += rti->total_offset;
  1782 			} else {
  1811 			} else {
  1783 				image += relocation;
  1812 				image += relocation;
  1784 			}
  1813 			}
  1785 
  1814 
  1786 			if (!IsTransparencySet(TO_BUILDINGS) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
  1815 			if (!(!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS)) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
  1787 				pal = _drawtile_track_palette;
  1816 				pal = _drawtile_track_palette;
  1788 			} else {
  1817 			} else {
  1789 				pal = dtss->pal;
  1818 				pal = dtss->pal;
  1790 			}
  1819 			}
  1791 
  1820 
  1793 				AddSortableSpriteToDraw(
  1822 				AddSortableSpriteToDraw(
  1794 					image, pal,
  1823 					image, pal,
  1795 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
  1824 					ti->x + dtss->delta_x, ti->y + dtss->delta_y,
  1796 					dtss->size_x, dtss->size_y,
  1825 					dtss->size_x, dtss->size_y,
  1797 					dtss->size_z, ti->z + dtss->delta_z,
  1826 					dtss->size_z, ti->z + dtss->delta_z,
  1798 					IsTransparencySet(TO_BUILDINGS)
  1827 					!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS)
  1799 				);
  1828 				);
  1800 			} else {
  1829 			} else {
  1801 				AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
  1830 				AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y);
  1802 			}
  1831 			}
  1803 		}
  1832 		}
  1833 {
  1862 {
  1834 	uint32 offset = GetRailTypeInfo(railtype)->total_offset;
  1863 	uint32 offset = GetRailTypeInfo(railtype)->total_offset;
  1835 	const DrawTileSprites* dts = &_waypoint_gfx_table[AXIS_X];
  1864 	const DrawTileSprites* dts = &_waypoint_gfx_table[AXIS_X];
  1836 
  1865 
  1837 	DrawTileSequence(x, y, dts->ground_sprite + offset, dts->seq, 0);
  1866 	DrawTileSequence(x, y, dts->ground_sprite + offset, dts->seq, 0);
  1838 }
       
  1839 
       
  1840 struct SetSignalsData {
       
  1841 	int cur;
       
  1842 	int cur_stack;
       
  1843 	bool stop;
       
  1844 	bool has_presignal;
       
  1845 
       
  1846 	/* presignal info */
       
  1847 	int presignal_exits;
       
  1848 	int presignal_exits_free;
       
  1849 
       
  1850 	/* these are used to keep track of the signals that change. */
       
  1851 	TrackdirByte bit[NUM_SSD_ENTRY];
       
  1852 	TileIndex tile[NUM_SSD_ENTRY];
       
  1853 
       
  1854 	/* these are used to keep track of the stack that modifies presignals recursively */
       
  1855 	TileIndex next_tile[NUM_SSD_STACK];
       
  1856 	DiagDirectionByte next_dir[NUM_SSD_STACK];
       
  1857 
       
  1858 };
       
  1859 
       
  1860 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
       
  1861 {
       
  1862 	SetSignalsData* ssd = (SetSignalsData*)data;
       
  1863 	Track track = TrackdirToTrack(trackdir);
       
  1864 
       
  1865 	if (!IsTileType(tile, MP_RAILWAY)) return false;
       
  1866 
       
  1867 	/* the tile has signals? */
       
  1868 	if (HasSignalOnTrack(tile, track)) {
       
  1869 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
       
  1870 			/* yes, add the signal to the list of signals */
       
  1871 			if (ssd->cur != NUM_SSD_ENTRY) {
       
  1872 				ssd->tile[ssd->cur] = tile; // remember the tile index
       
  1873 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
       
  1874 				ssd->cur++;
       
  1875 			}
       
  1876 
       
  1877 			/* remember if this block has a presignal. */
       
  1878 			ssd->has_presignal |= IsPresignalEntry(tile, track);
       
  1879 		}
       
  1880 
       
  1881 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile, track)) {
       
  1882 			/* this is an exit signal that points out from the segment */
       
  1883 			ssd->presignal_exits++;
       
  1884 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
       
  1885 				ssd->presignal_exits_free++;
       
  1886 		}
       
  1887 
       
  1888 		return true;
       
  1889 	} else if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
       
  1890 		return true; // don't look further if the tile is a depot
       
  1891 	}
       
  1892 
       
  1893 	return false;
       
  1894 }
       
  1895 
       
  1896 /* Struct to parse data from VehicleFromPos to SignalVehicleCheckProc */
       
  1897 struct SignalVehicleCheckStruct {
       
  1898 	TileIndex tile;
       
  1899 	uint track;
       
  1900 };
       
  1901 
       
  1902 static void *SignalVehicleCheckProc(Vehicle *v, void *data)
       
  1903 {
       
  1904 	const SignalVehicleCheckStruct* dest = (SignalVehicleCheckStruct*)data;
       
  1905 
       
  1906 	if (v->type != VEH_TRAIN) return NULL;
       
  1907 
       
  1908 	/* Wrong tile, or no train? Not a match */
       
  1909 	if (v->tile != dest->tile) return NULL;
       
  1910 
       
  1911 	/* Are we on the same piece of track? */
       
  1912 	if (dest->track & v->u.rail.track * 0x101) return v;
       
  1913 
       
  1914 	return NULL;
       
  1915 }
       
  1916 
       
  1917 /* Special check for SetSignalsAfterProc, to see if there is a vehicle on this tile */
       
  1918 static bool SignalVehicleCheck(TileIndex tile, uint track)
       
  1919 {
       
  1920 	SignalVehicleCheckStruct dest;
       
  1921 
       
  1922 	dest.tile = tile;
       
  1923 	dest.track = track;
       
  1924 
       
  1925 	/* Locate vehicles in tunnels or on bridges */
       
  1926 	if (IsTunnelTile(tile) || IsBridgeTile(tile)) {
       
  1927 		TileIndex end;
       
  1928 		DiagDirection direction;
       
  1929 
       
  1930 		if (IsTunnelTile(tile)) {
       
  1931 			end = GetOtherTunnelEnd(tile);
       
  1932 			direction = GetTunnelDirection(tile);
       
  1933 		} else {
       
  1934 			end = GetOtherBridgeEnd(tile);
       
  1935 			direction = GetBridgeRampDirection(tile);
       
  1936 		}
       
  1937 
       
  1938 		dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
       
  1939 
       
  1940 		/* check for a vehicle with that trackdir on the start tile of the tunnel */
       
  1941 		if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
       
  1942 
       
  1943 		/* check for a vehicle with that trackdir on the end tile of the tunnel */
       
  1944 		if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
       
  1945 
       
  1946 		/* now check all tiles from start to end for a warping vehicle */
       
  1947 		dest.track = 0x40;   //Vehicle inside a tunnel or on a bridge
       
  1948 		if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
       
  1949 		if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
       
  1950 
       
  1951 		/* no vehicle found */
       
  1952 		return false;
       
  1953 	}
       
  1954 
       
  1955 	return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
       
  1956 }
       
  1957 
       
  1958 static void SetSignalsAfterProc(TrackPathFinder *tpf)
       
  1959 {
       
  1960 	SetSignalsData *ssd = (SetSignalsData*)tpf->userdata;
       
  1961 	const TrackPathFinderLink* link;
       
  1962 	uint offs;
       
  1963 	uint i;
       
  1964 
       
  1965 	ssd->stop = false;
       
  1966 
       
  1967 	/* Go through all the PF tiles */
       
  1968 	for (i = 0; i < lengthof(tpf->hash_head); i++) {
       
  1969 		/* Empty hash item */
       
  1970 		if (tpf->hash_head[i] == 0) continue;
       
  1971 
       
  1972 		/* If 0x8000 is not set, there is only 1 item */
       
  1973 		if (!(tpf->hash_head[i] & 0x8000)) {
       
  1974 			/* Check if there is a vehicle on this tile */
       
  1975 			if (SignalVehicleCheck(tpf->hash_tile[i], tpf->hash_head[i])) {
       
  1976 				ssd->stop = true;
       
  1977 				return;
       
  1978 			}
       
  1979 		} else {
       
  1980 			/* There are multiple items, where hash_tile points to the first item in the list */
       
  1981 			offs = tpf->hash_tile[i];
       
  1982 			do {
       
  1983 				/* Find the next item */
       
  1984 				link = PATHFIND_GET_LINK_PTR(tpf, offs);
       
  1985 				/* Check if there is a vehicle on this tile */
       
  1986 				if (SignalVehicleCheck(link->tile, link->flags)) {
       
  1987 					ssd->stop = true;
       
  1988 					return;
       
  1989 				}
       
  1990 				/* Goto the next item */
       
  1991 			} while ((offs = link->next) != 0xFFFF);
       
  1992 		}
       
  1993 	}
       
  1994 }
       
  1995 
       
  1996 static void ChangeSignalStates(SetSignalsData *ssd)
       
  1997 {
       
  1998 	int i;
       
  1999 
       
  2000 	/* thinking about presignals...
       
  2001 	 * the presignal is green if,
       
  2002 	 *   if no train is in the segment AND
       
  2003 	 *   there is at least one green exit signal OR
       
  2004 	 *   there are no exit signals in the segment */
       
  2005 
       
  2006 	/* then mark the signals in the segment accordingly */
       
  2007 	for (i = 0; i != ssd->cur; i++) {
       
  2008 		TileIndex tile = ssd->tile[i];
       
  2009 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
       
  2010 		uint signals = GetSignalStates(tile);
       
  2011 		Track track = TrackdirToTrack(ssd->bit[i]);
       
  2012 
       
  2013 		/* presignals don't turn green if there is at least one presignal exit and none are free */
       
  2014 		if (IsPresignalEntry(tile, track)) {
       
  2015 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
       
  2016 
       
  2017 			/* subtract for dual combo signals so they don't count themselves */
       
  2018 			if (IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
       
  2019 				ex--;
       
  2020 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
       
  2021 			}
       
  2022 
       
  2023 			/* if we have exits and none are free, make red. */
       
  2024 			if (ex && !exfree) goto make_red;
       
  2025 		}
       
  2026 
       
  2027 		/* check if the signal is unaffected. */
       
  2028 		if (ssd->stop) {
       
  2029 make_red:
       
  2030 			/* turn red */
       
  2031 			if ((bit & signals) == 0) continue;
       
  2032 		} else {
       
  2033 			/* turn green */
       
  2034 			if ((bit & signals) != 0) continue;
       
  2035 		}
       
  2036 
       
  2037 		/* Update signals on the other side of this exit-combo signal; it changed. */
       
  2038 		if (IsPresignalExit(tile, track)) {
       
  2039 			if (ssd->cur_stack != NUM_SSD_STACK) {
       
  2040 				ssd->next_tile[ssd->cur_stack] = tile;
       
  2041 				ssd->next_dir[ssd->cur_stack] = TrackdirToExitdir(ssd->bit[i]);
       
  2042 				ssd->cur_stack++;
       
  2043 			} else {
       
  2044 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
       
  2045 			}
       
  2046 		}
       
  2047 
       
  2048 		/* it changed, so toggle it */
       
  2049 		SetSignalStates(tile, signals ^ bit);
       
  2050 		MarkTileDirtyByTile(tile);
       
  2051 	}
       
  2052 }
       
  2053 
       
  2054 
       
  2055 bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction)
       
  2056 {
       
  2057 	SetSignalsData ssd;
       
  2058 	int result = -1;
       
  2059 
       
  2060 	ssd.cur_stack = 0;
       
  2061 
       
  2062 	for (;;) {
       
  2063 		/* go through one segment and update all signals pointing into that segment. */
       
  2064 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
       
  2065 		ssd.has_presignal = false;
       
  2066 
       
  2067 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, 0, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
       
  2068 		ChangeSignalStates(&ssd);
       
  2069 
       
  2070 		/* remember the result only for the first iteration. */
       
  2071 		if (result < 0) {
       
  2072 			/* stay in depot while segment is occupied or while all presignal exits are blocked */
       
  2073 			result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0);
       
  2074 		}
       
  2075 
       
  2076 		/* if any exit signals were changed, we need to keep going to modify the stuff behind those. */
       
  2077 		if (ssd.cur_stack == 0) break;
       
  2078 
       
  2079 		/* one or more exit signals were changed, so we need to update another segment too. */
       
  2080 		tile = ssd.next_tile[--ssd.cur_stack];
       
  2081 		direction = ssd.next_dir[ssd.cur_stack];
       
  2082 	}
       
  2083 
       
  2084 	return result != 0;
       
  2085 }
       
  2086 
       
  2087 void SetSignalsOnBothDir(TileIndex tile, byte track)
       
  2088 {
       
  2089 	static const DiagDirection _search_dir_1[] = {
       
  2090 		DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
       
  2091 	};
       
  2092 	static const DiagDirection _search_dir_2[] = {
       
  2093 		DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
       
  2094 	};
       
  2095 
       
  2096 	UpdateSignalsOnSegment(tile, _search_dir_1[track]);
       
  2097 	UpdateSignalsOnSegment(tile, _search_dir_2[track]);
       
  2098 }
  1867 }
  2099 
  1868 
  2100 static uint GetSlopeZ_Track(TileIndex tile, uint x, uint y)
  1869 static uint GetSlopeZ_Track(TileIndex tile, uint x, uint y)
  2101 {
  1870 {
  2102 	uint z;
  1871 	uint z;
  2358 static const signed char _deltacoord_leaveoffset[8] = {
  2127 static const signed char _deltacoord_leaveoffset[8] = {
  2359 	-1,  0,  1,  0, /* x */
  2128 	-1,  0,  1,  0, /* x */
  2360 	 0,  1,  0, -1  /* y */
  2129 	 0,  1,  0, -1  /* y */
  2361 };
  2130 };
  2362 
  2131 
  2363 static uint32 VehicleEnter_Track(Vehicle *v, TileIndex tile, int x, int y)
  2132 static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *v, TileIndex tile, int x, int y)
  2364 {
  2133 {
  2365 	byte fract_coord;
  2134 	byte fract_coord;
  2366 	byte fract_coord_leave;
  2135 	byte fract_coord_leave;
  2367 	DiagDirection dir;
  2136 	DiagDirection dir;
  2368 	int length;
  2137 	int length;
  2441 		case TRACK_BIT_LOWER: track_corner = CORNER_S; break;
  2210 		case TRACK_BIT_LOWER: track_corner = CORNER_S; break;
  2442 		case TRACK_BIT_RIGHT: track_corner = CORNER_E; break;
  2211 		case TRACK_BIT_RIGHT: track_corner = CORNER_E; break;
  2443 		case TRACK_BIT_UPPER: track_corner = CORNER_N; break;
  2212 		case TRACK_BIT_UPPER: track_corner = CORNER_N; break;
  2444 
  2213 
  2445 		/* Surface slope must not be changed */
  2214 		/* Surface slope must not be changed */
  2446 		default: return (((z_old != z_new) || (tileh_old != tileh_new)) ? CMD_ERROR : _price.terraform);
  2215 		default: return (((z_old != z_new) || (tileh_old != tileh_new)) ? CMD_ERROR : CommandCost(EXPENSES_CONSTRUCTION, _price.terraform));
  2447 	}
  2216 	}
  2448 
  2217 
  2449 	/* The height of the track_corner must not be changed. The rest ensures GetRailFoundation() already. */
  2218 	/* The height of the track_corner must not be changed. The rest ensures GetRailFoundation() already. */
  2450 	z_old += GetSlopeZInCorner((Slope)(tileh_old & ~SLOPE_HALFTILE_MASK), track_corner);
  2219 	z_old += GetSlopeZInCorner((Slope)(tileh_old & ~SLOPE_HALFTILE_MASK), track_corner);
  2451 	z_new += GetSlopeZInCorner((Slope)(tileh_new & ~SLOPE_HALFTILE_MASK), track_corner);
  2220 	z_new += GetSlopeZInCorner((Slope)(tileh_new & ~SLOPE_HALFTILE_MASK), track_corner);
  2452 	if (z_old != z_new) return CMD_ERROR;
  2221 	if (z_old != z_new) return CMD_ERROR;
  2453 
  2222 
  2454 	CommandCost cost = CommandCost(_price.terraform);
  2223 	CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2455 	/* Make the ground dirty, if surface slope has changed */
  2224 	/* Make the ground dirty, if surface slope has changed */
  2456 	if (tileh_old != tileh_new) {
  2225 	if (tileh_old != tileh_new) {
  2457 		if (GetRailGroundType(tile) == RAIL_GROUND_WATER) cost.AddCost(_price.clear_water);
  2226 		if (GetRailGroundType(tile) == RAIL_GROUND_WATER) cost.AddCost(_price.clear_water);
  2458 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
  2227 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
  2459 	}
  2228 	}
  2496 
  2265 
  2497 		/* Make the ground dirty */
  2266 		/* Make the ground dirty */
  2498 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
  2267 		if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
  2499 
  2268 
  2500 		/* allow terraforming */
  2269 		/* allow terraforming */
  2501 		return (was_water ? CommandCost(_price.clear_water) : CommandCost());
  2270 		return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price.clear_water : (Money)0);
  2502 	} else {
  2271 	} else {
  2503 		if (_patches.build_on_slopes && AutoslopeEnabled()) {
  2272 		if (_patches.build_on_slopes && AutoslopeEnabled()) {
  2504 			switch (GetRailTileType(tile)) {
  2273 			switch (GetRailTileType(tile)) {
  2505 				case RAIL_TILE_WAYPOINT: {
  2274 				case RAIL_TILE_WAYPOINT: {
  2506 					CommandCost cost = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, GetRailWaypointBits(tile));
  2275 					CommandCost cost = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, GetRailWaypointBits(tile));
  2507 					if (!CmdFailed(cost)) return cost; // allow autoslope
  2276 					if (!CmdFailed(cost)) return cost; // allow autoslope
  2508 					break;
  2277 					break;
  2509 				}
  2278 				}
  2510 
  2279 
  2511 				case RAIL_TILE_DEPOT:
  2280 				case RAIL_TILE_DEPOT:
  2512 					if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) return _price.terraform;
  2281 					if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
  2513 					break;
  2282 					break;
  2514 
  2283 
  2515 				default: NOT_REACHED();
  2284 				default: NOT_REACHED();
  2516 			}
  2285 			}
  2517 		}
  2286 		}