RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
TraversalMap.java
1package com.osroyale.game.world.pathfinding;
2
3import com.osroyale.game.world.World;
4import com.osroyale.game.world.entity.mob.Direction;
5import com.osroyale.game.world.object.GameObject;
6import com.osroyale.game.world.object.GameObjectDefinition;
7import com.osroyale.game.world.object.ObjectDirection;
8import com.osroyale.game.world.object.ObjectType;
9import com.osroyale.game.world.position.Position;
10import com.osroyale.game.world.region.Region;
11import com.osroyale.util.RandomUtils;
12
13import java.util.LinkedList;
14import java.util.List;
15
16import static com.osroyale.game.world.object.ObjectType.*;
17
60
61public final class TraversalMap {
62
63 private TraversalMap() {}
64
73 public static void markObject(Region region, GameObject object, boolean add, boolean list) {
74 if (object.getId() > GameObjectDefinition.MAX_DEFINITIONS) {
75 return;
76 }
77
78 GameObjectDefinition def = object.getDefinition();
79
80 if (def.isSolid()) {
81 Position position = object.getPosition();
82
83 //Sets the sizes.
84 final int sizeX;
85 final int sizeY;
86
87 if (object.getDirection() == ObjectDirection.NORTH || object.getDirection() == ObjectDirection.SOUTH) {
88 sizeX = def.getLength();
89 sizeY = def.getWidth();
90 } else {
91 sizeX = def.getWidth();
92 sizeY = def.getLength();
93 }
94
95 if (object.getObjectType() == GROUND_PROP) {
96 if (def.hasActions() || def.isDecoration()) {
97 if (def.hasActions()) {
98 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, false, add);
99 }
100 }
101 } else if (object.getObjectType() == GENERAL_PROP || object.getObjectType() == WALKABLE_PROP) {
102 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, def.isImpenetrable(), add);
103 } else if (object.getObjectType().getId() >= 12) {
104 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, def.isImpenetrable(), add);
105 } else if (object.getObjectType() == DIAGONAL_WALL) {
106 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, def.isImpenetrable(), add);
107 } else if (object.getObjectType().getId() >= 0 && object.getObjectType().getId() <= 3) {
108 if (add)
109 markWall(region, object.getDirection(), position.getHeight(), position.getX(), position.getY(), object.getObjectType(), def.isImpenetrable());
110 else
111 unmarkWall(region, object.getDirection(), position.getHeight(), position.getX(), position.getY(), object.getObjectType(), def.isImpenetrable());
112 }
113 }
114
115 if (list && (object.getId() == 11700 || object.getDefinition().hasActions())) {
116 if (add) region.addObject(object);
117 else region.removeObject(object);
118 }
119 }
120
131 private static void markWall(Region reg, ObjectDirection orientation, int height, int x, int y, ObjectType type, boolean impenetrable) {
132 switch (type) {
133 case STRAIGHT_WALL:
134 if (orientation == ObjectDirection.WEST) {
135 set(reg, height, x, y, TraversalConstants.WALL_WEST);
136 set(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
137 if (impenetrable) {
138 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
139 set(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
140 }
141 }
142 if (orientation == ObjectDirection.NORTH) {
143 set(reg, height, x, y, TraversalConstants.WALL_NORTH);
144 set(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
145 if (impenetrable) {
146 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH);
147 set(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
148 }
149 }
150 if (orientation == ObjectDirection.EAST) {
151 set(reg, height, x, y, TraversalConstants.WALL_EAST);
152 set(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
153 if (impenetrable) {
154 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
155 set(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
156 }
157 }
158 if (orientation == ObjectDirection.SOUTH) {
159 set(reg, height, x, y, TraversalConstants.WALL_SOUTH);
160 set(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
161 if (impenetrable) {
162 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
163 set(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
164 }
165 }
166 break;
167
168 case ENTIRE_WALL:
169 if (orientation == ObjectDirection.WEST) {
170 set(reg, height, x, y, TraversalConstants.WALL_WEST | TraversalConstants.WALL_NORTH);
171 set(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
172 set(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
173 if (impenetrable) {
174 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_WALL_NORTH);
175 set(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
176 set(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
177 }
178 }
179 if (orientation == ObjectDirection.NORTH) {
180 set(reg, height, x, y, TraversalConstants.WALL_EAST | TraversalConstants.WALL_NORTH);
181 set(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
182 set(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
183 if (impenetrable) {
184 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_NORTH);
185 set(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
186 set(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
187 }
188 }
189 if (orientation == ObjectDirection.EAST) {
190 set(reg, height, x, y, TraversalConstants.WALL_EAST | TraversalConstants.WALL_SOUTH);
191 set(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
192 set(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
193 if (impenetrable) {
194 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_SOUTH);
195 set(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
196 set(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
197 }
198 }
199 if (orientation == ObjectDirection.SOUTH) {
200 set(reg, height, x, y, TraversalConstants.WALL_WEST | TraversalConstants.WALL_SOUTH);
201 set(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
202 set(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
203 if (impenetrable) {
204 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_WALL_SOUTH);
205 set(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
206 set(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
207 }
208 }
209 break;
210
211 case DIAGONAL_CORNER_WALL:
212 case WALL_CORNER:
213 if (orientation == ObjectDirection.WEST) {
214 set(reg, height, x, y, TraversalConstants.WALL_NORTH_WEST);
215 set(reg, height, x - 1, y + 1, TraversalConstants.WALL_SOUTH_EAST);
216 if (impenetrable) {
217 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
218 set(reg, height, x - 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
219 }
220 }
221 if (orientation == ObjectDirection.NORTH) {
222 set(reg, height, x, y, TraversalConstants.WALL_NORTH_EAST);
223 set(reg, height, x + 1, y + 1, TraversalConstants.WALL_SOUTH_WEST);
224 if (impenetrable) {
225 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
226 set(reg, height, x + 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
227 }
228 }
229 if (orientation == ObjectDirection.EAST) {
230 set(reg, height, x, y, TraversalConstants.WALL_SOUTH_EAST);
231 set(reg, height, x + 1, y - 1, TraversalConstants.WALL_NORTH_WEST);
232 if (impenetrable) {
233 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
234 set(reg, height, x + 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
235 }
236 }
237 if (orientation == ObjectDirection.SOUTH) {
238 set(reg, height, x, y, TraversalConstants.WALL_SOUTH_WEST);
239 set(reg, height, x - 1, y - 1, TraversalConstants.WALL_NORTH_EAST);
240 if (impenetrable) {
241 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
242 set(reg, height, x - 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
243 }
244 }
245 break;
246 default:
247 break;
248 }
249 }
250
261 private static void unmarkWall(Region reg, ObjectDirection orientation, int height, int x, int y, ObjectType type, boolean impenetrable) {
262 switch (type) {
263 case STRAIGHT_WALL:
264 if (orientation == ObjectDirection.WEST) {
265 unset(reg, height, x, y, TraversalConstants.WALL_WEST);
266 unset(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
267 if (impenetrable) {
268 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
269 unset(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
270 }
271 }
272 if (orientation == ObjectDirection.NORTH) {
273 unset(reg, height, x, y, TraversalConstants.WALL_NORTH);
274 unset(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
275 if (impenetrable) {
276 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH);
277 unset(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
278 }
279 }
280 if (orientation == ObjectDirection.EAST) {
281 unset(reg, height, x, y, TraversalConstants.WALL_EAST);
282 unset(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
283 if (impenetrable) {
284 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
285 unset(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
286 }
287 }
288 if (orientation == ObjectDirection.SOUTH) {
289 unset(reg, height, x, y, TraversalConstants.WALL_SOUTH);
290 unset(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
291 if (impenetrable) {
292 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
293 unset(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
294 }
295 }
296 break;
297
298 case ENTIRE_WALL:
299 if (orientation == ObjectDirection.WEST) {
300 unset(reg, height, x, y, TraversalConstants.WALL_WEST | TraversalConstants.WALL_NORTH);
301 unset(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
302 unset(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
303 if (impenetrable) {
304 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_WALL_NORTH);
305 unset(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
306 unset(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
307 }
308 }
309 if (orientation == ObjectDirection.NORTH) {
310 unset(reg, height, x, y, TraversalConstants.WALL_EAST | TraversalConstants.WALL_NORTH);
311 unset(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
312 unset(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
313 if (impenetrable) {
314 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_NORTH);
315 unset(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
316 unset(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
317 }
318 }
319 if (orientation == ObjectDirection.EAST) {
320 unset(reg, height, x, y, TraversalConstants.WALL_EAST | TraversalConstants.WALL_SOUTH);
321 unset(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
322 unset(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
323 if (impenetrable) {
324 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_SOUTH);
325 unset(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
326 unset(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
327 }
328 }
329 if (orientation == ObjectDirection.SOUTH) {
330 unset(reg, height, x, y, TraversalConstants.WALL_EAST | TraversalConstants.WALL_SOUTH);
331 unset(reg, height, x, y - 1, TraversalConstants.WALL_WEST);
332 unset(reg, height, x - 1, y, TraversalConstants.WALL_NORTH);
333 if (impenetrable) {
334 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_SOUTH);
335 unset(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_WEST);
336 unset(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_NORTH);
337 }
338 }
339 break;
340
341 case DIAGONAL_CORNER_WALL:
342 case WALL_CORNER:
343 if (orientation == ObjectDirection.WEST) {
344 unset(reg, height, x, y, TraversalConstants.WALL_NORTH_WEST);
345 unset(reg, height, x - 1, y + 1, TraversalConstants.WALL_SOUTH_EAST);
346 if (impenetrable) {
347 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
348 unset(reg, height, x - 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
349 }
350 }
351 if (orientation == ObjectDirection.NORTH) {
352 unset(reg, height, x, y, TraversalConstants.WALL_NORTH_EAST);
353 unset(reg, height, x + 1, y + 1, TraversalConstants.WALL_SOUTH_WEST);
354 if (impenetrable) {
355 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
356 unset(reg, height, x + 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
357 }
358 }
359 if (orientation == ObjectDirection.EAST) {
360 unset(reg, height, x, y, TraversalConstants.WALL_SOUTH_EAST);
361 unset(reg, height, x + 1, y - 1, TraversalConstants.WALL_NORTH_WEST);
362 if (impenetrable) {
363 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
364 unset(reg, height, x + 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
365 }
366 }
367 if (orientation == ObjectDirection.SOUTH) {
368 unset(reg, height, x, y, TraversalConstants.WALL_SOUTH_WEST);
369 unset(reg, height, x - 1, y - 1, TraversalConstants.WALL_NORTH_EAST);
370 if (impenetrable) {
371 unset(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
372 unset(reg, height, x - 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
373 }
374 }
375 break;
376 default:
377 break;
378 }
379 }
380
389 public static void block(Region region, int height, int localX, int localY) {
390 region.setFlags(height, localX, localY, TraversalConstants.BLOCKED);
391 }
392
405 public static void markOccupant(Region region, int height, int x, int y, int width, int length, boolean impenetrable, boolean add) {
406 int flag = TraversalConstants.BLOCKED;
407 if (impenetrable) {
409 }
410 for (int xPos = x; xPos < x + width; xPos++) {
411 for (int yPos = y; yPos < y + length; yPos++) {
412 if (add) set(region, height, xPos, yPos, flag);
413 else unset(region, height, xPos, yPos, flag);
414 }
415 }
416 }
417
425 public static void markBridge(Region region, int height, int x, int y) {
426 set(region, height, x, y, TraversalConstants.BRIDGE);
427 }
428
439 private static boolean isTraversableNorth(int height, int x, int y, int size) {
440 for (int offsetX = 0; offsetX < size; offsetX++) {
441 for (int offsetY = 0; offsetY < size; offsetY++) {
442 if (!isTraversableNorth(height, x + offsetX, y + offsetY)) {
443 return false;
444 }
445 }
446 }
447 return true;
448 }
449
459 private static boolean isTraversableNorth(int height, int x, int y) {
460 return isTraversableNorth(height, x, y, false);
461 }
462
473 private static boolean isTraversableNorth(int height, int x, int y, boolean impenetrable) {
474 if (impenetrable) {
475 return isInactive(height, x, y + 1, TraversalConstants.IMPENETRABLE_BLOCKED | TraversalConstants.IMPENETRABLE_WALL_SOUTH);
476 }
477 return isInactive(height, x, y + 1, TraversalConstants.WALL_SOUTH | TraversalConstants.BLOCKED);
478 }
479
490 private static boolean isTraversableSouth(int height, int x, int y, int size) {
491 for (int offsetX = 0; offsetX < size; offsetX++) {
492 for (int offsetY = 0; offsetY < size; offsetY++) {
493 if (!isTraversableSouth(height, x + offsetX, y + offsetY)) {
494 return false;
495 }
496 }
497 }
498 return true;
499 }
500
510 private static boolean isTraversableSouth(int height, int x, int y) {
511 return isTraversableSouth(height, x, y, false);
512 }
513
524 private static boolean isTraversableSouth(int height, int x, int y, boolean impenetrable) {
525 if (impenetrable) {
526 return isInactive(height, x, y - 1, TraversalConstants.IMPENETRABLE_BLOCKED | TraversalConstants.IMPENETRABLE_WALL_NORTH);
527 }
528 return isInactive(height, x, y - 1, TraversalConstants.WALL_NORTH | TraversalConstants.BLOCKED);
529 }
530
541 private static boolean isTraversableEast(int height, int x, int y, int size) {
542 for (int offsetX = 0; offsetX < size; offsetX++) {
543 for (int offsetY = 0; offsetY < size; offsetY++) {
544 if (!isTraversableEast(height, x + offsetX, y + offsetY)) {
545 return false;
546 }
547 }
548 }
549 return true;
550 }
551
561 private static boolean isTraversableEast(int height, int x, int y) {
562 return isTraversableEast(height, x, y, false);
563 }
564
575 private static boolean isTraversableEast(int height, int x, int y, boolean impenetrable) {
576 if (impenetrable) {
577 return isInactive(height, x + 1, y, TraversalConstants.IMPENETRABLE_BLOCKED | TraversalConstants.IMPENETRABLE_WALL_WEST);
578 }
579 return isInactive(height, x + 1, y, TraversalConstants.WALL_WEST | TraversalConstants.BLOCKED);
580 }
581
592 private static boolean isTraversableWest(int height, int x, int y, int size) {
593 for (int width = 0; width < size; width++) {
594 for (int length = 0; length < size; length++) {
595 if (!isTraversableWest(height, x + width, y + length)) {
596 return false;
597 }
598 }
599 }
600 return true;
601 }
602
612 private static boolean isTraversableWest(int height, int x, int y) {
613 return isTraversableWest(height, x, y, false);
614 }
615
626 private static boolean isTraversableWest(int height, int x, int y, boolean impenetrable) {
627 if (impenetrable) {
628 return isInactive(height, x - 1, y, TraversalConstants.IMPENETRABLE_BLOCKED | TraversalConstants.IMPENETRABLE_WALL_EAST);
629 }
630 return isInactive(height, x - 1, y, TraversalConstants.WALL_EAST | TraversalConstants.BLOCKED);
631 }
632
643 private static boolean isTraversableNorthEast(int height, int x, int y, int size) {
644 for (int offsetX = 0; offsetX < size; offsetX++) {
645 for (int offsetY = 0; offsetY < size; offsetY++) {
646 if (!isTraversableNorthEast(height, x + offsetX, y + offsetY)) {
647 return false;
648 }
649 }
650 }
651 return true;
652 }
653
663 private static boolean isTraversableNorthEast(int height, int x, int y) {
664 return isTraversableNorthEast(height, x, y, false);
665 }
666
677 private static boolean isTraversableNorthEast(int height, int x, int y, boolean impenetrable) {
678 if (impenetrable) {
679 return isInactive(height, x + 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_WALL_SOUTH | TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST) && isInactive(height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_BLOCKED) && isInactive(height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH | TraversalConstants.IMPENETRABLE_BLOCKED);
680 }
681 return isInactive(height, x + 1, y + 1, TraversalConstants.WALL_WEST | TraversalConstants.WALL_SOUTH | TraversalConstants.WALL_SOUTH_WEST | TraversalConstants.BLOCKED) && isInactive(height, x + 1, y, TraversalConstants.WALL_WEST | TraversalConstants.BLOCKED) && isInactive(height, x, y + 1, TraversalConstants.WALL_SOUTH | TraversalConstants.BLOCKED);
682 }
683
694 private static boolean isTraversableNorthWest(int height, int x, int y, int size) {
695 for (int offsetX = 0; offsetX < size; offsetX++) {
696 for (int offsetY = 0; offsetY < size; offsetY++) {
697 if (!isTraversableNorthWest(height, x + offsetX, y + offsetY)) {
698 return false;
699 }
700 }
701 }
702 return true;
703 }
704
714 private static boolean isTraversableNorthWest(int height, int x, int y) {
715 return isTraversableNorthWest(height, x, y, false);
716 }
717
728 private static boolean isTraversableNorthWest(int height, int x, int y, boolean impenetrable) {
729 if (impenetrable) {
730 return isInactive(height, x - 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_SOUTH | TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST) && isInactive(height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_BLOCKED) && isInactive(height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH | TraversalConstants.IMPENETRABLE_BLOCKED);
731 }
732 return isInactive(height, x - 1, y + 1, TraversalConstants.WALL_EAST | TraversalConstants.WALL_SOUTH | TraversalConstants.WALL_SOUTH_EAST | TraversalConstants.BLOCKED) && isInactive(height, x - 1, y, TraversalConstants.WALL_EAST | TraversalConstants.BLOCKED) && isInactive(height, x, y + 1, TraversalConstants.WALL_SOUTH | TraversalConstants.BLOCKED);
733 }
734
745 private static boolean isTraversableSouthEast(int height, int x, int y, int size) {
746 for (int offsetX = 0; offsetX < size; offsetX++) {
747 for (int offsetY = 0; offsetY < size; offsetY++) {
748 if (!isTraversableSouthEast(height, x + offsetX, y + offsetY)) {
749 return false;
750 }
751 }
752 }
753 return true;
754 }
755
765 private static boolean isTraversableSouthEast(int height, int x, int y) {
766 return isTraversableSouthEast(height, x, y, false);
767 }
768
779 private static boolean isTraversableSouthEast(int height, int x, int y, boolean impenetrable) {
780 if (impenetrable) {
781 return isInactive(height, x + 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_WALL_NORTH | TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST) && isInactive(height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST | TraversalConstants.IMPENETRABLE_BLOCKED) && isInactive(height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH | TraversalConstants.IMPENETRABLE_BLOCKED);
782 }
783 return isInactive(height, x + 1, y - 1, TraversalConstants.WALL_WEST | TraversalConstants.WALL_NORTH | TraversalConstants.WALL_NORTH_WEST | TraversalConstants.BLOCKED) && isInactive(height, x + 1, y, TraversalConstants.WALL_WEST | TraversalConstants.BLOCKED) && isInactive(height, x, y - 1, TraversalConstants.WALL_NORTH | TraversalConstants.BLOCKED);
784 }
785
796 private static boolean isTraversableSouthWest(int height, int x, int y, int size) {
797 for (int offsetX = 0; offsetX < size; offsetX++) {
798 for (int offsetY = 0; offsetY < size; offsetY++) {
799 if (!isTraversableSouthWest(height, x + offsetX, y + offsetY)) {
800 return false;
801 }
802 }
803 }
804 return true;
805 }
806
816 private static boolean isTraversableSouthWest(int height, int x, int y) {
817 return isTraversableSouthWest(height, x, y, false);
818 }
819
830 private static boolean isTraversableSouthWest(int height, int x, int y, boolean impenetrable) {
831 if (impenetrable) {
832 return isInactive(height, x - 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_WALL_NORTH | TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST) && isInactive(height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST | TraversalConstants.IMPENETRABLE_BLOCKED) && isInactive(height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH | TraversalConstants.IMPENETRABLE_BLOCKED);
833 }
834 return isInactive(height, x - 1, y - 1, TraversalConstants.WALL_EAST | TraversalConstants.WALL_NORTH | TraversalConstants.WALL_NORTH_EAST | TraversalConstants.BLOCKED) && isInactive(height, x - 1, y, TraversalConstants.WALL_EAST | TraversalConstants.BLOCKED) && isInactive(height, x, y - 1, TraversalConstants.WALL_NORTH | TraversalConstants.BLOCKED);
835 }
836
845 public static void set(Region region, int height, int x, int y, int flag) {
846 region.setFlags(height, x & 0x3F, y & 0x3F, flag);
847 }
848
860 private static boolean isInactive(int height, int x, int y, int flag) {
861 int localX = x & 0x3F;
862 int localY = y & 0x3F;
863 Region region = World.getRegions().getRegion(x, y);
864 return (region.getFlags(height, localX, localY) & flag) == 0;
865 }
866
875 private static void unset(Region region, int height, int x, int y, int flag) {
876 region.unsetFlags(height, x & 0x3F, y & 0x3F, flag);
877 }
878
889 public static boolean isTraversable(Position from, Direction direction, int size) {
890 switch (direction) {
891 case NORTH:
892 return isTraversableNorth(from.getHeight(), from.getX(), from.getY(), size);
893 case SOUTH:
894 return isTraversableSouth(from.getHeight(), from.getX(), from.getY(), size);
895 case EAST:
896 return isTraversableEast(from.getHeight(), from.getX(), from.getY(), size);
897 case WEST:
898 return isTraversableWest(from.getHeight(), from.getX(), from.getY(), size);
899 case NORTH_EAST:
900 return isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), size);
901 case NORTH_WEST:
902 return isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), size);
903 case SOUTH_EAST:
904 return isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), size);
905 case SOUTH_WEST:
906 return isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), size);
907 case NONE:
908 return false;
909 default:
910 throw new IllegalArgumentException("direction: " + direction + " is not valid");
911 }
912 }
913
924 public static boolean isTraversable(Position from, Direction direction, boolean impenetrable) {
925 switch (direction) {
926 case NORTH:
927 return isTraversableNorth(from.getHeight(), from.getX(), from.getY(), impenetrable);
928 case SOUTH:
929 return isTraversableSouth(from.getHeight(), from.getX(), from.getY(), impenetrable);
930 case EAST:
931 return isTraversableEast(from.getHeight(), from.getX(), from.getY(), impenetrable);
932 case WEST:
933 return isTraversableWest(from.getHeight(), from.getX(), from.getY(), impenetrable);
934 case NORTH_EAST:
935 return isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), impenetrable);
936 case NORTH_WEST:
937 return isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), impenetrable);
938 case SOUTH_EAST:
939 return isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), impenetrable);
940 case SOUTH_WEST:
941 return isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), impenetrable);
942 case NONE:
943 return true;
944 default:
945 throw new IllegalArgumentException("direction: " + direction + " is not valid");
946 }
947 }
948
958 public static List<Position> getTraversableTiles(Position southWest, int width, int length) {
959 List<Position> positions = new LinkedList<>();
960 for (int y = 0; y < length; y++) {
961 for (int x = 0; x < width; x++) {
962 Position from = southWest.transform(x, y);
963
964 if (isTraversableNorth(from.getHeight(), from.getX(), from.getY()))
965 positions.add(from.north());
966
967 if (isTraversableSouth(from.getHeight(), from.getX(), from.getY()))
968 positions.add(from.south());
969
970 if (isTraversableEast(from.getHeight(), from.getX(), from.getY()))
971 positions.add(from.east());
972
973 if (isTraversableWest(from.getHeight(), from.getX(), from.getY()))
974 positions.add(from.west());
975
976 if (isTraversableNorthEast(from.getHeight(), from.getX(), from.getY()))
977 positions.add(from.northEast());
978
979 if (isTraversableNorthWest(from.getHeight(), from.getX(), from.getY()))
980 positions.add(from.northWest());
981
982 if (isTraversableSouthEast(from.getHeight(), from.getX(), from.getY()))
983 positions.add(from.southEast());
984
985 if (isTraversableSouthWest(from.getHeight(), from.getX(), from.getY()))
986 positions.add(from.southWest());
987 }
988 }
989 return positions;
990 }
991
992 public static Position getRandomTraversableTile(Position southWest, int width, int length) {
993 List<Position> positions = new LinkedList<>();
994 for (int y = 0; y < length; y++) {
995 for (int x = 0; x < width; x++) {
996 Position from = southWest.transform(x, y);
997
998 if (isTraversableNorth(from.getHeight(), from.getX(), from.getY()))
999 positions.add(from.north());
1000
1001 if (isTraversableSouth(from.getHeight(), from.getX(), from.getY()))
1002 positions.add(from.south());
1003
1004 if (isTraversableEast(from.getHeight(), from.getX(), from.getY()))
1005 positions.add(from.east());
1006
1007 if (isTraversableWest(from.getHeight(), from.getX(), from.getY()))
1008 positions.add(from.west());
1009
1010 if (isTraversableNorthEast(from.getHeight(), from.getX(), from.getY()))
1011 positions.add(from.northEast());
1012
1013 if (isTraversableNorthWest(from.getHeight(), from.getX(), from.getY()))
1014 positions.add(from.northWest());
1015
1016 if (isTraversableSouthEast(from.getHeight(), from.getX(), from.getY()))
1017 positions.add(from.southEast());
1018
1019 if (isTraversableSouthWest(from.getHeight(), from.getX(), from.getY()))
1020 positions.add(from.southWest());
1021 }
1022 }
1023 if (positions.isEmpty())
1024 return null;
1025 return RandomUtils.random(positions);
1026 }
1027
1028 public static Position getRandomNonDiagonal(Position from) {
1029 List<Position> positions = new LinkedList<>();
1030
1031 if (isTraversableNorth(from.getHeight(), from.getX(), from.getY()))
1032 positions.add(from.north());
1033
1034 if (isTraversableSouth(from.getHeight(), from.getX(), from.getY()))
1035 positions.add(from.south());
1036
1037 if (isTraversableEast(from.getHeight(), from.getX(), from.getY()))
1038 positions.add(from.east());
1039
1040 if (isTraversableWest(from.getHeight(), from.getX(), from.getY()))
1041 positions.add(from.west());
1042
1043 if (positions.isEmpty())
1044 return null;
1045
1046 return RandomUtils.random(positions);
1047 }
1048
1049 public static int getFlags(int x, int y, int height) {
1050 int localX = x & 0x3F;
1051 int localY = y & 0x3F;
1052 Region region = World.getRegions().getRegion(x, y);
1053 return region.getFlags(height, localX, localY);
1054 }
1055
1056 public static int getFlags(Position position) {
1057 return getFlags(position.getX(), position.getY(), position.getHeight());
1058 }
1059
1060 public static boolean blockedNorth(Position position) {
1061 return !isTraversableNorth(position.getHeight(), position.getX(), position.getY(), false);
1062 }
1063
1064 public static boolean blockedEast(Position position) {
1065 return !isTraversableEast(position.getHeight(), position.getX(), position.getY(), false);
1066 }
1067
1068 public static boolean blockedSouth(Position position) {
1069 return !isTraversableSouth(position.getHeight(), position.getX(), position.getY(), false);
1070 }
1071
1072 public static boolean blockedWest(Position position) {
1073 return !isTraversableWest(position.getHeight(), position.getX(), position.getY(), false);
1074 }
1075
1076}
static void markObject(Region region, GameObject object, boolean add, boolean list)
static void block(Region region, int height, int localX, int localY)
static boolean isTraversable(Position from, Direction direction, int size)
static void markOccupant(Region region, int height, int x, int y, int width, int length, boolean impenetrable, boolean add)
static boolean isTraversable(Position from, Direction direction, boolean impenetrable)
static List< Position > getTraversableTiles(Position southWest, int width, int length)
static void markBridge(Region region, int height, int x, int y)
Position transform(int diffX, int diffY, int diffZ)
int getFlags(int height, int x, int y)
Definition Region.java:103
void unsetFlags(int height, int x, int y, int flags)
Definition Region.java:129