Changeset - r23178:e613ba71d020
[Not reviewed]
master
0 12 0
Peter Nelson - 6 years ago 2019-01-14 23:33:42
peter1138@openttd.org
Change: Add path cache for ships.
12 files changed with 67 insertions and 21 deletions:
0 comments (0 inline, 0 general)
src/order_cmd.cpp
Show inline comments
 
@@ -2041,13 +2041,13 @@ bool UpdateOrderDest(Vehicle *v, const O
 
{
 
	if (conditional_depth > v->GetNumOrders()) {
 
		v->current_order.Free();
 
		v->dest_tile = 0;
 
		v->SetDestTile(0);
 
		return false;
 
	}
 

	
 
	switch (order->GetType()) {
 
		case OT_GOTO_STATION:
 
			v->dest_tile = v->GetOrderStationLocation(order->GetDestination());
 
			v->SetDestTile(v->GetOrderStationLocation(order->GetDestination()));
 
			return true;
 

	
 
		case OT_GOTO_DEPOT:
 
@@ -2068,7 +2068,7 @@ bool UpdateOrderDest(Vehicle *v, const O
 
					/* PBS reservations cannot reverse */
 
					if (pbs_look_ahead && reverse) return false;
 

	
 
					v->dest_tile = location;
 
					v->SetDestTile(location);
 
					v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo());
 

	
 
					/* If there is no depot in front, reverse automatically (trains only) */
 
@@ -2092,14 +2092,14 @@ bool UpdateOrderDest(Vehicle *v, const O
 
				v->IncrementRealOrderIndex();
 
			} else {
 
				if (v->type != VEH_AIRCRAFT) {
 
					v->dest_tile = Depot::Get(order->GetDestination())->xy;
 
					v->SetDestTile(Depot::Get(order->GetDestination())->xy);
 
				}
 
				return true;
 
			}
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
 
			v->dest_tile = Waypoint::Get(order->GetDestination())->xy;
 
			v->SetDestTile(Waypoint::Get(order->GetDestination())->xy);
 
			return true;
 

	
 
		case OT_CONDITIONAL: {
 
@@ -2127,7 +2127,7 @@ bool UpdateOrderDest(Vehicle *v, const O
 
		}
 

	
 
		default:
 
			v->dest_tile = 0;
 
			v->SetDestTile(0);
 
			return false;
 
	}
 

	
 
@@ -2143,7 +2143,7 @@ bool UpdateOrderDest(Vehicle *v, const O
 

	
 
	if (order == NULL) {
 
		v->current_order.Free();
 
		v->dest_tile = 0;
 
		v->SetDestTile(0);
 
		return false;
 
	}
 

	
 
@@ -2219,7 +2219,7 @@ bool ProcessOrders(Vehicle *v)
 
		}
 

	
 
		v->current_order.Free();
 
		v->dest_tile = 0;
 
		v->SetDestTile(0);
 
		return false;
 
	}
 

	
src/pathfinder/pathfinder_type.h
Show inline comments
 
@@ -40,6 +40,9 @@ static const int YAPF_TILE_CORNER_LENGTH
 
 */
 
static const int YAPF_INFINITE_PENALTY = 1000 * YAPF_TILE_LENGTH;
 

	
 
/** Maximum length of ship path cache */
 
static const int YAPF_SHIP_PATH_CACHE_LENGTH = 32;
 

	
 
/**
 
 * Helper container to find a depot
 
 */
src/pathfinder/yapf/yapf.h
Show inline comments
 
@@ -15,6 +15,7 @@
 
#include "../../direction_type.h"
 
#include "../../track_type.h"
 
#include "../../vehicle_type.h"
 
#include "../../ship.h"
 
#include "../pathfinder_type.h"
 

	
 
/**
 
@@ -26,7 +27,7 @@
 
 * @param path_found [out] Whether a path has been found (true) or has been guessed (false)
 
 * @return         the best trackdir for next turn or INVALID_TRACK if the path could not be found
 
 */
 
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found);
 
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache);
 

	
 
/**
 
 * Returns true if it is better to reverse the ship before leaving depot using YAPF.
src/pathfinder/yapf/yapf_ship.cpp
Show inline comments
 
@@ -54,7 +54,7 @@ public:
 
		return 'w';
 
	}
 

	
 
	static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)
 
	static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache)
 
	{
 
		/* handle special case - when next tile is destination tile */
 
		if (tile == v->dest_tile) {
 
@@ -90,9 +90,17 @@ public:
 

	
 
		Node *pNode = pf.GetBestNode();
 
		if (pNode != NULL) {
 
			uint steps = 0;
 
			for (Node *n = pNode; n->m_parent != NULL; n = n->m_parent) steps++;
 

	
 
			/* walk through the path back to the origin */
 
			Node *pPrevNode = NULL;
 
			while (pNode->m_parent != NULL) {
 
				if (steps > 1 && --steps < YAPF_SHIP_PATH_CACHE_LENGTH) {
 
					TrackdirByte td;
 
					td = pNode->GetTrackdir();
 
					path_cache.push_front(td);
 
				}
 
				pPrevNode = pNode;
 
				pNode = pNode->m_parent;
 
			}
 
@@ -100,6 +108,8 @@ public:
 
			Node &best_next_node = *pPrevNode;
 
			assert(best_next_node.GetTile() == tile);
 
			next_trackdir = best_next_node.GetTrackdir();
 
			/* remove last element for the special case when tile == dest_tile */
 
			if (path_found && !path_cache.empty()) path_cache.pop_back();
 
		}
 
		return next_trackdir;
 
	}
 
@@ -222,10 +232,10 @@ struct CYapfShip2 : CYapfT<CYapfShip_Typ
 
struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {};
 

	
 
/** Ship controller helper - path finder invoker */
 
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)
 
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache)
 
{
 
	/* default is YAPF type 2 */
 
	typedef Trackdir (*PfnChooseShipTrack)(const Ship*, TileIndex, DiagDirection, TrackBits, bool &path_found);
 
	typedef Trackdir (*PfnChooseShipTrack)(const Ship*, TileIndex, DiagDirection, TrackBits, bool &path_found, ShipPathCache &path_cache);
 
	PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir, allow 90-deg
 

	
 
	/* check if non-default YAPF type needed */
 
@@ -235,7 +245,7 @@ Track YapfShipChooseTrack(const Ship *v,
 
		pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir, allow 90-deg
 
	}
 

	
 
	Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks, path_found);
 
	Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks, path_found, path_cache);
 
	return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;
 
}
 

	
src/roadveh_cmd.cpp
Show inline comments
 
@@ -1639,7 +1639,7 @@ static void CheckIfRoadVehNeedsService(R
 

	
 
	SetBit(v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
 
	v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
 
	v->dest_tile = rfdd.tile;
 
	v->SetDestTile(rfdd.tile);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
 
}
 

	
src/saveload/saveload.cpp
Show inline comments
 
@@ -272,8 +272,9 @@
 
 *  200   #6805   Extend railtypes to 64, adding uint16 to map array.
 
 *  201   #6885   Extend NewGRF persistant storages.
 
 *  202   #6867   Increase industry cargo slots to 16 in, 16 out
 
 *  203   #7072   Add path cache for ships
 
 */
 
extern const uint16 SAVEGAME_VERSION = 202; ///< Current savegame version of OpenTTD.
 
extern const uint16 SAVEGAME_VERSION = 203; ///< Current savegame version of OpenTTD.
 

	
 
SavegameType _savegame_type; ///< type of savegame we are loading
 
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
src/saveload/vehicle_sl.cpp
Show inline comments
 
@@ -753,7 +753,8 @@ const SaveLoad *GetVehicleDescription(Ve
 
	static const SaveLoad _ship_desc[] = {
 
		SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
 
		SLE_VEH_INCLUDE(),
 
		     SLE_VAR(Ship, state, SLE_UINT8),
 
		      SLE_VAR(Ship, state,     SLE_UINT8),
 
		SLE_CONDDEQUE(Ship, path,      SLE_UINT8,  203, SL_MAX_VERSION),
 

	
 
		SLE_CONDNULL(16, 2, 143), // old reserved space
 

	
src/ship.h
Show inline comments
 
@@ -12,17 +12,22 @@
 
#ifndef SHIP_H
 
#define SHIP_H
 

	
 
#include <deque>
 

	
 
#include "vehicle_base.h"
 
#include "water_map.h"
 

	
 
void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type);
 
WaterClass GetEffectiveWaterClass(TileIndex tile);
 

	
 
typedef std::deque<TrackdirByte> ShipPathCache;
 

	
 
/**
 
 * All ships have this type.
 
 */
 
struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
 
	TrackBitsByte state; ///< The "track" the ship is following.
 
	ShipPathCache path;  ///< Cached path.
 

	
 
	/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
 
	Ship() : SpecializedVehicleBase() {}
 
@@ -46,6 +51,7 @@ struct Ship FINAL : public SpecializedVe
 
	TileIndex GetOrderStationLocation(StationID station);
 
	bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
 
	void UpdateCache();
 
	void SetDestTile(TileIndex tile);
 
};
 

	
 
static const uint SHIP_MAX_ORDER_DISTANCE = 130;
src/ship_cmd.cpp
Show inline comments
 
@@ -193,7 +193,7 @@ static void CheckIfShipNeedsService(Vehi
 
	}
 

	
 
	v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);
 
	v->dest_tile = depot->xy;
 
	v->SetDestTile(depot->xy);
 
	SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
 
}
 

	
 
@@ -473,10 +473,24 @@ static Track ChooseShipTrack(Ship *v, Ti
 
		}
 
		path_found = false;
 
	} else {
 
		/* Attempt to follow cached path. */
 
		if (!v->path.empty()) {
 
			track = TrackdirToTrack(v->path.front());
 

	
 
			if (HasBit(tracks, track)) {
 
				v->path.pop_front();
 
				/* HandlePathfindResult() is not called here because this is not a new pathfinder result. */
 
				return track;
 
			}
 

	
 
			/* Cached path is invalid so continue with pathfinder. */
 
		}
 

	
 
		v->path.clear();
 
		switch (_settings_game.pf.pathfinder_for_ships) {
 
			case VPF_OPF: track = OPFShipChooseTrack(v, tile, enterdir, tracks, path_found); break;
 
			case VPF_NPF: track = NPFShipChooseTrack(v, tile, enterdir, tracks, path_found); break;
 
			case VPF_YAPF: track = YapfShipChooseTrack(v, tile, enterdir, tracks, path_found); break;
 
			case VPF_YAPF: track = YapfShipChooseTrack(v, tile, enterdir, tracks, path_found, v->path); break;
 
			default: NOT_REACHED();
 
		}
 
	}
 
@@ -665,6 +679,7 @@ getout:
 
reverse_direction:
 
	dir = ReverseDir(v->direction);
 
	v->direction = dir;
 
	v->path.clear();
 
	goto getout;
 
}
 

	
 
@@ -679,6 +694,13 @@ bool Ship::Tick()
 
	return true;
 
}
 

	
 
void Ship::SetDestTile(TileIndex tile)
 
{
 
	if (tile == this->dest_tile) return;
 
	this->path.clear();
 
	this->dest_tile = tile;
 
}
 

	
 
/**
 
 * Build a ship.
 
 * @param tile     tile of the depot where ship is built.
src/station_cmd.cpp
Show inline comments
 
@@ -1980,7 +1980,7 @@ static CommandCost RemoveRoadStop(TileIn
 
		FOR_ALL_ROADVEHICLES(v) {
 
			if (v->First() == v && v->current_order.IsType(OT_GOTO_STATION) &&
 
					v->dest_tile == tile) {
 
				v->dest_tile = v->GetOrderStationLocation(st->index);
 
				v->SetDestTile(v->GetOrderStationLocation(st->index));
 
			}
 
		}
 

	
 
@@ -2604,7 +2604,7 @@ static CommandCost RemoveDock(TileIndex 
 
			}
 

	
 
			if (s->dest_tile == docking_location) {
 
				s->dest_tile = 0;
 
				s->SetDestTile(0);
 
				s->current_order.Free();
 
			}
 
		}
src/vehicle.cpp
Show inline comments
 
@@ -2337,7 +2337,7 @@ CommandCost Vehicle::SendToDepot(DoComma
 
			SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
 
		}
 

	
 
		this->dest_tile = location;
 
		this->SetDestTile(location);
 
		this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
 
		if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
 
		SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
src/vehicle_base.h
Show inline comments
 
@@ -749,6 +749,8 @@ public:
 
	 */
 
	virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
 

	
 
	virtual void SetDestTile(TileIndex tile) { this->dest_tile = tile; }
 

	
 
	CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
 

	
 
	void UpdateVisualEffect(bool allow_power_change = true);
0 comments (0 inline, 0 general)