// Token: 0x060047BA RID: 18362 RVA: 0x0021ADFC File Offset: 0x002191FC public override void Regenerate() { LayerSubMesh subMesh = base.GetSubMesh(this.HiveMaterial); if (subMesh.mesh.vertexCount == 0) { SectionLayerGeometryMaker_Solid.MakeBaseGeometry(this.section, subMesh, AltitudeLayer.Terrain); } subMesh.Clear(MeshParts.Colors); MapComponent_HiveGrid _AvPHiveCreep = base.Map.GetComponent <MapComponent_HiveGrid>(); // Log.Message(string.Format(" 6 {0}", _AvPHiveCreep.DepthGridDirect_Unsafe)); float[] depthGridDirect_Unsafe = _AvPHiveCreep.DepthGridDirect_Unsafe; CellRect cellRect = this.section.CellRect; int num = base.Map.Size.z - 1; int num2 = base.Map.Size.x - 1; bool flag = false; CellIndices cellIndices = base.Map.cellIndices; for (int i = cellRect.minX; i <= cellRect.maxX; i++) { for (int j = cellRect.minZ; j <= cellRect.maxZ; j++) { float num3 = depthGridDirect_Unsafe[cellIndices.CellToIndex(i, j)]; int num4 = cellIndices.CellToIndex(i, j - 1); float num5 = (j <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i - 1, j - 1); float num6 = (j <= 0 || i <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i - 1, j); float num7 = (i <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i - 1, j + 1); float num8 = (j >= num || i <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i, j + 1); float num9 = (j >= num) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i + 1, j + 1); float num10 = (j >= num || i >= num2) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i + 1, j); float num11 = (i >= num2) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i + 1, j - 1); float num12 = (j <= 0 || i >= num2) ? num3 : depthGridDirect_Unsafe[num4]; this.vertDepth[0] = (num5 + num6 + num7 + num3) / 4f; this.vertDepth[1] = (num7 + num3) / 2f; this.vertDepth[2] = (num7 + num8 + num9 + num3) / 4f; this.vertDepth[3] = (num9 + num3) / 2f; this.vertDepth[4] = (num9 + num10 + num11 + num3) / 4f; this.vertDepth[5] = (num11 + num3) / 2f; this.vertDepth[6] = (num11 + num12 + num5 + num3) / 4f; this.vertDepth[7] = (num5 + num3) / 2f; this.vertDepth[8] = num3; for (int k = 0; k < 9; k++) { if (this.vertDepth[k] > 0.01f) { ; flag = true; } subMesh.colors.Add(SectionLayer_Hive.HiveDepthColor(this.vertDepth[k])); } } } if (flag) { subMesh.disabled = false; subMesh.FinalizeMesh(MeshParts.Colors); } else { subMesh.disabled = true; } }
public void OnCellClicked(CellIndices indices) { targetGame.OnCellClicked(indices); }
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); }
private static void _Regenerate(this object obj) { if (!MatBases.SunShadow.shader.isSupported) { return; } Section section = obj.Section(); var sectionLayer = obj as SectionLayer; LayerSubMesh subMesh = sectionLayer.GetSubMesh(MatBases.IndoorMask); subMesh.Clear(MeshParts.All); Building[] innerArray = Find.EdificeGrid.InnerArray; CellRect cellRect = new CellRect( section.botLeft.x, section.botLeft.z, 17, 17); cellRect.ClipInsideMap(); subMesh.verts.Capacity = cellRect.Area * 2; subMesh.tris.Capacity = cellRect.Area * 4; float y = Altitudes.AltitudeFor(AltitudeLayer.MetaOverlays); for (int index1 = cellRect.minX; index1 <= cellRect.maxX; ++index1) { for (int index2 = cellRect.minZ; index2 <= cellRect.maxZ; ++index2) { IntVec3 c1 = new IntVec3(index1, 0, index2); if (!(bool)_HideRainPrimary.Invoke(obj, new System.Object[] { c1 })) { bool flag1 = c1.Roofed(); bool flag2 = false; if (flag1) { for (int index3 = 0; index3 < 8; ++index3) { IntVec3 c2 = c1 + GenAdj.AdjacentCells[index3]; if ( (c2.InBounds()) && (!(bool)_HideRainPrimary.Invoke(obj, new System.Object[] { c2 })) ) { flag2 = true; break; } } } if ( (!flag1) || (!flag2) ) { continue; } } Thing thing = innerArray[CellIndices.CellToIndex(index1, index2)]; float num = (thing == null) || (thing.def.passability != Traversability.Impassable) && ( (thing.def.thingClass != typeof(Building_Door)) || (!thing.def.thingClass.IsSubclassOf(typeof(Building_Door))) ) ? 0.16f : 0.0f; subMesh.verts.Add(new Vector3((float)index1 - num, y, (float)index2 - num)); subMesh.verts.Add(new Vector3((float)index1 - num, y, (float)(index2 + 1) + num)); subMesh.verts.Add(new Vector3((float)(index1 + 1) + num, y, (float)(index2 + 1) + num)); subMesh.verts.Add(new Vector3((float)(index1 + 1) + num, y, (float)index2 - num)); int count = subMesh.verts.Count; subMesh.tris.Add(count - 4); subMesh.tris.Add(count - 3); subMesh.tris.Add(count - 2); subMesh.tris.Add(count - 4); subMesh.tris.Add(count - 2); subMesh.tris.Add(count - 1); } } if (subMesh.verts.Count <= 0) { return; } subMesh.FinalizeMesh(MeshParts.Verts | MeshParts.Tris); }
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 bool Equals(CellIndices other) { return(EqualsImpl(ref this, ref other)); }
public Cell(CellIndices correctPosition) { this.correctPosition = correctPosition; }
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 bool FloodFill(FloodFiller __instance, IntVec3 root, Predicate <IntVec3> passCheck, Func <IntVec3, int, bool> processor, int maxCellsToProcess = 2147483647, bool rememberParents = false, IEnumerable <IntVec3> extraRoots = null) { lock (__instance) { if (__instance.working) { Log.Error("Nested FloodFill calls are not allowed. This will cause bugs."); } __instance.working = true; __instance.ClearVisited(); if (rememberParents && __instance.parentGrid == null) { __instance.parentGrid = new CellGrid(__instance.map); } if (root.IsValid && extraRoots == null && !passCheck(root)) { if (rememberParents) { __instance.parentGrid[root] = IntVec3.Invalid; } __instance.working = false; } else { int area = __instance.map.Area; IntVec3[] directionsAround = GenAdj.CardinalDirectionsAround; int length = directionsAround.Length; CellIndices cellIndices = __instance.map.cellIndices; int num1 = 0; __instance.openSet.Clear(); if (root.IsValid) { int index = cellIndices.CellToIndex(root); __instance.visited.Add(index); __instance.traversalDistance[index] = 0; __instance.openSet.Enqueue(root); } if (extraRoots != null) { if (extraRoots is IList <IntVec3> intVec3List) { for (int index1 = 0; index1 < intVec3List.Count; ++index1) { int index2 = cellIndices.CellToIndex(intVec3List[index1]); __instance.visited.Add(index2); __instance.traversalDistance[index2] = 0; __instance.openSet.Enqueue(intVec3List[index1]); } } else { foreach (IntVec3 extraRoot in extraRoots) { int index = cellIndices.CellToIndex(extraRoot); __instance.visited.Add(index); __instance.traversalDistance[index] = 0; __instance.openSet.Enqueue(extraRoot); } } } if (rememberParents) { for (int index = 0; index < __instance.visited.Count; ++index) { IntVec3 cell = cellIndices.IndexToCell(__instance.visited[index]); __instance.parentGrid[__instance.visited[index]] = passCheck(cell) ? cell : IntVec3.Invalid; } } while (__instance.openSet.Count > 0) { IntVec3 c1 = __instance.openSet.Dequeue(); int num2 = __instance.traversalDistance[cellIndices.CellToIndex(c1)]; if (!processor(c1, num2)) { ++num1; if (num1 != maxCellsToProcess) { for (int index1 = 0; index1 < length; ++index1) { IntVec3 c2 = c1 + directionsAround[index1]; int index2 = cellIndices.CellToIndex(c2); if (!c2.InBounds(__instance.map) || __instance.traversalDistance[index2] != -1 || !passCheck(c2)) { continue; } __instance.visited.Add(index2); __instance.openSet.Enqueue(c2); __instance.traversalDistance[index2] = num2 + 1; if (rememberParents) { __instance.parentGrid[index2] = c1; } } if (__instance.openSet.Count <= area) { continue; } Log.Error("Overflow on flood fill (>" + area + " cells). Make sure we're not flooding over the same area after we check it."); __instance.working = false; return(false); } } break; } __instance.working = false; } } return(false); }
public static void InitStatusesAndPushStartNode3(ref int curIndex, IntVec3 start, CellIndices cellIndices, PathFinderNodeFast[] calcGrid, ref ushort local_statusOpenValue, ref ushort local_statusClosedValue) { local_statusOpenValue += 2; local_statusClosedValue += 2; if (local_statusClosedValue >= 65435) { int num = calcGrid.Length; for (int i = 0; i < num; i++) { calcGrid[i].status = 0; } local_statusOpenValue = 1; local_statusClosedValue = 2; } openValues[Thread.CurrentThread.ManagedThreadId] = local_statusOpenValue; closedValues[Thread.CurrentThread.ManagedThreadId] = local_statusClosedValue; curIndex = cellIndices.CellToIndex(start); calcGrid[curIndex].knownCost = 0; calcGrid[curIndex].heuristicCost = 0; calcGrid[curIndex].costNodeCost = 0; calcGrid[curIndex].parentIndex = curIndex; calcGrid[curIndex].status = local_statusOpenValue; //fastPriorityQueue.Clear(); //object newCostNode = constructorCostNode.Invoke(new object[] { curIndex, 0 }); //fastPriorityQueue.Push(newCostNode); }
public static PawnPath FinalizedPath2(int finalIndex, bool usedRegionHeuristics, CellIndices cellIndices, PathFinderNodeFast[] calcGrid) { //HACK - fix pool //PawnPath emptyPawnPath = map(__instance).pawnPathPool.GetEmptyPawnPath(); PawnPath emptyPawnPath = new PawnPath(); int num = finalIndex; while (true) { int parentIndex = calcGrid[num].parentIndex; emptyPawnPath.AddNode(cellIndices.IndexToCell(num)); if (num == parentIndex) { break; } num = parentIndex; } emptyPawnPath.SetupFound(calcGrid[finalIndex].knownCost, usedRegionHeuristics); return(emptyPawnPath); }
public static void InitStatusesAndPushStartNode2(ref int curIndex, IntVec3 start, CellIndices cellIndices, PathFinderNodeFast[] pathFinderNodeFast, FastPriorityQueue <CostNode2> fastPriorityQueue, ref ushort local_statusOpenValue, ref ushort local_statusClosedValue) { local_statusOpenValue += 2; local_statusClosedValue += 2; if (local_statusClosedValue >= 65435) { int num = pathFinderNodeFast.Length; for (int i = 0; i < num; i++) { pathFinderNodeFast[i].status = 0; } local_statusOpenValue = 1; local_statusClosedValue = 2; } curIndex = cellIndices.CellToIndex(start); pathFinderNodeFast[curIndex].knownCost = 0; pathFinderNodeFast[curIndex].heuristicCost = 0; pathFinderNodeFast[curIndex].costNodeCost = 0; pathFinderNodeFast[curIndex].parentIndex = curIndex; pathFinderNodeFast[curIndex].status = local_statusOpenValue; fastPriorityQueue.Clear(); //CostNode2 newCostNode = constructorCostNode.Invoke(new object[] { curIndex, 0 }); fastPriorityQueue.Push(new CostNode2(curIndex, 0)); }
internal static void AddFloodGlowFor(this GlowFlooder g, CompGlower theGlower) { if (g.GetCalcGrid() == null) { MethodInfo method = typeof(GlowFlooder).GetMethod("InitializeWorkingData", BindingFlags.Default | BindingFlags.NonPublic); method.Invoke(g, new object[] { }); } typeof(GlowFlooder).GetField("glowGrid", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(g, g.GetMap().glowGrid.glowGrid); typeof(GlowFlooder).GetField("glower", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(g, theGlower); Thing[] innerArray = g.GetMap().edificeGrid.InnerArray; typeof(GlowFlooder).GetField("unseenVal", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(g, g.GetUnseenVal() + 3u ); typeof(GlowFlooder).GetField("openVal", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(g, g.GetOpenVal() + 3u ); typeof(GlowFlooder).GetField("finalizedVal", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(g, g.GetFinalizedVal() + 3u ); IntVec3 position = g.GetGlower().parent.Position; typeof(GlowFlooder).GetField("attenLinearSlope", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(g, -1f / g.GetGlower().Props.glowRadius); int num = Mathf.RoundToInt(g.GetGlower().Props.glowRadius * 100f); IntVec3 intVec = default(IntVec3); IntVec3 c = default(IntVec3); int num2 = 0; CellIndices cellIndices = g.GetMap().cellIndices; g.GetOpenSet().Clear(); int num3 = (position.z << (int)g.GetGridSizeZLog2()) + position.x; g.GetCalcGrid()[num3].intDist = 100; g.GetOpenSet().Push(num3); while (g.GetOpenSet().Count != 0) { int num4 = g.GetOpenSet().Pop(); intVec.x = (int)((ushort)(num4 & (int)g.GetGridSizeXMinus1())); intVec.z = (int)((ushort)(num4 >> (int)g.GetGridSizeZLog2())); g.GetCalcGrid()[num4].status = g.GetFinalizedVal(); MethodInfo method0 = typeof(GlowFlooder).GetMethod("SetGlowGridFromDist", BindingFlags.Default | BindingFlags.NonPublic); method0.Invoke(g, new object[] { intVec }); if (UnityData.isDebugBuild && DebugViewSettings.drawGlow) { g.GetMap().debugDrawer.FlashCell(intVec, (float)g.GetCalcGrid()[num4].intDist / 10f, g.GetCalcGrid()[num4].intDist.ToString("F2")); num2++; } for (int i = 0; i < 8; i++) { c.x = (int)((ushort)(intVec.x + (int)_GlowFlooder.Directions[i, 0])); c.z = (int)((ushort)(intVec.z + (int)_GlowFlooder.Directions[i, 1])); int num5 = (c.z << (int)g.GetGridSizeZLog2()) + c.x; if (c.InBounds(g.GetMap())) { if (g.GetCalcGrid()[num5].status != g.GetFinalizedVal()) { g.GetBlockers()[i] = innerArray[cellIndices.CellToIndex(c)]; if (g.GetBlockers()[i] != null) { if (g.GetBlockers()[i].def.blockLight) { goto IL_47C; } g.GetBlockers()[i] = null; } int num6; if (i < 4) { num6 = 100; } else { num6 = 141; } int num7 = g.GetCalcGrid()[num4].intDist + num6; if (num7 <= num) { if (g.GetCalcGrid()[num5].status != g.GetFinalizedVal()) { if (i >= 4) { bool flag = false; switch (i) { case 4: if (g.GetBlockers()[0] != null && g.GetBlockers()[1] != null) { flag = true; } break; case 5: if (g.GetBlockers()[1] != null && g.GetBlockers()[2] != null) { flag = true; } break; case 6: if (g.GetBlockers()[2] != null && g.GetBlockers()[3] != null) { flag = true; } break; case 7: if (g.GetBlockers()[0] != null && g.GetBlockers()[3] != null) { flag = true; } break; } if (flag) { goto IL_47C; } } if (g.GetCalcGrid()[num5].status <= g.GetUnseenVal()) { g.GetCalcGrid()[num5].intDist = 999999; g.GetCalcGrid()[num5].status = g.GetOpenVal(); } if (num7 < g.GetCalcGrid()[num5].intDist) { g.GetCalcGrid()[num5].intDist = num7; g.GetCalcGrid()[num5].status = g.GetOpenVal(); g.GetOpenSet().Push(num5); } } } } } IL_47C :; } } }
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); }
// METHODS public override void CreateObstacles(Cell[,] canvas, int rowsAmount, int colsAmount, float cellWidth, float cellHeight) { sets.Clear(); listSets.Clear(); // save every odd indices in their own set for (int i = 1; i < rowsAmount - 1; i += 2) { for (int j = 1; j < colsAmount - 1; j += 2) { CellIndices indices = new CellIndices(i, j); sets.MakeSet(indices); listSets.Add(indices); } } int index = 0; // while there is more than one set while (sets.SetsAmount != 1) { // take element CellIndices firstCell = listSets[index++ % listSets.Count]; // take another one horizontal OR vertical with random chances int h; int v; double firstRand = random.NextDouble(); if (firstRand < 0.3) { h = -2; } else if (firstRand > 0.6) { h = 2; } else { h = 0; } if (h == 0) { v = random.NextDouble() < 0.5 ? 2 : -2; } else { v = 0; } CellIndices secondCell = new CellIndices(firstCell.I + v, firstCell.J + h); // if they in difference sets -> combine them(make a path, combine sets) if (indexInRange(secondCell.I, secondCell.J, rowsAmount, colsAmount) && sets.InDifferentSets(firstCell, secondCell)) { // path with 2 cells for (int i = firstCell.I, j = firstCell.J, count = 0; count != 3; i += v / 2, j += h / 2, ++count) { canvas[i, j] = new Cell(i, j, j * cellWidth, i * cellHeight); } // combine sets sets.UnionSets(firstCell, secondCell); } } // walls in null cell spots FillInAllWithWalls(canvas, rowsAmount, colsAmount, cellWidth, cellHeight, (cell) => cell == null); }
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; } } } }
private static bool EqualsImpl(ref CellIndices Lhs, ref CellIndices Rhs) { return(Lhs.column == Rhs.column && Lhs.row == Rhs.row); }
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 Cell(Cell other) { this.correctPosition = other.correctPosition; }
private bool CheckCellBasedReachability(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParms) { IntVec3 foundCell = IntVec3.Invalid; VehicleRegion[] directionRegionGrid = regionGrid.DirectGrid; VehiclePathGrid pathGrid = map.GetCachedMapComponent <VehicleMapping>().VehiclePathGrid; CellIndices cellIndices = map.cellIndices; map.floodFiller.FloodFill(start, delegate(IntVec3 c) { int num = cellIndices.CellToIndex(c); if ((traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParms.mode == TraverseMode.NoPassClosedDoorsOrWater) && c.GetTerrain(map).IsWater) { return(false); } if (traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater) { if (!pathGrid.WalkableFast(num)) { Building edifice = c.GetEdifice(map); if (edifice is null || !VehiclePathFinder.IsDestroyable(edifice)) { return(false); } } } else if (traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater) { Log.ErrorOnce("Do not use this method for non-cell based modes!", 938476762); if (!pathGrid.WalkableFast(num)) { return(false); } } VehicleRegion region = directionRegionGrid[num]; return(region is null || region.Allows(traverseParms, false)); }, delegate(IntVec3 c) { if (VehicleReachabilityImmediate.CanReachImmediateShip(c, dest, map, peMode, traverseParms.pawn)) { foundCell = c; return(true); } return(false); }, int.MaxValue, false, null); if (foundCell.IsValid) { if (CanUseCache(traverseParms.mode)) { VehicleRegion validRegionAt = regionGrid.GetValidRegionAt(foundCell); if (!(validRegionAt is null)) { foreach (VehicleRegion startRegion in startingRegions) { cache.AddCachedResult(startRegion.Room, validRegionAt.Room, traverseParms, true); } } } return(true); } if (CanUseCache(traverseParms.mode)) { foreach (VehicleRegion startRegion in startingRegions) { foreach (VehicleRegion destRegion in destRegions) { cache.AddCachedResult(startRegion.Room, destRegion.Room, traverseParms, false); } } } return(false); }
private static bool CheckCellBasedReachability( IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams, RegionGrid regionGrid, Reachability __instance, List <Region> this_startingRegions, ReachabilityCache this_cache, List <Region> this_destRegions) { IntVec3 foundCell = IntVec3.Invalid; Region[] directRegionGrid = regionGrid.DirectGrid; PathGrid pathGrid = map(__instance).pathGrid; CellIndices cellIndices = map(__instance).cellIndices; map(__instance).floodFiller.FloodFill(start, (Predicate <IntVec3>)(c => { int index = cellIndices.CellToIndex(c); if ((traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater) && c.GetTerrain(map(__instance)).IsWater) { return(false); } if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater) { if (!pathGrid.WalkableFast(index)) { Building edifice = c.GetEdifice(map(__instance)); if (edifice == null || !PathFinder.IsDestroyable((Thing)edifice)) { return(false); } } } else if (traverseParams.mode != TraverseMode.NoPassClosedDoorsOrWater) { Log.ErrorOnce("Do not use this method for non-cell based modes!", 938476762, false); if (!pathGrid.WalkableFast(index)) { return(false); } } Region region = directRegionGrid[index]; return(region == null || region.Allows(traverseParams, false)); }), (Func <IntVec3, bool>)(c => { if (!ReachabilityImmediate.CanReachImmediate(c, dest, map(__instance), peMode, traverseParams.pawn)) { return(false); } foundCell = c; return(true); }), int.MaxValue, false, (IEnumerable <IntVec3>)null); if (foundCell.IsValid) { if (CanUseCache(traverseParams.mode)) { Region validRegionAt = regionGrid.GetValidRegionAt(foundCell); if (validRegionAt != null) { for (int index = 0; index < this_startingRegions.Count; ++index) { this_cache.AddCachedResult(this_startingRegions[index].Room, validRegionAt.Room, traverseParams, true); } } } return(true); } if (CanUseCache(traverseParams.mode)) { for (int index1 = 0; index1 < this_startingRegions.Count; ++index1) { for (int index2 = 0; index2 < this_destRegions.Count; ++index2) { this_cache.AddCachedResult(this_startingRegions[index1].Room, this_destRegions[index2].Room, traverseParams, false); } } } return(false); }
public override void Regenerate() { LayerSubMesh subMesh = base.GetSubMesh(Verse.MatBases.Snow); // LayerSubMesh subMesh = base.GetSubMesh(MatBases.Frost); // for some reason the custom one was causing a huge memory issue and rendering in giant squares :( if (subMesh.mesh.vertexCount == 0) { // SectionLayerGeometryMaker_Solid.MakeBaseGeometry(this.section, subMesh, AltitudeLayer.MoteLow); SectionLayerGeometryMaker_Solid.MakeBaseGeometry(this.section, subMesh, AltitudeLayer.LayingPawn); //so frost forms over items/plants } subMesh.Clear(MeshParts.Colors); float[] depthGridDirect_Unsafe = base.Map.GetComponent <FrostGrid>().DepthGridDirect_Unsafe; CellRect cellRect = this.section.CellRect; int num = base.Map.Size.z - 1; int num2 = base.Map.Size.x - 1; bool flag = false; CellIndices cellIndices = base.Map.cellIndices; for (int i = cellRect.minX; i <= cellRect.maxX; i++) // this is what renders it all blobby, I think { for (int j = cellRect.minZ; j <= cellRect.maxZ; j++) { float num3 = depthGridDirect_Unsafe[cellIndices.CellToIndex(i, j)]; int num4 = cellIndices.CellToIndex(i, j - 1); float num5 = (j <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i - 1, j - 1); float num6 = (j <= 0 || i <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i - 1, j); float num7 = (i <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i - 1, j + 1); float num8 = (j >= num || i <= 0) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i, j + 1); float num9 = (j >= num) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i + 1, j + 1); float num10 = (j >= num || i >= num2) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i + 1, j); float num11 = (i >= num2) ? num3 : depthGridDirect_Unsafe[num4]; num4 = cellIndices.CellToIndex(i + 1, j - 1); float num12 = (j <= 0 || i >= num2) ? num3 : depthGridDirect_Unsafe[num4]; this.vertDepth[0] = (num5 + num6 + num7 + num3) / 4f; this.vertDepth[1] = (num7 + num3) / 2f; this.vertDepth[2] = (num7 + num8 + num9 + num3) / 4f; this.vertDepth[3] = (num9 + num3) / 2f; this.vertDepth[4] = (num9 + num10 + num11 + num3) / 4f; this.vertDepth[5] = (num11 + num3) / 2f; this.vertDepth[6] = (num11 + num12 + num5 + num3) / 4f; this.vertDepth[7] = (num5 + num3) / 2f; this.vertDepth[8] = num3; for (int k = 0; k < 9; k++) { if (this.vertDepth[k] > 0.01f) { flag = true; } subMesh.colors.Add(SectionLayer_Frost.FrostDepthColor(this.vertDepth[k])); } } } if (flag) { subMesh.disabled = false; subMesh.FinalizeMesh(MeshParts.Colors); } else { subMesh.disabled = true; } }