protected override void ScatterAt(IntVec3 c, Map map, GenStepParams parms, int stackCount = 1)
        {
            int      randomInRange  = SettlementSizeRange.RandomInRange;
            int      randomInRange2 = SettlementSizeRange.RandomInRange;
            CellRect rect           = new CellRect(c.x - randomInRange / 2, c.z - randomInRange2 / 2, randomInRange, randomInRange2);

            rect.ClipInsideMap(map);
            var           faction       = ExtendedFactionUtility.RandomFactionOfTechLevel(TechLevel.Medieval, allowDefeated: true);
            ResolveParams resolveParams = default;

            resolveParams.faction = faction;
            resolveParams.rect    = rect;
            resolveParams.noRoof  = true;
            resolveParams.chanceToSkipWallBlock = 0.22f;
            resolveParams.SetCustom(VFEResolveParams.Name, new VFEResolveParams());
            var vfeParams = resolveParams.GetCustom <VFEResolveParams>(VFEResolveParams.Name);

            Log.Message(vfeParams.ToStringSafe());
            vfeParams.hasDoors                  = false;
            vfeParams.outdoorLighting           = false;
            vfeParams.generatePawns             = false;
            BaseGen.globalSettings.map          = map;
            BaseGen.globalSettings.minBuildings = 1;
            BaseGen.globalSettings.minBarracks  = 1;
            BaseGen.symbolStack.Push("VFEM_medievalSettlement", resolveParams);
            BaseGen.Generate();
        }
        public override void Resolve(ResolveParams rp)
        {
            if (rp.wallStuff == null)
            {
                rp.wallStuff = ThingDefOf.Steel;
            }
            if (rp.floorDef == null)
            {
                rp.floorDef = BaseGenUtility.CorrespondingTerrainDef(rp.wallStuff, true);
            }
            ResolveParams resolveParams  = rp;
            ResolveParams resolveParams2 = rp;
            ResolveParams resolveParams3 = rp;
            ResolveParams resolveParams4 = rp;

            resolveParams.rect = new CellRect(rp.rect.minX, rp.rect.minZ, 1 + 2 * Rand.RangeInclusive(2, 4), 1 + 2 * Rand.RangeInclusive(3, 7));
            int num  = 1 + 2 * Rand.RangeInclusive(4, 12);
            int num2 = 1 + 2 * Rand.RangeInclusive(4, 10);

            resolveParams2.rect = new CellRect(resolveParams.rect.maxX, resolveParams.rect.minZ - (int)Math.Round((double)((float)(num2 - resolveParams.rect.Height) / 2f)), num, num2);
            num  = 1 + 2 * Rand.RangeInclusive(4, 8);
            num2 = num;
            resolveParams3.rect = new CellRect(resolveParams2.rect.maxX, resolveParams2.rect.minZ - (int)Math.Round((double)((float)(num2 - resolveParams2.rect.Height) / 2f)), num, num2);
            if (resolveParams3.rect.Height >= resolveParams2.rect.Height && resolveParams3.rect.Height >= resolveParams.rect.Height)
            {
                resolveParams4.rect = new CellRect(0, resolveParams3.rect.minZ, resolveParams3.rect.minX, resolveParams3.rect.Height);
            }
            else if (resolveParams2.rect.Height >= resolveParams.rect.Height)
            {
                resolveParams4.rect = new CellRect(0, resolveParams2.rect.minZ, resolveParams2.rect.minX, resolveParams2.rect.Height);
            }
            else
            {
                resolveParams4.rect = new CellRect(0, resolveParams.rect.minZ, resolveParams.rect.minX, resolveParams.rect.Height);
            }
            ResolveParams resolveParams5 = resolveParams;

            resolveParams5.rect           = new CellRect(resolveParams.rect.minX - 2, resolveParams.rect.minZ + 1, 1, 1);
            resolveParams5.thingRot       = new Rot4?(new Rot4(1));
            resolveParams5.singleThingDef = ThingDefOf.Ship_Engine;
            BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null);
            resolveParams5.rect.minZ = resolveParams5.rect.minZ + 2;
            BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null);
            resolveParams5.rect.minZ = resolveParams.rect.maxZ;
            BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null);
            resolveParams5.rect.minZ = resolveParams5.rect.minZ - 2;
            BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null);
            BaseGen.symbolStack.Push("batteryRoom", resolveParams, null);
            resolveParams2.SetCustom <char[]>("hasDoor", new char[]
            {
                'N',
                'S',
                'E',
                'W'
            }, false);
            BaseGen.symbolStack.Push("interior_diningRoom", resolveParams2, null);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams2, null);
            BaseGen.symbolStack.Push("triangularRoom", resolveParams3, null);
            BaseGen.symbolStack.Push("pathOfDestruction", resolveParams4, null);
        }
예제 #3
0
        public override void Generate(Map map, GenStepParams parms)
        {
            Debug.Log(Debug.Scatter, "Medium generate");
            Find.TickManager.Pause();

            currentOptions = RealRuins_ModSettings.defaultScatterOptions.Copy();     //store as instance variable to keep accessible on subsequent ScatterAt calls

            currentOptions.minRadius               = 24;
            currentOptions.maxRadius               = 50;
            currentOptions.scavengingMultiplier    = 0.1f;
            currentOptions.deteriorationMultiplier = 0.1f;
            currentOptions.hostileChance           = 0.8f;
            currentOptions.itemCostLimit           = 800;

            currentOptions.minimumCostRequired        = 25000;
            currentOptions.minimumDensityRequired     = 0.01f;
            currentOptions.minimumAreaRequired        = 4000;
            currentOptions.deleteLowQuality           = false; //do not delete since we have much higher requirements for base ruins
            currentOptions.shouldKeepDefencesAndPower = true;

            ResolveParams rp = default(ResolveParams);

            BaseGen.globalSettings.map = map;
            rp.rect = new CellRect(0, 0, map.Size.x, map.Size.z);
            rp.SetCustom <ScatterOptions>(Constants.ScatterOptions, currentOptions);
            rp.faction = Find.FactionManager.OfAncientsHostile;
            BaseGen.symbolStack.Push("chargeBatteries", rp);
            BaseGen.symbolStack.Push("refuel", rp);
            BaseGen.symbolStack.Push("scatterRuins", rp);


            if (Rand.Chance(0.5f * Find.Storyteller.difficulty.threatScale))
            {
                float pointsCost = Math.Abs(Rand.Gaussian()) * 500 * Find.Storyteller.difficulty.threatScale;

                rp.faction        = Find.FactionManager.RandomEnemyFaction();
                rp.singlePawnLord = LordMaker.MakeNewLord(rp.faction,
                                                          new LordJob_AssaultColony(rp.faction, false, false, true, true), map, null);

                rp.pawnGroupKindDef = (rp.pawnGroupKindDef ?? PawnGroupKindDefOf.Settlement);

                if (rp.pawnGroupMakerParams == null)
                {
                    rp.pawnGroupMakerParams         = new PawnGroupMakerParms();
                    rp.pawnGroupMakerParams.tile    = map.Tile;
                    rp.pawnGroupMakerParams.faction = rp.faction;
                    PawnGroupMakerParms pawnGroupMakerParams = rp.pawnGroupMakerParams;
                    pawnGroupMakerParams.points = pointsCost;
                }

                BaseGen.symbolStack.Push("pawnGroup", rp);
            }


            BaseGen.Generate();
        }
        public override void Resolve(ResolveParams rp)
        {
            ResolveParams resolveParams = rp;

            resolveParams.rect      = rp.rect.ContractedBy(1);
            resolveParams.wallStuff = ThingDefOf.BlocksGranite;
            resolveParams.SetCustom <int>("minRoomDimension", 6, false);
            BaseGen.symbolStack.Push("nestedRoomMaze", resolveParams, null);
            BaseGen.symbolStack.Push("edgeWalls", resolveParams, null);
            rp.wallStuff = ThingDefOf.Steel;
            BaseGen.symbolStack.Push("edgeWalls", rp, null);
            BaseGen.symbolStack.Push("floor", rp, null);
            BaseGen.symbolStack.Push("clear", rp, null);
        }
예제 #5
0
 private void MakeRoom(ResolveParams rp)
 {
     char[] array  = new char[3];
     char[] source = new char[]
     {
         'N',
         'S',
         'E',
         'W'
     };
     array[0] = source.RandomElement <char>();
     array[1] = source.RandomElement <char>();
     if (array[1] == array[0])
     {
         array[1] = 'X';
     }
     rp.SetCustom <char[]>("hasDoor", array, false);
     BaseGen.symbolStack.Push("roomWithDoor", rp, null);
 }
        public override void Resolve(ResolveParams rp)
        {
            ResolveParams resolveParams = rp;

            resolveParams.rect      = rp.rect.ContractedBy(1);
            resolveParams.wallStuff = ThingDefOf.BlocksGranite;
            rp.wallStuff            = ThingDefOf.Steel;
            resolveParams.SetCustom <int>("minRoomDimension", 6, false);
            BaseGen.globalSettings.minBuildings = 3;
            BaseGen.globalSettings.minBarracks  = 1;
            BaseGen.symbolStack.Push("factionBase", resolveParams);



            //BaseGen.symbolStack.Push("edgeStreet", resolveParams);
            //BaseGen.symbolStack.Push("edgeDefense", resolveParams);
            BaseGen.symbolStack.Push("ancientCryptosleepCasket", rp);
            BaseGen.symbolStack.Push("ancientCryptosleepCasket", rp);
            BaseGen.symbolStack.Push("ancientCryptosleepCasket", rp);


            CellRect field = rp.rect;

            field.minX   = Rand.RangeInclusive(rp.rect.minX, rp.rect.maxX - 15);
            field.minZ   = Rand.RangeInclusive(rp.rect.minZ + 15, rp.rect.maxZ - 15);
            field.Width  = 5;
            field.Height = 4;
            //BaseGen.symbolStack.Push("cultivatedPlants", field);
            BaseGen.symbolStack.Push("wireOutline", rp);
            //field.minX = Rand.RangeInclusive(rp.rect.minX, rp.rect.maxX);
            //field.minZ = Rand.RangeInclusive(rp.rect.minZ, rp.rect.maxZ);
            //field.Width = 4;
            //field.Height = 4;
            //BaseGen.symbolStack.Push("batteryRoom", field);
            //field.Width = 2;
            //field.Height = 2;
            //BaseGen.symbolStack.Push("wireOutline", field);
            BaseGen.symbolStack.Push("chargeBatteries", resolveParams);

            BaseGen.symbolStack.Push("clear", rp);
        }
        public override void Resolve(ResolveParams rp)
        {
            ThingDef thingDef = (from d in DefDatabase <ThingDef> .AllDefs
                                 where d.IsStuff && d.stuffProps.CanMake(ThingDefOf.Wall) && d.stuffProps.categories.Contains(StuffCategoryDefOf.Stony) && d != ThingDef.Named("Jade")
                                 select d).ToList <ThingDef>().RandomElementByWeight((ThingDef x) => 3f + 1f / x.BaseMarketValue);

            rp.wallStuff = thingDef;
            rp.floorDef  = BaseGenUtility.CorrespondingTerrainDef(thingDef, true);
            int num = Rand.RangeInclusive(30, 40);

            for (int i = 0; i < num; i++)
            {
                int           minX          = Rand.RangeInclusive(rp.rect.minX, rp.rect.maxX - 1);
                int           minZ          = Rand.RangeInclusive(rp.rect.minZ, rp.rect.maxZ - 1);
                ResolveParams resolveParams = rp;
                resolveParams.rect = new CellRect(minX, minZ, Rand.RangeInclusive(1, 3), Rand.RangeInclusive(1, 3));
                BaseGen.symbolStack.Push("pathOfDestruction", resolveParams, null);
            }
            for (int j = 0; j < Rand.RangeInclusive(2, 5); j++)
            {
                int           minX2          = Rand.RangeInclusive(rp.rect.minX + 4, rp.rect.maxX - 10);
                int           minZ2          = Rand.RangeInclusive(rp.rect.minZ + 4, rp.rect.maxZ - 10);
                ResolveParams resolveParams2 = rp;
                resolveParams2.rect = new CellRect(minX2, minZ2, Rand.RangeInclusive(5, 8), Rand.RangeInclusive(5, 8));
                BaseGen.symbolStack.Push("emptyRoom", resolveParams2, null);
            }
            ResolveParams resolveParams3 = rp;

            resolveParams3.rect = resolveParams3.rect.ContractedBy(21);
            ResolveParams resolveParams4 = resolveParams3;

            resolveParams4.rect.Width  = (int)(0.25 * (double)resolveParams3.rect.Width);
            resolveParams4.rect.Height = resolveParams4.rect.Width;
            for (int k = 0; k < 4; k++)
            {
                BaseGen.symbolStack.Push("roomWithDoor", resolveParams4, null);
                resolveParams4.rect = new CellRect(resolveParams4.rect.minX, resolveParams4.rect.maxZ, resolveParams4.rect.Width, resolveParams4.rect.Height);
            }
            resolveParams3.SetCustom <char[]>("hasDoor", new char[]
            {
                'N'
            }, false);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams3, null);
            ResolveParams resolveParams5 = rp;

            resolveParams5.rect = rp.rect.ContractedBy(5);
            ResolveParams resolveParams6 = resolveParams5;

            for (int l = 0; l < 25; l++)
            {
                int width  = Rand.RangeInclusive(4, 6);
                int height = Rand.RangeInclusive(4, 7);
                if (resolveParams6.rect.minX > resolveParams5.rect.maxX - 3)
                {
                    break;
                }
                resolveParams6.rect = new CellRect(resolveParams6.rect.minX, resolveParams5.rect.minZ, width, height);
                if (Rand.Chance(0.15f))
                {
                    resolveParams6.rect.minX = resolveParams6.rect.minX + 3;
                }
                else
                {
                    char c = (!Rand.Chance(0.1f)) ? 'N' : 'W';
                    resolveParams6.SetCustom <char[]>("hasDoor", new char[]
                    {
                        c
                    }, false);
                    BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null);
                    resolveParams6.rect.minX = resolveParams6.rect.maxX;
                }
            }
            resolveParams6 = resolveParams5;
            for (int m = 0; m < 25; m++)
            {
                int width2 = Rand.RangeInclusive(4, 6);
                int num2   = Rand.RangeInclusive(4, 7);
                if (resolveParams6.rect.minX > resolveParams5.rect.maxX - 3)
                {
                    break;
                }
                resolveParams6.rect = new CellRect(resolveParams6.rect.minX, resolveParams5.rect.maxZ + 1 - num2, width2, num2);
                if (Rand.Chance(0.15f))
                {
                    resolveParams6.rect.minX = resolveParams6.rect.minX + 3;
                }
                else
                {
                    char c2 = (!Rand.Chance(0.1f)) ? 'S' : 'W';
                    resolveParams6.SetCustom <char[]>("hasDoor", new char[]
                    {
                        c2
                    }, false);
                    BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null);
                    resolveParams6.rect.minX = resolveParams6.rect.maxX;
                }
            }
            resolveParams6           = resolveParams5;
            resolveParams6.rect.minZ = resolveParams6.rect.minZ + 4;
            for (int n = 0; n < 25; n++)
            {
                int width3  = Rand.RangeInclusive(4, 6);
                int height2 = Rand.RangeInclusive(4, 7);
                if (resolveParams6.rect.minZ > resolveParams5.rect.maxZ - 4)
                {
                    break;
                }
                resolveParams6.rect = new CellRect(resolveParams5.rect.minX, resolveParams6.rect.minZ, width3, height2);
                if (Rand.Chance(0.15f))
                {
                    resolveParams6.rect.minZ = resolveParams6.rect.minZ + 3;
                }
                else
                {
                    char c3 = (!Rand.Chance(0.1f)) ? 'E' : 'S';
                    resolveParams6.SetCustom <char[]>("hasDoor", new char[]
                    {
                        c3
                    }, false);
                    BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null);
                    resolveParams6.rect.minZ = resolveParams6.rect.maxZ;
                }
            }
            resolveParams6           = resolveParams5;
            resolveParams6.rect.minZ = resolveParams6.rect.minZ + 4;
            for (int num3 = 0; num3 < 25; num3++)
            {
                int num4    = Rand.RangeInclusive(4, 6);
                int height3 = Rand.RangeInclusive(4, 7);
                if (resolveParams6.rect.minZ > resolveParams5.rect.maxZ - 4)
                {
                    break;
                }
                resolveParams6.rect = new CellRect(resolveParams5.rect.maxX + 1 - num4, resolveParams6.rect.minZ, num4, height3);
                if (Rand.Chance(0.15f))
                {
                    resolveParams6.rect.minZ = resolveParams6.rect.minZ + 3;
                }
                else
                {
                    char c4 = (!Rand.Chance(0.1f)) ? 'W' : 'S';
                    resolveParams6.SetCustom <char[]>("hasDoor", new char[]
                    {
                        c4
                    }, false);
                    BaseGen.symbolStack.Push("roomWithDoor", resolveParams6, null);
                    resolveParams6.rect.minZ = resolveParams6.rect.maxZ;
                }
            }
            ResolveParams resolveParams10;
            ResolveParams resolveParams9;
            ResolveParams resolveParams8;
            ResolveParams resolveParams7 = resolveParams8 = (resolveParams9 = (resolveParams10 = rp));
            CellRect      cellRect       = new CellRect(rp.rect.maxX, rp.rect.maxZ, 1, 1);

            resolveParams8.rect = cellRect.ExpandedBy(4);
            CellRect cellRect2 = new CellRect(rp.rect.minX, rp.rect.maxZ, 1, 1);

            resolveParams7.rect = cellRect2.ExpandedBy(4);
            CellRect cellRect3 = new CellRect(rp.rect.maxX, rp.rect.minZ, 1, 1);

            resolveParams9.rect = cellRect3.ExpandedBy(4);
            CellRect cellRect4 = new CellRect(rp.rect.minX, rp.rect.minZ, 1, 1);

            resolveParams10.rect = cellRect4.ExpandedBy(4);
            resolveParams8.SetCustom <char[]>("hasDoor", new char[]
            {
                'S',
                'W'
            }, false);
            resolveParams7.SetCustom <char[]>("hasDoor", new char[]
            {
                'S',
                'E'
            }, false);
            resolveParams9.SetCustom <char[]>("hasDoor", new char[]
            {
                'N',
                'W'
            }, false);
            resolveParams10.SetCustom <char[]>("hasDoor", new char[]
            {
                'N',
                'E'
            }, false);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams8, null);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams7, null);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams9, null);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams10, null);
            ResolveParams resolveParams11 = rp;

            resolveParams11.rect = resolveParams11.rect.ContractedBy(3);
            BaseGen.symbolStack.Push("edgeShields", resolveParams11, null);
            ResolveParams resolveParams12 = rp;

            BaseGen.symbolStack.Push("doors", resolveParams12, null);
            BaseGen.symbolStack.Push("edgeWalls", resolveParams12, null);
            BaseGen.symbolStack.Push("floor", resolveParams12, null);
        }
예제 #8
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);
        }
예제 #9
0
        public override void Resolve(ResolveParams rp)
        {
            rp.floorDef = TerrainDefOf.Concrete;
            ThingDef      plasteel      = ThingDefOf.Plasteel;
            ResolveParams resolveParams = rp;

            rp.wallStuff = plasteel;
            int minX   = Rand.RangeInclusive(rp.rect.minX + 5, rp.rect.minX + 10);
            int minZ   = Rand.RangeInclusive(rp.rect.minZ + 5, rp.rect.minZ + 10);
            int width  = Rand.RangeInclusive(25, 35);
            int height = Rand.RangeInclusive(25, 35);

            resolveParams.rect      = new CellRect(minX, minZ, width, height);
            resolveParams.floorDef  = TerrainDefOf.WoodPlankFloor;
            resolveParams.wallStuff = ThingDefOf.Plasteel;
            ResolveParams   resolveParams2 = resolveParams;
            ResolveParams   resolveParams3 = resolveParams;
            List <ThingDef> list           = new List <ThingDef>();

            list.Add(ThingDef.Named("DrugLab"));
            list.Add(ThingDef.Named("SimpleResearchBench"));
            list.Add(ThingDef.Named("SimpleResearchBench"));
            list.Add(ThingDef.Named("SimpleResearchBench"));
            list.Add(ThingDef.Named("HiTechResearchBench"));
            resolveParams2.floorDef  = TerrainDefOf.MetalTile;
            resolveParams2.wallStuff = ThingDefOf.Plasteel;
            resolveParams2.SetCustom <char[]>("hasDoor", new char[]
            {
                'E'
            }, false);
            for (int i = 0; i < 20; i++)
            {
                if (resolveParams2.rect.minZ > resolveParams.rect.maxZ - 2)
                {
                    break;
                }
                resolveParams2.rect           = new CellRect(resolveParams2.rect.minX, resolveParams2.rect.minZ, 7, 6);
                resolveParams3.rect           = resolveParams2.rect.ContractedBy(1);
                resolveParams3.rect           = new CellRect(resolveParams3.rect.minX + 1, resolveParams3.rect.minZ + 1, 1, 1);
                resolveParams3.thingRot       = new Rot4?(Rot4.West);
                resolveParams3.singleThingDef = list.RandomElement <ThingDef>();
                BaseGen.symbolStack.Push("insertFurnishing", resolveParams3, null);
                BaseGen.symbolStack.Push("roomWithDoor", resolveParams2, null);
                resolveParams2.rect.minZ = resolveParams2.rect.maxZ;
            }
            resolveParams2.rect.minX = resolveParams2.rect.maxX + 3;
            Rot4 rot = Rot4.North;

            if (Rand.Chance(0.5f))
            {
                resolveParams2.rect.minZ = resolveParams.rect.minZ;
                resolveParams2.SetCustom <char[]>("hasDoor", new char[]
                {
                    'N'
                }, false);
                resolveParams.SetCustom <char[]>("hasDoor", new char[]
                {
                    'E',
                    'N'
                }, false);
                rot = Rot4.South;
            }
            else
            {
                resolveParams2.rect.minZ = resolveParams.rect.maxZ - 6;
                resolveParams2.SetCustom <char[]>("hasDoor", new char[]
                {
                    'S'
                }, false);
                resolveParams.SetCustom <char[]>("hasDoor", new char[]
                {
                    'E',
                    'S'
                }, false);
            }
            for (int j = 0; j < 20; j++)
            {
                if (resolveParams2.rect.minX > resolveParams.rect.maxX - 2)
                {
                    break;
                }
                resolveParams2.rect = new CellRect(resolveParams2.rect.minX, resolveParams2.rect.minZ, 6, 7);
                resolveParams3.rect = resolveParams2.rect.ContractedBy(1);
                if (rot == Rot4.South)
                {
                    resolveParams3.rect = new CellRect(resolveParams3.rect.minX + 1, resolveParams3.rect.minZ + 1, 1, 1);
                }
                else
                {
                    resolveParams3.rect = new CellRect(resolveParams3.rect.minX + 1, resolveParams3.rect.maxZ - 1, 1, 1);
                }
                resolveParams3.thingRot       = new Rot4?(rot);
                resolveParams3.singleThingDef = list.RandomElement <ThingDef>();
                BaseGen.symbolStack.Push("insertFurnishing", resolveParams3, null);
                BaseGen.symbolStack.Push("roomWithDoor", resolveParams2, null);
                resolveParams2.rect.minX = resolveParams2.rect.maxX;
            }
            ResolveParams resolveParams4 = rp;

            resolveParams4.singleThingDef = ThingDef.Named("Table2x4c");
            resolveParams4.rect           = new CellRect(resolveParams.rect.CenterCell.x, resolveParams.rect.CenterCell.z, 1, 1);
            resolveParams4.thingRot       = new Rot4?(Rot4.North);
            BaseGen.symbolStack.Push("insertFurnishing", resolveParams4, null);
            for (int k = 0; k < 4; k++)
            {
                resolveParams4.singleThingDef = ThingDef.Named("DiningChair");
                resolveParams4.rect           = new CellRect(resolveParams.rect.CenterCell.x - 1, resolveParams.rect.CenterCell.z + 2 - k, 1, 1);
                resolveParams4.thingRot       = new Rot4?(Rot4.East);
                BaseGen.symbolStack.Push("insertFurnishing", resolveParams4, null);
            }
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams, null);
            resolveParams.chanceToSkipWallBlock = new float?(0.05f);
            BaseGen.symbolStack.Push("wireOutline", resolveParams, null);
            ResolveParams resolveParams5 = rp;

            resolveParams5.rect      = rp.rect.ContractedBy(2);
            resolveParams5.rect      = new CellRect(resolveParams5.rect.minX, resolveParams5.rect.minZ, 6, 5);
            resolveParams5.wallStuff = ThingDef.Named("BlocksLimestone");
            resolveParams5.SetCustom <char[]>("hasDoor", new char[]
            {
                'N'
            }, false);
            BaseGen.symbolStack.Push("roomWithDoor", resolveParams5, null);
            BaseGen.symbolStack.Push("wireOutline", resolveParams5, null);
            resolveParams5.rect           = resolveParams5.rect.ContractedBy(1);
            resolveParams5.singleThingDef = ThingDef.Named("ChemfuelPoweredGenerator");
            resolveParams5.thingRot       = new Rot4?(Rot4.North);
            BaseGen.symbolStack.Push("insertFurnishing", resolveParams5, null);
            BaseGen.symbolStack.Push("edgeFence", rp, null);
            BaseGen.symbolStack.Push("floor", rp, null);
            BaseGen.symbolStack.Push("clear", rp, null);
        }
예제 #10
0
        public override void Resolve(ResolveParams rp)
        {
            char[] array;
            if (rp.TryGetCustom <char[]>("hasDoor", out array))
            {
                if (rp.rect.Width < 3 && rp.rect.Height < 3)
                {
                    return;
                }
                ResolveParams resolveParams = rp;
                char[]        array2        = array;
                int           i             = 0;
                while (i < array2.Length)
                {
                    char c = array2[i];
                    if (c == 'N')
                    {
                        resolveParams.thingRot = new Rot4?(Rot4.North);
                        resolveParams.rect     = new CellRect(rp.rect.minX + 1, rp.rect.maxZ, rp.rect.Width - 2, 1);
                        goto IL_1AA;
                    }
                    if (c == 'S')
                    {
                        resolveParams.thingRot = new Rot4?(Rot4.South);
                        resolveParams.rect     = new CellRect(rp.rect.minX + 1, rp.rect.minZ, rp.rect.Width - 2, 1);
                        goto IL_1AA;
                    }
                    if (c == 'E')
                    {
                        resolveParams.thingRot = new Rot4?(Rot4.East);
                        resolveParams.rect     = new CellRect(rp.rect.maxX, rp.rect.minZ + 1, 1, rp.rect.Height - 2);
                        goto IL_1AA;
                    }
                    if (c == 'W')
                    {
                        resolveParams.thingRot = new Rot4?(Rot4.West);
                        resolveParams.rect     = new CellRect(rp.rect.minX, rp.rect.minZ + 1, 1, rp.rect.Height - 2);
                        goto IL_1AA;
                    }
IL_1BB:
                    i++;
                    continue;
IL_1AA:
                    BaseGen.symbolStack.Push("wallDoor", resolveParams, null);
                    goto IL_1BB;
                }
            }
            float chance;

            rp.TryGetCustom <float>("madAnimalChance", out chance);
            float chance2;

            rp.TryGetCustom <float>("luciferiumGasChance", out chance2);
            float chance3;

            rp.TryGetCustom <float>("psionicLandmineChance", out chance3);
            float chance4;

            rp.TryGetCustom <float>("smallGoldChance", out chance4);
            float chance5;

            rp.TryGetCustom <float>("smallSilverChance", out chance5);
            RectActionTrigger rectActionTrigger = ThingMaker.MakeThing(ThingDefOfReconAndDiscovery.RD_RectActionTrigger, null) as RectActionTrigger;

            rectActionTrigger.Rect = rp.rect;
            if (Rand.Chance(chance))
            {
                rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_MadAnimal;
            }
            else if (Rand.Chance(chance2))
            {
                rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_LuciferiumGas;
            }
            else if (Rand.Chance(chance3))
            {
                rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_PsionicLandmine;
            }
            else if (Rand.Chance(chance4))
            {
                rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_SmallGold;
            }
            else if (Rand.Chance(chance5))
            {
                rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_SmallSilver;
            }
            else
            {
                rectActionTrigger.actionDef = ActionDefOfReconAndDiscovery.RD_BaseActivatedAction;
            }
            if (rectActionTrigger.actionDef != null)
            {
                ResolveParams resolveParams2 = rp;
                resolveParams2.SetCustom <RectActionTrigger>("trigger", rectActionTrigger, false);
                BaseGen.symbolStack.Push("placeTrigger", resolveParams2, null);
            }
            BaseGen.symbolStack.Push("emptyRoom", rp, null);
        }
예제 #11
0
        public override void Resolve(ResolveParams rp)
        {
            int num;

            if (!rp.TryGetCustom <int>("minRoomDimension", out num))
            {
                Log.Error("Could not find a field minRoomDimension");
            }
            else
            {
                int width  = rp.rect.Width;
                int height = rp.rect.Height;
                Log.Message(string.Format("Current nested room dimensions -> ({0}:{1})", width, height));
                if (width < 2 * num && height < 2 * num)
                {
                    this.MakeRoom(rp);
                }
                else if ((width < 4 * num || height < 4 * num) && Rand.Value < 0.2f)
                {
                    ResolveParams rp2 = rp;
                    ResolveParams rp3 = rp;
                    rp2.rect.Width = rp.rect.Width / 2;
                    rp3.rect.minX  = rp2.rect.maxX;
                    rp3.rect.Width = rp.rect.Width / 2;
                    this.MakeRoom(rp2);
                    this.MakeRoom(rp3);
                }
                else if (width < 4 * num && height < 4 * num && Rand.Value < 0.1f)
                {
                    this.MakeRoom(rp);
                }
                else
                {
                    List <CellRect> list  = new List <CellRect>();
                    List <CellRect> list2 = new List <CellRect>();
                    if (width > 2 * num)
                    {
                        list.Add(new CellRect(rp.rect.minX, rp.rect.minZ, rp.rect.Width / 2, rp.rect.Height));
                        list.Add(new CellRect(rp.rect.minX + rp.rect.Width / 2 - 1, rp.rect.minZ, rp.rect.Width / 2, rp.rect.Height));
                    }
                    else
                    {
                        list.Add(new CellRect(rp.rect.minX, rp.rect.minZ, rp.rect.Width, rp.rect.Height));
                    }
                    foreach (CellRect item in list)
                    {
                        if (height > 2 * num)
                        {
                            list2.Add(new CellRect(item.minX, item.minZ, item.Width, item.Height / 2));
                            list2.Add(new CellRect(item.minX, item.minZ + item.Height / 2 - 1, item.Width, item.Height / 2));
                        }
                        else
                        {
                            list2.Add(item);
                        }
                    }
                    foreach (CellRect rect in list2)
                    {
                        ResolveParams resolveParams = rp;
                        resolveParams.rect = rect;
                        resolveParams.SetCustom <int>("minRoomDimension", num, false);
                        BaseGen.symbolStack.Push("nestedRoomMaze", resolveParams, null);
                    }
                }
            }
        }
예제 #12
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);
                }
            }
        }
예제 #13
0
        public override void Generate(Map map, GenStepParams parms)
        {
            //skip generation due to low blueprints count
            if (SnapshotStoreManager.Instance.StoredSnapshotsCount() < 10)
            {
                Debug.Error(Debug.Scatter, "Skipping ruins gerenation due to low blueprints count.");
                return;
            }

            //Skip generation for starting tile if corresponding settings flag is set
            if (RealRuins_ModSettings.startWithoutRuins)
            {
                int homes   = 0;
                var allMaps = Find.Maps;
                for (int i = 0; i < allMaps.Count; i++)
                {
                    Map someMap = allMaps[i];
                    if (someMap.IsPlayerHome)
                    {
                        homes++;
                    }
                }

                if (homes == 1 && Find.TickManager.TicksGame < 10)
                {
                    return;                                                //single home => we're generating that single home => that's starting map => no ruins here if this option is selected.
                }
            }

            //Skip generation on other ruins world objects
            foreach (WorldObject wo in Find.World.worldObjects.ObjectsAt(map.Tile))
            {
                if (wo is RealRuinsPOIWorldObject || wo is AbandonedBaseWorldObject)
                {
                    return;
                }
            }

            if (!map.TileInfo.WaterCovered)
            {
                float densityMultiplier    = 1.0f;
                float scaleMultiplier      = 1.0f;
                float distanceToSettlement = 0.0f;
                float totalDensity         = RealRuins_ModSettings.defaultScatterOptions.densityMultiplier;
                currentOptions = RealRuins_ModSettings.defaultScatterOptions.Copy(); //store as instance variable to keep accessible on subsequent ScatterAt calls

                if (RealRuins_ModSettings.defaultScatterOptions.enableProximity)
                {
                    distanceToSettlement = CalculateDistanceToNearestSettlement(map);
                    if (distanceToSettlement >= 16 && Rand.Chance(0.5f))
                    {
                        totalDensity = 0;
                    }

                    if (totalDensity > 0)
                    {
                        densityMultiplier = (float)(Math.Exp(1.0 / (distanceToSettlement / 10.0 + 0.3)) - 0.7);
                        scaleMultiplier   = (float)(Math.Exp(1 / (distanceToSettlement / 5 + 0.5)) - 0.3);
                    }
                    else
                    {
                        densityMultiplier = 0.0f;
                    }

                    currentOptions.densityMultiplier       *= densityMultiplier;
                    currentOptions.minRadius                = Math.Min(60, Math.Max(6, (int)(currentOptions.minRadius * scaleMultiplier))); //keep between 6 and 60
                    currentOptions.maxRadius                = Math.Min(60, Math.Max(6, (int)(currentOptions.maxRadius * scaleMultiplier))); //keep between 6 and 60
                    currentOptions.scavengingMultiplier    *= scaleMultiplier * densityMultiplier;
                    currentOptions.deteriorationMultiplier += Math.Min(0.2f, (1.0f / (scaleMultiplier * densityMultiplier * 3)));


                    if (densityMultiplier > 20.0f)
                    {
                        densityMultiplier = 20.0f;
                    }
                    while (densityMultiplier * currentOptions.maxRadius > 800)
                    {
                        densityMultiplier *= 0.9f; //WHAT? Why not 800/radius?
                    }
                }

                //number of ruins based on density settings
                var num = (int)((float)map.Area / 10000.0f) * Rand.Range(1 * totalDensity, 2 * totalDensity);

                Debug.Log(Debug.Scatter, "dist {0}, dens {1} (x{2}), scale x{3} ({4}-{5}), scav {6}, deter {7}", distanceToSettlement, currentOptions.densityMultiplier, densityMultiplier, scaleMultiplier, currentOptions.minRadius, currentOptions.maxRadius, currentOptions.scavengingMultiplier, currentOptions.deteriorationMultiplier);
                Debug.Log(Debug.Scatter, "Spawning {0} ruin chunks", num);
                BaseGen.globalSettings.map = map;

                bool shouldUnpause = false;
                Find.TickManager.Pause();
                if (!Find.TickManager.Paused)
                {
                    Find.TickManager.TogglePaused();
                    shouldUnpause = true;
                }

                CoverageMap coverageMap = CoverageMap.EmptyCoverageMap(map);

                for (int i = 0; i < num; i++)
                {
                    //We use copy of scatteroptions because each scatteroptions represents separate chunk with separate location, size, maps, etc.
                    //should use struct instead? is it compatible with IExposable?
                    ResolveParams rp = default(ResolveParams);
                    rp.SetCustom(Constants.ScatterOptions, currentOptions.Copy());
                    rp.SetCustom(Constants.CoverageMap, coverageMap);

                    if (Rand.Chance(currentOptions.hostileChance))
                    {
                        if (Rand.Chance(0.8f))
                        {
                            rp.SetCustom(Constants.ForcesGenerators, new List <AbstractDefenderForcesGenerator> {
                                new AnimalInhabitantsForcesGenerator()
                            });
                        }
                        else
                        {
                            rp.SetCustom(Constants.ForcesGenerators, new List <AbstractDefenderForcesGenerator> {
                                new MechanoidsForcesGenerator(0)
                            });
                        }
                    }
                    rp.faction = Find.FactionManager.OfAncientsHostile;
                    var center = CellFinder.RandomNotEdgeCell(10, map);
                    rp.rect = new CellRect(center.x, center.z, 1, 1); //after generation will be extended to a real size
                    BaseGen.symbolStack.Push("scatterRuins", rp);
                }
                BaseGen.Generate();

                if (shouldUnpause)
                {
                    //Debug.Message("Finished spawning, unpausing");
                    Find.TickManager.TogglePaused();
                }
            }
        }
예제 #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);
                }
            }
        }