mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Use local string parameters for order and timetable windows.
Order display is now composed of concatenated strings instead of a complex 10-parameter format string, which simplifies things and fixes duplicate spaces.pull/13654/head
parent
23ba18ada7
commit
7fd0e6c27d
|
@ -4592,7 +4592,6 @@ STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}Switch t
|
|||
|
||||
STR_ORDERS_LIST_TOOLTIP :{BLACK}Order list - click on an order to highlight it. Ctrl+Click to scroll to the order's destination
|
||||
STR_ORDER_INDEX :{COMMA}:{NBSP}
|
||||
STR_ORDER_TEXT :{STRING4} {STRING2} {STRING} {STRING}
|
||||
|
||||
STR_ORDERS_END_OF_ORDERS :- - End of Orders - -
|
||||
STR_ORDERS_END_OF_SHARED_ORDERS :- - End of Shared Orders - -
|
||||
|
@ -4691,63 +4690,62 @@ STR_ORDER_GO_NON_STOP_TO_WAYPOINT :Go non-stop via
|
|||
STR_ORDER_SERVICE_AT :Service at
|
||||
STR_ORDER_SERVICE_NON_STOP_AT :Service non-stop at
|
||||
|
||||
STR_ORDER_NEAREST_DEPOT :the nearest
|
||||
STR_ORDER_NEAREST_HANGAR :the nearest Hangar
|
||||
###length 3
|
||||
STR_ORDER_TRAIN_DEPOT :Train Depot
|
||||
STR_ORDER_ROAD_VEHICLE_DEPOT :Road Vehicle Depot
|
||||
STR_ORDER_SHIP_DEPOT :Ship Depot
|
||||
###next-name-looks-similar
|
||||
|
||||
STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} {STRING} {STRING}
|
||||
STR_ORDER_GO_TO_NEAREST_HANGAR_FORMAT :{STRING} the nearest Hangar
|
||||
STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} the nearest {STRING}
|
||||
STR_ORDER_GO_TO_DEPOT_FORMAT :{STRING} {DEPOT}
|
||||
|
||||
STR_ORDER_REFIT_ORDER :(Refit to {STRING})
|
||||
STR_ORDER_REFIT_STOP_ORDER :(Refit to {STRING} and stop)
|
||||
STR_ORDER_STOP_ORDER :(Stop)
|
||||
STR_ORDER_REFIT_ORDER :{SPACE}(Refit to {STRING})
|
||||
STR_ORDER_REFIT_STOP_ORDER :{SPACE}(Refit to {STRING} and stop)
|
||||
STR_ORDER_STOP_ORDER :{SPACE}(Stop)
|
||||
|
||||
STR_ORDER_WAIT_TO_UNBUNCH :(Wait to unbunch)
|
||||
STR_ORDER_WAIT_TO_UNBUNCH :{SPACE}(Wait to unbunch)
|
||||
|
||||
STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING1}
|
||||
STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Can't use station){POP_COLOUR} {STRING} {STATION} {STRING1}
|
||||
STR_ORDER_GO_TO_STATION :{STRING} {STATION}
|
||||
STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Can't use station){POP_COLOUR} {STRING} {STATION}
|
||||
|
||||
STR_ORDER_IMPLICIT :(Implicit)
|
||||
STR_ORDER_IMPLICIT :{SPACE}(Implicit)
|
||||
|
||||
STR_ORDER_FULL_LOAD :(Full load)
|
||||
STR_ORDER_FULL_LOAD_ANY :(Full load any cargo)
|
||||
STR_ORDER_NO_LOAD :(No loading)
|
||||
STR_ORDER_UNLOAD :(Unload and take cargo)
|
||||
STR_ORDER_UNLOAD_FULL_LOAD :(Unload and wait for full load)
|
||||
STR_ORDER_UNLOAD_FULL_LOAD_ANY :(Unload and wait for any full load)
|
||||
STR_ORDER_UNLOAD_NO_LOAD :(Unload and leave empty)
|
||||
STR_ORDER_TRANSFER :(Transfer and take cargo)
|
||||
STR_ORDER_TRANSFER_FULL_LOAD :(Transfer and wait for full load)
|
||||
STR_ORDER_TRANSFER_FULL_LOAD_ANY :(Transfer and wait for any full load)
|
||||
STR_ORDER_TRANSFER_NO_LOAD :(Transfer and leave empty)
|
||||
STR_ORDER_NO_UNLOAD :(No unloading and take cargo)
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD :(No unloading and wait for full load)
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :(No unloading and wait for any full load)
|
||||
STR_ORDER_NO_UNLOAD_NO_LOAD :(No unloading and no loading)
|
||||
STR_ORDER_FULL_LOAD :{SPACE}(Full load)
|
||||
STR_ORDER_FULL_LOAD_ANY :{SPACE}(Full load any cargo)
|
||||
STR_ORDER_NO_LOAD :{SPACE}(No loading)
|
||||
STR_ORDER_UNLOAD :{SPACE}(Unload and take cargo)
|
||||
STR_ORDER_UNLOAD_FULL_LOAD :{SPACE}(Unload and wait for full load)
|
||||
STR_ORDER_UNLOAD_FULL_LOAD_ANY :{SPACE}(Unload and wait for any full load)
|
||||
STR_ORDER_UNLOAD_NO_LOAD :{SPACE}(Unload and leave empty)
|
||||
STR_ORDER_TRANSFER :{SPACE}(Transfer and take cargo)
|
||||
STR_ORDER_TRANSFER_FULL_LOAD :{SPACE}(Transfer and wait for full load)
|
||||
STR_ORDER_TRANSFER_FULL_LOAD_ANY :{SPACE}(Transfer and wait for any full load)
|
||||
STR_ORDER_TRANSFER_NO_LOAD :{SPACE}(Transfer and leave empty)
|
||||
STR_ORDER_NO_UNLOAD :{SPACE}(No unloading and take cargo)
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD :{SPACE}(No unloading and wait for full load)
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :{SPACE}(No unloading and wait for any full load)
|
||||
STR_ORDER_NO_UNLOAD_NO_LOAD :{SPACE}(No unloading and no loading)
|
||||
|
||||
STR_ORDER_AUTO_REFIT :(Refit to {STRING})
|
||||
STR_ORDER_FULL_LOAD_REFIT :(Full load with refit to {STRING})
|
||||
STR_ORDER_FULL_LOAD_ANY_REFIT :(Full load any cargo with refit to {STRING})
|
||||
STR_ORDER_UNLOAD_REFIT :(Unload and take cargo with refit to {STRING})
|
||||
STR_ORDER_UNLOAD_FULL_LOAD_REFIT :(Unload and wait for full load with refit to {STRING})
|
||||
STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT :(Unload and wait for any full load with refit to {STRING})
|
||||
STR_ORDER_TRANSFER_REFIT :(Transfer and take cargo with refit to {STRING})
|
||||
STR_ORDER_TRANSFER_FULL_LOAD_REFIT :(Transfer and wait for full load with refit to {STRING})
|
||||
STR_ORDER_TRANSFER_FULL_LOAD_ANY_REFIT :(Transfer and wait for any full load with refit to {STRING})
|
||||
STR_ORDER_NO_UNLOAD_REFIT :(No unloading and take cargo with refit to {STRING})
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT :(No unloading and wait for full load with refit to {STRING})
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT :(No unloading and wait for any full load with refit to {STRING})
|
||||
STR_ORDER_AUTO_REFIT :{SPACE}(Refit to {STRING})
|
||||
STR_ORDER_FULL_LOAD_REFIT :{SPACE}(Full load with refit to {STRING})
|
||||
STR_ORDER_FULL_LOAD_ANY_REFIT :{SPACE}(Full load any cargo with refit to {STRING})
|
||||
STR_ORDER_UNLOAD_REFIT :{SPACE}(Unload and take cargo with refit to {STRING})
|
||||
STR_ORDER_UNLOAD_FULL_LOAD_REFIT :{SPACE}(Unload and wait for full load with refit to {STRING})
|
||||
STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT :{SPACE}(Unload and wait for any full load with refit to {STRING})
|
||||
STR_ORDER_TRANSFER_REFIT :{SPACE}(Transfer and take cargo with refit to {STRING})
|
||||
STR_ORDER_TRANSFER_FULL_LOAD_REFIT :{SPACE}(Transfer and wait for full load with refit to {STRING})
|
||||
STR_ORDER_TRANSFER_FULL_LOAD_ANY_REFIT :{SPACE}(Transfer and wait for any full load with refit to {STRING})
|
||||
STR_ORDER_NO_UNLOAD_REFIT :{SPACE}(No unloading and take cargo with refit to {STRING})
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT :{SPACE}(No unloading and wait for full load with refit to {STRING})
|
||||
STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT :{SPACE}(No unloading and wait for any full load with refit to {STRING})
|
||||
|
||||
STR_ORDER_AUTO_REFIT_ANY :available cargo
|
||||
|
||||
###length 3
|
||||
STR_ORDER_STOP_LOCATION_NEAR_END :[near end]
|
||||
STR_ORDER_STOP_LOCATION_MIDDLE :[middle]
|
||||
STR_ORDER_STOP_LOCATION_FAR_END :[far end]
|
||||
STR_ORDER_STOP_LOCATION_NEAR_END :{SPACE}[near end]
|
||||
STR_ORDER_STOP_LOCATION_MIDDLE :{SPACE}[middle]
|
||||
STR_ORDER_STOP_LOCATION_FAR_END :{SPACE}[far end]
|
||||
|
||||
STR_ORDER_OUT_OF_RANGE :{RED} (Next destination is out of range)
|
||||
|
||||
|
@ -4772,8 +4770,8 @@ STR_TIMETABLE_TRAVEL_FOR :Travel for {STR
|
|||
STR_TIMETABLE_TRAVEL_FOR_SPEED :Travel for {STRING1} with at most {VELOCITY}
|
||||
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Travel (for {STRING1}, not timetabled)
|
||||
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Travel (for {STRING1}, not timetabled) with at most {VELOCITY}
|
||||
STR_TIMETABLE_STAY_FOR_ESTIMATED :(stay for {STRING1}, not timetabled)
|
||||
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(travel for {STRING1}, not timetabled)
|
||||
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(stay for {STRING1}, not timetabled)
|
||||
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(travel for {STRING1}, not timetabled)
|
||||
STR_TIMETABLE_STAY_FOR :and stay for {STRING1}
|
||||
STR_TIMETABLE_AND_TRAVEL_FOR :and travel for {STRING1}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ static const StringID _station_load_types[][5][5] = {
|
|||
{
|
||||
/* No refitting. */
|
||||
{
|
||||
STR_EMPTY,
|
||||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
STR_ORDER_FULL_LOAD,
|
||||
STR_ORDER_FULL_LOAD_ANY,
|
||||
|
@ -68,6 +68,7 @@ static const StringID _station_load_types[][5][5] = {
|
|||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
}, {
|
||||
STR_ORDER_NO_UNLOAD,
|
||||
INVALID_STRING_ID,
|
||||
|
@ -101,6 +102,7 @@ static const StringID _station_load_types[][5][5] = {
|
|||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
INVALID_STRING_ID,
|
||||
}, {
|
||||
STR_ORDER_NO_UNLOAD_REFIT,
|
||||
INVALID_STRING_ID,
|
||||
|
@ -199,6 +201,15 @@ static const StringID _order_refit_action_dropdown[] = {
|
|||
STR_ORDER_DROP_REFIT_AUTO_ANY,
|
||||
};
|
||||
|
||||
static StringID GetOrderGoToString(const Order &order)
|
||||
{
|
||||
if (order.GetDepotOrderType() & ODTFB_SERVICE) {
|
||||
return (order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT;
|
||||
} else {
|
||||
return (order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an order in order or timetable GUI
|
||||
* @param v Vehicle the order belongs to
|
||||
|
@ -233,30 +244,18 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
|
|||
colour = TC_WHITE;
|
||||
}
|
||||
|
||||
SetDParam(0, order_index + 1);
|
||||
DrawString(left, rtl ? right - 2 * sprite_size.width - 3 : middle, y, STR_ORDER_INDEX, colour, SA_RIGHT | SA_FORCE);
|
||||
DrawString(left, rtl ? right - 2 * sprite_size.width - 3 : middle, y, GetString(STR_ORDER_INDEX, order_index + 1), colour, SA_RIGHT | SA_FORCE);
|
||||
|
||||
SetDParam(5, STR_EMPTY);
|
||||
SetDParam(8, STR_EMPTY);
|
||||
SetDParam(9, STR_EMPTY);
|
||||
|
||||
/* Check range for aircraft. */
|
||||
if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->GetRange() > 0 && order->IsGotoOrder()) {
|
||||
const Order *next = order->next != nullptr ? order->next : v->GetFirstOrder();
|
||||
if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) SetDParam(9, STR_ORDER_OUT_OF_RANGE);
|
||||
}
|
||||
std::string line;
|
||||
|
||||
switch (order->GetType()) {
|
||||
case OT_DUMMY:
|
||||
SetDParam(0, STR_INVALID_ORDER);
|
||||
SetDParam(1, order->GetDestination());
|
||||
line = GetString(STR_INVALID_ORDER);
|
||||
break;
|
||||
|
||||
case OT_IMPLICIT:
|
||||
SetDParam(0, STR_ORDER_GO_TO_STATION);
|
||||
SetDParam(1, STR_ORDER_GO_TO);
|
||||
SetDParam(2, order->GetDestination());
|
||||
SetDParam(3, timetable ? STR_EMPTY : STR_ORDER_IMPLICIT);
|
||||
line = GetString(STR_ORDER_GO_TO_STATION, STR_ORDER_GO_TO, order->GetDestination());
|
||||
if (!timetable) line += GetString(STR_ORDER_IMPLICIT);
|
||||
break;
|
||||
|
||||
case OT_GOTO_STATION: {
|
||||
|
@ -264,30 +263,30 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
|
|||
OrderUnloadFlags unload = order->GetUnloadType();
|
||||
bool valid_station = CanVehicleUseStation(v, Station::Get(order->GetDestination().ToStationID()));
|
||||
|
||||
SetDParam(0, valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION);
|
||||
SetDParam(1, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : 0));
|
||||
SetDParam(2, order->GetDestination());
|
||||
|
||||
line = GetString(valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : 0), order->GetDestination());
|
||||
if (timetable) {
|
||||
/* Show only wait time in the timetable window. */
|
||||
SetDParam(3, STR_EMPTY);
|
||||
|
||||
if (order->GetWaitTime() > 0) {
|
||||
SetDParam(5, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED);
|
||||
SetTimetableParams(6, 7, order->GetWaitTime());
|
||||
auto [str, value] = GetTimetableParameters(order->GetWaitTime());
|
||||
line += GetString(order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED, str, value);
|
||||
}
|
||||
} else {
|
||||
/* Show non-stop, refit and stop location only in the order window. */
|
||||
SetDParam(3, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ? STR_EMPTY : _station_load_types[order->IsRefit()][unload][load]);
|
||||
if (order->IsRefit()) {
|
||||
SetDParam(4, order->IsAutoRefit() ? STR_ORDER_AUTO_REFIT_ANY : CargoSpec::Get(order->GetRefitCargo())->name);
|
||||
if (!(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) {
|
||||
StringID str = _station_load_types[order->IsRefit()][unload][load];
|
||||
if (str != INVALID_STRING_ID) {
|
||||
if (order->IsRefit()) {
|
||||
line += GetString(str, order->IsAutoRefit() ? STR_ORDER_AUTO_REFIT_ANY : CargoSpec::Get(order->GetRefitCargo())->name);
|
||||
} else {
|
||||
line += GetString(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (v->type == VEH_TRAIN && (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0) {
|
||||
/* Only show the stopping location if other than the default chosen by the player. */
|
||||
if (order->GetStopLocation() != (OrderStopLocation)(_settings_client.gui.stop_location)) {
|
||||
SetDParam(5, STR_ORDER_STOP_LOCATION_NEAR_END + order->GetStopLocation());
|
||||
} else {
|
||||
SetDParam(5, STR_EMPTY);
|
||||
line += GetString(STR_ORDER_STOP_LOCATION_NEAR_END + order->GetStopLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -295,79 +294,71 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
|
|||
}
|
||||
|
||||
case OT_GOTO_DEPOT:
|
||||
if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
|
||||
/* Going to the nearest depot. */
|
||||
SetDParam(0, STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT);
|
||||
if (v->type == VEH_AIRCRAFT) {
|
||||
SetDParam(2, STR_ORDER_NEAREST_HANGAR);
|
||||
SetDParam(3, STR_EMPTY);
|
||||
} else {
|
||||
SetDParam(2, STR_ORDER_NEAREST_DEPOT);
|
||||
SetDParam(3, STR_ORDER_TRAIN_DEPOT + v->type);
|
||||
}
|
||||
} else {
|
||||
if (!(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT)) {
|
||||
/* Going to a specific depot. */
|
||||
SetDParam(0, STR_ORDER_GO_TO_DEPOT_FORMAT);
|
||||
SetDParam(2, v->type);
|
||||
SetDParam(3, order->GetDestination());
|
||||
}
|
||||
|
||||
if (order->GetDepotOrderType() & ODTFB_SERVICE) {
|
||||
SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT);
|
||||
line = GetString(STR_ORDER_GO_TO_DEPOT_FORMAT, GetOrderGoToString(*order), v->type, order->GetDestination());
|
||||
} else if (v->type == VEH_AIRCRAFT) {
|
||||
/* Going to the nearest hangar. */
|
||||
line = GetString(STR_ORDER_GO_TO_NEAREST_HANGAR_FORMAT, GetOrderGoToString(*order));
|
||||
} else {
|
||||
SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO);
|
||||
/* Going to the nearest depot. */
|
||||
line = GetString(STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT, GetOrderGoToString(*order), STR_ORDER_TRAIN_DEPOT + v->type);
|
||||
}
|
||||
|
||||
/* Do not show stopping in the depot in the timetable window. */
|
||||
if (!timetable && (order->GetDepotActionType() & ODATFB_HALT)) {
|
||||
SetDParam(5, STR_ORDER_STOP_ORDER);
|
||||
line += GetString(STR_ORDER_STOP_ORDER);
|
||||
}
|
||||
|
||||
/* Do not show refitting in the depot in the timetable window. */
|
||||
if (!timetable && order->IsRefit()) {
|
||||
SetDParam(5, (order->GetDepotActionType() & ODATFB_HALT) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER);
|
||||
SetDParam(6, CargoSpec::Get(order->GetRefitCargo())->name);
|
||||
line += GetString((order->GetDepotActionType() & ODATFB_HALT) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER, CargoSpec::Get(order->GetRefitCargo())->name);
|
||||
}
|
||||
|
||||
/* Show unbunching depot in both order and timetable windows. */
|
||||
if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
|
||||
SetDParam(8, STR_ORDER_WAIT_TO_UNBUNCH);
|
||||
line += GetString(STR_ORDER_WAIT_TO_UNBUNCH);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OT_GOTO_WAYPOINT:
|
||||
SetDParam(0, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO_WAYPOINT : STR_ORDER_GO_TO_WAYPOINT);
|
||||
SetDParam(1, order->GetDestination());
|
||||
line = GetString((order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO_WAYPOINT : STR_ORDER_GO_TO_WAYPOINT, order->GetDestination());
|
||||
break;
|
||||
|
||||
case OT_CONDITIONAL:
|
||||
SetDParam(1, order->GetConditionSkipToOrder() + 1);
|
||||
if (order->GetConditionVariable() == OCV_UNCONDITIONALLY) {
|
||||
SetDParam(0, STR_ORDER_CONDITIONAL_UNCONDITIONAL);
|
||||
line = GetString(STR_ORDER_CONDITIONAL_UNCONDITIONAL, order->GetConditionSkipToOrder() + 1);
|
||||
} else {
|
||||
OrderConditionComparator occ = order->GetConditionComparator();
|
||||
SetDParam(0, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM);
|
||||
SetDParam(2, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable());
|
||||
SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
|
||||
|
||||
uint value = order->GetConditionValue();
|
||||
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, v->type);
|
||||
SetDParam(4, value);
|
||||
|
||||
line = GetString((occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM,
|
||||
order->GetConditionSkipToOrder() + 1,
|
||||
STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable(),
|
||||
STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ,
|
||||
value);
|
||||
}
|
||||
|
||||
if (timetable && order->GetWaitTime() > 0) {
|
||||
SetDParam(5, order->IsWaitTimetabled() ? STR_TIMETABLE_AND_TRAVEL_FOR : STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED);
|
||||
SetTimetableParams(6, 7, order->GetWaitTime());
|
||||
} else {
|
||||
SetDParam(5, STR_EMPTY);
|
||||
auto [str, value] = GetTimetableParameters(order->GetWaitTime());
|
||||
line += GetString(order->IsWaitTimetabled() ? STR_TIMETABLE_AND_TRAVEL_FOR : STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED, str, value);
|
||||
}
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
DrawString(rtl ? left : middle, rtl ? middle : right, y, STR_ORDER_TEXT, colour);
|
||||
/* Check range for aircraft. */
|
||||
if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->GetRange() > 0 && order->IsGotoOrder()) {
|
||||
const Order *next = order->next != nullptr ? order->next : v->GetFirstOrder();
|
||||
if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) {
|
||||
line += GetString(STR_ORDER_OUT_OF_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
DrawString(rtl ? left : middle, rtl ? middle : right, y, line, colour);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1116,8 +1107,8 @@ public:
|
|||
|
||||
Rect ir = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
SetDParamMaxValue(0, this->vehicle->GetNumOrders(), 2);
|
||||
int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
|
||||
uint64_t max_value = GetParamMaxValue(this->vehicle->GetNumOrders(), 2);
|
||||
int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, max_value)).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
|
||||
int middle = rtl ? ir.right - index_column_width : ir.left + index_column_width;
|
||||
|
||||
int y = ir.top;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef TIMETABLE_H
|
||||
#define TIMETABLE_H
|
||||
|
||||
#include "strings_type.h"
|
||||
#include "timer/timer_game_tick.h"
|
||||
#include "timer/timer_game_economy.h"
|
||||
#include "vehicle_type.h"
|
||||
|
@ -27,6 +28,7 @@ TimerGameEconomy::Date GetDateFromStartTick(TimerGameTick::TickCounter start_tic
|
|||
|
||||
void ShowTimetableWindow(const Vehicle *v);
|
||||
void UpdateVehicleTimetable(Vehicle *v, bool travelling);
|
||||
void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks);
|
||||
|
||||
std::pair<StringParameter, StringParameter> GetTimetableParameters(TimerGameTick::Ticks ticks);
|
||||
|
||||
#endif /* TIMETABLE_H */
|
||||
|
|
|
@ -42,26 +42,16 @@ struct TimetableArrivalDeparture {
|
|||
};
|
||||
|
||||
/**
|
||||
* Set the timetable parameters in the format as described by the setting.
|
||||
* @param param1 the first DParam to fill
|
||||
* @param param2 the second DParam to fill
|
||||
* @param ticks the number of ticks to 'draw'
|
||||
* Get parameters to format timetable time.
|
||||
* @param ticks Number of ticks to format.
|
||||
* @returns Pair of parameters to format timetable time.
|
||||
*/
|
||||
void SetTimetableParams(int param1, int param2, TimerGameTick::Ticks ticks)
|
||||
std::pair<StringParameter, StringParameter> GetTimetableParameters(TimerGameTick::Ticks ticks)
|
||||
{
|
||||
switch (_settings_client.gui.timetable_mode) {
|
||||
case TimetableMode::Days:
|
||||
SetDParam(param1, STR_UNITS_DAYS);
|
||||
SetDParam(param2, ticks / Ticks::DAY_TICKS);
|
||||
break;
|
||||
case TimetableMode::Seconds:
|
||||
SetDParam(param1, STR_UNITS_SECONDS);
|
||||
SetDParam(param2, ticks / Ticks::TICKS_PER_SECOND);
|
||||
break;
|
||||
case TimetableMode::Ticks:
|
||||
SetDParam(param1, STR_UNITS_TICKS);
|
||||
SetDParam(param2, ticks);
|
||||
break;
|
||||
case TimetableMode::Days: return {STR_UNITS_DAYS, ticks / Ticks::DAY_TICKS};
|
||||
case TimetableMode::Seconds: return {STR_UNITS_SECONDS, ticks / Ticks::TICKS_PER_SECOND};
|
||||
case TimetableMode::Ticks: return {STR_UNITS_TICKS, ticks};
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
@ -255,11 +245,17 @@ struct TimetableWindow : Window {
|
|||
/* We handle this differently depending on the timetable mode. */
|
||||
if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
|
||||
/* A five-digit number would fit a timetable lasting 2.7 real-world hours, which should be plenty. */
|
||||
SetDParamMaxDigits(1, 4, FS_SMALL);
|
||||
size.width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE).width) + WidgetDimensions::scaled.hsep_wide + padding.width;
|
||||
uint64_t max_digits = GetParamMaxDigits(4, FS_SMALL);
|
||||
size.width = std::max(
|
||||
GetStringBoundingBox(GetString(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE, TC_BLACK, max_digits)).width,
|
||||
GetStringBoundingBox(GetString(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE, TC_BLACK, max_digits)).width)
|
||||
+ WidgetDimensions::scaled.hsep_wide + padding.width;
|
||||
} else {
|
||||
SetDParamMaxValue(1, TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR), 0, FS_SMALL);
|
||||
size.width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_DATE).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_DATE).width) + WidgetDimensions::scaled.hsep_wide + padding.width;
|
||||
uint64_t max_value = GetParamMaxValue(TimerGameEconomy::DateAtStartOfYear(EconomyTime::MAX_YEAR).base(), 0, FS_SMALL);
|
||||
size.width = std::max(
|
||||
GetStringBoundingBox(GetString(STR_TIMETABLE_ARRIVAL_DATE, TC_BLACK, max_value)).width,
|
||||
GetStringBoundingBox(GetString(STR_TIMETABLE_DEPARTURE_DATE, TC_BLACK, max_value)).width)
|
||||
+ WidgetDimensions::scaled.hsep_wide + padding.width;
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
||||
|
@ -410,6 +406,38 @@ struct TimetableWindow : Window {
|
|||
}
|
||||
}
|
||||
|
||||
std::string GetTimetableTravelString(const Order &order, int i, TextColour &colour) const
|
||||
{
|
||||
colour = (i == this->sel_index) ? TC_WHITE : TC_BLACK;
|
||||
|
||||
if (order.IsType(OT_CONDITIONAL)) {
|
||||
return GetString(STR_TIMETABLE_NO_TRAVEL);
|
||||
}
|
||||
|
||||
if (order.IsType(OT_IMPLICIT)) {
|
||||
colour = ((i == this->sel_index) ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
|
||||
return GetString(STR_TIMETABLE_NOT_TIMETABLEABLE);
|
||||
}
|
||||
|
||||
if (order.IsTravelTimetabled()) {
|
||||
auto [str, value] = GetTimetableParameters(order.GetTimetabledTravel());
|
||||
return order.GetMaxSpeed() != UINT16_MAX
|
||||
? GetString(STR_TIMETABLE_TRAVEL_FOR_SPEED, str, value, PackVelocity(order.GetMaxSpeed(), this->vehicle->type))
|
||||
: GetString(STR_TIMETABLE_TRAVEL_FOR, str, value);
|
||||
}
|
||||
|
||||
if (order.GetTravelTime() > 0) {
|
||||
auto [str, value] = GetTimetableParameters(order.GetTravelTime());
|
||||
return order.GetMaxSpeed() != UINT16_MAX
|
||||
? GetString(STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED, str, value, PackVelocity(order.GetMaxSpeed(), this->vehicle->type))
|
||||
: GetString(STR_TIMETABLE_TRAVEL_FOR_ESTIMATED, str, value);
|
||||
}
|
||||
|
||||
return order.GetMaxSpeed() != UINT16_MAX
|
||||
? GetString(STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED, PackVelocity(order.GetMaxSpeed(), this->vehicle->type))
|
||||
: GetString(STR_TIMETABLE_TRAVEL_NOT_TIMETABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to draw the timetable panel.
|
||||
* @param r The rect to draw within.
|
||||
|
@ -424,8 +452,7 @@ struct TimetableWindow : Window {
|
|||
int selected = this->sel_index;
|
||||
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
SetDParamMaxValue(0, v->GetNumOrders(), 2);
|
||||
int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
|
||||
int index_column_width = GetStringBoundingBox(GetString(STR_ORDER_INDEX, GetParamMaxValue(v->GetNumOrders(), 2))).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal;
|
||||
int middle = rtl ? tr.right - index_column_width : tr.left + index_column_width;
|
||||
|
||||
const Order *order = v->GetOrder(order_id);
|
||||
|
@ -445,30 +472,8 @@ struct TimetableWindow : Window {
|
|||
order = order->next;
|
||||
}
|
||||
} else {
|
||||
StringID string;
|
||||
TextColour colour = (i == selected) ? TC_WHITE : TC_BLACK;
|
||||
if (order->IsType(OT_CONDITIONAL)) {
|
||||
string = STR_TIMETABLE_NO_TRAVEL;
|
||||
} else if (order->IsType(OT_IMPLICIT)) {
|
||||
string = STR_TIMETABLE_NOT_TIMETABLEABLE;
|
||||
colour = ((i == selected) ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
|
||||
} else if (!order->IsTravelTimetabled()) {
|
||||
if (order->GetTravelTime() > 0) {
|
||||
SetTimetableParams(0, 1, order->GetTravelTime());
|
||||
string = order->GetMaxSpeed() != UINT16_MAX ?
|
||||
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :
|
||||
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED;
|
||||
} else {
|
||||
string = order->GetMaxSpeed() != UINT16_MAX ?
|
||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :
|
||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED;
|
||||
}
|
||||
} else {
|
||||
SetTimetableParams(0, 1, order->GetTimetabledTravel());
|
||||
string = order->GetMaxSpeed() != UINT16_MAX ?
|
||||
STR_TIMETABLE_TRAVEL_FOR_SPEED : STR_TIMETABLE_TRAVEL_FOR;
|
||||
}
|
||||
SetDParam(2, PackVelocity(order->GetMaxSpeed(), v->type));
|
||||
TextColour colour;
|
||||
std::string string = GetTimetableTravelString(*order, i, colour);
|
||||
|
||||
DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour);
|
||||
|
||||
|
@ -509,7 +514,7 @@ struct TimetableWindow : Window {
|
|||
if (!this->vscroll->IsVisible(i)) break;
|
||||
|
||||
/* TC_INVALID will skip the colour change. */
|
||||
SetDParam(0, show_late ? TC_RED : TC_INVALID);
|
||||
TextColour tc = show_late ? TC_RED : TC_INVALID;
|
||||
if (i % 2 == 0) {
|
||||
/* Draw an arrival time. */
|
||||
if (arr_dep[i / 2].arrival != Ticks::INVALID_TICKS) {
|
||||
|
@ -518,7 +523,7 @@ struct TimetableWindow : Window {
|
|||
if (this->show_expected && i / 2 == earlyID) {
|
||||
/* Show expected arrival. */
|
||||
this_offset = 0;
|
||||
SetDParam(0, TC_GREEN);
|
||||
tc = TC_GREEN;
|
||||
} else {
|
||||
/* Show scheduled arrival. */
|
||||
this_offset = offset;
|
||||
|
@ -527,12 +532,14 @@ struct TimetableWindow : Window {
|
|||
/* Now actually draw the arrival time. */
|
||||
if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
|
||||
/* Display seconds from now. */
|
||||
SetDParam(1, ((arr_dep[i / 2].arrival + offset) / Ticks::TICKS_PER_SECOND));
|
||||
DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE, i == selected ? TC_WHITE : TC_BLACK);
|
||||
DrawString(tr.left, tr.right, tr.top,
|
||||
GetString(STR_TIMETABLE_ARRIVAL_SECONDS_IN_FUTURE, tc, (arr_dep[i / 2].arrival + offset) / Ticks::TICKS_PER_SECOND),
|
||||
i == selected ? TC_WHITE : TC_BLACK);
|
||||
} else {
|
||||
/* Show a date. */
|
||||
SetDParam(1, TimerGameEconomy::date + (arr_dep[i / 2].arrival + this_offset) / Ticks::DAY_TICKS);
|
||||
DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_ARRIVAL_DATE, i == selected ? TC_WHITE : TC_BLACK);
|
||||
DrawString(tr.left, tr.right, tr.top,
|
||||
GetString(STR_TIMETABLE_ARRIVAL_DATE, tc, TimerGameEconomy::date + (arr_dep[i / 2].arrival + this_offset) / Ticks::DAY_TICKS),
|
||||
i == selected ? TC_WHITE : TC_BLACK);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -540,12 +547,14 @@ struct TimetableWindow : Window {
|
|||
if (arr_dep[i / 2].departure != Ticks::INVALID_TICKS) {
|
||||
if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
|
||||
/* Display seconds from now. */
|
||||
SetDParam(1, ((arr_dep[i / 2].departure + offset) / Ticks::TICKS_PER_SECOND));
|
||||
DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE, i == selected ? TC_WHITE : TC_BLACK);
|
||||
DrawString(tr.left, tr.right, tr.top,
|
||||
GetString(STR_TIMETABLE_DEPARTURE_SECONDS_IN_FUTURE, tc, (arr_dep[i / 2].departure + offset) / Ticks::TICKS_PER_SECOND),
|
||||
i == selected ? TC_WHITE : TC_BLACK);
|
||||
} else {
|
||||
/* Show a date. */
|
||||
SetDParam(1, TimerGameEconomy::date + (arr_dep[i / 2].departure + offset) / Ticks::DAY_TICKS);
|
||||
DrawString(tr.left, tr.right, tr.top, STR_TIMETABLE_DEPARTURE_DATE, i == selected ? TC_WHITE : TC_BLACK);
|
||||
DrawString(tr.left, tr.right, tr.top,
|
||||
GetString(STR_TIMETABLE_DEPARTURE_DATE, tc, TimerGameEconomy::date + (arr_dep[i / 2].departure + offset) / Ticks::DAY_TICKS),
|
||||
i == selected ? TC_WHITE : TC_BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -553,6 +562,14 @@ struct TimetableWindow : Window {
|
|||
}
|
||||
}
|
||||
|
||||
std::string GetTimetableTotalTimeString(TimerGameTick::Ticks total_time) const
|
||||
{
|
||||
auto [str, value] = GetTimetableParameters(total_time);
|
||||
if (!this->vehicle->orders->IsCompleteTimetable()) return GetString(STR_TIMETABLE_TOTAL_TIME_INCOMPLETE, str, value);
|
||||
if (total_time % TicksPerTimetableUnit() == 0) return GetString(STR_TIMETABLE_TOTAL_TIME, str, value);
|
||||
return GetString(STR_TIMETABLE_APPROX_TIME, str, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to draw the summary panel.
|
||||
* @param r The rect to draw within.
|
||||
|
@ -564,14 +581,7 @@ struct TimetableWindow : Window {
|
|||
|
||||
TimerGameTick::Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0;
|
||||
if (total_time != 0) {
|
||||
SetTimetableParams(0, 1, total_time);
|
||||
if (!v->orders->IsCompleteTimetable()) {
|
||||
DrawString(tr, STR_TIMETABLE_TOTAL_TIME_INCOMPLETE);
|
||||
} else if (total_time % TicksPerTimetableUnit() == 0) {
|
||||
DrawString(tr, STR_TIMETABLE_TOTAL_TIME);
|
||||
} else {
|
||||
DrawString(tr, STR_TIMETABLE_APPROX_TIME);
|
||||
}
|
||||
DrawString(tr, GetTimetableTotalTimeString(total_time));
|
||||
}
|
||||
tr.top += GetCharacterHeight(FS_NORMAL);
|
||||
|
||||
|
@ -581,13 +591,10 @@ struct TimetableWindow : Window {
|
|||
* timetable at the given time. */
|
||||
if (_settings_client.gui.timetable_mode == TimetableMode::Seconds) {
|
||||
/* Real time units use seconds relative to now. */
|
||||
SetDParam(0, (static_cast<TimerGameTick::Ticks>(v->timetable_start - TimerGameTick::counter) / Ticks::TICKS_PER_SECOND));
|
||||
DrawString(tr, STR_TIMETABLE_STATUS_START_IN_SECONDS);
|
||||
DrawString(tr, GetString(STR_TIMETABLE_STATUS_START_IN_SECONDS, static_cast<TimerGameTick::Ticks>(v->timetable_start - TimerGameTick::counter) / Ticks::TICKS_PER_SECOND));
|
||||
} else {
|
||||
/* Other units use dates. */
|
||||
SetDParam(0, STR_JUST_DATE_TINY);
|
||||
SetDParam(1, GetDateFromStartTick(v->timetable_start));
|
||||
DrawString(tr, STR_TIMETABLE_STATUS_START_AT_DATE);
|
||||
DrawString(tr, GetString(STR_TIMETABLE_STATUS_START_AT_DATE, STR_JUST_DATE_TINY, GetDateFromStartTick(v->timetable_start)));
|
||||
}
|
||||
} else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
|
||||
/* We aren't running on a timetable yet. */
|
||||
|
@ -597,8 +604,8 @@ struct TimetableWindow : Window {
|
|||
DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME);
|
||||
} else {
|
||||
/* We are late. */
|
||||
SetTimetableParams(0, 1, abs(v->lateness_counter));
|
||||
DrawString(tr, v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE);
|
||||
auto [str, value] = GetTimetableParameters(abs(v->lateness_counter));
|
||||
DrawString(tr, GetString(v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE, str, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue