Changeset - r22906:1b252dc87a48
[Not reviewed]
master
0 3 0
PeterN - 6 years ago 2018-06-14 08:25:39
peter@fuzzle.org
Fix: Prevent ships moving into docks after finishing (un)loading. (#6791)
3 files changed with 31 insertions and 27 deletions:
0 comments (0 inline, 0 general)
src/ship_cmd.cpp
Show inline comments
 
@@ -534,12 +534,16 @@ static void ShipController(Ship *v)
 

	
 
				/* A leave station order only needs one tick to get processed, so we can
 
				 * always skip ahead. */
 
				if (v->current_order.IsType(OT_LEAVESTATION)) {
 
					v->current_order.Free();
 
					SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
 
					/* Test if continuing forward would lead to a dead-end, moving into the dock. */
 
					DiagDirection exitdir = VehicleExitDir(v->direction, v->state);
 
					TileIndex tile = TileAddByDiagDir(v->tile, exitdir);
 
					if (TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, exitdir)) == TRACK_BIT_NONE) goto reverse_direction;
 
				} else if (v->dest_tile != 0) {
 
					/* We have a target, let's see if we reached it... */
 
					if (v->current_order.IsType(OT_GOTO_WAYPOINT) &&
 
							DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
 
						/* We got within 3 tiles of our target buoy, so let's skip to our
 
						 * next order */
src/track_func.h
Show inline comments
 
@@ -689,7 +689,28 @@ static inline bool IsUphillTrackdir(Slop
 
{
 
	assert(IsValidTrackdirForRoadVehicle(dir));
 
	extern const TrackdirBits _uphill_trackdirs[];
 
	return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
 
}
 

	
 
/**
 
 * Determine the side in which the vehicle will leave the tile
 
 *
 
 * @param direction vehicle direction
 
 * @param track vehicle track bits
 
 * @return side of tile the vehicle will leave
 
 */
 
static inline DiagDirection VehicleExitDir(Direction direction, TrackBits track)
 
{
 
	static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
 

	
 
	DiagDirection diagdir = DirToDiagDir(direction);
 

	
 
	/* Determine the diagonal direction in which we will exit this tile */
 
	if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) {
 
		diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT);
 
	}
 

	
 
	return diagdir;
 
}
 

	
 
#endif /* TRACK_FUNC_H */
src/train_cmd.cpp
Show inline comments
 
@@ -54,33 +54,12 @@ static const byte _vehicle_initial_y_fra
 
template <>
 
bool IsValidImageIndex<VEH_TRAIN>(uint8 image_index)
 
{
 
	return image_index < lengthof(_engine_sprite_base);
 
}
 

	
 
/**
 
 * Determine the side in which the train will leave the tile
 
 *
 
 * @param direction vehicle direction
 
 * @param track vehicle track bits
 
 * @return side of tile the train will leave
 
 */
 
static inline DiagDirection TrainExitDir(Direction direction, TrackBits track)
 
{
 
	static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
 

	
 
	DiagDirection diagdir = DirToDiagDir(direction);
 

	
 
	/* Determine the diagonal direction in which we will exit this tile */
 
	if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) {
 
		diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT);
 
	}
 

	
 
	return diagdir;
 
}
 

	
 

	
 
/**
 
 * Return the cargo weight multiplier to use for a rail vehicle
 
 * @param cargo Cargo type to get multiplier for
 
 * @return Cargo weight multiplier
 
 */
 
@@ -1869,15 +1848,15 @@ void ReverseTrainDirection(Train *v)
 
		/* Can't be stuck here as inside a depot is always a safe tile. */
 
		if (HasBit(v->flags, VRF_TRAIN_STUCK)) SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
 
		ClrBit(v->flags, VRF_TRAIN_STUCK);
 
		return;
 
	}
 

	
 
	/* TrainExitDir does not always produce the desired dir for depots and
 
	/* VehicleExitDir does not always produce the desired dir for depots and
 
	 * tunnels/bridges that is needed for UpdateSignalsOnSegment. */
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	DiagDirection dir = VehicleExitDir(v->direction, v->track);
 
	if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;
 

	
 
	if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
 
		/* If we are currently on a tile with conventional signals, we can't treat the
 
		 * current tile as a safe tile or we would enter a PBS block without a reservation. */
 
		bool first_tile_okay = !(IsTileType(v->tile, MP_RAILWAY) &&
 
@@ -3095,13 +3074,13 @@ static Vehicle *CheckTrainAtSignal(Vehic
 
	Train *t = Train::From(v);
 
	DiagDirection exitdir = *(DiagDirection *)data;
 

	
 
	/* not front engine of a train, inside wormhole or depot, crashed */
 
	if (!t->IsFrontEngine() || !(t->track & TRACK_BIT_MASK)) return NULL;
 

	
 
	if (t->cur_speed > 5 || TrainExitDir(t->direction, t->track) != exitdir) return NULL;
 
	if (t->cur_speed > 5 || VehicleExitDir(t->direction, t->track) != exitdir) return NULL;
 

	
 
	return t;
 
}
 

	
 
/**
 
 * Move a vehicle chain one movement stop forwards.
 
@@ -3678,13 +3657,13 @@ static TileIndex TrainApproachingCrossin
 
{
 
	assert(v->IsFrontEngine());
 
	assert(!(v->vehstatus & VS_CRASHED));
 

	
 
	if (!TrainCanLeaveTile(v)) return INVALID_TILE;
 

	
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	DiagDirection dir = VehicleExitDir(v->direction, v->track);
 
	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
 

	
 
	/* not a crossing || wrong axis || unusable rail (wrong type or owner) */
 
	if (!IsLevelCrossingTile(tile) || DiagDirToAxis(dir) == GetCrossingRoadAxis(tile) ||
 
			!CheckCompatibleRail(v, tile)) {
 
		return INVALID_TILE;
 
@@ -3715,13 +3694,13 @@ static bool TrainCheckIfLineEnds(Train *
 
		v->vehstatus &= ~VS_TRAIN_SLOWING;
 
	}
 

	
 
	if (!TrainCanLeaveTile(v)) return true;
 

	
 
	/* Determine the non-diagonal direction in which we will exit this tile */
 
	DiagDirection dir = TrainExitDir(v->direction, v->track);
 
	DiagDirection dir = VehicleExitDir(v->direction, v->track);
 
	/* Calculate next tile */
 
	TileIndex tile = v->tile + TileOffsByDiagDir(dir);
 

	
 
	/* Determine the track status on the next tile */
 
	TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir));
 
	TrackdirBits reachable_trackdirs = DiagdirReachesTrackdirs(dir);
 
@@ -3783,13 +3762,13 @@ static bool TrainLocoHandler(Train *v, b
 
		ReverseTrainDirection(v);
 
		return true;
 
	} else if (HasBit(v->flags, VRF_LEAVING_STATION)) {
 
		/* Try to reserve a path when leaving the station as we
 
		 * might not be marked as wanting a reservation, e.g.
 
		 * when an overlength train gets turned around in a station. */
 
		DiagDirection dir = TrainExitDir(v->direction, v->track);
 
		DiagDirection dir = VehicleExitDir(v->direction, v->track);
 
		if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;
 

	
 
		if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
 
			TryPathReserve(v, true, true);
 
		}
 
		ClrBit(v->flags, VRF_LEAVING_STATION);
0 comments (0 inline, 0 general)