From d59252d15b6de56baf6d7ca15fc8904db9c862fd Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 7 May 2016 01:15:46 +0100 Subject: [PATCH] Timetable auto separation is now per vehicle, with a company default. Remove global on-off setting. Add button to timetable GUI. Add company setting to control default for new vehicles. Fix automate, start date, change time and autofill buttons being shown enabled for other companies' vehicles. --- src/aircraft_cmd.cpp | 1 + src/command.cpp | 2 ++ src/command_type.h | 1 + src/lang/english.txt | 11 +++++---- src/order_cmd.cpp | 16 +++++++++++-- src/roadveh_cmd.cpp | 1 + src/saveload/afterload.cpp | 5 ++++ src/saveload/company_sl.cpp | 5 +++- src/saveload/extended_ver_sl.cpp | 2 +- src/settings_gui.cpp | 2 +- src/settings_type.h | 3 ++- src/ship_cmd.cpp | 1 + src/table/company_settings.ini | 9 ++++++++ src/table/settings.ini | 6 ++--- src/timetable_cmd.cpp | 39 ++++++++++++++++++++++++++++++-- src/timetable_gui.cpp | 19 ++++++++++++---- src/train_cmd.cpp | 1 + src/vehicle.cpp | 8 +++---- src/vehicle_base.h | 1 + src/vehicle_cmd.cpp | 2 +- src/widgets/timetable_widget.h | 1 + 21 files changed, 111 insertions(+), 25 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 7a4e0d8f5b..d796d73db8 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -326,6 +326,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine * if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent); SB(v->vehicle_flags, VF_AUTOMATE_TIMETABLE, 1, Company::Get(_current_company)->settings.vehicle.auto_timetable_by_default); + SB(v->vehicle_flags, VF_TIMETABLE_SEPARATION, 1, Company::Get(_current_company)->settings.vehicle.auto_separation_by_default); v->InvalidateNewGRFCacheOfChain(); diff --git a/src/command.cpp b/src/command.cpp index b76efa86ab..974c747c5a 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -195,6 +195,7 @@ CommandProc CmdChangeTimetable; CommandProc CmdSetVehicleOnTime; CommandProc CmdAutofillTimetable; CommandProc CmdAutomateTimetable; +CommandProc CmdTimetableSeparation; CommandProc CmdSetTimetableStart; CommandProc CmdOpenCloseAirport; @@ -353,6 +354,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_VEHICLE_ON_TIME DEF_CMD(CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_AUTOFILL_TIMETABLE DEF_CMD(CmdAutomateTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_AUTOMATE_TIMETABLE + DEF_CMD(CmdTimetableSeparation, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_TIMETABLE_SEPARATION DEF_CMD(CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_TIMETABLE_START DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT diff --git a/src/command_type.h b/src/command_type.h index 9aeeaf7f7e..63e2617ace 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -326,6 +326,7 @@ enum Commands { CMD_SET_VEHICLE_ON_TIME, ///< set the vehicle on time feature (timetable) CMD_AUTOFILL_TIMETABLE, ///< autofill the timetable CMD_AUTOMATE_TIMETABLE, ///< automate the timetable + CMD_TIMETABLE_SEPARATION, ///< auto timetable separation CMD_SET_TIMETABLE_START, ///< set the date that a timetable should start CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft diff --git a/src/lang/english.txt b/src/lang/english.txt index 55aaa829a6..527ba0b845 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1394,10 +1394,12 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Use groups in v STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Enable usage of the advanced vehicle lists for grouping vehicles STR_CONFIG_SETTING_LOADING_INDICATORS :Use loading indicators: {STRING2} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Select whether loading indicators are displayed above loading or unloading vehicles +STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT :Use automatic timetables by default: {STRING2} +STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT_HELPTEXT :Choose whether automatic timetables should by automatically enabled for new vehicles +STR_CONFIG_SETTING_TIMETABLE_SEPARATION_BY_DEFAULT :Use timetable to ensure vehicle separation by default: {STRING2} +STR_CONFIG_SETTING_TIMETABLE_SEPARATION_BY_DEFAULT_HELPTEXT :Choose whether to ensure separation of vehicles should by automatically enabled for new vehicles STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Show timetable in ticks rather than days: {STRING2} STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Show travel times in time tables in game ticks instead of days -STR_CONFIG_SETTING_TIMETABLE_SEPARATION :Use timetable to ensure vehicle separation: {STRING2} -STR_CONFIG_SETTING_TIMETABLE_SEPARATION_HELPTEXT :Select whether to ensure separation of vehicles when using automatic timetables STR_CONFIG_SETTING_TIMETABLE_SEPARATION_RATE :Auto timetable vehicle separation factor: {STRING2} STR_CONFIG_SETTING_TIMETABLE_SEPARATION_RATE_HELPTEXT :How much of the vehicle separation auto timetable change to apply at each step STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Show arrival and departure in timetables: {STRING2} @@ -1478,8 +1480,6 @@ 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_AUTO_TIMETABLE_BY_DEFAULT :Use automatic timetables by default -STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT_HELPTEXT :Choose whether automatic timetables should by automatically enabled for new vehicles STR_CONFIG_SETTING_NOSERVICE :Disable servicing when breakdowns set to none: {STRING2} STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :When enabled, vehicles do not get serviced if they cannot break down STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Enable wagon speed limits: {STRING2} @@ -3948,6 +3948,9 @@ STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the STR_TIMETABLE_AUTOMATE :{BLACK}Automate STR_TIMETABLE_AUTOMATE_TOOLTIP :{BLACK}Manage the timetables automatically by updating the values for each journey (Ctrl+Click when disabling to keep the current timetable) +STR_TIMETABLE_AUTO_SEPARATION :{BLACK}Auto Separation +STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP :{BLACK}Automatically adjust timetable start times to ensure vehicle separation + STR_TIMETABLE_EXPECTED :{BLACK}Expected STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}Switch between expected and scheduled diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 3163ff658a..e42bf091ed 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1162,7 +1162,7 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 InvalidateVehicleOrder(v, VIWD_MODIFY_ORDERS); v->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED); } /* We have an aircraft/ship, they have a mini-schedule, so update them all */ @@ -1627,11 +1627,17 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } else { ClrBit(dst->vehicle_flags, VF_AUTOMATE_TIMETABLE); } + /* Set auto separation bit if target has it. */ + if (HasBit(src->vehicle_flags, VF_TIMETABLE_SEPARATION)) { + SetBit(dst->vehicle_flags, VF_TIMETABLE_SEPARATION); + } else { + ClrBit(dst->vehicle_flags, VF_TIMETABLE_SEPARATION); + } ClrBit(dst->vehicle_flags, VF_AUTOFILL_TIMETABLE); ClrBit(dst->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); dst->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(dst->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(dst->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(dst->vehicle_flags, VF_TIMETABLE_STARTED); InvalidateVehicleOrder(dst, VIWD_REMOVE_ALL_ORDERS); InvalidateVehicleOrder(src, VIWD_MODIFY_ORDERS); @@ -1705,6 +1711,12 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } else { ClrBit(dst->vehicle_flags, VF_AUTOMATE_TIMETABLE); } + /* Set auto separation bit if target has it. */ + if (HasBit(src->vehicle_flags, VF_TIMETABLE_SEPARATION)) { + SetBit(dst->vehicle_flags, VF_TIMETABLE_SEPARATION); + } else { + ClrBit(dst->vehicle_flags, VF_TIMETABLE_SEPARATION); + } InvalidateVehicleOrder(dst, VIWD_REMOVE_ALL_ORDERS); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 8dbcca1027..997c3da87d 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -317,6 +317,7 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent); SB(v->vehicle_flags, VF_AUTOMATE_TIMETABLE, 1, Company::Get(_current_company)->settings.vehicle.auto_timetable_by_default); + SB(v->vehicle_flags, VF_TIMETABLE_SEPARATION, 1, Company::Get(_current_company)->settings.vehicle.auto_separation_by_default); AddArticulatedParts(v); v->InvalidateNewGRFCacheOfChain(); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 9690481154..f63ca4ee2e 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2975,6 +2975,11 @@ bool AfterLoadGame() FOR_ALL_STATIONS(st) UpdateStationAcceptance(st, false); } + if (SlXvIsFeaturePresent(XSLFI_AUTO_TIMETABLE, 1, 3)) { + Vehicle *v; + FOR_ALL_VEHICLES(v) SB(v->vehicle_flags, VF_TIMETABLE_SEPARATION, 1, _settings_game.order.old_timetable_separation); + } + /* Road stops is 'only' updating some caches */ AfterLoadRoadStops(); AfterLoadLabelMaps(); diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 94b7952a9c..c01c111b56 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -493,10 +493,13 @@ static void Load_PLYR() SaveLoad_PLYR(c); _company_colours[index] = (Colours)c->colour; - // setting moved from game settings to company settings + // settings moved from game settings to company settings if (SlXvIsFeaturePresent(XSLFI_AUTO_TIMETABLE, 1, 2)) { c->settings.auto_timetable_separation_rate = _settings_game.order.old_timetable_separation_rate; } + if (SlXvIsFeaturePresent(XSLFI_AUTO_TIMETABLE, 1, 3)) { + c->settings.vehicle.auto_separation_by_default = _settings_game.order.old_timetable_separation; + } } } diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 914f2e7e81..a6a814f529 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -45,7 +45,7 @@ std::vector _sl_xv_discardable_chunk_ids; ///< list of chunks static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { - { XSLFI_AUTO_TIMETABLE, XSCF_NULL, 3, 3, "auto_timetables", NULL, NULL, NULL }, + { XSLFI_AUTO_TIMETABLE, XSCF_NULL, 4, 4, "auto_timetables", NULL, NULL, NULL }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 2d64659c7c..ecdea71dd1 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1587,6 +1587,7 @@ static SettingsContainer &GetSettingsTree() company->Add(new SettingEntry("vehicle.servint_ships")); company->Add(new SettingEntry("vehicle.servint_aircraft")); company->Add(new SettingEntry("vehicle.auto_timetable_by_default")); + company->Add(new SettingEntry("vehicle.auto_separation_by_default")); company->Add(new SettingEntry("auto_timetable_separation_rate")); company->Add(new SettingEntry("timetable_autofill_rounding")); } @@ -1629,7 +1630,6 @@ static SettingsContainer &GetSettingsTree() vehicles->Add(new SettingEntry("order.no_servicing_if_no_breakdowns")); vehicles->Add(new SettingEntry("order.serviceathelipad")); - vehicles->Add(new SettingEntry("order.timetable_separation")); } SettingsPage *limitations = main->Add(new SettingsPage(STR_CONFIG_SETTING_LIMITATIONS)); diff --git a/src/settings_type.h b/src/settings_type.h index 96ba2ce3b4..74275420db 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -438,9 +438,9 @@ struct OrderSettings { bool gradual_loading; ///< load vehicles gradually bool selectgoods; ///< only send the goods to station if a train has been there bool no_servicing_if_no_breakdowns; ///< don't send vehicles to depot when breakdowns are disabled - bool timetable_separation; ///< whether to perform automatic separation based on timetable bool serviceathelipad; ///< service helicopters at helipads automatically (no need to send to depot) + bool old_timetable_separation; ///< moved to company settings: whether to perform automatic separation based on timetable uint8 old_timetable_separation_rate; ///< moved to company settings: percentage of timetable separation change to apply }; @@ -530,6 +530,7 @@ struct VehicleDefaultSettings { uint16 servint_aircraft; ///< service interval for aircraft uint16 servint_ships; ///< service interval for ships bool auto_timetable_by_default; ///< use automatic timetables by default + bool auto_separation_by_default; ///< use automatic timetable separation by default }; /** Settings that can be set per company. */ diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 85bd20ed8a..a5a5946570 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -718,6 +718,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent); SB(v->vehicle_flags, VF_AUTOMATE_TIMETABLE, 1, Company::Get(_current_company)->settings.vehicle.auto_timetable_by_default); + SB(v->vehicle_flags, VF_TIMETABLE_SEPARATION, 1, Company::Get(_current_company)->settings.vehicle.auto_separation_by_default); v->InvalidateNewGRFCacheOfChain(); diff --git a/src/table/company_settings.ini b/src/table/company_settings.ini index 08d9373cfd..fa67a4d401 100644 --- a/src/table/company_settings.ini +++ b/src/table/company_settings.ini @@ -144,6 +144,15 @@ str = STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT strhelp = STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT_HELPTEXT patxname = ""vehicle.auto_timetable_by_default"" +[SDT_BOOL] +base = CompanySettings +var = vehicle.auto_separation_by_default +guiflags = SGF_PER_COMPANY +def = true +str = STR_CONFIG_SETTING_TIMETABLE_SEPARATION_BY_DEFAULT +strhelp = STR_CONFIG_SETTING_TIMETABLE_SEPARATION_BY_DEFAULT_HELPTEXT +patxname = ""vehicle.auto_separation_by_default"" + [SDT_VAR] base = CompanySettings var = auto_timetable_separation_rate diff --git a/src/table/settings.ini b/src/table/settings.ini index e3cea287dc..0a21fdaac7 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -333,12 +333,10 @@ cat = SC_BASIC [SDT_BOOL] base = GameSettings -var = order.timetable_separation +var = order.old_timetable_separation def = true -str = STR_CONFIG_SETTING_TIMETABLE_SEPARATION -strhelp = STR_CONFIG_SETTING_TIMETABLE_SEPARATION_HELPTEXT cat = SC_EXPERT -extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE) +extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE, 1, 3) patxname = ""auto_timetables.order.timetable_separation"" [SDT_VAR] diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 318c8adf78..04decefa70 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -443,6 +443,41 @@ CommandCost CmdAutomateTimetable(TileIndex index, DoCommandFlag flags, uint32 p1 return CommandCost(); } +/** + * Enable or disable auto timetable separation + * @param tile Not used. + * @param flags Operation to perform. + * @param p1 Vehicle index. + * @param p2 Various bitstuffed elements + * - p2 = (bit 0) - Set to 1 to enable, 0 to disable auto separatiom. + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdTimetableSeparation(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + VehicleID veh = GB(p1, 0, 20); + + Vehicle *v = Vehicle::GetIfValid(veh); + if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + + CommandCost ret = CheckOwnership(v->owner); + if (ret.Failed()) return ret; + + if (flags & DC_EXEC) { + for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) { + if (HasBit(p2, 0)) { + SetBit(v2->vehicle_flags, VF_TIMETABLE_SEPARATION); + } else { + ClrBit(v2->vehicle_flags, VF_TIMETABLE_SEPARATION); + } + v2->ClearSeparation(); + SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); + } + } + + return CommandCost(); +} + static inline bool IsOrderUsableForSeparation(const Order *order) { if (order->IsType(OT_CONDITIONAL)) { @@ -594,7 +629,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) v->ClearSeparation(); SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED); v->lateness_counter = 0; - if (_settings_game.order.timetable_separation) UpdateSeparationOrder(v); + if (HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)) UpdateSeparationOrder(v); for (v = v->FirstShared(); v != NULL; v = v->NextShared()) { SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); } @@ -716,7 +751,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) * when this happens. */ if (timetabled == 0 && (travelling || v->lateness_counter >= 0)) return; - if (_settings_game.order.timetable_separation && HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) { + if (HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION) && HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) { v->current_order_time = time_taken; v->current_loading_time = time_loading; UpdateSeparationOrder(v); diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index ae294e3e9c..5128ac7876 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -325,6 +325,11 @@ struct TimetableWindow : Window { this->SetWidgetDisabledState(WID_VT_RESET_LATENESS, v->orders.list == NULL); this->SetWidgetDisabledState(WID_VT_AUTOFILL, v->orders.list == NULL); this->EnableWidget(WID_VT_AUTOMATE); + this->EnableWidget(WID_VT_AUTO_SEPARATION); + this->SetWidgetDisabledState(WID_VT_START_DATE, HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)); + this->SetWidgetDisabledState(WID_VT_CHANGE_TIME, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); + this->SetWidgetDisabledState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); + this->SetWidgetDisabledState(WID_VT_CLEAR_TIME, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); } else { this->DisableWidget(WID_VT_START_DATE); this->DisableWidget(WID_VT_CHANGE_TIME); @@ -334,15 +339,13 @@ struct TimetableWindow : Window { this->DisableWidget(WID_VT_RESET_LATENESS); this->DisableWidget(WID_VT_AUTOFILL); this->DisableWidget(WID_VT_AUTOMATE); + this->DisableWidget(WID_VT_AUTO_SEPARATION); this->DisableWidget(WID_VT_SHARED_ORDER_LIST); } this->SetWidgetLoweredState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)); this->SetWidgetLoweredState(WID_VT_AUTOMATE, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); - this->SetWidgetDisabledState(WID_VT_START_DATE, _settings_game.order.timetable_separation); - this->SetWidgetDisabledState(WID_VT_CHANGE_TIME, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); - this->SetWidgetDisabledState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); - this->SetWidgetDisabledState(WID_VT_CLEAR_TIME, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)); + this->SetWidgetLoweredState(WID_VT_AUTO_SEPARATION, HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)); this->DrawWidgets(); } @@ -616,6 +619,13 @@ struct TimetableWindow : Window { break; } + case WID_VT_AUTO_SEPARATION: { + uint32 p2 = 0; + if (!HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)) SetBit(p2, 0); + DoCommandP(0, v->index, p2, CMD_TIMETABLE_SEPARATION | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + break; + } + case WID_VT_EXPECTED: this->show_expected = !this->show_expected; break; @@ -693,6 +703,7 @@ static const NWidgetPart _nested_timetable_widgets[] = { EndContainer(), NWidget(NWID_VERTICAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_START_DATE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_STARTING_DATE, STR_TIMETABLE_STARTING_DATE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTO_SEPARATION), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTO_SEPARATION, STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_RESET_LATENESS), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_RESET_LATENESS, STR_TIMETABLE_RESET_LATENESS_TOOLTIP), EndContainer(), NWidget(NWID_VERTICAL, NC_EQUALSIZE), diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 53c19d9db6..2858f0d6d0 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -776,6 +776,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engin if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent); SB(v->vehicle_flags, VF_AUTOMATE_TIMETABLE, 1, Company::Get(_current_company)->settings.vehicle.auto_timetable_by_default); + SB(v->vehicle_flags, VF_TIMETABLE_SEPARATION, 1, Company::Get(_current_company)->settings.vehicle.auto_separation_by_default); v->group_id = DEFAULT_GROUP; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 139670547e..4083ba5957 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -210,7 +210,7 @@ uint Vehicle::Crash(bool flooded) } this->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(this->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); /* Dirty some windows */ InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0); @@ -2231,7 +2231,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) this->current_order.SetDepotOrderType(ODTF_MANUAL); this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT); this->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(this->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); } return CommandCost(); @@ -2249,7 +2249,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) } this->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(this->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); this->current_order.MakeDummy(); SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); @@ -2702,7 +2702,7 @@ void Vehicle::RemoveFromShared() this->previous_shared = NULL; this->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(this->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED); } void VehiclesYearlyLoop() diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 58a9b7dbc1..c370e06ed6 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -54,6 +54,7 @@ enum VehicleFlags { // Additional flags not in trunk are added at the end to avoid clashing with any new // flags which get added in future trunk, and to avoid re-ordering flags which are in trunk already, // as this breaks savegame compatibility. + VF_TIMETABLE_SEPARATION = 14,///< Whether the vehicle should manage the timetable automatically. VF_AUTOMATE_TIMETABLE = 15, ///< Whether the vehicle should manage the timetable automatically. }; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 8ea1ac7786..3dfc131afa 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -579,7 +579,7 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(p1, STR_NEWS_TRAIN_IS_WAITING + v->type); v->ClearSeparation(); - if (_settings_game.order.timetable_separation) ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED); + if (HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)) ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED); v->vehstatus ^= VS_STOPPED; if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly' diff --git a/src/widgets/timetable_widget.h b/src/widgets/timetable_widget.h index d21e3c2b7e..341608c58b 100644 --- a/src/widgets/timetable_widget.h +++ b/src/widgets/timetable_widget.h @@ -26,6 +26,7 @@ enum VehicleTimetableWidgets { WID_VT_RESET_LATENESS, ///< Reset lateness button. WID_VT_AUTOFILL, ///< Autofill button. WID_VT_AUTOMATE, ///< Automate button. + WID_VT_AUTO_SEPARATION, ///< Auto separation button. WID_VT_EXPECTED, ///< Toggle between expected and scheduled arrivals. WID_VT_SHARED_ORDER_LIST, ///< Show the shared order list. WID_VT_ARRIVAL_DEPARTURE_SELECTION, ///< Disable/hide the arrival departure panel.