13 [DllImport(
"KERNEL32.DLL", EntryPoint =
"RtlZeroMemory")]
14 public unsafe
static extern bool ZeroMemory(
byte* destination,
int length);
20 this.weightMap = _weightMap;
21 this.mGridX = (int)((ushort)size);
22 this.mGridZ = (int)((ushort)size);
23 this.mGridXZ = this.mGridX * this.mGridZ;
24 if (this.mCalcGrid ==
null || this.mCalcGrid.Length !=
this.mGridXZ)
34 this.moveType = path.moveType;
36 if (path.nodes.Count > 0)
39 if (pathFinderNode.X == path.startPoint.x && pathFinderNode.Z == path.startPoint.z)
41 path.nodes.RemoveAt(path.nodes.Count - 1);
44 if (path.nodes.Count == 0)
50 path.nodeIndex = path.nodes.Count - 1;
58 Point startPoint = path.startPoint;
59 Point destPoint = path.destPoint;
61 this.mFound = (this.mStop = (this.mStopped =
false));
62 this.mCloseNodeCounter = 0;
63 this.mOpenNodeValue += 2;
64 this.mCloseNodeValue += 2;
66 this.mLocation = (this.mStartLocation = startPoint.z * this.mGridX + startPoint.x);
67 this.mEndLocation = destPoint.z * this.mGridX + destPoint.x;
68 if (this.mLocation >= this.mCalcGrid.Length)
72 Debug.Log(
"length over");
75 else if (this.mEndLocation != this.mLocation)
77 this.mCalcGrid[this.mLocation].G = 0;
78 this.mCalcGrid[this.mLocation].F = this.mHEstimate;
79 this.mCalcGrid[this.mLocation].PX = (ushort)startPoint.x;
80 this.mCalcGrid[this.mLocation].PZ = (ushort)startPoint.z;
81 this.mCalcGrid[this.mLocation].Status = this.mOpenNodeValue;
82 this.mOpen.Push(this.mLocation);
83 while (this.mOpen.Count > 0 && !
this.mStop)
85 this.mLocation = this.mOpen.Pop();
86 if (this.mCalcGrid[this.mLocation].Status != this.mCloseNodeValue)
88 this.mLocationX = (ushort)(this.mLocation % this.mGridX);
89 this.mLocationZ = (ushort)(this.mLocation % this.mGridXZ / this.mGridX);
90 if (this.mLocation == this.mEndLocation)
92 this.mCalcGrid[this.mLocation].Status = this.mCloseNodeValue;
96 if (this.mCloseNodeCounter > path.searchLimit)
99 if (path.searchLimit > 1000)
101 string str =
"search limit: ";
102 Point startPoint2 = path.startPoint;
103 string str2 = (startPoint2 !=
null) ? startPoint2.ToString() :
null;
105 Point destPoint2 = path.destPoint;
106 Debug.Log(str + str2 + str3 + ((destPoint2 !=
null) ? destPoint2.ToString() :
null));
110 if (this.PunishChangeDirection)
112 this.mHoriz = (int)(this.mLocationX - this.mCalcGrid[this.mLocation].PX);
114 for (
int i = 0; i < (this.Diagonals ? 8 : 4); i++)
116 this.mNewLocationX = this.mLocationX + (ushort)this.mDirection[i, 0];
117 this.mNewLocationZ = this.mLocationZ + (ushort)this.mDirection[i, 1];
118 this.mNewLocation = (int)this.mNewLocationZ * this.mGridX + (
int)this.mNewLocationX;
119 if ((
int)this.mNewLocationX < this.mGridX && (
int)this.mNewLocationZ < this.mGridZ && (this.mCalcGrid[this.mNewLocation].Status != this.mCloseNodeValue || this.mReopenCloseNodes))
121 if (path.ignoreConnection &&
this.mEndLocation ==
this.mNewLocation)
129 this.index = ((this.mNewLocationZ < this.mLocationZ) ? 0 : ((this.mNewLocationX > this.mLocationX) ? 1 : ((this.mNewLocationZ > this.mLocationZ) ? 2 : 3)));
130 this._weight = this.weightMap[(int)this.mLocationX, (
int)this.mLocationZ].weights[this.index];
134 this.mx = (int)(this.mLocationX + (ushort)this.mDirection[i, 0]);
135 this.mz = (int)this.mLocationZ;
136 this.index = ((this.mz < (int)this.mLocationZ) ? 0 : ((this.mx > (int)this.mLocationX) ? 1 : ((this.mz > (int)this.mLocationZ) ? 2 : 3)));
137 this._weight = this.weightMap[(int)this.mLocationX, (
int)this.mLocationZ].weights[this.index];
138 if (this.weightMap[this.mx, this.mz].IsPathBlocked(this.moveType))
142 if (this._weight > 0)
144 this.index = ((this.mz < (int)this.mNewLocationZ) ? 0 : ((this.mx > (int)this.mNewLocationX) ? 1 : ((this.mz > (int)this.mNewLocationZ) ? 2 : 3)));
145 this._weight = this.weightMap[(int)this.mNewLocationX, (
int)this.mNewLocationZ].weights[this.index];
146 if (this._weight > 0)
148 this.mx = (int)this.mLocationX;
149 this.mz = (int)(this.mLocationZ + (ushort)this.mDirection[i, 1]);
150 this.index = ((this.mz < (int)this.mLocationZ) ? 0 : ((this.mx > (int)this.mLocationX) ? 1 : ((this.mz > (int)this.mLocationZ) ? 2 : 3)));
151 this._weight = this.weightMap[(int)this.mLocationX, (
int)this.mLocationZ].weights[this.index];
152 if (this.weightMap[this.mx, this.mz].IsPathBlocked(this.moveType))
156 if (this._weight > 0)
158 this.index = ((this.mz < (int)this.mNewLocationZ) ? 0 : ((this.mx > (int)this.mNewLocationX) ? 1 : ((this.mz > (int)this.mNewLocationZ) ? 2 : 3)));
159 this._weight = this.weightMap[(int)this.mNewLocationX, (
int)this.mNewLocationZ].weights[this.index];
164 if (this._weight == 0)
168 this._weight += this.weightMap[(int)this.mLocationX, (
int)this.mLocationZ].baseWeight;
169 if (this.mEndLocation != this.mNewLocation && this.weightMap[(
int)this.mNewLocationX, (
int)this.mNewLocationZ].IsPathBlocked(this.moveType))
174 this.mNewG = this.mCalcGrid[this.mLocation].G + (int)this._weight;
175 if (this.PunishChangeDirection)
177 if (this.mNewLocationX - this.mLocationX != 0 && this.mHoriz == 0)
179 this.mNewG += Math.Abs((
int)this.mNewLocationX - destPoint.x) + Math.Abs((
int)this.mNewLocationZ - destPoint.z);
181 if (this.mNewLocationZ - this.mLocationZ != 0 && this.mHoriz != 0)
183 this.mNewG += Math.Abs((
int)this.mNewLocationX - destPoint.x) + Math.Abs((
int)this.mNewLocationZ - destPoint.z);
186 if ((this.mCalcGrid[this.mNewLocation].Status != this.mOpenNodeValue && this.mCalcGrid[this.mNewLocation].Status != this.mCloseNodeValue) || this.mCalcGrid[this.mNewLocation].G > this.mNewG)
188 this.mCalcGrid[this.mNewLocation].PX = this.mLocationX;
189 this.mCalcGrid[this.mNewLocation].PZ = this.mLocationZ;
190 this.mCalcGrid[this.mNewLocation].G = this.mNewG;
191 switch (this.mFormula)
194 this.mH = this.mHEstimate * (Math.Abs((
int)this.mNewLocationX - destPoint.x) + Math.Abs((
int)
this.mNewLocationZ - destPoint.z));
196 case HeuristicFormula.MaxDXDY:
197 this.mH = this.mHEstimate * Math.Max(Math.Abs((
int)
this.mNewLocationX - destPoint.x), Math.Abs((
int)
this.mNewLocationZ - destPoint.z));
199 case HeuristicFormula.DiagonalShortCut:
201 int num = Math.Min(Math.Abs((
int)
this.mNewLocationX - destPoint.x), Math.Abs((
int)
this.mNewLocationZ - destPoint.z));
202 int num2 = Math.Abs((
int)this.mNewLocationX - destPoint.x) + Math.Abs((
int)this.mNewLocationZ - destPoint.z);
203 this.mH = this.mHEstimate * 2 * num + this.mHEstimate * (num2 - 2 * num);
206 case HeuristicFormula.Euclidean:
207 this.mH = (int)((
double)this.mHEstimate * Math.Sqrt(Math.Pow((
double)((
int)
this.mNewLocationZ - destPoint.x), 2.0) + Math.Pow((
double)((
int)
this.mNewLocationZ - destPoint.z), 2.0)));
209 case HeuristicFormula.EuclideanNoSQR:
210 this.mH = (int)((
double)this.mHEstimate * (Math.Pow((
double)((
int)
this.mNewLocationX - destPoint.x), 2.0) + Math.Pow((
double)((
int)
this.mNewLocationZ - destPoint.z), 2.0)));
215 int num3 = (int)this.mLocationX - destPoint.x;
216 int num4 = (int)this.mLocationZ - destPoint.z;
217 int num5 = startPoint.x - destPoint.x;
218 int num6 = startPoint.z - destPoint.z;
219 int num7 = Math.Abs(num3 * num6 - num5 * num4);
220 this.mH = (int)((
double)this.mH + (
double)num7 * 0.001);
222 this.mCalcGrid[this.mNewLocation].F = this.mNewG + this.mH;
223 this.mOpen.Push(this.mNewLocation);
224 this.mCalcGrid[this.mNewLocation].Status = this.mOpenNodeValue;
229 this.mCloseNodeCounter++;
230 this.mCalcGrid[this.mLocation].Status = this.mCloseNodeValue;
235 int num8 = destPoint.x;
236 int num9 = destPoint.z;
237 PathFinder.PathFinderNodeFast pathFinderNodeFast = this.mCalcGrid[destPoint.z * this.mGridX + destPoint.x];
239 pathFinderNode.G = pathFinderNodeFast.G;
240 pathFinderNode.PX = (int)pathFinderNodeFast.PX;
241 pathFinderNode.PZ = (int)pathFinderNodeFast.PZ;
242 pathFinderNode.X = destPoint.x;
243 pathFinderNode.Z = destPoint.z;
244 while (pathFinderNode.X != pathFinderNode.PX || pathFinderNode.Z != pathFinderNode.PZ)
246 path.nodes.Add(pathFinderNode);
247 num8 = pathFinderNode.PX;
248 num9 = pathFinderNode.PZ;
249 pathFinderNodeFast = this.mCalcGrid[num9 * this.mGridX + num8];
250 pathFinderNode.G = pathFinderNodeFast.G;
251 pathFinderNode.PX = (int)pathFinderNodeFast.PX;
252 pathFinderNode.PZ = (int)pathFinderNodeFast.PZ;
253 pathFinderNode.X = num8;
254 pathFinderNode.Z = num9;
256 path.nodes.Add(pathFinderNode);
257 this.mStopped =
true;
261 this.mStopped =
true;
271 public bool Diagonals;
274 public bool PunishChangeDirection;
277 public float HeavyDiagonals = 1f;
280 public bool TieBreaker;
283 public HeuristicFormula mFormula = HeuristicFormula.Manhattan;
289 private int mHEstimate = 2;
298 private bool mStopped =
true;
304 private bool mReopenCloseNodes =
true;
310 private byte mOpenNodeValue = 1;
313 private byte mCloseNodeValue = 2;
316 private PathManager.MoveType moveType;
326 private int mLocation;
329 private int mNewLocation;
332 private ushort mLocationX;
335 private ushort mLocationZ;
338 private ushort mNewLocationX;
341 private ushort mNewLocationZ;
353 private int mCloseNodeCounter;
359 private sbyte[,] mDirection =
new sbyte[,]
396 private int mEndLocation;
399 private int mStartLocation;
405 private byte _weight;
420 internal struct PathFinderNodeFast
439 internal class ComparePFNodeMatrix : IComparer<int>
444 this.mMatrix = matrix;
448 public int Compare(
int a,
int b)
450 if (this.mMatrix[a].F > this.mMatrix[b].F)
454 if (this.mMatrix[a].F < this.mMatrix[b].F)