void initDungeonCells() { for (int x = 0; x < dungeonWidth; x++) { for (int z = 0; z < dungeonDepth; z++) { Vector3Int pos = new Vector3Int(x, 0, z); FloorCell fCell = new FloorCell(pos); fCell.type = FloorCell.FloorCellType.VOID_CELL; foreach (DungeonNode node in dungeonNodes) { if (node.room == null) { continue; } if (fCell.isWithinBoundaries(node.room.firstVert, node.room.lastVert)) { fCell.type = FloorCell.FloorCellType.ROOM_CELL; node.room.floorCells.Add(pos, fCell); break; } } dungeonCells.Add(pos, fCell); } } }
Vector3Int getGateOffset(FloorCell corridorCell) { Vector3Int offset = Vector3Int.zero; List <FloorCell> neis = getNeighbourListOfType(corridorCell, dungeonCells, FloorCell.FloorCellType.ROOM_CELL); if (neis.Count != 1) { Debug.Log("Las celdas vecinas son distintas de 1"); return(offset); } Vector3 diff = neis[0].position - corridorCell.position; if (diff.x == 1) { offset = new Vector3Int(6, 0, 0); } else if (diff.z == 1) { offset = new Vector3Int(0, 0, 6); } return(offset); }
private static void BuildShortestPath(ref List <FloorCell> list, FloorCell node) { if (node.nearestTileToStart == null) { return; } list.Add(node.nearestTileToStart); BuildShortestPath(ref list, node.nearestTileToStart); }
void placePlayer(DungeonNode startingNode) { Room playerRoom = startingNode.roomsInNode.First <Room>(); playerRoom.type = Room.RoomType.PLAYER_ROOM; FloorCell cell = playerRoom.getCentricFloorCell(); player.transform.position = cell.position * cellWidth + offsetVector + new Vector3Int(0, 4, 0); //Debug.Log("Hemos colocado al jugador en" + (cell.position * cellWidth + offsetVector + new Vector3Int(0, 4, 0)) + " en el nodo " + playerRoom.parentNode.NodeId); }
Corridor findCorridorOfCell(FloorCell cell) { if (cell.type != FloorCell.FloorCellType.CORRIDOR_CELL) { return(null); } foreach (Corridor corridor in corridorList) { if (corridor.floorCells.Values.Contains(cell)) { return(corridor); } } return(null); }
public static bool hasNeighbourCellsOfType(FloorCell tile, Dictionary <Vector3Int, FloorCell> FloorCellDictionary, FloorCell.FloorCellType type, int distance = 1) { bool hasNeiCells = false; List <FloorCell> neigbours = new List <FloorCell>(); neigbours = getNeighbourList(tile, FloorCellDictionary); foreach (FloorCell nei in neigbours) { if (nei.type == type) { hasNeiCells = true; break; } } return(hasNeiCells); }
static int getTurningCost(FloorCell currentCell, FloorCell nextCell) { int turningCost = 0; if (currentCell.nearestTileToStart == null) { return(0); } Vector3 diffWithPrevious = currentCell.position - currentCell.nearestTileToStart.position; Vector3 diffWithNext = currentCell.position - nextCell.position; if (Mathf.Abs(diffWithNext.x) != Mathf.Abs(diffWithPrevious.x)) { //Debug.Log("Es un giro"); turningCost = 2; } return(turningCost); }
public static List <FloorCell> getNeighbourList(FloorCell tile, Dictionary <Vector3Int, FloorCell> FloorCellDictionary, int distance = 1) { // Cogemos los vecinos List <FloorCell> neigbours = new List <FloorCell>(); for (int x = -distance; x < distance + 1; x++) { for (int y = -distance; y < distance + 1; y++) { // Cogemos vecinos en cruz if (FloorCellDictionary.ContainsKey(new Vector3Int(x, 0, y) + tile.position) && Mathf.Abs(x) + Mathf.Abs(y) == 1) { FloorCell nei = FloorCellDictionary[new Vector3Int(x, 0, y) + tile.position]; neigbours.Add(nei); } } } return(neigbours); }
Quaternion getGateRotation(FloorCell corridorCell) { Quaternion rotation = Quaternion.identity; List <FloorCell> neis = getNeighbourListOfType(corridorCell, dungeonCells, FloorCell.FloorCellType.ROOM_CELL); if (neis.Count != 1) { Debug.Log("Las celdas vecinas son distintas de 1"); return(rotation); } Vector3 diff = neis[0].position - corridorCell.position; if (Mathf.Abs(diff.x) == 1) { rotation = Quaternion.Euler(0, -90, 0); } return(rotation); }
static void initGraph(Dictionary <Vector3Int, FloorCell> FloorCellDictionary) { List <Vector3Int> keys = new List <Vector3Int>(FloorCellDictionary.Keys); foreach (var tileKey in keys) { FloorCell tile = FloorCellDictionary[tileKey]; tile.MinCostToStart = -1; tile.nearestTileToStart = null; tile.StraightLineDistanceToEnd = -1; tile.visited = false; List <FloorCell> neighbours = DungeonGenerator.getNeighbourList(tile, FloorCellDictionary); foreach (FloorCell nei in neighbours) { FloorCell.Connection connection = new FloorCell.Connection(); connection.cost = 10; connection.ConnectedNode = nei; tile.connections.Add(connection); } } }
public void RegisterTarget(FloorCell cell) { targets.Add(cell); }
public static List <FloorCell> Astar(FloorCell firstPoint, FloorCell endPoint, Dictionary <Vector3Int, FloorCell> FloorCellDictionary, DungeonNode endNode = null) { initGraph(FloorCellDictionary); List <Vector3Int> keys = new List <Vector3Int>(FloorCellDictionary.Keys); foreach (var tileKey in keys) { FloorCellDictionary[tileKey].StraightLineDistanceToEnd = (tileKey - endPoint.position).magnitude; } firstPoint.MinCostToStart = 0; List <FloorCell> prioQueue = new List <FloorCell>(); prioQueue.Add(firstPoint); do { prioQueue.Sort((x, y) => (x.MinCostToStart + x.StraightLineDistanceToEnd).CompareTo(y.MinCostToStart + y.StraightLineDistanceToEnd)); FloorCell node = prioQueue[0]; prioQueue.Remove(node); List <FloorCell.Connection> connections = node.connections; connections.Sort((x, y) => x.cost.CompareTo(y.cost)); foreach (FloorCell.Connection cnn in node.connections) { FloorCell childNode = cnn.ConnectedNode; if (childNode.visited) { continue; } if (childNode.MinCostToStart == -1 || node.MinCostToStart + cnn.cost + getTurningCost(node, childNode) < childNode.MinCostToStart) { childNode.MinCostToStart = node.MinCostToStart + cnn.cost + getTurningCost(node, childNode); childNode.nearestTileToStart = node; if (!prioQueue.Contains(childNode)) { prioQueue.Add(childNode); } } } node.visited = true; if (node.position == endPoint.position) { break; } // Quitar este if para modo normal if (endNode != null) { if (node.type == FloorCell.FloorCellType.ROOM_CELL || node.type == FloorCell.FloorCellType.CORRIDOR_CELL) { Vector3Int firstNodeVert = new Vector3Int(endNode.startX, 0, endNode.startZ); Vector3Int lastNodeVert = new Vector3Int(endNode.endX, 0, endNode.endZ); if (node.isWithinBoundaries(firstNodeVert, lastNodeVert)) { //Debug.Log("La primera es " + firstPoint.position + " el final es " + node.position); endPoint = node; break; } } } } while (prioQueue.Count != 0); //Debug.Log("Coste al inicio" + endPoint.MinCostToStart); List <FloorCell> roadPath = new List <FloorCell>(); BuildShortestPath(ref roadPath, endPoint); roadPath.Remove(firstPoint); roadPath.Remove(endPoint); return(roadPath); }
void spawnCorridors() { foreach (FloorCell cell in dungeonCells.Values) { if (cell.type != FloorCell.FloorCellType.CORRIDOR_CELL) { continue; } // Corridor de la celda Corridor corridor = findCorridorOfCell(cell); GameObject prefabToUse = corridorFloorCell; GameObject.Instantiate(roofModel, cell.position * cellWidth + offsetVector, Quaternion.identity, corridor.corridorGameObject.transform); List <FloorCell> neis = getNeighbourList(cell, dungeonCells); List <FloorCell> corridorNeis = getNeighbourListOfType(cell, dungeonCells, FloorCell.FloorCellType.CORRIDOR_CELL); // Checkeamos si hace esquina if (corridorNeis.Count == 2) { FloorCell corridorCell1 = corridorNeis[0]; FloorCell corridorCell2 = corridorNeis[1]; Vector3Int diffWith1 = corridorCell1.position - cell.position; Vector3Int diffWith2 = corridorCell2.position - cell.position; //Debug.Log(diffWith1 + " vs " + diffWith2); if (Mathf.Abs(diffWith1.x) != Mathf.Abs(diffWith2.x)) { prefabToUse = floorCell; } } else if (corridorNeis.Count > 2) { prefabToUse = floorCell; cell.type = FloorCell.FloorCellType.ROOM_CELL; } bool firstTime = true; foreach (FloorCell nei in neis) { if (nei.type == FloorCell.FloorCellType.VOID_CELL) { int rotationY = 0; Vector3 diff = (nei.position - cell.position); Vector3 offsetPosition = new Vector3(0, 0, 0); Vector3 cellOffset = new Vector3Int(0, 0, 0); if (diff.z == 1) { rotationY = 90; cellOffset.z = 6; } else if (diff.z == -1) { rotationY = 90; cellOffset.z = 6; offsetPosition.z = 4; } else if (diff.x == 1) { offsetPosition.x = 2; } else { offsetPosition.x = 6; } if (firstTime) { GameObject.Instantiate(prefabToUse, cell.position * cellWidth + offsetVector + cellOffset, Quaternion.Euler(0, rotationY, 0), corridor.corridorGameObject.transform); firstTime = false; } GameObject.Instantiate(corridorWallModel, cellPosToGlobal(nei.position) + offsetPosition, Quaternion.Euler(0, rotationY, 0), corridor.corridorGameObject.transform); GameObject.Instantiate(wallTop, cellPosToGlobal(nei.position) + offsetPosition, Quaternion.Euler(0, rotationY, 0), corridor.corridorGameObject.transform); } } } }
void alternatePlaceFinishRoom(DungeonNode startNode, DungeonNode nodeWithStart = null) { DungeonNode finishNode = null; Room playerRoom = startNode.roomsInNode.First <Room>(); foreach (DungeonNode node in dungeonNodes) { if (node.children != null) { continue; } if (node.roomsInNode.First <Room>() == playerRoom) { continue; } if (nodeWithStart.getTotalChildren().Contains(node)) { continue; } Room startingRoom = playerRoom; //Debug.Log("El inicio es " + playerRoom.parentNode.NodeId); int iterationCount = 0; DungeonNode currentNode = node; while (currentNode != null) { DungeonNode bro = currentNode.brother; // ¿El nodo actual tiene el inciio? if (currentNode.roomsInNode.Contains(startingRoom)) { node.distanceToStartRoom = iterationCount; //Debug.Log("El iterationCount para " + node.NodeId + " es " + node.distanceToStartRoom); if (finishNode == null) { finishNode = node; } else if (finishNode.distanceToStartRoom < node.distanceToStartRoom) { finishNode = node; } else if (finishNode.distanceToStartRoom == node.distanceToStartRoom && finishNode.nodeLevel > node.nodeLevel) { finishNode = node; } break; } // ¿ Lo tiene el hermano ? if (bro.roomsInNode.Contains(startingRoom)) { startingRoom = getRoomLeadingToStart(currentNode, startingRoom); iterationCount++; // Reseteamos el padre currentNode = node; } // Ascendemos a nuestro padre else { currentNode = bro.parent; } } } Room finishRoom = finishNode.roomsInNode.First <Room>(); finishRoom.type = Room.RoomType.FINISH_ROOM; //Debug.Log("La cantidad de rooms para poner el final es " + finishNode.roomsInNode.Count); FloorCell fCell = finishRoom.getCentricFloorCell(); GameObject.Instantiate(teleportExit, fCell.position * cellWidth + offsetVector + new Vector3Int(0, 0, 0), Quaternion.identity); //Debug.Log("Hemos colocado el final en" + (fCell.position * cellWidth + offsetVector + new Vector3Int(0, 0, 0)) + " en el nodo " + finishRoom.parentNode.NodeId); }