src/roadveh_cmd.cpp
branchNewGRF_ports
changeset 10731 67db0d431d5e
parent 10724 68a692eacf22
child 10991 d8811e327d12
equal deleted inserted replaced
10724:68a692eacf22 10731:67db0d431d5e
   203 
   203 
   204 	v = vl[0];
   204 	v = vl[0];
   205 
   205 
   206 	/* find the first free roadveh id */
   206 	/* find the first free roadveh id */
   207 	unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD);
   207 	unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD);
   208 	if (unit_num > _patches.max_roadveh)
   208 	if (unit_num > _settings.vehicle.max_roadveh)
   209 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   209 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
   210 
   210 
   211 	if (flags & DC_EXEC) {
   211 	if (flags & DC_EXEC) {
   212 		int x;
   212 		int x;
   213 		int y;
   213 		int y;
   255 		v->max_age = e->lifelength * 366;
   255 		v->max_age = e->lifelength * 366;
   256 		_new_vehicle_id = v->index;
   256 		_new_vehicle_id = v->index;
   257 
   257 
   258 		v->name = NULL;
   258 		v->name = NULL;
   259 
   259 
   260 		v->service_interval = _patches.servint_roadveh;
   260 		v->service_interval = _settings.vehicle.servint_roadveh;
   261 
   261 
   262 		v->date_of_last_service = _date;
   262 		v->date_of_last_service = _date;
   263 		v->build_year = _cur_year;
   263 		v->build_year = _cur_year;
   264 
   264 
   265 		v->cur_image = 0xC15;
   265 		v->cur_image = 0xC15;
   278 		AddArticulatedParts(vl, VEH_ROAD);
   278 		AddArticulatedParts(vl, VEH_ROAD);
   279 
   279 
   280 		VehiclePositionChanged(v);
   280 		VehiclePositionChanged(v);
   281 
   281 
   282 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   282 		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
   283 		RebuildVehicleLists();
   283 		InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
   284 		InvalidateWindow(WC_COMPANY, v->owner);
   284 		InvalidateWindow(WC_COMPANY, v->owner);
   285 		if (IsLocalPlayer())
   285 		if (IsLocalPlayer())
   286 			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
   286 			InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
   287 
   287 
   288 		GetPlayer(_current_player)->num_engines[p1]++;
   288 		GetPlayer(_current_player)->num_engines[p1]++;
   379 	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
   379 	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
   380 
   380 
   381 	if (flags & DC_EXEC) {
   381 	if (flags & DC_EXEC) {
   382 		// Invalidate depot
   382 		// Invalidate depot
   383 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   383 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
   384 		RebuildVehicleLists();
   384 		InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
   385 		InvalidateWindow(WC_COMPANY, v->owner);
   385 		InvalidateWindow(WC_COMPANY, v->owner);
   386 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   386 		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   387 		DeleteDepotHighlightOfVehicle(v);
   387 		DeleteDepotHighlightOfVehicle(v);
   388 		delete v;
   388 		delete v;
   389 	}
   389 	}
   417 	return false;
   417 	return false;
   418 }
   418 }
   419 
   419 
   420 static const Depot* FindClosestRoadDepot(const Vehicle* v)
   420 static const Depot* FindClosestRoadDepot(const Vehicle* v)
   421 {
   421 {
   422 	switch (_patches.pathfinder_for_roadvehs) {
   422 	switch (_settings.pf.pathfinder_for_roadvehs) {
   423 		case VPF_YAPF: /* YAPF */
   423 		case VPF_YAPF: /* YAPF */
   424 			return YapfFindNearestRoadDepot(v);
   424 			return YapfFindNearestRoadDepot(v);
   425 
   425 
   426 		case VPF_NPF: { /* NPF */
   426 		case VPF_NPF: { /* NPF */
   427 			/* See where we are now */
   427 			/* See where we are now */
   572 	for (; v->Next() != NULL; v = v->Next()) u = v;
   572 	for (; v->Next() != NULL; v = v->Next()) u = v;
   573 	u->SetNext(NULL);
   573 	u->SetNext(NULL);
   574 
   574 
   575 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   575 	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
   576 
   576 
   577 	RebuildVehicleLists();
   577 	InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
   578 	InvalidateWindow(WC_COMPANY, v->owner);
   578 	InvalidateWindow(WC_COMPANY, v->owner);
   579 
   579 
   580 	if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
   580 	if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
   581 
   581 
   582 	MarkSingleVehicleDirty(v);
   582 	MarkSingleVehicleDirty(v);
   700 
   700 
   701 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
   701 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
   702 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   702 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   703 
   703 
   704 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
   704 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
   705 			SndPlayVehicleFx((_opt.landscape != LT_TOYLAND) ?
   705 			SndPlayVehicleFx((_settings.game_creation.landscape != LT_TOYLAND) ?
   706 				SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
   706 				SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
   707 		}
   707 		}
   708 
   708 
   709 		if (!(v->vehstatus & VS_HIDDEN)) {
   709 		if (!(v->vehstatus & VS_HIDDEN)) {
   710 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
   710 			Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE);
   861 	}
   861 	}
   862 
   862 
   863 	/* updates statusbar only if speed have changed to save CPU time */
   863 	/* updates statusbar only if speed have changed to save CPU time */
   864 	if (spd != v->cur_speed) {
   864 	if (spd != v->cur_speed) {
   865 		v->cur_speed = spd;
   865 		v->cur_speed = spd;
   866 		if (_patches.vehicle_speed) {
   866 		if (_settings.gui.vehicle_speed) {
   867 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   867 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
   868 		}
   868 		}
   869 	}
   869 	}
   870 
   870 
   871 	/* Decrease somewhat when turning */
   871 	/* Decrease somewhat when turning */
  1083 			if (GetRoadStopType(tile) != rstype) {
  1083 			if (GetRoadStopType(tile) != rstype) {
  1084 				/* Wrong station type */
  1084 				/* Wrong station type */
  1085 				trackdirs = TRACKDIR_BIT_NONE;
  1085 				trackdirs = TRACKDIR_BIT_NONE;
  1086 			} else {
  1086 			} else {
  1087 				/* Proper station type, check if there is free loading bay */
  1087 				/* Proper station type, check if there is free loading bay */
  1088 				if (!_patches.roadveh_queue && IsStandardRoadStopTile(tile) &&
  1088 				if (!_settings.pf.roadveh_queue && IsStandardRoadStopTile(tile) &&
  1089 						!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
  1089 						!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
  1090 					/* Station is full and RV queuing is off */
  1090 					/* Station is full and RV queuing is off */
  1091 					trackdirs = TRACKDIR_BIT_NONE;
  1091 					trackdirs = TRACKDIR_BIT_NONE;
  1092 				}
  1092 				}
  1093 			}
  1093 			}
  1122 	/* Only one track to choose between? */
  1122 	/* Only one track to choose between? */
  1123 	if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) {
  1123 	if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) {
  1124 		return_track(FindFirstBit2x64(trackdirs));
  1124 		return_track(FindFirstBit2x64(trackdirs));
  1125 	}
  1125 	}
  1126 
  1126 
  1127 	switch (_patches.pathfinder_for_roadvehs) {
  1127 	switch (_settings.pf.pathfinder_for_roadvehs) {
  1128 		case VPF_YAPF: { /* YAPF */
  1128 		case VPF_YAPF: { /* YAPF */
  1129 			Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
  1129 			Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
  1130 			if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
  1130 			if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
  1131 			return_track(PickRandomBit(trackdirs));
  1131 			return_track(PickRandomBit(trackdirs));
  1132 		} break;
  1132 		} break;
  1209 	return best_track;
  1209 	return best_track;
  1210 }
  1210 }
  1211 
  1211 
  1212 static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
  1212 static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
  1213 {
  1213 {
  1214 	if (_patches.pathfinder_for_roadvehs == VPF_YAPF) {
  1214 	if (_settings.pf.pathfinder_for_roadvehs == VPF_YAPF) {
  1215 		/* use YAPF */
  1215 		/* use YAPF */
  1216 		return YapfRoadVehDistanceToTile(v, tile);
  1216 		return YapfRoadVehDistanceToTile(v, tile);
  1217 	}
  1217 	}
  1218 
  1218 
  1219 	/* use NPF */
  1219 	/* use NPF */
  1271 
  1271 
  1272 	DiagDirection dir = GetRoadDepotDirection(v->tile);
  1272 	DiagDirection dir = GetRoadDepotDirection(v->tile);
  1273 	v->direction = DiagDirToDir(dir);
  1273 	v->direction = DiagDirToDir(dir);
  1274 
  1274 
  1275 	Trackdir tdir = _roadveh_depot_exit_trackdir[dir];
  1275 	Trackdir tdir = _roadveh_depot_exit_trackdir[dir];
  1276 	const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + tdir];
  1276 	const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_settings.vehicle.road_side << RVS_DRIVE_SIDE) + tdir];
  1277 
  1277 
  1278 	int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
  1278 	int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
  1279 	int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
  1279 	int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
  1280 
  1280 
  1281 	if (first) {
  1281 	if (first) {
  1449 	/* Get move position data for next frame.
  1449 	/* Get move position data for next frame.
  1450 	 * For a drive-through road stop use 'straight road' move data.
  1450 	 * For a drive-through road stop use 'straight road' move data.
  1451 	 * In this case v->u.road.state is masked to give the road stop entry direction. */
  1451 	 * In this case v->u.road.state is masked to give the road stop entry direction. */
  1452 	rd = _road_drive_data[v->u.road.roadtype][(
  1452 	rd = _road_drive_data[v->u.road.roadtype][(
  1453 		(HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
  1453 		(HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
  1454 		(_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
  1454 		(_settings.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
  1455 
  1455 
  1456 	if (rd.x & RDE_NEXT_TILE) {
  1456 	if (rd.x & RDE_NEXT_TILE) {
  1457 		TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3));
  1457 		TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3));
  1458 		Trackdir dir;
  1458 		Trackdir dir;
  1459 		uint32 r;
  1459 		uint32 r;
  1527 				tile = v->tile;
  1527 				tile = v->tile;
  1528 			}
  1528 			}
  1529 		}
  1529 		}
  1530 
  1530 
  1531 		/* Get position data for first frame on the new tile */
  1531 		/* Get position data for first frame on the new tile */
  1532 		rdp = _road_drive_data[v->u.road.roadtype][(dir + (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking];
  1532 		rdp = _road_drive_data[v->u.road.roadtype][(dir + (_settings.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking];
  1533 
  1533 
  1534 		x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
  1534 		x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
  1535 		y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
  1535 		y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
  1536 
  1536 
  1537 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1537 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1630 		if (dir == INVALID_TRACKDIR) {
  1630 		if (dir == INVALID_TRACKDIR) {
  1631 			v->cur_speed = 0;
  1631 			v->cur_speed = 0;
  1632 			return false;
  1632 			return false;
  1633 		}
  1633 		}
  1634 
  1634 
  1635 		rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + dir];
  1635 		rdp = _road_drive_data[v->u.road.roadtype][(_settings.vehicle.road_side << RVS_DRIVE_SIDE) + dir];
  1636 
  1636 
  1637 		x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x;
  1637 		x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x;
  1638 		y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
  1638 		y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
  1639 
  1639 
  1640 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1640 		newdir = RoadVehGetSlidingDirection(v, x, y);
  1709 	 * if the vehicle is in a drive-through road stop and this is the destination station
  1709 	 * if the vehicle is in a drive-through road stop and this is the destination station
  1710 	 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
  1710 	 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
  1711 	 * (the station test and stop type test ensure that other vehicles, using the road stop as
  1711 	 * (the station test and stop type test ensure that other vehicles, using the road stop as
  1712 	 * a through route, do not stop) */
  1712 	 * a through route, do not stop) */
  1713 	if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
  1713 	if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
  1714 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
  1714 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
  1715 			(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
  1715 			(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
  1716 			v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
  1716 			v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
  1717 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
  1717 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
  1718 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
  1718 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
  1719 
  1719 
  1885 }
  1885 }
  1886 
  1886 
  1887 static void CheckIfRoadVehNeedsService(Vehicle *v)
  1887 static void CheckIfRoadVehNeedsService(Vehicle *v)
  1888 {
  1888 {
  1889 	/* If we already got a slot at a stop, use that FIRST, and go to a depot later */
  1889 	/* If we already got a slot at a stop, use that FIRST, and go to a depot later */
  1890 	if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
  1890 	if (v->u.road.slot != NULL || _settings.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
  1891 	if (v->IsInDepot()) {
  1891 	if (v->IsInDepot()) {
  1892 		VehicleServiceInDepot(v);
  1892 		VehicleServiceInDepot(v);
  1893 		return;
  1893 		return;
  1894 	}
  1894 	}
  1895 
  1895 
  2114 			v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
  2114 			v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0);
  2115 			v->cargo_type = new_cid;
  2115 			v->cargo_type = new_cid;
  2116 			v->cargo_subtype = new_subtype;
  2116 			v->cargo_subtype = new_subtype;
  2117 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  2117 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
  2118 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  2118 			InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  2119 			RebuildVehicleLists();
  2119 			InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
  2120 		}
  2120 		}
  2121 
  2121 
  2122 		if (only_this) break;
  2122 		if (only_this) break;
  2123 	}
  2123 	}
  2124 
  2124