1 package cz.cuni.amis.pogamut.ut2004.agent.navigation.loquenavigator;
2
3 import java.util.logging.Level;
4 import java.util.logging.Logger;
5
6 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObject;
7 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
8 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
9 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
10 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
11 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Players;
12 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Senses;
13 import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004PathRunner;
14 import cz.cuni.amis.pogamut.ut2004.bot.command.AdvancedLocomotion;
15 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
16 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Move;
17 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLink;
18 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
19 import cz.cuni.amis.utils.NullCheck;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 @Deprecated
59 public class LoqueRunner implements IUT2004PathRunner {
60
61
62
63 private int runnerStep = 0;
64
65
66
67
68 private int runnerSingleJump = 0;
69
70
71
72 private int runnerDoubleJump = 0;
73
74
75
76
77 private int collisionCount = 0;
78
79
80
81
82 private Location collisionSpot = null;
83
84
85
86
87
88
89 public void reset()
90 {
91
92 runnerStep = 0;
93 runnerSingleJump = 0;
94 runnerDoubleJump = 0;
95 collisionCount = 0;
96 collisionSpot = null;
97 }
98
99
100
101 private Move addFocus(Move move, ILocated focus) {
102 if (focus != null) {
103 if (focus instanceof Player && ((IWorldObject)focus).getId() instanceof UnrealId) {
104 move.setFocusTarget((UnrealId)((IWorldObject)focus).getId());
105 } else {
106 move.setFocusLocation(focus.getLocation());
107 }
108 }
109 return move;
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public boolean runToLocation (Location fromLocation, Location firstLocation, Location secondLocation, ILocated focus, NavPointNeighbourLink navPointsLink, boolean reachable)
138 {
139
140 if (log != null && log.isLoggable(Level.FINER)) {
141 log.finer(
142 "Runner.runToLocation(): runnerStep is "
143 + runnerStep + ", reachable is " + reachable + ", navPointsLink is" + navPointsLink
144 );
145 }
146
147
148 runnerStep++;
149
150
151
152 if (runnerStep <= 0) {
153
154 return true;
155 }
156
157
158
159 if (runnerStep <= 1)
160 {
161
162 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
163
164
165
166 if ((navPointsLink != null) && (
167 navPointsLink.isForceDoubleJump()
168 || (navPointsLink.getNeededJump() != null)
169 || (navPointsLink.getFlags() & 8) != 0
170 )) {
171
172
173 if (((navPointsLink.getFlags() & 8) == 0) || (memory.getLocation().z - 100 <= firstLocation.z)) {
174 Location direction = Location.sub(firstLocation, memory.getLocation()).getNormalized();
175 Location velocityDir = new Location(memory.getVelocity().asVector3d()).getNormalized();
176 Double result = Math.acos(direction.dot(velocityDir));
177
178
179 if (memory.getVelocity().size() > 200 && !result.isNaN() && result < (Math.PI / 9))
180 return resolveJump(firstLocation, secondLocation, focus, navPointsLink, reachable);
181 }
182 }
183
184 return true;
185 }
186
187
188 if (runnerSingleJump > 0)
189 {
190
191 return iterateSingleJumpSequence (firstLocation, secondLocation, focus, reachable);
192 }
193
194 else if (runnerDoubleJump > 0)
195 {
196
197 return iterateDoubleJumpSequence (firstLocation, secondLocation, focus, reachable);
198 }
199
200 if (senses.isCollidingOnce())
201 {
202
203 return resolveCollision (firstLocation, secondLocation, focus, reachable);
204 }
205
206 else
207 if
208 (
209
210 (runnerSingleJump == 0) && (runnerDoubleJump == 0)
211 &&
212 (
213
214 !reachable
215
216 || (navPointsLink != null) &&
217 (
218 navPointsLink.isForceDoubleJump()
219 || (navPointsLink.getNeededJump() != null)
220 || (navPointsLink.getFlags() & 8) != 0
221 )
222
223
224
225
226
227
228
229 )
230 )
231 {
232
233 return resolveJump (firstLocation, secondLocation, focus, navPointsLink, reachable);
234 }
235
236
237 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
238
239 if (log != null && log.isLoggable(Level.FINER)) {
240 log.finer(
241 "Runner.runToLocation(): issuing default move command to: " + firstLocation
242 );
243 }
244
245 return true;
246 }
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 private boolean resolveCollision (Location firstLocation, Location secondLocation, ILocated focus, boolean reachable)
263 {
264
265 if (
266
267 (collisionSpot == null)
268
269 || (memory.getLocation().getDistance2D(collisionSpot) > 120)
270 ) {
271
272 if (log != null && log.isLoggable(Level.FINER))
273 log.finer(
274 "Runner.resolveCollision(): collision at "
275 + (int) memory.getLocation().getDistance2D(firstLocation)
276 );
277 collisionSpot = memory.getLocation();
278 collisionCount = 1;
279
280 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
281 return true;
282 }
283
284
285 else
286 switch (collisionCount++ % 2) {
287 case 0:
288
289 if (log != null && log.isLoggable(Level.FINER))
290 log.finer(
291 "Runner.resolveCollision(): repeated collision (" + collisionCount + "):"
292 + " double-jumping at " + (int) memory.getLocation().getDistance2D(firstLocation)
293 );
294 return initDoubleJumpSequence (firstLocation, secondLocation, focus, reachable);
295
296 default:
297
298 if (log != null && log.isLoggable(Level.FINER))
299 log.finer(
300 "Runner.resolveCollision(): repeated collision (" + collisionCount + "):"
301 + " single-jumping at " + (int) memory.getLocation().getDistance2D(firstLocation)
302 );
303 return initSingleJumpSequence (firstLocation, secondLocation, focus, reachable);
304 }
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323 private boolean resolveJump (Location firstLocation, Location secondLocation, ILocated focus, NavPointNeighbourLink navPointsLink, boolean reachable)
324 {
325
326 int distance = (int) memory.getLocation().getDistance2D(firstLocation);
327
328 int velocity = (int) memory.getVelocity().size();
329
330
331
332
333 int jumpDistance = distance % 1000;
334
335
336 int zDistance = (int) firstLocation.getDistanceZ(memory.getLocation());
337
338
339
340
341 jumpDistance += Math.min (200, Math.max (-200, zDistance));
342
343 log.finer("Runner.resolveJump: distance = " + distance + ", velocity = " + velocity + ", jumpDistance = " + jumpDistance + ", zDistance = " + zDistance);
344
345
346 boolean enforceDoubleJump = false;
347 if ((navPointsLink != null)
348 &&
349 ( (navPointsLink.getNeededJump() != null || (navPointsLink.getFlags() & 8 ) != 0)
350 && (zDistance > 60 || jumpDistance > 380)
351 )
352 ){
353
354
355 enforceDoubleJump = true;
356 log.finest("Runner.resolveJump(): double jump indicated");
357 }
358
359
360 if (jumpDistance < 370)
361 {
362
363
364 if (navPointsLink != null) {
365 if (navPointsLink.getNeededJump() != null || (navPointsLink.getFlags() & 8 ) != 0)
366
367 if (enforceDoubleJump) return initDoubleJumpSequence(firstLocation, secondLocation, focus, reachable);
368 return initSingleJumpSequence (firstLocation, secondLocation, focus, reachable);
369 }
370
371
372
373 if (reachable || (distance >= 1000))
374 {
375
376 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
377 return true;
378 }
379
380
381
382
383
384
385
386 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
387 return true;
388 }
389
390 else if (jumpDistance < 470)
391 {
392
393 if (enforceDoubleJump) return initDoubleJumpSequence(firstLocation, secondLocation, focus, reachable);
394
395 return initSingleJumpSequence (firstLocation, secondLocation, focus, reachable);
396 }
397
398
399 else if (jumpDistance < 600)
400 {
401
402 if (enforceDoubleJump) {
403
404
405 return initDoubleJumpSequence(firstLocation, secondLocation, focus, reachable);
406 }
407
408
409 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
410 return true;
411 }
412
413
414 else if ((jumpDistance < 700) && (velocity > 300))
415 {
416 if (!enforceDoubleJump) {
417
418
419 if (navPointsLink != null && (navPointsLink.getFlags() & 8 ) != 0) {
420
421 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
422 return true;
423 }
424 }
425
426
427
428 return initDoubleJumpSequence (firstLocation, secondLocation, focus, reachable);
429 }
430
431
432 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
433 return true;
434 }
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451 private boolean initSingleJumpSequence (Location firstLocation, Location secondLocation, ILocated focus, boolean reachable)
452 {
453
454 if ((runnerSingleJump > 0) || (runnerDoubleJump > 0))
455 throw new RuntimeException ("jumping sequence aleady started");
456
457 log.finer("Runner.initSingleJumpSequence() !");
458
459
460 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
461
462 body.jump ();
463
464 runnerSingleJump = 1;
465 return true;
466 }
467
468
469
470
471
472
473
474
475
476 private boolean iterateSingleJumpSequence (Location firstLocation, Location secondLocation, ILocated focus, boolean reachable)
477 {
478
479 int distance = (int) memory.getLocation().getDistance2D(firstLocation);
480
481 int zVelocity = (int) memory.getVelocity().z;
482
483
484 switch (runnerSingleJump)
485 {
486
487 case 1:
488
489 if (zVelocity > 100)
490 {
491
492 if (log != null && log.isLoggable(Level.FINER)) log.finer("Runner.iterateSingleJumpSequence(): single-jump registered at " + distance + ", z-velo " + zVelocity);
493 runnerSingleJump++;
494 }
495
496 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
497 return true;
498
499
500 default:
501
502 if (zVelocity <= 0)
503 {
504
505 if (log != null && log.isLoggable(Level.FINER)) log.finer("Runner.iterateSingleJumpSequence(): single-jump completed at " + distance + ", z-velo " + zVelocity);
506 runnerSingleJump = 0;
507 }
508
509 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
510 return true;
511 }
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528 private boolean initDoubleJumpSequence (Location firstLocation, Location secondLocation, ILocated focus, boolean reachable)
529 {
530
531 if ((runnerSingleJump > 0) || (runnerDoubleJump > 0))
532 throw new RuntimeException ("jumping sequence aleady started");
533
534
535
536
537
538 boolean doubleJump = true;
539 double delay = 0.39;
540 double jumpZ = 680;
541
542
543 double distanceZ = firstLocation.getDistanceZ(memory.getLocation());
544 double distance2D = firstLocation.getDistance2D(memory.getLocation());
545 log.finer("Runner.initDoubleJumpSequence(): disntane2D = " + distance2D + ", distanceZ = " + distanceZ);
546 if (distanceZ > 0) {
547 log.finer("Runner.initDoubleJumpSequence(): JUMPING UP! Adjusting parameters of the jump...");
548
549 double jumpZ_up = 680 * distanceZ / 70;
550 boolean doubleJump_up = jumpZ_up > 340;
551
552 double jumpZ_forward = 680;
553 boolean doubleJump_forward = true;
554 if (distance2D < 250) {
555
556 doubleJump_forward = false;
557 jumpZ_forward = 340 * distance2D / 250;
558 } else
559 if (distance2D < 350) {
560
561 jumpZ_forward = 340 + 340 * (distance2D - 250) / 100;
562 }
563
564 if (jumpZ_up > jumpZ_forward) {
565 jumpZ = jumpZ_up;
566 doubleJump = doubleJump_up;
567 log.finer("Runner.initDoubleJumpSequence(): jumping up more than jumping forward, jumpZ_up = " + jumpZ_up + " > " + jumpZ_forward + " = jumpZ_forward");
568 } else {
569 jumpZ = jumpZ_forward;
570 doubleJump = doubleJump_forward;
571 log.finer("Runner.initDoubleJumpSequence(): jumping forward more than jumping up, jumpZ_up = " + jumpZ_up + " < " + jumpZ_forward + " = jumpZ_forward");
572 }
573
574 } else {
575 log.finer("Runner.initDoubleJumpSequence(): FALLING DOWN! Adjusting parameters of the jump for falling...");
576
577
578
579 double distanceTravelledByFalling = 451/382 * Math.abs(distanceZ);
580
581 double remainingDistance2D = distance2D - distanceTravelledByFalling;
582
583
584
585
586
587
588 if (remainingDistance2D < 300) {
589 log.finer("Runner.initDoubleJumpSequence(): single jump suffice, distance2D = " + distance2D + ", estimated distance travelled by just falling = " + distanceTravelledByFalling + ", remaining distance 2D to jump = " + remainingDistance2D);
590 doubleJump = false;
591 jumpZ = 340 * remainingDistance2D / 300;
592 } else
593 if (remainingDistance2D < 450) {
594 log.finer("Runner.initDoubleJumpSequence(): smaller double jump is needed, distance2D = " + distance2D + ", estimated distance travelled by just falling = " + distanceTravelledByFalling + ", remaining distance 2D to jump = " + remainingDistance2D);
595 jumpZ = 340 + 340 * (remainingDistance2D - 220) * 150;
596 } else {
597 log.finer("Runner.initDoubleJumpSequence(): full double jump is needed, distance2D = " + distance2D + ", estimated distance travelled by just falling = " + distanceTravelledByFalling + ", remaining distance 2D to jump = " + remainingDistance2D);
598
599 }
600 }
601
602 log.finer("Runner.initDoubleJumpSequence(): " + (doubleJump ? "double jumping, double jump delay = " + delay : "single jumping") + ", jumpZ = " + jumpZ);
603
604
605
606
607 body.doubleJump(delay, jumpZ);
608
609 runnerDoubleJump = 1;
610 return true;
611 }
612
613
614
615
616
617
618
619
620
621 private boolean iterateDoubleJumpSequence (Location firstLocation, Location secondLocation, ILocated focus, boolean reachable)
622 {
623
624 int distance = (int) memory.getLocation().getDistance2D(firstLocation);
625
626 int zVelocity = (int) memory.getVelocity().z;
627
628
629 switch (runnerDoubleJump)
630 {
631
632 case 1:
633
634 if (zVelocity > 100)
635 {
636
637 if (log != null && log.isLoggable(Level.FINER)) log.finer("Runner.iterateDoubleJumpSequence(): double-jump registered at " + distance + ", z-velo " + zVelocity);
638 runnerDoubleJump++;
639 }
640
641 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
642 return true;
643
644
645 case 2:
646
647 if (zVelocity < 150)
648 {
649
650 if (log != null && log.isLoggable(Level.FINER)) log.finer("Runner.iterateDoubleJumpSequence(): double-jump boost at " + distance + ", z-velo " + zVelocity);
651 body.jump ();
652 runnerDoubleJump++;
653 return true;
654 }
655
656 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
657 return true;
658
659
660 default:
661
662 if (zVelocity <= 0)
663 {
664
665 runnerDoubleJump = 0;
666 }
667
668 bot.getAct().act(addFocus(new Move().setFirstLocation(firstLocation).setSecondLocation(secondLocation), focus));
669 return true;
670 }
671 }
672
673
674
675
676 protected UT2004Bot bot;
677
678 protected AgentInfo memory;
679
680 protected AdvancedLocomotion body;
681
682 protected Logger log;
683
684 protected Senses senses;
685
686
687
688
689
690
691
692
693 public LoqueRunner (UT2004Bot bot, AgentInfo agentInfo, AdvancedLocomotion locomotion, Logger log) {
694
695 NullCheck.check(bot, "bot");
696 this.bot = bot;
697 NullCheck.check(agentInfo, "agentInfo");
698 this.memory = agentInfo;
699 NullCheck.check(locomotion, "locomotion");
700 this.body = new AdvancedLocomotion(bot, log);
701 this.senses = new Senses(bot, memory, new Players(bot), log);
702 this.log = log;
703 }
704
705 }