| 131 | } // anonymous namespace |
| 132 | |
| 133 | std::list<Vec3<int>> TileMap::findShortestPath(Vec3<int> origin, Vec3<int> destinationStart, |
| 134 | Vec3<int> destinationEnd, int iterationLimit, |
| 135 | const CanEnterTileHelper &canEnterTileHelper, |
| 136 | bool approachOnly, bool ignoreStaticUnits, |
| 137 | bool ignoreMovingUnits, bool ignoreAllUnits, |
| 138 | float *cost, float maxCost) |
| 139 | { |
| 140 | #ifdef PATHFINDING_DEBUG |
| 141 | for (auto &t : tiles) |
| 142 | t.pathfindingDebugFlag = false; |
| 143 | #endif |
| 144 | |
| 145 | maxCost /= canEnterTileHelper.pathOverheadAlloawnce(); |
| 146 | // Faster than looking up in a set |
| 147 | std::vector<bool> visitedTiles = std::vector<bool>(size.x * size.y * size.z, false); |
| 148 | int strideZ = size.x * size.y; |
| 149 | int strideY = size.x; |
| 150 | std::list<PathNode *> nodesToDelete; |
| 151 | std::list<PathNode *> fringe; |
| 152 | Vec3<float> goalPositionStart; |
| 153 | Vec3<float> goalPositionEnd; |
| 154 | bool destinationIsSingleTile = destinationStart == destinationEnd - Vec3<int>{1, 1, 1}; |
| 155 | int iterationCount = 0; |
| 156 | |
| 157 | // Approach Only makes no sense with pathing into a block, but we'll fix it anyway |
| 158 | if (approachOnly && !destinationIsSingleTile) |
| 159 | { |
| 160 | LogWarning("Trying to route from %s to %s-%s in approachOnly mode? Extending destination's " |
| 161 | "xy boundaries by 1.", |
| 162 | origin, destinationStart, destinationEnd); |
| 163 | approachOnly = false; |
| 164 | destinationStart -= |
| 165 | Vec3<int>(destinationStart.x > 0 ? 1 : 0, destinationStart.y > 0 ? 1 : 0, 0); |
| 166 | destinationEnd += |
| 167 | Vec3<int>(destinationEnd.x < size.x ? 1 : 0, destinationEnd.y < size.y ? 1 : 0, 0); |
| 168 | } |
| 169 | |
| 170 | if (destinationIsSingleTile) |
| 171 | { |
| 172 | LogInfo("Trying to route from %s to %s", origin, destinationStart); |
| 173 | } |
| 174 | else |
| 175 | { |
| 176 | LogInfo("Trying to route from %s to %s-%s", origin, destinationStart, destinationEnd); |
| 177 | } |
| 178 | |
| 179 | if (!tileIsValid(origin)) |
| 180 | { |
| 181 | LogError("Bad origin %s", origin); |
| 182 | return {}; |
| 183 | } |
| 184 | if (!tileIsValid(destinationStart)) |
| 185 | { |
| 186 | LogError("Bad destinationStart %s", destinationStart); |
| 187 | return {}; |
| 188 | } |
| 189 | if (destinationEnd.x <= destinationStart.x || destinationEnd.x > this->size.x || |
| 190 | destinationEnd.y <= destinationStart.y || destinationEnd.y > this->size.y || |
no test coverage detected