Add conditional orders for cargo load percentage and waiting cargo amount

See: #90
pull/132/head
Jonathan G Rennison 4 years ago
parent bb363695fc
commit 09b13dd484

@ -139,6 +139,9 @@ void InitializeSortedCargoSpecs();
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
extern uint8 _sorted_standard_cargo_specs_size;
uint ConvertCargoQuantityToDisplayQuantity(CargoID cargo, uint quantity);
uint ConvertDisplayQuantityToCargoQuantity(CargoID cargo, uint quantity);
/**
* Does cargo \a c have cargo class \a cc?
* @param c Cargo type.

@ -4648,7 +4648,7 @@ STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}Switch t
STR_ORDERS_LIST_TOOLTIP :{BLACK}Order list - click on an order to highlight it. Ctrl+Click scrolls to the order's destination
STR_ORDER_INDEX :{COMMA}:{NBSP}
STR_ORDER_TEXT :{STRING4} {STRING4} {STRING}
STR_ORDER_TEXT :{STRING5} {STRING4} {STRING}
STR_ORDERS_END_OF_ORDERS :- - End of Orders - -
STR_ORDERS_END_OF_SHARED_ORDERS :- - End of Shared Orders - -
@ -4711,6 +4711,8 @@ STR_ORDER_CONDITIONAL_FREE_PLATFORMS :Free platforms
STR_ORDER_CONDITIONAL_PERCENT :Percent of times
STR_ORDER_CONDITIONAL_SLOT_OCCUPANCY :Slot occupancy
STR_ORDER_CONDITIONAL_TRAIN_IN_SLOT :Train in slot
STR_ORDER_CONDITIONAL_CARGO_LOAD_PERCENTAGE :Cargo load percentage
STR_ORDER_CONDITIONAL_CARGO_WAITING_AMOUNT :Waiting cargo amount
STR_ORDER_CONDITIONAL_REQUIRES_SERVICE_ORDER :Requires service {STRING}
STR_ORDER_CONDITIONAL_CARGO_WAITING_ORDER :Next station {STRING} {STRING} waiting
@ -4862,6 +4864,8 @@ STR_ORDER_CONDITIONAL_INVALID_SLOT :Jump to order {
STR_ORDER_CONDITIONAL_IN_SLOT :Jump to order {COMMA} when {STRING} slot: {TRSLOT}
STR_ORDER_CONDITIONAL_IN_INVALID_SLOT :Jump to order {COMMA} when {STRING} {PUSH_COLOUR}{RED}{STRING} {POP_COLOUR}
STR_ORDER_CONDITIONAL_TRUE_FALSE :Jump to order {COMMA} when {STRING} {STRING}
STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE_DISPLAY :Jump to order {COMMA} when Load percentage of {STRING} {STRING} {COMMA}
STR_ORDER_CONDITIONAL_CARGO_WAITING_AMOUNT_DISPLAY :Jump to order {COMMA} when {STRING} at next station {STRING} {CARGO_SHORT}
STR_INVALID_ORDER :{RED} (Invalid Order)

@ -1114,6 +1114,17 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
break;
}
case OCV_CARGO_LOAD_PERCENTAGE:
if (!CargoSpec::Get(new_order.GetConditionValue())->IsValid()) return CMD_ERROR;
if (new_order.GetXData() > 100) return CMD_ERROR;
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) return CMD_ERROR;
break;
case OCV_CARGO_WAITING_AMOUNT:
if (!CargoSpec::Get(new_order.GetConditionValue())->IsValid()) return CMD_ERROR;
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) return CMD_ERROR;
break;
case OCV_CARGO_WAITING:
case OCV_CARGO_ACCEPTANCE:
if (!CargoSpec::Get(new_order.GetConditionValue())->IsValid()) return CMD_ERROR;
@ -1598,7 +1609,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
break;
case OT_CONDITIONAL:
if (mof != MOF_COND_VARIABLE && mof != MOF_COND_COMPARATOR && mof != MOF_COND_VALUE && mof != MOF_COND_DESTINATION) return CMD_ERROR;
if (mof != MOF_COND_VARIABLE && mof != MOF_COND_COMPARATOR && mof != MOF_COND_VALUE && mof != MOF_COND_VALUE_2 && mof != MOF_COND_DESTINATION) return CMD_ERROR;
break;
default:
@ -1685,6 +1696,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
case OCV_LOAD_PERCENTAGE:
case OCV_RELIABILITY:
case OCV_PERCENT:
case OCV_CARGO_LOAD_PERCENTAGE:
if (data > 100) return CMD_ERROR;
break;
@ -1698,12 +1710,27 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (!(data < NUM_CARGO && CargoSpec::Get(data)->IsValid())) return CMD_ERROR;
break;
case OCV_CARGO_WAITING_AMOUNT:
break;
default:
if (data > 2047) return CMD_ERROR;
break;
}
break;
case MOF_COND_VALUE_2:
switch (order->GetConditionVariable()) {
case OCV_CARGO_LOAD_PERCENTAGE:
case OCV_CARGO_WAITING_AMOUNT:
if (!(data < NUM_CARGO && CargoSpec::Get(data)->IsValid())) return CMD_ERROR;
break;
default:
return CMD_ERROR;
}
break;
case MOF_COND_DESTINATION:
if (data >= v->GetNumOrders()) return CMD_ERROR;
break;
@ -1779,7 +1806,8 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
case MOF_COND_VARIABLE: {
/* Check whether old conditional variable had a cargo as value */
bool old_var_was_cargo = (order->GetConditionVariable() == OCV_CARGO_ACCEPTANCE || order->GetConditionVariable() == OCV_CARGO_WAITING);
bool old_var_was_cargo = (order->GetConditionVariable() == OCV_CARGO_ACCEPTANCE || order->GetConditionVariable() == OCV_CARGO_WAITING
|| order->GetConditionVariable() == OCV_CARGO_LOAD_PERCENTAGE || order->GetConditionVariable() == OCV_CARGO_WAITING_AMOUNT);
bool old_var_was_slot = (order->GetConditionVariable() == OCV_SLOT_OCCUPANCY || order->GetConditionVariable() == OCV_TRAIN_IN_SLOT);
order->SetConditionVariable((OrderConditionVariable)data);
@ -1801,6 +1829,11 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (!old_var_was_cargo) order->SetConditionValue((uint16) GetFirstValidCargo());
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
break;
case OCV_CARGO_LOAD_PERCENTAGE:
case OCV_CARGO_WAITING_AMOUNT:
if (!old_var_was_cargo) order->SetConditionValue((uint16) GetFirstValidCargo());
order->GetXDataRef() = 0;
break;
case OCV_REQUIRES_SERVICE:
if (old_var_was_cargo || old_var_was_slot) order->SetConditionValue(0);
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
@ -1831,6 +1864,8 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
switch (order->GetConditionVariable()) {
case OCV_SLOT_OCCUPANCY:
case OCV_TRAIN_IN_SLOT:
case OCV_CARGO_LOAD_PERCENTAGE:
case OCV_CARGO_WAITING_AMOUNT:
order->GetXDataRef() = data;
break;
@ -1840,6 +1875,10 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
}
break;
case MOF_COND_VALUE_2:
order->SetConditionValue(data);
break;
case MOF_COND_DESTINATION:
order->SetConditionSkipToOrder(data);
break;
@ -2537,6 +2576,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v)
// OrderConditionCompare ignores the last parameter for occ == OCC_IS_TRUE or occ == OCC_IS_FALSE.
switch (order->GetConditionVariable()) {
case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, nullptr), value); break;
case OCV_CARGO_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilledOfCargo(v, (CargoType) value), order->GetXData()); break;
case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break;
case OCV_MAX_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break;
case OCV_MAX_SPEED: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break;
@ -2546,7 +2586,12 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v)
case OCV_CARGO_WAITING: {
StationID next_station = GetNextRealStation(v, order);
if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, (Station::Get(next_station)->goods[value].cargo.AvailableCount() > 0), value);
break;
break;
}
case OCV_CARGO_WAITING_AMOUNT: {
StationID next_station = GetNextRealStation(v, order);
if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, Station::Get(next_station)->goods[value].cargo.AvailableCount(), order->GetXData());
break;
}
case OCV_CARGO_ACCEPTANCE: {
StationID next_station = GetNextRealStation(v, order);

@ -31,6 +31,7 @@
#include "engine_func.h"
#include "vehiclelist.h"
#include "tracerestrict.h"
#include "scope.h"
#include "widgets/order_widget.h"
@ -596,6 +597,7 @@ static const StringID _order_goto_dropdown_aircraft[] = {
/** Variables for conditional orders; this defines the order of appearance in the dropdown box */
static const OrderConditionVariable _order_conditional_variable[] = {
OCV_LOAD_PERCENTAGE,
OCV_CARGO_LOAD_PERCENTAGE,
OCV_RELIABILITY,
OCV_MAX_RELIABILITY,
OCV_MAX_SPEED,
@ -603,6 +605,7 @@ static const OrderConditionVariable _order_conditional_variable[] = {
OCV_REMAINING_LIFETIME,
OCV_REQUIRES_SERVICE,
OCV_CARGO_WAITING,
OCV_CARGO_WAITING_AMOUNT,
OCV_CARGO_ACCEPTANCE,
OCV_FREE_PLATFORMS,
OCV_SLOT_OCCUPANCY,
@ -736,13 +739,13 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(0, order_index + 1);
DrawString(left, rtl ? right - 2 * sprite_size.width - 3 : middle, y, STR_ORDER_INDEX, colour, SA_RIGHT | SA_FORCE);
SetDParam(5, STR_EMPTY);
SetDParam(10, STR_EMPTY);
SetDParam(6, STR_EMPTY);
SetDParam(11, 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(10, STR_ORDER_OUT_OF_RANGE);
if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) SetDParam(11, STR_ORDER_OUT_OF_RANGE);
}
bool timetable_wait_time_valid = false;
@ -772,8 +775,8 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(3, STR_EMPTY);
if (order->GetWaitTime() > 0) {
SetDParam(5, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED);
SetTimetableParams(6, order->GetWaitTime());
SetDParam(6, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED);
SetTimetableParams(7, order->GetWaitTime());
}
timetable_wait_time_valid = true;
} else {
@ -782,7 +785,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(4, order->IsAutoRefit() ? STR_ORDER_AUTO_REFIT_ANY : CargoSpec::Get(order->GetRefitCargo())->name);
}
if (v->type == VEH_TRAIN && (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0) {
SetDParam(5, order->GetStopLocation() + STR_ORDER_STOP_LOCATION_NEAR_END);
SetDParam(6, order->GetStopLocation() + STR_ORDER_STOP_LOCATION_NEAR_END);
}
}
break;
@ -811,22 +814,22 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
}
if (!timetable && (order->GetDepotActionType() & ODATFB_SELL)) {
SetDParam(5, STR_ORDER_SELL_ORDER);
SetDParam(6, STR_ORDER_SELL_ORDER);
} else {
if (!timetable && (order->GetDepotActionType() & ODATFB_HALT)) {
SetDParam(5, STR_ORDER_STOP_ORDER);
SetDParam(6, STR_ORDER_STOP_ORDER);
}
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);
SetDParam(6, (order->GetDepotActionType() & ODATFB_HALT) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER);
SetDParam(7, CargoSpec::Get(order->GetRefitCargo())->name);
}
}
if (timetable) {
if (order->GetWaitTime() > 0) {
SetDParam(5, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED);
SetTimetableParams(6, order->GetWaitTime());
SetDParam(6, order->IsWaitTimetabled() ? STR_TIMETABLE_STAY_FOR : STR_TIMETABLE_STAY_FOR_ESTIMATED);
SetTimetableParams(7, order->GetWaitTime());
}
timetable_wait_time_valid = !(order->GetDepotActionType() & ODATFB_HALT);
}
@ -838,8 +841,8 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(0, str);
SetDParam(1, order->GetDestination());
if (timetable && order->IsWaitTimetabled()) {
SetDParam(5, STR_TIMETABLE_STAY_FOR);
SetTimetableParams(6, order->GetWaitTime());
SetDParam(6, STR_TIMETABLE_STAY_FOR);
SetTimetableParams(7, order->GetWaitTime());
timetable_wait_time_valid = true;
}
break;
@ -876,6 +879,17 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(3, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED);
}
SetDParam(2, order->GetConditionComparator() == OCC_IS_TRUE ? STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_SLOT : STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_SLOT);
} else if (ocv == OCV_CARGO_LOAD_PERCENTAGE) {
SetDParam(0, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE_DISPLAY);
SetDParam(2, CargoSpec::Get(order->GetConditionValue())->name);
SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + order->GetConditionComparator());
SetDParam(4, order->GetXData());
} else if (ocv == OCV_CARGO_WAITING_AMOUNT) {
SetDParam(0, STR_ORDER_CONDITIONAL_CARGO_WAITING_AMOUNT_DISPLAY);
SetDParam(2, CargoSpec::Get(order->GetConditionValue())->name);
SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + order->GetConditionComparator());
SetDParam(4, order->GetConditionValue());
SetDParam(5, order->GetXData());
} else {
OrderConditionComparator occ = order->GetConditionComparator();
bool is_cargo = ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING;
@ -901,15 +915,15 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
/* FALL THROUGH */
default:
SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ);
SetDParam(4, value);
SetDParam(4, value);
}
}
if (timetable && order->GetWaitTime() > 0) {
SetDParam(5, order->IsWaitTimetabled() ? STR_TIMETABLE_AND_TRAVEL_FOR : STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED);
SetTimetableParams(6, order->GetWaitTime());
SetDParam(6, order->IsWaitTimetabled() ? STR_TIMETABLE_AND_TRAVEL_FOR : STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED);
SetTimetableParams(7, order->GetWaitTime());
} else {
SetDParam(5, STR_EMPTY);
SetDParam(6, STR_EMPTY);
}
break;
@ -1110,6 +1124,9 @@ private:
DP_COND_VALUE_CARGO = 1, ///< Display dropdown widget cargo types
DP_COND_VALUE_SLOT = 2, ///< Display dropdown widget tracerestrict slots
/* WID_O_SEL_COND_AUX */
DP_COND_AUX_CARGO = 0, ///< Display dropdown widget cargo types
DP_ROW_CONDITIONAL = 2, ///< Display the conditional order buttons in the top row of the ship/airplane order window.
/* WID_O_SEL_BOTTOM_MIDDLE */
@ -1129,6 +1146,7 @@ private:
bool can_do_refit; ///< Vehicle chain can be refitted in depot.
bool can_do_autorefit; ///< Vehicle chain can be auto-refitted.
int query_text_widget; ///< widget which most recently called ShowQueryString
int current_aux_plane;
/**
* Return the memorised selected order.
@ -1423,6 +1441,8 @@ public:
if (v->owner == _local_company) {
this->GetWidget<NWidgetStacked>(WID_O_SEL_OCCUPANCY)->SetDisplayedPlane(SZSP_NONE);
}
this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_AUX)->SetDisplayedPlane(SZSP_NONE);
this->current_aux_plane = SZSP_NONE;
this->FinishInitNested(v->index);
if (v->owner == _local_company) {
this->DisableWidget(WID_O_EMPTY);
@ -1635,6 +1655,14 @@ public:
NWidgetStacked *row_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_TOP_ROW);
assert(row_sel != nullptr || (train_row_sel != nullptr && left_sel != nullptr && middle_sel != nullptr && right_sel != nullptr));
NWidgetStacked *aux_sel = this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_AUX);
auto aux_plane_guard = scope_guard([&]() {
if (this->current_aux_plane != aux_sel->shown_plane) {
this->current_aux_plane = aux_sel->shown_plane;
this->ReInit();
}
});
if (order == nullptr) {
if (row_sel != nullptr) {
@ -1723,6 +1751,7 @@ public:
OrderConditionVariable ocv = (order == nullptr) ? OCV_LOAD_PERCENTAGE : order->GetConditionVariable();
bool is_cargo = (ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING);
bool is_slot_occupancy = (ocv == OCV_SLOT_OCCUPANCY || ocv == OCV_TRAIN_IN_SLOT);
bool is_auxiliary_cargo = (ocv == OCV_CARGO_LOAD_PERCENTAGE || ocv == OCV_CARGO_WAITING_AMOUNT);
if (is_cargo) {
if (order == nullptr || !CargoSpec::Get(order->GetConditionValue())->IsValid()) {
@ -1740,6 +1769,17 @@ public:
this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_VALUE)->SetDisplayedPlane(DP_COND_VALUE_NUMBER);
}
if (is_auxiliary_cargo) {
if (order == nullptr || !CargoSpec::Get(order->GetConditionValue())->IsValid()) {
this->GetWidget<NWidgetCore>(WID_O_COND_AUX_CARGO)->widget_data = STR_NEWGRF_INVALID_CARGO;
} else {
this->GetWidget<NWidgetCore>(WID_O_COND_AUX_CARGO)->widget_data = CargoSpec::Get(order->GetConditionValue())->name;
}
aux_sel->SetDisplayedPlane(DP_COND_AUX_CARGO);
} else {
aux_sel->SetDisplayedPlane(SZSP_NONE);
}
/* Set the strings for the dropdown boxes. */
this->GetWidget<NWidgetCore>(WID_O_COND_VARIABLE)->widget_data = STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv;
this->GetWidget<NWidgetCore>(WID_O_COND_COMPARATOR)->widget_data = GetComparatorStrings(order)[order->GetConditionComparator()];
@ -1886,8 +1926,10 @@ public:
const Order *order = this->vehicle->GetOrder(sel);
if (order != nullptr && order->IsType(OT_CONDITIONAL)) {
uint value = order->GetConditionValue();
OrderConditionVariable ocv = order->GetConditionVariable();
uint value = (ocv == OCV_CARGO_LOAD_PERCENTAGE || ocv == OCV_CARGO_WAITING_AMOUNT) ? order->GetXData() : order->GetConditionValue();
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
if (order->GetConditionVariable() == OCV_CARGO_WAITING_AMOUNT) value = ConvertCargoQuantityToDisplayQuantity(order->GetConditionValue(), value);
SetDParam(0, value);
}
break;
@ -2085,14 +2127,15 @@ public:
break;
}
case WID_O_COND_CARGO: {
case WID_O_COND_CARGO:
case WID_O_COND_AUX_CARGO: {
uint value = this->vehicle->GetOrder(this->OrderGetSel())->GetConditionValue();
DropDownList list;
for (size_t i = 0; i < _sorted_standard_cargo_specs_size; ++i) {
const CargoSpec *cs = _sorted_cargo_specs[i];
list.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false));
}
if (!list.empty()) ShowDropDownList(this, std::move(list), value, WID_O_COND_CARGO, 0);
if (!list.empty()) ShowDropDownList(this, std::move(list), value, widget, 0);
break;
}
@ -2127,9 +2170,11 @@ public:
case WID_O_COND_VALUE: {
const Order *order = this->vehicle->GetOrder(this->OrderGetSel());
uint value = order->GetConditionValue();
OrderConditionVariable ocv = order->GetConditionVariable();
uint value = (ocv == OCV_CARGO_LOAD_PERCENTAGE || ocv == OCV_CARGO_WAITING_AMOUNT) ? order->GetXData() : order->GetConditionValue();
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value);
this->query_text_widget = WID_O_COND_VALUE;
if (order->GetConditionVariable() == OCV_CARGO_WAITING_AMOUNT) value = ConvertCargoQuantityToDisplayQuantity(order->GetConditionValue(), value);
this->query_text_widget = widget;
SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, this, CS_NUMERAL, QSF_NONE);
break;
@ -2167,9 +2212,14 @@ public:
case OCV_PERCENT:
case OCV_RELIABILITY:
case OCV_LOAD_PERCENTAGE:
case OCV_CARGO_LOAD_PERCENTAGE:
value = Clamp(value, 0, 100);
break;
case OCV_CARGO_WAITING_AMOUNT:
value = ConvertDisplayQuantityToCargoQuantity(this->vehicle->GetOrder(sel)->GetConditionValue(), value);
break;
default:
break;
}
@ -2226,6 +2276,10 @@ public:
DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VALUE | index << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
break;
case WID_O_COND_AUX_CARGO:
DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VALUE_2 | index << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
break;
case WID_O_COND_SLOT:
DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VALUE | index << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
break;
@ -2444,6 +2498,10 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_VARIABLE), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_AUX),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_AUX_CARGO), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_VALUE),
@ -2532,6 +2590,10 @@ static const NWidgetPart _nested_orders_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_VARIABLE), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_AUX),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_AUX_CARGO), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_VALUE),

@ -143,6 +143,8 @@ enum OrderConditionVariable {
OCV_PERCENT, ///< Skip xx percent of times
OCV_SLOT_OCCUPANCY, ///< Test if train slot is fully occupied
OCV_TRAIN_IN_SLOT, ///< Test if train is in slot
OCV_CARGO_LOAD_PERCENTAGE, ///< Skip based on the amount of load of a specific cargo
OCV_CARGO_WAITING_AMOUNT, ///< Skip based on the amount of a specific cargo waiting at next station
OCV_END
};
@ -174,6 +176,7 @@ enum ModifyOrderFlags {
MOF_COND_VARIABLE, ///< A conditional variable changes.
MOF_COND_COMPARATOR, ///< A comparator changes.
MOF_COND_VALUE, ///< The value to set the condition to.
MOF_COND_VALUE_2, ///< The secondary value to set the condition to.
MOF_COND_DESTINATION,///< Change the destination of a conditional order.
MOF_WAYPOINT_FLAGS, ///< Change the waypoint flags
MOF_CARGO_TYPE_UNLOAD, ///< Passes an OrderUnloadType and a CargoID.

@ -77,7 +77,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" },
{ XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 2, 2, "variable_day_length", nullptr, nullptr, nullptr },
{ XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr },
{ XSLFI_MORE_COND_ORDERS, XSCF_NULL, 2, 2, "more_cond_orders", nullptr, nullptr, nullptr },
{ XSLFI_MORE_COND_ORDERS, XSCF_NULL, 3, 3, "more_cond_orders", nullptr, nullptr, nullptr },
{ XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr },
{ XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr },
{ XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr },

@ -947,6 +947,36 @@ uint ConvertDisplayToForceWeightRatio(double in)
return ConvertDisplayToWeightRatio(_units_force[_settings_game.locale.units_force], in);
}
uint ConvertCargoQuantityToDisplayQuantity(CargoID cargo, uint quantity)
{
switch (CargoSpec::Get(cargo)->units_volume) {
case STR_TONS:
return _units_weight[_settings_game.locale.units_weight].c.ToDisplay(quantity);
case STR_LITERS:
return _units_volume[_settings_game.locale.units_volume].c.ToDisplay(quantity);
default:
break;
}
return quantity;
}
uint ConvertDisplayQuantityToCargoQuantity(CargoID cargo, uint quantity)
{
switch (CargoSpec::Get(cargo)->units_volume) {
case STR_TONS:
return _units_weight[_settings_game.locale.units_weight].c.FromDisplay(quantity);
case STR_LITERS:
return _units_volume[_settings_game.locale.units_volume].c.FromDisplay(quantity);
default:
break;
}
return quantity;
}
/**
* Parse most format codes within a string and write the result to a buffer.
* @param buff The buffer to write the final string to.

@ -2158,6 +2158,31 @@ uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
}
}
uint8 CalcPercentVehicleFilledOfCargo(const Vehicle *front, CargoID cargo)
{
int count = 0;
int max = 0;
/* Count up max and used */
for (const Vehicle *v = front; v != nullptr; v = v->Next()) {
if (v->cargo_type != cargo) continue;
count += v->cargo.StoredCount();
max += v->cargo_cap;
}
/* Train without capacity */
if (max == 0) return 100;
/* Return the percentage */
if (count * 2 < max) {
/* Less than 50%; round up, so that 0% means really empty. */
return CeilDiv(count * 100, max);
} else {
/* More than 50%; round down, so that 100% means really full. */
return (count * 100) / max;
}
}
/**
* Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it, etc.
* @param v Vehicle that entered a depot.

@ -46,6 +46,7 @@ bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc);
void CallVehicleTicks();
uint8 CalcPercentVehicleFilled(const Vehicle *v, StringID *colour);
uint8 CalcPercentVehicleFilledOfCargo(const Vehicle *v, CargoID cargo);
void VehicleLengthChanged(const Vehicle *u);

@ -34,8 +34,10 @@ enum OrderWidgets {
WID_O_COND_COMPARATOR, ///< Choose condition type.
WID_O_COND_VALUE, ///< Choose condition value.
WID_O_COND_CARGO, ///< Choose condition cargo.
WID_O_COND_AUX_CARGO, ///< Choose condition cargo.
WID_O_COND_SLOT, ///< Choose condition slot.
WID_O_SEL_COND_VALUE, ///< Widget for conditional value or conditional cargo type.
WID_O_SEL_COND_AUX, ///< Widget for auxiliary conditional cargo type.
WID_O_SEL_TOP_LEFT, ///< #NWID_SELECTION widget for left part of the top row of the 'your train' order window.
WID_O_SEL_TOP_MIDDLE, ///< #NWID_SELECTION widget for middle part of the top row of the 'your train' order window.
WID_O_SEL_TOP_RIGHT, ///< #NWID_SELECTION widget for right part of the top row of the 'your train' order window.

Loading…
Cancel
Save