src/roadveh_cmd.cpp
branchgamebalance
changeset 9895 7bd07f43b0e3
parent 6502 7ca154aca2b7
child 9903 dc85aaa556ae
equal deleted inserted replaced
9894:70d78ac95d6c 9895:7bd07f43b0e3
    28 #include "newgrf_engine.h"
    28 #include "newgrf_engine.h"
    29 #include "newgrf_text.h"
    29 #include "newgrf_text.h"
    30 #include "newgrf_sound.h"
    30 #include "newgrf_sound.h"
    31 #include "yapf/yapf.h"
    31 #include "yapf/yapf.h"
    32 #include "date.h"
    32 #include "date.h"
       
    33 #include "cargotype.h"
    33 
    34 
    34 static const uint16 _roadveh_images[63] = {
    35 static const uint16 _roadveh_images[63] = {
    35 	0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
    36 	0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
    36 	0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
    37 	0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
    37 	0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
    38 	0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
   126 	int32 cost;
   127 	int32 cost;
   127 	Vehicle *v;
   128 	Vehicle *v;
   128 	UnitID unit_num;
   129 	UnitID unit_num;
   129 	Engine *e;
   130 	Engine *e;
   130 
   131 
   131 	if (!IsEngineBuildable(p1, VEH_Road, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
   132 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE);
   132 
   133 
   133 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   134 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   134 
   135 
   135 	cost = EstimateRoadVehCost(p1);
   136 	cost = EstimateRoadVehCost(p1);
   136 	if (flags & DC_QUERY_COST) return cost;
   137 	if (flags & DC_QUERY_COST) return cost;
   142 
   143 
   143 	v = AllocateVehicle();
   144 	v = AllocateVehicle();
   144 	if (v == NULL) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   145 	if (v == NULL) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   145 
   146 
   146 	/* find the first free roadveh id */
   147 	/* find the first free roadveh id */
   147 	unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Road);
   148 	unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD);
   148 	if (unit_num > _patches.max_roadveh)
   149 	if (unit_num > _patches.max_roadveh)
   149 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   150 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   150 
   151 
   151 	if (flags & DC_EXEC) {
   152 	if (flags & DC_EXEC) {
   152 		int x;
   153 		int x;
   198 		v->service_interval = _patches.servint_roadveh;
   199 		v->service_interval = _patches.servint_roadveh;
   199 
   200 
   200 		v->date_of_last_service = _date;
   201 		v->date_of_last_service = _date;
   201 		v->build_year = _cur_year;
   202 		v->build_year = _cur_year;
   202 
   203 
   203 		v->type = VEH_Road;
   204 		v->type = VEH_ROAD;
   204 		v->cur_image = 0xC15;
   205 		v->cur_image = 0xC15;
   205 		v->random_bits = VehicleRandomBits();
   206 		v->random_bits = VehicleRandomBits();
   206 
   207 
   207 		v->vehicle_flags = 0;
   208 		v->vehicle_flags = 0;
   208 		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   209 		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   211 
   212 
   212 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   213 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   213 		RebuildVehicleLists();
   214 		RebuildVehicleLists();
   214 		InvalidateWindow(WC_COMPANY, v->owner);
   215 		InvalidateWindow(WC_COMPANY, v->owner);
   215 		if (IsLocalPlayer())
   216 		if (IsLocalPlayer())
   216 			InvalidateAutoreplaceWindow(VEH_Road); // updates the replace Road window
   217 			InvalidateAutoreplaceWindow(VEH_ROAD); // updates the replace Road window
   217 
   218 
   218 		GetPlayer(_current_player)->num_engines[p1]++;
   219 		GetPlayer(_current_player)->num_engines[p1]++;
   219 	}
   220 	}
   220 
   221 
   221 	return cost;
   222 	return cost;
   233 
   234 
   234 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   235 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   235 
   236 
   236 	v = GetVehicle(p1);
   237 	v = GetVehicle(p1);
   237 
   238 
   238 	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
   239 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   239 
   240 
   240 	/* Check if this road veh can be started/stopped. The callback will fail or
   241 	/* Check if this road veh can be started/stopped. The callback will fail or
   241 	 * return 0xFF if it can. */
   242 	 * return 0xFF if it can. */
   242 	callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
   243 	callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
   243 	if (callback != CALLBACK_FAILED && callback != 0xFF) {
   244 	if (callback != CALLBACK_FAILED && callback != 0xFF) {
   283 
   284 
   284 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   285 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   285 
   286 
   286 	v = GetVehicle(p1);
   287 	v = GetVehicle(p1);
   287 
   288 
   288 	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
   289 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   289 
   290 
   290 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   291 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   291 
   292 
   292 	if (!IsRoadVehInDepotStopped(v)) {
   293 	if (!IsRoadVehInDepotStopped(v)) {
   293 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
   294 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
   304 	}
   305 	}
   305 
   306 
   306 	return -(int32)v->value;
   307 	return -(int32)v->value;
   307 }
   308 }
   308 
   309 
   309 typedef struct RoadFindDepotData {
   310 struct RoadFindDepotData {
   310 	uint best_length;
   311 	uint best_length;
   311 	TileIndex tile;
   312 	TileIndex tile;
   312 	OwnerByte owner;
   313 	OwnerByte owner;
   313 } RoadFindDepotData;
   314 };
   314 
   315 
   315 static const DiagDirection _road_pf_directions[] = {
   316 static const DiagDirection _road_pf_directions[] = {
   316 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR,
   317 	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR,
   317 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, INVALID_DIAGDIR, INVALID_DIAGDIR
   318 	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, INVALID_DIAGDIR, INVALID_DIAGDIR
   318 };
   319 };
   382 	const Depot *dep;
   383 	const Depot *dep;
   383 
   384 
   384 	if (p2 & DEPOT_MASS_SEND) {
   385 	if (p2 & DEPOT_MASS_SEND) {
   385 		/* Mass goto depot requested */
   386 		/* Mass goto depot requested */
   386 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
   387 		if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR;
   387 		return SendAllVehiclesToDepot(VEH_Road, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
   388 		return SendAllVehiclesToDepot(VEH_ROAD, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1);
   388 	}
   389 	}
   389 
   390 
   390 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   391 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   391 
   392 
   392 	v = GetVehicle(p1);
   393 	v = GetVehicle(p1);
   393 
   394 
   394 	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
   395 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   395 
   396 
   396 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
   397 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
   397 
   398 
   398 	if (IsRoadVehInDepot(v)) return CMD_ERROR;
   399 	if (IsRoadVehInDepot(v)) return CMD_ERROR;
   399 
   400 
   452 
   453 
   453 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   454 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   454 
   455 
   455 	v = GetVehicle(p1);
   456 	v = GetVehicle(p1);
   456 
   457 
   457 	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
   458 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   458 
   459 
   459 	if (v->vehstatus & VS_STOPPED ||
   460 	if (v->vehstatus & VS_STOPPED ||
   460 			v->u.road.crashed_ctr != 0 ||
   461 			v->u.road.crashed_ctr != 0 ||
   461 			v->breakdown_ctr != 0 ||
   462 			v->breakdown_ctr != 0 ||
   462 			v->u.road.overtaking != 0 ||
   463 			v->u.road.overtaking != 0 ||
   575 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
   576 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
   576 {
   577 {
   577 	const Vehicle* u = (Vehicle*)data;
   578 	const Vehicle* u = (Vehicle*)data;
   578 
   579 
   579 	return
   580 	return
   580 		v->type == VEH_Train &&
   581 		v->type == VEH_TRAIN &&
   581 		myabs(v->z_pos - u->z_pos) <= 6 &&
   582 		myabs(v->z_pos - u->z_pos) <= 6 &&
   582 		myabs(v->x_pos - u->x_pos) <= 4 &&
   583 		myabs(v->x_pos - u->x_pos) <= 4 &&
   583 		myabs(v->y_pos - u->y_pos) <= 4 ?
   584 		myabs(v->y_pos - u->y_pos) <= 4 ?
   584 			v : NULL;
   585 			v : NULL;
   585 }
   586 }
   593 	ClearSlot(v);
   594 	ClearSlot(v);
   594 
   595 
   595 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   596 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   596 
   597 
   597 	pass = 1;
   598 	pass = 1;
   598 	if (v->cargo_type == CT_PASSENGERS) pass += v->cargo_count;
   599 	if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo_count;
   599 	v->cargo_count = 0;
   600 	v->cargo_count = 0;
   600 
   601 
   601 	SetDParam(0, pass);
   602 	SetDParam(0, pass);
   602 	AddNewsItem(
   603 	AddNewsItem(
   603 		(pass == 1) ?
   604 		(pass == 1) ?
   680 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
   681 	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
   681 
   682 
   682 	order = GetVehicleOrder(v, v->cur_order_index);
   683 	order = GetVehicleOrder(v, v->cur_order_index);
   683 
   684 
   684 	if (order == NULL) {
   685 	if (order == NULL) {
   685 		v->current_order.type = OT_NOTHING;
   686 		v->current_order.Free();
   686 		v->current_order.flags = 0;
       
   687 		v->dest_tile = 0;
   687 		v->dest_tile = 0;
   688 		ClearSlot(v);
   688 		ClearSlot(v);
   689 		return;
   689 		return;
   690 	}
   690 	}
   691 
   691 
   704 			if (order->dest == v->last_station_visited) {
   704 			if (order->dest == v->last_station_visited) {
   705 				v->last_station_visited = INVALID_STATION;
   705 				v->last_station_visited = INVALID_STATION;
   706 			}
   706 			}
   707 
   707 
   708 			rs = GetStation(order->dest)->GetPrimaryRoadStop(
   708 			rs = GetStation(order->dest)->GetPrimaryRoadStop(
   709 				v->cargo_type == CT_PASSENGERS ? RoadStop::BUS : RoadStop::TRUCK
   709 				IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK
   710 			);
   710 			);
   711 
   711 
   712 			if (rs != NULL) {
   712 			if (rs != NULL) {
   713 				TileIndex dest = rs->xy;
   713 				TileIndex dest = rs->xy;
   714 				uint mindist = DistanceManhattan(v->tile, rs->xy);
   714 				uint mindist = DistanceManhattan(v->tile, rs->xy);
   783 			s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN;
   783 			s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN;
   784 		SndPlayVehicleFx(s, v);
   784 		SndPlayVehicleFx(s, v);
   785 	}
   785 	}
   786 }
   786 }
   787 
   787 
   788 typedef struct RoadVehFindData {
   788 struct RoadVehFindData {
   789 	int x;
   789 	int x;
   790 	int y;
   790 	int y;
   791 	const Vehicle* veh;
   791 	const Vehicle* veh;
   792 	Direction dir;
   792 	Direction dir;
   793 } RoadVehFindData;
   793 };
   794 
   794 
   795 static void* EnumCheckRoadVehClose(Vehicle *v, void* data)
   795 static void* EnumCheckRoadVehClose(Vehicle *v, void* data)
   796 {
   796 {
   797 	static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
   797 	static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
   798 	static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
   798 	static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
   802 	short x_diff = v->x_pos - rvf->x;
   802 	short x_diff = v->x_pos - rvf->x;
   803 	short y_diff = v->y_pos - rvf->y;
   803 	short y_diff = v->y_pos - rvf->y;
   804 
   804 
   805 	return
   805 	return
   806 		rvf->veh != v &&
   806 		rvf->veh != v &&
   807 		v->type == VEH_Road &&
   807 		v->type == VEH_ROAD &&
   808 		!IsRoadVehInDepot(v) &&
   808 		!IsRoadVehInDepot(v) &&
   809 		myabs(v->z_pos - rvf->veh->z_pos) < 6 &&
   809 		myabs(v->z_pos - rvf->veh->z_pos) < 6 &&
   810 		v->direction == rvf->dir &&
   810 		v->direction == rvf->dir &&
   811 		(dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
   811 		(dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
   812 		(dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
   812 		(dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
   842 	return u;
   842 	return u;
   843 }
   843 }
   844 
   844 
   845 static void RoadVehArrivesAt(const Vehicle* v, Station* st)
   845 static void RoadVehArrivesAt(const Vehicle* v, Station* st)
   846 {
   846 {
   847 	if (v->cargo_type == CT_PASSENGERS) {
   847 	if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) {
   848 		/* Check if station was ever visited before */
   848 		/* Check if station was ever visited before */
   849 		if (!(st->had_vehicle_of_type & HVOT_BUS)) {
   849 		if (!(st->had_vehicle_of_type & HVOT_BUS)) {
   850 			uint32 flags;
   850 			uint32 flags;
   851 
   851 
   852 			st->had_vehicle_of_type |= HVOT_BUS;
   852 			st->had_vehicle_of_type |= HVOT_BUS;
   931 	if (new_dir == old_dir) return old_dir;
   931 	if (new_dir == old_dir) return old_dir;
   932 	delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
   932 	delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
   933 	return ChangeDir(old_dir, delta);
   933 	return ChangeDir(old_dir, delta);
   934 }
   934 }
   935 
   935 
   936 typedef struct OvertakeData {
   936 struct OvertakeData {
   937 	const Vehicle* u;
   937 	const Vehicle* u;
   938 	const Vehicle* v;
   938 	const Vehicle* v;
   939 	TileIndex tile;
   939 	TileIndex tile;
   940 	byte tilebits;
   940 	byte tilebits;
   941 } OvertakeData;
   941 };
   942 
   942 
   943 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
   943 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
   944 {
   944 {
   945 	const OvertakeData* od = (OvertakeData*)data;
   945 	const OvertakeData* od = (OvertakeData*)data;
   946 
   946 
   947 	return
   947 	return
   948 		v->tile == od->tile && v->type == VEH_Road && v != od->u && v != od->v ?
   948 		v->tile == od->tile && v->type == VEH_ROAD && v != od->u && v != od->v ?
   949 			v : NULL;
   949 			v : NULL;
   950 }
   950 }
   951 
   951 
   952 static bool FindRoadVehToOvertake(OvertakeData *od)
   952 static bool FindRoadVehToOvertake(OvertakeData *od)
   953 {
   953 {
  1028 
  1028 
  1029 	for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
  1029 	for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
  1030 	return i;
  1030 	return i;
  1031 }
  1031 }
  1032 
  1032 
  1033 typedef struct {
  1033 struct FindRoadToChooseData {
  1034 	TileIndex dest;
  1034 	TileIndex dest;
  1035 	uint maxtracklen;
  1035 	uint maxtracklen;
  1036 	uint mindist;
  1036 	uint mindist;
  1037 } FindRoadToChooseData;
  1037 };
  1038 
  1038 
  1039 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1039 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1040 {
  1040 {
  1041 	FindRoadToChooseData* frd = (FindRoadToChooseData*)data;
  1041 	FindRoadToChooseData* frd = (FindRoadToChooseData*)data;
  1042 	uint dist = DistanceManhattan(tile, frd->dest);
  1042 	uint dist = DistanceManhattan(tile, frd->dest);
  1090 		if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) {
  1090 		if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) {
  1091 			/* different station owner or wrong orientation */
  1091 			/* different station owner or wrong orientation */
  1092 			trackdirs = TRACKDIR_BIT_NONE;
  1092 			trackdirs = TRACKDIR_BIT_NONE;
  1093 		} else {
  1093 		} else {
  1094 			/* Our station */
  1094 			/* Our station */
  1095 			RoadStop::Type rstype = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
  1095 			RoadStop::Type rstype = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
  1096 
  1096 
  1097 			if (GetRoadStopType(tile) != rstype) {
  1097 			if (GetRoadStopType(tile) != rstype) {
  1098 				/* Wrong station type */
  1098 				/* Wrong station type */
  1099 				trackdirs = TRACKDIR_BIT_NONE;
  1099 				trackdirs = TRACKDIR_BIT_NONE;
  1100 			} else {
  1100 			} else {
  1254 	RVC_DEPOT_START_FRAME        = 6,
  1254 	RVC_DEPOT_START_FRAME        = 6,
  1255 	/* Stop frame for a vehicle in a drive-through stop */
  1255 	/* Stop frame for a vehicle in a drive-through stop */
  1256 	RVC_DRIVE_THROUGH_STOP_FRAME = 7
  1256 	RVC_DRIVE_THROUGH_STOP_FRAME = 7
  1257 };
  1257 };
  1258 
  1258 
  1259 typedef struct RoadDriveEntry {
  1259 struct RoadDriveEntry {
  1260 	byte x,y;
  1260 	byte x, y;
  1261 } RoadDriveEntry;
  1261 };
  1262 
  1262 
  1263 #include "table/roadveh.h"
  1263 #include "table/roadveh.h"
  1264 
  1264 
  1265 static const byte _road_veh_data_1[] = {
  1265 static const byte _road_veh_data_1[] = {
  1266 	20, 20, 16, 16, 0, 0, 0, 0,
  1266 	20, 20, 16, 16, 0, 0, 0, 0,
  1545 	 * a through route, do not stop) */
  1545 	 * a through route, do not stop) */
  1546 	if ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
  1546 	if ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
  1547 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
  1547 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
  1548 			(IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
  1548 			(IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
  1549 			v->current_order.dest == GetStationIndex(v->tile) &&
  1549 			v->current_order.dest == GetStationIndex(v->tile) &&
  1550 			GetRoadStopType(v->tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
  1550 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
  1551 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME)) {
  1551 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME)) {
  1552 
  1552 
  1553 		RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
  1553 		RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
  1554 		Station* st = GetStationByTile(v->tile);
  1554 		Station* st = GetStationByTile(v->tile);
  1555 
  1555 
  1561 			/* Vehicle has arrived at a bay in a road stop */
  1561 			/* Vehicle has arrived at a bay in a road stop */
  1562 			Order old_order;
  1562 			Order old_order;
  1563 
  1563 
  1564 			if (IsDriveThroughStopTile(v->tile)) {
  1564 			if (IsDriveThroughStopTile(v->tile)) {
  1565 				TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction));
  1565 				TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction));
  1566 				RoadStop::Type type = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
  1566 				RoadStop::Type type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
  1567 
  1567 
  1568 				assert(HASBIT(v->u.road.state, RVS_IS_STOPPING));
  1568 				assert(HASBIT(v->u.road.state, RVS_IS_STOPPING));
  1569 
  1569 
  1570 				/* Check if next inline bay is free */
  1570 				/* Check if next inline bay is free */
  1571 				if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) {
  1571 				if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) {
  1616 			if (rs->IsEntranceBusy()) {
  1616 			if (rs->IsEntranceBusy()) {
  1617 				/* Road stop entrance is busy, so wait as there is nowhere else to go */
  1617 				/* Road stop entrance is busy, so wait as there is nowhere else to go */
  1618 				v->cur_speed = 0;
  1618 				v->cur_speed = 0;
  1619 				return;
  1619 				return;
  1620 			}
  1620 			}
  1621 			v->current_order.type = OT_NOTHING;
  1621 			v->current_order.Free();
  1622 			v->current_order.flags = 0;
       
  1623 			ClearSlot(v);
  1622 			ClearSlot(v);
  1624 		}
  1623 		}
  1625 
  1624 
  1626 		if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
  1625 		if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
  1627 
  1626 
  1754 	if (v->vehstatus & VS_STOPPED) return;
  1753 	if (v->vehstatus & VS_STOPPED) return;
  1755 
  1754 
  1756 	/* update destination */
  1755 	/* update destination */
  1757 	if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) {
  1756 	if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) {
  1758 		Station* st = GetStation(v->current_order.dest);
  1757 		Station* st = GetStation(v->current_order.dest);
  1759 		RoadStop* rs = st->GetPrimaryRoadStop(v->cargo_type == CT_PASSENGERS ? RoadStop::BUS : RoadStop::TRUCK);
  1758 		RoadStop* rs = st->GetPrimaryRoadStop(IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK);
  1760 		RoadStop* best = NULL;
  1759 		RoadStop* best = NULL;
  1761 
  1760 
  1762 		if (rs != NULL) {
  1761 		if (rs != NULL) {
  1763 			/* We try to obtain a slot if:
  1762 			/* We try to obtain a slot if:
  1764 			 * 1) we're reasonably close to the primary road stop
  1763 			 * 1) we're reasonably close to the primary road stop
  1822 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1821 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1823 	InvalidateWindowClasses(WC_ROADVEH_LIST);
  1822 	InvalidateWindowClasses(WC_ROADVEH_LIST);
  1824 }
  1823 }
  1825 
  1824 
  1826 
  1825 
  1827 void RoadVehiclesYearlyLoop(void)
  1826 void RoadVehiclesYearlyLoop()
  1828 {
  1827 {
  1829 	Vehicle *v;
  1828 	Vehicle *v;
  1830 
  1829 
  1831 	FOR_ALL_VEHICLES(v) {
  1830 	FOR_ALL_VEHICLES(v) {
  1832 		if (v->type == VEH_Road) {
  1831 		if (v->type == VEH_ROAD) {
  1833 			v->profit_last_year = v->profit_this_year;
  1832 			v->profit_last_year = v->profit_this_year;
  1834 			v->profit_this_year = 0;
  1833 			v->profit_this_year = 0;
  1835 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1834 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1836 		}
  1835 		}
  1837 	}
  1836 	}
  1854 
  1853 
  1855 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1854 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1856 
  1855 
  1857 	v = GetVehicle(p1);
  1856 	v = GetVehicle(p1);
  1858 
  1857 
  1859 	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
  1858 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
  1860 	if (!IsRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
  1859 	if (!IsRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
  1861 
  1860 
  1862 	if (new_cid > NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
  1861 	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
  1863 
  1862 
  1864 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  1863 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  1865 
  1864 
  1866 	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
  1865 	if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) {
  1867 		/* Back up the cargo type */
  1866 		/* Back up the cargo type */