protected override void ResolveInt(ResolveParams parms)
        {
            CellRect outerRect = parms.rect ?? parms.sketch.OccupiedRect;

            if (!TryFindFloors(out TerrainDef floor, out TerrainDef floor2, parms))
            {
                return;
            }
            bool num  = parms.floorFillRoomsOnly ?? false;
            bool flag = parms.singleFloorType ?? false;

            if (num)
            {
                tmpWalls.Clear();
                for (int i = 0; i < parms.sketch.Things.Count; i++)
                {
                    SketchThing sketchThing = parms.sketch.Things[i];
                    if (sketchThing.def.passability == Traversability.Impassable && sketchThing.def.Fillage == FillCategory.Full)
                    {
                        foreach (IntVec3 item in sketchThing.OccupiedRect)
                        {
                            tmpWalls.Add(item);
                        }
                    }
                }
                tmpVisited.Clear();
                foreach (IntVec3 item2 in outerRect)
                {
                    if (!tmpWalls.Contains(item2))
                    {
                        FloorFillRoom_NewTmp(item2, tmpWalls, tmpVisited, parms.sketch, floor, floor2, outerRect, flag);
                    }
                }
            }
            else
            {
                bool[,] array = AbstractShapeGenerator.Generate(outerRect.Width, outerRect.Height, horizontalSymmetry: true, verticalSymmetry: true);
                foreach (IntVec3 item3 in outerRect)
                {
                    if (!parms.sketch.ThingsAt(item3).Any((SketchThing x) => x.def.Fillage == FillCategory.Full))
                    {
                        if (array[item3.x - outerRect.minX, item3.z - outerRect.minZ] | flag)
                        {
                            parms.sketch.AddTerrain(floor, item3, wipeIfCollides: false);
                        }
                        else
                        {
                            parms.sketch.AddTerrain(floor2, item3, wipeIfCollides: false);
                        }
                    }
                }
            }
        }
        protected override void ResolveInt(ResolveParams parms)
        {
            IntVec2 intVec;

            if (parms.monumentSize.HasValue)
            {
                intVec = parms.monumentSize.Value;
            }
            else
            {
                int num = Rand.Range(10, 50);
                intVec = new IntVec2(num, num);
            }
            int            width    = intVec.x;
            int            height   = intVec.z;
            bool           flag     = ((!parms.monumentOpen.HasValue) ? Rand.Chance(OpenChancePerSizeCurve.Evaluate(Mathf.Max(width, height))) : parms.monumentOpen.Value);
            Sketch         monument = new Sketch();
            bool           onlyBuildableByPlayer = parms.onlyBuildableByPlayer ?? false;
            bool           filterAllowsAll       = parms.allowedMonumentThings == null;
            List <IntVec3> list = new List <IntVec3>();
            bool           horizontalSymmetry;
            bool           verticalSymmetry;

            if (flag)
            {
                horizontalSymmetry = true;
                verticalSymmetry   = true;
                bool[,] array      = AbstractShapeGenerator.Generate(width, height, horizontalSymmetry, verticalSymmetry, allTruesMustBeConnected: false, allowEnclosedFalses: false, preferOutlines: true);
                for (int i = 0; i < array.GetLength(0); i++)
                {
                    for (int j = 0; j < array.GetLength(1); j++)
                    {
                        if (array[i, j])
                        {
                            monument.AddThing(ThingDefOf.Wall, new IntVec3(i, 0, j), Rot4.North, ThingDefOf.WoodLog);
                        }
                    }
                }
            }
            else
            {
                horizontalSymmetry = Rand.Bool;
                verticalSymmetry   = !horizontalSymmetry || Rand.Bool;
                bool[,] shape      = AbstractShapeGenerator.Generate(width - 2, height - 2, horizontalSymmetry, verticalSymmetry, allTruesMustBeConnected: true);
                Func <int, int, bool> func = (int x, int z) => x >= 0 && z >= 0 && x < shape.GetLength(0) && z < shape.GetLength(1) && shape[x, z];
                for (int k = -1; k < shape.GetLength(0) + 1; k++)
                {
                    for (int l = -1; l < shape.GetLength(1) + 1; l++)
                    {
                        if (!func(k, l) && (func(k - 1, l) || func(k, l - 1) || func(k, l + 1) || func(k + 1, l) || func(k - 1, l - 1) || func(k - 1, l + 1) || func(k + 1, l - 1) || func(k + 1, l + 1)))
                        {
                            int newX = k + 1;
                            int newZ = l + 1;
                            monument.AddThing(ThingDefOf.Wall, new IntVec3(newX, 0, newZ), Rot4.North, ThingDefOf.WoodLog);
                        }
                    }
                }
                for (int m = -1; m < shape.GetLength(0) + 1; m++)
                {
                    for (int n = -1; n < shape.GetLength(1) + 1; n++)
                    {
                        if (!func(m, n) && (func(m - 1, n) || func(m, n - 1) || func(m, n + 1) || func(m + 1, n)))
                        {
                            int num2 = m + 1;
                            int num3 = n + 1;
                            if ((!func(m - 1, n) && monument.Passable(new IntVec3(num2 - 1, 0, num3))) || (!func(m, n - 1) && monument.Passable(new IntVec3(num2, 0, num3 - 1))) || (!func(m, n + 1) && monument.Passable(new IntVec3(num2, 0, num3 + 1))) || (!func(m + 1, n) && monument.Passable(new IntVec3(num2 + 1, 0, num3))))
                            {
                                list.Add(new IntVec3(num2, 0, num3));
                            }
                        }
                    }
                }
            }
            ResolveParams parms2 = parms;

            parms2.sketch = monument;
            parms2.connectedGroupsSameStuff = true;
            parms2.assignRandomStuffTo      = ThingDefOf.Wall;
            SketchResolverDefOf.AssignRandomStuff.Resolve(parms2);
            if (parms.addFloors ?? true)
            {
                ResolveParams parms3 = parms;
                parms3.singleFloorType    = true;
                parms3.sketch             = monument;
                parms3.floorFillRoomsOnly = !flag;
                parms3.onlyStoneFloors    = parms.onlyStoneFloors ?? true;
                parms3.allowConcrete      = parms.allowConcrete ?? false;
                parms3.rect = new CellRect(0, 0, width, height);
                SketchResolverDefOf.FloorFill.Resolve(parms3);
            }
            if (CanUse(ThingDefOf.Column))
            {
                ResolveParams parms4 = parms;
                parms4.rect         = new CellRect(0, 0, width, height);
                parms4.sketch       = monument;
                parms4.requireFloor = true;
                SketchResolverDefOf.AddColumns.Resolve(parms4);
            }
            TryPlaceFurniture(parms, monument, CanUse);
            for (int num4 = 0; num4 < 2; num4++)
            {
                ResolveParams parms5 = parms;
                parms5.addFloors = false;
                parms5.sketch    = monument;
                parms5.rect      = new CellRect(0, 0, width, height);
                SketchResolverDefOf.AddInnerMonuments.Resolve(parms5);
            }
            bool num5 = parms.allowMonumentDoors ?? (filterAllowsAll || parms.allowedMonumentThings.Allows(ThingDefOf.Door));

            if (num5 && list.Where((IntVec3 x) => (!horizontalSymmetry || x.x < width / 2) && (!verticalSymmetry || x.z < height / 2) && monument.ThingsAt(x).Any((SketchThing y) => y.def == ThingDefOf.Wall) && ((!monument.ThingsAt(new IntVec3(x.x - 1, x.y, x.z)).Any() && !monument.ThingsAt(new IntVec3(x.x + 1, x.y, x.z)).Any()) || (!monument.ThingsAt(new IntVec3(x.x, x.y, x.z - 1)).Any() && !monument.ThingsAt(new IntVec3(x.x, x.y, x.z + 1)).Any()))).TryRandomElement(out var result))
            {
                SketchThing sketchThing = monument.ThingsAt(result).FirstOrDefault((SketchThing x) => x.def == ThingDefOf.Wall);
                if (sketchThing != null)
                {
                    monument.Remove(sketchThing);
                    monument.AddThing(ThingDefOf.Door, result, Rot4.North, sketchThing.Stuff);
                }
            }
            TryPlaceFurniture(parms, monument, CanUse);
            ApplySymmetry(parms, horizontalSymmetry, verticalSymmetry, monument, width, height);
            if (num5 && !flag && !monument.Things.Any((SketchThing x) => x.def == ThingDefOf.Door) && monument.Things.Where((SketchThing x) => x.def == ThingDefOf.Wall && ((monument.Passable(x.pos.x - 1, x.pos.z) && monument.Passable(x.pos.x + 1, x.pos.z) && monument.AnyTerrainAt(x.pos.x - 1, x.pos.z) != monument.AnyTerrainAt(x.pos.x + 1, x.pos.z)) || (monument.Passable(x.pos.x, x.pos.z - 1) && monument.Passable(x.pos.x, x.pos.z + 1) && monument.AnyTerrainAt(x.pos.x, x.pos.z - 1) != monument.AnyTerrainAt(x.pos.x, x.pos.z + 1)))).TryRandomElement(out var result2))
            {
                SketchThing sketchThing2 = monument.ThingsAt(result2.pos).FirstOrDefault((SketchThing x) => x.def == ThingDefOf.Wall);
                if (sketchThing2 != null)
                {
                    monument.Remove(sketchThing2);
                }
                monument.AddThing(ThingDefOf.Door, result2.pos, Rot4.North, result2.Stuff);
            }
            List <SketchThing> things = monument.Things;

            for (int num6 = 0; num6 < things.Count; num6++)
            {
                if (things[num6].def == ThingDefOf.Wall)
                {
                    monument.RemoveTerrain(things[num6].pos);
                }
            }
            parms.sketch.MergeAt(monument, default(IntVec3), Sketch.SpawnPosType.OccupiedCenter);
            bool CanUse(ThingDef def)
            {
                if (onlyBuildableByPlayer && !SketchGenUtility.PlayerCanBuildNow(def))
                {
                    return(false);
                }
                if (!filterAllowsAll && !parms.allowedMonumentThings.Allows(def))
                {
                    return(false);
                }
                return(true);
            }
        }
Example #3
0
        private void FloorFillRoom_NewTmp(IntVec3 c, HashSet <IntVec3> walls, HashSet <IntVec3> visited, Sketch sketch, TerrainDef def1, TerrainDef def2, CellRect outerRect, bool singleFloorType)
        {
            if (visited.Contains(c))
            {
                return;
            }
            tmpCells.Clear();
            tmpStack.Clear();
            tmpStack.Push(new Pair <int, int>(c.x, c.z));
            visited.Add(c);
            int num  = c.x;
            int num2 = c.x;
            int num3 = c.z;
            int num4 = c.z;

            while (tmpStack.Count != 0)
            {
                Pair <int, int> pair   = tmpStack.Pop();
                int             first  = pair.First;
                int             second = pair.Second;
                tmpCells.Add(new IntVec3(first, 0, second));
                num  = Mathf.Min(num, first);
                num2 = Mathf.Max(num2, first);
                num3 = Mathf.Min(num3, second);
                num4 = Mathf.Max(num4, second);
                if (first > outerRect.minX && !walls.Contains(new IntVec3(first - 1, 0, second)) && !visited.Contains(new IntVec3(first - 1, 0, second)))
                {
                    visited.Add(new IntVec3(first - 1, 0, second));
                    tmpStack.Push(new Pair <int, int>(first - 1, second));
                }
                if (second > outerRect.minZ && !walls.Contains(new IntVec3(first, 0, second - 1)) && !visited.Contains(new IntVec3(first, 0, second - 1)))
                {
                    visited.Add(new IntVec3(first, 0, second - 1));
                    tmpStack.Push(new Pair <int, int>(first, second - 1));
                }
                if (first < outerRect.maxX && !walls.Contains(new IntVec3(first + 1, 0, second)) && !visited.Contains(new IntVec3(first + 1, 0, second)))
                {
                    visited.Add(new IntVec3(first + 1, 0, second));
                    tmpStack.Push(new Pair <int, int>(first + 1, second));
                }
                if (second < outerRect.maxZ && !walls.Contains(new IntVec3(first, 0, second + 1)) && !visited.Contains(new IntVec3(first, 0, second + 1)))
                {
                    visited.Add(new IntVec3(first, 0, second + 1));
                    tmpStack.Push(new Pair <int, int>(first, second + 1));
                }
            }
            for (int i = 0; i < tmpCells.Count; i++)
            {
                if (outerRect.IsOnEdge(tmpCells[i]))
                {
                    return;
                }
            }
            CellRect cellRect = CellRect.FromLimits(num, num3, num2, num4);

            bool[,] array = AbstractShapeGenerator.Generate(cellRect.Width, cellRect.Height, horizontalSymmetry: true, verticalSymmetry: true);
            for (int j = 0; j < tmpCells.Count; j++)
            {
                IntVec3 pos = tmpCells[j];
                if (!sketch.ThingsAt(pos).Any((SketchThing x) => x.def.passability == Traversability.Impassable && x.def.Fillage == FillCategory.Full))
                {
                    if (array[pos.x - cellRect.minX, pos.z - cellRect.minZ] || singleFloorType)
                    {
                        sketch.AddTerrain(def1, pos, wipeIfCollides: false);
                    }
                    else
                    {
                        sketch.AddTerrain(def2, pos, wipeIfCollides: false);
                    }
                }
            }
        }