// Token: 0x06000014 RID: 20 RVA: 0x0000339C File Offset: 0x0000159C private IntVec3 TryFindValidScatterCellNear(IntVec3 loc, MapGeneratorBlueprintDef blueprint, Map map, List <IntVec3> invalidCells) { IntVec3 result; if (usedCells.Count == 0) { result = loc; } else { var size = blueprint.size; var mapCenterBlueprint = blueprint.mapCenterBlueprint; var i = 0; var num = 30; while (i < num) { if (!mapCenterBlueprint) { var intVec = new IntVec2(map.Size.x / 2, map.Size.z / 2); var cellRect = new CellRect(intVec.x, intVec.z, 1, 1); cellRect = cellRect.ExpandedBy(10); if (cellRect.Contains(loc)) { loc = new IntVec3(loc.x + 20, loc.y, loc.z - 20); } } var num2 = Rand.RangeInclusive(0, 7); var intVec2 = IntVec3.Invalid; foreach (var intVec3 in usedCells) { switch (num2) { case 0: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z > intVec2.z ? intVec3 : intVec2; break; case 1: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z > intVec2.z && intVec3.x > intVec2.x ? intVec3 : intVec2; break; case 2: intVec2 = intVec2 == IntVec3.Invalid || intVec3.x > intVec2.x ? intVec3 : intVec2; break; case 3: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z <intVec2.z && intVec3.x> intVec2.x ? intVec3 : intVec2; break; case 4: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z < intVec2.z ? intVec3 : intVec2; break; case 5: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z < intVec2.z && intVec3.x < intVec2.x ? intVec3 : intVec2; break; case 6: intVec2 = intVec2 == IntVec3.Invalid || intVec3.x < intVec2.x ? intVec3 : intVec2; break; case 7: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z > intVec2.z && intVec3.x < intVec2.x ? intVec3 : intVec2; break; default: intVec2 = IntVec3.Invalid; break; } } if (intVec2 == IntVec3.Invalid) { return(IntVec3.Invalid); } var invalid = IntVec3.Invalid; int num3; if (size.x > size.z) { num3 = size.x + Rand.RangeInclusive(1, 5); } else { num3 = size.z + Rand.RangeInclusive(1, 5); } switch (num2) { case 0: invalid = new IntVec3(0, 0, num3); intVec2 += invalid; break; case 1: invalid = new IntVec3(num3, 0, num3); intVec2 += invalid; break; case 2: invalid = new IntVec3(num3, 0, 0); intVec2 += invalid; break; case 3: invalid = new IntVec3(num3, 0, -num3 - (int)ruinOffsetVerticalRange.Average); intVec2 += invalid; break; case 4: invalid = new IntVec3(0, 0, -num3 - (int)ruinOffsetVerticalRange.Average); intVec2 += invalid; break; case 5: invalid = new IntVec3(-num3 - (int)ruinOffsetHorizontalRange.Average, 0, -num3 - (int)ruinOffsetVerticalRange.Average); intVec2 += invalid; break; case 6: invalid = new IntVec3(-num3 - (int)ruinOffsetHorizontalRange.Average, 0, 0); intVec2 += invalid; break; case 7: invalid = new IntVec3(-num3 - (int)ruinOffsetHorizontalRange.Average, 0, num3); intVec2 += invalid; break; default: intVec2 = IntVec3.Invalid; break; } var isValid = invalid.IsValid; if (isValid) { if (Math.Abs(invalid.x) / 2 < ruinDistanceRange.max && Math.Abs(invalid.z) / 2 < ruinDistanceRange.max) { if (Math.Abs(invalid.x) > Math.Abs(invalid.z)) { ruinDistanceRange.min = Math.Abs(invalid.x) / 2; } else { ruinDistanceRange.min = Math.Abs(invalid.z) / 2; } if (ruinDistanceRange.min > ruinDistanceRange.max) { ruinDistanceRange.max = ruinDistanceRange.min; } } } if (intVec2.InBounds(map) && CanScatterAt(intVec2, map) && IsPositionValidForBlueprint(intVec2, size, invalidCells)) { return(intVec2); } i++; } result = IntVec3.Invalid; } return(result); }
private void GenerateRiverLookupTexture(Map map, RiverMaker riverMaker) { int num = Mathf.CeilToInt((from rd in DefDatabase <RiverDef> .AllDefs select(float)(rd.widthOnMap / 2.0 + 5.0)).Max()); int num2 = Mathf.Max(4, num) * 2; Dictionary <int, GRLT_Entry> dictionary = new Dictionary <int, GRLT_Entry>(); Dictionary <int, GRLT_Entry> dictionary2 = new Dictionary <int, GRLT_Entry>(); Dictionary <int, GRLT_Entry> dictionary3 = new Dictionary <int, GRLT_Entry>(); int num3 = -num2; while (true) { int num4 = num3; IntVec3 size = map.Size; if (num4 < size.z + num2) { int num5 = -num2; while (true) { int num6 = num5; IntVec3 size2 = map.Size; if (num6 < size2.x + num2) { IntVec3 intVec = new IntVec3(num5, 0, num3); Vector3 vector = riverMaker.WaterCoordinateAt(intVec); int entryId = Mathf.FloorToInt((float)(vector.z / 4.0)); this.UpdateRiverAnchorEntry(dictionary, intVec, entryId, (float)((vector.z + Mathf.Abs(vector.x)) / 4.0)); this.UpdateRiverAnchorEntry(dictionary2, intVec, entryId, (float)((vector.z + Mathf.Abs(vector.x - (float)num)) / 4.0)); this.UpdateRiverAnchorEntry(dictionary3, intVec, entryId, (float)((vector.z + Mathf.Abs(vector.x + (float)num)) / 4.0)); num5++; continue; } break; } num3++; continue; } break; } int num7 = Mathf.Max(dictionary.Keys.Min(), dictionary2.Keys.Min(), dictionary3.Keys.Min()); int num8 = Mathf.Min(dictionary.Keys.Max(), dictionary2.Keys.Max(), dictionary3.Keys.Max()); for (int i = num7; i < num8; i++) { WaterInfo waterInfo = map.waterInfo; if (dictionary2.ContainsKey(i) && dictionary2.ContainsKey(i + 1)) { List <Vector3> riverDebugData = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry = dictionary2[i]; riverDebugData.Add(gRLT_Entry.bestNode.ToVector3Shifted()); List <Vector3> riverDebugData2 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry2 = dictionary2[i + 1]; riverDebugData2.Add(gRLT_Entry2.bestNode.ToVector3Shifted()); } if (dictionary.ContainsKey(i) && dictionary.ContainsKey(i + 1)) { List <Vector3> riverDebugData3 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry3 = dictionary[i]; riverDebugData3.Add(gRLT_Entry3.bestNode.ToVector3Shifted()); List <Vector3> riverDebugData4 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry4 = dictionary[i + 1]; riverDebugData4.Add(gRLT_Entry4.bestNode.ToVector3Shifted()); } if (dictionary3.ContainsKey(i) && dictionary3.ContainsKey(i + 1)) { List <Vector3> riverDebugData5 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry5 = dictionary3[i]; riverDebugData5.Add(gRLT_Entry5.bestNode.ToVector3Shifted()); List <Vector3> riverDebugData6 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry6 = dictionary3[i + 1]; riverDebugData6.Add(gRLT_Entry6.bestNode.ToVector3Shifted()); } if (dictionary2.ContainsKey(i) && dictionary.ContainsKey(i)) { List <Vector3> riverDebugData7 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry7 = dictionary2[i]; riverDebugData7.Add(gRLT_Entry7.bestNode.ToVector3Shifted()); List <Vector3> riverDebugData8 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry8 = dictionary[i]; riverDebugData8.Add(gRLT_Entry8.bestNode.ToVector3Shifted()); } if (dictionary.ContainsKey(i) && dictionary3.ContainsKey(i)) { List <Vector3> riverDebugData9 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry9 = dictionary[i]; riverDebugData9.Add(gRLT_Entry9.bestNode.ToVector3Shifted()); List <Vector3> riverDebugData10 = waterInfo.riverDebugData; GRLT_Entry gRLT_Entry10 = dictionary3[i]; riverDebugData10.Add(gRLT_Entry10.bestNode.ToVector3Shifted()); } } IntVec3 size3 = map.Size; int width = size3.x + 4; IntVec3 size4 = map.Size; CellRect cellRect = new CellRect(-2, -2, width, size4.z + 4); float[] array = new float[cellRect.Area * 2]; int num9 = 0; for (int j = cellRect.minZ; j <= cellRect.maxZ; j++) { for (int k = cellRect.minX; k <= cellRect.maxX; k++) { IntVec3 a = new IntVec3(k, 0, j); bool flag = true; int num10 = 0; while (num10 < GenAdj.AdjacentCellsAndInside.Length) { if (riverMaker.TerrainAt(a + GenAdj.AdjacentCellsAndInside[num10], false) == null) { num10++; continue; } flag = false; break; } if (!flag) { Vector2 p = a.ToIntVec2.ToVector2(); int num11 = -2147483648; Vector2 vector2 = Vector2.zero; for (int l = num7; l < num8; l++) { GRLT_Entry gRLT_Entry11 = dictionary2[l]; Vector2 p2 = gRLT_Entry11.bestNode.ToIntVec2.ToVector2(); GRLT_Entry gRLT_Entry12 = dictionary2[l + 1]; Vector2 p3 = gRLT_Entry12.bestNode.ToIntVec2.ToVector2(); GRLT_Entry gRLT_Entry13 = dictionary[l]; Vector2 p4 = gRLT_Entry13.bestNode.ToIntVec2.ToVector2(); GRLT_Entry gRLT_Entry14 = dictionary[l + 1]; Vector2 p5 = gRLT_Entry14.bestNode.ToIntVec2.ToVector2(); GRLT_Entry gRLT_Entry15 = dictionary3[l]; Vector2 p6 = gRLT_Entry15.bestNode.ToIntVec2.ToVector2(); GRLT_Entry gRLT_Entry16 = dictionary3[l + 1]; Vector2 p7 = gRLT_Entry16.bestNode.ToIntVec2.ToVector2(); Vector2 vector3 = GenGeo.InverseQuadBilinear(p, p4, p2, p5, p3); if (vector3.x >= -9.9999997473787516E-05 && vector3.x <= 1.0001000165939331 && vector3.y >= -9.9999997473787516E-05 && vector3.y <= 1.0001000165939331) { vector2 = new Vector2((float)((0.0 - vector3.x) * (float)num), (float)((vector3.y + (float)l) * 4.0)); num11 = l; break; } Vector2 vector4 = GenGeo.InverseQuadBilinear(p, p4, p6, p5, p7); if (vector4.x >= -9.9999997473787516E-05 && vector4.x <= 1.0001000165939331 && vector4.y >= -9.9999997473787516E-05 && vector4.y <= 1.0001000165939331) { vector2 = new Vector2(vector4.x * (float)num, (float)((vector4.y + (float)l) * 4.0)); num11 = l; break; } } if (num11 == -2147483648) { Log.ErrorOnce("Failed to find all necessary river flow data", 5273133); } array[num9] = vector2.x; array[num9 + 1] = vector2.y; } num9 += 2; } } float[] array2 = new float[cellRect.Area * 2]; float[] array3 = new float[9] { 0.123317f, 0.123317f, 0.123317f, 0.123317f, 0.077847f, 0.077847f, 0.077847f, 0.077847f, 0.195346f }; int num12 = 0; for (int m = cellRect.minZ; m <= cellRect.maxZ; m++) { for (int n = cellRect.minX; n <= cellRect.maxX; n++) { IntVec3 a2 = new IntVec3(n, 0, m); float num13 = 0f; float num14 = 0f; float num15 = 0f; for (int num16 = 0; num16 < GenAdj.AdjacentCellsAndInside.Length; num16++) { IntVec3 c = a2 + GenAdj.AdjacentCellsAndInside[num16]; if (cellRect.Contains(c)) { int num17 = num12 + (GenAdj.AdjacentCellsAndInside[num16].x + GenAdj.AdjacentCellsAndInside[num16].z * cellRect.Width) * 2; if (array.Length <= num17 + 1 || num17 < 0) { Log.Message("you wut"); } if (array[num17] != 0.0 || array[num17 + 1] != 0.0) { num13 += array[num17] * array3[num16]; num14 += array[num17 + 1] * array3[num16]; num15 += array3[num16]; } } } if (num15 > 0.0) { array2[num12] = num13 / num15; array2[num12 + 1] = num14 / num15; } num12 += 2; } } array = array2; for (int num18 = 0; num18 < array.Length; num18 += 2) { if (array[num18] != 0.0 || array[num18 + 1] != 0.0) { Vector3 vector5 = Rand.PointOnDisc * 0.4f; array[num18] += vector5.x; array[num18 + 1] += vector5.z; } } byte[] array4 = new byte[array.Length * 4]; Buffer.BlockCopy(array, 0, array4, 0, array.Length * 4); map.waterInfo.riverOffsetMap = array4; map.waterInfo.GenerateRiverFlowMap(); }
private void TryExpandSnow() { if (this.parent.Map.mapTemperature.OutdoorTemp > 10f) { this.snowRadius = 0f; return; } if (this.snowNoise == null) { this.snowNoise = new Perlin(0.054999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); } if (this.snowRadius < 8f) { this.snowRadius += 1.3f; } else if (this.snowRadius < 17f) { this.snowRadius += 0.7f; } else if (this.snowRadius < 30f) { this.snowRadius += 0.4f; } else { this.snowRadius += 0.1f; } this.snowRadius = Mathf.Min(this.snowRadius, this.Props.maxRadius); CellRect occupiedRect = this.parent.OccupiedRect(); CompSnowExpand.reachableCells.Clear(); this.parent.Map.floodFiller.FloodFill(this.parent.Position, (IntVec3 x) => (float)x.DistanceToSquared(this.parent.Position) <= this.snowRadius * this.snowRadius && (occupiedRect.Contains(x) || !x.Filled(this.parent.Map)), delegate(IntVec3 x) { CompSnowExpand.reachableCells.Add(x); }, int.MaxValue, false, null); int num = GenRadial.NumCellsInRadius(this.snowRadius); for (int i = 0; i < num; i++) { IntVec3 intVec = this.parent.Position + GenRadial.RadialPattern[i]; if (intVec.InBounds(this.parent.Map)) { if (CompSnowExpand.reachableCells.Contains(intVec)) { float num2 = this.snowNoise.GetValue(intVec); num2 += 1f; num2 *= 0.5f; if (num2 < 0.1f) { num2 = 0.1f; } if (this.parent.Map.snowGrid.GetDepth(intVec) <= num2) { float lengthHorizontal = (intVec - this.parent.Position).LengthHorizontal; float num3 = 1f - lengthHorizontal / this.snowRadius; this.parent.Map.snowGrid.AddDepth(intVec, num3 * this.Props.addAmount * num2); } } } } }
private static void RecalcRootLocY(ref Vector3 rootLoc, Pawn pawn, CompBodyAnimator compAnimator) { Vector3 loc = rootLoc; CellRect viewRect = Find.CameraDriver.CurrentViewRect; viewRect = viewRect.ExpandedBy(1); List <Pawn> pawns = new List <Pawn>(); foreach (Pawn otherPawn in pawn.Map.mapPawns.AllPawnsSpawned) { if (!viewRect.Contains(otherPawn.Position)) { continue; } if (otherPawn == pawn) { continue; } if (otherPawn.DrawPos.x < loc.x - 0.5f) { continue; } if (otherPawn.DrawPos.x > loc.x + 0.5f) { continue; } if (otherPawn.DrawPos.z >= loc.z) { continue; } // ignore above pawns.Add(otherPawn); } // pawns = pawn.Map.mapPawns.AllPawnsSpawned // .Where( // otherPawn => _viewRect.Contains(otherPawn.Position) && // otherPawn != pawn && // otherPawn.DrawPos.x >= loc.x - 1 && // otherPawn.DrawPos.x <= loc.x + 1 && // otherPawn.DrawPos.z <= loc.z).ToList(); // List<Pawn> leftOfPawn = pawns.Where(other => other.DrawPos.x <= loc.x).ToList(); bool flag = compAnimator != null; if (!pawns.NullOrEmpty()) { float pawnOffset = YOffsetPawns * pawns.Count; loc.y -= pawnOffset; if (flag) { compAnimator.DrawOffsetY = pawnOffset; } // loc.y -= 0.1f * leftOfPawn.Count; } else { if (flag) { compAnimator.DrawOffsetY = 0f; } } rootLoc = loc; }
private IEnumerable <IntVec3> GetSuggestedRoofCells() { if (!Empty) { CellRect occupiedRect = OccupiedRect; tmpSuggestedRoofCellsVisited.Clear(); tmpYieldedSuggestedRoofCells.Clear(); foreach (IntVec3 item in OccupiedRect) { if (!tmpSuggestedRoofCellsVisited.Contains(item) && !AnyRoofHolderAt(item)) { tmpSuggestedRoofCells.Clear(); FloodFill(item, (IntVec3 c) => !AnyRoofHolderAt(c), delegate(IntVec3 c, int dist) { tmpSuggestedRoofCellsVisited.Add(c); tmpSuggestedRoofCells.Add(c); return(false); }); bool flag = false; for (int k = 0; k < tmpSuggestedRoofCells.Count; k++) { if (occupiedRect.IsOnEdge(tmpSuggestedRoofCells[k])) { flag = true; break; } } if (!flag) { for (int j = 0; j < tmpSuggestedRoofCells.Count; j++) { for (int i = 0; i < 9; i++) { IntVec3 intVec = tmpSuggestedRoofCells[j] + GenAdj.AdjacentCellsAndInside[i]; if (!tmpYieldedSuggestedRoofCells.Contains(intVec) && occupiedRect.Contains(intVec) && (i == 8 || AnyRoofHolderAt(intVec))) { tmpYieldedSuggestedRoofCells.Add(intVec); yield return(intVec); } } } } } } tmpSuggestedRoofCellsVisited.Clear(); tmpYieldedSuggestedRoofCells.Clear(); } bool AnyRoofHolderAt(IntVec3 c) { return(EdificeAt(c)?.def.holdsRoof ?? false); } }
// Token: 0x060029C1 RID: 10689 RVA: 0x0013C434 File Offset: 0x0013A834 private void TryExpandGoo() { if (this.parent.Map.mapTemperature.OutdoorTemp > 50f) { this.hiveRadius = 0f; return; } if (this.snowNoise == null) { this.snowNoise = new Perlin(0.074999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); //new Perlin(0.054999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); } float z = (float)this.plantHarmAge / 60000f; float numf = this.Props.radiusPerDayCurve.Evaluate(z); this.hiveRadius = numf < this.maxRadius ? numf : this.maxRadius;// Mathf.Min(this.hiveRadius, this.maxRadius); // Log.Message(string.Format("hiveRadius: {0}", hiveRadius)); CellRect occupiedRect = this.parent.OccupiedRect(); CompGooSpread.reachableCells.Clear(); this.parent.Map.floodFiller.FloodFill(this.parent.Position, (IntVec3 x) => (float)x.DistanceToSquared(this.parent.Position) <= this.hiveRadius * this.hiveRadius && (occupiedRect.Contains(x) || !x.Filled(this.parent.Map) && x.InBounds(this.parent.Map)), delegate(IntVec3 x) { CompGooSpread.reachableCells.Add(x); }, int.MaxValue, false, null); // Log.Message(string.Format("2")); errors here V when greater than 56.4 ish int num = GenRadial.NumCellsInRadius(this.hiveRadius); // Log.Message(string.Format("3")); errors here ^ when greater than 56.4 ish for (int i = 0; i < num; i++) { if ((this.parent.Position + GenRadial.RadialPattern[i]).InBounds(this.parent.Map)) { IntVec3 intVec = this.parent.Position + GenRadial.RadialPattern[i]; if (intVec.InBounds(this.parent.Map)) { if (CompGooSpread.reachableCells.Contains(intVec)) { float num2 = this.snowNoise.GetValue(intVec); num2 += 1f; num2 *= 0.5f; if (num2 < 0.1f) { num2 = 0.1f; } float lengthHorizontal = this.parent.Position.DistanceTo(intVec); float num3 = 1f - (1 * (lengthHorizontal / this.hiveRadius)); this.parent.Map.GetComponent <MapComponent_GooGrid>().AddDepth(intVec, num3 * this.Props.addAmount /** num2*/); /* * if (this.parent.Map.GetComponent<MapComponent_GooGrid>().GetDepth(intVec) <= num2) * { * float lengthHorizontal = this.parent.Position.DistanceTo(intVec); * float num3 = 1f * lengthHorizontal / this.hiveRadius; * this.parent.Map.GetComponent<MapComponent_GooGrid>().AddDepth(intVec, num3 * this.Props.addAmount * num2); * } */ } } } } }
public static bool TryFindSpectatorCellFor(Pawn p, CellRect spectateRect, Map map, out IntVec3 cell, SpectateRectSide allowedSides = SpectateRectSide.All, int margin = 1, List <IntVec3> extraDisallowedCells = null) { spectateRect.ClipInsideMap(map); if (spectateRect.Area == 0 || allowedSides == SpectateRectSide.None) { cell = IntVec3.Invalid; return(false); } CellRect rectWithMargin = spectateRect.ExpandedBy(margin).ClipInsideMap(map); Predicate <IntVec3> predicate = delegate(IntVec3 x) { if (!x.InBounds(map)) { return(false); } if (!x.Standable(map)) { return(false); } if (x.Fogged(map)) { return(false); } if (rectWithMargin.Contains(x)) { return(false); } if ((x.z <= rectWithMargin.maxZ || (allowedSides & SpectateRectSide.Up) != SpectateRectSide.Up) && (x.x <= rectWithMargin.maxX || (allowedSides & SpectateRectSide.Right) != SpectateRectSide.Right) && (x.z >= rectWithMargin.minZ || (allowedSides & SpectateRectSide.Down) != SpectateRectSide.Down) && (x.x >= rectWithMargin.minX || (allowedSides & SpectateRectSide.Left) != SpectateRectSide.Left)) { return(false); } IntVec3 intVec3 = spectateRect.ClosestCellTo(x); if ((float)intVec3.DistanceToSquared(x) > 210.25f) { return(false); } if (!GenSight.LineOfSight(intVec3, x, map, true, null, 0, 0)) { return(false); } if (x.GetThingList(map).Find((Thing y) => y is Pawn && y != p) != null) { return(false); } if (p != null) { if (!p.CanReserveAndReach(x, PathEndMode.OnCell, Danger.Some, 1, -1, null, false)) { return(false); } Building edifice = x.GetEdifice(map); if (edifice != null && edifice.def.category == ThingCategory.Building && edifice.def.building.isSittable && !p.CanReserve(edifice, 1, -1, null, false)) { return(false); } if (x.IsForbidden(p)) { return(false); } if (x.GetDangerFor(p, map) != Danger.None) { return(false); } } if (extraDisallowedCells != null && extraDisallowedCells.Contains(x)) { return(false); } if (!SpectatorCellFinder.CorrectlyRotatedChairAt(x, map, spectateRect)) { int num = 0; for (int k = 0; k < GenAdj.AdjacentCells.Length; k++) { IntVec3 x2 = x + GenAdj.AdjacentCells[k]; if (SpectatorCellFinder.CorrectlyRotatedChairAt(x2, map, spectateRect)) { num++; } } if (num >= 3) { return(false); } int num2 = SpectatorCellFinder.DistanceToClosestChair(x, new IntVec3(-1, 0, 0), map, 4, spectateRect); if (num2 >= 0) { int num3 = SpectatorCellFinder.DistanceToClosestChair(x, new IntVec3(1, 0, 0), map, 4, spectateRect); if (num3 >= 0 && Mathf.Abs(num2 - num3) <= 1) { return(false); } } int num4 = SpectatorCellFinder.DistanceToClosestChair(x, new IntVec3(0, 0, 1), map, 4, spectateRect); if (num4 >= 0) { int num5 = SpectatorCellFinder.DistanceToClosestChair(x, new IntVec3(0, 0, -1), map, 4, spectateRect); if (num5 >= 0 && Mathf.Abs(num4 - num5) <= 1) { return(false); } } } return(true); }; if (p != null && predicate(p.Position) && SpectatorCellFinder.CorrectlyRotatedChairAt(p.Position, map, spectateRect)) { cell = p.Position; return(true); } for (int i = 0; i < 1000; i++) { IntVec3 intVec = rectWithMargin.CenterCell + GenRadial.RadialPattern[i]; if (predicate(intVec)) { if (!SpectatorCellFinder.CorrectlyRotatedChairAt(intVec, map, spectateRect)) { for (int j = 0; j < 90; j++) { IntVec3 intVec2 = intVec + GenRadial.RadialPattern[j]; if (SpectatorCellFinder.CorrectlyRotatedChairAt(intVec2, map, spectateRect) && predicate(intVec2)) { cell = intVec2; return(true); } } } cell = intVec; return(true); } } cell = IntVec3.Invalid; return(false); }
public static bool Spawn(ref Thing __result, 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 <Thing>() + " in a null map.", false); __result = (Thing)null; return(false); } if (!loc.InBounds(map)) { Log.Error("Tried to spawn " + newThing.ToStringSafe <Thing>() + " out of bounds at " + (object)loc + ".", false); __result = (Thing)null; return(false); } if (null != newThing) { if (null != newThing.def) { 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 <Thing>() + " out of bounds at " + (object)loc + " (out of bounds because size is " + (object)newThing.def.Size + ").", false); __result = (Thing)null; return(false); } if (newThing.Spawned) { Log.Error("Tried to spawn " + (object)newThing + " but it's already spawned.", false); __result = newThing; return(false); } switch (wipeMode) { case WipeMode.Vanish: GenSpawn.WipeExistingThings(loc, rot, (BuildableDef)newThing.def, map, DestroyMode.Vanish); break; case WipeMode.FullRefund: GenSpawn.WipeAndRefundExistingThings(loc, rot, (BuildableDef)newThing.def, map); break; case WipeMode.VanishOrMoveAside: GenSpawn.CheckMoveItemsAside(loc, rot, newThing.def, map); GenSpawn.WipeExistingThings(loc, rot, (BuildableDef)newThing.def, map, DestroyMode.Vanish); break; } if (newThing.def.category == ThingCategory.Item) { foreach (IntVec3 intVec3 in occupiedRect) { foreach (Thing thing in intVec3.GetThingList(map).ToList <Thing>()) { if (thing != newThing && thing.def.category == ThingCategory.Item) { thing.DeSpawn(DestroyMode.Vanish); if (!GenPlace.TryPlaceThing(thing, intVec3, map, ThingPlaceMode.Near, (Action <Thing, int>)null, (Predicate <IntVec3>)(x => !occupiedRect.Contains(x)), new Rot4())) { 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: " + (object)newThing, false); newThing.Destroy(DestroyMode.Vanish); __result = (Thing)null; return(false); } if (newThing.def.passability == Traversability.Impassable) { foreach (IntVec3 c in occupiedRect) { foreach (Thing thing in c.GetThingList(map).ToList <Thing>()) { if (thing != newThing && thing is Pawn pawn) { pawn.pather.TryRecoverFromUnwalkablePosition(false); } } } } } } __result = newThing; return(false); }
// This function may need some work... private IntVec3 TryFindValidScatterCellNear(IntVec3 loc, Map map, MapGeneratorBlueprintDef blueprint, HashSet <IntVec3> invalidCells) { if (usedCells.Count == 0) { return(loc); } IntVec2 size = blueprint.size; bool allowCenter = blueprint.mapCenterBlueprint; int searchTry = 0; int searchTriesMax = 30; while (searchTry < searchTriesMax) { if (!allowCenter) { // Check if the loc is near the spawn location -> move loc by +20, 0, -20 IntVec2 nogoCenter = new IntVec2(map.Size.x / 2, map.Size.z / 2); CellRect nogoCenterRect = new CellRect(nogoCenter.x, nogoCenter.z, 1, 1); nogoCenterRect = nogoCenterRect.ExpandedBy(10); if (nogoCenterRect.Contains(loc)) { loc = new IntVec3(loc.x + 20, loc.y, loc.z - 20); } } int placement = Rand.RangeInclusive(0, 7); // Find nearest used cell to the distance IntVec3 workCell = IntVec3.Invalid; foreach (IntVec3 cell in usedCells) { switch (placement) { case 0: // north workCell = workCell == IntVec3.Invalid || cell.z > workCell.z ? cell : workCell; break; case 1: // north-east workCell = workCell == IntVec3.Invalid || cell.z > workCell.z && cell.x > workCell.x ? cell : workCell; break; case 2: // east workCell = workCell == IntVec3.Invalid || cell.x > workCell.x ? cell : workCell; break; case 3: // south-east workCell = workCell == IntVec3.Invalid || cell.z <workCell.z && cell.x> workCell.x ? cell : workCell; break; case 4: // south workCell = workCell == IntVec3.Invalid || cell.z < workCell.z ? cell : workCell; break; case 5: // south-west workCell = workCell == IntVec3.Invalid || cell.z < workCell.z && cell.x < workCell.x ? cell : workCell; break; case 6: // west workCell = workCell == IntVec3.Invalid || cell.x < workCell.x ? cell : workCell; break; case 7: // north-west workCell = workCell == IntVec3.Invalid || cell.z > workCell.z && cell.x < workCell.x ? cell : workCell; break; default: // error workCell = IntVec3.Invalid; break; } } // No valid cell found if (workCell == IntVec3.Invalid) { return(IntVec3.Invalid); } IntVec3 tmpCell = IntVec3.Invalid; int workDistance = ruinDistanceRange.RandomInRange; // set workDistance according to blueprint size if (size.x > size.z) { workDistance = size.x + Rand.RangeInclusive(1, 5); } else { workDistance = size.z + Rand.RangeInclusive(1, 5); } // set new cell switch (placement) { case 0: // north tmpCell = new IntVec3(0, 0, +workDistance); workCell += tmpCell; break; case 1: // north-east tmpCell = new IntVec3(+workDistance, 0, +workDistance); workCell += tmpCell; break; case 2: // east tmpCell = new IntVec3(+workDistance, 0, 0); workCell += tmpCell; break; case 3: // south-east tmpCell = new IntVec3(+workDistance, 0, -workDistance - (int)ruinOffsetVerticalRange.Average); workCell += tmpCell; break; case 4: // south tmpCell = new IntVec3(0, 0, -workDistance - (int)ruinOffsetVerticalRange.Average); workCell += tmpCell; break; case 5: // south-west tmpCell = new IntVec3(-workDistance - (int)ruinOffsetHorizontalRange.Average, 0, -workDistance - (int)ruinOffsetVerticalRange.Average); workCell += tmpCell; break; case 6: // west tmpCell = new IntVec3(-workDistance - (int)ruinOffsetHorizontalRange.Average, 0, 0); workCell += tmpCell; break; case 7: // north-west tmpCell = new IntVec3(-workDistance - (int)ruinOffsetHorizontalRange.Average, 0, +workDistance); workCell += tmpCell; break; default: // error workCell = IntVec3.Invalid; break; } // set new min distance according to tmpCell if (tmpCell.IsValid) { if (Math.Abs(tmpCell.x) / 2 < ruinDistanceRange.max && Math.Abs(tmpCell.z) / 2 < ruinDistanceRange.max) { if (Math.Abs(tmpCell.x) > Math.Abs(tmpCell.z)) { ruinDistanceRange.min = Math.Abs(tmpCell.x) / 2; } else { ruinDistanceRange.min = Math.Abs(tmpCell.z) / 2; } if (ruinDistanceRange.min > ruinDistanceRange.max) { ruinDistanceRange.max = ruinDistanceRange.min; } } } if (workCell.InBounds(map) && CanScatterAt(workCell, map) && IsPositionValidForBlueprint(workCell, size, invalidCells)) { return(workCell); } searchTry++; } return(IntVec3.Invalid); }
public static void Postfix(DynamicDrawManager __instance, Map ___map, ref bool ___drawingNow) { var ZTracker = ZUtils.ZTracker; int curLevel = ZTracker.GetZIndexFor(___map); if (curLevel > 0) { foreach (var map2 in ZTracker.GetAllMaps(___map.Tile)) //.OrderBy(x => ZTracker.GetZIndexFor(x))) { int baseLevel = ZTracker.GetZIndexFor(map2); if (curLevel > baseLevel && baseLevel >= 0) { ___drawingNow = true; bool[] fogGrid = map2.fogGrid.fogGrid; CellRect cellRect = Find.CameraDriver.CurrentViewRect; cellRect.ClipInsideMap(map2); cellRect = cellRect.ExpandedBy(1); CellIndices cellIndices = map2.cellIndices; foreach (Thing thing in map2.dynamicDrawManager.drawThings) { if (thing.def.drawerType != DrawerType.None && thing.def.drawerType != DrawerType.RealtimeOnly) { if (thing is Building_TurretGun turretGun) { var turretDrawPos = turretGun.DrawPos; turretDrawPos.y += Math.Abs(baseLevel - curLevel); turretDrawPos.z += (baseLevel - curLevel) / turretDrawZOffset; Vector3 b = new Vector3(turretGun.def.building.turretTopOffset.x, 0f, turretGun.def.building.turretTopOffset.y).RotatedBy(turretGun.top.CurRotation); float turretTopDrawSize = turretGun.top.parentTurret.def.building.turretTopDrawSize * (1f - (((float)(curLevel) - (float)baseLevel) / 5f)); Matrix4x4 matrix = default(Matrix4x4); matrix.SetTRS(turretDrawPos + Altitudes.AltIncVect + b, (turretGun.top.CurRotation + (float)TurretTop.ArtworkRotation).ToQuat(), new Vector3(turretTopDrawSize, 1f, turretTopDrawSize)); Graphics.DrawMesh(MeshPool.plane10, matrix, turretGun.def.building.turretTopMat, 0); } continue; } IntVec3 position = thing.Position; IntVec3 position2 = position + new IntVec3(0, 0, -1); var positionTerrain = position.GetTerrain(___map); if (positionTerrain == ZLevelsDefOf.ZL_OutsideTerrain || position2.InBounds(___map) && positionTerrain != ZLevelsDefOf.ZL_OutsideTerrain && position2.GetTerrain(___map) == ZLevelsDefOf.ZL_OutsideTerrain) { if ((cellRect.Contains(position) || thing.def.drawOffscreen) //&& (!fogGrid[cellIndices.CellToIndex(position)] //|| thing.def.seeThroughFog) && (thing.def.hideAtSnowDepth >= 1f || map2.snowGrid.GetDepth(position) <= thing.def.hideAtSnowDepth)) { DrawPos_Patch.ChangeDrawPos = true; DrawPos_Patch.zLevelOffset = (baseLevel - curLevel) / globalZOffset; DrawPos_Patch.yLevelOffset = baseLevel - curLevel; try { var graphicType = thing.Graphic.GetType(); if (graphicType == typeof(Graphic_LinkedCornerFiller) || graphicType == typeof(Graphic_Linked)) { thing.Draw(); } else if (thing is Pawn pawn) { DrawPos_Patch.ChangeDrawPos = false; var newDrawPos = thing.DrawPos; newDrawPos.z += (baseLevel - curLevel) / pawnZOffset; newDrawPos.y -= baseLevel - curLevel; newDrawPos.y -= pawnYOffset; // TODO Transpile PawnRenderer } else if (thing is Corpse corpse) { DrawPos_Patch.ChangeDrawPos = false; var newDrawPos = thing.DrawPos; newDrawPos.z += (baseLevel - curLevel) / pawnZOffset; newDrawPos.y -= baseLevel - curLevel; newDrawPos.y -= 4f; // TODO Transpile PawnRenderer } else if (thing.def.projectile == null && !thing.def.IsDoor) { if (!cachedGraphics.TryGetValue(thing, out var graphics)) { graphics = new Dictionary <int, Graphic>(); cachedGraphics[thing] = graphics; } if (!graphics.TryGetValue(curLevel, out var graphic) || true) { Vector2 drawSize = thing.Graphic.drawSize; drawSize.x *= 1f - ((curLevel - baseLevel) / thingDrawScale); drawSize.y *= 1f - ((curLevel - baseLevel) / thingDrawScale); if (thing.Graphic is Graphic_RandomRotated graphicRandomRotated) { graphic = graphicRandomRotated.subGraphic.GetCopy(drawSize, graphicRandomRotated.Shader); graphic.data = graphicRandomRotated.subGraphic.data; } else { graphic = thing.Graphic.GetCopy(drawSize, thing.Graphic.Shader); graphic.data = thing.Graphic.data; } graphic.data.drawSize = drawSize; graphics[curLevel] = graphic; } if (thing.def.mote != null) { DrawPos_Patch.zLevelOffset = (baseLevel - curLevel) / moteZOffset; } graphic.Draw(thing.DrawPos, thing.Rotation, thing); } else { if (thing is Building_Door door) { DrawPos_Patch.ChangeDrawPos = false; DrawDoor(door, baseLevel, curLevel); } else { thing.Draw(); } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { "Exception drawing ", thing, ": ", ex.ToString() })); } DrawPos_Patch.ChangeDrawPos = false; } } } ___drawingNow = false; } } } }
public static bool CheckMoveItemsAside( IntVec3 thingPos, Rot4 thingRot, ThingDef thingDef, Map map) { if (thingDef.surfaceType != SurfaceType.None || thingDef.passability == Traversability.Standable) { return(false); } CellRect occupiedRect = GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size); foreach (IntVec3 intVec3 in occupiedRect) { if (intVec3.InBounds(map)) { CellIndices cellIndices = map.cellIndices; List <Thing> list = ThingGrid_Patch.thingGridDict[map.thingGrid][cellIndices.CellToIndex(intVec3)]; lock (list) { foreach (Thing thing in list.ToArray()) { //if (!thing.Destroyed) //{ if (thing.def.category == ThingCategory.Item) { thing.DeSpawn(DestroyMode.Vanish); if (!GenPlace.TryPlaceThing(thing, intVec3, map, ThingPlaceMode.Near, null, (x => !occupiedRect.Contains(x)), new Rot4())) { thing.Destroy(DestroyMode.Vanish); } } //} } } } } return(false); }
private void ExpandSnow() { if (this.snowNoise == null) { this.snowNoise = new Perlin(0.054999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); } if (this.snowRadius < 8f) { this.snowRadius += 1.3f; } else { if (this.snowRadius < 17f) { this.snowRadius += 0.7f; } else { if (this.snowRadius < 30f) { this.snowRadius += 0.4f; } else { this.snowRadius += 0.1f; } } } if (this.snowRadius > 55f) { this.snowRadius = 55f; } CellRect occupiedRect = this.OccupiedRect(); Building_CrashedShipPartCopy.reachableCells.Clear(); FloodFiller.FloodFill(base.Position, (IntVec3 x) => x.DistanceToSquared(this.Position) <= this.snowRadius * this.snowRadius && (occupiedRect.Contains(x) || !x.Filled()), delegate(IntVec3 x) { Building_CrashedShipPartCopy.reachableCells.Add(x); }); int num = GenRadial.NumCellsInRadius(this.snowRadius); for (int i = 0; i < num; i++) { IntVec3 intVec = base.Position + GenRadial.RadialPattern[i]; if (intVec.InBounds()) { if (Building_CrashedShipPartCopy.reachableCells.Contains(intVec)) { float num2 = this.snowNoise.GetValue(intVec); num2 += 1f; num2 *= 0.5f; if (num2 < 0.1f) { num2 = 0.1f; } if (Find.SnowGrid.GetDepth(intVec) <= num2) { float lengthHorizontal = (intVec - base.Position).LengthHorizontal; float num3 = 1f - lengthHorizontal / this.snowRadius; Find.SnowGrid.AddDepth(intVec, num3 * 0.12f * num2); } } } } }
private static bool TryFindRandomPlaceFor(ThingDef thingDef, Sketch sketch, IntVec2 size, out IntVec3 pos, bool lowerLeftQuarterOnly, bool avoidCenter, bool requireLOSToEdge, bool avoidEdge, List <CellRect> edgeWallRects) { for (int i = 0; i < 200; i++) { CellRect cellRect = new CellRect(0, 0, size.x, size.z); if (lowerLeftQuarterOnly) { cellRect = new CellRect(cellRect.minX, cellRect.minZ, cellRect.Width / 2, cellRect.Height / 2); } IntVec3 randomCell = cellRect.RandomCell; if (avoidCenter) { CellRect cellRect2 = CellRect.CenteredOn(new CellRect(0, 0, size.x, size.z).CenterCell, size.x / 2, size.z / 2); for (int j = 0; j < 5; j++) { if (!cellRect2.Contains(randomCell)) { break; } randomCell = cellRect.RandomCell; } } if (avoidEdge) { CellRect cellRect3 = CellRect.CenteredOn(new CellRect(0, 0, size.x, size.z).CenterCell, Mathf.RoundToInt((float)size.x * 0.75f), Mathf.RoundToInt((float)size.z * 0.75f)); for (int k = 0; k < 5; k++) { if (cellRect3.Contains(randomCell)) { break; } randomCell = cellRect.RandomCell; } } if (requireLOSToEdge) { IntVec3 end = randomCell; end.x += size.x + 1; IntVec3 end2 = randomCell; end2.x -= size.x + 1; IntVec3 end3 = randomCell; end3.z -= size.z + 1; IntVec3 end4 = randomCell; end4.z += size.z + 1; if (!sketch.LineOfSight(randomCell, end) && !sketch.LineOfSight(randomCell, end2) && !sketch.LineOfSight(randomCell, end3) && !sketch.LineOfSight(randomCell, end4)) { continue; } } if (thingDef.building.minDistanceToSameTypeOfBuilding > 0) { bool flag = false; for (int l = 0; l < sketch.Things.Count; l++) { if (sketch.Things[l].def == thingDef && sketch.Things[l].pos.InHorDistOf(randomCell, thingDef.building.minDistanceToSameTypeOfBuilding)) { flag = true; break; } } if (flag) { continue; } } bool flag2 = false; CellRect cellRect4 = GenAdj.OccupiedRect(randomCell, Rot4.North, thingDef.Size); for (int m = 0; m < 4; m++) { if (cellRect4.Overlaps(edgeWallRects[m])) { flag2 = true; break; } } if (!flag2 && !sketch.WouldCollide(thingDef, randomCell, Rot4.North)) { pos = randomCell; return(true); } } pos = IntVec3.Invalid; return(false); }
public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell) { if (DebugSettings.pathThroughWalls) { traverseParms.mode = TraverseMode.PassAllDestroyableThings; } Pawn pawn = traverseParms.pawn; if (pawn != null && pawn.Map != map) { Log.Error(string.Concat("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=", pawn, " pawn.Map=", pawn.Map, " map=", map)); return(PawnPath.NotFound); } if (!start.IsValid) { Log.Error(string.Concat("Tried to FindPath with invalid start ", start, ", pawn= ", pawn)); return(PawnPath.NotFound); } if (!dest.IsValid) { Log.Error(string.Concat("Tried to FindPath with invalid dest ", dest, ", pawn= ", pawn)); return(PawnPath.NotFound); } if (traverseParms.mode == TraverseMode.ByPawn) { if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode)) { return(PawnPath.NotFound); } } else if (!map.reachability.CanReach(start, dest, peMode, traverseParms)) { return(PawnPath.NotFound); } PfProfilerBeginSample(string.Concat("FindPath for ", pawn, " from ", start, " to ", dest, dest.HasThing ? (" at " + dest.Cell) : "")); cellIndices = map.cellIndices; pathGrid = map.pathGrid; this.edificeGrid = map.edificeGrid.InnerArray; blueprintGrid = map.blueprintGrid.InnerArray; int x = dest.Cell.x; int z = dest.Cell.z; int curIndex = cellIndices.CellToIndex(start); int num = cellIndices.CellToIndex(dest.Cell); ByteGrid byteGrid = pawn?.GetAvoidGrid(); bool flag = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater; bool flag2 = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater; bool flag3 = !flag; CellRect cellRect = CalculateDestinationRect(dest, peMode); bool flag4 = cellRect.Width == 1 && cellRect.Height == 1; int[] array = map.pathGrid.pathGrid; TerrainDef[] topGrid = map.terrainGrid.topGrid; EdificeGrid edificeGrid = map.edificeGrid; int num2 = 0; int num3 = 0; Area allowedArea = GetAllowedArea(pawn); bool flag5 = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn); bool flag6 = !flag && start.GetRegion(map) != null && flag2; bool flag7 = !flag || !flag3; bool flag8 = false; bool flag9 = pawn?.Drafted ?? false; int num4 = ((pawn?.IsColonist ?? false) ? 100000 : 2000); int num5 = 0; int num6 = 0; float num7 = DetermineHeuristicStrength(pawn, start, dest); int num8; int num9; if (pawn != null) { num8 = pawn.TicksPerMoveCardinal; num9 = pawn.TicksPerMoveDiagonal; } else { num8 = 13; num9 = 18; } CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect); InitStatusesAndPushStartNode(ref curIndex, start); while (true) { PfProfilerBeginSample("Open cell"); if (openList.Count <= 0) { string text = ((pawn != null && pawn.CurJob != null) ? pawn.CurJob.ToString() : "null"); string text2 = ((pawn != null && pawn.Faction != null) ? pawn.Faction.ToString() : "null"); Log.Warning(string.Concat(pawn, " pathing from ", start, " to ", dest, " ran out of cells to process.\nJob:", text, "\nFaction: ", text2)); DebugDrawRichData(); PfProfilerEndSample(); PfProfilerEndSample(); return(PawnPath.NotFound); } num5 += openList.Count; num6++; CostNode costNode = openList.Pop(); curIndex = costNode.index; if (costNode.cost != calcGrid[curIndex].costNodeCost) { PfProfilerEndSample(); continue; } if (calcGrid[curIndex].status == statusClosedValue) { PfProfilerEndSample(); continue; } IntVec3 c = cellIndices.IndexToCell(curIndex); int x2 = c.x; int z2 = c.z; if (flag4) { if (curIndex == num) { PfProfilerEndSample(); PawnPath result = FinalizedPath(curIndex, flag8); PfProfilerEndSample(); return(result); } } else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(curIndex)) { PfProfilerEndSample(); PawnPath result2 = FinalizedPath(curIndex, flag8); PfProfilerEndSample(); return(result2); } if (num2 > 160000) { break; } PfProfilerEndSample(); PfProfilerBeginSample("Neighbor consideration"); for (int i = 0; i < 8; i++) { uint num10 = (uint)(x2 + Directions[i]); uint num11 = (uint)(z2 + Directions[i + 8]); if (num10 >= mapSizeX || num11 >= mapSizeZ) { continue; } int num12 = (int)num10; int num13 = (int)num11; int num14 = cellIndices.CellToIndex(num12, num13); if (calcGrid[num14].status == statusClosedValue && !flag8) { continue; } int num15 = 0; bool flag10 = false; if (!flag2 && new IntVec3(num12, 0, num13).GetTerrain(map).HasTag("Water")) { continue; } if (!pathGrid.WalkableFast(num14)) { if (!flag) { continue; } flag10 = true; num15 += 70; Building building = edificeGrid[num14]; if (building == null || !IsDestroyable(building)) { continue; } num15 += (int)((float)building.HitPoints * 0.2f); } switch (i) { case 4: if (BlocksDiagonalMovement(curIndex - mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex + 1)) { if (flag7) { continue; } num15 += 70; } break; case 5: if (BlocksDiagonalMovement(curIndex + mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex + 1)) { if (flag7) { continue; } num15 += 70; } break; case 6: if (BlocksDiagonalMovement(curIndex + mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex - 1)) { if (flag7) { continue; } num15 += 70; } break; case 7: if (BlocksDiagonalMovement(curIndex - mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex - 1)) { if (flag7) { continue; } num15 += 70; } break; } int num16 = ((i > 3) ? num9 : num8); num16 += num15; if (!flag10) { num16 += array[num14]; num16 = ((!flag9) ? (num16 + topGrid[num14].extraNonDraftedPerceivedPathCost) : (num16 + topGrid[num14].extraDraftedPerceivedPathCost)); } if (byteGrid != null) { num16 += byteGrid[num14] * 8; } if (allowedArea != null && !allowedArea[num14]) { num16 += 600; } if (flag5 && PawnUtility.AnyPawnBlockingPathAt(new IntVec3(num12, 0, num13), pawn, actAsIfHadCollideWithPawnsJob: false, collideOnlyWithStandingPawns: false, forPathFinder: true)) { num16 += 175; } Building building2 = this.edificeGrid[num14]; if (building2 != null) { PfProfilerBeginSample("Edifices"); int buildingCost = GetBuildingCost(building2, traverseParms, pawn); if (buildingCost == int.MaxValue) { PfProfilerEndSample(); continue; } num16 += buildingCost; PfProfilerEndSample(); } List <Blueprint> list = blueprintGrid[num14]; if (list != null) { PfProfilerBeginSample("Blueprints"); int num17 = 0; for (int j = 0; j < list.Count; j++) { num17 = Mathf.Max(num17, GetBlueprintCost(list[j], pawn)); } if (num17 == int.MaxValue) { PfProfilerEndSample(); continue; } num16 += num17; PfProfilerEndSample(); } int num18 = num16 + calcGrid[curIndex].knownCost; ushort status = calcGrid[num14].status; if (status == statusClosedValue || status == statusOpenValue) { int num19 = 0; if (status == statusClosedValue) { num19 = num8; } if (calcGrid[num14].knownCost <= num18 + num19) { continue; } } if (flag8) { calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)regionCostCalculator.GetPathCostFromDestToRegion(num14) * RegionHeuristicWeightByNodesOpened.Evaluate(num3)); if (calcGrid[num14].heuristicCost < 0) { Log.ErrorOnce(string.Concat("Heuristic cost overflow for ", pawn.ToStringSafe(), " pathing from ", start, " to ", dest, "."), pawn.GetHashCode() ^ 0xB8DC389); calcGrid[num14].heuristicCost = 0; } } else if (status != statusClosedValue && status != statusOpenValue) { int dx = Math.Abs(num12 - x); int dz = Math.Abs(num13 - z); int num20 = GenMath.OctileDistance(dx, dz, num8, num9); calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num20 * num7); } int num21 = num18 + calcGrid[num14].heuristicCost; if (num21 < 0) { Log.ErrorOnce(string.Concat("Node cost overflow for ", pawn.ToStringSafe(), " pathing from ", start, " to ", dest, "."), pawn.GetHashCode() ^ 0x53CB9DE); num21 = 0; } calcGrid[num14].parentIndex = curIndex; calcGrid[num14].knownCost = num18; calcGrid[num14].status = statusOpenValue; calcGrid[num14].costNodeCost = num21; num3++; openList.Push(new CostNode(num14, num21)); } PfProfilerEndSample(); num2++; calcGrid[curIndex].status = statusClosedValue; if (num3 >= num4 && flag6 && !flag8) { flag8 = true; regionCostCalculator.Init(cellRect, traverseParms, num8, num9, byteGrid, allowedArea, flag9, disallowedCornerIndices); InitStatusesAndPushStartNode(ref curIndex, start); num3 = 0; num2 = 0; } } Log.Warning(string.Concat(pawn, " pathing from ", start, " to ", dest, " hit search limit of ", 160000, " cells.")); DebugDrawRichData(); PfProfilerEndSample(); PfProfilerEndSample(); return(PawnPath.NotFound); }
public static void DebugDraw() { if (DebugViewSettings.drawInfestationChance) { if (tmpCachedInfestationChanceCellColors == null) { tmpCachedInfestationChanceCellColors = new List <Pair <IntVec3, float> >(); } if (Time.frameCount % 8 == 0) { tmpCachedInfestationChanceCellColors.Clear(); Map currentMap = Find.CurrentMap; CellRect currentViewRect = Find.CameraDriver.CurrentViewRect; currentViewRect.ClipInsideMap(currentMap); currentViewRect = currentViewRect.ExpandedBy(1); CalculateTraversalDistancesToUnroofed(currentMap); CalculateClosedAreaSizeGrid(currentMap); CalculateDistanceToColonyBuildingGrid(currentMap); float num = 0.001f; int num2 = 0; while (true) { int num3 = num2; IntVec3 size = currentMap.Size; if (num3 >= size.z) { break; } int num4 = 0; while (true) { int num5 = num4; IntVec3 size2 = currentMap.Size; if (num5 >= size2.x) { break; } IntVec3 cell = new IntVec3(num4, 0, num2); float scoreAt = GetScoreAt(cell, currentMap); if (scoreAt > num) { num = scoreAt; } num4++; } num2++; } int num6 = 0; while (true) { int num7 = num6; IntVec3 size3 = currentMap.Size; if (num7 >= size3.z) { break; } int num8 = 0; while (true) { int num9 = num8; IntVec3 size4 = currentMap.Size; if (num9 >= size4.x) { break; } IntVec3 intVec = new IntVec3(num8, 0, num6); if (currentViewRect.Contains(intVec)) { float scoreAt2 = GetScoreAt(intVec, currentMap); if (!(scoreAt2 <= 7.5f)) { float second = GenMath.LerpDouble(7.5f, num, 0f, 1f, scoreAt2); tmpCachedInfestationChanceCellColors.Add(new Pair <IntVec3, float>(intVec, second)); } } num8++; } num6++; } } for (int i = 0; i < tmpCachedInfestationChanceCellColors.Count; i++) { IntVec3 first = tmpCachedInfestationChanceCellColors[i].First; float second2 = tmpCachedInfestationChanceCellColors[i].Second; CellRenderer.RenderCell(first, SolidColorMaterials.SimpleSolidColorMaterial(new Color(0f, 0f, 1f, second2))); } } else { tmpCachedInfestationChanceCellColors = null; } }
public static void DynamicDrawManagerPostfix(DynamicDrawManager __instance, Map ___map, ref bool ___drawingNow) { var ZTracker = ZUtils.ZTracker; int curLevel = ZTracker.GetZIndexFor(___map); foreach (var map2 in ZTracker.GetAllMaps(___map.Tile).OrderBy(x => ZTracker.GetZIndexFor(x))) { int baseLevel = ZTracker.GetZIndexFor(map2); if (curLevel > baseLevel && baseLevel >= 0) { if (!DebugViewSettings.drawThingsDynamic) { return; } ___drawingNow = true; bool[] fogGrid = map2.fogGrid.fogGrid; CellRect cellRect = Find.CameraDriver.CurrentViewRect; cellRect.ClipInsideMap(map2); cellRect = cellRect.ExpandedBy(1); CellIndices cellIndices = map2.cellIndices; HashSet <Thing> drawThings = Traverse.Create(map2.dynamicDrawManager) .Field("drawThings").GetValue <HashSet <Thing> >(); foreach (Thing thing in drawThings) { IntVec3 position = thing.Position; if (position.GetTerrain(___map) == ZLevelsDefOf.ZL_OutsideTerrain) { if ((cellRect.Contains(position) || thing.def.drawOffscreen) //&& (!fogGrid[cellIndices.CellToIndex(position)] //|| thing.def.seeThroughFog) && (thing.def.hideAtSnowDepth >= 1f || map2.snowGrid.GetDepth(position) <= thing.def.hideAtSnowDepth)) { try { if (thing.Graphic is Graphic_Mote) { } else if (thing.Graphic is Graphic_LinkedCornerFiller || thing.Graphic is Graphic_RandomRotated || thing.Graphic is Graphic_Linked) { thing.Draw(); } else if (thing is Pawn pawn) { var newRenderer = new PawnRendererScaled(pawn); pawn.Drawer.renderer.graphics.ResolveAllGraphics(); newRenderer.graphics.nakedGraphic = pawn.Drawer.renderer.graphics.nakedGraphic; newRenderer.graphics.headGraphic = pawn.Drawer.renderer.graphics.headGraphic; newRenderer.graphics.hairGraphic = pawn.Drawer.renderer.graphics.hairGraphic; newRenderer.graphics.rottingGraphic = pawn.Drawer.renderer.graphics.rottingGraphic; newRenderer.graphics.dessicatedGraphic = pawn.Drawer.renderer.graphics.dessicatedGraphic; newRenderer.graphics.apparelGraphics = pawn.Drawer.renderer.graphics.apparelGraphics; newRenderer.graphics.packGraphic = pawn.Drawer.renderer.graphics.packGraphic; newRenderer.graphics.flasher = pawn.Drawer.renderer.graphics.flasher; newRenderer.RenderPawnAt(thing.DrawPos, curLevel, baseLevel); } else { Vector2 drawSize = thing.Graphic.drawSize; drawSize.x *= 1f - (((float)(curLevel) - (float)baseLevel) / 5f); drawSize.y *= 1f - (((float)(curLevel) - (float)baseLevel) / 5f); var newGraphic = thing.Graphic.GetCopy(drawSize); newGraphic.Draw(thing.DrawPos, thing.Rotation, thing); } } catch (Exception ex) { Log.Error(string.Concat(new object[] { "Exception drawing ", thing, ": ", ex.ToString() }), false); } } } } ___drawingNow = false; } } }
public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell) { if (DebugSettings.pathThroughWalls) { traverseParms.mode = TraverseMode.PassAllDestroyableThings; } Pawn pawn = traverseParms.pawn; if (pawn != null && pawn.Map != map) { Log.Warning(String.Format("Map object was rebuilt, but new pather was not assigned to new map (new {0}) (old {1})", pawn.Map.uniqueID, map.uniqueID)); Log.Error("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=" + pawn + " pawn.Map=" + pawn.Map + " map=" + map); return(PawnPath.NotFound); } if (!start.IsValid) { Log.Error("Tried to FindPath with invalid start " + start + ", pawn= " + pawn); return(PawnPath.NotFound); } if (!dest.IsValid) { Log.Error("Tried to FindPath with invalid dest " + dest + ", pawn= " + pawn); return(PawnPath.NotFound); } if (traverseParms.mode == TraverseMode.ByPawn) { if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode)) { return(PawnPath.NotFound); } } else if (!map.reachability.CanReach(start, dest, peMode, traverseParms)) { return(PawnPath.NotFound); } PfProfilerBeginSample("FindPath for " + pawn + " from " + start + " to " + dest + (dest.HasThing ? (" at " + dest.Cell) : "")); cellIndices = map.cellIndices; pathGrid = map.pathGrid; this.edificeGrid = map.edificeGrid.InnerArray; blueprintGrid = map.blueprintGrid.InnerArray; int x = dest.Cell.x; int z = dest.Cell.z; int curIndex = cellIndices.CellToIndex(start); int num = cellIndices.CellToIndex(dest.Cell); ByteGrid byteGrid = pawn?.GetAvoidGrid(); bool flag = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater; bool flag2 = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater; bool flag3 = !flag; CellRect cellRect = CalculateDestinationRect(dest, peMode); bool flag4 = cellRect.Width == 1 && cellRect.Height == 1; int[] array = map.pathGrid.pathGrid; TerrainDef[] topGrid = map.terrainGrid.topGrid; EdificeGrid edificeGrid = map.edificeGrid; int num2 = 0; int num3 = 0; Area allowedArea = GetAllowedArea(pawn); bool flag5 = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn); bool flag6 = (!flag && start.GetRegion(map) != null) & flag2; bool flag7 = !flag || !flag3; bool flag8 = false; bool flag9 = pawn?.Drafted ?? false; int num4 = (pawn?.IsColonist ?? false) ? 100000 : 2000; int num5 = 0; int num6 = 0; float num7 = DetermineHeuristicStrength(pawn, start, dest); // BEGIN CHANGED SECTION // In case pawn is null int num8 = 13; int num9 = 18; Dictionary <TerrainDef, int> pawnTerrainCacheCardinal = new Dictionary <TerrainDef, int>(); Dictionary <TerrainDef, int> pawnTerrainCacheDiagonal = new Dictionary <TerrainDef, int>(); Dictionary <TerrainDef, bool> pawnSpecialMovementCache = new Dictionary <TerrainDef, bool>(); Dictionary <TerrainDef, bool> pawnImpassibleMovementCache = new Dictionary <TerrainDef, bool>(); Dictionary <TerrainDef, int> pawnTerrainMovementCache = new Dictionary <TerrainDef, int>(); // END CHANGED SECTION CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect); InitStatusesAndPushStartNode(ref curIndex, start); while (true) { PfProfilerBeginSample("Open cell"); if (openList.Count <= 0) { string text = (pawn != null && pawn.CurJob != null) ? pawn.CurJob.ToString() : "null"; string text2 = (pawn != null && pawn.Faction != null) ? pawn.Faction.ToString() : "null"; Log.Warning(pawn + " pathing from " + start + " to " + dest + " ran out of cells to process.\nJob:" + text + "\nFaction: " + text2); DebugDrawRichData(); PfProfilerEndSample(); PfProfilerEndSample(); return(PawnPath.NotFound); } num5 += openList.Count; num6++; CostNode costNode = openList.Pop(); curIndex = costNode.index; if (costNode.cost != calcGrid[curIndex].costNodeCost) { PfProfilerEndSample(); continue; } if (calcGrid[curIndex].status == statusClosedValue) { PfProfilerEndSample(); continue; } IntVec3 c = cellIndices.IndexToCell(curIndex); int x2 = c.x; int z2 = c.z; if (flag4) { if (curIndex == num) { PfProfilerEndSample(); PawnPath result = FinalizedPath(curIndex, flag8); PfProfilerEndSample(); return(result); } } else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(curIndex)) { PfProfilerEndSample(); PawnPath result2 = FinalizedPath(curIndex, flag8); PfProfilerEndSample(); return(result2); } if (num2 > 160000) { break; } PfProfilerEndSample(); PfProfilerBeginSample("Neighbor consideration"); for (int i = 0; i < 8; i++) { uint num10 = (uint)(x2 + Directions[i]); uint num11 = (uint)(z2 + Directions[i + 8]); if (num10 >= mapSizeX || num11 >= mapSizeZ) { continue; } int num12 = (int)num10; int num13 = (int)num11; int num14 = cellIndices.CellToIndex(num12, num13); if (calcGrid[num14].status == statusClosedValue && !flag8) { continue; } // BEGIN CHANGED SECTION IntVec3 targetCell = new IntVec3(num12, 0, num13); TerrainDef targetTerrain = topGrid[num14]; if (pawn != null) { // Use cache of terrain movement indicators to avoid a lot of repeated computation if (!pawnImpassibleMovementCache.TryGetValue(targetTerrain, out bool impassible)) { impassible = pawn.kindDef.UnreachableTerrainCheck(targetTerrain); pawnImpassibleMovementCache[targetTerrain] = impassible; } if (impassible) { // Skip this cell for pathing calculations calcGrid[num14].status = statusClosedValue; continue; } // Overwrite directional move costs if (!pawnTerrainCacheCardinal.TryGetValue(targetTerrain, out num8)) { num8 = pawn.TerrainAwareTicksPerMoveCardinal(targetTerrain); pawnTerrainCacheCardinal[targetTerrain] = num8; } if (!pawnTerrainCacheDiagonal.TryGetValue(targetTerrain, out num9)) { num9 = pawn.TerrainAwareTicksPerMoveDiagonal(targetTerrain); pawnTerrainCacheDiagonal[targetTerrain] = num9; } } // END CHANGED SECTION int num15 = 0; bool flag10 = false; //if (!flag2 && new IntVec3(num12, 0, num13).GetTerrain(map).HasTag("Water")) if (!flag2 && targetTerrain.HasTag("Water")) { continue; } if (!pathGrid.WalkableFast(num14)) { if (!flag) { continue; } flag10 = true; num15 += 70; Building building = edificeGrid[num14]; if (building == null || !IsDestroyable(building)) { continue; } num15 += (int)((float)building.HitPoints * 0.2f); } switch (i) { case 4: if (BlocksDiagonalMovement(curIndex - mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex + 1)) { if (flag7) { continue; } num15 += 70; } break; case 5: if (BlocksDiagonalMovement(curIndex + mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex + 1)) { if (flag7) { continue; } num15 += 70; } break; case 6: if (BlocksDiagonalMovement(curIndex + mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex - 1)) { if (flag7) { continue; } num15 += 70; } break; case 7: if (BlocksDiagonalMovement(curIndex - mapSizeX)) { if (flag7) { continue; } num15 += 70; } if (BlocksDiagonalMovement(curIndex - 1)) { if (flag7) { continue; } num15 += 70; } break; } int num16 = (i > 3) ? num9 : num8; num16 += num15; if (!flag10) { // BEGIN CHANGED SECTION //num16 += array[num14]; //num16 = ((!flag9) ? (num16 + topGrid[num14].extraNonDraftedPerceivedPathCost) : (num16 + topGrid[num14].extraDraftedPerceivedPathCost)); if (pawn == null) { num16 += array[num14]; if (flag9) { num16 += targetTerrain.extraDraftedPerceivedPathCost; } else { num16 += targetTerrain.extraNonDraftedPerceivedPathCost; } } else { // Use cache of terrain perceived cost instead of fixed pathCost grid to avoid a lot of repeated computation while maintaining accuracy if (!pawnTerrainMovementCache.TryGetValue(targetTerrain, out int terrainMoveCost)) { terrainMoveCost = pawn.TerrainMoveCost(targetTerrain); pawnTerrainMovementCache[targetTerrain] = terrainMoveCost; } // This was really really expensive, so we opted to mod this pre-calced value //num16 += pathGrid.TerrainCalculatedCostAt(map, pawn, targetCell, true, IntVec3.Invalid, terrainMoveCost); num16 += pathGrid.ApplyTerrainModToCalculatedCost(targetTerrain, array[num14], terrainMoveCost); // Use cache of terrain movement indicators to avoid a lot of repeated computation if (!pawnSpecialMovementCache.TryGetValue(targetTerrain, out bool specialMovement)) { specialMovement = pawn.TerrainMoveStat(targetTerrain) != StatDefOf.MoveSpeed; pawnSpecialMovementCache[targetTerrain] = specialMovement; } // Skip applying the PerceivedPathCost hack if we've got a specialized speed stat for this terrain if (!specialMovement) { if (flag9) { num16 += targetTerrain.extraDraftedPerceivedPathCost; } else { num16 += targetTerrain.extraNonDraftedPerceivedPathCost; } } } // END CHANGED SECTION } if (byteGrid != null) { num16 += byteGrid[num14] * 8; } if (allowedArea != null && !allowedArea[num14]) { num16 += 600; } //new IntVec3(num12, 0, num13) -> targetCell if (flag5 && PawnUtility.AnyPawnBlockingPathAt(targetCell, pawn, actAsIfHadCollideWithPawnsJob: false, collideOnlyWithStandingPawns: false, forPathFinder: true)) { num16 += 175; } Building building2 = this.edificeGrid[num14]; if (building2 != null) { PfProfilerBeginSample("Edifices"); int buildingCost = GetBuildingCost(building2, traverseParms, pawn); if (buildingCost == int.MaxValue) { PfProfilerEndSample(); continue; } num16 += buildingCost; PfProfilerEndSample(); } List <Blueprint> list = blueprintGrid[num14]; if (list != null) { PfProfilerBeginSample("Blueprints"); int num17 = 0; for (int j = 0; j < list.Count; j++) { num17 = Mathf.Max(num17, GetBlueprintCost(list[j], pawn)); } if (num17 == int.MaxValue) { PfProfilerEndSample(); continue; } num16 += num17; PfProfilerEndSample(); } int num18 = num16 + calcGrid[curIndex].knownCost; ushort status = calcGrid[num14].status; if (status == statusClosedValue || status == statusOpenValue) { int num19 = 0; if (status == statusClosedValue) { num19 = num8; } if (calcGrid[num14].knownCost <= num18 + num19) { continue; } } if (flag8) { calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)regionCostCalculator.GetPathCostFromDestToRegion(num14) * RegionHeuristicWeightByNodesOpened.Evaluate(num3)); if (calcGrid[num14].heuristicCost < 0) { Log.ErrorOnce("Heuristic cost overflow for " + pawn.ToStringSafe() + " pathing from " + start + " to " + dest + ".", pawn.GetHashCode() ^ 0xB8DC389); calcGrid[num14].heuristicCost = 0; } } else if (status != statusClosedValue && status != statusOpenValue) { int dx = Math.Abs(num12 - x); int dz = Math.Abs(num13 - z); int num20 = GenMath.OctileDistance(dx, dz, num8, num9); calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num20 * num7); } int num21 = num18 + calcGrid[num14].heuristicCost; if (num21 < 0) { Log.ErrorOnce("Node cost overflow for " + pawn.ToStringSafe() + " pathing from " + start + " to " + dest + ".", pawn.GetHashCode() ^ 0x53CB9DE); num21 = 0; } calcGrid[num14].parentIndex = curIndex; calcGrid[num14].knownCost = num18; calcGrid[num14].status = statusOpenValue; calcGrid[num14].costNodeCost = num21; num3++; openList.Push(new CostNode(num14, num21)); } PfProfilerEndSample(); num2++; calcGrid[curIndex].status = statusClosedValue; if (num3 >= num4 && flag6 && !flag8) { flag8 = true; regionCostCalculator.Init(cellRect, traverseParms, num8, num9, byteGrid, allowedArea, flag9, disallowedCornerIndices); InitStatusesAndPushStartNode(ref curIndex, start); num3 = 0; num2 = 0; } } Log.Warning(pawn + " pathing from " + start + " to " + dest + " hit search limit of " + 160000 + " cells."); DebugDrawRichData(); PfProfilerEndSample(); PfProfilerEndSample(); return(PawnPath.NotFound); }
public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode = false, Thing thingToIgnore = null, Thing thing = null, ThingDef stuffDef = null) { CellRect cellRect = GenAdj.OccupiedRect(center, rot, entDef.Size); if (stuffDef == null && thing != null) { stuffDef = thing.Stuff; } foreach (IntVec3 item in cellRect) { if (!item.InBounds(map)) { return(new AcceptanceReport("OutOfBounds".Translate())); } if (item.InNoBuildEdgeArea(map) && !godMode) { return("TooCloseToMapEdge".Translate()); } } if (center.Fogged(map)) { return("CannotPlaceInUndiscovered".Translate()); } List <Thing> thingList = center.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing2 = thingList[i]; if (thing2 == thingToIgnore || !(thing2.Position == center) || !(thing2.Rotation == rot)) { continue; } if (thing2.def == entDef) { return(new AcceptanceReport("IdenticalThingExists".Translate())); } if (thing2.def.entityDefToBuild == entDef) { if (thing2 is Blueprint) { return(new AcceptanceReport("IdenticalBlueprintExists".Translate())); } return(new AcceptanceReport("IdenticalThingExists".Translate())); } } ThingDef thingDef = entDef as ThingDef; if (thingDef != null && thingDef.hasInteractionCell) { IntVec3 c = ThingUtility.InteractionCellWhenAt(thingDef, center, rot, map); if (!c.InBounds(map)) { return(new AcceptanceReport("InteractionSpotOutOfBounds".Translate())); } List <Thing> list = map.thingGrid.ThingsListAtFast(c); for (int j = 0; j < list.Count; j++) { if (list[j] != thingToIgnore) { if (list[j].def.passability == Traversability.Impassable || list[j].def == thingDef) { return(new AcceptanceReport("InteractionSpotBlocked".Translate(list[j].LabelNoCount, list[j]).CapitalizeFirst())); } BuildableDef entityDefToBuild = list[j].def.entityDefToBuild; if (entityDefToBuild != null && (entityDefToBuild.passability == Traversability.Impassable || entityDefToBuild == thingDef)) { return(new AcceptanceReport("InteractionSpotWillBeBlocked".Translate(list[j].LabelNoCount, list[j]).CapitalizeFirst())); } } } } foreach (IntVec3 item2 in GenAdj.CellsAdjacentCardinal(center, rot, entDef.Size)) { if (item2.InBounds(map)) { thingList = item2.GetThingList(map); for (int k = 0; k < thingList.Count; k++) { Thing thing3 = thingList[k]; if (thing3 != thingToIgnore) { ThingDef thingDef2 = null; Blueprint blueprint = thing3 as Blueprint; if (blueprint != null) { ThingDef thingDef3 = blueprint.def.entityDefToBuild as ThingDef; if (thingDef3 == null) { continue; } thingDef2 = thingDef3; } else { thingDef2 = thing3.def; } if (thingDef2.hasInteractionCell && (entDef.passability == Traversability.Impassable || entDef == thingDef2) && cellRect.Contains(ThingUtility.InteractionCellWhenAt(thingDef2, thing3.Position, thing3.Rotation, thing3.Map))) { return(new AcceptanceReport("WouldBlockInteractionSpot".Translate(entDef.label, thingDef2.label).CapitalizeFirst())); } } } } } TerrainDef terrainDef = entDef as TerrainDef; if (terrainDef != null) { if (map.terrainGrid.TerrainAt(center) == terrainDef) { return(new AcceptanceReport("TerrainIsAlready".Translate(terrainDef.label))); } if (map.designationManager.DesignationAt(center, DesignationDefOf.SmoothFloor) != null) { return(new AcceptanceReport("SpaceBeingSmoothed".Translate())); } } if (!CanBuildOnTerrain(entDef, center, map, rot, thingToIgnore, stuffDef)) { if (entDef.GetTerrainAffordanceNeed(stuffDef) != null) { if (entDef.useStuffTerrainAffordance && stuffDef != null) { return(new AcceptanceReport("TerrainCannotSupport_TerrainAffordanceFromStuff".Translate(entDef, entDef.GetTerrainAffordanceNeed(stuffDef), stuffDef).CapitalizeFirst())); } return(new AcceptanceReport("TerrainCannotSupport_TerrainAffordance".Translate(entDef, entDef.GetTerrainAffordanceNeed(stuffDef)).CapitalizeFirst())); } return(new AcceptanceReport("TerrainCannotSupport".Translate(entDef).CapitalizeFirst())); } if (ModsConfig.RoyaltyActive) { List <Thing> list2 = map.listerThings.ThingsOfDef(ThingDefOf.MonumentMarker); for (int l = 0; l < list2.Count; l++) { MonumentMarker monumentMarker = (MonumentMarker)list2[l]; if (!monumentMarker.complete && !monumentMarker.AllowsPlacingBlueprint(entDef, center, rot, stuffDef)) { return(new AcceptanceReport("BlueprintWouldCollideWithMonument".Translate())); } } } if (!godMode) { foreach (IntVec3 item3 in cellRect) { thingList = item3.GetThingList(map); for (int m = 0; m < thingList.Count; m++) { Thing thing4 = thingList[m]; if (thing4 != thingToIgnore && !CanPlaceBlueprintOver(entDef, thing4.def)) { return(new AcceptanceReport("SpaceAlreadyOccupied".Translate())); } } } } if (entDef.PlaceWorkers != null) { for (int n = 0; n < entDef.PlaceWorkers.Count; n++) { AcceptanceReport result = entDef.PlaceWorkers[n].AllowsPlacing(entDef, center, rot, map, thingToIgnore, thing); if (!result.Accepted) { return(result); } } } return(AcceptanceReport.WasAccepted); }
public static bool TryFindCastPosition(CastPositionRequest newReq, out IntVec3 dest) { req = newReq; casterLoc = req.caster.Position; targetLoc = req.target.Position; verb = req.verb; avoidGrid = newReq.caster.GetAvoidGrid(onlyIfLordAllows: false); if (verb == null) { Log.Error(string.Concat(req.caster, " tried to find casting position without a verb.")); dest = IntVec3.Invalid; return(false); } if (req.maxRegions > 0) { Region region = casterLoc.GetRegion(req.caster.Map); if (region == null) { Log.Error("TryFindCastPosition requiring region traversal but root region is null."); dest = IntVec3.Invalid; return(false); } inRadiusMark = Rand.Int; RegionTraverser.MarkRegionsBFS(region, null, newReq.maxRegions, inRadiusMark); if (req.maxRangeFromLocus > 0.01f) { Region locusReg = req.locus.GetRegion(req.caster.Map); if (locusReg == null) { Log.Error(string.Concat("locus ", req.locus, " has no region")); dest = IntVec3.Invalid; return(false); } if (locusReg.mark != inRadiusMark) { inRadiusMark = Rand.Int; RegionTraverser.BreadthFirstTraverse(region, null, delegate(Region r) { r.mark = inRadiusMark; req.maxRegions++; return(r == locusReg); }); } } } CellRect cellRect = CellRect.WholeMap(req.caster.Map); if (req.maxRangeFromCaster > 0.01f) { int num = Mathf.CeilToInt(req.maxRangeFromCaster); CellRect otherRect = new CellRect(casterLoc.x - num, casterLoc.z - num, num * 2 + 1, num * 2 + 1); cellRect.ClipInsideRect(otherRect); } int num2 = Mathf.CeilToInt(req.maxRangeFromTarget); CellRect otherRect2 = new CellRect(targetLoc.x - num2, targetLoc.z - num2, num2 * 2 + 1, num2 * 2 + 1); cellRect.ClipInsideRect(otherRect2); if (req.maxRangeFromLocus > 0.01f) { int num3 = Mathf.CeilToInt(req.maxRangeFromLocus); CellRect otherRect3 = new CellRect(targetLoc.x - num3, targetLoc.z - num3, num3 * 2 + 1, num3 * 2 + 1); cellRect.ClipInsideRect(otherRect3); } bestSpot = IntVec3.Invalid; bestSpotPref = 0.001f; maxRangeFromCasterSquared = req.maxRangeFromCaster * req.maxRangeFromCaster; maxRangeFromTargetSquared = req.maxRangeFromTarget * req.maxRangeFromTarget; maxRangeFromLocusSquared = req.maxRangeFromLocus * req.maxRangeFromLocus; rangeFromTarget = (req.caster.Position - req.target.Position).LengthHorizontal; rangeFromTargetSquared = (req.caster.Position - req.target.Position).LengthHorizontalSquared; optimalRangeSquared = verb.verbProps.range * 0.8f * (verb.verbProps.range * 0.8f); EvaluateCell(req.caster.Position); if ((double)bestSpotPref >= 1.0) { dest = req.caster.Position; return(true); } float slope = -1f / CellLine.Between(req.target.Position, req.caster.Position).Slope; CellLine cellLine = new CellLine(req.target.Position, slope); bool flag = cellLine.CellIsAbove(req.caster.Position); foreach (IntVec3 item in cellRect) { if (cellLine.CellIsAbove(item) == flag && cellRect.Contains(item)) { EvaluateCell(item); } } if (bestSpot.IsValid && bestSpotPref > 0.33f) { dest = bestSpot; return(true); } foreach (IntVec3 item2 in cellRect) { if (cellLine.CellIsAbove(item2) != flag && cellRect.Contains(item2)) { EvaluateCell(item2); } } if (bestSpot.IsValid) { dest = bestSpot; return(true); } dest = casterLoc; return(false); }
private void TryExpandSnow() { if (parent.Map.mapTemperature.OutdoorTemp > 10f) { snowRadius = 0f; return; } if (snowNoise == null) { snowNoise = new Perlin(0.054999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); } if (snowRadius < 8f) { snowRadius += 1.3f; } else if (snowRadius < 17f) { snowRadius += 0.7f; } else if (snowRadius < 30f) { snowRadius += 0.4f; } else { snowRadius += 0.1f; } snowRadius = Mathf.Min(snowRadius, Props.maxRadius); CellRect occupiedRect = parent.OccupiedRect(); reachableCells.Clear(); parent.Map.floodFiller.FloodFill(parent.Position, delegate(IntVec3 x) { if ((float)x.DistanceToSquared(parent.Position) > snowRadius * snowRadius) { return(false); } return(occupiedRect.Contains(x) || !x.Filled(parent.Map)); }, delegate(IntVec3 x) { reachableCells.Add(x); }); int num = GenRadial.NumCellsInRadius(snowRadius); for (int i = 0; i < num; i++) { IntVec3 intVec = parent.Position + GenRadial.RadialPattern[i]; if (intVec.InBounds(parent.Map) && reachableCells.Contains(intVec)) { float value = snowNoise.GetValue(intVec); value += 1f; value *= 0.5f; if (value < 0.1f) { value = 0.1f; } if (!(parent.Map.snowGrid.GetDepth(intVec) > value)) { float lengthHorizontal = (intVec - parent.Position).LengthHorizontal; float num2 = 1f - lengthHorizontal / snowRadius; parent.Map.snowGrid.AddDepth(intVec, num2 * Props.addAmount * value); } } } }
public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, ThingDef stuff, bool godMode = false, Thing thingToIgnore = null) { CellRect cellRect = GenAdj.OccupiedRect(center, rot, entDef.Size); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (!current.InBounds(map)) { return(new AcceptanceReport("OutOfBounds".Translate())); } if (current.InNoBuildEdgeArea(map) && !DebugSettings.godMode) { return("TooCloseToMapEdge".Translate()); } iterator.MoveNext(); } if (center.Fogged(map)) { return("CannotPlaceInUndiscovered".Translate()); } List <Thing> thingList = center.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing != thingToIgnore) { if (thing.Position == center && thing.Rotation == rot) { if (thing.def == entDef) { //Start my code, this code allows blueprint to be placed, so canPlaceOverWall can do it's thing. if (((walls.Contains(thing.def.defName) && walls.Contains(entDef.defName)) || (doors.Contains(thing.def.defName) && doors.Contains(entDef.defName))) && thing.Stuff != stuff) { return(AcceptanceReport.WasAccepted); } //End my code return(new AcceptanceReport("IdenticalThingExists".Translate())); } if (thing.def.entityDefToBuild == entDef) { if (thing is Blueprint) { return(new AcceptanceReport("IdenticalBlueprintExists".Translate())); } return(new AcceptanceReport("IdenticalThingExists".Translate())); } } } } ThingDef thingDef = entDef as ThingDef; if (thingDef != null && thingDef.hasInteractionCell) { IntVec3 c = ThingUtility.InteractionCellWhenAt(thingDef, center, rot, map); if (!c.InBounds(map)) { return(new AcceptanceReport("InteractionSpotOutOfBounds".Translate())); } List <Thing> list = map.thingGrid.ThingsListAtFast(c); for (int j = 0; j < list.Count; j++) { if (list[j] != thingToIgnore) { if (list[j].def.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotBlocked".Translate(new object[] { list[j].LabelNoCount }).CapitalizeFirst())); } Blueprint blueprint = list[j] as Blueprint; if (blueprint != null && blueprint.def.entityDefToBuild.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotWillBeBlocked".Translate(new object[] { blueprint.LabelNoCount }).CapitalizeFirst())); } } } } if (entDef.passability != Traversability.Standable) { foreach (IntVec3 current2 in GenAdj.CellsAdjacentCardinal(center, rot, entDef.Size)) { if (current2.InBounds(map)) { thingList = current2.GetThingList(map); for (int k = 0; k < thingList.Count; k++) { Thing thing2 = thingList[k]; if (thing2 != thingToIgnore) { Blueprint blueprint2 = thing2 as Blueprint; ThingDef thingDef3; if (blueprint2 != null) { ThingDef thingDef2 = blueprint2.def.entityDefToBuild as ThingDef; if (thingDef2 == null) { goto IL_37E; } thingDef3 = thingDef2; } else { thingDef3 = thing2.def; } if (thingDef3.hasInteractionCell && cellRect.Contains(ThingUtility.InteractionCellWhenAt(thingDef3, thing2.Position, thing2.Rotation, thing2.Map))) { return(new AcceptanceReport("WouldBlockInteractionSpot".Translate(new object[] { entDef.label, thingDef3.label }).CapitalizeFirst())); } } IL_37E :; } } } } TerrainDef terrainDef = entDef as TerrainDef; if (terrainDef != null) { if (map.terrainGrid.TerrainAt(center) == terrainDef) { return(new AcceptanceReport("TerrainIsAlready".Translate(new object[] { terrainDef.label }))); } if (map.designationManager.DesignationAt(center, DesignationDefOf.SmoothFloor) != null) { return(new AcceptanceReport("BeingSmoothed".Translate())); } } if (!GenConstruct.CanBuildOnTerrain(entDef, center, map, rot, thingToIgnore)) { return(new AcceptanceReport("TerrainCannotSupport".Translate())); } if (!godMode) { CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { thingList = iterator2.Current.GetThingList(map); for (int l = 0; l < thingList.Count; l++) { Thing thing3 = thingList[l]; if (thing3 != thingToIgnore) { if (!GenConstruct.CanPlaceBlueprintOver(entDef, thing3.def)) { //Start my code, entDef is new, thing3 is old //Allows for doors to replace each other only if different stuff or door <--> autodoor if (thing3?.def?.defName != null) { if ((doors.Contains(entDef.defName) && doors.Contains(thing3.def.defName)) && //New and old are both doors (thing3.Stuff != stuff || !entDef.defName.Equals(thing3.def.defName))) //Not the same stuff or not same thing { return(AcceptanceReport.WasAccepted); } //Allow placing over mineable if (thing3 is Mineable && (doors.Contains(entDef.defName) || walls.Contains(entDef.defName))) { return(AcceptanceReport.WasAccepted); } //Allow walls and doors to be placed over walls if ((walls.Contains(entDef.defName) || doors.Contains(entDef.defName)) && walls.Contains(thing3.def.defName)) { return(AcceptanceReport.WasAccepted); } //Allow replacing invisible power lines from PowerSwitch by Haplo if (conduits.Contains(entDef.defName) && conduits.Contains(thing3.def.defName)) { return(AcceptanceReport.WasAccepted); } } //End my code return(new AcceptanceReport("SpaceAlreadyOccupied".Translate())); } } } iterator2.MoveNext(); } } if (entDef.PlaceWorkers != null) { for (int m = 0; m < entDef.PlaceWorkers.Count; m++) { AcceptanceReport result = entDef.PlaceWorkers[m].AllowsPlacing(entDef, center, rot, map, thingToIgnore); if (!result.Accepted) { return(result); } } } return(AcceptanceReport.WasAccepted); }
protected override void ScatterAt(IntVec3 loc, Map map, int stackCount = 1) { // Once a mapcenter blueprint is placed, don't do anything more if (mapCenterBlueprintUsed) { return; } // After 5 min reset the saved cells! if (usedCells_lastChange.AddMinutes(5) < DateTime.UtcNow) { usedCells.Clear(); usedCells_lastChange = DateTime.UtcNow; } // update the usedSpots if (usedSpots != null && usedSpots.Count > 0) { foreach (IntVec3 usedSpot in usedSpots) { usedCells.Add(usedSpot); } usedCells_lastChange = DateTime.UtcNow; } MapGeneratorBlueprintDef blueprint; // Safety: only use blueprints where the size is smaller than the map size => Safety really needed? blueprint = DefDatabase <MapGeneratorBlueprintDef> .AllDefsListForReading .RandomElementByWeight((MapGeneratorBlueprintDef b) => b.chance); if (!blueprint.mapCenterBlueprint && blueprint.pawnLegend != null && blueprint.pawnLegend.Count > 0) { // Check if the loc is near the spawn location IntVec2 nogoCenter = new IntVec2(Find.World.info.initialMapSize.x / 2, Find.World.info.initialMapSize.z / 2); CellRect nogoCenterRect = new CellRect(nogoCenter.x, nogoCenter.z, 1, 1); nogoCenterRect = nogoCenterRect.ExpandedBy(20); if (nogoCenterRect.Contains(loc)) { // If loc is near the center, find new blueprint that doesn't contain any pawns blueprint = DefDatabase <MapGeneratorBlueprintDef> .AllDefsListForReading .Where(b => (b.pawnLegend == null || b.pawnLegend.Count == 0)) .RandomElementByWeight((MapGeneratorBlueprintDef b) => b.chance); } } if (blueprint == null) { return; } // if the blueprint is a map center blueprint, set the loc so that the center is at the map center if (blueprint.mapCenterBlueprint) { loc = new IntVec3(map.Center.x - (blueprint.size.x / 2), map.Center.y, map.Center.z - (blueprint.size.z / 2)); mapCenterBlueprintUsed = true; } // place a blueprint ruin //ScatterBlueprintAt(loc, map, blueprint, ref selectedWallStuff, this.usedSpots); try { ScatterBlueprintAt(loc, map, blueprint, ref selectedWallStuff, usedCells); } catch (Exception err) { Log.Error("Could not spawn blueprint '" + blueprint.defName + "'. Error: " + err.Message + "\n" + err.StackTrace); } // reset selectedWallStuff = null; }
// Token: 0x060029C1 RID: 10689 RVA: 0x0013C434 File Offset: 0x0013A834 private void TryExpandHive() { if (this.snowNoise == null) { this.snowNoise = new Perlin(5.074999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); //new Perlin(0.054999999701976776, 2.0, 0.5, 5, Rand.Range(0, 651431), QualityMode.Medium); } if (this.hiveRadius < 8f) { this.hiveRadius += 1.3f; } else if (this.hiveRadius < 17f) { this.hiveRadius += 0.7f; } else if (this.hiveRadius < 30f) { this.hiveRadius += 0.4f; } else { this.hiveRadius += 0.1f; } this.hiveRadius = this.maxRadius; // Mathf.Min(this.hiveRadius, this.maxRadius); CellRect occupiedRect = this.parent.OccupiedRect(); CompHiveCreep.reachableCells.Clear(); // Log.Message(string.Format("1")); this.parent.Map.floodFiller.FloodFill(this.parent.Position, (IntVec3 x) => (float)x.DistanceToSquared(this.parent.Position) <= this.hiveRadius * this.hiveRadius && (occupiedRect.Contains(x) || !x.Filled(this.parent.Map) && x.InBounds(this.parent.Map)), delegate(IntVec3 x) { CompHiveCreep.reachableCells.Add(x); }, int.MaxValue, false, null); // Log.Message(string.Format("2")); errors here V int num = GenRadial.NumCellsInRadius(this.hiveRadius); // Log.Message(string.Format("3")); errors here ^ for (int i = 0; i < num; i++) { // Log.Message(string.Format("3 {0} a", i), true); if ((this.parent.Position + GenRadial.RadialPattern[i]).InBounds(this.parent.Map)) { IntVec3 intVec = this.parent.Position + GenRadial.RadialPattern[i]; if (intVec.InBounds(this.parent.Map)) { // if (i % 50 == 0) Log.Message(string.Format("3 {0} b", i), true); if (CompHiveCreep.reachableCells.Contains(intVec)) { List <Thing> list = intVec.GetThingList(parent.Map); if (!list.NullOrEmpty()) { if (list.Any(x => x.def.IsFilth)) { foreach (var item in list.FindAll(x => x.def.IsFilth)) { if (Rand.ChanceSeeded(0.25f, AvPConstants.AvPSeed)) { item.Destroy(); } } } } // Log.Message(string.Format("3 {0} c", i)); float num2 = 1f; num2 += 1f; num2 *= 0.5f; if (num2 < 0.1f) { num2 = 0.1f; } if (this.parent.Map.GetComponent <MapComponent_HiveGrid>().GetDepth(intVec) <= num2) { // Log.Message(string.Format("3 {0} d", i)); float lengthHorizontal = (intVec - this.parent.Position).LengthHorizontal; float num3 = 1f - lengthHorizontal / this.hiveRadius; this.parent.Map.GetComponent <MapComponent_HiveGrid>().AddDepth(intVec, num3 * this.Props.addAmount * num2); // Log.Message(string.Format("3 {0} e", i)); } } } } } }
public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell) { if (DebugSettings.pathThroughWalls) { traverseParms.mode = TraverseMode.PassAllDestroyableThings; } Pawn pawn = traverseParms.pawn; if (pawn != null && pawn.Map != this.map) { Log.Error(string.Concat(new object[] { "Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=", pawn, " pawn.Map=", pawn.Map, " map=", this.map })); return(PawnPath.NotFound); } if (!start.IsValid) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid start ", start, ", pawn= ", pawn })); return(PawnPath.NotFound); } if (!dest.IsValid) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid dest ", dest, ", pawn= ", pawn })); return(PawnPath.NotFound); } if (traverseParms.mode == TraverseMode.ByPawn) { if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode)) { return(PawnPath.NotFound); } } else if (!this.map.reachability.CanReach(start, dest, peMode, traverseParms)) { return(PawnPath.NotFound); } this.PfProfilerBeginSample(string.Concat(new object[] { "FindPath for ", pawn, " from ", start, " to ", dest, (!dest.HasThing) ? string.Empty : (" at " + dest.Cell) })); this.cellIndices = this.map.cellIndices; this.pathGrid = this.map.pathGrid; this.edificeGrid = this.map.edificeGrid.InnerArray; int x = dest.Cell.x; int z = dest.Cell.z; int num = this.cellIndices.CellToIndex(start); int num2 = this.cellIndices.CellToIndex(dest.Cell); ByteGrid byteGrid = (pawn == null) ? null : pawn.GetAvoidGrid(); bool flag = traverseParms.mode == TraverseMode.PassAllDestroyableThings; bool flag2 = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater; bool flag3 = !flag; CellRect cellRect = this.CalculateDestinationRect(dest, peMode); bool flag4 = cellRect.Width == 1 && cellRect.Height == 1; int[] array = this.map.pathGrid.pathGrid; EdificeGrid edificeGrid = this.map.edificeGrid; int num3 = 0; int num4 = 0; Area allowedArea = this.GetAllowedArea(pawn); bool flag5 = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn); bool flag6 = true && DebugViewSettings.drawPaths; bool flag7 = !flag && start.GetRegion(this.map, RegionType.Set_Passable) != null; bool flag8 = !flag || !flag3; bool flag9 = false; int num5 = 0; int num6 = 0; float num7 = this.DetermineHeuristicStrength(pawn, start, dest); int num8; int num9; if (pawn != null) { num8 = pawn.TicksPerMoveCardinal; num9 = pawn.TicksPerMoveDiagonal; } else { num8 = 13; num9 = 18; } this.CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect); this.InitStatusesAndPushStartNode(ref num, start); while (true) { this.PfProfilerBeginSample("Open cell"); if (this.openList.Count <= 0) { break; } num5 += this.openList.Count; num6++; newPathFinder.CostNode costNode = this.openList.Pop(); num = costNode.index; if (costNode.cost != this.calcGrid[num].costNodeCost) { this.PfProfilerEndSample(); } else if (this.calcGrid[num].status == this.statusClosedValue) { this.PfProfilerEndSample(); } else { IntVec3 c = this.cellIndices.IndexToCell(num); int x2 = c.x; int z2 = c.z; if (flag6) { this.DebugFlash(c, (float)this.calcGrid[num].knownCost / 1500f, this.calcGrid[num].knownCost.ToString()); } if (flag4) { if (num == num2) { goto Block_27; } } else if (cellRect.Contains(c) && !this.disallowedCornerIndices.Contains(num)) { goto Block_29; } if (num3 > 160000) { goto Block_30; } this.PfProfilerEndSample(); this.PfProfilerBeginSample("Neighbor consideration"); for (int i = 0; i < 8; i++) { uint num10 = (uint)(x2 + newPathFinder.Directions[i]); uint num11 = (uint)(z2 + newPathFinder.Directions[i + 8]); if ((ulong)num10 < (ulong)((long)this.mapSizeX) && (ulong)num11 < (ulong)((long)this.mapSizeZ)) { int num12 = (int)num10; int num13 = (int)num11; int num14 = this.cellIndices.CellToIndex(num12, num13); if (this.calcGrid[num14].status != this.statusClosedValue || flag9) { int num15 = 0; bool flag10 = false; if (flag2 || !new IntVec3(num12, 0, num13).GetTerrain(this.map).HasTag("Water")) { if (!this.pathGrid.WalkableFast(num14)) { if (!flag) { if (flag6) { this.DebugFlash(new IntVec3(num12, 0, num13), 0.22f, "walk"); } goto IL_C2E; } flag10 = true; num15 += 70; Building building = edificeGrid[num14]; if (building == null) { goto IL_C2E; } if (!newPathFinder.IsDestroyable(building)) { goto IL_C2E; } num15 += (int)((float)building.HitPoints * 0.11f); } if (i > 3) { switch (i) { case 4: if (this.BlocksDiagonalMovement(num - this.mapSizeX)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } if (this.BlocksDiagonalMovement(num + 1)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } break; case 5: if (this.BlocksDiagonalMovement(num + this.mapSizeX)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } if (this.BlocksDiagonalMovement(num + 1)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } break; case 6: if (this.BlocksDiagonalMovement(num + this.mapSizeX)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } if (this.BlocksDiagonalMovement(num - 1)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } break; case 7: if (this.BlocksDiagonalMovement(num - this.mapSizeX)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } if (this.BlocksDiagonalMovement(num - 1)) { if (flag8) { if (flag6) { this.DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "corn"); } goto IL_C2E; } num15 += 70; } break; } } int num16 = (i <= 3) ? num8 : num9; num16 += num15; if (!flag10) { num16 += array[num14]; } if (byteGrid != null) { num16 += (int)(byteGrid[num14] * 8); } if (allowedArea != null && !allowedArea[num14]) { num16 += 600; } if (flag5 && PawnUtility.AnyPawnBlockingPathAt(new IntVec3(num12, 0, num13), pawn, false, false)) { num16 += 175; } Building building2 = this.edificeGrid[num14]; if (building2 != null) { this.PfProfilerBeginSample("Edifices"); int buildingCost = newPathFinder.GetBuildingCost(building2, traverseParms, pawn); if (buildingCost == 2147483647) { this.PfProfilerEndSample(); goto IL_C2E; } num16 += buildingCost; this.PfProfilerEndSample(); } int num17 = num16 + this.calcGrid[num].knownCost; ushort status = this.calcGrid[num14].status; if (status == this.statusClosedValue || status == this.statusOpenValue) { int num18 = 0; if (status == this.statusClosedValue) { num18 = num8; } if (this.calcGrid[num14].knownCost <= num17 + num18) { goto IL_C2E; } } if (status != this.statusClosedValue && status != this.statusOpenValue) { if (flag9) { this.calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)this.regionCostCalculator.GetPathCostFromDestToRegion(num14) * newPathFinder.RegionHeuristicWeightByNodesOpened.Evaluate((float)num4)); } else { int dx = Math.Abs(num12 - x); int dz = Math.Abs(num13 - z); int num19 = GenMath.OctileDistance(dx, dz, num8, num9); this.calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num19 * num7); } } int num20 = num17 + this.calcGrid[num14].heuristicCost; this.calcGrid[num14].parentIndex = num; this.calcGrid[num14].knownCost = num17; this.calcGrid[num14].status = this.statusOpenValue; this.calcGrid[num14].costNodeCost = num20; num4++; this.openList.Push(new newPathFinder.CostNode(num14, num20)); } } } IL_C2E :; } this.PfProfilerEndSample(); num3++; this.calcGrid[num].status = this.statusClosedValue; if (num4 >= 2000 && flag7 && !flag9) { flag9 = true; this.regionCostCalculator.Init(cellRect, traverseParms, num8, num9, byteGrid, allowedArea, this.disallowedCornerIndices); this.InitStatusesAndPushStartNode(ref num, start); num4 = 0; num3 = 0; } } } string text = (pawn == null || pawn.CurJob == null) ? "null" : pawn.CurJob.ToString(); string text2 = (pawn == null || pawn.Faction == null) ? "null" : pawn.Faction.ToString(); Log.Warning(string.Concat(new object[] { pawn, " pathing from ", start, " to ", dest, " ran out of cells to process.\nJob:", text, "\nFaction: ", text2 })); this.DebugDrawRichData(); this.PfProfilerEndSample(); return(PawnPath.NotFound); Block_27: this.PfProfilerEndSample(); PawnPath result = this.FinalizedPath(num); this.PfProfilerEndSample(); return(result); Block_29: this.PfProfilerEndSample(); PawnPath result2 = this.FinalizedPath(num); this.PfProfilerEndSample(); return(result2); Block_30: Log.Warning(string.Concat(new object[] { pawn, " pathing from ", start, " to ", dest, " hit search limit of ", 160000, " cells." })); this.DebugDrawRichData(); this.PfProfilerEndSample(); return(PawnPath.NotFound); }
public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode = false, Thing thingToIgnore = null) { CellRect cellRect = GenAdj.OccupiedRect(center, rot, entDef.Size); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (!current.InBounds(map)) { return(new AcceptanceReport("OutOfBounds".Translate())); } if (current.InNoBuildEdgeArea(map) && !DebugSettings.godMode && entDef != ThingDefOf.DeepDrill) { return("TooCloseToMapEdge".Translate()); } iterator.MoveNext(); } if (center.Fogged(map)) { return("CannotPlaceInUndiscovered".Translate()); } List <Thing> thingList = center.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing != thingToIgnore) { if (thing.Position == center && thing.Rotation == rot) { if (thing.def == entDef) { return(new AcceptanceReport("IdenticalThingExists".Translate())); } if (thing.def.entityDefToBuild == entDef) { if (thing is Blueprint) { return(new AcceptanceReport("IdenticalBlueprintExists".Translate())); } return(new AcceptanceReport("IdenticalThingExists".Translate())); } } } } ThingDef thingDef = entDef as ThingDef; if (thingDef != null && thingDef.hasInteractionCell) { IntVec3 c = Thing.InteractionCellWhenAt(thingDef, center, rot, map); if (!c.InBounds(map)) { return(new AcceptanceReport("InteractionSpotOutOfBounds".Translate())); } List <Thing> list = map.thingGrid.ThingsListAtFast(c); for (int j = 0; j < list.Count; j++) { if (list[j] != thingToIgnore) { if (list[j].def.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotBlocked".Translate(list[j].LabelNoCount).CapitalizeFirst())); } Blueprint blueprint = list[j] as Blueprint; if (blueprint != null && blueprint.def.entityDefToBuild.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotWillBeBlocked".Translate(blueprint.LabelNoCount).CapitalizeFirst())); } } } } if (entDef.passability != Traversability.Standable) { foreach (IntVec3 current2 in GenAdj.CellsAdjacentCardinal(center, rot, entDef.Size)) { if (current2.InBounds(map)) { thingList = current2.GetThingList(map); for (int k = 0; k < thingList.Count; k++) { Thing thing2 = thingList[k]; if (thing2 != thingToIgnore) { Blueprint blueprint2 = thing2 as Blueprint; ThingDef thingDef3; if (blueprint2 != null) { ThingDef thingDef2 = blueprint2.def.entityDefToBuild as ThingDef; if (thingDef2 == null) { goto IL_37E; } thingDef3 = thingDef2; } else { thingDef3 = thing2.def; } if (thingDef3.hasInteractionCell && cellRect.Contains(Thing.InteractionCellWhenAt(thingDef3, thing2.Position, thing2.Rotation, thing2.Map))) { return(new AcceptanceReport("WouldBlockInteractionSpot".Translate(entDef.label, thingDef3.label).CapitalizeFirst())); } } IL_37E :; } } } } TerrainDef terrainDef = entDef as TerrainDef; if (terrainDef != null) { if (map.terrainGrid.TerrainAt(center) == terrainDef) { return(new AcceptanceReport("TerrainIsAlready".Translate(terrainDef.label))); } if (map.designationManager.DesignationAt(center, DesignationDefOf.SmoothFloor) != null) { return(new AcceptanceReport("BeingSmoothed".Translate())); } } if (!GenConstruct.CanBuildOnTerrain(entDef, center, map, rot, thingToIgnore)) { return(new AcceptanceReport("TerrainCannotSupport".Translate())); } if (!godMode) { CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { thingList = iterator2.Current.GetThingList(map); for (int l = 0; l < thingList.Count; l++) { Thing thing3 = thingList[l]; if (thing3 != thingToIgnore) { if (!GenConstruct.CanPlaceBlueprintOver(entDef, thing3.def)) { return(new AcceptanceReport("SpaceAlreadyOccupied".Translate())); } } } iterator2.MoveNext(); } } if (entDef.PlaceWorkers != null) { for (int m = 0; m < entDef.PlaceWorkers.Count; m++) { AcceptanceReport result = entDef.PlaceWorkers[m].AllowsPlacing(entDef, center, rot, thingToIgnore); if (!result.Accepted) { return(result); } } } return(AcceptanceReport.WasAccepted); }
public static bool TryFindSpawnCellAroundOrNear(CellRect around, IntVec3 near, Map map, out IntVec3 spawnCell) { if (near.IsValid) { if (!CellFinder.TryFindRandomSpawnCellForPawnNear(near, map, out spawnCell, 10)) { return(false); } } else if (!CellFinder.TryFindRandomCellInsideWith(around.ExpandedBy(8), (IntVec3 x) => !around.Contains(x) && x.InBounds(map) && x.Standable(map) && !x.Fogged(map), out spawnCell)) { return(false); } return(true); }
private void GenerateRiverLookupTexture(Map map, RiverMaker riverMaker) { int num = Mathf.CeilToInt(DefDatabase <RiverDef> .AllDefs.Select((RiverDef rd) => rd.widthOnMap / 2f + 8f).Max()); int num2 = Mathf.Max(4, num) * 2; Dictionary <int, GRLT_Entry> dictionary = new Dictionary <int, GRLT_Entry>(); Dictionary <int, GRLT_Entry> dictionary2 = new Dictionary <int, GRLT_Entry>(); Dictionary <int, GRLT_Entry> dictionary3 = new Dictionary <int, GRLT_Entry>(); for (int i = -num2; i < map.Size.z + num2; i++) { for (int j = -num2; j < map.Size.x + num2; j++) { IntVec3 intVec = new IntVec3(j, 0, i); Vector3 vector = riverMaker.WaterCoordinateAt(intVec); int entryId = Mathf.FloorToInt(vector.z / 4f); UpdateRiverAnchorEntry(dictionary, intVec, entryId, (vector.z + Mathf.Abs(vector.x)) / 4f); UpdateRiverAnchorEntry(dictionary2, intVec, entryId, (vector.z + Mathf.Abs(vector.x - (float)num)) / 4f); UpdateRiverAnchorEntry(dictionary3, intVec, entryId, (vector.z + Mathf.Abs(vector.x + (float)num)) / 4f); } } int num3 = Mathf.Max(dictionary.Keys.Min(), dictionary2.Keys.Min(), dictionary3.Keys.Min()); int num4 = Mathf.Min(dictionary.Keys.Max(), dictionary2.Keys.Max(), dictionary3.Keys.Max()); for (int k = num3; k < num4; k++) { WaterInfo waterInfo = map.waterInfo; if (dictionary2.ContainsKey(k) && dictionary2.ContainsKey(k + 1)) { waterInfo.riverDebugData.Add(dictionary2[k].bestNode.ToVector3Shifted()); waterInfo.riverDebugData.Add(dictionary2[k + 1].bestNode.ToVector3Shifted()); } if (dictionary.ContainsKey(k) && dictionary.ContainsKey(k + 1)) { waterInfo.riverDebugData.Add(dictionary[k].bestNode.ToVector3Shifted()); waterInfo.riverDebugData.Add(dictionary[k + 1].bestNode.ToVector3Shifted()); } if (dictionary3.ContainsKey(k) && dictionary3.ContainsKey(k + 1)) { waterInfo.riverDebugData.Add(dictionary3[k].bestNode.ToVector3Shifted()); waterInfo.riverDebugData.Add(dictionary3[k + 1].bestNode.ToVector3Shifted()); } if (dictionary2.ContainsKey(k) && dictionary.ContainsKey(k)) { waterInfo.riverDebugData.Add(dictionary2[k].bestNode.ToVector3Shifted()); waterInfo.riverDebugData.Add(dictionary[k].bestNode.ToVector3Shifted()); } if (dictionary.ContainsKey(k) && dictionary3.ContainsKey(k)) { waterInfo.riverDebugData.Add(dictionary[k].bestNode.ToVector3Shifted()); waterInfo.riverDebugData.Add(dictionary3[k].bestNode.ToVector3Shifted()); } } CellRect cellRect = new CellRect(-2, -2, map.Size.x + 4, map.Size.z + 4); float[] array = new float[cellRect.Area * 2]; int num5 = 0; for (int l = cellRect.minZ; l <= cellRect.maxZ; l++) { for (int m = cellRect.minX; m <= cellRect.maxX; m++) { IntVec3 a = new IntVec3(m, 0, l); bool flag = true; for (int n = 0; n < GenAdj.AdjacentCellsAndInside.Length; n++) { if (riverMaker.TerrainAt(a + GenAdj.AdjacentCellsAndInside[n]) != null) { flag = false; break; } } if (!flag) { Vector2 p = a.ToIntVec2.ToVector2(); int num6 = int.MinValue; Vector2 vector2 = Vector2.zero; for (int num7 = num3; num7 < num4; num7++) { if (dictionary2.ContainsKey(num7) && dictionary2.ContainsKey(num7 + 1) && dictionary.ContainsKey(num7) && dictionary.ContainsKey(num7 + 1) && dictionary3.ContainsKey(num7) && dictionary3.ContainsKey(num7 + 1)) { Vector2 p2 = dictionary2[num7].bestNode.ToIntVec2.ToVector2(); Vector2 p3 = dictionary2[num7 + 1].bestNode.ToIntVec2.ToVector2(); Vector2 p4 = dictionary[num7].bestNode.ToIntVec2.ToVector2(); Vector2 p5 = dictionary[num7 + 1].bestNode.ToIntVec2.ToVector2(); Vector2 p6 = dictionary3[num7].bestNode.ToIntVec2.ToVector2(); Vector2 p7 = dictionary3[num7 + 1].bestNode.ToIntVec2.ToVector2(); Vector2 vector3 = GenGeo.InverseQuadBilinear(p, p4, p2, p5, p3); if (vector3.x >= -0.0001f && vector3.x <= 1.0001f && vector3.y >= -0.0001f && vector3.y <= 1.0001f) { vector2 = new Vector2((0f - vector3.x) * (float)num, (vector3.y + (float)num7) * 4f); num6 = num7; break; } Vector2 vector4 = GenGeo.InverseQuadBilinear(p, p4, p6, p5, p7); if (vector4.x >= -0.0001f && vector4.x <= 1.0001f && vector4.y >= -0.0001f && vector4.y <= 1.0001f) { vector2 = new Vector2(vector4.x * (float)num, (vector4.y + (float)num7) * 4f); num6 = num7; break; } } } array[num5] = vector2.x; array[num5 + 1] = vector2.y; } num5 += 2; } } float[] array2 = new float[cellRect.Area * 2]; float[] array3 = new float[9] { 0.123317f, 0.123317f, 0.123317f, 0.123317f, 0.077847f, 0.077847f, 0.077847f, 0.077847f, 0.195346f }; int num8 = 0; for (int num9 = cellRect.minZ; num9 <= cellRect.maxZ; num9++) { for (int num10 = cellRect.minX; num10 <= cellRect.maxX; num10++) { IntVec3 a2 = new IntVec3(num10, 0, num9); float num11 = 0f; float num12 = 0f; float num13 = 0f; for (int num14 = 0; num14 < GenAdj.AdjacentCellsAndInside.Length; num14++) { IntVec3 c = a2 + GenAdj.AdjacentCellsAndInside[num14]; if (cellRect.Contains(c)) { int num15 = num8 + (GenAdj.AdjacentCellsAndInside[num14].x + GenAdj.AdjacentCellsAndInside[num14].z * cellRect.Width) * 2; if (array[num15] != 0f || array[num15 + 1] != 0f) { num11 += array[num15] * array3[num14]; num12 += array[num15 + 1] * array3[num14]; num13 += array3[num14]; } } } if (num13 > 0f) { array2[num8] = num11 / num13; array2[num8 + 1] = num12 / num13; } num8 += 2; } } array = array2; for (int num16 = 0; num16 < array.Length; num16 += 2) { if (array[num16] != 0f || array[num16 + 1] != 0f) { Vector2 vector5 = Rand.InsideUnitCircle * 0.4f; array[num16] += vector5.x; array[num16 + 1] += vector5.y; } } byte[] array4 = new byte[array.Length * 4]; Buffer.BlockCopy(array, 0, array4, 0, array.Length * 4); map.waterInfo.riverOffsetMap = array4; map.waterInfo.GenerateRiverFlowMap(); }
public static bool TryFindBestWatchCell(Thing toWatch, Pawn pawn, bool desireSit, out IntVec3 result, out Building chair) { List <int> list = WatchBuildingUtility.CalculateAllowedDirections(toWatch.def, toWatch.Rotation); IntVec3 intVec = IntVec3.Invalid; for (int i = 0; i < list.Count; i++) { CellRect watchCellRect = WatchBuildingUtility.GetWatchCellRect(toWatch.def, toWatch.Position, toWatch.Rotation, list[i]); IntVec3 centerCell = watchCellRect.CenterCell; int num = watchCellRect.Area * 4; for (int j = 0; j < num; j++) { IntVec3 intVec2 = centerCell + GenRadial.RadialPattern[j]; if (watchCellRect.Contains(intVec2)) { bool flag = false; Building building = null; if (WatchBuildingUtility.EverPossibleToWatchFrom(intVec2, toWatch.Position, toWatch.Map, false) && !intVec2.IsForbidden(pawn) && pawn.CanReserve(intVec2, 1, -1, null, false) && pawn.Map.pawnDestinationReservationManager.CanReserve(intVec2, pawn, false)) { if (desireSit) { building = intVec2.GetEdifice(pawn.Map); if (building != null && building.def.building.isSittable && pawn.CanReserve(building, 1, -1, null, false)) { flag = true; } } else { flag = true; } } if (flag) { if (desireSit) { Rot4 rotation = building.Rotation; Rot4 rot = new Rot4(list[i]); if (rotation != rot.Opposite) { intVec = intVec2; goto IL_191; } } result = intVec2; chair = building; return(true); } IL_191 :; } } } if (intVec.IsValid) { result = intVec; chair = intVec.GetEdifice(pawn.Map); return(true); } result = IntVec3.Invalid; chair = null; return(false); }
public bool IsInBounds(int x, int z) { return(bounds.Contains(Coords(x, z))); }
public static bool Prefix(MethodBase __originalMethod, DynamicDrawManager __instance) { if (!Active) { return(true); } __instance.drawingNow = true; try { bool[] fogGrid = __instance.map.fogGrid.fogGrid; CellRect cellRect = Find.CameraDriver.CurrentViewRect; cellRect.ClipInsideMap(__instance.map); cellRect = cellRect.ExpandedBy(1); CellIndices cellIndices = __instance.map.cellIndices; foreach (Thing thing in __instance.drawThings) { IntVec3 position = thing.Position; if (cellRect.Contains(position) || thing.def.drawOffscreen) { if (!fogGrid[cellIndices.CellToIndex(position)] || thing.def.seeThroughFog) { if (thing.def.hideAtSnowDepth >= 1f || __instance.map.snowGrid.GetDepth(thing.Position) <= thing.def.hideAtSnowDepth) { try { string Namer() { string n = string.Empty; if (ByDef) { n = $"{thing.def.defName} - {thing?.def?.modContentPack?.Name}"; } else { n = thing.GetType().ToString(); } return(n); } string name = string.Empty; if (ByDef) { name = thing.def.defName; } else { name = thing.GetType().Name; } var prof = ProfileController.Start(name, Namer, thing.GetType(), thing.def, null, __originalMethod); thing.Draw(); prof.Stop(); } catch (Exception ex) { Log.Error(string.Concat("Exception drawing ", thing, ": ", ex.ToString())); } } } } } } catch (Exception arg) { Log.Error("Exception drawing dynamic things: " + arg); } __instance.drawingNow = false; return(false); }