1 package cz.cuni.amis.pogamut.ut2004.agent.module.sensor;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Random;
11 import java.util.Set;
12 import java.util.logging.Logger;
13
14 import cz.cuni.amis.pogamut.base.agent.module.SensorModule;
15 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
16 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
17 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
18 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
19 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent;
20 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
21 import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.Weaponry;
22 import cz.cuni.amis.pogamut.ut2004.agent.module.utils.TabooSet;
23 import cz.cuni.amis.pogamut.ut2004.bot.IUT2004BotController;
24 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
25 import cz.cuni.amis.pogamut.ut2004.communication.messages.ItemType;
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.ItemPickedUp;
29 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
30 import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.MapPointListObtained;
31 import cz.cuni.amis.pogamut.ut2004.utils.UnrealUtils;
32 import cz.cuni.amis.utils.NullCheck;
33 import cz.cuni.amis.utils.collections.MyCollections;
34 import cz.cuni.amis.utils.maps.HashMapMap;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public abstract class Items extends SensorModule<UT2004Bot> {
54
55 private Random random = new Random(System.currentTimeMillis());
56
57
58
59
60
61
62
63
64
65
66 public abstract boolean isPickable(Item item);
67
68
69
70
71
72
73
74
75 public Item getRandomItem() {
76 if (getAllItems().size() == 0) return null;
77 int num = random.nextInt(getAllItems().size());
78 Iterator<Item> iter = getAllItems().values().iterator();
79 for (int i = 0; i < num-1; ++i) iter.next();
80 return iter.next();
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95 public Map<UnrealId, Item> getAllItems()
96 {
97 return Collections.unmodifiableMap(items.all);
98 }
99
100
101
102
103
104
105
106
107
108
109 public Map<UnrealId, Item> getAllItems(ItemType type)
110 {
111 return Collections.unmodifiableMap(items.allCategories.get(type));
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public Map<UnrealId, Item> getAllItems(ItemType.Category category) {
127 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
128 for (ItemType type : category.getTypes()) {
129 result.putAll(getAllItems(type));
130 }
131 return result;
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public Map<UnrealId, Item> getAllItems(ItemType.Group group) {
147 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
148 for (ItemType type : group.getTypes()) {
149 result.putAll(getAllItems(type));
150 }
151 return result;
152 }
153
154
155
156
157
158
159
160
161
162 public Item getItem(UnrealId id) {
163 Item item = items.all.get(id);
164 if (item == null) item = items.visible.get(id);
165 return item;
166 }
167
168
169
170
171
172
173
174
175
176 public Item getItem(String stringUnrealId) {
177 return getItem(UnrealId.get(stringUnrealId));
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192 public Map<UnrealId, Item> getVisibleItems()
193 {
194 return Collections.unmodifiableMap(items.visible);
195 }
196
197
198
199
200
201
202
203
204
205
206
207 public Map<UnrealId, Item> getVisibleItems(ItemType type)
208 {
209 return Collections.unmodifiableMap(items.visibleCategories.get(type));
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224 public Map<UnrealId, Item> getVisibleItems(ItemType.Category category) {
225 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
226 for (ItemType type : category.getTypes()) {
227 result.putAll(getVisibleItems(type));
228 }
229 return result;
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244 public Map<UnrealId, Item> getVisibleItems(ItemType.Group group) {
245 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
246 for (ItemType type : group.getTypes()) {
247 result.putAll(getVisibleItems(type));
248 }
249 return result;
250 }
251
252
253
254
255
256
257
258
259
260
261 public Item getVisibleItem(UnrealId id) {
262 Item item = items.visible.get(id);
263 return item;
264 }
265
266
267
268
269
270
271
272
273
274
275 public Item getVisibleItem(String stringUnrealId) {
276 return getVisibleItem(UnrealId.get(stringUnrealId));
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 public Map<UnrealId, Item> getKnownPickups()
293 {
294 return Collections.unmodifiableMap(items.known);
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308 public Map<UnrealId, Item> getKnownPickups(ItemType type)
309 {
310 return Collections.unmodifiableMap(items.knownCategories.get(type));
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325 public Map<UnrealId, Item> getKnownPickups(ItemType.Category category) {
326 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
327 for (ItemType type : category.getTypes()) {
328 result.putAll(getKnownPickups(type));
329 }
330 return result;
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345 public Map<UnrealId, Item> getKnownPickups(ItemType.Group group) {
346 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
347 for (ItemType type : group.getTypes()) {
348 result.putAll(getKnownPickups(type));
349 }
350 return result;
351 }
352
353
354
355
356
357
358
359
360
361 public Item getKnownPickup(UnrealId id) {
362 return items.known.get(id);
363 }
364
365
366
367
368
369
370
371
372
373 public Item getKnownPickup(String stringUnrealId) {
374 return getKnownPickup(UnrealId.get(stringUnrealId));
375 }
376
377
378
379
380
381
382
383
384
385
386
387 public Map<UnrealId, Item> getSpawnedItems() {
388 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
389 for (Item item : getAllItems().values()) {
390 if (isPickupSpawned(item)) result.put(item.getId(), item);
391 }
392 return result;
393 }
394
395
396
397
398
399
400
401
402
403 public Map<UnrealId, Item> getSpawnedItems(ItemType type) {
404 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
405 for (Item item : getAllItems(type).values()) {
406 if (isPickupSpawned(item)) {
407 result.put(item.getId(), item);
408 }
409 }
410 return result;
411 }
412
413
414
415
416
417
418
419
420
421
422
423
424
425 public Map<UnrealId, Item> getSpawnedItems(ItemType.Category category) {
426 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
427 for (ItemType type : category.getTypes()) {
428 result.putAll(getSpawnedItems(type));
429 }
430 return result;
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445 public Map<UnrealId, Item> getSpawnedItems(ItemType.Group group) {
446 Map<UnrealId, Item> result = new HashMap<UnrealId, Item>();
447 for (ItemType type : group.getTypes()) {
448 result.putAll(getSpawnedItems(type));
449 }
450 return result;
451 }
452
453
454
455
456
457
458 public double getItemRespawnUT2004Time(Item item) {
459 return getItemRespawnTime(item.getType()) * UnrealUtils.UT2004_TIME_SPEED;
460 }
461
462
463
464
465
466
467 public double getItemRespawnUT2004Time(ItemType itemType) {
468 return getItemRespawnTime(itemType) * UnrealUtils.UT2004_TIME_SPEED;
469 }
470
471
472
473
474
475
476 public double getItemRespawnTime(Item item) {
477 return getItemRespawnTime(item.getType());
478 }
479
480
481
482
483
484
485 public abstract double getItemRespawnTime(ItemType itemType);
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503 public boolean isPickupSpawned(Item item) {
504 if (item == null) return false;
505 if (item.isVisible()) {
506
507 return true;
508 }
509 NavPoint np = item.getNavPoint();
510 if (np == null) {
511 np = navPoints.get(item.getNavPointId());
512 }
513 if (np != null) {
514 if (np.isVisible()) {
515
516 return np.isItemSpawned();
517 } else {
518 return !items.itemMissing.isTaboo(item);
519 }
520 } else {
521
522 return !items.itemMissing.isTaboo(item);
523 }
524 }
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542 public boolean isPickupSpawned(UnrealId itemId) {
543 return isPickupSpawned(items.all.get(itemId));
544 }
545
546
547
548
549
550
551 private class ItemMaps
552 {
553
554 private HashMap<UnrealId, Item> all = new HashMap<UnrealId, Item> ();
555
556 private HashMap<UnrealId, Item> visible = new HashMap<UnrealId, Item> ();
557
558 private HashMap<UnrealId, Item> reachable = new HashMap<UnrealId, Item> ();
559
560 private HashMap<UnrealId, Item> known = new HashMap<UnrealId, Item> ();
561
562 private HashMapMap<ItemType, UnrealId, Item> allCategories = new HashMapMap<ItemType, UnrealId, Item>();
563
564 private HashMapMap<ItemType, UnrealId, Item> visibleCategories = new HashMapMap<ItemType, UnrealId, Item> ();
565
566 private HashMapMap<ItemType, UnrealId, Item> reachableCategories = new HashMapMap<ItemType, UnrealId, Item> ();
567
568 private HashMapMap<ItemType, UnrealId, Item> knownCategories = new HashMapMap<ItemType, UnrealId, Item> ();
569
570 private TabooSet<Item> itemMissing;
571
572 private Set<Item> justPickedUp = new HashSet<Item>();
573
574 private HashMap<UnrealId, Boolean> itemSpawned = new HashMap<UnrealId, Boolean>();
575
576 public ItemMaps(UT2004Bot bot) {
577 itemMissing = new TabooSet<Item>(bot);
578 }
579
580 private void notify(NavPoint navPoint) {
581 if (navPoint.getItem() == null) return;
582 Item item = getItem(navPoint.getItem());
583 if (item == null) return;
584
585 if (navPoint.isItemSpawned()) {
586
587 itemMissing.remove(item);
588 } else {
589 if (itemMissing.isTaboo(item)) {
590
591 return;
592 }
593 itemMissing.add(item, getItemRespawnUT2004Time(item));
594 }
595 }
596
597
598
599
600
601 private void notify(Item item)
602 {
603 UnrealId uid = item.getId();
604
605
606 if (!all.containsKey(uid)) {
607 all.put(uid, item);
608 allCategories.put(item.getType(), item.getId(), item);
609 }
610
611
612 boolean wasVisible = visible.containsKey(uid);
613 boolean isVisible = item.isVisible();
614
615
616 if (isVisible && !wasVisible)
617 {
618
619 visible.put(uid, item);
620 visibleCategories.put(item.getType(), item.getId(), item);
621 }
622 else if (!isVisible && wasVisible)
623 {
624
625 visible.remove(uid);
626 visibleCategories.remove(item.getType(), item.getId());
627 }
628
629
630 if (!isVisible && item.isDropped()) {
631 all.remove(uid);
632 allCategories.remove(item.getType(), item.getId());
633 }
634
635 }
636
637
638
639
640
641 private void notify(Map<UnrealId, Item> items)
642 {
643
644 known.putAll(items);
645 for (Item item : items.values()) {
646 knownCategories.put(item.getType(), item.getId(), item);
647 notify(item);
648 }
649 }
650
651
652
653
654
655 private void notifyBatchEnd(List<NavPoint> navPoints) {
656 justPickedUp.clear();
657 }
658
659
660
661
662
663 private void notify(ItemPickedUp event) {
664 Item item = all.get(event.getId());
665 if (item == null) return;
666 justPickedUp.add(item);
667 itemMissing.add(item, getItemRespawnUT2004Time(item));
668 }
669
670 private void clear() {
671 all.clear();
672 allCategories.clear();
673 itemMissing.clear();
674 justPickedUp.clear();
675 known.clear();
676 knownCategories.clear();
677 reachable.clear();
678 reachableCategories.clear();
679 visible.clear();
680 visibleCategories.clear();
681 }
682 }
683
684
685 private ItemMaps items;
686
687
688
689 protected class ItemsListener implements IWorldObjectEventListener<Item, IWorldObjectEvent<Item>> {
690
691 public ItemsListener(IWorldView worldView) {
692 worldView.addObjectListener(Item.class, IWorldObjectEvent.class, this);
693 }
694
695 public void notify(IWorldObjectEvent<Item> event) {
696 items.notify(event.getObject());
697 }
698
699 }
700
701 protected ItemsListener itemsListener;
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717 protected ItemsListener createItemsListener(IWorldView worldView) {
718 return new ItemsListener(worldView);
719 }
720
721
722
723
724
725
726 protected class MapPointsListener implements IWorldEventListener<MapPointListObtained>
727 {
728
729
730
731
732 public MapPointsListener(IWorldView worldView)
733 {
734 worldView.addEventListener(MapPointListObtained.class, this);
735 }
736
737 @Override
738 public void notify(MapPointListObtained event)
739 {
740 navPoints = event.getNavPoints();
741 items.notify(event.getItems());
742 }
743
744 }
745
746
747 protected MapPointsListener mapPointsListener;
748 protected Map<UnrealId, NavPoint> navPoints = new HashMap<UnrealId, NavPoint>();
749
750
751
752
753
754
755
756
757
758
759
760 protected MapPointsListener createMapPointsListener(IWorldView worldView) {
761 return new MapPointsListener(worldView);
762 }
763
764
765
766
767
768
769 protected class NavPointListener implements IWorldObjectEventListener<NavPoint, WorldObjectUpdatedEvent<NavPoint>>
770 {
771
772
773
774
775 public NavPointListener(IWorldView worldView) {
776 worldView.addObjectListener(NavPoint.class, WorldObjectUpdatedEvent.class, this);
777 }
778
779 @Override
780 public void notify(WorldObjectUpdatedEvent<NavPoint> event) {
781 items.notify(event.getObject());
782 if (event.getObject().isVisible()) {
783 navPointsToProcess.add(event.getObject());
784 } else {
785 navPointsToProcess.remove(event.getObject());
786 }
787 }
788
789 }
790
791
792
793
794
795 protected List<NavPoint> navPointsToProcess = new ArrayList<NavPoint>();
796
797 protected NavPointListener navPointListener;
798
799
800
801
802
803
804 protected class EndMessageListener implements IWorldEventListener<EndMessage>
805 {
806
807
808
809
810 public EndMessageListener(IWorldView worldView)
811 {
812 worldView.addEventListener(EndMessage.class, this);
813 }
814
815 @Override
816 public void notify(EndMessage event)
817 {
818 items.notifyBatchEnd(navPointsToProcess);
819 }
820
821 }
822
823 protected EndMessageListener endMessageListener;
824
825
826
827
828
829
830 protected class ItemPickedUpListener implements IWorldEventListener<ItemPickedUp>
831 {
832
833
834
835
836 public ItemPickedUpListener(IWorldView worldView)
837 {
838 worldView.addEventListener(ItemPickedUp.class, this);
839 }
840
841 @Override
842 public void notify(ItemPickedUp event)
843 {
844 items.notify(event);
845 }
846
847 }
848
849 protected ItemPickedUpListener itemPickedUpListener;
850
851
852
853
854 protected AgentInfo agentInfo;
855
856
857 protected Weaponry weaponry;
858
859
860 protected Game game;
861
862
863
864
865
866
867
868
869 public Items(UT2004Bot bot, AgentInfo agentInfo, Game game, Weaponry weaponry, Logger log)
870 {
871 super(bot, log);
872
873
874 this.agentInfo = agentInfo;
875 NullCheck.check(this.agentInfo, "agentInfo");
876
877 this.weaponry = weaponry;
878 NullCheck.check(this.weaponry, "weaponry");
879
880 this.game = game;
881 NullCheck.check(this.game, "game");
882
883 items = new ItemMaps(bot);
884
885
886 itemsListener = createItemsListener(worldView);
887 mapPointsListener = createMapPointsListener(worldView);
888 navPointListener = new NavPointListener(worldView);
889 endMessageListener = new EndMessageListener(worldView);
890 itemPickedUpListener = new ItemPickedUpListener(worldView);
891
892 cleanUp();
893 }
894
895 @Override
896 protected void cleanUp() {
897 super.cleanUp();
898 navPoints.clear();
899 items.clear();
900 }
901
902 }