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 GenerateStartingParty(Map map, ResolveParams rp) { ScatterOptions currentOptions = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); float uncoveredCost = currentOptions.uncoveredCost; int points = (int)(uncoveredCost / (10 * militaryPower)); int initialGroup = 0; if (points > 10000) { initialGroup = Rand.Range(5000, 10000); } else { initialGroup = points; } Debug.Log(Debug.ForceGen, "Military gen: uncoveredCost {0}, military power: {1}, total points allowed: {2}", uncoveredCost, militaryPower, points); points -= initialGroup; SpawnGroup((int)ScalePointsToDifficulty(initialGroup), rp.rect, rp.faction, map); Debug.Log(Debug.ForceGen, "Initial group of {0} spawned, {1} points left for triggers", initialGroup, points); while (points > 0) { IntVec3 mapLocation = rp.rect.RandomCell; if (!mapLocation.InBounds(map)) { continue; } ThingDef raidTriggerDef = ThingDef.Named("RaidTrigger"); RaidTrigger trigger = ThingMaker.MakeThing(raidTriggerDef) as RaidTrigger; trigger.faction = rp.faction; trigger.SetTimeouts(0, 300); int raidMaxPoints = (int)(10000 / Math.Max(Math.Sqrt(d: militaryPower), 1.0)); float raidValue = Math.Abs(Rand.Gaussian()) * raidMaxPoints + Rand.Value * raidMaxPoints + 250.0f; if (raidValue > 10000) { raidValue = Rand.Range(8000, 11000); //sanity cap. against some beta-poly bases. } points -= (int)raidValue; trigger.value = ScalePointsToDifficulty(points); GenSpawn.Spawn(trigger, mapLocation, map); Debug.Log(Debug.ForceGen, "Spawned trigger at {0}, {1} for {2} points, autofiring after {3} rare ticks", mapLocation.x, mapLocation.z, trigger.value, 0); } }
public override void Resolve(ResolveParams rp) { var perimeterWallCells = rp.rect.EdgeCells.ToList(); var map = BaseGen.globalSettings.map; var faction = rp.faction ?? Find.FactionManager.RandomEnemyFaction(); var medievalrp = rp.GetCustom <VFEResolveParams>(VFEResolveParams.Name); // Generate towers on each corner of the rect var corners = rp.rect.Corners.ToList(); float towerRadius = medievalrp?.towerRadius ?? 3.9f; var wallDef = medievalrp?.edgeWallDef ?? RimWorld.ThingDefOf.Wall; var wallStuff = rp.wallStuff ?? GenStuff.RandomStuffInexpensiveFor(wallDef, faction); for (int i = 0; i < corners.Count; i++) { var corner = corners[i]; var towerCells = GenRadial.RadialCellsAround(corner, towerRadius, true).ToList(); if (ValidAreaForTower(towerCells, map)) { perimeterWallCells = perimeterWallCells.Where(c => !towerCells.Contains(c)).ToList(); var towerInteriorCells = GenRadial.RadialCellsAround(corner, towerRadius - 1.42f, true).ToList(); var towerExteriorCells = towerCells.Where(c => !towerInteriorCells.Contains(c)).ToList(); TryGenerateTower(towerExteriorCells, towerInteriorCells, map, rp, wallDef, wallStuff); potentialTowerDoorCells = potentialTowerDoorCells.Concat(towerExteriorCells.Where(c => rp.rect.ContractedBy(1).Contains(c) && ValidDoorCell(c, map))).ToList(); } } // Generate tower entrances if (medievalrp.hasDoors != false) { for (int i = 0; i < potentialTowerDoorCells.Count; i++) { var pos = potentialTowerDoorCells[i]; TrySpawnFloor(pos, map); var doorStuff = faction.def.techLevel.IsNeolithicOrWorse() ? RimWorld.ThingDefOf.WoodLog : RimWorld.ThingDefOf.Steel; var door = ThingMaker.MakeThing(RimWorld.ThingDefOf.Door, doorStuff); door.SetFaction(faction); GenSpawn.Spawn(door, pos, map); } } potentialTowerDoorCells.Clear(); // Generate perimeter walls for (int i = 0; i < perimeterWallCells.Count; i++) { var pos = perimeterWallCells[i]; TrySpawnWall(pos, map, rp, wallDef, wallStuff); } }
public BlueprintTransferUtility(Blueprint blueprint, Map map, ResolveParams rp) { this.blueprint = blueprint; this.map = map; this.rp = rp; mapOriginX = rp.rect.minX + rp.rect.Width / 2 - blueprint.width / 2; mapOriginZ = rp.rect.minZ + rp.rect.Height / 2 - blueprint.height / 2; if (mapOriginX < 0) { mapOriginX = 0; } if (mapOriginZ < 0) { mapOriginZ = 0; } if (mapOriginX + blueprint.width >= map.Size.x) { mapOriginX = map.Size.x - blueprint.width - 1; } if (mapOriginZ + blueprint.height >= map.Size.z) { mapOriginZ = map.Size.z - blueprint.height - 1; } options = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); if (options.overridePosition != IntVec3.Zero) { if (!options.centerIfExceedsBounds || (options.overridePosition.x + blueprint.width < map.Size.x && options.overridePosition.z + blueprint.height < map.Size.z)) { mapOriginX = options.overridePosition.x; mapOriginZ = options.overridePosition.z; } else { Debug.Warning(Debug.BlueprintTransfer, "Tried to override position, but map exceeded bounds and position was reverted due to corresponding options flag."); Debug.Warning(Debug.BlueprintTransfer, "New position: {0}, {1}", mapOriginX, mapOriginZ); } } }
public override void Resolve(ResolveParams rp) { var map = BaseGen.globalSettings.map; var faction = rp.faction ?? Find.FactionManager.RandomEnemyFaction(); var medievalrp = rp.GetCustom <VFEResolveParams>(VFEResolveParams.Name); float towerRadius = medievalrp?.towerRadius ?? 0; bool symmetrical = medievalrp?.symmetricalSandbags ?? Rand.Bool; // North GenerateSandbags(Rot4.North, rp, map, faction, towerRadius, symmetrical); // East GenerateSandbags(Rot4.East, rp, map, faction, towerRadius, symmetrical); // South GenerateSandbags(Rot4.South, rp, map, faction, towerRadius, symmetrical); // West GenerateSandbags(Rot4.West, rp, map, faction, towerRadius, symmetrical); }
public override void GenerateStartingParty(Map map, ResolveParams rp) { ScatterOptions currentOptions = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); float uncoveredCost = currentOptions.uncoveredCost; Faction faction = rp.faction; if (this.faction != null) { faction = this.faction; } if (faction == null) { faction = Find.FactionManager.RandomEnemyFaction(true, true, false); } Debug.Log(Debug.ForceGen, "Citizen force gen: uncoveredCost {0}. rect {1}", uncoveredCost, rp.rect); int maxPoints = Math.Min((int)(uncoveredCost / 10), 5000); SpawnGroup((int)ScalePointsToDifficulty(maxPoints), rp.rect, faction, map, Rand.Range(Math.Max(2, (int)(bedCount * 0.7)), (int)(bedCount * 1.5))); currentOptions.uncoveredCost -= maxPoints * 10; }
public override void GenerateStartingParty(Map map, ResolveParams rp) { ScatterOptions currentOptions = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); float uncoveredCost = currentOptions.uncoveredCost; if (uncoveredCost > 0 || currentOptions.startingPartyPoints > 0) { float pointsCost = 0; if (currentOptions.startingPartyPoints > 0) { pointsCost = currentOptions.startingPartyPoints; } else { pointsCost = uncoveredCost / 10.0f; FloatRange defaultPoints = new FloatRange(pointsCost * 0.7f, Math.Min(12000.0f, pointsCost * 2.0f)); Debug.Log(Debug.ForceGen, "Adding starting party. Remaining points: {0}. Used points range: {1}", currentOptions.uncoveredCost, defaultPoints); } pointsCost = ScalePointsToDifficulty(pointsCost); ScatterStartingParties((int)pointsCost, currentOptions.allowFriendlyRaids, map); } }
public override void GenerateForces(Map map, ResolveParams rp) { Debug.Log(Debug.ForceGen, "Generating mechanoid forces"); ScatterOptions options = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); CellRect rect = rp.rect; /*if (rect.minX < 15 || rect.minZ < 15 || rect.maxX > map.Size.x - 15 || rect.maxZ > map.Size.z - 15) { * return; //do not add enemies if we're on the map edge * } * * if (!CellFinder.TryFindRandomCellInsideWith(rect, (IntVec3 x) => x.Standable(map) && options.roomMap[x.x - rect.BottomLeft.x, x.z - rect.BottomLeft.z] > 1, out IntVec3 testCell)) { * return; //interrupt if there are no closed cells available * }*/ PawnKindDef pawnKindDef = null; if (powerMax == 0) { powerMax = rect.Area / 30.0f; } powerMax = ScalePointsToDifficulty(powerMax); float powerThreshold = (Math.Abs(Rand.Gaussian(0.5f, 1)) * powerMax) + 1; float cumulativePower = 0; Faction faction = Faction.OfAncientsHostile; Lord lord = LordMaker.MakeNewLord(lordJob: new LordJob_DefendPoint(rect.CenterCell), faction: faction, map: map, startingPawns: null); int tile = map.Tile; while (cumulativePower <= powerThreshold) { PawnKindDef currentPawnKindDef = (from kind in DefDatabase <PawnKindDef> .AllDefsListForReading where kind.RaceProps.IsMechanoid select kind).RandomElementByWeight((PawnKindDef kind) => 1f / kind.combatPower); PawnGenerationRequest request = new PawnGenerationRequest(currentPawnKindDef, faction, PawnGenerationContext.NonPlayer, tile, true, false, false, //allowDead is last false, true, false, 1f, false, true, true, false, false, false, false, null, null, null, null, null, null, null, null); IntVec3 cell = IntVec3.Invalid; // if (!CellFinder.TryFindRandomCellInsideWith(rect, (IntVec3 x) => x.Standable(map) && options.roomMap[x.x - rect.minX, x.z - rect.minZ] > 1, out cell)) { CellFinder.TryFindRandomSpawnCellForPawnNear(rect.CenterCell, map, out cell); // } if (cell != IntVec3.Invalid) { Pawn pawn = PawnGenerator.GeneratePawn(request); FilthMaker.MakeFilth(cell, map, ThingDefOf.Filth_Blood, 5); GenSpawn.Spawn(pawn, cell, map, WipeMode.Vanish); lord.AddPawn(pawn); cumulativePower += pawn.kindDef.combatPower; } else { break; //no more suitable cells } } }
public override void GenerateForces(Map map, ResolveParams rp) { ScatterOptions options = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); if (options == null) { return; } int addedTriggers = 0; float ratio = 10; float remainingCost = options.uncoveredCost * (Rand.Value + 0.5f); //cost estimation as seen by other factions float initialCost = remainingCost; int triggersAbsoluteMaximum = 100; while (remainingCost > 0) { IntVec3 mapLocation = rp.rect.RandomCell; if (!mapLocation.InBounds(map)) { continue; } ThingDef raidTriggerDef = ThingDef.Named("RaidTrigger"); RaidTrigger trigger = ThingMaker.MakeThing(raidTriggerDef) as RaidTrigger; if (options.allowFriendlyRaids) { if (Rand.Chance(0.2f)) { trigger.faction = Find.FactionManager.RandomNonHostileFaction(); } else { trigger.faction = Find.FactionManager.RandomEnemyFaction(); } } else { trigger.faction = Find.FactionManager.RandomEnemyFaction(); } int raidMaxPoints = (int)(remainingCost / ratio); float raidValue = Math.Abs(Rand.Gaussian()) * raidMaxPoints + Rand.Value * raidMaxPoints + 250.0f; if (raidValue > 10000) { raidValue = Rand.Range(8000, 11000); //sanity cap. against some beta-poly bases. } remainingCost -= raidValue * ratio; trigger.value = ScalePointsToDifficulty(raidValue); GenSpawn.Spawn(trigger, mapLocation, map); Debug.Log(Debug.ForceGen, "Spawned trigger at {0}, {1} for {2} points, autofiring after {3} rare ticks", mapLocation.x, mapLocation.z, trigger.value, 0); addedTriggers++; options.uncoveredCost = Math.Abs(remainingCost); if (addedTriggers > triggersAbsoluteMaximum) { if (remainingCost < initialCost * 0.2f) { if (Rand.Chance(0.1f)) { if (remainingCost > 100000) { remainingCost = Rand.Range(80000, 110000); } return; } } } } }
public override void GenerateForces(Map map, ResolveParams rp) { Debug.Log(Debug.ForceGen, "Animal forces generation"); ScatterOptions options = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); CellRect rect = rp.rect; /*if (rect.minX < 15 || rect.minZ < 15 || rect.maxX > map.Size.x - 15 || rect.maxZ > map.Size.z - 15) { * return; //do not add enemies if we're on the map edge * } * * if (!CellFinder.TryFindRandomCellInsideWith(rect, (IntVec3 x) => x.Standable(map) && options.roomMap[x.x - rect.BottomLeft.x, x.z - rect.BottomLeft.z] > 1, out IntVec3 testCell)) { * return; //interrupt if there are no closed cells available * }*/ PawnKindDef pawnKindDef = null; pawnKindDef = map.Biome.AllWildAnimals.RandomElementByWeight((PawnKindDef def) => (def.RaceProps.foodType == FoodTypeFlags.CarnivoreAnimal || def.RaceProps.foodType == FoodTypeFlags.OmnivoreAnimal) ? 1 : 0); float powerMax = (float)Math.Sqrt(options.uncoveredCost / 10 * (rect.Area / 30.0f)); Debug.Log(Debug.ForceGen, "Unscaled power is {0} based on cost of {1} and area of {2}", powerMax, options.uncoveredCost, rect.Area); powerMax = ScalePointsToDifficulty(powerMax); float powerThreshold = (Math.Abs(Rand.Gaussian(0.5f, 1)) * powerMax) + 1; float cumulativePower = 0; Faction faction = Faction.OfAncientsHostile; Lord lord = LordMaker.MakeNewLord(lordJob: new LordJob_DefendPoint(rect.CenterCell), faction: faction, map: map, startingPawns: null); int tile = map.Tile; while (cumulativePower <= powerThreshold) { PawnKindDef currentPawnKindDef = pawnKindDef; PawnGenerationRequest request = new PawnGenerationRequest(currentPawnKindDef, faction, PawnGenerationContext.NonPlayer, tile, true, false, false, //allowDead is last false, true, false, 1f, false, true, true, false, false, false, false, null, null, null, null, null, null, null, null); IntVec3 cell = IntVec3.Invalid; if (!CellFinder.TryFindRandomCellInsideWith(rect, (IntVec3 x) => x.Standable(map) && options.roomMap[x.x - rect.minX, x.z - rect.minZ] > 1, out cell)) { CellFinder.TryFindRandomSpawnCellForPawnNear(rect.CenterCell, map, out cell); } if (cell != IntVec3.Invalid) { Pawn pawn = PawnGenerator.GeneratePawn(request); FilthMaker.MakeFilth(cell, map, ThingDefOf.Filth_Blood, 5); GenSpawn.Spawn(pawn, cell, map, WipeMode.Vanish); lord.AddPawn(pawn); cumulativePower += pawn.kindDef.combatPower; } else { break; //no more suitable cells } } }
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) { ScatterOptions options = rp.GetCustom <ScatterOptions>(Constants.ScatterOptions); if (options == null) { return; } //Debug.Message("Loading blueprint of size {0} - {1} to deploy at {2}, {3}", options.minRadius, options.maxRadius, rp.rect.minX, rp.rect.minZ); Blueprint bp = null; Map map = BaseGen.globalSettings.map; //probably should split scattering options into several distinct objects string filename = options.blueprintFileName; if (string.IsNullOrEmpty(filename)) { bp = BlueprintFinder.FindRandomBlueprintWithParameters(out filename, options.minimumAreaRequired, options.minimumDensityRequired, 15, removeNonQualified: true); if (string.IsNullOrEmpty(filename)) { //still null = no suitable blueprints, fail. return; } } if (!options.shouldLoadPartOnly) //should not cut => load whole { if (bp == null) //if not loaded yet { bp = BlueprintLoader.LoadWholeBlueprintAtPath(filename); } } else { int radius = Rand.Range(options.minRadius, options.maxRadius); if (bp == null) { bp = BlueprintLoader.LoadWholeBlueprintAtPath(filename).RandomPartCenteredAtRoom(new IntVec3(radius, 0, radius)); } else { bp = bp.RandomPartCenteredAtRoom(new IntVec3(radius, 0, radius)); } } if (bp == null) { Debug.Warning(Debug.Scatter, "Blueprint is still null after attempting to load any qualifying, returning"); return; } bp.CutIfExceedsBounds(map.Size); // Here we have our blueprint loaded and ready to action. Doing stuff: BlueprintPreprocessor.ProcessBlueprint(bp, options); //Preprocess: remove missing and unnecessary items according to options bp.FindRooms(); //Traverse blueprint and construct rooms map options.roomMap = bp.wallMap; //Debug.PrintIntMap(bp.wallMap, delta: 1); BlueprintTransferUtility btu = new BlueprintTransferUtility(bp, map, rp); //prepare blueprint transferrer btu.RemoveIncompatibleItems(); //remove incompatible items bp.UpdateBlueprintStats(true); //Update total cost, items count, etc DeteriorationProcessor.Process(bp, options); //create deterioration maps and do deterioration ScavengingProcessor sp = new ScavengingProcessor(); sp.RaidAndScavenge(bp, options); //scavenge remaining items according to scavenge options btu.Transfer(); //transfer blueprint List <AbstractDefenderForcesGenerator> generators = rp.GetCustom <List <AbstractDefenderForcesGenerator> >(Constants.ForcesGenerators); if (generators != null) { foreach (AbstractDefenderForcesGenerator generator in generators) { generator.GenerateForces(map, rp); } } if (options.shouldAddFilth) { btu.AddFilthAndRubble(); //add filth and rubble //rp.GetCustom<CoverageMap>(Constants.CoverageMap).DebugPrint(); } }
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) { 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); } } }