private IntVec3 FindBestSpawnCellForNonItem(CellRect rect, ThingDef thingDef, Rot4 rot, out bool hasToWipeBuilding, out bool doesntFit) { Map map = BaseGen.globalSettings.map; if (thingDef.category == ThingCategory.Building) { foreach (IntVec3 item in rect.Cells.InRandomOrder()) { CellRect rect2 = GenAdj.OccupiedRect(item, rot, thingDef.size); if (rect2.FullyContainedWithin(rect) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(rect2, map) && !AnyNonStandableCellOrAnyBuildingInside(rect2) && GenConstruct.TerrainCanSupport(rect2, map, thingDef)) { hasToWipeBuilding = false; doesntFit = false; return(item); } } foreach (IntVec3 item2 in rect.Cells.InRandomOrder()) { CellRect rect3 = GenAdj.OccupiedRect(item2, rot, thingDef.size); if (rect3.FullyContainedWithin(rect) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(rect3, map) && !AnyNonStandableCellOrAnyBuildingInside(rect3)) { hasToWipeBuilding = false; doesntFit = false; return(item2); } } } foreach (IntVec3 item3 in rect.Cells.InRandomOrder()) { CellRect rect4 = GenAdj.OccupiedRect(item3, rot, thingDef.size); if (rect4.FullyContainedWithin(rect) && !AnyNonStandableCellOrAnyBuildingInside(rect4)) { hasToWipeBuilding = false; doesntFit = false; return(item3); } } foreach (IntVec3 item4 in rect.Cells.InRandomOrder()) { if (GenAdj.OccupiedRect(item4, rot, thingDef.size).FullyContainedWithin(rect)) { hasToWipeBuilding = true; doesntFit = false; return(item4); } } IntVec3 centerCell = rect.CenterCell; CellRect cellRect = GenAdj.OccupiedRect(centerCell, rot, thingDef.size); if (cellRect.minX < 0) { centerCell.x += -cellRect.minX; } if (cellRect.minZ < 0) { centerCell.z += -cellRect.minZ; } if (cellRect.maxX >= map.Size.x) { centerCell.x -= cellRect.maxX - map.Size.x + 1; } if (cellRect.maxZ >= map.Size.z) { centerCell.z -= cellRect.maxZ - map.Size.z + 1; } hasToWipeBuilding = true; doesntFit = true; return(centerCell); }
private bool TryFindRandomInnerRectTouchingEdge(CellRect rect, out CellRect mortarRect) { Map map = BaseGen.globalSettings.map; IntVec2 size = new IntVec2(3, 3); if (rect.TryFindRandomInnerRectTouchingEdge(size, out mortarRect, (Predicate <CellRect>)((CellRect x) => x.Cells.All((IntVec3 y) => y.Standable(map) && y.GetEdifice(map) == null) && GenConstruct.TerrainCanSupport(x, map, ThingDefOf.Turret_Mortar)))) { return(true); } if (rect.TryFindRandomInnerRectTouchingEdge(size, out mortarRect, (Predicate <CellRect>)((CellRect x) => x.Cells.All((IntVec3 y) => y.Standable(map) && y.GetEdifice(map) == null)))) { return(true); } return(false); }
// RimWorld.BaseGen.SymbolResolver_SingleThing private static IntVec3 FindBestSpawnCellForNonItem(Map map, CellRect rect, ThingDef thingDef, Rot4 rot, out bool hasToWipeBuilding, out bool doesntFit) { if (thingDef.category == ThingCategory.Building) { foreach (IntVec3 current in rect.Cells.InRandomOrder(null)) { CellRect rect2 = GenAdj.OccupiedRect(current, rot, thingDef.size); if (rect2.FullyContainedWithin(rect) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(rect2, map) && !RunwayUtility.AnyNonStandableCellOrAnyBuildingInside(map, rect2) && GenConstruct.TerrainCanSupport(rect2, map, thingDef)) { hasToWipeBuilding = false; doesntFit = false; IntVec3 result = current; return(result); } } foreach (IntVec3 current2 in rect.Cells.InRandomOrder(null)) { CellRect rect3 = GenAdj.OccupiedRect(current2, rot, thingDef.size); if (rect3.FullyContainedWithin(rect) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(rect3, map) && !RunwayUtility.AnyNonStandableCellOrAnyBuildingInside(map, rect3)) { hasToWipeBuilding = false; doesntFit = false; IntVec3 result = current2; return(result); } } } foreach (IntVec3 current3 in rect.Cells.InRandomOrder(null)) { CellRect rect4 = GenAdj.OccupiedRect(current3, rot, thingDef.size); if (rect4.FullyContainedWithin(rect) && !RunwayUtility.AnyNonStandableCellOrAnyBuildingInside(map, rect4)) { hasToWipeBuilding = false; doesntFit = false; IntVec3 result = current3; return(result); } } foreach (IntVec3 current4 in rect.Cells.InRandomOrder(null)) { if (GenAdj.OccupiedRect(current4, rot, thingDef.size).FullyContainedWithin(rect)) { hasToWipeBuilding = true; doesntFit = false; IntVec3 result = current4; return(result); } } IntVec3 centerCell = rect.CenterCell; CellRect cellRect = GenAdj.OccupiedRect(centerCell, rot, thingDef.size); if (cellRect.minX < 0) { centerCell.x += -cellRect.minX; } if (cellRect.minZ < 0) { centerCell.z += -cellRect.minZ; } if (cellRect.maxX >= map.Size.x) { centerCell.x -= cellRect.maxX - map.Size.x + 1; } if (cellRect.maxZ >= map.Size.z) { centerCell.z -= cellRect.maxZ - map.Size.z + 1; } hasToWipeBuilding = true; doesntFit = true; return(centerCell); }
private bool TryFindSpawnCell(CellRect rect, ThingDef thingDef, Rot4 rot, out IntVec3 spawnCell) { Map map = BaseGen.globalSettings.map; IntVec3 zero = IntVec3.Zero; IntVec2 size = thingDef.size; GenAdj.AdjustForRotation(ref zero, ref size, rot); CellRect empty = CellRect.Empty; Predicate <CellRect> basePredicate = delegate(CellRect x) { int arg_83_0; if (x.Cells.All((IntVec3 y) => y.Standable(map))) { if (!GenSpawn.WouldWipeAnythingWith(x, thingDef, map, (Thing z) => z.def.category == ThingCategory.Building)) { arg_83_0 = ((thingDef.category != ThingCategory.Item || x.CenterCell.GetFirstItem(map) == null) ? 1 : 0); return(arg_83_0 != 0); } } arg_83_0 = 0; return(arg_83_0 != 0); }; bool flag = false; if (thingDef.category == ThingCategory.Building) { flag = rect.TryFindRandomInnerRectTouchingEdge(size, out empty, (CellRect x) => basePredicate(x) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(x, map) && GenConstruct.TerrainCanSupport(x, map, thingDef)); if (!flag) { flag = rect.TryFindRandomInnerRectTouchingEdge(size, out empty, (CellRect x) => basePredicate(x) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(x, map)); } } if (!flag && !rect.TryFindRandomInnerRectTouchingEdge(size, out empty, basePredicate)) { spawnCell = IntVec3.Invalid; return(false); } CellRect.CellRectIterator iterator = empty.GetIterator(); while (!iterator.Done()) { if (GenAdj.OccupiedRect(iterator.Current, rot, thingDef.size) == empty) { spawnCell = iterator.Current; return(true); } iterator.MoveNext(); } Log.Error("We found a valid rect but we couldn't find the root position. This should never happen.", false); spawnCell = IntVec3.Invalid; return(false); }
private bool TryFindSpawnCell(CellRect rect, ThingDef thingDef, Rot4 rot, bool mustReachMapEdge, out IntVec3 spawnCell) { Map map = BaseGen.globalSettings.map; IntVec3 center = IntVec3.Zero; IntVec2 size = thingDef.size; GenAdj.AdjustForRotation(ref center, ref size, rot); CellRect rect2 = CellRect.Empty; TraverseParms traverseParms = TraverseParms.For(TraverseMode.PassDoors); Predicate <CellRect> basePredicate = (CellRect x) => x.Cells.All((IntVec3 y) => y.Standable(map)) && !GenSpawn.WouldWipeAnythingWith(x, thingDef, map, (Thing z) => z.def.category == ThingCategory.Building) && (thingDef.category != ThingCategory.Item || x.CenterCell.GetFirstItem(map) == null) && (!mustReachMapEdge || map.reachability.CanReachMapEdge(x.CenterCell, traverseParms)); bool flag = false; if (thingDef.category == ThingCategory.Building) { flag = rect.TryFindRandomInnerRectTouchingEdge(size, out rect2, (CellRect x) => basePredicate(x) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(x, map) && GenConstruct.TerrainCanSupport(x, map, thingDef)); if (!flag) { flag = rect.TryFindRandomInnerRectTouchingEdge(size, out rect2, (CellRect x) => basePredicate(x) && !BaseGenUtility.AnyDoorAdjacentCardinalTo(x, map)); } } if (!flag && !rect.TryFindRandomInnerRectTouchingEdge(size, out rect2, basePredicate)) { spawnCell = IntVec3.Invalid; return(false); } foreach (IntVec3 item in rect2) { if (GenAdj.OccupiedRect(item, rot, thingDef.size) == rect2) { spawnCell = item; return(true); } } Log.Error("We found a valid rect but we couldn't find the root position. This should never happen."); spawnCell = IntVec3.Invalid; return(false); }