RuneHive-Game
Loading...
Searching...
No Matches
TraversalMap.java
Go to the documentation of this file.
1package com.runehive.game.world.pathfinding;
2
3import com.runehive.game.world.World;
4import com.runehive.game.world.entity.mob.Direction;
5import com.runehive.game.world.object.GameObject;
6import com.runehive.game.world.object.GameObjectDefinition;
7import com.runehive.game.world.object.ObjectDirection;
8import com.runehive.game.world.object.ObjectType;
9import com.runehive.game.world.position.Position;
10import com.runehive.game.world.region.Region;
11import com.runehive.util.RandomUtils;
12
13import java.util.LinkedList;
14import java.util.List;
15
16import static com.runehive.game.world.object.ObjectType.*;
17
18/**
19 * Contains traversal data for a set of regions.
20 *
21 * @author Artem Batutin <artembatutin@gmail.com>
22 * @author Ryley Kimmel <ryley.kimmel@live.com>
23 */
24public final class TraversalMap {
25
26 private TraversalMap() {}
27
28 /**
29 * Marks a {@link GameObject} with the specified attributes on the specified
30 * {@link Position} to the {@code TraversalMap}.
31 *
32 * @param object The game object.
33 * @param add The condition if the object is added.
34 * @param list the condition if the region object list will be affected.
35 */
36 public static void markObject(Region region, GameObject object, boolean add, boolean list) {
37 if (object.getId() > GameObjectDefinition.MAX_DEFINITIONS) {
38 return;
39 }
40
41 GameObjectDefinition def = object.getDefinition();
42
43 if (def.isSolid()) {
44 Position position = object.getPosition();
45
46 //Sets the sizes.
47 final int sizeX;
48 final int sizeY;
49
50 if (object.getDirection() == ObjectDirection.NORTH || object.getDirection() == ObjectDirection.SOUTH) {
51 sizeX = def.getLength();
52 sizeY = def.getWidth();
53 } else {
54 sizeX = def.getWidth();
55 sizeY = def.getLength();
56 }
57
58 if (object.getObjectType() == GROUND_PROP) {
59 if (def.hasActions() || def.isDecoration()) {
60 if (def.hasActions()) {
61 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, false, add);
62 }
63 }
64 } else if (object.getObjectType() == GENERAL_PROP || object.getObjectType() == WALKABLE_PROP) {
65 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, def.isImpenetrable(), add);
66 } else if (object.getObjectType().getId() >= 12) {
67 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, def.isImpenetrable(), add);
68 } else if (object.getObjectType() == DIAGONAL_WALL) {
69 markOccupant(region, position.getHeight(), position.getX(), position.getY(), sizeX, sizeY, def.isImpenetrable(), add);
70 } else if (object.getObjectType().getId() >= 0 && object.getObjectType().getId() <= 3) {
71 if (add)
72 markWall(region, object.getDirection(), position.getHeight(), position.getX(), position.getY(), object.getObjectType(), def.isImpenetrable());
73 else
74 unmarkWall(region, object.getDirection(), position.getHeight(), position.getX(), position.getY(), object.getObjectType(), def.isImpenetrable());
75 }
76 }
77
78 if (list && (object.getId() == 11700 || object.getDefinition().hasActions())) {
79 if (add) region.addObject(object);
80 else region.removeObject(object);
81 }
82 }
83
84 /**
85 * Informs the region of an existing wall.
86 *
87 * @param orientation The orientation of the wall.
88 * @param height The walls height.
89 * @param x The walls x coordinate.
90 * @param y The walls y coordinate.
91 * @param type The type of wall.
92 * @param impenetrable Whether or not this wall can be passed through.
93 */
94 private static void markWall(Region reg, ObjectDirection orientation, int height, int x, int y, ObjectType type, boolean impenetrable) {
95 switch (type) {
96 case STRAIGHT_WALL:
97 if (orientation == ObjectDirection.WEST) {
98 set(reg, height, x, y, TraversalConstants.WALL_WEST);
99 set(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
100 if (impenetrable) {
101 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
102 set(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
103 }
104 }
105 if (orientation == ObjectDirection.NORTH) {
106 set(reg, height, x, y, TraversalConstants.WALL_NORTH);
107 set(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
108 if (impenetrable) {
109 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH);
110 set(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
111 }
112 }
113 if (orientation == ObjectDirection.EAST) {
114 set(reg, height, x, y, TraversalConstants.WALL_EAST);
115 set(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
116 if (impenetrable) {
117 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
118 set(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
119 }
120 }
121 if (orientation == ObjectDirection.SOUTH) {
122 set(reg, height, x, y, TraversalConstants.WALL_SOUTH);
123 set(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
124 if (impenetrable) {
125 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
126 set(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
127 }
128 }
129 break;
130
131 case ENTIRE_WALL:
132 if (orientation == ObjectDirection.WEST) {
134 set(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
135 set(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
136 if (impenetrable) {
138 set(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
139 set(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
140 }
141 }
142 if (orientation == ObjectDirection.NORTH) {
144 set(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
145 set(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
146 if (impenetrable) {
148 set(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
149 set(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
150 }
151 }
152 if (orientation == ObjectDirection.EAST) {
154 set(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
155 set(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
156 if (impenetrable) {
158 set(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
159 set(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
160 }
161 }
162 if (orientation == ObjectDirection.SOUTH) {
164 set(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
165 set(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
166 if (impenetrable) {
168 set(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
169 set(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
170 }
171 }
172 break;
173
174 case DIAGONAL_CORNER_WALL:
175 case WALL_CORNER:
176 if (orientation == ObjectDirection.WEST) {
177 set(reg, height, x, y, TraversalConstants.WALL_NORTH_WEST);
178 set(reg, height, x - 1, y + 1, TraversalConstants.WALL_SOUTH_EAST);
179 if (impenetrable) {
180 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
181 set(reg, height, x - 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
182 }
183 }
184 if (orientation == ObjectDirection.NORTH) {
185 set(reg, height, x, y, TraversalConstants.WALL_NORTH_EAST);
186 set(reg, height, x + 1, y + 1, TraversalConstants.WALL_SOUTH_WEST);
187 if (impenetrable) {
188 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
189 set(reg, height, x + 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
190 }
191 }
192 if (orientation == ObjectDirection.EAST) {
193 set(reg, height, x, y, TraversalConstants.WALL_SOUTH_EAST);
194 set(reg, height, x + 1, y - 1, TraversalConstants.WALL_NORTH_WEST);
195 if (impenetrable) {
196 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
197 set(reg, height, x + 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
198 }
199 }
200 if (orientation == ObjectDirection.SOUTH) {
201 set(reg, height, x, y, TraversalConstants.WALL_SOUTH_WEST);
202 set(reg, height, x - 1, y - 1, TraversalConstants.WALL_NORTH_EAST);
203 if (impenetrable) {
204 set(reg, height, x, y, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
205 set(reg, height, x - 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
206 }
207 }
208 break;
209 default:
210 break;
211 }
212 }
213
214 /**
215 * Informs the region of an existing wall being removed.
216 *
217 * @param orientation The orientation of the wall.
218 * @param height The walls height.
219 * @param x The walls x coordinate.
220 * @param y The walls y coordinate.
221 * @param type The type of wall.
222 * @param impenetrable Whether or not this wall can be passed through.
223 */
224 private static void unmarkWall(Region reg, ObjectDirection orientation, int height, int x, int y, ObjectType type, boolean impenetrable) {
225 switch (type) {
226 case STRAIGHT_WALL:
227 if (orientation == ObjectDirection.WEST) {
228 unset(reg, height, x, y, TraversalConstants.WALL_WEST);
229 unset(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
230 if (impenetrable) {
232 unset(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
233 }
234 }
235 if (orientation == ObjectDirection.NORTH) {
236 unset(reg, height, x, y, TraversalConstants.WALL_NORTH);
237 unset(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
238 if (impenetrable) {
240 unset(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
241 }
242 }
243 if (orientation == ObjectDirection.EAST) {
244 unset(reg, height, x, y, TraversalConstants.WALL_EAST);
245 unset(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
246 if (impenetrable) {
248 unset(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
249 }
250 }
251 if (orientation == ObjectDirection.SOUTH) {
252 unset(reg, height, x, y, TraversalConstants.WALL_SOUTH);
253 unset(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
254 if (impenetrable) {
256 unset(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
257 }
258 }
259 break;
260
261 case ENTIRE_WALL:
262 if (orientation == ObjectDirection.WEST) {
264 unset(reg, height, x - 1, y, TraversalConstants.WALL_EAST);
265 unset(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
266 if (impenetrable) {
268 unset(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_EAST);
269 unset(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
270 }
271 }
272 if (orientation == ObjectDirection.NORTH) {
274 unset(reg, height, x, y + 1, TraversalConstants.WALL_SOUTH);
275 unset(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
276 if (impenetrable) {
278 unset(reg, height, x, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH);
279 unset(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
280 }
281 }
282 if (orientation == ObjectDirection.EAST) {
284 unset(reg, height, x + 1, y, TraversalConstants.WALL_WEST);
285 unset(reg, height, x, y - 1, TraversalConstants.WALL_NORTH);
286 if (impenetrable) {
288 unset(reg, height, x + 1, y, TraversalConstants.IMPENETRABLE_WALL_WEST);
289 unset(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH);
290 }
291 }
292 if (orientation == ObjectDirection.SOUTH) {
294 unset(reg, height, x, y - 1, TraversalConstants.WALL_WEST);
295 unset(reg, height, x - 1, y, TraversalConstants.WALL_NORTH);
296 if (impenetrable) {
298 unset(reg, height, x, y - 1, TraversalConstants.IMPENETRABLE_WALL_WEST);
299 unset(reg, height, x - 1, y, TraversalConstants.IMPENETRABLE_WALL_NORTH);
300 }
301 }
302 break;
303
304 case DIAGONAL_CORNER_WALL:
305 case WALL_CORNER:
306 if (orientation == ObjectDirection.WEST) {
307 unset(reg, height, x, y, TraversalConstants.WALL_NORTH_WEST);
308 unset(reg, height, x - 1, y + 1, TraversalConstants.WALL_SOUTH_EAST);
309 if (impenetrable) {
311 unset(reg, height, x - 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_EAST);
312 }
313 }
314 if (orientation == ObjectDirection.NORTH) {
315 unset(reg, height, x, y, TraversalConstants.WALL_NORTH_EAST);
316 unset(reg, height, x + 1, y + 1, TraversalConstants.WALL_SOUTH_WEST);
317 if (impenetrable) {
319 unset(reg, height, x + 1, y + 1, TraversalConstants.IMPENETRABLE_WALL_SOUTH_WEST);
320 }
321 }
322 if (orientation == ObjectDirection.EAST) {
323 unset(reg, height, x, y, TraversalConstants.WALL_SOUTH_EAST);
324 unset(reg, height, x + 1, y - 1, TraversalConstants.WALL_NORTH_WEST);
325 if (impenetrable) {
327 unset(reg, height, x + 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_WEST);
328 }
329 }
330 if (orientation == ObjectDirection.SOUTH) {
331 unset(reg, height, x, y, TraversalConstants.WALL_SOUTH_WEST);
332 unset(reg, height, x - 1, y - 1, TraversalConstants.WALL_NORTH_EAST);
333 if (impenetrable) {
335 unset(reg, height, x - 1, y - 1, TraversalConstants.IMPENETRABLE_WALL_NORTH_EAST);
336 }
337 }
338 break;
339 default:
340 break;
341 }
342 }
343
344 /**
345 * Marks the specified set of coordinates blocked, unable to be passed
346 * through.
347 *
348 * @param height The height.
349 * @param localX The x coordinate.
350 * @param localY The y coordinate.
351 */
352 public static void block(Region region, int height, int localX, int localY) {
353 region.setFlags(height, localX, localY, TraversalConstants.BLOCKED);
354 }
355
356 /**
357 * Marks the specified coordinates occupied by some object.
358 *
359 * @param height The height.
360 * @param x The x coordinate.
361 * @param y The y coordinate.
362 * @param width The width of the occupation.
363 * @param length The length of the occupation.
364 * @param impenetrable Whether or not this occupation can be passed
365 * through.
366 * @param add Flag if the occupant is added or removed.
367 */
368 public static void markOccupant(Region region, int height, int x, int y, int width, int length, boolean impenetrable, boolean add) {
369 int flag = TraversalConstants.BLOCKED;
370 if (impenetrable) {
372 }
373 for (int xPos = x; xPos < x + width; xPos++) {
374 for (int yPos = y; yPos < y + length; yPos++) {
375 if (add) set(region, height, xPos, yPos, flag);
376 else unset(region, height, xPos, yPos, flag);
377 }
378 }
379 }
380
381 /**
382 * Marks the specified coordinates a bridge.
383 *
384 * @param height The height.
385 * @param x The x coordinate.
386 * @param y The y coordinate.
387 */
388 public static void markBridge(Region region, int height, int x, int y) {
389 set(region, height, x, y, TraversalConstants.BRIDGE);
390 }
391
392 /**
393 * Tests if the specified position can be traversed north.
394 *
395 * @param height The height.
396 * @param x The x coordinate.
397 * @param y The y coordinate.
398 * @param size The size of the entity attempting to traverse north.
399 * @return <code>true</code> if it is possible to traverse north otherwise
400 * <code>false</code>
401 */
402 private static boolean isTraversableNorth(int height, int x, int y, int size) {
403 for (int offsetX = 0; offsetX < size; offsetX++) {
404 for (int offsetY = 0; offsetY < size; offsetY++) {
405 if (!isTraversableNorth(height, x + offsetX, y + offsetY)) {
406 return false;
407 }
408 }
409 }
410 return true;
411 }
412
413 /**
414 * Tests if the specified position can be traversed north.
415 *
416 * @param height The height.
417 * @param x The x coordinate.
418 * @param y The y coordinate.
419 * @return <code>true</code> if it is possible to traverse north otherwise
420 * <code>false</code>.
421 */
422 private static boolean isTraversableNorth(int height, int x, int y) {
423 return isTraversableNorth(height, x, y, false);
424 }
425
426 /**
427 * Tests if the specified position can be traversed north.
428 *
429 * @param height The height.
430 * @param x The x coordinate.
431 * @param y The y coordinate.
432 * @param impenetrable Whether or not this occupation can be traversed.
433 * @return <code>true</code> if it is possible to traverse north otherwise
434 * <code>false</code>.
435 */
436 private static boolean isTraversableNorth(int height, int x, int y, boolean impenetrable) {
437 if (impenetrable) {
439 }
441 }
442
443 /**
444 * Tests if the specified position can be traversed south.
445 *
446 * @param height The height.
447 * @param x The x coordinate.
448 * @param y The y coordinate.
449 * @param size The size of the entity attempting to traverse south.
450 * @return <code>true</code> if it is possible to traverse south otherwise
451 * <code>false</code>
452 */
453 private static boolean isTraversableSouth(int height, int x, int y, int size) {
454 for (int offsetX = 0; offsetX < size; offsetX++) {
455 for (int offsetY = 0; offsetY < size; offsetY++) {
456 if (!isTraversableSouth(height, x + offsetX, y + offsetY)) {
457 return false;
458 }
459 }
460 }
461 return true;
462 }
463
464 /**
465 * Tests if the specified position can be traversed south.
466 *
467 * @param height The height.
468 * @param x The x coordinate.
469 * @param y The y coordinate.
470 * @return <code>true</code> if it is possible to traverse south otherwise
471 * <code>false</code>.
472 */
473 private static boolean isTraversableSouth(int height, int x, int y) {
474 return isTraversableSouth(height, x, y, false);
475 }
476
477 /**
478 * Tests if the specified position can be traversed south.
479 *
480 * @param height The height.
481 * @param x The x coordinate.
482 * @param y The y coordinate.
483 * @param impenetrable Whether or not this occupation can be traversed.
484 * @return <code>true</code> if it is possible to traverse south otherwise
485 * <code>false</code>.
486 */
487 private static boolean isTraversableSouth(int height, int x, int y, boolean impenetrable) {
488 if (impenetrable) {
490 }
492 }
493
494 /**
495 * Tests if the specified position can be traversed east.
496 *
497 * @param height The height.
498 * @param x The x coordinate.
499 * @param y The y coordinate.
500 * @param size The size of the entity attempting to traverse east.
501 * @return <code>true</code> if it is possible to traverse east otherwise
502 * <code>false</code>
503 */
504 private static boolean isTraversableEast(int height, int x, int y, int size) {
505 for (int offsetX = 0; offsetX < size; offsetX++) {
506 for (int offsetY = 0; offsetY < size; offsetY++) {
507 if (!isTraversableEast(height, x + offsetX, y + offsetY)) {
508 return false;
509 }
510 }
511 }
512 return true;
513 }
514
515 /**
516 * Tests if the specified position can be traversed east.
517 *
518 * @param height The height.
519 * @param x The x coordinate.
520 * @param y The y coordinate.
521 * @return <code>true</code> if it is possible to traverse east otherwise
522 * <code>false</code>.
523 */
524 private static boolean isTraversableEast(int height, int x, int y) {
525 return isTraversableEast(height, x, y, false);
526 }
527
528 /**
529 * Tests if the specified position can be traversed east.
530 *
531 * @param height The height.
532 * @param x The x coordinate.
533 * @param y The y coordinate.
534 * @param impenetrable Whether or not this occupation can be traversed.
535 * @return <code>true</code> if it is possible to traverse east otherwise
536 * <code>false</code>.
537 */
538 private static boolean isTraversableEast(int height, int x, int y, boolean impenetrable) {
539 if (impenetrable) {
541 }
543 }
544
545 /**
546 * Tests if the specified position can be traversed west.
547 *
548 * @param height The height.
549 * @param x The x coordinate.
550 * @param y The y coordinate.
551 * @param size The size of the entity attempting to traverse west.
552 * @return <code>true</code> if it is possible to traverse west otherwise
553 * <code>false</code>
554 */
555 private static boolean isTraversableWest(int height, int x, int y, int size) {
556 for (int width = 0; width < size; width++) {
557 for (int length = 0; length < size; length++) {
558 if (!isTraversableWest(height, x + width, y + length)) {
559 return false;
560 }
561 }
562 }
563 return true;
564 }
565
566 /**
567 * Tests if the specified position can be traversed west.
568 *
569 * @param height The height.
570 * @param x The x coordinate.
571 * @param y The y coordinate.
572 * @return <code>true</code> if it is possible to traverse west otherwise
573 * <code>false</code>.
574 */
575 private static boolean isTraversableWest(int height, int x, int y) {
576 return isTraversableWest(height, x, y, false);
577 }
578
579 /**
580 * Tests if the specified position can be traversed west.
581 *
582 * @param height The height.
583 * @param x The x coordinate.
584 * @param y The y coordinate.
585 * @param impenetrable Whether or not this occupation can be traversed.
586 * @return <code>true</code> if it is possible to traverse west otherwise
587 * <code>false</code>.
588 */
589 private static boolean isTraversableWest(int height, int x, int y, boolean impenetrable) {
590 if (impenetrable) {
592 }
594 }
595
596 /**
597 * Tests if the specified position can be traversed north east.
598 *
599 * @param height The height.
600 * @param x The x coordinate.
601 * @param y The y coordinate.
602 * @param size The size of the entity attempting to traverse north east.
603 * @return <code>true</code> if it is possible to traverse north east
604 * otherwise <code>false</code>
605 */
606 private static boolean isTraversableNorthEast(int height, int x, int y, int size) {
607 for (int offsetX = 0; offsetX < size; offsetX++) {
608 for (int offsetY = 0; offsetY < size; offsetY++) {
609 if (!isTraversableNorthEast(height, x + offsetX, y + offsetY)) {
610 return false;
611 }
612 }
613 }
614 return true;
615 }
616
617 /**
618 * Tests if the specified position can be traversed north east.
619 *
620 * @param height The height.
621 * @param x The x coordinate.
622 * @param y The y coordinate.
623 * @return <code>true</code> if it is possible to traverse north east
624 * otherwise <code>false</code>.
625 */
626 private static boolean isTraversableNorthEast(int height, int x, int y) {
627 return isTraversableNorthEast(height, x, y, false);
628 }
629
630 /**
631 * Tests if the specified position can be traversed north east.
632 *
633 * @param height The height.
634 * @param x The x coordinate.
635 * @param y The y coordinate.
636 * @param impenetrable Whether or not this occupation can be traversed.
637 * @return <code>true</code> if it is possible to traverse north east
638 * otherwise <code>false</code>.
639 */
646
647 /**
648 * Tests if the specified position can be traversed north west.
649 *
650 * @param height The height.
651 * @param x The x coordinate.
652 * @param y The y coordinate.
653 * @param size The size of the entity attempting to traverse north west.
654 * @return <code>true</code> if it is possible to traverse north west
655 * otherwise <code>false</code>
656 */
657 private static boolean isTraversableNorthWest(int height, int x, int y, int size) {
658 for (int offsetX = 0; offsetX < size; offsetX++) {
659 for (int offsetY = 0; offsetY < size; offsetY++) {
660 if (!isTraversableNorthWest(height, x + offsetX, y + offsetY)) {
661 return false;
662 }
663 }
664 }
665 return true;
666 }
667
668 /**
669 * Tests if the specified position can be traversed north west.
670 *
671 * @param height The height.
672 * @param x The x coordinate.
673 * @param y The y coordinate.
674 * @return <code>true</code> if it is possible to traverse north west
675 * otherwise <code>false</code>.
676 */
677 private static boolean isTraversableNorthWest(int height, int x, int y) {
678 return isTraversableNorthWest(height, x, y, false);
679 }
680
681 /**
682 * Tests if the specified position can be traversed north west.
683 *
684 * @param height The height.
685 * @param x The x coordinate.
686 * @param y The y coordinate.
687 * @param impenetrable Whether or not this occupation can be traversed.
688 * @return <code>true</code> if it is possible to traverse north west
689 * otherwise <code>false</code>.
690 */
697
698 /**
699 * Tests if the specified position can be traversed south east.
700 *
701 * @param height The height.
702 * @param x The x coordinate.
703 * @param y The y coordinate.
704 * @param size The size of the entity attempting to traverse south east.
705 * @return <code>true</code> if it is possible to traverse south east
706 * otherwise <code>false</code>
707 */
708 private static boolean isTraversableSouthEast(int height, int x, int y, int size) {
709 for (int offsetX = 0; offsetX < size; offsetX++) {
710 for (int offsetY = 0; offsetY < size; offsetY++) {
711 if (!isTraversableSouthEast(height, x + offsetX, y + offsetY)) {
712 return false;
713 }
714 }
715 }
716 return true;
717 }
718
719 /**
720 * Tests if the specified position can be traversed south east.
721 *
722 * @param height The height.
723 * @param x The x coordinate.
724 * @param y The y coordinate.
725 * @return <code>true</code> if it is possible to traverse south east
726 * otherwise <code>false</code>.
727 */
728 private static boolean isTraversableSouthEast(int height, int x, int y) {
729 return isTraversableSouthEast(height, x, y, false);
730 }
731
732 /**
733 * Tests if the specified position can be traversed south east.
734 *
735 * @param height The height.
736 * @param x The x coordinate.
737 * @param y The y coordinate.
738 * @param impenetrable Whether or not this occupation can be traversed.
739 * @return <code>true</code> if it is possible to traverse south east
740 * otherwise <code>false</code>.
741 */
748
749 /**
750 * Tests if the specified position can be traversed south west.
751 *
752 * @param height The height.
753 * @param x The x coordinate.
754 * @param y The y coordinate.
755 * @param size The size of the entity attempting to traverse south west.
756 * @return <code>true</code> if it is possible to traverse south west
757 * otherwise <code>false</code>
758 */
759 private static boolean isTraversableSouthWest(int height, int x, int y, int size) {
760 for (int offsetX = 0; offsetX < size; offsetX++) {
761 for (int offsetY = 0; offsetY < size; offsetY++) {
762 if (!isTraversableSouthWest(height, x + offsetX, y + offsetY)) {
763 return false;
764 }
765 }
766 }
767 return true;
768 }
769
770 /**
771 * Tests if the specified position can be traversed south west.
772 *
773 * @param height The height.
774 * @param x The x coordinate.
775 * @param y The y coordinate.
776 * @return <code>true</code> if it is possible to traverse south west
777 * otherwise <code>false</code>.
778 */
779 private static boolean isTraversableSouthWest(int height, int x, int y) {
780 return isTraversableSouthWest(height, x, y, false);
781 }
782
783 /**
784 * Tests if the specified position can be traversed south west.
785 *
786 * @param height The height.
787 * @param x The x coordinate.
788 * @param y The y coordinate.
789 * @param impenetrable Whether or not this occupation can be traversed.
790 * @return <code>true</code> if it is possible to traverse south west
791 * otherwise <code>false</code>.
792 */
799
800 /**
801 * Sets a flag on the specified position.
802 *
803 * @param height The height.
804 * @param x The x coordinate.
805 * @param y The y coordinate.
806 * @param flag The flag to put on this tile.
807 */
808 public static void set(Region region, int height, int x, int y, int flag) {
809 region.setFlags(height, x & 0x3F, y & 0x3F, flag);
810 }
811
812 /**
813 * Checks whether or not the specified flag is not active on the specified
814 * position.
815 *
816 * @param height The height.
817 * @param x The x coordinate.
818 * @param y The y coordinate.
819 * @param flag The flag to check.
820 * @return <code>true</code> if the specified flag is not active on the
821 * specified position, otherwise <code>false</code>.
822 */
823 private static boolean isInactive(int height, int x, int y, int flag) {
824 int localX = x & 0x3F;
825 int localY = y & 0x3F;
827 return (region.getFlags(height, localX, localY) & flag) == 0;
828 }
829
830 /**
831 * Unsets the specified flag from the specified position.
832 *
833 * @param height The height.
834 * @param x The x coordinate.
835 * @param y The y coordinate.
836 * @param flag The flag to unset from the specified position.
837 */
838 private static void unset(Region region, int height, int x, int y, int flag) {
839 region.unsetFlags(height, x & 0x3F, y & 0x3F, flag);
840 }
841
842 /**
843 * Tests whether or not a specified position is traversable in the specified
844 * direction.
845 *
846 * @param from The position.
847 * @param direction The direction to traverse.
848 * @param size The size of the entity attempting to traverse.
849 * @return <code>true</code> if the direction is traversable otherwise
850 * <code>false</code>.
851 */
852 public static boolean isTraversable(Position from, Direction direction, int size) {
853 switch (direction) {
854 case NORTH:
855 return isTraversableNorth(from.getHeight(), from.getX(), from.getY(), size);
856 case SOUTH:
857 return isTraversableSouth(from.getHeight(), from.getX(), from.getY(), size);
858 case EAST:
859 return isTraversableEast(from.getHeight(), from.getX(), from.getY(), size);
860 case WEST:
861 return isTraversableWest(from.getHeight(), from.getX(), from.getY(), size);
862 case NORTH_EAST:
863 return isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), size);
864 case NORTH_WEST:
865 return isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), size);
866 case SOUTH_EAST:
867 return isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), size);
868 case SOUTH_WEST:
869 return isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), size);
870 case NONE:
871 return false;
872 default:
873 throw new IllegalArgumentException("direction: " + direction + " is not valid");
874 }
875 }
876
877 /**
878 * Tests whether or not a specified position is traversable in the specified
879 * direction.
880 *
881 * @param from The position.
882 * @param direction The direction to traverse.
883 * @param impenetrable The condition if impenetrability must be checked.
884 * @return <code>true</code> if the direction is traversable otherwise
885 * <code>false</code>.
886 */
887 public static boolean isTraversable(Position from, Direction direction, boolean impenetrable) {
888 switch (direction) {
889 case NORTH:
890 return isTraversableNorth(from.getHeight(), from.getX(), from.getY(), impenetrable);
891 case SOUTH:
892 return isTraversableSouth(from.getHeight(), from.getX(), from.getY(), impenetrable);
893 case EAST:
894 return isTraversableEast(from.getHeight(), from.getX(), from.getY(), impenetrable);
895 case WEST:
896 return isTraversableWest(from.getHeight(), from.getX(), from.getY(), impenetrable);
897 case NORTH_EAST:
898 return isTraversableNorthEast(from.getHeight(), from.getX(), from.getY(), impenetrable);
899 case NORTH_WEST:
900 return isTraversableNorthWest(from.getHeight(), from.getX(), from.getY(), impenetrable);
901 case SOUTH_EAST:
902 return isTraversableSouthEast(from.getHeight(), from.getX(), from.getY(), impenetrable);
903 case SOUTH_WEST:
904 return isTraversableSouthWest(from.getHeight(), from.getX(), from.getY(), impenetrable);
905 case NONE:
906 return true;
907 default:
908 throw new IllegalArgumentException("direction: " + direction + " is not valid");
909 }
910 }
911
912 /**
913 * Returns a {@link List} of positions that are traversable from the
914 * specified position.
915 *
916 * @param southWest The position moving from.
917 * @param width The size of the mob attempting to traverse.
918 * @param length
919 * @return A {@link List} of positions.
920 */
921 public static List<Position> getTraversableTiles(Position southWest, int width, int length) {
922 List<Position> positions = new LinkedList<>();
923 for (int y = 0; y < length; y++) {
924 for (int x = 0; x < width; x++) {
925 Position from = southWest.transform(x, y);
926
927 if (isTraversableNorth(from.getHeight(), from.getX(), from.getY()))
928 positions.add(from.north());
929
930 if (isTraversableSouth(from.getHeight(), from.getX(), from.getY()))
931 positions.add(from.south());
932
933 if (isTraversableEast(from.getHeight(), from.getX(), from.getY()))
934 positions.add(from.east());
935
936 if (isTraversableWest(from.getHeight(), from.getX(), from.getY()))
937 positions.add(from.west());
938
939 if (isTraversableNorthEast(from.getHeight(), from.getX(), from.getY()))
940 positions.add(from.northEast());
941
942 if (isTraversableNorthWest(from.getHeight(), from.getX(), from.getY()))
943 positions.add(from.northWest());
944
945 if (isTraversableSouthEast(from.getHeight(), from.getX(), from.getY()))
946 positions.add(from.southEast());
947
948 if (isTraversableSouthWest(from.getHeight(), from.getX(), from.getY()))
949 positions.add(from.southWest());
950 }
951 }
952 return positions;
953 }
954
955 public static Position getRandomTraversableTile(Position southWest, int width, int length) {
956 List<Position> positions = new LinkedList<>();
957 for (int y = 0; y < length; y++) {
958 for (int x = 0; x < width; x++) {
959 Position from = southWest.transform(x, y);
960
961 if (isTraversableNorth(from.getHeight(), from.getX(), from.getY()))
962 positions.add(from.north());
963
964 if (isTraversableSouth(from.getHeight(), from.getX(), from.getY()))
965 positions.add(from.south());
966
967 if (isTraversableEast(from.getHeight(), from.getX(), from.getY()))
968 positions.add(from.east());
969
970 if (isTraversableWest(from.getHeight(), from.getX(), from.getY()))
971 positions.add(from.west());
972
973 if (isTraversableNorthEast(from.getHeight(), from.getX(), from.getY()))
974 positions.add(from.northEast());
975
976 if (isTraversableNorthWest(from.getHeight(), from.getX(), from.getY()))
977 positions.add(from.northWest());
978
979 if (isTraversableSouthEast(from.getHeight(), from.getX(), from.getY()))
980 positions.add(from.southEast());
981
982 if (isTraversableSouthWest(from.getHeight(), from.getX(), from.getY()))
983 positions.add(from.southWest());
984 }
985 }
986 if (positions.isEmpty())
987 return null;
988 return RandomUtils.random(positions);
989 }
990
992 List<Position> positions = new LinkedList<>();
993
994 if (isTraversableNorth(from.getHeight(), from.getX(), from.getY()))
995 positions.add(from.north());
996
997 if (isTraversableSouth(from.getHeight(), from.getX(), from.getY()))
998 positions.add(from.south());
999
1000 if (isTraversableEast(from.getHeight(), from.getX(), from.getY()))
1001 positions.add(from.east());
1002
1003 if (isTraversableWest(from.getHeight(), from.getX(), from.getY()))
1004 positions.add(from.west());
1005
1006 if (positions.isEmpty())
1007 return null;
1008
1009 return RandomUtils.random(positions);
1010 }
1011
1012 public static int getFlags(int x, int y, int height) {
1013 int localX = x & 0x3F;
1014 int localY = y & 0x3F;
1016 return region.getFlags(height, localX, localY);
1017 }
1018
1019 public static int getFlags(Position position) {
1020 return getFlags(position.getX(), position.getY(), position.getHeight());
1021 }
1022
1023 public static boolean blockedNorth(Position position) {
1024 return !isTraversableNorth(position.getHeight(), position.getX(), position.getY(), false);
1025 }
1026
1027 public static boolean blockedEast(Position position) {
1028 return !isTraversableEast(position.getHeight(), position.getX(), position.getY(), false);
1029 }
1030
1031 public static boolean blockedSouth(Position position) {
1032 return !isTraversableSouth(position.getHeight(), position.getX(), position.getY(), false);
1033 }
1034
1035 public static boolean blockedWest(Position position) {
1036 return !isTraversableWest(position.getHeight(), position.getX(), position.getY(), false);
1037 }
1038
1039}
Represents the game world.
Definition World.java:46
static RegionManager getRegions()
Definition World.java:552
static final int MAX_DEFINITIONS
The maximum number of object definitions.
Represents flags for each of the traversals.
static final int IMPENETRABLE_BLOCKED
The flag for an object occupant, which is impenetrable.
static final int IMPENETRABLE_WALL_SOUTH_WEST
The flag for a impenetrable south west facing wall.
static final int BLOCKED
The flag which denotes a blocked tile.
static final int WALL_EAST
The flag for a east facing wall.
static final int IMPENETRABLE_WALL_SOUTH_EAST
The flag for a impenetrable south east facing wall.
static final int WALL_NORTH
The flag for a north facing wall.
static final int IMPENETRABLE_WALL_WEST
The flag for a impenetrable west facing wall.
static final int IMPENETRABLE_WALL_EAST
The flag for a impenetrable east facing wall.
static final int WALL_NORTH_WEST
The flag for a north west facing wall.
static final int IMPENETRABLE_WALL_NORTH_EAST
The flag for a impenetrable north east facing wall.
static final int WALL_WEST
The flag for a west facing wall.
static final int WALL_SOUTH
The flag for a south facing wall.
static final int WALL_NORTH_EAST
The flag for a north east facing wall.
static final int BRIDGE
The flag which denotes a bridge tile.
static final int IMPENETRABLE_WALL_NORTH_WEST
The flag for a impenetrable north west facing wall.
static final int WALL_SOUTH_WEST
The flag for a south west facing wall.
static final int IMPENETRABLE_WALL_NORTH
The flag for a impenetrable north facing wall.
static final int IMPENETRABLE_WALL_SOUTH
The flag for a impenetrable south facing wall.
static final int WALL_SOUTH_EAST
The flag for a south east facing wall.
static boolean isTraversableNorthWest(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed north west.
static boolean isTraversableNorth(int height, int x, int y, int size)
Tests if the specified position can be traversed north.
static boolean isTraversableNorthEast(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed north east.
static void block(Region region, int height, int localX, int localY)
Marks the specified set of coordinates blocked, unable to be passed through.
static boolean blockedSouth(Position position)
static void markObject(Region region, GameObject object, boolean add, boolean list)
Marks a GameObject with the specified attributes on the specified Position to the TraversalMap.
static boolean isTraversableSouthWest(int height, int x, int y, int size)
Tests if the specified position can be traversed south west.
static boolean isTraversableNorthEast(int height, int x, int y, int size)
Tests if the specified position can be traversed north east.
static Position getRandomTraversableTile(Position southWest, int width, int length)
static boolean isTraversableEast(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed east.
static boolean isTraversableSouthEast(int height, int x, int y, int size)
Tests if the specified position can be traversed south east.
static boolean blockedNorth(Position position)
static boolean isTraversableNorthWest(int height, int x, int y)
Tests if the specified position can be traversed north west.
static boolean isTraversableWest(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed west.
static boolean blockedEast(Position position)
static boolean isTraversableSouth(int height, int x, int y, int size)
Tests if the specified position can be traversed south.
static boolean isTraversableNorth(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed north.
static void markBridge(Region region, int height, int x, int y)
Marks the specified coordinates a bridge.
static boolean isInactive(int height, int x, int y, int flag)
Checks whether or not the specified flag is not active on the specified position.
static boolean isTraversable(Position from, Direction direction, int size)
Tests whether or not a specified position is traversable in the specified direction.
static boolean isTraversableSouthEast(int height, int x, int y)
Tests if the specified position can be traversed south east.
static boolean isTraversableNorth(int height, int x, int y)
Tests if the specified position can be traversed north.
static List< Position > getTraversableTiles(Position southWest, int width, int length)
Returns a List of positions that are traversable from the specified position.
static boolean isTraversableSouthEast(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed south east.
static boolean isTraversableNorthWest(int height, int x, int y, int size)
Tests if the specified position can be traversed north west.
static boolean blockedWest(Position position)
static void unset(Region region, int height, int x, int y, int flag)
Unsets the specified flag from the specified position.
static boolean isTraversableWest(int height, int x, int y, int size)
Tests if the specified position can be traversed west.
static boolean isTraversableWest(int height, int x, int y)
Tests if the specified position can be traversed west.
static boolean isTraversableNorthEast(int height, int x, int y)
Tests if the specified position can be traversed north east.
static void markWall(Region reg, ObjectDirection orientation, int height, int x, int y, ObjectType type, boolean impenetrable)
Informs the region of an existing wall.
static boolean isTraversableSouth(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed south.
static void unmarkWall(Region reg, ObjectDirection orientation, int height, int x, int y, ObjectType type, boolean impenetrable)
Informs the region of an existing wall being removed.
static boolean isTraversableSouthWest(int height, int x, int y, boolean impenetrable)
Tests if the specified position can be traversed south west.
static boolean isTraversableEast(int height, int x, int y)
Tests if the specified position can be traversed east.
static boolean isTraversableSouthWest(int height, int x, int y)
Tests if the specified position can be traversed south west.
static int getFlags(int x, int y, int height)
static void markOccupant(Region region, int height, int x, int y, int width, int length, boolean impenetrable, boolean add)
Marks the specified coordinates occupied by some object.
static boolean isTraversableEast(int height, int x, int y, int size)
Tests if the specified position can be traversed east.
static boolean isTraversableSouth(int height, int x, int y)
Tests if the specified position can be traversed south.
static boolean isTraversable(Position from, Direction direction, boolean impenetrable)
Tests whether or not a specified position is traversable in the specified direction.
static Position getRandomNonDiagonal(Position from)
Represents a single tile on the game world.
Definition Position.java:14
int getHeight()
Gets the height coordinate, or height.
Definition Position.java:51
int getY()
Gets the absolute y coordinate.
Definition Position.java:46
int getX()
Gets the absolute x coordinate.
Definition Position.java:41
Position transform(int diffX, int diffY, int diffZ)
Creates a new location based on this location.
Represents a single region.
Definition Region.java:21
Region getRegion(Position position)
Gets a region by position.
A static-util class that provides additional functionality for generating pseudo-random numbers.
static< T > T random(T[] array)
Pseudo-randomly retrieves a element from array.
Represents the enumerated directions an entity can walk or face.
The enumerated type whose elements represent the directions for objects.
The enumerated type whose elements represent all of the object types.