diff --git a/src/lang/english.txt b/src/lang/english.txt index 0e38639ccd..34a7bb0b91 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2465,6 +2465,7 @@ STR_TRACE_RESTRICT_INSERT :{BLACK}Insert STR_TRACE_RESTRICT_REMOVE :{BLACK}Remove STR_TRACE_RESTRICT_RESET :{BLACK}Reset STR_TRACE_RESTRICT_COPY :{BLACK}Copy +STR_TRACE_RESTRICT_APPEND :{BLACK}Append STR_TRACE_RESTRICT_SHARE :{BLACK}Share STR_TRACE_RESTRICT_UNSHARE :{BLACK}Unshare STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Select Target @@ -2472,7 +2473,7 @@ STR_TRACE_RESTRICT_SELECT_SIGNAL :{BLACK}Select S STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction{}Ctrl+Click to remove the selected conditional instruction but retain its contents STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs) -STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal +STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal{}Ctrl+click to append program from another signal STR_TRACE_RESTRICT_SHARE_TOOLTIP :{BLACK}Share program with another signal STR_TRACE_RESTRICT_UNSHARE_TOOLTIP :{BLACK}Stop sharing program with other signals, create a copy of the program STR_TRACE_RESTRICT_SIGNAL_GUI_TOOLTIP :{BLACK}Routefinding restriction @@ -2495,6 +2496,7 @@ STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION :Validation fail STR_TRACE_RESTRICT_ERROR_SOURCE_SAME_AS_TARGET :Source and target signals are the same STR_TRACE_RESTRICT_ERROR_CAN_T_RESET_SIGNAL :{WHITE}Can't reset signal STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM :{WHITE}Can't copy program +STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_APPEND_PROGRAM :{WHITE}Can't append program STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM :{WHITE}Can't share program STR_TRACE_RESTRICT_ERROR_CAN_T_UNSHARE_PROGRAM :{WHITE}Can't unshare program diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 58e24e51e2..d522503f51 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -1167,7 +1167,8 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag if (self == source) { return_cmd_error(STR_TRACE_RESTRICT_ERROR_SOURCE_SAME_AS_TARGET); } - + } + if (type == TRDCT_PROG_SHARE || type == TRDCT_PROG_COPY || type == TRDCT_PROG_COPY_APPEND) { ret = TraceRestrictCheckTileIsUsable(source_tile, source_track); if (ret.Failed()) { return ret; @@ -1199,6 +1200,21 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag break; } + case TRDCT_PROG_COPY_APPEND: { + TraceRestrictProgram *source_prog = GetTraceRestrictProgram(source, false); + if (source_prog && !source_prog->items.empty()) { + TraceRestrictProgram *prog = GetTraceRestrictProgram(self, true); + if (!prog) { + // allocation failed + return CMD_ERROR; + } + prog->items.reserve(prog->items.size() + source_prog->items.size()); // this is in case prog == source_prog + prog->items.insert(prog->items.end(), source_prog->items.begin(), source_prog->items.end()); // append + prog->Validate(); + } + break; + } + case TRDCT_PROG_SHARE: { TraceRestrictRemoveProgramMapping(self); TraceRestrictProgram *source_prog = GetTraceRestrictProgram(source, true); diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 520e183477..74403e586e 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -632,6 +632,7 @@ enum TraceRestrictDoCommandType { TRDCT_MOVE_ITEM, ///< move instruction or block at offset field TRDCT_PROG_COPY, ///< copy program operation. Do not re-order this with respect to other values + TRDCT_PROG_COPY_APPEND, ///< copy and append program operation TRDCT_PROG_SHARE, ///< share program operation TRDCT_PROG_UNSHARE, ///< unshare program (copy as a new program) TRDCT_PROG_RESET, ///< reset program state of signal diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 4860631b34..e212d7e3ec 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -50,6 +50,7 @@ enum TraceRestrictWindowWidgets { TR_WIDGET_SEL_TOP_MIDDLE, TR_WIDGET_SEL_TOP_RIGHT, TR_WIDGET_SEL_SHARE, + TR_WIDGET_SEL_COPY, TR_WIDGET_UP_BTN, TR_WIDGET_DOWN_BTN, @@ -74,6 +75,7 @@ enum TraceRestrictWindowWidgets { TR_WIDGET_REMOVE, TR_WIDGET_RESET, TR_WIDGET_COPY, + TR_WIDGET_COPY_APPEND, TR_WIDGET_SHARE, TR_WIDGET_UNSHARE, }; @@ -104,6 +106,10 @@ enum PanelWidgets { // Share DPS_SHARE = 0, DPS_UNSHARE, + + // Copy + DPC_COPY = 0, + DPC_APPEND, }; /** @@ -1191,6 +1197,7 @@ public: } case TR_WIDGET_COPY: + case TR_WIDGET_COPY_APPEND: case TR_WIDGET_SHARE: SetObjectToPlaceAction(widget, ANIMCURSOR_BUILDSIGNALS); break; @@ -1353,6 +1360,10 @@ public: OnPlaceObjectSignal(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM); break; + case TR_WIDGET_COPY_APPEND: + OnPlaceObjectSignal(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_APPEND_PROGRAM); + break; + case TR_WIDGET_SHARE: OnPlaceObjectSignal(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM); break; @@ -1411,6 +1422,11 @@ public: source_tile, source_track, STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM); break; + case TR_WIDGET_COPY_APPEND: + TraceRestrictProgMgmtWithSourceDoCommandP(this->tile, this->track, TRDCT_PROG_COPY_APPEND, + source_tile, source_track, STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_APPEND_PROGRAM); + break; + case TR_WIDGET_SHARE: TraceRestrictProgMgmtWithSourceDoCommandP(this->tile, this->track, TRDCT_PROG_SHARE, source_tile, source_track, STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM); @@ -1782,6 +1798,7 @@ private: NWidgetStacked *middle_sel = this->GetWidget(TR_WIDGET_SEL_TOP_MIDDLE); NWidgetStacked *right_sel = this->GetWidget(TR_WIDGET_SEL_TOP_RIGHT); NWidgetStacked *share_sel = this->GetWidget(TR_WIDGET_SEL_SHARE); + NWidgetStacked *copy_sel = this->GetWidget(TR_WIDGET_SEL_COPY); this->DisableWidget(TR_WIDGET_TYPE_COND); this->DisableWidget(TR_WIDGET_TYPE_NONCOND); @@ -1808,11 +1825,14 @@ private: this->DisableWidget(TR_WIDGET_UP_BTN); this->DisableWidget(TR_WIDGET_DOWN_BTN); + this->EnableWidget(TR_WIDGET_COPY_APPEND); + left_2_sel->SetDisplayedPlane(DPL2_BLANK); left_sel->SetDisplayedPlane(DPL_BLANK); middle_sel->SetDisplayedPlane(DPM_BLANK); right_sel->SetDisplayedPlane(DPR_BLANK); share_sel->SetDisplayedPlane(DPS_SHARE); + copy_sel->SetDisplayedPlane(_ctrl_pressed ? DPC_APPEND : DPC_COPY); const TraceRestrictProgram *prog = this->GetProgram(); @@ -2178,8 +2198,12 @@ static const NWidgetPart _nested_program_widgets[] = { SetDataTip(STR_TRACE_RESTRICT_REMOVE, STR_TRACE_RESTRICT_REMOVE_TOOLTIP), SetResize(1, 0), NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_RESET), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_TRACE_RESTRICT_RESET, STR_TRACE_RESTRICT_RESET_TOOLTIP), SetResize(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_COPY), SetMinimalSize(124, 12), SetFill(1, 0), + NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_COPY), + NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_COPY), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_TRACE_RESTRICT_COPY, STR_TRACE_RESTRICT_COPY_TOOLTIP), SetResize(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_COPY_APPEND), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_TRACE_RESTRICT_APPEND, STR_TRACE_RESTRICT_COPY_TOOLTIP), SetResize(1, 0), + EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_SHARE), NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_SHARE), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_TRACE_RESTRICT_SHARE, STR_TRACE_RESTRICT_SHARE_TOOLTIP), SetResize(1, 0),