Tracerestrict: Add condition whether reservation passes through tile
This commit is contained in:
@@ -3260,6 +3260,8 @@ STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_EQUALS :can carry
|
|||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_NOT_EQUALS :can't carry
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_NOT_EQUALS :can't carry
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_HAS_STATUS :has
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_HAS_STATUS :has
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_DOESNT_HAVE_STATUS :doesn't have
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_DOESNT_HAVE_STATUS :doesn't have
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_PASS :passes through
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_DOESNT_PASS :doesn't pass through
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_IF :If
|
STR_TRACE_RESTRICT_CONDITIONAL_IF :If
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_ELIF :Else if
|
STR_TRACE_RESTRICT_CONDITIONAL_ELIF :Else if
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_ORIF :Or if
|
STR_TRACE_RESTRICT_CONDITIONAL_ORIF :Or if
|
||||||
@@ -3297,6 +3299,8 @@ STR_TRACE_RESTRICT_VARIABLE_TRAIN_OWNER :train owner
|
|||||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_STATUS :train status
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_STATUS :train status
|
||||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_ENGINE_CLASS :engine class
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_ENGINE_CLASS :engine class
|
||||||
STR_TRACE_RESTRICT_VARIABLE_ORDER_TARGET_DIRECTION :direction of order target
|
STR_TRACE_RESTRICT_VARIABLE_ORDER_TARGET_DIRECTION :direction of order target
|
||||||
|
STR_TRACE_RESTRICT_VARIABLE_RESERVATION_THROUGH :PBS reservation passes tile
|
||||||
|
STR_TRACE_RESTRICT_VARIABLE_RESERVATION_THROUGH_SHORT :PBS reservation
|
||||||
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined
|
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined
|
||||||
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED :{PUSH_COLOUR}{RED}undefined{POP_COLOUR}
|
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED :{PUSH_COLOUR}{RED}undefined{POP_COLOUR}
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then
|
||||||
@@ -3327,6 +3331,7 @@ STR_TRACE_RESTRICT_CONDITIONAL_COUNTER :{STRING} value
|
|||||||
STR_TRACE_RESTRICT_CONDITIONAL_COUNTER_STR :{STRING} value of counter: {STRING} {BLACK}{STRING} {STRING} {COMMA} then
|
STR_TRACE_RESTRICT_CONDITIONAL_COUNTER_STR :{STRING} value of counter: {STRING} {BLACK}{STRING} {STRING} {COMMA} then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_ENGINE_CLASSES :{STRING} train {STRING}: {STRING} then
|
STR_TRACE_RESTRICT_CONDITIONAL_ENGINE_CLASSES :{STRING} train {STRING}: {STRING} then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_TARGET_DIRECTION :{STRING} tile of {STRING} {STRING} further {STRING} than this signal tile then
|
STR_TRACE_RESTRICT_CONDITIONAL_TARGET_DIRECTION :{STRING} tile of {STRING} {STRING} further {STRING} than this signal tile then
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_PASSES_TILE_INDEX :{STRING} {STRING} {STRING} {NUM} x {NUM} then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED :{STRING} {STRING} {STRING} {RED}undefined {BLACK}{STRING}then
|
STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED :{STRING} {STRING} {STRING} {RED}undefined {BLACK}{STRING}then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED :{STRING} {RED}undefined {BLACK}{STRING}then
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED :{STRING} {RED}undefined {BLACK}{STRING}then
|
||||||
STR_TRACE_RESTRICT_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA}
|
STR_TRACE_RESTRICT_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA}
|
||||||
|
118
src/pbs.cpp
118
src/pbs.cpp
@@ -707,6 +707,108 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
|
|||||||
return PBSTileInfo(tile, trackdir, false);
|
return PBSTileInfo(tile, trackdir, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Follow a reservation starting from a specific tile to the end. */
|
||||||
|
template <typename T>
|
||||||
|
static void FollowReservationEnumerate(Owner o, RailTypes rts, TileIndex tile, Trackdir trackdir, FollowReservationFlags flags, T handler)
|
||||||
|
{
|
||||||
|
TileIndex start_tile = tile;
|
||||||
|
Trackdir start_trackdir = trackdir;
|
||||||
|
bool first_loop = true;
|
||||||
|
|
||||||
|
/* Start track not reserved? This can happen if two trains
|
||||||
|
* are on the same tile. The reservation on the next tile
|
||||||
|
* is not ours in this case, so exit. */
|
||||||
|
if (!(flags & FRF_TB_EXIT_FREE) && !HasReservedTracks(tile, TrackToTrackBits(TrackdirToTrack(trackdir)))) return;
|
||||||
|
|
||||||
|
if (handler(start_tile, start_trackdir)) return;
|
||||||
|
|
||||||
|
/* Do not disallow 90 deg turns as the setting might have changed between reserving and now. */
|
||||||
|
CFollowTrackRail ft(o, rts);
|
||||||
|
auto check_tunnel_bridge = [&]() -> bool {
|
||||||
|
if (IsTunnelBridgeWithSignalSimulation(tile) && TrackdirEntersTunnelBridge(tile, trackdir)) {
|
||||||
|
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsTunnelBridgeSignalSimulationEntrance(tile)) {
|
||||||
|
TileIndex end = GetOtherTunnelBridgeEnd(tile);
|
||||||
|
if (HasAcrossTunnelBridgeReservation(end) && GetTunnelBridgeExitSignalState(end) == SIGNAL_STATE_GREEN &&
|
||||||
|
((flags & FRF_TB_EXIT_FREE) || TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded())) {
|
||||||
|
/* skip far end */
|
||||||
|
Trackdir end_trackdir = GetTunnelBridgeExitTrackdir(end);
|
||||||
|
tile = end;
|
||||||
|
trackdir = end_trackdir;
|
||||||
|
if (handler(tile, trackdir)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((flags & FRF_IGNORE_ONEWAY) && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsTunnelBridgeSignalSimulationExit(tile) &&
|
||||||
|
GetTunnelBridgeExitSignalState(tile) == SIGNAL_STATE_GREEN) {
|
||||||
|
TileIndex end = GetOtherTunnelBridgeEnd(tile);
|
||||||
|
if (HasAcrossTunnelBridgeReservation(end) && TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded()) {
|
||||||
|
/* skip far end */
|
||||||
|
tile = end;
|
||||||
|
trackdir = GetTunnelBridgeExitTrackdir(tile);
|
||||||
|
if (handler(tile, trackdir)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
while (check_tunnel_bridge() && ft.Follow(tile, trackdir)) {
|
||||||
|
flags &= ~FRF_TB_EXIT_FREE;
|
||||||
|
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
|
||||||
|
|
||||||
|
if (ft.m_is_station) {
|
||||||
|
/* Check skipped station tiles as well, maybe our reservation ends inside the station. */
|
||||||
|
TileIndexDiff diff = TileOffsByDiagDir(ft.m_exitdir);
|
||||||
|
TileIndex t = ft.m_new_tile - (ft.m_tiles_skipped * diff);
|
||||||
|
while (ft.m_tiles_skipped-- > 0) {
|
||||||
|
if (HasStationReservation(t)) {
|
||||||
|
if (handler(t, DiagDirToDiagTrackdir(ft.m_exitdir))) return;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t += diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No reservation --> path end found */
|
||||||
|
if (reserved == TRACKDIR_BIT_NONE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can't have more than one reserved trackdir */
|
||||||
|
Trackdir new_trackdir = FindFirstTrackdir(reserved);
|
||||||
|
|
||||||
|
/* One-way signal against us. The reservation can't be ours as it is not
|
||||||
|
* a safe position from our direction and we can never pass the signal. */
|
||||||
|
if (!(flags & FRF_IGNORE_ONEWAY) && HasOnewaySignalBlockingTrackdir(ft.m_new_tile, new_trackdir)) break;
|
||||||
|
|
||||||
|
tile = ft.m_new_tile;
|
||||||
|
trackdir = new_trackdir;
|
||||||
|
|
||||||
|
if (handler(tile, trackdir)) return;
|
||||||
|
|
||||||
|
if (first_loop) {
|
||||||
|
/* Update the start tile after we followed the track the first
|
||||||
|
* time. This is necessary because the track follower can skip
|
||||||
|
* tiles (in stations for example) which means that we might
|
||||||
|
* never visit our original starting tile again. */
|
||||||
|
start_tile = tile;
|
||||||
|
start_trackdir = trackdir;
|
||||||
|
first_loop = false;
|
||||||
|
} else {
|
||||||
|
/* Loop encountered? */
|
||||||
|
if (tile == start_tile && trackdir == start_trackdir) break;
|
||||||
|
}
|
||||||
|
/* Depot tile? Can't continue. */
|
||||||
|
if (IsRailDepotTile(tile)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Non-pbs signal? Reservation can't continue. */
|
||||||
|
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper struct for finding the best matching vehicle on a specific track.
|
* Helper struct for finding the best matching vehicle on a specific track.
|
||||||
*/
|
*/
|
||||||
@@ -1302,6 +1404,22 @@ TileIndex VehiclePosTraceRestrictPreviousSignalCallback(const Train *v, const vo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether a train's reservation passes through a given tile.
|
||||||
|
*/
|
||||||
|
bool TrainReservationPassesThroughTile(const Train *v, TileIndex search_tile)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
FollowReservationEnumerate(v->owner, GetRailTypeInfo(v->railtype)->all_compatible_railtypes, v->tile, v->GetVehicleTrackdir(), FRF_NONE, [&](TileIndex tile, Trackdir trackdir) -> bool {
|
||||||
|
if (tile == search_tile) {
|
||||||
|
found = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether a certain track on a tile is a safe position to end a path.
|
* Determine whether a certain track on a tile is a safe position to end a path.
|
||||||
*
|
*
|
||||||
|
@@ -166,6 +166,7 @@ void ApplyAvailableFreeTunnelBridgeTiles(TrainReservationLookAhead *lookahead, i
|
|||||||
void TryCreateLookAheadForTrainInTunnelBridge(Train *t);
|
void TryCreateLookAheadForTrainInTunnelBridge(Train *t);
|
||||||
void SetTrainReservationLookaheadEnd(Train *v);
|
void SetTrainReservationLookaheadEnd(Train *v);
|
||||||
void FillTrainReservationLookAhead(Train *v);
|
void FillTrainReservationLookAhead(Train *v);
|
||||||
|
bool TrainReservationPassesThroughTile(const Train *v, TileIndex search_tile);
|
||||||
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false);
|
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false);
|
||||||
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false, PBSWaitingPositionRestrictedSignalInfo *restricted_signal_info = nullptr);
|
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false, PBSWaitingPositionRestrictedSignalInfo *restricted_signal_info = nullptr);
|
||||||
|
|
||||||
|
@@ -70,7 +70,7 @@ static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run);
|
|||||||
|
|
||||||
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||||
{ XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr },
|
{ XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr },
|
||||||
{ XSLFI_TRACE_RESTRICT, XSCF_NULL, 14, 14, "tracerestrict", nullptr, nullptr, "TRRM,TRRP,TRRS" },
|
{ XSLFI_TRACE_RESTRICT, XSCF_NULL, 15, 15, "tracerestrict", nullptr, nullptr, "TRRM,TRRP,TRRS" },
|
||||||
{ XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", nullptr, nullptr, nullptr },
|
{ XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 4, 4, "tracerestrict_order_cond", nullptr, nullptr, nullptr },
|
{ XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 4, 4, "tracerestrict_order_cond", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TRACE_RESTRICT_STATUSCND,XSCF_NULL, 1, 1, "tracerestrict_status_cond", nullptr, nullptr, nullptr },
|
{ XSLFI_TRACE_RESTRICT_STATUSCND,XSCF_NULL, 1, 1, "tracerestrict_status_cond", nullptr, nullptr, nullptr },
|
||||||
|
@@ -612,6 +612,14 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TRIT_COND_RESERVATION_THROUGH: {
|
||||||
|
// TRIT_COND_RESERVATION_THROUGH value type uses the next slot
|
||||||
|
i++;
|
||||||
|
uint32_t test_tile = this->items[i];
|
||||||
|
result = TestBinaryConditionCommon(item, TrainReservationPassesThroughTile(v, test_tile));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -1002,6 +1010,7 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
|||||||
case TRIT_COND_TIME_DATE_VALUE:
|
case TRIT_COND_TIME_DATE_VALUE:
|
||||||
case TRIT_COND_RESERVED_TILES:
|
case TRIT_COND_RESERVED_TILES:
|
||||||
case TRIT_COND_CATEGORY:
|
case TRIT_COND_CATEGORY:
|
||||||
|
case TRIT_COND_RESERVATION_THROUGH:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRIT_COND_CURRENT_ORDER:
|
case TRIT_COND_CURRENT_ORDER:
|
||||||
@@ -1209,6 +1218,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
|
|||||||
case TRVT_DENY:
|
case TRVT_DENY:
|
||||||
case TRVT_SPEED:
|
case TRVT_SPEED:
|
||||||
case TRVT_TILE_INDEX:
|
case TRVT_TILE_INDEX:
|
||||||
|
case TRVT_TILE_INDEX_THROUGH:
|
||||||
case TRVT_RESERVE_THROUGH:
|
case TRVT_RESERVE_THROUGH:
|
||||||
case TRVT_LONG_RESERVE:
|
case TRVT_LONG_RESERVE:
|
||||||
case TRVT_WEIGHT:
|
case TRVT_WEIGHT:
|
||||||
@@ -1547,6 +1557,7 @@ static uint32 GetDualInstructionInitialValue(TraceRestrictItem item)
|
|||||||
{
|
{
|
||||||
switch (GetTraceRestrictType(item)) {
|
switch (GetTraceRestrictType(item)) {
|
||||||
case TRIT_COND_PBS_ENTRY_SIGNAL:
|
case TRIT_COND_PBS_ENTRY_SIGNAL:
|
||||||
|
case TRIT_COND_RESERVATION_THROUGH:
|
||||||
return INVALID_TILE;
|
return INVALID_TILE;
|
||||||
|
|
||||||
case TRIT_COND_SLOT_OCCUPANCY:
|
case TRIT_COND_SLOT_OCCUPANCY:
|
||||||
|
@@ -154,6 +154,7 @@ enum TraceRestrictItemType {
|
|||||||
TRIT_COND_RESERVED_TILES = 29, ///< Test reserved tiles ahead of train
|
TRIT_COND_RESERVED_TILES = 29, ///< Test reserved tiles ahead of train
|
||||||
TRIT_COND_CATEGORY = 30, ///< Test train category
|
TRIT_COND_CATEGORY = 30, ///< Test train category
|
||||||
TRIT_COND_TARGET_DIRECTION = 31, ///< Test direction of order target tile relative to this signal tile
|
TRIT_COND_TARGET_DIRECTION = 31, ///< Test direction of order target tile relative to this signal tile
|
||||||
|
TRIT_COND_RESERVATION_THROUGH = 32, ///< Test if train reservation passes through tile
|
||||||
|
|
||||||
TRIT_COND_END = 48, ///< End (exclusive) of conditional item types, note that this has the same value as TRIT_REVERSE
|
TRIT_COND_END = 48, ///< End (exclusive) of conditional item types, note that this has the same value as TRIT_REVERSE
|
||||||
TRIT_REVERSE = 48, ///< Reverse behind signal
|
TRIT_REVERSE = 48, ///< Reverse behind signal
|
||||||
@@ -666,7 +667,8 @@ static inline bool IsTraceRestrictConditional(TraceRestrictItem item)
|
|||||||
static inline bool IsTraceRestrictDoubleItem(TraceRestrictItem item)
|
static inline bool IsTraceRestrictDoubleItem(TraceRestrictItem item)
|
||||||
{
|
{
|
||||||
const TraceRestrictItemType type = GetTraceRestrictType(item);
|
const TraceRestrictItemType type = GetTraceRestrictType(item);
|
||||||
return type == TRIT_COND_PBS_ENTRY_SIGNAL || type == TRIT_COND_SLOT_OCCUPANCY || type == TRIT_COUNTER || type == TRIT_COND_COUNTER_VALUE || type == TRIT_COND_TIME_DATE_VALUE;
|
return type == TRIT_COND_PBS_ENTRY_SIGNAL || type == TRIT_COND_SLOT_OCCUPANCY || type == TRIT_COUNTER ||
|
||||||
|
type == TRIT_COND_COUNTER_VALUE || type == TRIT_COND_TIME_DATE_VALUE || type == TRIT_COND_RESERVATION_THROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -717,6 +719,7 @@ enum TraceRestrictValueType {
|
|||||||
TRVT_SPEED_ADAPTATION_CONTROL = 48,///< takes a TraceRestrictSpeedAdaptationControlField
|
TRVT_SPEED_ADAPTATION_CONTROL = 48,///< takes a TraceRestrictSpeedAdaptationControlField
|
||||||
TRVT_SIGNAL_MODE_CONTROL = 49,///< takes a TraceRestrictSignalModeControlField
|
TRVT_SIGNAL_MODE_CONTROL = 49,///< takes a TraceRestrictSignalModeControlField
|
||||||
TRVT_ORDER_TARGET_DIAGDIR = 50,///< takes a DiagDirection, and the order type in the auxiliary field
|
TRVT_ORDER_TARGET_DIAGDIR = 50,///< takes a DiagDirection, and the order type in the auxiliary field
|
||||||
|
TRVT_TILE_INDEX_THROUGH = 51,///< takes a TileIndex in the next item slot (passes through)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -871,6 +874,11 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
|
|||||||
out.cond_type = TRCOT_BINARY;
|
out.cond_type = TRCOT_BINARY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRIT_COND_RESERVATION_THROUGH:
|
||||||
|
out.value_type = TRVT_TILE_INDEX_THROUGH;
|
||||||
|
out.cond_type = TRCOT_BINARY;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
|
@@ -589,6 +589,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
|||||||
STR_TRACE_RESTRICT_VARIABLE_RESERVED_TILES_AHEAD,
|
STR_TRACE_RESTRICT_VARIABLE_RESERVED_TILES_AHEAD,
|
||||||
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_TILE,
|
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_TILE,
|
||||||
STR_TRACE_RESTRICT_VARIABLE_ORDER_TARGET_DIRECTION,
|
STR_TRACE_RESTRICT_VARIABLE_ORDER_TARGET_DIRECTION,
|
||||||
|
STR_TRACE_RESTRICT_VARIABLE_RESERVATION_THROUGH,
|
||||||
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED,
|
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED,
|
||||||
INVALID_STRING_ID,
|
INVALID_STRING_ID,
|
||||||
};
|
};
|
||||||
@@ -620,6 +621,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
|||||||
TRIT_COND_RESERVED_TILES, // 0x1000000
|
TRIT_COND_RESERVED_TILES, // 0x1000000
|
||||||
TRIT_COND_PBS_ENTRY_SIGNAL | (TRPESAF_RES_END_TILE << 16),
|
TRIT_COND_PBS_ENTRY_SIGNAL | (TRPESAF_RES_END_TILE << 16),
|
||||||
TRIT_COND_TARGET_DIRECTION,
|
TRIT_COND_TARGET_DIRECTION,
|
||||||
|
TRIT_COND_RESERVATION_THROUGH,
|
||||||
TRIT_COND_UNDEFINED,
|
TRIT_COND_UNDEFINED,
|
||||||
};
|
};
|
||||||
static const TraceRestrictDropDownListSet set_cond = {
|
static const TraceRestrictDropDownListSet set_cond = {
|
||||||
@@ -631,7 +633,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
|||||||
if (_settings_client.gui.show_adv_tracerestrict_features) {
|
if (_settings_client.gui.show_adv_tracerestrict_features) {
|
||||||
*hide_mask = 0;
|
*hide_mask = 0;
|
||||||
} else {
|
} else {
|
||||||
*hide_mask = is_conditional ? 0x1FE0000 : 0xEF0;
|
*hide_mask = is_conditional ? 0x9FE0000 : 0xEF0;
|
||||||
}
|
}
|
||||||
if (is_conditional && _settings_game.vehicle.train_braking_model != TBM_REALISTIC) *hide_mask |= 0x1040000;
|
if (is_conditional && _settings_game.vehicle.train_braking_model != TBM_REALISTIC) *hide_mask |= 0x1040000;
|
||||||
if (!is_conditional && !_settings_game.vehicle.train_speed_adaptation) *hide_mask |= 0x800;
|
if (!is_conditional && !_settings_game.vehicle.train_speed_adaptation) *hide_mask |= 0x800;
|
||||||
@@ -828,6 +830,20 @@ static const TraceRestrictDropDownListSet _train_status_cond_ops = {
|
|||||||
_train_status_cond_ops_str, _train_status_cond_ops_val,
|
_train_status_cond_ops_str, _train_status_cond_ops_val,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const StringID _passes_through_cond_ops_str[] = {
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_PASS,
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_DOESNT_PASS,
|
||||||
|
INVALID_STRING_ID,
|
||||||
|
};
|
||||||
|
static const uint _passes_through_cond_ops_val[] = {
|
||||||
|
TRCO_IS,
|
||||||
|
TRCO_ISNOT,
|
||||||
|
};
|
||||||
|
/** passes through conditional operators dropdown list set */
|
||||||
|
static const TraceRestrictDropDownListSet _passes_through_cond_ops = {
|
||||||
|
_passes_through_cond_ops_str, _passes_through_cond_ops_val,
|
||||||
|
};
|
||||||
|
|
||||||
static const StringID _slot_op_cond_ops_str[] = {
|
static const StringID _slot_op_cond_ops_str[] = {
|
||||||
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT,
|
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT,
|
||||||
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE,
|
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE,
|
||||||
@@ -930,6 +946,7 @@ static const TraceRestrictDropDownListSet *GetCondOpDropDownListSet(TraceRestric
|
|||||||
if (properties.value_type == TRVT_CARGO_ID) return &_cargo_cond_ops;
|
if (properties.value_type == TRVT_CARGO_ID) return &_cargo_cond_ops;
|
||||||
if (properties.value_type == TRVT_TRAIN_STATUS) return &_train_status_cond_ops;
|
if (properties.value_type == TRVT_TRAIN_STATUS) return &_train_status_cond_ops;
|
||||||
if (properties.value_type == TRVT_ENGINE_CLASS) return &_train_status_cond_ops;
|
if (properties.value_type == TRVT_ENGINE_CLASS) return &_train_status_cond_ops;
|
||||||
|
if (properties.value_type == TRVT_TILE_INDEX_THROUGH) return &_passes_through_cond_ops;
|
||||||
|
|
||||||
switch (properties.cond_type) {
|
switch (properties.cond_type) {
|
||||||
case TRCOT_NONE:
|
case TRCOT_NONE:
|
||||||
@@ -1334,6 +1351,23 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TRVT_TILE_INDEX_THROUGH: {
|
||||||
|
assert(prog != nullptr);
|
||||||
|
assert(GetTraceRestrictType(item) == TRIT_COND_RESERVATION_THROUGH);
|
||||||
|
TileIndex tile = *(TraceRestrictProgram::InstructionAt(prog->items, index - 1) + 1);
|
||||||
|
if (tile == INVALID_TILE) {
|
||||||
|
DrawInstructionStringConditionalInvalidValue(item, properties, instruction_string, selected);
|
||||||
|
} else {
|
||||||
|
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_PASSES_TILE_INDEX;
|
||||||
|
SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]);
|
||||||
|
SetDParam(2, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item)));
|
||||||
|
SetDParam(3, TileX(tile));
|
||||||
|
SetDParam(4, TileY(tile));
|
||||||
|
}
|
||||||
|
SetDParam(1, STR_TRACE_RESTRICT_VARIABLE_RESERVATION_THROUGH_SHORT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TRVT_GROUP_INDEX: {
|
case TRVT_GROUP_INDEX: {
|
||||||
assert(GetTraceRestrictCondFlags(item) <= TRCF_OR);
|
assert(GetTraceRestrictCondFlags(item) <= TRCF_OR);
|
||||||
SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]);
|
SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]);
|
||||||
@@ -1792,7 +1826,8 @@ public:
|
|||||||
if (sel == -1) return;
|
if (sel == -1) return;
|
||||||
|
|
||||||
TraceRestrictItem item = this->GetItem(this->GetProgram(), sel);
|
TraceRestrictItem item = this->GetItem(this->GetProgram(), sel);
|
||||||
if (GetTraceRestrictTypeProperties(item).value_type == TRVT_ORDER) {
|
TraceRestrictValueType val_type = GetTraceRestrictTypeProperties(item).value_type;
|
||||||
|
if (val_type == TRVT_ORDER) {
|
||||||
switch (static_cast<TraceRestrictOrderCondAuxField>(GetTraceRestrictAuxField(item))) {
|
switch (static_cast<TraceRestrictOrderCondAuxField>(GetTraceRestrictAuxField(item))) {
|
||||||
case TROCAF_STATION:
|
case TROCAF_STATION:
|
||||||
case TROCAF_WAYPOINT: {
|
case TROCAF_WAYPOINT: {
|
||||||
@@ -1811,7 +1846,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (GetTraceRestrictTypeProperties(item).value_type == TRVT_TILE_INDEX) {
|
} else if (val_type == TRVT_TILE_INDEX || val_type == TRVT_TILE_INDEX_THROUGH) {
|
||||||
TileIndex tile = *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, sel - 1) + 1);
|
TileIndex tile = *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, sel - 1) + 1);
|
||||||
if (tile != INVALID_TILE) {
|
if (tile != INVALID_TILE) {
|
||||||
ScrollMainWindowToTile(tile);
|
ScrollMainWindowToTile(tile);
|
||||||
@@ -2469,7 +2504,8 @@ public:
|
|||||||
void OnPlaceObjectSignalTileValue(Point pt, TileIndex tile, int widget, int error_message)
|
void OnPlaceObjectSignalTileValue(Point pt, TileIndex tile, int widget, int error_message)
|
||||||
{
|
{
|
||||||
TraceRestrictItem item = GetSelected();
|
TraceRestrictItem item = GetSelected();
|
||||||
if (GetTraceRestrictTypeProperties(item).value_type != TRVT_TILE_INDEX) return;
|
TraceRestrictValueType val_type = GetTraceRestrictTypeProperties(item).value_type;
|
||||||
|
if (val_type != TRVT_TILE_INDEX && val_type != TRVT_TILE_INDEX_THROUGH) return;
|
||||||
|
|
||||||
if (!IsInfraTileUsageAllowed(VEH_TRAIN, _local_company, tile)) {
|
if (!IsInfraTileUsageAllowed(VEH_TRAIN, _local_company, tile)) {
|
||||||
ShowErrorMessage(error_message, STR_ERROR_AREA_IS_OWNED_BY_ANOTHER, WL_INFO);
|
ShowErrorMessage(error_message, STR_ERROR_AREA_IS_OWNED_BY_ANOTHER, WL_INFO);
|
||||||
@@ -2501,7 +2537,8 @@ public:
|
|||||||
void OnPlaceObjectTileValue(Point pt, TileIndex tile, int widget, int error_message)
|
void OnPlaceObjectTileValue(Point pt, TileIndex tile, int widget, int error_message)
|
||||||
{
|
{
|
||||||
TraceRestrictItem item = GetSelected();
|
TraceRestrictItem item = GetSelected();
|
||||||
if (GetTraceRestrictTypeProperties(item).value_type != TRVT_TILE_INDEX) return;
|
TraceRestrictValueType val_type = GetTraceRestrictTypeProperties(item).value_type;
|
||||||
|
if (val_type != TRVT_TILE_INDEX && val_type != TRVT_TILE_INDEX_THROUGH) return;
|
||||||
|
|
||||||
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, tile, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, tile, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||||
}
|
}
|
||||||
@@ -3030,6 +3067,11 @@ private:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRVT_TILE_INDEX_THROUGH:
|
||||||
|
right_sel->SetDisplayedPlane(DPR_VALUE_TILE);
|
||||||
|
this->EnableWidget(TR_WIDGET_VALUE_TILE);
|
||||||
|
break;
|
||||||
|
|
||||||
case TRVT_PF_PENALTY:
|
case TRVT_PF_PENALTY:
|
||||||
right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN);
|
right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN);
|
||||||
this->EnableWidget(TR_WIDGET_VALUE_DROPDOWN);
|
this->EnableWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||||
|
Reference in New Issue
Block a user