예제 #1
0
        private static ITerrainOverride GenerateMiddleArea(Random r, Map map)
        {
            int basePatchX = RandomBasePatch(r, map.Size.x);
            int basePatchZ = RandomBasePatch(r, map.Size.z);

            middleAreaCenter = new IntVec2(basePatchX, basePatchZ);

            if (Settings.OpenAreaShape == ImpassableShape.Square)
            {
                int halfXSize = Settings.OpenAreaSizeX / 2;
                int halfZSize = Settings.OpenAreaSizeZ / 2;
                return(new TerrainOverrideSquare(basePatchX - halfXSize, basePatchZ - halfZSize, basePatchX + halfXSize, basePatchZ + halfZSize));
            }
            return(new TerrainOverrideRound(new IntVec3(basePatchX, 0, basePatchZ), Settings.OpenAreaSizeX));
        }
예제 #2
0
        private static bool IsSafeDropSpot(IntVec3 cell, Map map, Faction faction, IntVec2?size = null, int distToEdge = 25, int distToHostiles = 35, int distToFires = 15)
        {
            Faction factionBaseFaction = map.ParentFaction ?? Faction.OfPlayer;

            if (size.HasValue)
            {
                foreach (IntVec3 item in GenAdj.OccupiedRect(cell, Rot4.North, size.Value))
                {
                    if (!IsGoodDropSpot(item, map, allowFogged: false, canRoofPunch: false, allowIndoors: false))
                    {
                        return(false);
                    }
                }
            }
            else if (!IsGoodDropSpot(cell, map, allowFogged: false, canRoofPunch: false, allowIndoors: false))
            {
                return(false);
            }
            if (distToEdge > 0 && cell.CloseToEdge(map, distToEdge))
            {
                return(false);
            }
            if (faction != null)
            {
                foreach (IAttackTarget item2 in map.attackTargetsCache.TargetsHostileToFaction(faction))
                {
                    if (!item2.ThreatDisabled(null) && item2.Thing.Position.InHorDistOf(cell, distToHostiles))
                    {
                        return(false);
                    }
                }
            }
            if (!map.reachability.CanReachFactionBase(cell, factionBaseFaction))
            {
                return(false);
            }
            if (size.HasValue)
            {
                foreach (IntVec3 cell2 in CellRect.CenteredOn(cell, size.Value.x, size.Value.z).Cells)
                {
                    if (CellHasCrops(cell2))
                    {
                        return(false);
                    }
                }
            }
            else if (CellHasCrops(cell))
            {
                return(false);
            }
            float minDistToFiresSq = distToFires * distToFires;
            float closestDistSq    = float.MaxValue;
            int   firesCount       = 0;

            RegionTraverser.BreadthFirstTraverse(cell, map, (Region from, Region to) => true, delegate(Region x)
            {
                List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire);
                for (int i = 0; i < list.Count; i++)
                {
                    float num = cell.DistanceToSquared(list[i].Position);
                    if (!(num > minDistToFiresSq))
                    {
                        if (num < closestDistSq)
                        {
                            closestDistSq = num;
                        }
                        firesCount++;
                    }
                }
                return(closestDistSq <= minDistToFiresSq && firesCount >= 5);
            }, 15);
            if (closestDistSq <= minDistToFiresSq && firesCount >= 5)
            {
                return(false);
            }
            return(true);

            bool CellHasCrops(IntVec3 c)
            {
                Plant plant = c.GetPlant(map);

                if (plant != null && plant.sown)
                {
                    return(map.zoneManager.ZoneAt(c) is Zone_Growing);
                }
                return(false);
            }
        }
예제 #3
0
 public static bool FindSafeLandingSpotNearAvoidingHostiles(Thing thing, Map map, out IntVec3 spot, int distToHostiles = 35, int distToFires = 15, int distToEdge = 25, IntVec2?size = null)
 {
     return(RCellFinder.TryFindRandomSpotNearAvoidingHostilePawns(thing, map, (IntVec3 s) => IsSafeDropSpot(s, map, thing.Faction, size, distToEdge, distToHostiles, distToFires), out spot));
 }
예제 #4
0
        public static bool FindSafeLandingSpot(out IntVec3 spot, Faction faction, Map map, int distToHostiles = 35, int distToFires = 15, int distToEdge = 25, IntVec2?size = null)
        {
            spot = IntVec3.Invalid;
            int num = 200;

            while (num-- > 0)
            {
                IntVec3 intVec = RandomDropSpot(map);
                if (IsSafeDropSpot(intVec, map, faction, size, distToEdge, distToHostiles, distToFires))
                {
                    spot = intVec;
                    return(true);
                }
            }
            return(false);
        }
예제 #5
0
        public static bool TryFindDropSpotNear(IntVec3 center, Map map, out IntVec3 result, bool allowFogged, bool canRoofPunch, bool allowIndoors = true, IntVec2?size = null)
        {
            if (DebugViewSettings.drawDestSearch)
            {
                map.debugDrawer.FlashCell(center, 1f, "center");
            }
            Room centerRoom = center.GetRoom(map);
            Predicate <IntVec3> validator = delegate(IntVec3 c)
            {
                if (size.HasValue)
                {
                    foreach (IntVec3 item in GenAdj.OccupiedRect(c, Rot4.North, size.Value))
                    {
                        if (!IsGoodDropSpot(item, map, allowFogged, canRoofPunch, allowIndoors))
                        {
                            return(false);
                        }
                    }
                }
                else if (!IsGoodDropSpot(c, map, allowFogged, canRoofPunch, allowIndoors))
                {
                    return(false);
                }
                return(map.reachability.CanReach(center, c, PathEndMode.OnCell, TraverseMode.PassDoors, Danger.Deadly) ? true : false);
            };

            if (allowIndoors && canRoofPunch && centerRoom != null && !centerRoom.PsychologicallyOutdoors)
            {
                Predicate <IntVec3> v2 = (IntVec3 c) => validator(c) && c.GetRoom(map) == centerRoom;
                if (TryFindCell(v2, out result))
                {
                    return(true);
                }
                Predicate <IntVec3> v3 = delegate(IntVec3 c)
                {
                    if (!validator(c))
                    {
                        return(false);
                    }
                    Room room = c.GetRoom(map);
                    return(room != null && !room.PsychologicallyOutdoors);
                };
                if (TryFindCell(v3, out result))
                {
                    return(true);
                }
            }
            return(TryFindCell(validator, out result));

            bool TryFindCell(Predicate <IntVec3> v, out IntVec3 r)
            {
                int num = 5;

                do
                {
                    if (CellFinder.TryFindRandomCellNear(center, map, num, v, out r))
                    {
                        return(true);
                    }
                    num += 3;
                }while (num <= 16);
                r = center;
                return(false);
            }
        }
예제 #6
0
        public static void FindCloseLandingSpot(out IntVec3 spot, Faction faction, Map map, IntVec2?size)
        {
            IntVec3 center = default;
            int     count  = 0;

            foreach (Building building in map.listerBuildings.allBuildingsColonist.Where(x => x.def.size.x > 1 || x.def.size.z > 1))
            {
                center += building.Position;
                count++;
            }

            if (count == 0)
            {
                FindAnyLandingSpot(out spot, faction, map, size);
                return;
            }

            center.x /= count;
            center.z /= count;

            int   spotCount    = 20;
            float bestDistance = 999999f;

            spot = default;

            for (int i = 0; i < spotCount; i++)
            {
                IntVec3 s;
                FindAnyLandingSpot(out s, faction, map, size);

                if ((s - center).LengthManhattan < bestDistance)
                {
                    bestDistance = (s - center).LengthManhattan;
                    spot         = s;
                }
            }
        }
예제 #7
0
        public static bool FindAnyLandingSpot(out IntVec3 spot, Faction faction, Map map, IntVec2?size)
        {
            if (!DropCellFinder.FindSafeLandingSpot(out spot, faction, map, 0, 15, 25, size))
            {
                IntVec3 intVec = DropCellFinder.RandomDropSpot(map);
                if (!DropCellFinder.TryFindDropSpotNear(intVec, map, out spot, false, false, false, size))
                {
                    spot = intVec;
                }
            }

            return(true);
        }
예제 #8
0
        public Texture2D GetTexture(string content, IntVec2?position = null)
        {
            LinkedListNode <Render> render;

            if (content == blankRender.text)
            {
                return(blankRender.tex);
            }
            else if (rendersByContent.TryGetValue(content, out render))
            {
            }
            else if (content == null || content.Length != ContentLengthRequirement)
            {
                throw new System.ArgumentException();
            }
            else
            {
                if (position.HasValue && rendersByPosition.TryGetValue(position.Value, out render))
                {
                    var matchingPositions = render.Value.positions;
                    if (!matchingPositions.Contains(position.Value))
                    {
                        throw new System.InvalidOperationException("rendersByPosition and Render objects are not in agreement about the Cache state.");
                    }
                    if (matchingPositions.Count > 1)
                    {
                        //split (from other positions)
                        matchingPositions.Remove(position.Value);
                        render = new LinkedListNode <Render>(new Render(render.Value));
                    }
                }
                else if (rendersChronologically.Count < renderTextureMaxCacheSize)
                {
                    render = new LinkedListNode <Render>(new Render(blankRender));
                }
                else
                {
                    render = rendersChronologically.First;
                    foreach (IntVec2 pos in render.Value.positions)
                    {
                        rendersByPosition.Remove(pos);
                    }
                }

                render.Value.positions.Clear();
                var old_content = render.Value.text;
                rendersByContent.Remove(old_content);
                rendersByContent[content] = render;
                UpdateTexture(render.Value.tex, old_content, content);
            }

            if (position.HasValue)
            {
                render.Value.positions.Add(position.Value);
                rendersByPosition[position.Value] = render;
            }

            render.List?.Remove(render);
            rendersChronologically.AddLast(render);
            return(render.Value.tex);
        }
예제 #9
0
        static void Postfix(Map map)
        {
            //Log.Error($"Roof Edge: {Settings.RoofEdgeDepth}");
            middleAreaCenter = null;
            if (map.TileInfo.hilliness == Hilliness.Impassable)
            {
                int radius = (int)(((float)map.Size.x + map.Size.z) * 0.25f) + Settings.OuterRadius;

                int    middleWallSmoothness = Settings.MiddleWallSmoothness;
                Random r;
                if (Settings.TrueRandom)
                {
                    r = new Random(Guid.NewGuid().GetHashCode());
                }
                else
                {
                    r = new Random((Find.World.info.name + map.Tile).GetHashCode());
                }

                ITerrainOverride middleArea = null;
                if (Settings.HasMiddleArea)
                {
                    middleArea = GenerateMiddleArea(r, map);
                }

                QuestArea = null;
                if (Patch_MapGenerator_Generate.IsQuestMap)
                {
                    Log.Message("[Impassable Map Maker] map is for a quest. An open area will be created to support it.");
                    QuestArea = GenerateAreaForQuests(r, map);
                }

                ITerrainOverride quaryArea = null;
                if (Settings.IncludeQuarySpot)
                {
                    quaryArea = DetermineQuary(r, map, middleArea);
                }
#if DEBUG
                Log.Warning(
                    "size " + map.Size.x +
                    " basePatchX " + basePatchX + " basePatchZ " + basePatchZ);
#endif
                MapGenFloatGrid fertility   = MapGenerator.Fertility;
                MapGenFloatGrid elevation   = MapGenerator.Elevation;
                IntVec2         roofXMinMax = new IntVec2(Settings.RoofEdgeDepth, map.Size.x - Settings.RoofEdgeDepth);
                IntVec2         roofZMinMax = new IntVec2(Settings.RoofEdgeDepth, map.Size.z - Settings.RoofEdgeDepth);
                foreach (IntVec3 current in map.AllCells)
                {
                    float elev = 0;
                    if (IsMountain(current, map, radius))
                    {
                        elev = 3.40282347E+38f;
                        map.roofGrid.SetRoof(current, RoofDefOf.RoofRockThick);
                    }
                    else if (Settings.ScatteredRocks && IsScatteredRock(current, r, map, radius))
                    {
                        elev = 0.75f;
                    }
                    else
                    {
                        elev = 0.57f;
                        map.roofGrid.SetRoof(current, null);
                    }

                    if (QuestArea?.IsInside(current) == true)
                    {
                        elev = 0;
                        map.roofGrid.SetRoof(current, null);
                    }
                    else if (quaryArea?.IsInside(current) == true)
                    {
                        // Gravel
                        elev = 0.57f;
                        map.roofGrid.SetRoof(current, null);
                    }
                    else if (middleArea != null)
                    {
                        int i = (middleWallSmoothness == 0) ? 0 : r.Next(middleWallSmoothness);
                        if (middleArea.IsInside(current, i))
                        {
                            AddMiddleAreaCell(current);
                            elev = 0;
                            map.roofGrid.SetRoof(current, null);
                        }
                    }

                    /*if (current.x == 0 || current.x == map.Size.x - 1 ||
                     *  current.z == 0 || current.z == map.Size.z - 1)
                     * {
                     *  map.fogGrid.Notify_FogBlockerRemoved(current);
                     * }*/
                    elevation[current] = elev;

                    if (Settings.OuterShape == ImpassableShape.Fill && roofXMinMax.x > 0)
                    {
                        if (current.x <= roofXMinMax.x ||
                            current.x >= roofXMinMax.z ||
                            current.z <= roofZMinMax.x ||
                            current.z >= roofZMinMax.z)
                        {
                            elevation[current] = 0.75f;
                            map.roofGrid.SetRoof(current, null);
                        }
                    }
                }
            }
        }