Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
 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);
     }
 }
Ejemplo n.º 3
0
 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);
 }
Ejemplo n.º 4
0
 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);
 }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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';
                }
            }
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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));
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        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");
                        }
                    }
                }
            }
        }