public void RoomCellRect(DungeonNode node) { CellRect result; var resultX = Mathf.Clamp(new IntRange(minRoomX, maxRoomX).RandomInRange, minRoomX, node.cells.Width - 1); var resultZ = Mathf.Clamp(new IntRange(minRoomZ, maxRoomZ).RandomInRange, minRoomZ, node.cells.Height - 1); node.cells.TryFindRandomInnerRect(new IntVec2(resultX, resultZ), out result); node.room = result; }
public List <DungeonNode> GetLeaves(DungeonNode root, List <DungeonNode> list) { if (root.left == null && root.right == null) { var temp = new List <DungeonNode>(); temp.AddRange(list); temp.Add(root); return(temp); } else { var temp = new List <DungeonNode>(); temp.AddRange(GetLeaves(root.left, list)); temp.AddRange(GetLeaves(root.right, list)); return(temp); } }
public void CreateDungeonHallways(DungeonNode cur) { if (cur.left == null || cur.right == null) { return; } try { ConnectDungeonHallways(cur.left, cur.right); } catch (Exception e) { Log.Message(e.ToString()); } CreateDungeonHallways(cur.left); CreateDungeonHallways(cur.right); }
public HashSet <CellRect> SubordinateRooms(DungeonNode cur, HashSet <CellRect> curList) { if (cur.left == null || cur.right == null) { return(curList); } if (cur.left.room != default(CellRect)) { curList.Add(cur.left.room); } if (cur.right.room != default(CellRect)) { curList.Add(cur.right.room); } curList.AddRange(SubordinateRooms(cur.left, curList)); curList.AddRange(SubordinateRooms(cur.right, curList)); return(curList); }
public DungeonNode CreateDungeonLayers(int currentIndex, int numOfLayers, DungeonNode root, CellRect cellRect) { DungeonNode temp = new DungeonNode(cellRect); var currentDepth = root == null ? 1 : root.depth + 1; //Log.Message($"Current depth: {currentDepth.ToString()}"); temp.parent = root; temp.depth = currentDepth; root = temp; if (this.baseRoot == null) { this.baseRoot = root; } //Create room if (root != null && root.depth >= maxDepth) { RoomCellRect(root); if (root.room.Width < minRoomX) { return(root); } if (root.room.Height < minRoomZ) { return(root); } //Log.Message($"Room created at: {root.Cells.CenterCell.ToString()}"); return(root); } if (root == null || root.depth <= maxDepth) { //Split cells CellRect[] splitDungeon = SplitCellRects(root.cells); //Add left child root.left = CreateDungeonLayers(currentIndex + 1, numOfLayers, root, splitDungeon[0]); //Add right child root.right = CreateDungeonLayers(currentIndex + 1, numOfLayers, root, splitDungeon[1]); } return(root); }
public void RoomGeneration(DungeonNode node, bool isStartingRoom) { //Clear base space if (isStartingRoom) { var finalRoom = new CellRect(node.room.CenterCell.x - 12, node.room.CenterCell.z - 12, 24, 24); node.room = finalRoom; startingRoomRect = finalRoom; } CellRect rect = node.room; HashSet <IntVec3> edgeCells = new HashSet <IntVec3>(rect.EdgeCells); HashSet <IntVec3> innerCells = new HashSet <IntVec3>(rect.ContractedBy(1).Cells); foreach (IntVec3 cell in innerCells) { if (cellPainter.ContainsKey(cell)) { if (cellPainter[cell] != SpawnType.Door) { cellPainter[cell] = SpawnType.Floor; } } else { cellPainter.Add(cell, SpawnType.Floor); } } foreach (IntVec3 cell in edgeCells) { if (cellPainter.ContainsKey(cell)) { if (cellPainter[cell] == SpawnType.Door) { continue; } //if (cellPainter[cell] == SpawnType.HallwayWall) //{ // cellPainter[cell] = SpawnType.Door; // continue; //} if (cellPainter[cell] == SpawnType.HallwayFloor) { cellPainter[cell] = SpawnType.Door; continue; } cellPainter[cell] = SpawnType.Wall; } else { cellPainter.Add(cell, SpawnType.Wall); } } hallwaysAndRooms.Add(node.room); foreach (var cell in rect.Cells) { if (isStartingRoom) { debugMap[cell.x, cell.z] = 'S'; } else { debugMap[cell.x, cell.z] = 'R'; } } }
public void ConnectDungeonHallways(DungeonNode a, DungeonNode b) { bool noARoomExists = a.room == default(CellRect); bool noBRoomExists = b.room == default(CellRect); IntVec3 midA = a.cells.CenterCell; // : a.room.CenterCell; IntVec3 midB = b.cells.CenterCell; // : b.room.CenterCell; if (noARoomExists) { var rooms = a.SubordinateRooms(a, new HashSet <CellRect>()); midA = rooms.RandomElement().CenterCell; } else { midA = a.room.CenterCell; } if (noBRoomExists) { var rooms = b.SubordinateRooms(b, new HashSet <CellRect>()); midB = rooms.RandomElement().CenterCell; } else { midB = b.room.CenterCell; } CellRect betweenBox = new CellRect(); betweenBox.minX = midA.x < midB.x ? midA.x : midB.x; betweenBox.minZ = midA.z < midB.z ? midA.z : midB.z; betweenBox.Width = midA.x < midB.x ? midB.x - midA.x : midA.x - midB.x; betweenBox.Height = midA.z < midB.z ? midB.z - midA.z : midA.z - midB.z; //Log.Message($"Hallway Created: {betweenBox.minX} {betweenBox.minZ} {betweenBox.Width} {betweenBox.Height}"); CellRect horizontalRect; CellRect verticalRect; //Case 1 - Horizontal Only // // A===B B===A // //if(Mathf.Abs(midA.z - midB.z) is int absDistZ && absDistZ < 4) if ( (midB.z < midA.z + 4 && midB.z > midA.z - 4) || (midA.z < midB.z + 4 && midA.z > midB.z - 4) ) { verticalRect = new CellRect(betweenBox.minX, betweenBox.minZ, 3, 3); horizontalRect = new CellRect(betweenBox.minX, betweenBox.minZ, betweenBox.Width, new IntRange(3, 5).RandomInRange); foreach (var cell in verticalRect.Cells.Concat(horizontalRect.Cells)) { debugMap[cell.x, cell.z] = '1'; } } //Case 2 - Vertical Only // A B // || || // B A else if ( (midB.x < midA.x + 4 && midB.x > midA.x - 4) || (midA.x < midB.x + 4 && midA.x > midB.x - 4) ) { horizontalRect = new CellRect(betweenBox.minX, betweenBox.minZ, 3, 3); verticalRect = new CellRect(betweenBox.minX, betweenBox.minZ, new IntRange(3, 5).RandomInRange, betweenBox.Height); foreach (var cell in verticalRect.Cells.Concat(horizontalRect.Cells)) { debugMap[cell.x, cell.z] = '2'; } } //Case 3 - L Shape // A B // || || // LL==B LL==A // // OR // // Dropped Flipped L // A ==|| B==|| // || || // B A else if ( (midA.x < midB.x && midA.z > midB.z) || (midB.x < midA.x && midB.z > midA.z) ) { var hallwaySize = new IntRange(3, 5).RandomInRange; //L Shape if (Rand.Value > 0.5f) { verticalRect = new CellRect(betweenBox.minX, betweenBox.minZ, hallwaySize, betweenBox.Height); horizontalRect = new CellRect(betweenBox.minX, betweenBox.minZ, betweenBox.Width, hallwaySize); } //Dropped Flipped L else { verticalRect = new CellRect(betweenBox.maxX, betweenBox.minZ, hallwaySize, betweenBox.Height); horizontalRect = new CellRect(betweenBox.minX, betweenBox.maxZ, betweenBox.Width + hallwaySize - 1, hallwaySize); } foreach (var cell in verticalRect.Cells.Concat(horizontalRect.Cells)) { debugMap[cell.x, cell.z] = '3'; } } //Case 4 - Flipped L // B A // || || // A==| B==| // // OR // // Dropped L // ||==B ||==A // || || // A B else if ( (midA.x < midB.x && midA.z < midB.z) || (midB.x < midA.x && midB.z < midA.z) ) { var hallwaySize = new IntRange(3, 5).RandomInRange; //Flipped L if (Rand.Value > 0.5f) { verticalRect = new CellRect(betweenBox.maxX, betweenBox.minZ, hallwaySize, betweenBox.Height); horizontalRect = new CellRect(betweenBox.minX, betweenBox.minZ, betweenBox.Width, hallwaySize); } //Dropped L else { verticalRect = new CellRect(betweenBox.minX, betweenBox.minZ, hallwaySize, betweenBox.Height); horizontalRect = new CellRect(betweenBox.minX, betweenBox.maxZ, betweenBox.Width, hallwaySize); } foreach (var cell in verticalRect.Cells.Concat(horizontalRect.Cells)) { debugMap[cell.x, cell.z] = '4'; } } else { var hallwaySize = new IntRange(3, 5).RandomInRange; verticalRect = new CellRect(betweenBox.minX, betweenBox.minZ, hallwaySize, betweenBox.Height); horizontalRect = new CellRect(betweenBox.minX, betweenBox.maxX, betweenBox.Width, hallwaySize); } var combinedArea = horizontalRect.ContractedBy(1).Cells.Concat(verticalRect.ContractedBy(1).Cells).ToList(); var combinedEdges = horizontalRect.EdgeCells.Concat(verticalRect.EdgeCells).ToList(); foreach (IntVec3 cell in combinedArea) { if (cellPainter.ContainsKey(cell)) { cellPainter[cell] = SpawnType.HallwayFloor; } else { cellPainter.Add(cell, SpawnType.HallwayFloor); } } foreach (IntVec3 cell in combinedEdges) { if (cellPainter.ContainsKey(cell)) { if (cellPainter[cell] != SpawnType.HallwayFloor) { cellPainter[cell] = SpawnType.HallwayWall; } } else { cellPainter.Add(cell, SpawnType.HallwayWall); } } a.numOfHallways++; b.numOfHallways++; ////Find two door spots //IntVec3 aDoor = IntVec3.Invalid; //if (!noARoomExists) //{ // foreach (IntVec3 cell in combinedArea) // { // if (a.room.Contains(cell) && cellPainter.ContainsKey(cell) && cellPainter[cell] == SpawnType.Wall) // { // cellPainter[cell] = SpawnType.Door; // break; // } // } //} //if (!noBRoomExists) //{ // foreach (IntVec3 cell in combinedArea) // { // if (b.room.Contains(cell) && cellPainter.ContainsKey(cell) && cellPainter[cell] == SpawnType.Wall) // { // cellPainter[cell] = SpawnType.Door; // break; // } // } //} hallwaysAndRooms.Add(horizontalRect); hallwaysAndRooms.Add(verticalRect); }
public void ApplyRoomDefToRoom(DungeonNode node, RoomGenDef rgd) { Log.Message($"{rgd.defName} for {node.room.CenterCell.ToString()}"); bool hasCenterpiece = false; var minWallSize = Mathf.Min(node.room.Width, node.room.Height); if (minWallSize <= 5) { SpawnBuildings(rgd.furnishingsDef.tinyRoomBuildingsToSpawn, node, ref hasCenterpiece); } else if (minWallSize <= 8) { SpawnBuildings(rgd.furnishingsDef.tinyRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.smallRoomBuildingsToSpawn, node, ref hasCenterpiece); } else if (minWallSize <= 12) { SpawnBuildings(rgd.furnishingsDef.tinyRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.smallRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.mediumRoomBuildingsToSpawn, node, ref hasCenterpiece); } else if (minWallSize <= 24) { SpawnBuildings(rgd.furnishingsDef.tinyRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.smallRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.mediumRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.largeRoomBuildingsToSpawn, node, ref hasCenterpiece); } else { SpawnBuildings(rgd.furnishingsDef.tinyRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.smallRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.mediumRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.largeRoomBuildingsToSpawn, node, ref hasCenterpiece); SpawnBuildings(rgd.furnishingsDef.colossalRoomBuildingsToSpawn, node, ref hasCenterpiece); } if (rgd.pawnsToSpawn?.Count > 0) { foreach (var pawnKind in rgd.pawnsToSpawn) { for (int i = 0; i < pawnKind.numToSpawn.RandomInRange; i++) { IntVec3 spawnPoint; CellFinder.TryFindRandomCellInsideWith(node.room, ((IntVec3 x) => { return(x.Standable(map)); }), out spawnPoint); var pawn = PawnGenerator.GeneratePawn(pawnKind.pawnKindDef, null); GenSpawn.Spawn(pawn, spawnPoint, map); if (pawnKind.spawnDead) { pawn.Kill(null); } if (pawnKind.factionDef != null) { pawn.SetFactionDirect(Find.FactionManager.FirstFactionOfDef(pawnKind.factionDef)); } } } } }
public void SpawnBuildings(List <BuildingToSpawn> bldsToSpawn, DungeonNode node, ref bool hasCenterpiece) { if (bldsToSpawn?.Count > 0) { foreach (var building in bldsToSpawn) { if (building.isCenterpiece && hasCenterpiece) { continue; } //Spawn the buildings for (int i = 0; i < building.numToSpawn.RandomInRange; i++) { //Can the building be spawned at this node? if (building.buildingDef.Size.x >= node.room.Width - 2 || building.buildingDef.Size.z >= node.room.Height - 2) { break; } var rot = building.buildingDef.rotatable ? Rot4.Random : building.buildingDef.defaultPlacingRot; IntVec3 spawnPoint = (building.isCenterpiece) ? node.room.CenterCell : CellFinder.FindNoWipeSpawnLocNear( node.room.ContractedBy( Mathf.Max(building.buildingDef.Size.x, building.buildingDef.Size.z)).RandomCell, map, building.buildingDef, rot, (int)(node.cells.Width * 0.3f)); if (building.buildingDef == ThingDefOf.GeothermalGenerator) { var powerSource = ThingMaker.MakeThing(ThingDefOf.SteamGeyser); GenPlace.TryPlaceThing(powerSource, spawnPoint, map, ThingPlaceMode.Direct); } var stuffDef = building.buildingDef.MadeFromStuff && building.stuffDef == null ? ThingDefOf.Steel : building.stuffDef; var buildingSpawned = ThingMaker.MakeThing(building.buildingDef, stuffDef); GenPlace.TryPlaceThing(buildingSpawned, spawnPoint, map, ThingPlaceMode.Near, null, null, rot); if (building.isCenterpiece) { hasCenterpiece = true; } if (buildingSpawned is Plant plant) { plant.Growth = 1f; } if (building.chairDef != null) { var chairStuffDef = building.chairDef.MadeFromStuff ? ThingDefOf.Steel : stuffDef; var chairSpawned = ThingMaker.MakeThing(building.chairDef, chairStuffDef); GenPlace.TryPlaceThing(chairSpawned, buildingSpawned.InteractionCell, map, ThingPlaceMode.Direct, null, null, buildingSpawned.Rotation); } if (buildingSpawned?.TryGetComp <CompRefuelable>() is CompRefuelable compRefuelable) { Traverse.Create(compRefuelable).Field("fuel").SetValue(compRefuelable.Props.fuelCapacity); ((ThingWithComps)buildingSpawned).BroadcastCompSignal("Refueled"); } } } } }