Пример #1
0
fixed CCmpPathfinder::GetMovementSpeed(entity_pos_t x0, entity_pos_t z0, u8 costClass)
{
	UpdateGrid();

	u16 i, j;
	NearestTile(x0, z0, i, j);
	TerrainTile tileTag = m_Grid->get(i, j);
	return m_MoveSpeeds.at(costClass).at(GET_COST_CLASS(tileTag));
}
Пример #2
0
// Do the A* processing for a neighbour tile i,j.
static void ProcessNeighbour(u16 pi, u16 pj, u16 i, u16 j, u32 pg, PathfinderState& state)
{
#if PATHFIND_STATS
	state.numProcessed++;
#endif

	// Reject impassable tiles
	TerrainTile tileTag = state.terrain->get(i, j);
	if (!IS_PASSABLE(tileTag, state.passClass) && !state.ignoreImpassable)
		return;

	u32 dg = CalculateCostDelta(pi, pj, i, j, state.tiles, state.moveCosts.at(GET_COST_CLASS(tileTag)));

	u32 g = pg + dg; // cost to this tile = cost to predecessor + delta from predecessor

	PathfindTile& n = state.tiles->get(i, j);

	// If this is a new tile, compute the heuristic distance
	if (n.IsUnexplored())
	{
		n.h = CalculateHeuristic(i, j, state.iGoal, state.jGoal, state.rGoal);
		// Remember the best tile we've seen so far, in case we never actually reach the target
		if (n.h < state.hBest)
		{
			state.hBest = n.h;
			state.iBest = i;
			state.jBest = j;
		}
	}
	else
	{
		// If we've already seen this tile, and the new path to this tile does not have a
		// better cost, then stop now
		if (g >= n.cost)
			return;

		// Otherwise, we have a better path.

		// If we've already added this tile to the open list:
		if (n.IsOpen())
		{
			// This is a better path, so replace the old one with the new cost/parent
			n.cost = g;
			n.SetPred(pi, pj, i, j);
			n.SetStep(state.steps);
			state.open.promote(std::make_pair(i, j), g + n.h);
#if PATHFIND_STATS
			state.numImproveOpen++;
#endif
			return;
		}

		// If we've already found the 'best' path to this tile:
		if (n.IsClosed())
		{
			// This is a better path (possible when we use inadmissible heuristics), so reopen it
#if PATHFIND_STATS
			state.numImproveClosed++;
#endif
			// (fall through)
		}
	}

	// Add it to the open list:
	n.SetStatusOpen();
	n.cost = g;
	n.SetPred(pi, pj, i, j);
	n.SetStep(state.steps);
	PriorityQueue::Item t = { std::make_pair(i, j), g + n.h };
	state.open.push(t);
#if PATHFIND_STATS
	state.numAddToOpen++;
#endif
}