diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/npf.cpp | 76 | ||||
-rw-r--r-- | src/npf.h | 2 | ||||
-rw-r--r-- | src/settings.cpp | 2 | ||||
-rw-r--r-- | src/settings_type.h | 2 |
4 files changed, 61 insertions, 21 deletions
diff --git a/src/npf.cpp b/src/npf.cpp index b8cb499a8..4aa817b70 100644 --- a/src/npf.cpp +++ b/src/npf.cpp @@ -24,6 +24,7 @@ #include "vehicle_base.h" #include "settings_type.h" #include "tunnelbridge.h" +#include "pbs.h" static AyStar _npf_aystar; @@ -221,6 +222,23 @@ static uint NPFSlopeCost(AyStarNode* current) * there is only one level of steepness... */ } +static uint NPFReservedTrackCost(AyStarNode *current) +{ + TileIndex tile = current->tile; + TrackBits track = TrackToTrackBits(TrackdirToTrack((Trackdir)current->direction)); + TrackBits res = GetReservedTrackbits(tile); + + if (NPFGetFlag(current, NPF_FLAG_3RD_SIGNAL) || ((res & track) == TRACK_BIT_NONE && !TracksOverlap(res | track))) return 0; + + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction); + if (GetTunnelBridgeDirection(tile) == ReverseDiagDir(exitdir)) { + return _settings_game.pf.npf.npf_rail_pbs_cross_penalty * (GetTunnelBridgeLength(tile, GetOtherTunnelBridgeEnd(tile)) + 1); + } + } + return _settings_game.pf.npf.npf_rail_pbs_cross_penalty; +} + /** * Mark tiles by mowing the grass when npf debug level >= 1. * Will not work for multiplayer games, since it can (will) cause desyncs. @@ -354,30 +372,46 @@ static int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* pare /* Determine extra costs */ /* Check for signals */ - if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir)) { - /* Ordinary track with signals */ - if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_RED) { - /* Signal facing us is red */ - if (!NPFGetFlag(current, NPF_FLAG_SEEN_SIGNAL)) { - /* Penalize the first signal we - * encounter, if it is red */ - - /* Is this a presignal exit or combo? */ - SignalType sigtype = GetSignalType(tile, TrackdirToTrack(trackdir)); - if (sigtype == SIGTYPE_EXIT || sigtype == SIGTYPE_COMBO) { - /* Penalise exit and combo signals differently (heavier) */ - cost += _settings_game.pf.npf.npf_rail_firstred_exit_penalty; + if (IsTileType(tile, MP_RAILWAY)) { + if (HasSignalOnTrackdir(tile, trackdir)) { + /* Ordinary track with signals */ + if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_RED) { + /* Signal facing us is red */ + if (!NPFGetFlag(current, NPF_FLAG_SEEN_SIGNAL)) { + /* Penalize the first signal we + * encounter, if it is red */ + + /* Is this a presignal exit or combo? */ + SignalType sigtype = GetSignalType(tile, TrackdirToTrack(trackdir)); + if (!IsPbsSignal(sigtype)) { + if (sigtype == SIGTYPE_EXIT || sigtype == SIGTYPE_COMBO) { + /* Penalise exit and combo signals differently (heavier) */ + cost += _settings_game.pf.npf.npf_rail_firstred_exit_penalty; + } else { + cost += _settings_game.pf.npf.npf_rail_firstred_penalty; + } + } + } + /* Record the state of this signal */ + NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, true); + } else { + /* Record the state of this signal */ + NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, false); + } + if (NPFGetFlag(current, NPF_FLAG_SEEN_SIGNAL)) { + if (NPFGetFlag(current, NPF_FLAG_2ND_SIGNAL)) { + NPFSetFlag(current, NPF_FLAG_3RD_SIGNAL, true); } else { - cost += _settings_game.pf.npf.npf_rail_firstred_penalty; + NPFSetFlag(current, NPF_FLAG_2ND_SIGNAL, true); } + } else { + NPFSetFlag(current, NPF_FLAG_SEEN_SIGNAL, true); } - /* Record the state of this signal */ - NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, true); - } else { - /* Record the state of this signal */ - NPFSetFlag(current, NPF_FLAG_LAST_SIGNAL_RED, false); } - NPFSetFlag(current, NPF_FLAG_SEEN_SIGNAL, true); + + if (HasPbsSignalOnTrackdir(tile, ReverseTrackdir(trackdir)) && !NPFGetFlag(current, NPF_FLAG_3RD_SIGNAL)) { + cost += _settings_game.pf.npf.npf_rail_pbs_signal_back_penalty; + } } /* Penalise the tile if it is a target tile and the last signal was @@ -406,7 +440,7 @@ static int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* pare } /* Check for occupied track */ - //TODO + cost += NPFReservedTrackCost(current); NPFMarkTile(tile); DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost); @@ -66,6 +66,8 @@ enum { /* Flags for AyStarNode.userdata[NPF_NODE_FLAGS]. Use NPFGetBit() and NPFGetBit() to use them. */ enum NPFNodeFlag { NPF_FLAG_SEEN_SIGNAL, ///< Used to mark that a signal was seen on the way, for rail only + NPF_FLAG_2ND_SIGNAL, ///< Used to mark that two signals were seen, rail only + NPF_FLAG_3RD_SIGNAL, ///< Used to mark that three signals were seen, rail only NPF_FLAG_REVERSE, ///< Used to mark that this node was reached from the second start node, if applicable NPF_FLAG_LAST_SIGNAL_RED, ///< Used to mark that the last signal on this path was red NPF_FLAG_IGNORE_START_TILE, ///< Used to mark that the start tile is invalid, and searching should start from the second tile on diff --git a/src/settings.cpp b/src/settings.cpp index 71f4463eb..dd2451802 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1701,6 +1701,8 @@ const SettingDesc _patch_settings[] = { SDT_VAR(GameSettings, pf.npf.npf_rail_slope_penalty, SLE_UINT, 0, 0, ( 1 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL), SDT_VAR(GameSettings, pf.npf.npf_rail_curve_penalty, SLE_UINT, 0, 0, 1, 0, 100000, 0, STR_NULL, NULL), SDT_VAR(GameSettings, pf.npf.npf_rail_depot_reverse_penalty, SLE_UINT, 0, 0, ( 50 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL), + SDT_CONDVAR(GameSettings, pf.npf.npf_rail_pbs_cross_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, ( 3 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL), + SDT_CONDVAR(GameSettings, pf.npf.npf_rail_pbs_signal_back_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, ( 15 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL), SDT_VAR(GameSettings, pf.npf.npf_buoy_penalty, SLE_UINT, 0, 0, ( 2 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL), SDT_VAR(GameSettings, pf.npf.npf_water_curve_penalty, SLE_UINT, 0, 0, (NPF_TILE_LENGTH / 4), 0, 100000, 0, STR_NULL, NULL), SDT_VAR(GameSettings, pf.npf.npf_road_curve_penalty, SLE_UINT, 0, 0, 1, 0, 100000, 0, STR_NULL, NULL), diff --git a/src/settings_type.h b/src/settings_type.h index 708d44134..493e60118 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -185,6 +185,8 @@ struct NPFSettings { uint32 npf_rail_slope_penalty; ///< the penalty for sloping upwards uint32 npf_rail_curve_penalty; ///< the penalty for curves uint32 npf_rail_depot_reverse_penalty; ///< the penalty for reversing in depots + uint32 npf_rail_pbs_cross_penalty; ///< the penalty for crossing a reserved rail track + uint32 npf_rail_pbs_signal_back_penalty; ///< the penalty for passing a pbs signal from the backside uint32 npf_buoy_penalty; ///< the penalty for going over (through) a buoy uint32 npf_water_curve_penalty; ///< the penalty for curves uint32 npf_road_curve_penalty; ///< the penalty for curves |