src/roadveh_cmd.cpp
branchNewGRF_ports
changeset 6720 35756db7e577
parent 6719 4cc327ad39d5
child 6725 23339968083f
equal deleted inserted replaced
6719:4cc327ad39d5 6720:35756db7e577
    12 #include "station_map.h"
    12 #include "station_map.h"
    13 #include "table/strings.h"
    13 #include "table/strings.h"
    14 #include "map.h"
    14 #include "map.h"
    15 #include "tile.h"
    15 #include "tile.h"
    16 #include "vehicle.h"
    16 #include "vehicle.h"
       
    17 #include "timetable.h"
    17 #include "engine.h"
    18 #include "engine.h"
    18 #include "command.h"
    19 #include "command.h"
    19 #include "station.h"
    20 #include "station.h"
    20 #include "news.h"
    21 #include "news.h"
    21 #include "pathfind.h"
    22 #include "pathfind.h"
    25 #include "depot.h"
    26 #include "depot.h"
    26 #include "bridge.h"
    27 #include "bridge.h"
    27 #include "tunnel_map.h"
    28 #include "tunnel_map.h"
    28 #include "bridge_map.h"
    29 #include "bridge_map.h"
    29 #include "vehicle_gui.h"
    30 #include "vehicle_gui.h"
       
    31 #include "articulated_vehicles.h"
    30 #include "newgrf_callbacks.h"
    32 #include "newgrf_callbacks.h"
    31 #include "newgrf_engine.h"
    33 #include "newgrf_engine.h"
    32 #include "newgrf_text.h"
    34 #include "newgrf_text.h"
    33 #include "newgrf_sound.h"
    35 #include "newgrf_sound.h"
    34 #include "yapf/yapf.h"
    36 #include "yapf/yapf.h"
    81 /** Converts the exit direction of a depot to trackdir the vehicle is going to drive to */
    83 /** Converts the exit direction of a depot to trackdir the vehicle is going to drive to */
    82 static const Trackdir _roadveh_depot_exit_trackdir[DIAGDIR_END] = {
    84 static const Trackdir _roadveh_depot_exit_trackdir[DIAGDIR_END] = {
    83 	TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW
    85 	TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW
    84 };
    86 };
    85 
    87 
    86 int GetRoadVehImage(const Vehicle* v, Direction direction)
    88 int RoadVehicle::GetImage(Direction direction) const
    87 {
    89 {
    88 	int img = v->spritenum;
    90 	int img = this->spritenum;
    89 	int image;
    91 	int image;
    90 
    92 
    91 	if (is_custom_sprite(img)) {
    93 	if (is_custom_sprite(img)) {
    92 		image = GetCustomVehicleSprite(v, direction);
    94 		image = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
    93 		if (image != 0) return image;
    95 		if (image != 0) return image;
    94 		img = orig_road_vehicle_info[v->engine_type - ROAD_ENGINES_INDEX].image_index;
    96 		img = orig_road_vehicle_info[this->engine_type - ROAD_ENGINES_INDEX].image_index;
    95 	}
    97 	}
    96 
    98 
    97 	image = direction + _roadveh_images[img];
    99 	image = direction + _roadveh_images[img];
    98 	if (v->cargo_count >= v->cargo_cap / 2) image += _roadveh_full_adder[img];
   100 	if (this->cargo.Count() >= this->cargo_cap / 2U) image += _roadveh_full_adder[img];
    99 	return image;
   101 	return image;
   100 }
   102 }
   101 
   103 
   102 void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal)
   104 void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal)
   103 {
   105 {
   113 		spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
   115 		spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
   114 	}
   116 	}
   115 	DrawSprite(6 + _roadveh_images[spritenum], pal, x, y);
   117 	DrawSprite(6 + _roadveh_images[spritenum], pal, x, y);
   116 }
   118 }
   117 
   119 
   118 static int32 EstimateRoadVehCost(EngineID engine_type)
   120 static CommandCost EstimateRoadVehCost(EngineID engine_type)
   119 {
   121 {
   120 	return ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5;
   122 	return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
       
   123 }
       
   124 
       
   125 byte GetRoadVehLength(const Vehicle *v)
       
   126 {
       
   127 	byte length = 8;
       
   128 
       
   129 	uint16 veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, v->engine_type, v);
       
   130 	if (veh_len != CALLBACK_FAILED) {
       
   131 		length -= clamp(veh_len, 0, 7);
       
   132 	}
       
   133 
       
   134 	return length;
       
   135 }
       
   136 
       
   137 void RoadVehUpdateCache(Vehicle *v)
       
   138 {
       
   139 	assert(v->type == VEH_ROAD);
       
   140 	assert(IsRoadVehFront(v));
       
   141 
       
   142 	for (Vehicle *u = v; u != NULL; u = u->next) {
       
   143 		/* Update the v->first cache. */
       
   144 		if (u->first == NULL) u->first = v;
       
   145 
       
   146 		/* Update the 'first engine' */
       
   147 		u->u.road.first_engine = (v == u) ? INVALID_ENGINE : v->engine_type;
       
   148 
       
   149 		/* Update the length of the vehicle. */
       
   150 		u->u.road.cached_veh_length = GetRoadVehLength(u);
       
   151 	}
   121 }
   152 }
   122 
   153 
   123 /** Build a road vehicle.
   154 /** Build a road vehicle.
   124  * @param tile tile of depot where road vehicle is built
   155  * @param tile tile of depot where road vehicle is built
   125  * @param flags operation to perform
   156  * @param flags operation to perform
   126  * @param p1 bus/truck type being built (engine)
   157  * @param p1 bus/truck type being built (engine)
   127  * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number
   158  * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number
   128  */
   159  */
   129 int32 CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   160 CommandCost CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   130 {
   161 {
   131 	int32 cost;
   162 	CommandCost cost;
   132 	Vehicle *v;
   163 	Vehicle *v;
   133 	UnitID unit_num;
   164 	UnitID unit_num;
   134 	Engine *e;
   165 	Engine *e;
   135 
   166 
   136 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
   167 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
   145 	if (!IsTileDepotType(tile, TRANSPORT_ROAD)) return CMD_ERROR;
   176 	if (!IsTileDepotType(tile, TRANSPORT_ROAD)) return CMD_ERROR;
   146 	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   177 	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
   147 
   178 
   148 	if (HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM) != HASBIT(EngInfo(p1)->misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_DEPOT_WRONG_DEPOT_TYPE);
   179 	if (HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM) != HASBIT(EngInfo(p1)->misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_DEPOT_WRONG_DEPOT_TYPE);
   149 
   180 
   150 	v = AllocateVehicle();
   181 	uint num_vehicles = 1 + CountArticulatedParts(p1);
   151 	if (v == NULL) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   182 
       
   183 	/* Allow for the front and up to 10 articulated parts. */
       
   184 	Vehicle *vl[11];
       
   185 	memset(&vl, 0, sizeof(vl));
       
   186 
       
   187 	if (!AllocateVehicles(vl, num_vehicles)) {
       
   188 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
       
   189 	}
       
   190 
       
   191 	v = vl[0];
   152 
   192 
   153 	/* find the first free roadveh id */
   193 	/* find the first free roadveh id */
   154 	unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD);
   194 	unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD);
   155 	if (unit_num > _patches.max_roadveh)
   195 	if (unit_num > _patches.max_roadveh)
   156 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   196 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   160 		int y;
   200 		int y;
   161 
   201 
   162 		const RoadVehicleInfo *rvi = RoadVehInfo(p1);
   202 		const RoadVehicleInfo *rvi = RoadVehInfo(p1);
   163 
   203 
   164 		v->unitnumber = unit_num;
   204 		v->unitnumber = unit_num;
   165 		v->direction = INVALID_DIR;
   205 		v->direction = DiagDirToDir(GetRoadDepotDirection(tile));
   166 		v->owner = _current_player;
   206 		v->owner = _current_player;
   167 
   207 
   168 		v->tile = tile;
   208 		v->tile = tile;
   169 		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
   209 		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
   170 		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
   210 		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
   178 		v->spritenum = rvi->image_index;
   218 		v->spritenum = rvi->image_index;
   179 		v->cargo_type = rvi->cargo_type;
   219 		v->cargo_type = rvi->cargo_type;
   180 		v->cargo_subtype = 0;
   220 		v->cargo_subtype = 0;
   181 		v->cargo_cap = rvi->capacity;
   221 		v->cargo_cap = rvi->capacity;
   182 //		v->cargo_count = 0;
   222 //		v->cargo_count = 0;
   183 		v->value = cost;
   223 		v->value = cost.GetCost();
   184 //		v->day_counter = 0;
   224 //		v->day_counter = 0;
   185 //		v->next_order_param = v->next_order = 0;
   225 //		v->next_order_param = v->next_order = 0;
   186 //		v->load_unload_time_rem = 0;
   226 //		v->load_unload_time_rem = 0;
   187 //		v->progress = 0;
   227 //		v->progress = 0;
   188 
   228 
   190 //	v->u.road.overtaking = 0;
   230 //	v->u.road.overtaking = 0;
   191 
   231 
   192 		v->last_station_visited = INVALID_STATION;
   232 		v->last_station_visited = INVALID_STATION;
   193 		v->max_speed = rvi->max_speed;
   233 		v->max_speed = rvi->max_speed;
   194 		v->engine_type = (byte)p1;
   234 		v->engine_type = (byte)p1;
   195 
       
   196 		v->u.road.roadtype = HASBIT(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
       
   197 		v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
       
   198 
   235 
   199 		e = GetEngine(p1);
   236 		e = GetEngine(p1);
   200 		v->reliability = e->reliability;
   237 		v->reliability = e->reliability;
   201 		v->reliability_spd_dec = e->reliability_spd_dec;
   238 		v->reliability_spd_dec = e->reliability_spd_dec;
   202 		v->max_age = e->lifelength * 366;
   239 		v->max_age = e->lifelength * 366;
   210 		v->build_year = _cur_year;
   247 		v->build_year = _cur_year;
   211 
   248 
   212 		v = new (v) RoadVehicle();
   249 		v = new (v) RoadVehicle();
   213 		v->cur_image = 0xC15;
   250 		v->cur_image = 0xC15;
   214 		v->random_bits = VehicleRandomBits();
   251 		v->random_bits = VehicleRandomBits();
       
   252 		SetRoadVehFront(v);
       
   253 
       
   254 		v->u.road.roadtype = HASBIT(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
       
   255 		v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
       
   256 		v->u.road.cached_veh_length = GetRoadVehLength(v);
   215 
   257 
   216 		v->vehicle_flags = 0;
   258 		v->vehicle_flags = 0;
   217 		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   259 		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
   218 
   260 
       
   261 		v->first = NULL;
   219 		v->cargo_cap = GetVehicleProperty(v, 0x0F, rvi->capacity);
   262 		v->cargo_cap = GetVehicleProperty(v, 0x0F, rvi->capacity);
       
   263 
       
   264 		AddArticulatedParts(vl, VEH_ROAD);
   220 
   265 
   221 		VehiclePositionChanged(v);
   266 		VehiclePositionChanged(v);
   222 
   267 
   223 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   268 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   224 		RebuildVehicleLists();
   269 		RebuildVehicleLists();
   225 		InvalidateWindow(WC_COMPANY, v->owner);
   270 		InvalidateWindow(WC_COMPANY, v->owner);
   226 		if (IsLocalPlayer())
   271 		if (IsLocalPlayer())
   227 			InvalidateAutoreplaceWindow(VEH_ROAD); // updates the replace Road window
   272 			InvalidateAutoreplaceWindow(VEH_ROAD, v->group_id); // updates the replace Road window
   228 
   273 
   229 		GetPlayer(_current_player)->num_engines[p1]++;
   274 		GetPlayer(_current_player)->num_engines[p1]++;
   230 	}
   275 	}
   231 
   276 
   232 	return cost;
   277 	return CommandCost(cost);
   233 }
   278 }
   234 
   279 
   235 /** Start/Stop a road vehicle.
   280 /** Start/Stop a road vehicle.
   236  * @param tile unused
   281  * @param tile unused
   237  * @param flags operation to perform
   282  * @param flags operation to perform
   238  * @param p1 road vehicle ID to start/stop
   283  * @param p1 road vehicle ID to start/stop
   239  * @param p2 unused
   284  * @param p2 unused
   240  */
   285  */
   241 int32 CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   286 CommandCost CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   242 {
   287 {
   243 	Vehicle *v;
   288 	Vehicle *v;
   244 	uint16 callback;
   289 	uint16 callback;
   245 
   290 
   246 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   291 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   266 		v->cur_speed = 0;
   311 		v->cur_speed = 0;
   267 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   312 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   268 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   313 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   269 	}
   314 	}
   270 
   315 
   271 	return 0;
   316 	return CommandCost();
   272 }
   317 }
   273 
   318 
   274 void ClearSlot(Vehicle *v)
   319 void ClearSlot(Vehicle *v)
   275 {
   320 {
   276 	RoadStop *rs = v->u.road.slot;
   321 	RoadStop *rs = v->u.road.slot;
   281 
   326 
   282 	assert(rs->num_vehicles != 0);
   327 	assert(rs->num_vehicles != 0);
   283 	rs->num_vehicles--;
   328 	rs->num_vehicles--;
   284 
   329 
   285 	DEBUG(ms, 3, "Clearing slot at 0x%X", rs->xy);
   330 	DEBUG(ms, 3, "Clearing slot at 0x%X", rs->xy);
       
   331 }
       
   332 
       
   333 static bool CheckRoadVehInDepotStopped(const Vehicle *v)
       
   334 {
       
   335 	TileIndex tile = v->tile;
       
   336 
       
   337 	if (!IsTileDepotType(tile, TRANSPORT_ROAD) || !(v->vehstatus & VS_STOPPED)) return false;
       
   338 
       
   339 	for (; v != NULL; v = v->next) {
       
   340 		if (v->u.road.state != RVSB_IN_DEPOT || v->tile != tile) return false;
       
   341 	}
       
   342 	return true;
   286 }
   343 }
   287 
   344 
   288 /** Sell a road vehicle.
   345 /** Sell a road vehicle.
   289  * @param tile unused
   346  * @param tile unused
   290  * @param flags operation to perform
   347  * @param flags operation to perform
   291  * @param p1 vehicle ID to be sold
   348  * @param p1 vehicle ID to be sold
   292  * @param p2 unused
   349  * @param p2 unused
   293  */
   350  */
   294 int32 CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   351 CommandCost CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   295 {
   352 {
   296 	Vehicle *v;
   353 	Vehicle *v;
   297 
   354 
   298 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   355 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   299 
   356 
   301 
   358 
   302 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   359 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   303 
   360 
   304 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   361 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
   305 
   362 
   306 	if (!IsRoadVehInDepotStopped(v)) {
   363 	if (!CheckRoadVehInDepotStopped(v)) {
   307 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
   364 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
   308 	}
   365 	}
   309 
   366 
   310 	if (flags & DC_EXEC) {
   367 	if (flags & DC_EXEC) {
   311 		// Invalidate depot
   368 		// Invalidate depot
   315 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   372 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   316 		DeleteDepotHighlightOfVehicle(v);
   373 		DeleteDepotHighlightOfVehicle(v);
   317 		DeleteVehicle(v);
   374 		DeleteVehicle(v);
   318 	}
   375 	}
   319 
   376 
   320 	return -(int32)v->value;
   377 	return CommandCost(-v->value);
   321 }
   378 }
   322 
   379 
   323 struct RoadFindDepotData {
   380 struct RoadFindDepotData {
   324 	uint best_length;
   381 	uint best_length;
   325 	TileIndex tile;
   382 	TileIndex tile;
   357 	} else if (_patches.new_pathfinding_all) {
   414 	} else if (_patches.new_pathfinding_all) {
   358 		NPFFoundTargetData ftd;
   415 		NPFFoundTargetData ftd;
   359 		/* See where we are now */
   416 		/* See where we are now */
   360 		Trackdir trackdir = GetVehicleTrackdir(v);
   417 		Trackdir trackdir = GetVehicleTrackdir(v);
   361 
   418 
   362 		ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE);
   419 		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, v->tile, ReverseTrackdir(trackdir), TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE, 0);
   363 		if (ftd.best_bird_dist == 0) {
   420 		if (ftd.best_bird_dist == 0) {
   364 			return GetDepotByTile(ftd.node.tile); /* Target found */
   421 			return GetDepotByTile(ftd.node.tile); /* Target found */
   365 		} else {
   422 		} else {
   366 			return NULL; /* Target not found */
   423 			return NULL; /* Target not found */
   367 		}
   424 		}
   389  * @param p1 vehicle ID to send to the depot
   446  * @param p1 vehicle ID to send to the depot
   390  * @param p2 various bitmasked elements
   447  * @param p2 various bitmasked elements
   391  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
   448  * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
   392  * - p2 bit 8-10 - VLW flag (for mass goto depot)
   449  * - p2 bit 8-10 - VLW flag (for mass goto depot)
   393  */
   450  */
   394 int32 CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   451 CommandCost CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   395 {
   452 {
   396 	Vehicle *v;
   453 	Vehicle *v;
   397 	const Depot *dep;
   454 	const Depot *dep;
   398 
   455 
   399 	if (p2 & DEPOT_MASS_SEND) {
   456 	if (p2 & DEPOT_MASS_SEND) {
   420 			 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
   477 			 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
   421 			if (flags & DC_EXEC) {
   478 			if (flags & DC_EXEC) {
   422 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
   479 				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
   423 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   480 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   424 			}
   481 			}
   425 			return 0;
   482 			return CommandCost();
   426 		}
   483 		}
   427 
   484 
   428 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
   485 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
   429 		if (flags & DC_EXEC) {
   486 		if (flags & DC_EXEC) {
   430 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
   487 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
   434 
   491 
   435 			v->current_order.type = OT_DUMMY;
   492 			v->current_order.type = OT_DUMMY;
   436 			v->current_order.flags = 0;
   493 			v->current_order.flags = 0;
   437 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   494 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   438 		}
   495 		}
   439 		return 0;
   496 		return CommandCost();
   440 	}
   497 	}
   441 
   498 
   442 	dep = FindClosestRoadDepot(v);
   499 	dep = FindClosestRoadDepot(v);
   443 	if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
   500 	if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
   444 
   501 
   453 		v->current_order.dest = dep->index;
   510 		v->current_order.dest = dep->index;
   454 		v->dest_tile = dep->xy;
   511 		v->dest_tile = dep->xy;
   455 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   512 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   456 	}
   513 	}
   457 
   514 
   458 	return 0;
   515 	return CommandCost();
   459 }
   516 }
   460 
   517 
   461 /** Turn a roadvehicle around.
   518 /** Turn a roadvehicle around.
   462  * @param tile unused
   519  * @param tile unused
   463  * @param flags operation to perform
   520  * @param flags operation to perform
   464  * @param p1 vehicle ID to turn
   521  * @param p1 vehicle ID to turn
   465  * @param p2 unused
   522  * @param p2 unused
   466  */
   523  */
   467 int32 CmdTurnRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   524 CommandCost CmdTurnRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   468 {
   525 {
   469 	Vehicle *v;
   526 	Vehicle *v;
   470 
   527 
   471 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   528 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
   472 
   529 
   490 	if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
   547 	if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
   491 	if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR;
   548 	if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR;
   492 
   549 
   493 	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
   550 	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
   494 
   551 
   495 	return 0;
   552 	return CommandCost();
   496 }
   553 }
   497 
   554 
   498 
   555 
   499 void RoadVehicle::MarkDirty()
   556 void RoadVehicle::MarkDirty()
   500 {
   557 {
   501 	this->cur_image = GetRoadVehImage(this, this->direction);
   558 	this->cur_image = this->GetImage(this->direction);
   502 	MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1);
   559 	MarkAllViewportsDirty(this->left_coord, this->top_coord, this->right_coord + 1, this->bottom_coord + 1);
   503 }
   560 }
   504 
   561 
   505 void RoadVehicle::UpdateDeltaXY(Direction direction)
   562 void RoadVehicle::UpdateDeltaXY(Direction direction)
   506 {
   563 {
   534 
   591 
   535 	/* Free the parking bay */
   592 	/* Free the parking bay */
   536 	rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY));
   593 	rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY));
   537 }
   594 }
   538 
   595 
   539 static void RoadVehDelete(Vehicle *v)
   596 static void DeleteLastRoadVeh(Vehicle *v)
   540 {
   597 {
       
   598 	Vehicle *u = v;
       
   599 	for (; v->next != NULL; v = v->next) u = v;
       
   600 	u->next = NULL;
       
   601 
   541 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   602 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   542 
   603 
   543 	RebuildVehicleLists();
   604 	RebuildVehicleLists();
   544 	InvalidateWindow(WC_COMPANY, v->owner);
   605 	InvalidateWindow(WC_COMPANY, v->owner);
   545 
   606 
   572 {
   633 {
   573 	static const DirDiff delta[] = {
   634 	static const DirDiff delta[] = {
   574 		DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
   635 		DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
   575 	};
   636 	};
   576 
   637 
   577 	uint32 r = Random();
   638 	do {
   578 
   639 		uint32 r = Random();
   579 	v->direction = ChangeDir(v->direction, delta[r & 3]);
   640 
   580 	BeginVehicleMove(v);
   641 		v->direction = ChangeDir(v->direction, delta[r & 3]);
   581 	v->UpdateDeltaXY(v->direction);
   642 		BeginVehicleMove(v);
   582 	v->cur_image = GetRoadVehImage(v, v->direction);
   643 		v->UpdateDeltaXY(v->direction);
   583 	SetRoadVehPosition(v, v->x_pos, v->y_pos);
   644 		v->cur_image = v->GetImage(v->direction);
       
   645 		SetRoadVehPosition(v, v->x_pos, v->y_pos);
       
   646 	} while ((v = v->next) != NULL);
   584 }
   647 }
   585 
   648 
   586 static void RoadVehIsCrashed(Vehicle *v)
   649 static void RoadVehIsCrashed(Vehicle *v)
   587 {
   650 {
   588 	v->u.road.crashed_ctr++;
   651 	v->u.road.crashed_ctr++;
   589 	if (v->u.road.crashed_ctr == 2) {
   652 	if (v->u.road.crashed_ctr == 2) {
   590 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
   653 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
   591 	} else if (v->u.road.crashed_ctr <= 45) {
   654 	} else if (v->u.road.crashed_ctr <= 45) {
   592 		if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v);
   655 		if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v);
   593 	} else if (v->u.road.crashed_ctr >= 2220) {
   656 	} else if (v->u.road.crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) {
   594 		RoadVehDelete(v);
   657 		DeleteLastRoadVeh(v);
   595 	}
   658 	}
   596 }
   659 }
   597 
   660 
   598 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
   661 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data)
   599 {
   662 {
   607 			v : NULL;
   670 			v : NULL;
   608 }
   671 }
   609 
   672 
   610 static void RoadVehCrash(Vehicle *v)
   673 static void RoadVehCrash(Vehicle *v)
   611 {
   674 {
   612 	uint16 pass;
   675 	uint16 pass = 1;
   613 
   676 
   614 	v->u.road.crashed_ctr++;
   677 	v->u.road.crashed_ctr++;
   615 	v->vehstatus |= VS_CRASHED;
   678 
       
   679 	for (Vehicle *u = v; u != NULL; u = u->next) {
       
   680 		if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count();
       
   681 
       
   682 		u->vehstatus |= VS_CRASHED;
       
   683 
       
   684 		MarkAllViewportsDirty(u->left_coord, u->top_coord, u->right_coord + 1, u->bottom_coord + 1);
       
   685 	}
       
   686 
   616 	ClearSlot(v);
   687 	ClearSlot(v);
   617 
   688 
   618 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   689 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   619 
       
   620 	pass = 1;
       
   621 	if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo_count;
       
   622 	v->cargo_count = 0;
       
   623 
   690 
   624 	SetDParam(0, pass);
   691 	SetDParam(0, pass);
   625 	AddNewsItem(
   692 	AddNewsItem(
   626 		(pass == 1) ?
   693 		(pass == 1) ?
   627 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   694 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   634 	SndPlayVehicleFx(SND_12_EXPLOSION, v);
   701 	SndPlayVehicleFx(SND_12_EXPLOSION, v);
   635 }
   702 }
   636 
   703 
   637 static void RoadVehCheckTrainCrash(Vehicle *v)
   704 static void RoadVehCheckTrainCrash(Vehicle *v)
   638 {
   705 {
   639 	TileIndex tile;
   706 	for (Vehicle *u = v; u != NULL; u = u->next) {
   640 
   707 		if (u->u.road.state == RVSB_WORMHOLE) continue;
   641 	if (v->u.road.state == RVSB_WORMHOLE) return;
   708 
   642 
   709 		TileIndex tile = u->tile;
   643 	tile = v->tile;
   710 
   644 
   711 		if (!IsLevelCrossingTile(tile)) continue;
   645 	if (!IsLevelCrossingTile(tile)) return;
   712 
   646 
   713 		if (VehicleFromPosXY(v->x_pos, v->y_pos, u, EnumCheckRoadVehCrashTrain) != NULL) {
   647 	if (VehicleFromPos(tile, v, EnumCheckRoadVehCrashTrain) != NULL)
   714 			RoadVehCrash(v);
   648 		RoadVehCrash(v);
   715 			return;
       
   716 		}
       
   717 	}
   649 }
   718 }
   650 
   719 
   651 static void HandleBrokenRoadVeh(Vehicle *v)
   720 static void HandleBrokenRoadVeh(Vehicle *v)
   652 {
   721 {
   653 	if (v->breakdown_ctr != 1) {
   722 	if (v->breakdown_ctr != 1) {
   687 		case OT_GOTO_DEPOT:
   756 		case OT_GOTO_DEPOT:
   688 			/* Let a depot order in the orderlist interrupt. */
   757 			/* Let a depot order in the orderlist interrupt. */
   689 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
   758 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
   690 			if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
   759 			if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
   691 					!VehicleNeedsService(v)) {
   760 					!VehicleNeedsService(v)) {
       
   761 				UpdateVehicleTimetable(v, true);
   692 				v->cur_order_index++;
   762 				v->cur_order_index++;
   693 			}
   763 			}
   694 			break;
   764 			break;
   695 
   765 
   696 		case OT_LOADING:
   766 		case OT_LOADING:
   796 
   866 
   797 	short x_diff = v->x_pos - rvf->x;
   867 	short x_diff = v->x_pos - rvf->x;
   798 	short y_diff = v->y_pos - rvf->y;
   868 	short y_diff = v->y_pos - rvf->y;
   799 
   869 
   800 	return
   870 	return
   801 		rvf->veh != v &&
       
   802 		v->type == VEH_ROAD &&
   871 		v->type == VEH_ROAD &&
   803 		!IsRoadVehInDepot(v) &&
   872 		!IsRoadVehInDepot(v) &&
   804 		myabs(v->z_pos - rvf->veh->z_pos) < 6 &&
   873 		myabs(v->z_pos - rvf->veh->z_pos) < 6 &&
   805 		v->direction == rvf->dir &&
   874 		v->direction == rvf->dir &&
       
   875 		GetFirstVehicleInChain(rvf->veh) != GetFirstVehicleInChain(v) &&
   806 		(dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
   876 		(dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
   807 		(dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
   877 		(dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
   808 		(dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
   878 		(dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
   809 		(dist_y[v->direction] <= 0 || (y_diff < dist_y[v->direction] && y_diff >= 0)) ?
   879 		(dist_y[v->direction] <= 0 || (y_diff < dist_y[v->direction] && y_diff >= 0)) ?
   810 			v : NULL;
   880 			v : NULL;
   819 
   889 
   820 	rvf.x = x;
   890 	rvf.x = x;
   821 	rvf.y = y;
   891 	rvf.y = y;
   822 	rvf.dir = dir;
   892 	rvf.dir = dir;
   823 	rvf.veh = v;
   893 	rvf.veh = v;
   824 	u = (Vehicle*)VehicleFromPos(TileVirtXY(x, y), &rvf, EnumCheckRoadVehClose);
   894 	u = (Vehicle*)VehicleFromPosXY(x, y, &rvf, EnumCheckRoadVehClose);
   825 
   895 
   826 	/* This code protects a roadvehicle from being blocked for ever
   896 	/* This code protects a roadvehicle from being blocked for ever
   827 	 * If more than 1480 / 74 days a road vehicle is blocked, it will
   897 	 * If more than 1480 / 74 days a road vehicle is blocked, it will
   828 	 * drive just through it. The ultimate backup-code of TTD.
   898 	 * drive just through it. The ultimate backup-code of TTD.
   829 	 * It can be disabled. */
   899 	 * It can be disabled. */
   970 	}
  1040 	}
   971 
  1041 
   972 	/* Trams can't overtake other trams */
  1042 	/* Trams can't overtake other trams */
   973 	if (v->u.road.roadtype == ROADTYPE_TRAM) return;
  1043 	if (v->u.road.roadtype == ROADTYPE_TRAM) return;
   974 
  1044 
       
  1045 	/* For now, articulated road vehicles can't overtake anything. */
       
  1046 	if (RoadVehHasArticPart(v)) return;
       
  1047 
   975 	if (v->direction != u->direction || !(v->direction & 1)) return;
  1048 	if (v->direction != u->direction || !(v->direction & 1)) return;
   976 
  1049 
   977 	/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
  1050 	/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
   978 	if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return;
  1051 	if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return;
   979 
  1052 
  1012 	}
  1085 	}
  1013 }
  1086 }
  1014 
  1087 
  1015 static int PickRandomBit(uint bits)
  1088 static int PickRandomBit(uint bits)
  1016 {
  1089 {
  1017 	uint num = 0;
       
  1018 	uint b = bits;
       
  1019 	uint i;
  1090 	uint i;
  1020 
  1091 	uint num = RandomRange(CountBitsSet(bits));
  1021 	do {
       
  1022 		if (b & 1) num++;
       
  1023 	} while (b >>= 1);
       
  1024 
       
  1025 	num = RandomRange(num);
       
  1026 
  1092 
  1027 	for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
  1093 	for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
  1028 	return i;
  1094 	return i;
  1029 }
  1095 }
  1030 
  1096 
  1265 	19, 19, 15, 15, 0, 0, 0, 0,
  1331 	19, 19, 15, 15, 0, 0, 0, 0,
  1266 	16, 16, 12, 12, 0, 0, 0, 0,
  1332 	16, 16, 12, 12, 0, 0, 0, 0,
  1267 	15, 15, 11, 11
  1333 	15, 15, 11, 11
  1268 };
  1334 };
  1269 
  1335 
  1270 static void RoadVehController(Vehicle *v)
  1336 static bool RoadVehLeaveDepot(Vehicle *v, bool first)
       
  1337 {
       
  1338 	/* Don't leave if not all the wagons are in the depot. */
       
  1339 	for (const Vehicle *u = v; u != NULL; u = u->next) {
       
  1340 		if (u->u.road.state != RVSB_IN_DEPOT || u->tile != v->tile) return false;
       
  1341 	}
       
  1342 
       
  1343 	DiagDirection dir = GetRoadDepotDirection(v->tile);
       
  1344 	v->direction = DiagDirToDir(dir);
       
  1345 
       
  1346 	Trackdir tdir = _roadveh_depot_exit_trackdir[dir];
       
  1347 	const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + tdir];
       
  1348 
       
  1349 	int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
       
  1350 	int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
       
  1351 
       
  1352 	if (first) {
       
  1353 		if (RoadVehFindCloseTo(v, x, y, v->direction) != NULL) return true;
       
  1354 
       
  1355 		VehicleServiceInDepot(v);
       
  1356 
       
  1357 		StartRoadVehSound(v);
       
  1358 
       
  1359 		/* Vehicle is about to leave a depot */
       
  1360 		v->cur_speed = 0;
       
  1361 	}
       
  1362 
       
  1363 	BeginVehicleMove(v);
       
  1364 
       
  1365 	v->vehstatus &= ~VS_HIDDEN;
       
  1366 	v->u.road.state = tdir;
       
  1367 	v->u.road.frame = RVC_DEPOT_START_FRAME;
       
  1368 
       
  1369 	v->cur_image = v->GetImage(v->direction);
       
  1370 	v->UpdateDeltaXY(v->direction);
       
  1371 	SetRoadVehPosition(v,x,y);
       
  1372 
       
  1373 	InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
  1374 
       
  1375 	return true;
       
  1376 }
       
  1377 
       
  1378 static Trackdir FollowPreviousRoadVehicle(const Vehicle *v, const Vehicle *prev, TileIndex tile, DiagDirection entry_dir)
       
  1379 {
       
  1380 	if (prev->tile == v->tile) {
       
  1381 		/* If the previous vehicle is on the same tile as this vehicle is
       
  1382 		 * then it must have reversed. */
       
  1383 		return _road_reverse_table[entry_dir];
       
  1384 	}
       
  1385 
       
  1386 	byte prev_state = prev->u.road.state;
       
  1387 	Trackdir dir;
       
  1388 
       
  1389 	if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
       
  1390 		DiagDirection diag_dir = INVALID_DIAGDIR;
       
  1391 
       
  1392 		if (IsTunnelTile(tile)) {
       
  1393 			diag_dir = GetTunnelDirection(tile);
       
  1394 		} else if (IsBridgeTile(tile)) {
       
  1395 			diag_dir = GetBridgeRampDirection(tile);
       
  1396 		} else if (IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
       
  1397 			diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
       
  1398 		}
       
  1399 
       
  1400 		if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR;
       
  1401 		dir = DiagdirToDiagTrackdir(diag_dir);
       
  1402 	} else if (HASBIT(prev_state, RVS_IN_DT_ROAD_STOP)) {
       
  1403 		dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
       
  1404 	} else if (prev_state < TRACKDIR_END) {
       
  1405 		dir = (Trackdir)prev_state;
       
  1406 	} else {
       
  1407 		return INVALID_TRACKDIR;
       
  1408 	}
       
  1409 
       
  1410 	/* Do some sanity checking. */
       
  1411 	static const RoadBits required_roadbits[] = {
       
  1412 		ROAD_X,            ROAD_Y,            ROAD_NW | ROAD_NE, ROAD_SW | ROAD_SE,
       
  1413 		ROAD_NW | ROAD_SW, ROAD_NE | ROAD_SE, ROAD_X,            ROAD_Y
       
  1414 	};
       
  1415 	RoadBits required = required_roadbits[dir & 0x07];
       
  1416 
       
  1417 	if ((required & GetAnyRoadBits(tile, v->u.road.roadtype)) == ROAD_NONE) {
       
  1418 		dir = INVALID_TRACKDIR;
       
  1419 	}
       
  1420 
       
  1421 	return dir;
       
  1422 }
       
  1423 
       
  1424 static bool IndividualRoadVehicleController(Vehicle *v, const Vehicle *prev)
  1271 {
  1425 {
  1272 	Direction new_dir;
  1426 	Direction new_dir;
  1273 	Direction old_dir;
  1427 	Direction old_dir;
  1274 	RoadDriveEntry rd;
  1428 	RoadDriveEntry rd;
  1275 	int x,y;
  1429 	int x,y;
  1276 	uint32 r;
  1430 	uint32 r;
  1277 
       
  1278 	/* decrease counters */
       
  1279 	v->tick_counter++;
       
  1280 	if (v->u.road.reverse_ctr != 0) v->u.road.reverse_ctr--;
       
  1281 
       
  1282 	/* handle crashed */
       
  1283 	if (v->u.road.crashed_ctr != 0) {
       
  1284 		RoadVehIsCrashed(v);
       
  1285 		return;
       
  1286 	}
       
  1287 
       
  1288 	RoadVehCheckTrainCrash(v);
       
  1289 
       
  1290 	/* road vehicle has broken down? */
       
  1291 	if (v->breakdown_ctr != 0) {
       
  1292 		if (v->breakdown_ctr <= 2) {
       
  1293 			HandleBrokenRoadVeh(v);
       
  1294 			return;
       
  1295 		}
       
  1296 		v->breakdown_ctr--;
       
  1297 	}
       
  1298 
       
  1299 	if (v->vehstatus & VS_STOPPED) return;
       
  1300 
       
  1301 	ProcessRoadVehOrder(v);
       
  1302 	v->HandleLoading();
       
  1303 
       
  1304 	if (v->current_order.type == OT_LOADING) return;
       
  1305 
       
  1306 	if (IsRoadVehInDepot(v)) {
       
  1307 		/* Vehicle is about to leave a depot */
       
  1308 		DiagDirection dir;
       
  1309 		const RoadDriveEntry* rdp;
       
  1310 		Trackdir tdir;
       
  1311 
       
  1312 		v->cur_speed = 0;
       
  1313 
       
  1314 		dir = GetRoadDepotDirection(v->tile);
       
  1315 		v->direction = DiagDirToDir(dir);
       
  1316 
       
  1317 		tdir = _roadveh_depot_exit_trackdir[dir];
       
  1318 		rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + tdir];
       
  1319 
       
  1320 		x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
       
  1321 		y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
       
  1322 
       
  1323 		if (RoadVehFindCloseTo(v, x, y, v->direction) != NULL) return;
       
  1324 
       
  1325 		VehicleServiceInDepot(v);
       
  1326 
       
  1327 		StartRoadVehSound(v);
       
  1328 
       
  1329 		BeginVehicleMove(v);
       
  1330 
       
  1331 		v->vehstatus &= ~VS_HIDDEN;
       
  1332 		v->u.road.state = tdir;
       
  1333 		v->u.road.frame = RVC_DEPOT_START_FRAME;
       
  1334 
       
  1335 		v->cur_image = GetRoadVehImage(v, v->direction);
       
  1336 		v->UpdateDeltaXY(v->direction);
       
  1337 		SetRoadVehPosition(v,x,y);
       
  1338 
       
  1339 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
       
  1340 		return;
       
  1341 	}
       
  1342 
       
  1343 	/* Check if vehicle needs to proceed, return if it doesn't */
       
  1344 	if (!RoadVehAccelerate(v)) return;
       
  1345 
  1431 
  1346 	if (v->u.road.overtaking != 0)  {
  1432 	if (v->u.road.overtaking != 0)  {
  1347 		if (++v->u.road.overtaking_ctr >= 35)
  1433 		if (++v->u.road.overtaking_ctr >= 35)
  1348 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
  1434 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
  1349 			 *  if the vehicle started a corner. To protect that, only allow an abort of
  1435 			 *  if the vehicle started a corner. To protect that, only allow an abort of
  1351 			if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) {
  1437 			if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) {
  1352 				v->u.road.overtaking = 0;
  1438 				v->u.road.overtaking = 0;
  1353 			}
  1439 			}
  1354 	}
  1440 	}
  1355 
  1441 
       
  1442 	/* If this vehicle is in a depot and we've reached this point it must be
       
  1443 	 * one of the articulated parts. It will stay in the depot until activated
       
  1444 	 * by the previous vehicle in the chain when it gets to the right place. */
       
  1445 	if (IsRoadVehInDepot(v)) return true;
       
  1446 
  1356 	/* Save old vehicle position to use at end of move to set viewport area dirty */
  1447 	/* Save old vehicle position to use at end of move to set viewport area dirty */
  1357 	BeginVehicleMove(v);
  1448 	BeginVehicleMove(v);
  1358 
  1449 
  1359 	if (v->u.road.state == RVSB_WORMHOLE) {
  1450 	if (v->u.road.state == RVSB_WORMHOLE) {
  1360 		/* Vehicle is entering a depot or is on a bridge or in a tunnel */
  1451 		/* Vehicle is entering a depot or is on a bridge or in a tunnel */
  1361 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  1452 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  1362 
  1453 
  1363 		const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
  1454 		const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
  1364 		if (u != NULL && u->cur_speed < v->cur_speed) {
  1455 		if (u != NULL && u->cur_speed < v->cur_speed) {
  1365 			v->cur_speed = u->cur_speed;
  1456 			v->cur_speed = u->cur_speed;
  1366 			return;
  1457 			return false;
  1367 		}
  1458 		}
  1368 
  1459 
  1369 		if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  1460 		if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  1370 			/* Vehicle has just entered a bridge or tunnel */
  1461 			/* Vehicle has just entered a bridge or tunnel */
  1371 			v->cur_image = GetRoadVehImage(v, v->direction);
  1462 			v->cur_image = v->GetImage(v->direction);
  1372 			v->UpdateDeltaXY(v->direction);
  1463 			v->UpdateDeltaXY(v->direction);
  1373 			SetRoadVehPosition(v,gp.x,gp.y);
  1464 			SetRoadVehPosition(v,gp.x,gp.y);
  1374 			return;
  1465 			return true;
  1375 		}
  1466 		}
  1376 
  1467 
  1377 		v->x_pos = gp.x;
  1468 		v->x_pos = gp.x;
  1378 		v->y_pos = gp.y;
  1469 		v->y_pos = gp.y;
  1379 		VehiclePositionChanged(v);
  1470 		VehiclePositionChanged(v);
  1380 		if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
  1471 		if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
  1381 		return;
  1472 		return true;
  1382 	}
  1473 	}
  1383 
  1474 
  1384 	/* Get move position data for next frame.
  1475 	/* Get move position data for next frame.
  1385 	 * For a drive-through road stop use 'straight road' move data.
  1476 	 * For a drive-through road stop use 'straight road' move data.
  1386 	 * In this case v->u.road.state is masked to give the road stop entry direction. */
  1477 	 * In this case v->u.road.state is masked to give the road stop entry direction. */
  1388 		(HASBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
  1479 		(HASBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
  1389 		(_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
  1480 		(_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
  1390 
  1481 
  1391 	if (rd.x & RDE_NEXT_TILE) {
  1482 	if (rd.x & RDE_NEXT_TILE) {
  1392 		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
  1483 		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
  1393 		Trackdir dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
  1484 		Trackdir dir;
  1394 		uint32 r;
  1485 		uint32 r;
  1395 		Direction newdir;
  1486 		Direction newdir;
  1396 		const RoadDriveEntry *rdp;
  1487 		const RoadDriveEntry *rdp;
  1397 
  1488 
       
  1489 		if (IsRoadVehFront(v)) {
       
  1490 			/* If this is the front engine, look for the right path. */
       
  1491 			dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
       
  1492 		} else {
       
  1493 			dir = FollowPreviousRoadVehicle(v, prev, tile, (DiagDirection)(rd.x & 3));
       
  1494 		}
       
  1495 
  1398 		if (dir == INVALID_TRACKDIR) {
  1496 		if (dir == INVALID_TRACKDIR) {
       
  1497 			if (!IsRoadVehFront(v)) error("!Disconnecting road vehicle.");
  1399 			v->cur_speed = 0;
  1498 			v->cur_speed = 0;
  1400 			return;
  1499 			return false;
  1401 		}
  1500 		}
  1402 
  1501 
  1403 again:
  1502 again:
  1404 		if (IsReversingRoadTrackdir(dir)) {
  1503 		if (IsReversingRoadTrackdir(dir)) {
  1405 			/* Turning around */
  1504 			/* Turning around */
  1410 					case TRACKDIR_RVREV_NE: needed = ROAD_SW; break;
  1509 					case TRACKDIR_RVREV_NE: needed = ROAD_SW; break;
  1411 					case TRACKDIR_RVREV_SE: needed = ROAD_NW; break;
  1510 					case TRACKDIR_RVREV_SE: needed = ROAD_NW; break;
  1412 					case TRACKDIR_RVREV_SW: needed = ROAD_NE; break;
  1511 					case TRACKDIR_RVREV_SW: needed = ROAD_NE; break;
  1413 					case TRACKDIR_RVREV_NW: needed = ROAD_SE; break;
  1512 					case TRACKDIR_RVREV_NW: needed = ROAD_SE; break;
  1414 				}
  1513 				}
  1415 				if (!IsTileType(tile, MP_STREET) || GetRoadTileType(tile) != ROAD_TILE_NORMAL || (needed & GetRoadBits(tile, ROADTYPE_TRAM)) == ROAD_NONE) {
  1514 				if (!IsTileType(tile, MP_STREET) || GetRoadTileType(tile) != ROAD_TILE_NORMAL || HasRoadWorks(tile) || (needed & GetRoadBits(tile, ROADTYPE_TRAM)) == ROAD_NONE) {
  1416 					/* The tram cannot turn here */
  1515 					/* The tram cannot turn here */
  1417 					v->cur_speed = 0;
  1516 					v->cur_speed = 0;
  1418 					return;
  1517 					return false;
  1419 				}
  1518 				}
  1420 			} else if (IsTileType(v->tile, MP_STREET) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) {
  1519 			} else if (IsTileType(v->tile, MP_STREET) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) {
  1421 				v->cur_speed = 0;
  1520 				v->cur_speed = 0;
  1422 				return;
  1521 				return false;
  1423 			} else {
  1522 			} else {
  1424 				tile = v->tile;
  1523 				tile = v->tile;
  1425 			}
  1524 			}
  1426 		}
  1525 		}
  1427 
  1526 
  1430 
  1529 
  1431 		x = TileX(tile) * TILE_SIZE + rdp[RVC_DEFAULT_START_FRAME].x;
  1530 		x = TileX(tile) * TILE_SIZE + rdp[RVC_DEFAULT_START_FRAME].x;
  1432 		y = TileY(tile) * TILE_SIZE + rdp[RVC_DEFAULT_START_FRAME].y;
  1531 		y = TileY(tile) * TILE_SIZE + rdp[RVC_DEFAULT_START_FRAME].y;
  1433 
  1532 
  1434 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1533 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1435 		if (RoadVehFindCloseTo(v, x, y, newdir) != NULL) return;
  1534 		if (IsRoadVehFront(v) && RoadVehFindCloseTo(v, x, y, newdir) != NULL) return false;
  1436 
  1535 
  1437 		r = VehicleEnterTile(v, tile, x, y);
  1536 		r = VehicleEnterTile(v, tile, x, y);
  1438 		if (HASBIT(r, VETS_CANNOT_ENTER)) {
  1537 		if (HASBIT(r, VETS_CANNOT_ENTER)) {
  1439 			if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
  1538 			if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
  1440 				v->cur_speed = 0;
  1539 				v->cur_speed = 0;
  1441 				return;
  1540 				return false;
  1442 			}
  1541 			}
  1443 			/* Try an about turn to re-enter the previous tile */
  1542 			/* Try an about turn to re-enter the previous tile */
  1444 			dir = _road_reverse_table[rd.x & 3];
  1543 			dir = _road_reverse_table[rd.x & 3];
  1445 			goto again;
  1544 			goto again;
  1446 		}
  1545 		}
  1448 		if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
  1547 		if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
  1449 			if (IsReversingRoadTrackdir(dir) && IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
  1548 			if (IsReversingRoadTrackdir(dir) && IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
  1450 				/* New direction is trying to turn vehicle around.
  1549 				/* New direction is trying to turn vehicle around.
  1451 				 * We can't turn at the exit of a road stop so wait.*/
  1550 				 * We can't turn at the exit of a road stop so wait.*/
  1452 				v->cur_speed = 0;
  1551 				v->cur_speed = 0;
  1453 				return;
  1552 				return false;
  1454 			}
  1553 			}
  1455 			if (IsRoadStop(v->tile)) {
  1554 			if (IsRoadStop(v->tile)) {
  1456 				RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
  1555 				RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
  1457 
  1556 
  1458 				/* Vehicle is leaving a road stop tile, mark bay as free
  1557 				/* Vehicle is leaving a road stop tile, mark bay as free
  1473 		if (newdir != v->direction) {
  1572 		if (newdir != v->direction) {
  1474 			v->direction = newdir;
  1573 			v->direction = newdir;
  1475 			v->cur_speed -= v->cur_speed >> 2;
  1574 			v->cur_speed -= v->cur_speed >> 2;
  1476 		}
  1575 		}
  1477 
  1576 
  1478 		v->cur_image = GetRoadVehImage(v, newdir);
  1577 		v->cur_image = v->GetImage(newdir);
  1479 		v->UpdateDeltaXY(v->direction);
  1578 		v->UpdateDeltaXY(v->direction);
  1480 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1579 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1481 		return;
  1580 		return true;
  1482 	}
  1581 	}
  1483 
  1582 
  1484 	if (rd.x & RDE_TURNED) {
  1583 	if (rd.x & RDE_TURNED) {
  1485 		/* Vehicle has finished turning around, it will now head back onto the same tile */
  1584 		/* Vehicle has finished turning around, it will now head back onto the same tile */
  1486 		Trackdir dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
  1585 		Trackdir dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
  1488 		Direction newdir;
  1587 		Direction newdir;
  1489 		const RoadDriveEntry *rdp;
  1588 		const RoadDriveEntry *rdp;
  1490 
  1589 
  1491 		if (dir == INVALID_TRACKDIR) {
  1590 		if (dir == INVALID_TRACKDIR) {
  1492 			v->cur_speed = 0;
  1591 			v->cur_speed = 0;
  1493 			return;
  1592 			return false;
  1494 		}
  1593 		}
  1495 
  1594 
  1496 		rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + dir];
  1595 		rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + dir];
  1497 
  1596 
  1498 		x = TileX(v->tile) * TILE_SIZE + rdp[RVC_TURN_AROUND_START_FRAME].x;
  1597 		x = TileX(v->tile) * TILE_SIZE + rdp[RVC_TURN_AROUND_START_FRAME].x;
  1499 		y = TileY(v->tile) * TILE_SIZE + rdp[RVC_TURN_AROUND_START_FRAME].y;
  1598 		y = TileY(v->tile) * TILE_SIZE + rdp[RVC_TURN_AROUND_START_FRAME].y;
  1500 
  1599 
  1501 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1600 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1502 		if (RoadVehFindCloseTo(v, x, y, newdir) != NULL) return;
  1601 		if (IsRoadVehFront(v) && RoadVehFindCloseTo(v, x, y, newdir) != NULL) return false;
  1503 
  1602 
  1504 		r = VehicleEnterTile(v, v->tile, x, y);
  1603 		r = VehicleEnterTile(v, v->tile, x, y);
  1505 		if (HASBIT(r, VETS_CANNOT_ENTER)) {
  1604 		if (HASBIT(r, VETS_CANNOT_ENTER)) {
  1506 			v->cur_speed = 0;
  1605 			v->cur_speed = 0;
  1507 			return;
  1606 			return false;
  1508 		}
  1607 		}
  1509 
  1608 
  1510 		v->u.road.state = dir;
  1609 		v->u.road.state = dir;
  1511 		v->u.road.frame = RVC_TURN_AROUND_START_FRAME;
  1610 		v->u.road.frame = RVC_TURN_AROUND_START_FRAME;
  1512 
  1611 
  1513 		if (newdir != v->direction) {
  1612 		if (newdir != v->direction) {
  1514 			v->direction = newdir;
  1613 			v->direction = newdir;
  1515 			v->cur_speed -= v->cur_speed >> 2;
  1614 			v->cur_speed -= v->cur_speed >> 2;
  1516 		}
  1615 		}
  1517 
  1616 
  1518 		v->cur_image = GetRoadVehImage(v, newdir);
  1617 		v->cur_image = v->GetImage(newdir);
  1519 		v->UpdateDeltaXY(v->direction);
  1618 		v->UpdateDeltaXY(v->direction);
  1520 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1619 		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1521 		return;
  1620 		return true;
       
  1621 	}
       
  1622 
       
  1623 	/* This vehicle is not in a wormhole and it hasn't entered a new tile. If
       
  1624 	 * it's on a depot tile, check if it's time to activate the next vehicle in
       
  1625 	 * the chain yet. */
       
  1626 	if (v->next != NULL &&
       
  1627 			IsTileType(v->tile, MP_STREET) && GetRoadTileType(v->tile) == ROAD_TILE_DEPOT) {
       
  1628 
       
  1629 		if (v->u.road.frame == v->u.road.cached_veh_length + RVC_DEPOT_START_FRAME) {
       
  1630 			RoadVehLeaveDepot(v->next, false);
       
  1631 		}
  1522 	}
  1632 	}
  1523 
  1633 
  1524 	/* Calculate new position for the vehicle */
  1634 	/* Calculate new position for the vehicle */
  1525 	x = (v->x_pos & ~15) + (rd.x & 15);
  1635 	x = (v->x_pos & ~15) + (rd.x & 15);
  1526 	y = (v->y_pos & ~15) + (rd.y & 15);
  1636 	y = (v->y_pos & ~15) + (rd.y & 15);
  1527 
  1637 
  1528 	new_dir = RoadVehGetSlidingDirection(v, x, y);
  1638 	new_dir = RoadVehGetSlidingDirection(v, x, y);
  1529 
  1639 
  1530 	if (!IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
  1640 	if (IsRoadVehFront(v) && !IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
  1531 		/* Vehicle is not in a road stop.
  1641 		/* Vehicle is not in a road stop.
  1532 		 * Check for another vehicle to overtake */
  1642 		 * Check for another vehicle to overtake */
  1533 		Vehicle* u = RoadVehFindCloseTo(v, x, y, new_dir);
  1643 		Vehicle* u = RoadVehFindCloseTo(v, x, y, new_dir);
  1534 
  1644 
  1535 		if (u != NULL) {
  1645 		if (u != NULL) {
  1536 			v->cur_speed = u->cur_speed;
  1646 			v->cur_speed = u->cur_speed;
  1537 			/* There is a vehicle in front overtake it if possible */
  1647 			/* There is a vehicle in front overtake it if possible */
  1538 			if (v->u.road.overtaking == 0) RoadVehCheckOvertake(v, u);
  1648 			if (v->u.road.overtaking == 0) RoadVehCheckOvertake(v, u);
  1539 			return;
  1649 			return false;
  1540 		}
  1650 		}
  1541 	}
  1651 	}
  1542 
  1652 
  1543 	old_dir = v->direction;
  1653 	old_dir = v->direction;
  1544 	if (new_dir != old_dir) {
  1654 	if (new_dir != old_dir) {
  1545 		v->direction = new_dir;
  1655 		v->direction = new_dir;
  1546 		v->cur_speed -= (v->cur_speed >> 2);
  1656 		v->cur_speed -= (v->cur_speed >> 2);
  1547 		if (old_dir != v->u.road.state) {
  1657 		if (old_dir != v->u.road.state) {
  1548 			/* The vehicle is in a road stop */
  1658 			/* The vehicle is in a road stop */
  1549 			v->cur_image = GetRoadVehImage(v, new_dir);
  1659 			v->cur_image = v->GetImage(new_dir);
  1550 			v->UpdateDeltaXY(v->direction);
  1660 			v->UpdateDeltaXY(v->direction);
  1551 			SetRoadVehPosition(v, v->x_pos, v->y_pos);
  1661 			SetRoadVehPosition(v, v->x_pos, v->y_pos);
  1552 			/* Note, return here means that the frame counter is not incremented
  1662 			/* Note, return here means that the frame counter is not incremented
  1553 			 * for vehicles changing direction in a road stop. This causes frames to
  1663 			 * for vehicles changing direction in a road stop. This causes frames to
  1554 			 * be repeated. (XXX) Is this intended? */
  1664 			 * be repeated. (XXX) Is this intended? */
  1555 			return;
  1665 			return true;
  1556 		}
  1666 		}
  1557 	}
  1667 	}
  1558 
  1668 
  1559 	/* If the vehicle is in a normal road stop and the frame equals the stop frame OR
  1669 	/* If the vehicle is in a normal road stop and the frame equals the stop frame OR
  1560 	 * if the vehicle is in a drive-through road stop and this is the destination station
  1670 	 * if the vehicle is in a drive-through road stop and this is the destination station
  1561 	 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
  1671 	 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
  1562 	 * (the station test and stop type test ensure that other vehicles, using the road stop as
  1672 	 * (the station test and stop type test ensure that other vehicles, using the road stop as
  1563 	 * a through route, do not stop) */
  1673 	 * a through route, do not stop) */
  1564 	if ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
  1674 	if (IsRoadVehFront(v) && ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
  1565 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
  1675 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
  1566 			(IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
  1676 			(IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
  1567 			v->current_order.dest == GetStationIndex(v->tile) &&
  1677 			v->current_order.dest == GetStationIndex(v->tile) &&
  1568 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
  1678 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
  1569 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME)) {
  1679 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
  1570 
  1680 
  1571 		RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
  1681 		RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
  1572 		Station* st = GetStationByTile(v->tile);
  1682 		Station* st = GetStationByTile(v->tile);
  1573 
  1683 
  1574 		/* Vehicle is at the stop position (at a bay) in a road stop.
  1684 		/* Vehicle is at the stop position (at a bay) in a road stop.
  1594 						v->dest_tile = rs_n->xy;
  1704 						v->dest_tile = rs_n->xy;
  1595 						v->u.road.slot_age = 14;
  1705 						v->u.road.slot_age = 14;
  1596 
  1706 
  1597 						v->u.road.frame++;
  1707 						v->u.road.frame++;
  1598 						RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1708 						RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1599 						return;
  1709 						return true;
  1600 					}
  1710 					}
  1601 				}
  1711 				}
  1602 			}
  1712 			}
  1603 
  1713 
  1604 			rs->SetEntranceBusy(false);
  1714 			rs->SetEntranceBusy(false);
  1606 			v->last_station_visited = GetStationIndex(v->tile);
  1716 			v->last_station_visited = GetStationIndex(v->tile);
  1607 
  1717 
  1608 			RoadVehArrivesAt(v, st);
  1718 			RoadVehArrivesAt(v, st);
  1609 			v->BeginLoading();
  1719 			v->BeginLoading();
  1610 
  1720 
  1611 			return;
  1721 			return false;
  1612 		}
  1722 		}
  1613 
  1723 
  1614 		/* Vehicle is ready to leave a bay in a road stop */
  1724 		/* Vehicle is ready to leave a bay in a road stop */
  1615 		if (v->current_order.type != OT_GOTO_DEPOT) {
  1725 		if (v->current_order.type != OT_GOTO_DEPOT) {
  1616 			if (rs->IsEntranceBusy()) {
  1726 			if (rs->IsEntranceBusy()) {
  1617 				/* Road stop entrance is busy, so wait as there is nowhere else to go */
  1727 				/* Road stop entrance is busy, so wait as there is nowhere else to go */
  1618 				v->cur_speed = 0;
  1728 				v->cur_speed = 0;
  1619 				return;
  1729 				return false;
  1620 			}
  1730 			}
  1621 			v->current_order.Free();
  1731 			v->current_order.Free();
  1622 			ClearSlot(v);
  1732 			ClearSlot(v);
  1623 		}
  1733 		}
  1624 
  1734 
  1657 	/* Check tile position conditions - i.e. stop position in depot,
  1767 	/* Check tile position conditions - i.e. stop position in depot,
  1658 	 * entry onto bridge or into tunnel */
  1768 	 * entry onto bridge or into tunnel */
  1659 	r = VehicleEnterTile(v, v->tile, x, y);
  1769 	r = VehicleEnterTile(v, v->tile, x, y);
  1660 	if (HASBIT(r, VETS_CANNOT_ENTER)) {
  1770 	if (HASBIT(r, VETS_CANNOT_ENTER)) {
  1661 		v->cur_speed = 0;
  1771 		v->cur_speed = 0;
  1662 		return;
  1772 		return false;
  1663 	}
  1773 	}
  1664 
  1774 
  1665 	/* Move to next frame unless vehicle arrived at a stop position
  1775 	/* Move to next frame unless vehicle arrived at a stop position
  1666 	 * in a depot or entered a tunnel/bridge */
  1776 	 * in a depot or entered a tunnel/bridge */
  1667 	if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++;
  1777 	if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++;
  1668 
  1778 
  1669 	v->cur_image = GetRoadVehImage(v, v->direction);
  1779 	v->cur_image = v->GetImage(v->direction);
  1670 	v->UpdateDeltaXY(v->direction);
  1780 	v->UpdateDeltaXY(v->direction);
  1671 	RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
  1781 	RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
       
  1782 	return true;
       
  1783 }
       
  1784 
       
  1785 static void RoadVehController(Vehicle *v)
       
  1786 {
       
  1787 	/* decrease counters */
       
  1788 	v->tick_counter++;
       
  1789 	v->current_order_time++;
       
  1790 	if (v->u.road.reverse_ctr != 0) v->u.road.reverse_ctr--;
       
  1791 
       
  1792 	/* handle crashed */
       
  1793 	if (v->u.road.crashed_ctr != 0) {
       
  1794 		RoadVehIsCrashed(v);
       
  1795 		return;
       
  1796 	}
       
  1797 
       
  1798 	RoadVehCheckTrainCrash(v);
       
  1799 
       
  1800 	/* road vehicle has broken down? */
       
  1801 	if (v->breakdown_ctr != 0) {
       
  1802 		if (v->breakdown_ctr <= 2) {
       
  1803 			HandleBrokenRoadVeh(v);
       
  1804 			return;
       
  1805 		}
       
  1806 		v->breakdown_ctr--;
       
  1807 	}
       
  1808 
       
  1809 	if (v->vehstatus & VS_STOPPED) return;
       
  1810 
       
  1811 	ProcessRoadVehOrder(v);
       
  1812 	v->HandleLoading();
       
  1813 
       
  1814 	if (v->current_order.type == OT_LOADING) return;
       
  1815 
       
  1816 	if (IsRoadVehInDepot(v) && RoadVehLeaveDepot(v, true)) return;
       
  1817 
       
  1818 	/* Check if vehicle needs to proceed, return if it doesn't */
       
  1819 	if (!RoadVehAccelerate(v)) return;
       
  1820 
       
  1821 	for (Vehicle *prev = NULL; v != NULL; prev = v, v = v->next) {
       
  1822 		if (!IndividualRoadVehicleController(v, prev)) break;
       
  1823 	}
  1672 }
  1824 }
  1673 
  1825 
  1674 static void AgeRoadVehCargo(Vehicle *v)
  1826 static void AgeRoadVehCargo(Vehicle *v)
  1675 {
  1827 {
  1676 	if (_age_cargo_skip_counter != 0) return;
  1828 	if (_age_cargo_skip_counter != 0) return;
  1677 	if (v->cargo_days != 255) v->cargo_days++;
  1829 	v->cargo.AgeCargo();
  1678 }
  1830 }
  1679 
  1831 
  1680 void RoadVeh_Tick(Vehicle *v)
  1832 void RoadVehicle::Tick()
  1681 {
  1833 {
  1682 	AgeRoadVehCargo(v);
  1834 	AgeRoadVehCargo(this);
  1683 	RoadVehController(v);
  1835 
       
  1836 	if (IsRoadVehFront(this)) RoadVehController(this);
  1684 }
  1837 }
  1685 
  1838 
  1686 static void CheckIfRoadVehNeedsService(Vehicle *v)
  1839 static void CheckIfRoadVehNeedsService(Vehicle *v)
  1687 {
  1840 {
  1688 	const Depot* depot;
  1841 	const Depot* depot;
  1734 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1887 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1735 }
  1888 }
  1736 
  1889 
  1737 void OnNewDay_RoadVeh(Vehicle *v)
  1890 void OnNewDay_RoadVeh(Vehicle *v)
  1738 {
  1891 {
  1739 	int32 cost;
  1892 	CommandCost cost;
       
  1893 
       
  1894 	if (!IsRoadVehFront(v)) return;
  1740 
  1895 
  1741 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  1896 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  1742 	if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v);
  1897 	if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v);
  1743 
  1898 
  1744 	AgeVehicle(v);
  1899 	AgeVehicle(v);
  1814 		}
  1969 		}
  1815 	}
  1970 	}
  1816 
  1971 
  1817 	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
  1972 	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
  1818 
  1973 
  1819 	v->profit_this_year -= cost >> 8;
  1974 	v->profit_this_year -= cost.GetCost() >> 8;
  1820 
  1975 
  1821 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  1976 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  1822 	SubtractMoneyFromPlayerFract(v->owner, cost);
  1977 	SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
  1823 
  1978 
  1824 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1979 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1825 	InvalidateWindowClasses(WC_ROADVEH_LIST);
  1980 	InvalidateWindowClasses(WC_ROADVEH_LIST);
  1826 }
  1981 }
  1827 
  1982 
  1847  * - p2 = (bit 0-7) - the new cargo type to refit to
  2002  * - p2 = (bit 0-7) - the new cargo type to refit to
  1848  * - p2 = (bit 8-15) - the new cargo subtype to refit to
  2003  * - p2 = (bit 8-15) - the new cargo subtype to refit to
  1849  * - p2 = (bit 16) - refit only this vehicle (ignored)
  2004  * - p2 = (bit 16) - refit only this vehicle (ignored)
  1850  * @return cost of refit or error
  2005  * @return cost of refit or error
  1851  */
  2006  */
  1852 int32 CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2007 CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  1853 {
  2008 {
  1854 	Vehicle *v;
  2009 	Vehicle *v;
  1855 	int32 cost;
  2010 	CommandCost cost;
  1856 	CargoID new_cid = GB(p2, 0, 8);
  2011 	CargoID new_cid = GB(p2, 0, 8);
  1857 	byte new_subtype = GB(p2, 8, 8);
  2012 	byte new_subtype = GB(p2, 8, 8);
  1858 	uint16 capacity = CALLBACK_FAILED;
  2013 	uint16 capacity = CALLBACK_FAILED;
  1859 
  2014 
  1860 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  2015 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
  1861 
  2016 
  1862 	v = GetVehicle(p1);
  2017 	v = GetVehicle(p1);
  1863 
  2018 
  1864 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
  2019 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
  1865 	if (!IsRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
  2020 	if (!CheckRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
  1866 
  2021 
  1867 	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
  2022 	if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR;
  1868 
  2023 
  1869 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  2024 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  1870 
  2025 
  1906 			default:       capacity /= 4; break;
  2061 			default:       capacity /= 4; break;
  1907 		}
  2062 		}
  1908 	}
  2063 	}
  1909 	_returned_refit_capacity = capacity;
  2064 	_returned_refit_capacity = capacity;
  1910 
  2065 
  1911 	cost = 0;
       
  1912 	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
  2066 	if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) {
  1913 		cost = GetRefitCost(v->engine_type);
  2067 		cost = GetRefitCost(v->engine_type);
  1914 	}
  2068 	}
  1915 
  2069 
  1916 	if (flags & DC_EXEC) {
  2070 	if (flags & DC_EXEC) {
  1917 		v->cargo_cap = capacity;
  2071 		v->cargo_cap = capacity;
  1918 		v->cargo_count = (v->cargo_type == new_cid) ? min(capacity, v->cargo_count) : 0;
  2072 		v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
  1919 		v->cargo_type = new_cid;
  2073 		v->cargo_type = new_cid;
  1920 		v->cargo_subtype = new_subtype;
  2074 		v->cargo_subtype = new_subtype;
  1921 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  2075 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  1922 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  2076 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1923 		RebuildVehicleLists();
  2077 		RebuildVehicleLists();