/// <summary> /// Builds the dungeon layout. In this method, you should build your dungeon layout and save it in your model file /// No markers should be emitted here. (EmitMarkers function will be called later by the engine to do that) /// </summary> /// <param name="config">The builder configuration</param> /// <param name="model">The dungeon model that the builder will populate</param> public override void BuildDungeon(DungeonConfig config, DungeonModel model) { base.BuildDungeon(config, model); random = new System.Random((int)config.Seed); // We know that the dungeon prefab would have the appropriate config and models attached to it // Cast and save it for future reference floorPlanConfig = config as FloorPlanConfig; floorPlanModel = model as FloorPlanModel; floorPlanModel.Config = floorPlanConfig; // Generate the city layout and save it in a model. No markers are emitted here. BuildLayout(); propSockets.Clear(); }
/// <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); } } }