| 1285 | }; |
| 1286 | |
| 1287 | void CheckVehicleBreakdown(Vehicle *v) |
| 1288 | { |
| 1289 | int rel, rel_old; |
| 1290 | |
| 1291 | /* decrease reliability */ |
| 1292 | if (!_settings_game.order.no_servicing_if_no_breakdowns || |
| 1293 | _settings_game.difficulty.vehicle_breakdowns != 0) { |
| 1294 | v->reliability = rel = std::max((rel_old = v->reliability) - v->reliability_spd_dec, 0); |
| 1295 | if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index); |
| 1296 | } |
| 1297 | |
| 1298 | if (v->breakdown_ctr != 0 || v->vehstatus.Test(VehState::Stopped) || |
| 1299 | _settings_game.difficulty.vehicle_breakdowns < 1 || |
| 1300 | v->cur_speed < 5 || _game_mode == GM_MENU) { |
| 1301 | return; |
| 1302 | } |
| 1303 | |
| 1304 | uint32_t r = Random(); |
| 1305 | |
| 1306 | /* increase chance of failure */ |
| 1307 | int chance = v->breakdown_chance + 1; |
| 1308 | if (Chance16I(1, 25, r)) chance += 25; |
| 1309 | v->breakdown_chance = ClampTo<uint8_t>(chance); |
| 1310 | |
| 1311 | /* calculate reliability value to use in comparison */ |
| 1312 | rel = v->reliability; |
| 1313 | if (v->type == VEH_SHIP) rel += 0x6666; |
| 1314 | |
| 1315 | /* reduced breakdowns? */ |
| 1316 | if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666; |
| 1317 | |
| 1318 | /* check if to break down */ |
| 1319 | if (_breakdown_chance[ClampTo<uint16_t>(rel) >> 10] <= v->breakdown_chance) { |
| 1320 | v->breakdown_ctr = GB(r, 16, 6) + 0x3F; |
| 1321 | v->breakdown_delay = GB(r, 24, 7) + 0x80; |
| 1322 | v->breakdown_chance = 0; |
| 1323 | } |
| 1324 | } |
| 1325 | |
| 1326 | /** |
| 1327 | * Handle all of the aspects of a vehicle breakdown |
no test coverage detected