* @brief Core breadth-first search for pathfinding through boxes. * * This function expands the search from the current Head box to all connected boxes. * It builds a "flow field" where each box's exitBox points toward the target. * * ALGORITHM: * 1. Take the box at Head of the queue. * 2. For each overlapping (connected) box: * a. Check zone compatibility (skip if different zone, unles
| 1770 | * @return true if more boxes remain to expand, false if search exhausted. |
| 1771 | */ |
| 1772 | bool SearchLOT_BFS(LOTInfo* LOT, int depth) |
| 1773 | { |
| 1774 | auto& zone = g_Level.Zones[(int)LOT->Zone][(int)FlipStatus]; |
| 1775 | |
| 1776 | for (int i = 0; i < depth; i++) |
| 1777 | { |
| 1778 | // Search exhausted - no more boxes to expand. |
| 1779 | if (LOT->Head == NO_VALUE) |
| 1780 | { |
| 1781 | LOT->Tail = NO_VALUE; |
| 1782 | return false; |
| 1783 | } |
| 1784 | |
| 1785 | auto* node = &LOT->Node[LOT->Head]; |
| 1786 | |
| 1787 | int index = g_Level.PathfindingBoxes[LOT->Head].overlapIndex; |
| 1788 | int searchZone = zone[LOT->Head]; |
| 1789 | |
| 1790 | bool done = false; |
| 1791 | |
| 1792 | // Iterate through all boxes that overlap with current box. |
| 1793 | if (index >= 0) |
| 1794 | { |
| 1795 | do |
| 1796 | { |
| 1797 | int boxNumber = g_Level.Overlaps[index].box; |
| 1798 | int flags = g_Level.Overlaps[index].flags; |
| 1799 | |
| 1800 | index++; |
| 1801 | |
| 1802 | if (flags & OVERLAP_END_BIT) |
| 1803 | done = true; |
| 1804 | |
| 1805 | if (!CanExpandToBox(LOT, LOT->Head, boxNumber, flags, searchZone, zone)) |
| 1806 | continue; |
| 1807 | |
| 1808 | // SEARCH STATE: Check if we've already visited this box. |
| 1809 | auto* expand = &LOT->Node[boxNumber]; |
| 1810 | if ((node->searchNumber & SEARCH_NUMBER) < (expand->searchNumber & SEARCH_NUMBER)) |
| 1811 | continue; |
| 1812 | |
| 1813 | // Handle blocked path propagation. |
| 1814 | if (node->searchNumber & SEARCH_BLOCKED) |
| 1815 | { |
| 1816 | if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER)) |
| 1817 | continue; |
| 1818 | |
| 1819 | expand->searchNumber = node->searchNumber; |
| 1820 | } |
| 1821 | else |
| 1822 | { |
| 1823 | if ((node->searchNumber & SEARCH_NUMBER) == (expand->searchNumber & SEARCH_NUMBER) && !(expand->searchNumber & SEARCH_BLOCKED)) |
| 1824 | continue; |
| 1825 | |
| 1826 | // Mark blocked boxes but still allow traversal through them. |
| 1827 | if (g_Level.PathfindingBoxes[boxNumber].flags & LOT->BlockMask) |
| 1828 | { |
| 1829 | expand->searchNumber = node->searchNumber | SEARCH_BLOCKED; |
no test coverage detected