changeset 9805:a9cb777d40b5 draft

(svn r13947) -Codechange [YAPP]: Added YAPP-related penalties to NPF. (michi_cc)
author rubidium <rubidium@openttd.org>
date Sat, 02 Aug 2008 22:52:36 +0000
parents 0cf61f727bc4
children a8cc8e4fb3a0
files src/npf.cpp src/npf.h src/settings.cpp src/settings_type.h
diffstat 4 files changed, 61 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
 	 * 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 @@
 	/* 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 */
+	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 (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;
+					/* 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);
 			}
-			/* 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 {
+					NPFSetFlag(current, NPF_FLAG_2ND_SIGNAL, true);
+				}
+			} else {
+				NPFSetFlag(current, NPF_FLAG_SEEN_SIGNAL, true);
+			}
 		}
-		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 @@
 	}
 
 	/* 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);
--- a/src/npf.h
+++ b/src/npf.h
@@ -66,6 +66,8 @@
 /* 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
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -1701,6 +1701,8 @@
 	     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),
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -185,6 +185,8 @@
 	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