public static bool CanPlaceAt(CustomVector point, StructureLayoutDef building, CustomVector[][] grid) { bool result = true; RectUtils.HeightWidthFromLayout(building, out int height, out int width); for (int i = (int)point.X - 1; i < width + point.X + 1 && result; i++) { for (int j = (int)(point.Y - 1); j < height + point.Y + 1 && result; j++) { if (IsInBound(i, j, grid.Length, grid[0].Length)) { if (grid[i][j] != null && grid[i][j].Type != CellType.NONE) { return(false); } } else { return(false); } } } return(result); }
public override void Resolve(ResolveParams rp) { Map map = BaseGen.globalSettings.map; StructureLayoutDef rld = DefDatabase <StructureLayoutDef> .GetNamed(FactionSettlement.temp); foreach (List <String> item in rld.layouts) { KCSG_Utilities.GenerateRoomFromLayout(item, rp.rect, map, rld); } 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); }
private static List <CustomVector> GetDoorsInLayout(StructureLayoutDef building) { List <CustomVector> doors = new List <CustomVector>(); foreach (List <string> layout in building.layouts) { List <string> rLayout = layout.ListFullCopy(); rLayout.Reverse(); for (int row = 0; row < rLayout.Count; row++) { string[] array = rLayout[row].Split(','); for (int col = 0; col < array.Length; col++) { if (array[col] != ".") { SymbolDef tempS = DefDatabase <SymbolDef> .GetNamedSilentFail(array[col]); if (tempS != null && tempS.thingDef != null && tempS.thingDef.altitudeLayer == AltitudeLayer.DoorMoveable) { doors.Add(new CustomVector(col, row)); } } } } } return(doors); }
public static List <CustomVector> PlaceAt(CustomVector point, StructureLayoutDef building, CustomVector[][] grid) { RectUtils.HeightWidthFromLayout(building, out int height, out int width); List <CustomVector> doors = GetDoorsInLayout(building); List <CustomVector> doorsAdjusted = new List <CustomVector>(); for (int i = (int)point.X; i < width + point.X; i++) { for (int j = (int)point.Y; j < height + point.Y; j++) { CellType type = doors.FindAll(d => i == d.X + point.X && j == d.Y + point.Y).Any() ? CellType.DOOR : CellType.BUILDING; if (type == CellType.DOOR) { doorsAdjusted.Add(new CustomVector(i, j)); } if (grid[i][j] != null) { grid[i][j].Type = type; } else { grid[i][j] = new CustomVector(i, j, type: type); } } } return(doorsAdjusted); }
private static void QuickspawnStructure() { if (DefDatabase <StructureLayoutDef> .AllDefs.Count() > 0) { List <DebugMenuOption> list = new List <DebugMenuOption>(); foreach (StructureLayoutDef localDef2 in DefDatabase <StructureLayoutDef> .AllDefs) { StructureLayoutDef localDef = localDef2; list.Add(new DebugMenuOption(localDef.defName, DebugMenuOptionMode.Tool, delegate() { if (UI.MouseCell().InBounds(Find.CurrentMap)) { RectUtils.HeightWidthFromLayout(localDef, out int h, out int w); CellRect cellRect = CellRect.CenteredOn(UI.MouseCell(), w, h); foreach (List <string> item in localDef.layouts) { GenUtils.GenerateRoomFromLayout(item, cellRect, Find.CurrentMap, localDef); } } })); } Find.WindowStack.Add(new Dialog_DebugOptionListLister(list)); } }
public override void PostMapGenerate(Map map) { if (Find.TickManager.TicksGame > 5f) { return; } StructureLayoutDef structureLayoutDef = chooseFrom.RandomElement(); if (VFECore.VFEGlobal.settings.enableLog) { Log.Message("ScenPart_AddStartingStructure - Structure choosen: " + structureLayoutDef.defName); } KCSG_Utilities.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = this.CreateCellRect(map, h, w); int count = 0; foreach (List <string> item in structureLayoutDef.layouts) { KCSG_Utilities.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef); if (VFECore.VFEGlobal.settings.enableLog) { Log.Message("ScenPart_AddStartingStructure - Layout " + count++.ToString() + " generation - PASS"); } } if (this.unfogBuilding) { this.UnfogBuildingsInRect(map, cellRect); } }
public static void HeightWidthFromLayout(StructureLayoutDef structureLayoutDef, out int height, out int width) { if (structureLayoutDef == null || structureLayoutDef.layouts.Count == 0) { Log.Warning("StructureLayoutDef was null or empty. Throwing 10 10 size"); height = 10; width = 10; return; } height = structureLayoutDef.layouts[0].Count; width = structureLayoutDef.layouts[0][0].Split(',').ToList().Count; }
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); }
public override void Resolve(ResolveParams rp) { CGO.currentGenStep = "Generating single structure"; Map map = BaseGen.globalSettings.map; StructureLayoutDef rld = CGO.structureLayoutDef; foreach (List <string> item in rld.layouts) { GenUtils.GenerateRoomFromLayout(item, rp.rect, map, rld); } GenUtils.EnsureBatteriesConnectedAndMakeSense(map, tmpThings, tmpPowerNetPredicateResults, tmpCells, KThingDefOf.KCSG_PowerConduit); GenUtils.EnsurePowerUsersConnected(map, tmpThings, tmpPowerNetPredicateResults, tmpCells, KThingDefOf.KCSG_PowerConduit); GenUtils.EnsureGeneratorsConnectedAndMakeSense(map, tmpThings, tmpPowerNetPredicateResults, tmpCells, KThingDefOf.KCSG_PowerConduit); }
public override void Generate(Map map, GenStepParams parms) { StructureLayoutDef structureLayoutDef = structureLayoutDefs.RandomElement(); RectUtils.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = CellRect.CenteredOn(map.Center, w, h); GenUtils.PreClean(map, cellRect, structureLayoutDef.roofGrid, fullClear); foreach (List <string> item in structureLayoutDef.layouts) { GenUtils.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef); } if (shouldRuin) { CGO.factionSettlement = new CustomGenOption { filthTypes = filthTypes, scatterThings = scatterThings, scatterChance = scatterChance }; ResolveParams rp = new ResolveParams { faction = map.ParentFaction, rect = cellRect }; foreach (string resolver in ruinSymbolResolvers) { if (!(ruinSymbolResolvers.Contains("kcsg_randomroofremoval") && resolver == "kcsg_scatterstuffaround")) { BaseGen.symbolStack.Push(resolver, rp, null); } } } // Flood refog if (map.mapPawns.FreeColonistsSpawned.Count > 0) { FloodFillerFog.DebugRefogMap(map); } }
public override void Generate(Map map, GenStepParams parms) { StructureLayoutDef structureLayoutDef = structureLayoutDefs.RandomElement(); KCSG_Utilities.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = CellRect.CenteredOn(map.Center, w, h); int count = 1; foreach (List <String> item in structureLayoutDef.layouts) { KCSG_Utilities.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef); if (VFECore.VFEGlobal.settings.enableLog) { Log.Message("Layout " + count.ToString() + " generation - PASS"); } count++; } }
public override void Generate(Map map, GenStepParams parms) { StructureLayoutDef structureLayoutDef = structureLayoutDefs.RandomElement(); KCSG_Utilities.HeightWidthFromLayout(structureLayoutDef, out int h, out int w); CellRect cellRect = CellRect.CenteredOn(map.Center, w, h); foreach (List <String> item in structureLayoutDef.layouts) { KCSG_Utilities.GenerateRoomFromLayout(item, cellRect, map, structureLayoutDef); } // Flood refog this.SetAllFogged(map); foreach (IntVec3 loc in map.AllCells) { map.mapDrawer.MapMeshDirty(loc, MapMeshFlag.FogOfWar); } // Remove power cable not connected to a powered grid map.listerBuildings.allBuildingsNonColonist.RemoveAll(b => b.TryGetComp <CompPowerTransmitter>() is CompPowerTransmitter cp && cp != null && cp.Props.transmitsPower == true && !cp.PowerNet.HasActivePowerSource); }
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); }
public WeightedStruct(StructureLayoutDef structureLayoutDef, float weight) { this.structureLayoutDef = structureLayoutDef; this.weight = weight; }
public static void GenerateRoomFromLayout(List <string> layoutList, CellRect roomRect, Map map, StructureLayoutDef rld, bool generateConduit = true) { bool parentFaction = map.ParentFaction != null; if (rld.roofGrid != null) { GenerateRoofGrid(rld.roofGrid, roomRect, map); } List <string> allSymbList = new List <string>(); foreach (string str in layoutList) { allSymbList.AddRange(str.Split(',')); } int l = 0; foreach (IntVec3 cell in roomRect) { if (l < allSymbList.Count && allSymbList[l] != ".") { SymbolDef temp = DefDatabase <SymbolDef> .GetNamedSilentFail(allSymbList[l]); Thing thing; if (temp != null) { if (temp.isTerrain && temp.terrainDef != null) { GenerateTerrainAt(map, cell, temp.terrainDef); } else if (temp.pawnKindDefNS != null && CGO.factionSettlement?.shouldRuin == false) { if (temp.lordJob != null) { Lord lord = CreateNewLord(temp.lordJob, map, cell); for (int i = 0; i < temp.numberToSpawn; i++) { Pawn pawn = temp.spawnPartOfFaction ? PawnGenerator.GeneratePawn(temp.pawnKindDefNS, map.ParentFaction) : PawnGenerator.GeneratePawn(temp.pawnKindDefNS); if (pawn != null) { if (temp.isSlave && parentFaction) { pawn.guest.SetGuestStatus(map.ParentFaction, GuestStatus.Prisoner); } GenSpawn.Spawn(pawn, cell, map, WipeMode.FullRefund); lord.AddPawn(pawn); } } } else { for (int i = 0; i < temp.numberToSpawn; i++) { Pawn pawn = temp.spawnPartOfFaction ? PawnGenerator.GeneratePawn(temp.pawnKindDefNS, map.ParentFaction) : PawnGenerator.GeneratePawn(temp.pawnKindDefNS); if (pawn != null) { if (temp.isSlave && parentFaction) { pawn.guest.SetGuestStatus(map.ParentFaction, GuestStatus.Prisoner); } GenSpawn.Spawn(pawn, cell, map, WipeMode.FullRefund); } } } } else if (temp.thingDef?.category == ThingCategory.Item && cell.Walkable(map)) { thing = ThingMaker.MakeThing(temp.thingDef, temp.stuffDef ?? (temp.thingDef.stuffCategories?.Count > 0 ? GenStuff.RandomStuffFor(temp.thingDef) : null)); thing.stackCount = Mathf.Clamp(Rand.RangeInclusive(1, temp.thingDef.stackLimit), 1, 75); CompQuality quality = thing.TryGetComp <CompQuality>(); quality?.SetQuality(QualityUtility.GenerateQualityBaseGen(), ArtGenerationContext.Outsider); GenSpawn.Spawn(thing, cell, map, WipeMode.FullRefund); thing.SetForbidden(true, false); } else if (temp.thingDef != null) { thing = ThingMaker.MakeThing(temp.thingDef, temp.thingDef.CostStuffCount > 0 ? (temp.stuffDef ?? temp.thingDef.defaultStuff ?? ThingDefOf.WoodLog) : null); CompRefuelable refuelable = thing.TryGetComp <CompRefuelable>(); refuelable?.Refuel(refuelable.Props.fuelCapacity); CompPowerBattery battery = thing.TryGetComp <CompPowerBattery>(); battery?.AddEnergy(battery.Props.storedEnergyMax); if (thing is Building_CryptosleepCasket cryptosleepCasket && Rand.Value < temp.chanceToContainPawn) { Pawn pawn = GeneratePawnForContainer(temp, map); if (!cryptosleepCasket.TryAcceptThing(pawn)) { pawn.Destroy(); } } else if (thing is Building_CorpseCasket corpseCasket && Rand.Value < temp.chanceToContainPawn) { Pawn pawn = GeneratePawnForContainer(temp, map); if (!corpseCasket.TryAcceptThing(pawn)) { pawn.Destroy(); } } else if (thing is Building_Crate crate) { List <Thing> thingList = new List <Thing>(); if (map.ParentFaction == Faction.OfPlayer && temp.thingSetMakerDefForPlayer != null) { thingList = temp.thingSetMakerDefForPlayer.root.Generate(new ThingSetMakerParams()); } else if (temp.thingSetMakerDef != null) { thingList = temp.thingSetMakerDef.root.Generate(new ThingSetMakerParams()); } foreach (Thing t in thingList) { t.stackCount = Math.Min((int)(t.stackCount * temp.crateStackMultiplier), t.def.stackLimit); } thingList.ForEach(t => { if (!crate.TryAcceptThing(t, false)) { t.Destroy(); } }); } if (thing.def.category == ThingCategory.Pawn && CGO.factionSettlement?.shouldRuin == true) { l++; continue; } else if (cell.GetFirstMineable(map) is Mineable m && thing.def.designationCategory == DesignationCategoryDefOf.Security) { l++; continue; } else if (thing.def.category == ThingCategory.Plant && cell.GetTerrain(map).fertility > 0.5 && cell.Walkable(map)) // If it's a plant { Plant plant = thing as Plant; plant.Growth = temp.plantGrowth; // apply the growth GenSpawn.Spawn(plant, cell, map, WipeMode.VanishOrMoveAside); } else if (thing.def.category == ThingCategory.Building) { if (!cell.GetTerrain(map).affordances.Contains(TerrainAffordanceDefOf.Heavy)) { if (thing.def.building.isNaturalRock) { TerrainDef t = DefDatabase <TerrainDef> .GetNamedSilentFail($"{thing.def.defName}_Rough"); map.terrainGrid.SetTerrain(cell, t ?? TerrainDefOf.Soil); foreach (IntVec3 intVec3 in CellRect.CenteredOn(cell, 1)) { if (!intVec3.GetTerrain(map).BuildableByPlayer) { map.terrainGrid.SetTerrain(intVec3, t ?? TerrainDefOf.Soil); } } } else { map.terrainGrid.SetTerrain(cell, TerrainDefOf.Bridge); } } if (thing.def.rotatable) { GenSpawn.Spawn(thing, cell, map, new Rot4(temp.rotation.AsInt), WipeMode.VanishOrMoveAside); } else { GenSpawn.Spawn(thing, cell, map, WipeMode.VanishOrMoveAside); } if (parentFaction) { thing.SetFactionDirect(map.ParentFaction); } } if (generateConduit && rld.spawnConduits && !thing.def.mineable && (thing.def.passability == Traversability.Impassable || thing.def.IsDoor) && map.ParentFaction?.def.techLevel >= TechLevel.Industrial) // Add power cable under all impassable { Thing c = ThingMaker.MakeThing(ThingDefOf.PowerConduit); if (parentFaction) { c.SetFactionDirect(map.ParentFaction); } GenSpawn.Spawn(c, cell, map, WipeMode.FullRefund); } // Handle mortar and mortar pawns if (thing?.def?.building?.buildingTags?.Count > 0) { if (thing.def.building.IsMortar && thing.def.category == ThingCategory.Building && thing.def.building.buildingTags.Contains("Artillery_MannedMortar") && thing.def.HasComp(typeof(CompMannable)) && parentFaction) { // Spawn pawn Lord singlePawnLord = LordMaker.MakeNewLord(map.ParentFaction, new LordJob_ManTurrets(), map, null); PawnGenerationRequest value = new PawnGenerationRequest(map.ParentFaction.RandomPawnKind(), map.ParentFaction, PawnGenerationContext.NonPlayer, map.Tile, mustBeCapableOfViolence: true, inhabitant: true); ResolveParams rpPawn = new ResolveParams { faction = map.ParentFaction, singlePawnGenerationRequest = new PawnGenerationRequest?(value), rect = CellRect.SingleCell(thing.InteractionCell), singlePawnLord = singlePawnLord }; BaseGen.symbolStack.Push("pawn", rpPawn); // Spawn shells ThingDef shellDef = TurretGunUtility.TryFindRandomShellDef(thing.def, false, true, map.ParentFaction.def.techLevel, false, 250f); if (shellDef != null) { ResolveParams rpShell = new ResolveParams { faction = map.ParentFaction, singleThingDef = shellDef, singleThingStackCount = Rand.RangeInclusive(8, Math.Min(12, shellDef.stackLimit)) }; BaseGen.symbolStack.Push("thing", rpShell); } } } }
public static void ClearFalling() { fallingStructure = null; fallingStructureChoosen = null; }