mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Use result structure for ChooseTrainTrack
This commit is contained in:
parent
a0dbd04e34
commit
ff89547280
@ -80,10 +80,22 @@ enum ChooseTrainTrackFlags {
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(ChooseTrainTrackFlags)
|
||||
|
||||
/** Result flags for ChooseTrainTrack */
|
||||
enum ChooseTrainTrackResultFlags {
|
||||
CTTRF_NONE = 0, ///< No flags
|
||||
CTTRF_RESERVATION_MADE = 0x01, ///< A reservation was made
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(ChooseTrainTrackResultFlags)
|
||||
|
||||
struct ChooseTrainTrackResult {
|
||||
Track track;
|
||||
ChooseTrainTrackResultFlags ctt_flags;
|
||||
};
|
||||
|
||||
btree::btree_map<SignalSpeedKey, SignalSpeedValue> _signal_speeds;
|
||||
|
||||
static void TryLongReserveChooseTrainTrackFromReservationEnd(Train *v, bool no_reserve_vehicle_tile = false);
|
||||
static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, ChooseTrainTrackFlags flags, bool *p_got_reservation, ChooseTrainTrackLookAheadState lookahead_state = {});
|
||||
static ChooseTrainTrackResult ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, ChooseTrainTrackFlags flags, ChooseTrainTrackLookAheadState lookahead_state = {});
|
||||
static bool TrainApproachingLineEnd(Train *v, bool signal, bool reverse);
|
||||
static bool TrainCheckIfLineEnds(Train *v, bool reverse = true);
|
||||
static bool TrainCanLeaveTile(const Train *v);
|
||||
@ -3385,7 +3397,7 @@ static void CheckNextTrainTile(Train *v)
|
||||
if (ft.m_tiles_skipped == 0 && Rail90DegTurnDisallowedTilesFromTrackdir(ft.m_old_tile, ft.m_new_tile, ft.m_old_td)) {
|
||||
tracks &= ~TrackCrossesTracks(TrackdirToTrack(ft.m_old_td));
|
||||
}
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, tracks, CTTF_NONE, nullptr);
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, tracks, CTTF_NONE);
|
||||
}
|
||||
}
|
||||
} else if (v->lookahead != nullptr && v->lookahead->reservation_end_tile == ft.m_new_tile && IsTileType(ft.m_new_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationEntrance(ft.m_new_tile) &&
|
||||
@ -4339,7 +4351,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
|
||||
}
|
||||
SetTunnelBridgeExitSignalState(exit_tile, SIGNAL_STATE_GREEN);
|
||||
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), nullptr, lookahead_state);
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), lookahead_state);
|
||||
|
||||
if (reserved_bits == GetReservedTrackbits(ft.m_new_tile)) {
|
||||
/* next tile is still not reserved, so unreserve exit and restore signal state */
|
||||
@ -4364,7 +4376,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
|
||||
CFollowTrackRail ft(v);
|
||||
if (ft.Follow(tile, td) && HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits), !long_enough, lookahead_state.flags)) {
|
||||
// We reserved up to a LR signal, reserve past it as well. recursion
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), nullptr, lookahead_state);
|
||||
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), lookahead_state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4397,10 +4409,9 @@ static void TryLongReserveChooseTrainTrackFromReservationEnd(Train *v, bool no_r
|
||||
* @param enterdir
|
||||
* @param tracks
|
||||
* @param flags ChooseTrainTrackFlags flags
|
||||
* @param got_reservation [out] If the train has a reservation
|
||||
* @return The track the train should take.
|
||||
* @return The track the train should take and the result flags
|
||||
*/
|
||||
static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, ChooseTrainTrackFlags flags, bool *p_got_reservation, ChooseTrainTrackLookAheadState lookahead_state)
|
||||
static ChooseTrainTrackResult ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, ChooseTrainTrackFlags flags, ChooseTrainTrackLookAheadState lookahead_state)
|
||||
{
|
||||
Track best_track = INVALID_TRACK;
|
||||
bool do_track_reservation = _settings_game.pf.reserve_paths || (flags & CTTF_FORCE_RES);
|
||||
@ -4409,13 +4420,12 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
|
||||
dbg_assert((tracks & ~TRACK_BIT_MASK) == 0);
|
||||
|
||||
bool got_reservation = false;
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = got_reservation;
|
||||
ChooseTrainTrackResultFlags result_flags = CTTRF_NONE;
|
||||
|
||||
/* Don't use tracks here as the setting to forbid 90 deg turns might have been switched between reservation and now. */
|
||||
TrackBits res_tracks = (TrackBits)(GetReservedTrackbits(tile) & DiagdirReachesTracks(enterdir));
|
||||
/* Do we have a suitable reserved track? */
|
||||
if (res_tracks != TRACK_BIT_NONE) return FindFirstTrack(res_tracks);
|
||||
if (res_tracks != TRACK_BIT_NONE) return { FindFirstTrack(res_tracks), result_flags };
|
||||
|
||||
bool mark_stuck = (flags & CTTF_MARK_STUCK);
|
||||
|
||||
@ -4436,7 +4446,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
}
|
||||
if (out.flags & TRPRF_WAIT_AT_PBS) {
|
||||
if (mark_stuck) MarkTrainAsStuck(v, true);
|
||||
return track;
|
||||
return { track, result_flags };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4450,7 +4460,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
UpdateAspectDeferredWithVehicle(v, tile, changed_signal, true);
|
||||
}
|
||||
} else if (!do_track_reservation) {
|
||||
return track;
|
||||
return { track, result_flags };
|
||||
}
|
||||
best_track = track;
|
||||
}
|
||||
@ -4482,7 +4492,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
/* Reservation failed? */
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
if (changed_signal != INVALID_TRACKDIR) SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_RED);
|
||||
return FindFirstTrack(tracks);
|
||||
return { FindFirstTrack(tracks), result_flags };
|
||||
}
|
||||
if (res_dest.okay) {
|
||||
if (temporary_slot_state.IsActive()) temporary_slot_state.PopFromChangeStackApplyTemporaryChanges(v);
|
||||
@ -4497,11 +4507,11 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
|
||||
if (!long_reserve) {
|
||||
/* Got a valid reservation that ends at a safe target, quick exit. */
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = true;
|
||||
result_flags |= CTTRF_RESERVATION_MADE;
|
||||
if (changed_signal != INVALID_TRACKDIR) MarkSingleSignalDirty(tile, changed_signal);
|
||||
if (!HasBit(lookahead_state.flags, CTTLASF_NO_RES_VEH_TILE)) TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) FillTrainReservationLookAhead(v);
|
||||
return best_track;
|
||||
return { best_track, result_flags };
|
||||
}
|
||||
}
|
||||
|
||||
@ -4536,13 +4546,13 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
}
|
||||
|
||||
/* No track reservation requested -> finished. */
|
||||
if (!do_track_reservation) return best_track;
|
||||
if (!do_track_reservation) return { best_track, result_flags };
|
||||
|
||||
/* A path was found, but could not be reserved. */
|
||||
if (res_dest.tile != INVALID_TILE && !res_dest.okay) {
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
return best_track;
|
||||
return { best_track, result_flags };
|
||||
}
|
||||
|
||||
/* No possible reservation target found, we are probably lost. */
|
||||
@ -4554,17 +4564,17 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
TrackBits res = GetReservedTrackbits(tile) & DiagdirReachesTracks(enterdir);
|
||||
best_track = FindFirstTrack(res);
|
||||
if (!HasBit(lookahead_state.flags, CTTLASF_NO_RES_VEH_TILE)) TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = true;
|
||||
result_flags |= CTTRF_RESERVATION_MADE;
|
||||
if (changed_signal != INVALID_TRACKDIR) MarkSingleSignalDirty(tile, changed_signal);
|
||||
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) FillTrainReservationLookAhead(v);
|
||||
} else {
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
}
|
||||
return best_track;
|
||||
return { best_track, result_flags };;
|
||||
}
|
||||
|
||||
got_reservation = true;
|
||||
result_flags |= CTTRF_RESERVATION_MADE;
|
||||
|
||||
auto check_destination_seen = [&](TileIndex tile) {
|
||||
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && v->current_order.IsBaseStationOrder() &&
|
||||
@ -4606,7 +4616,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
/* Path found, but could not be reserved. */
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
got_reservation = false;
|
||||
result_flags &= ~CTTRF_RESERVATION_MADE;
|
||||
changed_signal = INVALID_TRACKDIR;
|
||||
if (temporary_slot_state.IsActive()) temporary_slot_state.PopFromChangeStackRevertTemporaryChanges(v->index);
|
||||
break;
|
||||
@ -4616,14 +4626,14 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
if (!TryReserveSafeTrack(v, res_dest.tile, res_dest.trackdir, true)) {
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
got_reservation = false;
|
||||
result_flags &= ~CTTRF_RESERVATION_MADE;
|
||||
changed_signal = INVALID_TRACKDIR;
|
||||
if (temporary_slot_state.IsActive()) temporary_slot_state.PopFromChangeStackRevertTemporaryChanges(v->index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (got_reservation) {
|
||||
if (result_flags & CTTRF_RESERVATION_MADE) {
|
||||
if (temporary_slot_state.IsActive()) temporary_slot_state.PopFromChangeStackApplyTemporaryChanges(v);
|
||||
if (v->current_order.IsBaseStationOrder() && HasStationTileRail(res_dest.tile) && v->current_order.GetDestination() == GetStationIndex(res_dest.tile)) {
|
||||
if (v->current_order.ShouldStopAtStation(v, v->current_order.GetDestination(), v->current_order.IsType(OT_GOTO_WAYPOINT))) {
|
||||
@ -4641,7 +4651,6 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
if (!HasBit(lookahead_state.flags, CTTLASF_NO_RES_VEH_TILE)) TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
|
||||
if (changed_signal != INVALID_TRACKDIR) MarkSingleSignalDirty(tile, changed_signal);
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = got_reservation;
|
||||
|
||||
orders.Restore();
|
||||
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
|
||||
@ -4652,7 +4661,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
||||
}
|
||||
|
||||
return best_track;
|
||||
return { best_track, result_flags };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4760,7 +4769,8 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
||||
|
||||
bool res_made = false;
|
||||
if (reachable != TRACK_BIT_NONE) {
|
||||
ChooseTrainTrack(v, new_tile, exitdir, reachable, CTTF_FORCE_RES | (mark_as_stuck ? CTTF_MARK_STUCK : CTTF_NONE), &res_made);
|
||||
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 (!res_made) {
|
||||
@ -5672,7 +5682,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
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, nullptr));
|
||||
chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits, CTTF_MARK_STUCK | CTTF_NON_LOOKAHEAD).track);
|
||||
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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user