src/rail_cmd.cpp
branchgamebalance
changeset 9908 0fa543611bbe
parent 9907 3b068c3a1c74
child 9909 dce9a6923bb7
equal deleted inserted replaced
9907:3b068c3a1c74 9908:0fa543611bbe
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file rail_cmd.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "bridge_map.h"
     7 #include "bridge_map.h"
     6 #include "bridge.h"
     8 #include "bridge.h"
    75  *               11uuuudd => rail depot
    77  *               11uuuudd => rail depot
    76  */
    78  */
    77 
    79 
    78 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
    80 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
    79 {
    81 {
    80 	TrackBits current; /* The current track layout */
    82 	TrackBits current; // The current track layout
    81 	TrackBits future; /* The track layout we want to build */
    83 	TrackBits future;  // The track layout we want to build
    82 	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
    84 	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
    83 
    85 
    84 	if (!IsPlainRailTile(tile)) return false;
    86 	if (!IsPlainRailTile(tile)) return false;
    85 
    87 
    86 	/* So, we have a tile with tracks on it (and possibly signals). Let's see
    88 	/* So, we have a tile with tracks on it (and possibly signals). Let's see
   107 }
   109 }
   108 
   110 
   109 
   111 
   110 static const TrackBits _valid_tileh_slopes[][15] = {
   112 static const TrackBits _valid_tileh_slopes[][15] = {
   111 
   113 
   112 // set of normal ones
   114 /* set of normal ones */
   113 {
   115 {
   114 	TRACK_BIT_ALL,
   116 	TRACK_BIT_ALL,
   115 	TRACK_BIT_RIGHT,
   117 	TRACK_BIT_RIGHT,
   116 	TRACK_BIT_UPPER,
   118 	TRACK_BIT_UPPER,
   117 	TRACK_BIT_X,
   119 	TRACK_BIT_X,
   129 	TRACK_BIT_X,
   131 	TRACK_BIT_X,
   130 	TRACK_BIT_UPPER,
   132 	TRACK_BIT_UPPER,
   131 	TRACK_BIT_RIGHT,
   133 	TRACK_BIT_RIGHT,
   132 },
   134 },
   133 
   135 
   134 // allowed rail for an evenly raised platform
   136 /* allowed rail for an evenly raised platform */
   135 {
   137 {
   136 	TRACK_BIT_NONE,
   138 	TRACK_BIT_NONE,
   137 	TRACK_BIT_LEFT,
   139 	TRACK_BIT_LEFT,
   138 	TRACK_BIT_LOWER,
   140 	TRACK_BIT_LOWER,
   139 	TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
   141 	TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
   188 
   190 
   189 
   191 
   190 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   192 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   191 {
   193 {
   192 	if (IsSteepSlope(tileh)) {
   194 	if (IsSteepSlope(tileh)) {
   193 		if (existing == 0) {
   195 		if (_patches.build_on_slopes && existing == 0) {
   194 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   196 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   195 			if (valid & rail_bits) return _eco->GetPrice(CEconomy::TERRAFORM);
   197 			if (valid & rail_bits) return _eco->GetPrice(CEconomy::TERRAFORM);
   196 		}
   198 		}
   197 	} else {
   199 	} else {
   198 		rail_bits |= existing;
   200 		rail_bits |= existing;
   199 
   201 
   200 		// don't allow building on the lower side of a coast
   202 		/* don't allow building on the lower side of a coast */
   201 		if (IsTileType(tile, MP_WATER) &&
   203 		if (IsTileType(tile, MP_WATER) &&
   202 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   204 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   203 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   205 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   204 		}
   206 		}
   205 
   207 
   206 		// no special foundation
   208 		/* no special foundation */
   207 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0)
   209 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0)
   208 			return 0;
   210 			return 0;
   209 
   211 
   210 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
   212 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
   211 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
   213 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
   250 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   252 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   251 
   253 
   252 	switch (GetTileType(tile)) {
   254 	switch (GetTileType(tile)) {
   253 		case MP_RAILWAY:
   255 		case MP_RAILWAY:
   254 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   256 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   255 					!EnsureNoVehicle(tile)) {
   257 					!EnsureNoVehicleOnGround(tile)) {
   256 				return CMD_ERROR;
   258 				return CMD_ERROR;
   257 			}
   259 			}
   258 			if (!IsTileOwner(tile, _current_player) ||
   260 			if (!IsTileOwner(tile, _current_player) ||
   259 					!IsCompatibleRail(GetRailType(tile), railtype)) {
   261 					!IsCompatibleRail(GetRailType(tile), railtype)) {
   260 				// Get detailed error message
   262 				/* Get detailed error message */
   261 				return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   263 				return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   262 			}
   264 			}
   263 
   265 
   264 			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
   266 			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
   265 			if (CmdFailed(ret)) return ret;
   267 			if (CmdFailed(ret)) return ret;
   286 			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
   288 			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
   287 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   289 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   288 			}
   290 			}
   289 #undef M
   291 #undef M
   290 
   292 
   291 			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   293 			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
   292 
   294 
   293 			if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
   295 			if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
   294 				if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
   296 				if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
   295 
   297 
   296 				if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) ||
   298 				if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) ||
   350 	switch (GetTileType(tile)) {
   352 	switch (GetTileType(tile)) {
   351 		case MP_STREET: {
   353 		case MP_STREET: {
   352 			if (!IsLevelCrossing(tile) ||
   354 			if (!IsLevelCrossing(tile) ||
   353 					GetCrossingRailBits(tile) != trackbit ||
   355 					GetCrossingRailBits(tile) != trackbit ||
   354 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   356 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   355 					!EnsureNoVehicle(tile)) {
   357 					!EnsureNoVehicleOnGround(tile)) {
   356 				return CMD_ERROR;
   358 				return CMD_ERROR;
   357 			}
   359 			}
   358 
   360 
   359 			cost += _eco->GetPrice(CEconomy::PRICE_RAIL_REMOVE, tile, true);
   361 			cost += _eco->GetPrice(CEconomy::PRICE_RAIL_REMOVE, tile, true);
   360 			if (flags & DC_EXEC) {
   362 			if (flags & DC_EXEC) {
   366 		case MP_RAILWAY: {
   368 		case MP_RAILWAY: {
   367 			TrackBits present;
   369 			TrackBits present;
   368 
   370 
   369 			if (!IsPlainRailTile(tile) ||
   371 			if (!IsPlainRailTile(tile) ||
   370 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   372 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   371 					!EnsureNoVehicle(tile)) {
   373 					!EnsureNoVehicleOnGround(tile)) {
   372 				return CMD_ERROR;
   374 				return CMD_ERROR;
   373 			}
   375 			}
   374 
   376 
   375 			present = GetTrackBits(tile);
   377 			present = GetTrackBits(tile);
   376 			if ((present & trackbit) == 0) return CMD_ERROR;
   378 			if ((present & trackbit) == 0) return CMD_ERROR;
   434 	int ey = TileY(end);
   436 	int ey = TileY(end);
   435 	int dx, dy, trdx, trdy;
   437 	int dx, dy, trdx, trdy;
   436 
   438 
   437 	if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR;
   439 	if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR;
   438 
   440 
   439 	// calculate delta x,y from start to end tile
   441 	/* calculate delta x,y from start to end tile */
   440 	dx = ex - x;
   442 	dx = ex - x;
   441 	dy = ey - y;
   443 	dy = ey - y;
   442 
   444 
   443 	// calculate delta x,y for the first direction
   445 	/* calculate delta x,y for the first direction */
   444 	trdx = _trackdelta[*trackdir].x;
   446 	trdx = _trackdelta[*trackdir].x;
   445 	trdy = _trackdelta[*trackdir].y;
   447 	trdy = _trackdelta[*trackdir].y;
   446 
   448 
   447 	if (!IsDiagonalTrackdir(*trackdir)) {
   449 	if (!IsDiagonalTrackdir(*trackdir)) {
   448 		trdx += _trackdelta[*trackdir ^ 1].x;
   450 		trdx += _trackdelta[*trackdir ^ 1].x;
   449 		trdy += _trackdelta[*trackdir ^ 1].y;
   451 		trdy += _trackdelta[*trackdir ^ 1].y;
   450 	}
   452 	}
   451 
   453 
   452 	// validate the direction
   454 	/* validate the direction */
   453 	while (
   455 	while (
   454 		(trdx <= 0 && dx > 0) ||
   456 		(trdx <= 0 && dx > 0) ||
   455 		(trdx >= 0 && dx < 0) ||
   457 		(trdx >= 0 && dx < 0) ||
   456 		(trdy <= 0 && dy > 0) ||
   458 		(trdy <= 0 && dy > 0) ||
   457 		(trdy >= 0 && dy < 0)
   459 		(trdy >= 0 && dy < 0)
   463 		} else { // other direction is invalid too, invalid drag
   465 		} else { // other direction is invalid too, invalid drag
   464 			return CMD_ERROR;
   466 			return CMD_ERROR;
   465 		}
   467 		}
   466 	}
   468 	}
   467 
   469 
   468 	// (for diagonal tracks, this is already made sure of by above test), but:
   470 	/* (for diagonal tracks, this is already made sure of by above test), but:
   469 	// for non-diagonal tracks, check if the start and end tile are on 1 line
   471 	 * for non-diagonal tracks, check if the start and end tile are on 1 line */
   470 	if (!IsDiagonalTrackdir(*trackdir)) {
   472 	if (!IsDiagonalTrackdir(*trackdir)) {
   471 		trdx = _trackdelta[*trackdir].x;
   473 		trdx = _trackdelta[*trackdir].x;
   472 		trdy = _trackdelta[*trackdir].y;
   474 		trdy = _trackdelta[*trackdir].y;
   473 		if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx))
   475 		if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx))
   474 			return CMD_ERROR;
   476 			return CMD_ERROR;
   517 
   519 
   518 		if (tile == end_tile) break;
   520 		if (tile == end_tile) break;
   519 
   521 
   520 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   522 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   521 
   523 
   522 		// toggle railbit for the non-diagonal tracks
   524 		/* toggle railbit for the non-diagonal tracks */
   523 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   525 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   524 	}
   526 	}
   525 
   527 
   526 	return (total_cost == 0) ? CMD_ERROR : total_cost;
   528 	return (total_cost == 0) ? CMD_ERROR : total_cost;
   527 }
   529 }
   625 	Track track = (Track)GB(p1, 0, 3);
   627 	Track track = (Track)GB(p1, 0, 3);
   626 	bool pre_signal = HASBIT(p1, 3);
   628 	bool pre_signal = HASBIT(p1, 3);
   627 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   629 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   628 	int32 cost;
   630 	int32 cost;
   629 
   631 
   630 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
   632 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
   631 		return CMD_ERROR;
   633 		return CMD_ERROR;
   632 
   634 
   633 	/* Protect against invalid signal copying */
   635 	/* Protect against invalid signal copying */
   634 	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
   636 	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
   635 
   637 
   651 	}
   653 	}
   652 
   654 
   653 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   655 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   654 
   656 
   655 	if (!HasSignalOnTrack(tile, track)) {
   657 	if (!HasSignalOnTrack(tile, track)) {
   656 		// build new signals
   658 		/* build new signals */
   657 		cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS);
   659 		cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS);
   658 	} else {
   660 	} else {
   659 		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
   661 		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
   660 			// convert signals <-> semaphores
   662 			/* convert signals <-> semaphores */
   661 			cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS) + _eco->GetPrice(CEconomy::REMOVE_SIGNALS);
   663 			cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS) + _eco->GetPrice(CEconomy::REMOVE_SIGNALS);
   662 		} else {
   664 		} else {
   663 			// it is free to change orientation/pre-exit-combo signals
   665 			/* it is free to change orientation/pre-exit-combo signals */
   664 			cost = 0;
   666 			cost = 0;
   665 		}
   667 		}
   666 	}
   668 	}
   667 
   669 
   668 	if (flags & DC_EXEC) {
   670 	if (flags & DC_EXEC) {
   669 		if (!HasSignals(tile)) {
   671 		if (!HasSignals(tile)) {
   670 			// there are no signals at all on this tile yet
   672 			/* there are no signals at all on this tile yet */
   671 			SetHasSignals(tile, true);
   673 			SetHasSignals(tile, true);
   672 			_m[tile].m2 |= 0xF0;              // all signals are on
   674 			_m[tile].m2 |= 0xF0;              // all signals are on
   673 			_m[tile].m3 &= ~0xF0;          // no signals built by default
   675 			_m[tile].m3 &= ~0xF0;             // no signals built by default
   674 			SetSignalType(tile, SIGTYPE_NORMAL);
   676 			SetSignalType(tile, SIGTYPE_NORMAL);
   675 			SetSignalVariant(tile, sigvar);
   677 			SetSignalVariant(tile, sigvar);
   676 		}
   678 		}
   677 
   679 
   678 		if (p2 == 0) {
   680 		if (p2 == 0) {
   679 			if (!HasSignalOnTrack(tile, track)) {
   681 			if (!HasSignalOnTrack(tile, track)) {
   680 				// build new signals
   682 				/* build new signals */
   681 				_m[tile].m3 |= SignalOnTrack(track);
   683 				_m[tile].m3 |= SignalOnTrack(track);
   682 			} else {
   684 			} else {
   683 				if (pre_signal) {
   685 				if (pre_signal) {
   684 					// cycle between normal -> pre -> exit -> combo -> ...
   686 					/* cycle between normal -> pre -> exit -> combo -> ... */
   685 					SignalType type = GetSignalType(tile);
   687 					SignalType type = GetSignalType(tile);
   686 
   688 
   687 					SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   689 					SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   688 				} else {
   690 				} else {
   689 					CycleSignalSide(tile, track);
   691 					CycleSignalSide(tile, track);
   743 
   745 
   744 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
   746 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
   745 
   747 
   746 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
   748 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
   747 
   749 
   748 	// copy the signal-style of the first rail-piece if existing
   750 	/* copy the signal-style of the first rail-piece if existing */
   749 	if (HasSignals(tile)) {
   751 	if (HasSignals(tile)) {
   750 		signals = _m[tile].m3 & SignalOnTrack(track);
   752 		signals = _m[tile].m3 & SignalOnTrack(track);
   751 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   753 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   752 
   754 
   753 		// copy signal/semaphores style (independent of CTRL)
   755 		/* copy signal/semaphores style (independent of CTRL) */
   754 		semaphores = GetSignalVariant(tile) != SIG_ELECTRIC;
   756 		semaphores = GetSignalVariant(tile) != SIG_ELECTRIC;
   755 	} else { // no signals exist, drag a two-way signal stretch
   757 	} else { // no signals exist, drag a two-way signal stretch
   756 		signals = SignalOnTrack(track);
   758 		signals = SignalOnTrack(track);
   757 	}
   759 	}
   758 
   760 
   764 	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
   766 	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
   765 	 *              and convert all others to semaphore/signal
   767 	 *              and convert all others to semaphore/signal
   766 	 * remove     - 1 remove signals, 0 build signals */
   768 	 * remove     - 1 remove signals, 0 build signals */
   767 	signal_ctr = total_cost = 0;
   769 	signal_ctr = total_cost = 0;
   768 	for (;;) {
   770 	for (;;) {
   769 		// only build/remove signals with the specified density
   771 		/* only build/remove signals with the specified density */
   770 		if (signal_ctr % signal_density == 0) {
   772 		if (signal_ctr % signal_density == 0) {
   771 			uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
   773 			uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
   772 			SB(p1, 3, 1, mode);
   774 			SB(p1, 3, 1, mode);
   773 			SB(p1, 4, 1, semaphores);
   775 			SB(p1, 4, 1, semaphores);
   774 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
   776 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
   783 		if (tile == end_tile) break;
   785 		if (tile == end_tile) break;
   784 
   786 
   785 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   787 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   786 		signal_ctr++;
   788 		signal_ctr++;
   787 
   789 
   788 		// toggle railbit for the non-diagonal tracks (|, -- tracks)
   790 		/* toggle railbit for the non-diagonal tracks (|, -- tracks) */
   789 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   791 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   790 	}
   792 	}
   791 
   793 
   792 	return error ? CMD_ERROR : total_cost;
   794 	return error ? CMD_ERROR : total_cost;
   793 }
   795 }
   812 {
   814 {
   813 	Track track = (Track)GB(p1, 0, 3);
   815 	Track track = (Track)GB(p1, 0, 3);
   814 
   816 
   815 	if (!ValParamTrackOrientation(track) ||
   817 	if (!ValParamTrackOrientation(track) ||
   816 			!IsTileType(tile, MP_RAILWAY) ||
   818 			!IsTileType(tile, MP_RAILWAY) ||
   817 			!EnsureNoVehicle(tile) ||
   819 			!EnsureNoVehicleOnGround(tile) ||
   818 			!HasSignalOnTrack(tile, track)) {
   820 			!HasSignalOnTrack(tile, track)) {
   819 		return CMD_ERROR;
   821 		return CMD_ERROR;
   820 	}
   822 	}
   821 
   823 
   822 	/* Only water can remove signals from anyone */
   824 	/* Only water can remove signals from anyone */
   869 {
   871 {
   870 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   872 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   871 
   873 
   872 	if (GetRailType(tile) == totype) return CMD_ERROR;
   874 	if (GetRailType(tile) == totype) return CMD_ERROR;
   873 
   875 
   874 	if (!EnsureNoVehicle(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR;
   876 	if (!EnsureNoVehicleOnGround(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR;
   875 
   877 
   876 	// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
   878 	/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
   877 	if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   879 	if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   878 
   880 
   879 	// change type.
   881 	/* change type. */
   880 	if (exec) {
   882 	if (exec) {
   881 		SetRailType(tile, totype);
   883 		SetRailType(tile, totype);
   882 		MarkTileDirtyByTile(tile);
   884 		MarkTileDirtyByTile(tile);
   883 
   885 
   884 		// notify YAPF about the track layout change
   886 		/* notify YAPF about the track layout change */
   885 		TrackBits tracks = GetTrackBits(tile);
   887 		TrackBits tracks = GetTrackBits(tile);
   886 		while (tracks != TRACK_BIT_NONE) {
   888 		while (tracks != TRACK_BIT_NONE) {
   887 			YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
   889 			YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
   888 		}
   890 		}
   889 
   891 
   925 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   927 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   926 
   928 
   927 	if (!ValParamRailtype(p2)) return CMD_ERROR;
   929 	if (!ValParamRailtype(p2)) return CMD_ERROR;
   928 	if (p1 >= MapSize()) return CMD_ERROR;
   930 	if (p1 >= MapSize()) return CMD_ERROR;
   929 
   931 
   930 	// make sure sx,sy are smaller than ex,ey
   932 	/* make sure sx,sy are smaller than ex,ey */
   931 	ex = TileX(tile);
   933 	ex = TileX(tile);
   932 	ey = TileY(tile);
   934 	ey = TileY(tile);
   933 	sx = TileX(p1);
   935 	sx = TileX(p1);
   934 	sy = TileY(p1);
   936 	sy = TileY(p1);
   935 	if (ex < sx) Swap(ex, sx);
   937 	if (ex < sx) Swap(ex, sx);
   973 static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
   975 static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
   974 {
   976 {
   975 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
   977 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
   976 		return CMD_ERROR;
   978 		return CMD_ERROR;
   977 
   979 
   978 	if (!EnsureNoVehicle(tile))
   980 	if (!EnsureNoVehicleOnGround(tile))
   979 		return CMD_ERROR;
   981 		return CMD_ERROR;
   980 
   982 
   981 	if (flags & DC_EXEC) {
   983 	if (flags & DC_EXEC) {
   982 		DiagDirection dir = GetRailDepotDirection(tile);
   984 		DiagDirection dir = GetRailDepotDirection(tile);
   983 
   985 
  1190 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
  1192 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
  1191 	SpriteID image;
  1193 	SpriteID image;
  1192 	SpriteID pal = PAL_NONE;
  1194 	SpriteID pal = PAL_NONE;
  1193 	bool junction = false;
  1195 	bool junction = false;
  1194 
  1196 
  1195 	// Select the sprite to use.
  1197 	/* Select the sprite to use. */
  1196 	(image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
  1198 	(image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
  1197 	(image++,                           track == TRACK_BIT_X) ||
  1199 	(image++,                           track == TRACK_BIT_X) ||
  1198 	(image++,                           track == TRACK_BIT_UPPER) ||
  1200 	(image++,                           track == TRACK_BIT_UPPER) ||
  1199 	(image++,                           track == TRACK_BIT_LOWER) ||
  1201 	(image++,                           track == TRACK_BIT_LOWER) ||
  1200 	(image++,                           track == TRACK_BIT_RIGHT) ||
  1202 	(image++,                           track == TRACK_BIT_RIGHT) ||
  1214 	if (ti->tileh != SLOPE_FLAT) {
  1216 	if (ti->tileh != SLOPE_FLAT) {
  1215 		uint foundation = GetRailFoundation(ti->tileh, track);
  1217 		uint foundation = GetRailFoundation(ti->tileh, track);
  1216 
  1218 
  1217 		if (foundation != 0) DrawFoundation(ti, foundation);
  1219 		if (foundation != 0) DrawFoundation(ti, foundation);
  1218 
  1220 
  1219 		// DrawFoundation() modifies ti.
  1221 		/* DrawFoundation() modifies it.
  1220 		// Default sloped sprites..
  1222 		 * Default sloped sprites.. */
  1221 		if (ti->tileh != SLOPE_FLAT)
  1223 		if (ti->tileh != SLOPE_FLAT)
  1222 			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
  1224 			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
  1223 	}
  1225 	}
  1224 
  1226 
  1225 	switch (GetRailGroundType(ti->tile)) {
  1227 	switch (GetRailGroundType(ti->tile)) {
  1228 		default: break;
  1230 		default: break;
  1229 	}
  1231 	}
  1230 
  1232 
  1231 	DrawGroundSprite(image, pal);
  1233 	DrawGroundSprite(image, pal);
  1232 
  1234 
  1233 	// Draw track pieces individually for junction tiles
  1235 	/* Draw track pieces individually for junction tiles */
  1234 	if (junction) {
  1236 	if (junction) {
  1235 		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
  1237 		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
  1236 		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
  1238 		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
  1237 		if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE);
  1239 		if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE);
  1238 		if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE);
  1240 		if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE);
  1290 
  1292 
  1291 		if (_display_opt & DO_FULL_DETAIL) DrawTrackDetails(ti);
  1293 		if (_display_opt & DO_FULL_DETAIL) DrawTrackDetails(ti);
  1292 
  1294 
  1293 		if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
  1295 		if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
  1294 	} else {
  1296 	} else {
  1295 		// draw depot/waypoint
  1297 		/* draw depot/waypoint */
  1296 		const DrawTileSprites* dts;
  1298 		const DrawTileSprites* dts;
  1297 		const DrawTileSeqStruct* dtss;
  1299 		const DrawTileSeqStruct* dtss;
  1298 		uint32 relocation;
  1300 		uint32 relocation;
  1299 
  1301 
  1300 		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
  1302 		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
  1305 			relocation = rti->total_offset;
  1307 			relocation = rti->total_offset;
  1306 
  1308 
  1307 			image = dts->ground_sprite;
  1309 			image = dts->ground_sprite;
  1308 			if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
  1310 			if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
  1309 
  1311 
  1310 			// adjust ground tile for desert
  1312 			/* adjust ground tile for desert
  1311 			// don't adjust for snow, because snow in depots looks weird
  1313 			 * don't adjust for snow, because snow in depots looks weird */
  1312 			if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_TROPIC) {
  1314 			if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_TROPIC) {
  1313 				if (image != SPR_FLAT_GRASS_TILE) {
  1315 				if (image != SPR_FLAT_GRASS_TILE) {
  1314 					image += rti->snow_offset; // tile with tracks
  1316 					image += rti->snow_offset; // tile with tracks
  1315 				} else {
  1317 				} else {
  1316 					image = SPR_FLAT_SNOWY_TILE; // flat ground
  1318 					image = SPR_FLAT_SNOWY_TILE; // flat ground
  1317 				}
  1319 				}
  1318 			}
  1320 			}
  1319 		} else {
  1321 		} else {
  1320 			// look for customization
  1322 			/* look for customization */
  1321 			byte stat_id = GetWaypointByTile(ti->tile)->stat_id;
  1323 			byte stat_id = GetWaypointByTile(ti->tile)->stat_id;
  1322 			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id);
  1324 			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id);
  1323 
  1325 
  1324 			if (statspec != NULL) {
  1326 			if (statspec != NULL) {
  1325 				// emulate station tile - open with building
  1327 				/* emulate station tile - open with building */
  1326 				const Station* st = ComposeWaypointStation(ti->tile);
  1328 				const Station* st = ComposeWaypointStation(ti->tile);
  1327 				uint gfx = 2;
  1329 				uint gfx = 2;
  1328 
  1330 
  1329 				if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
  1331 				if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
  1330 					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
  1332 					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
  1350 				} else {
  1352 				} else {
  1351 					goto default_waypoint;
  1353 					goto default_waypoint;
  1352 				}
  1354 				}
  1353 			} else {
  1355 			} else {
  1354 default_waypoint:
  1356 default_waypoint:
  1355 				// There is no custom layout, fall back to the default graphics
  1357 				/* There is no custom layout, fall back to the default graphics */
  1356 				dts = &_waypoint_gfx_table[GetWaypointAxis(ti->tile)];
  1358 				dts = &_waypoint_gfx_table[GetWaypointAxis(ti->tile)];
  1357 				relocation = 0;
  1359 				relocation = 0;
  1358 				image = dts->ground_sprite + rti->total_offset;
  1360 				image = dts->ground_sprite + rti->total_offset;
  1359 				if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
  1361 				if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
  1360 			}
  1362 			}
  1375 				image += rti->total_offset;
  1377 				image += rti->total_offset;
  1376 			} else {
  1378 			} else {
  1377 				image += relocation;
  1379 				image += relocation;
  1378 			}
  1380 			}
  1379 
  1381 
  1380 			if (_display_opt & DO_TRANS_BUILDINGS) {
  1382 			if (HASBIT(_transparent_opt, TO_BUILDINGS)) {
  1381 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1383 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1382 				pal = PALETTE_TO_TRANSPARENT;
  1384 				pal = PALETTE_TO_TRANSPARENT;
  1383 			} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
  1385 			} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
  1384 				pal = _drawtile_track_palette;
  1386 				pal = _drawtile_track_palette;
  1385 			} else {
  1387 			} else {
  1437 	int cur;
  1439 	int cur;
  1438 	int cur_stack;
  1440 	int cur_stack;
  1439 	bool stop;
  1441 	bool stop;
  1440 	bool has_presignal;
  1442 	bool has_presignal;
  1441 
  1443 
  1442 	// presignal info
  1444 	/* presignal info */
  1443 	int presignal_exits;
  1445 	int presignal_exits;
  1444 	int presignal_exits_free;
  1446 	int presignal_exits_free;
  1445 
  1447 
  1446 	// these are used to keep track of the signals that change.
  1448 	/* these are used to keep track of the signals that change. */
  1447 	TrackdirByte bit[NUM_SSD_ENTRY];
  1449 	TrackdirByte bit[NUM_SSD_ENTRY];
  1448 	TileIndex tile[NUM_SSD_ENTRY];
  1450 	TileIndex tile[NUM_SSD_ENTRY];
  1449 
  1451 
  1450 	// these are used to keep track of the stack that modifies presignals recursively
  1452 	/* these are used to keep track of the stack that modifies presignals recursively */
  1451 	TileIndex next_tile[NUM_SSD_STACK];
  1453 	TileIndex next_tile[NUM_SSD_STACK];
  1452 	DiagDirectionByte next_dir[NUM_SSD_STACK];
  1454 	DiagDirectionByte next_dir[NUM_SSD_STACK];
  1453 
  1455 
  1454 };
  1456 };
  1455 
  1457 
  1457 {
  1459 {
  1458 	SetSignalsData* ssd = (SetSignalsData*)data;
  1460 	SetSignalsData* ssd = (SetSignalsData*)data;
  1459 
  1461 
  1460 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1462 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1461 
  1463 
  1462 	// the tile has signals?
  1464 	/* the tile has signals? */
  1463 	if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) {
  1465 	if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) {
  1464 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1466 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1465 			// yes, add the signal to the list of signals
  1467 			/* yes, add the signal to the list of signals */
  1466 			if (ssd->cur != NUM_SSD_ENTRY) {
  1468 			if (ssd->cur != NUM_SSD_ENTRY) {
  1467 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1469 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1468 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1470 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1469 				ssd->cur++;
  1471 				ssd->cur++;
  1470 			}
  1472 			}
  1471 
  1473 
  1472 			// remember if this block has a presignal.
  1474 			/* remember if this block has a presignal. */
  1473 			ssd->has_presignal |= IsPresignalEntry(tile);
  1475 			ssd->has_presignal |= IsPresignalEntry(tile);
  1474 		}
  1476 		}
  1475 
  1477 
  1476 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) {
  1478 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) {
  1477 			// this is an exit signal that points out from the segment
  1479 			/* this is an exit signal that points out from the segment */
  1478 			ssd->presignal_exits++;
  1480 			ssd->presignal_exits++;
  1479 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1481 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1480 				ssd->presignal_exits_free++;
  1482 				ssd->presignal_exits_free++;
  1481 		}
  1483 		}
  1482 
  1484 
  1530 			direction = GetBridgeRampDirection(tile);
  1532 			direction = GetBridgeRampDirection(tile);
  1531 		}
  1533 		}
  1532 
  1534 
  1533 		dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
  1535 		dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
  1534 
  1536 
  1535 		// check for a vehicle with that trackdir on the start tile of the tunnel
  1537 		/* check for a vehicle with that trackdir on the start tile of the tunnel */
  1536 		if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
  1538 		if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
  1537 
  1539 
  1538 		// check for a vehicle with that trackdir on the end tile of the tunnel
  1540 		/* check for a vehicle with that trackdir on the end tile of the tunnel */
  1539 		if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
  1541 		if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
  1540 
  1542 
  1541 		// now check all tiles from start to end for a warping vehicle
  1543 		/* now check all tiles from start to end for a warping vehicle
  1542 		// NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile?
  1544 		 * NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile? */
  1543 		dest.track = 0x40;   //Vehicle inside a tunnel or on a bridge
  1545 		dest.track = 0x40;   //Vehicle inside a tunnel or on a bridge
  1544 		for (; tile != end; tile += TileOffsByDiagDir(direction)) {
  1546 		for (; tile != end; tile += TileOffsByDiagDir(direction)) {
  1545 			if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
  1547 			if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
  1546 				return true;
  1548 				return true;
  1547 		}
  1549 		}
  1548 
  1550 
  1549 		// no vehicle found
  1551 		/* no vehicle found */
  1550 		return false;
  1552 		return false;
  1551 	}
  1553 	}
  1552 
  1554 
  1553 	return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
  1555 	return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
  1554 }
  1556 }
  1599 
  1601 
  1600 static void ChangeSignalStates(SetSignalsData *ssd)
  1602 static void ChangeSignalStates(SetSignalsData *ssd)
  1601 {
  1603 {
  1602 	int i;
  1604 	int i;
  1603 
  1605 
  1604 	// thinking about presignals...
  1606 	/* thinking about presignals...
  1605 	// the presignal is green if,
  1607 	 * the presignal is green if,
  1606 	//   if no train is in the segment AND
  1608 	 *   if no train is in the segment AND
  1607 	//   there is at least one green exit signal OR
  1609 	 *   there is at least one green exit signal OR
  1608 	//   there are no exit signals in the segment
  1610 	 *   there are no exit signals in the segment */
  1609 
  1611 
  1610 	// then mark the signals in the segment accordingly
  1612 	/* then mark the signals in the segment accordingly */
  1611 	for (i = 0; i != ssd->cur; i++) {
  1613 	for (i = 0; i != ssd->cur; i++) {
  1612 		TileIndex tile = ssd->tile[i];
  1614 		TileIndex tile = ssd->tile[i];
  1613 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1615 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1614 		uint16 m2 = _m[tile].m2;
  1616 		uint16 m2 = _m[tile].m2;
  1615 
  1617 
  1616 		// presignals don't turn green if there is at least one presignal exit and none are free
  1618 		/* presignals don't turn green if there is at least one presignal exit and none are free */
  1617 		if (IsPresignalEntry(tile)) {
  1619 		if (IsPresignalEntry(tile)) {
  1618 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1620 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1619 
  1621 
  1620 			// subtract for dual combo signals so they don't count themselves
  1622 			/* subtract for dual combo signals so they don't count themselves */
  1621 			if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1623 			if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1622 				ex--;
  1624 				ex--;
  1623 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1625 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1624 			}
  1626 			}
  1625 
  1627 
  1626 			// if we have exits and none are free, make red.
  1628 			/* if we have exits and none are free, make red. */
  1627 			if (ex && !exfree) goto make_red;
  1629 			if (ex && !exfree) goto make_red;
  1628 		}
  1630 		}
  1629 
  1631 
  1630 		// check if the signal is unaffected.
  1632 		/* check if the signal is unaffected. */
  1631 		if (ssd->stop) {
  1633 		if (ssd->stop) {
  1632 make_red:
  1634 make_red:
  1633 			// turn red
  1635 			/* turn red */
  1634 			if ((bit & m2) == 0) continue;
  1636 			if ((bit & m2) == 0) continue;
  1635 		} else {
  1637 		} else {
  1636 			// turn green
  1638 			/* turn green */
  1637 			if ((bit & m2) != 0) continue;
  1639 			if ((bit & m2) != 0) continue;
  1638 		}
  1640 		}
  1639 
  1641 
  1640 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1642 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1641 		if (IsPresignalExit(tile)) {
  1643 		if (IsPresignalExit(tile)) {
  1646 			} else {
  1648 			} else {
  1647 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
  1649 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
  1648 			}
  1650 			}
  1649 		}
  1651 		}
  1650 
  1652 
  1651 		// it changed, so toggle it
  1653 		/* it changed, so toggle it */
  1652 		_m[tile].m2 = m2 ^ bit;
  1654 		_m[tile].m2 = m2 ^ bit;
  1653 		MarkTileDirtyByTile(tile);
  1655 		MarkTileDirtyByTile(tile);
  1654 	}
  1656 	}
  1655 }
  1657 }
  1656 
  1658 
  1661 	int result = -1;
  1663 	int result = -1;
  1662 
  1664 
  1663 	ssd.cur_stack = 0;
  1665 	ssd.cur_stack = 0;
  1664 
  1666 
  1665 	for (;;) {
  1667 	for (;;) {
  1666 		// go through one segment and update all signals pointing into that segment.
  1668 		/* go through one segment and update all signals pointing into that segment. */
  1667 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
  1669 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
  1668 		ssd.has_presignal = false;
  1670 		ssd.has_presignal = false;
  1669 
  1671 
  1670 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
  1672 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
  1671 		ChangeSignalStates(&ssd);
  1673 		ChangeSignalStates(&ssd);
  1672 
  1674 
  1673 		// remember the result only for the first iteration.
  1675 		/* remember the result only for the first iteration. */
  1674 		if (result < 0) {
  1676 		if (result < 0) {
  1675 			// stay in depot while segment is occupied or while all presignal exits are blocked
  1677 			/* stay in depot while segment is occupied or while all presignal exits are blocked */
  1676 			result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0);
  1678 			result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0);
  1677 		}
  1679 		}
  1678 
  1680 
  1679 		// if any exit signals were changed, we need to keep going to modify the stuff behind those.
  1681 		/* if any exit signals were changed, we need to keep going to modify the stuff behind those. */
  1680 		if (ssd.cur_stack == 0) break;
  1682 		if (ssd.cur_stack == 0) break;
  1681 
  1683 
  1682 		// one or more exit signals were changed, so we need to update another segment too.
  1684 		/* one or more exit signals were changed, so we need to update another segment too. */
  1683 		tile = ssd.next_tile[--ssd.cur_stack];
  1685 		tile = ssd.next_tile[--ssd.cur_stack];
  1684 		direction = ssd.next_dir[ssd.cur_stack];
  1686 		direction = ssd.next_dir[ssd.cur_stack];
  1685 	}
  1687 	}
  1686 
  1688 
  1687 	return result != 0;
  1689 	return result != 0;
  1770 
  1772 
  1771 	if (!IsPlainRailTile(tile)) return;
  1773 	if (!IsPlainRailTile(tile)) return;
  1772 
  1774 
  1773 	new_ground = RAIL_GROUND_GRASS;
  1775 	new_ground = RAIL_GROUND_GRASS;
  1774 
  1776 
  1775 	if (old_ground != RAIL_GROUND_BARREN) { /* wait until bottom is green */
  1777 	if (old_ground != RAIL_GROUND_BARREN) { // wait until bottom is green
  1776 		/* determine direction of fence */
  1778 		/* determine direction of fence */
  1777 		TrackBits rail = GetTrackBits(tile);
  1779 		TrackBits rail = GetTrackBits(tile);
  1778 
  1780 
  1779 		switch (rail) {
  1781 		switch (rail) {
  1780 			case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
  1782 			case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
  1964 	byte fract_coord;
  1966 	byte fract_coord;
  1965 	byte fract_coord_leave;
  1967 	byte fract_coord_leave;
  1966 	DiagDirection dir;
  1968 	DiagDirection dir;
  1967 	int length;
  1969 	int length;
  1968 
  1970 
  1969 	// this routine applies only to trains in depot tiles
  1971 	/* this routine applies only to trains in depot tiles */
  1970 	if (v->type != VEH_TRAIN || !IsTileDepotType(tile, TRANSPORT_RAIL)) return VETSB_CONTINUE;
  1972 	if (v->type != VEH_TRAIN || !IsTileDepotType(tile, TRANSPORT_RAIL)) return VETSB_CONTINUE;
  1971 
  1973 
  1972 	/* depot direction */
  1974 	/* depot direction */
  1973 	dir = GetRailDepotDirection(tile);
  1975 	dir = GetRailDepotDirection(tile);
  1974 
  1976