mirror of https://github.com/OpenTTD/OpenTTD
Add: Use specific error message when vehicle cannot go to station/waypoint
parent
44848f4edf
commit
3719f60de0
|
@ -5085,6 +5085,20 @@ 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_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aircraft has not enough range
|
||||
|
||||
# Extra messages which go on the third line of errors, explaining why orders failed
|
||||
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 type
|
||||
STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}There are no stops with a compatible tram type
|
||||
STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{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_HELICOPTERS :{WHITE}This helicopter cannot land at this airport
|
||||
STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}There is no railway waypoint
|
||||
STR_ERROR_NO_BUOY :{WHITE}There is no buoy
|
||||
|
||||
# Timetable related errors
|
||||
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
|
||||
|
|
|
@ -758,9 +758,9 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
|
|||
if (ret.Failed()) return ret;
|
||||
}
|
||||
|
||||
if (!CanVehicleUseStation(v, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER);
|
||||
if (!CanVehicleUseStation(v, st)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, GetVehicleCannotUseStationReason(v, st));
|
||||
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(STR_ERROR_CAN_T_ADD_ORDER_SHARED, GetVehicleCannotUseStationReason(u, st));
|
||||
}
|
||||
|
||||
/* Non stop only allowed for ground vehicles. */
|
||||
|
@ -847,7 +847,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
|
|||
default: return CMD_ERROR;
|
||||
|
||||
case VEH_TRAIN: {
|
||||
if (!(wp->facilities & FACIL_TRAIN)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER);
|
||||
if (!(wp->facilities & FACIL_TRAIN)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_RAIL_WAYPOINT);
|
||||
|
||||
ret = CheckOwnership(wp->owner);
|
||||
if (ret.Failed()) return ret;
|
||||
|
@ -855,7 +855,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
|
|||
}
|
||||
|
||||
case VEH_SHIP:
|
||||
if (!(wp->facilities & FACIL_DOCK)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER);
|
||||
if (!(wp->facilities & FACIL_DOCK)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_BUOY);
|
||||
if (wp->owner != OWNER_NONE) {
|
||||
ret = CheckOwnership(wp->owner);
|
||||
if (ret.Failed()) return ret;
|
||||
|
@ -1533,7 +1533,7 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve
|
|||
* are temporarily invalid due to reconstruction. */
|
||||
const Station *st = Station::Get(order->GetDestination());
|
||||
if (CanVehicleUseStation(src, st) && !CanVehicleUseStation(dst, st)) {
|
||||
return_cmd_error(STR_ERROR_CAN_T_COPY_SHARE_ORDER);
|
||||
return CommandCost(STR_ERROR_CAN_T_COPY_SHARE_ORDER, GetVehicleCannotUseStationReason(dst, st));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1577,9 +1577,9 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve
|
|||
/* Trucks can't copy all the orders from busses (and visa versa),
|
||||
* and neither can helicopters and aircraft. */
|
||||
for (const Order *order : src->Orders()) {
|
||||
if (OrderGoesToStation(dst, order) &&
|
||||
!CanVehicleUseStation(dst, Station::Get(order->GetDestination()))) {
|
||||
return_cmd_error(STR_ERROR_CAN_T_COPY_SHARE_ORDER);
|
||||
Station *st = Station::Get(order->GetDestination());
|
||||
if (OrderGoesToStation(dst, order) && !CanVehicleUseStation(dst, st)) {
|
||||
return CommandCost(STR_ERROR_CAN_T_COPY_SHARE_ORDER, GetVehicleCannotUseStationReason(dst, st));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2903,6 +2903,58 @@ bool CanVehicleUseStation(const Vehicle *v, const Station *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 The string explaining why the vehicle cannot use the 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) {
|
||||
/* Articulated vehicles cannot use bay road stops, only drive-through. Make sure the vehicle can actually use this bay stop */
|
||||
if (HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && IsStandardRoadStopTile(rs->xy) && rv->HasArticulatedPart()) {
|
||||
err = STR_ERROR_NO_STOP_ARTICULATED_VEHICLE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Bay stop errors take precedence, but otherwise the vehicle may not be compatible with the roadtype/tramtype of this station tile.
|
||||
* We give bay stop errors precedence because they are usually a bus sent to a tram station or vice versa. */
|
||||
if (!HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && err != STR_ERROR_NO_STOP_ARTICULATED_VEHICLE) {
|
||||
err = RoadTypeIsRoad(rv->roadtype) ? STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE : STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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_HELICOPTERS;
|
||||
}
|
||||
|
||||
default:
|
||||
return INVALID_STRING_ID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the ground vehicle cache of the vehicle.
|
||||
* @pre The vehicle is a #GroundVehicle.
|
||||
|
|
|
@ -166,6 +166,7 @@ CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits);
|
|||
|
||||
bool CanVehicleUseStation(EngineID engine_type, 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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue