(svn r2599) Fix: Road vehicle multistop handling used NPF even if NPF was off????
authorludde
Sun, 17 Jul 2005 12:29:33 +0000
changeset 2089 36f1c7177730
parent 2088 f290b54c97cb
child 2090 9bbad972eb2a
(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.
order_cmd.c
roadveh_cmd.c
--- a/order_cmd.c	Sun Jul 17 11:09:03 2005 +0000
+++ b/order_cmd.c	Sun Jul 17 12:29:33 2005 +0000
@@ -844,7 +844,7 @@
 		return false;
 
 	/* 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;
 		const Order *order;
 		const Station *st;
--- a/roadveh_cmd.c	Sun Jul 17 11:09:03 2005 +0000
+++ b/roadveh_cmd.c	Sun Jul 17 12:29:33 2005 +0000
@@ -1634,87 +1634,61 @@
 
 	/* update destination */
 	if (v->current_order.type == OT_GOTO_STATION && !(v->vehstatus & VS_CRASHED)) {
-		RoadStop *rs;
-		uint32 mindist = 0xFFFFFFFF;
 		int num;
 		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);
-		rs = GetPrimaryRoadStop(st, type);
 		num = GetNumRoadStops(st, type);
 
-		firststop = stop = malloc(num * sizeof(StopStruct));
-
 		//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);
-		}
 
 		//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);
+		if (v->u.road.slot == NULL) {
+			RoadStop *rs = GetPrimaryRoadStop(st, type);
+			RoadStop *first_stop = rs;
+			RoadStop *best_stop = NULL;
+			uint32 mindist = 120, dist; // 120 is threshold distance.
 
-				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;
+		//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;
 
-							v->dest_tile = stop->rs->xy;
-							v->u.road.slot_age = -30;
-							v->u.road.slotindex = i;
+				// Previously the NPF pathfinder was used here even if NPF is OFF.. WTF?
+				assert(NUM_SLOTS == 2);
+				dist = DistanceManhattan(v->tile, rs->xy);
 
-							br = true;
-							break;
-
-						}
-					}
-					stop++;
-					if (br) break;
+				// 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);
 			}
 
-		//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) {
+			// best_stop now contains the best stop we found.
+			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 = firststop->rs->xy;
+				v->dest_tile = first_stop->xy;
 			}
 		}
-
-		free(firststop);
-		firststop = stop = NULL;
 	}
 
 	if (v->vehstatus & VS_STOPPED)
@@ -1748,4 +1722,3 @@
 		}
 	}
 }
-