First implementation of conditional order checking slot occupancy

(cherry picked from commit 524e3e56cb4a357ba60335f91dce1e00cb8d22f2)

Some code adjustments: serialisation/storage, formatting

See: #40
This commit is contained in:
keldorkatarn
2018-04-11 18:06:22 +02:00
committed by Jonathan G Rennison
parent 2e4ac325e2
commit 78588d8ce5
9 changed files with 130 additions and 18 deletions

View File

@@ -4437,6 +4437,7 @@ STR_ORDER_CONDITIONAL_CARGO_WAITING :Waiting cargo
STR_ORDER_CONDITIONAL_ACCEPTANCE_DROPDOWN :Accepted cargo STR_ORDER_CONDITIONAL_ACCEPTANCE_DROPDOWN :Accepted cargo
STR_ORDER_CONDITIONAL_FREE_PLATFORMS :Free platforms STR_ORDER_CONDITIONAL_FREE_PLATFORMS :Free platforms
STR_ORDER_CONDITIONAL_PERCENT :Percent of times STR_ORDER_CONDITIONAL_PERCENT :Percent of times
STR_ORDER_CONDITIONAL_SLOT_OCCUPANCY :Slot occupancy
STR_ORDER_CONDITIONAL_REQUIRES_SERVICE_ORDER :Requires service {STRING} STR_ORDER_CONDITIONAL_REQUIRES_SERVICE_ORDER :Requires service {STRING}
STR_ORDER_CONDITIONAL_CARGO_WAITING_ORDER :Next station {STRING} {STRING} waiting STR_ORDER_CONDITIONAL_CARGO_WAITING_ORDER :Next station {STRING} {STRING} waiting
@@ -4458,6 +4459,7 @@ STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE :is false
STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}The value to compare the vehicle data against STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}The value to compare the vehicle data against
STR_ORDER_CONDITIONAL_CARGO_TOOLTIP :{BLACK}The cargo to compare the station data against STR_ORDER_CONDITIONAL_CARGO_TOOLTIP :{BLACK}The cargo to compare the station data against
STR_ORDER_CONDITIONAL_SLOT_TOOLTIP :{BLACK}The train slot to check the occupancy of
STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Enter value to compare against STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Enter value to compare against
STR_ORDER_CONDITIONAL_COMPARATOR_ACCEPTS :accepts STR_ORDER_CONDITIONAL_COMPARATOR_ACCEPTS :accepts
@@ -4468,6 +4470,8 @@ STR_ORDER_CONDITIONAL_COMPARATOR_HAS_LESS_THAN :has less than
STR_ORDER_CONDITIONAL_COMPARATOR_HAS_LESS_EQUALS :has less than or exactly STR_ORDER_CONDITIONAL_COMPARATOR_HAS_LESS_EQUALS :has less than or exactly
STR_ORDER_CONDITIONAL_COMPARATOR_HAS_MORE_THAN :has more than STR_ORDER_CONDITIONAL_COMPARATOR_HAS_MORE_THAN :has more than
STR_ORDER_CONDITIONAL_COMPARATOR_HAS_MORE_EQUALS :has more than or exactly STR_ORDER_CONDITIONAL_COMPARATOR_HAS_MORE_EQUALS :has more than or exactly
STR_ORDER_CONDITIONAL_COMPARATOR_FULLY_OCCUPIED :is fully occupied
STR_ORDER_CONDITIONAL_COMPARATOR_NOT_YET_FULLY_OCCUPIED :is not fully occupied
STR_ORDERS_SKIP_BUTTON :{BLACK}Skip STR_ORDERS_SKIP_BUTTON :{BLACK}Skip
STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click skips to the selected order STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click skips to the selected order
@@ -4577,6 +4581,8 @@ STR_ORDER_OUT_OF_RANGE :{RED} (Next des
STR_ORDER_CONDITIONAL_UNCONDITIONAL :Jump to order {COMMA} STR_ORDER_CONDITIONAL_UNCONDITIONAL :Jump to order {COMMA}
STR_ORDER_CONDITIONAL_NUM :Jump to order {COMMA} when {STRING} {STRING} {COMMA} STR_ORDER_CONDITIONAL_NUM :Jump to order {COMMA} when {STRING} {STRING} {COMMA}
STR_ORDER_CONDITIONAL_CARGO :Jump to order {COMMA} when {STRING} {STRING} {STRING} STR_ORDER_CONDITIONAL_CARGO :Jump to order {COMMA} when {STRING} {STRING} {STRING}
STR_ORDER_CONDITIONAL_SLOT :Jump to order {COMMA} when {TRSLOT} {STRING}
STR_ORDER_CONDITIONAL_INVALID_SLOT :Jump to order {COMMA} when {RED}{STRING} {PREVIOUS_COLOUR}{STRING}
STR_ORDER_CONDITIONAL_TRUE_FALSE :Jump to order {COMMA} when {STRING} {STRING} STR_ORDER_CONDITIONAL_TRUE_FALSE :Jump to order {COMMA} when {STRING} {STRING}
STR_INVALID_ORDER :{RED} (Invalid Order) STR_INVALID_ORDER :{RED} (Invalid Order)

View File

@@ -38,6 +38,7 @@
#include "viewport_func.h" #include "viewport_func.h"
#include "order_cmd.h" #include "order_cmd.h"
#include "vehiclelist.h" #include "vehiclelist.h"
#include "tracerestrict.h"
#include "table/strings.h" #include "table/strings.h"
@@ -1003,10 +1004,18 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
OrderConditionComparator occ = new_order.GetConditionComparator(); OrderConditionComparator occ = new_order.GetConditionComparator();
if (occ >= OCC_END) return CMD_ERROR; if (occ >= OCC_END) return CMD_ERROR;
switch (new_order.GetConditionVariable()) { switch (new_order.GetConditionVariable()) {
case OCV_SLOT_OCCUPANCY: {
TraceRestrictSlotID slot = new_order.GetXData();
if (slot != INVALID_TRACE_RESTRICT_SLOT_ID && !TraceRestrictSlot::IsValidID(slot)) return CMD_ERROR;
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) return CMD_ERROR;
break;
}
case OCV_CARGO_WAITING: case OCV_CARGO_WAITING:
case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_ACCEPTANCE:
if (!CargoSpec::Get(new_order.GetConditionValue())->IsValid()) return CMD_ERROR; if (!CargoSpec::Get(new_order.GetConditionValue())->IsValid()) return CMD_ERROR;
/* FALL THROUGH */ /* FALL THROUGH */
case OCV_REQUIRES_SERVICE: case OCV_REQUIRES_SERVICE:
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) return CMD_ERROR; if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) return CMD_ERROR;
break; break;
@@ -1480,8 +1489,8 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
* the maximum vehicle order id is 254. * the maximum vehicle order id is 254.
* @param p2 various bitstuffed elements * @param p2 various bitstuffed elements
* - p2 = (bit 0 - 3) - what data to modify (@see ModifyOrderFlags) * - p2 = (bit 0 - 3) - what data to modify (@see ModifyOrderFlags)
* - p2 = (bit 4 - 15) - the data to modify * - p2 = (bit 4 - 19) - the data to modify
* - p2 = (bit 16 - 23) - a CargoID for cargo type orders (MOF_CARGO_TYPE_UNLOAD or MOF_CARGO_TYPE_LOAD) * - p2 = (bit 20 - 27) - a CargoID for cargo type orders (MOF_CARGO_TYPE_UNLOAD or MOF_CARGO_TYPE_LOAD)
* @param text unused * @param text unused
* @return the cost of this operation or an error * @return the cost of this operation or an error
*/ */
@@ -1490,8 +1499,8 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
VehicleOrderID sel_ord = GB(p1, 20, 8); VehicleOrderID sel_ord = GB(p1, 20, 8);
VehicleID veh = GB(p1, 0, 20); VehicleID veh = GB(p1, 0, 20);
ModifyOrderFlags mof = Extract<ModifyOrderFlags, 0, 4>(p2); ModifyOrderFlags mof = Extract<ModifyOrderFlags, 0, 4>(p2);
uint16 data = GB(p2, 4, 11); uint16 data = GB(p2, 4, 16);
CargoID cargo_id = (mof == MOF_CARGO_TYPE_UNLOAD || mof == MOF_CARGO_TYPE_LOAD) ? (CargoID) GB(p2, 16, 8) : (CargoID) CT_INVALID; CargoID cargo_id = (mof == MOF_CARGO_TYPE_UNLOAD || mof == MOF_CARGO_TYPE_LOAD) ? (CargoID) GB(p2, 20, 8) : (CargoID) CT_INVALID;
if (mof >= MOF_END) return CMD_ERROR; if (mof >= MOF_END) return CMD_ERROR;
@@ -1583,6 +1592,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
case OCV_REQUIRES_SERVICE: case OCV_REQUIRES_SERVICE:
case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_ACCEPTANCE:
case OCV_CARGO_WAITING: case OCV_CARGO_WAITING:
case OCV_SLOT_OCCUPANCY:
if (data != OCC_IS_TRUE && data != OCC_IS_FALSE) return CMD_ERROR; if (data != OCC_IS_TRUE && data != OCC_IS_FALSE) return CMD_ERROR;
break; break;
@@ -1604,6 +1614,10 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (data > 100) return CMD_ERROR; if (data > 100) return CMD_ERROR;
break; break;
case OCV_SLOT_OCCUPANCY:
if (data != INVALID_TRACE_RESTRICT_SLOT_ID && !TraceRestrictSlot::IsValidID(data)) return CMD_ERROR;
break;
case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_ACCEPTANCE:
case OCV_CARGO_WAITING: case OCV_CARGO_WAITING:
if (!(data < NUM_CARGO && CargoSpec::Get(data)->IsValid())) return CMD_ERROR; if (!(data < NUM_CARGO && CargoSpec::Get(data)->IsValid())) return CMD_ERROR;
@@ -1684,6 +1698,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
case MOF_COND_VARIABLE: { case MOF_COND_VARIABLE: {
/* Check whether old conditional variable had a cargo as value */ /* 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);
bool old_var_was_slot = (order->GetConditionVariable() == OCV_SLOT_OCCUPANCY);
order->SetConditionVariable((OrderConditionVariable)data); order->SetConditionVariable((OrderConditionVariable)data);
OrderConditionComparator occ = order->GetConditionComparator(); OrderConditionComparator occ = order->GetConditionComparator();
@@ -1693,13 +1708,18 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
order->SetConditionValue(0); order->SetConditionValue(0);
break; break;
case OCV_SLOT_OCCUPANCY:
if (!old_var_was_slot) order->GetXDataRef() = INVALID_TRACE_RESTRICT_SLOT_ID;
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
break;
case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_ACCEPTANCE:
case OCV_CARGO_WAITING: case OCV_CARGO_WAITING:
if (!old_var_was_cargo) order->SetConditionValue((uint16) GetFirstValidCargo()); if (!old_var_was_cargo) order->SetConditionValue((uint16) GetFirstValidCargo());
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE); if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
break; break;
case OCV_REQUIRES_SERVICE: case OCV_REQUIRES_SERVICE:
if (old_var_was_cargo) order->SetConditionValue(0); 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); if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
order->SetConditionValue(0); order->SetConditionValue(0);
break; break;
@@ -1713,7 +1733,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
FALLTHROUGH; FALLTHROUGH;
default: default:
if (old_var_was_cargo) order->SetConditionValue(0); if (old_var_was_cargo || old_var_was_slot) order->SetConditionValue(0);
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS); if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS);
break; break;
} }
@@ -1725,8 +1745,16 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
break; break;
case MOF_COND_VALUE: case MOF_COND_VALUE:
switch (order->GetConditionVariable()) {
case OCV_SLOT_OCCUPANCY:
order->GetXDataRef() = data;
break;
default:
order->SetConditionValue(data); order->SetConditionValue(data);
break; break;
}
break;
case MOF_COND_DESTINATION: case MOF_COND_DESTINATION:
order->SetConditionSkipToOrder(data); order->SetConditionSkipToOrder(data);
@@ -2349,6 +2377,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v)
OrderConditionComparator occ = order->GetConditionComparator(); OrderConditionComparator occ = order->GetConditionComparator();
uint16 value = order->GetConditionValue(); uint16 value = order->GetConditionValue();
// OrderConditionCompare ignores the last parameter for occ == OCC_IS_TRUE or occ == OCC_IS_FALSE.
switch (order->GetConditionVariable()) { switch (order->GetConditionVariable()) {
case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, NULL), value); break; case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, NULL), value); break;
case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break; case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break;
@@ -2366,6 +2395,11 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v)
if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, HasBit(Station::Get(next_station)->goods[value].status, GoodsEntry::GES_ACCEPTANCE), value); if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, HasBit(Station::Get(next_station)->goods[value].status, GoodsEntry::GES_ACCEPTANCE), value);
break; break;
} }
case OCV_SLOT_OCCUPANCY: {
const TraceRestrictSlot* slot = TraceRestrictSlot::GetIfValid(order->GetXData());
if (slot != nullptr) skip_order = OrderConditionCompare(occ, slot->occupants.size() >= slot->max_occupancy, value);
break;
}
case OCV_FREE_PLATFORMS: { case OCV_FREE_PLATFORMS: {
StationID next_station = GetNextRealStation(v, order); StationID next_station = GetNextRealStation(v, order);
if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, GetFreeStationPlatforms(next_station), value); if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, GetFreeStationPlatforms(next_station), value);

View File

@@ -31,6 +31,7 @@
#include "aircraft.h" #include "aircraft.h"
#include "engine_func.h" #include "engine_func.h"
#include "vehiclelist.h" #include "vehiclelist.h"
#include "tracerestrict.h"
#include "widgets/order_widget.h" #include "widgets/order_widget.h"
@@ -63,6 +64,8 @@ static const StringID _cargo_type_unload_order_drowdown[] = {
}; };
static const uint32 _cargo_type_unload_order_drowdown_hidden_mask = 0x8; // 01000 static const uint32 _cargo_type_unload_order_drowdown_hidden_mask = 0x8; // 01000
DropDownList* GetSlotDropDownList(Owner owner, TraceRestrictSlotID slot_id, int &selected);
struct CargoTypeOrdersWindow : public Window { struct CargoTypeOrdersWindow : public Window {
private: private:
CargoTypeOrdersWindowVariant variant; CargoTypeOrdersWindowVariant variant;
@@ -244,7 +247,7 @@ public:
if (action_type == order_action_type) return; if (action_type == order_action_type) return;
ModifyOrderFlags mof = (this->variant == CTOWV_LOAD) ? MOF_CARGO_TYPE_LOAD : MOF_CARGO_TYPE_UNLOAD; ModifyOrderFlags mof = (this->variant == CTOWV_LOAD) ? MOF_CARGO_TYPE_LOAD : MOF_CARGO_TYPE_UNLOAD;
DoCommandP(this->vehicle->tile, this->vehicle->index + (this->order_id << 20), mof | (action_type << 4) | (cargo_id << 16), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); DoCommandP(this->vehicle->tile, this->vehicle->index + (this->order_id << 20), mof | (action_type << 4) | (cargo_id << 20), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER));
this->GetWidget<NWidgetCore>(widget)->SetDataTip(this->cargo_type_order_dropdown[this->GetOrderActionTypeForCargo(cargo_id)], STR_CARGO_TYPE_LOAD_ORDERS_DROP_TOOLTIP + this->variant); this->GetWidget<NWidgetCore>(widget)->SetDataTip(this->cargo_type_order_dropdown[this->GetOrderActionTypeForCargo(cargo_id)], STR_CARGO_TYPE_LOAD_ORDERS_DROP_TOOLTIP + this->variant);
this->SetWidgetDirty(widget); this->SetWidgetDirty(widget);
@@ -602,6 +605,7 @@ static const OrderConditionVariable _order_conditional_variable[] = {
OCV_CARGO_WAITING, OCV_CARGO_WAITING,
OCV_CARGO_ACCEPTANCE, OCV_CARGO_ACCEPTANCE,
OCV_FREE_PLATFORMS, OCV_FREE_PLATFORMS,
OCV_SLOT_OCCUPANCY,
OCV_PERCENT, OCV_PERCENT,
OCV_UNCONDITIONALLY, OCV_UNCONDITIONALLY,
}; };
@@ -642,6 +646,18 @@ static const StringID _order_conditional_condition_accepts[] = {
INVALID_STRING_ID, INVALID_STRING_ID,
}; };
static const StringID _order_conditional_condition_is_fully_occupied[] = {
STR_NULL,
STR_NULL,
STR_NULL,
STR_NULL,
STR_NULL,
STR_NULL,
STR_ORDER_CONDITIONAL_COMPARATOR_FULLY_OCCUPIED,
STR_ORDER_CONDITIONAL_COMPARATOR_NOT_YET_FULLY_OCCUPIED,
INVALID_STRING_ID,
};
extern uint ConvertSpeedToDisplaySpeed(uint speed); extern uint ConvertSpeedToDisplaySpeed(uint speed);
extern uint ConvertDisplaySpeedToSpeed(uint speed); extern uint ConvertDisplaySpeedToSpeed(uint speed);
@@ -813,6 +829,15 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(0, STR_CONDITIONAL_FREE_PLATFORMS ); SetDParam(0, STR_CONDITIONAL_FREE_PLATFORMS );
SetDParam(2, STR_ORDER_CONDITIONAL_COMPARATOR_HAS + order->GetConditionComparator()); SetDParam(2, STR_ORDER_CONDITIONAL_COMPARATOR_HAS + order->GetConditionComparator());
SetDParam(3, order->GetConditionValue()); SetDParam(3, order->GetConditionValue());
} else if (ocv == OCV_SLOT_OCCUPANCY) {
if (TraceRestrictSlot::IsValidID(order->GetXData())) {
SetDParam(0, STR_ORDER_CONDITIONAL_SLOT);
SetDParam(2, order->GetXData());
} else {
SetDParam(0, STR_ORDER_CONDITIONAL_INVALID_SLOT);
SetDParam(2, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED);
}
SetDParam(3, order->GetConditionComparator() == OCC_IS_TRUE ? STR_ORDER_CONDITIONAL_COMPARATOR_FULLY_OCCUPIED : STR_ORDER_CONDITIONAL_COMPARATOR_NOT_YET_FULLY_OCCUPIED);
} else { } else {
OrderConditionComparator occ = order->GetConditionComparator(); OrderConditionComparator occ = order->GetConditionComparator();
bool is_cargo = ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING; bool is_cargo = ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING;
@@ -1016,6 +1041,7 @@ private:
/* WID_O_SEL_COND_VALUE */ /* WID_O_SEL_COND_VALUE */
DP_COND_VALUE_NUMBER = 0, ///< Display number widget DP_COND_VALUE_NUMBER = 0, ///< Display number widget
DP_COND_VALUE_CARGO = 1, ///< Display dropdown widget cargo types DP_COND_VALUE_CARGO = 1, ///< Display dropdown widget cargo types
DP_COND_VALUE_SLOT = 2, ///< Display dropdown widget tracerestrict slots
DP_ROW_CONDITIONAL = 2, ///< Display the conditional order buttons in the top row of the ship/airplane order window. DP_ROW_CONDITIONAL = 2, ///< Display the conditional order buttons in the top row of the ship/airplane order window.
@@ -1087,6 +1113,9 @@ private:
case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_ACCEPTANCE:
return _order_conditional_condition_accepts; return _order_conditional_condition_accepts;
case OCV_SLOT_OCCUPANCY:
return _order_conditional_condition_is_fully_occupied;
default: default:
return _order_conditional_condition; return _order_conditional_condition;
} }
@@ -1634,12 +1663,19 @@ public:
} else { } else {
train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_CONDITIONAL); train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_CONDITIONAL);
} }
OrderConditionVariable ocv = (order == NULL) ? OCV_LOAD_PERCENTAGE : order->GetConditionVariable();
OrderConditionVariable ocv = (order == nullptr) ? OCV_LOAD_PERCENTAGE : order->GetConditionVariable();
bool is_cargo = (ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING); bool is_cargo = (ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING);
bool is_slot_occupancy = (ocv == OCV_SLOT_OCCUPANCY);
if (is_cargo) { if (is_cargo) {
this->GetWidget<NWidgetCore>(WID_O_COND_CARGO)->widget_data = cargo_names_list[(order == NULL) ? 0 : order->GetConditionValue()]; this->GetWidget<NWidgetCore>(WID_O_COND_CARGO)->widget_data = cargo_names_list[(order == NULL) ? 0 : order->GetConditionValue()];
this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_VALUE)->SetDisplayedPlane(DP_COND_VALUE_CARGO); this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_VALUE)->SetDisplayedPlane(DP_COND_VALUE_CARGO);
} else if (is_slot_occupancy) {
TraceRestrictSlotID slot_id = (order != nullptr && TraceRestrictSlot::IsValidID(order->GetXData()) ? order->GetXData() : INVALID_TRACE_RESTRICT_SLOT_ID);
this->GetWidget<NWidgetCore>(WID_O_COND_SLOT)->widget_data = (slot_id != INVALID_TRACE_RESTRICT_SLOT_ID) ? STR_TRACE_RESTRICT_SLOT_NAME : STR_TRACE_RESTRICT_VARIABLE_UNDEFINED;
this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_VALUE)->SetDisplayedPlane(DP_COND_VALUE_SLOT);
} else { } else {
this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_VALUE)->SetDisplayedPlane(DP_COND_VALUE_NUMBER); this->GetWidget<NWidgetStacked>(WID_O_SEL_COND_VALUE)->SetDisplayedPlane(DP_COND_VALUE_NUMBER);
} }
@@ -1797,6 +1833,17 @@ public:
break; break;
} }
case WID_O_COND_SLOT: {
VehicleOrderID sel = this->OrderGetSel();
const Order *order = this->vehicle->GetOrder(sel);
if (order != nullptr && order->IsType(OT_CONDITIONAL)) {
TraceRestrictSlotID value = order->GetXData();
SetDParam(0, value);
}
break;
}
case WID_O_CAPTION: case WID_O_CAPTION:
SetDParam(0, this->vehicle->index); SetDParam(0, this->vehicle->index);
break; break;
@@ -1958,6 +2005,14 @@ public:
} }
break; break;
case WID_O_COND_SLOT: {
int selected;
TraceRestrictSlotID value = this->vehicle->GetOrder(this->OrderGetSel())->GetXData();
DropDownList *list = GetSlotDropDownList(this->vehicle->owner, value, selected);
if (list != nullptr) ShowDropDownList(this, list, selected, WID_O_COND_SLOT, 0, true);
break;
}
case WID_O_REVERSE: { case WID_O_REVERSE: {
VehicleOrderID sel_ord = this->OrderGetSel(); VehicleOrderID sel_ord = this->OrderGetSel();
const Order *order = this->vehicle->GetOrder(sel_ord); const Order *order = this->vehicle->GetOrder(sel_ord);
@@ -1992,7 +2047,10 @@ public:
const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
OrderConditionVariable cond_var = o->GetConditionVariable(); OrderConditionVariable cond_var = o->GetConditionVariable();
ShowDropDownMenu(this, GetComparatorStrings(o), o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, ShowDropDownMenu(this, GetComparatorStrings(o), o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0,
(cond_var == OCV_REQUIRES_SERVICE || cond_var == OCV_CARGO_ACCEPTANCE || cond_var == OCV_CARGO_WAITING) ? 0x3F : 0xC0, 0, DDSF_LOST_FOCUS); (cond_var == OCV_REQUIRES_SERVICE ||
cond_var == OCV_CARGO_ACCEPTANCE ||
cond_var == OCV_CARGO_WAITING ||
cond_var == OCV_SLOT_OCCUPANCY) ? 0x3F : 0xC0, 0, DDSF_LOST_FOCUS);
break; break;
} }
@@ -2096,6 +2154,10 @@ public:
case WID_O_COND_CARGO: case WID_O_COND_CARGO:
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)); 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; 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;
} }
} }
@@ -2318,6 +2380,8 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_CARGO), SetMinimalSize(124, 12), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_CARGO), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_SLOT), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_SLOT_TOOLTIP), SetResize(1, 0),
EndContainer(), EndContainer(),
EndContainer(), EndContainer(),
EndContainer(), EndContainer(),
@@ -2404,6 +2468,8 @@ static const NWidgetPart _nested_orders_widgets[] = {
SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_CARGO), SetMinimalSize(124, 12), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_CARGO), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_SLOT), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_SLOT_TOOLTIP), SetResize(1, 0),
EndContainer(), EndContainer(),
EndContainer(), EndContainer(),
EndContainer(), EndContainer(),

View File

@@ -144,6 +144,7 @@ enum OrderConditionVariable {
OCV_CARGO_ACCEPTANCE, ///< Skip if specified cargo is accepted at next station OCV_CARGO_ACCEPTANCE, ///< Skip if specified cargo is accepted at next station
OCV_FREE_PLATFORMS, ///< Skip based on free platforms at next station OCV_FREE_PLATFORMS, ///< Skip based on free platforms at next station
OCV_PERCENT, ///< Skip xx percent of times OCV_PERCENT, ///< Skip xx percent of times
OCV_SLOT_OCCUPANCY, ///< Test if train slot is fully occupied
OCV_END OCV_END
}; };

View File

@@ -49,6 +49,7 @@ static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_TRACE_RESTRICT, XSCF_NULL, 8, 8, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" }, { XSLFI_TRACE_RESTRICT, XSCF_NULL, 8, 8, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" },
{ XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", NULL, NULL, NULL }, { XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", NULL, NULL, NULL },
{ XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 1, 1, "tracerestrict_order_cond", NULL, NULL, NULL },
{ XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", NULL, NULL, "SPRG" }, { XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", NULL, NULL, "SPRG" },
{ XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", NULL, NULL, NULL }, { XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", NULL, NULL, NULL },
{ XSLFI_SAFER_CROSSINGS, XSCF_NULL, 1, 1, "safer_crossings", NULL, NULL, NULL }, { XSLFI_SAFER_CROSSINGS, XSCF_NULL, 1, 1, "safer_crossings", NULL, NULL, NULL },

View File

@@ -23,6 +23,7 @@ enum SlXvFeatureIndex {
XSLFI_NULL = 0, ///< Unused value, to indicate that no extended feature test is in use XSLFI_NULL = 0, ///< Unused value, to indicate that no extended feature test is in use
XSLFI_TRACE_RESTRICT, ///< Trace restrict XSLFI_TRACE_RESTRICT, ///< Trace restrict
XSLFI_TRACE_RESTRICT_OWNER, ///< Trace restrict: train owner test XSLFI_TRACE_RESTRICT_OWNER, ///< Trace restrict: train owner test
XSLFI_TRACE_RESTRICT_ORDRCND, ///< Trace restrict: slot conditional order
XSLFI_PROG_SIGS, ///< programmable signals patch XSLFI_PROG_SIGS, ///< programmable signals patch
XSLFI_ADJACENT_CROSSINGS, ///< Adjacent level crossings closure patch XSLFI_ADJACENT_CROSSINGS, ///< Adjacent level crossings closure patch
XSLFI_SAFER_CROSSINGS, ///< Safer level crossings XSLFI_SAFER_CROSSINGS, ///< Safer level crossings

View File

@@ -1661,6 +1661,7 @@ CommandCost CmdDeleteTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint
InvalidateWindowClassesData(WC_TRACE_RESTRICT); InvalidateWindowClassesData(WC_TRACE_RESTRICT);
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
InvalidateWindowClassesData(WC_VEHICLE_ORDERS);
} }
return CommandCost(); return CommandCost();
@@ -1707,6 +1708,7 @@ CommandCost CmdAlterTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint3
// update windows // update windows
InvalidateWindowClassesData(WC_TRACE_RESTRICT); InvalidateWindowClassesData(WC_TRACE_RESTRICT);
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
InvalidateWindowClassesData(WC_VEHICLE_ORDERS);
} }
return CommandCost(); return CommandCost();

View File

@@ -457,7 +457,7 @@ static int CDECL SlotNameSorter(const TraceRestrictSlot * const *a, const TraceR
/** /**
* Get a DropDownList of the group list * Get a DropDownList of the group list
*/ */
static DropDownList *GetSlotDropDownList(Owner owner, TraceRestrictSlotID slot_id, int &selected) DropDownList *GetSlotDropDownList(Owner owner, TraceRestrictSlotID slot_id, int &selected)
{ {
GUIList<const TraceRestrictSlot*> list; GUIList<const TraceRestrictSlot*> list;

View File

@@ -35,8 +35,9 @@ enum OrderWidgets {
WID_O_COND_VARIABLE, ///< Choose condition variable. WID_O_COND_VARIABLE, ///< Choose condition variable.
WID_O_COND_COMPARATOR, ///< Choose condition type. WID_O_COND_COMPARATOR, ///< Choose condition type.
WID_O_COND_VALUE, ///< Choose condition value. WID_O_COND_VALUE, ///< Choose condition value.
WID_O_COND_CARGO, WID_O_COND_CARGO, ///< Choose condition cargo.
WID_O_SEL_COND_VALUE, ///< widget for conditional value or conditional cargo type. WID_O_COND_SLOT, ///< Choose condition slot.
WID_O_SEL_COND_VALUE, ///< Widget for conditional value or 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_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_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. WID_O_SEL_TOP_RIGHT, ///< #NWID_SELECTION widget for right part of the top row of the 'your train' order window.