src/rail_cmd.cpp
branchgamebalance
changeset 9912 1ac8aac92385
parent 9911 0b8b245a2391
child 9913 e79cd19772dd
equal deleted inserted replaced
9911:0b8b245a2391 9912:1ac8aac92385
   204 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   204 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   205 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   205 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   206 		}
   206 		}
   207 
   207 
   208 		/* no special foundation */
   208 		/* no special foundation */
   209 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0)
   209 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) {
   210 			return 0;
   210 			return 0;
       
   211 		} else if (!_patches.build_on_slopes || _is_old_ai_player) {
       
   212 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   213 		}
   211 
   214 
   212 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
   215 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
   213 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
   216 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
   214 					(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
   217 					(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
   215 				)) { // partly up
   218 				)) { // partly up
   216 			if (existing != 0) {
   219 			return (existing != 0) ? 0 : _eco->GetPrice(CEconomy::TERRAFORM);
   217 				return 0;
       
   218 			} else if (!_patches.build_on_slopes || _is_old_ai_player) {
       
   219 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
       
   220 			} else {
       
   221 				return _eco->GetPrice(CEconomy::TERRAFORM);
       
   222 			}
       
   223 		}
   220 		}
   224 	}
   221 	}
   225 	return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   222 	return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   226 }
   223 }
   227 
   224 
   299 				RoadTypes roadtypes = GetRoadTypes(tile);
   296 				RoadTypes roadtypes = GetRoadTypes(tile);
   300 				RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
   297 				RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
   301 				RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
   298 				RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
   302 				switch (roadtypes) {
   299 				switch (roadtypes) {
   303 					default: break;
   300 					default: break;
       
   301 					case ROADTYPES_TRAM:
       
   302 						/* Tram crossings must always have road. */
       
   303 						SetRoadOwner(tile, ROADTYPE_ROAD, _current_player);
       
   304 						roadtypes |= ROADTYPES_ROAD;
       
   305 						break;
       
   306 
   304 					case ROADTYPES_ROADTRAM: if (road == tram) break;
   307 					case ROADTYPES_ROADTRAM: if (road == tram) break;
   305 						/* FALL THROUGH */
   308 						/* FALL THROUGH */
   306 					case ROADTYPES_ROADHWAY: // Road and highway are incompatible in this case
   309 					case ROADTYPES_ROADHWAY: // Road and highway are incompatible in this case
   307 					case ROADTYPES_TRAMHWAY: // Tram and highway are incompatible in this case
   310 					case ROADTYPES_TRAMHWAY: // Tram and highway are incompatible in this case
   308 					case ROADTYPES_ALL:      // Also incompatible
   311 					case ROADTYPES_ALL:      // Also incompatible
   690 
   693 
   691 	if (!HasSignalOnTrack(tile, track)) {
   694 	if (!HasSignalOnTrack(tile, track)) {
   692 		/* build new signals */
   695 		/* build new signals */
   693 		cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS);
   696 		cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS);
   694 	} else {
   697 	} else {
   695 		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
   698 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
   696 			/* convert signals <-> semaphores */
   699 			/* convert signals <-> semaphores */
   697 			cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS) + _eco->GetPrice(CEconomy::REMOVE_SIGNALS);
   700 			cost = _eco->GetPrice(CEconomy::BUILD_SIGNALS) + _eco->GetPrice(CEconomy::REMOVE_SIGNALS);
   698 		} else {
   701 		} else {
   699 			/* it is free to change orientation/pre-exit-combo signals */
   702 			/* it is free to change orientation/pre-exit-combo signals */
   700 			cost = 0;
   703 			cost = 0;
   703 
   706 
   704 	if (flags & DC_EXEC) {
   707 	if (flags & DC_EXEC) {
   705 		if (!HasSignals(tile)) {
   708 		if (!HasSignals(tile)) {
   706 			/* there are no signals at all on this tile yet */
   709 			/* there are no signals at all on this tile yet */
   707 			SetHasSignals(tile, true);
   710 			SetHasSignals(tile, true);
   708 			_m[tile].m2 |= 0xF0;              // all signals are on
   711 			SetSignalStates(tile, 0xF); // all signals are on
   709 			_m[tile].m3 &= ~0xF0;             // no signals built by default
   712 			SetPresentSignals(tile, 0); // no signals built by default
   710 			SetSignalType(tile, SIGTYPE_NORMAL);
   713 			SetSignalType(tile, track, SIGTYPE_NORMAL);
   711 			SetSignalVariant(tile, sigvar);
   714 			SetSignalVariant(tile, track, sigvar);
   712 		}
   715 		}
   713 
   716 
   714 		if (p2 == 0) {
   717 		if (p2 == 0) {
   715 			if (!HasSignalOnTrack(tile, track)) {
   718 			if (!HasSignalOnTrack(tile, track)) {
   716 				/* build new signals */
   719 				/* build new signals */
   717 				_m[tile].m3 |= SignalOnTrack(track);
   720 				SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track));
       
   721 				SetSignalType(tile, track, SIGTYPE_NORMAL);
       
   722 				SetSignalVariant(tile, track, sigvar);
   718 			} else {
   723 			} else {
   719 				if (pre_signal) {
   724 				if (pre_signal) {
   720 					/* cycle between normal -> pre -> exit -> combo -> ... */
   725 					/* cycle between normal -> pre -> exit -> combo -> ... */
   721 					SignalType type = GetSignalType(tile);
   726 					SignalType type = GetSignalType(tile, track);
   722 
   727 
   723 					SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   728 					SetSignalType(tile, track, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   724 				} else {
   729 				} else {
   725 					CycleSignalSide(tile, track);
   730 					CycleSignalSide(tile, track);
   726 				}
   731 				}
   727 			}
   732 			}
   728 		} else {
   733 		} else {
   729 			/* If CmdBuildManySignals is called with copying signals, just copy the
   734 			/* If CmdBuildManySignals is called with copying signals, just copy the
   730 			 * direction of the first signal given as parameter by CmdBuildManySignals */
   735 			 * direction of the first signal given as parameter by CmdBuildManySignals */
   731 			_m[tile].m3 &= ~SignalOnTrack(track);
   736 			SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
   732 			_m[tile].m3 |= p2 & SignalOnTrack(track);
   737 			SetSignalVariant(tile, track, sigvar);
   733 			SetSignalVariant(tile, sigvar);
       
   734 		}
   738 		}
   735 
   739 
   736 		MarkTileDirtyByTile(tile);
   740 		MarkTileDirtyByTile(tile);
   737 		SetSignalsOnBothDir(tile, track);
   741 		SetSignalsOnBothDir(tile, track);
   738 		YapfNotifyTrackLayoutChange(tile, track);
   742 		YapfNotifyTrackLayoutChange(tile, track);
   782 
   786 
   783 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
   787 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
   784 
   788 
   785 	/* copy the signal-style of the first rail-piece if existing */
   789 	/* copy the signal-style of the first rail-piece if existing */
   786 	if (HasSignals(tile)) {
   790 	if (HasSignals(tile)) {
   787 		signals = _m[tile].m3 & SignalOnTrack(track);
   791 		signals = GetPresentSignals(tile) & SignalOnTrack(track);
   788 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   792 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   789 
   793 
   790 		/* copy signal/semaphores style (independent of CTRL) */
   794 		/* copy signal/semaphores style (independent of CTRL) */
   791 		semaphores = GetSignalVariant(tile) != SIG_ELECTRIC;
   795 		semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC;
   792 	} else { // no signals exist, drag a two-way signal stretch
   796 	} else { // no signals exist, drag a two-way signal stretch
   793 		signals = SignalOnTrack(track);
   797 		signals = SignalOnTrack(track);
   794 	}
   798 	}
   795 
   799 
   796 	/* signal_ctr         - amount of tiles already processed
   800 	/* signal_ctr         - amount of tiles already processed
   872 
   876 
   873 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   877 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   874 
   878 
   875 	/* Do it? */
   879 	/* Do it? */
   876 	if (flags & DC_EXEC) {
   880 	if (flags & DC_EXEC) {
   877 		_m[tile].m3 &= ~SignalOnTrack(track);
   881 		SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track));
   878 
   882 
   879 		/* removed last signal from tile? */
   883 		/* removed last signal from tile? */
   880 		if (GB(_m[tile].m3, 4, 4) == 0) {
   884 		if (GetPresentSignals(tile) == 0) {
   881 			SB(_m[tile].m2, 4, 4, 0);
   885 			SetSignalStates(tile, 0);
   882 			SetHasSignals(tile, false);
   886 			SetHasSignals(tile, false);
   883 			SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores
   887 			SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
   884 		}
   888 		}
   885 
   889 
   886 		SetSignalsOnBothDir(tile, track);
   890 		SetSignalsOnBothDir(tile, track);
   887 		YapfNotifyTrackLayoutChange(tile, track);
   891 		YapfNotifyTrackLayoutChange(tile, track);
   888 
   892 
  1089 	}
  1093 	}
  1090 }
  1094 }
  1091 
  1095 
  1092 #include "table/track_land.h"
  1096 #include "table/track_land.h"
  1093 
  1097 
  1094 static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos)
  1098 static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos)
  1095 {
  1099 {
  1096 	bool side = (_opt.road_side != 0) && _patches.signal_side;
  1100 	bool side = (_opt.road_side != 0) && _patches.signal_side;
  1097 	static const Point SignalPositions[2][12] = {
  1101 	static const Point SignalPositions[2][12] = {
  1098 		{      /* Signals on the left side */
  1102 		{      /* Signals on the left side */
  1099 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
  1103 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
  1126 	SpriteID sprite;
  1130 	SpriteID sprite;
  1127 
  1131 
  1128 	/* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
  1132 	/* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
  1129 	 * just draw the standard signals, else we get the offset from _signal_base
  1133 	 * just draw the standard signals, else we get the offset from _signal_base
  1130 	 * and draw that sprite. All the signal sprites are loaded sequentially. */
  1134 	 * and draw that sprite. All the signal sprites are loaded sequentially. */
  1131 	if (_signal_base == 0 || (GetSignalType(tile) == 0 && GetSignalVariant(tile) == SIG_ELECTRIC)) {
  1135 	if (_signal_base == 0 || (GetSignalType(tile, track) == SIGTYPE_NORMAL && GetSignalVariant(tile, track) == SIG_ELECTRIC)) {
  1132 		sprite = SignalBase[side][GetSignalVariant(tile)][GetSignalType(tile)] + image + condition;
  1136 		sprite = SignalBase[side][GetSignalVariant(tile, track)][GetSignalType(tile, track)] + image + condition;
  1133 	} else {
  1137 	} else {
  1134 		sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition;
  1138 		sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition;
  1135 	}
  1139 	}
  1136 
  1140 
  1137 	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
  1141 	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
  1138 }
  1142 }
  1139 
  1143 
  1299 
  1303 
  1300 }
  1304 }
  1301 
  1305 
  1302 static void DrawSignals(TileIndex tile, TrackBits rails)
  1306 static void DrawSignals(TileIndex tile, TrackBits rails)
  1303 {
  1307 {
  1304 #define MAYBE_DRAW_SIGNAL(x,y,z) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, GetSingleSignalState(tile, x), y - 0x4FB, z)
  1308 #define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y - 0x4FB, z)
  1305 
  1309 
  1306 	if (!(rails & TRACK_BIT_Y)) {
  1310 	if (!(rails & TRACK_BIT_Y)) {
  1307 		if (!(rails & TRACK_BIT_X)) {
  1311 		if (!(rails & TRACK_BIT_X)) {
  1308 			if (rails & TRACK_BIT_LEFT) {
  1312 			if (rails & TRACK_BIT_LEFT) {
  1309 				MAYBE_DRAW_SIGNAL(2, 0x509, 0);
  1313 				MAYBE_DRAW_SIGNAL(2, 0x509, 0, TRACK_LEFT);
  1310 				MAYBE_DRAW_SIGNAL(3, 0x507, 1);
  1314 				MAYBE_DRAW_SIGNAL(3, 0x507, 1, TRACK_LEFT);
  1311 			}
  1315 			}
  1312 			if (rails & TRACK_BIT_RIGHT) {
  1316 			if (rails & TRACK_BIT_RIGHT) {
  1313 				MAYBE_DRAW_SIGNAL(0, 0x509, 2);
  1317 				MAYBE_DRAW_SIGNAL(0, 0x509, 2, TRACK_RIGHT);
  1314 				MAYBE_DRAW_SIGNAL(1, 0x507, 3);
  1318 				MAYBE_DRAW_SIGNAL(1, 0x507, 3, TRACK_RIGHT);
  1315 			}
  1319 			}
  1316 			if (rails & TRACK_BIT_UPPER) {
  1320 			if (rails & TRACK_BIT_UPPER) {
  1317 				MAYBE_DRAW_SIGNAL(3, 0x505, 4);
  1321 				MAYBE_DRAW_SIGNAL(3, 0x505, 4, TRACK_UPPER);
  1318 				MAYBE_DRAW_SIGNAL(2, 0x503, 5);
  1322 				MAYBE_DRAW_SIGNAL(2, 0x503, 5, TRACK_UPPER);
  1319 			}
  1323 			}
  1320 			if (rails & TRACK_BIT_LOWER) {
  1324 			if (rails & TRACK_BIT_LOWER) {
  1321 				MAYBE_DRAW_SIGNAL(1, 0x505, 6);
  1325 				MAYBE_DRAW_SIGNAL(1, 0x505, 6, TRACK_LOWER);
  1322 				MAYBE_DRAW_SIGNAL(0, 0x503, 7);
  1326 				MAYBE_DRAW_SIGNAL(0, 0x503, 7, TRACK_LOWER);
  1323 			}
  1327 			}
  1324 		} else {
  1328 		} else {
  1325 			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
  1329 			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8, TRACK_X);
  1326 			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
  1330 			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9, TRACK_X);
  1327 		}
  1331 		}
  1328 	} else {
  1332 	} else {
  1329 		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
  1333 		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10, TRACK_Y);
  1330 		MAYBE_DRAW_SIGNAL(2, 0x501, 11);
  1334 		MAYBE_DRAW_SIGNAL(2, 0x501, 11, TRACK_Y);
  1331 	}
  1335 	}
  1332 }
  1336 }
  1333 
  1337 
  1334 static void DrawTile_Track(TileInfo *ti)
  1338 static void DrawTile_Track(TileInfo *ti)
  1335 {
  1339 {
  1509 };
  1513 };
  1510 
  1514 
  1511 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1515 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1512 {
  1516 {
  1513 	SetSignalsData* ssd = (SetSignalsData*)data;
  1517 	SetSignalsData* ssd = (SetSignalsData*)data;
       
  1518 	Track track = TrackdirToTrack(trackdir);
  1514 
  1519 
  1515 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1520 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1516 
  1521 
  1517 	/* the tile has signals? */
  1522 	/* the tile has signals? */
  1518 	if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) {
  1523 	if (HasSignalOnTrack(tile, track)) {
  1519 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1524 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1520 			/* yes, add the signal to the list of signals */
  1525 			/* yes, add the signal to the list of signals */
  1521 			if (ssd->cur != NUM_SSD_ENTRY) {
  1526 			if (ssd->cur != NUM_SSD_ENTRY) {
  1522 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1527 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1523 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1528 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1524 				ssd->cur++;
  1529 				ssd->cur++;
  1525 			}
  1530 			}
  1526 
  1531 
  1527 			/* remember if this block has a presignal. */
  1532 			/* remember if this block has a presignal. */
  1528 			ssd->has_presignal |= IsPresignalEntry(tile);
  1533 			ssd->has_presignal |= IsPresignalEntry(tile, track);
  1529 		}
  1534 		}
  1530 
  1535 
  1531 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) {
  1536 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile, track)) {
  1532 			/* this is an exit signal that points out from the segment */
  1537 			/* this is an exit signal that points out from the segment */
  1533 			ssd->presignal_exits++;
  1538 			ssd->presignal_exits++;
  1534 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1539 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1535 				ssd->presignal_exits_free++;
  1540 				ssd->presignal_exits_free++;
  1536 		}
  1541 		}
  1664 
  1669 
  1665 	/* then mark the signals in the segment accordingly */
  1670 	/* then mark the signals in the segment accordingly */
  1666 	for (i = 0; i != ssd->cur; i++) {
  1671 	for (i = 0; i != ssd->cur; i++) {
  1667 		TileIndex tile = ssd->tile[i];
  1672 		TileIndex tile = ssd->tile[i];
  1668 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1673 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1669 		uint16 m2 = _m[tile].m2;
  1674 		uint signals = GetSignalStates(tile);
       
  1675 		Track track = TrackdirToTrack(ssd->bit[i]);
  1670 
  1676 
  1671 		/* presignals don't turn green if there is at least one presignal exit and none are free */
  1677 		/* presignals don't turn green if there is at least one presignal exit and none are free */
  1672 		if (IsPresignalEntry(tile)) {
  1678 		if (IsPresignalEntry(tile, track)) {
  1673 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1679 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1674 
  1680 
  1675 			/* subtract for dual combo signals so they don't count themselves */
  1681 			/* subtract for dual combo signals so they don't count themselves */
  1676 			if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1682 			if (IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1677 				ex--;
  1683 				ex--;
  1678 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1684 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1679 			}
  1685 			}
  1680 
  1686 
  1681 			/* if we have exits and none are free, make red. */
  1687 			/* if we have exits and none are free, make red. */
  1684 
  1690 
  1685 		/* check if the signal is unaffected. */
  1691 		/* check if the signal is unaffected. */
  1686 		if (ssd->stop) {
  1692 		if (ssd->stop) {
  1687 make_red:
  1693 make_red:
  1688 			/* turn red */
  1694 			/* turn red */
  1689 			if ((bit & m2) == 0) continue;
  1695 			if ((bit & signals) == 0) continue;
  1690 		} else {
  1696 		} else {
  1691 			/* turn green */
  1697 			/* turn green */
  1692 			if ((bit & m2) != 0) continue;
  1698 			if ((bit & signals) != 0) continue;
  1693 		}
  1699 		}
  1694 
  1700 
  1695 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1701 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1696 		if (IsPresignalExit(tile)) {
  1702 		if (IsPresignalExit(tile, track)) {
  1697 			if (ssd->cur_stack != NUM_SSD_STACK) {
  1703 			if (ssd->cur_stack != NUM_SSD_STACK) {
  1698 				ssd->next_tile[ssd->cur_stack] = tile;
  1704 				ssd->next_tile[ssd->cur_stack] = tile;
  1699 				ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
  1705 				ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
  1700 				ssd->cur_stack++;
  1706 				ssd->cur_stack++;
  1701 			} else {
  1707 			} else {
  1702 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
  1708 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
  1703 			}
  1709 			}
  1704 		}
  1710 		}
  1705 
  1711 
  1706 		/* it changed, so toggle it */
  1712 		/* it changed, so toggle it */
  1707 		_m[tile].m2 = m2 ^ bit;
  1713 		SetSignalStates(tile, signals ^ bit);
  1708 		MarkTileDirtyByTile(tile);
  1714 		MarkTileDirtyByTile(tile);
  1709 	}
  1715 	}
  1710 }
  1716 }
  1711 
  1717 
  1712 
  1718 
  1720 	for (;;) {
  1726 	for (;;) {
  1721 		/* go through one segment and update all signals pointing into that segment. */
  1727 		/* go through one segment and update all signals pointing into that segment. */
  1722 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
  1728 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
  1723 		ssd.has_presignal = false;
  1729 		ssd.has_presignal = false;
  1724 
  1730 
  1725 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
  1731 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, 0, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
  1726 		ChangeSignalStates(&ssd);
  1732 		ChangeSignalStates(&ssd);
  1727 
  1733 
  1728 		/* remember the result only for the first iteration. */
  1734 		/* remember the result only for the first iteration. */
  1729 		if (result < 0) {
  1735 		if (result < 0) {
  1730 			/* stay in depot while segment is occupied or while all presignal exits are blocked */
  1736 			/* stay in depot while segment is occupied or while all presignal exits are blocked */
  1912 		MarkTileDirtyByTile(tile);
  1918 		MarkTileDirtyByTile(tile);
  1913 	}
  1919 	}
  1914 }
  1920 }
  1915 
  1921 
  1916 
  1922 
  1917 static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode)
  1923 static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode)
  1918 {
  1924 {
  1919 	if (mode != TRANSPORT_RAIL) return 0;
  1925 	if (mode != TRANSPORT_RAIL) return 0;
  1920 
  1926 
  1921 	switch (GetRailTileType(tile)) {
  1927 	switch (GetRailTileType(tile)) {
  1922 		default: NOT_REACHED();
  1928 		default: NOT_REACHED();
  1926 			return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret;
  1932 			return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret;
  1927 		}
  1933 		}
  1928 
  1934 
  1929 		case RAIL_TILE_SIGNALS: {
  1935 		case RAIL_TILE_SIGNALS: {
  1930 			uint32 ret = GetTrackBits(tile) * 0x101;
  1936 			uint32 ret = GetTrackBits(tile) * 0x101;
  1931 			byte a;
  1937 			byte a = GetPresentSignals(tile);
  1932 			uint16 b;
  1938 			uint b = GetSignalStates(tile);
  1933 
       
  1934 			a = _m[tile].m3;
       
  1935 			b = _m[tile].m2;
       
  1936 
  1939 
  1937 			b &= a;
  1940 			b &= a;
  1938 
  1941 
  1939 			/* When signals are not present (in neither
  1942 			/* When signals are not present (in neither
  1940 			 * direction), we pretend them to be green. (So if
  1943 			 * direction), we pretend them to be green. (So if
  1941 			 * signals are only one way, the other way will
  1944 			 * signals are only one way, the other way will
  1942 			 * implicitely become `red' */
  1945 			 * implicitely become `red' */
  1943 			if ((a & 0xC0) == 0) b |= 0xC0;
  1946 			if ((a & 0xC) == 0) b |= 0xC;
  1944 			if ((a & 0x30) == 0) b |= 0x30;
  1947 			if ((a & 0x3) == 0) b |= 0x3;
  1945 
  1948 
  1946 			if ((b & 0x80) == 0) ret |= 0x10070000;
  1949 			if ((b & 0x8) == 0) ret |= 0x10070000;
  1947 			if ((b & 0x40) == 0) ret |= 0x07100000;
  1950 			if ((b & 0x4) == 0) ret |= 0x07100000;
  1948 			if ((b & 0x20) == 0) ret |= 0x20080000;
  1951 			if ((b & 0x2) == 0) ret |= 0x20080000;
  1949 			if ((b & 0x10) == 0) ret |= 0x08200000;
  1952 			if ((b & 0x1) == 0) ret |= 0x08200000;
  1950 
  1953 
  1951 			return ret;
  1954 			return ret;
  1952 		}
  1955 		}
  1953 
  1956 
  1954 		case RAIL_TILE_DEPOT:    return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101;
  1957 		case RAIL_TILE_DEPOT:    return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101;
  1972 		case RAIL_TILE_NORMAL:
  1975 		case RAIL_TILE_NORMAL:
  1973 			td->str = STR_1021_RAILROAD_TRACK;
  1976 			td->str = STR_1021_RAILROAD_TRACK;
  1974 			break;
  1977 			break;
  1975 
  1978 
  1976 		case RAIL_TILE_SIGNALS: {
  1979 		case RAIL_TILE_SIGNALS: {
  1977 			const StringID signal_type[] = {
  1980 			const StringID signal_type[4][4] = {
  1978 				STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
  1981 				{
  1979 				STR_RAILROAD_TRACK_WITH_PRESIGNALS,
  1982 					STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
  1980 				STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
  1983 					STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS,
  1981 				STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
  1984 					STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS,
       
  1985 					STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS
       
  1986 				},
       
  1987 				{
       
  1988 					STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS,
       
  1989 					STR_RAILROAD_TRACK_WITH_PRESIGNALS,
       
  1990 					STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS,
       
  1991 					STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS
       
  1992 				},
       
  1993 				{
       
  1994 					STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS,
       
  1995 					STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS,
       
  1996 					STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
       
  1997 					STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS
       
  1998 				},
       
  1999 				{
       
  2000 					STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS,
       
  2001 					STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS,
       
  2002 					STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS,
       
  2003 					STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
       
  2004 				}
  1982 			};
  2005 			};
  1983 
  2006 
  1984 			td->str = signal_type[GetSignalType(tile)];
  2007 			td->str = signal_type[GetSignalType(tile, TRACK_UPPER)][GetSignalType(tile, TRACK_LOWER)];
  1985 			break;
  2008 			break;
  1986 		}
  2009 		}
  1987 
  2010 
  1988 		case RAIL_TILE_DEPOT:
  2011 		case RAIL_TILE_DEPOT:
  1989 			td->str = STR_1023_RAILROAD_TRAIN_DEPOT;
  2012 			td->str = STR_1023_RAILROAD_TRAIN_DEPOT;