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 |