protected override void ScatterAt(IntVec3 c, Map map, GenStepParams parms, int stackCount = 1) { int randomInRange = SettlementSizeRange.RandomInRange; int randomInRange2 = SettlementSizeRange.RandomInRange; CellRect rect = new CellRect(c.x - randomInRange / 2, c.z - randomInRange2 / 2, randomInRange, randomInRange2); rect.ClipInsideMap(map); var faction = ExtendedFactionUtility.RandomFactionOfTechLevel(TechLevel.Medieval, allowDefeated: true); ResolveParams resolveParams = default; resolveParams.faction = faction; resolveParams.rect = rect; resolveParams.noRoof = true; resolveParams.chanceToSkipWallBlock = 0.22f; resolveParams.SetCustom(VFEResolveParams.Name, new VFEResolveParams()); var vfeParams = resolveParams.GetCustom <VFEResolveParams>(VFEResolveParams.Name); Log.Message(vfeParams.ToStringSafe()); vfeParams.hasDoors = false; vfeParams.outdoorLighting = false; vfeParams.generatePawns = false; BaseGen.globalSettings.map = map; BaseGen.globalSettings.minBuildings = 1; BaseGen.globalSettings.minBarracks = 1; BaseGen.symbolStack.Push("VFEM_medievalSettlement", resolveParams); BaseGen.Generate(); }
public override void Resolve(ResolveParams rp) { if (rp.wallStuff == null) { rp.wallStuff = ThingDefOf.Steel; } if (rp.floorDef == null) { rp.floorDef = BaseGenUtility.CorrespondingTerrainDef(rp.wallStuff, true); } ResolveParams resolveParams = rp; ResolveParams resolveParams2 = rp; ResolveParams resolveParams3 = rp; ResolveParams resolveParams4 = rp; resolveParams.rect = new CellRect(rp.rect.minX, rp.rect.minZ, 1 + 2 * Rand.RangeInclusive(2, 4), 1 + 2 * Rand.RangeInclusive(3, 7)); int num = 1 + 2 * Rand.RangeInclusive(4, 12); int num2 = 1 + 2 * Rand.RangeInclusive(4, 10); resolveParams2.rect = new CellRect(resolveParams.rect.maxX, resolveParams.rect.minZ - (int)Math.Round((double)((float)(num2 - resolveParams.rect.Height) / 2f)), num, num2); num = 1 + 2 * Rand.RangeInclusive(4, 8); num2 = num; resolveParams3.rect = new CellRect(resolveParams2.rect.maxX, resolveParams2.rect.minZ - (int)Math.Round((double)((float)(num2 - resolveParams2.rect.Height) / 2f)), num, num2); if (resolveParams3.rect.Height >= resolveParams2.rect.Height && resolveParams3.rect.Height >= resolveParams.rect.Height) { resolveParams4.rect = new CellRect(0, resolveParams3.rect.minZ, resolveParams3.rect.minX, resolveParams3.rect.Height); } else if (resolveParams2.rect.Height >= resolveParams.rect.Height) { resolveParams4.rect = new CellRect(0, resolveParams2.rect.minZ, resolveParams2.rect.minX, resolveParams2.rect.Height); } else { resolveParams4.rect = new CellRect(0, resolveParams.rect.minZ, resolveParams.rect.minX, resolveParams.rect.Height); } ResolveParams resolveParams5 = resolveParams; resolveParams5.rect = new CellRect(resolveParams.rect.minX - 2, resolveParams.rect.minZ + 1, 1, 1); resolveParams5.thingRot = new Rot4?(new Rot4(1)); resolveParams5.singleThingDef = ThingDefOf.Ship_Engine; BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null); resolveParams5.rect.minZ = resolveParams5.rect.minZ + 2; BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null); resolveParams5.rect.minZ = resolveParams.rect.maxZ; BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null); resolveParams5.rect.minZ = resolveParams5.rect.minZ - 2; BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null); BaseGen.symbolStack.Push("batteryRoom", resolveParams, null); resolveParams2.SetCustom <char[]>("hasDoor", new char[] { 'N', 'S', 'E', 'W' }, false); BaseGen.symbolStack.Push("interior_diningRoom", resolveParams2, null); BaseGen.symbolStack.Push("roomWithDoor", resolveParams2, null); BaseGen.symbolStack.Push("triangularRoom", resolveParams3, null); BaseGen.symbolStack.Push("pathOfDestruction", resolveParams4, null); }
public override void Generate(Map map, GenStepParams parms) { Debug.Log(Debug.Scatter, "Medium generate"); Find.TickManager.Pause(); currentOptions = RealRuins_ModSettings.defaultScatterOptions.Copy(); //store as instance variable to keep accessible on subsequent ScatterAt calls currentOptions.minRadius = 24; currentOptions.maxRadius = 50; currentOptions.scavengingMultiplier = 0.1f; currentOptions.deteriorationMultiplier = 0.1f; currentOptions.hostileChance = 0.8f; currentOptions.itemCostLimit = 800; currentOptions.minimumCostRequired = 25000; currentOptions.minimumDensityRequired = 0.01f; currentOptions.minimumAreaRequired = 4000; currentOptions.deleteLowQuality = false; //do not delete since we have much higher requirements for base ruins currentOptions.shouldKeepDefencesAndPower = true; ResolveParams rp = default(ResolveParams); BaseGen.globalSettings.map = map; rp.rect = new CellRect(0, 0, map.Size.x, map.Size.z); rp.SetCustom <ScatterOptions>(Constants.ScatterOptions, currentOptions); rp.faction = Find.FactionManager.OfAncientsHostile; BaseGen.symbolStack.Push("chargeBatteries", rp); BaseGen.symbolStack.Push("refuel", rp); BaseGen.symbolStack.Push("scatterRuins", rp); if (Rand.Chance(0.5f * Find.Storyteller.difficulty.threatScale)) { float pointsCost = Math.Abs(Rand.Gaussian()) * 500 * Find.Storyteller.difficulty.threatScale; rp.faction = Find.FactionManager.RandomEnemyFaction(); rp.singlePawnLord = LordMaker.MakeNewLord(rp.faction, new LordJob_AssaultColony(rp.faction, false, false, true, true), map, null); rp.pawnGroupKindDef = (rp.pawnGroupKindDef ?? PawnGroupKindDefOf.Settlement); if (rp.pawnGroupMakerParams == null) { rp.pawnGroupMakerParams = new PawnGroupMakerParms(); rp.pawnGroupMakerParams.tile = map.Tile; rp.pawnGroupMakerParams.faction = rp.faction; PawnGroupMakerParms pawnGroupMakerParams = rp.pawnGroupMakerParams; pawnGroupMakerParams.points = pointsCost; } BaseGen.symbolStack.Push("pawnGroup", rp); } BaseGen.Generate(); }
public override void Resolve(ResolveParams rp) { ResolveParams resolveParams = rp; resolveParams.rect = rp.rect.ContractedBy(1); resolveParams.wallStuff = ThingDefOf.BlocksGranite; resolveParams.SetCustom <int>("minRoomDimension", 6, false); BaseGen.symbolStack.Push("nestedRoomMaze", resolveParams, null); BaseGen.symbolStack.Push("edgeWalls", resolveParams, null); rp.wallStuff = ThingDefOf.Steel; BaseGen.symbolStack.Push("edgeWalls", rp, null); BaseGen.symbolStack.Push("floor", rp, null); BaseGen.symbolStack.Push("clear", rp, null); }
private void MakeRoom(ResolveParams rp) { char[] array = new char[3]; char[] source = new char[] { 'N', 'S', 'E', 'W' }; array[0] = source.RandomElement <char>(); array[1] = source.RandomElement <char>(); if (array[1] == array[0]) { array[1] = 'X'; } rp.SetCustom <char[]>("hasDoor", array, false); BaseGen.symbolStack.Push("roomWithDoor", rp, null); }
public override void Resolve(ResolveParams rp) { ResolveParams resolveParams = rp; resolveParams.rect = rp.rect.ContractedBy(1); resolveParams.wallStuff = ThingDefOf.BlocksGranite; rp.wallStuff = ThingDefOf.Steel; resolveParams.SetCustom <int>("minRoomDimension", 6, false); BaseGen.globalSettings.minBuildings = 3; BaseGen.globalSettings.minBarracks = 1; BaseGen.symbolStack.Push("factionBase", resolveParams); //BaseGen.symbolStack.Push("edgeStreet", resolveParams); //BaseGen.symbolStack.Push("edgeDefense", resolveParams); BaseGen.symbolStack.Push("ancientCryptosleepCasket", rp); BaseGen.symbolStack.Push("ancientCryptosleepCasket", rp); BaseGen.symbolStack.Push("ancientCryptosleepCasket", rp); CellRect field = rp.rect; field.minX = Rand.RangeInclusive(rp.rect.minX, rp.rect.maxX - 15); field.minZ = Rand.RangeInclusive(rp.rect.minZ + 15, rp.rect.maxZ - 15); field.Width = 5; field.Height = 4; //BaseGen.symbolStack.Push("cultivatedPlants", field); BaseGen.symbolStack.Push("wireOutline", rp); //field.minX = Rand.RangeInclusive(rp.rect.minX, rp.rect.maxX); //field.minZ = Rand.RangeInclusive(rp.rect.minZ, rp.rect.maxZ); //field.Width = 4; //field.Height = 4; //BaseGen.symbolStack.Push("batteryRoom", field); //field.Width = 2; //field.Height = 2; //BaseGen.symbolStack.Push("wireOutline", field); BaseGen.symbolStack.Push("chargeBatteries", resolveParams); BaseGen.symbolStack.Push("clear", rp); }
public override void Resolve(ResolveParams rp) { ThingDef thingDef = (from d in DefDatabase <ThingDef> .AllDefs where d.IsStuff && d.stuffProps.CanMake(ThingDefOf.Wall) && d.stuffProps.categories.Contains(StuffCategoryDefOf.Stony) && d != ThingDef.Named("Jade") select d).ToList <ThingDef>().RandomElementByWeight((ThingDef x) => 3f + 1f / x.BaseMarketValue); rp.wallStuff = thingDef; rp.floorDef = BaseGenUtility.CorrespondingTerrainDef(thingDef, true); int num = Rand.RangeInclusive(30, 40); for (int i = 0; i < num; i++) { int minX = Rand.RangeInclusive(rp.rect.minX, rp.rect.maxX - 1); int minZ = Rand.RangeInclusive(rp.rect.minZ, rp.rect.maxZ - 1); ResolveParams resolveParams = rp; resolveParams.rect = new CellRect(minX, minZ, Rand.RangeInclusive(1, 3), Rand.RangeInclusive(1, 3)); BaseGen.symbolStack.Push("pathOfDestruction", resolveParams, null); } for (int j = 0; j < Rand.RangeInclusive(2, 5); j++) { int minX2 = Rand.RangeInclusive(rp.rect.minX + 4, rp.rect.maxX - 10); int minZ2 = Rand.RangeInclusive(rp.rect.minZ + 4, rp.rect.maxZ - 10); ResolveParams resolveParams2 = rp; resolveParams2.rect = new CellRect(minX2, minZ2, Rand.RangeInclusive(5, 8), Rand.RangeInclusive(5, 8)); BaseGen.symbolStack.Push("emptyRoom", resolveParams2, null); } ResolveParams resolveParams3 = rp; resolveParams3.rect = resolveParams3.rect.ContractedBy(21); ResolveParams resolveParams4 = resolveParams3; resolveParams4.rect.Width = (int)(0.25 * (double)resolveParams3.rect.Width); resolveParams4.rect.Height = resolveParams4.rect.Width; for (int k = 0; k < 4; k++) { BaseGen.symbolStack.Push("roomWithDoor", resolveParams4, null); resolveParams4.rect = new CellRect(resolveParams4.rect.minX, resolveParams4.rect.maxZ, resolveParams4.rect.Width, resolveParams4.rect.Height); } resolveParams3.SetCustom <char[]>("hasDoor", new char[] { 'N' }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams3, null); ResolveParams resolveParams5 = rp; resolveParams5.rect = rp.rect.ContractedBy(5); ResolveParams resolveParams6 = resolveParams5; for (int l = 0; l < 25; l++) { int width = Rand.RangeInclusive(4, 6); int height = Rand.RangeInclusive(4, 7); if (resolveParams6.rect.minX > resolveParams5.rect.maxX - 3) { break; } resolveParams6.rect = new CellRect(resolveParams6.rect.minX, resolveParams5.rect.minZ, width, height); if (Rand.Chance(0.15f)) { resolveParams6.rect.minX = resolveParams6.rect.minX + 3; } else { char c = (!Rand.Chance(0.1f)) ? 'N' : 'W'; resolveParams6.SetCustom <char[]>("hasDoor", new char[] { c }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null); resolveParams6.rect.minX = resolveParams6.rect.maxX; } } resolveParams6 = resolveParams5; for (int m = 0; m < 25; m++) { int width2 = Rand.RangeInclusive(4, 6); int num2 = Rand.RangeInclusive(4, 7); if (resolveParams6.rect.minX > resolveParams5.rect.maxX - 3) { break; } resolveParams6.rect = new CellRect(resolveParams6.rect.minX, resolveParams5.rect.maxZ + 1 - num2, width2, num2); if (Rand.Chance(0.15f)) { resolveParams6.rect.minX = resolveParams6.rect.minX + 3; } else { char c2 = (!Rand.Chance(0.1f)) ? 'S' : 'W'; resolveParams6.SetCustom <char[]>("hasDoor", new char[] { c2 }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null); resolveParams6.rect.minX = resolveParams6.rect.maxX; } } resolveParams6 = resolveParams5; resolveParams6.rect.minZ = resolveParams6.rect.minZ + 4; for (int n = 0; n < 25; n++) { int width3 = Rand.RangeInclusive(4, 6); int height2 = Rand.RangeInclusive(4, 7); if (resolveParams6.rect.minZ > resolveParams5.rect.maxZ - 4) { break; } resolveParams6.rect = new CellRect(resolveParams5.rect.minX, resolveParams6.rect.minZ, width3, height2); if (Rand.Chance(0.15f)) { resolveParams6.rect.minZ = resolveParams6.rect.minZ + 3; } else { char c3 = (!Rand.Chance(0.1f)) ? 'E' : 'S'; resolveParams6.SetCustom <char[]>("hasDoor", new char[] { c3 }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null); resolveParams6.rect.minZ = resolveParams6.rect.maxZ; } } resolveParams6 = resolveParams5; resolveParams6.rect.minZ = resolveParams6.rect.minZ + 4; for (int num3 = 0; num3 < 25; num3++) { int num4 = Rand.RangeInclusive(4, 6); int height3 = Rand.RangeInclusive(4, 7); if (resolveParams6.rect.minZ > resolveParams5.rect.maxZ - 4) { break; } resolveParams6.rect = new CellRect(resolveParams5.rect.maxX + 1 - num4, resolveParams6.rect.minZ, num4, height3); if (Rand.Chance(0.15f)) { resolveParams6.rect.minZ = resolveParams6.rect.minZ + 3; } else { char c4 = (!Rand.Chance(0.1f)) ? 'W' : 'S'; resolveParams6.SetCustom <char[]>("hasDoor", new char[] { c4 }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null); resolveParams6.rect.minZ = resolveParams6.rect.maxZ; } } ResolveParams resolveParams10; ResolveParams resolveParams9; ResolveParams resolveParams8; ResolveParams resolveParams7 = resolveParams8 = (resolveParams9 = (resolveParams10 = rp)); CellRect cellRect = new CellRect(rp.rect.maxX, rp.rect.maxZ, 1, 1); resolveParams8.rect = cellRect.ExpandedBy(4); CellRect cellRect2 = new CellRect(rp.rect.minX, rp.rect.maxZ, 1, 1); resolveParams7.rect = cellRect2.ExpandedBy(4); CellRect cellRect3 = new CellRect(rp.rect.maxX, rp.rect.minZ, 1, 1); resolveParams9.rect = cellRect3.ExpandedBy(4); CellRect cellRect4 = new CellRect(rp.rect.minX, rp.rect.minZ, 1, 1); resolveParams10.rect = cellRect4.ExpandedBy(4); resolveParams8.SetCustom <char[]>("hasDoor", new char[] { 'S', 'W' }, false); resolveParams7.SetCustom <char[]>("hasDoor", new char[] { 'S', 'E' }, false); resolveParams9.SetCustom <char[]>("hasDoor", new char[] { 'N', 'W' }, false); resolveParams10.SetCustom <char[]>("hasDoor", new char[] { 'N', 'E' }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams8, null); BaseGen.symbolStack.Push("roomWithDoor", resolveParams7, null); BaseGen.symbolStack.Push("roomWithDoor", resolveParams9, null); BaseGen.symbolStack.Push("roomWithDoor", resolveParams10, null); ResolveParams resolveParams11 = rp; resolveParams11.rect = resolveParams11.rect.ContractedBy(3); BaseGen.symbolStack.Push("edgeShields", resolveParams11, null); ResolveParams resolveParams12 = rp; BaseGen.symbolStack.Push("doors", resolveParams12, null); BaseGen.symbolStack.Push("edgeWalls", resolveParams12, null); BaseGen.symbolStack.Push("floor", resolveParams12, null); }
public override void Resolve(ResolveParams rp) { rp.SetCustom(VFEResolveParams.Name, new VFEResolveParams(), true); var medievalResolveParams = rp.GetCustom <VFEResolveParams>(VFEResolveParams.Name); var faction = rp.faction ?? Find.FactionManager.RandomEnemyFaction(false, false, true, TechLevel.Undefined); float num2 = rp.rect.Area / 144f * 0.17f; BaseGen.globalSettings.minEmptyNodes = (num2 >= 1f) ? GenMath.RoundRandom(num2) : 0; // Generate pawns if (medievalResolveParams.generatePawns != false) { var map = BaseGen.globalSettings.map; var pawnParams = rp; pawnParams.rect = rp.rect; pawnParams.faction = faction; pawnParams.singlePawnLord = rp.singlePawnLord ?? LordMaker.MakeNewLord(faction, new LordJob_DefendBase(faction, rp.rect.CenterCell), map, null); pawnParams.pawnGroupKindDef = rp.pawnGroupKindDef ?? PawnGroupKindDefOf.Settlement; pawnParams.singlePawnSpawnCellExtraPredicate = rp.singlePawnSpawnCellExtraPredicate ?? ((IntVec3 x) => map.reachability.CanReachMapEdge(x, TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false))); if (pawnParams.pawnGroupMakerParams == null) { pawnParams.pawnGroupMakerParams = new PawnGroupMakerParms(); pawnParams.pawnGroupMakerParams.tile = map.Tile; pawnParams.pawnGroupMakerParams.faction = faction; var pawnGroupMakerParams = pawnParams.pawnGroupMakerParams; float?settlementPawnGroupPoints = rp.settlementPawnGroupPoints; pawnGroupMakerParams.points = (settlementPawnGroupPoints == null) ? DefaultPawnsPoints.RandomInRange : settlementPawnGroupPoints.Value; pawnParams.pawnGroupMakerParams.inhabitants = true; pawnParams.pawnGroupMakerParams.seed = rp.settlementPawnGroupSeed; } BaseGen.symbolStack.Push("pawnGroup", pawnParams); } // Generate outdoor lighting if (medievalResolveParams.outdoorLighting != false) { BaseGen.symbolStack.Push("outdoorLighting", rp); } // Generate firefoam poppers if applicable if (faction.def.techLevel >= TechLevel.Industrial) { int num3 = (!Rand.Chance(0.75f)) ? 0 : GenMath.RoundRandom((float)rp.rect.Area / 400f); for (int i = 0; i < num3; i++) { ResolveParams firefoamParams = rp; firefoamParams.faction = faction; BaseGen.symbolStack.Push("firefoamPopper", firefoamParams); } } // Generate defences float towerRadius = 0; float?curTowerRadius = medievalResolveParams.towerRadius; if (curTowerRadius != null) { towerRadius = rp.edgeDefenseWidth.Value; } else if (rp.rect.Width >= 20 && rp.rect.Height >= 20) { towerRadius = (Rand.Bool) ? 3.9f : 4.9f; } if (towerRadius > 0) { ResolveParams defenceParams = rp; var medievalDefenceParams = defenceParams.GetCustom <VFEResolveParams>(VFEResolveParams.Name); defenceParams.faction = faction; medievalDefenceParams.towerRadius = towerRadius; BaseGen.symbolStack.Push("VFEM_medievalEdgeDefense", defenceParams); } // Map edge reachability int towerRadCeil = Mathf.CeilToInt(towerRadius); ResolveParams edgeReachParams = rp; edgeReachParams.rect = rp.rect.ContractedBy(towerRadCeil); edgeReachParams.faction = faction; BaseGen.symbolStack.Push("ensureCanReachMapEdge", edgeReachParams); // Generate base ResolveParams baseParams = rp; baseParams.rect = rp.rect.ContractedBy(towerRadCeil); baseParams.faction = faction; BaseGen.symbolStack.Push("basePart_outdoors", baseParams); // Generate flooring ResolveParams floorParams = rp; floorParams.floorDef = TerrainDefOf.Bridge; bool?floorOnlyIfTerrainSupports = rp.floorOnlyIfTerrainSupports; floorParams.floorOnlyIfTerrainSupports = floorOnlyIfTerrainSupports == null || floorOnlyIfTerrainSupports.Value; BaseGen.symbolStack.Push("floor", floorParams); }
public override void Resolve(ResolveParams rp) { rp.floorDef = TerrainDefOf.Concrete; ThingDef plasteel = ThingDefOf.Plasteel; ResolveParams resolveParams = rp; rp.wallStuff = plasteel; int minX = Rand.RangeInclusive(rp.rect.minX + 5, rp.rect.minX + 10); int minZ = Rand.RangeInclusive(rp.rect.minZ + 5, rp.rect.minZ + 10); int width = Rand.RangeInclusive(25, 35); int height = Rand.RangeInclusive(25, 35); resolveParams.rect = new CellRect(minX, minZ, width, height); resolveParams.floorDef = TerrainDefOf.WoodPlankFloor; resolveParams.wallStuff = ThingDefOf.Plasteel; ResolveParams resolveParams2 = resolveParams; ResolveParams resolveParams3 = resolveParams; List <ThingDef> list = new List <ThingDef>(); list.Add(ThingDef.Named("DrugLab")); list.Add(ThingDef.Named("SimpleResearchBench")); list.Add(ThingDef.Named("SimpleResearchBench")); list.Add(ThingDef.Named("SimpleResearchBench")); list.Add(ThingDef.Named("HiTechResearchBench")); resolveParams2.floorDef = TerrainDefOf.MetalTile; resolveParams2.wallStuff = ThingDefOf.Plasteel; resolveParams2.SetCustom <char[]>("hasDoor", new char[] { 'E' }, false); for (int i = 0; i < 20; i++) { if (resolveParams2.rect.minZ > resolveParams.rect.maxZ - 2) { break; } resolveParams2.rect = new CellRect(resolveParams2.rect.minX, resolveParams2.rect.minZ, 7, 6); resolveParams3.rect = resolveParams2.rect.ContractedBy(1); resolveParams3.rect = new CellRect(resolveParams3.rect.minX + 1, resolveParams3.rect.minZ + 1, 1, 1); resolveParams3.thingRot = new Rot4?(Rot4.West); resolveParams3.singleThingDef = list.RandomElement <ThingDef>(); BaseGen.symbolStack.Push("insertFurnishing", resolveParams3, null); BaseGen.symbolStack.Push("roomWithDoor", resolveParams2, null); resolveParams2.rect.minZ = resolveParams2.rect.maxZ; } resolveParams2.rect.minX = resolveParams2.rect.maxX + 3; Rot4 rot = Rot4.North; if (Rand.Chance(0.5f)) { resolveParams2.rect.minZ = resolveParams.rect.minZ; resolveParams2.SetCustom <char[]>("hasDoor", new char[] { 'N' }, false); resolveParams.SetCustom <char[]>("hasDoor", new char[] { 'E', 'N' }, false); rot = Rot4.South; } else { resolveParams2.rect.minZ = resolveParams.rect.maxZ - 6; resolveParams2.SetCustom <char[]>("hasDoor", new char[] { 'S' }, false); resolveParams.SetCustom <char[]>("hasDoor", new char[] { 'E', 'S' }, false); } for (int j = 0; j < 20; j++) { if (resolveParams2.rect.minX > resolveParams.rect.maxX - 2) { break; } resolveParams2.rect = new CellRect(resolveParams2.rect.minX, resolveParams2.rect.minZ, 6, 7); resolveParams3.rect = resolveParams2.rect.ContractedBy(1); if (rot == Rot4.South) { resolveParams3.rect = new CellRect(resolveParams3.rect.minX + 1, resolveParams3.rect.minZ + 1, 1, 1); } else { resolveParams3.rect = new CellRect(resolveParams3.rect.minX + 1, resolveParams3.rect.maxZ - 1, 1, 1); } resolveParams3.thingRot = new Rot4?(rot); resolveParams3.singleThingDef = list.RandomElement <ThingDef>(); BaseGen.symbolStack.Push("insertFurnishing", resolveParams3, null); BaseGen.symbolStack.Push("roomWithDoor", resolveParams2, null); resolveParams2.rect.minX = resolveParams2.rect.maxX; } ResolveParams resolveParams4 = rp; resolveParams4.singleThingDef = ThingDef.Named("Table2x4c"); resolveParams4.rect = new CellRect(resolveParams.rect.CenterCell.x, resolveParams.rect.CenterCell.z, 1, 1); resolveParams4.thingRot = new Rot4?(Rot4.North); BaseGen.symbolStack.Push("insertFurnishing", resolveParams4, null); for (int k = 0; k < 4; k++) { resolveParams4.singleThingDef = ThingDef.Named("DiningChair"); resolveParams4.rect = new CellRect(resolveParams.rect.CenterCell.x - 1, resolveParams.rect.CenterCell.z + 2 - k, 1, 1); resolveParams4.thingRot = new Rot4?(Rot4.East); BaseGen.symbolStack.Push("insertFurnishing", resolveParams4, null); } BaseGen.symbolStack.Push("roomWithDoor", resolveParams, null); resolveParams.chanceToSkipWallBlock = new float?(0.05f); BaseGen.symbolStack.Push("wireOutline", resolveParams, null); ResolveParams resolveParams5 = rp; resolveParams5.rect = rp.rect.ContractedBy(2); resolveParams5.rect = new CellRect(resolveParams5.rect.minX, resolveParams5.rect.minZ, 6, 5); resolveParams5.wallStuff = ThingDef.Named("BlocksLimestone"); resolveParams5.SetCustom <char[]>("hasDoor", new char[] { 'N' }, false); BaseGen.symbolStack.Push("roomWithDoor", resolveParams5, null); BaseGen.symbolStack.Push("wireOutline", resolveParams5, null); resolveParams5.rect = resolveParams5.rect.ContractedBy(1); resolveParams5.singleThingDef = ThingDef.Named("ChemfuelPoweredGenerator"); resolveParams5.thingRot = new Rot4?(Rot4.North); BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null); BaseGen.symbolStack.Push("edgeFence", rp, null); BaseGen.symbolStack.Push("floor", rp, null); BaseGen.symbolStack.Push("clear", rp, null); }
public override void Resolve(ResolveParams rp) { char[] array; if (rp.TryGetCustom <char[]>("hasDoor", out array)) { if (rp.rect.Width < 3 && rp.rect.Height < 3) { return; } ResolveParams resolveParams = rp; char[] array2 = array; int i = 0; while (i < array2.Length) { char c = array2[i]; if (c == 'N') { resolveParams.thingRot = new Rot4?(Rot4.North); resolveParams.rect = new CellRect(rp.rect.minX + 1, rp.rect.maxZ, rp.rect.Width - 2, 1); goto IL_1AA; } if (c == 'S') { resolveParams.thingRot = new Rot4?(Rot4.South); resolveParams.rect = new CellRect(rp.rect.minX + 1, rp.rect.minZ, rp.rect.Width - 2, 1); goto IL_1AA; } if (c == 'E') { resolveParams.thingRot = new Rot4?(Rot4.East); resolveParams.rect = new CellRect(rp.rect.maxX, rp.rect.minZ + 1, 1, rp.rect.Height - 2); goto IL_1AA; } if (c == 'W') { resolveParams.thingRot = new Rot4?(Rot4.West); resolveParams.rect = new CellRect(rp.rect.minX, rp.rect.minZ + 1, 1, rp.rect.Height - 2); goto IL_1AA; } IL_1BB: i++; continue; IL_1AA: BaseGen.symbolStack.Push("wallDoor", resolveParams, null); goto IL_1BB; } } float chance; rp.TryGetCustom <float>("madAnimalChance", out chance); float chance2; rp.TryGetCustom <float>("luciferiumGasChance", out chance2); float chance3; rp.TryGetCustom <float>("psionicLandmineChance", out chance3); float chance4; rp.TryGetCustom <float>("smallGoldChance", out chance4); float chance5; rp.TryGetCustom <float>("smallSilverChance", out chance5); RectActionTrigger rectActionTrigger = ThingMaker.MakeThing(ThingDefOfReconAndDiscovery.RD_RectActionTrigger, null) as RectActionTrigger; rectActionTrigger.Rect = rp.rect; if (Rand.Chance(chance)) { rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_MadAnimal; } else if (Rand.Chance(chance2)) { rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_LuciferiumGas; } else if (Rand.Chance(chance3)) { rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_PsionicLandmine; } else if (Rand.Chance(chance4)) { rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_SmallGold; } else if (Rand.Chance(chance5)) { rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_SmallSilver; } else { rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_BaseActivatedAction; } if (rectActionTrigger.actionDef != null) { ResolveParams resolveParams2 = rp; resolveParams2.SetCustom <RectActionTrigger>("trigger", rectActionTrigger, false); BaseGen.symbolStack.Push("placeTrigger", resolveParams2, null); } BaseGen.symbolStack.Push("emptyRoom", rp, null); }
public override void Resolve(ResolveParams rp) { int num; if (!rp.TryGetCustom <int>("minRoomDimension", out num)) { Log.Error("Could not find a field minRoomDimension"); } else { int width = rp.rect.Width; int height = rp.rect.Height; Log.Message(string.Format("Current nested room dimensions -> ({0}:{1})", width, height)); if (width < 2 * num && height < 2 * num) { this.MakeRoom(rp); } else if ((width < 4 * num || height < 4 * num) && Rand.Value < 0.2f) { ResolveParams rp2 = rp; ResolveParams rp3 = rp; rp2.rect.Width = rp.rect.Width / 2; rp3.rect.minX = rp2.rect.maxX; rp3.rect.Width = rp.rect.Width / 2; this.MakeRoom(rp2); this.MakeRoom(rp3); } else if (width < 4 * num && height < 4 * num && Rand.Value < 0.1f) { this.MakeRoom(rp); } else { List <CellRect> list = new List <CellRect>(); List <CellRect> list2 = new List <CellRect>(); if (width > 2 * num) { list.Add(new CellRect(rp.rect.minX, rp.rect.minZ, rp.rect.Width / 2, rp.rect.Height)); list.Add(new CellRect(rp.rect.minX + rp.rect.Width / 2 - 1, rp.rect.minZ, rp.rect.Width / 2, rp.rect.Height)); } else { list.Add(new CellRect(rp.rect.minX, rp.rect.minZ, rp.rect.Width, rp.rect.Height)); } foreach (CellRect item in list) { if (height > 2 * num) { list2.Add(new CellRect(item.minX, item.minZ, item.Width, item.Height / 2)); list2.Add(new CellRect(item.minX, item.minZ + item.Height / 2 - 1, item.Width, item.Height / 2)); } else { list2.Add(item); } } foreach (CellRect rect in list2) { ResolveParams resolveParams = rp; resolveParams.rect = rect; resolveParams.SetCustom <int>("minRoomDimension", num, false); BaseGen.symbolStack.Push("nestedRoomMaze", resolveParams, null); } } } }
public override void Generate(Map map, GenStepParams parms) { Find.TickManager.Pause(); //Debug.Message("Overridden LARGE generate"); RealRuinsPOIComp poiComp = map.Parent.GetComponent <RealRuinsPOIComp>(); string filename = SnapshotStoreManager.Instance.SnapshotNameFor(poiComp.blueprintName, poiComp.gameName); Debug.Log("Spawning POI: Preselected file name is {0}", filename); Debug.Log("Location is {0} {1}", poiComp.originX, poiComp.originZ); currentOptions = RealRuins_ModSettings.defaultScatterOptions.Copy(); //store as instance variable to keep accessible on subsequent ScatterAt calls currentOptions.minRadius = 400; currentOptions.maxRadius = 400; currentOptions.scavengingMultiplier = 0.0f; currentOptions.deteriorationMultiplier = 0.0f; currentOptions.hostileChance = 0.0f; currentOptions.blueprintFileName = filename; currentOptions.costCap = -1; currentOptions.startingPartyPoints = -1; currentOptions.minimumCostRequired = 0; currentOptions.minimumDensityRequired = 0.0f; currentOptions.minimumAreaRequired = 0; currentOptions.deleteLowQuality = false; currentOptions.shouldKeepDefencesAndPower = true; currentOptions.shouldLoadPartOnly = false; currentOptions.shouldAddRaidTriggers = false; currentOptions.claimableBlocks = false; if (poiComp.poiType == (int)POIType.Ruins || map.ParentFaction == null) { /*if (Rand.Chance(0.1f)) { * currentOptions.wallsDoorsOnly = true; * } else { * currentOptions.deteriorationMultiplier = Math.Abs(Rand.Gaussian(0, 0.15f)); * }*/ currentOptions.shouldAddFilth = true; currentOptions.forceFullHitPoints = false; currentOptions.enableDeterioration = true; currentOptions.overwritesEverything = false; currentOptions.costCap = (int)Math.Abs(Rand.Gaussian(0, 10000)); currentOptions.itemCostLimit = Rand.Range(50, 300); } else { currentOptions.shouldAddFilth = false; currentOptions.forceFullHitPoints = true; currentOptions.enableDeterioration = false; currentOptions.overwritesEverything = true; } currentOptions.overridePosition = new IntVec3(poiComp.originX, 0, poiComp.originZ); currentOptions.centerIfExceedsBounds = true; var bp = BlueprintLoader.LoadWholeBlueprintAtPath(filename); //FOR DEBUG LOGGING //var a = new BlueprintAnalyzer(bp, currentOptions); //a.Analyze(); Debug.Log(Debug.BlueprintTransfer, "Trying to place POI map at tile {0}, at {1},{2} to {3},{4} ({5}x{6})", map.Parent.Tile, poiComp.originX, poiComp.originZ, poiComp.originX + bp.width, poiComp.originZ + bp.height, bp.width, bp.height); var generators = GeneratorsForBlueprint(bp, poiComp, map.Parent.Faction); ResolveParams resolveParams = default(ResolveParams); BaseGen.globalSettings.map = map; resolveParams.SetCustom <ScatterOptions>(Constants.ScatterOptions, currentOptions); resolveParams.faction = map.ParentFaction; resolveParams.SetCustom(Constants.ForcesGenerators, generators); resolveParams.rect = new CellRect(currentOptions.overridePosition.x, currentOptions.overridePosition.z, map.Size.x - currentOptions.overridePosition.x, map.Size.z - currentOptions.overridePosition.z); BaseGen.globalSettings.mainRect = resolveParams.rect; float uncoveredCost = currentOptions.uncoveredCost; if (resolveParams.faction != null) { //Debug.Log("Mannable count: {0}", poiComp.mannableCount); ManTurrets((int)(poiComp.mannableCount * 1.25f + 1), resolveParams, map); } //ok, but why LIFO? Queue looks more suitable for map generation. //Looks like it was done for nested symbols resolving, but looks strange anyway. BaseGen.symbolStack.Push("chargeBatteries", resolveParams); BaseGen.symbolStack.Push("ensureCanHoldRoof", resolveParams); BaseGen.symbolStack.Push("refuel", resolveParams); BaseGen.symbolStack.Push("scatterRuins", resolveParams); BaseGen.Generate(); List <AbstractDefenderForcesGenerator> f_generators = resolveParams.GetCustom <List <AbstractDefenderForcesGenerator> >(Constants.ForcesGenerators); if (f_generators != null) { foreach (AbstractDefenderForcesGenerator generator in f_generators) { generator.GenerateStartingParty(map, resolveParams); } } }
public override void Generate(Map map, GenStepParams parms) { //skip generation due to low blueprints count if (SnapshotStoreManager.Instance.StoredSnapshotsCount() < 10) { Debug.Error(Debug.Scatter, "Skipping ruins gerenation due to low blueprints count."); return; } //Skip generation for starting tile if corresponding settings flag is set if (RealRuins_ModSettings.startWithoutRuins) { int homes = 0; var allMaps = Find.Maps; for (int i = 0; i < allMaps.Count; i++) { Map someMap = allMaps[i]; if (someMap.IsPlayerHome) { homes++; } } if (homes == 1 && Find.TickManager.TicksGame < 10) { return; //single home => we're generating that single home => that's starting map => no ruins here if this option is selected. } } //Skip generation on other ruins world objects foreach (WorldObject wo in Find.World.worldObjects.ObjectsAt(map.Tile)) { if (wo is RealRuinsPOIWorldObject || wo is AbandonedBaseWorldObject) { return; } } if (!map.TileInfo.WaterCovered) { float densityMultiplier = 1.0f; float scaleMultiplier = 1.0f; float distanceToSettlement = 0.0f; float totalDensity = RealRuins_ModSettings.defaultScatterOptions.densityMultiplier; currentOptions = RealRuins_ModSettings.defaultScatterOptions.Copy(); //store as instance variable to keep accessible on subsequent ScatterAt calls if (RealRuins_ModSettings.defaultScatterOptions.enableProximity) { distanceToSettlement = CalculateDistanceToNearestSettlement(map); if (distanceToSettlement >= 16 && Rand.Chance(0.5f)) { totalDensity = 0; } if (totalDensity > 0) { densityMultiplier = (float)(Math.Exp(1.0 / (distanceToSettlement / 10.0 + 0.3)) - 0.7); scaleMultiplier = (float)(Math.Exp(1 / (distanceToSettlement / 5 + 0.5)) - 0.3); } else { densityMultiplier = 0.0f; } currentOptions.densityMultiplier *= densityMultiplier; currentOptions.minRadius = Math.Min(60, Math.Max(6, (int)(currentOptions.minRadius * scaleMultiplier))); //keep between 6 and 60 currentOptions.maxRadius = Math.Min(60, Math.Max(6, (int)(currentOptions.maxRadius * scaleMultiplier))); //keep between 6 and 60 currentOptions.scavengingMultiplier *= scaleMultiplier * densityMultiplier; currentOptions.deteriorationMultiplier += Math.Min(0.2f, (1.0f / (scaleMultiplier * densityMultiplier * 3))); if (densityMultiplier > 20.0f) { densityMultiplier = 20.0f; } while (densityMultiplier * currentOptions.maxRadius > 800) { densityMultiplier *= 0.9f; //WHAT? Why not 800/radius? } } //number of ruins based on density settings var num = (int)((float)map.Area / 10000.0f) * Rand.Range(1 * totalDensity, 2 * totalDensity); Debug.Log(Debug.Scatter, "dist {0}, dens {1} (x{2}), scale x{3} ({4}-{5}), scav {6}, deter {7}", distanceToSettlement, currentOptions.densityMultiplier, densityMultiplier, scaleMultiplier, currentOptions.minRadius, currentOptions.maxRadius, currentOptions.scavengingMultiplier, currentOptions.deteriorationMultiplier); Debug.Log(Debug.Scatter, "Spawning {0} ruin chunks", num); BaseGen.globalSettings.map = map; bool shouldUnpause = false; Find.TickManager.Pause(); if (!Find.TickManager.Paused) { Find.TickManager.TogglePaused(); shouldUnpause = true; } CoverageMap coverageMap = CoverageMap.EmptyCoverageMap(map); for (int i = 0; i < num; i++) { //We use copy of scatteroptions because each scatteroptions represents separate chunk with separate location, size, maps, etc. //should use struct instead? is it compatible with IExposable? ResolveParams rp = default(ResolveParams); rp.SetCustom(Constants.ScatterOptions, currentOptions.Copy()); rp.SetCustom(Constants.CoverageMap, coverageMap); if (Rand.Chance(currentOptions.hostileChance)) { if (Rand.Chance(0.8f)) { rp.SetCustom(Constants.ForcesGenerators, new List <AbstractDefenderForcesGenerator> { new AnimalInhabitantsForcesGenerator() }); } else { rp.SetCustom(Constants.ForcesGenerators, new List <AbstractDefenderForcesGenerator> { new MechanoidsForcesGenerator(0) }); } } rp.faction = Find.FactionManager.OfAncientsHostile; var center = CellFinder.RandomNotEdgeCell(10, map); rp.rect = new CellRect(center.x, center.z, 1, 1); //after generation will be extended to a real size BaseGen.symbolStack.Push("scatterRuins", rp); } BaseGen.Generate(); if (shouldUnpause) { //Debug.Message("Finished spawning, unpausing"); Find.TickManager.TogglePaused(); } } }
public override void Generate(Map map, GenStepParams parms) { Find.TickManager.Pause(); //Debug.Message("Overridden LARGE generate"); string filename = map.Parent.GetComponent <RuinedBaseComp>()?.blueprintFileName; Debug.Log(Debug.Scatter, "Preselected file name is {0}", filename); currentOptions = RealRuins_ModSettings.defaultScatterOptions.Copy(); //store as instance variable to keep accessible on subsequent ScatterAt calls currentOptions.minRadius = 200; currentOptions.maxRadius = 200; currentOptions.scavengingMultiplier = 0.1f; currentOptions.deteriorationMultiplier = 0.0f; currentOptions.hostileChance = 1.0f; currentOptions.blueprintFileName = filename; currentOptions.costCap = map.Parent.GetComponent <RuinedBaseComp>()?.currentCapCost ?? -1; currentOptions.startingPartyPoints = (int)(map.Parent.GetComponent <RuinedBaseComp>()?.raidersActivity ?? -1); currentOptions.minimumCostRequired = 100000; currentOptions.minimumDensityRequired = 0.015f; currentOptions.minimumAreaRequired = 6400; currentOptions.deleteLowQuality = false; //do not delete since we have much higher requirements for base ruins currentOptions.shouldKeepDefencesAndPower = true; currentOptions.shouldLoadPartOnly = false; currentOptions.shouldAddRaidTriggers = Find.Storyteller.difficulty.allowBigThreats; currentOptions.claimableBlocks = false; currentOptions.enableDeterioration = false; ResolveParams resolveParams = default(ResolveParams); BaseGen.globalSettings.map = map; resolveParams.SetCustom(Constants.ScatterOptions, currentOptions); resolveParams.faction = Find.FactionManager.OfAncientsHostile; resolveParams.SetCustom(Constants.ForcesGenerators, new List <AbstractDefenderForcesGenerator> { new BattleRoyaleForcesGenerator() }); resolveParams.rect = new CellRect(0, 0, map.Size.x, map.Size.z); BaseGen.symbolStack.Push("chargeBatteries", resolveParams); BaseGen.symbolStack.Push("refuel", resolveParams); BaseGen.symbolStack.Push("scatterRuins", resolveParams); BaseGen.globalSettings.mainRect = resolveParams.rect; float uncoveredCost = currentOptions.uncoveredCost; if (uncoveredCost < 0) { if (Rand.Chance(0.5f)) { uncoveredCost = -uncoveredCost; //adding really small party } } BaseGen.Generate(); //adding starting party //don't doing it via basegen because of uh oh i don't remember, something with pawn location control List <AbstractDefenderForcesGenerator> generators = resolveParams.GetCustom <List <AbstractDefenderForcesGenerator> >(Constants.ForcesGenerators); if (generators != null) { foreach (AbstractDefenderForcesGenerator generator in generators) { generator.GenerateStartingParty(map, resolveParams); } } }