protected override bool TryExecuteWorker(IncidentParms parms) { Faction faction = parms.faction; if (faction == null) { faction = Find.FactionManager.RandomNonHostileFaction(false, false, false, TechLevel.Undefined); } if (faction == null) { return(false); } if (!TryFindTile(out int tile)) { return(false); } AbandonedBaseWorldObject site = (AbandonedBaseWorldObject)WorldObjectMaker.MakeWorldObject(DefDatabase <WorldObjectDef> .GetNamed("AbandonedBase")); site.Tile = tile; site.SetFaction(null); Find.WorldObjects.Add(site); string filename = null; Blueprint bp = BlueprintFinder.FindRandomBlueprintWithParameters(out filename, 6400, 0.01f, 30000, maxAttemptsCount: 50); RuinedBaseComp comp = site.GetComponent <RuinedBaseComp>(); if (comp == null) { Debug.Warning("Component is null"); } else { Debug.Warning("Starting scavenging..."); int cost = 10000; if (bp != null) { cost = (int)bp.totalCost; } comp.blueprintFileName = filename; comp.StartScavenging(cost); } var lifetime = (int)(Math.Pow(site.GetComponent <RuinedBaseComp>().currentCapCost / 1000, 0.41) * 1.1); string letterText = GetLetterText(faction, lifetime); Find.LetterStack.ReceiveLetter(def.letterLabel, letterText, def.letterDef, site, faction, null); return(true); }
//ResolveParams's GetCustom/SetCustom is broken now, and it is a sealed (WHY??!) struct (WHY??!?!?) so I neither can fix it, nor make a dirty hack. //Seems like I have to abandon this approach and make direct calls. static public void Scatter(ResolveParams rp, ScatterOptions options, CoverageMap coverage, List <AbstractDefenderForcesGenerator> generators) { Debug.Log(Debug.Scatter, "Running stand-alone scatterer"); if (options == null) { Debug.Warning(Debug.Scatter, "Scatter options are null, aborting"); return; } DateTime start = DateTime.UtcNow; Debug.Log(Debug.Scatter, "[0 s]: 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) || !BlueprintLoader.CanLoadBlueprintAtPath(filename)) { bp = BlueprintFinder.FindRandomBlueprintWithParameters(out filename, options.minimumAreaRequired, options.minimumDensityRequired, 15, removeNonQualified: options.deleteLowQuality); if (string.IsNullOrEmpty(filename)) { //still null = no suitable blueprints, fail. Debug.Warning(Debug.Scatter, "Blueprint name was null and could not find another suitable blueprint, skipping"); 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; } Debug.Extra(Debug.Scatter, "Blueprint loaded, cutting and searching for rooms"); 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); Debug.Extra(Debug.Scatter, "Rooms traversed, initializing transfer utility"); BlueprintTransferUtility btu = new BlueprintTransferUtility(bp, map, rp, options); //prepare blueprint transferrer Debug.Extra(Debug.Scatter, "Initialized, removing incompatible items..."); btu?.RemoveIncompatibleItems(); //remove incompatible items Debug.Extra(Debug.Scatter, "Recalculating stats..."); bp.UpdateBlueprintStats(true); //Update total cost, items count, etc Debug.Extra(Debug.Scatter, "Deteriorating..."); DeteriorationProcessor.Process(bp, options); //create deterioration maps and do deterioration Debug.Extra(Debug.Scatter, "Scavenging..."); ScavengingProcessor sp = new ScavengingProcessor(); sp.RaidAndScavenge(bp, options); //scavenge remaining items according to scavenge options Debug.Extra(Debug.Scatter, "[{0} s] Prepared, about to start transferring.", DateTime.UtcNow.Subtract(start).TotalSeconds); try { btu.Transfer(coverage); //transfer blueprint Debug.Extra(Debug.Scatter, "[{0} s] Transferred.", DateTime.UtcNow.Subtract(start).TotalSeconds); } catch (Exception e) { Debug.Error(Debug.BlueprintTransfer, "Failed to transfer blueprint due to {0}", e); } if (generators != null) { foreach (AbstractDefenderForcesGenerator generator in generators) { try { generator.GenerateForces(map, rp, options); } catch (Exception e) { Debug.Error(Debug.BlueprintTransfer, "Failed to generate forces: {0}", e); } } } Debug.Log(Debug.Scatter, "[{0} s] Generated forces.", DateTime.UtcNow.Subtract(start).TotalSeconds); if (options.shouldAddFilth) { try { btu.AddFilthAndRubble(); //add filth and rubble } catch (Exception e) { Debug.Warning(Debug.BlueprintTransfer, "Failed to add filth and rubble: {0}", e); } } Debug.Extra(Debug.Scatter, "[{0} s] Spiced up with rubble. Completed.", DateTime.UtcNow.Subtract(start).TotalSeconds); Debug.Log(Debug.Scatter, "Chunk scattering finished, moving"); }
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(); } }