예제 #1
0
        private void GenerateRooms(SettlementLayoutDef sld, Map map, ResolveParams rp)
        {
            List <StructureLayoutDef> authorizedLayouts = DefDatabase <StructureLayoutDef> .AllDefsListForReading.FindAll(s => s.tags.Any(t => sld.allowedTags.Contains(t)));

            Log.Message(authorizedLayouts.Count + " auhtorized layouts.");

            map.terrainGrid.SetTerrain(rp.rect.Last(), TerrainDefOf.Bridge);
        }
        private void GenerateRooms(SettlementLayoutDef sld, Map map, ResolveParams rp)
        {
            int seed = new Random().Next(0, 100000);

            CGO.offset = rp.rect.Corners.ElementAt(2);
            CGO.grid   = GridUtils.GenerateGrid(seed, sld, map);

            BaseGen.symbolStack.Push("kcsg_roomgenfromlist", rp, null);
        }
예제 #3
0
        public override void Resolve(ResolveParams rp)
        {
            Map map = BaseGen.globalSettings.map;
            SettlementLayoutDef lDef      = FactionSettlement.temp;
            List <CellRect>     gridRects = FactionSettlement.tempRectList;

            if (VFECore.VFEGlobal.settings.enableLog)
            {
                Log.Message("KCSG_RoomGen generating " + lDef.defName.ToString());
            }

            int count = 0;

            foreach (string str in lDef.roomLayout)
            {
                if (str != ".")
                {
                    StructureLayoutDef rld = DefDatabase <StructureLayoutDef> .GetNamed(str);

                    KCSG_Utilities.FillCellThingsList(gridRects[count].Cells.ToList(), map, pairsCellThingList);

                    foreach (List <String> item in rld.layouts)
                    {
                        KCSG_Utilities.GenerateRoomFromLayout(item, gridRects[count], map, rld);
                    }

                    if (rld.isStockpile)
                    {
                        KCSG_Utilities.FillStockpileRoom(rld, gridRects[count], map);
                    }
                }
                count++;
            }

            ThingDef conduit;

            if (LoadedModManager.RunningMods.ToList().FindAll(m => m.Name == "Subsurface Conduit").Count > 0)
            {
                conduit = DefDatabase <ThingDef> .AllDefsListForReading.FindAll(d => d.defName == "MUR_SubsurfaceConduit").First();
            }
            else
            {
                conduit = ThingDefOf.PowerConduit;
            }

            KCSG_Utilities.EnsureBatteriesConnectedAndMakeSense(map, tmpThings, tmpPowerNetPredicateResults, tmpCells, conduit);
            KCSG_Utilities.EnsurePowerUsersConnected(map, tmpThings, tmpPowerNetPredicateResults, tmpCells, conduit);
            KCSG_Utilities.EnsureGeneratorsConnectedAndMakeSense(map, tmpThings, tmpPowerNetPredicateResults, tmpCells, conduit);
        }
예제 #4
0
        public override void Resolve(ResolveParams rp)
        {
            Map     map     = BaseGen.globalSettings.map;
            Faction faction = rp.faction ?? Find.FactionManager.RandomEnemyFaction(false, false, true, TechLevel.Undefined);

            if (FactionSettlement.tempUseStructureLayout)
            {
                this.AddHostilePawnGroup(faction, map, rp);

                ResolveParams usl_rp = rp;
                usl_rp.faction = faction;
                BaseGen.symbolStack.Push("kcsg_roomsgenfromstructure", usl_rp, null);

                this.PreClean(map, false, rp);
            }
            else
            {
                SettlementLayoutDef sld = DefDatabase <SettlementLayoutDef> .GetNamed(FactionSettlement.temp);

                this.PreClean(map, true, rp);
                if (sld.pathThing != null)
                {
                    ResolveParams sld_rp_1 = rp;
                    sld_rp_1.floorDef = sld.pathThing;
                    sld_rp_1.allowBridgeOnAnyImpassableTerrain = true;
                    BaseGen.symbolStack.Push("floor", sld_rp_1, null);
                }

                this.GenerateRooms(sld, map, rp);

                if (sld.vanillaLikeDefense)
                {
                    int           dWidth = (Rand.Bool ? 2 : 4);
                    ResolveParams rp3    = rp;
                    rp3.rect                      = new CellRect(rp.rect.minX - dWidth, rp.rect.minZ - dWidth, rp.rect.Width + (dWidth * 2), rp.rect.Height + (dWidth * 2));
                    rp3.faction                   = faction;
                    rp3.edgeDefenseWidth          = dWidth;
                    rp3.edgeThingMustReachMapEdge = new bool?(rp.edgeThingMustReachMapEdge ?? true);
                    BaseGen.symbolStack.Push("edgeDefense", rp3, null);
                }

                this.AddHostilePawnGroup(faction, map, rp);
            }
        }
        public static List <CustomVector> Run(SettlementLayoutDef sld, CustomVector[][] grid, int maxTries)
        {
            CGO.vectStruct = new Dictionary <CustomVector, StructureLayoutDef>();

            Dictionary <string, int> structCount = new Dictionary <string, int>();

            List <CustomVector> doors = new List <CustomVector>();

            foreach (CustomVector vector in CGO.vectors.ListFullCopy())
            {
                for (int i = 0; i < maxTries; i++)
                {
                    sld.allowedStructuresConverted.TryRandomElementByWeight(p => GetWeight(p, structCount), out StructOption option);
                    List <StructureLayoutDef> all = DefDatabase <StructureLayoutDef> .AllDefsListForReading.FindAll(s => s.tags.Contains(option.structureLayoutTag));

                    StructureLayoutDef b = LayoutUtils.ChooseLayoutFrom(all);

                    if (CanPlaceAt(vector, b, grid))
                    {
                        CGO.vectStruct.Add(vector, b);
                        doors.AddRange(PlaceAt(vector, b, grid));
                        if (structCount.ContainsKey(option.structureLayoutTag))
                        {
                            structCount[option.structureLayoutTag]++;
                        }
                        else
                        {
                            structCount.Add(option.structureLayoutTag, 1);
                        }
                        CGO.vectors.Remove(vector);
                        break;
                    }
                }
            }
            return(doors);
        }
        /// <summary>
        /// Generate a grid, add the preexisting vanilla road if needed. Add main roads. Fill the potential point list, add buildings on grid and fill the origin/layout dictionnary
        /// </summary>
        /// <param name="seed">Seed for Random</param>
        /// <param name="sld">SettlementLayoutDef to get all StructureLayoutDef authorized</param>
        /// <param name="map">The map</param>
        /// <returns></returns>
        public static CustomVector[][] GenerateGrid(int seed, SettlementLayoutDef sld, Map map)
        {
            CGO.currentGenStepMoreInfo = "Generating grid and main road";
            int mapWidth  = Math.Min(map.Size.x, sld.settlementSize.x),
                mapHeight = Math.Min(map.Size.z, sld.settlementSize.z);

            // Search for the smallest sized allowed structure. It will be the radius between potential building spawn points
            CGO.radius = 9999;
            for (int i = 0; i < sld.allowedStructures.Count; i++)
            {
                foreach (StructureLayoutDef item in DefDatabase <StructureLayoutDef> .AllDefsListForReading.FindAll(s => s.tags.Contains(sld.allowedStructuresConverted[i].structureLayoutTag)))
                {
                    RectUtils.HeightWidthFromLayout(item, out int height, out int width);
                    if (height < CGO.radius)
                    {
                        CGO.radius = height;
                    }
                    if (width < CGO.radius)
                    {
                        CGO.radius = width;
                    }
                }
            }
            CGO.radius += 2; // Add to radius to ensure no building touch one another

            // Initialize the grid used for generation
            Random r = new Random(seed);

            CustomVector[][] grid = new CustomVector[mapWidth][];
            for (int i = 0; i < mapWidth; i++)
            {
                grid[i] = new CustomVector[mapHeight];
                for (int j = 0; j < mapHeight; j++)
                {
                    grid[i][j] = new CustomVector(i, j);
                }
            }

            // Exclude non bridgeable cells
            for (int i = 0; i < mapWidth; i++)
            {
                for (int j = 0; j < mapHeight; j++)
                {
                    TerrainDef t = map.terrainGrid.TerrainAt(new IntVec3(CGO.offset.x + i, 0, CGO.offset.y + j));
                    if (t.HasTag("Water") && (t.affordances == null || !t.affordances.Contains(TerrainAffordanceDefOf.Bridgeable)))
                    {
                        grid[i][j].Type = CellType.WATER;
                    }
                }
            }
            // Main roads
            CGO.usePathCostReduction = false; // No path cost reduction for main road, for them to be distinct
            DrawXMainRoad(grid, mapWidth, mapHeight, 15, r);
            DrawYMainRoad(grid, mapWidth, mapHeight, 15, r);
            // If bigger sized settlement, add more main roads
            for (int i = 0; i < mapWidth / 100; i++)
            {
                if (i == 0)
                {
                    DrawXMainRoad(grid, mapWidth, mapHeight, mapWidth / 2, r);
                    DrawYMainRoad(grid, mapWidth, mapHeight, mapHeight / 2, r);
                }
                else
                {
                    DrawXMainRoad(grid, mapWidth, mapHeight, 50, r);
                    DrawYMainRoad(grid, mapWidth, mapHeight, 50, r);
                }
            }
            // Get vanilla world road type and use it if present
            if (CGO.preRoadTypes?.Count > 0)
            {
                for (int i = 0; i < mapWidth; i++)
                {
                    for (int j = 0; j < mapHeight; j++)
                    {
                        TerrainDef t = map.terrainGrid.TerrainAt(new IntVec3(CGO.offset.x + i, 0, CGO.offset.y + j));
                        if (CGO.preRoadTypes.Contains(t))
                        {
                            grid[i][j].Type = CellType.MAINROAD; // Add vanilla generated road to the grid
                        }
                    }
                }
            }
            CGO.usePathCostReduction = true;                                         // Renable path cost reduction

            CGO.vectors = PoissonDiskSampling.Run(50, mapWidth, mapHeight, r, grid); // Get all possible points with radius
            CGO.doors   = BuildingPlacement.Run(sld, grid, 50);                      // Place buildings on grid and add them/their origin into vectStruct
            return(grid);
        }
        public static void Generate(Map map, IntVec3 c, FactionSettlement sf, string symbolResolver = "kcsg_settlement")
        {
            FactionSettlement.tempUseStructureLayout = sf.useStructureLayout;

            string sld;

            if (!sf.useStructureLayout)
            {
                sld = sf.chooseFromSettlements.RandomElement().defName;
            }
            else
            {
                if (ModLister.RoyaltyInstalled)
                {
                    sld = sf.chooseFromlayouts.RandomElement().defName;
                }
                else
                {
                    sld = sf.chooseFromlayouts.ToList().FindAll(sfl => !sfl.requireRoyalty).RandomElement().defName;
                }
            }

            FactionSettlement.temp = sld;

            // Get faction
            Faction faction;

            if (map.ParentFaction == null || map.ParentFaction == Faction.OfPlayer)
            {
                faction = Find.FactionManager.RandomEnemyFaction(false, false, true, TechLevel.Undefined);
            }
            else
            {
                faction = map.ParentFaction;
            }

            // Get settlement size
            int width;
            int height;

            if (sf.useStructureLayout)
            {
                KCSG_Utilities.HeightWidthFromLayout(DefDatabase <StructureLayoutDef> .GetNamed(sld), out height, out width);
            }
            else
            {
                SettlementLayoutDef temp = DefDatabase <SettlementLayoutDef> .GetNamed(sld);

                height = temp.settlementSize.x;
                width  = temp.settlementSize.z;
            }

            CellRect rect = new CellRect(c.x - width / 2, c.z - height / 2, width, height);

            rect.ClipInsideMap(map);

            ResolveParams rp = default(ResolveParams);

            rp.faction = faction;
            rp.rect    = rect;

            BaseGen.globalSettings.map = map;
            BaseGen.symbolStack.Push(symbolResolver, rp, null);
            BaseGen.Generate();
        }
예제 #8
0
        public override void Resolve(ResolveParams rp)
        {
            Map                 map     = BaseGen.globalSettings.map;
            Faction             faction = rp.faction ?? Find.FactionManager.RandomEnemyFaction(false, false, true, TechLevel.Undefined);
            SettlementLayoutDef lDef    = FactionSettlement.temp;

            List <CellRect> gridRects = KCSG_Utilities.GetRects(rp.rect, lDef, map, out rp.rect);

            FactionSettlement.tempRectList = gridRects;

            if (VFECore.VFEGlobal.settings.enableLog)
            {
                Log.Message("Hostile pawns generation - PASS");
            }

            // Add pawn to the base
            Lord          singlePawnLord = rp.singlePawnLord ?? LordMaker.MakeNewLord(faction, new LordJob_DefendBase(faction, rp.rect.CenterCell), map, null);
            TraverseParms traverseParms  = TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false);
            ResolveParams resolveParams  = rp;

            resolveParams.rect             = rp.rect;
            resolveParams.faction          = faction;
            resolveParams.singlePawnLord   = singlePawnLord;
            resolveParams.pawnGroupKindDef = (rp.pawnGroupKindDef ?? PawnGroupKindDefOf.Settlement);
            resolveParams.singlePawnSpawnCellExtraPredicate = (rp.singlePawnSpawnCellExtraPredicate ?? ((IntVec3 x) => map.reachability.CanReachMapEdge(x, traverseParms)));
            if (resolveParams.pawnGroupMakerParams == null && faction.def.pawnGroupMakers.Any(pgm => pgm.kindDef == PawnGroupKindDefOf.Settlement))
            {
                resolveParams.pawnGroupMakerParams             = new PawnGroupMakerParms();
                resolveParams.pawnGroupMakerParams.tile        = map.Tile;
                resolveParams.pawnGroupMakerParams.faction     = faction;
                resolveParams.pawnGroupMakerParams.points      = (rp.settlementPawnGroupPoints ?? SymbolResolver_Settlement.DefaultPawnsPoints.RandomInRange);
                resolveParams.pawnGroupMakerParams.inhabitants = true;
                resolveParams.pawnGroupMakerParams.seed        = rp.settlementPawnGroupSeed;
            }
            if (faction.def.pawnGroupMakers.Any(pgm => pgm.kindDef == PawnGroupKindDefOf.Settlement))
            {
                BaseGen.symbolStack.Push("pawnGroup", resolveParams, null);
            }

            // Add defense
            if (lDef.vanillaLikeDefense)
            {
                int           dWidth = (Rand.Bool ? 2 : 4);
                ResolveParams rp3    = rp;
                rp3.rect                      = new CellRect(rp.rect.minX - dWidth, rp.rect.minZ - dWidth, rp.rect.Width + (dWidth * 2), rp.rect.Height + (dWidth * 2));
                rp3.faction                   = faction;
                rp3.edgeDefenseWidth          = dWidth;
                rp3.edgeThingMustReachMapEdge = new bool?(rp.edgeThingMustReachMapEdge ?? true);
                BaseGen.symbolStack.Push("edgeDefense", rp3, null);
            }

            if (VFECore.VFEGlobal.settings.enableLog)
            {
                Log.Message("Structures generation - PASS");
            }

            // Create the rooms
            ResolveParams rp2 = rp;

            rp2.faction = faction;
            BaseGen.symbolStack.Push("kcsg_roomsgen", rp2, null);

            // Add path

            if (VFECore.VFEGlobal.settings.enableLog)
            {
                Log.Message("Adding paths - PASS");
            }

            if (lDef.path)
            {
                ResolveParams rp1 = rp;
                rp1.floorDef = lDef.pathType ?? TerrainDefOf.Gravel;
                rp1.allowBridgeOnAnyImpassableTerrain = true;
                BaseGen.symbolStack.Push("floor", rp1, null);
            }

            // Destroy all things before spawning the base

            if (VFECore.VFEGlobal.settings.enableLog)
            {
                Log.Message("Clearing ground - PASS");
            }

            if (lDef.clearEverything)
            {
                foreach (IntVec3 c in rp.rect)
                {
                    c.GetThingList(map).ToList().ForEach((t) => t.DeSpawn()); // Remove all things
                    map.roofGrid.SetRoof(c, null);                            // Remove roof
                }
                map.roofGrid.RoofGridUpdate();                                // Update roof grid
            }
            else
            {
                foreach (IntVec3 c in rp.rect)
                {
                    c.GetThingList(map).ToList().FindAll(t1 => t1.def.category == ThingCategory.Filth || t1.def.category == ThingCategory.Item).ForEach((t) => t.DeSpawn());
                }
            }
        }
예제 #9
0
        public static void Generate(Map map, IntVec3 c, CustomGenOption sf, string symbolResolver = "kcsg_settlement")
        {
            CGO.useStructureLayout = sf.useStructureLayout;

            if (sf.useStructureLayout)
            {
                CGO.structureLayoutDef = LayoutUtils.ChooseLayoutFrom(sf.chooseFromlayouts);
            }
            else
            {
                CGO.settlementLayoutDef = sf.chooseFromSettlements.RandomElement();
            }

            // Get faction
            Faction faction;

            if (map.ParentFaction == null || map.ParentFaction == Faction.OfPlayer)
            {
                faction = Find.FactionManager.RandomEnemyFaction(false, false, true, TechLevel.Undefined);
            }
            else
            {
                faction = map.ParentFaction;
            }

            // Get settlement size
            int width;
            int height;

            if (sf.useStructureLayout)
            {
                RectUtils.HeightWidthFromLayout(CGO.structureLayoutDef, out height, out width);
            }
            else
            {
                SettlementLayoutDef temp = CGO.settlementLayoutDef;
                height = temp.settlementSize.x;
                width  = temp.settlementSize.z;
            }

            IntVec3 intVec3 = c;

            if (CGO.factionSettlement.tryFindFreeArea)
            {
                bool success = RCellFinder.TryFindRandomCellNearTheCenterOfTheMapWith(cell => new CellRect(cell.x - width / 2, cell.z - height / 2, width, height).Cells.All(pC => pC.Walkable(map) && !pC.GetTerrain(map).affordances.Contains(TerrainAffordanceDefOf.Bridgeable)), map, out intVec3);
                KLog.Message($"Trying to find free spawn area success: {success}");
            }

            CellRect rect = new CellRect(intVec3.x - width / 2, intVec3.z - height / 2, width, height);

            rect.ClipInsideMap(map);

            ResolveParams rp = default;

            rp.faction = faction;
            rp.rect    = rect;

            BaseGen.globalSettings.map = map;
            BaseGen.symbolStack.Push(symbolResolver, rp, null);
            BaseGen.Generate();
        }