RuneHive-Game
Loading...
Searching...
No Matches
DijkstraPathFinder.java
Go to the documentation of this file.
1package com.runehive.game.world.pathfinding.path.impl;
2
3import com.runehive.game.world.Interactable;
4import com.runehive.game.world.entity.mob.Mob;
5import com.runehive.game.world.pathfinding.path.Path;
6import com.runehive.game.world.pathfinding.path.PathFinder;
7import com.runehive.game.world.position.Position;
8import com.runehive.game.world.region.Region;
9import com.runehive.util.Utility;
10
11import java.util.ArrayList;
12import java.util.Deque;
13import java.util.LinkedList;
14import java.util.List;
15
16import static com.runehive.game.world.entity.mob.Direction.*;
17
18public final class DijkstraPathFinder extends PathFinder {
19
20 @Override
21 public Path find(Mob source, Position target, int targetWidth, int targetLength) {
22 final Deque<Position> path = new LinkedList<>();
23
24 final int distance = source.getPosition().getChebyshevDistance(target);
25 if (distance > Region.SIZE) {
26 return new Path(path); // don't allow pathfinding too far distances away to prevent easily abusing smart pathfinder.
27 }
28
29 Position targ = target;
30 target = Utility.findBestInside(source, Interactable.create(target, targetWidth, targetLength));
31
32 if (source.getPosition().equals(target)) {
33 path.add(source.getPosition());
34 return new Path(path);
35 }
36
37 int tail = 0;
38 int[][] via = new int[104][104];
39 int[][] cost = new int[104][104];
40 int regionX = source.getPosition().getChunkX() << 3;
41 int regionY = source.getPosition().getChunkY() << 3;
42 int curX = source.getPosition().getLocalX();
43 int curY = source.getPosition().getLocalY();
44 int destX = target.getX() - regionX;
45 int destY = target.getY() - regionY;
46 List<Integer> tileQueueX = new ArrayList<>(9000);
47 List<Integer> tileQueueY = new ArrayList<>(9000);
48
49 via[curX][curY] = 99;
50 cost[curX][curY] = 1;
51 tileQueueX.add(curX);
52 tileQueueY.add(curY);
53
54 boolean foundPath = false;
55 int pathLength = 4096;
56
57 while (tail != tileQueueX.size() && tileQueueX.size() < pathLength) {
58
59 curX = tileQueueX.get(tail);
60 curY = tileQueueY.get(tail);
61
62 int curAbsX = regionX + curX;
63 int curAbsY = regionY + curY;
64
65 if (curX == destX && curY == destY) {
66 foundPath = true;
67 break;
68 }
69
70 Position position = Position.create(curAbsX, curAbsY, source.getHeight());
71 if (targetWidth > 0 && targetLength > 0 && Region.reachable(targ, targetWidth, targetLength, position, source.width(), source.length())) {
72 foundPath = true;
73 break;
74 }
75
76 int thisCost = cost[curX][curY] + 1 + 1;
77 tail = (tail + 1) % pathLength;
78
79 if (curY > 0 && via[curX][curY - 1] == 0
80 && traversable(position, source.width(), SOUTH)) {
81 tileQueueX.add(curX);
82 tileQueueY.add(curY - 1);
83 via[curX][curY - 1] = 1;
84 cost[curX][curY - 1] = thisCost;
85 }
86
87 if (curX > 0 && via[curX - 1][curY] == 0
88 && traversable(position, source.width(), WEST)) {
89 tileQueueX.add(curX - 1);
90 tileQueueY.add(curY);
91 via[curX - 1][curY] = 2;
92 cost[curX - 1][curY] = thisCost;
93 }
94
95 if (curY < 104 - 1 && via[curX][curY + 1] == 0
96 && traversable(position, source.width(), NORTH)) {
97 tileQueueX.add(curX);
98 tileQueueY.add(curY + 1);
99 via[curX][curY + 1] = 4;
100 cost[curX][curY + 1] = thisCost;
101 }
102
103 if (curX < 104 - 1 && via[curX + 1][curY] == 0
104 && traversable(position, source.width(), EAST)) {
105 tileQueueX.add(curX + 1);
106 tileQueueY.add(curY);
107 via[curX + 1][curY] = 8;
108 cost[curX + 1][curY] = thisCost;
109 }
110
111 if (curX > 0 && curY > 0 && via[curX - 1][curY - 1] == 0
112 && traversable(position, source.width(), SOUTH_WEST)
113 && traversable(position, source.width(), SOUTH)
114 && traversable(position, source.width(), WEST)) {
115 tileQueueX.add(curX - 1);
116 tileQueueY.add(curY - 1);
117 via[curX - 1][curY - 1] = 3;
118 cost[curX - 1][curY - 1] = thisCost;
119 }
120
121 if (curX > 0 && curY < 104 - 1 && via[curX - 1][curY + 1] == 0
122 && traversable(position, source.width(), NORTH_WEST)
123 && traversable(position, source.width(), NORTH)
124 && traversable(position, source.width(), WEST)) {
125 tileQueueX.add(curX - 1);
126 tileQueueY.add(curY + 1);
127 via[curX - 1][curY + 1] = 6;
128 cost[curX - 1][curY + 1] = thisCost;
129 }
130
131 if (curX < 104 - 1 && curY > 0 && via[curX + 1][curY - 1] == 0
132 && traversable(position, source.width(), SOUTH_EAST)
133 && traversable(position, source.width(), SOUTH)
134 && traversable(position, source.width(), EAST)) {
135 tileQueueX.add(curX + 1);
136 tileQueueY.add(curY - 1);
137 via[curX + 1][curY - 1] = 9;
138 cost[curX + 1][curY - 1] = thisCost;
139 }
140
141 if (curX < 104 - 1 && curY < 104 - 1 && via[curX + 1][curY + 1] == 0
142 && traversable(position, source.width(), NORTH_EAST)
143 && traversable(position, source.width(), NORTH)
144 && traversable(position, source.width(), EAST)) {
145 tileQueueX.add(curX + 1);
146 tileQueueY.add(curY + 1);
147 via[curX + 1][curY + 1] = 12;
148 cost[curX + 1][curY + 1] = thisCost;
149 }
150 }
151
152 if (!foundPath) {
153 int hippo_max = 1_000;
154 int thisCost = 100 + 1;
155 int init_x = 10;
156
157 for (int x = destX - init_x; x <= destX + init_x; x++) {
158 for (int y = destY - init_x; y <= destY + init_x; y++) {
159 if (x >= 0 && y >= 0 && x < 104 && y < 104 && cost[x][y] < 100 && cost[x][y] != 0) {
160 int dx = 0;
161 if (x < destX) {
162 dx = destX - x;
163 } else if (x > destX + source.width() - 1) {
164 dx = x - (destX + source.width() - 1);
165 }
166 int dy = 0;
167 if (y < destY) {
168 dy = destY - y;
169 } else if (y > destY + source.length() - 1) {
170 dy = y - (destY + source.length() - 1);
171 }
172 int hippo = dx * dx + dy * dy;
173 if (hippo < hippo_max || hippo == hippo_max && cost[x][y] < thisCost && cost[x][y] != 0) {
174 hippo_max = hippo;
175 thisCost = cost[x][y];
176 curX = x;
177 curY = y;
178 }
179 }
180 }
181 }
182
183 if (hippo_max == 1000) {
184 return new Path(null);
185 }
186 }
187
188 tail = 0;
189 tileQueueX.set(tail, curX);
190 tileQueueY.set(tail++, curY);
191 int vurVia;
192
193 for (int nextVia = vurVia = via[curX][curY]; curX != source.getPosition().getLocalX() || curY != source.getPosition().getLocalY(); nextVia = via[curX][curY]) {
194 if (nextVia != vurVia) {
195 vurVia = nextVia;
196 tileQueueX.set(tail, curX);
197 tileQueueY.set(tail++, curY);
198 }
199 if ((nextVia & 2) != 0) {
200 curX++;
201 } else if ((nextVia & 8) != 0) {
202 curX--;
203 }
204 if ((nextVia & 1) != 0) {
205 curY++;
206 } else if ((nextVia & 4) != 0) {
207 curY--;
208 }
209 }
210
211 int s = tail--;
212 int pathX = (regionX) + tileQueueX.get(tail);
213 int pathY = (regionY) + tileQueueY.get(tail);
214
215 path.add(Position.create(pathX, pathY));
216
217 for (int i = 1; i < s; i++) {
218 tail--;
219 pathX = (regionX) + tileQueueX.get(tail);
220 pathY = (regionY) + tileQueueY.get(tail);
221 path.add(Position.create(pathX, pathY));
222 }
223
224 return new Path(path);
225 }
226
227}
Handles the mob class.
Definition Mob.java:66
An algorithm used to find a path between two Positions.
boolean traversable(Position current, int size, Direction... directions)
Returns whether or not a Position walking one step in any of the specified Directions would lead to i...
Represents a single path in the path finding system.
Definition Path.java:13
Path find(Mob source, Position target, int targetWidth, int targetLength)
Finds a valid path from the origin Position to the target one.
Represents a single tile on the game world.
Definition Position.java:14
int getY()
Gets the absolute y coordinate.
Definition Position.java:46
int getX()
Gets the absolute x coordinate.
Definition Position.java:41
int getLocalY()
Gets the local y coordinate relative to this region.
Definition Position.java:61
static Position create(int x, int y, int z)
Creates a location.
int getChunkX()
Gets the chunk x coordinate.
Definition Position.java:76
int getLocalX()
Gets the local x coordinate relative to this region.
Definition Position.java:56
int getChunkY()
Gets the chunk y coordinate.
Definition Position.java:81
Represents a single region.
Definition Region.java:21
static boolean reachable(Interactable source, Interactable target)
Definition Region.java:227
Handles miscellaneous methods.
Definition Utility.java:27
static Position findBestInside(Interactable source, Interactable target)
Definition Utility.java:498
An object implementing Interactable has uses.
static Interactable create(Position position)
Creates a new instance of an Interactable.