void SetEndingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); // Destroy all old level goal objects var oldGoals = GameObject.FindObjectsOfType <LevelEndGoal2D>(); foreach (var oldGoal in oldGoals) { var oldGoalObj = oldGoal.gameObject; if (oldGoalObj != null) { if (Application.isPlaying) { Destroy(oldGoalObj); } else { DestroyImmediate(oldGoalObj); } } } var goal = Instantiate(levelEndGoalTemplate) as GameObject; goal.transform.position = FlipYZ(roomCenter); if (goal.GetComponent <LevelEndGoal2D>() == null) { Debug.LogWarning("No LevelGoal component attached to the Level goal prefab. cleanup will not be proper"); } }
void SetEndingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); // Destroy all old level goal objects var oldGoals = GameObject.FindObjectsOfType<DAShooter.LevelGoal>(); foreach (var oldGoal in oldGoals) { var oldGoalObj = oldGoal.gameObject; if (oldGoalObj != null) { if (Application.isPlaying) { Destroy(oldGoalObj); } else { DestroyImmediate(oldGoalObj); } } } var goal = Instantiate(levelEndGoalTemplate) as GameObject; goal.transform.position = roomCenter; if (goal.GetComponent<DAShooter.LevelGoal>() == null) { Debug.LogWarning("No LevelGoal component attached to the Level goal prefab. cleanup will not be proper"); } }
void DecorateRoom(Dungeon dungeon, GridDungeonModel gridModel, Cell cell, Graph theme) { if (theme == null || cell == null) { return; } // Grid size used to convert logical grid coords to world coords var gridSize = gridModel.Config.GridCellSize; Vector3 position = cell.Bounds.Location * gridSize; Vector3 size = cell.Bounds.Size * gridSize; var center = position + size / 2.0f; var scale = size; scale.y = 5; // Fixed height of the volume. Optionally make this customizable var volumeObject = Instantiate(themeVolumeTemplate.gameObject) as GameObject; volumeObject.transform.position = center; volumeObject.transform.localScale = scale; var volume = volumeObject.GetComponent <ThemeOverrideVolume>(); volume.dungeon = dungeon; // Let the volume know that it belongs to this dungeon volume.overrideTheme = theme; // Assign the theme we'd like this volume to override // Save a reference to the volume so we can destroy it when it is rebuilt the next time (or we will end up with duplicate volumes on rebuilds) managedVolumes.Add(volumeObject); }
bool ConfigMatches(GridDungeonModel Model, IntVector Point, CellSpatialConfig3D Config) { var centerCellInfo = Model.GetGridCellLookup(Point.x, Point.z); var neighbors = Config.NeighborConfig; for (int i = 0; i < neighbors.Length; i++) { int code = neighbors[i]; if (code == 0) { // Don't care about this cell continue; } int dx = i % 3; int dz = i / 3; dx--; dz--; // bring to -1..1 range (from previous 0..2) //dy *= -1; int x = Point.x + dx; int z = Point.z + dz; var cellInfo = Model.GetGridCellLookup(x, z); bool empty = cellInfo.CellType == CellType.Unknown; if (!centerCellInfo.ContainsDoor) { empty |= IsRoomCorridor(centerCellInfo.CellType, cellInfo.CellType); } if (!empty && centerCellInfo.CellType == CellType.Room && cellInfo.CellType == CellType.Room && centerCellInfo.CellId != cellInfo.CellId) { if (!mergeRoomCorridor) { empty = true; } } if (!empty) { var cell0 = Model.GetCell(cellInfo.CellId); var cell1 = Model.GetCell(centerCellInfo.CellId); if (cell0.Bounds.Location.y != cell1.Bounds.Location.y) { empty = true; } } if (code == 1 && empty) { // We were expecting a non-empty space here, but it is empty return(false); } else if (code == 2 && !empty) { // We were expecting a empty space here, but it is not empty return(false); } } // Matches, all tests have passed return(true); }
void SetStartingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); // Teleport the player here var player = GameObject.FindGameObjectWithTag(GameTags.Player); if (player != null) { player.transform.position = roomCenter; } }
void EmitCornerMarker(DungeonBuilder builder, GridDungeonModel model, IntVector point, float angleY, string markerName) { var gridSize = model.Config.GridCellSize; var position = point * gridSize; position += Vector3.Scale(new Vector3(0.5f, 0, 0.5f), gridSize); var rotation = Quaternion.Euler(0, angleY, 0); var transform = Matrix4x4.TRS(position, rotation, Vector3.one); builder.EmitMarker(markerName, transform, point, -1); }
void SetStartingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); // Teleport the player here var player = GameObject.FindGameObjectWithTag(DAShooter.GameTags.Player); if (player != null) { player.transform.position = FlipYZ(roomCenter); } }
void UpdateTerrainTextures(GridDungeonModel model) { if (terrain == null || terrain.terrainData == null) { return; } var data = terrain.terrainData; var map = data.GetAlphamaps(0, 0, data.alphamapWidth, data.alphamapHeight); UpdateBaseTexture(model, map); data.SetAlphamaps(0, 0, map); }
void EmitForPoint(DungeonBuilder builder, GridDungeonModel model, IntVector point) { foreach (var config in CornerConfigs) { if (ConfigMatches(model, point, config)) { EmitCornerMarker(builder, model, point, config.RotationOffsetZ, config.MarkerName); if (config.StopOnFound) { break; } } } }
void Start() { if (dungeon != null) { // Requires a rebuild for now as the state is not fully saved (data in hash sets is not serialized properly) dungeon.Build(); gridModel = dungeon.GetComponent <GridDungeonModel>(); } // Setup materials materialCursor = CreateMaterial(Color.white); materialCorridors = CreateMaterial(Color.yellow); materialRooms = CreateMaterial(Color.red); }
bool HasDirectPath(GridDungeonModel gridModel, Cell cellA, Cell cellB) { bool directPath = true; if (cellA.CellType == CellType.Room || cellB.CellType == CellType.Room) { directPath = gridModel.DoorManager.ContainsDoorBetweenCells(cellA.Id, cellB.Id); } else { // Check if we have a fence separating them if they have different heights if (cellA.Bounds.Location.y != cellB.Bounds.Location.y) { directPath = gridModel.ContainsStair(cellA.Id, cellB.Id); } } return directPath; }
void FindStartEndRooms(GridDungeonModel gridModel, out Cell spawnCell, out Cell finalBossCell) { var furthestCells = GridDungeonModelUtils.FindFurthestRooms(gridModel); if (furthestCells.Length == 2 && furthestCells[0] != null && furthestCells[1] != null) { spawnCell = furthestCells[0]; finalBossCell = furthestCells[1]; } else { spawnCell = null; finalBossCell = null; } }
void UpdateTerrainDetails(GridDungeonModel model) { if (terrain == null || terrain.terrainData == null) { return; } var data = terrain.terrainData; for (int layer = 0; layer < data.alphamapLayers; layer++) { var map = data.GetDetailLayer(0, 0, data.detailWidth, data.detailHeight, layer); UpdateDetailTexture(model, map); data.SetDetailLayer(0, 0, layer, map); } }
void DrawOverlayData(GridDungeonConfig config, GridDungeonModel model, bool mode2D) { var mode = target as DungeonPaintModeGrid; var opacity = mode.overlayOpacity; var gridSize = config.GridCellSize; var cellColorProcedural = Color.blue; var cellColorUserDefined = Color.cyan; // Visualize the user defined cells defined by the paint tool foreach (var cell in model.Cells) { var size = Vector3.Scale(DMathUtils.ToVector3(cell.Bounds.Size), gridSize); var location = Vector3.Scale(DMathUtils.ToVector3(cell.Bounds.Location), gridSize); var color = cell.UserDefined ? cellColorUserDefined : cellColorProcedural; DrawRect(location, size, color, opacity, 0.3f, mode2D); } }
void SetEndingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); // Destroy old level end goal var oldGoal = GameObject.FindGameObjectWithTag(GameTags.LevelGoal); if (oldGoal != null) { if (Application.isPlaying) { Destroy (oldGoal); } else { DestroyImmediate(oldGoal); } } var goal = Instantiate(levelEndGoalTemplate) as GameObject; goal.tag = GameTags.LevelGoal; goal.transform.position = roomCenter; }
void UpdateBaseTexture(GridDungeonModel model, float[, ,] map) { var gridSize = model.Config.GridCellSize; var layoutMap = new float[map.GetLength(0), map.GetLength(1)]; foreach (var cell in model.Cells) { var bounds = cell.Bounds; var locationGrid = bounds.Location; var location = locationGrid * gridSize; var size = bounds.Size * gridSize; int gx1, gy1, gx2, gy2; LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x, location.z, out gx1, out gy1); LandscapeDataRasterizer.WorldToTerrainTextureCoord(terrain, location.x + size.x, location.z + size.z, out gx2, out gy2); for (var gx = gx1; gx <= gx2; gx++) { for (var gy = gy1; gy <= gy2; gy++) { layoutMap[gy, gx] = 1; } } } // Blur the layout data var filter = new BlurFilter(roadBlurDistance); layoutMap = filter.ApplyFilter(layoutMap); var data = terrain.terrainData; // Fill up the inner region with corridor index for (var y = 0; y < data.alphamapHeight; y++) { for (var x = 0; x < data.alphamapWidth; x++) { bool corridor = (layoutMap[y, x] > corridorBlurThreshold); if (corridor) { for (int layer = 0; layer < data.alphamapLayers; layer++) { var weight = (layer == corridorTextureIndex) ? 1 : 0; map[y, x, layer] = weight; } } } } }
bool HasDirectPath(GridDungeonModel gridModel, Cell cellA, Cell cellB) { bool directPath = true; if (cellA.CellType == CellType.Room || cellB.CellType == CellType.Room) { directPath = gridModel.DoorManager.ContainsDoorBetweenCells(cellA.Id, cellB.Id); } else { // Check if we have a fence separating them if they have different heights if (cellA.Bounds.Location.y != cellB.Bounds.Location.y) { directPath = gridModel.ContainsStair(cellA.Id, cellB.Id); } } return(directPath); }
void UpdateDetailTexture(GridDungeonModel model, int[,] map) { var gridSize = model.Config.GridCellSize; foreach (var cell in model.Cells) { var bounds = cell.Bounds; var locationGrid = bounds.Location; var location = locationGrid * gridSize; var size = bounds.Size * gridSize; int gx1, gy1, gx2, gy2; LandscapeDataRasterizer.WorldToTerrainDetailCoord(terrain, location.x, location.z, out gx1, out gy1); LandscapeDataRasterizer.WorldToTerrainDetailCoord(terrain, location.x + size.x, location.z + size.z, out gx2, out gy2); for (var gx = gx1; gx <= gx2; gx++) { for (var gy = gy1; gy <= gy2; gy++) { map[gy, gx] = 0; } } } }
void SetEndingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); // Destroy old level end goal var oldGoal = GameObject.FindGameObjectWithTag(GameTags.LevelGoal); if (oldGoal != null) { if (Application.isPlaying) { Destroy(oldGoal); } else { DestroyImmediate(oldGoal); } } var goal = Instantiate(levelEndGoalTemplate) as GameObject; goal.tag = GameTags.LevelGoal; goal.transform.position = roomCenter; }
void PostInitializeForGridBuilder(Dungeon dungeon, GridDungeonModel gridModel) { var _groupInfoArray = GameObject.FindObjectsOfType <DungeonItemGroupInfo>(); Dictionary <int, DungeonItemGroupInfo> groupObjectByCellId = new Dictionary <int, DungeonItemGroupInfo>(); foreach (var groupInfo in _groupInfoArray) { if (groupInfo.dungeon == dungeon) { var cellId = groupInfo.groupId; var cell = gridModel.GetCell(cellId); if (cell == null || cell.CellType == CellType.Unknown) { continue; } string objectNamePrefix = ""; if (cell.CellType == CellType.Room) { objectNamePrefix = "Room_"; } else { groupObjectByCellId[cell.Id] = groupInfo; objectNamePrefix = (cell.CellType == CellType.Corridor) ? "CorridorBlock_" : "CorridorPad_"; } if (objectNamePrefix.Length == 0) { objectNamePrefix = "Cell_"; } string groupName = objectNamePrefix + cell.Id; groupInfo.gameObject.name = groupName; } } var visited = new HashSet <int>(); int clusterCounter = 1; var oldGroupsToDelete = new List <GameObject>(); foreach (var groupInfo in groupObjectByCellId.Values) { var cellId = groupInfo.groupId; if (visited.Contains(cellId)) { continue; } var clusters = GridBuilderUtils.GetCellCluster(gridModel, cellId); var itemsToGroup = new List <GameObject>(); // Mark all cluster cells as visited foreach (var clusterItemId in clusters) { visited.Add(clusterItemId); if (groupObjectByCellId.ContainsKey(clusterItemId)) { var clusterItemGroupInfo = groupObjectByCellId[clusterItemId]; for (int i = 0; i < clusterItemGroupInfo.transform.childCount; i++) { var childObject = clusterItemGroupInfo.transform.GetChild(i); itemsToGroup.Add(childObject.gameObject); } oldGroupsToDelete.Add(clusterItemGroupInfo.gameObject); } } int clusterId = clusterCounter++; GroupItems(itemsToGroup.ToArray(), "Corridor_" + clusterId, dungeon, clusterId); } groupObjectByCellId.Clear(); // Destroy the inner group info objects foreach (var itemToDestory in oldGroupsToDelete) { EditorDestroyObject(itemToDestory); } }
void SetEndingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); CreateLevelGoalAt(roomCenter); }
void SetStartingCell(GridDungeonModel model, Cell cell) { var roomCenter = MathUtils.GridToWorld(model.Config.GridCellSize, cell.CenterF); TeleportPlayerTo(roomCenter); }
void BuildGridWaypoints(GridDungeonModel gridModel, LevelMarkerList markers) { mode2D = gridModel.Config.Mode2D; // Destroy all existing waypoints DestroyAllWaypoints(); var cellToWaypoint = new Dictionary <int, Waypoint>(); int idCounter = 1; var wall2DPositions = new HashSet <IntVector>(); if (mode2D) { foreach (var marker in markers) { if (marker.SocketType == DungeonConstants.ST_WALL2D) { wall2DPositions.Add(marker.gridPosition); } } } // Create a waypoint on each cell foreach (var cell in gridModel.Cells) { if (mode2D) { if (wall2DPositions.Contains(cell.Bounds.Location)) { // Don't want to create a waypoint on a wall tile continue; } } var worldPos = MathUtils.GridToWorld(gridModel.Config.GridCellSize, cell.CenterF); worldPos += waypointOffset; if (mode2D) { worldPos = FlipYZ(worldPos); } var waypointObject = Instantiate(waypointTemplate, worldPos, Quaternion.identity) as GameObject; waypointObject.transform.parent = waypointParent.transform; var waypoint = waypointObject.GetComponent <Waypoint>(); waypoint.id = idCounter++; cellToWaypoint.Add(cell.Id, waypoint); } // Connect adjacent waypoints foreach (var cellId in cellToWaypoint.Keys) { var waypoint = cellToWaypoint[cellId]; var cell = gridModel.GetCell(cellId); var adjacentWaypoints = new List <Waypoint>(); var visited = new HashSet <int>(); foreach (var adjacentCellId in cell.AdjacentCells) { if (visited.Contains(GetHash(cellId, adjacentCellId))) { continue; } var adjacentCell = gridModel.GetCell(adjacentCellId); // add only if there is a direct path to it (through a door or stair or open space) bool directPath = HasDirectPath(gridModel, cell, adjacentCell); if (directPath) { if (cellToWaypoint.ContainsKey(adjacentCellId)) { var adjacentWaypoint = cellToWaypoint[adjacentCellId]; adjacentWaypoints.Add(adjacentWaypoint); visited.Add(GetHash(cellId, adjacentCellId)); visited.Add(GetHash(adjacentCellId, cellId)); } } } waypoint.AdjacentWaypoints = adjacentWaypoints.ToArray(); } }