roadveh_cmd.c
changeset 2089 36f1c7177730
parent 2049 ad0d49c916d4
child 2093 357b05db938f
equal deleted inserted replaced
2088:f290b54c97cb 2089:36f1c7177730
  1632 
  1632 
  1633 	CheckOrders(v->index, OC_INIT);
  1633 	CheckOrders(v->index, OC_INIT);
  1634 
  1634 
  1635 	/* update destination */
  1635 	/* update destination */
  1636 	if (v->current_order.type == OT_GOTO_STATION && !(v->vehstatus & VS_CRASHED)) {
  1636 	if (v->current_order.type == OT_GOTO_STATION && !(v->vehstatus & VS_CRASHED)) {
  1637 		RoadStop *rs;
       
  1638 		uint32 mindist = 0xFFFFFFFF;
       
  1639 		int num;
  1637 		int num;
  1640 		RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
  1638 		RoadStopType type = (v->cargo_type == CT_PASSENGERS) ? RS_BUS : RS_TRUCK;
  1641 
  1639 
  1642 		typedef struct {
       
  1643 			uint32 dist;
       
  1644 			RoadStop *rs;
       
  1645 		} StopStruct;
       
  1646 
       
  1647 		StopStruct *stop, *firststop;
       
  1648 
       
  1649 		st = GetStation(v->current_order.station);
  1640 		st = GetStation(v->current_order.station);
  1650 		rs = GetPrimaryRoadStop(st, type);
       
  1651 		num = GetNumRoadStops(st, type);
  1641 		num = GetNumRoadStops(st, type);
  1652 
  1642 
  1653 		firststop = stop = malloc(num * sizeof(StopStruct));
       
  1654 
       
  1655 		//Current slot has expired
  1643 		//Current slot has expired
  1656 		if ( (v->u.road.slot_age++ <= 0) && (v->u.road.slot != NULL)) {
  1644 		if ( (v->u.road.slot_age++ <= 0) && (v->u.road.slot != NULL))
  1657 			ClearSlot(v, v->u.road.slot);
  1645 			ClearSlot(v, v->u.road.slot);
  1658 		}
       
  1659 
  1646 
  1660 		//We do not have a slot, so make one
  1647 		//We do not have a slot, so make one
  1661 		if (v->u.road.slot == NULL && rs != NULL) {
  1648 		if (v->u.road.slot == NULL) {
       
  1649 			RoadStop *rs = GetPrimaryRoadStop(st, type);
       
  1650 			RoadStop *first_stop = rs;
       
  1651 			RoadStop *best_stop = NULL;
       
  1652 			uint32 mindist = 120, dist; // 120 is threshold distance.
       
  1653 
  1662 		//first we need to find out how far our stations are away.
  1654 		//first we need to find out how far our stations are away.
  1663 
       
  1664 			DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy);
  1655 			DEBUG(ms, 2) ("Multistop: Attempting to obtain a slot for vehicle %d at station %d (0x%x)", v->unitnumber, st->index, st->xy);
  1665 			do {
  1656 			for(; rs != NULL; rs = rs->next) {
  1666 				stop->dist = RoadFindPathToStation(v, rs->xy) / NPF_TILE_LENGTH;
  1657 				// Only consider those with at least a free slot.
  1667 				DEBUG(ms, 3) ("Multistop: Distance to stop at 0x%x is %d", rs->xy, stop->dist);
  1658 				if (!(rs->slot[0] == INVALID_SLOT || rs->slot[1] == INVALID_SLOT))
  1668 				stop->rs = rs;
  1659 					continue;
  1669 
  1660 
  1670 				if (stop->dist < mindist) {
  1661 				// Previously the NPF pathfinder was used here even if NPF is OFF.. WTF?
  1671 					mindist = stop->dist;
  1662 				assert(NUM_SLOTS == 2);
       
  1663 				dist = DistanceManhattan(v->tile, rs->xy);
       
  1664 
       
  1665 				// Remember the one with the shortest distance
       
  1666 				if (dist < mindist) {
       
  1667 					mindist = dist;
       
  1668 					best_stop = rs;
  1672 				}
  1669 				}
  1673 
  1670 				DEBUG(ms, 3) ("Multistop: Distance to stop at 0x%x is %d", rs->xy, dist);
  1674 				stop++;
       
  1675 				rs = rs->next;
       
  1676 			} while (rs != NULL);
       
  1677 
       
  1678 			if (mindist < 180) {	//if we're reasonably close, get us a slot
       
  1679 				int k;
       
  1680 				bubblesort(firststop, num, sizeof(StopStruct), dist_compare);
       
  1681 
       
  1682 				stop = firststop;
       
  1683 				for (k = 0; k < num; k++) {
       
  1684 					int i;
       
  1685 					bool br = false;
       
  1686 					for (i = 0; i < NUM_SLOTS; i++) {
       
  1687 						if ((stop->rs->slot[i] == INVALID_SLOT) && (stop->dist < 120)) {
       
  1688 
       
  1689 							//Hooray we found a free slot. Assign it
       
  1690 							DEBUG(ms, 1) ("Multistop: Slot %d at 0x%x assigned to vehicle %d", i, stop->rs->xy, v->unitnumber);
       
  1691 							stop->rs->slot[i] = v->index;
       
  1692 							v->u.road.slot = stop->rs;
       
  1693 
       
  1694 							v->dest_tile = stop->rs->xy;
       
  1695 							v->u.road.slot_age = -30;
       
  1696 							v->u.road.slotindex = i;
       
  1697 
       
  1698 							br = true;
       
  1699 							break;
       
  1700 
       
  1701 						}
       
  1702 					}
       
  1703 					stop++;
       
  1704 					if (br) break;
       
  1705 				}
       
  1706 			}
  1671 			}
  1707 
  1672 
  1708 		//now we couldn't assign a slot for one reason or another.
  1673 			// best_stop now contains the best stop we found.
  1709 		//so we just go to the nearest station
  1674 			if (best_stop) {
  1710 			if (v->u.road.slot == NULL) {
  1675 				int slot;
       
  1676 				// Find a free slot in this stop. We know that at least one is free.
       
  1677 				assert(best_stop->slot[0] == INVALID_SLOT || best_stop->slot[1] == INVALID_SLOT);
       
  1678 				slot = (best_stop->slot[0] == INVALID_SLOT) ? 0 : 1;
       
  1679 				best_stop->slot[slot] = v->index;
       
  1680 				v->u.road.slot = best_stop;
       
  1681 				v->dest_tile = best_stop->xy;
       
  1682 				v->u.road.slot_age = -30;
       
  1683 				v->u.road.slotindex = slot;
       
  1684 				DEBUG(ms, 1) ("Multistop: Slot %d at 0x%x assigned to vehicle %d", slot, best_stop->xy, v->unitnumber);
       
  1685 			} else if (first_stop) {
       
  1686 				//now we couldn't assign a slot for one reason or another.
       
  1687 				//so we just go towards the first station
  1711 				DEBUG(ms, 1) ("Multistop: No free slot found for vehicle %d, going to default station", v->unitnumber);
  1688 				DEBUG(ms, 1) ("Multistop: No free slot found for vehicle %d, going to default station", v->unitnumber);
  1712 				v->dest_tile = firststop->rs->xy;
  1689 				v->dest_tile = first_stop->xy;
  1713 			}
  1690 			}
  1714 		}
  1691 		}
  1715 
       
  1716 		free(firststop);
       
  1717 		firststop = stop = NULL;
       
  1718 	}
  1692 	}
  1719 
  1693 
  1720 	if (v->vehstatus & VS_STOPPED)
  1694 	if (v->vehstatus & VS_STOPPED)
  1721 		return;
  1695 		return;
  1722 
  1696 
  1746 			v->profit_this_year = 0;
  1720 			v->profit_this_year = 0;
  1747 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1721 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1748 		}
  1722 		}
  1749 	}
  1723 	}
  1750 }
  1724 }
  1751