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