Show specific reason why vehicle cannot be ordered to a particular station

This commit is contained in:
Jonathan G Rennison
2022-03-29 22:14:12 +01:00
parent 358e41d471
commit d3efa2afe0
4 changed files with 68 additions and 5 deletions

View File

@@ -6413,6 +6413,19 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Can't co
STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... too far from previous destination STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... too far from previous destination
STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aircraft has not enough range STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aircraft has not enough range
STR_ERROR_NO_RAIL_STATION :{WHITE}There is no railway station...
STR_ERROR_NO_BUS_STATION :{WHITE}There is no bus station...
STR_ERROR_NO_TRUCK_STATION :{WHITE}There is no lorry station...
STR_ERROR_NO_DOCK :{WHITE}There is no dock...
STR_ERROR_NO_AIRPORT :{WHITE}There is no airport/heliport...
STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}There are no stops with a compatible road/tram type...
STR_ERROR_NO_STOP_ARTIC_VEH :{WHITE}There are no stops which are suitable for articulated road vehicles.{}Articulated road vehicles require a drive-through stop, not a bay stop...
STR_ERROR_AIRPORT_NO_PLANES :{WHITE}This plane cannot land at this heliport...
STR_ERROR_AIRPORT_NO_HELIS :{WHITE}This helicopter cannot land at this airport...
STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}There is no railway waypoint...
STR_ERROR_NO_ROAD_WAYPOINT :{WHITE}There is no road waypoint...
STR_ERROR_NO_BUOY :{WHITE}There is no buoy...
# Timetable related errors # Timetable related errors
STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Can't timetable vehicle... STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Can't timetable vehicle...
STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehicles can only wait at stations STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehicles can only wait at stations

View File

@@ -984,9 +984,9 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
} }
if (!CanVehicleUseStation(v, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); if (!CanVehicleUseStation(v, st)) return CommandCost::DualErrorMessage(STR_ERROR_CAN_T_ADD_ORDER, GetVehicleCannotUseStationReason(v, st));
for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) { for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
if (!CanVehicleUseStation(u, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER_SHARED); if (!CanVehicleUseStation(u, st)) return CommandCost::DualErrorMessage(STR_ERROR_CAN_T_ADD_ORDER_SHARED, GetVehicleCannotUseStationReason(u, st));
} }
/* Non stop only allowed for ground vehicles. */ /* Non stop only allowed for ground vehicles. */
@@ -1083,7 +1083,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
default: return CMD_ERROR; default: return CMD_ERROR;
case VEH_TRAIN: { case VEH_TRAIN: {
if (!(wp->facilities & FACIL_TRAIN)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); if (!(wp->facilities & FACIL_TRAIN)) return CommandCost::DualErrorMessage(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_RAIL_WAYPOINT);
CommandCost ret = CheckInfraUsageAllowed(v->type, wp->owner); CommandCost ret = CheckInfraUsageAllowed(v->type, wp->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
@@ -1091,7 +1091,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
} }
case VEH_ROAD: { case VEH_ROAD: {
if (!(wp->facilities & FACIL_BUS_STOP) || !(wp->facilities & FACIL_TRUCK_STOP)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); if (!(wp->facilities & FACIL_BUS_STOP) || !(wp->facilities & FACIL_TRUCK_STOP)) return CommandCost::DualErrorMessage(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_ROAD_WAYPOINT);
CommandCost ret = CheckInfraUsageAllowed(v->type, wp->owner); CommandCost ret = CheckInfraUsageAllowed(v->type, wp->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
@@ -1099,7 +1099,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
} }
case VEH_SHIP: case VEH_SHIP:
if (!(wp->facilities & FACIL_DOCK)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); if (!(wp->facilities & FACIL_DOCK)) return CommandCost::DualErrorMessage(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_BUOY);
if (wp->owner != OWNER_NONE) { if (wp->owner != OWNER_NONE) {
CommandCost ret = CheckInfraUsageAllowed(v->type, wp->owner); CommandCost ret = CheckInfraUsageAllowed(v->type, wp->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;

View File

@@ -4338,6 +4338,55 @@ bool CanVehicleUseStation(const Vehicle *v, const Station *st)
return CanVehicleUseStation(v->engine_type, st); return CanVehicleUseStation(v->engine_type, st);
} }
/**
* Get reason string why this station can't be used by the given vehicle
* @param v the vehicle to test
* @param st the station to test for
* @return true if and only if the vehicle can use this station.
*/
StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st)
{
switch (v->type) {
case VEH_TRAIN:
return STR_ERROR_NO_RAIL_STATION;
case VEH_ROAD: {
const RoadVehicle *rv = RoadVehicle::From(v);
RoadStop *rs = st->GetPrimaryRoadStop(rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK);
StringID err = rv->IsBus() ? STR_ERROR_NO_BUS_STATION : STR_ERROR_NO_TRUCK_STATION;
for (; rs != nullptr; rs = rs->next) {
/* The vehicle is articulated and can therefore not go to a standard road stop. */
if (IsStandardRoadStopTile(rs->xy) && rv->HasArticulatedPart()) {
err = STR_ERROR_NO_STOP_ARTIC_VEH;
continue;
}
/* The vehicle cannot go to this roadstop (different roadtype) */
if (!HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes)) return STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE;
return INVALID_STRING_ID;
}
return err;
}
case VEH_SHIP:
return STR_ERROR_NO_DOCK;
case VEH_AIRCRAFT:
if ((st->facilities & FACIL_AIRPORT) == 0) return STR_ERROR_NO_AIRPORT;
if (v->GetEngine()->u.air.subtype & AIR_CTOL) {
return STR_ERROR_AIRPORT_NO_PLANES;
} else {
return STR_ERROR_AIRPORT_NO_HELIS;
}
default:
return INVALID_STRING_ID;
}
}
/** /**
* Access the ground vehicle cache of the vehicle. * Access the ground vehicle cache of the vehicle.
* @pre The vehicle is a #GroundVehicle. * @pre The vehicle is a #GroundVehicle.

View File

@@ -248,6 +248,7 @@ extern uint16 _returned_mail_refit_capacity;
bool CanVehicleUseStation(EngineID engine_type, const struct Station *st); bool CanVehicleUseStation(EngineID engine_type, const struct Station *st);
bool CanVehicleUseStation(const Vehicle *v, const struct Station *st); bool CanVehicleUseStation(const Vehicle *v, const struct Station *st);
StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st);
void ReleaseDisastersTargetingVehicle(VehicleID vehicle); void ReleaseDisastersTargetingVehicle(VehicleID vehicle);