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