File diff r18781:e1de9a06f7cd → r18782:6453522c2154
src/pathfinder/yapf/yapf_ship.cpp
Show inline comments
 
@@ -6,69 +6,69 @@
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file yapf_ship.cpp Implementation of YAPF for ships. */
 

	
 
#include "../../stdafx.h"
 
#include "../../ship.h"
 

	
 
#include "yapf.hpp"
 
#include "yapf_node_ship.hpp"
 

	
 
/** Node Follower module of YAPF for ships */
 
template <class Types>
 
class CYapfFollowShipT
 
{
 
public:
 
	typedef typename Types::Tpf Tpf;                     ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node;        ///< this will be our node type
 
	typedef typename Node::Key Key;                      ///< key to hash tables
 

	
 
protected:
 
	/** to access inherited path finder */
 
	FORCEINLINE Tpf& Yapf()
 
	inline Tpf& Yapf()
 
	{
 
		return *static_cast<Tpf*>(this);
 
	}
 

	
 
public:
 
	/**
 
	 * Called by YAPF to move from the given node to the next tile. For each
 
	 *  reachable trackdir on the new tile creates new node, initializes it
 
	 *  and adds it to the open list by calling Yapf().AddNewNode(n)
 
	 */
 
	inline void PfFollowNode(Node& old_node)
 
	{
 
		TrackFollower F(Yapf().GetVehicle());
 
		if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td)) {
 
			Yapf().AddMultipleNodes(&old_node, F);
 
		}
 
	}
 

	
 
	/** return debug report character to identify the transportation type */
 
	FORCEINLINE char TransportTypeChar() const
 
	inline char TransportTypeChar() const
 
	{
 
		return 'w';
 
	}
 

	
 
	static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)
 
	{
 
		/* handle special case - when next tile is destination tile */
 
		if (tile == v->dest_tile) {
 
			/* convert tracks to trackdirs */
 
			TrackdirBits trackdirs = (TrackdirBits)(tracks | ((int)tracks << 8));
 
			/* choose any trackdir reachable from enterdir */
 
			trackdirs &= DiagdirReachesTrackdirs(enterdir);
 
			return (Trackdir)FindFirstBit2x64(trackdirs);
 
		}
 

	
 
		/* move back to the old tile/trackdir (where ship is coming from) */
 
		TileIndex src_tile = TILE_ADD(tile, TileOffsByDiagDir(ReverseDiagDir(enterdir)));
 
		Trackdir trackdir = v->GetVehicleTrackdir();
 
		assert(IsValidTrackdir(trackdir));
 

	
 
		/* convert origin trackdir to TrackdirBits */
 
		TrackdirBits trackdirs = TrackdirToTrackdirBits(trackdir);
 
		/* get available trackdirs on the destination tile */
 
		TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0));
 
@@ -102,49 +102,49 @@ public:
 

	
 
/** Cost Provider module of YAPF for ships */
 
template <class Types>
 
class CYapfCostShipT
 
{
 
public:
 
	typedef typename Types::Tpf Tpf;              ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 
	typedef typename Node::Key Key;               ///< key to hash tables
 

	
 
protected:
 
	/** to access inherited path finder */
 
	Tpf& Yapf()
 
	{
 
		return *static_cast<Tpf*>(this);
 
	}
 

	
 
public:
 
	/**
 
	 * Called by YAPF to calculate the cost from the origin to the given node.
 
	 *  Calculates only the cost of given node, adds it to the parent node cost
 
	 *  and stores the result into Node::m_cost member
 
	 */
 
	FORCEINLINE bool PfCalcCost(Node& n, const TrackFollower *tf)
 
	inline bool PfCalcCost(Node& n, const TrackFollower *tf)
 
	{
 
		/* base tile cost depending on distance */
 
		int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH;
 
		/* additional penalty for curves */
 
		if (n.m_parent != NULL && n.GetTrackdir() != NextTrackdir(n.m_parent->GetTrackdir())) {
 
			/* new trackdir does not match the next one when going straight */
 
			c += YAPF_TILE_LENGTH;
 
		}
 

	
 
		/* Skipped tile cost for aqueducts. */
 
		c += YAPF_TILE_LENGTH * tf->m_tiles_skipped;
 

	
 
		/* Ocean/canal speed penalty. */
 
		const ShipVehicleInfo *svi = ShipVehInfo(Yapf().GetVehicle()->engine_type);
 
		byte speed_frac = (GetEffectiveWaterClass(n.GetTile()) == WATER_CLASS_SEA) ? svi->ocean_speed_frac : svi->canal_speed_frac;
 
		if (speed_frac > 0) c += YAPF_TILE_LENGTH * (1 + tf->m_tiles_skipped) * speed_frac / (256 - speed_frac);
 

	
 
		/* apply it */
 
		n.m_cost = n.m_parent->m_cost + c;
 
		return true;
 
	}
 
};
 

	
 
/**