FIXME: This can be improved with caching of results, though I am not sure if it would be worth it. The way to improve is as follows: After we find a path, we know for sure that this path is optimal for all the subpaths in it. For example, if optimal path from A to D is A->B->C->D, then the optimal path from B to D would certainly be B->C->D, and from A to C will be A->B->C etc. Additionally, sin
| 728 | // |
| 729 | // Obviously, when any update of the LOS block pathfinding happens, this would have to be cleared. |
| 730 | std::list<int> Battle::findLosBlockPath(int origin, int destination, BattleUnitType type, |
| 731 | int iterationLimit) |
| 732 | { |
| 733 | int lbCount = losBlocks.size(); |
| 734 | std::vector<bool> visitedBlocks = std::vector<bool>(lbCount, false); |
| 735 | std::list<LosNode *> nodesToDelete; |
| 736 | std::list<LosNode *> fringe; |
| 737 | int iterationCount = 0; |
| 738 | |
| 739 | LogInfo("Trying to route from lb %d to lb %d", origin, destination); |
| 740 | |
| 741 | if (origin == destination) |
| 742 | { |
| 743 | LogInfo("Origin is destination!"); |
| 744 | return {destination}; |
| 745 | } |
| 746 | |
| 747 | if (!blockAvailable[type][origin]) |
| 748 | { |
| 749 | LogInfo("Origin unavailable!"); |
| 750 | return {}; |
| 751 | } |
| 752 | |
| 753 | if (!blockAvailable[type][destination]) |
| 754 | { |
| 755 | LogInfo("Destination unavailable!"); |
| 756 | return {}; |
| 757 | } |
| 758 | |
| 759 | auto startNode = |
| 760 | new LosNode(0.0f, |
| 761 | BattleUnitTileHelper::getDistanceStatic(blockCenterPos[type][origin], |
| 762 | blockCenterPos[type][destination]), |
| 763 | nullptr, origin); |
| 764 | nodesToDelete.push_back(startNode); |
| 765 | fringe.emplace_back(startNode); |
| 766 | |
| 767 | auto closestNodeSoFar = *fringe.begin(); |
| 768 | |
| 769 | while (iterationCount++ < iterationLimit) |
| 770 | { |
| 771 | auto first = fringe.begin(); |
| 772 | if (first == fringe.end()) |
| 773 | { |
| 774 | LogInfo("No more blocks to expand after %d iterations", iterationCount); |
| 775 | break; |
| 776 | } |
| 777 | auto nodeToExpand = *first; |
| 778 | fringe.erase(first); |
| 779 | |
| 780 | // Skip if we've already expanded this |
| 781 | if (visitedBlocks[nodeToExpand->block]) |
| 782 | { |
| 783 | iterationCount--; |
| 784 | continue; |
| 785 | } |
| 786 | visitedBlocks[nodeToExpand->block] = true; |
| 787 |
nothing calls this directly
no test coverage detected