public static Blueprint LoadWholeBlueprintAtPath(string path)
        {
            BlueprintLoader loader = new BlueprintLoader(path);

            try {
                loader.LoadBlueprint();
                return(loader.blueprint);
            } catch (Exception) {
                return(null);
            }
        }
        public static Blueprint LoadRandomBlueprintPartAtPath(string path, IntVec3 size)
        {
            BlueprintLoader loader = new BlueprintLoader(path);

            try {
                loader.LoadBlueprint();
                loader.CutRandomRectOfSize(size);
                return(loader.blueprint);
            } catch (Exception) {
                return(null);
            }
        }
        public static Blueprint FindRandomBlueprintWithParameters(out string filename, int minArea = 100, float minDensity = 0.01f, int minCost = 0, int maxAttemptsCount = 5, bool removeNonQualified = false)
        {
            Blueprint bp = null;

            filename = null;
            int attemptCount = 0;

            while (attemptCount < maxAttemptsCount)
            {
                attemptCount++;
                filename = SnapshotStoreManager.Instance.RandomSnapshotFilename();
                bp       = BlueprintLoader.LoadWholeBlueprintAtPath(filename);


                if (bp == null)
                {
                    Debug.Error(Debug.Store, "Corrupted XML at path {0}, removing", filename);
                    SnapshotStoreManager.Instance.RemoveBlueprintWithName(filename);
                    continue;
                }

                bp.UpdateBlueprintStats(includeCost: true);

                //Debug.Message("size: {0}x{1} (needed {2}). density {3} (needed {4}). cost {5} (needed {6})", bp.width, bp.height, minArea, bp.itemsDensity, minDensity, bp.totalCost, minCost);

                if (bp.height * bp.width > minArea && bp.itemsDensity > minDensity && bp.totalCost >= minCost)
                {
                    //Debug.Message("Qualified, using.");
                    return(bp);
                }
                else if (removeNonQualified)
                {
                    Debug.Warning(Debug.Store, "Non-qualified XML at path {0}, removing", filename);
                    SnapshotStoreManager.Instance.RemoveBlueprintWithName(filename);
                }
            }
            filename = null;
            return(null);
        }
        //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");
        }
Exemple #5
0
        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.faction      = map.ParentFaction;
            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);
            }


            RuinsScatterer.Scatter(resolveParams, currentOptions, null, generators);

            //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.Generate();

            if (generators != null)
            {
                foreach (AbstractDefenderForcesGenerator generator in generators)
                {
                    generator.GenerateStartingParty(map, resolveParams, currentOptions);
                }
            }
        }
Exemple #6
0
        public static bool CreatePOI(PlanetTileInfo tileInfo, string gameName, bool biomeStrict, bool costStrict, bool itemsStrict)
        {
            if (tileInfo.tile >= Find.WorldGrid.TilesCount)
            {
                return(false);
            }

            if (!TileFinder.IsValidTileForNewSettlement(tileInfo.tile))
            {
                return(false);
            }

            if (biomeStrict && tileInfo.biomeName != Find.WorldGrid.tiles[tileInfo.tile].biome.defName)
            {
                Debug.Warning(Debug.POI, "Skipped blueprint due to wrong biome");
                return(false);
            }

            string    filename = SnapshotStoreManager.Instance.SnapshotNameFor(tileInfo.mapId, gameName);
            Blueprint bp       = BlueprintLoader.LoadWholeBlueprintAtPath(filename);

            if (bp == null)
            {
                return(false);
            }

            if (tileInfo.originX + bp.width > Find.World.info.initialMapSize.x || tileInfo.originZ + bp.height > Find.World.info.initialMapSize.z)
            {
                Debug.Warning(Debug.POI, "Skipped because of exceeding size ({{0} + {1} > {2} && {3} + {4} > {5})", tileInfo.originX, bp.width, Find.World.info.initialMapSize.x, tileInfo.originZ, bp.height, Find.World.info.initialMapSize.z);
                return(false);
            }

            BlueprintAnalyzer ba = new BlueprintAnalyzer(bp);

            ba.Analyze();
            if (costStrict && (ba.result.totalItemsCost < 1000))
            {
                Debug.Warning(Debug.POI, "Skipped blueprint due to low total cost or tiles count");
                return(false);
            }

            if (ba.result.occupiedTilesCount < 50 || ba.result.totalArea < 200)
            {
                Debug.Warning(Debug.POI, "Skipped blueprint due to low area ({0}) and/or items count {1}", ba.result.totalArea, ba.result.occupiedTilesCount);
                return(false);
            }

            var poiType = ba.determinedType;

            Faction faction = null;

            if (Rand.Chance(ba.chanceOfHavingFaction()))
            {
                Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction(out faction, false, false, minTechLevel: MinTechLevelForPOIType(poiType));
            }

            RealRuinsPOIWorldObject site = TryCreateWorldObject(tileInfo.tile, faction);

            if (site == null)
            {
                return(false);
            }

            RealRuinsPOIComp comp = site.GetComponent <RealRuinsPOIComp>();

            if (comp == null)
            {
                Debug.Error(Debug.BlueprintTransfer, "POI Component is null!");
            }
            else
            {
                comp.blueprintName           = tileInfo.mapId;
                comp.gameName                = gameName;
                comp.originX                 = tileInfo.originX;
                comp.originZ                 = tileInfo.originZ;
                comp.poiType                 = (int)poiType;
                comp.militaryPower           = ba.militaryPower;
                comp.mannableCount           = ba.mannableCount;
                comp.approximateSnapshotCost = ba.result.totalItemsCost;
                comp.bedsCount               = ba.result.bedsCount;
            }

            return(true);
        }
Exemple #7
0
        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();
            }
        }