40 #include "sound_func.h" |
38 #include "sound_func.h" |
41 #include "variables.h" |
39 #include "variables.h" |
42 #include "autoreplace_gui.h" |
40 #include "autoreplace_gui.h" |
43 #include "gfx_func.h" |
41 #include "gfx_func.h" |
44 #include "settings_type.h" |
42 #include "settings_type.h" |
|
43 #include "order_func.h" |
45 |
44 |
46 #include "table/strings.h" |
45 #include "table/strings.h" |
47 |
46 |
48 static const uint16 _roadveh_images[63] = { |
47 static const uint16 _roadveh_images[63] = { |
49 0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14, |
48 0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14, |
435 rfdd.owner = v->owner; |
434 rfdd.owner = v->owner; |
436 rfdd.best_length = UINT_MAX; |
435 rfdd.best_length = UINT_MAX; |
437 |
436 |
438 /* search in all directions */ |
437 /* search in all directions */ |
439 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { |
438 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { |
440 FollowTrack(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd); |
439 FollowTrack(v->tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd); |
441 } |
440 } |
442 |
441 |
443 if (rfdd.best_length != UINT_MAX) return GetDepotByTile(rfdd.tile); |
442 if (rfdd.best_length != UINT_MAX) return GetDepotByTile(rfdd.tile); |
444 } break; |
443 } break; |
445 } |
444 } |
475 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
474 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
476 |
475 |
477 if (v->IsInDepot()) return CMD_ERROR; |
476 if (v->IsInDepot()) return CMD_ERROR; |
478 |
477 |
479 /* If the current orders are already goto-depot */ |
478 /* If the current orders are already goto-depot */ |
480 if (v->current_order.type == OT_GOTO_DEPOT) { |
479 if (v->current_order.IsType(OT_GOTO_DEPOT)) { |
481 if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) { |
480 bool halt_in_depot = v->current_order.GetDepotActionType() & ODATFB_HALT; |
|
481 if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) { |
482 /* We called with a different DEPOT_SERVICE setting. |
482 /* We called with a different DEPOT_SERVICE setting. |
483 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
483 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
484 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
484 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
485 if (flags & DC_EXEC) { |
485 if (flags & DC_EXEC) { |
486 ClrBit(v->current_order.flags, OF_PART_OF_ORDERS); |
486 v->current_order.SetDepotOrderType(ODTF_MANUAL); |
487 ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT); |
487 v->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT); |
488 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
488 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
489 } |
489 } |
490 return CommandCost(); |
490 return CommandCost(); |
491 } |
491 } |
492 |
492 |
493 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
493 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
494 if (flags & DC_EXEC) { |
494 if (flags & DC_EXEC) { |
495 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
495 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
496 * then skip to the next order; effectively cancelling this forced service */ |
496 * then skip to the next order; effectively cancelling this forced service */ |
497 if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) |
497 if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) v->cur_order_index++; |
498 v->cur_order_index++; |
498 |
499 |
499 v->current_order.MakeDummy(); |
500 v->current_order.type = OT_DUMMY; |
|
501 v->current_order.flags = 0; |
|
502 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
500 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
503 } |
501 } |
504 return CommandCost(); |
502 return CommandCost(); |
505 } |
503 } |
506 |
504 |
507 dep = FindClosestRoadDepot(v); |
505 dep = FindClosestRoadDepot(v); |
508 if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT); |
506 if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT); |
509 |
507 |
510 if (flags & DC_EXEC) { |
508 if (flags & DC_EXEC) { |
511 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
509 if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); |
512 |
510 |
513 ClearSlot(v); |
511 ClearSlot(v); |
514 v->current_order.type = OT_GOTO_DEPOT; |
512 v->current_order.MakeGoToDepot(dep->index, ODTF_MANUAL); |
515 v->current_order.flags = OFB_NON_STOP; |
513 if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(ODATFB_HALT); |
516 if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT); |
|
517 v->current_order.refit_cargo = CT_INVALID; |
|
518 v->current_order.dest = dep->index; |
|
519 v->dest_tile = dep->xy; |
514 v->dest_tile = dep->xy; |
520 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
515 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
521 } |
516 } |
522 |
517 |
523 return CommandCost(); |
518 return CommandCost(); |
583 #undef MKIT |
578 #undef MKIT |
584 |
579 |
585 uint32 x = _delta_xy_table[direction]; |
580 uint32 x = _delta_xy_table[direction]; |
586 this->x_offs = GB(x, 0, 8); |
581 this->x_offs = GB(x, 0, 8); |
587 this->y_offs = GB(x, 8, 8); |
582 this->y_offs = GB(x, 8, 8); |
588 this->sprite_width = GB(x, 16, 8); |
583 this->x_extent = GB(x, 16, 8); |
589 this->sprite_height = GB(x, 24, 8); |
584 this->y_extent = GB(x, 24, 8); |
590 this->z_height = 6; |
585 this->z_extent = 6; |
591 } |
586 } |
592 |
587 |
593 static void ClearCrashedStation(Vehicle *v) |
588 static void ClearCrashedStation(Vehicle *v) |
594 { |
589 { |
595 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
590 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
753 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
748 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
754 } |
749 } |
755 } |
750 } |
756 } |
751 } |
757 |
752 |
758 static void ProcessRoadVehOrder(Vehicle *v) |
753 TileIndex RoadVehicle::GetOrderStationLocation(StationID station) |
759 { |
754 { |
760 const Order *order; |
755 if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION; |
761 |
756 |
762 switch (v->current_order.type) { |
757 TileIndex dest = INVALID_TILE; |
763 case OT_GOTO_DEPOT: |
758 const RoadStop *rs = GetStation(station)->GetPrimaryRoadStop(this); |
764 /* Let a depot order in the orderlist interrupt. */ |
759 if (rs != NULL) { |
765 if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return; |
760 uint mindist = MAX_UVALUE(uint); |
766 if (v->current_order.flags & OFB_SERVICE_IF_NEEDED && |
761 |
767 !VehicleNeedsService(v)) { |
762 for (; rs != NULL; rs = rs->GetNextRoadStop(this)) { |
768 UpdateVehicleTimetable(v, true); |
763 uint dist = DistanceManhattan(this->tile, rs->xy); |
769 v->cur_order_index++; |
764 |
770 } |
765 if (dist < mindist) { |
771 break; |
766 mindist = dist; |
772 |
767 dest = rs->xy; |
773 case OT_LOADING: |
768 } |
774 case OT_LEAVESTATION: |
769 } |
775 return; |
770 } |
776 |
771 |
777 default: break; |
772 if (dest != INVALID_TILE) { |
778 } |
773 return dest; |
779 |
774 } else { |
780 if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0; |
775 /* There is no stop left at the station, so don't even TRY to go there */ |
781 |
776 this->cur_order_index++; |
782 order = GetVehicleOrder(v, v->cur_order_index); |
777 return 0; |
783 |
778 } |
784 if (order == NULL) { |
|
785 v->current_order.Free(); |
|
786 v->dest_tile = 0; |
|
787 ClearSlot(v); |
|
788 return; |
|
789 } |
|
790 |
|
791 if (order->type == v->current_order.type && |
|
792 order->flags == v->current_order.flags && |
|
793 order->dest == v->current_order.dest) { |
|
794 return; |
|
795 } |
|
796 |
|
797 v->current_order = *order; |
|
798 |
|
799 switch (order->type) { |
|
800 case OT_GOTO_STATION: { |
|
801 if (order->dest == v->last_station_visited) { |
|
802 v->last_station_visited = INVALID_STATION; |
|
803 } |
|
804 |
|
805 const RoadStop *rs = GetStation(order->dest)->GetPrimaryRoadStop(v); |
|
806 |
|
807 TileIndex dest = INVALID_TILE; |
|
808 if (rs != NULL) { |
|
809 uint mindist = MAX_UVALUE(uint); |
|
810 |
|
811 for (; rs != NULL; rs = rs->GetNextRoadStop(v)) { |
|
812 uint dist = DistanceManhattan(v->tile, rs->xy); |
|
813 |
|
814 if (dist < mindist) { |
|
815 mindist = dist; |
|
816 dest = rs->xy; |
|
817 } |
|
818 } |
|
819 } |
|
820 |
|
821 if (dest != INVALID_TILE) { |
|
822 v->dest_tile = dest; |
|
823 } else { |
|
824 /* There is no stop left at the station, so don't even TRY to go there */ |
|
825 v->cur_order_index++; |
|
826 v->dest_tile = 0; |
|
827 } |
|
828 break; |
|
829 } |
|
830 |
|
831 case OT_GOTO_DEPOT: |
|
832 v->dest_tile = GetDepot(order->dest)->xy; |
|
833 break; |
|
834 |
|
835 default: |
|
836 v->dest_tile = 0; |
|
837 break; |
|
838 } |
|
839 |
|
840 InvalidateVehicleOrder(v); |
|
841 } |
779 } |
842 |
780 |
843 static void StartRoadVehSound(const Vehicle* v) |
781 static void StartRoadVehSound(const Vehicle* v) |
844 { |
782 { |
845 if (!PlayVehicleSound(v, VSE_START)) { |
783 if (!PlayVehicleSound(v, VSE_START)) { |
916 static void RoadVehArrivesAt(const Vehicle* v, Station* st) |
854 static void RoadVehArrivesAt(const Vehicle* v, Station* st) |
917 { |
855 { |
918 if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) { |
856 if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) { |
919 /* Check if station was ever visited before */ |
857 /* Check if station was ever visited before */ |
920 if (!(st->had_vehicle_of_type & HVOT_BUS)) { |
858 if (!(st->had_vehicle_of_type & HVOT_BUS)) { |
921 uint32 flags; |
|
922 |
|
923 st->had_vehicle_of_type |= HVOT_BUS; |
859 st->had_vehicle_of_type |= HVOT_BUS; |
924 SetDParam(0, st->index); |
860 SetDParam(0, st->index); |
925 flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0); |
|
926 AddNewsItem( |
861 AddNewsItem( |
927 v->u.road.roadtype == ROADTYPE_ROAD ? STR_902F_CITIZENS_CELEBRATE_FIRST : STR_CITIZENS_CELEBRATE_FIRST_PASSENGER_TRAM, |
862 v->u.road.roadtype == ROADTYPE_ROAD ? STR_902F_CITIZENS_CELEBRATE_FIRST : STR_CITIZENS_CELEBRATE_FIRST_PASSENGER_TRAM, |
928 flags, |
863 NM_THIN, NF_VIEWPORT | NF_VEHICLE, (v->owner == _local_player) ? NT_ARRIVAL_PLAYER : NT_ARRIVAL_OTHER, DNC_NONE, |
929 v->index, |
864 v->index, |
930 0); |
865 0); |
931 } |
866 } |
932 } else { |
867 } else { |
933 /* Check if station was ever visited before */ |
868 /* Check if station was ever visited before */ |
934 if (!(st->had_vehicle_of_type & HVOT_TRUCK)) { |
869 if (!(st->had_vehicle_of_type & HVOT_TRUCK)) { |
935 uint32 flags; |
|
936 |
|
937 st->had_vehicle_of_type |= HVOT_TRUCK; |
870 st->had_vehicle_of_type |= HVOT_TRUCK; |
938 SetDParam(0, st->index); |
871 SetDParam(0, st->index); |
939 flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0); |
|
940 AddNewsItem( |
872 AddNewsItem( |
941 v->u.road.roadtype == ROADTYPE_ROAD ? STR_9030_CITIZENS_CELEBRATE_FIRST : STR_CITIZENS_CELEBRATE_FIRST_CARGO_TRAM, |
873 v->u.road.roadtype == ROADTYPE_ROAD ? STR_9030_CITIZENS_CELEBRATE_FIRST : STR_CITIZENS_CELEBRATE_FIRST_CARGO_TRAM, |
942 flags, |
874 NM_THIN, NF_VIEWPORT | NF_VEHICLE, (v->owner == _local_player) ? NT_ARRIVAL_PLAYER : NT_ARRIVAL_OTHER, DNC_NONE, |
943 v->index, |
875 v->index, |
944 0 |
876 0 |
945 ); |
877 ); |
946 } |
878 } |
947 } |
879 } |
1174 if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || RoadVehHasArticPart(v)) { |
1106 if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || RoadVehHasArticPart(v)) { |
1175 /* different station owner or wrong orientation or the vehicle has articulated parts */ |
1107 /* different station owner or wrong orientation or the vehicle has articulated parts */ |
1176 trackdirs = TRACKDIR_BIT_NONE; |
1108 trackdirs = TRACKDIR_BIT_NONE; |
1177 } else { |
1109 } else { |
1178 /* Our station */ |
1110 /* Our station */ |
1179 RoadStop::Type rstype = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; |
1111 RoadStopType rstype = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK; |
1180 |
1112 |
1181 if (GetRoadStopType(tile) != rstype) { |
1113 if (GetRoadStopType(tile) != rstype) { |
1182 /* Wrong station type */ |
1114 /* Wrong station type */ |
1183 trackdirs = TRACKDIR_BIT_NONE; |
1115 trackdirs = TRACKDIR_BIT_NONE; |
1184 } else { |
1116 } else { |
1287 uint i; |
1219 uint i; |
1288 FOR_EACH_SET_BIT(i, bitmask) { |
1220 FOR_EACH_SET_BIT(i, bitmask) { |
1289 if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track |
1221 if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track |
1290 frd.maxtracklen = UINT_MAX; |
1222 frd.maxtracklen = UINT_MAX; |
1291 frd.mindist = UINT_MAX; |
1223 frd.mindist = UINT_MAX; |
1292 FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); |
1224 FollowTrack(tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); |
1293 |
1225 |
1294 if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) { |
1226 if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) { |
1295 best_dist = frd.mindist; |
1227 best_dist = frd.mindist; |
1296 best_maxlen = frd.maxtracklen; |
1228 best_maxlen = frd.maxtracklen; |
1297 best_track = (Trackdir)i; |
1229 best_track = (Trackdir)i; |
1459 ROAD_X, ROAD_Y, ROAD_NW | ROAD_NE, ROAD_SW | ROAD_SE, |
1391 ROAD_X, ROAD_Y, ROAD_NW | ROAD_NE, ROAD_SW | ROAD_SE, |
1460 ROAD_NW | ROAD_SW, ROAD_NE | ROAD_SE, ROAD_X, ROAD_Y |
1392 ROAD_NW | ROAD_SW, ROAD_NE | ROAD_SE, ROAD_X, ROAD_Y |
1461 }; |
1393 }; |
1462 RoadBits required = required_roadbits[dir & 0x07]; |
1394 RoadBits required = required_roadbits[dir & 0x07]; |
1463 |
1395 |
1464 if ((required & GetAnyRoadBits(tile, v->u.road.roadtype)) == ROAD_NONE) { |
1396 if ((required & GetAnyRoadBits(tile, v->u.road.roadtype, true)) == ROAD_NONE) { |
1465 dir = INVALID_TRACKDIR; |
1397 dir = INVALID_TRACKDIR; |
1466 } |
1398 } |
1467 |
1399 |
1468 return dir; |
1400 return dir; |
1469 } |
1401 } |
1696 const RoadDriveEntry *rdp; |
1628 const RoadDriveEntry *rdp; |
1697 |
1629 |
1698 uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME; |
1630 uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME; |
1699 |
1631 |
1700 RoadBits tram; |
1632 RoadBits tram; |
1701 if (v->u.road.roadtype == ROADTYPE_TRAM && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM)) == 1) { |
1633 if (v->u.road.roadtype == ROADTYPE_TRAM && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true)) == 1) { |
1702 /* |
1634 /* |
1703 * The tram is turning around with one tram 'roadbit'. This means that |
1635 * The tram is turning around with one tram 'roadbit'. This means that |
1704 * it is using the 'big' corner 'drive data'. However, to support the |
1636 * it is using the 'big' corner 'drive data'. However, to support the |
1705 * trams to take a small corner, there is a 'turned' marker in the middle |
1637 * trams to take a small corner, there is a 'turned' marker in the middle |
1706 * of the turning 'drive data'. When the tram took the long corner, we |
1638 * of the turning 'drive data'. When the tram took the long corner, we |
1809 * (the station test and stop type test ensure that other vehicles, using the road stop as |
1741 * (the station test and stop type test ensure that other vehicles, using the road stop as |
1810 * a through route, do not stop) */ |
1742 * a through route, do not stop) */ |
1811 if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && |
1743 if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && |
1812 _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || |
1744 _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || |
1813 (IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && |
1745 (IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && |
1814 v->current_order.dest == GetStationIndex(v->tile) && |
1746 v->current_order.GetDestination() == GetStationIndex(v->tile) && |
1815 GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) && |
1747 GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && |
1816 v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { |
1748 v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { |
1817 |
1749 |
1818 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
1750 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
1819 Station* st = GetStationByTile(v->tile); |
1751 Station* st = GetStationByTile(v->tile); |
1820 |
1752 |
1821 /* Vehicle is at the stop position (at a bay) in a road stop. |
1753 /* Vehicle is at the stop position (at a bay) in a road stop. |
1822 * Note, if vehicle is loading/unloading it has already been handled, |
1754 * Note, if vehicle is loading/unloading it has already been handled, |
1823 * so if we get here the vehicle has just arrived or is just ready to leave. */ |
1755 * so if we get here the vehicle has just arrived or is just ready to leave. */ |
1824 if (v->current_order.type != OT_LEAVESTATION && |
1756 if (!v->current_order.IsType(OT_LEAVESTATION) && |
1825 v->current_order.type != OT_GOTO_DEPOT) { |
1757 !v->current_order.IsType(OT_GOTO_DEPOT)) { |
1826 /* Vehicle has arrived at a bay in a road stop */ |
1758 /* Vehicle has arrived at a bay in a road stop */ |
1827 |
1759 |
1828 if (IsDriveThroughStopTile(v->tile)) { |
1760 if (IsDriveThroughStopTile(v->tile)) { |
1829 TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); |
1761 TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); |
1830 RoadStop::Type type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; |
1762 RoadStopType type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK; |
1831 |
1763 |
1832 /* Check if next inline bay is free */ |
1764 /* Check if next inline bay is free */ |
1833 if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { |
1765 if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { |
1834 RoadStop *rs_n = GetRoadStopByTile(next_tile, type); |
1766 RoadStop *rs_n = GetRoadStopByTile(next_tile, type); |
1835 |
1767 |
1883 DEBUG(ms, 2, " current tile 0x%X is not destination tile 0x%X. Route problem", v->tile, v->dest_tile); |
1815 DEBUG(ms, 2, " current tile 0x%X is not destination tile 0x%X. Route problem", v->tile, v->dest_tile); |
1884 } |
1816 } |
1885 if (v->dest_tile != v->u.road.slot->xy) { |
1817 if (v->dest_tile != v->u.road.slot->xy) { |
1886 DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->u.road.slot->xy, v->dest_tile); |
1818 DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->u.road.slot->xy, v->dest_tile); |
1887 } |
1819 } |
1888 if (v->current_order.type != OT_GOTO_STATION) { |
1820 if (!v->current_order.IsType(OT_GOTO_STATION)) { |
1889 DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.type); |
1821 DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType()); |
1890 } else { |
1822 } else { |
1891 if (v->current_order.dest != st->index) |
1823 if (v->current_order.GetDestination() != st->index) |
1892 DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)", |
1824 DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)", |
1893 st->index, v->current_order.dest); |
1825 st->index, v->current_order.GetDestination()); |
1894 } |
1826 } |
1895 |
1827 |
1896 DEBUG(ms, 2, " force a slot clearing"); |
1828 DEBUG(ms, 2, " force a slot clearing"); |
1897 ClearSlot(v); |
1829 ClearSlot(v); |
1898 } |
1830 } |
1977 } |
1909 } |
1978 |
1910 |
1979 static void CheckIfRoadVehNeedsService(Vehicle *v) |
1911 static void CheckIfRoadVehNeedsService(Vehicle *v) |
1980 { |
1912 { |
1981 /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ |
1913 /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ |
1982 if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !VehicleNeedsService(v)) return; |
1914 if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; |
1983 if (v->IsInDepot()) { |
1915 if (v->IsInDepot()) { |
1984 VehicleServiceInDepot(v); |
1916 VehicleServiceInDepot(v); |
1985 return; |
1917 return; |
1986 } |
1918 } |
1987 |
1919 |
1988 /* XXX If we already have a depot order, WHY do we search over and over? */ |
1920 /* XXX If we already have a depot order, WHY do we search over and over? */ |
1989 const Depot *depot = FindClosestRoadDepot(v); |
1921 const Depot *depot = FindClosestRoadDepot(v); |
1990 |
1922 |
1991 if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) { |
1923 if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) { |
1992 if (v->current_order.type == OT_GOTO_DEPOT) { |
1924 if (v->current_order.IsType(OT_GOTO_DEPOT)) { |
1993 v->current_order.type = OT_DUMMY; |
1925 v->current_order.MakeDummy(); |
1994 v->current_order.flags = 0; |
|
1995 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
1926 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
1996 } |
1927 } |
1997 return; |
1928 return; |
1998 } |
1929 } |
1999 |
1930 |
2000 if (v->current_order.type == OT_GOTO_DEPOT && |
1931 if (v->current_order.IsType(OT_GOTO_DEPOT) && |
2001 v->current_order.flags & OFB_NON_STOP && |
1932 v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS && |
2002 !Chance16(1, 20)) { |
1933 !Chance16(1, 20)) { |
2003 return; |
1934 return; |
2004 } |
1935 } |
2005 |
1936 |
2006 if (v->current_order.type == OT_LOADING) v->LeaveStation(); |
1937 if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); |
2007 ClearSlot(v); |
1938 ClearSlot(v); |
2008 |
1939 |
2009 v->current_order.type = OT_GOTO_DEPOT; |
1940 v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); |
2010 v->current_order.flags = OFB_NON_STOP; |
|
2011 v->current_order.dest = depot->index; |
|
2012 v->dest_tile = depot->xy; |
1941 v->dest_tile = depot->xy; |
2013 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
1942 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
2014 } |
1943 } |
2015 |
1944 |
2016 void RoadVehicle::OnNewDay() |
1945 void RoadVehicle::OnNewDay() |
2024 CheckIfRoadVehNeedsService(this); |
1953 CheckIfRoadVehNeedsService(this); |
2025 |
1954 |
2026 CheckOrders(this); |
1955 CheckOrders(this); |
2027 |
1956 |
2028 /* Current slot has expired */ |
1957 /* Current slot has expired */ |
2029 if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { |
1958 if (this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { |
2030 DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", |
1959 DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", |
2031 this->unitnumber, this->index, this->u.road.slot->xy); |
1960 this->unitnumber, this->index, this->u.road.slot->xy); |
2032 ClearSlot(this); |
1961 ClearSlot(this); |
2033 } |
1962 } |
2034 |
1963 |
2035 /* update destination */ |
1964 /* update destination */ |
2036 if (!(this->vehstatus & VS_STOPPED) && this->current_order.type == OT_GOTO_STATION && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { |
1965 if (!(this->vehstatus & VS_STOPPED) && this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { |
2037 Station *st = GetStation(this->current_order.dest); |
1966 Station *st = GetStation(this->current_order.GetDestination()); |
2038 RoadStop *rs = st->GetPrimaryRoadStop(this); |
1967 RoadStop *rs = st->GetPrimaryRoadStop(this); |
2039 RoadStop *best = NULL; |
1968 RoadStop *best = NULL; |
2040 |
1969 |
2041 if (rs != NULL) { |
1970 if (rs != NULL) { |
2042 /* We try to obtain a slot if: |
1971 /* We try to obtain a slot if: |