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)); }
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); } }
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)); }
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); }
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); } }
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; } } }
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); }
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); }
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); } } } } }