src/roadveh_cmd.cpp
branchNewGRF_ports
changeset 10184 fcf5fb2548eb
parent 6878 7d1ff2f621c7
child 10200 aba3af04cdbd
equal deleted inserted replaced
10179:eec5a7dcbf61 10184:fcf5fb2548eb
     8 #include "tile_cmd.h"
     8 #include "tile_cmd.h"
     9 #include "landscape.h"
     9 #include "landscape.h"
    10 #include "road_map.h"
    10 #include "road_map.h"
    11 #include "roadveh.h"
    11 #include "roadveh.h"
    12 #include "station_map.h"
    12 #include "station_map.h"
    13 #include "timetable.h"
       
    14 #include "engine.h"
       
    15 #include "command_func.h"
    13 #include "command_func.h"
    16 #include "station.h"
    14 #include "station_base.h"
    17 #include "news.h"
    15 #include "news_func.h"
    18 #include "pathfind.h"
    16 #include "pathfind.h"
    19 #include "npf.h"
    17 #include "npf.h"
    20 #include "player_func.h"
    18 #include "player_func.h"
    21 #include "player_base.h"
    19 #include "player_base.h"
    22 #include "depot.h"
    20 #include "depot.h"
    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));
   697 
   692 
   698 	SetDParam(0, pass);
   693 	SetDParam(0, pass);
   699 	AddNewsItem(
   694 	AddNewsItem(
   700 		(pass == 1) ?
   695 		(pass == 1) ?
   701 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   696 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   702 		NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
   697 		NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, DNC_NONE,
   703 		v->index,
   698 		v->index,
   704 		0
   699 		0
   705 	);
   700 	);
   706 
   701 
   707 	ModifyStationRatingAround(v->tile, v->owner, -160, 22);
   702 	ModifyStationRatingAround(v->tile, v->owner, -160, 22);
   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 
  1857 
  1789 
  1858 			return false;
  1790 			return false;
  1859 		}
  1791 		}
  1860 
  1792 
  1861 		/* Vehicle is ready to leave a bay in a road stop */
  1793 		/* Vehicle is ready to leave a bay in a road stop */
  1862 		if (v->current_order.type != OT_GOTO_DEPOT) {
  1794 		if (!v->current_order.IsType(OT_GOTO_DEPOT)) {
  1863 			if (rs->IsEntranceBusy()) {
  1795 			if (rs->IsEntranceBusy()) {
  1864 				/* Road stop entrance is busy, so wait as there is nowhere else to go */
  1796 				/* Road stop entrance is busy, so wait as there is nowhere else to go */
  1865 				v->cur_speed = 0;
  1797 				v->cur_speed = 0;
  1866 				return false;
  1798 				return false;
  1867 			}
  1799 			}
  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 		}
  1943 		v->breakdown_ctr--;
  1875 		v->breakdown_ctr--;
  1944 	}
  1876 	}
  1945 
  1877 
  1946 	if (v->vehstatus & VS_STOPPED) return;
  1878 	if (v->vehstatus & VS_STOPPED) return;
  1947 
  1879 
  1948 	ProcessRoadVehOrder(v);
  1880 	ProcessOrders(v);
  1949 	v->HandleLoading();
  1881 	v->HandleLoading();
  1950 
  1882 
  1951 	if (v->current_order.type == OT_LOADING) return;
  1883 	if (v->current_order.IsType(OT_LOADING)) return;
  1952 
  1884 
  1953 	if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return;
  1885 	if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return;
  1954 
  1886 
  1955 	/* Check if vehicle needs to proceed, return if it doesn't */
  1887 	/* Check if vehicle needs to proceed, return if it doesn't */
  1956 	if (!RoadVehAccelerate(v)) return;
  1888 	if (!RoadVehAccelerate(v)) return;
  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: