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