Allow naming scheduled dispatch schedules

pull/512/head
Jonathan G Rennison 1 year ago
parent 6445d688ed
commit 211c1ba61d

@ -294,6 +294,7 @@ CommandProc CmdScheduledDispatchResetLastDispatch;
CommandProc CmdScheduledDispatchClear;
CommandProcEx CmdScheduledDispatchAddNewSchedule;
CommandProc CmdScheduledDispatchRemoveSchedule;
CommandProc CmdScheduledDispatchRenameSchedule;
CommandProc CmdAddPlan;
CommandProcEx CmdAddPlanLine;
@ -549,6 +550,7 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdScheduledDispatchClear, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_CLEAR
DEF_CMD(CmdScheduledDispatchAddNewSchedule, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE
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(CmdAddPlan, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN
DEF_CMD(CmdAddPlanLine, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN_LINE

@ -516,6 +516,7 @@ enum Commands {
CMD_SCHEDULED_DISPATCH_CLEAR, ///< scheduled dispatch clear schedule
CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE, ///< scheduled dispatch add new schedule
CMD_SCHEDULED_DISPATCH_REMOVE_SCHEDULE, ///< scheduled dispatch remove schedule
CMD_SCHEDULED_DISPATCH_RENAME_SCHEDULE, ///< scheduled dispatch rename schedule
CMD_ADD_PLAN,
CMD_ADD_PLAN_LINE,

@ -1632,6 +1632,7 @@ STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Open sch
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :{PUSH_COLOUR}{YELLOW}[{STRING1}scheduled dispatch]{POP_COLOUR}
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[{STRING1}scheduled dispatch - no wait time timetabled]{POP_COLOUR}
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_SCHEDULE_INDEX :{NUM}{NBSP}-{NBSP}
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NAMED_SCHEDULE :{RAW_STRING}{NBSP}-{NBSP}
STR_TIMETABLE_LOCK_ORDER_TIME_TOOLTIP :{BLACK}Lock/unlock the amount of time for the highlighted order (Ctrl+Click set lock state for all orders).{}When locked the time will not be changed by timetable autofill or automate.
@ -1799,6 +1800,7 @@ STR_JUST_TIME_HHMM :{TIME_HHMM}
STR_JUST_STRING1 :{STRING1}
STR_JUST_STRING2 :{STRING2}
STR_JUST_STRING3 :{STRING3}
STR_JUST_VELOCITY :{VELOCITY}
@ -2005,6 +2007,10 @@ STR_SCHDISPATCH_REMOVE_SCHEDULE :{BLACK}Remove C
STR_SCHDISPATCH_REMOVE_SCHEDULE_TOOLTIP :{BLACK}Remove this dispatch schedule entirely.
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})
STR_SCHDISPATCH_RENAME_SCHEDULE_TOOLTIP :{BLACK}Name schedule
STR_SCHDISPATCH_RENAME_SCHEDULE_CAPTION :{WHITE}Name schedule
STR_ERROR_CAN_T_RENAME_SCHEDULE :{WHITE}Can't name schedule...
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {DATE_WALLCLOCK_TINY}.
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}Last departure has not left yet, it will depart at {DATE_WALLCLOCK_TINY}.

@ -697,6 +697,8 @@ private:
int32 scheduled_dispatch_last_dispatch = 0; ///< Last vehicle dispatched offset
int32 scheduled_dispatch_max_delay = 0; ///< Maximum allowed delay
std::string name; ///< Name of dispatch schedule
inline void CopyBasicFields(const DispatchSchedule &other)
{
this->scheduled_dispatch_duration = other.scheduled_dispatch_duration;
@ -801,6 +803,9 @@ public:
{
other.scheduled_dispatch = std::move(this->scheduled_dispatch);
}
inline std::string &ScheduleName() { return this->name; }
inline const std::string &ScheduleName() const { return this->name; }
};
/**

@ -1075,11 +1075,16 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
} else if (ocv == OCV_DISPATCH_SLOT) {
SetDParam(0, STR_ORDER_CONDITIONAL_DISPATCH_SLOT_DISPLAY);
if (GB(order->GetXData(), 0, 16) != UINT16_MAX) {
char buf[256];
int64 args_array[] = { GB(order->GetXData(), 0, 16) + 1 };
StringParameters tmp_params(args_array);
char *end = GetStringWithArgs(buf, STR_TIMETABLE_ASSIGN_SCHEDULE_ID, &tmp_params, lastof(buf));
_temp_special_strings[0].assign(buf, end);
const DispatchSchedule &ds = v->orders->GetDispatchScheduleByIndex(GB(order->GetXData(), 0, 16));
if (ds.ScheduleName().empty()) {
char buf[256];
int64 args_array[] = { GB(order->GetXData(), 0, 16) + 1 };
StringParameters tmp_params(args_array);
char *end = GetStringWithArgs(buf, STR_TIMETABLE_ASSIGN_SCHEDULE_ID, &tmp_params, lastof(buf));
_temp_special_strings[0].assign(buf, end);
} else {
_temp_special_strings[0] = ds.ScheduleName();
}
SetDParam(2, SPECSTR_TEMP_START);
} else {
SetDParam(2, STR_TIMETABLE_ASSIGN_SCHEDULE_NONE);
@ -1199,8 +1204,14 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
}
if (timetable && HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && order->IsScheduledDispatchOrder(false) && edge != 0) {
StringID str = order->IsWaitTimetabled() ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER : STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME;
SetDParam(0, v->orders->GetScheduledDispatchScheduleCount() > 1 ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_SCHEDULE_INDEX : STR_EMPTY);
SetDParam(1, order->GetDispatchScheduleIndex() + 1);
const DispatchSchedule &ds = v->orders->GetDispatchScheduleByIndex(order->GetDispatchScheduleIndex());
if (!ds.ScheduleName().empty()) {
SetDParam(0, STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NAMED_SCHEDULE);
SetDParamStr(1, ds.ScheduleName().c_str());
} else {
SetDParam(0, v->orders->GetScheduledDispatchScheduleCount() > 1 ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_SCHEDULE_INDEX : STR_EMPTY);
SetDParam(1, order->GetDispatchScheduleIndex() + 1);
}
edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, str, colour);
}
@ -2489,8 +2500,14 @@ public:
const Order *order = this->vehicle->GetOrder(sel);
if (order != nullptr && order->IsType(OT_CONDITIONAL) && GB(order->GetXData(), 0, 16) != UINT16_MAX) {
SetDParam(0, STR_TIMETABLE_ASSIGN_SCHEDULE_ID);
SetDParam(1, GB(order->GetXData(), 0, 16) + 1);
const DispatchSchedule &ds = this->vehicle->orders->GetDispatchScheduleByIndex(GB(order->GetXData(), 0, 16));
if (ds.ScheduleName().empty()) {
SetDParam(0, STR_TIMETABLE_ASSIGN_SCHEDULE_ID);
SetDParam(1, GB(order->GetXData(), 0, 16) + 1);
} else {
SetDParam(0, STR_JUST_RAW_STRING);
SetDParamStr(1, ds.ScheduleName().c_str());
}
} else {
SetDParam(0, STR_TIMETABLE_ASSIGN_SCHEDULE_NONE);
}
@ -2811,9 +2828,15 @@ public:
uint count = this->vehicle->orders->GetScheduledDispatchScheduleCount();
DropDownList list;
for (uint i = 0; i < count; ++i) {
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_ID, i, false);
item->SetParam(0, i + 1);
list.emplace_back(item);
const DispatchSchedule &ds = this->vehicle->orders->GetDispatchScheduleByIndex(i);
if (ds.ScheduleName().empty()) {
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_ID, i, false);
item->SetParam(0, i + 1);
list.emplace_back(item);
} else {
DropDownListCharStringItem *item = new DropDownListCharStringItem(ds.ScheduleName(), i, false);
list.emplace_back(item);
}
}
if (!list.empty()) ShowDropDownList(this, std::move(list), selected, WID_O_COND_SCHED_SELECT, 0);
break;

@ -115,7 +115,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_STATION_CATCHMENT_INC, XSCF_NULL, 1, 1, "station_catchment_inc", nullptr, nullptr, nullptr },
{ XSLFI_CUSTOM_BRIDGE_HEADS, XSCF_NULL, 4, 4, "custom_bridge_heads", nullptr, nullptr, nullptr },
{ XSLFI_CHUNNEL, XSCF_NULL, 2, 2, "chunnel", nullptr, nullptr, "TUNN" },
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 3, 3, "scheduled_dispatch", nullptr, nullptr, nullptr },
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 4, 4, "scheduled_dispatch", nullptr, nullptr, nullptr },
{ XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", nullptr, nullptr, nullptr },
{ XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 2, 2, "multiple_docks", nullptr, nullptr, nullptr },
{ XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 7, 7, "timetable_extra", nullptr, nullptr, "ORDX" },

@ -266,6 +266,7 @@ SaveLoadTable GetDispatchScheduleDescription()
SLE_VAR(DispatchSchedule, scheduled_dispatch_start_full_date_fract, SLE_UINT16),
SLE_VAR(DispatchSchedule, scheduled_dispatch_last_dispatch, SLE_INT32),
SLE_VAR(DispatchSchedule, scheduled_dispatch_max_delay, SLE_INT32),
SLE_CONDSSTR_X(DispatchSchedule, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 4)),
};
return _order_extra_info_desc;

@ -411,6 +411,49 @@ CommandCost CmdScheduledDispatchRemoveSchedule(TileIndex tile, DoCommandFlag fla
return CommandCost();
}
/**
* Rename scheduled dispatch schedule
*
* @param tile Not used.
* @param flags Operation to perform.
* @param p1 Vehicle index
* @param p2 Not used
* @param text name
* @return the cost of this operation or an error
*/
CommandCost CmdScheduledDispatchRenameSchedule(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
VehicleID veh = GB(p1, 0, 20);
uint schedule_index = GB(p1, 20, 12);
Vehicle *v = Vehicle::GetIfValid(veh);
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner);
if (ret.Failed()) return ret;
if (v->orders == nullptr) return CMD_ERROR;
if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
bool reset = StrEmpty(text);
if (!reset) {
if (Utf8StringLength(text) >= MAX_LENGTH_VEHICLE_NAME_CHARS) return CMD_ERROR;
}
if (flags & DC_EXEC) {
if (reset) {
v->orders->GetDispatchScheduleByIndex(schedule_index).ScheduleName().clear();
} else {
v->orders->GetDispatchScheduleByIndex(schedule_index).ScheduleName() = text;
}
SetTimetableWindowsDirty(v, true);
}
return CommandCost();
}
/**
* Set scheduled dispatch slot list.
* @param dispatch_list The offset time list, must be correctly sorted.

@ -38,6 +38,7 @@
enum SchdispatchWidgets {
WID_SCHDISPATCH_CAPTION, ///< Caption of window.
WID_SCHDISPATCH_RENAME, ///< Rename button.
WID_SCHDISPATCH_MATRIX, ///< Matrix of vehicles.
WID_SCHDISPATCH_V_SCROLL, ///< Vertical scrollbar.
WID_SCHDISPATCH_SUMMARY_PANEL, ///< Summary panel
@ -323,6 +324,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
this->SetWidgetDisabledState(WID_SCHDISPATCH_ENABLED, unusable || HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION));
this->SetWidgetDisabledState(WID_SCHDISPATCH_RENAME, unusable || v->orders->GetScheduledDispatchScheduleCount() == 0);
this->SetWidgetDisabledState(WID_SCHDISPATCH_PREV, v->orders == nullptr || this->schedule_index <= 0);
this->SetWidgetDisabledState(WID_SCHDISPATCH_NEXT, v->orders == nullptr || this->schedule_index >= (int)(v->orders->GetScheduledDispatchScheduleCount() - 1));
this->SetWidgetDisabledState(WID_SCHDISPATCH_ADD_SCHEDULE, unusable || v->orders->GetScheduledDispatchScheduleCount() >= 4096);
@ -349,9 +351,17 @@ struct SchdispatchWindow : GeneralVehicleWindow {
case WID_SCHDISPATCH_HEADER:
if (this->IsScheduleSelected()) {
SetDParam(0, STR_SCHDISPATCH_SCHEDULE_ID);
SetDParam(1, this->schedule_index + 1);
SetDParam(2, this->vehicle->orders->GetScheduledDispatchScheduleCount());
const DispatchSchedule &ds = this->GetSelectedSchedule();
if (ds.ScheduleName().empty()) {
SetDParam(0, STR_SCHDISPATCH_SCHEDULE_ID);
SetDParam(1, this->schedule_index + 1);
SetDParam(2, this->vehicle->orders->GetScheduledDispatchScheduleCount());
} else {
SetDParam(0, STR_SCHDISPATCH_NAMED_SCHEDULE_ID);
SetDParamStr(1, ds.ScheduleName().c_str());
SetDParam(2, this->schedule_index + 1);
SetDParam(3, this->vehicle->orders->GetScheduledDispatchScheduleCount());
}
} else {
SetDParam(0, STR_SCHDISPATCH_NO_SCHEDULES);
}
@ -737,6 +747,13 @@ struct SchdispatchWindow : GeneralVehicleWindow {
case WID_SCHDISPATCH_ADD_SCHEDULE:
AddNewScheduledDispatchSchedule(this->vehicle->index);
break;
case WID_SCHDISPATCH_RENAME:
if (!this->IsScheduleSelected()) break;
SetDParamStr(0, this->GetSelectedSchedule().ScheduleName().c_str());
ShowQueryString(STR_JUST_RAW_STRING, STR_SCHDISPATCH_RENAME_SCHEDULE_CAPTION,
MAX_LENGTH_VEHICLE_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
break;
}
this->SetDirty();
@ -861,6 +878,13 @@ struct SchdispatchWindow : GeneralVehicleWindow {
}
break;
}
case WID_SCHDISPATCH_RENAME: {
if (str == nullptr) return;
DoCommandP(0, v->index | (this->schedule_index << 20), 0, CMD_SCHEDULED_DISPATCH_RENAME_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_RENAME_SCHEDULE), nullptr, str);
break;
}
}
this->SetDirty();
@ -919,6 +943,7 @@ void CcAddNewSchDispatchSchedule(const CommandCost &result, TileIndex tile, uint
static const NWidgetPart _nested_schdispatch_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SCHDISPATCH_RENAME), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_SCHDISPATCH_RENAME_SCHEDULE_TOOLTIP),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_SCHDISPATCH_CAPTION), SetDataTip(STR_SCHDISPATCH_CAPTION, STR_NULL),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
@ -927,7 +952,7 @@ static const NWidgetPart _nested_schdispatch_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_ENABLED), SetDataTip(STR_SCHDISPATCH_ENABLED, STR_SCHDISPATCH_ENABLED_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_SCHDISPATCH_HEADER), SetAlignment(SA_CENTER), SetDataTip(STR_JUST_STRING2, STR_NULL), SetFill(1, 1), SetResize(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_SCHDISPATCH_HEADER), SetAlignment(SA_CENTER), SetDataTip(STR_JUST_STRING3, STR_NULL), SetFill(1, 1), SetResize(1, 0),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_PREV), SetDataTip(STR_SCHDISPATCH_PREV_SCHEDULE, STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_NEXT), SetDataTip(STR_SCHDISPATCH_NEXT_SCHEDULE, STR_SCHDISPATCH_NEXT_SCHEDULE_TOOLTIP), SetFill(1, 1), SetResize(1, 0),

@ -1071,9 +1071,15 @@ struct TimetableWindow : GeneralVehicleWindow {
list.emplace_back(new DropDownListStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_NONE, -1, false));
for (uint i = 0; i < v->orders->GetScheduledDispatchScheduleCount(); i++) {
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_ID, i, false);
item->SetParam(0, i + 1);
list.emplace_back(item);
const DispatchSchedule &ds = this->vehicle->orders->GetDispatchScheduleByIndex(i);
if (ds.ScheduleName().empty()) {
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_ID, i, false);
item->SetParam(0, i + 1);
list.emplace_back(item);
} else {
DropDownListCharStringItem *item = new DropDownListCharStringItem(ds.ScheduleName(), i, false);
list.emplace_back(item);
}
}
ShowDropDownList(this, std::move(list), order->GetDispatchScheduleIndex(), WID_VT_ASSIGN_SCHEDULE);
break;

Loading…
Cancel
Save