mirror of https://github.com/OpenTTD/OpenTTD
(svn r2599) Fix: Road vehicle multistop handling used NPF even if NPF was off????
- Also simplified/optimized the code. - Now it uses manhattan distance as an approximation instead of actual distance to find the distance. Much faster.release/0.4.5
parent
2469cedd15
commit
718307ffa4
|
@ -844,7 +844,7 @@ bool CheckOrders(uint data_a, uint data_b)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Only check every 20 days, so that we don't flood the message log */
|
/* Only check every 20 days, so that we don't flood the message log */
|
||||||
if ( ( ( v->day_counter % 20) == 0 ) && (v->owner == _local_player) ) {
|
if ( (v->owner == _local_player) && (v->day_counter % 20 == 0) ) {
|
||||||
int n_st, problem_type = -1;
|
int n_st, problem_type = -1;
|
||||||
const Order *order;
|
const Order *order;
|
||||||
const Station *st;
|
const Station *st;
|
||||||
|
|
109
roadveh_cmd.c
109
roadveh_cmd.c
|
@ -1634,87 +1634,61 @@ void OnNewDay_RoadVeh(Vehicle *v)
|
||||||
|
|
||||||
/* update destination */
|
/* update destination */
|
||||||
if (v->current_order.type == OT_GOTO_STATION && !(v->vehstatus & VS_CRASHED)) {
|
if (v->current_order.type == OT_GOTO_STATION && !(v->vehstatus & VS_CRASHED)) {
|
||||||
RoadStop *rs;
|
|
||||||
uint32 mindist = 0xFFFFFFFF;
|
|
||||||
int num;
|
int num;
|
||||||
RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
|
RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32 dist;
|
|
||||||
RoadStop *rs;
|
|
||||||
} StopStruct;
|
|
||||||
|
|
||||||
StopStruct *stop, *firststop;
|
|
||||||
|
|
||||||
st = GetStation(v->current_order.station);
|
st = GetStation(v->current_order.station);
|
||||||
rs = GetPrimaryRoadStop(st, type);
|
|
||||||
num = GetNumRoadStops(st, type);
|
num = GetNumRoadStops(st, type);
|
||||||
|
|
||||||
firststop = stop = malloc(num * sizeof(StopStruct));
|
|
||||||
|
|
||||||
//Current slot has expired
|
//Current slot has expired
|
||||||
if ( (v->u.road.slot_age++ <= 0) && (v->u.road.slot != NULL)) {
|
if ( (v->u.road.slot_age++ <= 0) && (v->u.road.slot != NULL))
|
||||||
ClearSlot(v, v->u.road.slot);
|
ClearSlot(v, v->u.road.slot);
|
||||||
}
|
|
||||||
|
|
||||||
//We do not have a slot, so make one
|
//We do not have a slot, so make one
|
||||||
if (v->u.road.slot == NULL && rs != NULL) {
|
|
||||||
//first we need to find out how far our stations are away.
|
|
||||||
|
|
||||||
DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy);
|
|
||||||
do {
|
|
||||||
stop->dist = RoadFindPathToStation(v, rs->xy) / NPF_TILE_LENGTH;
|
|
||||||
DEBUG(ms, 3) ("Multistop: Distance to stop at 0x%x is %d", rs->xy, stop->dist);
|
|
||||||
stop->rs = rs;
|
|
||||||
|
|
||||||
if (stop->dist < mindist) {
|
|
||||||
mindist = stop->dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
stop++;
|
|
||||||
rs = rs->next;
|
|
||||||
} while (rs != NULL);
|
|
||||||
|
|
||||||
if (mindist < 180) { //if we're reasonably close, get us a slot
|
|
||||||
int k;
|
|
||||||
bubblesort(firststop, num, sizeof(StopStruct), dist_compare);
|
|
||||||
|
|
||||||
stop = firststop;
|
|
||||||
for (k = 0; k < num; k++) {
|
|
||||||
int i;
|
|
||||||
bool br = false;
|
|
||||||
for (i = 0; i < NUM_SLOTS; i++) {
|
|
||||||
if ((stop->rs->slot[i] == INVALID_SLOT) && (stop->dist < 120)) {
|
|
||||||
|
|
||||||
//Hooray we found a free slot. Assign it
|
|
||||||
DEBUG(ms, 1) ("Multistop: Slot %d at 0x%x assigned to vehicle %d", i, stop->rs->xy, v->unitnumber);
|
|
||||||
stop->rs->slot[i] = v->index;
|
|
||||||
v->u.road.slot = stop->rs;
|
|
||||||
|
|
||||||
v->dest_tile = stop->rs->xy;
|
|
||||||
v->u.road.slot_age = -30;
|
|
||||||
v->u.road.slotindex = i;
|
|
||||||
|
|
||||||
br = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stop++;
|
|
||||||
if (br) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//now we couldn't assign a slot for one reason or another.
|
|
||||||
//so we just go to the nearest station
|
|
||||||
if (v->u.road.slot == NULL) {
|
if (v->u.road.slot == NULL) {
|
||||||
DEBUG(ms, 1) ("Multistop: No free slot found for vehicle %d, going to default station", v->unitnumber);
|
RoadStop *rs = GetPrimaryRoadStop(st, type);
|
||||||
v->dest_tile = firststop->rs->xy;
|
RoadStop *first_stop = rs;
|
||||||
|
RoadStop *best_stop = NULL;
|
||||||
|
uint32 mindist = 120, dist; // 120 is threshold distance.
|
||||||
|
|
||||||
|
//first we need to find out how far our stations are away.
|
||||||
|
DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy);
|
||||||
|
for(; rs != NULL; rs = rs->next) {
|
||||||
|
// Only consider those with at least a free slot.
|
||||||
|
if (!(rs->slot[0] == INVALID_SLOT || rs->slot[1] == INVALID_SLOT))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Previously the NPF pathfinder was used here even if NPF is OFF.. WTF?
|
||||||
|
assert(NUM_SLOTS == 2);
|
||||||
|
dist = DistanceManhattan(v->tile, rs->xy);
|
||||||
|
|
||||||
|
// Remember the one with the shortest distance
|
||||||
|
if (dist < mindist) {
|
||||||
|
mindist = dist;
|
||||||
|
best_stop = rs;
|
||||||
}
|
}
|
||||||
|
DEBUG(ms, 3) ("Multistop: Distance to stop at 0x%x is %d", rs->xy, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(firststop);
|
// best_stop now contains the best stop we found.
|
||||||
firststop = stop = NULL;
|
if (best_stop) {
|
||||||
|
int slot;
|
||||||
|
// Find a free slot in this stop. We know that at least one is free.
|
||||||
|
assert(best_stop->slot[0] == INVALID_SLOT || best_stop->slot[1] == INVALID_SLOT);
|
||||||
|
slot = (best_stop->slot[0] == INVALID_SLOT) ? 0 : 1;
|
||||||
|
best_stop->slot[slot] = v->index;
|
||||||
|
v->u.road.slot = best_stop;
|
||||||
|
v->dest_tile = best_stop->xy;
|
||||||
|
v->u.road.slot_age = -30;
|
||||||
|
v->u.road.slotindex = slot;
|
||||||
|
DEBUG(ms, 1) ("Multistop: Slot %d at 0x%x assigned to vehicle %d", slot, best_stop->xy, v->unitnumber);
|
||||||
|
} else if (first_stop) {
|
||||||
|
//now we couldn't assign a slot for one reason or another.
|
||||||
|
//so we just go towards the first station
|
||||||
|
DEBUG(ms, 1) ("Multistop: No free slot found for vehicle %d, going to default station", v->unitnumber);
|
||||||
|
v->dest_tile = first_stop->xy;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->vehstatus & VS_STOPPED)
|
if (v->vehstatus & VS_STOPPED)
|
||||||
|
@ -1748,4 +1722,3 @@ void RoadVehiclesYearlyLoop(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue