public override List <GraphNode> GetNodesInRegion(IntRect rect) { List <GraphNode> list = ListPool <GraphNode> .Claim(); IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); rect = IntRect.Intersection(rect, b); if (this.nodes == null || !rect.IsValid() || this.nodes.Length != this.width * this.depth * this.layerCount) { return(list); } for (int i = 0; i < this.layerCount; i++) { int num = i * base.Width * base.Depth; for (int j = rect.ymin; j <= rect.ymax; j++) { int num2 = num + j * base.Width; for (int k = rect.xmin; k <= rect.xmax; k++) { LevelGridNode levelGridNode = this.nodes[num2 + k]; if (levelGridNode != null) { list.Add(levelGridNode); } } } } return(list); }
/// <summary>Creates a list for every tile and adds every mesh that touches a tile to the corresponding list</summary> List <RasterizationMesh>[] PutMeshesIntoTileBuckets(List <RasterizationMesh> meshes, IntRect tileBuckets) { var bucketCount = tileBuckets.Width * tileBuckets.Height; var result = new List <RasterizationMesh> [bucketCount]; var borderExpansion = new Vector3(1, 0, 1) * TileBorderSizeInWorldUnits * 2; for (int i = 0; i < result.Length; i++) { result[i] = ListPool <RasterizationMesh> .Claim(); } var offset = new Int2(-tileBuckets.xmin, -tileBuckets.ymin); var clamp = new IntRect(0, 0, tileBuckets.Width - 1, tileBuckets.Height - 1); for (int i = 0; i < meshes.Count; i++) { var mesh = meshes[i]; var bounds = mesh.bounds; // Expand borderSize voxels on each side bounds.Expand(borderExpansion); var rect = GetTouchingTiles(bounds); rect = IntRect.Intersection(rect.Offset(offset), clamp); for (int z = rect.ymin; z <= rect.ymax; z++) { for (int x = rect.xmin; x <= rect.xmax; x++) { result[x + z * tileBuckets.Width].Add(mesh); } } } return(result); }
/** Returns a rect containing the indices of all tiles touching the specified bounds. * \param rect Graph space rectangle (in graph space all tiles are on the XZ plane regardless of graph rotation and other transformations, the first tile has a corner at the origin) */ public static IntRect GetTouchingTilesInGraphSpace(this NavmeshBase self, Rect rect) { // Calculate world bounds of all affected tiles var r = new IntRect(Mathf.FloorToInt(rect.xMin / self.TileWorldSizeX), Mathf.FloorToInt(rect.yMin / self.TileWorldSizeZ), Mathf.FloorToInt(rect.xMax / self.TileWorldSizeX), Mathf.FloorToInt(rect.yMax / self.TileWorldSizeZ)); // Clamp to bounds r = IntRect.Intersection(r, new IntRect(0, 0, self.tileXCount - 1, self.tileZCount - 1)); return(r); }
/** Returns a rect containing the indices of all tiles touching the specified bounds */ public static IntRect GetTouchingTiles(this NavmeshBase self, Bounds bounds) { bounds = self.transform.InverseTransform(bounds); // Calculate world bounds of all affected tiles var r = new IntRect(Mathf.FloorToInt(bounds.min.x / self.TileWorldSizeX), Mathf.FloorToInt(bounds.min.z / self.TileWorldSizeZ), Mathf.FloorToInt(bounds.max.x / self.TileWorldSizeX), Mathf.FloorToInt(bounds.max.z / self.TileWorldSizeZ)); // Clamp to bounds r = IntRect.Intersection(r, new IntRect(0, 0, self.tileXCount - 1, self.tileZCount - 1)); return(r); }
public override int GetNodesInRegion(IntRect rect, GridNodeBase[] buffer) { IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); rect = IntRect.Intersection(rect, b); if (this.nodes == null || !rect.IsValid() || this.nodes.Length != this.width * this.depth * this.layerCount) { return(0); } int num = 0; try { for (int i = 0; i < this.layerCount; i++) { int num2 = i * base.Width * base.Depth; for (int j = rect.ymin; j <= rect.ymax; j++) { int num3 = num2 + j * base.Width; for (int k = rect.xmin; k <= rect.xmax; k++) { LevelGridNode levelGridNode = this.nodes[num3 + k]; if (levelGridNode != null) { buffer[num] = levelGridNode; num++; } } } } } catch (IndexOutOfRangeException) { throw new ArgumentException("Buffer is too small"); } return(num); }
/// <summary>Async method for moving the graph</summary> IEnumerator UpdateGraphCoroutine() { // Find the direction that we want to move the graph in. // Calcuculate this in graph space (where a distance of one is the size of one node) Vector3 dir = PointToGraphSpace(target.position) - PointToGraphSpace(graph.center); // Snap to a whole number of nodes dir.x = Mathf.Round(dir.x); dir.z = Mathf.Round(dir.z); dir.y = 0; // Nothing do to if (dir == Vector3.zero) { yield break; } // Number of nodes to offset in each direction Int2 offset = new Int2(-Mathf.RoundToInt(dir.x), -Mathf.RoundToInt(dir.z)); // Move the center (this is in world units, so we need to convert it back from graph space) graph.center += graph.transform.TransformVector(dir); graph.UpdateTransform(); // Cache some variables for easier access int width = graph.width; int depth = graph.depth; GridNodeBase[] nodes; // Layers are required when handling LayeredGridGraphs int layers = graph.LayerCount; var layeredGraph = graph as LayerGridGraph; if (layeredGraph != null) { nodes = layeredGraph.nodes; } else { nodes = graph.nodes; } // Create a temporary buffer required for the calculations if (buffer == null || buffer.Length != width * depth) { buffer = new GridNodeBase[width * depth]; } // Check if we have moved less than a whole graph width all directions // If we have moved more than this we can just as well recalculate the whole graph if (Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth) { IntRect recalculateRect = new IntRect(0, 0, offset.x, offset.y); // If offset.x < 0, adjust the rect if (recalculateRect.xmin > recalculateRect.xmax) { int tmp2 = recalculateRect.xmax; recalculateRect.xmax = width + recalculateRect.xmin; recalculateRect.xmin = width + tmp2; } // If offset.y < 0, adjust the rect if (recalculateRect.ymin > recalculateRect.ymax) { int tmp2 = recalculateRect.ymax; recalculateRect.ymax = depth + recalculateRect.ymin; recalculateRect.ymin = depth + tmp2; } // Connections need to be recalculated for the neighbours as well, so we need to expand the rect by 1 var connectionRect = recalculateRect.Expand(1); // Makes sure the rect stays inside the grid connectionRect = IntRect.Intersection(connectionRect, new IntRect(0, 0, width, depth)); // Offset each node by the #offset variable // nodes which would end up outside the graph // will wrap around to the other side of it for (int l = 0; l < layers; l++) { int layerOffset = l * width * depth; for (int z = 0; z < depth; z++) { int pz = z * width; int tz = ((z + offset.y + depth) % depth) * width; for (int x = 0; x < width; x++) { buffer[tz + ((x + offset.x + width) % width)] = nodes[layerOffset + pz + x]; } } yield return(null); // Copy the nodes back to the graph // and set the correct indices for (int z = 0; z < depth; z++) { int pz = z * width; for (int x = 0; x < width; x++) { int newIndex = pz + x; var node = buffer[newIndex]; if (node != null) { node.NodeInGridIndex = newIndex; } nodes[layerOffset + newIndex] = node; } // Calculate the limits for the region that has been wrapped // to the other side of the graph int xmin, xmax; if (z >= recalculateRect.ymin && z < recalculateRect.ymax) { xmin = 0; xmax = depth; } else { xmin = recalculateRect.xmin; xmax = recalculateRect.xmax; } for (int x = xmin; x < xmax; x++) { var node = buffer[pz + x]; if (node != null) { // Clear connections on all nodes that are wrapped and placed on the other side of the graph. // This is both to clear any custom connections (which do not really make sense after moving the node) // and to prevent possible exceptions when the node will later (possibly) be destroyed because it was // not needed anymore (only for layered grid graphs). node.ClearConnections(false); } } } yield return(null); } // The calculation will only update approximately this number of // nodes per frame. This is used to keep CPU load per frame low int yieldEvery = 1000; // To avoid the update taking too long, make yieldEvery somewhat proportional to the number of nodes that we are going to update int approxNumNodesToUpdate = Mathf.Max(Mathf.Abs(offset.x), Mathf.Abs(offset.y)) * Mathf.Max(width, depth); yieldEvery = Mathf.Max(yieldEvery, approxNumNodesToUpdate / 10); int counter = 0; // Recalculate the nodes // Take a look at the image in the docs for the UpdateGraph method // to see which nodes are being recalculated. for (int z = 0; z < depth; z++) { int xmin, xmax; if (z >= recalculateRect.ymin && z < recalculateRect.ymax) { xmin = 0; xmax = width; } else { xmin = recalculateRect.xmin; xmax = recalculateRect.xmax; } for (int x = xmin; x < xmax; x++) { graph.RecalculateCell(x, z, false, false); } counter += (xmax - xmin); if (counter > yieldEvery) { counter = 0; yield return(null); } } for (int z = 0; z < depth; z++) { int xmin, xmax; if (z >= connectionRect.ymin && z < connectionRect.ymax) { xmin = 0; xmax = width; } else { xmin = connectionRect.xmin; xmax = connectionRect.xmax; } for (int x = xmin; x < xmax; x++) { graph.CalculateConnections(x, z); } counter += (xmax - xmin); if (counter > yieldEvery) { counter = 0; yield return(null); } } yield return(null); // Calculate all connections for the nodes along the boundary // of the graph, these always need to be updated /// <summary>TODO: Optimize to not traverse all nodes in the graph, only those at the edges</summary> for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { if (x == 0 || z == 0 || x == width - 1 || z == depth - 1) { graph.CalculateConnections(x, z); } } } } else { // The calculation will only update approximately this number of // nodes per frame. This is used to keep CPU load per frame low int yieldEvery = Mathf.Max(depth * width / 20, 1000); int counter = 0; // Just update all nodes for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { graph.RecalculateCell(x, z); } counter += width; if (counter > yieldEvery) { counter = 0; yield return(null); } } // Recalculate the connections of all nodes for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { graph.CalculateConnections(x, z); } counter += width; if (counter > yieldEvery) { counter = 0; yield return(null); } } } }
public new void UpdateArea(GraphUpdateObject o) { if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount) { Debug.LogWarning("The Grid Graph is not scanned, cannot update area "); return; } IntRect a; IntRect a2; IntRect intRect; bool flag; int num; base.CalculateAffectedRegions(o, out a, out a2, out intRect, out flag, out num); bool flag2 = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes; bool flag3 = (!(o is LayerGridGraphUpdate)) ? (!o.resetPenaltyOnPhysics) : ((LayerGridGraphUpdate)o).preserveExistingNodes; if (o.trackChangedNodes && flag2) { Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph"); return; } IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); IntRect intRect2 = IntRect.Intersection(a2, b); if (!flag2) { for (int i = intRect2.xmin; i <= intRect2.xmax; i++) { for (int j = intRect2.ymin; j <= intRect2.ymax; j++) { for (int k = 0; k < this.layerCount; k++) { o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]); } } } } if (o.updatePhysics && !o.modifyWalkability) { this.collision.Initialize(base.transform, this.nodeSize); intRect2 = IntRect.Intersection(intRect, b); for (int l = intRect2.xmin; l <= intRect2.xmax; l++) { for (int m = intRect2.ymin; m <= intRect2.ymax; m++) { this.RecalculateCell(l, m, !flag3, false); } } for (int n = intRect2.xmin; n <= intRect2.xmax; n++) { for (int num2 = intRect2.ymin; num2 <= intRect2.ymax; num2++) { this.CalculateConnections(n, num2); } } } intRect2 = IntRect.Intersection(a, b); for (int num3 = intRect2.xmin; num3 <= intRect2.xmax; num3++) { for (int num4 = intRect2.ymin; num4 <= intRect2.ymax; num4++) { for (int num5 = 0; num5 < this.layerCount; num5++) { int num6 = num5 * this.width * this.depth + num4 * this.width + num3; LevelGridNode levelGridNode = this.nodes[num6]; if (levelGridNode != null) { if (flag) { levelGridNode.Walkable = levelGridNode.WalkableErosion; if (o.bounds.Contains((Vector3)levelGridNode.position)) { o.Apply(levelGridNode); } levelGridNode.WalkableErosion = levelGridNode.Walkable; } else if (o.bounds.Contains((Vector3)levelGridNode.position)) { o.Apply(levelGridNode); } } } } } if (flag && num == 0) { intRect2 = IntRect.Intersection(a2, b); for (int num7 = intRect2.xmin; num7 <= intRect2.xmax; num7++) { for (int num8 = intRect2.ymin; num8 <= intRect2.ymax; num8++) { this.CalculateConnections(num7, num8); } } } else if (flag && num > 0) { IntRect a3 = IntRect.Union(a, intRect).Expand(num); IntRect a4 = a3.Expand(num); a3 = IntRect.Intersection(a3, b); a4 = IntRect.Intersection(a4, b); for (int num9 = a4.xmin; num9 <= a4.xmax; num9++) { for (int num10 = a4.ymin; num10 <= a4.ymax; num10++) { for (int num11 = 0; num11 < this.layerCount; num11++) { int num12 = num11 * this.width * this.depth + num10 * this.width + num9; LevelGridNode levelGridNode2 = this.nodes[num12]; if (levelGridNode2 != null) { bool walkable = levelGridNode2.Walkable; levelGridNode2.Walkable = levelGridNode2.WalkableErosion; if (!a3.Contains(num9, num10)) { levelGridNode2.TmpWalkable = walkable; } } } } } for (int num13 = a4.xmin; num13 <= a4.xmax; num13++) { for (int num14 = a4.ymin; num14 <= a4.ymax; num14++) { this.CalculateConnections(num13, num14); } } base.ErodeWalkableArea(a4.xmin, a4.ymin, a4.xmax + 1, a4.ymax + 1); for (int num15 = a4.xmin; num15 <= a4.xmax; num15++) { for (int num16 = a4.ymin; num16 <= a4.ymax; num16++) { if (!a3.Contains(num15, num16)) { for (int num17 = 0; num17 < this.layerCount; num17++) { int num18 = num17 * this.width * this.depth + num16 * this.width + num15; LevelGridNode levelGridNode3 = this.nodes[num18]; if (levelGridNode3 != null) { levelGridNode3.Walkable = levelGridNode3.TmpWalkable; } } } } } for (int num19 = a4.xmin; num19 <= a4.xmax; num19++) { for (int num20 = a4.ymin; num20 <= a4.ymax; num20++) { this.CalculateConnections(num19, num20); } } } }
// Token: 0x06002430 RID: 9264 RVA: 0x00196841 File Offset: 0x00194A41 private IEnumerator UpdateGraphCoroutine() { Vector3 vector = this.PointToGraphSpace(this.target.position) - this.PointToGraphSpace(this.graph.center); vector.x = Mathf.Round(vector.x); vector.z = Mathf.Round(vector.z); vector.y = 0f; if (vector == Vector3.zero) { yield break; } Int2 offset = new Int2(-Mathf.RoundToInt(vector.x), -Mathf.RoundToInt(vector.z)); this.graph.center += this.graph.transform.TransformVector(vector); this.graph.UpdateTransform(); int width = this.graph.width; int depth = this.graph.depth; int layers = this.graph.LayerCount; LayerGridGraph layerGridGraph = this.graph as LayerGridGraph; GridNodeBase[] nodes; if (layerGridGraph != null) { GridNodeBase[] nodes2 = layerGridGraph.nodes; nodes = nodes2; } else { GridNodeBase[] nodes2 = this.graph.nodes; nodes = nodes2; } if (this.buffer == null || this.buffer.Length != width * depth) { this.buffer = new GridNodeBase[width * depth]; } if (Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth) { IntRect recalculateRect = new IntRect(0, 0, offset.x, offset.y); if (recalculateRect.xmin > recalculateRect.xmax) { int xmax = recalculateRect.xmax; recalculateRect.xmax = width + recalculateRect.xmin; recalculateRect.xmin = width + xmax; } if (recalculateRect.ymin > recalculateRect.ymax) { int ymax = recalculateRect.ymax; recalculateRect.ymax = depth + recalculateRect.ymin; recalculateRect.ymin = depth + ymax; } IntRect connectionRect = recalculateRect.Expand(1); connectionRect = IntRect.Intersection(connectionRect, new IntRect(0, 0, width, depth)); int num7; for (int i = 0; i < layers; i = num7 + 1) { int layerOffset = i * width * depth; for (int j = 0; j < depth; j++) { int num = j * width; int num2 = (j + offset.y + depth) % depth * width; for (int k = 0; k < width; k++) { this.buffer[num2 + (k + offset.x + width) % width] = nodes[layerOffset + num + k]; } } yield return(null); for (int l = 0; l < depth; l++) { int num3 = l * width; for (int m = 0; m < width; m++) { int num4 = num3 + m; GridNodeBase gridNodeBase = this.buffer[num4]; if (gridNodeBase != null) { gridNodeBase.NodeInGridIndex = num4; } nodes[layerOffset + num4] = gridNodeBase; } int num5; int num6; if (l >= recalculateRect.ymin && l < recalculateRect.ymax) { num5 = 0; num6 = depth; } else { num5 = recalculateRect.xmin; num6 = recalculateRect.xmax; } for (int n = num5; n < num6; n++) { GridNodeBase gridNodeBase2 = this.buffer[num3 + n]; if (gridNodeBase2 != null) { gridNodeBase2.ClearConnections(false); } } } yield return(null); num7 = i; } int yieldEvery = 1000; int num8 = Mathf.Max(Mathf.Abs(offset.x), Mathf.Abs(offset.y)) * Mathf.Max(width, depth); yieldEvery = Mathf.Max(yieldEvery, num8 / 10); int counter = 0; for (int i = 0; i < depth; i = num7 + 1) { int num9; int num10; if (i >= recalculateRect.ymin && i < recalculateRect.ymax) { num9 = 0; num10 = width; } else { num9 = recalculateRect.xmin; num10 = recalculateRect.xmax; } for (int num11 = num9; num11 < num10; num11++) { this.graph.RecalculateCell(num11, i, false, false); } counter += num10 - num9; if (counter > yieldEvery) { counter = 0; yield return(null); } num7 = i; } for (int i = 0; i < depth; i = num7 + 1) { int num12; int num13; if (i >= connectionRect.ymin && i < connectionRect.ymax) { num12 = 0; num13 = width; } else { num12 = connectionRect.xmin; num13 = connectionRect.xmax; } for (int num14 = num12; num14 < num13; num14++) { this.graph.CalculateConnections(num14, i); } counter += num13 - num12; if (counter > yieldEvery) { counter = 0; yield return(null); } num7 = i; } yield return(null); for (int num15 = 0; num15 < depth; num15++) { for (int num16 = 0; num16 < width; num16++) { if (num16 == 0 || num15 == 0 || num16 == width - 1 || num15 == depth - 1) { this.graph.CalculateConnections(num16, num15); } } } if (!this.floodFill) { this.graph.GetNodes(delegate(GraphNode node) { node.Area = 1u; }); } } else { int counter = Mathf.Max(depth * width / 20, 1000); int yieldEvery = 0; int num7; for (int i = 0; i < depth; i = num7 + 1) { for (int num17 = 0; num17 < width; num17++) { this.graph.RecalculateCell(num17, i, true, true); } yieldEvery += width; if (yieldEvery > counter) { yieldEvery = 0; yield return(null); } num7 = i; } for (int i = 0; i < depth; i = num7 + 1) { for (int num18 = 0; num18 < width; num18++) { this.graph.CalculateConnections(num18, i); } yieldEvery += width; if (yieldEvery > counter) { yieldEvery = 0; yield return(null); } num7 = i; } } yield break; }
public new void UpdateArea(GraphUpdateObject o) { if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount) { Debug.LogWarning("The Grid Graph is not scanned, cannot update area "); return; } Bounds bounds = o.bounds; Vector3 a; Vector3 a2; base.GetBoundsMinMax(bounds, this.inverseMatrix, out a, out a2); int xmin = Mathf.RoundToInt(a.x - 0.5f); int xmax = Mathf.RoundToInt(a2.x - 0.5f); int ymin = Mathf.RoundToInt(a.z - 0.5f); int ymax = Mathf.RoundToInt(a2.z - 0.5f); IntRect intRect = new IntRect(xmin, ymin, xmax, ymax); IntRect intRect2 = intRect; IntRect b = new IntRect(0, 0, this.width - 1, this.depth - 1); IntRect intRect3 = intRect; bool flag = o.updatePhysics || o.modifyWalkability; bool flag2 = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes; bool preserveExistingNodes = !(o is LayerGridGraphUpdate) || ((LayerGridGraphUpdate)o).preserveExistingNodes; int num = (!o.updateErosion) ? 0 : this.erodeIterations; if (o.trackChangedNodes && flag2) { Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph"); return; } if (o.updatePhysics && !o.modifyWalkability && this.collision.collisionCheck) { Vector3 a3 = new Vector3(this.collision.diameter, 0f, this.collision.diameter) * 0.5f; a -= a3 * 1.02f; a2 += a3 * 1.02f; intRect3 = new IntRect(Mathf.RoundToInt(a.x - 0.5f), Mathf.RoundToInt(a.z - 0.5f), Mathf.RoundToInt(a2.x - 0.5f), Mathf.RoundToInt(a2.z - 0.5f)); intRect2 = IntRect.Union(intRect3, intRect2); } if (flag || num > 0) { intRect2 = intRect2.Expand(num + 1); } IntRect intRect4 = IntRect.Intersection(intRect2, b); if (!flag2) { for (int i = intRect4.xmin; i <= intRect4.xmax; i++) { for (int j = intRect4.ymin; j <= intRect4.ymax; j++) { for (int k = 0; k < this.layerCount; k++) { o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]); } } } } if (o.updatePhysics && !o.modifyWalkability) { this.collision.Initialize(this.matrix, this.nodeSize); intRect4 = IntRect.Intersection(intRect3, b); bool flag3 = false; for (int l = intRect4.xmin; l <= intRect4.xmax; l++) { for (int m = intRect4.ymin; m <= intRect4.ymax; m++) { flag3 |= this.RecalculateCell(l, m, preserveExistingNodes); } } for (int n = intRect4.xmin; n <= intRect4.xmax; n++) { for (int num2 = intRect4.ymin; num2 <= intRect4.ymax; num2++) { for (int num3 = 0; num3 < this.layerCount; num3++) { int num4 = num3 * this.width * this.depth + num2 * this.width + n; LevelGridNode levelGridNode = this.nodes[num4]; if (levelGridNode != null) { this.CalculateConnections(this.nodes, levelGridNode, n, num2, num3); } } } } } intRect4 = IntRect.Intersection(intRect, b); for (int num5 = intRect4.xmin; num5 <= intRect4.xmax; num5++) { for (int num6 = intRect4.ymin; num6 <= intRect4.ymax; num6++) { for (int num7 = 0; num7 < this.layerCount; num7++) { int num8 = num7 * this.width * this.depth + num6 * this.width + num5; LevelGridNode levelGridNode2 = this.nodes[num8]; if (levelGridNode2 != null) { if (flag) { levelGridNode2.Walkable = levelGridNode2.WalkableErosion; if (o.bounds.Contains((Vector3)levelGridNode2.position)) { o.Apply(levelGridNode2); } levelGridNode2.WalkableErosion = levelGridNode2.Walkable; } else if (o.bounds.Contains((Vector3)levelGridNode2.position)) { o.Apply(levelGridNode2); } } } } } if (flag && num == 0) { intRect4 = IntRect.Intersection(intRect2, b); for (int num9 = intRect4.xmin; num9 <= intRect4.xmax; num9++) { for (int num10 = intRect4.ymin; num10 <= intRect4.ymax; num10++) { for (int num11 = 0; num11 < this.layerCount; num11++) { int num12 = num11 * this.width * this.depth + num10 * this.width + num9; LevelGridNode levelGridNode3 = this.nodes[num12]; if (levelGridNode3 != null) { this.CalculateConnections(this.nodes, levelGridNode3, num9, num10, num11); } } } } } else if (flag && num > 0) { IntRect a4 = IntRect.Union(intRect, intRect3).Expand(num); IntRect a5 = a4.Expand(num); a4 = IntRect.Intersection(a4, b); a5 = IntRect.Intersection(a5, b); for (int num13 = a5.xmin; num13 <= a5.xmax; num13++) { for (int num14 = a5.ymin; num14 <= a5.ymax; num14++) { for (int num15 = 0; num15 < this.layerCount; num15++) { int num16 = num15 * this.width * this.depth + num14 * this.width + num13; LevelGridNode levelGridNode4 = this.nodes[num16]; if (levelGridNode4 != null) { bool walkable = levelGridNode4.Walkable; levelGridNode4.Walkable = levelGridNode4.WalkableErosion; if (!a4.Contains(num13, num14)) { levelGridNode4.TmpWalkable = walkable; } } } } } for (int num17 = a5.xmin; num17 <= a5.xmax; num17++) { for (int num18 = a5.ymin; num18 <= a5.ymax; num18++) { for (int num19 = 0; num19 < this.layerCount; num19++) { int num20 = num19 * this.width * this.depth + num18 * this.width + num17; LevelGridNode levelGridNode5 = this.nodes[num20]; if (levelGridNode5 != null) { this.CalculateConnections(this.nodes, levelGridNode5, num17, num18, num19); } } } } this.ErodeWalkableArea(a5.xmin, a5.ymin, a5.xmax + 1, a5.ymax + 1); for (int num21 = a5.xmin; num21 <= a5.xmax; num21++) { for (int num22 = a5.ymin; num22 <= a5.ymax; num22++) { if (!a4.Contains(num21, num22)) { for (int num23 = 0; num23 < this.layerCount; num23++) { int num24 = num23 * this.width * this.depth + num22 * this.width + num21; LevelGridNode levelGridNode6 = this.nodes[num24]; if (levelGridNode6 != null) { levelGridNode6.Walkable = levelGridNode6.TmpWalkable; } } } } } for (int num25 = a5.xmin; num25 <= a5.xmax; num25++) { for (int num26 = a5.ymin; num26 <= a5.ymax; num26++) { for (int num27 = 0; num27 < this.layerCount; num27++) { int num28 = num27 * this.width * this.depth + num26 * this.width + num25; LevelGridNode levelGridNode7 = this.nodes[num28]; if (levelGridNode7 != null) { this.CalculateConnections(this.nodes, levelGridNode7, num25, num26, num27); } } } } } }