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 float GetEnergyStored(float currentEnergyOtherSide) { if (thisBattery.PowerNet == null) { //Logger.MessageFormat(this, "No PowerNet found."); reloadedEnergyCalculated = true; oldDuplicateEnergy = duplicateEnergy = 1.0f; return(0.0f); } List <CompPowerBattery> networkBatteries = this.AvailableBatteries(); oldNetworkEnergy = networkEnergy; oldDuplicateEnergy = duplicateEnergy; duplicateEnergy = currentEnergyOtherSide; float duplicateEnergyChange = duplicateEnergy - oldDuplicateEnergy; networkEnergy = networkBatteries.Select(x => x.StoredEnergy).DefaultIfEmpty(0.0f).Sum(); float networkMaxEnergy = networkBatteries.Select(x => x.Props.storedEnergyMax).DefaultIfEmpty(0.0f).Sum(); energyGained = networkEnergy - oldNetworkEnergy; energyReturned = duplicateEnergyChange; //Logger.MessageFormat(this, "{0}, Old duplicate energy: {1}, new duplicate energy: {2}, Duplicate energy change: {3}, network: {4}/{5}", this.parent.GetType().ToString(), oldDuplicateEnergy, duplicateEnergy, duplicateEnergyChange, networkEnergy, networkMaxEnergy); if (reloadedEnergyCalculated && duplicateEnergyChange != 0.0f) { float networkEnergyPlusDuplicate = networkEnergy + duplicateEnergyChange; // If more energy lost in duplicate battery than available in duplicated network if (networkEnergyPlusDuplicate < 0.0f) { if (networkEnergy > 0.0f) { // Drain the whole thing foreach (CompPowerBattery battery in networkBatteries) { battery.SetStoredEnergyPct(0.0f); } networkEnergy = 0.0f; //Logger.MessageFormat(this, "Network drained"); } } // If more energy gained in duplicate battery than the network can hold else if (networkEnergyPlusDuplicate > networkMaxEnergy) { if (networkEnergy < networkMaxEnergy) { // Max the whole thing foreach (CompPowerBattery battery in networkBatteries) { battery.SetStoredEnergyPct(1.0f); } networkEnergy = networkMaxEnergy; //Logger.MessageFormat(this, "Network filled"); } } else if (oldDuplicateEnergy > 0.0f) { if (duplicateEnergyChange > 0.0f) { List <CompPowerBattery> shuffledBatteries = new List <CompPowerBattery>(); shuffledBatteries.AddRange(networkBatteries); float totalEnergyToGive = duplicateEnergyChange; int i = 0; while (totalEnergyToGive > 0.0f && i < shuffledBatteries.Count) { CompPowerBattery compPowerBattery = shuffledBatteries[i]; float energyCanRecieve = (compPowerBattery.Props.storedEnergyMax - compPowerBattery.StoredEnergy); float energyToGive = Mathf.Min(totalEnergyToGive, energyCanRecieve); compPowerBattery.AddEnergy(energyToGive / compPowerBattery.Props.efficiency); totalEnergyToGive -= energyToGive; ++i; } } else if (duplicateEnergyChange < 0.0f) { List <CompPowerBattery> shuffledBatteries = new List <CompPowerBattery>(); shuffledBatteries.AddRange(networkBatteries); float totalEnergyToGive = -duplicateEnergyChange; int i = 0; while (totalEnergyToGive > 0.0f && i < shuffledBatteries.Count) { CompPowerBattery compPowerBattery = shuffledBatteries[i]; float energyCanRemove = compPowerBattery.StoredEnergy; float energyToRemove = Mathf.Min(totalEnergyToGive, energyCanRemove); compPowerBattery.DrawPower(energyToRemove); totalEnergyToGive -= energyToRemove; ++i; } } //Logger.MessageFormat(this, "Duplicate energy change: {0}, energy returned to network: {1}", energyGained, energyReturned); } } reloadedEnergyCalculated = true; // Add in any extra energy stored in the sharer if (currentEnergyOtherSide > networkMaxEnergy) { networkEnergy += (currentEnergyOtherSide - networkMaxEnergy); } duplicateEnergy = networkEnergy; return(networkEnergy); }