| 1433 | } |
| 1434 | |
| 1435 | std::list<Tile*> GameMap::path(int x1, int y1, int x2, int y2, const Creature* creature, Seat* seat, bool throughDiggableTiles) |
| 1436 | { |
| 1437 | ++mNumCallsTo_path; |
| 1438 | std::list<Tile*> returnList; |
| 1439 | |
| 1440 | // If the start tile was not found return an empty path |
| 1441 | Tile* start = getTile(x1, y1); |
| 1442 | if (start == nullptr) |
| 1443 | return returnList; |
| 1444 | |
| 1445 | // If the end tile was not found return an empty path |
| 1446 | Tile* destination = getTile(x2, y2); |
| 1447 | if (destination == nullptr) |
| 1448 | return returnList; |
| 1449 | |
| 1450 | if (creature == nullptr) |
| 1451 | return returnList; |
| 1452 | |
| 1453 | // If flood filling is enabled, we can possibly eliminate this path by checking to see if they two tiles are floodfilled differently. |
| 1454 | if (!throughDiggableTiles && !pathExists(creature, start, destination)) |
| 1455 | return returnList; |
| 1456 | |
| 1457 | AstarEntry *currentEntry = new AstarEntry(start, x1, y1, x2, y2); |
| 1458 | AstarEntry neighbor; |
| 1459 | |
| 1460 | std::vector<AstarEntry*> openList; |
| 1461 | openList.push_back(currentEntry); |
| 1462 | |
| 1463 | // This list will contain the processed and the to process entries |
| 1464 | // allowing to quickly know if a tile has been processed or not |
| 1465 | std::vector<std::vector<AstarEntry*>> processList(getMapSizeX(), std::vector<AstarEntry*>(getMapSizeY(), nullptr)); |
| 1466 | processList[currentEntry->getTile()->getX()][currentEntry->getTile()->getY()] = currentEntry; |
| 1467 | AstarEntry* destinationEntry = nullptr; |
| 1468 | while (true) |
| 1469 | { |
| 1470 | // if the openList is empty we failed to find a path |
| 1471 | if (openList.empty()) |
| 1472 | break; |
| 1473 | |
| 1474 | // openList being sorted, the last element is the smallest |
| 1475 | auto smallestAstar = openList.rbegin(); |
| 1476 | openList.pop_back(); |
| 1477 | |
| 1478 | currentEntry = *smallestAstar; |
| 1479 | currentEntry->setHasBeenProcessed(); |
| 1480 | |
| 1481 | // We found the path, break out of the search loop |
| 1482 | if (currentEntry->getTile() == destination) |
| 1483 | { |
| 1484 | destinationEntry = currentEntry; |
| 1485 | break; |
| 1486 | } |
| 1487 | |
| 1488 | // Check the tiles surrounding the current square |
| 1489 | bool areTilesPassable[4] = {false, false, false, false}; |
| 1490 | // Note : to disable diagonals, process tiles from 0 to 3. To allow them, process tiles from 0 to 7 |
| 1491 | for (unsigned int i = 0; i < 8; ++i) |
| 1492 | { |
no test coverage detected