RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
DijkstraPathFinder.java
1package com.osroyale.game.world.pathfinding.path.impl;
2
3import com.osroyale.game.world.Interactable;
4import com.osroyale.game.world.entity.mob.Mob;
5import com.osroyale.game.world.pathfinding.path.Path;
6import com.osroyale.game.world.pathfinding.path.PathFinder;
7import com.osroyale.game.world.position.Position;
8import com.osroyale.game.world.region.Region;
9import com.osroyale.util.Utility;
10
11import java.util.ArrayList;
12import java.util.Deque;
13import java.util.LinkedList;
14import java.util.List;
15
16import static com.osroyale.game.world.entity.mob.Direction.*;
17
48
49public final class DijkstraPathFinder extends PathFinder {
50
51 @Override
52 public Path find(Mob source, Position target, int targetWidth, int targetLength) {
53 final Deque<Position> path = new LinkedList<>();
54
55 final int distance = source.getPosition().getChebyshevDistance(target);
56 if (distance > Region.SIZE) {
57 return new Path(path); // don't allow pathfinding too far distances away to prevent easily abusing smart pathfinder.
58 }
59
60 Position targ = target;
61 target = Utility.findBestInside(source, Interactable.create(target, targetWidth, targetLength));
62
63 if (source.getPosition().equals(target)) {
64 path.add(source.getPosition());
65 return new Path(path);
66 }
67
68 int tail = 0;
69 int[][] via = new int[104][104];
70 int[][] cost = new int[104][104];
71 int regionX = source.getPosition().getChunkX() << 3;
72 int regionY = source.getPosition().getChunkY() << 3;
73 int curX = source.getPosition().getLocalX();
74 int curY = source.getPosition().getLocalY();
75 int destX = target.getX() - regionX;
76 int destY = target.getY() - regionY;
77 List<Integer> tileQueueX = new ArrayList<>(9000);
78 List<Integer> tileQueueY = new ArrayList<>(9000);
79
80 via[curX][curY] = 99;
81 cost[curX][curY] = 1;
82 tileQueueX.add(curX);
83 tileQueueY.add(curY);
84
85 boolean foundPath = false;
86 int pathLength = 4096;
87
88 while (tail != tileQueueX.size() && tileQueueX.size() < pathLength) {
89
90 curX = tileQueueX.get(tail);
91 curY = tileQueueY.get(tail);
92
93 int curAbsX = regionX + curX;
94 int curAbsY = regionY + curY;
95
96 if (curX == destX && curY == destY) {
97 foundPath = true;
98 break;
99 }
100
101 Position position = Position.create(curAbsX, curAbsY, source.getHeight());
102 if (targetWidth > 0 && targetLength > 0 && Region.reachable(targ, targetWidth, targetLength, position, source.width(), source.length())) {
103 foundPath = true;
104 break;
105 }
106
107 int thisCost = cost[curX][curY] + 1 + 1;
108 tail = (tail + 1) % pathLength;
109
110 if (curY > 0 && via[curX][curY - 1] == 0
111 && traversable(position, source.width(), SOUTH)) {
112 tileQueueX.add(curX);
113 tileQueueY.add(curY - 1);
114 via[curX][curY - 1] = 1;
115 cost[curX][curY - 1] = thisCost;
116 }
117
118 if (curX > 0 && via[curX - 1][curY] == 0
119 && traversable(position, source.width(), WEST)) {
120 tileQueueX.add(curX - 1);
121 tileQueueY.add(curY);
122 via[curX - 1][curY] = 2;
123 cost[curX - 1][curY] = thisCost;
124 }
125
126 if (curY < 104 - 1 && via[curX][curY + 1] == 0
127 && traversable(position, source.width(), NORTH)) {
128 tileQueueX.add(curX);
129 tileQueueY.add(curY + 1);
130 via[curX][curY + 1] = 4;
131 cost[curX][curY + 1] = thisCost;
132 }
133
134 if (curX < 104 - 1 && via[curX + 1][curY] == 0
135 && traversable(position, source.width(), EAST)) {
136 tileQueueX.add(curX + 1);
137 tileQueueY.add(curY);
138 via[curX + 1][curY] = 8;
139 cost[curX + 1][curY] = thisCost;
140 }
141
142 if (curX > 0 && curY > 0 && via[curX - 1][curY - 1] == 0
143 && traversable(position, source.width(), SOUTH_WEST)
144 && traversable(position, source.width(), SOUTH)
145 && traversable(position, source.width(), WEST)) {
146 tileQueueX.add(curX - 1);
147 tileQueueY.add(curY - 1);
148 via[curX - 1][curY - 1] = 3;
149 cost[curX - 1][curY - 1] = thisCost;
150 }
151
152 if (curX > 0 && curY < 104 - 1 && via[curX - 1][curY + 1] == 0
153 && traversable(position, source.width(), NORTH_WEST)
154 && traversable(position, source.width(), NORTH)
155 && traversable(position, source.width(), WEST)) {
156 tileQueueX.add(curX - 1);
157 tileQueueY.add(curY + 1);
158 via[curX - 1][curY + 1] = 6;
159 cost[curX - 1][curY + 1] = thisCost;
160 }
161
162 if (curX < 104 - 1 && curY > 0 && via[curX + 1][curY - 1] == 0
163 && traversable(position, source.width(), SOUTH_EAST)
164 && traversable(position, source.width(), SOUTH)
165 && traversable(position, source.width(), EAST)) {
166 tileQueueX.add(curX + 1);
167 tileQueueY.add(curY - 1);
168 via[curX + 1][curY - 1] = 9;
169 cost[curX + 1][curY - 1] = thisCost;
170 }
171
172 if (curX < 104 - 1 && curY < 104 - 1 && via[curX + 1][curY + 1] == 0
173 && traversable(position, source.width(), NORTH_EAST)
174 && traversable(position, source.width(), NORTH)
175 && traversable(position, source.width(), EAST)) {
176 tileQueueX.add(curX + 1);
177 tileQueueY.add(curY + 1);
178 via[curX + 1][curY + 1] = 12;
179 cost[curX + 1][curY + 1] = thisCost;
180 }
181 }
182
183 if (!foundPath) {
184 int hippo_max = 1_000;
185 int thisCost = 100 + 1;
186 int init_x = 10;
187
188 for (int x = destX - init_x; x <= destX + init_x; x++) {
189 for (int y = destY - init_x; y <= destY + init_x; y++) {
190 if (x >= 0 && y >= 0 && x < 104 && y < 104 && cost[x][y] < 100 && cost[x][y] != 0) {
191 int dx = 0;
192 if (x < destX) {
193 dx = destX - x;
194 } else if (x > destX + source.width() - 1) {
195 dx = x - (destX + source.width() - 1);
196 }
197 int dy = 0;
198 if (y < destY) {
199 dy = destY - y;
200 } else if (y > destY + source.length() - 1) {
201 dy = y - (destY + source.length() - 1);
202 }
203 int hippo = dx * dx + dy * dy;
204 if (hippo < hippo_max || hippo == hippo_max && cost[x][y] < thisCost && cost[x][y] != 0) {
205 hippo_max = hippo;
206 thisCost = cost[x][y];
207 curX = x;
208 curY = y;
209 }
210 }
211 }
212 }
213
214 if (hippo_max == 1000) {
215 return new Path(null);
216 }
217 }
218
219 tail = 0;
220 tileQueueX.set(tail, curX);
221 tileQueueY.set(tail++, curY);
222 int vurVia;
223
224 for (int nextVia = vurVia = via[curX][curY]; curX != source.getPosition().getLocalX() || curY != source.getPosition().getLocalY(); nextVia = via[curX][curY]) {
225 if (nextVia != vurVia) {
226 vurVia = nextVia;
227 tileQueueX.set(tail, curX);
228 tileQueueY.set(tail++, curY);
229 }
230 if ((nextVia & 2) != 0) {
231 curX++;
232 } else if ((nextVia & 8) != 0) {
233 curX--;
234 }
235 if ((nextVia & 1) != 0) {
236 curY++;
237 } else if ((nextVia & 4) != 0) {
238 curY--;
239 }
240 }
241
242 int s = tail--;
243 int pathX = (regionX) + tileQueueX.get(tail);
244 int pathY = (regionY) + tileQueueY.get(tail);
245
246 path.add(Position.create(pathX, pathY));
247
248 for (int i = 1; i < s; i++) {
249 tail--;
250 pathX = (regionX) + tileQueueX.get(tail);
251 pathY = (regionY) + tileQueueY.get(tail);
252 path.add(Position.create(pathX, pathY));
253 }
254
255 return new Path(path);
256 }
257
258}
boolean traversable(Position current, int size, Direction... directions)
Path find(Mob source, Position target, int targetWidth, int targetLength)
static Position create(int x, int y, int z)
static Interactable create(Position position)