src/roadveh_cmd.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6877 889301acc299
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     3 /** @file roadveh_cmd.cpp */
     3 /** @file roadveh_cmd.cpp */
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "debug.h"
     7 #include "debug.h"
     8 #include "functions.h"
     8 #include "tile_cmd.h"
     9 #include "landscape.h"
     9 #include "landscape.h"
    10 #include "road_map.h"
    10 #include "road_map.h"
    11 #include "roadveh.h"
    11 #include "roadveh.h"
    12 #include "station_map.h"
    12 #include "station_map.h"
    13 #include "table/strings.h"
       
    14 #include "strings.h"
       
    15 #include "map.h"
       
    16 #include "tile.h"
       
    17 #include "vehicle.h"
       
    18 #include "timetable.h"
    13 #include "timetable.h"
    19 #include "engine.h"
    14 #include "engine.h"
    20 #include "command.h"
    15 #include "command_func.h"
    21 #include "station.h"
    16 #include "station.h"
    22 #include "news.h"
    17 #include "news.h"
    23 #include "pathfind.h"
    18 #include "pathfind.h"
    24 #include "npf.h"
    19 #include "npf.h"
    25 #include "player.h"
    20 #include "player_func.h"
    26 #include "sound.h"
    21 #include "player_base.h"
    27 #include "depot.h"
    22 #include "depot.h"
    28 #include "bridge.h"
    23 #include "bridge.h"
    29 #include "tunnel_map.h"
    24 #include "tunnel_map.h"
    30 #include "bridge_map.h"
    25 #include "bridge_map.h"
    31 #include "vehicle_gui.h"
    26 #include "vehicle_gui.h"
    33 #include "newgrf_callbacks.h"
    28 #include "newgrf_callbacks.h"
    34 #include "newgrf_engine.h"
    29 #include "newgrf_engine.h"
    35 #include "newgrf_text.h"
    30 #include "newgrf_text.h"
    36 #include "newgrf_sound.h"
    31 #include "newgrf_sound.h"
    37 #include "yapf/yapf.h"
    32 #include "yapf/yapf.h"
    38 #include "date.h"
       
    39 #include "cargotype.h"
    33 #include "cargotype.h"
       
    34 #include "strings_func.h"
       
    35 #include "tunnelbridge_map.h"
       
    36 #include "functions.h"
       
    37 #include "window_func.h"
       
    38 #include "date_func.h"
       
    39 #include "vehicle_func.h"
       
    40 #include "sound_func.h"
       
    41 #include "variables.h"
       
    42 #include "autoreplace_gui.h"
       
    43 #include "gfx_func.h"
       
    44 #include "settings_type.h"
       
    45 
       
    46 #include "table/strings.h"
    40 
    47 
    41 static const uint16 _roadveh_images[63] = {
    48 static const uint16 _roadveh_images[63] = {
    42 	0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
    49 	0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
    43 	0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
    50 	0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
    44 	0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
    51 	0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
    92 	int image;
    99 	int image;
    93 
   100 
    94 	if (is_custom_sprite(img)) {
   101 	if (is_custom_sprite(img)) {
    95 		image = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
   102 		image = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
    96 		if (image != 0) return image;
   103 		if (image != 0) return image;
    97 		img = orig_road_vehicle_info[this->engine_type - ROAD_ENGINES_INDEX].image_index;
   104 		img = _orig_road_vehicle_info[this->engine_type - ROAD_ENGINES_INDEX].image_index;
    98 	}
   105 	}
    99 
   106 
   100 	image = direction + _roadveh_images[img];
   107 	image = direction + _roadveh_images[img];
   101 	if (this->cargo.Count() >= this->cargo_cap / 2U) image += _roadveh_full_adder[img];
   108 	if (this->cargo.Count() >= this->cargo_cap / 2U) image += _roadveh_full_adder[img];
   102 	return image;
   109 	return image;
   111 
   118 
   112 		if (sprite != 0) {
   119 		if (sprite != 0) {
   113 			DrawSprite(sprite, pal, x, y);
   120 			DrawSprite(sprite, pal, x, y);
   114 			return;
   121 			return;
   115 		}
   122 		}
   116 		spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
   123 		spritenum = _orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
   117 	}
   124 	}
   118 	DrawSprite(6 + _roadveh_images[spritenum], pal, x, y);
   125 	DrawSprite(6 + _roadveh_images[spritenum], pal, x, y);
   119 }
   126 }
   120 
   127 
   121 static CommandCost EstimateRoadVehCost(EngineID engine_type)
   128 static CommandCost EstimateRoadVehCost(EngineID engine_type)
   122 {
   129 {
   123 	return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
   130 	return CommandCost(EXPENSES_NEW_VEHICLES, ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
   124 }
   131 }
   125 
   132 
   126 byte GetRoadVehLength(const Vehicle *v)
   133 byte GetRoadVehLength(const Vehicle *v)
   127 {
   134 {
   128 	byte length = 8;
   135 	byte length = 8;
   164 	Vehicle *v;
   171 	Vehicle *v;
   165 	UnitID unit_num;
   172 	UnitID unit_num;
   166 	Engine *e;
   173 	Engine *e;
   167 
   174 
   168 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
   175 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
   169 
       
   170 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
   171 
   176 
   172 	cost = EstimateRoadVehCost(p1);
   177 	cost = EstimateRoadVehCost(p1);
   173 	if (flags & DC_QUERY_COST) return cost;
   178 	if (flags & DC_QUERY_COST) return cost;
   174 
   179 
   175 	/* The ai_new queries the vehicle cost before building the route,
   180 	/* The ai_new queries the vehicle cost before building the route,
   231 //	v->u.road.unk2 = 0;
   236 //	v->u.road.unk2 = 0;
   232 //	v->u.road.overtaking = 0;
   237 //	v->u.road.overtaking = 0;
   233 
   238 
   234 		v->last_station_visited = INVALID_STATION;
   239 		v->last_station_visited = INVALID_STATION;
   235 		v->max_speed = rvi->max_speed;
   240 		v->max_speed = rvi->max_speed;
   236 		v->engine_type = (byte)p1;
   241 		v->engine_type = (EngineID)p1;
   237 
   242 
   238 		e = GetEngine(p1);
   243 		e = GetEngine(p1);
   239 		v->reliability = e->reliability;
   244 		v->reliability = e->reliability;
   240 		v->reliability_spd_dec = e->reliability_spd_dec;
   245 		v->reliability_spd_dec = e->reliability_spd_dec;
   241 		v->max_age = e->lifelength * 366;
   246 		v->max_age = e->lifelength * 366;
   242 		_new_vehicle_id = v->index;
   247 		_new_vehicle_id = v->index;
   243 
   248 
   244 		v->string_id = STR_SV_ROADVEH_NAME;
   249 		v->name = NULL;
   245 
   250 
   246 		v->service_interval = _patches.servint_roadveh;
   251 		v->service_interval = _patches.servint_roadveh;
   247 
   252 
   248 		v->date_of_last_service = _date;
   253 		v->date_of_last_service = _date;
   249 		v->build_year = _cur_year;
   254 		v->build_year = _cur_year;
   272 			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
   277 			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
   273 
   278 
   274 		GetPlayer(_current_player)->num_engines[p1]++;
   279 		GetPlayer(_current_player)->num_engines[p1]++;
   275 	}
   280 	}
   276 
   281 
   277 	return CommandCost(cost);
   282 	return cost;
   278 }
   283 }
   279 
   284 
   280 /** Start/Stop a road vehicle.
   285 /** Start/Stop a road vehicle.
   281  * @param tile unused
   286  * @param tile unused
   282  * @param flags operation to perform
   287  * @param flags operation to perform
   307 			DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
   312 			DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
   308 		}
   313 		}
   309 
   314 
   310 		v->vehstatus ^= VS_STOPPED;
   315 		v->vehstatus ^= VS_STOPPED;
   311 		v->cur_speed = 0;
   316 		v->cur_speed = 0;
   312 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   317 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   313 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   318 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   314 	}
   319 	}
   315 
   320 
   316 	return CommandCost();
   321 	return CommandCost();
   317 }
   322 }
   359 
   364 
   360 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   365 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
   361 
   366 
   362 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
   367 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
   363 
   368 
   364 	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
       
   365 
       
   366 	if (!CheckRoadVehInDepotStopped(v)) {
   369 	if (!CheckRoadVehInDepotStopped(v)) {
   367 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
   370 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
   368 	}
   371 	}
   369 
   372 
   370 	CommandCost ret(-v->value);
   373 	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
   371 
   374 
   372 	if (flags & DC_EXEC) {
   375 	if (flags & DC_EXEC) {
   373 		// Invalidate depot
   376 		// Invalidate depot
   374 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   377 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   375 		RebuildVehicleLists();
   378 		RebuildVehicleLists();
   419 	} else if (_patches.new_pathfinding_all) {
   422 	} else if (_patches.new_pathfinding_all) {
   420 		NPFFoundTargetData ftd;
   423 		NPFFoundTargetData ftd;
   421 		/* See where we are now */
   424 		/* See where we are now */
   422 		Trackdir trackdir = GetVehicleTrackdir(v);
   425 		Trackdir trackdir = GetVehicleTrackdir(v);
   423 
   426 
   424 		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, v->tile, ReverseTrackdir(trackdir), TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE, 0);
   427 		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, v->tile, ReverseTrackdir(trackdir), TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES, 0);
   425 		if (ftd.best_bird_dist == 0) {
   428 		if (ftd.best_bird_dist == 0) {
   426 			return GetDepotByTile(ftd.node.tile); /* Target found */
   429 			return GetDepotByTile(ftd.node.tile); /* Target found */
   427 		} else {
   430 		} else {
   428 			return NULL; /* Target not found */
   431 			return NULL; /* Target not found */
   429 		}
   432 		}
   474 
   477 
   475 	if (v->IsInDepot()) return CMD_ERROR;
   478 	if (v->IsInDepot()) return CMD_ERROR;
   476 
   479 
   477 	/* If the current orders are already goto-depot */
   480 	/* If the current orders are already goto-depot */
   478 	if (v->current_order.type == OT_GOTO_DEPOT) {
   481 	if (v->current_order.type == OT_GOTO_DEPOT) {
   479 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
   482 		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
   480 			/* We called with a different DEPOT_SERVICE setting.
   483 			/* We called with a different DEPOT_SERVICE setting.
   481 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
   484 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
   482 			 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
   485 			 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
   483 			if (flags & DC_EXEC) {
   486 			if (flags & DC_EXEC) {
   484 				ClrBit(v->current_order.flags, OFB_PART_OF_ORDERS);
   487 				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
   485 				ToggleBit(v->current_order.flags, OFB_HALT_IN_DEPOT);
   488 				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
   486 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   489 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   487 			}
   490 			}
   488 			return CommandCost();
   491 			return CommandCost();
   489 		}
   492 		}
   490 
   493 
   491 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
   494 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
   492 		if (flags & DC_EXEC) {
   495 		if (flags & DC_EXEC) {
   493 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
   496 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
   494 			 * then skip to the next order; effectively cancelling this forced service */
   497 			 * then skip to the next order; effectively cancelling this forced service */
   495 			if (HasBit(v->current_order.flags, OFB_PART_OF_ORDERS))
   498 			if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS))
   496 				v->cur_order_index++;
   499 				v->cur_order_index++;
   497 
   500 
   498 			v->current_order.type = OT_DUMMY;
   501 			v->current_order.type = OT_DUMMY;
   499 			v->current_order.flags = 0;
   502 			v->current_order.flags = 0;
   500 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   503 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   501 		}
   504 		}
   502 		return CommandCost();
   505 		return CommandCost();
   503 	}
   506 	}
   504 
   507 
   505 	dep = FindClosestRoadDepot(v);
   508 	dep = FindClosestRoadDepot(v);
   508 	if (flags & DC_EXEC) {
   511 	if (flags & DC_EXEC) {
   509 		if (v->current_order.type == OT_LOADING) v->LeaveStation();
   512 		if (v->current_order.type == OT_LOADING) v->LeaveStation();
   510 
   513 
   511 		ClearSlot(v);
   514 		ClearSlot(v);
   512 		v->current_order.type = OT_GOTO_DEPOT;
   515 		v->current_order.type = OT_GOTO_DEPOT;
   513 		v->current_order.flags = OF_NON_STOP;
   516 		v->current_order.flags = OFB_NON_STOP;
   514 		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OFB_HALT_IN_DEPOT);
   517 		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
   515 		v->current_order.refit_cargo = CT_INVALID;
   518 		v->current_order.refit_cargo = CT_INVALID;
   516 		v->current_order.dest = dep->index;
   519 		v->current_order.dest = dep->index;
   517 		v->dest_tile = dep->xy;
   520 		v->dest_tile = dep->xy;
   518 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   521 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   519 	}
   522 	}
   520 
   523 
   521 	return CommandCost();
   524 	return CommandCost();
   522 }
   525 }
   523 
   526 
   547 		return CMD_ERROR;
   550 		return CMD_ERROR;
   548 	}
   551 	}
   549 
   552 
   550 	if (IsTileType(v->tile, MP_ROAD) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) return CMD_ERROR;
   553 	if (IsTileType(v->tile, MP_ROAD) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) return CMD_ERROR;
   551 
   554 
   552 	if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
   555 	if (IsTileType(v->tile, MP_TUNNELBRIDGE) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
   553 	if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR;
       
   554 
   556 
   555 	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
   557 	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
   556 
   558 
   557 	return CommandCost();
   559 	return CommandCost();
   558 }
   560 }
   560 
   562 
   561 void RoadVehicle::MarkDirty()
   563 void RoadVehicle::MarkDirty()
   562 {
   564 {
   563 	for (Vehicle *v = this; v != NULL; v = v->Next()) {
   565 	for (Vehicle *v = this; v != NULL; v = v->Next()) {
   564 		v->cur_image = v->GetImage(v->direction);
   566 		v->cur_image = v->GetImage(v->direction);
   565 		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
   567 		MarkSingleVehicleDirty(v);
   566 	}
   568 	}
   567 }
   569 }
   568 
   570 
   569 void RoadVehicle::UpdateDeltaXY(Direction direction)
   571 void RoadVehicle::UpdateDeltaXY(Direction direction)
   570 {
   572 {
   611 	RebuildVehicleLists();
   613 	RebuildVehicleLists();
   612 	InvalidateWindow(WC_COMPANY, v->owner);
   614 	InvalidateWindow(WC_COMPANY, v->owner);
   613 
   615 
   614 	if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
   616 	if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
   615 
   617 
   616 	BeginVehicleMove(v);
   618 	MarkSingleVehicleDirty(v);
   617 	EndVehicleMove(v);
       
   618 
   619 
   619 	delete v;
   620 	delete v;
   620 }
   621 }
   621 
   622 
   622 static byte SetRoadVehPosition(Vehicle *v, int x, int y)
   623 static byte SetRoadVehPosition(Vehicle *v, int x, int y)
   686 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   687 	for (Vehicle *u = v; u != NULL; u = u->Next()) {
   687 		if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count();
   688 		if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count();
   688 
   689 
   689 		u->vehstatus |= VS_CRASHED;
   690 		u->vehstatus |= VS_CRASHED;
   690 
   691 
   691 		MarkAllViewportsDirty(u->left_coord, u->top_coord, u->right_coord + 1, u->bottom_coord + 1);
   692 		MarkSingleVehicleDirty(u);
   692 	}
   693 	}
   693 
   694 
   694 	ClearSlot(v);
   695 	ClearSlot(v);
   695 
   696 
   696 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   697 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   697 
   698 
   698 	SetDParam(0, pass);
   699 	SetDParam(0, pass);
   699 	AddNewsItem(
   700 	AddNewsItem(
   700 		(pass == 1) ?
   701 		(pass == 1) ?
   701 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   702 			STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE,
   760 	const Order *order;
   761 	const Order *order;
   761 
   762 
   762 	switch (v->current_order.type) {
   763 	switch (v->current_order.type) {
   763 		case OT_GOTO_DEPOT:
   764 		case OT_GOTO_DEPOT:
   764 			/* Let a depot order in the orderlist interrupt. */
   765 			/* Let a depot order in the orderlist interrupt. */
   765 			if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return;
   766 			if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return;
   766 			if (v->current_order.flags & OF_SERVICE_IF_NEEDED &&
   767 			if (v->current_order.flags & OFB_SERVICE_IF_NEEDED &&
   767 					!VehicleNeedsService(v)) {
   768 					!VehicleNeedsService(v)) {
   768 				UpdateVehicleTimetable(v, true);
   769 				UpdateVehicleTimetable(v, true);
   769 				v->cur_order_index++;
   770 				v->cur_order_index++;
   770 			}
   771 			}
   771 			break;
   772 			break;
   892 	rvf.y = y;
   893 	rvf.y = y;
   893 	rvf.dir = dir;
   894 	rvf.dir = dir;
   894 	rvf.veh = v;
   895 	rvf.veh = v;
   895 	if (front->u.road.state == RVSB_WORMHOLE) {
   896 	if (front->u.road.state == RVSB_WORMHOLE) {
   896 		u = (Vehicle*)VehicleFromPos(v->tile, &rvf, EnumCheckRoadVehClose);
   897 		u = (Vehicle*)VehicleFromPos(v->tile, &rvf, EnumCheckRoadVehClose);
       
   898 		if (u == NULL) u = (Vehicle*)VehicleFromPos(GetOtherTunnelBridgeEnd(v->tile), &rvf, EnumCheckRoadVehClose);
   897 	} else {
   899 	} else {
   898 		u = (Vehicle*)VehicleFromPosXY(x, y, &rvf, EnumCheckRoadVehClose);
   900 		u = (Vehicle*)VehicleFromPosXY(x, y, &rvf, EnumCheckRoadVehClose);
   899 	}
   901 	}
   900 
   902 
   901 	/* This code protects a roadvehicle from being blocked for ever
   903 	/* This code protects a roadvehicle from being blocked for ever
   959 
   961 
   960 	/* updates statusbar only if speed have changed to save CPU time */
   962 	/* updates statusbar only if speed have changed to save CPU time */
   961 	if (spd != v->cur_speed) {
   963 	if (spd != v->cur_speed) {
   962 		v->cur_speed = spd;
   964 		v->cur_speed = spd;
   963 		if (_patches.vehicle_speed) {
   965 		if (_patches.vehicle_speed) {
   964 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
   966 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   965 		}
   967 		}
   966 	}
   968 	}
   967 
   969 
   968 	/* Decrease somewhat when turning */
   970 	/* Decrease somewhat when turning */
   969 	if (!(v->direction & 1)) spd = spd * 3 >> 2;
   971 	if (!(v->direction & 1)) spd = spd * 3 >> 2;
  1013 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
  1015 static void* EnumFindVehToOvertake(Vehicle* v, void* data)
  1014 {
  1016 {
  1015 	const OvertakeData* od = (OvertakeData*)data;
  1017 	const OvertakeData* od = (OvertakeData*)data;
  1016 
  1018 
  1017 	return
  1019 	return
  1018 		v->tile == od->tile && v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v ?
  1020 		v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v ?
  1019 			v : NULL;
  1021 			v : NULL;
  1020 }
  1022 }
  1021 
  1023 
  1022 static bool FindRoadVehToOvertake(OvertakeData *od)
  1024 static bool FindRoadVehToOvertake(OvertakeData *od)
  1023 {
  1025 {
  1124 		frd->mindist = dist;
  1126 		frd->mindist = dist;
  1125 	}
  1127 	}
  1126 	return false;
  1128 	return false;
  1127 }
  1129 }
  1128 
  1130 
  1129 static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes)
  1131 static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypes railtypes)
  1130 {
  1132 {
  1131 
  1133 
  1132 	void* perf = NpfBeginInterval();
  1134 	void* perf = NpfBeginInterval();
  1133 	NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, sub_type, owner, railtypes);
  1135 	NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, sub_type, owner, railtypes);
  1134 	int t = NpfEndInterval(perf);
  1136 	int t = NpfEndInterval(perf);
  1226 
  1228 
  1227 		NPFFillWithOrderData(&fstd, v);
  1229 		NPFFillWithOrderData(&fstd, v);
  1228 		trackdir = DiagdirToDiagTrackdir(enterdir);
  1230 		trackdir = DiagdirToDiagTrackdir(enterdir);
  1229 		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
  1231 		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
  1230 
  1232 
  1231 		ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE);
  1233 		ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES);
  1232 		if (ftd.best_trackdir == INVALID_TRACKDIR) {
  1234 		if (ftd.best_trackdir == INVALID_TRACKDIR) {
  1233 			/* We are already at our target. Just do something
  1235 			/* We are already at our target. Just do something
  1234 			 * @todo: maybe display error?
  1236 			 * @todo: maybe display error?
  1235 			 * @todo: go straight ahead if possible? */
  1237 			 * @todo: go straight ahead if possible? */
  1236 			return_track(FindFirstBit2x64(trackdirs));
  1238 			return_track(FindFirstBit2x64(trackdirs));
  1308 		assert(trackdir != INVALID_TRACKDIR);
  1310 		assert(trackdir != INVALID_TRACKDIR);
  1309 
  1311 
  1310 		fstd.dest_coords = tile;
  1312 		fstd.dest_coords = tile;
  1311 		fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
  1313 		fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
  1312 
  1314 
  1313 		dist = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE).best_path_dist;
  1315 		dist = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES).best_path_dist;
  1314 		/* change units from NPF_TILE_LENGTH to # of tiles */
  1316 		/* change units from NPF_TILE_LENGTH to # of tiles */
  1315 		if (dist != UINT_MAX)
  1317 		if (dist != UINT_MAX)
  1316 			dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH;
  1318 			dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH;
  1317 	}
  1319 	}
  1318 	return dist;
  1320 	return dist;
  1403 	Trackdir dir;
  1405 	Trackdir dir;
  1404 
  1406 
  1405 	if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
  1407 	if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
  1406 		DiagDirection diag_dir = INVALID_DIAGDIR;
  1408 		DiagDirection diag_dir = INVALID_DIAGDIR;
  1407 
  1409 
  1408 		if (IsTunnelTile(tile)) {
  1410 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
  1409 			diag_dir = GetTunnelDirection(tile);
  1411 			diag_dir = GetTunnelBridgeDirection(tile);
  1410 		} else if (IsBridgeTile(tile)) {
       
  1411 			diag_dir = GetBridgeRampDirection(tile);
       
  1412 		} else if (IsTileType(tile, MP_ROAD) && GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
  1412 		} else if (IsTileType(tile, MP_ROAD) && GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
  1413 			diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
  1413 			diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
  1414 		}
  1414 		}
  1415 
  1415 
  1416 		if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR;
  1416 		if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR;
  1417 		dir = DiagdirToDiagTrackdir(diag_dir);
  1417 		dir = DiagdirToDiagTrackdir(diag_dir);
  1418 	} else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) {
  1418 	} else {
  1419 		dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
       
  1420 	} else if (prev_state < TRACKDIR_END) {
       
  1421 		if (already_reversed && prev->tile != tile) {
  1419 		if (already_reversed && prev->tile != tile) {
  1422 			/*
  1420 			/*
  1423 			 * The vehicle has reversed, but did not go straight back.
  1421 			 * The vehicle has reversed, but did not go straight back.
  1424 			 * It immediatelly turn onto another tile. This means that
  1422 			 * It immediatelly turn onto another tile. This means that
  1425 			 * the roadstate of the previous vehicle cannot be used
  1423 			 * the roadstate of the previous vehicle cannot be used
  1436 			 */
  1434 			 */
  1437 			Trackdir reversed_turn_lookup[2][DIAGDIR_END] = {
  1435 			Trackdir reversed_turn_lookup[2][DIAGDIR_END] = {
  1438 				{ TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N,  TRACKDIR_UPPER_E },
  1436 				{ TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N,  TRACKDIR_UPPER_E },
  1439 				{ TRACKDIR_RIGHT_S, TRACKDIR_LOWER_W, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S  }};
  1437 				{ TRACKDIR_RIGHT_S, TRACKDIR_LOWER_W, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S  }};
  1440 			dir = reversed_turn_lookup[prev->tile < tile ? 0 : 1][ReverseDiagDir(entry_dir)];
  1438 			dir = reversed_turn_lookup[prev->tile < tile ? 0 : 1][ReverseDiagDir(entry_dir)];
       
  1439 		} else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) {
       
  1440 			dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
       
  1441 		} else if (prev_state < TRACKDIR_END) {
       
  1442 			dir = (Trackdir)prev_state;
  1441 		} else {
  1443 		} else {
  1442 			dir = (Trackdir)prev_state;
  1444 			return INVALID_TRACKDIR;
  1443 		}
  1445 		}
  1444 	} else {
       
  1445 		return INVALID_TRACKDIR;
       
  1446 	}
  1446 	}
  1447 
  1447 
  1448 	/* Do some sanity checking. */
  1448 	/* Do some sanity checking. */
  1449 	static const RoadBits required_roadbits[] = {
  1449 	static const RoadBits required_roadbits[] = {
  1450 		ROAD_X,            ROAD_Y,            ROAD_NW | ROAD_NE, ROAD_SW | ROAD_SE,
  1450 		ROAD_X,            ROAD_Y,            ROAD_NW | ROAD_NE, ROAD_SW | ROAD_SE,
  1459 	return dir;
  1459 	return dir;
  1460 }
  1460 }
  1461 
  1461 
  1462 /**
  1462 /**
  1463  * Can a tram track build without destruction on the given tile?
  1463  * Can a tram track build without destruction on the given tile?
       
  1464  * @param p the player that would be building the tram tracks
  1464  * @param t the tile to build on.
  1465  * @param t the tile to build on.
       
  1466  * @param r the road bits needed.
  1465  * @return true when a track track can be build on 't'
  1467  * @return true when a track track can be build on 't'
  1466  */
  1468  */
  1467 static bool CanBuildTramTrackOnTile(TileIndex t)
  1469 static bool CanBuildTramTrackOnTile(PlayerID p, TileIndex t, RoadBits r)
  1468 {
  1470 {
  1469 	switch (GetTileType(t)) {
  1471 	/* The 'current' player is not necessarily the owner of the vehicle. */
  1470 		case MP_CLEAR:
  1472 	PlayerID original_player = _current_player;
  1471 		case MP_TREES:
  1473 	_current_player = p;
  1472 			return true;
  1474 
  1473 
  1475 	CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, 0, CMD_BUILD_ROAD);
  1474 		case MP_ROAD:
  1476 
  1475 			return GetRoadTileType(t) == ROAD_TILE_NORMAL;
  1477 	_current_player = original_player;
  1476 
  1478 	return CmdSucceeded(ret);
  1477 		case MP_WATER:
       
  1478 			return IsCoast(t);
       
  1479 
       
  1480 		default:
       
  1481 			return false;
       
  1482 	}
       
  1483 }
  1479 }
  1484 
  1480 
  1485 static bool IndividualRoadVehicleController(Vehicle *v, const Vehicle *prev)
  1481 static bool IndividualRoadVehicleController(Vehicle *v, const Vehicle *prev)
  1486 {
  1482 {
  1487 	Direction new_dir;
  1483 	Direction new_dir;
  1489 	RoadDriveEntry rd;
  1485 	RoadDriveEntry rd;
  1490 	int x,y;
  1486 	int x,y;
  1491 	uint32 r;
  1487 	uint32 r;
  1492 
  1488 
  1493 	if (v->u.road.overtaking != 0)  {
  1489 	if (v->u.road.overtaking != 0)  {
  1494 		if (++v->u.road.overtaking_ctr >= 35)
  1490 		if (IsTileType(v->tile, MP_STATION)) {
       
  1491 			/* Force us to be not overtaking! */
       
  1492 			v->u.road.overtaking = 0;
       
  1493 		} else if (++v->u.road.overtaking_ctr >= 35) {
  1495 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
  1494 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
  1496 			 *  if the vehicle started a corner. To protect that, only allow an abort of
  1495 			 *  if the vehicle started a corner. To protect that, only allow an abort of
  1497 			 *  overtake if we are on straight roads */
  1496 			 *  overtake if we are on straight roads */
  1498 			if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) {
  1497 			if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) {
  1499 				v->u.road.overtaking = 0;
  1498 				v->u.road.overtaking = 0;
  1500 			}
  1499 			}
       
  1500 		}
  1501 	}
  1501 	}
  1502 
  1502 
  1503 	/* If this vehicle is in a depot and we've reached this point it must be
  1503 	/* If this vehicle is in a depot and we've reached this point it must be
  1504 	 * one of the articulated parts. It will stay in the depot until activated
  1504 	 * one of the articulated parts. It will stay in the depot until activated
  1505 	 * by the previous vehicle in the chain when it gets to the right place. */
  1505 	 * by the previous vehicle in the chain when it gets to the right place. */
  1510 
  1510 
  1511 	if (v->u.road.state == RVSB_WORMHOLE) {
  1511 	if (v->u.road.state == RVSB_WORMHOLE) {
  1512 		/* Vehicle is entering a depot or is on a bridge or in a tunnel */
  1512 		/* Vehicle is entering a depot or is on a bridge or in a tunnel */
  1513 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  1513 		GetNewVehiclePosResult gp = GetNewVehiclePos(v);
  1514 
  1514 
  1515 		const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
  1515 		if (IsRoadVehFront(v)) {
  1516 		if (u != NULL && u->First()->cur_speed < v->cur_speed) {
  1516 			const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
  1517 			v->cur_speed = u->First()->cur_speed;
  1517 			if (u != NULL) {
  1518 			return false;
  1518 				v->cur_speed = u->First()->cur_speed;
       
  1519 				return false;
       
  1520 			}
  1519 		}
  1521 		}
  1520 
  1522 
  1521 		if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  1523 		if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
  1522 			/* Vehicle has just entered a bridge or tunnel */
  1524 			/* Vehicle has just entered a bridge or tunnel */
  1523 			v->cur_image = v->GetImage(v->direction);
  1525 			v->cur_image = v->GetImage(v->direction);
  1587 					 *   doing a reversing turn when the piece of tram track on the next
  1589 					 *   doing a reversing turn when the piece of tram track on the next
  1588 					 *   tile did not exist yet. Do not use the big tram loop as that is
  1590 					 *   tile did not exist yet. Do not use the big tram loop as that is
  1589 					 *   going to cause the tram to split up.
  1591 					 *   going to cause the tram to split up.
  1590 					 * - Or the front of the tram can drive over the next tile.
  1592 					 * - Or the front of the tram can drive over the next tile.
  1591 					 */
  1593 					 */
  1592 				} else if (!IsRoadVehFront(v) || !CanBuildTramTrackOnTile(tile)) {
  1594 				} else if (!IsRoadVehFront(v) || !CanBuildTramTrackOnTile(v->owner, tile, needed)) {
  1593 					/*
  1595 					/*
  1594 					 * Taking the 'small' corner for trams only happens when:
  1596 					 * Taking the 'small' corner for trams only happens when:
  1595 					 * - We are not the from vehicle of an articulated tram.
  1597 					 * - We are not the from vehicle of an articulated tram.
  1596 					 * - Or when the player cannot build on the next tile.
  1598 					 * - Or when the player cannot build on the next tile.
  1597 					 *
  1599 					 *
  1888 			DEBUG(ms, 2, " force a slot clearing");
  1890 			DEBUG(ms, 2, " force a slot clearing");
  1889 			ClearSlot(v);
  1891 			ClearSlot(v);
  1890 		}
  1892 		}
  1891 
  1893 
  1892 		StartRoadVehSound(v);
  1894 		StartRoadVehSound(v);
  1893 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1895 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1894 	}
  1896 	}
  1895 
  1897 
  1896 	/* Check tile position conditions - i.e. stop position in depot,
  1898 	/* Check tile position conditions - i.e. stop position in depot,
  1897 	 * entry onto bridge or into tunnel */
  1899 	 * entry onto bridge or into tunnel */
  1898 	r = VehicleEnterTile(v, v->tile, x, y);
  1900 	r = VehicleEnterTile(v, v->tile, x, y);
  1979 
  1981 
  1980 	if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
  1982 	if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) {
  1981 		if (v->current_order.type == OT_GOTO_DEPOT) {
  1983 		if (v->current_order.type == OT_GOTO_DEPOT) {
  1982 			v->current_order.type = OT_DUMMY;
  1984 			v->current_order.type = OT_DUMMY;
  1983 			v->current_order.flags = 0;
  1985 			v->current_order.flags = 0;
  1984 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  1986 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  1985 		}
  1987 		}
  1986 		return;
  1988 		return;
  1987 	}
  1989 	}
  1988 
  1990 
  1989 	if (v->current_order.type == OT_GOTO_DEPOT &&
  1991 	if (v->current_order.type == OT_GOTO_DEPOT &&
  1990 			v->current_order.flags & OF_NON_STOP &&
  1992 			v->current_order.flags & OFB_NON_STOP &&
  1991 			!Chance16(1, 20)) {
  1993 			!Chance16(1, 20)) {
  1992 		return;
  1994 		return;
  1993 	}
  1995 	}
  1994 
  1996 
  1995 	if (v->current_order.type == OT_LOADING) v->LeaveStation();
  1997 	if (v->current_order.type == OT_LOADING) v->LeaveStation();
  1996 	ClearSlot(v);
  1998 	ClearSlot(v);
  1997 
  1999 
  1998 	v->current_order.type = OT_GOTO_DEPOT;
  2000 	v->current_order.type = OT_GOTO_DEPOT;
  1999 	v->current_order.flags = OF_NON_STOP;
  2001 	v->current_order.flags = OFB_NON_STOP;
  2000 	v->current_order.dest = depot->index;
  2002 	v->current_order.dest = depot->index;
  2001 	v->dest_tile = depot->xy;
  2003 	v->dest_tile = depot->xy;
  2002 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
  2004 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
  2003 }
  2005 }
  2004 
  2006 
  2005 void OnNewDay_RoadVeh(Vehicle *v)
  2007 void OnNewDay_RoadVeh(Vehicle *v)
  2006 {
  2008 {
  2007 	CommandCost cost;
  2009 	CommandCost cost(EXPENSES_ROADVEH_RUN);
  2008 
  2010 
  2009 	if (!IsRoadVehFront(v)) return;
  2011 	if (!IsRoadVehFront(v)) return;
  2010 
  2012 
  2011 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  2013 	if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v);
  2012 	if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v);
  2014 	if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v);
  2082 			DEBUG(ms, 4, "No road stop for vehicle %d (index %d) at station %d (0x%X)",
  2084 			DEBUG(ms, 4, "No road stop for vehicle %d (index %d) at station %d (0x%X)",
  2083 					v->unitnumber, v->index, st->index, st->xy);
  2085 					v->unitnumber, v->index, st->index, st->xy);
  2084 		}
  2086 		}
  2085 	}
  2087 	}
  2086 
  2088 
  2087 	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
  2089 	cost = CommandCost(EXPENSES_ROADVEH_RUN, RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364);
  2088 
  2090 
  2089 	v->profit_this_year -= cost.GetCost() >> 8;
  2091 	v->profit_this_year -= cost.GetCost() >> 8;
  2090 
  2092 
  2091 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
  2093 	SubtractMoneyFromPlayerFract(v->owner, cost);
  2092 	SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
       
  2093 
  2094 
  2094 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  2095 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  2095 	InvalidateWindowClasses(WC_ROADVEH_LIST);
  2096 	InvalidateWindowClasses(WC_ROADVEH_LIST);
  2096 }
  2097 }
  2097 
  2098 
  2120  * @return cost of refit or error
  2121  * @return cost of refit or error
  2121  */
  2122  */
  2122 CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2123 CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
  2123 {
  2124 {
  2124 	Vehicle *v;
  2125 	Vehicle *v;
  2125 	CommandCost cost;
  2126 	CommandCost cost(EXPENSES_ROADVEH_RUN);
  2126 	CargoID new_cid = GB(p2, 0, 8);
  2127 	CargoID new_cid = GB(p2, 0, 8);
  2127 	byte new_subtype = GB(p2, 8, 8);
  2128 	byte new_subtype = GB(p2, 8, 8);
  2128 	bool only_this = HasBit(p2, 16);
  2129 	bool only_this = HasBit(p2, 16);
  2129 	uint16 capacity = CALLBACK_FAILED;
  2130 	uint16 capacity = CALLBACK_FAILED;
  2130 	uint total_capacity = 0;
  2131 	uint total_capacity = 0;
  2133 
  2134 
  2134 	v = GetVehicle(p1);
  2135 	v = GetVehicle(p1);
  2135 
  2136 
  2136 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
  2137 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
  2137 	if (!CheckRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
  2138 	if (!CheckRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
       
  2139 	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_REFIT_DESTROYED_VEHICLE);
  2138 
  2140 
  2139 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
  2141 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
  2140 
       
  2141 	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
       
  2142 
  2142 
  2143 	for (; v != NULL; v = v->Next()) {
  2143 	for (; v != NULL; v = v->Next()) {
  2144 		/* XXX: We refit all the attached wagons en-masse if they can be
  2144 		/* XXX: We refit all the attached wagons en-masse if they can be
  2145 		 * refitted. This is how TTDPatch does it.  TODO: Have some nice
  2145 		 * refitted. This is how TTDPatch does it.  TODO: Have some nice
  2146 		 * [Refit] button near each wagon. */
  2146 		 * [Refit] button near each wagon. */