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, info, move,
166 new LoqueNavigator<ILocated>(bot,info, move, 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 ILocated getFocus() {
263 return pathExecutor.getFocus();
264 }
265
266 @Override
267 public void setFocus(ILocated located) {
268 pathExecutor.setFocus(located);
269 getBackToNavGraph.setFocus(located);
270 runStraight.setFocus(located);
271 }
272
273 @Override
274 public void stopNavigation() {
275 reset(true, NavigationState.STOPPED);
276 bot.getAct().act(new Stop());
277 }
278
279 @Override
280 public void navigate(ILocated target) {
281 if (target == null) {
282 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL target!");
283 reset(true, NavigationState.STOPPED);
284 return;
285 }
286
287 if (target instanceof Player) {
288
289 navigate((Player)target);
290 return;
291 }
292
293 if (navigating) {
294 if (currentTarget == target || currentTarget.getLocation().equals(target.getLocation())) {
295
296 return;
297 }
298
299
300 reset(false, null);
301 }
302
303 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start navigating to: " + target);
304
305 navigating = true;
306 switchState(NavigationState.NAVIGATING);
307
308 currentTarget = target;
309
310 navigate();
311 }
312
313 @Override
314 public void navigate(Player player) {
315 if (player == null) {
316 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL player!");
317 return;
318 }
319
320 if (navigating) {
321 if (currentTarget == player) {
322
323 return;
324 }
325
326
327 reset(false, null);
328 }
329
330 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start pursuing: " + player);
331
332 navigating = true;
333 switchState(NavigationState.NAVIGATING);
334
335
336
337
338 currentTarget = player;
339 currentTargetPlayer = player;
340
341 navigate();
342 }
343
344 @Override
345 public void navigate(IPathFuture<ILocated> pathHandle) {
346 if (pathHandle == null) {
347 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Cannot navigate to NULL pathHandle!");
348 return;
349 }
350
351 if (navigating) {
352 if (currentPathFuture == pathHandle) {
353
354 return;
355 }
356
357
358 reset(false, null);
359 }
360
361 if (log != null && log.isLoggable(Level.FINE)) log.fine("Start running along the path to target: " + pathHandle.getPathTo());
362
363 navigating = true;
364 switchState(NavigationState.NAVIGATING);
365
366 currentTarget = pathHandle.getPathTo();
367 currentPathFuture = pathHandle;
368
369 navigate();
370 }
371
372
373 @Override
374 public NavPoint getNearestNavPoint(ILocated location) {
375 if (location == null) return null;
376 if (location instanceof NavPoint) return (NavPoint)location;
377 if (location instanceof Item) {
378 if (((Item)location).getNavPoint() != null) return ((Item)location).getNavPoint();
379 }
380 return DistanceUtils.getNearest(bot.getWorldView().getAll(NavPoint.class).values(), location);
381 }
382
383 public ILocated getContinueTo() {
384 return continueTo;
385 }
386
387 public void setContinueTo(ILocated continueTo) {
388 if (!isNavigating()) {
389 log.warning("Cannot continueTo(" + continueTo + ") as navigation is not navigating!");
390 return;
391 }
392 if (isNavigatingToPlayer()) {
393 log.warning("Cannot continueTo(" + continueTo + ") as we're navigating to player!");
394 return;
395 }
396 this.continueTo = continueTo;
397
398 NavPoint from = getNearestNavPoint(currentTarget);
399 NavPoint to = getNearestNavPoint(continueTo);
400
401 this.continueToPath = pathPlanner.computePath(from, to);
402
403 checkExtendPath();
404 }
405
406 @Override
407 public List<ILocated> getCurrentPathCopy() {
408 List<ILocated> result = new ArrayList();
409 if (currentPathFuture != null) {
410 result.addAll(currentPathFuture.get());
411 }
412 return result;
413 }
414
415 @Override
416 public List<ILocated> getCurrentPathDirect() {
417 if (currentPathFuture != null) {
418 return currentPathFuture.get();
419 }
420 return null;
421 }
422
423 @Override
424 public ILocated getCurrentTarget() {
425 return currentTarget;
426 }
427
428 @Override
429 public Player getCurrentTargetPlayer() {
430 return currentTargetPlayer;
431 }
432
433 @Override
434 public Item getCurrentTargetItem() {
435 if (currentTarget instanceof Item) return (Item) currentTarget;
436 return null;
437 }
438
439 @Override
440 public NavPoint getCurrentTargetNavPoint() {
441 if (currentTarget instanceof NavPoint) return (NavPoint) currentTarget;
442 return null;
443 }
444
445
446 @Override
447 public ILocated getLastTarget() {
448 return lastTarget;
449 }
450
451 @Override
452 public Player getLastTargetPlayer() {
453 return lastTargetPlayer;
454 }
455
456 @Override
457 public Item getLastTargetItem() {
458 if (lastTarget instanceof Item) return (Item)lastTarget;
459 return null;
460 }
461
462 @Override
463 public double getRemainingDistance() {
464 if (!isNavigating()) return 0;
465 if (isNavigatingToPlayer()) {
466 if (isPathExecuting()) {
467 return pathExecutor.getRemainingDistance() + pathExecutor.getPathTo().getLocation().getDistance(currentTargetPlayer.getLocation());
468 } else {
469
470 NavPoint from = getNearestNavPoint(bot.getLocation());
471 NavPoint to = getNearestNavPoint(currentTargetPlayer.getLocation());
472 IPathFuture<NavPoint> pathFuture = pathPlanner.computePath(from, to);
473 if (pathFuture.isDone()) {
474 return bot.getLocation().getDistance(from.getLocation()) + getPathDistance(pathFuture.get()) + to.getLocation().getDistance(currentTargetPlayer.getLocation());
475 } else {
476
477 return -1;
478 }
479 }
480 } else {
481 if (isPathExecuting()) {
482 return pathExecutor.getRemainingDistance();
483 } else {
484
485 NavPoint from = getNearestNavPoint(bot.getLocation());
486 NavPoint to = getNearestNavPoint(currentTarget.getLocation());
487 IPathFuture<NavPoint> pathFuture = pathPlanner.computePath(from, to);
488 if (pathFuture.isDone()) {
489 return bot.getLocation().getDistance(from.getLocation()) + getPathDistance(pathFuture.get()) + to.getLocation().getDistance(currentTarget.getLocation());
490 } else {
491
492 return -1;
493 }
494 }
495 }
496 }
497
498
499
500
501
502
503 private double getPathDistance(List list) {
504 if (list == null || list.size() <= 0) return 0;
505 double distance = 0;
506 ILocated curr = (ILocated) list.get(0);
507 for (int i = 1; i < list.size(); ++i) {
508 ILocated next = (ILocated) list.get(i);
509 distance += curr.getLocation().getDistance(next.getLocation());
510 curr = next;
511 }
512 return distance;
513 }
514
515
516
517
518
519
520
521 protected ILocated lastTarget = null;
522
523 protected Player lastTargetPlayer = null;
524
525 protected ILocated currentTarget = null;
526
527 protected Player currentTargetPlayer = null;
528
529 protected NavPoint fromNavPoint;
530
531 protected NavPoint toNavPoint;
532
533 protected IPathFuture currentPathFuture;
534
535 protected boolean navigating = false;
536
537 protected boolean runningStraightToPlayer = false;
538
539 protected Location runningStraightToPlayerFailedAt = null;
540
541 protected boolean usingGetBackToNavGraph = false;
542
543 protected ILocated continueTo;
544
545 protected IPathFuture<NavPoint> continueToPath;
546
547
548
549
550
551 protected void navigate() {
552 if (!navigating) return;
553
554 if (log != null && log.isLoggable(Level.FINE)) {
555 log.fine("NAVIGATING");
556 }
557 if (currentTargetPlayer != null) {
558 if (log != null && log.isLoggable(Level.FINE)) log.fine("Pursuing " + currentTargetPlayer);
559 navigatePlayer();
560 } else {
561 if (log != null && log.isLoggable(Level.FINE)) log.fine("Navigating to " + currentTarget);
562 navigateLocation();
563 }
564 }
565
566 private void navigateLocation() {
567 if (isPathExecuting()) {
568
569
570 checkExtendPath();
571 if (log != null && log.isLoggable(Level.FINE)) log.fine("Path executor running");
572 return;
573 }
574
575
576
577
578
579 if (!getBackToNavGraph.isOnNavGraph()) {
580
581
582 if (log != null && log.isLoggable(Level.FINE)) log.fine("Getting back to navigation graph");
583 if (getBackToNavGraph.isExecuting()) {
584
585 return;
586 }
587 if (usingGetBackToNavGraph) {
588
589
590 if (log != null && log.isLoggable(Level.WARNING)) log.warning("UT2004Navigation:stuck(). GetBackToNavGraph was already called && stopped && we're still not on nav graph.");
591 stuck();
592 return;
593 }
594 getBackToNavGraph.backToNavGraph();
595
596 usingGetBackToNavGraph = true;
597 return;
598 } else {
599 usingGetBackToNavGraph = false;
600 }
601
602
603
604 if (currentPathFuture == null) {
605 fromNavPoint = getNearestNavPoint(bot.getLocation());
606 toNavPoint = getNearestNavPoint(currentTarget);
607
608 if (log != null && log.isLoggable(Level.FINE)) log.fine("Computing path from " + fromNavPoint.getId().getStringId() + " to " + toNavPoint.getId().getStringId());
609
610 currentPathFuture = pathPlanner.computePath(fromNavPoint, toNavPoint);
611 }
612
613 switch(currentPathFuture.getStatus()) {
614 case FUTURE_IS_READY:
615
616 break;
617 case FUTURE_IS_BEING_COMPUTED:
618 if (log != null && log.isLoggable(Level.FINE)) log.fine("Waiting for the path to be computed...");
619 return;
620 case CANCELED:
621 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has been canceled.");
622 noPath();
623 return;
624 case COMPUTATION_EXCEPTION:
625 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has failed with an exception.");
626 noPath();
627 return;
628 }
629
630
631
632 if (!processPathFuture(currentPathFuture, currentTarget)) {
633 noPath();
634 return;
635 }
636
637 pathExecutor.followPath(currentPathFuture);
638 }
639
640 private void checkExtendPath() {
641 if (continueTo == null) return;
642 if (continueToPath == null) {
643 log.severe("continueTo specified, but continueToPath is NULL!");
644 return;
645 }
646 if (isNavigatingToPlayer()) {
647 log.warning("continueTo specified, but navigating to Player, INVALID!");
648 return;
649 }
650 if (isPathExecuting()) {
651 double remainingDistance = getRemainingDistance();
652 if (remainingDistance < extendPathThreshold) {
653 if (!continueToPath.isDone()) {
654 log.warning("Should extend path, remainingDistance = " + remainingDistance + " < " + extendPathThreshold + " = extendPathThreshold, but continueToPath.isDone() == false, cannot extend path!");
655 return;
656 }
657 log.info("Extending path to continue to " + continueTo);
658
659 pathExecutor.extendPath(((List)continueToPath.get()));
660
661
662 currentPathFuture = pathExecutor.getPathFuture();
663 lastTarget = currentTarget;
664 currentTarget = continueTo;
665 fromNavPoint = getNearestNavPoint(((IPathFuture<ILocated>)currentPathFuture).get().get(0).getLocation());
666 toNavPoint = getNearestNavPoint(((IPathFuture<ILocated>)currentPathFuture).get().get(currentPathFuture.get().size()-1).getLocation());
667
668 continueTo = null;
669 continueToPath = null;
670 }
671 }
672
673 }
674
675
676 private void navigatePlayer() {
677 double vDistance = bot.getLocation().getDistanceZ(currentTargetPlayer.getLocation());
678 double hDistance = bot.getLocation().getDistance2D(currentTargetPlayer.getLocation());
679
680 if (hDistance < AT_PLAYER && vDistance < 50) {
681
682 if (log != null && log.isLoggable(Level.FINE)) log.fine("Player reached");
683 if (pathExecutor.isExecuting()) {
684 pathExecutor.getPath().set(pathExecutor.getPath().size()-1, bot.getLocation());
685 } else {
686 targetReached();
687 }
688 return;
689 }
690
691 if (hDistance < 400 && Math.abs(vDistance) < 50) {
692
693 if (runningStraightToPlayer) {
694 if (runStraight.isFailed()) {
695 runningStraightToPlayer = false;
696 runningStraightToPlayerFailedAt = bot.getLocation();
697 }
698 } else {
699 if (runningStraightToPlayerFailedAt == null ||
700 bot.getLocation().getDistance(runningStraightToPlayerFailedAt) > 500
701 ) {
702 if (getBackToNavGraph.isExecuting()) {
703 getBackToNavGraph.stop();
704 usingGetBackToNavGraph = false;
705 }
706 if (pathExecutor.isExecuting()) {
707 pathExecutor.stop();
708 }
709 runningStraightToPlayer = true;
710 runningStraightToPlayerFailedAt = null;
711 runStraight.runStraight(currentTargetPlayer);
712 }
713 }
714 if (runningStraightToPlayer) {
715 if (log != null && log.isLoggable(Level.FINE)) log.fine("Running straight to player");
716 return;
717 }
718 } else {
719 if (runningStraightToPlayer) {
720 runningStraightToPlayer = false;
721 runStraight.stop(false);
722 }
723 }
724
725 if (pathExecutor.isExecuting()) {
726
727 if (log != null && log.isLoggable(Level.FINE)) log.fine("Path executor running");
728
729 double distance = currentTarget.getLocation().getDistance(currentTargetPlayer.getLocation());
730
731 if (distance < PLAYER_DISTANCE_TRASHOLD) {
732
733
734 return;
735 }
736
737 if (log != null && log.isLoggable(Level.FINE)) log.fine("Player moved " + distance + " from its original location, checking path...");
738
739 NavPoint newToNavPoint = getNearestNavPoint(currentTargetPlayer);
740 if (newToNavPoint != toNavPoint) {
741
742 if (log != null && log.isLoggable(Level.FINE)) log.fine("Replanning path to get to " + currentTargetPlayer);
743 pathExecutor.stop();
744 currentPathFuture = null;
745 } else {
746 if (log != null && log.isLoggable(Level.FINE)) log.fine("Path remains the same");
747 return;
748 }
749 }
750
751
752
753
754
755
756 if (!getBackToNavGraph.isOnNavGraph()) {
757
758
759 if (log != null && log.isLoggable(Level.FINE)) log.fine("Getting back to navigation graph");
760 if (getBackToNavGraph.isExecuting()) {
761
762 return;
763 }
764 if (usingGetBackToNavGraph) {
765
766
767 if (log != null && log.isLoggable(Level.WARNING)) log.warning("UT2004Navigation:stuck(). GetBackToNavGraph was already called && stopped && we're still not on nav graph.");
768 stuck();
769 return;
770 }
771 getBackToNavGraph.backToNavGraph();
772
773 usingGetBackToNavGraph = true;
774 return;
775 } else {
776 usingGetBackToNavGraph = false;
777 }
778
779
780
781 if (currentPathFuture == null) {
782 fromNavPoint = getNearestNavPoint(bot.getLocation());
783 toNavPoint = getNearestNavPoint(currentTarget);
784
785 if (log != null && log.isLoggable(Level.FINE)) log.fine("Computing path from " + fromNavPoint.getId().getStringId() + " to " + toNavPoint.getId().getStringId());
786
787 currentPathFuture = pathPlanner.computePath(fromNavPoint, toNavPoint);
788 }
789
790 switch(currentPathFuture.getStatus()) {
791 case FUTURE_IS_READY:
792
793 break;
794 case FUTURE_IS_BEING_COMPUTED:
795 if (log != null && log.isLoggable(Level.FINE)) log.fine("Waiting for the path to be computed...");
796 return;
797 case CANCELED:
798 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has been canceled.");
799 noPath();
800 return;
801 case COMPUTATION_EXCEPTION:
802 if (log != null && log.isLoggable(Level.WARNING)) log.warning("Path computation has failed with an exception.");
803 noPath();
804 return;
805 }
806
807
808
809 if (!processPathFuture(currentPathFuture, currentTarget)) {
810 noPath();
811 return;
812 }
813
814 pathExecutor.followPath(currentPathFuture);
815 }
816
817
818
819
820
821
822 protected boolean processPathFuture(IPathFuture futurePath, ILocated currentTarget) {
823 List<ILocated> pathList = futurePath.get();
824
825 if (pathList == null) {
826
827 return false;
828 }
829
830 if (currentTarget == null) {
831 if (pathList.size() == 0) return false;
832 currentTarget = pathList.get(pathList.size()-1);
833 } else
834 if (pathList.size() == 0) {
835 currentPathFuture.get().add(currentTarget);
836 } else {
837 ILocated lastPathElement = pathList.get(pathList.size() - 1);
838 if (lastPathElement.getLocation().getDistance(currentTarget.getLocation()) > NEW_PATH_DISTANCE_THRESHOLD) {
839 currentPathFuture.get().add(currentTarget);
840 }
841 }
842 return true;
843 }
844
845 protected void switchState(NavigationState newState) {
846 state.setFlag(newState);
847 }
848
849 protected void noPath() {
850
851 reset(true, NavigationState.PATH_COMPUTATION_FAILED);
852 }
853
854
855 protected void stuck() {
856
857 reset(true, NavigationState.STUCK);
858 }
859
860 protected void targetReached() {
861
862 reset(true, NavigationState.TARGET_REACHED);
863 }
864
865 protected void reset(boolean stopGetBackToNavGraph, NavigationState resultState) {
866 if (currentTarget != null) {
867 lastTarget = currentTarget;
868 lastTargetPlayer = currentTargetPlayer;
869 }
870
871 navigating = false;
872
873 currentTarget = null;
874 currentTargetPlayer = null;
875
876 fromNavPoint = null;
877 toNavPoint = null;
878
879 currentPathFuture = null;
880
881 runningStraightToPlayer = false;
882 runningStraightToPlayerFailedAt = null;
883
884 continueTo = null;
885 continueToPath = null;
886
887 pathExecutor.stop();
888 runStraight.stop(false);
889 if (stopGetBackToNavGraph) {
890 getBackToNavGraph.stop();
891 usingGetBackToNavGraph = false;
892 }
893
894
895 if (resultState == null) return;
896 switchState(resultState);
897 }
898
899 @Override
900 public Flag<NavigationState> getState() {
901 return state.getImmutable();
902 }
903
904 }