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(); |