Elin Decompiled Documentation EA 23.315 Nightly
Loading...
Searching...
No Matches
PathFinder.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Runtime.InteropServices;
4using UnityEngine;
5
6namespace Algorithms;
7
8[Serializable]
9public class PathFinder : IPathfinder
10{
11 internal struct PathFinderNodeFast
12 {
13 public int F;
14
15 public int G;
16
17 public ushort PX;
18
19 public ushort PZ;
20
21 public byte Status;
22 }
23
24 internal class ComparePFNodeMatrix : IComparer<int>
25 {
27
29 {
30 mMatrix = matrix;
31 }
32
33 public int Compare(int a, int b)
34 {
35 if (mMatrix[a].F > mMatrix[b].F)
36 {
37 return 1;
38 }
39 if (mMatrix[a].F < mMatrix[b].F)
40 {
41 return -1;
42 }
43 return 0;
44 }
45 }
46
47 public bool debug;
48
49 public bool Diagonals;
50
52
53 public float HeavyDiagonals = 1f;
54
55 public bool TieBreaker;
56
58
60
62
63 private int mHEstimate = 2;
64
66
67 private bool mStop;
68
69 private bool mStopped = true;
70
71 private int mHoriz;
72
73 private bool mReopenCloseNodes = true;
74
76
77 private byte mOpenNodeValue = 1;
78
79 private byte mCloseNodeValue = 2;
80
82
83 [NonSerialized]
84 public int total;
85
86 private int mH;
87
88 private int mLocation;
89
90 private int mNewLocation;
91
92 private ushort mLocationX;
93
94 private ushort mLocationZ;
95
96 private ushort mNewLocationX;
97
98 private ushort mNewLocationZ;
99
100 private int mGridXZ;
101
102 private int mGridX;
103
104 private int mGridZ;
105
106 private int mCloseNodeCounter;
107
108 private bool mFound;
109
110 private sbyte[,] mDirection = new sbyte[8, 2]
111 {
112 { 0, -1 },
113 { 1, 0 },
114 { 0, 1 },
115 { -1, 0 },
116 { -1, -1 },
117 { 1, -1 },
118 { -1, 1 },
119 { 1, 1 }
120 };
121
122 private int mEndLocation;
123
124 private int mStartLocation;
125
126 private int mNewG;
127
128 private byte _weight;
129
131
132 private int index;
133
134 private int mx;
135
136 private int mz;
137
138 [DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
139 public unsafe static extern bool ZeroMemory(byte* destination, int length);
140
141 public void Init(IPathfindGrid _grid, WeightCell[,] _weightMap, int size)
142 {
143 grid = _grid;
144 weightMap = _weightMap;
145 mGridX = (ushort)size;
146 mGridZ = (ushort)size;
148 if (mCalcGrid == null || mCalcGrid.Length != mGridXZ)
149 {
152 }
153 }
154
155 public void FindPath(PathProgress path)
156 {
157 moveType = path.moveType;
158 walker = path.walker;
159 _FindPath(path);
160 if (path.nodes.Count > 0)
161 {
162 PathFinderNode pathFinderNode = path.nodes[path.nodes.Count - 1];
163 if (pathFinderNode.X == path.startPoint.x && pathFinderNode.Z == path.startPoint.z)
164 {
165 path.nodes.RemoveAt(path.nodes.Count - 1);
166 }
167 }
168 if (path.nodes.Count == 0)
169 {
170 path.state = PathProgress.State.Fail;
171 return;
172 }
173 path.state = PathProgress.State.PathReady;
174 path.nodeIndex = path.nodes.Count - 1;
175 }
176
177 private void _FindPath(PathProgress path)
178 {
179 lock (this)
180 {
181 Point startPoint = path.startPoint;
182 Point destPoint = path.destPoint;
183 path.nodes.Clear();
184 mFound = (mStop = (mStopped = false));
186 mOpenNodeValue += 2;
187 mCloseNodeValue += 2;
188 mOpen.Clear();
189 mLocation = (mStartLocation = startPoint.z * mGridX + startPoint.x);
190 mEndLocation = destPoint.z * mGridX + destPoint.x;
191 if (mLocation >= mCalcGrid.Length)
192 {
193 if (debug)
194 {
195 Debug.Log("length over");
196 }
197 }
198 else
199 {
200 if (mEndLocation == mLocation)
201 {
202 return;
203 }
204 mCalcGrid[mLocation].G = 0;
206 mCalcGrid[mLocation].PX = (ushort)startPoint.x;
207 mCalcGrid[mLocation].PZ = (ushort)startPoint.z;
210 while (mOpen.Count > 0 && !mStop)
211 {
212 mLocation = mOpen.Pop();
213 if (mCalcGrid[mLocation].Status == mCloseNodeValue)
214 {
215 continue;
216 }
217 mLocationX = (ushort)(mLocation % mGridX);
218 mLocationZ = (ushort)(mLocation % mGridXZ / mGridX);
219 if (mLocation == mEndLocation)
220 {
222 mFound = true;
223 break;
224 }
226 {
227 mStopped = true;
228 if (path.searchLimit > 1000)
229 {
230 Debug.Log("search limit: " + path.startPoint?.ToString() + " " + path.destPoint);
231 }
232 return;
233 }
235 {
237 }
238 for (int i = 0; i < (Diagonals ? 8 : 4); i++)
239 {
240 mNewLocationX = (ushort)(mLocationX + mDirection[i, 0]);
241 mNewLocationZ = (ushort)(mLocationZ + mDirection[i, 1]);
244 {
245 continue;
246 }
248 {
249 _weight = 1;
250 }
251 else
252 {
253 if (i < 4)
254 {
255 index = ((mNewLocationZ >= mLocationZ) ? ((mNewLocationX > mLocationX) ? 1 : ((mNewLocationZ > mLocationZ) ? 2 : 3)) : 0);
257 }
258 else
259 {
260 mx = mLocationX + mDirection[i, 0];
261 mz = mLocationZ;
262 index = ((mz >= mLocationZ) ? ((mx > mLocationX) ? 1 : ((mz > mLocationZ) ? 2 : 3)) : 0);
264 if (weightMap[mx, mz].IsPathBlocked(walker, moveType))
265 {
266 _weight = 0;
267 }
268 if (_weight > 0)
269 {
270 index = ((mz >= mNewLocationZ) ? ((mx > mNewLocationX) ? 1 : ((mz > mNewLocationZ) ? 2 : 3)) : 0);
272 if (_weight > 0)
273 {
274 mx = mLocationX;
275 mz = mLocationZ + mDirection[i, 1];
276 index = ((mz >= mLocationZ) ? ((mx > mLocationX) ? 1 : ((mz > mLocationZ) ? 2 : 3)) : 0);
278 if (weightMap[mx, mz].IsPathBlocked(walker, moveType))
279 {
280 _weight = 0;
281 }
282 if (_weight > 0)
283 {
284 index = ((mz >= mNewLocationZ) ? ((mx > mNewLocationX) ? 1 : ((mz > mNewLocationZ) ? 2 : 3)) : 0);
286 }
287 }
288 }
289 }
290 if (_weight == 0)
291 {
292 continue;
293 }
296 {
297 continue;
298 }
299 }
302 {
303 if (mNewLocationX - mLocationX != 0 && mHoriz == 0)
304 {
305 mNewG += Math.Abs(mNewLocationX - destPoint.x) + Math.Abs(mNewLocationZ - destPoint.z);
306 }
307 if (mNewLocationZ - mLocationZ != 0 && mHoriz != 0)
308 {
309 mNewG += Math.Abs(mNewLocationX - destPoint.x) + Math.Abs(mNewLocationZ - destPoint.z);
310 }
311 }
313 {
317 switch (mFormula)
318 {
319 default:
320 mH = mHEstimate * (Math.Abs(mNewLocationX - destPoint.x) + Math.Abs(mNewLocationZ - destPoint.z));
321 break;
322 case HeuristicFormula.MaxDXDY:
323 mH = mHEstimate * Math.Max(Math.Abs(mNewLocationX - destPoint.x), Math.Abs(mNewLocationZ - destPoint.z));
324 break;
325 case HeuristicFormula.DiagonalShortCut:
326 {
327 int num = Math.Min(Math.Abs(mNewLocationX - destPoint.x), Math.Abs(mNewLocationZ - destPoint.z));
328 int num2 = Math.Abs(mNewLocationX - destPoint.x) + Math.Abs(mNewLocationZ - destPoint.z);
329 mH = mHEstimate * 2 * num + mHEstimate * (num2 - 2 * num);
330 break;
331 }
332 case HeuristicFormula.Euclidean:
333 mH = (int)((double)mHEstimate * Math.Sqrt(Math.Pow(mNewLocationZ - destPoint.x, 2.0) + Math.Pow(mNewLocationZ - destPoint.z, 2.0)));
334 break;
335 case HeuristicFormula.EuclideanNoSQR:
336 mH = (int)((double)mHEstimate * (Math.Pow(mNewLocationX - destPoint.x, 2.0) + Math.Pow(mNewLocationZ - destPoint.z, 2.0)));
337 break;
338 }
339 if (TieBreaker)
340 {
341 int num3 = mLocationX - destPoint.x;
342 int num4 = mLocationZ - destPoint.z;
343 int num5 = startPoint.x - destPoint.x;
344 int num6 = startPoint.z - destPoint.z;
345 int num7 = Math.Abs(num3 * num6 - num5 * num4);
346 mH = (int)((double)mH + (double)num7 * 0.001);
347 }
351 }
352 }
355 }
356 if (mFound)
357 {
358 int x = destPoint.x;
359 int z = destPoint.z;
360 PathFinderNodeFast pathFinderNodeFast = mCalcGrid[destPoint.z * mGridX + destPoint.x];
362 item.G = pathFinderNodeFast.G;
363 item.PX = pathFinderNodeFast.PX;
364 item.PZ = pathFinderNodeFast.PZ;
365 item.X = destPoint.x;
366 item.Z = destPoint.z;
367 while (item.X != item.PX || item.Z != item.PZ)
368 {
369 path.nodes.Add(item);
370 x = item.PX;
371 z = item.PZ;
372 pathFinderNodeFast = mCalcGrid[z * mGridX + x];
373 item.G = pathFinderNodeFast.G;
374 item.PX = pathFinderNodeFast.PX;
375 item.PZ = pathFinderNodeFast.PZ;
376 item.X = x;
377 item.Z = z;
378 }
379 path.nodes.Add(item);
380 mStopped = true;
381 }
382 else
383 {
384 mStopped = true;
385 }
386 }
387 }
388 }
389}
ComparePFNodeMatrix(PathFinderNodeFast[] matrix)
Definition: PathFinder.cs:28
void FindPath(PathProgress path)
Definition: PathFinder.cs:155
IPathfindGrid grid
Definition: PathFinder.cs:59
IPathfindWalker walker
Definition: PathFinder.cs:61
HeuristicFormula mFormula
Definition: PathFinder.cs:57
PathManager.MoveType moveType
Definition: PathFinder.cs:81
PathFinderNodeFast[] mCalcGrid
Definition: PathFinder.cs:75
PriorityQueueB< int > mOpen
Definition: PathFinder.cs:65
void Init(IPathfindGrid _grid, WeightCell[,] _weightMap, int size)
Definition: PathFinder.cs:141
WeightCell[,] weightMap
Definition: PathFinder.cs:130
static unsafe bool ZeroMemory(byte *destination, int length)
void _FindPath(PathProgress path)
Definition: PathFinder.cs:177
Point startPoint
Definition: PathProgress.cs:18
Point destPoint
Definition: PathProgress.cs:20
PathManager.MoveType moveType
Definition: PathProgress.cs:32
List< PathFinderNode > nodes
Definition: PathProgress.cs:16
bool ignoreConnection
Definition: PathProgress.cs:30
IPathfindWalker walker
Definition: PathProgress.cs:14
Definition: Point.cs:9
override string ToString()
Definition: Point.cs:524
int x
Definition: Point.cs:36
int z
Definition: Point.cs:39