Allow manually removing/setting train speed restriction

From vehicle details window
See: #674
tmp-jgrpp
Jonathan G Rennison 1 month ago
parent a0454490ab
commit 0484ba700f

@ -246,6 +246,7 @@ CommandProc CmdAutoreplaceVehicle;
CommandProc CmdTemplateReplaceVehicle;
CommandProc CmdDepotSellAllVehicles;
CommandProc CmdDepotMassAutoReplace;
CommandProc CmdSetTrainSpeedRestriction;
CommandProc CmdCreateGroup;
CommandProc CmdAlterGroup;
@ -515,6 +516,7 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdTemplateReplaceVehicle, CMD_NO_TEST, CMDT_VEHICLE_MANAGEMENT ), // CMD_TEMPLATE_REPLACE_VEHICLE
DEF_CMD(CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION ), // CMD_DEPOT_SELL_ALL_VEHICLES
DEF_CMD(CmdDepotMassAutoReplace, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION ), // CMD_DEPOT_MASS_AUTOREPLACE
DEF_CMD(CmdSetTrainSpeedRestriction, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_SET_TRAIN_SPEED_RESTRICTION
DEF_CMD(CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CREATE_GROUP
DEF_CMD(CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_DELETE_GROUP
DEF_CMD(CmdAlterGroup, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ALTER_GROUP

@ -462,6 +462,7 @@ enum Commands {
CMD_TEMPLATE_REPLACE_VEHICLE, ///< template replace a vehicle while it is in a depot
CMD_DEPOT_SELL_ALL_VEHICLES, ///< sell all vehicles which are in a given depot
CMD_DEPOT_MASS_AUTOREPLACE, ///< force the autoreplace to take action in a given depot
CMD_SET_TRAIN_SPEED_RESTRICTION, ///< manually set train speed restriction
CMD_CREATE_GROUP, ///< create a new group
CMD_DELETE_GROUP, ///< delete a group

@ -1619,6 +1619,10 @@ STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE_AND_SPEED :{LTBLUE}{ENGINE
STR_VEHICLE_DETAILS_TRAIN_TOTAL_WEIGHT :{BLACK}Total weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}(empty) - {LTBLUE}{WEIGHT_SHORT} {BLACK}(loaded)
STR_VEHICLE_DETAILS_TRAIN_MAX_SPEED :{BLACK}Max. speed: {LTBLUE}{VELOCITY} {BLACK}(empty) - {LTBLUE}{VELOCITY} {BLACK}(loaded)
STR_VEHICLE_DETAILS_EXTRA_ACTIONS_TOOLTIP :{BLACK}Extra vehicle actions
STR_VEHICLE_DETAILS_REMOVE_SPEED_RESTRICTION :Remove speed restriction
STR_VEHICLE_DETAILS_SET_SPEED_RESTRICTION :Set speed restriction
STR_ORDER_DROP_CARGO_TYPE_LOAD :Load by cargo type
STR_ORDER_DROP_CARGO_TYPE_UNLOAD :Unload by cargo type
@ -2312,3 +2316,5 @@ STR_VIEWPORT_TOWN_COLOUR_CITY_POP :{WHITE}{TOWN} {
STR_ABOUT_MENU_SHOW_PICKER_TOOL :Picker tool
STR_ABOUT_MENU_SHOW_TOGGLE_MODIFIER_KEYS :Modifier key window
STR_ERROR_CAN_T_CHANGE_SPEED_RESTRICTION :{WHITE}Can't change vehicle's speed restriction...

@ -7733,3 +7733,35 @@ uint16_t Train::GetMaxWeight() const
return weight;
}
/**
* Set train speed restriction
* @param tile unused
* @param flags type of operation
* @param p1 vehicle
* @param p2 new speed restriction value
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdSetTrainSpeedRestriction(TileIndex tile, DoCommandFlag flags, uint32_t p1, uint32_t p2, const char *text)
{
Vehicle *v = Vehicle::GetIfValid(p1);
if (v == nullptr || v->type != VEH_TRAIN || !v->IsPrimaryVehicle()) return CMD_ERROR;
CommandCost ret = CheckVehicleControlAllowed(v);
if (ret.Failed()) return ret;
if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED);
if (flags & DC_EXEC) {
Train *t = Train::From(v);
if (HasBit(t->flags, VRF_PENDING_SPEED_RESTRICTION)) {
_pending_speed_restriction_change_map.erase(t->index);
ClrBit(t->flags, VRF_PENDING_SPEED_RESTRICTION);
}
t->speed_restriction = (uint16_t)p2;
SetWindowDirty(WC_VEHICLE_DETAILS, t->index);
}
return CommandCost();
}

@ -2757,6 +2757,7 @@ static_assert(WID_VD_DETAILS_TOTAL_CARGO == WID_VD_DETAILS_CARGO_CARRIED +
static constexpr NWidgetPart _nested_nontrain_vehicle_details_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_VD_EXTRA_ACTIONS), SetDataTip(SPR_ARROW_DOWN, STR_VEHICLE_DETAILS_EXTRA_ACTIONS_TOOLTIP),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetDataTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
@ -2780,6 +2781,7 @@ static constexpr NWidgetPart _nested_nontrain_vehicle_details_widgets[] = {
static constexpr NWidgetPart _nested_train_vehicle_details_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_IMGBTN, COLOUR_GREY, WID_VD_EXTRA_ACTIONS), SetDataTip(SPR_ARROW_DOWN, STR_VEHICLE_DETAILS_EXTRA_ACTIONS_TOOLTIP),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetDataTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
@ -2843,6 +2845,11 @@ struct VehicleDetailsWindow : Window {
bool vehicle_speed_restriction_line_shown;
bool vehicle_speed_adaptation_exempt_line_shown;
enum DropDownAction {
VDWDDA_CLEAR_SPEED_RESTRICTION,
VDWDDA_SET_SPEED_RESTRICTION,
};
/** Initialize a newly created vehicle details window */
VehicleDetailsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
{
@ -3331,6 +3338,8 @@ struct VehicleDetailsWindow : Window {
WID_VD_INCREASE_SERVICING_INTERVAL,
WID_VD_DECREASE_SERVICING_INTERVAL);
this->SetWidgetDisabledState(WID_VD_EXTRA_ACTIONS, v->type != VEH_TRAIN);
StringID str =
!v->ServiceIntervalIsCustom() ? STR_VEHICLE_DETAILS_DEFAULT :
v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT :
@ -3382,6 +3391,18 @@ struct VehicleDetailsWindow : Window {
this->tab = (TrainDetailsWindowTabs)(widget - WID_VD_DETAILS_CARGO_CARRIED);
this->SetDirty();
break;
case WID_VD_EXTRA_ACTIONS: {
const Vehicle *v = Vehicle::Get(this->window_number);
DropDownList list;
if (v->type == VEH_TRAIN) {
bool change_allowed = IsVehicleControlAllowed(v, _local_company);
list.emplace_back(new DropDownListStringItem(STR_VEHICLE_DETAILS_REMOVE_SPEED_RESTRICTION, VDWDDA_CLEAR_SPEED_RESTRICTION, !change_allowed || Train::From(v)->speed_restriction == 0));
list.emplace_back(new DropDownListStringItem(STR_VEHICLE_DETAILS_SET_SPEED_RESTRICTION, VDWDDA_SET_SPEED_RESTRICTION, !change_allowed));
}
ShowDropDownList(this, std::move(list), -1, WID_VD_EXTRA_ACTIONS, 140);
break;
}
}
}
@ -3415,9 +3436,32 @@ struct VehicleDetailsWindow : Window {
DoCommandP(v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING));
break;
}
case WID_VD_EXTRA_ACTIONS: {
const Vehicle *v = Vehicle::Get(this->window_number);
switch (index) {
case VDWDDA_CLEAR_SPEED_RESTRICTION:
DoCommandP(v->tile, v->index, 0, CMD_SET_TRAIN_SPEED_RESTRICTION | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SPEED_RESTRICTION));
break;
case VDWDDA_SET_SPEED_RESTRICTION: {
SetDParam(0, ConvertKmhishSpeedToDisplaySpeed(Train::From(v)->speed_restriction, VEH_TRAIN));
ShowQueryString(STR_JUST_INT, STR_TIMETABLE_CHANGE_SPEED, 10, this, CS_NUMERAL, QSF_NONE);
}
}
break;
}
}
}
void OnQueryTextFinished(char *str) override
{
if (str == nullptr || StrEmpty(str)) return;
const Vehicle *v = Vehicle::Get(this->window_number);
DoCommandP(v->tile, v->index, ConvertDisplaySpeedToKmhishSpeed(std::strtoul(str, nullptr, 10), VEH_TRAIN), CMD_SET_TRAIN_SPEED_RESTRICTION | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SPEED_RESTRICTION));
}
void OnResize() override
{
NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_VD_MATRIX);

@ -59,6 +59,7 @@ enum VehicleDetailsWidgets : WidgetID {
WID_VD_DETAILS_TRAIN_VEHICLES, ///< Show all parts of the train with their description.
WID_VD_DETAILS_CAPACITY_OF_EACH, ///< Show the capacity of all train parts.
WID_VD_DETAILS_TOTAL_CARGO, ///< Show the capacity and carried cargo amounts aggregated per cargo of the train.
WID_VD_EXTRA_ACTIONS, ///< Extra actions drop-down.
};
/** Widgets of the #VehicleListWindow class. */

Loading…
Cancel
Save