1 package cz.cuni.amis.pogamut.ut2004.agent.navigation;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.logging.Level;
6 import java.util.logging.Logger;
7
8 import cz.cuni.amis.pogamut.base.agent.navigation.IPathExecutorState;
9 import cz.cuni.amis.pogamut.base.agent.navigation.IPathFuture;
10 import cz.cuni.amis.pogamut.base.agent.navigation.IPathPlanner;
11 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
12 import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
13 import cz.cuni.amis.pogamut.base.utils.math.DistanceUtils;
14 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
15 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
16 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
17 import cz.cuni.amis.pogamut.ut2004.agent.navigation.floydwarshall.FloydWarshallMap;
18 import cz.cuni.amis.pogamut.ut2004.agent.navigation.loquenavigator.LoqueNavigator;
19 import cz.cuni.amis.pogamut.ut2004.agent.navigation.navmesh.pathfollowing.UT2004AcceleratedPathExecutor;
20 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.AccUT2004DistanceStuckDetector;
21 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.AccUT2004PositionStuckDetector;
22 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.AccUT2004TimeStuckDetector;
23 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004DistanceStuckDetector;
24 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004PositionStuckDetector;
25 import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004TimeStuckDetector;
26 import cz.cuni.amis.pogamut.ut2004.bot.command.AdvancedLocomotion;
27 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
28 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Stop;
29 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BotKilled;
30 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
31 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Item;
32 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
33 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
34 import cz.cuni.amis.utils.flag.Flag;
35 import cz.cuni.amis.utils.flag.FlagListener;
36
37
38
39
40
41
42
43
44
45
46
47 public class UT2004Navigation implements IUT2004Navigation {
48
49 public static double EXTEND_PATH_THRESHOLD = 500;
50
51
52 protected LogCategory log;
53
54 protected IUT2004PathExecutor<ILocated> pathExecutor;
55
56 protected IPathPlanner<NavPoint> pathPlanner;
57
58 protected UT2004Bot bot;
59
60 protected IUT2004GetBackToNavGraph getBackToNavGraph;
61
62 protected IUT2004RunStraight runStraight;
63
64 protected double extendPathThreshold;
65
66 protected static final int NEW_PATH_DISTANCE_THRESHOLD = 40;
67
68 protected static final int ARRIVED_AT_LOCATION_XY_THRESHOLD = 50;
69
70 protected static final int ARRIVED_AT_LOCATION_Z_THRESHOLD = 100;
71
72 protected static final double PLAYER_DISTANCE_TRASHOLD = 600;
73
74 public static final double AT_PLAYER = 100;
75
76 protected Flag<NavigationState> state = new Flag<NavigationState>(NavigationState.STOPPED);
77
78
79
80
81 FlagListener<IPathExecutorState> myUT2004PathExecutorStateListener = new FlagListener<IPathExecutorState>() {
82
83 @Override
84 public void flagChanged(IPathExecutorState changedValue) {
85 switch (changedValue.getState()) {
86 case TARGET_REACHED:
87 targetReached();
88 break;
89 case PATH_COMPUTATION_FAILED:
90 noPath();
91 break;
92 case STUCK:
93 if (log != null && log.isLoggable(Level.WARNING)) log.warning("UT2004Navigation:stuck(). Path executor reported stuck!");
94 stuck();
95 break;
96 }
97 }
98 };
99
100 protected IWorldEventListener<EndMessage> endMessageListener = new IWorldEventListener<EndMessage>() {
101 @Override
102 public void notify(EndMessage event) {
103 navigate();
104 }
105 };
106
107 protected IWorldEventListener<BotKilled> botKilledMessageListener = new IWorldEventListener<BotKilled>() {
108 @Override
109 public void notify(BotKilled event) {
110 reset(true, NavigationState.STOPPED);
111 }
112 };
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public UT2004Navigation(UT2004Bot bot, IUT2004PathExecutor ut2004PathExecutor, IPathPlanner<NavPoint> pathPlanner, IUT2004GetBackToNavGraph getBackOnPath, IUT2004RunStraight runStraight) {
129 this(bot, ut2004PathExecutor, pathPlanner, getBackOnPath, runStraight, EXTEND_PATH_THRESHOLD);
130 }
131
132
133
134
135
136
137
138
139
140
141 public UT2004Navigation(UT2004Bot bot, IUT2004PathExecutor ut2004PathExecutor, IPathPlanner<NavPoint> pathPlanner, IUT2004GetBackToNavGraph getBackOnPath, IUT2004RunStraight runStraight, double extendPathThreshold) {
142 this.log = bot.getLogger().getCategory(this.getClass().getSimpleName());
143 this.bot = bot;
144
145 this.pathPlanner = pathPlanner;
146 this.pathExecutor = ut2004PathExecutor;
147
148 this.getBackToNavGraph = getBackOnPath;
149 this.runStraight = runStraight;
150
151 this.extendPathThreshold = extendPathThreshold;
152
153 initListeners();
154 }
155
156
157
158
159
160
161
162 public UT2004Navigation(UT2004Bot bot, AgentInfo info, AdvancedLocomotion move) {
163 this.log = bot.getLogger().getCategory(this.getClass().getSimpleName());
164 this.bot = bot;
165 this.pathPlanner = new FloydWarshallMap(bot);
166
167 this.pathExecutor =
168 new UT2004AcceleratedPathExecutor<ILocated>(
169 bot, info, move,
170 new LoqueNavigator<ILocated>(bot,info, move, bot.getLog())
171 );
172
173
174
175
176 this.pathExecutor.addStuckDetector(new AccUT2004TimeStuckDetector(bot, 3000, 100000));
177 this.pathExecutor.addStuckDetector(new AccUT2004PositionStuckDetector(bot));
178 this.pathExecutor.addStuckDetector(new AccUT2004DistanceStuckDetector(bot));
179
180 this.getBackToNavGraph = new UT2004GetBackToNavGraph(bot, info, move);
181 this.runStraight = new UT2004RunStraight(bot, info, move);
182
183 initListeners();
184 }
185
186 @Override
187 public Logger getLog() {
188 return log;
189 }
190
191 @Override
192 public void setLogLevel(Level level) {
193 getLog().setLevel(level);
194 pathExecutor.getLog().setLevel(level);
195 getBackToNavGraph.getLog().setLevel(level);
196 runStraight.getLog().setLevel(level);
197 }
198
199 private void initListeners() {
200 this.pathExecutor.getState().addListener(myUT2004PathExecutorStateListener);
201 bot.getWorldView().addEventListener(EndMessage.class, endMessageListener);
202 bot.getWorldView().addEventListener(BotKilled.class, botKilledMessageListener);
203 }
204
205
206
207
208
209 @Override
210 public void addStrongNavigationListener(FlagListener<NavigationState> listener) {
211 state.addStrongListener(listener);
212 }
213
214 @Override
215 public void removeStrongNavigationListener(FlagListener<NavigationState> listener) {
216 state.removeListener(listener);
217 }
218
219 @Override
220 public IUT2004PathExecutor<ILocated> getPathExecutor() {
221 return pathExecutor;
222 }
223
224 @Override
225 public IPathPlanner<ILocated> getPathPlanner() {
226 return (IPathPlanner<ILocated>)(IPathPlanner)pathPlanner;
227 }
228
229 @Override
230 public IUT2004GetBackToNavGraph getBackToNavGraph() {
231 return getBackToNavGraph;
232 }
233
234 @Override
235 public IUT2004RunStraight getRunStraight() {
236 return runStraight;
237 }
238
239
240
241
242
243 @Override
244 public boolean isNavigating() {
245 return navigating;
246 }
247
248 @Override
249 public boolean isNavigatingToNavPoint() {
250 return isNavigating() && getCurrentTarget() instanceof NavPoint;
251 }
252
253 @Override
254 public boolean isNavigatingToItem() {
255 return isNavigating() && getCurrentTarget() instanceof Item;
256 }
257
258 @Override
259 public boolean isNavigatingToPlayer() {
260 return isNavigating() && getCurrentTarget() instanceof Player;
261 }
262
263 @Override
264 public boolean isTryingToGetBackToNav() {
265 return getBackToNavGraph.isExecuting();
266 }
267
268 @Override
269 public boolean isPathExecuting() {
270 return pathExecutor.isExecuting();
271 }
272
273 @Override
274 public boolean isRunningStraight() {
275 return runStraight.isExecuting();
276 }
277
278 @Override
279 public ILocated getFocus() {
280 return pathExecutor.getFocus();
281 }
282
283 @Override
284 public void setFocus(ILocated located) {
285 pathExecutor.setFocus(located);
286 getBackToNavGraph.setFocus(located);
287 runStraight.setFocus(located);
288 }
289
290 @Override
291 public void stopNavigation() {
292 reset(true, NavigationState.STOPPED);
293 bot.getAct().act(new Stop());
294 }
295
296 @Override
297 public void navigate(ILocated target) {
298 if (target == null) {
299 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL target!");
300 reset(true, NavigationState.STOPPED);
301 return;
302 }
303
304 if (target instanceof Player) {
305
306 navigate((Player)target);
307 return;
308 }
309
310 if (navigating) {
311 if (currentTarget == target || currentTarget.getLocation().equals(target.getLocation())) {
312
313 return;
314 }
315
316
317 reset(false, null);
318 }
319
320 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start navigating to: " + target);
321
322 navigating = true;
323 switchState(NavigationState.NAVIGATING);
324
325 currentTarget = target;
326
327 navigate();
328 }
329
330 @Override
331 public void navigate(Player player) {
332 if (player == null) {
333 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL player!");
334 return;
335 }
336
337 if (navigating) {
338 if (currentTarget == player) {
339
340 return;
341 }
342
343
344 reset(false, null);
345 }
346
347 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start pursuing: " + player);
348
349 navigating = true;
350 switchState(NavigationState.NAVIGATING);
351
352
353
354
355 currentTarget = player;
356 currentTargetPlayer = player;
357
358 navigate();
359 }
360
361 @Override
362 public void navigate(IPathFuture<ILocated> pathHandle) {
363 if (pathHandle == null) {
364 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL pathHandle!");
365 return;
366 }
367
368 if (navigating) {
369 if (currentPathFuture == pathHandle) {
370
371 return;
372 }
373
374
375 reset(false, null);
376 }
377
378 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start running along the path to target: " + pathHandle.getPathTo());
379
380 navigating = true;
381 switchState(NavigationState.NAVIGATING);
382
383 currentTarget = pathHandle.getPathTo();
384 currentPathFuture = pathHandle;
385
386 navigate();
387 }
388
389
390 @Override
391 public NavPoint getNearestNavPoint(ILocated location) {
392 if (location == null) return null;
393 if (location instanceof NavPoint) return (NavPoint)location;
394 if (location instanceof Item) {
395 if (((Item)location).getNavPoint() != null) return ((Item)location).getNavPoint();
396 }
397 return DistanceUtils.getNearest(bot.getWorldView().getAll(NavPoint.class).values(), location);
398 }
399
400 public ILocated getContinueTo() {
401 return continueTo;
402 }
403
404 public void setContinueTo(ILocated continueTo) {
405 if (!isNavigating()) {
406 log.warning("Cannot continueTo(" + continueTo + ") as navigation is not navigating!");
407 return;
408 }
409 if (isNavigatingToPlayer()) {
410 log.warning("Cannot continueTo(" + continueTo + ") as we're navigating to player!");
411 return;
412 }
413 this.continueTo = continueTo;
414
415 NavPoint from = getNearestNavPoint(currentTarget);
416 NavPoint to = getNearestNavPoint(continueTo);
417
418 this.continueToPath = pathPlanner.computePath(from, to);
419
420 checkExtendPath();
421 }
422
423 @Override
424 public List<ILocated> getCurrentPathCopy() {
425 List<ILocated> result = new ArrayList();
426 if (currentPathFuture != null) {
427 result.addAll(currentPathFuture.get());
428 }
429 return result;
430 }
431
432 @Override
433 public List<ILocated> getCurrentPathDirect() {
434 if (currentPathFuture != null) {
435 return currentPathFuture.get();
436 }
437 return null;
438 }
439
440 @Override
441 public ILocated getCurrentTarget() {
442 return currentTarget;
443 }
444
445 @Override
446 public Player getCurrentTargetPlayer() {
447 return currentTargetPlayer;
448 }
449
450 @Override
451 public Item getCurrentTargetItem() {
452 if (currentTarget instanceof Item) return (Item) currentTarget;
453 return null;
454 }
455
456 @Override
457 public NavPoint getCurrentTargetNavPoint() {
458 if (currentTarget instanceof NavPoint) return (NavPoint) currentTarget;
459 return null;
460 }
461
462
463 @Override
464 public ILocated getLastTarget() {
465 return lastTarget;
466 }
467
468 @Override
469 public Player getLastTargetPlayer() {
470 return lastTargetPlayer;
471 }
472
473 @Override
474 public Item getLastTargetItem() {
475 if (lastTarget instanceof Item) return (Item)lastTarget;
476 return null;
477 }
478
479 @Override
480 public double getRemainingDistance() {
481 if (!isNavigating()) return 0;
482 if (isNavigatingToPlayer()) {
483 if (isPathExecuting()) {
484 return pathExecutor.getRemainingDistance() + pathExecutor.getPathTo().getLocation().getDistance(currentTargetPlayer.getLocation());
485 } else {
486
487 NavPoint from = getNearestNavPoint(bot.getLocation());
488 NavPoint to = getNearestNavPoint(currentTargetPlayer.getLocation());
489 IPathFuture<NavPoint> pathFuture = pathPlanner.computePath(from, to);
490 if (pathFuture.isDone()) {
491 return bot.getLocation().getDistance(from.getLocation()) + getPathDistance(pathFuture.get()) + to.getLocation().getDistance(currentTargetPlayer.getLocation());
492 } else {
493
494 return -1;
495 }
496 }
497 } else {
498 if (isPathExecuting()) {
499 return pathExecutor.getRemainingDistance();
500 } else {
501
502 NavPoint from = getNearestNavPoint(bot.getLocation());
503 NavPoint to = getNearestNavPoint(currentTarget.getLocation());
504 IPathFuture<NavPoint> pathFuture = pathPlanner.computePath(from, to);
505 if (pathFuture.isDone()) {
506 return bot.getLocation().getDistance(from.getLocation()) + getPathDistance(pathFuture.get()) + to.getLocation().getDistance(currentTarget.getLocation());
507 } else {
508
509 return -1;
510 }
511 }
512 }
513 }
514
515
516
517
518
519
520 private double getPathDistance(List list) {
521 if (list == null || list.size() <= 0) return 0;
522 double distance = 0;
523 ILocated curr = (ILocated) list.get(0);
524 for (int i = 1; i < list.size(); ++i) {
525 ILocated next = (ILocated) list.get(i);
526 distance += curr.getLocation().getDistance(next.getLocation());
527 curr = next;
528 }
529 return distance;
530 }
531
532
533
534
535
536
537
538 protected ILocated lastTarget = null;
539
540 protected Player lastTargetPlayer = null;
541
542 protected ILocated currentTarget = null;
543
544 protected Player currentTargetPlayer = null;
545
546 protected NavPoint fromNavPoint;
547
548 protected NavPoint toNavPoint;
549
550 protected IPathFuture currentPathFuture;
551
552 protected boolean navigating = false;
553
554 protected boolean runningStraightToPlayer = false;
555
556 protected Location runningStraightToPlayerFailedAt = null;
557
558 protected boolean usingGetBackToNavGraph = false;
559
560 protected ILocated continueTo;
561
562 protected IPathFuture<NavPoint> continueToPath;
563
564
565
566
567
568 protected void navigate() {
569 if (!navigating) return;
570
571 if (log != null && log.isLoggable(Level.FINE)) {
572 log.fine("NAVIGATING");
573 }
574 if (currentTargetPlayer != null) {
575 if (log != null && log.isLoggable(Level.FINE)) log.fine("Pursuing " + currentTargetPlayer);
576 navigatePlayer();
577 } else {
578 if (log != null && log.isLoggable(Level.FINE)) log.fine("Navigating to " + currentTarget);
579 navigateLocation();
580 }
581 }
582
583 private void navigateLocation() {
584 if (isPathExecuting()) {
585
586
587 checkExtendPath();
588 if (log != null && log.isLoggable(Level.FINE)) log.fine("Path executor running");
589 return;
590 }
591
592
593
594
595
596 if (!getBackToNavGraph.isOnNavGraph()) {
597
598
599 if (log != null && log.isLoggable(Level.FINE)) log.fine("Getting back to navigation graph");
600 if (getBackToNavGraph.isExecuting()) {
601
602 return;
603 }
604 if (usingGetBackToNavGraph) {
605
606
607 if (log != null && log.isLoggable(Level.WARNING)) log.warning("UT2004Navigation:stuck(). GetBackToNavGraph was already called && stopped && we're still not on nav graph.");
608 stuck();
609 return;
610 }
611 getBackToNavGraph.backToNavGraph();
612
613 usingGetBackToNavGraph = true;
614 return;
615 } else {
616 usingGetBackToNavGraph = false;
617 }
618
619
620
621 if (currentPathFuture == null) {
622 fromNavPoint = getNearestNavPoint(bot.getLocation());
623 toNavPoint = getNearestNavPoint(currentTarget);
624
625 if (log != null && log.isLoggable(Level.FINE)) log.fine("Computing path from " + fromNavPoint.getId().getStringId() + " to " + toNavPoint.getId().getStringId());
626
627 currentPathFuture = pathPlanner.computePath(fromNavPoint, toNavPoint);
628 }
629
630 switch(currentPathFuture.getStatus()) {
631 case FUTURE_IS_READY:
632
633 break;
634 case FUTURE_IS_BEING_COMPUTED:
635 if (log != null && log.isLoggable(Level.FINE)) log.fine("Waiting for the path to be computed...");
636 return;
637 case CANCELED:
638 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has been canceled.");
639 noPath();
640 return;
641 case COMPUTATION_EXCEPTION:
642 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has failed with an exception.");
643 noPath();
644 return;
645 }
646
647
648
649 if (!processPathFuture(currentPathFuture, currentTarget)) {
650 noPath();
651 return;
652 }
653
654 pathExecutor.followPath(currentPathFuture);
655 }
656
657 private void checkExtendPath() {
658 if (continueTo == null) return;
659 if (continueToPath == null) {
660 log.severe("continueTo specified, but continueToPath is NULL!");
661 return;
662 }
663 if (isNavigatingToPlayer()) {
664 log.warning("continueTo specified, but navigating to Player, INVALID!");
665 return;
666 }
667 if (isPathExecuting()) {
668 double remainingDistance = getRemainingDistance();
669 if (remainingDistance < extendPathThreshold) {
670 if (!continueToPath.isDone()) {
671 log.warning("Should extend path, remainingDistance = " + remainingDistance + " < " + extendPathThreshold + " = extendPathThreshold, but continueToPath.isDone() == false, cannot extend path!");
672 return;
673 }
674 log.info("Extending path to continue to " + continueTo);
675
676 pathExecutor.extendPath(((List)continueToPath.get()));
677
678
679 currentPathFuture = pathExecutor.getPathFuture();
680 lastTarget = currentTarget;
681 currentTarget = continueTo;
682 fromNavPoint = getNearestNavPoint(((IPathFuture<ILocated>)currentPathFuture).get().get(0).getLocation());
683 toNavPoint = getNearestNavPoint(((IPathFuture<ILocated>)currentPathFuture).get().get(currentPathFuture.get().size()-1).getLocation());
684
685 continueTo = null;
686 continueToPath = null;
687 }
688 }
689
690 }
691
692
693 private void navigatePlayer() {
694 double vDistance = bot.getLocation().getDistanceZ(currentTargetPlayer.getLocation());
695 double hDistance = bot.getLocation().getDistance2D(currentTargetPlayer.getLocation());
696
697 if (hDistance < AT_PLAYER && vDistance < 50) {
698
699 if (log != null && log.isLoggable(Level.FINE)) log.fine("Player reached");
700 if (pathExecutor.isExecuting()) {
701 pathExecutor.getPath().set(pathExecutor.getPath().size()-1, bot.getLocation());
702 } else {
703 targetReached();
704 }
705 return;
706 }
707
708 if (hDistance < 400 && Math.abs(vDistance) < 50) {
709
710 if (runningStraightToPlayer) {
711 if (runStraight.isFailed()) {
712 runningStraightToPlayer = false;
713 runningStraightToPlayerFailedAt = bot.getLocation();
714 }
715 } else {
716 if (runningStraightToPlayerFailedAt == null ||
717 bot.getLocation().getDistance(runningStraightToPlayerFailedAt) > 500
718 ) {
719 if (getBackToNavGraph.isExecuting()) {
720 getBackToNavGraph.stop();
721 usingGetBackToNavGraph = false;
722 }
723 if (pathExecutor.isExecuting()) {
724 pathExecutor.stop();
725 }
726 runningStraightToPlayer = true;
727 runningStraightToPlayerFailedAt = null;
728 runStraight.runStraight(currentTargetPlayer);
729 }
730 }
731 if (runningStraightToPlayer) {
732 if (log != null && log.isLoggable(Level.FINE)) log.fine("Running straight to player");
733 return;
734 }
735 } else {
736 if (runningStraightToPlayer) {
737 runningStraightToPlayer = false;
738 runStraight.stop(false);
739 }
740 }
741
742 if (pathExecutor.isExecuting()) {
743
744 if (log != null && log.isLoggable(Level.FINE)) log.fine("Path executor running");
745
746 double distance = currentTarget.getLocation().getDistance(currentTargetPlayer.getLocation());
747
748 if (distance < PLAYER_DISTANCE_TRASHOLD) {
749
750
751 return;
752 }
753
754 if (log != null && log.isLoggable(Level.FINE)) log.fine("Player moved " + distance + " from its original location, checking path...");
755
756 NavPoint newToNavPoint = getNearestNavPoint(currentTargetPlayer);
757 if (newToNavPoint != toNavPoint) {
758
759 if (log != null && log.isLoggable(Level.FINE)) log.fine("Replanning path to get to " + currentTargetPlayer);
760 pathExecutor.stop();
761 currentPathFuture = null;
762 } else {
763 if (log != null && log.isLoggable(Level.FINE)) log.fine("Path remains the same");
764 return;
765 }
766 }
767
768
769
770
771
772
773 if (!getBackToNavGraph.isOnNavGraph()) {
774
775
776 if (log != null && log.isLoggable(Level.FINE)) log.fine("Getting back to navigation graph");
777 if (getBackToNavGraph.isExecuting()) {
778
779 return;
780 }
781 if (usingGetBackToNavGraph) {
782
783
784 if (log != null && log.isLoggable(Level.WARNING)) log.warning("UT2004Navigation:stuck(). GetBackToNavGraph was already called && stopped && we're still not on nav graph.");
785 stuck();
786 return;
787 }
788 getBackToNavGraph.backToNavGraph();
789
790 usingGetBackToNavGraph = true;
791 return;
792 } else {
793 usingGetBackToNavGraph = false;
794 }
795
796
797
798 if (currentPathFuture == null) {
799 fromNavPoint = getNearestNavPoint(bot.getLocation());
800 toNavPoint = getNearestNavPoint(currentTarget);
801
802 if (log != null && log.isLoggable(Level.FINE)) log.fine("Computing path from " + fromNavPoint.getId().getStringId() + " to " + toNavPoint.getId().getStringId());
803
804 currentPathFuture = pathPlanner.computePath(fromNavPoint, toNavPoint);
805 }
806
807 switch(currentPathFuture.getStatus()) {
808 case FUTURE_IS_READY:
809
810 break;
811 case FUTURE_IS_BEING_COMPUTED:
812 if (log != null && log.isLoggable(Level.FINE)) log.fine("Waiting for the path to be computed...");
813 return;
814 case CANCELED:
815 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has been canceled.");
816 noPath();
817 return;
818 case COMPUTATION_EXCEPTION:
819 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has failed with an exception.");
820 noPath();
821 return;
822 }
823
824
825
826 if (!processPathFuture(currentPathFuture, currentTarget)) {
827 noPath();
828 return;
829 }
830
831 pathExecutor.followPath(currentPathFuture);
832 }
833
834
835
836
837
838
839 protected boolean processPathFuture(IPathFuture futurePath, ILocated currentTarget) {
840 List<ILocated> pathList = futurePath.get();
841
842 if (pathList == null) {
843
844 return false;
845 }
846
847 if (currentTarget == null) {
848 if (pathList.size() == 0) return false;
849 currentTarget = pathList.get(pathList.size()-1);
850 } else
851 if (pathList.size() == 0) {
852 currentPathFuture.get().add(currentTarget);
853 } else {
854 ILocated lastPathElement = pathList.get(pathList.size() - 1);
855 if (lastPathElement.getLocation().getDistance(currentTarget.getLocation()) > NEW_PATH_DISTANCE_THRESHOLD) {
856 currentPathFuture.get().add(currentTarget);
857 }
858 }
859 return true;
860 }
861
862 protected void switchState(NavigationState newState) {
863 state.setFlag(newState);
864 }
865
866 protected void noPath() {
867
868 reset(true, NavigationState.PATH_COMPUTATION_FAILED);
869 }
870
871
872 protected void stuck() {
873
874 reset(true, NavigationState.STUCK);
875 }
876
877 protected void targetReached() {
878
879 reset(true, NavigationState.TARGET_REACHED);
880 }
881
882 protected void reset(boolean stopGetBackToNavGraph, NavigationState resultState) {
883 if (currentTarget != null) {
884 lastTarget = currentTarget;
885 lastTargetPlayer = currentTargetPlayer;
886 }
887
888 navigating = false;
889
890 currentTarget = null;
891 currentTargetPlayer = null;
892
893 fromNavPoint = null;
894 toNavPoint = null;
895
896 currentPathFuture = null;
897
898 runningStraightToPlayer = false;
899 runningStraightToPlayerFailedAt = null;
900
901 continueTo = null;
902 continueToPath = null;
903
904 pathExecutor.stop();
905 runStraight.stop(false);
906 if (stopGetBackToNavGraph) {
907 getBackToNavGraph.stop();
908 usingGetBackToNavGraph = false;
909 }
910
911
912 if (resultState == null) return;
913 switchState(resultState);
914 }
915
916 @Override
917 public Flag<NavigationState> getState() {
918 return state.getImmutable();
919 }
920
921 }