mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Tracerestrict: Add reverse at PBS signal sub-action
This commit is contained in:
parent
0c3d1e1aac
commit
5b9ed03823
@ -1025,6 +1025,8 @@ STR_TRACE_RESTRICT_TRAIN_STATUS_REQUIRES_SERVICE :requires servic
|
||||
STR_TRACE_RESTRICT_TRAIN_STATUS_STOPPING_AT_STATION_WAYPOINT :stopping at station/waypoint
|
||||
STR_TRACE_RESTRICT_REVERSE_SIG :Reverse behind signal
|
||||
STR_TRACE_RESTRICT_REVERSE_SIG_CANCEL :Cancel reverse behind signal
|
||||
STR_TRACE_RESTRICT_REVERSE_AT_SIG :Reverse at PBS signal
|
||||
STR_TRACE_RESTRICT_REVERSE_AT_SIG_CANCEL :Cancel reverse at PBS signal
|
||||
STR_TRACE_RESTRICT_SET_SPEED_RESTRICTION :Restrict train speed to: {VELOCITY}
|
||||
STR_TRACE_RESTRICT_REMOVE_SPEED_RESTRICTION :Remove train speed restriction
|
||||
STR_TRACE_RESTRICT_TRAIN_NOT_STUCK :Train is not stuck, do not show news reports about waiting at this PBS signal
|
||||
|
@ -80,7 +80,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ 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_STATUSCND, XSCF_NULL, 2, 2, "tracerestrict_status_cond", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_REVERSE, XSCF_NULL, 1, 1, "tracerestrict_reverse", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_REVERSE, XSCF_NULL, 2, 2, "tracerestrict_reverse", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_NEWSCTRL, XSCF_NULL, 1, 1, "tracerestrict_newsctrl", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_COUNTER, XSCF_NULL, 1, 1, "tracerestrict_counter", nullptr, nullptr, "TRRC" },
|
||||
{ XSLFI_TRACE_RESTRICT_TIMEDATE, XSCF_NULL, 2, 2, "tracerestrict_timedate", nullptr, nullptr, nullptr },
|
||||
|
@ -2279,6 +2279,7 @@ class NIHTraceRestrict : public NIHelper {
|
||||
CA(RESERVE_THROUGH_ALWAYS)
|
||||
CA(CMB_SIGNAL_MODE_CTRL)
|
||||
CA(ORDER_CONDITIONALS)
|
||||
CA(REVERSE_AT)
|
||||
#undef CA
|
||||
output.print("");
|
||||
|
||||
|
@ -804,6 +804,13 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
||||
case TRRVF_CANCEL_REVERSE_BEHIND:
|
||||
out.flags &= ~TRPRF_REVERSE_BEHIND;
|
||||
break;
|
||||
|
||||
case TRRVF_REVERSE_AT:
|
||||
out.flags |= TRPRF_REVERSE_AT;
|
||||
break;
|
||||
|
||||
case TRRVF_CANCEL_REVERSE_AT:
|
||||
out.flags &= ~TRPRF_REVERSE_AT;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1410,6 +1417,14 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
||||
if (condstack.empty()) actions_used_flags &= ~TRPAUF_REVERSE_BEHIND;
|
||||
break;
|
||||
|
||||
case TRRVF_REVERSE_AT:
|
||||
actions_used_flags |= TRPAUF_REVERSE_AT;
|
||||
break;
|
||||
|
||||
case TRRVF_CANCEL_REVERSE_AT:
|
||||
if (condstack.empty()) actions_used_flags &= ~TRPAUF_REVERSE_AT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return unknown_instruction();
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ enum TraceRestrictItemType : uint8_t {
|
||||
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_REVERSE = 48, ///< Reverse behind signal
|
||||
TRIT_REVERSE = 48, ///< Reverse behind/at signal
|
||||
TRIT_SPEED_RESTRICTION = 49, ///< Speed restriction
|
||||
TRIT_NEWS_CONTROL = 50, ///< News control
|
||||
TRIT_COUNTER = 51, ///< Change counter value
|
||||
@ -312,6 +312,8 @@ enum TraceRestrictWaitAtPbsValueField : uint8_t {
|
||||
enum TraceRestrictReverseValueField : uint8_t {
|
||||
TRRVF_REVERSE_BEHIND = 0, ///< Reverse behind signal
|
||||
TRRVF_CANCEL_REVERSE_BEHIND = 1, ///< Cancel reverse behind signal
|
||||
TRRVF_REVERSE_AT = 2, ///< Reverse at PBS signal
|
||||
TRRVF_CANCEL_REVERSE_AT = 3, ///< Cancel reverse at PBS signal
|
||||
};
|
||||
|
||||
/**
|
||||
@ -448,6 +450,7 @@ enum TraceRestrictProgramResultFlags : uint16_t {
|
||||
TRPRF_RM_SPEED_ADAPT_EXEMPT = 1 << 10, ///< Remove speed adaptation exemption
|
||||
TRPRF_SIGNAL_MODE_NORMAL = 1 << 11, ///< Combined normal/shunt signal mode control: normal
|
||||
TRPRF_SIGNAL_MODE_SHUNT = 1 << 12, ///< Combined normal/shunt signal mode control: shunt
|
||||
TRPRF_REVERSE_AT = 1 << 13, ///< Reverse at PBS signal is set
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
|
||||
|
||||
@ -476,6 +479,7 @@ enum TraceRestrictProgramActionsUsedFlags : uint32_t {
|
||||
TRPAUF_RESERVE_THROUGH_ALWAYS = 1 << 17, ///< Reserve through action is unconditionally set
|
||||
TRPAUF_CMB_SIGNAL_MODE_CTRL = 1 << 18, ///< Combined normal/shunt signal mode control
|
||||
TRPAUF_ORDER_CONDITIONALS = 1 << 19, ///< Order conditionals are present
|
||||
TRPAUF_REVERSE_AT = 1 << 20, ///< Reverse at signal
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
|
||||
|
||||
|
@ -335,10 +335,14 @@ static const TraceRestrictDropDownListSet _train_status_value = {
|
||||
static const StringID _reverse_value_str[] = {
|
||||
STR_TRACE_RESTRICT_REVERSE_SIG,
|
||||
STR_TRACE_RESTRICT_REVERSE_SIG_CANCEL,
|
||||
STR_TRACE_RESTRICT_REVERSE_AT_SIG,
|
||||
STR_TRACE_RESTRICT_REVERSE_AT_SIG_CANCEL,
|
||||
};
|
||||
static const uint _reverse_value_val[] = {
|
||||
TRRVF_REVERSE_BEHIND,
|
||||
TRRVF_CANCEL_REVERSE_BEHIND,
|
||||
TRRVF_REVERSE_AT,
|
||||
TRRVF_CANCEL_REVERSE_AT,
|
||||
};
|
||||
|
||||
/** value drop down list for reverse types strings and values */
|
||||
@ -1614,6 +1618,14 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
|
||||
instruction_string = STR_TRACE_RESTRICT_REVERSE_SIG_CANCEL;
|
||||
break;
|
||||
|
||||
case TRRVF_REVERSE_AT:
|
||||
instruction_string = STR_TRACE_RESTRICT_REVERSE_AT_SIG;
|
||||
break;
|
||||
|
||||
case TRRVF_CANCEL_REVERSE_AT:
|
||||
instruction_string = STR_TRACE_RESTRICT_REVERSE_AT_SIG_CANCEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
|
@ -86,6 +86,7 @@ void FreeTrainTrackReservation(Train *v, TileIndex origin = INVALID_TILE, Trackd
|
||||
enum TryPathReserveResultFlags {
|
||||
TPRRF_NONE = 0, ///< No flags
|
||||
TPRRF_RESERVATION_OK = 0x01, ///< Reservation OK
|
||||
TPRRF_REVERSE_AT_SIGNAL = 0x02, ///< Reverse at signal
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TryPathReserveResultFlags)
|
||||
|
||||
|
@ -84,6 +84,7 @@ DECLARE_ENUM_AS_BIT_SET(ChooseTrainTrackFlags)
|
||||
enum ChooseTrainTrackResultFlags {
|
||||
CTTRF_NONE = 0, ///< No flags
|
||||
CTTRF_RESERVATION_MADE = 0x01, ///< A reservation was made
|
||||
CTTRF_REVERSE_AT_SIGNAL = 0x02, ///< Reverse at signal
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(ChooseTrainTrackResultFlags)
|
||||
|
||||
@ -4329,12 +4330,12 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
|
||||
long_reserve = (out.flags & TRPRF_LONG_RESERVE);
|
||||
}
|
||||
if (!long_reserve) return;
|
||||
if (prog != nullptr && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE)) {
|
||||
if (prog != nullptr && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE | TRPAUF_REVERSE_AT)) {
|
||||
TraceRestrictProgramResult out;
|
||||
TraceRestrictProgramInput input(exit_tile, exit_td, nullptr, nullptr);
|
||||
input.permitted_slot_operations = TRPISP_ACQUIRE;
|
||||
prog->Execute(v, input, out);
|
||||
if (out.flags & TRPRF_WAIT_AT_PBS) {
|
||||
if (out.flags & (TRPRF_WAIT_AT_PBS | TRPRF_REVERSE_AT)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4436,7 +4437,7 @@ static ChooseTrainTrackResult ChooseTrainTrack(Train *v, TileIndex tile, DiagDir
|
||||
if (track != INVALID_TRACK && HasPbsSignalOnTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir)) && !IsNoEntrySignal(tile, track)) {
|
||||
if (IsRestrictedSignal(tile) && v->force_proceed != TFP_SIGNAL) {
|
||||
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, track);
|
||||
if (prog != nullptr && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE | TRPAUF_TRAIN_NOT_STUCK)) {
|
||||
if (prog != nullptr && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE | TRPAUF_TRAIN_NOT_STUCK | TRPAUF_REVERSE_AT)) {
|
||||
TraceRestrictProgramResult out;
|
||||
TraceRestrictProgramInput input(tile, TrackEnterdirToTrackdir(track, enterdir), nullptr, nullptr);
|
||||
input.permitted_slot_operations = TRPISP_ACQUIRE;
|
||||
@ -4444,7 +4445,10 @@ static ChooseTrainTrackResult ChooseTrainTrack(Train *v, TileIndex tile, DiagDir
|
||||
if (out.flags & TRPRF_TRAIN_NOT_STUCK && !(v->track & TRACK_BIT_WORMHOLE) && !(v->track == TRACK_BIT_DEPOT)) {
|
||||
v->wait_counter = 0;
|
||||
}
|
||||
if (out.flags & TRPRF_WAIT_AT_PBS) {
|
||||
if (out.flags & TRPRF_REVERSE_AT) {
|
||||
result_flags |= CTTRF_REVERSE_AT_SIGNAL;
|
||||
}
|
||||
if (out.flags & (TRPRF_WAIT_AT_PBS | TRPRF_REVERSE_AT)) {
|
||||
if (mark_stuck) MarkTrainAsStuck(v, true);
|
||||
return { track, result_flags };
|
||||
}
|
||||
@ -4672,7 +4676,7 @@ static ChooseTrainTrackResult ChooseTrainTrack(Train *v, TileIndex tile, DiagDir
|
||||
* @param first_tile_okay True if no path should be reserved if the current tile is a safe position.
|
||||
* @return Result flags.
|
||||
*/
|
||||
TryPathReserveResultFlags TryPathReserveResultFlags(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
||||
TryPathReserveResultFlags TryPathReserveWithResultFlags(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
||||
{
|
||||
dbg_assert(v->IsFrontEngine());
|
||||
|
||||
@ -4767,16 +4771,20 @@ TryPathReserveResultFlags TryPathReserveResultFlags(Train *v, bool mark_as_stuck
|
||||
|
||||
if (Rail90DegTurnDisallowedTilesFromDiagDir(origin.tile, new_tile, exitdir)) reachable &= ~TrackCrossesTracks(TrackdirToTrack(origin.trackdir));
|
||||
|
||||
bool res_made = false;
|
||||
TryPathReserveResultFlags result_flags = TPRRF_NONE;
|
||||
if (reachable != TRACK_BIT_NONE) {
|
||||
ChooseTrainTrackResult result = ChooseTrainTrack(v, new_tile, exitdir, reachable, CTTF_FORCE_RES | (mark_as_stuck ? CTTF_MARK_STUCK : CTTF_NONE));
|
||||
if (result.ctt_flags & CTTRF_RESERVATION_MADE) res_made = true;
|
||||
if (result.ctt_flags & CTTRF_RESERVATION_MADE) {
|
||||
result_flags |= TPRRF_RESERVATION_OK;
|
||||
} else if (result.ctt_flags & CTTRF_REVERSE_AT_SIGNAL) {
|
||||
result_flags |= TPRRF_REVERSE_AT_SIGNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res_made) {
|
||||
if ((result_flags & TPRRF_RESERVATION_OK) == 0) {
|
||||
/* Free the depot reservation as well. */
|
||||
if (v->track == TRACK_BIT_DEPOT && v->tile == origin.tile) SetDepotReservation(v->tile, false);
|
||||
return false;
|
||||
return result_flags;
|
||||
}
|
||||
|
||||
if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
||||
@ -4785,7 +4793,7 @@ TryPathReserveResultFlags TryPathReserveResultFlags(Train *v, bool mark_as_stuck
|
||||
}
|
||||
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
||||
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) FillTrainReservationLookAhead(v);
|
||||
return true;
|
||||
return result_flags;
|
||||
}
|
||||
|
||||
|
||||
@ -5679,10 +5687,13 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
if (!CheckCompatibleRail(v, gp.new_tile, enterdir)) goto invalid_rail;
|
||||
|
||||
TrackBits chosen_track;
|
||||
bool reverse_at_signal = false;
|
||||
if (prev == nullptr) {
|
||||
/* Currently the locomotive is active. Determine which one of the
|
||||
* available tracks to choose */
|
||||
chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits, CTTF_MARK_STUCK | CTTF_NON_LOOKAHEAD).track);
|
||||
ChooseTrainTrackResult result = ChooseTrainTrack(v, gp.new_tile, enterdir, bits, CTTF_MARK_STUCK | CTTF_NON_LOOKAHEAD);
|
||||
chosen_track = TrackToTrackBits(result.track);
|
||||
reverse_at_signal = (result.ctt_flags & CTTRF_REVERSE_AT_SIGNAL);
|
||||
dbg_assert_msg_tile(chosen_track & (bits | GetReservedTrackbits(gp.new_tile)), gp.new_tile, "0x%X, 0x%X, 0x%X", chosen_track, bits, GetReservedTrackbits(gp.new_tile));
|
||||
|
||||
if (v->force_proceed != TFP_NONE && IsPlainRailTile(gp.new_tile) && HasSignals(gp.new_tile)) {
|
||||
@ -5706,6 +5717,11 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
/* In front of a red signal */
|
||||
Trackdir i = FindFirstTrackdir(trackdirbits);
|
||||
|
||||
if (reverse_at_signal) {
|
||||
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
||||
goto reverse_train_direction;
|
||||
}
|
||||
|
||||
/* Don't handle stuck trains here. */
|
||||
if (HasBit(v->flags, VRF_TRAIN_STUCK)) return false;
|
||||
|
||||
@ -6706,9 +6722,10 @@ static bool TrainLocoHandler(Train *v, bool mode)
|
||||
bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.reverse_at_signals;
|
||||
|
||||
if (!turn_around && v->wait_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == TFP_NONE) return true;
|
||||
if (!TryPathReserve(v)) {
|
||||
TryPathReserveResultFlags path_result = TryPathReserveWithResultFlags(v);
|
||||
if ((path_result & TPRRF_RESERVATION_OK) == 0) {
|
||||
/* Still stuck. */
|
||||
if (turn_around) ReverseTrainDirection(v);
|
||||
if (turn_around || (path_result & TPRRF_REVERSE_AT_SIGNAL)) ReverseTrainDirection(v);
|
||||
|
||||
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) {
|
||||
/* Show message to player. */
|
||||
|
Loading…
Reference in New Issue
Block a user