train_cmd.c
changeset 2049 538e73c53f54
parent 2044 df63b9a7dec3
child 2115 99198b563a9c
equal deleted inserted replaced
2048:54fd558314dc 2049:538e73c53f54
   167 	assert(v->type == VEH_Train);
   167 	assert(v->type == VEH_Train);
   168 	assert(IsTileType(v->tile, MP_STATION));
   168 	assert(IsTileType(v->tile, MP_STATION));
   169 	//When does a train drive through a station
   169 	//When does a train drive through a station
   170 	//first we deal with the "new nonstop handling"
   170 	//first we deal with the "new nonstop handling"
   171 	if (_patches.new_nonstop && o->flags & OF_NON_STOP &&
   171 	if (_patches.new_nonstop && o->flags & OF_NON_STOP &&
   172 			_map2[tile] == o->station )
   172 			_m[tile].m2 == o->station )
   173 		return false;
   173 		return false;
   174 
   174 
   175 	if (v->last_station_visited == _map2[tile])
   175 	if (v->last_station_visited == _m[tile].m2)
   176 		return false;
   176 		return false;
   177 
   177 
   178 	if (_map2[tile] != o->station &&
   178 	if (_m[tile].m2 != o->station &&
   179 			(o->flags & OF_NON_STOP || _patches.new_nonstop))
   179 			(o->flags & OF_NON_STOP || _patches.new_nonstop))
   180 		return false;
   180 		return false;
   181 
   181 
   182 	return true;
   182 	return true;
   183 }
   183 }
   430 				}
   430 				}
   431 			}
   431 			}
   432 
   432 
   433 			v->engine_type = engine;
   433 			v->engine_type = engine;
   434 
   434 
   435 			dir = _map5[tile] & 3;
   435 			dir = _m[tile].m5 & 3;
   436 
   436 
   437 			v->direction = (byte)(dir*2+1);
   437 			v->direction = (byte)(dir*2+1);
   438 			v->tile = tile;
   438 			v->tile = tile;
   439 
   439 
   440 			x = TileX(tile) * TILE_SIZE | _vehicle_initial_x_fract[dir];
   440 			x = TileX(tile) * TILE_SIZE | _vehicle_initial_x_fract[dir];
   606 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   606 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   607 
   607 
   608 		if (flags & DC_EXEC) {
   608 		if (flags & DC_EXEC) {
   609 			v->unitnumber = unit_num;
   609 			v->unitnumber = unit_num;
   610 
   610 
   611 			dir = _map5[tile] & 3;
   611 			dir = _m[tile].m5 & 3;
   612 
   612 
   613 			v->direction = (byte)(dir*2+1);
   613 			v->direction = (byte)(dir*2+1);
   614 			v->tile = tile;
   614 			v->tile = tile;
   615 			v->owner = _current_player;
   615 			v->owner = _current_player;
   616 			v->x_pos = (x |= _vehicle_initial_x_fract[dir]);
   616 			v->x_pos = (x |= _vehicle_initial_x_fract[dir]);
   666 	return value;
   666 	return value;
   667 }
   667 }
   668 
   668 
   669 static bool IsTunnelTile(TileIndex tile)
   669 static bool IsTunnelTile(TileIndex tile)
   670 {
   670 {
   671 	return IsTileType(tile, MP_TUNNELBRIDGE) && (_map5[tile] & 0x80) == 0;
   671 	return IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0x80) == 0;
   672 }
   672 }
   673 
   673 
   674 
   674 
   675 /* Check if all the wagons of the given train are in a depot, returns the
   675 /* Check if all the wagons of the given train are in a depot, returns the
   676  * number of cars (including loco) then. If not, sets the error message to
   676  * number of cars (including loco) then. If not, sets the error message to
  1241 	/* Test if we have a rail/road-crossing */
  1241 	/* Test if we have a rail/road-crossing */
  1242 	if (IsTileType(tile, MP_STREET) && IsLevelCrossing(tile)) {
  1242 	if (IsTileType(tile, MP_STREET) && IsLevelCrossing(tile)) {
  1243 		/* Check if there is a train on the tile itself */
  1243 		/* Check if there is a train on the tile itself */
  1244 		if (VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL) {
  1244 		if (VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL) {
  1245 			/* If light is on, switch light off */
  1245 			/* If light is on, switch light off */
  1246 			if (_map5[tile] & 4) {
  1246 			if (_m[tile].m5 & 4) {
  1247 				_map5[tile] &= ~4;
  1247 				_m[tile].m5 &= ~4;
  1248 				MarkTileDirtyByTile(tile);
  1248 				MarkTileDirtyByTile(tile);
  1249 			}
  1249 			}
  1250 		}
  1250 		}
  1251 	}
  1251 	}
  1252 }
  1252 }
  1306 	if (v->u.rail.track != 0x40)
  1306 	if (v->u.rail.track != 0x40)
  1307 		return v->tile;
  1307 		return v->tile;
  1308 
  1308 
  1309 	for (tile = v->tile;; tile += delta) {
  1309 	for (tile = v->tile;; tile += delta) {
  1310 		if (IsTileType(tile, MP_TUNNELBRIDGE) &&
  1310 		if (IsTileType(tile, MP_TUNNELBRIDGE) &&
  1311 				(_map5[tile] & 0xF3) != (direction) &&
  1311 				(_m[tile].m5 & 0xF3) != (direction) &&
  1312 				GetTileZ(tile) == v->z_pos)
  1312 				GetTileZ(tile) == v->z_pos)
  1313  			break;
  1313  			break;
  1314  	}
  1314  	}
  1315  	return tile;
  1315  	return tile;
  1316 
  1316 
  1566 } TrainFindDepotData;
  1566 } TrainFindDepotData;
  1567 
  1567 
  1568 static bool TrainFindDepotEnumProc(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length, byte *state)
  1568 static bool TrainFindDepotEnumProc(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length, byte *state)
  1569 {
  1569 {
  1570 	if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, tfdd->owner)) {
  1570 	if (IsTileType(tile, MP_RAILWAY) && IsTileOwner(tile, tfdd->owner)) {
  1571 		if ((_map5[tile] & ~0x3) == 0xC0) {
  1571 		if ((_m[tile].m5 & ~0x3) == 0xC0) {
  1572 			if (length < tfdd->best_length) {
  1572 			if (length < tfdd->best_length) {
  1573 				tfdd->best_length = length;
  1573 				tfdd->best_length = length;
  1574 				tfdd->tile = tile;
  1574 				tfdd->tile = tile;
  1575 			}
  1575 			}
  1576 			return true;
  1576 			return true;
  1577 		}
  1577 		}
  1578 
  1578 
  1579 		// make sure the train doesn't run against a oneway signal
  1579 		// make sure the train doesn't run against a oneway signal
  1580 		if ((_map5[tile] & 0xC0) == 0x40) {
  1580 		if ((_m[tile].m5 & 0xC0) == 0x40) {
  1581 			if (!(_map3_lo[tile] & SignalAlongTrackdir(track)) && _map3_lo[tile] & SignalAgainstTrackdir(track))
  1581 			if (!(_m[tile].m3 & SignalAlongTrackdir(track)) && _m[tile].m3 & SignalAgainstTrackdir(track))
  1582 				return true;
  1582 				return true;
  1583 		}
  1583 		}
  1584 	}
  1584 	}
  1585 
  1585 
  1586 	// stop  searching if we've found a destination that is closer already.
  1586 	// stop  searching if we've found a destination that is closer already.
  1886 	if (ttfd->dest_coords == 0)
  1886 	if (ttfd->dest_coords == 0)
  1887 		return false;
  1887 		return false;
  1888 
  1888 
  1889 	// did we reach the final station?
  1889 	// did we reach the final station?
  1890 	if ((ttfd->station_index == INVALID_STATION && tile == ttfd->dest_coords) ||
  1890 	if ((ttfd->station_index == INVALID_STATION && tile == ttfd->dest_coords) ||
  1891 		(IsTileType(tile, MP_STATION) && IS_BYTE_INSIDE(_map5[tile], 0, 8) && _map2[tile] == ttfd->station_index)) {
  1891 		(IsTileType(tile, MP_STATION) && IS_BYTE_INSIDE(_m[tile].m5, 0, 8) && _m[tile].m2 == ttfd->station_index)) {
  1892 		/* We do not check for dest_coords if we have a station_index,
  1892 		/* We do not check for dest_coords if we have a station_index,
  1893 		 * because in that case the dest_coords are just an
  1893 		 * because in that case the dest_coords are just an
  1894 		 * approximation of where the station is */
  1894 		 * approximation of where the station is */
  1895 		// found station
  1895 		// found station
  1896 		ttfd->best_bird_dist = 0;
  1896 		ttfd->best_bird_dist = 0;
  2178 		v->cur_order_index++;
  2178 		v->cur_order_index++;
  2179 	}
  2179 	}
  2180 
  2180 
  2181 	// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
  2181 	// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
  2182 	if (_patches.new_nonstop && v->current_order.flags & OF_NON_STOP &&
  2182 	if (_patches.new_nonstop && v->current_order.flags & OF_NON_STOP &&
  2183 		v->current_order.station == _map2[v->tile] && IsTileType(v->tile, MP_STATION) ) {
  2183 		v->current_order.station == _m[v->tile].m2 && IsTileType(v->tile, MP_STATION) ) {
  2184 		v->cur_order_index++;
  2184 		v->cur_order_index++;
  2185 	}
  2185 	}
  2186 
  2186 
  2187 	// Get the current order
  2187 	// Get the current order
  2188 	if (v->cur_order_index >= v->num_orders)
  2188 	if (v->cur_order_index >= v->num_orders)
  2389 
  2389 
  2390 		if (new_z != old_z) {
  2390 		if (new_z != old_z) {
  2391 			TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
  2391 			TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
  2392 
  2392 
  2393 			// XXX workaround, whole UP/DOWN detection needs overhaul
  2393 			// XXX workaround, whole UP/DOWN detection needs overhaul
  2394 			if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_map5[tile] & 0x80) != 0)
  2394 			if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_m[tile].m5 & 0x80) != 0)
  2395 				SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
  2395 				SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
  2396 		}
  2396 		}
  2397 	}
  2397 	}
  2398 
  2398 
  2399 	VehiclePositionChanged(v);
  2399 	VehiclePositionChanged(v);
  2452 		case MP_STATION:
  2452 		case MP_STATION:
  2453 			// normal tracks, jump to owner check
  2453 			// normal tracks, jump to owner check
  2454 			break;
  2454 			break;
  2455 
  2455 
  2456 		case MP_TUNNELBRIDGE:
  2456 		case MP_TUNNELBRIDGE:
  2457 			if ((_map5[tile] & 0xC0) == 0xC0) { // is bridge middle part?
  2457 			if ((_m[tile].m5 & 0xC0) == 0xC0) { // is bridge middle part?
  2458 				uint height;
  2458 				uint height;
  2459 				uint tileh = GetTileSlope(tile, &height);
  2459 				uint tileh = GetTileSlope(tile, &height);
  2460 
  2460 
  2461 				// correct Z position of a train going under a bridge on slopes
  2461 				// correct Z position of a train going under a bridge on slopes
  2462 				if (CorrectZ(tileh)) height += 8;
  2462 				if (CorrectZ(tileh)) height += 8;
  2464 				if (v->z_pos != height) return true; // train is going over bridge
  2464 				if (v->z_pos != height) return true; // train is going over bridge
  2465 			}
  2465 			}
  2466 			break;
  2466 			break;
  2467 
  2467 
  2468 		case MP_STREET:
  2468 		case MP_STREET:
  2469 			// tracks over roads, do owner check of tracks (_map_owner[tile])
  2469 			// tracks over roads, do owner check of tracks (_m[tile].owner)
  2470 			return
  2470 			return
  2471 				IsTileOwner(tile, v->owner) &&
  2471 				IsTileOwner(tile, v->owner) &&
  2472 				(v->subtype != TS_Front_Engine || (_map3_hi[tile] & 0xF) == v->u.rail.railtype);
  2472 				(v->subtype != TS_Front_Engine || (_m[tile].m4 & 0xF) == v->u.rail.railtype);
  2473 
  2473 
  2474 		default:
  2474 		default:
  2475 			return true;
  2475 			return true;
  2476 	}
  2476 	}
  2477 
  2477 
  2531 };
  2531 };
  2532 
  2532 
  2533 static void TrainMovedChangeSignals(TileIndex tile, int dir)
  2533 static void TrainMovedChangeSignals(TileIndex tile, int dir)
  2534 {
  2534 {
  2535 	int i;
  2535 	int i;
  2536 	if (IsTileType(tile, MP_RAILWAY) && (_map5[tile] & 0xC0) == 0x40) {
  2536 	if (IsTileType(tile, MP_RAILWAY) && (_m[tile].m5 & 0xC0) == 0x40) {
  2537 		i = FindFirstBit2x64((_map5[tile]+(_map5[tile]<<8)) & _reachable_tracks[dir]);
  2537 		i = FindFirstBit2x64((_m[tile].m5+(_m[tile].m5<<8)) & _reachable_tracks[dir]);
  2538 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
  2538 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
  2539 	}
  2539 	}
  2540 }
  2540 }
  2541 
  2541 
  2542 
  2542 
  2848 		} else {
  2848 		} else {
  2849 			/* in tunnel */
  2849 			/* in tunnel */
  2850 			GetNewVehiclePos(v, &gp);
  2850 			GetNewVehiclePos(v, &gp);
  2851 
  2851 
  2852 			if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) &&
  2852 			if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) &&
  2853 					!(_map5[gp.new_tile] & 0xF0)) {
  2853 					!(_m[gp.new_tile].m5 & 0xF0)) {
  2854 				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2854 				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2855 				if (r & 0x4) goto common;
  2855 				if (r & 0x4) goto common;
  2856 			}
  2856 			}
  2857 
  2857 
  2858 			v->x_pos = gp.x;
  2858 			v->x_pos = gp.x;
  2891 	/* We're in front of a red signal ?? */
  2891 	/* We're in front of a red signal ?? */
  2892 		/* find the first set bit in ts. need to do it in 2 steps, since
  2892 		/* find the first set bit in ts. need to do it in 2 steps, since
  2893 		 * FIND_FIRST_BIT only handles 6 bits at a time. */
  2893 		 * FIND_FIRST_BIT only handles 6 bits at a time. */
  2894 		i = FindFirstBit2x64(ts);
  2894 		i = FindFirstBit2x64(ts);
  2895 
  2895 
  2896 		if (!(_map3_lo[gp.new_tile] & SignalAgainstTrackdir(i))) {
  2896 		if (!(_m[gp.new_tile].m3 & SignalAgainstTrackdir(i))) {
  2897 			v->cur_speed = 0;
  2897 			v->cur_speed = 0;
  2898 			v->subspeed = 0;
  2898 			v->subspeed = 0;
  2899 			v->progress = 255-100;
  2899 			v->progress = 255-100;
  2900 			if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20)
  2900 			if (++v->load_unload_time_rem < _patches.wait_oneway_signal * 20)
  2901 				return;
  2901 				return;
  2902 		} else if (_map3_lo[gp.new_tile] & SignalAlongTrackdir(i)){
  2902 		} else if (_m[gp.new_tile].m3 & SignalAlongTrackdir(i)){
  2903 			v->cur_speed = 0;
  2903 			v->cur_speed = 0;
  2904 			v->subspeed = 0;
  2904 			v->subspeed = 0;
  2905 			v->progress = 255-10;
  2905 			v->progress = 255-10;
  2906 			if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) {
  2906 			if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) {
  2907 				TileIndex o_tile = gp.new_tile + TileOffsByDir(enterdir);
  2907 				TileIndex o_tile = gp.new_tile + TileOffsByDir(enterdir);
  3112 
  3112 
  3113 	tile = v->tile;
  3113 	tile = v->tile;
  3114 
  3114 
  3115 	// tunnel entrance?
  3115 	// tunnel entrance?
  3116 	if (IsTileType(tile, MP_TUNNELBRIDGE) &&
  3116 	if (IsTileType(tile, MP_TUNNELBRIDGE) &&
  3117 			(_map5[tile] & 0xF0) == 0 && (byte)((_map5[tile] & 3)*2+1) == v->direction)
  3117 			(_m[tile].m5 & 0xF0) == 0 && (byte)((_m[tile].m5 & 3)*2+1) == v->direction)
  3118 				return true;
  3118 				return true;
  3119 
  3119 
  3120 	// depot?
  3120 	// depot?
  3121 	/* XXX -- When enabled, this makes it possible to crash trains of others
  3121 	/* XXX -- When enabled, this makes it possible to crash trains of others
  3122 	     (by building a depot right against a station) */
  3122 	     (by building a depot right against a station) */
  3123 /*	if (IsTileType(tile, MP_RAILWAY) && (_map5[tile] & 0xFC) == 0xC0)
  3123 /*	if (IsTileType(tile, MP_RAILWAY) && (_m[tile].m5 & 0xFC) == 0xC0)
  3124 		return true;*/
  3124 		return true;*/
  3125 
  3125 
  3126 	/* Determine the non-diagonal direction in which we will exit this tile */
  3126 	/* Determine the non-diagonal direction in which we will exit this tile */
  3127 	t = v->direction >> 1;
  3127 	t = v->direction >> 1;
  3128 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[t]) {
  3128 	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[t]) {
  3175 			return false;
  3175 			return false;
  3176 		}
  3176 		}
  3177 		if ((ts &= (ts >> 16)) == 0) {
  3177 		if ((ts &= (ts >> 16)) == 0) {
  3178 			// make a rail/road crossing red
  3178 			// make a rail/road crossing red
  3179 			if (IsTileType(tile, MP_STREET) && IsLevelCrossing(tile)) {
  3179 			if (IsTileType(tile, MP_STREET) && IsLevelCrossing(tile)) {
  3180 				if (!(_map5[tile] & 4)) {
  3180 				if (!(_m[tile].m5 & 4)) {
  3181 					_map5[tile] |= 4;
  3181 					_m[tile].m5 |= 4;
  3182 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
  3182 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
  3183 					MarkTileDirtyByTile(tile);
  3183 					MarkTileDirtyByTile(tile);
  3184 				}
  3184 				}
  3185 			}
  3185 			}
  3186 			return true;
  3186 			return true;
  3192 	}
  3192 	}
  3193 
  3193 
  3194 	if  (v->u.rail.pbs_status == PBS_STAT_HAS_PATH)
  3194 	if  (v->u.rail.pbs_status == PBS_STAT_HAS_PATH)
  3195 		return true;
  3195 		return true;
  3196 
  3196 
  3197 	if ((trackdir != INVALID_TRACKDIR) && (PBSIsPbsSignal(tile,trackdir)) && !(IsTileType(v->tile, MP_STATION) && (v->current_order.station == _map2[v->tile]))) {
  3197 	if ((trackdir != INVALID_TRACKDIR) && (PBSIsPbsSignal(tile,trackdir)) && !(IsTileType(v->tile, MP_STATION) && (v->current_order.station == _m[v->tile].m2))) {
  3198 		NPFFindStationOrTileData fstd;
  3198 		NPFFindStationOrTileData fstd;
  3199 		NPFFoundTargetData ftd;
  3199 		NPFFoundTargetData ftd;
  3200 
  3200 
  3201 		NPFFillWithOrderData(&fstd, v);
  3201 		NPFFillWithOrderData(&fstd, v);
  3202 
  3202 
  3320 	return  (v->u.rail.track == 0x80 && (v->vehstatus | VS_STOPPED));
  3320 	return  (v->u.rail.track == 0x80 && (v->vehstatus | VS_STOPPED));
  3321 }
  3321 }
  3322 
  3322 
  3323 void TrainEnterDepot(Vehicle *v, TileIndex tile)
  3323 void TrainEnterDepot(Vehicle *v, TileIndex tile)
  3324 {
  3324 {
  3325 	SetSignalsOnBothDir(tile, _depot_track_ind[_map5[tile]&3]);
  3325 	SetSignalsOnBothDir(tile, _depot_track_ind[_m[tile].m5&3]);
  3326 
  3326 
  3327 	if (v->subtype != TS_Front_Engine)
  3327 	if (v->subtype != TS_Front_Engine)
  3328 		v = GetFirstVehicleInChain(v);
  3328 		v = GetFirstVehicleInChain(v);
  3329 
  3329 
  3330 	VehicleServiceInDepot(v);
  3330 	VehicleServiceInDepot(v);