src/rail_cmd.cpp
changeset 7266 4b75e7b9fa91
parent 7249 3e6c9df9794d
child 7287 47f9d7abddc6
equal deleted inserted replaced
7265:74148c363f9d 7266:4b75e7b9fa91
   690 
   690 
   691 	if (!HasSignalOnTrack(tile, track)) {
   691 	if (!HasSignalOnTrack(tile, track)) {
   692 		/* build new signals */
   692 		/* build new signals */
   693 		cost = _price.build_signals;
   693 		cost = _price.build_signals;
   694 	} else {
   694 	} else {
   695 		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
   695 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
   696 			/* convert signals <-> semaphores */
   696 			/* convert signals <-> semaphores */
   697 			cost = _price.build_signals + _price.remove_signals;
   697 			cost = _price.build_signals + _price.remove_signals;
   698 		} else {
   698 		} else {
   699 			/* it is free to change orientation/pre-exit-combo signals */
   699 			/* it is free to change orientation/pre-exit-combo signals */
   700 			cost = 0;
   700 			cost = 0;
   705 		if (!HasSignals(tile)) {
   705 		if (!HasSignals(tile)) {
   706 			/* there are no signals at all on this tile yet */
   706 			/* there are no signals at all on this tile yet */
   707 			SetHasSignals(tile, true);
   707 			SetHasSignals(tile, true);
   708 			SetSignalStates(tile, 0xF); // all signals are on
   708 			SetSignalStates(tile, 0xF); // all signals are on
   709 			SetPresentSignals(tile, 0); // no signals built by default
   709 			SetPresentSignals(tile, 0); // no signals built by default
   710 			SetSignalType(tile, SIGTYPE_NORMAL);
   710 			SetSignalType(tile, track, SIGTYPE_NORMAL);
   711 			SetSignalVariant(tile, sigvar);
   711 			SetSignalVariant(tile, track, sigvar);
   712 		}
   712 		}
   713 
   713 
   714 		if (p2 == 0) {
   714 		if (p2 == 0) {
   715 			if (!HasSignalOnTrack(tile, track)) {
   715 			if (!HasSignalOnTrack(tile, track)) {
   716 				/* build new signals */
   716 				/* build new signals */
   717 				SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track));
   717 				SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track));
       
   718 				SetSignalType(tile, track, SIGTYPE_NORMAL);
       
   719 				SetSignalVariant(tile, track, sigvar);
   718 			} else {
   720 			} else {
   719 				if (pre_signal) {
   721 				if (pre_signal) {
   720 					/* cycle between normal -> pre -> exit -> combo -> ... */
   722 					/* cycle between normal -> pre -> exit -> combo -> ... */
   721 					SignalType type = GetSignalType(tile);
   723 					SignalType type = GetSignalType(tile, track);
   722 
   724 
   723 					SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   725 					SetSignalType(tile, track, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   724 				} else {
   726 				} else {
   725 					CycleSignalSide(tile, track);
   727 					CycleSignalSide(tile, track);
   726 				}
   728 				}
   727 			}
   729 			}
   728 		} else {
   730 		} else {
   729 			/* If CmdBuildManySignals is called with copying signals, just copy the
   731 			/* If CmdBuildManySignals is called with copying signals, just copy the
   730 			 * direction of the first signal given as parameter by CmdBuildManySignals */
   732 			 * direction of the first signal given as parameter by CmdBuildManySignals */
   731 			SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
   733 			SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
   732 			SetSignalVariant(tile, sigvar);
   734 			SetSignalVariant(tile, track, sigvar);
   733 		}
   735 		}
   734 
   736 
   735 		MarkTileDirtyByTile(tile);
   737 		MarkTileDirtyByTile(tile);
   736 		SetSignalsOnBothDir(tile, track);
   738 		SetSignalsOnBothDir(tile, track);
   737 		YapfNotifyTrackLayoutChange(tile, track);
   739 		YapfNotifyTrackLayoutChange(tile, track);
   785 	if (HasSignals(tile)) {
   787 	if (HasSignals(tile)) {
   786 		signals = GetPresentSignals(tile) & SignalOnTrack(track);
   788 		signals = GetPresentSignals(tile) & SignalOnTrack(track);
   787 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   789 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   788 
   790 
   789 		/* copy signal/semaphores style (independent of CTRL) */
   791 		/* copy signal/semaphores style (independent of CTRL) */
   790 		semaphores = GetSignalVariant(tile) != SIG_ELECTRIC;
   792 		semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC;
   791 	} else { // no signals exist, drag a two-way signal stretch
   793 	} else { // no signals exist, drag a two-way signal stretch
   792 		signals = SignalOnTrack(track);
   794 		signals = SignalOnTrack(track);
   793 	}
   795 	}
   794 
   796 
   795 	/* signal_ctr         - amount of tiles already processed
   797 	/* signal_ctr         - amount of tiles already processed
   877 
   879 
   878 		/* removed last signal from tile? */
   880 		/* removed last signal from tile? */
   879 		if (GetPresentSignals(tile) == 0) {
   881 		if (GetPresentSignals(tile) == 0) {
   880 			SetSignalStates(tile, 0);
   882 			SetSignalStates(tile, 0);
   881 			SetHasSignals(tile, false);
   883 			SetHasSignals(tile, false);
   882 			SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores
   884 			SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
   883 		}
   885 		}
   884 
   886 
   885 		SetSignalsOnBothDir(tile, track);
   887 		SetSignalsOnBothDir(tile, track);
   886 		YapfNotifyTrackLayoutChange(tile, track);
   888 		YapfNotifyTrackLayoutChange(tile, track);
   887 
   889 
  1088 	}
  1090 	}
  1089 }
  1091 }
  1090 
  1092 
  1091 #include "table/track_land.h"
  1093 #include "table/track_land.h"
  1092 
  1094 
  1093 static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos)
  1095 static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos)
  1094 {
  1096 {
  1095 	bool side = (_opt.road_side != 0) && _patches.signal_side;
  1097 	bool side = (_opt.road_side != 0) && _patches.signal_side;
  1096 	static const Point SignalPositions[2][12] = {
  1098 	static const Point SignalPositions[2][12] = {
  1097 		{      /* Signals on the left side */
  1099 		{      /* Signals on the left side */
  1098 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
  1100 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
  1125 	SpriteID sprite;
  1127 	SpriteID sprite;
  1126 
  1128 
  1127 	/* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
  1129 	/* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
  1128 	 * just draw the standard signals, else we get the offset from _signal_base
  1130 	 * just draw the standard signals, else we get the offset from _signal_base
  1129 	 * and draw that sprite. All the signal sprites are loaded sequentially. */
  1131 	 * and draw that sprite. All the signal sprites are loaded sequentially. */
  1130 	if (_signal_base == 0 || (GetSignalType(tile) == 0 && GetSignalVariant(tile) == SIG_ELECTRIC)) {
  1132 	if (_signal_base == 0 || (GetSignalType(tile, track) == SIGTYPE_NORMAL && GetSignalVariant(tile, track) == SIG_ELECTRIC)) {
  1131 		sprite = SignalBase[side][GetSignalVariant(tile)][GetSignalType(tile)] + image + condition;
  1133 		sprite = SignalBase[side][GetSignalVariant(tile, track)][GetSignalType(tile, track)] + image + condition;
  1132 	} else {
  1134 	} else {
  1133 		sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition;
  1135 		sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition;
  1134 	}
  1136 	}
  1135 
  1137 
  1136 	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
  1138 	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
  1137 }
  1139 }
  1138 
  1140 
  1298 
  1300 
  1299 }
  1301 }
  1300 
  1302 
  1301 static void DrawSignals(TileIndex tile, TrackBits rails)
  1303 static void DrawSignals(TileIndex tile, TrackBits rails)
  1302 {
  1304 {
  1303 #define MAYBE_DRAW_SIGNAL(x,y,z) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, GetSingleSignalState(tile, x), y - 0x4FB, z)
  1305 #define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y - 0x4FB, z)
  1304 
  1306 
  1305 	if (!(rails & TRACK_BIT_Y)) {
  1307 	if (!(rails & TRACK_BIT_Y)) {
  1306 		if (!(rails & TRACK_BIT_X)) {
  1308 		if (!(rails & TRACK_BIT_X)) {
  1307 			if (rails & TRACK_BIT_LEFT) {
  1309 			if (rails & TRACK_BIT_LEFT) {
  1308 				MAYBE_DRAW_SIGNAL(2, 0x509, 0);
  1310 				MAYBE_DRAW_SIGNAL(2, 0x509, 0, TRACK_LEFT);
  1309 				MAYBE_DRAW_SIGNAL(3, 0x507, 1);
  1311 				MAYBE_DRAW_SIGNAL(3, 0x507, 1, TRACK_LEFT);
  1310 			}
  1312 			}
  1311 			if (rails & TRACK_BIT_RIGHT) {
  1313 			if (rails & TRACK_BIT_RIGHT) {
  1312 				MAYBE_DRAW_SIGNAL(0, 0x509, 2);
  1314 				MAYBE_DRAW_SIGNAL(0, 0x509, 2, TRACK_RIGHT);
  1313 				MAYBE_DRAW_SIGNAL(1, 0x507, 3);
  1315 				MAYBE_DRAW_SIGNAL(1, 0x507, 3, TRACK_RIGHT);
  1314 			}
  1316 			}
  1315 			if (rails & TRACK_BIT_UPPER) {
  1317 			if (rails & TRACK_BIT_UPPER) {
  1316 				MAYBE_DRAW_SIGNAL(3, 0x505, 4);
  1318 				MAYBE_DRAW_SIGNAL(3, 0x505, 4, TRACK_UPPER);
  1317 				MAYBE_DRAW_SIGNAL(2, 0x503, 5);
  1319 				MAYBE_DRAW_SIGNAL(2, 0x503, 5, TRACK_UPPER);
  1318 			}
  1320 			}
  1319 			if (rails & TRACK_BIT_LOWER) {
  1321 			if (rails & TRACK_BIT_LOWER) {
  1320 				MAYBE_DRAW_SIGNAL(1, 0x505, 6);
  1322 				MAYBE_DRAW_SIGNAL(1, 0x505, 6, TRACK_LOWER);
  1321 				MAYBE_DRAW_SIGNAL(0, 0x503, 7);
  1323 				MAYBE_DRAW_SIGNAL(0, 0x503, 7, TRACK_LOWER);
  1322 			}
  1324 			}
  1323 		} else {
  1325 		} else {
  1324 			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
  1326 			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8, TRACK_X);
  1325 			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
  1327 			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9, TRACK_X);
  1326 		}
  1328 		}
  1327 	} else {
  1329 	} else {
  1328 		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
  1330 		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10, TRACK_Y);
  1329 		MAYBE_DRAW_SIGNAL(2, 0x501, 11);
  1331 		MAYBE_DRAW_SIGNAL(2, 0x501, 11, TRACK_Y);
  1330 	}
  1332 	}
  1331 }
  1333 }
  1332 
  1334 
  1333 static void DrawTile_Track(TileInfo *ti)
  1335 static void DrawTile_Track(TileInfo *ti)
  1334 {
  1336 {
  1508 };
  1510 };
  1509 
  1511 
  1510 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1512 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1511 {
  1513 {
  1512 	SetSignalsData* ssd = (SetSignalsData*)data;
  1514 	SetSignalsData* ssd = (SetSignalsData*)data;
       
  1515 	Track track = TrackdirToTrack(trackdir);
  1513 
  1516 
  1514 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1517 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1515 
  1518 
  1516 	/* the tile has signals? */
  1519 	/* the tile has signals? */
  1517 	if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) {
  1520 	if (HasSignalOnTrack(tile, track)) {
  1518 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1521 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1519 			/* yes, add the signal to the list of signals */
  1522 			/* yes, add the signal to the list of signals */
  1520 			if (ssd->cur != NUM_SSD_ENTRY) {
  1523 			if (ssd->cur != NUM_SSD_ENTRY) {
  1521 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1524 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1522 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1525 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1523 				ssd->cur++;
  1526 				ssd->cur++;
  1524 			}
  1527 			}
  1525 
  1528 
  1526 			/* remember if this block has a presignal. */
  1529 			/* remember if this block has a presignal. */
  1527 			ssd->has_presignal |= IsPresignalEntry(tile);
  1530 			ssd->has_presignal |= IsPresignalEntry(tile, track);
  1528 		}
  1531 		}
  1529 
  1532 
  1530 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) {
  1533 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile, track)) {
  1531 			/* this is an exit signal that points out from the segment */
  1534 			/* this is an exit signal that points out from the segment */
  1532 			ssd->presignal_exits++;
  1535 			ssd->presignal_exits++;
  1533 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1536 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1534 				ssd->presignal_exits_free++;
  1537 				ssd->presignal_exits_free++;
  1535 		}
  1538 		}
  1664 	/* then mark the signals in the segment accordingly */
  1667 	/* then mark the signals in the segment accordingly */
  1665 	for (i = 0; i != ssd->cur; i++) {
  1668 	for (i = 0; i != ssd->cur; i++) {
  1666 		TileIndex tile = ssd->tile[i];
  1669 		TileIndex tile = ssd->tile[i];
  1667 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1670 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1668 		uint signals = GetSignalStates(tile);
  1671 		uint signals = GetSignalStates(tile);
       
  1672 		Track track = TrackdirToTrack(ssd->bit[i]);
  1669 
  1673 
  1670 		/* presignals don't turn green if there is at least one presignal exit and none are free */
  1674 		/* presignals don't turn green if there is at least one presignal exit and none are free */
  1671 		if (IsPresignalEntry(tile)) {
  1675 		if (IsPresignalEntry(tile, track)) {
  1672 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1676 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1673 
  1677 
  1674 			/* subtract for dual combo signals so they don't count themselves */
  1678 			/* subtract for dual combo signals so they don't count themselves */
  1675 			if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1679 			if (IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1676 				ex--;
  1680 				ex--;
  1677 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1681 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1678 			}
  1682 			}
  1679 
  1683 
  1680 			/* if we have exits and none are free, make red. */
  1684 			/* if we have exits and none are free, make red. */
  1690 			/* turn green */
  1694 			/* turn green */
  1691 			if ((bit & signals) != 0) continue;
  1695 			if ((bit & signals) != 0) continue;
  1692 		}
  1696 		}
  1693 
  1697 
  1694 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1698 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1695 		if (IsPresignalExit(tile)) {
  1699 		if (IsPresignalExit(tile, track)) {
  1696 			if (ssd->cur_stack != NUM_SSD_STACK) {
  1700 			if (ssd->cur_stack != NUM_SSD_STACK) {
  1697 				ssd->next_tile[ssd->cur_stack] = tile;
  1701 				ssd->next_tile[ssd->cur_stack] = tile;
  1698 				ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
  1702 				ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
  1699 				ssd->cur_stack++;
  1703 				ssd->cur_stack++;
  1700 			} else {
  1704 			} else {
  1968 		case RAIL_TILE_NORMAL:
  1972 		case RAIL_TILE_NORMAL:
  1969 			td->str = STR_1021_RAILROAD_TRACK;
  1973 			td->str = STR_1021_RAILROAD_TRACK;
  1970 			break;
  1974 			break;
  1971 
  1975 
  1972 		case RAIL_TILE_SIGNALS: {
  1976 		case RAIL_TILE_SIGNALS: {
  1973 			const StringID signal_type[] = {
  1977 			const StringID signal_type[4][4] = {
  1974 				STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
  1978 				{
  1975 				STR_RAILROAD_TRACK_WITH_PRESIGNALS,
  1979 					STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
  1976 				STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
  1980 					STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS,
  1977 				STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
  1981 					STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS,
       
  1982 					STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS
       
  1983 				},
       
  1984 				{
       
  1985 					STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS,
       
  1986 					STR_RAILROAD_TRACK_WITH_PRESIGNALS,
       
  1987 					STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS,
       
  1988 					STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS
       
  1989 				},
       
  1990 				{
       
  1991 					STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS,
       
  1992 					STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS,
       
  1993 					STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
       
  1994 					STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS
       
  1995 				},
       
  1996 				{
       
  1997 					STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS,
       
  1998 					STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS,
       
  1999 					STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS,
       
  2000 					STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
       
  2001 				}
  1978 			};
  2002 			};
  1979 
  2003 
  1980 			td->str = signal_type[GetSignalType(tile)];
  2004 			td->str = signal_type[GetSignalType(tile, TRACK_UPPER)][GetSignalType(tile, TRACK_LOWER)];
  1981 			break;
  2005 			break;
  1982 		}
  2006 		}
  1983 
  2007 
  1984 		case RAIL_TILE_DEPOT:
  2008 		case RAIL_TILE_DEPOT:
  1985 			td->str = STR_1023_RAILROAD_TRAIN_DEPOT;
  2009 			td->str = STR_1023_RAILROAD_TRAIN_DEPOT;