View Javadoc

1   package cz.cuni.amis.pogamut.udk.communication.messages;
2   
3   import java.io.Serializable;
4   import java.util.HashMap;
5   import java.util.Set;
6   
7   import cz.cuni.amis.utils.maps.HashMapSet;
8   
9   /**
10   * Type of the item.
11   * 
12   * <p>
13   * Note: Items of the same type might have different names in UT engine.
14   * <b>Always use {@link #equals(Object)} to safely compare two ItemTypes.</b>
15   * 
16   * <p>
17   * Use {@link #getCategory()} to obtain basic categorization of items.
18   * 
19   * <p>
20   * Use {@link #getGroup()} to obtain detailed group info of items.
21   * 
22   * @author Juraj 'Loque' Simlovic
23   * @author Jimmy
24   * @author Radek 'Black_Hand' Pibil
25   */
26  public class ItemType implements Serializable {
27  	
28  	/**
29  	 * Contains item types that belongs to their categories.
30  	 */
31  	public static final HashMapSet<Category, ItemType> CATEGORIES = new HashMapSet<Category, ItemType>();
32  	
33  	/**
34  	 * List of all item categories. Categories divide items into several basic
35  	 * categories, based on what the item does and what is it intended to do.
36  	 */
37  	public enum Category {
38  		/** Weapons of all sorts. */
39  		WEAPON("Weapon"),
40  		/** Ammunition for weapons of all sorts. */
41  		AMMO("Ammo"),
42  		/** Health packs and other health restorers. */
43  		HEALTH("Health"),
44  		/** Armor packs and other armor restorers. */
45  		ARMOR("Armor"),
46  		/** UDamage, Keys + user defined items */
47  		OTHER("Other");
48  
49  		/* =================================================================== */
50  
51  		/** Human-readable name of the category. */
52  		public String name;
53  
54  		/* =================================================================== */
55  
56  		/**
57  		 * Constructor.
58  		 * 
59  		 * @param name
60  		 *            Human-readable name of the category.
61  		 */
62  		Category(String name) {
63  			this.name = name;
64  		}
65  		
66  		/**
67  		 * Return all item types of a certain category.
68  		 * @return
69  		 */
70  		public Set<ItemType> getTypes() {
71  			return CATEGORIES.get(this);
72  		}
73  		
74  	}
75  
76  	/* ======================================================================== */
77  
78  
79  	/**
80  	 * Contains item types that belongs to their groups.
81  	 */
82  	public static final HashMapSet<Group, ItemType> GROUPS = new HashMapSet<Group, ItemType>();
83  	
84  	/**
85  	 * List of all item groups. Groups fine down the categories into specific
86  	 * groups, based on what the item belongs to. Also, groups join items from
87  	 * different categories together, if they belong together (e.g. weapon with
88  	 * its ammo).
89  	 */
90  	public enum Group {
91                  /** UT3 specific item groups */
92  
93                  /** Avril weapon and accessory */
94                  AVRIL("Avril"),
95                  /** BioRifle weapon and accessory */
96                  BIORIFLE("BioRifle"),
97                  /** Enforcer weapon and accesory */
98                  ENFORCER("Enforcer"),
99                  /** FlakCannon weapon and accesory */
100                 FLAK_CANNON("FlakCannon"),
101                 /** ImpactHammer weapon and accesory */
102                 IMPACT_HAMMER("ImpactHammer"),
103                 /** IstagibRifle weapon and accesory */
104                 INSTAGIBRIFLE("InstagibRifle"),
105                 /** Redeemer weapon and accesory */
106                 REDEEMER("Redeemer"),
107                 /** SnierRifle weapon and accessory */
108                 SNIPERRIFLE("SniperRifle"),
109                 /** Stinger weapon and accessory */
110                 STINGER("Stinger"),
111                 /** Translocator weapon and accessory */
112                 TRANSLOCATOR("Translocator"),
113 
114                 /** UDK and UT3 item groups */
115 
116 		/** LinkGun weapon and accessory. */
117 		LINK_GUN("LinkGun"),
118 		/** ShockRifle weapon and accessory. */
119 		SHOCK_RIFLE("ShockRifle"),		
120 		/** RocketLauncher weapon and accessory. */
121 		ROCKET_LAUNCHER("RocketLauncher"),
122 		/** Physics gun */
123 		PHYSICS_GUN("PhysicsGun"),
124 
125 		/** Classic health pack. */
126 		HEALTH("HealthKit"),
127 		/** Mini health vial. */
128 		MINI_HEALTH("HealthVial"),
129 
130 		/** Thigh pad. */
131 		THIGH_PAD("Thighpad"),
132 		/** Base armor. */
133 		BASE_ARMOR("BaseArmor"),
134 		/** ShieldBelt. */
135 		SHIELD_BELT("ShieldBelt"),
136 
137 		/** Jump boots. */
138 		JUMP_BOOTS("JumpBoots"),
139 		/** UDamage bonus items. */
140 		UDAMAGE("UDamage"),
141 		/** Other items with user-defined group. */
142 		OTHER("Unknown"),
143 		/** No group, used for the prototype None */
144 		NONE("None");
145 
146 		/* =================================================================== */
147 
148 		/** Human-readable name of the group. */
149 		public String name;
150 
151 		/* =================================================================== */
152 
153 		/**
154 		 * Constructor.
155 		 * 
156 		 * @param name
157 		 *            Human-readable name of the group.
158 		 */
159 		Group(String name) {
160 			this.name = name;
161 		}
162 		
163 		public Set<ItemType> getTypes() {
164 			return GROUPS.get(this);
165 		}
166 	}
167 
168 	/* ======================================================================== */
169 
170 	/**
171 	 * Map of all registered ItemType prototypes.
172 	 */
173 	private static HashMap<String, ItemType> protos = new HashMap<String, ItemType>();
174 
175 	/* ======================================================================== */
176 
177         /** UT3 specific items */
178 
179         /** Avril weapon */
180         public static final ItemType AVRIL = MakePrototype(Category.WEAPON,
181                 Group.AVRIL,new String[] { "Avril.WeaponPickup",
182                                               "Avril" });
183          /** Avril ammo */
184         public static final ItemType AVRIL_AMMO = MakePrototype(Category.AMMO,
185                 Group.AVRIL,new String[] { "AvrilAmmo.AmmoPickup",
186                                               "AvrilAmmo" });
187         /** Biorifle weapon */
188         public static final ItemType BIORIFLE = MakePrototype(Category.WEAPON,
189                 Group.BIORIFLE,new String[] { "BioRifle.WeaponPickup",
190                                               "BioRifle" });
191          /** Biorifle ammo */
192         public static final ItemType BIORIFLE_AMMO = MakePrototype(Category.AMMO,
193                 Group.BIORIFLE,new String[] { "BioRifleAmmo.AmmoPickup",
194                                               "BioRifleAmmo" });
195         /** Enforcer weapon */
196         public static final ItemType ENFORCER = MakePrototype(Category.WEAPON,
197                 Group.ENFORCER,new String[] { "Enforcer.WeaponPickup",
198                                               "Enforcer" });
199          /** Enforcer ammo */
200         public static final ItemType ENFORCER_AMMO = MakePrototype(Category.AMMO,
201                 Group.ENFORCER,new String[] { "EnforcerAmmo.AmmoPickup", 
202                                               "EnforcerAmmo" });
203         /** FlakCannon weapon */
204         public static final ItemType FLAK_CANNON = MakePrototype(Category.WEAPON,
205                 Group.FLAK_CANNON,new String[] { "FlakCannon.WeaponPickup",
206                                               "FlakCannon" });
207          /** FlakCannon ammo */
208         public static final ItemType FLAK_CANNON_AMMO = MakePrototype(Category.AMMO,
209                 Group.FLAK_CANNON,new String[] { "FlakCannonAmmo.AmmoPickup",
210                                               "FlakCannonAmmo" });
211         /** ImpactHammer weapon */
212         public static final ItemType IMPACT_HAMMER = MakePrototype(Category.WEAPON,
213                 Group.IMPACT_HAMMER,new String[] { "ImpactHammer.WeaponPickup",
214                                                    "ImpactHammer" });
215          /** InstagibRifle weapon */
216         public static final ItemType INSTAGIBRIFLE = MakePrototype(Category.WEAPON,
217                 Group.INSTAGIBRIFLE,new String[] { "InstagibRifle.WeaponPickup",
218                                               "InstagibRifle" });
219          /** InstagibRifle ammo */
220         public static final ItemType INSTAGIBRIFLE_AMMO = MakePrototype(Category.AMMO,
221                 Group.INSTAGIBRIFLE,new String[] { "InstagibRifleAmmo.AmmoPickup",
222                                               "InstagibRifleAmmo" });
223         /** Redeemer weapon */
224         public static final ItemType REDEEMER = MakePrototype(Category.WEAPON,
225                 Group.REDEEMER,new String[] { "Redeemer.WeaponPickup",
226                                               "Redeemer" });
227          /** Redeemer ammo */
228         public static final ItemType REDEEMER_AMMO = MakePrototype(Category.AMMO,
229                 Group.REDEEMER,new String[] { "RedeemerAmmo.AmmoPickup",
230                                               "RedemerAmmo" });
231         /** SniperRifle weapon */
232         public static final ItemType SNIPERRIFLE = MakePrototype(Category.WEAPON,
233                 Group.SNIPERRIFLE,new String[] { "SniperRifle.WeaponPickup",
234                                               "SniperRifle" });
235          /** SniperRifle ammo */
236         public static final ItemType SNIPERRIFLE_AMMO = MakePrototype(Category.AMMO,
237                 Group.SNIPERRIFLE,new String[] { "SniperRifleAmmo.AmmoPickup",
238                                               "SniperRifleAmmo" });
239         /** Stinger weapon */
240         public static final ItemType STINGER = MakePrototype(Category.WEAPON,
241                 Group.STINGER,new String[] { "Stinger.WeaponPickup",
242                                               "Stinger" });
243          /** Stinger ammo */
244         public static final ItemType STINGER_AMMO = MakePrototype(Category.AMMO,
245                 Group.STINGER,new String[] { "StingerAmmo.AmmoPickup",
246                                               "StingerAmmo" });
247         /** Translocator weapon */
248         public static final ItemType TRANSLOCATOR = MakePrototype(Category.WEAPON,
249                 Group.TRANSLOCATOR,new String[] { "Translocator.WeaponPickup",
250                                               "Translocator" });
251         /** UDK and UT3 items */
252 
253 	/** ShockRifle weapon. */
254 	public static final ItemType SHOCK_RIFLE = MakePrototype(Category.WEAPON,
255 			Group.SHOCK_RIFLE, new String[] { "ShockRifle.WeaponPickup",
256                                                           "ShockRifle" });
257 	/** ShockRifle ammo. */
258 	public static final ItemType SHOCK_RIFLE_AMMO = MakePrototype(
259 			Category.AMMO, Group.SHOCK_RIFLE,
260 			new String[] { "ShockRifleAmmo.AmmoPickup",
261                                        "ShockRifleAmmo" });
262 
263 	/** LinkGun weapon. */
264 	public static final ItemType LINK_GUN = MakePrototype(Category.WEAPON,
265 			Group.LINK_GUN, new String[] { "LinkGun.WeaponPickup",
266                                                        "LinkGun" });
267 	/** LinkGun ammo. */
268 	public static final ItemType LINK_GUN_AMMO = MakePrototype(Category.AMMO,
269 			Group.LINK_GUN, new String[] { "LinkGunAmmo.AmmoPickup",
270                                                        "LinkGunAmmo" });
271 
272 	/** RocketLauncher weapon. */
273 	public static final ItemType ROCKET_LAUNCHER = MakePrototype(
274 			Category.WEAPON, Group.ROCKET_LAUNCHER, new String[] {
275 					"RocketLauncher.WeaponPickup",
276 					"RocketLauncher_Content.WeaponPickup",
277                                         "RocketLauncher" });
278 	/** RocketLauncher ammo. */
279 	public static final ItemType ROCKET_LAUNCHER_AMMO = MakePrototype(
280 			Category.AMMO, Group.ROCKET_LAUNCHER,
281 			new String[] { "RocketLauncherAmmo.AmmoPickup",
282 					"RocketLauncher_ContentAmmo.AmmoPickup",
283                                         "RocketLauncherAmmo" });
284 
285 	/** Health pack. */
286 	public static final ItemType HEALTH_PACK = MakePrototype(Category.HEALTH,
287 			Group.HEALTH, new String[] { "HealthPack.HealthPickup",
288                                                      "HealthPack" });
289 	/** Health vial. */
290 	public static final ItemType HEALTH_VIAL = MakePrototype(
291 			Category.HEALTH, Group.MINI_HEALTH,
292 			new String[] { "HealthVial.HealthPickup",
293                                        "HealthVial" });
294 
295 	/** Thigh pad. */
296 	public static final ItemType THIGH_PAD = MakePrototype(Category.ARMOR,
297 			Group.THIGH_PAD, new String[] { "Thighpad.ArmorPickup",
298                                                         "Thighpad" });
299 	/** Base armor. */
300 	public static final ItemType BASE_ARMOR = MakePrototype(
301 			Category.ARMOR, Group.BASE_ARMOR,
302 			new String[] { "BaseArmor.ArmorPickup",
303                                        "BaseArmor" });
304 	/** Shield belt. */
305 	public static final ItemType SHIELD_BELT = MakePrototype(
306 			Category.ARMOR, Group.SHIELD_BELT,
307 			new String[] { "ShieldBelt.ArmorPickup",
308                                        "ShieldBelt" });
309 
310 	/** UDamage bonus (damage multiplier). */
311 	public static final ItemType UDAMAGE = MakePrototype(
312 			Category.OTHER, Group.UDAMAGE, new String[] {
313 					"UDamage.Pickup" });
314 	/** UDamage bonus (damage multiplier). */
315 	public static final ItemType JUMP_BOOTS = MakePrototype(
316 			Category.OTHER, Group.JUMP_BOOTS, new String[] {
317 					"JumpBoots.Pickup",
318                                         "JumpBoots" });
319 	
320 	/** Weapons locker */
321 	public static final ItemType WEAPON_LOCKER = MakePrototype(
322 			Category.OTHER, Group.OTHER, new String[] {
323 					"WeaponLocker.LockerPickup",
324                                         "WeaponLocker" });
325 	
326 	/** No ItemType */
327 	public static final ItemType NONE = MakePrototype(Category.OTHER, Group.NONE,
328 			new String[] { "None", "NONE", "none" });
329 	
330 	/* ======================================================================== */
331 
332 	/**
333 	 * Name of the item in UT engine.
334 	 * 
335 	 * <p>
336 	 * Note: Items of the same type might have different names in UT engine. Use
337 	 * {@link #equals(Object)} to safely compare two ItemTypes. This name is
338 	 * informative only.
339 	 */
340 	private String name;
341 	
342 	public String toString() {
343 		return "ItemType[name = " + name + ", category = " + category + ", group = " + group + "]";
344 	}
345 
346 	/* ======================================================================== */
347 
348 	/**
349 	 * Category of the type.
350 	 */
351 	private Category category;
352 
353 	/**
354 	 * Group of the type.
355 	 */
356 	private Group group;
357 
358 	/**
359 	 * Retreives category of the item type.
360 	 * 
361 	 * @return Category of the item type.
362 	 */
363 	public Category getCategory() {
364 		// do we have a category already?
365 		return (category == null) ? (category = getProto().category) : category;
366 	}
367 
368 	/**
369 	 * Retreives group of the item type.
370 	 * 
371 	 * @return Group of the item type.
372 	 */
373 	public Group getGroup() {
374 		// do we have a group already?
375 		return (group == null) ? (group = getProto().group) : group;
376 	}
377 
378 	/* ======================================================================== */
379 
380 	/**
381 	 * Prototype reference.
382 	 */
383 	private ItemType proto;
384 
385 	/**
386 	 * Retreives (and caches) ItemType prototype.
387 	 * 
388 	 * @return ItemType prototype.
389 	 */
390 	private ItemType getProto() {
391 		// do we have a prototype already?
392 		if (proto != null) return proto;
393 		synchronized(protos) {
394 			return proto = protos.get(name);			
395 		}
396 	}
397 
398 	/* ======================================================================== */
399 
400 	/**
401 	 * Indicates whether some other ItemType is "equal to" this one.
402 	 * 
403 	 * @param obj
404 	 *            Object to be compared with.
405 	 * @return True, if the objects are equal.
406 	 */
407 	@Override
408 	public boolean equals(Object obj) {
409 		// the same object?
410 		if (this == obj)
411 			return true;
412 
413 		// the same type?
414 		if (obj instanceof ItemType) {
415 			// the same prototype?
416 			if (getProto() == ((ItemType) obj).getProto())
417 				return true;
418 		}
419 
420 		return false;
421 	}
422 
423 	/**
424 	 * Returns a hash code value for the object.
425 	 * 
426 	 * @return A hash code value for this object.
427 	 */
428 	@Override
429 	public int hashCode() {
430 		// provide hash of the string name
431 		return getProto().name.hashCode();
432 	}
433 
434 	/* ======================================================================== */
435 
436 	/**
437 	 * Public constructor - creates ItemType of the EXTRA category and Group OTHER.
438 	 * 
439 	 * @param name
440 	 *            Type name from GB engine.
441 	 */
442 	public ItemType(String name) {
443 		this.name = name;
444 		this.category = Category.OTHER;
445 		this.group = Group.OTHER;
446 		this.proto = this;
447 	}
448 
449 	/**
450 	 * Prototypes constructor.
451 	 */
452 	private ItemType(String name, Category category, Group group) {
453 		this.name = name;
454 		this.category = category;
455 		this.group = group;
456 		this.proto = this;
457 	}
458 
459 	/* ======================================================================== */
460 
461 	/**
462 	 * Proto-constructor.
463 	 * 
464 	 * @param category
465 	 *            Category of the item.
466 	 * @param group
467 	 *            Group of the item.
468 	 * @param utNames
469 	 *            Names of the item in UT engine.
470 	 * @return Prototype of known ItemType.
471 	 */
472 	public static ItemType MakePrototype(Category category,
473 			Group group, String[] utNames) {
474 		ItemType type;
475 		synchronized(protos) {
476 			// create new itemtype prototype
477 			type = new ItemType(utNames[0], category, group);
478 			// register the itemtype prototype
479 			for (String utName : utNames)
480 				protos.put(utName, type);
481 			// C'est la vie..
482 			if (category != null) {
483 				CATEGORIES.get(category).add(type);
484 			}
485 			if (group != null) {
486 				GROUPS.get(group).add(type);
487 			}
488 		}
489 		return type;
490 	}
491 
492 	/**
493 	 * Retrieves an ItemType for the specified item type name.
494 	 * @param utName e.g. Item.getType()
495 	 * @return
496 	 */
497 	public static ItemType getItemType(String utName) {
498 		ItemType type;
499 		synchronized(protos) {
500 			type = protos.get(utName);
501 			if (type != null) return type;
502 			
503 			type = new ItemType(utName);
504 			protos.put(utName, type);
505 		}
506 		return type;
507 	}
508 
509 	public String getName() {
510 		return name;
511 	}
512 
513 }