Changeset - r10452:e64515b3ea5c
[Not reviewed]
master
0 3 0
frosch - 15 years ago 2008-12-20 20:26:40
frosch@openttd.org
(svn r14707) -Cleanup: Replace an 'int' by 'Trackdir'.
3 files changed with 26 insertions and 25 deletions:
0 comments (0 inline, 0 general)
src/ai/trolly/pathfinder.cpp
Show inline comments
 
@@ -118,13 +118,13 @@ AyStar *new_AyStar_AiPathFinder(int max_
 

	
 
	// Set the user_data to the PathFinderInfo
 
	result->user_target = PathFinderInfo;
 

	
 
	// Set the start node
 
	start_node.parent = NULL;
 
	start_node.node.direction = 0;
 
	start_node.node.direction = INVALID_TRACKDIR;
 
	start_node.node.user_data[0] = 0;
 

	
 
	// Now we add all the starting tiles
 
	for (x = TileX(PathFinderInfo->start_tile_tl); x <= TileX(PathFinderInfo->start_tile_br); x++) {
 
		for (y = TileY(PathFinderInfo->start_tile_tl); y <= TileY(PathFinderInfo->start_tile_br); y++) {
 
			start_node.node.tile = TileXY(x, y);
 
@@ -147,13 +147,13 @@ void clean_AyStar_AiPathFinder(AyStar *a
 

	
 
	// Set the user_data to the PathFinderInfo
 
	aystar->user_target = PathFinderInfo;
 

	
 
	// Set the start node
 
	start_node.parent = NULL;
 
	start_node.node.direction = 0;
 
	start_node.node.direction = INVALID_TRACKDIR;
 
	start_node.node.user_data[0] = 0;
 
	start_node.node.tile = PathFinderInfo->start_tile_tl;
 

	
 
	// Now we add all the starting tiles
 
	for (x = TileX(PathFinderInfo->start_tile_tl); x <= TileX(PathFinderInfo->start_tile_br); x++) {
 
		for (y = TileY(PathFinderInfo->start_tile_tl); y <= TileY(PathFinderInfo->start_tile_br); y++) {
 
@@ -297,13 +297,13 @@ static void AyStar_AiPathFinder_GetNeigh
 
				}
 
			}
 

	
 
			// The tile can be connected
 
			aystar->neighbours[aystar->num_neighbours].tile = atile;
 
			aystar->neighbours[aystar->num_neighbours].user_data[0] = 0;
 
			aystar->neighbours[aystar->num_neighbours++].direction = 0;
 
			aystar->neighbours[aystar->num_neighbours++].direction = INVALID_TRACKDIR;
 
		}
 
	}
 

	
 
	// Next step, check for bridges and tunnels
 
	if (current->path.parent != NULL && current->path.node.user_data[0] == 0) {
 
		// First we get the dir from this tile and his parent
 
@@ -330,13 +330,13 @@ static void AyStar_AiPathFinder_GetNeigh
 
				// Try building the bridge..
 
				ret = AI_DoCommand(tile, new_tile, (0 << 8) + (MAX_BRIDGES / 2), DC_AUTO, CMD_BUILD_BRIDGE);
 
				if (CmdFailed(ret)) continue;
 
				// We can build a bridge here.. add him to the neighbours
 
				aystar->neighbours[aystar->num_neighbours].tile = new_tile;
 
				aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_BRIDGE + (dir << 8);
 
				aystar->neighbours[aystar->num_neighbours++].direction = 0;
 
				aystar->neighbours[aystar->num_neighbours++].direction = INVALID_TRACKDIR;
 
				// We can only have 12 neighbours, and we need 1 left for tunnels
 
				if (aystar->num_neighbours == 11) break;
 
			}
 
		}
 

	
 
		// Next, check for tunnels!
 
@@ -346,13 +346,13 @@ static void AyStar_AiPathFinder_GetNeigh
 
			// Now simply check if a tunnel can be build
 
			ret = AI_DoCommand(tile, (PathFinderInfo->rail_or_road ? 0 : 0x200), 0, DC_AUTO, CMD_BUILD_TUNNEL);
 
			tileh = GetTileSlope(_build_tunnel_endtile, NULL);
 
			if (CmdSucceeded(ret) && IsInclinedSlope(tileh)) {
 
				aystar->neighbours[aystar->num_neighbours].tile = _build_tunnel_endtile;
 
				aystar->neighbours[aystar->num_neighbours].user_data[0] = AI_PATHFINDER_FLAG_TUNNEL + (dir << 8);
 
				aystar->neighbours[aystar->num_neighbours++].direction = 0;
 
				aystar->neighbours[aystar->num_neighbours++].direction = INVALID_TRACKDIR;
 
			}
 
		}
 
	}
 
}
 

	
 

	
src/aystar.h
Show inline comments
 
@@ -10,12 +10,13 @@
 

	
 
#ifndef AYSTAR_H
 
#define AYSTAR_H
 

	
 
#include "queue.h"
 
#include "tile_type.h"
 
#include "track_type.h"
 

	
 
//#define AYSTAR_DEBUG
 
enum {
 
	AYSTAR_FOUND_END_NODE,
 
	AYSTAR_EMPTY_OPENLIST,
 
	AYSTAR_STILL_BUSY,
 
@@ -27,13 +28,13 @@ enum {
 
enum{
 
	AYSTAR_INVALID_NODE = -1,
 
};
 

	
 
struct AyStarNode {
 
	TileIndex tile;
 
	int direction;
 
	Trackdir direction;
 
	uint user_data[2];
 
};
 

	
 
// The resulting path has nodes looking like this.
 
struct PathNode {
 
	AyStarNode node;
src/npf.cpp
Show inline comments
 
@@ -155,13 +155,13 @@ static int32 NPFCalcStationOrTileHeurist
 
/* Fills AyStarNode.user_data[NPF_TRACKDIRCHOICE] with the chosen direction to
 
 * get here, either getting it from the current choice or from the parent's
 
 * choice */
 
static void NPFFillTrackdirChoice(AyStarNode* current, OpenListNode* parent)
 
{
 
	if (parent->path.parent == NULL) {
 
		Trackdir trackdir = (Trackdir)current->direction;
 
		Trackdir trackdir = current->direction;
 
		/* This is a first order decision, so we'd better save the
 
		 * direction we chose */
 
		current->user_data[NPF_TRACKDIR_CHOICE] = trackdir;
 
		DEBUG(npf, 6, "Saving trackdir: 0x%X", trackdir);
 
	} else {
 
		/* We've already made the decision, so just save our parent's decision */
 
@@ -171,13 +171,13 @@ static void NPFFillTrackdirChoice(AyStar
 

	
 
/* Will return the cost of the tunnel. If it is an entry, it will return the
 
 * cost of that tile. If the tile is an exit, it will return the tunnel length
 
 * including the exit tile. Requires that this is a Tunnel tile */
 
static uint NPFTunnelCost(AyStarNode* current)
 
{
 
	DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction);
 
	DiagDirection exitdir = TrackdirToExitdir(current->direction);
 
	TileIndex tile = current->tile;
 
	if (GetTunnelBridgeDirection(tile) == ReverseDiagDir(exitdir)) {
 
		/* We just popped out if this tunnel, since were
 
		 * facing the tunnel exit */
 
		return NPF_TILE_LENGTH * (GetTunnelBridgeLength(current->tile, GetOtherTunnelEnd(current->tile)) + 1);
 
		/* @todo: Penalty for tunnels? */
 
@@ -192,13 +192,13 @@ static inline uint NPFBridgeCost(AyStarN
 
{
 
	return NPF_TILE_LENGTH * GetTunnelBridgeLength(current->tile, GetOtherBridgeEnd(current->tile));
 
}
 

	
 
static uint NPFSlopeCost(AyStarNode* current)
 
{
 
	TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir((Trackdir)current->direction));
 
	TileIndex next = current->tile + TileOffsByDiagDir(TrackdirToExitdir(current->direction));
 

	
 
	/* Get center of tiles */
 
	int x1 = TileX(current->tile) * TILE_SIZE + TILE_SIZE / 2;
 
	int y1 = TileY(current->tile) * TILE_SIZE + TILE_SIZE / 2;
 
	int x2 = TileX(next) * TILE_SIZE + TILE_SIZE / 2;
 
	int y2 = TileY(next) * TILE_SIZE + TILE_SIZE / 2;
 
@@ -222,19 +222,19 @@ static uint NPFSlopeCost(AyStarNode* cur
 
	 * there is only one level of steepness... */
 
}
 

	
 
static uint NPFReservedTrackCost(AyStarNode *current)
 
{
 
	TileIndex tile = current->tile;
 
	TrackBits track = TrackToTrackBits(TrackdirToTrack((Trackdir)current->direction));
 
	TrackBits track = TrackToTrackBits(TrackdirToTrack(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);
 
		DiagDirection exitdir = TrackdirToExitdir(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;
 
}
 
@@ -270,13 +270,13 @@ static void NPFMarkTile(TileIndex tile)
 
}
 

	
 
static int32 NPFWaterPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent)
 
{
 
	/* TileIndex tile = current->tile; */
 
	int32 cost = 0;
 
	Trackdir trackdir = (Trackdir)current->direction;
 
	Trackdir trackdir = current->direction;
 

	
 
	cost = _trackdir_length[trackdir]; // Should be different for diagonal tracks
 

	
 
	if (IsBuoyTile(current->tile) && IsDiagonalTrackdir(trackdir))
 
		cost += _settings_game.pf.npf.npf_buoy_penalty; // A small penalty for going over buoys
 

	
 
@@ -320,26 +320,26 @@ static int32 NPFRoadPathCost(AyStar* as,
 

	
 
	/* Check for slope */
 
	cost += NPFSlopeCost(current);
 

	
 
	/* Check for turns. Road vehicles only really drive diagonal, turns are
 
	 * represented by non-diagonal tracks */
 
	if (!IsDiagonalTrackdir((Trackdir)current->direction))
 
	if (!IsDiagonalTrackdir(current->direction))
 
		cost += _settings_game.pf.npf.npf_road_curve_penalty;
 

	
 
	NPFMarkTile(tile);
 
	DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
 
	return cost;
 
}
 

	
 

	
 
/* Determine the cost of this node, for railway tracks */
 
static int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* parent)
 
{
 
	TileIndex tile = current->tile;
 
	Trackdir trackdir = (Trackdir)current->direction;
 
	Trackdir trackdir = current->direction;
 
	int32 cost = 0;
 
	/* HACK: We create a OpenListNode manually, so we can call EndNodeCheck */
 
	OpenListNode new_node;
 

	
 
	/* Determine base length */
 
	switch (GetTileType(tile)) {
 
@@ -459,14 +459,14 @@ static int32 NPFFindDepot(AyStar* as, Op
 
/** Find any safe and free tile. */
 
static int32 NPFFindSafeTile(AyStar *as, OpenListNode *current)
 
{
 
	const Vehicle *v = ((NPFFindStationOrTileData*)as->user_target)->v;
 

	
 
	return
 
		IsSafeWaitingPosition(v, current->path.node.tile, (Trackdir)current->path.node.direction, true, _settings_game.pf.forbid_90_deg) &&
 
		IsWaitingPositionFree(v, current->path.node.tile, (Trackdir)current->path.node.direction, _settings_game.pf.forbid_90_deg) ?
 
		IsSafeWaitingPosition(v, current->path.node.tile, current->path.node.direction, true, _settings_game.pf.forbid_90_deg) &&
 
		IsWaitingPositionFree(v, current->path.node.tile, current->path.node.direction, _settings_game.pf.forbid_90_deg) ?
 
			AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
 
}
 

	
 
/* Will find a station identified using the NPFFindStationOrTileData */
 
static int32 NPFFindStationOrTile(AyStar* as, OpenListNode *current)
 
{
 
@@ -496,13 +496,13 @@ static int32 NPFFindStationOrTile(AyStar
 
static const PathNode* FindSafePosition(PathNode *path, const Vehicle *v)
 
{
 
	/* If there is no signal, reserve the whole path. */
 
	PathNode *sig = path;
 

	
 
	for(; path->parent != NULL; path = path->parent) {
 
		if (IsSafeWaitingPosition(v, path->node.tile, (Trackdir)path->node.direction, true, _settings_game.pf.forbid_90_deg)) {
 
		if (IsSafeWaitingPosition(v, path->node.tile, path->node.direction, true, _settings_game.pf.forbid_90_deg)) {
 
			sig = path;
 
		}
 
	}
 

	
 
	return sig;
 
}
 
@@ -512,15 +512,15 @@ static const PathNode* FindSafePosition(
 
 */
 
static void ClearPathReservation(const PathNode *start, const PathNode *end)
 
{
 
	bool first_run = true;
 
	for (; start != end; start = start->parent) {
 
		if (IsRailwayStationTile(start->node.tile) && first_run) {
 
			SetRailwayStationPlatformReservation(start->node.tile, TrackdirToExitdir((Trackdir)start->node.direction), false);
 
			SetRailwayStationPlatformReservation(start->node.tile, TrackdirToExitdir(start->node.direction), false);
 
		} else {
 
			UnreserveRailTrack(start->node.tile, TrackdirToTrack((Trackdir)start->node.direction));
 
			UnreserveRailTrack(start->node.tile, TrackdirToTrack(start->node.direction));
 
		}
 
		first_run = false;
 
	}
 
}
 

	
 
/**
 
@@ -544,27 +544,27 @@ static void NPFSaveTargetData(AyStar* as
 

	
 
		const PathNode *target = FindSafePosition(&current->path, v);
 
		ftd->node = target->node;
 

	
 
		/* If the target is a station skip to platform end. */
 
		if (IsRailwayStationTile(target->node.tile)) {
 
			DiagDirection dir = TrackdirToExitdir((Trackdir)target->node.direction);
 
			DiagDirection dir = TrackdirToExitdir(target->node.direction);
 
			uint len = GetStationByTile(target->node.tile)->GetPlatformLength(target->node.tile, dir);
 
			TileIndex end_tile = TILE_ADD(target->node.tile, (len - 1) * TileOffsByDiagDir(dir));
 

	
 
			/* Update only end tile, trackdir of a station stays the same. */
 
			ftd->node.tile = end_tile;
 
			if (!IsWaitingPositionFree(v, end_tile, (Trackdir)target->node.direction, _settings_game.pf.forbid_90_deg)) return;
 
			if (!IsWaitingPositionFree(v, end_tile, target->node.direction, _settings_game.pf.forbid_90_deg)) return;
 
			SetRailwayStationPlatformReservation(target->node.tile, dir, true);
 
			SetRailwayStationReservation(target->node.tile, false);
 
		} else {
 
			if (!IsWaitingPositionFree(v, target->node.tile, (Trackdir)target->node.direction, _settings_game.pf.forbid_90_deg)) return;
 
			if (!IsWaitingPositionFree(v, target->node.tile, target->node.direction, _settings_game.pf.forbid_90_deg)) return;
 
		}
 

	
 
		for (const PathNode *cur = target; cur->parent != NULL; cur = cur->parent) {
 
			if (!TryReserveRailTrack(cur->node.tile, TrackdirToTrack((Trackdir)cur->node.direction))) {
 
			if (!TryReserveRailTrack(cur->node.tile, TrackdirToTrack(cur->node.direction))) {
 
				/* Reservation failed, undo. */
 
				ClearPathReservation(target, cur);
 
				return;
 
			}
 
		}
 

	
 
@@ -766,13 +766,13 @@ static TrackdirBits GetDriveableTrackdir
 
 * entry and exit are neighbours. Will fill
 
 * AyStarNode.user_data[NPF_TRACKDIR_CHOICE] with an appropriate value, and
 
 * copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */
 
static void NPFFollowTrack(AyStar* aystar, OpenListNode* current)
 
{
 
	/* We leave src_tile on track src_trackdir in direction src_exitdir */
 
	Trackdir src_trackdir = (Trackdir)current->path.node.direction;
 
	Trackdir src_trackdir = current->path.node.direction;
 
	TileIndex src_tile = current->path.node.tile;
 
	DiagDirection src_exitdir = TrackdirToExitdir(src_trackdir);
 

	
 
	/* Is src_tile valid, and can be used?
 
	 * When choosing track on a junction src_tile is the tile neighboured to the junction wrt. exitdir.
 
	 * But we must not check the validity of this move, as src_tile is totally unrelated to the move, if a roadvehicle reversed on a junction. */
 
@@ -997,13 +997,13 @@ NPFFoundTargetData NPFRouteToDepotTrialE
 
	 * far, is shorter than the manhattan distance. This will obviously
 
	 * always find the closest depot. It will probably be most efficient
 
	 * for ships, since the heuristic will not be to far off then. I hope.
 
	 */
 
	Queue depots;
 
	int r;
 
	NPFFoundTargetData best_result = {UINT_MAX, UINT_MAX, INVALID_TRACKDIR, {INVALID_TILE, 0, {0, 0}}, false};
 
	NPFFoundTargetData best_result = {UINT_MAX, UINT_MAX, INVALID_TRACKDIR, {INVALID_TILE, INVALID_TRACKDIR, {0, 0}}, false};
 
	NPFFoundTargetData result;
 
	NPFFindStationOrTileData target;
 
	AyStarNode start;
 
	Depot* current;
 
	Depot *depot;
 

	
0 comments (0 inline, 0 general)