diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp index 042ccf9275..b3d4af8eac 100644 --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.hpp @@ -154,16 +154,26 @@ public: inline int ReservationCost(Node &n, TileIndex tile, Trackdir trackdir, int skipped) { if (n.m_num_signals_passed >= m_sig_look_ahead_costs.size() / 2) return 0; - if (!IsPbsSignal(n.m_last_signal_type)) return 0; - - if (IsRailStationTile(tile) && IsAnyStationTileReserved(tile, trackdir, skipped)) { - return Yapf().PfGetSettings().rail_pbs_station_penalty * (skipped + 1); - } else if (TrackOverlapsTracks(GetReservedTrackbits(tile), TrackdirToTrack(trackdir))) { - int cost = Yapf().PfGetSettings().rail_pbs_cross_penalty; - if (!IsDiagonalTrackdir(trackdir)) cost = (cost * YAPF_TILE_CORNER_LENGTH) / YAPF_TILE_LENGTH; - return cost * (skipped + 1); + if(!IsPbsSignal(n.m_last_signal_type)) { + n.flags_u.flags_s.m_last_was_reserved = false; + return 0; } - return 0; + + bool station_reservation = IsRailStationTile(tile) && IsAnyStationTileReserved(tile, trackdir, skipped); + bool reservation = TrackOverlapsTracks(GetReservedTrackbits(tile), TrackdirToTrack(trackdir)); + int cost = 0; + + /* only apply the cost once per reserved segment */ + if(!n.flags_u.flags_s.m_last_was_reserved) { + if (station_reservation) { + cost = Yapf().PfGetSettings().rail_pbs_station_penalty; + } else if (reservation) { + cost = Yapf().PfGetSettings().rail_pbs_cross_penalty; + } + } + + n.flags_u.flags_s.m_last_was_reserved = station_reservation | reservation; + return cost; } int SignalCost(Node &n, TileIndex tile, Trackdir trackdir) diff --git a/src/pathfinder/yapf/yapf_node_rail.hpp b/src/pathfinder/yapf/yapf_node_rail.hpp index 8aa517e042..f045414464 100644 --- a/src/pathfinder/yapf/yapf_node_rail.hpp +++ b/src/pathfinder/yapf/yapf_node_rail.hpp @@ -130,6 +130,7 @@ struct CYapfRailNodeT bool m_targed_seen : 1; bool m_choice_seen : 1; bool m_last_signal_was_red : 1; + bool m_last_was_reserved : 1; } flags_s; } flags_u; SignalType m_last_red_signal_type; diff --git a/src/settings.cpp b/src/settings.cpp index 4d8134f267..56321e423c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -162,6 +162,7 @@ enum IniFileVersion : uint32_t { IFV_NETWORK_PRIVATE_SETTINGS, ///< 4 PR#10762 Move no_http_content_downloads / use_relay_service to private settings. IFV_AUTOSAVE_RENAME, ///< 5 PR#11143 Renamed values of autosave to be in minutes. IFV_RIGHT_CLICK_CLOSE, ///< 6 PR#10204 Add alternative right click to close windows setting. + IFV_PBS_COST_ONCE, ///< 7 PR#10807 Penalty for crossing a reserved segment is now constant IFV_MAX_VERSION, ///< Highest possible ini-file version. }; @@ -1282,6 +1283,11 @@ void LoadFromConfig(bool startup) /* Load basic settings only during bootstrap, load other settings not during bootstrap */ if (!startup) { + if(generic_version < IFV_PBS_COST_ONCE) { + _settings_newgame.pf.yapf.rail_pbs_cross_penalty *= 5; + _settings_newgame.pf.yapf.rail_pbs_station_penalty *= 5; + } + if (generic_version < IFV_LINKGRAPH_SECONDS) { _settings_newgame.linkgraph.recalc_interval *= SECONDS_PER_DAY; _settings_newgame.linkgraph.recalc_time *= SECONDS_PER_DAY; diff --git a/src/table/settings/pathfinding_settings.ini b/src/table/settings/pathfinding_settings.ini index 20c08aced4..f12fc13818 100644 --- a/src/table/settings/pathfinding_settings.ini +++ b/src/table/settings/pathfinding_settings.ini @@ -467,7 +467,7 @@ cat = SC_EXPERT var = pf.yapf.rail_pbs_cross_penalty type = SLE_UINT from = SLV_100 -def = 3 * YAPF_TILE_LENGTH +def = 3 * YAPF_TILE_LENGTH * 5 min = 0 max = 1000000 cat = SC_EXPERT @@ -476,7 +476,7 @@ cat = SC_EXPERT var = pf.yapf.rail_pbs_station_penalty type = SLE_UINT from = SLV_100 -def = 8 * YAPF_TILE_LENGTH +def = 8 * YAPF_TILE_LENGTH * 5 min = 0 max = 1000000 cat = SC_EXPERT