/// <summary> /// This method is called by the AIController script, when it desires a new path / target /// This returns the world position of a random room, or hallway, that is not the currently occupied one /// </summary> public Vector3 GetRandomCell(Vector3 m_currentPos) { DungeonGridCell currentCell = CurrentCell(m_currentPos); List <DungeonGridCell> randomCell = new List <DungeonGridCell>(); bool targetRoom = (Random.Range(0f, 1f) > .5) ? true : false; if (targetRoom) { foreach (DungeonGridCell room in m_allRooms) { if (room.m_gridPosition == currentCell.m_gridPosition) { continue; } randomCell.Add(room); } } else { foreach (DungeonGridCell hall in m_hallwayPoints) { if (hall.m_gridPosition == currentCell.m_gridPosition) { continue; } randomCell.Add(hall); } } return(randomCell[Random.Range(0, randomCell.Count)].m_worldPos); }
/// <summary> /// Calculates which cell the character is currently in /// </summary> public DungeonGridCell CurrentCell(Vector3 m_currentPos) { DungeonGridCell returnCell = new DungeonGridCell(); int xPos = 0, yPos = 0; for (int x = 0; x < m_currentDungeonType.m_cellsInDungeon.x; x++) { if ((x + 1) * m_currentDungeonType.m_cellSize.x > m_currentPos.x) { xPos = x; break; } } for (int y = 0; y < m_currentDungeonType.m_cellsInDungeon.y; y++) { if ((y + 1) * m_currentDungeonType.m_cellSize.y > m_currentPos.y) { yPos = y; break; } } bool inRoom = false; foreach (DungeonGridCell currentRoom in m_allRooms) { if (currentRoom.m_gridPosition.x == xPos) { if (currentRoom.m_gridPosition.y == yPos) { returnCell = currentRoom; inRoom = true; } } } if (!inRoom) { foreach (DungeonGridCell currentHallway in m_hallwayPoints) { if (currentHallway.m_gridPosition.x == xPos) { if (currentHallway.m_gridPosition.y == yPos) { returnCell = currentHallway; } } } } return(returnCell); }
public void UpdateCellAttendance() { if (m_currentCell != null && m_inRoom) { if (!m_currentCell.IsWithinCell(predictedPlace.position)) { if (m_currentCell.m_currentCellType == DungeonGridCell.CellType.Room) { DungeonManager.Instance.RemoveEntityFromRoom(m_currentCell.m_roomIndex, gameObject); } DungeonGridCell currentGrid = DungeonManager.Instance.CurrentCell(predictedPlace.position); if (currentGrid.IsWithinCell(predictedPlace.position)) { m_inRoom = true; m_currentCell = currentGrid; } else { m_currentCell = null; m_inRoom = false; } } } else { DungeonGridCell currentGrid = DungeonManager.Instance.CurrentCell(predictedPlace.position); if (currentGrid.IsWithinCell(predictedPlace.position)) { m_inRoom = true; m_currentCell = currentGrid; if (m_currentCell.m_currentCellType == DungeonGridCell.CellType.Room) { DungeonManager.Instance.AssignEntityToRoom(m_currentCell.m_roomIndex, gameObject); } } else { m_currentCell = null; m_inRoom = false; } } }
/// <summary> /// Called through an event in the TurnBased manager, when the cycle of agents is complete, and the player is given control again /// This determines whether an enemy should spawn, using a random chance to determine whether it should actually spawn /// If an enemy should spawn, it then uses another random to determine which Ai should spawn from the list of enemies in the dungeon theme scriptable object /// </summary> public void SpawnNewEnemy() { if (AIManager.Instance.m_currentAiOnScene < AIManager.Instance.m_maxAiOnScene) { float randomAi = Random.Range(0f, 1f); if (randomAi < m_dungeonTheme.m_chanceOfEnemySpawn) { AIManager.Instance.m_currentAiOnScene++; DungeonGridCell spawnRoom = m_allRooms[Random.Range(0, m_allRooms.Count)]; List <Vector2> possiblePos = new List <Vector2>(); foreach (Vector2 possibleSpot in spawnRoom.m_floorTiles) { if (!Physics2D.Raycast(possibleSpot, Vector3.forward, 100, m_spawnMask)) { possiblePos.Add(possibleSpot); } } Vector2 spawnPos = possiblePos[Random.Range(0, possiblePos.Count)]; spawnPos += new Vector2(.5f, .5f); randomAi = Random.Range(0f, 1f); foreach (AiStruct ai in m_currentEnemyTypesInDungeon) { if (randomAi < ai.m_aiRarity) { AIController newAi = m_pooler.NewObject(m_aiShell, spawnPos, Quaternion.identity).GetComponent <AIController>(); newAi.InitializeAi(ai.m_entityType); m_turnSystem.NewAgent(newAi.GetComponent <TurnBasedAgent>()); AIManager.Instance.AddAiEntity(newAi.gameObject); return; } } } } }
public abstract void RoomConnections(DungeonManager p_gen, DungeonTheme p_dungeonTheme, DungeonGridCell[,] p_allCells, DungeonGridCell p_currentCell, ConnectionPoint p_currentConnectionPoint, ref int[,] p_dungeonGrid);
public abstract void CreateCorridor(DungeonManager p_gen, DungeonTheme p_dungeonTheme, Vector3Int p_startPos, Vector3Int p_endPos, DungeonGridCell p_currentCell, ref int[,] p_dungeonGrid);
public abstract DungeonGridCell CreateRoom(DungeonManager p_gen, DungeonTheme p_dungeonTheme, Vector3Int p_roomPosition, DungeonGridCell p_currentCell, DungeonGridCell[,] p_allCells, ref int[,] p_dungeonGrid);
public override void RoomConnections(DungeonManager p_gen, DungeonTheme p_dungeonTheme, DungeonGridCell[,] p_allCells, DungeonGridCell p_currentCell, ConnectionPoint p_currentConnectionPoint, ref int[,] p_dungeonGrid) { Vector2Int neighbourIndex = new Vector2Int(); if (p_currentConnectionPoint.currentConnectionType != ConnectionPoint.ConnectionType.Node) { if (p_currentConnectionPoint.currentConnectionType == ConnectionPoint.ConnectionType.Left) { neighbourIndex = new Vector2Int(p_currentCell.m_gridPosition.x - 1, p_currentCell.m_gridPosition.y); if (p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectedTo.Contains(p_currentCell.m_gridPosition)) { return; } foreach (ConnectionPoint neighbour in p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectionPoints) { if (neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Right || neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Node) { CreateHallway(p_gen, p_dungeonTheme, p_currentConnectionPoint.m_connectionPos, neighbour.m_connectionPos, ref p_dungeonGrid); } } } else if (p_currentConnectionPoint.currentConnectionType == ConnectionPoint.ConnectionType.Right) { neighbourIndex = new Vector2Int(p_currentCell.m_gridPosition.x + 1, p_currentCell.m_gridPosition.y); if (p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectedTo.Contains(p_currentCell.m_gridPosition)) { return; } foreach (ConnectionPoint neighbour in p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectionPoints) { if (neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Left || neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Node) { CreateHallway(p_gen, p_dungeonTheme, p_currentConnectionPoint.m_connectionPos, neighbour.m_connectionPos, ref p_dungeonGrid); } } } else if (p_currentConnectionPoint.currentConnectionType == ConnectionPoint.ConnectionType.Up) { neighbourIndex = new Vector2Int(p_currentCell.m_gridPosition.x, p_currentCell.m_gridPosition.y + 1); if (p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectedTo.Contains(p_currentCell.m_gridPosition)) { return; } foreach (ConnectionPoint neighbour in p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectionPoints) { if (neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Down || neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Node) { CreateHallway(p_gen, p_dungeonTheme, p_currentConnectionPoint.m_connectionPos, neighbour.m_connectionPos, ref p_dungeonGrid); } } } else if (p_currentConnectionPoint.currentConnectionType == ConnectionPoint.ConnectionType.Down) { neighbourIndex = new Vector2Int(p_currentCell.m_gridPosition.x, p_currentCell.m_gridPosition.y - 1); if (p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectedTo.Contains(p_currentCell.m_gridPosition)) { return; } foreach (ConnectionPoint neighbour in p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectionPoints) { if (neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Up || neighbour.currentConnectionType == ConnectionPoint.ConnectionType.Node) { CreateHallway(p_gen, p_dungeonTheme, p_currentConnectionPoint.m_connectionPos, neighbour.m_connectionPos, ref p_dungeonGrid); } } } p_allCells[neighbourIndex.x, neighbourIndex.y].m_connectedTo.Add(p_currentCell.m_gridPosition); p_currentCell.m_connectedTo.Add(p_allCells[neighbourIndex.x, neighbourIndex.y].m_gridPosition); } else { for (int x = -1; x < 1; x++) { for (int y = -1; y < 1; y++) { if (x == 0 && y == 0 || x == -1 && y != 0 || x == 1 && y != 0 || x != 0 && y == -1 || x != 0 && y == 1) { continue; } if (x + p_currentCell.m_gridPosition.x < 0 || x + p_currentCell.m_gridPosition.x > m_cellsInDungeon.x - 1) { continue; } if (y + p_currentCell.m_gridPosition.y < 0 || y + p_currentCell.m_gridPosition.y > m_cellsInDungeon.y - 1) { continue; } DungeonGridCell neighbourCell = p_allCells[p_currentCell.m_gridPosition.x + x, p_currentCell.m_gridPosition.y + y]; if (neighbourCell.m_currentCellType == DungeonGridCell.CellType.Hallway) { if (!neighbourCell.m_connectedTo.Contains(p_currentCell.m_gridPosition)) { neighbourCell.m_connectedTo.Add(p_currentCell.m_gridPosition); p_currentCell.m_connectedTo.Add(neighbourCell.m_gridPosition); CreateHallway(p_gen, p_dungeonTheme, p_currentConnectionPoint.m_connectionPos, neighbourCell.m_connectionPoints[0].m_connectionPos, ref p_dungeonGrid); } } } } } }
public override DungeonGridCell CreateRoom(DungeonManager p_gen, DungeonTheme p_dungeonTheme, Vector3Int p_roomPosition, DungeonGridCell p_currentCell, DungeonGridCell[,] p_allCells, ref int[,] p_dungeonGrid) { Vector2Int bounds = new Vector2Int(m_cellSize.x - m_cellBoarder, m_cellSize.y - m_cellBoarder); Vector2Int roomSize = new Vector2Int(Random.Range(m_minRoomSize.x, m_maxRoomSize.x), Random.Range(m_minRoomSize.y, m_maxRoomSize.y)); Vector2Int randomStart = new Vector2Int(Random.Range(m_cellBoarder, bounds.x - roomSize.x), Random.Range(m_cellBoarder, bounds.y - roomSize.y)); //p_currentCell.m_worldPos = new Vector3(randomStart.x + p_roomPosition.x + .5f, randomStart.y + p_roomPosition.y + .5f); p_currentCell.m_worldPos = new Vector3(randomStart.x + p_roomPosition.x + ((float)roomSize.x / 2), randomStart.y + p_roomPosition.y + ((float)roomSize.y / 2)); p_currentCell.m_roomSize = roomSize; Vector3 pos = p_currentCell.m_worldPos; //GameObject.Instantiate(m_debugCube, pos - Vector3.forward*3, Quaternion.identity); List <Vector2> floorTiles = new List <Vector2>(); for (int x = randomStart.x; x < roomSize.x + randomStart.x; x++) { for (int y = randomStart.y; y < roomSize.y + randomStart.y; y++) { p_dungeonGrid[x + p_roomPosition.x, y + p_roomPosition.y] = 1; //GameObject.Instantiate(m_debugCube2, new Vector3(p_roomPosition.x + x + .5f, p_roomPosition.y +y + .5f), Quaternion.identity); if (x > randomStart.x && x < roomSize.x + randomStart.x - 1 && y > randomStart.y && y < roomSize.y + randomStart.y - 1) { floorTiles.Add(new Vector2(x + p_roomPosition.x, y + p_roomPosition.y)); } } } p_currentCell.m_floorTiles = floorTiles; for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { if (x == 0 && y == 0 || x == -1 && y != 0 || x == 1 && y != 0 || x != 0 && y == -1 || x != 0 && y == 1) { continue; } if (x + p_currentCell.m_gridPosition.x < 0 || x + p_currentCell.m_gridPosition.x > m_cellsInDungeon.x - 1) { continue; } if (y + p_currentCell.m_gridPosition.y < 0 || y + p_currentCell.m_gridPosition.y > m_cellsInDungeon.y - 1) { continue; } if (p_allCells[x + p_currentCell.m_gridPosition.x, y + p_currentCell.m_gridPosition.y].m_connectedTo.Contains(p_currentCell.m_gridPosition)) { continue; } if (p_allCells[x + p_currentCell.m_gridPosition.x, y + p_currentCell.m_gridPosition.y].m_currentCellType == DungeonGridCell.CellType.Hallway || p_allCells[x + p_currentCell.m_gridPosition.x, y + p_currentCell.m_gridPosition.y].m_currentCellType == DungeonGridCell.CellType.Room) { Vector3Int connectionPos = new Vector3Int(); ConnectionPoint.ConnectionType connectType = ConnectionPoint.ConnectionType.Node; if (y > 0) { connectionPos = new Vector3Int(Random.Range(0, roomSize.x) + p_roomPosition.x + randomStart.x, roomSize.y + p_roomPosition.y + randomStart.y, 0); connectType = ConnectionPoint.ConnectionType.Up; } else if (y < 0) { connectionPos = new Vector3Int(Random.Range(0, roomSize.x) + p_roomPosition.x + randomStart.x, p_roomPosition.y + randomStart.y - 1, 0); connectType = ConnectionPoint.ConnectionType.Down; } else if (x > 0) { connectionPos = new Vector3Int(roomSize.x + p_roomPosition.x + randomStart.x, Random.Range(0, roomSize.y) + p_roomPosition.y + randomStart.y, 0); connectType = ConnectionPoint.ConnectionType.Right; } else if (x < 0) { connectionPos = new Vector3Int(p_roomPosition.x + randomStart.x - 1, Random.Range(0, roomSize.y) + p_roomPosition.y + randomStart.y, 0); connectType = ConnectionPoint.ConnectionType.Left; } p_dungeonGrid[connectionPos.x, connectionPos.y] = 1; p_currentCell.AddConnectionPoint(connectionPos, connectType); } } } return(p_currentCell); }
public override void CreateCorridor(DungeonManager p_gen, DungeonTheme p_dungeonTheme, Vector3Int p_startPos, Vector3Int p_endPos, DungeonGridCell p_currentCell, ref int[,] p_dungeonGrid) { p_currentCell.m_worldPos = (Vector3)p_endPos + new Vector3(.5f, .5f, 0f); p_gen.m_hallwayPoints.Add(p_currentCell); p_dungeonGrid[p_endPos.x, p_endPos.y] = 1; }
public override List <DungeonGridCell> CreateDungeon(DungeonManager p_gen, DungeonTheme p_dungeonTheme, DungeonNavigation p_dungeonNav) { p_gen.m_allCells = new DungeonGridCell[m_cellsInDungeon.x, m_cellsInDungeon.y]; ///Generates a random amount of room cells #region Room Cell Generation int numOfRooms = Random.Range(m_minRooms, m_maxRooms); List <int> roomCells = new List <int>(); List <int> emptyCells = new List <int>(); List <DungeonGridCell> returningRoomCells = new List <DungeonGridCell>(); int cellCount = m_cellsInDungeon.x * m_cellsInDungeon.y; for (int z = 0; z < cellCount; z++) { roomCells.Add(z); } //Create the number of rooms for (int i = 0; i < cellCount - numOfRooms; i++) { int currentCellIndex = Random.Range(0, roomCells.Count); emptyCells.Add(roomCells[currentCellIndex]); roomCells.RemoveAt(currentCellIndex); } #endregion #region Hallway Cell Generation //The hallways int currentCorridors = Random.Range((int)((float)emptyCells.Count * m_minEmptyPercent), (int)((float)emptyCells.Count * m_maxEmptyPercent)); for (int c = 0; c < cellCount - numOfRooms; c++) { if (c >= currentCorridors) { int currentCellIndex = Random.Range(0, emptyCells.Count); emptyCells.RemoveAt(currentCellIndex); } } #endregion #region Creates the connections between cells int currentIndex = 0; for (int x = 0; x < m_cellsInDungeon.x; x++) { for (int y = 0; y < m_cellsInDungeon.y; y++) { p_gen.m_allCells[x, y] = new DungeonGridCell(); p_gen.m_allCells[x, y].m_connectionPoints = new List <ConnectionPoint>(); p_gen.m_allCells[x, y].m_connectedTo = new List <Vector2Int>(); //Create the rooms if (roomCells.Contains(currentIndex)) { p_gen.m_allCells[x, y].ChangeCellType(DungeonGridCell.CellType.Room); } else if (emptyCells.Contains(currentIndex)) { p_gen.m_allCells[x, y].ChangeCellType(DungeonGridCell.CellType.None); } //The connection points else { p_gen.m_allCells[x, y].ChangeCellType(DungeonGridCell.CellType.Hallway); Vector2Int bounds = new Vector2Int(m_cellSize.x - m_cellBoarder, m_cellSize.y - m_cellBoarder); Vector3Int newPos = new Vector3Int(Random.Range(2, bounds.x) + (x * m_cellSize.x), Random.Range(2, bounds.y) + (y * m_cellSize.y), 0); p_gen.m_allCells[x, y].AddConnectionPoint(newPos, ConnectionPoint.ConnectionType.Node); } currentIndex++; } } #endregion int[,] dungeonGrid = new int[m_cellsInDungeon.x * m_cellSize.x, m_cellsInDungeon.y *m_cellSize.y]; //Draw the boarder /*for (int x = -m_dungeonMapBounds.x; x < m_cellsInDungeon.x * m_cellSize.x + m_dungeonMapBounds.x; x++) * { * for (int y = -m_dungeonMapBounds.y; y < m_cellsInDungeon.y * m_cellSize.y + m_dungeonMapBounds.y; y++) * { * if(x > dungeonGrid.GetLength(0)) * { * Debug.LogError("X Too big: " + x); * } * else if (y > dungeonGrid.GetLength(1)) * { * Debug.LogError("Y Too big: " + y); * } * dungeonGrid[x, y] = 0; * * } * }*/ //Get the items structs p_dungeonTheme.FixRates(); List <ItemStruct> itemsInDungeon = p_dungeonTheme.ItemsInDungeon(); //Assign the tiles to the 2d array grid for (int x = 0; x < m_cellsInDungeon.x; x++) { for (int y = 0; y < m_cellsInDungeon.y; y++) { p_gen.m_allCells[x, y].SetGridPosition(new Vector2Int(x, y)); switch (p_gen.m_allCells[x, y].m_currentCellType) { case DungeonGridCell.CellType.Room: DungeonGridCell roomCell = CreateRoom(p_gen, p_dungeonTheme, new Vector3Int(x * m_cellSize.x, y * m_cellSize.y, 0), p_gen.m_allCells[x, y], p_gen.m_allCells, ref dungeonGrid); PopulateRoomWithItems(p_gen, p_dungeonTheme, roomCell.m_floorTiles, itemsInDungeon); roomCell.m_roomIndex = returningRoomCells.Count; returningRoomCells.Add(roomCell); break; case DungeonGridCell.CellType.HallwayOneWay: break; case DungeonGridCell.CellType.Hallway: CreateCorridor(p_gen, p_dungeonTheme, Vector3Int.zero, p_gen.m_allCells[x, y].m_connectionPoints[0].m_connectionPos, p_gen.m_allCells[x, y], ref dungeonGrid); break; case DungeonGridCell.CellType.None: break; } } } //Create the room connections for (int x = 0; x < m_cellsInDungeon.x; x++) { for (int y = 0; y < m_cellsInDungeon.y; y++) { p_gen.m_allRooms.Add(p_gen.m_allCells[x, y]); foreach (ConnectionPoint connectedPoint in p_gen.m_allCells[x, y].m_connectionPoints) { RoomConnections(p_gen, p_dungeonTheme, p_gen.m_allCells, p_gen.m_allCells[x, y], connectedPoint, ref dungeonGrid); } } } Vector2Int gridLength = new Vector2Int(dungeonGrid.GetLength(0), dungeonGrid.GetLength(1)); //Draw the tiles on the tilemaps for (int x = -m_dungeonMapBounds.x; x < dungeonGrid.GetLength(0) + m_dungeonMapBounds.x; x++) { for (int y = -m_dungeonMapBounds.y; y < dungeonGrid.GetLength(1) + m_dungeonMapBounds.y; y++) { if (x < 0 || x > gridLength.x - 1 || y < 0 || y > gridLength.y - 1) { p_gen.m_wallTiles.SetTile(new Vector3Int(x, y, 0), p_dungeonTheme.m_wallTile); continue; } ///Wall if (dungeonGrid[x, y] == 0) { p_gen.m_wallTiles.SetTile(new Vector3Int(x, y, 0), p_dungeonTheme.m_wallTile); } ///Floor else if (dungeonGrid[x, y] == 1) { p_gen.m_floorTiles.SetTile(new Vector3Int(x, y, 0), p_dungeonTheme.m_floorTile); p_gen.m_miniMapTiles.SetTile(new Vector3Int(x, y, 0), p_gen.m_miniMapTile); } } } p_dungeonNav.m_gridWorldSize = new Vector2(m_cellSize.x * m_cellsInDungeon.x, m_cellSize.y * m_cellsInDungeon.y); p_dungeonNav.m_gridOrigin = p_dungeonNav.m_gridWorldSize / 2; p_dungeonNav.CreateGrid(); return(returningRoomCells); }
public void Reinitialize() { m_currentCell = null; m_inRoom = false; }