diff --git a/src/lang/english.txt b/src/lang/english.txt index e7ab23a0a2..f170b13922 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1789,7 +1789,7 @@ STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Default service STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Set the default service interval for new aircraft, if no explicit service interval is set for the vehicle STR_CONFIG_SETTING_SERVINT_SHIPS :Default service interval for ships: {STRING2} STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Set the default service interval for new ships, if no explicit service interval is set for the vehicle -STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}day{P 0 "" s}/% +STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}Day{P 0 "" s}/Minute{P 0 "" s}/% ###setting-zero-is-special STR_CONFIG_SETTING_SERVINT_DISABLED :Disabled @@ -4369,14 +4369,17 @@ STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacity STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer Credits: {LTBLUE}{CURRENCY_LONG} -STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK} Last service: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} Last service: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Increase servicing interval by 10. Ctrl+Click to increase servicing interval by 5 -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Decrease servicing interval by 10. Ctrl+Click to decrease servicing interval by 5 +STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK} {STRING1} +STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}minutes{BLACK} {STRING1} +STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} {STRING1} +STR_VEHICLE_DETAILS_LAST_SERVICE_DATE :Last service: {LTBLUE}{DATE_LONG} +STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO :Last service: {LTBLUE}{NUM} minutes ago +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Increase servicing interval by {TKM 10 5}. Ctrl+Click to increase servicing interval by {TKM 5 1} +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Decrease servicing interval by {TKM 10 5}. Ctrl+Click to decrease servicing interval by {TKM 5 1} STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}Change servicing interval type STR_VEHICLE_DETAILS_DEFAULT :Default -STR_VEHICLE_DETAILS_DAYS :Days +STR_VEHICLE_DETAILS_TIME :{TKM Days Minutes} STR_VEHICLE_DETAILS_PERCENT :Percentage ###length VEHICLE_TYPES diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 04ada61c7b..1594065a10 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1845,13 +1845,21 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indic /** * Clamp the service interval to the correct min/max. The actual min/max values - * depend on whether it's in percent or days. - * @param interval proposed service interval - * @return Clamped service interval + * depend on whether it's in days, minutes, or percent. + * @param interval The proposed service interval. + * @param ispercent Whether the interval is a percent. + * @return The service interval clamped to use the chosen units. */ uint16_t GetServiceIntervalClamped(int interval, bool ispercent) { - return ispercent ? Clamp(interval, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT) : Clamp(interval, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS); + /* Service intervals are in percents. */ + if (ispercent) return Clamp(interval, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT); + + /* Service intervals are in minutes. */ + if (TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU)) return Clamp(interval, MIN_SERVINT_MINUTES, MAX_SERVINT_MINUTES); + + /* Service intervals are in days. */ + return Clamp(interval, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS); } /** diff --git a/src/order_func.h b/src/order_func.h index f8771b09dc..12f7d4684a 100644 --- a/src/order_func.h +++ b/src/order_func.h @@ -33,6 +33,13 @@ static const uint DEF_SERVINT_DAYS_SHIPS = 360; static const uint MIN_SERVINT_DAYS = 30; static const uint MAX_SERVINT_DAYS = 800; +static const uint DEF_SERVINT_MINUTES_TRAINS = 5; +static const uint DEF_SERVINT_MINUTES_ROADVEH = 5; +static const uint DEF_SERVINT_MINUTES_AIRCRAFT = 3; +static const uint DEF_SERVINT_MINUTES_SHIPS = 12; +static const uint MIN_SERVINT_MINUTES = 1; +static const uint MAX_SERVINT_MINUTES = 30; + static const uint DEF_SERVINT_PERCENT = 50; static const uint MIN_SERVINT_PERCENT = 5; static const uint MAX_SERVINT_PERCENT = 90; diff --git a/src/settings_table.cpp b/src/settings_table.cpp index d4c41b59f7..6bbdea874a 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -130,7 +130,7 @@ static void UpdateConsists(int32_t) /** * Check and update if needed all vehicle service intervals. - * @param new_value Contains 0 if service intervals are in days, otherwise intervals use percents. + * @param new_value Contains 0 if service intervals are in time (days or real-world minutes), otherwise intervals use percents. */ static void UpdateAllServiceInterval(int32_t new_value) { @@ -150,6 +150,12 @@ static void UpdateAllServiceInterval(int32_t new_value) vds->servint_roadveh = DEF_SERVINT_PERCENT; vds->servint_aircraft = DEF_SERVINT_PERCENT; vds->servint_ships = DEF_SERVINT_PERCENT; + } else if (TimerGameEconomy::UsingWallclockUnits(_game_mode == GM_MENU)) { + /* Service intervals are in minutes. */ + vds->servint_trains = DEF_SERVINT_MINUTES_TRAINS; + vds->servint_roadveh = DEF_SERVINT_MINUTES_ROADVEH; + vds->servint_aircraft = DEF_SERVINT_MINUTES_AIRCRAFT; + vds->servint_ships = DEF_SERVINT_MINUTES_SHIPS; } else { /* Service intervals are in days. */ vds->servint_trains = DEF_SERVINT_DAYS_TRAINS; @@ -483,4 +489,18 @@ static void UpdateClientConfigValues() } } +/** + * Callback for when the player changes the timekeeping units. + * @param Unused. + */ +static void ChangeTimekeepingUnits(int32_t) +{ + /* If service intervals are in time units (calendar days or real-world minutes), reset them to the correct defaults. */ + if (!_settings_client.company.vehicle.servint_ispercent) { + UpdateAllServiceInterval(0); + } + + InvalidateWindowClassesData(WC_GAME_OPTIONS, 0); +} + /* End - Callback Functions */ diff --git a/src/table/settings/company_settings.ini b/src/table/settings/company_settings.ini index c712b7b0a8..c00dbdee34 100644 --- a/src/table/settings/company_settings.ini +++ b/src/table/settings/company_settings.ini @@ -84,7 +84,7 @@ var = vehicle.servint_trains type = SLE_UINT16 flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL def = DEF_SERVINT_DAYS_TRAINS -min = MIN_SERVINT_PERCENT +min = MIN_SERVINT_MINUTES max = MAX_SERVINT_DAYS interval = 1 str = STR_CONFIG_SETTING_SERVINT_TRAINS @@ -98,7 +98,7 @@ var = vehicle.servint_roadveh type = SLE_UINT16 flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL def = DEF_SERVINT_DAYS_ROADVEH -min = MIN_SERVINT_PERCENT +min = MIN_SERVINT_MINUTES max = MAX_SERVINT_DAYS interval = 1 str = STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES @@ -112,7 +112,7 @@ var = vehicle.servint_ships type = SLE_UINT16 flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL def = DEF_SERVINT_DAYS_SHIPS -min = MIN_SERVINT_PERCENT +min = MIN_SERVINT_MINUTES max = MAX_SERVINT_DAYS interval = 1 str = STR_CONFIG_SETTING_SERVINT_SHIPS @@ -126,7 +126,7 @@ var = vehicle.servint_aircraft type = SLE_UINT16 flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL def = DEF_SERVINT_DAYS_AIRCRAFT -min = MIN_SERVINT_PERCENT +min = MIN_SERVINT_MINUTES max = MAX_SERVINT_DAYS interval = 1 str = STR_CONFIG_SETTING_SERVINT_AIRCRAFT diff --git a/src/table/settings/economy_settings.ini b/src/table/settings/economy_settings.ini index 4737befc0a..f824c50fe0 100644 --- a/src/table/settings/economy_settings.ini +++ b/src/table/settings/economy_settings.ini @@ -9,6 +9,7 @@ [pre-amble] static void TownFoundingChanged(int32_t new_value); +static void ChangeTimekeepingUnits(int32_t new_value); static const SettingVariant _economy_settings_table[] = { [post-amble] @@ -291,4 +292,5 @@ max = TKU_WALLCLOCK str = STR_CONFIG_SETTING_TIMEKEEPING_UNITS strval = STR_CONFIG_SETTING_TIMEKEEPING_UNITS_CALENDAR strhelp = STR_CONFIG_SETTING_TIMEKEEPING_UNITS_HELPTEXT +post_cb = ChangeTimekeepingUnits cat = SC_BASIC diff --git a/src/vehicle.cpp b/src/vehicle.cpp index b2f5e37c90..fabf14ce13 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -195,10 +195,17 @@ bool Vehicle::NeedsServicing() const /* Are we ready for the next service cycle? */ const Company *c = Company::Get(this->owner); - if (this->ServiceIntervalIsPercent() ? - (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) : - (this->date_of_last_service + this->GetServiceInterval() >= TimerGameEconomy::date)) { - return false; + + /* Service intervals can be measured in different units, which we handle individually. */ + if (this->ServiceIntervalIsPercent()) { + /* Service interval is in percents. */ + if (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) return false; + } else if (TimerGameEconomy::UsingWallclockUnits()) { + /* Service interval is in minutes. */ + if (this->date_of_last_service + (this->GetServiceInterval() * EconomyTime::DAYS_IN_ECONOMY_MONTH) >= TimerGameEconomy::date) return false; + } else { + /* Service interval is in days. */ + if (this->date_of_last_service + this->GetServiceInterval() >= TimerGameEconomy::date) return false; } /* If we're servicing anyway, because we have not disabled servicing when diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 3fb3e02895..00e6938a25 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2299,7 +2299,7 @@ extern void DrawAircraftDetails(const Aircraft *v, const Rect &r); static StringID _service_interval_dropdown[] = { STR_VEHICLE_DETAILS_DEFAULT, - STR_VEHICLE_DETAILS_DAYS, + STR_VEHICLE_DETAILS_TIME, STR_VEHICLE_DETAILS_PERCENT, INVALID_STRING_ID, }; @@ -2431,7 +2431,17 @@ struct VehicleDetailsWindow : Window { case WID_VD_SERVICING_INTERVAL: SetDParamMaxValue(0, MAX_SERVINT_DAYS); // Roughly the maximum interval - SetDParamMaxValue(1, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR)); // Roughly the maximum year + + /* Do we show the last serviced value as a date or minutes since service? */ + if (TimerGameEconomy::UsingWallclockUnits()) { + SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO); + /*/ Vehicle was last serviced at year 0, and we're at max year */ + SetDParamMaxValue(2, EconomyTime::MONTHS_IN_YEAR * EconomyTime::MAX_YEAR.base()); + } else { + SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_DATE); + /*/ Vehicle was last serviced at year 0, and we're at max year */ + SetDParamMaxValue(2, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR)); + } size->width = std::max( GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width, GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width @@ -2572,8 +2582,22 @@ struct VehicleDetailsWindow : Window { case WID_VD_SERVICING_INTERVAL: { /* Draw service interval text */ Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); + SetDParam(0, v->GetServiceInterval()); - SetDParam(1, v->date_of_last_service); + + /* We're using wallclock units. Show minutes since last serviced. */ + if (TimerGameEconomy::UsingWallclockUnits()) { + int minutes_since_serviced = (TimerGameEconomy::date - v->date_of_last_service).base() / EconomyTime::DAYS_IN_ECONOMY_MONTH; + SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_MINUTES_AGO); + SetDParam(2, minutes_since_serviced); + DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)), + v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_MINUTES); + break; + } + + /* We're using calendar dates. Show the date of last service. */ + SetDParam(1, STR_VEHICLE_DETAILS_LAST_SERVICE_DATE); + SetDParam(2, v->date_of_last_service); DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)), v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS); break; @@ -2597,7 +2621,7 @@ struct VehicleDetailsWindow : Window { WID_VD_DECREASE_SERVICING_INTERVAL); StringID str = v->ServiceIntervalIsCustom() ? - (v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_DAYS) : + (v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_TIME) : STR_VEHICLE_DETAILS_DEFAULT; this->GetWidget(WID_VD_SERVICE_INTERVAL_DROPDOWN)->widget_data = str; @@ -2609,7 +2633,7 @@ struct VehicleDetailsWindow : Window { switch (widget) { case WID_VD_INCREASE_SERVICING_INTERVAL: // increase int case WID_VD_DECREASE_SERVICING_INTERVAL: { // decrease int - int mod = _ctrl_pressed ? 5 : 10; + int mod = TimerGameEconomy::UsingWallclockUnits() ? (_ctrl_pressed ? 1 : 5) : (_ctrl_pressed ? 5 : 10); const Vehicle *v = Vehicle::Get(this->window_number); mod = (widget == WID_VD_DECREASE_SERVICING_INTERVAL) ? -mod : mod;