Index: src/autoreplace_cmd.cpp =================================================================== --- src/autoreplace_cmd.cpp (revision 27930) +++ src/autoreplace_cmd.cpp (working copy) @@ -78,11 +78,6 @@ if (HasBit(e_from->info.misc_flags, EF_ROAD_TRAM) != HasBit(e_to->info.misc_flags, EF_ROAD_TRAM)) return false; break; - case VEH_AIRCRAFT: - /* make sure that we do not replace a plane with a helicopter or vice versa */ - if ((e_from->u.air.subtype & AIR_CTOL) != (e_to->u.air.subtype & AIR_CTOL)) return false; - break; - default: break; } Index: src/autoreplace_gui.cpp =================================================================== --- src/autoreplace_gui.cpp (revision 27930) +++ src/autoreplace_gui.cpp (working copy) @@ -111,7 +111,27 @@ return true; } + /** + * Figure out if an aircraft should be added to the right list, regarding its type. + * @param from The EngineID of the selected aircraft on the left list. + * @param to The EngineID of the aircraft to be added to the right list. + * @return \c true if the engine should be added to the right list, else \c false. + */ + bool GenerateReplaceAircraftList(EngineID from, EngineID to) + { + const Engine *e_from = Engine::Get(from); + const Engine *e_to = Engine::Get(to); + if (_settings_client.gui.autoreplace_match_aircraft_type) { + /* make sure that we do not replace a mismatching aircraft type */ + if ((e_from->u.air.subtype == AIR_CTOL) != (e_to->u.air.subtype == AIR_CTOL)) return false; + if ((e_from->u.air.subtype == AIR_HELI) != (e_to->u.air.subtype == AIR_HELI)) return false; + if ((e_from->u.air.subtype == (AIR_CTOL | AIR_FAST)) != (e_to->u.air.subtype == (AIR_CTOL | AIR_FAST))) return false; + } + + return true; + } + /** * Generate an engines list * @param draw_left true if generating the left list, otherwise false @@ -138,6 +158,7 @@ if (num_engines == 0 && EngineReplacementForCompany(Company::Get(_local_company), eid, this->sel_group) == INVALID_ENGINE) continue; } else { if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue; + if (type == VEH_AIRCRAFT && !this->GenerateReplaceAircraftList(this->sel_engine[0], eid)) continue; } *list->Append() = eid; @@ -229,6 +250,12 @@ widget->widget_data = STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN + vehicletype; widget->tool_tip = STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP + vehicletype; widget->SetLowered(this->show_hidden_engines); + + if (vehicletype == VEH_AIRCRAFT) { + widget = this->GetWidget(WID_RV_MATCH_AIRCRAFT_TYPE); + widget->SetLowered(_settings_client.gui.autoreplace_match_aircraft_type); + } + this->FinishInitNested(vehicletype); this->sort_criteria = _engine_sort_last_criteria[vehicletype]; @@ -475,6 +502,13 @@ DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING); break; + case WID_RV_MATCH_AIRCRAFT_TYPE: // toggle autoreplace_match_aircraft_type + IConsoleSetSetting("gui.autoreplace_match_aircraft_type", !_settings_client.gui.autoreplace_match_aircraft_type); + this->engines[1].ForceRebuild(); + this->SetWidgetLoweredState(widget, _settings_client.gui.autoreplace_match_aircraft_type); + this->SetDirty(); + break; + case WID_RV_START_REPLACE: { // Start replacing if (this->GetWidget(widget)->ButtonHit(pt)) { this->HandleButtonClick(WID_RV_START_REPLACE); @@ -697,6 +731,60 @@ _nested_replace_vehicle_widgets, lengthof(_nested_replace_vehicle_widgets) ); +static const NWidgetPart _nested_replace_aircraft_vehicle_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetMinimalSize(433, 14), SetDataTip(STR_REPLACE_VEHICLES_WHITE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP), SetFill(1, 1), SetMinimalSize(0, 12), SetResize(1, 0), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP), SetFill(1, 1), SetMinimalSize(0, 12), SetResize(1, 0), + EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_MATCH_AIRCRAFT_TYPE), SetDataTip(STR_REPLACE_MATCH_AIRCRAFT_TYPE, STR_REPLACE_MATCH_AIRCRAFT_TYPE_HELP), SetResize(1, 0), SetFill(1, 1), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(228, 92), SetResize(1, 0), EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0), EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), +}; + +static WindowDesc _replace_aircraft_vehicle_desc( + WDP_AUTO, "replace_vehicle_aircraft", 456, 118, + WC_REPLACE_VEHICLE, WC_NONE, + WDF_CONSTRUCTION, + _nested_replace_aircraft_vehicle_widgets, lengthof(_nested_replace_aircraft_vehicle_widgets) +); + /** * Show the autoreplace configuration window for a particular group. * @param id_g The group to replace the vehicles for. @@ -705,5 +793,11 @@ void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype) { DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype); - new ReplaceVehicleWindow(vehicletype == VEH_TRAIN ? &_replace_rail_vehicle_desc : &_replace_vehicle_desc, vehicletype, id_g); + if (vehicletype == VEH_TRAIN) { + new ReplaceVehicleWindow(&_replace_rail_vehicle_desc, vehicletype, id_g); + } else if (vehicletype == VEH_AIRCRAFT) { + new ReplaceVehicleWindow(&_replace_aircraft_vehicle_desc, vehicletype, id_g); + } else { + new ReplaceVehicleWindow(&_replace_vehicle_desc, vehicletype, id_g); + } } Index: src/lang/english.txt =================================================================== --- src/lang/english.txt (revision 27930) +++ src/lang/english.txt (working copy) @@ -3585,6 +3585,9 @@ STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing wagons (starting at the front), if replacing the engine would make the train longer +STR_REPLACE_MATCH_AIRCRAFT_TYPE :{BLACK}Match aircraft type +STR_REPLACE_MATCH_AIRCRAFT_TYPE_HELP :{BLACK}By enabling this button, only aircraft matching the same type as the one selected for replacement are displayed + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} Index: src/script/api/game/game_window.hpp.sq =================================================================== --- src/script/api/game/game_window.hpp.sq (revision 27930) +++ src/script/api/game/game_window.hpp.sq (working copy) @@ -216,6 +216,7 @@ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_SORT_ASCENDING_DESCENDING, "WID_RV_SORT_ASCENDING_DESCENDING"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_SHOW_HIDDEN_ENGINES, "WID_RV_SHOW_HIDDEN_ENGINES"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_SORT_DROPDOWN, "WID_RV_SORT_DROPDOWN"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_MATCH_AIRCRAFT_TYPE, "WID_RV_MATCH_AIRCRAFT_TYPE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_LEFT_MATRIX, "WID_RV_LEFT_MATRIX"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_LEFT_SCROLLBAR, "WID_RV_LEFT_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_RIGHT_MATRIX, "WID_RV_RIGHT_MATRIX"); Index: src/script/api/script_window.hpp =================================================================== --- src/script/api/script_window.hpp (revision 27930) +++ src/script/api/script_window.hpp (working copy) @@ -927,6 +927,7 @@ WID_RV_SORT_ASCENDING_DESCENDING = ::WID_RV_SORT_ASCENDING_DESCENDING, ///< Ascending/descending sort order button. WID_RV_SHOW_HIDDEN_ENGINES = ::WID_RV_SHOW_HIDDEN_ENGINES, ///< Toggle whether to display the hidden vehicles. WID_RV_SORT_DROPDOWN = ::WID_RV_SORT_DROPDOWN, ///< Dropdown for the sort criteria. + WID_RV_MATCH_AIRCRAFT_TYPE = ::WID_RV_MATCH_AIRCRAFT_TYPE, ///< Toggle whether to match aircraft type. /* Left and right matrix + details. */ WID_RV_LEFT_MATRIX = ::WID_RV_LEFT_MATRIX, ///< The matrix on the left. Index: src/settings_type.h =================================================================== --- src/settings_type.h (revision 27930) +++ src/settings_type.h (working copy) @@ -133,6 +133,7 @@ bool station_show_coverage; ///< whether to highlight coverage area bool persistent_buildingtools; ///< keep the building tools active after usage bool expenses_layout; ///< layout of expenses window + bool autoreplace_match_aircraft_type; ///< whether to match aircraft type for autoreplace uint32 last_newgrf_count; ///< the numbers of NewGRFs we found during the last scan byte missing_strings_threshold; ///< the number of missing strings before showing the warning uint8 graph_line_thickness; ///< the thickness of the lines in the various graph guis Index: src/table/settings.ini =================================================================== --- src/table/settings.ini (revision 27930) +++ src/table/settings.ini (working copy) @@ -3093,6 +3093,11 @@ strhelp = STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT proc = RedrawScreen +[SDTC_BOOL] +var = gui.autoreplace_match_aircraft_type +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = true + [SDTC_VAR] var = gui.station_gui_group_order type = SLE_UINT8 Index: src/widgets/autoreplace_widget.h =================================================================== --- src/widgets/autoreplace_widget.h (revision 27930) +++ src/widgets/autoreplace_widget.h (working copy) @@ -20,6 +20,7 @@ WID_RV_SORT_ASCENDING_DESCENDING, ///< Ascending/descending sort order button. WID_RV_SHOW_HIDDEN_ENGINES, ///< Toggle whether to display the hidden vehicles. WID_RV_SORT_DROPDOWN, ///< Dropdown for the sort criteria. + WID_RV_MATCH_AIRCRAFT_TYPE, ///< Toggle whether to match aircraft type. /* Left and right matrix + details. */ WID_RV_LEFT_MATRIX, ///< The matrix on the left.