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();
        }
예제 #2
0
        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);
                }
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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;
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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
                }
            }
        }
예제 #9
0
        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;
                        }
                    }
                }
            }
        }
예제 #10
0
        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
                }
            }
        }
예제 #11
0
        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);
        }
예제 #12
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();
            }
        }
예제 #13
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.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);
                }
            }
        }
예제 #14
0
        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);
                }
            }
        }