1 package cz.cuni.amis.pogamut.udk.agent.module.sensomotoric;
2
3
4
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.Map;
8 import java.util.logging.Level;
9
10 import cz.cuni.amis.pogamut.base.agent.module.SensomotoricModule;
11 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
12 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
13 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
14 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent;
15 import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
16 import cz.cuni.amis.pogamut.udk.agent.module.sensor.AgentInfo;
17 import cz.cuni.amis.pogamut.udk.agent.module.sensor.ItemDescriptors;
18 import cz.cuni.amis.pogamut.udk.bot.impl.UDKBot;
19 import cz.cuni.amis.pogamut.udk.communication.messages.ItemType;
20 import cz.cuni.amis.pogamut.udk.communication.messages.ItemType.Category;
21 import cz.cuni.amis.pogamut.udk.communication.messages.gbcommands.ChangeWeapon;
22 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.AddInventoryMsg;
23 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.BotKilled;
24 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ItemPickedUp;
25 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.Self;
26 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.Thrown;
27 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.WeaponUpdate;
28 import cz.cuni.amis.pogamut.udk.communication.translator.itemdescriptor.AmmoDescriptor;
29 import cz.cuni.amis.pogamut.udk.communication.translator.itemdescriptor.ItemDescriptor;
30 import cz.cuni.amis.pogamut.udk.communication.translator.itemdescriptor.WeaponDescriptor;
31 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
32
33 import cz.cuni.amis.utils.maps.LazyMap;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class Weaponry extends SensomotoricModule<UDKBot> {
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public WeaponDescriptor getDescriptorForId(UnrealId inventoryWeaponId) {
66 WeaponDescriptor desc = inventoryUnrealIdToWeaponDescriptor.get(inventoryWeaponId);
67 if (desc == null) {
68 if (log.isLoggable(Level.WARNING)) log.warning("getDescriptorForId(): There is no WeaponDescriptor for the inventory weapon id '" + inventoryWeaponId.getStringId() + "'.");
69 }
70 return desc;
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public ItemType getItemTypeForId(UnrealId inventoryWeaponId) {
86 WeaponDescriptor desc = inventoryUnrealIdToWeaponDescriptor.get(inventoryWeaponId);
87 if (desc == null) {
88 if (log.isLoggable(Level.WARNING)) log.warning("getItemTypeForId(): There is no WeaponDescriptor for the inventory weapon id '" + inventoryWeaponId.getStringId() + "'.");
89 return null;
90 }
91 return desc.getPickupType();
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public UnrealId getWeaponInventoryId(ItemType weaponType) {
109 return weaponTypeToInventoryUnrealId.get(weaponType);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public UnrealId getWeaponInventoryId(WeaponDescriptor weaponDescriptor) {
127 if (weaponDescriptor == null) return null;
128 if (weaponDescriptor.getPickupType() == null) {
129 if (log.isLoggable(Level.WARNING)) log.warning("getWeaponInventoryId(): WeaponDescriptor does not have PickupType assigned!");
130 return null;
131 }
132 return weaponTypeToInventoryUnrealId.get(weaponDescriptor.getPickupType());
133 }
134
135
136
137
138
139
140
141 public boolean changeWeapon(ItemType weaponType) {
142 if (weaponType == null) return false;
143 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
144 Weapon weapon = getWeapon(weaponType);
145 return changeWeapon(getWeapon(weaponType));
146 }
147
148
149
150
151
152
153
154 public boolean changeWeapon(Weapon weapon) {
155 if (weapon == null) return false;
156 if (weapon == getCurrentWeapon()) return true;
157 if (weapon.getAmmo() <= 0) return false;
158 if (weaponsByItemType.all.get(weapon.getType()) == null) return false;
159 act.act(new ChangeWeapon().setId(weapon.getInventoryId().getStringId()));
160 return true;
161 }
162
163
164
165
166
167
168
169
170
171
172
173
174
175 public int getAmmo(ItemType ammoOrWeaponType) {
176 if (ammoOrWeaponType == null) return 0;
177 if (ammoOrWeaponType.getCategory() == ItemType.Category.WEAPON) {
178 if (hasSecondaryAmmoType(ammoOrWeaponType)) {
179 return getPrimaryWeaponAmmo(ammoOrWeaponType) + getSecondaryWeaponAmmo(ammoOrWeaponType);
180 } else {
181 return getPrimaryWeaponAmmo(ammoOrWeaponType);
182 }
183 }
184 if (ammoOrWeaponType.getCategory() == ItemType.Category.AMMO) {
185 return ammo.getAmmo(ammoOrWeaponType);
186 }
187 return 0;
188 }
189
190
191
192
193
194
195
196
197
198 public int getPrimaryWeaponAmmo(ItemType weaponType) {
199 if (weaponType == null) return 0;
200 if (weaponType.getCategory() != ItemType.Category.WEAPON) return 0;
201 return ammo.getPriAmmoForWeapon(weaponType);
202 }
203
204
205
206
207
208
209
210
211
212 public int getSecondaryWeaponAmmo(ItemType weaponType) {
213 if (weaponType == null) return 0;
214 if (weaponType.getCategory() != ItemType.Category.WEAPON) return 0;
215 return ammo.getSecAmmoForWeapon(weaponType);
216 }
217
218
219
220
221
222
223
224
225
226 public int getWeaponAmmo(ItemType weaponType) {
227 if (weaponType == null) return 0;
228 if (weaponType.getCategory() != ItemType.Category.WEAPON) return 0;
229 return ammo.getAmmoForWeapon(weaponType);
230 }
231
232
233
234
235
236
237
238
239
240
241 public boolean hasLowAmmoForWeapon(ItemType weaponType, double lowRatio) {
242 return hasPrimaryLowAmmoForWeapon(weaponType, lowRatio) || hasSecondaryLowAmmoForWeapon(weaponType, lowRatio);
243 }
244
245
246
247
248
249
250
251
252
253
254 public boolean hasSecondaryLowAmmoForWeapon(ItemType weaponType, double lowRatio) {
255 int ammo = getSecondaryWeaponAmmo(weaponType);
256 WeaponDescriptor desc = getWeaponDescriptor(weaponType);
257 return ammo / desc.getPriMaxAmount() < lowRatio;
258 }
259
260
261
262
263
264
265
266
267
268
269 public boolean hasPrimaryLowAmmoForWeapon(ItemType weaponType, double lowRatio) {
270 if (!hasSecondaryAmmoType(weaponType)) return false;
271 int ammo = getSecondaryWeaponAmmo(weaponType);
272 WeaponDescriptor desc = getWeaponDescriptor(weaponType);
273 return ammo / desc.getSecMaxAmount() < lowRatio;
274 }
275
276
277
278
279
280
281
282
283
284 public boolean hasAmmo(ItemType ammoType) {
285 if (ammoType == null) return false;
286 if (ammoType.getCategory() != ItemType.Category.AMMO) return false;
287 return ammo.getAmmo(ammoType) > 0;
288 }
289
290
291
292
293
294
295
296
297
298 public boolean hasAmmoForWeapon(ItemType weaponType) {
299 return hasWeaponAmmo(weaponType);
300 }
301
302
303
304
305
306
307
308
309
310
311 public boolean hasWeaponAmmo(ItemType weaponType) {
312 if (weaponType == null) return false;
313 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
314 return ammo.getAmmoForWeapon(weaponType) > 0;
315 }
316
317
318
319
320
321
322
323
324
325 public boolean hasPrimaryWeaponAmmo(ItemType weaponType) {
326 if (weaponType == null) return false;
327 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
328 return ammo.getPriAmmoForWeapon(weaponType) > 0;
329 }
330
331
332
333
334
335
336
337
338
339 public boolean hasSecondaryWeaponAmmo(ItemType weaponType) {
340 if (weaponType == null) return false;
341 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
342 return ammo.getSecAmmoForWeapon(weaponType) > 0;
343 }
344
345
346
347
348
349
350
351
352
353 public boolean hasWeapon(ItemType weaponType) {
354 if (weaponType == null) return false;
355 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
356 return weaponsByItemType.all.containsKey(weaponType);
357 }
358
359
360
361
362
363
364
365
366
367 public boolean hasWeapon(ItemType.Group weaponGroup) {
368 if (weaponGroup == null) return false;
369 return weaponsByGroup.all.containsKey(weaponGroup);
370 }
371
372
373
374
375
376
377
378
379
380 public boolean isLoaded(ItemType weaponType) {
381 if (weaponType == null) return false;
382 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
383 return weaponsByItemType.allLoaded.containsKey(weaponType);
384 }
385
386
387
388
389
390
391
392
393
394 public boolean isLoaded(ItemType.Group weaponGroup) {
395 if (weaponGroup == null) return false;
396 return weaponsByGroup.allLoaded.containsKey(weaponGroup);
397 }
398
399
400
401
402
403
404
405
406
407 public boolean hasSecondaryAmmoType(ItemType weaponType) {
408 if (weaponType == null) return false;
409 if (weaponType.getCategory() != ItemType.Category.WEAPON) return false;
410 WeaponDescriptor desc = (WeaponDescriptor) itemDescriptors.getDescriptor(weaponType);
411 if (desc == null) {
412 if (log.isLoggable(Level.WARNING)) log.warning("hasSecondaryAmmoType(): There is no weapon descriptor for the item type " + weaponType + "!");
413 return false;
414 }
415 return desc.getSecAmmoItemType() != null && desc.getPriAmmoItemType() != desc.getSecAmmoItemType();
416 }
417
418
419
420
421
422
423
424
425
426 public WeaponDescriptor getWeaponDescriptor(ItemType weaponType) {
427 if (weaponType == null) return null;
428 if (weaponType.getCategory() != ItemType.Category.WEAPON) return null;
429 WeaponDescriptor desc = (WeaponDescriptor) itemDescriptors.getDescriptor(weaponType);
430 if (desc == null) {
431 if (log.isLoggable(Level.WARNING)) log.warning("getWeaponDescriptor(): There is no weapon descriptor for the item type " + weaponType + "!");
432 }
433 return desc;
434 }
435
436
437
438
439
440
441
442
443
444
445 public Weapon getCurrentWeapon() {
446 if (self == null) {
447 return null;
448 }
449 if (self.getWeapon() == null) {
450 return null;
451 }
452 WeaponDescriptor desc = inventoryUnrealIdToWeaponDescriptor.get(UnrealId.get(self.getWeapon().getStringId()));
453 if (desc == null) {
454 if (self.getWeapon().getStringId().equalsIgnoreCase(AgentInfo.NONE_WEAPON_ID)) return null;
455 if (log.isLoggable(Level.WARNING)) log.warning("getCurrentWeapon(): There is no weapon descriptor for current bot's weapon of id: '" + self.getWeapon() + "'");
456 return null;
457 }
458 return weaponsByItemType.all.get(desc.getPickupType());
459 }
460
461
462
463
464
465
466
467
468
469
470 public int getCurrentAmmo() {
471 if (getCurrentWeapon() == null) return 0;
472 if (getCurrentWeapon().hasSecondaryAmmoType()) {
473 return getCurrentPrimaryAmmo() + getCurrentAlternateAmmo();
474 } else {
475 return getCurrentPrimaryAmmo();
476 }
477 }
478
479
480
481
482
483
484
485
486
487 public int getCurrentPrimaryAmmo() {
488
489 if (self == null) {
490 return 0;
491 }
492 return self.getPrimaryAmmo();
493 }
494
495
496
497
498
499
500
501
502
503
504 public int getCurrentAlternateAmmo() {
505 if (self == null) {
506 return 0;
507 }
508 if (self.getWeapon() == null) {
509 return 0;
510 }
511 WeaponDescriptor weaponDesc = inventoryUnrealIdToWeaponDescriptor.get(UnrealId.get(self.getWeapon().getStringId()));
512 if (weaponDesc == null) {
513 if (self.getWeapon().getStringId().equals(AgentInfo.NONE_WEAPON_ID)) return 0;
514 if (log.isLoggable(Level.WARNING)) log.warning("getCurrentAlternateAmmo(): There is no weapon descriptor for current bot's weapon of id: '" + self.getWeapon() + "'");
515 return 0;
516 }
517 if (weaponDesc.getSecAmmoItemType() != null) {
518 return self.getSecondaryAmmo();
519 } else {
520 return self.getPrimaryAmmo();
521 }
522 }
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537 public Map<ItemType, Weapon> getWeapons() {
538 return Collections.unmodifiableMap(weaponsByItemType.all);
539 }
540
541
542
543
544
545
546
547
548 public Weapon getWeapon(ItemType weaponType) {
549 if (weaponType == null) return null;
550 if (weaponType.getCategory() != ItemType.Category.WEAPON) return null;
551 return weaponsByItemType.all.get(weaponType);
552 }
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571 public Map<ItemType, Weapon> getLoadedWeapons() {
572 return Collections.unmodifiableMap(weaponsByItemType.allLoaded);
573 }
574
575
576
577
578
579
580
581
582
583
584
585
586 public Map<ItemType, Weapon> getMeleeWeapons() {
587 return Collections.unmodifiableMap(weaponsByItemType.allMelee);
588 }
589
590
591
592
593
594
595
596
597
598
599
600
601 public Map<ItemType, Weapon> getRangedWeapons() {
602 return Collections.unmodifiableMap(weaponsByItemType.allRanged);
603 }
604
605
606
607
608
609
610
611
612
613
614
615
616 public Map<ItemType, Weapon> getLoadedMeleeWeapons() {
617 return Collections.unmodifiableMap(weaponsByItemType.allLoadedMelee);
618 }
619
620
621
622
623
624
625
626
627
628
629
630
631 public Map<ItemType, Weapon> getLoadedRangedWeapons() {
632 return Collections.unmodifiableMap(weaponsByItemType.allLoadedRanged);
633 }
634
635
636
637
638
639
640
641
642
643 public Map<ItemType, Integer> getAmmos() {
644 return Collections.unmodifiableMap(ammo.ammo);
645 }
646
647
648
649
650
651
652
653
654
655
656
657 public boolean hasLoadedWeapon() {
658
659 return !getLoadedWeapons().isEmpty();
660 }
661
662
663
664
665
666
667
668
669
670 public boolean hasLoadedRangedWeapon() {
671
672 return !getLoadedRangedWeapons().isEmpty();
673 }
674
675
676
677
678
679
680
681
682
683
684
685 public boolean hasLoadedMeleeWeapon() {
686
687 return !getLoadedMeleeWeapons().isEmpty();
688 }
689
690
691
692
693
694
695 public boolean hasLoadedWeapon(ItemType weapon) {
696 return hasPrimaryLoadedWeapon(weapon) || hasSecondaryLoadedWeapon(weapon);
697 }
698
699
700
701
702
703
704 public boolean hasPrimaryLoadedWeapon(ItemType weapon) {
705 Weapon w = getWeapon(weapon);
706 if (w == null) return false;
707 return w.getPrimaryAmmo() > 0;
708 }
709
710
711
712
713
714
715 public boolean hasSecondaryLoadedWeapon(ItemType weapon) {
716 Weapon w = getWeapon(weapon);
717 if (w == null) return false;
718 return w.getSecondaryAmmo() > 0;
719 }
720
721
722
723
724
725
726
727 public ItemType getWeaponForAmmo(ItemType priOrSecAmmoType) {
728 for (ItemType weaponType : Category.WEAPON.getTypes()) {
729 WeaponDescriptor desc = (WeaponDescriptor)itemDescriptors.getDescriptor(weaponType);
730 if (desc == null) continue;
731 if (desc.getPriAmmoItemType() == priOrSecAmmoType) return weaponType;
732 if (desc.getSecAmmoItemType() == priOrSecAmmoType) return weaponType;
733 }
734 return null;
735 }
736
737
738
739
740
741
742 public ItemType getPrimaryWeaponAmmoType(ItemType weaponType) {
743 WeaponDescriptor desc = (WeaponDescriptor)itemDescriptors.getDescriptor(weaponType);
744 if (desc == null) return null;
745 return desc.getPriAmmoItemType();
746 }
747
748
749
750
751
752
753 public ItemType getSecondaryWeaponAmmoType(ItemType weaponType) {
754 WeaponDescriptor desc = (WeaponDescriptor)itemDescriptors.getDescriptor(weaponType);
755 if (desc == null) return null;
756 return desc.getSecAmmoItemType();
757 }
758
759
760
761
762
763
764
765
766
767
768
769 private class Ammunition {
770
771
772
773
774 private LazyMap<ItemType, Integer> ammo = new LazyMap<ItemType, Integer>() {
775 @Override
776 protected Integer create(ItemType key) {
777 return 0;
778 }
779 };
780
781
782
783
784
785
786 public int getAmmo(ItemType ammoType) {
787 if (ammoType == null) return 0;
788 if (ammoType.getCategory() != ItemType.Category.AMMO) return 0;
789 return ammo.get(ammoType);
790 }
791
792
793
794
795
796
797 public int getPriAmmoForWeapon(ItemType weapon) {
798 if (weapon == null) return 0;
799 if (weapon.getCategory() != ItemType.Category.WEAPON) return 0;
800 WeaponDescriptor desc = (WeaponDescriptor)itemDescriptors.getDescriptor(weapon);
801 if (desc == null) {
802 if (log.isLoggable(Level.WARNING)) log.warning("Ammunition.getPriAmmoForWeapon(): There is no WeaponDescriptor for the item type " + weapon + "!");
803 return 0;
804 }
805 return getAmmo(desc.getPriAmmoItemType());
806 }
807
808
809
810
811
812
813
814 public int getSecAmmoForWeapon(ItemType weaponType) {
815 if (weaponType == null) return 0;
816 if (weaponType.getCategory() != ItemType.Category.WEAPON) return 0;
817 WeaponDescriptor desc = (WeaponDescriptor)itemDescriptors.getDescriptor(weaponType);
818 if (desc == null) {
819 if (log.isLoggable(Level.WARNING)) log.warning("Ammunition.getSecAmmoForWeapon(): There is no WeaponDescriptor for the item type " + weaponType + "!");
820 return 0;
821 }
822 if (desc.getSecAmmoItemType() == null) return getPriAmmoForWeapon(weaponType);
823 return getAmmo(desc.getSecAmmoItemType());
824 }
825
826
827
828
829
830
831 public int getAmmoForWeapon(ItemType weaponType) {
832 if (weaponType == null) return 0;
833 if (weaponType.getCategory() != ItemType.Category.WEAPON) return 0;
834 WeaponDescriptor desc = (WeaponDescriptor) itemDescriptors.getDescriptor(weaponType);
835 if (desc == null) {
836 if (log.isLoggable(Level.WARNING)) log.warning("Ammunition.getAmmoForWeapon(): There is no WeaponDescriptor for the item type " + weaponType + "!");
837 return 0;
838 }
839 if (desc.getSecAmmoItemType() != null && desc.getPriAmmoItemType()!= desc.getSecAmmoItemType()) {
840 return getPriAmmoForWeapon(weaponType) + getSecAmmoForWeapon(weaponType);
841 } else {
842 return getPriAmmoForWeapon(weaponType);
843 }
844 }
845
846
847
848
849
850 public void itemPickedUp(ItemPickedUp pickedUp) {
851 if (pickedUp == null) return;
852 ItemDescriptor descriptor = itemDescriptors.getDescriptor(pickedUp.getType());
853 if (descriptor == null) {
854 if (log.isLoggable(Level.WARNING)) log.warning("Ammunition.itemPickedUp(): There is no ItemDescriptor for the item type " + pickedUp.getType() + "!");
855 return;
856 }
857
858 if (pickedUp.getDescriptor().getPickupType() == ItemType.REDEEMER
859 || pickedUp.getDescriptor().getPickupType() == ItemType.REDEEMER_AMMO
860 )
861
862 {
863
864 if (descriptor.getItemCategory() == Category.AMMO) {
865 if (ammo.get(pickedUp.getType()) <= 0) {
866 ammo.put(pickedUp.getType(), 1);
867 }
868 } else
869 if (descriptor.getItemCategory() == Category.WEAPON) {
870 WeaponDescriptor desc = (WeaponDescriptor)descriptor;
871 if (ammo.get(desc.getPriAmmoItemType()) == 0) {
872 ammo.put(desc.getPriAmmoItemType(), 1);
873 }
874 }
875 return;
876 }
877
878 if (descriptor.getItemCategory() == Category.AMMO) {
879 AmmoDescriptor desc = (AmmoDescriptor)descriptor;
880 int current = getAmmo(pickedUp.getType());
881 if (current + pickedUp.getAmount() > desc.getPriMaxAmount()) {
882 ammo.put(pickedUp.getType(), desc.getPriMaxAmount());
883 } else {
884 ammo.put(pickedUp.getType(), current + pickedUp.getAmount());
885 }
886 } else
887 if (descriptor.getItemCategory() == Category.WEAPON) {
888 WeaponDescriptor desc = (WeaponDescriptor)descriptor;
889
890 if (desc.getPriAmmoItemType() != null) {
891 int priAmmo = ammo.get(desc.getPriAmmoItemType());
892
893 int priWeaponAmmoPlus = pickedUp.getAmount();
894 if (priAmmo + priWeaponAmmoPlus <= desc.getPriMaxAmount()) {
895 ammo.put(desc.getPriAmmoItemType(), priAmmo + priWeaponAmmoPlus);
896 } else {
897 ammo.put(desc.getPriAmmoItemType(), desc.getPriMaxAmount());
898 }
899 }
900
901 if (desc.getSecAmmoItemType() != null && desc.getSecAmmoItemType() != desc.getPriAmmoItemType()) {
902 int secAmmo = ammo.get(desc.getSecAmmoItemType());
903 int secWeaponAmmoPlus = pickedUp.getAmountSec();
904 if (secAmmo + secWeaponAmmoPlus <= desc.getSecMaxAmount()) {
905 ammo.put(desc.getSecAmmoItemType(), secAmmo + secWeaponAmmoPlus);
906 } else {
907 ammo.put(desc.getSecAmmoItemType(), desc.getSecMaxAmount());
908 }
909 }
910 }
911 }
912
913
914
915
916
917
918
919 public void weaponUpdate(ItemType ammoType, int amount) {
920
921
922 if (ammoType == null) return;
923 if (ammoType.getCategory() != ItemType.Category.AMMO) {
924 if (log.isLoggable(Level.SEVERE)) log.severe("Ammunition.weaponUpdate: Can't update weapon ammo, unknown ammo type=" + ammoType.getName() + ", category=" + ammoType.getCategory() + ", group=" + ammoType.getGroup());
925 return;
926 }
927 ammo.put(ammoType, amount);
928 }
929
930
931
932
933 public void botKilled() {
934 ammo.clear();
935 }
936
937
938
939
940 public void updateWeaponAmmo(Weapon weapon) {
941 if (weapon == null) return;
942 weapon.primaryAmmo = getAmmo(weapon.getDescriptor().getPriAmmoItemType());
943 if (weapon.getDescriptor().getSecAmmoItemType() != null) {
944 weapon.secondaryAmmo = getAmmo(weapon.getDescriptor().getSecAmmoItemType());
945 }
946 weaponsByGroup.ammoChanged(weapon.getGroup());
947 weaponsByItemType.ammoChanged(weapon.getType());
948 weaponsById.ammoChanged(weapon.getInventoryId());
949 }
950 }
951
952 private Ammunition ammo = new Ammunition();
953
954
955
956
957
958
959 private class WeaponsByKey<KEY> {
960
961 private HashMap<KEY, Weapon> all = new HashMap<KEY, Weapon>();
962
963 private HashMap<KEY, Weapon> allLoaded = new HashMap<KEY, Weapon>();
964
965 private HashMap<KEY, Weapon> allMelee = new HashMap<KEY, Weapon>();
966
967 private HashMap<KEY, Weapon> allRanged = new HashMap<KEY, Weapon>();
968
969 private HashMap<KEY, Weapon> allLoadedMelee = new HashMap<KEY, Weapon>();
970
971 private HashMap<KEY, Weapon> allLoadedRanged = new HashMap<KEY, Weapon>();
972
973
974
975
976
977
978
979 public void add(KEY key, Weapon inv) {
980 if (key == null || inv == null) return;
981 if (inv.getDescriptor() == null) {
982 if (log.isLoggable(Level.WARNING)) log.warning("WeaponsByKey.add(): Can't add weapon " + inv.getType() + " that has associated weapon descriptor == null!");
983 return;
984 }
985 if (inv.getDescriptor() instanceof WeaponDescriptor) {
986 WeaponDescriptor desc = inv.getDescriptor();
987 all.put(key, inv);
988 if (desc.isMelee()) {
989 allMelee.put(key, inv);
990 if (inv.getAmmo() > 0) {
991 allLoadedMelee.put(key, inv);
992 allLoaded.put(key, inv);
993 }
994 } else {
995 allRanged.put(key, inv);
996 if (inv.getAmmo() > 0) {
997 allLoadedRanged.put(key, inv);
998 allLoaded.put(key, inv);
999 }
1000 }
1001 }
1002 }
1003
1004
1005
1006
1007 public void remove(KEY key) {
1008 all.remove(key);
1009 allLoaded.remove(key);
1010 allMelee.remove(key);
1011 allRanged.remove(key);
1012 allLoadedMelee.remove(key);
1013 allLoadedRanged.remove(key);
1014 }
1015
1016
1017
1018
1019
1020 public void ammoChanged(KEY key) {
1021 if (key == null) return;
1022 Weapon weapon = all.get(key);
1023 if (weapon == null) {
1024
1025 return;
1026 }
1027 if (weapon.getAmmo() > 0) {
1028 if (!allLoaded.containsKey(key)) {
1029
1030 WeaponDescriptor desc = (weapon.getDescriptor());
1031 allLoaded.put(key, weapon);
1032 if (desc.isMelee()) {
1033 allLoadedMelee.put(key, weapon);
1034 } else {
1035 allLoadedRanged.put(key, weapon);
1036 }
1037 }
1038 } else {
1039
1040 if (allLoaded.containsKey(key)) {
1041
1042 allLoaded.remove(key);
1043 allLoadedMelee.remove(key);
1044 allLoadedRanged.remove(key);
1045 }
1046 }
1047 }
1048
1049
1050
1051
1052 public void botKilled() {
1053 all.clear();
1054 allLoaded.clear();
1055 allLoadedMelee.clear();
1056 allLoadedRanged.clear();
1057 allMelee.clear();
1058 allRanged.clear();
1059 }
1060
1061 }
1062
1063 WeaponsByKey<ItemType.Group> weaponsByGroup = new WeaponsByKey<ItemType.Group>();
1064
1065 WeaponsByKey<ItemType> weaponsByItemType = new WeaponsByKey<ItemType>();
1066
1067 WeaponsByKey<UnrealId> weaponsById = new WeaponsByKey<UnrealId>();
1068
1069
1070
1071 private Map<ItemType, UnrealId> weaponTypeToInventoryUnrealId = new HashMap<ItemType, UnrealId>();
1072 private Map<UnrealId, WeaponDescriptor> inventoryUnrealIdToWeaponDescriptor = new HashMap<UnrealId, WeaponDescriptor>();
1073
1074
1075
1076
1077
1078
1079 private class AddInventoryMsgListener implements IWorldEventListener<AddInventoryMsg> {
1080
1081 @Override
1082 public void notify(AddInventoryMsg event) {
1083 if (event == null) return;
1084 if (event.getPickupType() == null) return;
1085 if (event.getPickupType().getCategory() != ItemType.Category.WEAPON) return;
1086
1087
1088
1089
1090 if (event.getPickupType() == ItemType.REDEEMER) {
1091 log.info("REDEEMER!");
1092 }
1093
1094 Weapon weapon = new Weapon(event, ammo.getPriAmmoForWeapon(event.getPickupType()), ammo.getSecAmmoForWeapon(event.getPickupType()));
1095
1096 if (weapon.getDescriptor() == null) {
1097 if (log.isLoggable(Level.SEVERE)) log.severe("AddInventoryMsgListener.notify(): There is no weapon descriptor for " + weapon.getType() + "!!! The newly gained weapon is not added to the Weaponry!");
1098 return;
1099 }
1100
1101
1102 weaponsByGroup.add(event.getPickupType().getGroup(), weapon);
1103 weaponsByItemType.add(event.getPickupType(), weapon);
1104 weaponsById.add(event.getId(), weapon);
1105
1106 weaponTypeToInventoryUnrealId.put(event.getPickupType(), event.getId());
1107 inventoryUnrealIdToWeaponDescriptor.put(event.getId(), (WeaponDescriptor) event.getDescriptor());
1108 }
1109
1110
1111
1112
1113
1114 public AddInventoryMsgListener(IWorldView worldView) {
1115 worldView.addEventListener(AddInventoryMsg.class, this);
1116 }
1117 }
1118
1119 AddInventoryMsgListener addInventoryMsgListener;
1120
1121
1122
1123
1124
1125
1126
1127 private class ItemPickedUpListener implements IWorldEventListener<ItemPickedUp> {
1128
1129 @Override
1130 public void notify(ItemPickedUp event) {
1131 if (event == null) return;
1132 if (event.getType() == null) return;
1133 if (event.getType().getCategory() == Category.AMMO || event.getType().getCategory() == Category.WEAPON) {
1134 ammo.itemPickedUp(event);
1135 Weapon weapon;
1136 if (event.getType().getCategory() == Category.AMMO) {
1137 ItemType weaponType = itemDescriptors.getWeaponForAmmo(event.getType());
1138 if (weaponType == null) {
1139 if (log.isLoggable(Level.WARNING)) log.warning("ItemPickedUpListener.notify(): There is no weapon for the ammo " + event.getType() + ", the weapon probably can not be found in this map.");
1140 return;
1141 }
1142 weapon = weaponsByItemType.all.get(weaponType);
1143 } else {
1144
1145 ItemType weaponType = event.getType();
1146 weapon = weaponsByItemType.all.get(weaponType);
1147 }
1148 if (weapon != null) {
1149 ammo.updateWeaponAmmo(weapon);
1150 }
1151 }
1152 }
1153
1154
1155
1156
1157
1158 public ItemPickedUpListener(IWorldView worldView) {
1159 worldView.addEventListener(ItemPickedUp.class, this);
1160 }
1161 }
1162
1163 ItemPickedUpListener itemPickedUpListener;
1164
1165
1166
1167
1168
1169
1170
1171
1172 private class WeaponUpdateListener implements IWorldEventListener<WeaponUpdate> {
1173
1174 @Override
1175 public void notify(WeaponUpdate event) {
1176 if (event == null) return;
1177 if (event.getInventoryType() == null) return;
1178 WeaponDescriptor weaponDesc = (WeaponDescriptor)itemDescriptors.getDescriptor(event.getInventoryType());
1179 if (weaponDesc == null) {
1180 Weapon weapon = weaponsById.all.get(event.getId());
1181 if (weapon != null) {
1182 weaponDesc = weapon.getDescriptor();
1183 }
1184 }
1185 if (weaponDesc == null) {
1186 if (log.isLoggable(Level.WARNING)) log.warning("WeaponUpdateListener.notify(): There is no weapon descriptor for the weapon for the event: " + event);
1187 return;
1188 }
1189 if (weaponDesc.getPriAmmoItemType() != null) {
1190 ammo.weaponUpdate(weaponDesc.getPriAmmoItemType(), event.getPrimaryAmmo());
1191 }
1192 if (weaponDesc.getSecAmmoItemType() != null && weaponDesc.getSecAmmoItemType() != weaponDesc.getPriAmmoItemType()) {
1193 ammo.weaponUpdate(weaponDesc.getSecAmmoItemType(), event.getSecondaryAmmo());
1194 }
1195
1196 Weapon weapon = weaponsByItemType.all.get(weaponDesc.getPickupType());
1197 if (weapon != null) {
1198 ammo.updateWeaponAmmo(weapon);
1199 }
1200 }
1201
1202
1203
1204
1205
1206 public WeaponUpdateListener(IWorldView worldView) {
1207 worldView.addEventListener(WeaponUpdate.class, this);
1208 }
1209 }
1210
1211 WeaponUpdateListener weaponUpdateListener;
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 private class SelfUpdateListener implements IWorldObjectEventListener<Self, WorldObjectUpdatedEvent<Self>> {
1222
1223 @Override
1224 public void notify(WorldObjectUpdatedEvent<Self> event) {
1225 if (event == null) return;
1226
1227
1228 if (self == null) {
1229 self = event.getObject();
1230 }
1231
1232 Weapon weaponToUpdate = getCurrentWeapon();
1233 if (weaponToUpdate != null) {
1234 WeaponDescriptor weaponDesc = weaponToUpdate.getDescriptor();
1235 if (weaponDesc == null) {
1236 if (log.isLoggable(Level.WARNING)) log.warning("SelfUpdateListener.notify(): There is no weapon descriptor for the weapon " + weaponToUpdate);
1237 return;
1238 }
1239 if (weaponDesc.getPriAmmoItemType() != null) {
1240 ammo.weaponUpdate(weaponDesc.getPriAmmoItemType(), self.getPrimaryAmmo());
1241 }
1242 if (weaponDesc.getSecAmmoItemType() != null && weaponDesc.getSecAmmoItemType() != weaponDesc.getPriAmmoItemType()) {
1243 ammo.weaponUpdate(weaponDesc.getSecAmmoItemType(), self.getSecondaryAmmo());
1244 }
1245 ammo.updateWeaponAmmo(weaponToUpdate);
1246 }
1247 }
1248
1249
1250
1251
1252
1253 public SelfUpdateListener(IWorldView worldView) {
1254 worldView.addObjectListener(Self.class, WorldObjectUpdatedEvent.class, this);
1255 }
1256 }
1257
1258
1259 SelfUpdateListener selfUpdateListener;
1260
1261
1262
1263
1264
1265
1266
1267 private class ThrownListener implements IWorldEventListener<Thrown> {
1268
1269 @Override
1270 public void notify(Thrown event) {
1271 WeaponDescriptor desc = inventoryUnrealIdToWeaponDescriptor.get(event.getId());
1272 if (desc == null) {
1273 if (log.isLoggable(Level.WARNING)) log.warning("ThrownListener.notify(): There is no known weapon descriptor for id " + event.getId() + " inside Weaponary.");
1274 return;
1275 }
1276 ItemType weaponType = desc.getPickupType();
1277 weaponsByGroup.remove(weaponType.getGroup());
1278 weaponsByItemType.remove(weaponType);
1279 }
1280
1281
1282
1283
1284
1285 public ThrownListener(IWorldView worldView) {
1286 worldView.addEventListener(Thrown.class, this);
1287 }
1288 }
1289
1290 ThrownListener thrownListener;
1291
1292
1293
1294
1295
1296
1297
1298 private class BotKilledListener implements IWorldEventListener<BotKilled> {
1299
1300 @Override
1301 public void notify(BotKilled event) {
1302 ammo.botKilled();
1303 weaponsByGroup.botKilled();
1304 weaponsByItemType.botKilled();
1305 weaponsById.botKilled();
1306 weaponTypeToInventoryUnrealId.clear();
1307 inventoryUnrealIdToWeaponDescriptor.clear();
1308 }
1309
1310
1311
1312
1313
1314 public BotKilledListener(IWorldView worldView) {
1315 worldView.addEventListener(BotKilled.class, this);
1316 }
1317
1318 }
1319
1320 BotKilledListener botKilledListener;
1321
1322
1323
1324 private ItemDescriptors itemDescriptors;
1325
1326
1327
1328 private Self self = null;
1329
1330
1331
1332
1333
1334 public Weaponry(UDKBot bot) {
1335 this(bot, new ItemDescriptors(bot));
1336 }
1337
1338
1339
1340
1341
1342
1343
1344 public Weaponry(UDKBot bot, ItemDescriptors itemDescriptors) {
1345 this(bot, itemDescriptors, null);
1346 }
1347
1348
1349
1350
1351
1352
1353
1354
1355 public Weaponry(UDKBot bot, ItemDescriptors descriptors, LogCategory moduleLog) {
1356 super(bot);
1357
1358 this.itemDescriptors = descriptors;
1359
1360 if (this.itemDescriptors == null) {
1361 this.itemDescriptors = new ItemDescriptors(bot, moduleLog);
1362 }
1363
1364
1365 addInventoryMsgListener = new AddInventoryMsgListener(worldView);
1366 itemPickedUpListener = new ItemPickedUpListener(worldView);
1367 weaponUpdateListener = new WeaponUpdateListener(worldView);
1368 selfUpdateListener = new SelfUpdateListener(worldView);
1369 thrownListener = new ThrownListener(worldView);
1370 botKilledListener = new BotKilledListener(worldView);
1371
1372 cleanUp();
1373 }
1374
1375 @Override
1376 protected void cleanUp() {
1377 super.cleanUp();
1378
1379 ammo.botKilled();
1380 weaponsByGroup.botKilled();
1381 weaponsByItemType.botKilled();
1382 weaponsById.botKilled();
1383 weaponTypeToInventoryUnrealId.clear();
1384 inventoryUnrealIdToWeaponDescriptor.clear();
1385 }
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395 public int getMaxAmmo(ItemType ammoType) {
1396 if (ammoType == null) return 0;
1397 WeaponDescriptor weapon = getWeaponDescriptor( getWeaponForAmmo(ammoType) );
1398 if (weapon == null) {
1399 if (log.isLoggable(Level.WARNING)) log.warning("There is no known weapon descriptor for item type " + ammoType + " inside Weaponary.");
1400 return 0;
1401 }
1402 if ( weapon.getPriAmmoItemType() == ammoType ) {
1403 return weapon.getPriMaxAmount();
1404 } else if ( weapon.getSecAmmoItemType() == ammoType ) {
1405 return weapon.getSecMaxAmount();
1406 } else {
1407 return 0;
1408 }
1409 }
1410
1411 }