mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-17 21:25:40 +00:00
(svn r2625) - Fix: [pbs] Store the end of a train's reserved path explicitly. Prevents trains from unreserving eachothers paths in some cases.
- CodeChange: Use the TrackdirToTrack function instead of &7, and remove an unneeded variable.
This commit is contained in:
parent
09195e0bda
commit
552aa1b4dc
24
npf.c
24
npf.c
@ -180,27 +180,35 @@ void NPFReservePBSPath(AyStar *as)
|
|||||||
* BUT, you have to have a pretty fucked up junction layout for this to happen,
|
* BUT, you have to have a pretty fucked up junction layout for this to happen,
|
||||||
* so we'll just stop this train, the user will eventually notice, so he can fix it.
|
* so we'll just stop this train, the user will eventually notice, so he can fix it.
|
||||||
*/
|
*/
|
||||||
PBSClearPath(start, trackdir);
|
PBSClearPath(start, trackdir, curr->node.tile, curr->node.direction);
|
||||||
NPFSetFlag(&ftd->node, NPF_FLAG_PBS_BLOCKED, true);
|
NPFSetFlag(&ftd->node, NPF_FLAG_PBS_BLOCKED, true);
|
||||||
DEBUG(pbs, 1) ("PBS: Self-crossing path!!!");
|
DEBUG(pbs, 1) ("PBS: Self-crossing path!!!");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
PBSReserveTrack(curr->node.tile, (curr->node.direction & 7) );
|
PBSReserveTrack(curr->node.tile, TrackdirToTrack(curr->node.direction) );
|
||||||
|
|
||||||
/* we want to reserve the last tile (with the signal) on the path too */
|
/* we want to reserve the last tile (with the signal) on the path too
|
||||||
if (prev != NULL && start == INVALID_TILE) {
|
also remember this tile, cause its the end of the path (where we exit the block) */
|
||||||
PBSReserveTrack(prev->node.tile, (prev->node.direction & 7) );
|
if (start == INVALID_TILE) {
|
||||||
start = prev->node.tile;
|
if (prev != NULL) {
|
||||||
trackdir = ReverseTrackdir(prev->node.direction);
|
PBSReserveTrack(prev->node.tile, TrackdirToTrack(prev->node.direction) );
|
||||||
|
start = prev->node.tile;
|
||||||
|
trackdir = ReverseTrackdir(prev->node.direction);
|
||||||
|
} else {
|
||||||
|
start = curr->node.tile;
|
||||||
|
trackdir = curr->node.direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = curr;
|
prev = curr;
|
||||||
curr = curr->parent;
|
curr = curr->parent;
|
||||||
} while (curr != NULL);
|
} while (curr != NULL);
|
||||||
|
// we remember the tile/track where this path leaves the pbs junction
|
||||||
|
ftd->node.tile = start;
|
||||||
|
ftd->node.direction = trackdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
14
pbs.c
14
pbs.c
@ -189,13 +189,17 @@ void PBSClearTrack(TileIndex tile, Track track) {
|
|||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
};
|
};
|
||||||
|
|
||||||
void PBSClearPath(TileIndex tile, Trackdir trackdir) {
|
void PBSClearPath(TileIndex tile, Trackdir trackdir, TileIndex end_tile, Trackdir end_trackdir) {
|
||||||
uint16 res;
|
uint16 res;
|
||||||
FindLengthOfTunnelResult flotr;
|
FindLengthOfTunnelResult flotr;
|
||||||
assert(IsValidTile(tile));
|
assert(IsValidTile(tile));
|
||||||
assert((trackdir & ~8) <= 5);
|
assert(IsValidTrackdir(trackdir));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
PBSClearTrack(tile, trackdir & 7);
|
PBSClearTrack(tile, TrackdirToTrack(trackdir));
|
||||||
|
|
||||||
|
if (tile == end_tile && TrackdirToTrack(trackdir) == TrackdirToTrack(end_trackdir))
|
||||||
|
return;
|
||||||
|
|
||||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0)==0 && (unsigned)(_m[tile].m5 & 3) == TrackdirToExitdir(trackdir)) {
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0)==0 && (unsigned)(_m[tile].m5 & 3) == TrackdirToExitdir(trackdir)) {
|
||||||
// this is a tunnel
|
// this is a tunnel
|
||||||
@ -204,11 +208,7 @@ void PBSClearPath(TileIndex tile, Trackdir trackdir) {
|
|||||||
tile = flotr.tile;
|
tile = flotr.tile;
|
||||||
} else {
|
} else {
|
||||||
byte exitdir = TrackdirToExitdir(trackdir);
|
byte exitdir = TrackdirToExitdir(trackdir);
|
||||||
if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != GetDepotDirection(tile, TRANSPORT_RAIL)))
|
|
||||||
return;
|
|
||||||
tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(exitdir));
|
tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(exitdir));
|
||||||
if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != ReverseDiagdir(GetDepotDirection(tile, TRANSPORT_RAIL))))
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
res = PBSTileReserved(tile);
|
res = PBSTileReserved(tile);
|
||||||
|
4
pbs.h
4
pbs.h
@ -56,11 +56,13 @@ void PBSClearTrack(TileIndex tile, Track track);
|
|||||||
* @param track The track to unreserve, valid values 0-5.
|
* @param track The track to unreserve, valid values 0-5.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void PBSClearPath(TileIndex tile, Trackdir trackdir);
|
void PBSClearPath(TileIndex tile, Trackdir trackdir, TileIndex end_tile, Trackdir end_trackdir);
|
||||||
/**<
|
/**<
|
||||||
* Follows a planned(reserved) path, and unreserves the tracks.
|
* Follows a planned(reserved) path, and unreserves the tracks.
|
||||||
* @param tile The tile on which the path starts
|
* @param tile The tile on which the path starts
|
||||||
* @param trackdir The trackdirection in which the path starts
|
* @param trackdir The trackdirection in which the path starts
|
||||||
|
* @param end_tile The tile on which the path ends
|
||||||
|
* @param end_trackdir The trackdirection in which the path ends
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool PBSIsPbsSignal(TileIndex tile, Trackdir trackdir);
|
bool PBSIsPbsSignal(TileIndex tile, Trackdir trackdir);
|
||||||
|
34
train_cmd.c
34
train_cmd.c
@ -1321,13 +1321,15 @@ static void ReverseTrainDirection(Vehicle *v)
|
|||||||
int l = 0, r = -1;
|
int l = 0, r = -1;
|
||||||
Vehicle *u;
|
Vehicle *u;
|
||||||
TileIndex tile;
|
TileIndex tile;
|
||||||
byte trackdir;
|
Trackdir trackdir;
|
||||||
|
TileIndex pbs_end_tile = v->u.rail.pbs_end_tile; // these may be changed, and we may need
|
||||||
|
Trackdir pbs_end_trackdir = v->u.rail.pbs_end_trackdir; // the old values, so cache them
|
||||||
|
|
||||||
u = GetLastVehicleInChain(v);
|
u = GetLastVehicleInChain(v);
|
||||||
tile = GetVehicleTileOutOfTunnel(u, false);
|
tile = GetVehicleTileOutOfTunnel(u, false);
|
||||||
trackdir = ReverseTrackdir(GetVehicleTrackdir(u));
|
trackdir = ReverseTrackdir(GetVehicleTrackdir(u));
|
||||||
|
|
||||||
if (PBSTileReserved(tile) & (1 << (trackdir&7))) {
|
if (PBSTileReserved(tile) & (1 << TrackdirToTrack(trackdir))) {
|
||||||
NPFFindStationOrTileData fstd;
|
NPFFindStationOrTileData fstd;
|
||||||
NPFFoundTargetData ftd;
|
NPFFoundTargetData ftd;
|
||||||
|
|
||||||
@ -1351,13 +1353,15 @@ static void ReverseTrainDirection(Vehicle *v)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v->u.rail.pbs_end_tile = ftd.node.tile;
|
||||||
|
v->u.rail.pbs_end_trackdir = ftd.node.direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile = GetVehicleTileOutOfTunnel(v, false);
|
tile = GetVehicleTileOutOfTunnel(v, false);
|
||||||
trackdir = GetVehicleTrackdir(v);
|
trackdir = GetVehicleTrackdir(v);
|
||||||
|
|
||||||
if (v->u.rail.pbs_status == PBS_STAT_HAS_PATH) {
|
if (v->u.rail.pbs_status == PBS_STAT_HAS_PATH) {
|
||||||
byte trackdir = GetVehicleTrackdir(v);
|
|
||||||
TileIndex tile = AddTileIndexDiffCWrap(v->tile, TileIndexDiffCByDir(TrackdirToExitdir(trackdir)));
|
TileIndex tile = AddTileIndexDiffCWrap(v->tile, TileIndexDiffCByDir(TrackdirToExitdir(trackdir)));
|
||||||
uint32 ts;
|
uint32 ts;
|
||||||
assert(tile != INVALID_TILE);
|
assert(tile != INVALID_TILE);
|
||||||
@ -1365,10 +1369,10 @@ static void ReverseTrainDirection(Vehicle *v)
|
|||||||
ts &= TrackdirReachesTrackdirs(trackdir);
|
ts &= TrackdirReachesTrackdirs(trackdir);
|
||||||
assert(ts != 0 && KillFirstBit2x64(ts) == 0);
|
assert(ts != 0 && KillFirstBit2x64(ts) == 0);
|
||||||
trackdir = FindFirstBit2x64(ts);
|
trackdir = FindFirstBit2x64(ts);
|
||||||
PBSClearPath(tile, trackdir);
|
PBSClearPath(tile, trackdir, pbs_end_tile, pbs_end_trackdir);
|
||||||
v->u.rail.pbs_status = PBS_STAT_NONE;
|
v->u.rail.pbs_status = PBS_STAT_NONE;
|
||||||
} else if (PBSTileReserved(tile) & (1 << (trackdir&7))) {
|
} else if (PBSTileReserved(tile) & (1 << TrackdirToTrack(trackdir))) {
|
||||||
PBSClearPath(tile, trackdir);
|
PBSClearPath(tile, trackdir, pbs_end_tile, pbs_end_trackdir);
|
||||||
if (v->u.rail.track != 0x40)
|
if (v->u.rail.track != 0x40)
|
||||||
PBSReserveTrack(tile, trackdir & 7);
|
PBSReserveTrack(tile, trackdir & 7);
|
||||||
};
|
};
|
||||||
@ -1838,8 +1842,11 @@ static bool CheckTrainStayInDepot(Vehicle *v)
|
|||||||
if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
|
if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
|
||||||
if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))
|
if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))
|
||||||
return true;
|
return true;
|
||||||
else
|
else {
|
||||||
|
v->u.rail.pbs_end_tile = ftd.node.tile;
|
||||||
|
v->u.rail.pbs_end_trackdir = ftd.node.direction;
|
||||||
goto green;
|
goto green;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2007,11 +2014,14 @@ static byte ChooseTrainTrack(Vehicle *v, TileIndex tile, int enterdir, TrackdirB
|
|||||||
if (pbs_tracks || (v->u.rail.pbs_status == PBS_STAT_NEED_PATH)) {
|
if (pbs_tracks || (v->u.rail.pbs_status == PBS_STAT_NEED_PATH)) {
|
||||||
DEBUG(pbs, 2) ("pbs: (%i) choosefromblock, tile_org:%x tile_dst:%x trackdir:%i pbs_tracks:%i",v->unitnumber, tile,tile - TileOffsByDir(enterdir), trackdir, pbs_tracks);
|
DEBUG(pbs, 2) ("pbs: (%i) choosefromblock, tile_org:%x tile_dst:%x trackdir:%i pbs_tracks:%i",v->unitnumber, tile,tile - TileOffsByDir(enterdir), trackdir, pbs_tracks);
|
||||||
// clear the currently planned path
|
// clear the currently planned path
|
||||||
if (v->u.rail.pbs_status != PBS_STAT_NEED_PATH) PBSClearPath(tile, FindFirstBit2x64(pbs_tracks));
|
if (v->u.rail.pbs_status != PBS_STAT_NEED_PATH) PBSClearPath(tile, FindFirstBit2x64(pbs_tracks), v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir);
|
||||||
|
|
||||||
// try to find a route to a green exit signal
|
// try to find a route to a green exit signal
|
||||||
ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_ANY);
|
ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_ANY);
|
||||||
|
|
||||||
|
v->u.rail.pbs_end_tile = ftd.node.tile;
|
||||||
|
v->u.rail.pbs_end_trackdir = ftd.node.direction;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_NONE);
|
ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_NONE);
|
||||||
|
|
||||||
@ -2779,6 +2789,8 @@ static void TrainController(Vehicle *v)
|
|||||||
if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))
|
if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))
|
||||||
goto red_light;
|
goto red_light;
|
||||||
else {
|
else {
|
||||||
|
v->u.rail.pbs_end_tile = ftd.node.tile;
|
||||||
|
v->u.rail.pbs_end_trackdir = ftd.node.direction;
|
||||||
goto green_light;
|
goto green_light;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2955,8 +2967,8 @@ static void DeleteLastWagon(Vehicle *v)
|
|||||||
// clear up reserved pbs tracks
|
// clear up reserved pbs tracks
|
||||||
if (PBSTileReserved(v->tile) & v->u.rail.track) {
|
if (PBSTileReserved(v->tile) & v->u.rail.track) {
|
||||||
if (v == u) {
|
if (v == u) {
|
||||||
PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track));
|
PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track), v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir);
|
||||||
PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track) + 8);
|
PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track) + 8, v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir);
|
||||||
};
|
};
|
||||||
if (v->tile != u->tile) {
|
if (v->tile != u->tile) {
|
||||||
PBSClearTrack(v->tile, FIND_FIRST_BIT(v->u.rail.track));
|
PBSClearTrack(v->tile, FIND_FIRST_BIT(v->u.rail.track));
|
||||||
@ -3206,6 +3218,8 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
|
|||||||
if (ftd.best_trackdir != 0xFF && NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
|
if (ftd.best_trackdir != 0xFF && NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
|
||||||
if (!(NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))) {
|
if (!(NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))) {
|
||||||
v->u.rail.pbs_status = PBS_STAT_HAS_PATH;
|
v->u.rail.pbs_status = PBS_STAT_HAS_PATH;
|
||||||
|
v->u.rail.pbs_end_tile = ftd.node.tile;
|
||||||
|
v->u.rail.pbs_end_trackdir = ftd.node.direction;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1947,8 +1947,10 @@ static const SaveLoad _train_desc[] = {
|
|||||||
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,days_since_order_progr), SLE_UINT16, 2, 255),
|
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,days_since_order_progr), SLE_UINT16, 2, 255),
|
||||||
|
|
||||||
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_status), SLE_UINT8, 2, 255),
|
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_status), SLE_UINT8, 2, 255),
|
||||||
// reserve extra space in savegame here. (currently 12 bytes)
|
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_end_tile), SLE_UINT32, 2, 255),
|
||||||
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 12, 2, 255),
|
SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_end_trackdir), SLE_UINT8, 2, 255),
|
||||||
|
// reserve extra space in savegame here. (currently 7 bytes)
|
||||||
|
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 7, 2, 255),
|
||||||
|
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user