public static void Refund(Thing thing, Map map, CellRect avoidThisRect) { bool flag = false; if (thing.def.Minifiable) { MinifiedThing minifiedThing = thing.MakeMinified(); if (GenPlace.TryPlaceThing(minifiedThing, thing.Position, map, ThingPlaceMode.Near, null, (IntVec3 x) => !avoidThisRect.Contains(x))) { flag = true; } else { minifiedThing.GetDirectlyHeldThings().Clear(); minifiedThing.Destroy(DestroyMode.Vanish); } } if (!flag) { GenLeaving.DoLeavingsFor(thing, map, DestroyMode.Refund, thing.OccupiedRect(), (IntVec3 x) => !avoidThisRect.Contains(x)); thing.Destroy(DestroyMode.Vanish); } }
public static Thing Spawn(Thing newThing, IntVec3 loc, Map map, Rot4 rot, WipeMode wipeMode = WipeMode.Vanish, bool respawningAfterLoad = false) { Thing result; if (map == null) { Log.Error("Tried to spawn " + newThing.ToStringSafe <Thing>() + " in a null map.", false); result = null; } else if (!loc.InBounds(map)) { Log.Error(string.Concat(new object[] { "Tried to spawn ", newThing.ToStringSafe <Thing>(), " out of bounds at ", loc, "." }), false); result = null; } else { if (newThing.def.randomizeRotationOnSpawn) { rot = Rot4.Random; } CellRect occupiedRect = GenAdj.OccupiedRect(loc, rot, newThing.def.Size); if (!occupiedRect.InBounds(map)) { Log.Error(string.Concat(new object[] { "Tried to spawn ", newThing.ToStringSafe <Thing>(), " out of bounds at ", loc, " (out of bounds because size is ", newThing.def.Size, ")." }), false); result = null; } else if (newThing.Spawned) { Log.Error("Tried to spawn " + newThing + " but it's already spawned.", false); result = newThing; } else { if (wipeMode == WipeMode.Vanish) { GenSpawn.WipeExistingThings(loc, rot, newThing.def, map, DestroyMode.Vanish); } else if (wipeMode == WipeMode.FullRefund) { GenSpawn.WipeAndRefundExistingThings(loc, rot, newThing.def, map); } if (newThing.def.category == ThingCategory.Item) { foreach (IntVec3 intVec in occupiedRect) { foreach (Thing thing in intVec.GetThingList(map).ToList <Thing>()) { if (thing != newThing) { if (thing.def.category == ThingCategory.Item) { thing.DeSpawn(DestroyMode.Vanish); if (!GenPlace.TryPlaceThing(thing, intVec, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x))) { thing.Destroy(DestroyMode.Vanish); } } } } } } newThing.Rotation = rot; newThing.Position = loc; if (newThing.holdingOwner != null) { newThing.holdingOwner.Remove(newThing); } newThing.SpawnSetup(map, respawningAfterLoad); if (newThing.Spawned && newThing.stackCount == 0) { Log.Error("Spawned thing with 0 stackCount: " + newThing, false); newThing.Destroy(DestroyMode.Vanish); result = null; } else { if (newThing.def.passability == Traversability.Impassable) { foreach (IntVec3 c in occupiedRect) { foreach (Thing thing2 in c.GetThingList(map).ToList <Thing>()) { if (thing2 != newThing) { Pawn pawn = thing2 as Pawn; if (pawn != null) { pawn.pather.TryRecoverFromUnwalkablePosition(false); } } } } } result = newThing; } } } return(result); }
public static Thing Spawn(Thing newThing, IntVec3 loc, Map map, Rot4 rot, WipeMode wipeMode = WipeMode.Vanish, bool respawningAfterLoad = false) { if (map == null) { Log.Error("Tried to spawn " + newThing.ToStringSafe() + " in a null map."); return(null); } if (!loc.InBounds(map)) { Log.Error("Tried to spawn " + newThing.ToStringSafe() + " out of bounds at " + loc + "."); return(null); } if (newThing.def.randomizeRotationOnSpawn) { rot = Rot4.Random; } CellRect occupiedRect = GenAdj.OccupiedRect(loc, rot, newThing.def.Size); if (!occupiedRect.InBounds(map)) { Log.Error("Tried to spawn " + newThing.ToStringSafe() + " out of bounds at " + loc + " (out of bounds because size is " + newThing.def.Size + ")."); return(null); } if (newThing.Spawned) { Log.Error("Tried to spawn " + newThing + " but it's already spawned."); return(newThing); } switch (wipeMode) { case WipeMode.Vanish: WipeExistingThings(loc, rot, newThing.def, map, DestroyMode.Vanish); break; case WipeMode.FullRefund: WipeAndRefundExistingThings(loc, rot, newThing.def, map); break; case WipeMode.VanishOrMoveAside: CheckMoveItemsAside(loc, rot, newThing.def, map); WipeExistingThings(loc, rot, newThing.def, map, DestroyMode.Vanish); break; } if (newThing.def.category == ThingCategory.Item) { foreach (IntVec3 item in occupiedRect) { foreach (Thing item2 in item.GetThingList(map).ToList()) { if (item2 != newThing && item2.def.category == ThingCategory.Item) { item2.DeSpawn(); if (!GenPlace.TryPlaceThing(item2, item, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x))) { item2.Destroy(); } } } } } newThing.Rotation = rot; newThing.Position = loc; if (newThing.holdingOwner != null) { newThing.holdingOwner.Remove(newThing); } newThing.SpawnSetup(map, respawningAfterLoad); if (newThing.Spawned && newThing.stackCount == 0) { Log.Error("Spawned thing with 0 stackCount: " + newThing); newThing.Destroy(); return(null); } if (newThing.def.passability == Traversability.Impassable) { foreach (IntVec3 item3 in occupiedRect) { foreach (Thing item4 in item3.GetThingList(map).ToList()) { if (item4 != newThing) { (item4 as Pawn)?.pather.TryRecoverFromUnwalkablePosition(error: false); } } } return(newThing); } return(newThing); }
public static void CheckMoveItemsAside(IntVec3 thingPos, Rot4 thingRot, ThingDef thingDef, Map map) { if (thingDef.surfaceType == SurfaceType.None && thingDef.passability != 0) { CellRect occupiedRect = GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size); foreach (IntVec3 item in occupiedRect) { foreach (Thing item2 in item.GetThingList(map).ToList()) { if (item2.def.category == ThingCategory.Item) { item2.DeSpawn(); if (!GenPlace.TryPlaceThing(item2, item, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x))) { item2.Destroy(); } } } } } }
public static void WipeAndRefundExistingThings(IntVec3 thingPos, Rot4 thingRot, BuildableDef thingDef, Map map) { CellRect occupiedRect = GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size); foreach (IntVec3 item in occupiedRect) { foreach (Thing item2 in item.GetThingList(map).ToList()) { if (SpawningWipes(thingDef, item2.def)) { if (item2.def.category == ThingCategory.Item) { item2.DeSpawn(); if (!GenPlace.TryPlaceThing(item2, item, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x))) { item2.Destroy(); } } else { Refund(item2, map, occupiedRect); } } } } }
public static FloodUnfogResult FloodUnfog(IntVec3 root, Map map) { FloodFillerFog.cellsToUnfog.Clear(); FloodUnfogResult result = default(FloodUnfogResult); bool[] fogGridDirect = map.fogGrid.fogGrid; FogGrid fogGrid = map.fogGrid; List <IntVec3> newlyUnfoggedCells = new List <IntVec3>(); int numUnfogged = 0; bool expanding = false; CellRect viewRect = CellRect.ViewRect(map); result.allOnScreen = true; Predicate <IntVec3> predicate = delegate(IntVec3 c) { if (!fogGridDirect[map.cellIndices.CellToIndex(c)]) { return(false); } Thing edifice = c.GetEdifice(map); return((edifice == null || !edifice.def.MakeFog) && (!FloodFillerFog.testMode || expanding || numUnfogged <= 500)); }; Action <IntVec3> processor = delegate(IntVec3 c) { fogGrid.Unfog(c); newlyUnfoggedCells.Add(c); List <Thing> thingList = c.GetThingList(map); for (int l = 0; l < thingList.Count; l++) { Pawn pawn = thingList[l] as Pawn; if (pawn != null) { pawn.mindState.Active = true; if (pawn.def.race.IsMechanoid) { result.mechanoidFound = true; } } } if (!viewRect.Contains(c)) { result.allOnScreen = false; } result.cellsUnfogged++; if (FloodFillerFog.testMode) { numUnfogged++; map.debugDrawer.FlashCell(c, (float)numUnfogged / 200f, numUnfogged.ToStringCached(), 50); } }; map.floodFiller.FloodFill(root, predicate, processor, 2147483647, false, null); expanding = true; for (int i = 0; i < newlyUnfoggedCells.Count; i++) { IntVec3 a = newlyUnfoggedCells[i]; for (int j = 0; j < 8; j++) { IntVec3 intVec = a + GenAdj.AdjacentCells[j]; if (intVec.InBounds(map) && fogGrid.IsFogged(intVec)) { if (!predicate(intVec)) { FloodFillerFog.cellsToUnfog.Add(intVec); } } } } for (int k = 0; k < FloodFillerFog.cellsToUnfog.Count; k++) { fogGrid.Unfog(FloodFillerFog.cellsToUnfog[k]); if (FloodFillerFog.testMode) { map.debugDrawer.FlashCell(FloodFillerFog.cellsToUnfog[k], 0.3f, "x", 50); } } FloodFillerFog.cellsToUnfog.Clear(); return(result); }
private static void DropRoofInCellPhaseTwo(IntVec3 c, Map map) { RoofDef roofDef = map.roofGrid.RoofAt(c); if (roofDef != null) { if (roofDef.filthLeaving != null) { FilthMaker.TryMakeFilth(c, map, roofDef.filthLeaving); } if (roofDef.VanishOnCollapse) { map.roofGrid.SetRoof(c, null); } CellRect bound = CellRect.CenteredOn(c, 2); foreach (Pawn item in map.mapPawns.AllPawnsSpawned.Where((Pawn pawn) => bound.Contains(pawn.Position))) { TaleRecorder.RecordTale(TaleDefOf.CollapseDodged, item); } } }
public static bool LineOfSight(IntVec3 start, IntVec3 end, Map map, CellRect startRect, CellRect endRect, Func <IntVec3, bool> validator = null) { if (!start.InBounds(map) || !end.InBounds(map)) { return(false); } bool flag; if (start.x == end.x) { flag = (start.z < end.z); } else { flag = (start.x < end.x); } int num = Mathf.Abs(end.x - start.x); int num2 = Mathf.Abs(end.z - start.z); int num3 = start.x; int num4 = start.z; int i = 1 + num + num2; int num5 = (end.x <= start.x) ? -1 : 1; int num6 = (end.z <= start.z) ? -1 : 1; int num7 = num - num2; num *= 2; num2 *= 2; IntVec3 intVec = default(IntVec3); while (i > 1) { intVec.x = num3; intVec.z = num4; if (endRect.Contains(intVec)) { return(true); } if (!startRect.Contains(intVec)) { if (!intVec.CanBeSeenOverFast(map)) { return(false); } if (validator != null && !validator(intVec)) { return(false); } } if (num7 > 0 || (num7 == 0 && flag)) { num3 += num5; num7 -= num2; } else { num4 += num6; num7 += num; } i--; } return(true); }
public static void WipeAndRefundExistingThings(IntVec3 thingPos, Rot4 thingRot, BuildableDef thingDef, Map map) { CellRect occupiedRect = GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size); foreach (IntVec3 intVec in occupiedRect) { foreach (Thing thing in intVec.GetThingList(map).ToList <Thing>()) { if (GenSpawn.SpawningWipes(thingDef, thing.def)) { if (thing.def.category == ThingCategory.Item) { thing.DeSpawn(DestroyMode.Vanish); if (!GenPlace.TryPlaceThing(thing, intVec, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x))) { thing.Destroy(DestroyMode.Vanish); } } else { GenSpawn.Refund(thing, map, occupiedRect); } } } } }