/*-------------------------------------------------------------------------------------------- -- FUNCTION: validateSpawns -- -- DATE: April 7th, 2016 -- -- DESIGNERS: Jaegar Sarauer -- -- REVISIONS: NONE -- -- PROGRAMMERS: Jaegar Sarauer -- -- INTERFACE: bool Map::validateSpawns (int ** map, int ** spawnPoints, int teams) -- int ** map = The map to check for walls and free space. -- int ** spawnPoints = A list of x and y points indicating spawn points. -- int teams = The amount of teams to check. -- -- -- RETURNS: bool = Are all spawns valid? -- -- NOTES: This function will attempt to caluclate if the passed in spawn points are able to -- access eachother determined using A* pathfinding to ensure this is a playable map. -- All untested paths from one spawn point to another is tested with A*, if the -- A* path has nodes in it, then the path was successful and this function will -- return true. ------------------------------------------------------------------------------------------*/ bool Map::validateSpawns (int ** map, int ** spawnPoints, int teams) { const int moveCost = 10; const int diagonalMoveCost = 14; //for each team that exists for (int i = 0; i < teams; i++) { //the x and y position of the team currently path finding from int thisTeamX = spawnPoints[0][i]; int thisTeamY = spawnPoints[1][i]; //for the team that is testing, find a path to all of the other teams for (int j = i + 1; j < teams; j++) { //the x and y position of the team currently path finding to int goalTeamX = spawnPoints[0][j]; int goalTeamY = spawnPoints[1][j]; //find the heuristic values for all points on the map to the goal if (aStarPath (thisTeamX, thisTeamY, goalTeamX, goalTeamY).size () == 0) return false; } } return true; }
void Pathfinding::calculate(BattleUnit *unit, Position endPosition) { Position startPosition = unit->getPosition(); _movementType = unit->getArmor()->getMovementType(); _unit = unit; Tile *destinationTile = _save->getTile(endPosition); // check if destination is not blocked if (isBlocked(destinationTile, MapData::O_FLOOR) || isBlocked(destinationTile, MapData::O_OBJECT)) return; // the following check avoids that the unit walks behind the stairs if we click behind the stairs to make it go up the stairs. // it only works if the unit is on one of the 2 tiles on the stairs, or on the tile right in front of the stairs. if (isOnStairs(startPosition, endPosition)) { endPosition.z++; destinationTile = _save->getTile(endPosition); } // check if we have floor, else lower destination (for non flying units only, because otherwise they never reached this place) while (canFallDown(destinationTile) && _movementType != MT_FLY) { endPosition.z--; destinationTile = _save->getTile(endPosition); } _path.clear(); // look for a possible fast and accurate bresenham path and skip A* if (startPosition.z == endPosition.z && bresenhamPath(startPosition,endPosition)) { std::reverse(_path.begin(), _path.end()); //paths are stored in reverse order return; } // Now try through A*. aStarPath(startPosition, endPosition); }