src/vehicle.cpp
branchNewGRF_ports
changeset 10991 d8811e327d12
parent 10731 67db0d431d5e
child 10994 cd9968b6f96b
equal deleted inserted replaced
10731:67db0d431d5e 10991:d8811e327d12
    23 #include "train.h"
    23 #include "train.h"
    24 #include "aircraft.h"
    24 #include "aircraft.h"
    25 #include "industry_map.h"
    25 #include "industry_map.h"
    26 #include "station_map.h"
    26 #include "station_map.h"
    27 #include "water_map.h"
    27 #include "water_map.h"
    28 #include "network/network.h"
       
    29 #include "yapf/yapf.h"
    28 #include "yapf/yapf.h"
    30 #include "newgrf_callbacks.h"
    29 #include "newgrf_callbacks.h"
    31 #include "newgrf_engine.h"
    30 #include "newgrf_engine.h"
    32 #include "newgrf_sound.h"
    31 #include "newgrf_sound.h"
    33 #include "newgrf_station.h"
    32 #include "newgrf_station.h"
    49 #include "oldpool_func.h"
    48 #include "oldpool_func.h"
    50 #include "depot_map.h"
    49 #include "depot_map.h"
    51 #include "animated_tile_func.h"
    50 #include "animated_tile_func.h"
    52 #include "effectvehicle_base.h"
    51 #include "effectvehicle_base.h"
    53 #include "core/alloc_func.hpp"
    52 #include "core/alloc_func.hpp"
       
    53 #include "vehiclelist.h"
    54 
    54 
    55 #include "table/sprites.h"
    55 #include "table/sprites.h"
    56 #include "table/strings.h"
    56 #include "table/strings.h"
    57 
    57 
    58 #define INVALID_COORD (0x7fffffff)
    58 #define INVALID_COORD (0x7fffffff)
   125 
   125 
   126 bool Vehicle::NeedsServicing() const
   126 bool Vehicle::NeedsServicing() const
   127 {
   127 {
   128 	if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
   128 	if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
   129 
   129 
   130 	if (_settings.order.no_servicing_if_no_breakdowns && _settings.difficulty.vehicle_breakdowns == 0) {
   130 	if (_settings_game.order.no_servicing_if_no_breakdowns && _settings_game.difficulty.vehicle_breakdowns == 0) {
   131 		/* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off.
   131 		/* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off.
   132 		 * Note: If servicing is enabled, we postpone replacement till next service. */
   132 		 * Note: If servicing is enabled, we postpone replacement till next service. */
   133 		return EngineHasReplacementForPlayer(GetPlayer(this->owner), this->engine_type, this->group_id);
   133 		return EngineHasReplacementForPlayer(GetPlayer(this->owner), this->engine_type, this->group_id);
   134 	}
   134 	}
   135 
   135 
   136 	return _settings.vehicle.servint_ispercent ?
   136 	return _settings_game.vehicle.servint_ispercent ?
   137 		(this->reliability < GetEngine(this->engine_type)->reliability * (100 - this->service_interval) / 100) :
   137 		(this->reliability < GetEngine(this->engine_type)->reliability * (100 - this->service_interval) / 100) :
   138 		(this->date_of_last_service + this->service_interval < _date);
   138 		(this->date_of_last_service + this->service_interval < _date);
   139 }
   139 }
   140 
   140 
   141 bool Vehicle::NeedsAutomaticServicing() const
   141 bool Vehicle::NeedsAutomaticServicing() const
   142 {
   142 {
   143 	if (_settings.order.gotodepot && VehicleHasDepotOrders(this)) return false;
   143 	if (_settings_game.order.gotodepot && VehicleHasDepotOrders(this)) return false;
   144 	if (this->current_order.IsType(OT_LOADING))            return false;
   144 	if (this->current_order.IsType(OT_LOADING))            return false;
   145 	if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
   145 	if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
   146 	return NeedsServicing();
   146 	return NeedsServicing();
   147 }
   147 }
   148 
   148 
   911 	/* decrease reliability */
   911 	/* decrease reliability */
   912 	v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
   912 	v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
   913 	if ((rel_old >> 8) != (rel >> 8)) InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   913 	if ((rel_old >> 8) != (rel >> 8)) InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
   914 
   914 
   915 	if (v->breakdown_ctr != 0 || v->vehstatus & VS_STOPPED ||
   915 	if (v->breakdown_ctr != 0 || v->vehstatus & VS_STOPPED ||
   916 			_settings.difficulty.vehicle_breakdowns < 1 ||
   916 			_settings_game.difficulty.vehicle_breakdowns < 1 ||
   917 			v->cur_speed < 5 || _game_mode == GM_MENU) {
   917 			v->cur_speed < 5 || _game_mode == GM_MENU) {
   918 		return;
   918 		return;
   919 	}
   919 	}
   920 
   920 
   921 	uint32 r = Random();
   921 	uint32 r = Random();
   928 	/* calculate reliability value to use in comparison */
   928 	/* calculate reliability value to use in comparison */
   929 	rel = v->reliability;
   929 	rel = v->reliability;
   930 	if (v->type == VEH_SHIP) rel += 0x6666;
   930 	if (v->type == VEH_SHIP) rel += 0x6666;
   931 
   931 
   932 	/* reduced breakdowns? */
   932 	/* reduced breakdowns? */
   933 	if (_settings.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
   933 	if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
   934 
   934 
   935 	/* check if to break down */
   935 	/* check if to break down */
   936 	if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
   936 	if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
   937 		v->breakdown_ctr    = GB(r, 16, 6) + 0x3F;
   937 		v->breakdown_ctr    = GB(r, 16, 6) + 0x3F;
   938 		v->breakdown_delay  = GB(r, 24, 7) + 0x80;
   938 		v->breakdown_delay  = GB(r, 24, 7) + 0x80;
  1290 
  1290 
  1291 	return total_cost;
  1291 	return total_cost;
  1292 }
  1292 }
  1293 
  1293 
  1294 /**
  1294 /**
  1295  * Generate a list of vehicles inside a depot.
       
  1296  * @param type    Type of vehicle
       
  1297  * @param tile    The tile the depot is located on
       
  1298  * @param engines Pointer to list to add vehicles to
       
  1299  * @param wagons  Pointer to list to add wagons to (can be NULL)
       
  1300  */
       
  1301 void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons)
       
  1302 {
       
  1303 	engines->Clear();
       
  1304 	if (wagons != NULL && wagons != engines) wagons->Clear();
       
  1305 
       
  1306 	const Vehicle *v;
       
  1307 	FOR_ALL_VEHICLES(v) {
       
  1308 		/* General tests for all vehicle types */
       
  1309 		if (v->type != type) continue;
       
  1310 		if (v->tile != tile) continue;
       
  1311 
       
  1312 		switch (type) {
       
  1313 			case VEH_TRAIN:
       
  1314 				if (v->u.rail.track != TRACK_BIT_DEPOT) continue;
       
  1315 				if (wagons != NULL && IsFreeWagon(v)) {
       
  1316 					*wagons->Append() = v;
       
  1317 					continue;
       
  1318 				}
       
  1319 				break;
       
  1320 
       
  1321 			default:
       
  1322 				if (!v->IsInDepot()) continue;
       
  1323 				break;
       
  1324 		}
       
  1325 
       
  1326 		if (!v->IsPrimaryVehicle()) continue;
       
  1327 
       
  1328 		*engines->Append() = v;
       
  1329 	}
       
  1330 
       
  1331 	/* Ensure the lists are not wasting too much space. If the lists are fresh
       
  1332 	 * (i.e. built within a command) then this will actually do nothing. */
       
  1333 	engines->Compact();
       
  1334 	if (wagons != NULL && wagons != engines) wagons->Compact();
       
  1335 }
       
  1336 
       
  1337 /**
       
  1338  * Generate a list of vehicles based on window type.
       
  1339  * @param list        Pointer to list to add vehicles to
       
  1340  * @param type        Type of vehicle
       
  1341  * @param owner       Player to generate list for
       
  1342  * @param index       This parameter has different meanings depending on window_type
       
  1343  *    <ul>
       
  1344  *      <li>VLW_STATION_LIST:  index of station to generate a list for</li>
       
  1345  *      <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
       
  1346  *      <li>VLW_STANDARD: not used<li>
       
  1347  *      <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
       
  1348  *      <li>VLW_GROUP_LIST: index of group to generate a list for</li>
       
  1349  *    </ul>
       
  1350  * @param window_type The type of window the list is for, using the VLW_ flags in vehicle_gui.h
       
  1351  */
       
  1352 void GenerateVehicleSortList(VehicleList *list, VehicleType type, PlayerID owner, uint32 index, uint16 window_type)
       
  1353 {
       
  1354 	list->Clear();
       
  1355 
       
  1356 	const Vehicle *v;
       
  1357 
       
  1358 	switch (window_type) {
       
  1359 		case VLW_STATION_LIST:
       
  1360 			FOR_ALL_VEHICLES(v) {
       
  1361 				if (v->type == type && v->IsPrimaryVehicle()) {
       
  1362 					const Order *order;
       
  1363 
       
  1364 					FOR_VEHICLE_ORDERS(v, order) {
       
  1365 						if (order->IsType(OT_GOTO_STATION) && order->GetDestination() == index) {
       
  1366 							*list->Append() = v;
       
  1367 							break;
       
  1368 						}
       
  1369 					}
       
  1370 				}
       
  1371 			}
       
  1372 			break;
       
  1373 
       
  1374 		case VLW_SHARED_ORDERS:
       
  1375 			FOR_ALL_VEHICLES(v) {
       
  1376 				/* Find a vehicle with the order in question */
       
  1377 				if (v->orders != NULL && v->orders->index == index) {
       
  1378 					/* Add all vehicles from this vehicle's shared order list */
       
  1379 					for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
       
  1380 						*list->Append() = v;
       
  1381 					}
       
  1382 					break;
       
  1383 				}
       
  1384 			}
       
  1385 			break;
       
  1386 
       
  1387 		case VLW_STANDARD:
       
  1388 			FOR_ALL_VEHICLES(v) {
       
  1389 				if (v->type == type && v->owner == owner && v->IsPrimaryVehicle()) {
       
  1390 					*list->Append() = v;
       
  1391 				}
       
  1392 			}
       
  1393 			break;
       
  1394 
       
  1395 		case VLW_DEPOT_LIST:
       
  1396 			FOR_ALL_VEHICLES(v) {
       
  1397 				if (v->type == type && v->IsPrimaryVehicle()) {
       
  1398 					const Order *order;
       
  1399 
       
  1400 					FOR_VEHICLE_ORDERS(v, order) {
       
  1401 						if (order->IsType(OT_GOTO_DEPOT) && order->GetDestination() == index) {
       
  1402 							*list->Append() = v;
       
  1403 							break;
       
  1404 						}
       
  1405 					}
       
  1406 				}
       
  1407 			}
       
  1408 			break;
       
  1409 
       
  1410 		case VLW_GROUP_LIST:
       
  1411 			FOR_ALL_VEHICLES(v) {
       
  1412 				if (v->type == type && v->IsPrimaryVehicle() &&
       
  1413 						v->owner == owner && v->group_id == index) {
       
  1414 					*list->Append() = v;
       
  1415 				}
       
  1416 			}
       
  1417 			break;
       
  1418 
       
  1419 		default: NOT_REACHED(); break;
       
  1420 	}
       
  1421 
       
  1422 	list->Compact();
       
  1423 }
       
  1424 
       
  1425 /**
       
  1426  * Send all vehicles of type to depots
  1295  * Send all vehicles of type to depots
  1427  * @param type type of vehicle
  1296  * @param type type of vehicle
  1428  * @param flags the flags used for DoCommand()
  1297  * @param flags the flags used for DoCommand()
  1429  * @param service should the vehicles only get service in the depots
  1298  * @param service should the vehicles only get service in the depots
  1430  * @param owner PlayerID of owner of the vehicles to send
  1299  * @param owner PlayerID of owner of the vehicles to send
  1824 	const Vehicle *u;
  1693 	const Vehicle *u;
  1825 	static bool *cache = NULL;
  1694 	static bool *cache = NULL;
  1826 	static UnitID gmax = 0;
  1695 	static UnitID gmax = 0;
  1827 
  1696 
  1828 	switch (type) {
  1697 	switch (type) {
  1829 		case VEH_TRAIN:    max = _settings.vehicle.max_trains; break;
  1698 		case VEH_TRAIN:    max = _settings_game.vehicle.max_trains; break;
  1830 		case VEH_ROAD:     max = _settings.vehicle.max_roadveh; break;
  1699 		case VEH_ROAD:     max = _settings_game.vehicle.max_roadveh; break;
  1831 		case VEH_SHIP:     max = _settings.vehicle.max_ships; break;
  1700 		case VEH_SHIP:     max = _settings_game.vehicle.max_ships; break;
  1832 		case VEH_AIRCRAFT: max = _settings.vehicle.max_aircraft; break;
  1701 		case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
  1833 		default: NOT_REACHED();
  1702 		default: NOT_REACHED();
  1834 	}
  1703 	}
  1835 
  1704 
  1836 	if (max == 0) {
  1705 	if (max == 0) {
  1837 		/* we can't build any of this kind of vehicle, so we just return 1 instead of looking for a free number
  1706 		/* we can't build any of this kind of vehicle, so we just return 1 instead of looking for a free number
  1877 bool CanBuildVehicleInfrastructure(VehicleType type)
  1746 bool CanBuildVehicleInfrastructure(VehicleType type)
  1878 {
  1747 {
  1879 	assert(IsPlayerBuildableVehicleType(type));
  1748 	assert(IsPlayerBuildableVehicleType(type));
  1880 
  1749 
  1881 	if (!IsValidPlayer(_current_player)) return false;
  1750 	if (!IsValidPlayer(_current_player)) return false;
  1882 	if (_settings.gui.always_build_infrastructure) return true;
  1751 	if (_settings_client.gui.always_build_infrastructure) return true;
  1883 
  1752 
  1884 	UnitID max;
  1753 	UnitID max;
  1885 	switch (type) {
  1754 	switch (type) {
  1886 		case VEH_TRAIN:    max = _settings.vehicle.max_trains; break;
  1755 		case VEH_TRAIN:    max = _settings_game.vehicle.max_trains; break;
  1887 		case VEH_ROAD:     max = _settings.vehicle.max_roadveh; break;
  1756 		case VEH_ROAD:     max = _settings_game.vehicle.max_roadveh; break;
  1888 		case VEH_SHIP:     max = _settings.vehicle.max_ships; break;
  1757 		case VEH_SHIP:     max = _settings_game.vehicle.max_ships; break;
  1889 		case VEH_AIRCRAFT: max = _settings.vehicle.max_aircraft; break;
  1758 		case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
  1890 		default: NOT_REACHED();
  1759 		default: NOT_REACHED();
  1891 	}
  1760 	}
  1892 
  1761 
  1893 	/* We can build vehicle infrastructure when we may build the vehicle type */
  1762 	/* We can build vehicle infrastructure when we may build the vehicle type */
  1894 	if (max > 0) {
  1763 	if (max > 0) {
  1916 	LiveryScheme scheme = LS_DEFAULT;
  1785 	LiveryScheme scheme = LS_DEFAULT;
  1917 	CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
  1786 	CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
  1918 
  1787 
  1919 	/* The default livery is always available for use, but its in_use flag determines
  1788 	/* The default livery is always available for use, but its in_use flag determines
  1920 	 * whether any _other_ liveries are in use. */
  1789 	 * whether any _other_ liveries are in use. */
  1921 	if (p->livery[LS_DEFAULT].in_use && (_settings.gui.liveries == 2 || (_settings.gui.liveries == 1 && player == _local_player))) {
  1790 	if (p->livery[LS_DEFAULT].in_use && (_settings_client.gui.liveries == 2 || (_settings_client.gui.liveries == 1 && player == _local_player))) {
  1922 		/* Determine the livery scheme to use */
  1791 		/* Determine the livery scheme to use */
  1923 		switch (GetEngine(engine_type)->type) {
  1792 		switch (GetEngine(engine_type)->type) {
  1924 			default: NOT_REACHED();
  1793 			default: NOT_REACHED();
  1925 			case VEH_TRAIN: {
  1794 			case VEH_TRAIN: {
  1926 				const RailVehicleInfo *rvi = RailVehInfo(engine_type);
  1795 				const RailVehicleInfo *rvi = RailVehInfo(engine_type);
  2485 		case OT_LOADING: {
  2354 		case OT_LOADING: {
  2486 			uint wait_time = max(this->current_order.wait_time - this->lateness_counter, 0);
  2355 			uint wait_time = max(this->current_order.wait_time - this->lateness_counter, 0);
  2487 
  2356 
  2488 			/* Not the first call for this tick, or still loading */
  2357 			/* Not the first call for this tick, or still loading */
  2489 			if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) ||
  2358 			if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) ||
  2490 					(_settings.order.timetabling && this->current_order_time < wait_time)) return;
  2359 					(_settings_game.order.timetabling && this->current_order_time < wait_time)) return;
  2491 
  2360 
  2492 			this->PlayLeaveStationSound();
  2361 			this->PlayLeaveStationSound();
  2493 
  2362 
  2494 			bool at_destination_station = this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE;
  2363 			bool at_destination_station = this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE;
  2495 			this->LeaveStation();
  2364 			this->LeaveStation();