Index: source/simulation2/components/CCmpPathfinder.cpp =================================================================== --- source/simulation2/components/CCmpPathfinder.cpp +++ source/simulation2/components/CCmpPathfinder.cpp @@ -670,6 +670,35 @@ } } +bool CCmpPathfinder::MakeGoalReachable(entity_pos_t x0, entity_pos_t z0, PathGoal &goal, pass_class_t passClass) +{ + u16 i0, j0; + Pathfinding::NearestNavcell(x0, z0, i0, j0, m_MapSize*Pathfinding::NAVCELLS_PER_TILE, m_MapSize*Pathfinding::NAVCELLS_PER_TILE); + if (!IS_PASSABLE(m_Grid->get(i0, j0), passClass)) + FindNearestPassableNavcell(i0, j0, passClass); + + return m_LongPathfinder.MakeGoalReachable(i0, j0, goal, passClass); +} + +u32 CCmpPathfinder::FindNearestPassableNavcell(entity_pos_t x, entity_pos_t z, u16& outI, u16& outJ, pass_class_t passClass) +{ + Pathfinding::NearestNavcell(x, z, outI, outJ, m_MapSize*Pathfinding::NAVCELLS_PER_TILE, m_MapSize*Pathfinding::NAVCELLS_PER_TILE); + u16 i0 = outI; + u16 j0 = outJ; + FindNearestPassableNavcell(outI, outJ, passClass); + return abs(i0 - outI) + abs(j0 - outJ); +} + +void CCmpPathfinder::FindNearestPassableNavcell(u16& i, u16& j, pass_class_t passClass) +{ + m_LongPathfinder.FindNearestPassableNavcell(i, j, passClass); +} + +bool CCmpPathfinder::NavcellIsReachable(u16 i0, u16 j0, u16 i1, u16 j1, pass_class_t passClass) +{ + return m_LongPathfinder.NavcellIsReachable(i0, j0, i1, j1, passClass); +} + ////////////////////////////////////////////////////////// // Async path requests: Index: source/simulation2/components/CCmpPathfinder_Common.h =================================================================== --- source/simulation2/components/CCmpPathfinder_Common.h +++ source/simulation2/components/CCmpPathfinder_Common.h @@ -245,6 +245,13 @@ virtual Grid ComputeShoreGrid(bool expandOnWater = false); + virtual bool MakeGoalReachable(entity_pos_t x0, entity_pos_t z0, PathGoal &goal, pass_class_t passClass); + + virtual u32 FindNearestPassableNavcell(entity_pos_t x, entity_pos_t z, u16& outI, u16& outJ, pass_class_t passClass); + void FindNearestPassableNavcell(u16& i, u16& j, pass_class_t passClass); + + virtual bool NavcellIsReachable(u16 i0, u16 j0, u16 i1, u16 j1, pass_class_t passClass); + virtual void ComputePath(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass, WaypointPath& ret) { m_LongPathfinder.ComputePath(x0, z0, goal, passClass, ret); Index: source/simulation2/components/ICmpPathfinder.h =================================================================== --- source/simulation2/components/ICmpPathfinder.h +++ source/simulation2/components/ICmpPathfinder.h @@ -88,6 +88,24 @@ */ virtual Grid ComputeShoreGrid(bool expandOnWater = false) = 0; + /** + * Transform an arbitrary PathGoal into a reachable Point PathGoal, see Hierarchical Pathfinder for details + * Return true if the goal was reachable originally, false otherwise. + */ + virtual bool MakeGoalReachable(entity_pos_t x0, entity_pos_t z0, PathGoal &goal, pass_class_t passClass) = 0; + + /** + * Gives the closest passable navcell from the given position. + * Returns how many navcells away (manhattan) that navcell is. + */ + virtual u32 FindNearestPassableNavcell(entity_pos_t x, entity_pos_t z, u16& outI, u16& outJ, pass_class_t passClass) = 0; + + /** + * Returns true if navcell (i0, j0) has the same global region ID as navcell (i1, j1). + * i.e. you can reach one from the other. + */ + virtual bool NavcellIsReachable(u16 i0, u16 j0, u16 i1, u16 j1, pass_class_t passClass) = 0; + /** * Compute a tile-based path from the given point to the goal, and return the set of waypoints. * The waypoints correspond to the centers of horizontally/vertically adjacent tiles Index: source/simulation2/helpers/LongPathfinder.h =================================================================== --- source/simulation2/helpers/LongPathfinder.h +++ source/simulation2/helpers/LongPathfinder.h @@ -162,6 +162,10 @@ LongPathfinder(); ~LongPathfinder(); +#ifdef TEST + HierarchicalPathfinder& GetHierarchicalPathfinder() { return m_PathfinderHier; } +#endif + void SetDebugOverlay(bool enabled); void SetHierDebugOverlay(bool enabled, const CSimContext *simContext) @@ -237,6 +241,16 @@ void ComputePath(entity_pos_t x0, entity_pos_t z0, const PathGoal& origGoal, pass_class_t passClass, std::vector excludedRegions, WaypointPath& path); + bool MakeGoalReachable(u16 i0, u16 j0, PathGoal &goal, pass_class_t passClass) { return m_PathfinderHier.MakeGoalReachable(i0, j0, goal, passClass); }; + + void FindNearestPassableNavcell(u16& i, u16& j, pass_class_t passClass) { return m_PathfinderHier.FindNearestPassableNavcell(i, j, passClass); }; + + bool NavcellIsReachable(u16 i0, u16 j0, u16 i1, u16 j1, pass_class_t passClass) + { + return m_PathfinderHier.GetGlobalRegion(i0, j0, passClass) == m_PathfinderHier.GetGlobalRegion(i1, j1, passClass); + }; + + Grid GetConnectivityGrid(pass_class_t passClass) { return m_PathfinderHier.GetConnectivityGrid(passClass);