diff --git a/src/command.cpp b/src/command.cpp index f1c4ea7924..c19cd48830 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -297,6 +297,7 @@ CommandProcEx CmdScheduledDispatchAddNewSchedule; CommandProc CmdScheduledDispatchRemoveSchedule; CommandProc CmdScheduledDispatchRenameSchedule; CommandProc CmdScheduledDispatchDuplicateSchedule; +CommandProc CmdScheduledDispatchAppendVehicleSchedules; CommandProc CmdAddPlan; CommandProcEx CmdAddPlanLine; @@ -555,6 +556,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdScheduledDispatchRemoveSchedule, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_REMOVE_SCHEDULE DEF_CMD(CmdScheduledDispatchRenameSchedule, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_RENAME_SCHEDULE DEF_CMD(CmdScheduledDispatchDuplicateSchedule, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_DUPLICATE_SCHEDULE + DEF_CMD(CmdScheduledDispatchAppendVehicleSchedules, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_APPEND_VEHICLE_SCHEDULE DEF_CMD(CmdAddPlan, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN DEF_CMD(CmdAddPlanLine, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN_LINE diff --git a/src/command_type.h b/src/command_type.h index 0f908962f6..a1b7fdb77f 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -519,6 +519,7 @@ enum Commands { CMD_SCHEDULED_DISPATCH_REMOVE_SCHEDULE, ///< scheduled dispatch remove schedule CMD_SCHEDULED_DISPATCH_RENAME_SCHEDULE, ///< scheduled dispatch rename schedule CMD_SCHEDULED_DISPATCH_DUPLICATE_SCHEDULE, ///< scheduled dispatch duplicate schedule + CMD_SCHEDULED_DISPATCH_APPEND_VEHICLE_SCHEDULE, ///< scheduled dispatch append schedules from another vehicle CMD_ADD_PLAN, CMD_ADD_PLAN_LINE, diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index 6adc77e65f..87ab841440 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -2010,7 +2010,7 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}Reset wh STR_SCHDISPATCH_CLEAR :{BLACK}Clear Departure Slots STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}Clear all departure slots from the schedule. STR_SCHDISPATCH_MANAGE :{BLACK}Manage Schedule -STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}{}{}{STRING} +STR_SCHDISPATCH_MANAGE_TOOLTIP_SUFFIX :{}{}{STRING} STR_SCHDISPATCH_PREV_SCHEDULE :{BLACK}Previous STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP :{BLACK}Go to previous dispatch schedule STR_SCHDISPATCH_NEXT_SCHEDULE :{BLACK}Next @@ -2021,6 +2021,8 @@ STR_SCHDISPATCH_REMOVE_SCHEDULE :{BLACK}Remove C STR_SCHDISPATCH_REMOVE_SCHEDULE_TOOLTIP :{BLACK}Remove this dispatch schedule entirely. STR_SCHDISPATCH_DUPLICATE_SCHEDULE :{BLACK}Duplicate Current Schedule STR_SCHDISPATCH_DUPLICATE_SCHEDULE_TOOLTIP :{BLACK}Create a copy of this dispatch schedule. +STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES :{BLACK}Append Schedules From Vehicle +STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES_TOOLTIP :{BLACK}Append the dispatch schedules from another vehicle. STR_SCHDISPATCH_NO_SCHEDULES :{BLACK}No Schedules STR_SCHDISPATCH_SCHEDULE_ID :{BLACK}Schedule {NUM} of {NUM} STR_SCHDISPATCH_NAMED_SCHEDULE_ID :{BLACK}{RAW_STRING} ({NUM} of {NUM}) diff --git a/src/lang/extra/galician.txt b/src/lang/extra/galician.txt index a5fad7a9d1..f6b927d646 100644 --- a/src/lang/extra/galician.txt +++ b/src/lang/extra/galician.txt @@ -1951,7 +1951,6 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}Restable STR_SCHDISPATCH_CLEAR :{BLACK}Limpar slots de saídas STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}Limpar todos os slots de saídas do programa STR_SCHDISPATCH_MANAGE :{BLACK}Xestionar programa -STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}{}{}{STRING} STR_SCHDISPATCH_PREV_SCHEDULE :{BLACK}Anterior STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP :{BLACK}Ir a saída programada anterior STR_SCHDISPATCH_NEXT_SCHEDULE :{BLACK}Seguinte diff --git a/src/lang/extra/german.txt b/src/lang/extra/german.txt index 9aab8b0ecc..17c5f4bd5a 100644 --- a/src/lang/extra/german.txt +++ b/src/lang/extra/german.txt @@ -1762,7 +1762,6 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}Setzt di STR_SCHDISPATCH_CLEAR :{BLACK}Lösche Abfahrtszeiten STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}Lösche alle Abfahrtszeiten aus dem Zeitplan. STR_SCHDISPATCH_MANAGE :{BLACK}Bearbeite Zeitplan -STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}{}{}{STRING} STR_SCHDISPATCH_PREV_SCHEDULE :{BLACK}Vorheriger STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP :{BLACK}Gehe zum vorherigen Zeitplan STR_SCHDISPATCH_NEXT_SCHEDULE :{BLACK}Nächster diff --git a/src/lang/extra/korean.txt b/src/lang/extra/korean.txt index 76eb08571e..c599fe7738 100644 --- a/src/lang/extra/korean.txt +++ b/src/lang/extra/korean.txt @@ -1958,7 +1958,6 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}최근 STR_SCHDISPATCH_CLEAR :{BLACK}출발 슬롯 초기화 STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}일정에서 모든 출발 슬롯을 제거합니다. STR_SCHDISPATCH_MANAGE :{BLACK}일정 관리 -STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}{}{}{STRING} STR_SCHDISPATCH_PREV_SCHEDULE :{BLACK}이전 STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP :{BLACK}이전 배차 일정으로 이동합니다 STR_SCHDISPATCH_NEXT_SCHEDULE :{BLACK}다음 diff --git a/src/lang/extra/simplified_chinese.txt b/src/lang/extra/simplified_chinese.txt index 98b12ef7cc..f4608c42e9 100644 --- a/src/lang/extra/simplified_chinese.txt +++ b/src/lang/extra/simplified_chinese.txt @@ -1918,7 +1918,6 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}当车 STR_SCHDISPATCH_CLEAR :{BLACK}清除出发条目 STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}从计划调度中清除全部的出发条目 STR_SCHDISPATCH_MANAGE :{BLACK}管理计划调度 -STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}{}{}{STRING} STR_SCHDISPATCH_PREV_SCHEDULE :{BLACK}上个 STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP :{BLACK}跳转到前一个出发条目 STR_SCHDISPATCH_NEXT_SCHEDULE :{BLACK}下个 diff --git a/src/schdispatch_cmd.cpp b/src/schdispatch_cmd.cpp index 08baf69b1d..b6a8547ddc 100644 --- a/src/schdispatch_cmd.cpp +++ b/src/schdispatch_cmd.cpp @@ -476,6 +476,7 @@ CommandCost CmdScheduledDispatchDuplicateSchedule(TileIndex tile, DoCommandFlag if (ret.Failed()) return ret; if (v->orders == nullptr) return CMD_ERROR; + if (v->orders->GetScheduledDispatchScheduleCount() >= 4096) return CMD_ERROR; if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR; @@ -489,6 +490,46 @@ CommandCost CmdScheduledDispatchDuplicateSchedule(TileIndex tile, DoCommandFlag return CommandCost(); } +/** + * Append scheduled dispatch schedules from another vehicle + * + * @param tile Not used. + * @param flags Operation to perform. + * @param p1 Vehicle index to append to + * @param p2 Vehicle index to copy from + * @param text name + * @return the cost of this operation or an error + */ +CommandCost CmdScheduledDispatchAppendVehicleSchedules(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + VehicleID veh1 = GB(p1, 0, 20); + VehicleID veh2 = GB(p2, 0, 20); + + Vehicle *v1 = Vehicle::GetIfValid(veh1); + if (v1 == nullptr || !v1->IsPrimaryVehicle()) return CMD_ERROR; + + const Vehicle *v2 = Vehicle::GetIfValid(veh2); + if (v2 == nullptr || !v2->IsPrimaryVehicle()) return CMD_ERROR; + + CommandCost ret = CheckOwnership(v1->owner); + if (ret.Failed()) return ret; + + if (v1->orders == nullptr || v2->orders == nullptr || v1->orders == v2->orders) return CMD_ERROR; + + if (v1->orders->GetScheduledDispatchScheduleCount() + v2->orders->GetScheduledDispatchScheduleCount() > 4096) return CMD_ERROR; + + if (flags & DC_EXEC) { + for (uint i = 0; i < v2->orders->GetScheduledDispatchScheduleCount(); i++) { + DispatchSchedule &ds = v1->orders->GetScheduledDispatchScheduleSet().emplace_back(v2->orders->GetDispatchScheduleByIndex(i)); + ds.SetScheduledDispatchLastDispatch(0); + ds.UpdateScheduledDispatch(nullptr); + } + SetTimetableWindowsDirty(v1, true); + } + + return CommandCost(); +} + /** * Set scheduled dispatch slot list. * @param dispatch_list The offset time list, must be correctly sorted. diff --git a/src/schdispatch_gui.cpp b/src/schdispatch_gui.cpp index da42bb5d98..6d1998a59f 100644 --- a/src/schdispatch_gui.cpp +++ b/src/schdispatch_gui.cpp @@ -26,6 +26,7 @@ #include "viewport_func.h" #include "zoom_func.h" #include "core/geometry_func.hpp" +#include "tilehighlight_func.h" #include #include @@ -225,6 +226,7 @@ struct SchdispatchWindow : GeneralVehicleWindow { SCH_MD_CLEAR_SCHEDULE, SCH_MD_REMOVE_SCHEDULE, SCH_MD_DUPLICATE_SCHEDULE, + SCH_MD_APPEND_VEHICLE_SCHEDULES, }; bool IsScheduleSelected() const @@ -384,12 +386,16 @@ struct SchdispatchWindow : GeneralVehicleWindow { } case WID_SCHDISPATCH_MANAGEMENT: { - uint64 params[4]; - params[0] = STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP; - params[1] = STR_SCHDISPATCH_CLEAR_TOOLTIP; - params[2] = STR_SCHDISPATCH_REMOVE_SCHEDULE_TOOLTIP; - params[3] = STR_SCHDISPATCH_DUPLICATE_SCHEDULE_TOOLTIP; - GuiShowTooltips(this, STR_SCHDISPATCH_MANAGE_TOOLTIP, lengthof(params), params, close_cond); + _temp_special_strings[0] = GetString(STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP); + auto add_suffix = [&](StringID str) { + SetDParam(0, str); + _temp_special_strings[0] += GetString(STR_SCHDISPATCH_MANAGE_TOOLTIP_SUFFIX); + }; + add_suffix(STR_SCHDISPATCH_CLEAR_TOOLTIP); + add_suffix(STR_SCHDISPATCH_REMOVE_SCHEDULE_TOOLTIP); + add_suffix(STR_SCHDISPATCH_DUPLICATE_SCHEDULE_TOOLTIP); + add_suffix(STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES_TOOLTIP); + GuiShowTooltips(this, SPECSTR_TEMP_START, 0, nullptr, close_cond); return true; } @@ -731,6 +737,7 @@ struct SchdispatchWindow : GeneralVehicleWindow { add_item(STR_SCHDISPATCH_CLEAR, SCH_MD_CLEAR_SCHEDULE); add_item(STR_SCHDISPATCH_REMOVE_SCHEDULE, SCH_MD_REMOVE_SCHEDULE); add_item(STR_SCHDISPATCH_DUPLICATE_SCHEDULE, SCH_MD_DUPLICATE_SCHEDULE); + add_item(STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES, SCH_MD_APPEND_VEHICLE_SCHEDULES); ShowDropDownList(this, std::move(list), -1, WID_SCHDISPATCH_MANAGEMENT); break; } @@ -807,6 +814,15 @@ struct SchdispatchWindow : GeneralVehicleWindow { case SCH_MD_DUPLICATE_SCHEDULE: DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), 0, CMD_SCHEDULED_DISPATCH_DUPLICATE_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); break; + + case SCH_MD_APPEND_VEHICLE_SCHEDULES: { + static const CursorID clone_icons[] = { + SPR_CURSOR_CLONE_TRAIN, SPR_CURSOR_CLONE_ROADVEH, + SPR_CURSOR_CLONE_SHIP, SPR_CURSOR_CLONE_AIRPLANE + }; + SetObjectToPlaceWnd(clone_icons[this->vehicle->type], PAL_NONE, HT_VEHICLE, this); + break; + } } } @@ -911,6 +927,15 @@ struct SchdispatchWindow : GeneralVehicleWindow { } } + bool OnVehicleSelect(const Vehicle *v) override + { + if (v->orders == nullptr || v->orders->GetScheduledDispatchScheduleCount() == 0) return false; + + DoCommandP(0, this->vehicle->index, v->index, CMD_SCHEDULED_DISPATCH_APPEND_VEHICLE_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + ResetObjectToPlace(); + return true; + } + const Vehicle *GetVehicle() { return this->vehicle; @@ -981,7 +1006,7 @@ static const NWidgetPart _nested_schdispatch_widgets[] = { EndContainer(), NWidget(NWID_VERTICAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_SET_DELAY), SetDataTip(STR_SCHDISPATCH_DELAY, STR_SCHDISPATCH_DELAY_TOOLTIP), SetFill(1, 1), SetResize(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SCHDISPATCH_MANAGEMENT), SetDataTip(STR_SCHDISPATCH_MANAGE, STR_SCHDISPATCH_MANAGE_TOOLTIP), SetFill(1, 1), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SCHDISPATCH_MANAGEMENT), SetDataTip(STR_SCHDISPATCH_MANAGE, STR_NULL), SetFill(1, 1), SetResize(1, 0), EndContainer(), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(),