/// <summary> /// Gets incremental incline data for a point and a neighboring point. /// </summary> /// <param name="mapMetaData">Map meta data.</param> /// <param name="startPoint">Start point, using mapmetadata indices.</param> /// <param name="endPoint">End point, using mapmetadata indices.</param> /// <param name="incline">Incline (out).</param> /// <param name="decline">Decline (out).</param> /// <param name="distance">Distance (out).</param> void getIncrementalInclines(MapMetaData mapMetaData, Point startPoint, Point endPoint, out float incline, out float decline, out float distance) { Vector3 startVector = mapMetaData.getWorldPos(startPoint); Vector3 endVector = mapMetaData.getWorldPos(endPoint); MapTerrainDataCell startCell = mapMetaData.GetCellAt(startPoint); MapTerrainDataCell endCell = mapMetaData.GetCellAt(endPoint); float horzDistance = Mathf.Abs(startVector.x - endVector.x) + Mathf.Abs(startVector.z - endVector.z); distance = horzDistance; float vertDistance = endCell.cachedHeight - startCell.cachedHeight; if (vertDistance > 0) { decline = 0.0f; incline = vertDistance / horzDistance; } else { incline = 0.0f; decline = -(vertDistance / horzDistance); } }
public CacheNode(Vector3 worldPosition, MapMetaData mapMetaData) { this.CellIndex = mapMetaData.GetIndex(worldPosition); this.cells = new MapTerrainDataCell[9]; for (int i = 0; i < 9; i++) { this.cells[i] = mapMetaData.GetCellAt(this.CellIndex.X + xDiff[i], this.CellIndex.Z + zDiff[i]); } this.UpdateLocalGrade(); this.UpdateSteepness(); this.UpdateIsPassableTerrain(); this.NeighborLinks = new CacheNodeLink[8]; }
public CacheNodeLink(CacheNode from, CacheNode to, float distance, int angle, MapMetaData mapMetaData) { this.From = from; this.To = to; this.Reciprocal = to.NeighborLinks[(angle + 4) % 8]; if (this.Reciprocal != null) { this.Reciprocal.Reciprocal = this; } this.PathCells = new List <MapTerrainDataCell>(); this.TargetDistCells = new List <DistCell[]>(); List <Point> indexLine = BresenhamLineUtil.BresenhamLine(from.CellIndex, to.CellIndex); for (int i = 0; i < indexLine.Count - 1; i++) { // Targets are indexLine[i + 1] and the cells in the adjacent cardinal directions DistCell[] targets = new DistCell[3]; Point current = indexLine[i]; int xDiff = indexLine[i + 1].X - current.X; int zDiff = indexLine[i + 1].Z - current.Z; if (xDiff >= 0) { targets[0] = new DistCell(cellDelta, mapMetaData.GetCellAt(current.X + 1, current.Z)); } else { targets[0] = new DistCell(cellDelta, mapMetaData.GetCellAt(current.X - 1, current.Z)); } if (zDiff >= 0) { targets[1] = new DistCell(cellDelta, mapMetaData.GetCellAt(current.X, current.Z + 1)); } else { targets[1] = new DistCell(cellDelta, mapMetaData.GetCellAt(current.X, current.Z - 1)); } if (xDiff == 0) { targets[2] = new DistCell(cellDelta, mapMetaData.GetCellAt(current.X - 1, current.Z)); } else if (zDiff == 0) { targets[2] = new DistCell(cellDelta, mapMetaData.GetCellAt(current.X, current.Z - 1)); } else { // this should be impossible with the modified bresenham they're using targets[2] = new DistCell(cellDeltaDiag, mapMetaData.GetCellAt(indexLine[i])); } this.PathCells.Add(mapMetaData.GetCellAt(current)); this.TargetDistCells.Add(targets); } this.Distance = distance; this.UpdateGrade(); this.UpdateMaxGrade(); }
private static bool NotPrefix( ref bool __result, Vector3 from, Vector3 to, MapMetaData ___mapMetaData, CombatGameState ___combat, List <Point> ___fbbLine, float ___maxGrade, float ___cellDelta, float ___cellDeltaDiag, Point ___incrementZ, Point ___incrementX, Point ___decrementX, Point ___decrementZ) { _stopwatch.Start(); Counter++; ___mapMetaData = ___combat.MapMetaData; Point index = ___mapMetaData.GetIndex(from); Point index2 = ___mapMetaData.GetIndex(to); if (!___mapMetaData.IsWithinBounds(index) || !___mapMetaData.IsWithinBounds(index)) { return(true); } ___fbbLine = BresenhamLineUtil.BresenhamLine(index, index2); if (___fbbLine.Count < 3) { return(false); } float cachedHeight = ___mapMetaData.GetCellAt(___fbbLine[___fbbLine.Count - 1]).cachedHeight; using (CancellationTokenSource cts = new CancellationTokenSource()) { availableThreads = Mod.MaxConcurrency; Task <bool>[] tasks = new Task <bool> [3]; CancellationToken token = cts.Token; for (int i = -1; i <= 1; i++) { while (availableThreads <= 0) { } Interlocked.Decrement(ref availableThreads); int k = i; tasks[i + 1] = Task.Run(() => { for (int j = -1; j <= 1; j++) { if (token.IsCancellationRequested) { return(false); } if (k == 0 && j == 0) { continue; } int num = ___fbbLine[___fbbLine.Count - 1].X + k; int num2 = ___fbbLine[___fbbLine.Count - 1].Z + j; if (___mapMetaData.IsWithinBounds(num, num2)) { float cachedHeight2 = ___mapMetaData.GetCellAt(num, num2).cachedHeight; if (PathNodeGrid.CheckForBlocker(cachedHeight, cachedHeight2, ___maxGrade, (k != 0 && j != 0) ? ___cellDeltaDiag : ___cellDelta)) { Interlocked.Increment(ref availableThreads); cts.Cancel(); return(true); } } } Interlocked.Increment(ref availableThreads); return(false); }); } if (token.IsCancellationRequested) { __result = true; PrintExceptions(tasks); return(false); } foreach (Task <bool> t in tasks) { // busy wait while (!t.IsCompleted) { } } PrintExceptions(tasks); if (token.IsCancellationRequested) { __result = true; return(false); } } availableThreads = Mod.MaxConcurrency; float fromHeight = ___mapMetaData.GetCellAt(___fbbLine[0]).cachedHeight; using (CancellationTokenSource cts = new CancellationTokenSource()) { CancellationToken token = cts.Token; Task <bool>[] tasks = new Task <bool> [___fbbLine.Count - 1]; for (int k = 1; k < ___fbbLine.Count; k++) { while (availableThreads <= 0) { } Interlocked.Decrement(ref availableThreads); int i = k - 1; tasks[i] = Task.Run(() => { cachedHeight = ___mapMetaData.GetCellAt(___fbbLine[i + 1]).cachedHeight; if (___fbbLine[i + 1].Z == ___fbbLine[i].Z) { if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } float cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___incrementZ).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___decrementZ).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } } else if (___fbbLine[i + 1].X == ___fbbLine[i].X) { if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } float cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___decrementX).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___incrementX).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } } else { if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight, ___maxGrade, ___cellDeltaDiag)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } if (___fbbLine[i + 1].X > ___fbbLine[i].X) { float cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___incrementX).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } if (___fbbLine[i + 1].Z > ___fbbLine[i].Z) { cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___incrementZ).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } } else if (___fbbLine[i + 1].Z < ___fbbLine[i].Z) { cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___decrementZ).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } } } else if (___fbbLine[i + 1].X < ___fbbLine[i].X) { float cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___decrementX).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } if (___fbbLine[i + 1].Z > ___fbbLine[i].Z) { cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___incrementZ).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } } else if (___fbbLine[i + 1].Z < ___fbbLine[i].Z) { cachedHeight2 = ___mapMetaData.GetCellAt(___fbbLine[i] + ___decrementZ).cachedHeight; if (PathNodeGrid.CheckForBlocker(fromHeight, cachedHeight2, ___maxGrade, ___cellDelta)) { cts.Cancel(); Interlocked.Increment(ref availableThreads); return(true); } } } } fromHeight = cachedHeight; Interlocked.Increment(ref availableThreads); return(false); }); if (token.IsCancellationRequested) { PrintExceptions(tasks); __result = true; return(false); } } if (token.IsCancellationRequested) { PrintExceptions(tasks); __result = true; return(false); } foreach (Task <bool> t in tasks) { // busy wait while (!t.IsCompleted) { if (token.IsCancellationRequested) { PrintExceptions(tasks); __result = true; return(false); } } } PrintExceptions(tasks); } __result = false; return(false); void PrintExceptions(Task <bool>[] tasks) { List <Task <bool> > faultyTasks = tasks.Where(t => t?.IsFaulted ?? false).ToList(); if (faultyTasks.Any()) { StringBuilder stringBuilder = new StringBuilder(); foreach (Task task in faultyTasks) { stringBuilder.AppendLine(task.Exception.Flatten().ToString()); } Utils.Logger.LogError($"{Utils.LOG_HEADER}" + stringBuilder); } } }