mirror of https://github.com/OpenTTD/OpenTTD
(svn r314) -Fix: [982611] Pathfinding bug; train likes the roundabout. If train needs servicing it will now look 16 tiles along the track instead of 12 tiles manhattan style (blathijs)
parent
198f841c7e
commit
36f18e7f40
52
train_cmd.c
52
train_cmd.c
|
@ -1089,50 +1089,48 @@ static bool TrainFindDepotEnumProc(uint tile, TrainFindDepotData *tfdd, int trac
|
||||||
return length >= tfdd->best_length;
|
return length >= tfdd->best_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the tile of a depot to goto to
|
// returns the tile of a depot to goto to.
|
||||||
static uint FindClosestTrainDepot(Vehicle *v)
|
static TrainFindDepotData FindClosestTrainDepot(Vehicle *v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
TrainFindDepotData tfdd;
|
TrainFindDepotData tfdd;
|
||||||
uint tile = v->tile;
|
uint tile = v->tile;
|
||||||
|
|
||||||
if (IsTrainDepotTile(tile))
|
|
||||||
return tile;
|
|
||||||
|
|
||||||
if (v->u.rail.track == 0x40) { tile = GetVehicleOutOfTunnelTile(v); }
|
|
||||||
|
|
||||||
tfdd.owner = v->owner;
|
tfdd.owner = v->owner;
|
||||||
tfdd.best_length = (uint)-1;
|
tfdd.best_length = (uint)-1;
|
||||||
|
|
||||||
|
if (IsTrainDepotTile(tile)){
|
||||||
|
tfdd.tile = tile;
|
||||||
|
tfdd.best_length = 0;
|
||||||
|
return tfdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v->u.rail.track == 0x40) { tile = GetVehicleOutOfTunnelTile(v); }
|
||||||
|
|
||||||
if (!_patches.new_depot_finding) {
|
if (!_patches.new_depot_finding) {
|
||||||
// search in all directions
|
// search in all directions
|
||||||
for(i=0; i!=4; i++)
|
for(i=0; i!=4; i++)
|
||||||
NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL);
|
NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL);
|
||||||
if (tfdd.best_length != (uint)-1)
|
|
||||||
return tfdd.tile;
|
|
||||||
} else {
|
} else {
|
||||||
// search in the forward direction first.
|
// search in the forward direction first.
|
||||||
i = v->direction >> 1;
|
i = v->direction >> 1;
|
||||||
if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; }
|
if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; }
|
||||||
NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL);
|
NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL);
|
||||||
if (tfdd.best_length != (uint)-1)
|
if (tfdd.best_length == (uint)-1){
|
||||||
return tfdd.tile;
|
|
||||||
|
|
||||||
// search in backwards direction
|
// search in backwards direction
|
||||||
i = (v->direction^4) >> 1;
|
i = (v->direction^4) >> 1;
|
||||||
if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; }
|
if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) { i = (i - 1) & 3; }
|
||||||
NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL);
|
NewTrainPathfind(tile, i, (TPFEnumProc*)TrainFindDepotEnumProc, &tfdd, NULL);
|
||||||
if (tfdd.best_length != (uint)-1)
|
}
|
||||||
return tfdd.tile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint)-1;
|
return tfdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
Vehicle *v = &_vehicles[p1];
|
Vehicle *v = &_vehicles[p1];
|
||||||
uint depot_tile;
|
TrainFindDepotData tfdd;
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
@ -1147,14 +1145,14 @@ int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
depot_tile = FindClosestTrainDepot(v);
|
tfdd = FindClosestTrainDepot(v);
|
||||||
if (depot_tile == (uint)-1)
|
if (tfdd.best_length == (uint)-1)
|
||||||
return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
|
return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->dest_tile = depot_tile;
|
v->dest_tile = tfdd.tile;
|
||||||
v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
|
v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
|
||||||
v->next_order_param = GetDepotByTile(depot_tile);
|
v->next_order_param = GetDepotByTile(tfdd.tile);
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2566,8 +2564,8 @@ void TrainEnterDepot(Vehicle *v, uint tile)
|
||||||
|
|
||||||
static void CheckIfTrainNeedsService(Vehicle *v)
|
static void CheckIfTrainNeedsService(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint tile;
|
|
||||||
byte depot;
|
byte depot;
|
||||||
|
TrainFindDepotData tfdd;
|
||||||
|
|
||||||
if (_patches.servint_trains == 0)
|
if (_patches.servint_trains == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -2587,23 +2585,27 @@ static void CheckIfTrainNeedsService(Vehicle *v)
|
||||||
(v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) != 0)
|
(v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tile = FindClosestTrainDepot(v);
|
tfdd = FindClosestTrainDepot(v);
|
||||||
if (tile == (uint)-1 || GetTileDist(v->tile, tile) > 12) {
|
/* Only go to the depot if it is not too far out of our way. */
|
||||||
|
if (tfdd.best_length == (uint)-1 || tfdd.best_length > 16 ) {
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
||||||
|
/* If we were already heading for a depot but it has
|
||||||
|
* suddenly moved farther away, we continue our normal
|
||||||
|
* schedule? */
|
||||||
v->next_order = OT_DUMMY;
|
v->next_order = OT_DUMMY;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
depot = GetDepotByTile(tile);
|
depot = GetDepotByTile(tfdd.tile);
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT && v->next_order_param != depot && !CHANCE16(3,16))
|
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT && v->next_order_param != depot && !CHANCE16(3,16))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
|
v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
|
||||||
v->next_order_param = depot;
|
v->next_order_param = depot;
|
||||||
v->dest_tile = tile;
|
v->dest_tile = tfdd.tile;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue