src/rail_cmd.cpp
changeset 7944 65c7c2e1bcb9
parent 7885 4eb9b01e37ff
child 7988 6075538f6111
equal deleted inserted replaced
7943:5bd1fbc094c6 7944:65c7c2e1bcb9
    76  *               01abcdef => rail w/ signals
    76  *               01abcdef => rail w/ signals
    77  *               10uuuuuu => unused
    77  *               10uuuuuu => unused
    78  *               11uuuudd => rail depot
    78  *               11uuuudd => rail depot
    79  */
    79  */
    80 
    80 
       
    81 /** Struct used in EnsureNoTrainOnTrack() */
       
    82 struct TrainOnTrackData {
       
    83 	TileIndex tile;       ///< tile to check
       
    84 	uint z;               ///< tile max Z
       
    85 	TrackBits rail_bits;  ///< trackbits of interest
       
    86 };
       
    87 
       
    88 static void *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
       
    89 {
       
    90 	const TrainOnTrackData *info = (const TrainOnTrackData *)data;
       
    91 
       
    92 	if (v->tile != info->tile || v->type != VEH_TRAIN) return NULL;
       
    93 	if (v->z_pos > info->z) return NULL;
       
    94 
       
    95 	if ((v->u.rail.track != info->rail_bits) && !TracksOverlap(v->u.rail.track | info->rail_bits)) return NULL;
       
    96 
       
    97 	_error_message = VehicleInTheWayErrMsg(v);
       
    98 	return v;
       
    99 }
       
   100 
       
   101 /**
       
   102  * Tests if a vehicle interacts with the specified track.
       
   103  * All track bits interact except parallel TRACK_BIT_HORZ or TRACK_BIT_VERT.
       
   104  *
       
   105  * @param tile The tile.
       
   106  * @param track The track.
       
   107  */
       
   108 static bool EnsureNoTrainOnTrack(TileIndex tile, Track track)
       
   109 {
       
   110 	TrainOnTrackData info;
       
   111 
       
   112 	info.tile = tile;
       
   113 	info.z = GetTileMaxZ(tile);
       
   114 	info.rail_bits = TrackToTrackBits(track);
       
   115 
       
   116 	return VehicleFromPos(tile, &info, EnsureNoTrainOnTrackProc) == NULL;
       
   117 }
       
   118 
    81 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
   119 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
    82 {
   120 {
    83 	TrackBits current; // The current track layout
   121 	TrackBits current; // The current track layout
    84 	TrackBits future;  // The track layout we want to build
   122 	TrackBits future;  // The track layout we want to build
    85 	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
   123 	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
   237 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   275 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   238 
   276 
   239 	switch (GetTileType(tile)) {
   277 	switch (GetTileType(tile)) {
   240 		case MP_RAILWAY:
   278 		case MP_RAILWAY:
   241 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   279 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   242 					!EnsureNoVehicleOnGround(tile)) {
   280 					!EnsureNoTrainOnTrack(tile, track)) {
   243 				return CMD_ERROR;
   281 				return CMD_ERROR;
   244 			}
   282 			}
   245 			if (!IsTileOwner(tile, _current_player) ||
   283 			if (!IsTileOwner(tile, _current_player) ||
   246 					!IsCompatibleRail(GetRailType(tile), railtype)) {
   284 					!IsCompatibleRail(GetRailType(tile), railtype)) {
   247 				/* Get detailed error message */
   285 				/* Get detailed error message */
   372 		case MP_RAILWAY: {
   410 		case MP_RAILWAY: {
   373 			TrackBits present;
   411 			TrackBits present;
   374 
   412 
   375 			if (!IsPlainRailTile(tile) ||
   413 			if (!IsPlainRailTile(tile) ||
   376 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   414 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   377 					!EnsureNoVehicleOnGround(tile)) {
   415 					!EnsureNoTrainOnTrack(tile, track)) {
   378 				return CMD_ERROR;
   416 				return CMD_ERROR;
   379 			}
   417 			}
   380 
   418 
   381 			present = GetTrackBits(tile);
   419 			present = GetTrackBits(tile);
   382 			if ((present & trackbit) == 0) return CMD_ERROR;
   420 			if ((present & trackbit) == 0) return CMD_ERROR;
   645 	Track track = (Track)GB(p1, 0, 3);
   683 	Track track = (Track)GB(p1, 0, 3);
   646 	bool pre_signal = HASBIT(p1, 3);
   684 	bool pre_signal = HASBIT(p1, 3);
   647 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   685 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   648 	CommandCost cost;
   686 	CommandCost cost;
   649 
   687 
   650 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
   688 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoTrainOnTrack(tile, track))
   651 		return CMD_ERROR;
   689 		return CMD_ERROR;
   652 
   690 
   653 	/* Protect against invalid signal copying */
   691 	/* Protect against invalid signal copying */
   654 	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
   692 	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
   655 
   693 
   933 {
   971 {
   934 	Track track = (Track)GB(p1, 0, 3);
   972 	Track track = (Track)GB(p1, 0, 3);
   935 
   973 
   936 	if (!ValParamTrackOrientation(track) ||
   974 	if (!ValParamTrackOrientation(track) ||
   937 			!IsTileType(tile, MP_RAILWAY) ||
   975 			!IsTileType(tile, MP_RAILWAY) ||
   938 			!EnsureNoVehicleOnGround(tile) ||
   976 			!EnsureNoTrainOnTrack(tile, track) ||
   939 			!HasSignalOnTrack(tile, track)) {
   977 			!HasSignalOnTrack(tile, track)) {
   940 		return CMD_ERROR;
   978 		return CMD_ERROR;
   941 	}
   979 	}
   942 
   980 
   943 	/* Only water can remove signals from anyone */
   981 	/* Only water can remove signals from anyone */