forked from 0ad/0ad
Fix the CheckLineMovement algorithm. Added some comments and a test to avoid problems.
This addresses some "stuck units" cases. This was SVN commit r16918.
This commit is contained in:
parent
01de76f4be
commit
1c9ea56800
@ -171,8 +171,8 @@ namespace Pathfinding
|
||||
// vice versa).
|
||||
|
||||
u16 i0, j0, i1, j1;
|
||||
Pathfinding::NearestNavcell(x0, z0, i0, j0, grid.m_W, grid.m_H);
|
||||
Pathfinding::NearestNavcell(x1, z1, i1, j1, grid.m_W, grid.m_H);
|
||||
NearestNavcell(x0, z0, i0, j0, grid.m_W, grid.m_H);
|
||||
NearestNavcell(x1, z1, i1, j1, grid.m_W, grid.m_H);
|
||||
|
||||
// Find which direction the line heads in
|
||||
int di = (i0 < i1 ? +1 : i1 < i0 ? -1 : 0);
|
||||
@ -185,6 +185,11 @@ namespace Pathfinding
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Make sure we are still in the limits
|
||||
ENSURE(
|
||||
((di > 0 && i0 <= i && i <= i1) || (di < 0 && i1 <= i && i <= i0) || (di == 0 && i == i0)) &&
|
||||
((dj > 0 && j0 <= j && j <= j1) || (dj < 0 && j1 <= j && j <= j0) || (dj == 0 && j == j0)));
|
||||
|
||||
// Fail if we're moving onto an impassable navcell
|
||||
bool passable = IS_PASSABLE(grid.get(i, j), passClass);
|
||||
if (passable)
|
||||
@ -197,12 +202,13 @@ namespace Pathfinding
|
||||
return true;
|
||||
|
||||
// If we can only move horizontally/vertically, then just move in that direction
|
||||
if (di == 0)
|
||||
// If we are reaching the limits, we can go straight to the end
|
||||
if (di == 0 || i == i1)
|
||||
{
|
||||
j += dj;
|
||||
continue;
|
||||
}
|
||||
else if (dj == 0)
|
||||
else if (dj == 0 || j == j1)
|
||||
{
|
||||
i += di;
|
||||
continue;
|
||||
@ -217,6 +223,11 @@ namespace Pathfinding
|
||||
// navcell, we simply need to test that the edge's endpoints are not both on the
|
||||
// same side of the line.
|
||||
|
||||
// If we are crossing exactly a vertex of the grid, we will get dota or dotb equal
|
||||
// to 0. In that case we arbitrarily choose to move of dj.
|
||||
// This only works because we handle the case (i == i1 || j == j1) beforehand.
|
||||
// Otherwise we could go outside the j limits and never reach the final navcell.
|
||||
|
||||
entity_pos_t xia = entity_pos_t::FromInt(i).Multiply(Pathfinding::NAVCELL_SIZE);
|
||||
entity_pos_t xib = entity_pos_t::FromInt(i+1).Multiply(Pathfinding::NAVCELL_SIZE);
|
||||
entity_pos_t zj = entity_pos_t::FromInt(j + (dj+1)/2).Multiply(Pathfinding::NAVCELL_SIZE);
|
||||
|
Loading…
Reference in New Issue
Block a user