View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.communication.messages;
2   
3   import java.io.Serializable;
4   import java.util.HashMap;
5   import java.util.Set;
6   
7   import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
8   import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
9   import cz.cuni.amis.utils.maps.HashMapSet;
10  
11  /**
12   * Type of the item.
13   * 
14   * <p>
15   * Note: Items of the same type might have different names in UT engine.
16   * <b>Always use {@link #equals(Object)} to safely compare two ItemTypes.</b>
17   * 
18   * <p>
19   * Use {@link #getCategory()} to obtain basic categorization of items.
20   * 
21   * <p>
22   * Use {@link #getGroup()} to obtain detailed group info of items.
23   * 
24   * @author Juraj 'Loque' Simlovic
25   * @author Jimmy
26   */
27  public class ItemType implements Serializable {
28  	
29  	/**
30  	 * Contains item types that belongs to their categories.
31  	 */
32  	public static final HashMapSet<Category, ItemType> CATEGORIES = new HashMapSet<Category, ItemType>();
33  	
34  	/**
35  	 * List of all item categories. Categories divide items into several basic
36  	 * categories, based on what the item does and what is it intended to do.
37  	 */
38  	public enum Category {
39  		/** Weapons of all sorts. */
40  		WEAPON("Weapon"),
41  		/** Ammunition for weapons of all sorts. */
42  		AMMO("Ammo"),
43  		/** Health packs and other health restorers. */
44  		HEALTH("Health"),
45  		/** Armor packs and other armor restorers. */
46  		ARMOR("Armor"),
47          /** Shield packs and other shield restorers. */
48          SHIELD("Shield"),
49  		/** Adrenaline */
50  		ADRENALINE("Adrenaline"),
51  		/** UDamage, Keys + user defined items */
52  		OTHER("Other"),
53  		/** No category */
54  		NONE("No category");
55  
56  		/* =================================================================== */
57  
58  		/** Human-readable name of the category. */
59  		public final String name;
60  
61  		/* =================================================================== */
62  
63  		/**
64  		 * Constructor.
65  		 * 
66  		 * @param name
67  		 *            Human-readable name of the category.
68  		 */
69  		Category(String name) {
70  			this.name = name;
71  		}
72  		
73  		/**
74  		 * Return all item types of a certain category.
75  		 * @return
76  		 */
77  		public Set<ItemType> getTypes() {
78  			return CATEGORIES.get(this);
79  		}
80  		
81  	}
82  
83  	/* ======================================================================== */
84  
85  
86  	/**
87  	 * Contains item types that belongs to their groups.
88  	 */
89  	public static final HashMapSet<Group, ItemType> GROUPS = new HashMapSet<Group, ItemType>();
90  	
91  	/**
92  	 * List of all item groups. Groups fine down the categories into specific
93  	 * groups, based on what the item belongs to. Also, groups join items from
94  	 * different categories together, if they belong together (e.g. weapon with
95  	 * its ammo).
96  	 */
97  	public enum Group {
98  		/** Translocating weapon and accessory. */
99  		TRANSLOCATOR("Translocator"),
100 		/** ShieldGun weapon and accessory. */
101 		SHIELD_GUN("ShieldGun"),
102 		/** AssaultRifle weapon and accessory. */
103 		ASSAULT_RIFLE("AssaultRifle"),
104 		/** BioRifle weapon and accessory. */
105 		BIO_RIFLE("BioRifle"),
106 		/** ShockRifle weapon and accessory. */
107 		SHOCK_RIFLE("ShockRifle"),
108 		/** LinkGun weapon and accessory. */
109 		LINK_GUN("LinkGun"),
110 		/** Minigun weapon and accessory. */
111 		MINIGUN("Minigun"),
112 		/** FlakCannon weapon and accessory. */
113 		FLAK_CANNON("FlakCannon"),
114 		/** RocketLauncher weapon and accessory. */
115 		ROCKET_LAUNCHER("RocketLauncher"),
116 		/** LightningGun weapon and accessory. */
117 		LIGHTNING_GUN("LightningGun"),
118 		/** SniperRifle weapon and accessory. */
119 		SNIPER_RIFLE("SniperRifle"),
120 		/** IonPainter weapon and accessory. */
121 		ION_PAINTER("IonPainter"),
122 		/** Redeemer weapon and accessory. */
123 		REDEEMER("Redeemer"),
124 		/** SuperShockRifle weapon and accessory. */
125 		SUPER_SHOCK_RIFLE("SuperShockRifle"),
126 		/** OnsMineLayer weapon and accessory. */
127 		ONS_MINE_LAYER("ONS MineLayer"),
128 		/** OnsGrenadeLauncher weapon and accessory. */
129 		ONS_GRENADE_LAUNCHER("ONS GrenadeLauncher"),
130 		/** OnsAvril weapon and accessory. */
131 		ONS_AVRIL("ONS AVRiL"),
132 		/** TargetPainter weapon and accessory. */
133 		ONS_TARGET_PAINTER("TargetPainter"),
134 
135 		/** Classic health pack. */
136 		HEALTH("HealthKit"),
137 		/** Mini health vial. */
138 		MINI_HEALTH("HealthVial"),
139 		/** Big health recharger. */
140 		SUPER_HEALTH("SuperHealth"),
141 
142 		/** Shield pack. */
143 		SMALL_ARMOR("SmallShield"),
144 		/** Shield pack. */
145 		SUPER_ARMOR("SuperShield"),
146 
147 		/** Adrenaline packs and adrenaline restorers. */
148 		ADRENALINE("Adrenaline"),
149 		/** UDamage bonus items. */
150 		UDAMAGE("UDamage"),
151 		/** Keys. */
152 		KEY("Key"),
153 		/** Other items with user-defined group. */
154 		OTHER("Unknown"),
155 		/** No group, used for the prototype None */
156 		NONE("None");
157 
158 		/* =================================================================== */
159 
160 		/** Human-readable name of the group. */
161 		public String name;
162 
163 		/* =================================================================== */
164 
165 		/**
166 		 * Constructor.
167 		 * 
168 		 * @param name
169 		 *            Human-readable name of the group.
170 		 */
171 		Group(String name) {
172 			this.name = name;
173 		}
174 		
175 		public Set<ItemType> getTypes() {
176 			return GROUPS.get(this);
177 		}
178 	}
179 
180 	/* ======================================================================== */
181 
182 	/**
183 	 * Map of all registered ItemType prototypes.
184 	 */
185 	private static HashMap<String, ItemType> protos = new HashMap<String, ItemType>();
186 
187 	/* ======================================================================== */
188 
189 	/** Translocator. */
190 	public static final ItemType TRANSLOCATOR = MakePrototype(Category.WEAPON,
191 			Group.TRANSLOCATOR, new String[] { "XWeapons.TransPickup", "XWeapons.Transpickup", "XWeapons.Translauncher" });
192 
193 	/** ShieldGun weapon. */
194 	public static final ItemType SHIELD_GUN = MakePrototype(Category.WEAPON,
195 			Group.SHIELD_GUN, new String[] { "XWeapons.ShieldGunPickup" });
196 	
197 	/** ShieldGun ammo - sent when the bot is spawned. */
198 	public static final ItemType SHIELD_GUN_AMMO = MakePrototype(Category.AMMO,
199 			Group.SHIELD_GUN, new String[] { "XWeapons.ShieldAmmoPickup", "XWeapons.ShieldAmmo" }
200 			);
201 
202 	/** AssaultRifle weapon. */
203 	public static final ItemType ASSAULT_RIFLE = MakePrototype(Category.WEAPON,
204 			Group.ASSAULT_RIFLE, new String[] { "XWeapons.AssaultRiflePickup" });
205 	/** AssaultRifle ammo. */
206 	public static final ItemType ASSAULT_RIFLE_AMMO = MakePrototype(
207 			Category.AMMO, Group.ASSAULT_RIFLE,
208 			new String[] { "XWeapons.AssaultAmmoPickup", "XWeapons.AssaultAmmo" });
209 	
210 	/** AssaultRifle secondary ammo. */
211 	public static final ItemType ASSAULT_RIFLE_GRENADE = MakePrototype(
212 			Category.AMMO, Group.ASSAULT_RIFLE,
213 			new String[] { "XWeapons.GrenadeAmmoPickup", "XWeapons.GrenadeAmmo" }
214 			);
215 
216 	/** BioRifle weapon. */
217 	public static final ItemType BIO_RIFLE = MakePrototype(Category.WEAPON,
218 			Group.BIO_RIFLE, new String[] { "XWeapons.BioRiflePickup",
219 					"UTClassic.ClassicBioRiflePickup" });
220 	/** BioRifle ammo. */
221 	public static final ItemType BIO_RIFLE_AMMO = MakePrototype(Category.AMMO,
222 			Group.BIO_RIFLE, new String[] { "XWeapons.BioAmmoPickup", "XWeapons.BioAmmo" });
223 
224 	/** ShockRifle weapon. */
225 	public static final ItemType SHOCK_RIFLE = MakePrototype(Category.WEAPON,
226 			Group.SHOCK_RIFLE, new String[] { "XWeapons.ShockRiflePickup",
227 					"UTClassic.ClassicShockRiflePickup" });
228 	/** ShockRifle ammo. */
229 	public static final ItemType SHOCK_RIFLE_AMMO = MakePrototype(
230 			Category.AMMO, Group.SHOCK_RIFLE,
231 			new String[] { "XWeapons.ShockAmmoPickup", "XWeapons.ShockAmmo" });
232 
233 	/** LinkGun weapon. */
234 	public static final ItemType LINK_GUN = MakePrototype(Category.WEAPON,
235 			Group.LINK_GUN, new String[] { "XWeapons.LinkGunPickup" });
236 	/** LinkGun ammo. */
237 	public static final ItemType LINK_GUN_AMMO = MakePrototype(Category.AMMO,
238 			Group.LINK_GUN, new String[] { "XWeapons.LinkAmmoPickup", "XWeapons.LinkAmmo" });
239 
240 	/** Minigun weapon. */
241 	public static final ItemType MINIGUN = MakePrototype(Category.WEAPON,
242 			Group.MINIGUN, new String[] { "XWeapons.MinigunPickup",
243 					"UTClassic.ClassicMinigunPickup" });
244 	/** Minigun ammo. */
245 	public static final ItemType MINIGUN_AMMO = MakePrototype(Category.AMMO,
246 			Group.MINIGUN, new String[] { "XWeapons.MinigunAmmoPickup", "XWeapons.MinigunAmmo" });
247 
248 	/** FlakCannon weapon. */
249 	public static final ItemType FLAK_CANNON = MakePrototype(Category.WEAPON,
250 			Group.FLAK_CANNON, new String[] { "XWeapons.FlakCannonPickup",
251 					"UTClassic.ClassicFlakCannonPickup" });
252 	/** FlakCannon ammo. */
253 	public static final ItemType FLAK_CANNON_AMMO = MakePrototype(
254 			Category.AMMO, Group.FLAK_CANNON,
255 			new String[] { "XWeapons.FlakAmmoPickup", "XWeapons.FlakAmmo" });
256 
257 	/** RocketLauncher weapon. */
258 	public static final ItemType ROCKET_LAUNCHER = MakePrototype(
259 			Category.WEAPON, Group.ROCKET_LAUNCHER, new String[] {
260 					"XWeapons.RocketLauncherPickup",
261 					"UTClassic.ClassicRocketLauncherPickup" });
262 	/** RocketLauncher ammo. */
263 	public static final ItemType ROCKET_LAUNCHER_AMMO = MakePrototype(
264 			Category.AMMO, Group.ROCKET_LAUNCHER,
265 			new String[] { "XWeapons.RocketAmmoPickup", "XWeapons.RocketAmmo" });
266 
267 	/** LightningGun weapon (modern sniper weapon). */
268 	public static final ItemType LIGHTNING_GUN = MakePrototype(Category.WEAPON,
269 			Group.LIGHTNING_GUN, new String[] { "XWeapons.SniperRiflePickup" });
270 	
271 	/** LightningGun ammo. */
272 	public static final ItemType LIGHTNING_GUN_AMMO = MakePrototype(
273 			Category.AMMO, Group.LIGHTNING_GUN,
274 			new String[] { "XWeapons.SniperAmmoPickup", "XWeapons.SniperAmmo" });
275 
276 	/** SniperRifle weapon (classic sniper weapon). */
277 	public static final ItemType SNIPER_RIFLE = MakePrototype(Category.WEAPON,
278 			Group.SNIPER_RIFLE,
279 			new String[] { "UTClassic.ClassicSniperRiflePickup" });
280 	/** SniperRifle ammo. */
281 	public static final ItemType SNIPER_RIFLE_AMMO = MakePrototype(
282 			Category.AMMO, Group.SNIPER_RIFLE,
283 			new String[] { "UTClassic.ClassicSniperAmmoPickup", "UTClassic.ClassicSniperAmmo" });
284 
285 	/** Redeemer weapon. */
286 	public static final ItemType REDEEMER = MakePrototype(Category.WEAPON,
287 			Group.REDEEMER, new String[] { "XWeapons.RedeemerPickup" });
288 
289 	/** SuperShockRifle weapon (instagib weapon). */
290 	public static final ItemType SUPER_SHOCK_RIFLE = MakePrototype(
291 			Category.WEAPON, Group.SUPER_SHOCK_RIFLE,
292 			new String[] { "XWeapons.SuperShockRiflePickup" });
293 
294 	/** IonPainter weapon. */
295 	public static final ItemType ION_PAINTER = MakePrototype(Category.WEAPON,
296 			Group.ION_PAINTER, new String[] { "XWeapons.PainterPickup" });
297 
298 	/** MineLayer Onslaught weapon. */
299 	public static final ItemType ONS_MINE_LAYER = MakePrototype(
300 			Category.WEAPON, Group.ONS_MINE_LAYER,
301 			new String[] { "Onslaught.ONSMineLayerPickup" });
302 	/** MineLayer ammo. */
303 	public static final ItemType ONS_MINE_LAYER_AMMO = MakePrototype(
304 			Category.AMMO, Group.ONS_MINE_LAYER,
305 			new String[] { "Onslaught.ONSMineAmmoPickup", "Onslaught.ONSMineAmmo" });
306 
307 	/** GrenadeLauncher Onslaught weapon. */
308 	public static final ItemType ONS_GRENADE_LAUNCHER = MakePrototype(
309 			Category.WEAPON, Group.ONS_GRENADE_LAUNCHER,
310 			new String[] { "Onslaught.ONSGrenadePickup" });
311 	/** GrenadeLauncher ammo. */
312 	public static final ItemType ONS_GRENADE_LAUNCHER_AMMO = MakePrototype(
313 			Category.AMMO, Group.ONS_GRENADE_LAUNCHER,
314 			new String[] { "Onslaught.ONSGrenadeAmmoPickup" });
315 
316 	/** AVRiL Onslaught weapon. */
317 	public static final ItemType ONS_AVRIL = MakePrototype(Category.WEAPON,
318 			Group.ONS_AVRIL, new String[] { "Onslaught.ONSAVRiLPickup" });
319 	/** AVRiL ammo. */
320 	public static final ItemType ONS_AVRIL_AMMO = MakePrototype(Category.AMMO,
321 			Group.ONS_AVRIL, new String[] { "Onslaught.ONSAVRiLAmmoPickup" });
322 
323 	/** TargetPainter Onslaught weapon. */
324 	public static final ItemType ONS_TARGET_PAINTER = MakePrototype(
325 			Category.WEAPON, Group.ONS_TARGET_PAINTER,
326 			new String[] { "OnslaughtFull.ONSPainterPickup" });
327 
328 	/** Health kit. */
329 	public static final ItemType HEALTH_PACK = MakePrototype(Category.HEALTH,
330 			Group.HEALTH, new String[] { "XPickups.HealthPack",
331 					"XPickups.TournamentHealth" });
332 	/** Health vial. */
333 	public static final ItemType MINI_HEALTH_PACK = MakePrototype(
334 			Category.HEALTH, Group.MINI_HEALTH,
335 			new String[] { "XPickups.MiniHealthPack" });
336 	/** SuperHealth charger. */
337 	public static final ItemType SUPER_HEALTH_PACK = MakePrototype(
338 			Category.HEALTH, Group.SUPER_HEALTH,
339 			new String[] { "XPickups.SuperHealthPack" });
340 
341 	/** SmallShield. */
342 	public static final ItemType SHIELD_PACK = MakePrototype(Category.ARMOR,
343 			Group.SMALL_ARMOR, new String[] { "XPickups.ShieldPack",
344 					"XPickups.ShieldPickup" });
345 	/** SuperShield. */
346 	public static final ItemType SUPER_SHIELD_PACK = MakePrototype(
347 			Category.ARMOR, Group.SUPER_ARMOR,
348 			new String[] { "XPickups.SuperShieldPack" });
349 
350 	/** UDamage bonus (damage multiplier). */
351 	public static final ItemType U_DAMAGE_PACK = MakePrototype(
352 			Category.OTHER, Group.UDAMAGE, new String[] {
353 					"XPickups.UDamagePack", "XGame.UDamageReward" });
354 
355 	/** Adrenaline capsule. */
356 	public static final ItemType ADRENALINE_PACK = MakePrototype(
357 			Category.ADRENALINE, Group.ADRENALINE,
358 			new String[] { "XPickups.AdrenalinePickup" });
359 
360 	/** Key. */
361 	public static final ItemType KEY = MakePrototype(Category.OTHER,
362 			Group.KEY, new String[] { "UnrealGame.KeyPickup" });
363 	
364 	/** No ItemType */
365 	public static final ItemType NONE = MakePrototype(Category.OTHER, Group.NONE,
366 			new String[] { "None", "NONE", "none" });
367 	
368 	/* ======================================================================== */
369 	
370 	////
371 	// STATIC METHODS
372 	////
373 	
374 	/**
375 	 * Attempts to recognize the weapon you are currently holding...
376 	 * <p><p>
377 	 * See {@link Self#getWeapon()}.
378 	 * <p><p>
379 	 * May return null == weapon was not recognized. ALWAYS CHECK!
380 	 * 
381 	 * @return 
382 	 */
383 	public static ItemType getWeapon(UnrealId id) {
384 		if (id == null) return null;
385 		String str = id.getStringId();
386 		if (str.contains(".")) str = str.substring(str.lastIndexOf(".")+1);
387 		str = str.toLowerCase();
388 		if (str.equals("assaultrifle")) return ItemType.ASSAULT_RIFLE;
389 		if (str.equals("shieldgun")) return ItemType.SHIELD_GUN;
390 		if (str.equals("flakcannon")) return ItemType.FLAK_CANNON;
391 		if (str.equals("biorifle")) return ItemType.BIO_RIFLE;
392 		if (str.equals("shockrifle")) return ItemType.SHOCK_RIFLE;
393 		if (str.equals("linkgun")) return ItemType.LINK_GUN;
394 		if (str.equals("sniperrifle")) return ItemType.SNIPER_RIFLE;
395 		if (str.equals("rocketlauncher")) return ItemType.ROCKET_LAUNCHER;
396 		if (str.equals("minigun")) return ItemType.MINIGUN;
397 		if (str.equals("lightinggun")) return ItemType.LIGHTNING_GUN;
398 		if (str.equals("translocator")) return ItemType.TRANSLOCATOR;
399 		if (str.equals("translauncher")) return ItemType.TRANSLOCATOR;
400 		if (str.equals("redeemer")) return ItemType.REDEEMER;
401 		if (str.equals("painter")) return ItemType.ION_PAINTER;
402 		return null;
403 	}
404 	
405 	/* ======================================================================== */
406 
407 	/**
408 	 * Name of the item in UT engine.
409 	 * 
410 	 * <p>
411 	 * Note: Items of the same type might have different names in UT engine. Use
412 	 * {@link #equals(Object)} to safely compare two ItemTypes. This name is
413 	 * informative only.
414 	 */
415 	private String name;
416 	
417 	@Override
418 	public String toString() {
419 		return "ItemType[name = " + name + ", category = " + category + ", group = " + group + "]";
420 	}
421 
422 	/* ======================================================================== */
423 
424 	/**
425 	 * Category of the type.
426 	 */
427 	private Category category;
428 
429 	/**
430 	 * Group of the type.
431 	 */
432 	private Group group;
433 
434 	/**
435 	 * Retreives category of the item type.
436 	 * 
437 	 * @return Category of the item type.
438 	 */
439 	public Category getCategory() {
440 		// do we have a category already?
441 		return (category == null) ? (category = getProto().category) : category;
442 	}
443 
444 	/**
445 	 * Retreives group of the item type.
446 	 * 
447 	 * @return Group of the item type.
448 	 */
449 	public Group getGroup() {
450 		// do we have a group already?
451 		return (group == null) ? (group = getProto().group) : group;
452 	}
453 
454 	/* ======================================================================== */
455 
456 	/**
457 	 * Prototype reference.
458 	 */
459 	private ItemType proto;
460 
461 	/**
462 	 * Retreives (and caches) ItemType prototype.
463 	 * 
464 	 * @return ItemType prototype.
465 	 */
466 	private ItemType getProto() {
467 		// do we have a prototype already?
468 		if (proto != null) return proto;
469 		synchronized(protos) {
470 			return proto = protos.get(name);			
471 		}
472 	}
473 
474 	/* ======================================================================== */
475 
476 	/**
477 	 * Indicates whether some other ItemType is "equal to" this one.
478 	 * 
479 	 * @param obj
480 	 *            Object to be compared with.
481 	 * @return True, if the objects are equal.
482 	 */
483 	@Override
484 	public boolean equals(Object obj) {
485 		// the same object?
486 		if (this == obj)
487 			return true;
488 
489 		// the same type?
490 		if (obj instanceof ItemType) {
491 			// the same prototype?
492 			if (getProto() == ((ItemType) obj).getProto())
493 				return true;
494 		}
495 
496 		return false;
497 	}
498 
499 	/**
500 	 * Returns a hash code value for the object.
501 	 * 
502 	 * @return A hash code value for this object.
503 	 */
504 	@Override
505 	public int hashCode() {
506 		// provide hash of the string name
507 		return getProto().name.hashCode();
508 	}
509 
510 	/* ======================================================================== */
511 
512 	/**
513 	 * Public constructor - creates ItemType of the EXTRA category and Group OTHER.
514 	 * 
515 	 * @param name
516 	 *            Type name from GB engine.
517 	 */
518 	public ItemType(String name) {
519 		this.name = name;
520 		this.category = Category.OTHER;
521 		this.group = Group.OTHER;
522 		this.proto = this;
523 	}
524 
525 	/**
526 	 * Prototypes constructor.
527 	 */
528 	private ItemType(String name, Category category, Group group) {
529 		this.name = name;
530 		this.category = category;
531 		this.group = group;
532 		this.proto = this;
533 	}
534 
535 	/* ======================================================================== */
536 
537 	/**
538 	 * Proto-constructor.
539 	 * 
540 	 * @param category
541 	 *            Category of the item.
542 	 * @param group
543 	 *            Group of the item.
544 	 * @param utNames
545 	 *            Names of the item in UT engine.
546 	 * @return Prototype of known ItemType.
547 	 */
548 	public static ItemType MakePrototype(Category category,
549 			Group group, String[] utNames) {
550 		ItemType type;
551 		synchronized(protos) {
552 			// create new itemtype prototype
553 			type = new ItemType(utNames[0], category, group);
554 			// register the itemtype prototype
555 			for (String utName : utNames)
556 				protos.put(utName, type);
557 			// C'est la vie..
558 			if (category != null) {
559 				CATEGORIES.get(category).add(type);
560 			}
561 			if (group != null) {
562 				GROUPS.get(group).add(type);
563 			}
564 		}
565 		return type;
566 	}
567 
568 	/**
569 	 * Retrieves an ItemType for the specified item type name.
570 	 * @param utName e.g. Item.getType()
571 	 * @return
572 	 */
573 	public static ItemType getItemType(String utName) {
574 		ItemType type;
575 		synchronized(protos) {
576 			type = protos.get(utName);
577 			if (type != null) return type;
578 			
579 			type = new ItemType(utName);
580 			protos.put(utName, type);
581 		}
582 		return type;
583 	}
584 
585 	public String getName() {
586 		return name;
587 	}
588 
589 }