Fix a rare case where units might get stuck around other idle entities, and clarify a related comment.

Refs #3471

This was SVN commit r17225.
This commit is contained in:
wraitii 2015-11-11 12:28:38 +00:00
parent c42160ec10
commit 3ddd72c1a4
3 changed files with 19 additions and 10 deletions

View File

@ -473,7 +473,7 @@ public:
virtual void GetObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares);
virtual void GetUnitObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares);
virtual void GetStaticObstructionsInRange(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, std::vector<ObstructionSquare>& squares);
virtual void GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter);
virtual void GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter, bool strict = false);
virtual void SetPassabilityCircular(bool enabled)
{
@ -990,7 +990,7 @@ void CCmpObstructionManager::GetStaticObstructionsInRange(const IObstructionTest
}
}
void CCmpObstructionManager::GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter)
void CCmpObstructionManager::GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter, bool strict)
{
PROFILE3("GetUnitsOnObstruction");
@ -1019,12 +1019,17 @@ void CCmpObstructionManager::GetUnitsOnObstruction(const ObstructionSquare& squa
if (rasterizedRects.find(shape.clearance) == rasterizedRects.end())
{
// Wraitii 31/10/15: check out helpers/Rasterize.cpp for more info, but
// a change in the long-range pathfinder rasterization to fix stuck units
// requires the foundation code to be more restrictive, thus adding the substraction
// of Pathfinding::NAVCELL_SIZE. Remove it if the problem in Rasterize.cpp is ever fixed.
// The rasterization is an approximation of the real shapes.
// Depending on your use, you may want to be more or less strict on the rasterization,
// ie this may either return some units that aren't actually on the shape (if strict is set)
// or this may not return some units that are on the shape (if strict is not set).
// Foundations need to be non-strict, as otherwise it sometimes detects the builder units
// as being on the shape, so it orders them away.
SimRasterize::Spans& newSpans = rasterizedRects[shape.clearance];
SimRasterize::RasterizeRectWithClearance(newSpans, square, shape.clearance-Pathfinding::NAVCELL_SIZE, Pathfinding::NAVCELL_SIZE);
if (strict)
SimRasterize::RasterizeRectWithClearance(newSpans, square, shape.clearance, Pathfinding::NAVCELL_SIZE);
else
SimRasterize::RasterizeRectWithClearance(newSpans, square, shape.clearance-Pathfinding::NAVCELL_SIZE, Pathfinding::NAVCELL_SIZE);
}
SimRasterize::Spans& spans = rasterizedRects[shape.clearance];

View File

@ -806,7 +806,6 @@ void CCmpUnitMotion::PathResult(u32 ticket, const WaypointPath& path)
return;
}
}
m_LongPath.m_Waypoints.clear();
RequestLongPath(pos, m_FinalGoal);
m_PathState = PATHSTATE_WAITING_REQUESTING_LONG;
return;
@ -1011,7 +1010,8 @@ void CCmpUnitMotion::Move(fixed dt)
square.x = m_LongPath.m_Waypoints.back().x;
square.z = m_LongPath.m_Waypoints.back().z;
std::vector<entity_id_t> unitOnGoal;
cmpObstructionManager->GetUnitsOnObstruction(square, unitOnGoal, GetObstructionFilter(true, false));
// don't ignore moving units as those might be units like us, ie not really moving.
cmpObstructionManager->GetUnitsOnObstruction(square, unitOnGoal, GetObstructionFilter(false, false), true);
if (!unitOnGoal.empty())
m_LongPath.m_Waypoints.pop_back();
}

View File

@ -244,8 +244,12 @@ public:
/**
* Returns the entity IDs of all unit shapes that intersect the given
* obstruction square, filtering out using the given filter.
* @param square the Obstruction squre we want to compare with.
* @param out output list of obstructions
* @param filter filter for the obstructing units
* @param strict whether to be strict in the check or more permissive (ie rasterize more or less). Default false.
*/
virtual void GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter) = 0;
virtual void GetUnitsOnObstruction(const ObstructionSquare& square, std::vector<entity_id_t>& out, const IObstructionTestFilter& filter, bool strict = false) = 0;
/**
* Get the obstruction square representing the given shape.