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  		/** LinkGun weapon and accessory. */
92  		LINK_GUN("LinkGun"),
93  		/** ShockRifle weapon and accessory. */
94  		SHOCK_RIFLE("ShockRifle"),		
95  		/** RocketLauncher weapon and accessory. */
96  		ROCKET_LAUNCHER("RocketLauncher"),
97  		/** Physics gun */
98  		PHYSICS_GUN("PhysicsGun"),
99  
100 		/** Classic health pack. */
101 		HEALTH("HealthKit"),
102 		/** Mini health vial. */
103 		MINI_HEALTH("HealthVial"),
104 
105 		/** Thigh pad. */
106 		THIGH_PAD("Thighpad"),
107 		/** Base armor. */
108 		BASE_ARMOR("BaseArmor"),
109 		/** ShieldBelt. */
110 		SHIELD_BELT("ShieldBelt"),
111 
112 		/** Jump boots. */
113 		JUMP_BOOTS("JumpBoots"),
114 		/** UDamage bonus items. */
115 		UDAMAGE("UDamage"),
116 		/** Other items with user-defined group. */
117 		OTHER("Unknown"),
118 		/** No group, used for the prototype None */
119 		NONE("None");
120 
121 		/* =================================================================== */
122 
123 		/** Human-readable name of the group. */
124 		public String name;
125 
126 		/* =================================================================== */
127 
128 		/**
129 		 * Constructor.
130 		 * 
131 		 * @param name
132 		 *            Human-readable name of the group.
133 		 */
134 		Group(String name) {
135 			this.name = name;
136 		}
137 		
138 		public Set<ItemType> getTypes() {
139 			return GROUPS.get(this);
140 		}
141 	}
142 
143 	/* ======================================================================== */
144 
145 	/**
146 	 * Map of all registered ItemType prototypes.
147 	 */
148 	private static HashMap<String, ItemType> protos = new HashMap<String, ItemType>();
149 
150 	/* ======================================================================== */
151 
152 	/** ShockRifle weapon. */
153 	public static final ItemType SHOCK_RIFLE = MakePrototype(Category.WEAPON,
154 			Group.SHOCK_RIFLE, new String[] { "ShockRifle.WeaponPickup" });
155 	/** ShockRifle ammo. */
156 	public static final ItemType SHOCK_RIFLE_AMMO = MakePrototype(
157 			Category.AMMO, Group.SHOCK_RIFLE,
158 			new String[] { "ShockRifleAmmo.AmmoPickup" });
159 
160 	/** LinkGun weapon. */
161 	public static final ItemType LINK_GUN = MakePrototype(Category.WEAPON,
162 			Group.LINK_GUN, new String[] { "LinkGun.WeaponPickup" });
163 	/** LinkGun ammo. */
164 	public static final ItemType LINK_GUN_AMMO = MakePrototype(Category.AMMO,
165 			Group.LINK_GUN, new String[] { "LinkGunAmmo.AmmoPickup" });
166 
167 	/** RocketLauncher weapon. */
168 	public static final ItemType ROCKET_LAUNCHER = MakePrototype(
169 			Category.WEAPON, Group.ROCKET_LAUNCHER, new String[] {
170 					"RocketLauncher.WeaponPickup",
171 					"RocketLauncher_Content.WeaponPickup" });
172 	/** RocketLauncher ammo. */
173 	public static final ItemType ROCKET_LAUNCHER_AMMO = MakePrototype(
174 			Category.AMMO, Group.ROCKET_LAUNCHER,
175 			new String[] { "RocketLauncherAmmo.AmmoPickup",
176 					"RocketLauncher_ContentAmmo.AmmoPickup" });
177 
178 	/** Health pack. */
179 	public static final ItemType HEALTH_PACK = MakePrototype(Category.HEALTH,
180 			Group.HEALTH, new String[] { "HealthPack.HealthPickup" });
181 	/** Health vial. */
182 	public static final ItemType HEALTH_VIAL = MakePrototype(
183 			Category.HEALTH, Group.MINI_HEALTH,
184 			new String[] { "HealthVial.HealthPickup" });
185 
186 	/** Thigh pad. */
187 	public static final ItemType THIGH_PAD = MakePrototype(Category.ARMOR,
188 			Group.THIGH_PAD, new String[] { "Thighpad.ArmorPickup" });
189 	/** Base armor. */
190 	public static final ItemType BASE_ARMOR = MakePrototype(
191 			Category.ARMOR, Group.BASE_ARMOR,
192 			new String[] { "BaseArmor.ArmorPickup" });
193 	/** Shield belt. */
194 	public static final ItemType SHIELD_BELT = MakePrototype(
195 			Category.ARMOR, Group.SHIELD_BELT,
196 			new String[] { "ShieldBelt.ArmorPickup" });	
197 
198 	/** UDamage bonus (damage multiplier). */
199 	public static final ItemType UDAMAGE = MakePrototype(
200 			Category.OTHER, Group.UDAMAGE, new String[] {
201 					"UDamage.Pickup" });
202 	/** UDamage bonus (damage multiplier). */
203 	public static final ItemType JUMP_BOOTS = MakePrototype(
204 			Category.OTHER, Group.JUMP_BOOTS, new String[] {
205 					"JumpBoots.Pickup" });
206 	
207 	/** Weapons locker */
208 	public static final ItemType WEAPON_LOCKER = MakePrototype(
209 			Category.OTHER, Group.OTHER, new String[] {
210 					"WeaponLocker.LockerPickup" });
211 	
212 	/** No ItemType */
213 	public static final ItemType NONE = MakePrototype(Category.OTHER, Group.NONE,
214 			new String[] { "None", "NONE", "none" });
215 	
216 	/* ======================================================================== */
217 
218 	/**
219 	 * Name of the item in UT engine.
220 	 * 
221 	 * <p>
222 	 * Note: Items of the same type might have different names in UT engine. Use
223 	 * {@link #equals(Object)} to safely compare two ItemTypes. This name is
224 	 * informative only.
225 	 */
226 	private String name;
227 	
228 	public String toString() {
229 		return "ItemType[name = " + name + ", category = " + category + ", group = " + group + "]";
230 	}
231 
232 	/* ======================================================================== */
233 
234 	/**
235 	 * Category of the type.
236 	 */
237 	private Category category;
238 
239 	/**
240 	 * Group of the type.
241 	 */
242 	private Group group;
243 
244 	/**
245 	 * Retreives category of the item type.
246 	 * 
247 	 * @return Category of the item type.
248 	 */
249 	public Category getCategory() {
250 		// do we have a category already?
251 		return (category == null) ? (category = getProto().category) : category;
252 	}
253 
254 	/**
255 	 * Retreives group of the item type.
256 	 * 
257 	 * @return Group of the item type.
258 	 */
259 	public Group getGroup() {
260 		// do we have a group already?
261 		return (group == null) ? (group = getProto().group) : group;
262 	}
263 
264 	/* ======================================================================== */
265 
266 	/**
267 	 * Prototype reference.
268 	 */
269 	private ItemType proto;
270 
271 	/**
272 	 * Retreives (and caches) ItemType prototype.
273 	 * 
274 	 * @return ItemType prototype.
275 	 */
276 	private ItemType getProto() {
277 		// do we have a prototype already?
278 		if (proto != null) return proto;
279 		synchronized(protos) {
280 			return proto = protos.get(name);			
281 		}
282 	}
283 
284 	/* ======================================================================== */
285 
286 	/**
287 	 * Indicates whether some other ItemType is "equal to" this one.
288 	 * 
289 	 * @param obj
290 	 *            Object to be compared with.
291 	 * @return True, if the objects are equal.
292 	 */
293 	@Override
294 	public boolean equals(Object obj) {
295 		// the same object?
296 		if (this == obj)
297 			return true;
298 
299 		// the same type?
300 		if (obj instanceof ItemType) {
301 			// the same prototype?
302 			if (getProto() == ((ItemType) obj).getProto())
303 				return true;
304 		}
305 
306 		return false;
307 	}
308 
309 	/**
310 	 * Returns a hash code value for the object.
311 	 * 
312 	 * @return A hash code value for this object.
313 	 */
314 	@Override
315 	public int hashCode() {
316 		// provide hash of the string name
317 		return getProto().name.hashCode();
318 	}
319 
320 	/* ======================================================================== */
321 
322 	/**
323 	 * Public constructor - creates ItemType of the EXTRA category and Group OTHER.
324 	 * 
325 	 * @param name
326 	 *            Type name from GB engine.
327 	 */
328 	public ItemType(String name) {
329 		this.name = name;
330 		this.category = Category.OTHER;
331 		this.group = Group.OTHER;
332 		this.proto = this;
333 	}
334 
335 	/**
336 	 * Prototypes constructor.
337 	 */
338 	private ItemType(String name, Category category, Group group) {
339 		this.name = name;
340 		this.category = category;
341 		this.group = group;
342 		this.proto = this;
343 	}
344 
345 	/* ======================================================================== */
346 
347 	/**
348 	 * Proto-constructor.
349 	 * 
350 	 * @param category
351 	 *            Category of the item.
352 	 * @param group
353 	 *            Group of the item.
354 	 * @param utNames
355 	 *            Names of the item in UT engine.
356 	 * @return Prototype of known ItemType.
357 	 */
358 	public static ItemType MakePrototype(Category category,
359 			Group group, String[] utNames) {
360 		ItemType type;
361 		synchronized(protos) {
362 			// create new itemtype prototype
363 			type = new ItemType(utNames[0], category, group);
364 			// register the itemtype prototype
365 			for (String utName : utNames)
366 				protos.put(utName, type);
367 			// C'est la vie..
368 			if (category != null) {
369 				CATEGORIES.get(category).add(type);
370 			}
371 			if (group != null) {
372 				GROUPS.get(group).add(type);
373 			}
374 		}
375 		return type;
376 	}
377 
378 	/**
379 	 * Retrieves an ItemType for the specified item type name.
380 	 * @param utName e.g. Item.getType()
381 	 * @return
382 	 */
383 	public static ItemType getItemType(String utName) {
384 		ItemType type;
385 		synchronized(protos) {
386 			type = protos.get(utName);
387 			if (type != null) return type;
388 			
389 			type = new ItemType(utName);
390 			protos.put(utName, type);
391 		}
392 		return type;
393 	}
394 
395 	public String getName() {
396 		return name;
397 	}
398 
399 }