public void Initialize(VehicleDef def) { if (!cells.NullOrEmpty()) { Hitbox = cells; } else { CellRect rect = CellRect.CenteredOn(new IntVec3(0, 0, 0), def.Size.x, def.Size.z); List <IntVec3> cells = new List <IntVec3>(); if (side == VehicleComponentPosition.Body) { cells = rect.Cells.ToList(); } else if (side == VehicleComponentPosition.BodyNoOverlap) { foreach (var cell in rect.Cells.Where(c => !def.components.Where(cp => noOverlapWith.Contains(cp.hitbox.side)).Any(cp => cp.hitbox.Contains(c)))) { cells.Add(new IntVec3(cell.x, 0, cell.z)); } } else { cells = rect.GetEdgeCells(RotationFromSide(side)).ToList(); } List <IntVec2> intVec2s = new List <IntVec2>(); foreach (IntVec3 cell in cells) { intVec2s.Add(new IntVec2(cell.x, cell.z)); } Hitbox = intVec2s; } }
private bool CanPlaceAt(CellRect rect, Rot4 dir, Sketch sketch) { foreach (IntVec3 edgeCell in rect.GetEdgeCells(dir)) { IntVec3 current = edgeCell; if (dir == Rot4.North) { current.z++; } else if (dir == Rot4.South) { current.z++; } else if (dir == Rot4.East) { current.x++; } else { current.x--; } if (!sketch.ThingsAt(current).Any((SketchThing x) => x.def == ThingDefOf.Wall)) { return(false); } } return(true); }
private bool WallHasDoor(CellRect rect, Rot4 dir) { foreach (IntVec3 edgeCell in rect.GetEdgeCells(dir)) { if (cellPainter.ContainsKey(edgeCell) && cellPainter[edgeCell] == SpawnType.Door) { return(true); } } return(false); }
private bool WallHasDoor(CellRect rect, Rot4 dir) { Map map = BaseGen.globalSettings.map; foreach (IntVec3 c in rect.GetEdgeCells(dir)) { if (c.GetDoor(map) != null) { return true; } } return false; }
private bool WallHasDoor(CellRect rect, Rot4 dir) { var map = BaseGen.globalSettings.map; foreach (var current in rect.GetEdgeCells(dir)) { if (current.GetDoor(map) != null) { return(true); } } return(false); }
private IEnumerable <Pair <IntVec3, Rot4> > GetPossibleDrapeCells(IntVec3 throneCell, CellRect rect) { for (int d = 0; d < 4; d++) { foreach (IntVec3 edgeCell in rect.GetEdgeCells(new Rot4(d))) { bool flag = true; foreach (IntVec3 item in GenAdj.OccupiedRect(edgeCell, new Rot4(d), ThingDefOf.Drape.size)) { if (item == throneCell || rect.IsCorner(item) || BaseGenUtility.AnyDoorAdjacentCardinalTo(item, BaseGen.globalSettings.map)) { flag = false; break; } } if (flag) { yield return(new Pair <IntVec3, Rot4>(edgeCell, new Rot4(d))); } } } }
public static CellRect AdjacentRectMaker(CellRect startRect, Rot4 dir, out IntVec3 doorLoc, int newSizeX, int newSizeZ = 0) { _ = IntVec3.Invalid; _ = new CellRect(); int oldX = startRect.GetEdgeCells(Rot4.North).Count <IntVec3>(); int oldZ = startRect.GetEdgeCells(Rot4.West).Count <IntVec3>(); CellRect adjRect; ///Make a rectangle to the North? if (dir == Rot4.North) { int heightCalc = newSizeX; if (newSizeZ != 0) { heightCalc = newSizeZ; } int newMinX = startRect.CenterCell.x - (newSizeX / 2); int newMinZ = startRect.CenterCell.z + (oldZ / 2); adjRect = new CellRect(newMinX, newMinZ, newSizeX, heightCalc); doorLoc = CellRectTopMiddle(startRect); } //South? else if (dir == Rot4.South) { int heightCalc = newSizeX; if (newSizeZ != 0) { heightCalc = newSizeZ; } int newMinX = startRect.CenterCell.x - (newSizeX / 2); int newMinZ = (startRect.CenterCell.z - ((oldZ / 2) - 1)) - heightCalc; adjRect = new CellRect(newMinX, newMinZ, newSizeX, heightCalc); doorLoc = CellRectBottomMiddle(startRect); } //East? else if (dir == Rot4.East) { int heightCalc = newSizeX; if (newSizeZ != 0) { heightCalc = newSizeZ; } int newMinX = startRect.CenterCell.x + (oldX / 2); int newMinZ = startRect.CenterCell.z - (heightCalc / 2); adjRect = new CellRect(newMinX, newMinZ, newSizeX, heightCalc); doorLoc = CellRectRightMiddle(startRect); } //West? else { int heightCalc = newSizeX; if (newSizeZ != 0) { heightCalc = newSizeZ; } int newMinX = ((startRect.CenterCell.x - (oldX / 2)) - newSizeX) + 1; int newMinZ = startRect.CenterCell.z - (heightCalc / 2); adjRect = new CellRect(newMinX, newMinZ, newSizeX, heightCalc); doorLoc = CellRectLeftMiddle(startRect); } RectReport(adjRect); return(adjRect); }
public override void PassingParameters(ResolveParams rp) { string defChair = "DiningChair"; string defLamp = "Jecrell_GasLamp"; ThingDef lampDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDef.Named(defLamp) : ThingDefOf.TorchLamp; ThingDef lampStuffDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDefOf.Steel : null; Map map = BaseGen.globalSettings.map; bool @bool = Rand.Bool; bool hasLamp = false; ThingDef thingDef = ThingDefOf.SleepingSpot; ThingDef chairDef = ThingDef.Named(defChair); foreach (IntVec3 current in rp.rect) { if (@bool) { if (current.x % 3 != 0 || current.z % 3 != 0) { continue; } } else if (current.x % 3 != 0 || current.z % 3 != 0) { continue; } Rot4 rot = (!@bool) ? Rot4.South : Rot4.West; if (!GenSpawn.WouldWipeAnythingWith(current, rot, thingDef, map, (Thing x) => x.def.category == ThingCategory.Building)) { bool flag = false; foreach (IntVec3 current2 in GenAdj.CellsOccupiedBy(current, rot, thingDef.Size)) { if (BaseGenUtility.AnyDoorAdjacentCardinalTo(current2, map)) { flag = true; break; } } if (!flag) { ///Bed ThingDef stuff = null; if (thingDef.MadeFromStuff) { stuff = ThingDefOf.WoodLog; } Thing thing = ThingMaker.MakeThing(thingDef, stuff); thing.SetFaction(rp.faction, null); GenSpawn.Spawn(thing, current, map, rot); if (thing != null) { if (thing.Spawned && thing.Position.InBounds(map)) { CellRect thingRect = thing.OccupiedRect(); if (thingRect != null) { thingRect = thingRect.ExpandedBy(1); List <IntVec3> possibleCells = new List <IntVec3>(); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.North)); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.South)); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.East)); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.West)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 0)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 1)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 2)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 3)); IntVec3 spawnPos = IntVec3.Invalid; spawnPos = possibleCells.InRandomOrder <IntVec3>().FirstOrDefault((IntVec3 x) => x.InBounds(map) && x.Walkable(map)); if (spawnPos != null) { possibleCells.Remove(spawnPos); Thing thing2 = ThingMaker.MakeThing(chairDef, ThingDefOf.WoodLog); thing2.SetFaction(rp.faction, null); GenSpawn.Spawn(thing2, spawnPos, map, rot.Opposite); } if (!hasLamp) { hasLamp = true; spawnPos = possibleCells.FirstOrDefault((IntVec3 x) => x.InBounds(map) && x.Walkable(map)); if (spawnPos != null) { possibleCells.Remove(spawnPos); Thing thing3 = ThingMaker.MakeThing(lampDef, lampStuffDef); thing3.SetFaction(rp.faction, null); GenSpawn.Spawn(thing3, spawnPos, map, rot.Opposite); } } } } } } } } //if (!Cthulhu.Utility.IsCosmicHorrorsLoaded()) //{ PawnGroupKindDef groupKind = rp.pawnGroupKindDef ?? PawnGroupKindDefOf.Combat; PawnGroupMakerParms pawnGroupMakerParms = new PawnGroupMakerParms() { faction = (from x in Find.FactionManager.AllFactions where x.HostileTo(rp.faction) && x.def.pawnGroupMakers != null && x.def.pawnGroupMakers.Count > 0 && x.def.humanlikeFaction && IsCosmicHorrorFaction(x) == false && (x.def.pawnGroupMakers.FirstOrDefault((PawnGroupMaker y) => y.kindDef == PawnGroupKindDefOf.Combat) != null) select x).RandomElement <Faction>(), tile = map.Tile, points = 5000, generateFightersOnly = false, }; int num = 0; foreach (Pawn current in PawnGroupMakerUtility.GeneratePawns(pawnGroupMakerParms, true)) { num++; ResolveParams resolveParams = rp; resolveParams.singlePawnToSpawn = current; BaseGen.symbolStack.Push("pawn", resolveParams); if (num == 3) { break; } } //} //else //{ // Faction tempFaction = Find.FactionManager.AllFactions.InRandomOrder<Faction>().FirstOrDefault((Faction z) => IsCosmicHorrorFaction(z)); // PawnGroupKindDef groupKind = rp.pawnGroupKindDef ?? PawnGroupKindDefOf.Combat; // PawnGroupMakerParms pawnGroupMakerParms = new PawnGroupMakerParms() // { // faction = tempFaction, // map = map, // points = 5000, // generateFightersOnly = false, // generateMeleeOnly = false // }; // int num = 0; // foreach (Pawn current in PawnGroupMakerUtility.GeneratePawns(groupKind, pawnGroupMakerParms, true)) // { // num++; // ResolveParams resolveParams = rp; // resolveParams.singlePawnToSpawn = current; // resolveParams.singlePawnLord = null; // BaseGen.symbolStack.Push("pawn", resolveParams); // if (num == 3) break; // } //} //List<int> corners = new List<int>() { 0, 1, 2, 3 }; //foreach (int corner in corners.InRandomOrder<int>()) //{ // IntVec3 loc = Cthulhu.Utility.GetCornerPos(rp.rect.ContractedBy(1), corner); // if (!GenSpawn.WouldWipeAnythingWith(loc, Rot4.South, lampDef, map, (Thing x) => x.def.category == ThingCategory.Building)) // { // ThingDef singleThingDef3 = (Cthulhu.Utility.IsIndustrialAgeLoaded()) ? lampDef : ThingDefOf.TorchLamp; // Thing thing3 = ThingMaker.MakeThing(singleThingDef3, ThingDefOf.Steel); // GenSpawn.Spawn(thing3, loc, map); // break; // } //} }
public override void PassingParameters(ResolveParams rp) { //string defLogo = "AgencySymbolFloorPainting"; string defTable = "TableLong"; string defChair = "DiningChair"; string defLamp = "Jecrell_GasLamp"; Map map = BaseGen.globalSettings.map; Rot4 rot = Rot4.North; int deskOffset = 1; //ThingDef logoDef = ThingDef.Named(defLogo); ThingDef thingDef = ThingDef.Named(defTable); ThingDef chairDef = ThingDef.Named(defChair); ThingDef lampDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDef.Named(defLamp) : ThingDefOf.TorchLamp; ThingDef lampStuffDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDefOf.Steel : null; IntVec3 locationCenter = rp.rect.CenterCell; for (int i = 0; i < deskOffset; i++) { locationCenter -= GenAdj.AdjacentCells[rot.AsInt]; } IntVec3 receptionCenter = rp.rect.CenterCell; for (int i = 0; i < deskOffset; i++) { receptionCenter += GenAdj.AdjacentCells[rot.AsInt]; } ///Center logo //ThingDef stuff = null; //Thing logo = ThingMaker.MakeThing(logoDef, stuff); //logo.SetFaction(rp.faction, null); //GenSpawn.Spawn(logo, locationCenter, map, rot); ///Reception table ThingDef stuff = null; if (thingDef.MadeFromStuff) { stuff = ThingDefOf.WoodLog; } Thing thing = ThingMaker.MakeThing(thingDef, stuff); thing.SetFaction(rp.faction, null); GenSpawn.Spawn(thing, receptionCenter, map, rot); ///Adjacent lamps IntVec3 loc1 = Cthulhu.Utility.GetCornerPos(thing.OccupiedRect(), 0) + GenAdj.AdjacentCells[Rot4.West.AsInt] + GenAdj.AdjacentCells[Rot4.West.AsInt]; Thing thing3 = ThingMaker.MakeThing(lampDef, lampStuffDef); GenSpawn.Spawn(thing3, loc1, map); IntVec3 loc2 = Cthulhu.Utility.GetCornerPos(thing.OccupiedRect(), 1) + GenAdj.AdjacentCells[Rot4.East.AsInt] + GenAdj.AdjacentCells[Rot4.East.AsInt]; Thing thing4 = ThingMaker.MakeThing(lampDef, lampStuffDef); GenSpawn.Spawn(thing4, loc2, map); if (thing != null) { if (thing.Spawned && thing.Position.InBounds(map)) { CellRect rectToEdit = thing.OccupiedRect().ExpandedBy(1); List <IntVec3> poss = new List <IntVec3>(); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.North)); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.South)); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.East)); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.West)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 0)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 1)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 2)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 3)); foreach (IntVec3 currentPos in poss.InRandomOrder <IntVec3>()) { ///CHAIR float angle = (currentPos - thing.Position).ToVector3().AngleFlat(); Rot4 newRot = Pawn_RotationTracker.RotFromAngleBiased(angle).Opposite; Building bld = thing as Building; //We need an interaction cell Thing thing2 = ThingMaker.MakeThing(chairDef, stuff); thing2.SetFaction(rp.faction, null); GenSpawn.Spawn(thing2, currentPos, map, newRot); } } } ///Four corners, four gas lamps. for (int i = 0; i < 1; i++) { Thing thing5 = ThingMaker.MakeThing(lampDef, lampStuffDef); IntVec3 loc = Cthulhu.Utility.GetCornerPos(rp.rect.ContractedBy(1), i); GenSpawn.Spawn(thing5, loc, map); } //Bring in MERF Lord singlePawnLord = rp.singlePawnLord ?? LordMaker.MakeNewLord(rp.faction, new LordJob_DefendBase(rp.faction, rp.rect.CenterCell), map, null); ResolveParams resolveParams = rp; resolveParams.rect = rp.rect.ExpandedBy(1); resolveParams.faction = rp.faction; resolveParams.singlePawnLord = singlePawnLord; resolveParams.pawnGroupKindDef = CthulhuFactionsDefOf.ROM_AgencyMERF; float points = 10000; resolveParams.pawnGroupMakerParams = new PawnGroupMakerParms(); resolveParams.pawnGroupMakerParams.tile = map.Tile; resolveParams.pawnGroupMakerParams.faction = rp.faction; resolveParams.pawnGroupMakerParams.points = points; BaseGen.symbolStack.Push("pawnGroup", resolveParams); }
public override void PassingParameters(ResolveParams rp) { string defChair = "DiningChair"; string defLamp = "Jecrell_GasLamp"; ThingDef lampDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDef.Named(defLamp) : ThingDefOf.TorchLamp; ThingDef lampStuffDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDefOf.Steel : null; Map map = BaseGen.globalSettings.map; bool @bool = Rand.Bool; bool hasLamp = false; ThingDef thingDef = ThingDefOf.Bed; ThingDef chairDef = ThingDef.Named(defChair); foreach (IntVec3 current in rp.rect) { if (@bool) { if (current.x % 3 != 0 || current.z % 3 != 0) { continue; } } else if (current.x % 3 != 0 || current.z % 3 != 0) { continue; } Rot4 rot = (!@bool) ? Rot4.South : Rot4.West; if (!GenSpawn.WouldWipeAnythingWith(current, rot, thingDef, map, (Thing x) => x.def.category == ThingCategory.Building)) { bool flag = false; foreach (IntVec3 current2 in GenAdj.CellsOccupiedBy(current, rot, thingDef.Size)) { if (BaseGenUtility.AnyDoorAdjacentCardinalTo(current2, map)) { flag = true; break; } } if (!flag) { ///Bed ThingDef stuff = null; if (thingDef.MadeFromStuff) { stuff = ThingDefOf.WoodLog; } Thing thing = ThingMaker.MakeThing(thingDef, stuff); thing.SetFaction(rp.faction, null); GenSpawn.Spawn(thing, current, map, rot); if (thing != null) { if (thing.Spawned && thing.Position.InBounds(map)) { CellRect thingRect = thing.OccupiedRect(); if (thingRect != null) { thingRect = thingRect.ExpandedBy(1); List <IntVec3> possibleCells = new List <IntVec3>(); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.North)); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.South)); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.East)); possibleCells.AddRange(thingRect.GetEdgeCells(Rot4.West)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 0)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 1)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 2)); possibleCells.Remove(Cthulhu.Utility.GetCornerPos(thingRect, 3)); IntVec3 spawnPos = IntVec3.Invalid; spawnPos = possibleCells.FirstOrDefault((IntVec3 x) => x.InBounds(map) && x.Walkable(map)); if (spawnPos != null) { possibleCells.Remove(spawnPos); Thing thing2 = ThingMaker.MakeThing(chairDef, stuff); thing2.SetFaction(rp.faction, null); GenSpawn.Spawn(thing2, spawnPos, map, rot.Opposite); } if (!hasLamp) { hasLamp = true; spawnPos = possibleCells.FirstOrDefault((IntVec3 x) => x.InBounds(map) && x.Walkable(map)); if (spawnPos != null) { possibleCells.Remove(spawnPos); Thing thing3 = ThingMaker.MakeThing(lampDef, lampStuffDef); thing3.SetFaction(rp.faction, null); GenSpawn.Spawn(thing3, spawnPos, map, rot.Opposite); } } } } } } } } //List<int> corners = new List<int>() { 0, 1, 2, 3 }; //foreach (int corner in corners.InRandomOrder<int>()) //{ // IntVec3 loc = Cthulhu.Utility.GetCornerPos(rp.rect.ContractedBy(1), corner); // if (!GenSpawn.WouldWipeAnythingWith(loc, Rot4.South, lampDef, map, (Thing x) => x.def.category == ThingCategory.Building)) // { // ThingDef singleThingDef3 = (Cthulhu.Utility.IsIndustrialAgeLoaded()) ? lampDef : ThingDefOf.TorchLamp; // Thing thing3 = ThingMaker.MakeThing(singleThingDef3, ThingDefOf.Steel); // GenSpawn.Spawn(thing3, loc, map); // break; // } //} }
public override void PassingParameters(ResolveParams paramsIn) { string defBench = "TableLong"; string defChair = "DiningChair"; string defLamp = "Jecrell_GasLamp"; ThingDef lampDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDef.Named(defLamp) : ThingDefOf.TorchLamp; ThingDef furnitureStuff = ThingDefOf.Steel; ThingDef lampStuffDef = Cthulhu.Utility.IsIndustrialAgeLoaded() ? ThingDefOf.Steel : null; ResolveParams rp = paramsIn; rp.rect = paramsIn.rect.ContractedBy(3); Map map = BaseGen.globalSettings.map; bool @bool = Rand.Bool; ThingDef thingDef = ThingDef.Named(defBench); ThingDef chairDef = ThingDef.Named(defChair); foreach (IntVec3 current in rp.rect) { if (@bool) { if (current.x % 4 != 0 || current.z % 4 != 0) { continue; } } else if (current.x % 4 != 0 || current.z % 4 != 0) { continue; } Rot4 rot = Rot4.Random; if (!GenSpawn.WouldWipeAnythingWith(current, rot, thingDef, map, (Thing x) => x.def.category == ThingCategory.Building)) { bool flag = false; foreach (IntVec3 current2 in GenAdj.CellsOccupiedBy(current, rot, thingDef.Size)) { if (BaseGenUtility.AnyDoorAdjacentCardinalTo(current2, map)) { flag = true; break; } } if (!flag) { ///TABLE ThingDef stuff = null; if (thingDef.MadeFromStuff) { stuff = furnitureStuff; } Thing thing = ThingMaker.MakeThing(thingDef, stuff); thing.SetFaction(rp.faction, null); GenSpawn.Spawn(thing, current, map, rot); if (thing != null) { if (thing.Spawned && thing.Position.InBounds(map)) { CellRect rectToEdit = thing.OccupiedRect().ExpandedBy(1); List <IntVec3> poss = new List <IntVec3>(); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.North)); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.South)); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.East)); poss.AddRange(rectToEdit.GetEdgeCells(Rot4.West)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 0)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 1)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 2)); poss.Remove(Cthulhu.Utility.GetCornerPos(rectToEdit, 3)); for (int i = 0; i < 4; i++) { ///CHAIR IntVec3 currentPos = poss.InRandomOrder <IntVec3>().RandomElement <IntVec3>(); poss.Remove(currentPos); Rot4 newRot = Rot4.North; if (currentPos.x > thing.Position.x) { newRot = Rot4.West; } else if (currentPos.x < thing.Position.x) { newRot = Rot4.East; } else if (currentPos.z > thing.Position.z) { newRot = Rot4.South; } else { newRot = Rot4.North; } Building bld = thing as Building; //We need an interaction cell Thing thing2 = ThingMaker.MakeThing(chairDef, stuff); thing2.SetFaction(rp.faction, null); GenSpawn.Spawn(thing2, currentPos, map, newRot); } } } } } } List <int> corners = new List <int>() { 0, 1, 2, 3 }; int count = 0; foreach (int corner in corners.InRandomOrder <int>()) { if (count == 1) { break; } IntVec3 loc = Cthulhu.Utility.GetCornerPos(paramsIn.rect.ContractedBy(1), corner); if (!GenSpawn.WouldWipeAnythingWith(loc, Rot4.South, lampDef, map, (Thing x) => x.def.category == ThingCategory.Building)) { ThingDef singleThingDef3 = (Cthulhu.Utility.IsIndustrialAgeLoaded()) ? lampDef : ThingDefOf.TorchLamp; Thing thing3 = ThingMaker.MakeThing(singleThingDef3, lampStuffDef); GenSpawn.Spawn(thing3, loc, map); } count++; } }
public static CellRect FindBiggestRectAt(IntVec3 c, CellRect outerRect, Sketch sketch, HashSet <IntVec3> processed, Predicate <IntVec3> canTraverse) { if (processed.Contains(c) || !canTraverse(c)) { return(CellRect.Empty); } CellRect result = CellRect.SingleCell(c); bool flag; do { flag = false; if (result.maxX < outerRect.maxX) { bool flag2 = false; foreach (IntVec3 edgeCell in result.GetEdgeCells(Rot4.East)) { IntVec3 current = edgeCell; current.x++; if (processed.Contains(current) || !canTraverse(current)) { flag2 = true; break; } } if (!flag2) { result.maxX++; flag = true; } } if (result.minX > outerRect.minX) { bool flag3 = false; foreach (IntVec3 edgeCell2 in result.GetEdgeCells(Rot4.West)) { IntVec3 current2 = edgeCell2; current2.x--; if (processed.Contains(current2) || !canTraverse(current2)) { flag3 = true; break; } } if (!flag3) { result.minX--; flag = true; } } if (result.maxZ < outerRect.maxZ) { bool flag4 = false; foreach (IntVec3 edgeCell3 in result.GetEdgeCells(Rot4.North)) { IntVec3 current3 = edgeCell3; current3.z++; if (processed.Contains(current3) || !canTraverse(current3)) { flag4 = true; break; } } if (!flag4) { result.maxZ++; flag = true; } } if (result.minZ > outerRect.minZ) { bool flag5 = false; foreach (IntVec3 edgeCell4 in result.GetEdgeCells(Rot4.South)) { IntVec3 current4 = edgeCell4; current4.z--; if (processed.Contains(current4) || !canTraverse(current4)) { flag5 = true; break; } } if (!flag5) { result.minZ--; flag = true; } } }while (flag); foreach (IntVec3 item in result) { processed.Add(item); } return(result); }