void FloodFill(IntVector StartLocation, int IslandId, HashSet <IntVector> Visited, List <FloorIslandNode> IslandNodes, FloorChunkDB ChunkDB) { FloorChunk PreferedChunk = ChunkDB.GetChunkAt(StartLocation); if (!PreferedChunk.bConnectDoors) { // We don't want doors here return; } if (PreferedChunk == null) { return; } Queue <IntVector> Queue = new Queue <IntVector>(); Queue.Enqueue(StartLocation); while (Queue.Count > 0) { IntVector Location = Queue.Dequeue(); FloorChunk CurrentChunk = ChunkDB.GetChunkAt(Location); if (CurrentChunk != PreferedChunk) { continue; } // Create a node here FloorIslandNode Node = new FloorIslandNode(); Node.IslandId = IslandId; Node.Chunk = CurrentChunk; Node.Location = Location; IslandNodes.Add(Node); // Add the neighbors to the queue List <IntVector> Neighbors = new List <IntVector>(); Neighbors.Add(Location + new IntVector(-1, 0, 0)); Neighbors.Add(Location + new IntVector(1, 0, 0)); Neighbors.Add(Location + new IntVector(0, 0, 1)); Neighbors.Add(Location + new IntVector(0, 0, -1)); foreach (IntVector Neighbor in Neighbors) { if (Visited.Contains(Neighbor)) { continue; } FloorChunk NeighborChunk = ChunkDB.GetChunkAt(Neighbor); if (NeighborChunk != null && NeighborChunk.Id == CurrentChunk.Id) { Queue.Enqueue(Neighbor); Visited.Add(Neighbor); } } } }
/// <summary> /// Generate a layout and save it in the model /// </summary> void EmitBuildingMarkers() { floorPlanConfig = config as FloorPlanConfig; floorPlanModel = model as FloorPlanModel; ClearSockets(); //TArray<AFloorPlanDoorVolume*> DoorVolumes = UDungeonModelHelper::GetVolumes<AFloorPlanDoorVolume>(Dungeon) ClearSockets(); int NumFloors = Mathf.RoundToInt(floorPlanConfig.BuildingSize.y); Vector3 GridSize = floorPlanConfig.GridSize; bool bBuildingWallLeft, bBuildingWallBottom; for (int y = 0; y < NumFloors; y++) { for (int x = -1; x < floorPlanConfig.BuildingSize.x; x++) { bBuildingWallLeft = (x == -1 || x == floorPlanConfig.BuildingSize.x - 1); for (int z = -1; z < floorPlanConfig.BuildingSize.z; z++) { bBuildingWallBottom = (z == -1 || z == floorPlanConfig.BuildingSize.z - 1); FloorChunk Chunk00 = ChunkDB.GetChunkAt(x, y, z); FloorChunk Chunk10 = ChunkDB.GetChunkAt(x + 1, y, z); FloorChunk Chunk01 = ChunkDB.GetChunkAt(x, y, z + 1); string GroundMarkerName = FloorPlanMarkers.MARKER_GROUND; string CeilingMarkerName = FloorPlanMarkers.MARKER_CEILING; FloorChunk ChunkAbove = ChunkDB.GetChunkAt(x, y + 1, z); FloorChunk ChunkBelow = ChunkDB.GetChunkAt(x, y - 1, z); bool bEmitGroundMarker = (Chunk00 != ChunkBelow); bool bEmitCeilingMarker = (Chunk00 != ChunkAbove); // Emit the ground marker if (Chunk00 != null && Chunk00.ChunkType != FloorChunkType.Outside) { if (bEmitGroundMarker) { Vector3 GridLocation = new Vector3(x + 0.5f, y, z + 0.5f); Vector3 WorldLocation = Vector3.Scale(GridLocation, GridSize); if (Chunk00.GroundMarker.Length > 0) { GroundMarkerName = Chunk00.GroundMarker; } EmitMarkerAt(WorldLocation, GroundMarkerName, 0); } if (bEmitCeilingMarker) { Vector3 GridLocation = new Vector3(x + 0.5f, y + 1, z + 0.5f); Vector3 WorldLocation = Vector3.Scale(GridLocation, GridSize); if (Chunk00.CeilingMarker.Length > 0) { CeilingMarkerName = Chunk00.CeilingMarker; } EmitMarkerAt(WorldLocation, CeilingMarkerName, Quaternion.Euler(180, 0, 0)); } } int Chunk00Id = (Chunk00 != null ? Chunk00.Id : -1); int Chunk10Id = (Chunk10 != null ? Chunk10.Id : -1); int Chunk01Id = (Chunk01 != null ? Chunk01.Id : -1); bool bEmitLeftWall = (Chunk00Id != Chunk10Id); bool bEmitBottomWall = (Chunk00Id != Chunk01Id); bool bLeftDoor = DoorManager.ContainsDoor(new IntVector(x, y, z), new IntVector(x + 1, y, z)); // || DoorManager.ContainsDoorVolume(Vector3.Scale(new Vector(x + 1, y, z + 0.5f) * GridSize), DoorVolumes); bool bBottomDoor = DoorManager.ContainsDoor(new IntVector(x, y, z), new IntVector(x, y, z + 1)); // || DoorManager.ContainsDoorVolume(Vector3.Scale(new Vector(x + 0.5f, y, z + 1) * GridSize), DoorVolumes); if (Chunk00 != null && Chunk10 != null && Chunk00.ChunkType == FloorChunkType.Hall && Chunk10.ChunkType == FloorChunkType.Hall) { // Do not block the halls with a wall bEmitLeftWall = false; } if (Chunk00 != null && Chunk01 != null && Chunk00.ChunkType == FloorChunkType.Hall && Chunk01.ChunkType == FloorChunkType.Hall) { // Do not block the halls with a wall bEmitBottomWall = false; } if (Chunk00 != null && Chunk10 != null && (!Chunk00.bEmitGroundMarker || !Chunk10.bEmitGroundMarker)) { // We don't have ground in one of the adjacent chunks. Can't have doors bLeftDoor = false; } if (Chunk00 != null && Chunk01 != null && (!Chunk00.bEmitGroundMarker || !Chunk01.bEmitGroundMarker)) { // We don't have ground in one of the adjacent chunks. Can't have doors bBottomDoor = false; } if (bEmitLeftWall) { FloorChunk PriorityChunk = GetPriorityChunk(Chunk00, Chunk10); bEmitLeftWall = PriorityChunk != null ? PriorityChunk.bCreateWalls : true; } if (bEmitBottomWall) { FloorChunk PriorityChunk = GetPriorityChunk(Chunk00, Chunk01); bEmitBottomWall = PriorityChunk != null ? PriorityChunk.bCreateWalls : true; } if (bEmitLeftWall) { Vector3 GridLocation = new Vector3(x + 1, y, z + 0.5f); Vector3 WorldLocation = Vector3.Scale(GridLocation, GridSize); string MarkerName; if (bLeftDoor) { MarkerName = GetDoorMarkerName(Chunk00, Chunk10); } else { MarkerName = FloorPlanMarkers.MARKER_WALL; if (bBuildingWallLeft) { MarkerName = FloorPlanMarkers.MARKER_BUILDING_WALL; } else { if (Chunk00 != null && Chunk10 != null) { FloorChunk PriorityChunk = (Chunk00.Priority > Chunk10.Priority) ? Chunk00 : Chunk10; if (PriorityChunk.WallMarker.Length > 0) { MarkerName = PriorityChunk.WallMarker; } } } } EmitMarkerAt(WorldLocation, MarkerName, 90); } if (bEmitBottomWall) { Vector3 GridLocation = new Vector3(x + 0.5f, y, z + 1); Vector3 WorldLocation = Vector3.Scale(GridLocation, GridSize); string MarkerName; if (bBottomDoor) { MarkerName = GetDoorMarkerName(Chunk00, Chunk01); } else { MarkerName = FloorPlanMarkers.MARKER_WALL; if (bBuildingWallBottom) { MarkerName = FloorPlanMarkers.MARKER_BUILDING_WALL; } else { if (Chunk00 != null && Chunk01 != null) { FloorChunk PriorityChunk = (Chunk00.Priority > Chunk01.Priority) ? Chunk00 : Chunk01; if (PriorityChunk.WallMarker.Length > 0) { MarkerName = PriorityChunk.WallMarker; } } } } EmitMarkerAt(WorldLocation, MarkerName, 0); } } } } // Emit center marker if specified List <FloorChunk> Chunks = new List <FloorChunk>(); ChunkDB.GetChunks(Chunks); foreach (FloorChunk Chunk in Chunks) { if (Chunk.bEmitGroundMarker && Chunk.CenterMarker.Length > 0) { Vector3 ChunkSize = MathUtils.ToVector3(Chunk.Bounds.Size) / 2.0f; ChunkSize.y = 0; Vector3 GridLocation = MathUtils.ToVector3(Chunk.Bounds.Location) + ChunkSize; Vector3 WorldLocation = Vector3.Scale(GridLocation, GridSize); EmitMarkerAt(WorldLocation, Chunk.CenterMarker, 0); } } }