diff --git a/src/lang/english.txt b/src/lang/english.txt index 15daa89471..300692a3bc 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1736,6 +1736,11 @@ STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change s STR_CONFIG_SETTING_ADJACENT_CROSSINGS :Close adjacent level crossings: {STRING2} STR_CONFIG_SETTING_ADJACENT_CROSSINGS_HELPTEXT :Closes all adjacent level crossings on parallel tracks whenever one or more is occupied +STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE :Pay for repairing vehicle: {STRING2} +STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE_HELPTEXT :Pay for repairing vehicle +STR_CONFIG_SETTING_REPAIR_COST :Cost of repairing vehicle: 1/{STRING2} of total cost +STR_CONFIG_SETTING_REPAIR_COST_HELPTEXT :Cost of repairing vehicle + # Config errors STR_CONFIG_ERROR :{WHITE}Error with the configuration file... STR_CONFIG_ERROR_ARRAY :{WHITE}... error in array '{RAW_STRING}' diff --git a/src/lang/russian.txt b/src/lang/russian.txt index ddccd9e2e9..a9220df663 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -5201,3 +5201,8 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) + +STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE :Взымать плату за починку тс: {STRING} +STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE_HELPTEXT :Если включено, в депо бужет взыматься плата за ремонт каждой поломки транспортного средства +STR_CONFIG_SETTING_REPAIR_COST :Стоимость ремонта: 1/{STRING} полной стоимости тс +STR_CONFIG_SETTING_REPAIR_COST_HELPTEXT :Стоимость ремонта одной поломки транспортного средства diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 475d204528..0f6dc84d15 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -56,6 +56,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XLSFI_IMPROVED_BREAKDOWNS, XSCF_NULL, 1, 1, "improved_breakdowns", NULL, NULL, NULL }, { XSLFI_TT_WAIT_IN_DEPOT, XSCF_NULL, 1, 1, "tt_wait_in_depot", NULL, NULL, NULL }, { XSLFI_AUTO_TIMETABLE, XSCF_NULL, 1, 1, "auto_timetables", NULL, NULL, NULL }, + { XSLFI_VEHICLE_REPAIR_COST, XSCF_NULL, 1, 1, "vehicle_repair_cost", NULL, NULL, NULL }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index c488f7d6d5..d4ded50cca 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -31,6 +31,7 @@ enum SlXvFeatureIndex { XLSFI_IMPROVED_BREAKDOWNS, ///< Improved breakdowns patch XSLFI_TT_WAIT_IN_DEPOT, ///< Timetabling waiting time in depot patch XSLFI_AUTO_TIMETABLE, ///< Auto timetables and separation patch + XSLFI_VEHICLE_REPAIR_COST, ///< Vehicle repair costs patch XSLFI_SIZE, ///< Total count of features, including null feature }; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 48ffbc5a4d..a396a2fe30 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -368,6 +368,24 @@ void AfterLoadVehicles(bool part_of_load) v->SetServiceIntervalIsPercent(c->settings.vehicle.servint_ispercent); } } + + if (SlXvIsFeatureMissing(XSLFI_VEHICLE_REPAIR_COST)) { + /* repair cost is value for new vehicles and each week +/256 part for old */ + FOR_ALL_VEHICLES(v) { + if (!v->IsPrimaryVehicle()) continue; + + v->repair_cost = v->value; + for (int w = 0; w < v->age / 7; w++, v->repair_cost += v->repair_cost >> 8); + //DEBUG(misc,0, "eid#%d, value=%lld, weeks=%d/%d, repair cost=%lld", + // v->engine_type, (int64)v->value, v->age, v->max_age, (int64)v->repair_cost ); + + if (v->age > v->max_age) { + Date weeks = (v->age - v->max_age) / 7; + for (int w = 0; w < weeks; w++, v->repair_cost += v->repair_cost >> 8); + //DEBUG(misc,0, "OLD: value=%lld, weeks=%d, repair cost=%lld", (int64)v->value, weeks, (int64)v->repair_cost ); + } + } + } } CheckValidVehicles(); @@ -692,6 +710,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67), SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, 0, 64), SLE_CONDVAR(Vehicle, value, SLE_INT64, 65, SL_MAX_VERSION), + SLE_CONDVAR_X(Vehicle, repair_cost, SLE_INT64, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_REPAIR_COST)), SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION), diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 8cb429305e..25b6aeacc8 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1611,6 +1611,8 @@ static SettingsContainer &GetSettingsTree() company->Add(new SettingEntry("company.engine_renew")); company->Add(new SettingEntry("company.engine_renew_months")); company->Add(new SettingEntry("company.engine_renew_money")); + company->Add(new SettingEntry("vehicle.pay_for_repair")); + company->Add(new SettingEntry("vehicle.repair_cost")); company->Add(new SettingEntry("vehicle.servint_ispercent")); company->Add(new SettingEntry("vehicle.servint_trains")); company->Add(new SettingEntry("vehicle.servint_roadveh")); diff --git a/src/settings_type.h b/src/settings_type.h index 18a8855bf3..07b5869fa2 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -489,6 +489,8 @@ struct VehicleSettings { uint8 plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal bool adjacent_crossings; ///< enable closing of adjacent level crossings bool improved_breakdowns; ///< different types, chances and serverities of breakdowns + bool pay_for_repair; ///< pay for repairing vehicle + uint8 repair_cost; ///< cost of repairing vehicle }; /** Settings related to the economy. */ diff --git a/src/table/settings.ini b/src/table/settings.ini index 532d062608..f6fe58bb89 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -4205,5 +4205,30 @@ strhelp = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT strval = STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND cat = SC_BASIC +[SDT_BOOL] +base = GameSettings +var = vehicle.pay_for_repair +def = true +str = STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE +strhelp = STR_CONFIG_SETTING_PAY_FOR_REPAIR_VEHICLE_HELPTEXT +cat = SC_EXPERT +extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_REPAIR_COST) +patxname = ""vehicle_repair_cost.vehicle.pay_for_repair"" + +[SDT_VAR] +base = GameSettings +var = vehicle.repair_cost +type = SLE_UINT8 +def = 100 +min = 1 +max = 255 +interval = 1 +str = STR_CONFIG_SETTING_REPAIR_COST +strhelp = STR_CONFIG_SETTING_REPAIR_COST_HELPTEXT +strval = STR_JUST_INT +cat = SC_EXPERT +extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_REPAIR_COST) +patxname = ""vehicle_repair_cost.vehicle.repair_cost"" + [SDT_END] diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 5854c04094..1ce56b7b16 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -122,6 +122,37 @@ void VehicleServiceInDepot(Vehicle *v) do { v->date_of_last_service = _date; + if (_settings_game.vehicle.pay_for_repair && v->breakdowns_since_last_service) { + ExpensesType type = INVALID_EXPENSES; + _current_company = v->owner; + switch (v->type) { + case VEH_AIRCRAFT: + type = EXPENSES_AIRCRAFT_RUN; + break; + + case VEH_TRAIN: + type = EXPENSES_TRAIN_RUN; + break; + + case VEH_SHIP: + type = EXPENSES_SHIP_RUN; + break; + + case VEH_ROAD: + type = EXPENSES_ROADVEH_RUN; + break; + + default: + NOT_REACHED(); + } + assert(type != INVALID_EXPENSES); + Money repair_cost = (v->breakdowns_since_last_service * v->repair_cost / _settings_game.vehicle.repair_cost) + 1; + CommandCost cost(type, repair_cost); + v->First()->profit_this_year -= cost.GetCost() << 8; + SubtractMoneyFromCompany(cost); + ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost()); + } + v->breakdowns_since_last_service = 0; v->reliability = v->GetEngine()->reliability; /* Prevent vehicles from breaking down directly after exiting the depot. */ @@ -1171,6 +1202,9 @@ Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y) void DecreaseVehicleValue(Vehicle *v) { v->value -= v->value >> 8; + if ( v->age > v->max_age ) { // double cost for each max_age days after max_age + v->repair_cost += v->repair_cost >> 8; + } SetWindowDirty(WC_VEHICLE_DETAILS, v->index); } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 756d635af4..db8a1bdf7d 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -190,6 +190,7 @@ public: Money profit_this_year; ///< Profit this year << 8, low 8 bits are fract Money profit_last_year; ///< Profit last year << 8, low 8 bits are fract Money value; ///< Value of the vehicle + Money repair_cost; ///< Cost to repair one breakdown CargoPayment *cargo_payment; ///< The cargo payment we're currently in diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 93250da44f..8c0c0106e0 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -128,6 +128,7 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (value.Succeeded() && flags & DC_EXEC) { v->unitnumber = unit_num; v->value = value.GetCost(); + v->repair_cost = value.GetCost(); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); InvalidateWindowClassesData(GetWindowClassForVehicleType(type), 0);