Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/components/CCmpPathfinder.cpp
Show First 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | |||||
const PathfinderPassability* CCmpPathfinder::GetPassabilityFromMask(pass_class_t passClass) const | const PathfinderPassability* CCmpPathfinder::GetPassabilityFromMask(pass_class_t passClass) const | ||||
{ | { | ||||
for (const PathfinderPassability& passability : m_PassClasses) | for (const PathfinderPassability& passability : m_PassClasses) | ||||
{ | { | ||||
if (passability.m_Mask == passClass) | if (passability.m_Mask == passClass) | ||||
return &passability; | return &passability; | ||||
} | } | ||||
wraitii: I'd rather use cmpObstruction::GetSize for that. It would let players construct tunnels (which… | |||||
Done Inline ActionsIt sounds like a stationary tunnel would work more like building garrison, so it wouldn't need to call this function. causative: It sounds like a stationary tunnel would work more like building garrison, so it wouldn't need… | |||||
return NULL; | return NULL; | ||||
} | } | ||||
const Grid<NavcellData>& CCmpPathfinder::GetPassabilityGrid() | const Grid<NavcellData>& CCmpPathfinder::GetPassabilityGrid() | ||||
{ | { | ||||
if (!m_Grid) | if (!m_Grid) | ||||
UpdateGrid(); | UpdateGrid(); | ||||
return *m_Grid; | return *m_Grid; | ||||
} | } | ||||
Done Inline ActionsCouldn't we replace set by unordered_set in future? vladislavbelov: Couldn't we replace `set` by `unordered_set` in future? | |||||
/** | /** | ||||
Done Inline ActionsI think you should also check right under the "ship" entity, to make this function more general (again, thinking of the "Roc" use-case from AoM) wraitii: I think you should also check right under the "ship" entity, to make this function more general… | |||||
* Given a grid of passable/impassable navcells (based on some passability mask), | * Given a grid of passable/impassable navcells (based on some passability mask), | ||||
* computes a new grid where a navcell is impassable (per that mask) if | * computes a new grid where a navcell is impassable (per that mask) if | ||||
* it is <=clearance navcells away from an impassable navcell in the original grid. | * it is <=clearance navcells away from an impassable navcell in the original grid. | ||||
* The results are ORed onto the original grid. | * The results are ORed onto the original grid. | ||||
* | * | ||||
* This is used for adding clearance onto terrain-based navcell passability. | * This is used for adding clearance onto terrain-based navcell passability. | ||||
* | * | ||||
* TODO PATHFINDER: might be nicer to get rounded corners by measuring clearances as | * TODO PATHFINDER: might be nicer to get rounded corners by measuring clearances as | ||||
* Euclidean distances; currently it effectively does dist=max(dx,dy) instead. | * Euclidean distances; currently it effectively does dist=max(dx,dy) instead. | ||||
Done Inline ActionsSpaces around = and below too. vladislavbelov: Spaces around `=` and below too. | |||||
* This would only really be a problem for big clearances. | * This would only really be a problem for big clearances. | ||||
*/ | */ | ||||
static void ExpandImpassableCells(Grid<NavcellData>& grid, u16 clearance, pass_class_t mask) | static void ExpandImpassableCells(Grid<NavcellData>& grid, u16 clearance, pass_class_t mask) | ||||
{ | { | ||||
PROFILE3("ExpandImpassableCells"); | PROFILE3("ExpandImpassableCells"); | ||||
u16 w = grid.m_W; | u16 w = grid.m_W; | ||||
Done Inline ActionsDo not use count if you only search a value, use reachable.find(landRegion) != reachable. vladislavbelov: Do not use count if you only search a value, use `reachable.find(landRegion) != reachable`. | |||||
Done Inline Actions... != reachable.end(). vladislavbelov: `... != reachable.end()`. | |||||
u16 h = grid.m_H; | u16 h = grid.m_H; | ||||
Done Inline ActionsUnecessary variable, you could just return a value: if (...) return true; // after loop return false; vladislavbelov: Unecessary variable, you could just return a value:
```lang=cpp
if (...)
return true;
//… | |||||
// First expand impassable cells horizontally into a temporary 1-bit grid | // First expand impassable cells horizontally into a temporary 1-bit grid | ||||
Grid<u8> tempGrid(w, h); | Grid<u8> tempGrid(w, h); | ||||
for (u16 j = 0; j < h; ++j) | for (u16 j = 0; j < h; ++j) | ||||
{ | { | ||||
// New cell (i,j) is blocked if (i',j) blocked for any i-clearance <= i' <= i+clearance | // New cell (i,j) is blocked if (i',j) blocked for any i-clearance <= i' <= i+clearance | ||||
// Count the number of blocked cells around i=0 | // Count the number of blocked cells around i=0 | ||||
u16 numBlocked = 0; | u16 numBlocked = 0; | ||||
▲ Show 20 Lines • Show All 554 Lines • ▼ Show 20 Lines | for (PathfinderWorker& worker : m_Workers) | ||||
amount = std::min(amount, from.size()); // Since we are rounding up before, ensure we aren't pushing beyond the end. | amount = std::min(amount, from.size()); // Since we are rounding up before, ensure we aren't pushing beyond the end. | ||||
worker.PushRequests(from, amount); | worker.PushRequests(from, amount); | ||||
from.erase(from.end() - amount, from.end()); | from.erase(from.end() - amount, from.end()); | ||||
} | } | ||||
} | } | ||||
////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////// | ||||
bool CCmpPathfinder::IsGoalReachable(entity_pos_t x0, entity_pos_t z0, const PathGoal& goal, pass_class_t passClass) | |||||
{ | |||||
PROFILE2("IsGoalReachable"); | |||||
u16 i, j; | |||||
Pathfinding::NearestNavcell(x0, z0, i, j, m_MapSize*Pathfinding::NAVCELLS_PER_TILE, m_MapSize*Pathfinding::NAVCELLS_PER_TILE); | |||||
if (!IS_PASSABLE(m_Grid->get(i, j), passClass)) | |||||
m_PathfinderHier->FindNearestPassableNavcell(i, j, passClass); | |||||
return m_PathfinderHier->IsGoalReachable(i, j, goal, passClass); | |||||
} | |||||
bool CCmpPathfinder::CheckMovement(const IObstructionTestFilter& filter, | bool CCmpPathfinder::CheckMovement(const IObstructionTestFilter& filter, | ||||
entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, | entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, | ||||
pass_class_t passClass) const | pass_class_t passClass) const | ||||
{ | { | ||||
PROFILE2_IFSPIKE("Check Movement", 0.001); | PROFILE2_IFSPIKE("Check Movement", 0.001); | ||||
// Test against obstructions first. filter may discard pathfinding-blocking obstructions. | // Test against obstructions first. filter may discard pathfinding-blocking obstructions. | ||||
// Use more permissive version of TestLine to allow unit-unit collisions to overlap slightly. | // Use more permissive version of TestLine to allow unit-unit collisions to overlap slightly. | ||||
▲ Show 20 Lines • Show All 87 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
I'd rather use cmpObstruction::GetSize for that. It would let players construct tunnels (which wouldn't have Motion) or something like that.