diff --git a/src/command.cpp b/src/command.cpp index f6d242a76c..2bdc45511b 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -187,6 +187,7 @@ CommandProc CmdSetAutoReplace; CommandProc CmdToggleReuseDepotVehicles; CommandProc CmdToggleKeepRemainingVehicles; CommandProc CmdToggleRefitAsTemplate; +CommandProc CmdToggleTemplateReplaceOldOnly; CommandProc CmdVirtualTrainFromTemplateVehicle; CommandProc CmdVirtualTrainFromTrain; @@ -403,6 +404,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdToggleReuseDepotVehicles, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_TOGGLE_REUSE_DEPOT_VEHICLES DEF_CMD(CmdToggleKeepRemainingVehicles, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_TOGGLE_KEEP_REMAINING_VEHICLES DEF_CMD(CmdToggleRefitAsTemplate, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_TOGGLE_REFIT_AS_TEMPLATE + DEF_CMD(CmdToggleTemplateReplaceOldOnly, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_TOGGLE_TMPL_REPLACE_OLD_ONLY DEF_CMD(CmdVirtualTrainFromTemplateVehicle, CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_VIRTUAL_TRAIN_FROM_TEMPLATE_VEHICLE DEF_CMD(CmdVirtualTrainFromTrain, CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_VIRTUAL_TRAIN_FROM_TRAIN diff --git a/src/command_type.h b/src/command_type.h index 58a201a390..badfa229cb 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -332,6 +332,7 @@ enum Commands { CMD_TOGGLE_REUSE_DEPOT_VEHICLES, ///< toggle 'reuse depot vehicles' on template CMD_TOGGLE_KEEP_REMAINING_VEHICLES, ///< toggle 'keep remaining vehicles' on template CMD_TOGGLE_REFIT_AS_TEMPLATE, ///< toggle 'refit as template' on template + CMD_TOGGLE_TMPL_REPLACE_OLD_ONLY, ///< toggle 'replace old vehicles only' on template CMD_VIRTUAL_TRAIN_FROM_TEMPLATE_VEHICLE, ///< Creates a virtual train from a template CMD_VIRTUAL_TRAIN_FROM_TRAIN, ///< Creates a virtual train from a regular train diff --git a/src/lang/english.txt b/src/lang/english.txt index d5a0b8a3e8..00ab6a6382 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5990,10 +5990,13 @@ STR_TMPL_SET_KEEPREMAINDERS :{BLACK}Keep rem STR_TMPL_SET_KEEPREMAINDERS_TIP :{BLACK}After finishing template replacement keep all remaining vehicles from the old train in a neutral and idle state for later use STR_TMPL_SET_REFIT :{BLACK}Use Refit STR_TMPL_SET_REFIT_TIP :{BLACK}If set, the train will use exactly the cargo refit specified by the template. If not every wagon that is to be newly bought or retrieved from the depot, will *attempt* to be refitted as the old one was. Standard refit if this is impossible. +STR_TMPL_SET_OLD_ONLY :{BLACK}Old Only +STR_TMPL_SET_OLD_ONLY_TIP :{BLACK}If set, only vehicles which are old and due for automatic replacement will be replaced STR_TMPL_CONFIG_USEDEPOT :use depot STR_TMPL_CONFIG_KEEPREMAINDERS :keep rem STR_TMPL_CONFIG_REFIT :refit +STR_TMPL_CONFIG_OLD_ONLY :old only STR_TMPL_NUM_TRAINS_NEED_RPL :# trains to replace: diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index d29cc32c2c..ca2f06aaf9 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -71,7 +71,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", NULL, NULL, NULL }, { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", NULL, NULL, NULL }, { XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 1, 1, "linkgraph_day_scale", NULL, NULL, NULL }, - { XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 4, 4, "template_replacement", NULL, NULL, "TRPL,TMPL" }, + { XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 5, 5, "template_replacement", NULL, NULL, "TRPL,TMPL" }, { XSLFI_MORE_RAIL_TYPES, XSCF_NULL, 0, 1, "more_rail_types", NULL, NULL, NULL }, { XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 3, 3, "cargo_type_orders", NULL, NULL, "ORDX,VEOX" }, { XSLFI_EXTENDED_GAMELOG, XSCF_NULL, 1, 1, "extended_gamelog", NULL, NULL, NULL }, diff --git a/src/saveload/tbtr_template_veh_sl.cpp b/src/saveload/tbtr_template_veh_sl.cpp index ae7c379534..07355660cc 100644 --- a/src/saveload/tbtr_template_veh_sl.cpp +++ b/src/saveload/tbtr_template_veh_sl.cpp @@ -17,6 +17,7 @@ const SaveLoad* GTD() { SLE_VAR(TemplateVehicle, reuse_depot_vehicles, SLE_UINT8), SLE_VAR(TemplateVehicle, keep_remaining_vehicles, SLE_UINT8), SLE_VAR(TemplateVehicle, refit_as_template, SLE_UINT8), + SLE_CONDVAR_X(TemplateVehicle, replace_old_only, SLE_UINT8, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 5)), SLE_CONDVAR_X(TemplateVehicle, owner, SLE_VAR_U8 | SLE_FILE_U32, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)), SLE_CONDVAR_X(TemplateVehicle, owner, SLE_UINT8, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 4)), diff --git a/src/tbtr_template_gui_main.cpp b/src/tbtr_template_gui_main.cpp index b3798f8dd9..77de26a9dd 100644 --- a/src/tbtr_template_gui_main.cpp +++ b/src/tbtr_template_gui_main.cpp @@ -80,6 +80,7 @@ enum TemplateReplaceWindowWidgets { TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE, TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_KEEP, TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REFIT, + TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_OLD_ONLY, TRW_WIDGET_TMPL_BUTTONS_CONFIG_RIGHTPANEL, TRW_WIDGET_TMPL_BUTTONS_DEFINE, @@ -154,6 +155,7 @@ static const NWidgetPart _widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE), SetMinimalSize(150,12), SetResize(0,0), SetDataTip(STR_TMPL_SET_USEDEPOT, STR_TMPL_SET_USEDEPOT_TIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_KEEP), SetMinimalSize(150,12), SetResize(0,0), SetDataTip(STR_TMPL_SET_KEEPREMAINDERS, STR_TMPL_SET_KEEPREMAINDERS_TIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REFIT), SetMinimalSize(150,12), SetResize(0,0), SetDataTip(STR_TMPL_SET_REFIT, STR_TMPL_SET_REFIT_TIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_OLD_ONLY), SetMinimalSize(150,12), SetResize(0,0), SetDataTip(STR_TMPL_SET_OLD_ONLY, STR_TMPL_SET_OLD_ONLY_TIP), NWidget(WWT_PANEL, COLOUR_GREY, TRW_WIDGET_TMPL_BUTTONS_CONFIG_RIGHTPANEL), SetMinimalSize(12,12), SetResize(1,0), EndContainer(), EndContainer(), // Edit buttons @@ -381,6 +383,14 @@ public: } break; } + case TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_OLD_ONLY: { + if ((this->selected_template_index >= 0) && (this->selected_template_index < (short)this->templates.Length())) { + uint32 template_index = ((this->templates)[selected_template_index])->index; + + DoCommandP(0, template_index, 0, CMD_TOGGLE_TMPL_REPLACE_OLD_ONLY, NULL); + } + break; + } case TRW_WIDGET_TMPL_BUTTONS_DEFINE: { editInProgress = true; ShowTemplateCreateWindow(nullptr, &editInProgress); @@ -697,13 +707,16 @@ public: TextColour color; color = v->IsSetReuseDepotVehicles() ? TC_LIGHT_BLUE : TC_GREY; - DrawString(right - ScaleGUITrad(225), right, bottom_edge, STR_TMPL_CONFIG_USEDEPOT, color, SA_LEFT); + DrawString(right - ScaleGUITrad(300), right, bottom_edge, STR_TMPL_CONFIG_USEDEPOT, color, SA_LEFT); color = v->IsSetKeepRemainingVehicles() ? TC_LIGHT_BLUE : TC_GREY; - DrawString(right - ScaleGUITrad(150), right, bottom_edge, STR_TMPL_CONFIG_KEEPREMAINDERS, color, SA_LEFT); + DrawString(right - ScaleGUITrad(225), right, bottom_edge, STR_TMPL_CONFIG_KEEPREMAINDERS, color, SA_LEFT); color = v->IsSetRefitAsTemplate() ? TC_LIGHT_BLUE : TC_GREY; - DrawString(right - ScaleGUITrad(75), right, bottom_edge, STR_TMPL_CONFIG_REFIT, color, SA_LEFT); + DrawString(right - ScaleGUITrad(150), right, bottom_edge, STR_TMPL_CONFIG_REFIT, color, SA_LEFT); + + color = v->IsReplaceOldOnly() ? TC_LIGHT_BLUE : TC_GREY; + DrawString(right - ScaleGUITrad(75), right, bottom_edge, STR_TMPL_CONFIG_OLD_ONLY, color, SA_LEFT); y += this->bottom_matrix_item_size; } @@ -778,6 +791,7 @@ public: this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REUSE, this->editInProgress || !selected_ok); this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_KEEP, this->editInProgress ||!selected_ok); this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_REFIT, this->editInProgress ||!selected_ok); + this->SetWidgetDisabledState(TRW_WIDGET_TMPL_BUTTONS_CONFIGTMPL_OLD_ONLY, this->editInProgress ||!selected_ok); this->SetWidgetDisabledState(TRW_WIDGET_START, this->editInProgress || !(selected_ok && group_ok && FindTemplateIndexForGroup(g_id) != this->selected_template_index)); this->SetWidgetDisabledState(TRW_WIDGET_STOP, this->editInProgress || !(group_ok && GetTemplateReplacementByGroupID(g_id) != NULL)); diff --git a/src/tbtr_template_vehicle.h b/src/tbtr_template_vehicle.h index 2b48780460..f86bbb865b 100644 --- a/src/tbtr_template_vehicle.h +++ b/src/tbtr_template_vehicle.h @@ -90,6 +90,7 @@ public: bool reuse_depot_vehicles; bool keep_remaining_vehicles; bool refit_as_template; + bool replace_old_only; // Things derived from a virtual train TemplateVehicle *other_multiheaded_part; ///< Multiheaded Engine support @@ -128,6 +129,7 @@ public: this->reuse_depot_vehicles = true; this->keep_remaining_vehicles = true; this->refit_as_template = true; + this->replace_old_only = false; this->sprite_seq.count = 1; } @@ -147,9 +149,11 @@ public: bool IsSetReuseDepotVehicles() const { return this->reuse_depot_vehicles; } bool IsSetKeepRemainingVehicles() const { return this->keep_remaining_vehicles; } bool IsSetRefitAsTemplate() const { return this->refit_as_template; } + bool IsReplaceOldOnly() const { return this->replace_old_only; } void ToggleReuseDepotVehicles() { this->reuse_depot_vehicles = !this->reuse_depot_vehicles; } void ToggleKeepRemainingVehicles() { this->keep_remaining_vehicles = !this->keep_remaining_vehicles; } void ToggleRefitAsTemplate() { this->refit_as_template = !this->refit_as_template; } + void ToggleReplaceOldOnly() { this->replace_old_only = !this->replace_old_only; } bool IsPrimaryVehicle() const { return this->IsFrontEngine(); } inline bool IsFrontEngine() const { return HasBit(this->subtype, GVSF_FRONT); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 23df59c04a..0607e0c725 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -5365,6 +5365,10 @@ CommandCost CmdTemplateReplaceVehicle(TileIndex tile, DoCommandFlag flags, uint3 /* first some tests on necessity and sanity */ if (tv == NULL) return buy; + if (tv->IsReplaceOldOnly() && !vehicle->NeedsAutorenewing(Company::Get(vehicle->owner), false)) { + if (!stayInDepot) incoming->vehstatus &= ~VS_STOPPED; + return buy; + } bool need_replacement = !TrainMatchesTemplate(incoming, tv); bool need_refit = !TrainMatchesTemplateRefit(incoming, tv); bool use_refit = tv->refit_as_template; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index a760cf5737..ff91966713 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -951,6 +951,35 @@ CommandCost CmdToggleRefitAsTemplate(TileIndex tile, DoCommandFlag flags, uint32 return CommandCost(); } +/** + * Toggles replace old only on a template vehicle. + * @param tile unused + * @param flags type of operation + * @param p1 the template vehicle's index + * @param p2 unused + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdToggleTemplateReplaceOldOnly(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + // Identify template to toggle + TemplateVehicle *template_vehicle = TemplateVehicle::GetIfValid(p1); + + if (template_vehicle == NULL) { + return CMD_ERROR; + } + + bool should_execute = (flags & DC_EXEC) != 0; + + if (should_execute) { + template_vehicle->ToggleReplaceOldOnly(); + + InvalidateWindowClassesData(WC_TEMPLATEGUI_MAIN, 0); + } + + return CommandCost(); +} + /** * Create a virtual train from a template vehicle. * @param tile unused