1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef XEEN_ITEM_H
24 #define XEEN_ITEM_H
25 
26 #include "common/scummsys.h"
27 #include "common/array.h"
28 #include "common/rect.h"
29 #include "common/serializer.h"
30 #include "xeen/sprites.h"
31 
32 namespace Xeen {
33 
34 #define INV_ITEMS_TOTAL 9
35 
36 class XeenEngine;
37 class Character;
38 
39 enum ItemCategory {
40 	CATEGORY_WEAPON = 0, CATEGORY_ARMOR = 1, CATEGORY_ACCESSORY = 2, CATEGORY_MISC = 3,
41 	NUM_ITEM_CATEGORIES = 4
42 };
43 
44 enum AttributeCategory {
45 	ATTR_MIGHT = 0, ATTR_INTELLECT = 1, ATTR_PERSONALITY = 2, ATTR_SPEED = 3,
46 	ATTR_ACCURACY = 4, ATTR_LUCK = 5, ATTR_HIT_POINTS = 6, ATTR_SPELL_POINTS = 7,
47 	ATTR_ARMOR_CLASS = 8, ATTR_THIEVERY = 9
48 };
49 
50 enum ElementalCategory {
51 	ELEM_FIRE = 0, ELEM_ELECTRICITY = 1, ELEM_COLD = 2, ELEM_ACID_POISON = 3,
52 	ELEM_ENERGY = 4, ELEM_MAGIC = 5
53 };
54 
55 enum WeaponId {
56 	XEEN_SLAYER_SWORD = 34
57 };
58 
59 enum Effectiveness {
60 	EFFECTIVE_NONE = 0, EFFECTIVE_DRAGON = 1, EFFECTIVE_UNDEAD = 2, EFFECTIVE_GOLEM = 3,
61 	EFFECTIVE_INSECT = 4, EFFEctIVE_MONSTERS = 5, EFFECTIVE_ANIMAL = 6
62 };
63 
64 struct ItemState {
65 	byte _counter : 6;		// Stores charges for Misc items, and the effective against for weapons
66 	bool _cursed : 1;
67 	bool _broken : 1;
68 
69 	/**
70 	 * Constructor
71 	 */
ItemStateItemState72 	ItemState() : _counter(0), _cursed(false), _broken(false) {}
73 
74 	/**
75 	 * Clear the state
76 	 */
clearItemState77 	void clear() {
78 		_counter = 0;
79 		_cursed = _broken = false;
80 	}
81 
82 	/**
83 	 * Returns true if the state is empty
84 	 */
emptyItemState85 	bool empty() const { return !_counter && !_cursed && !_broken; }
86 
87 	/**
88 	 * Synchronizes the item's state
89 	 */
90 	void synchronize(Common::Serializer &s);
91 
92 	/**
93 	 * Set the entire state value
94 	 */
95 	void operator=(byte val);
96 };
97 
98 class XeenItem {
99 public:
100 	int _material;
101 	uint _id;
102 	ItemState _state;
103 	int _frame;
104 public:
105 	/**
106 	 * Return the name of the item
107 	 */
108 	static const char *getItemName(ItemCategory category, uint id);
109 public:
110 	/**
111 	 * Constructor
112 	 */
113 	XeenItem();
114 
115 	/**
116 	 * Clear the data for the item
117 	 */
118 	void clear();
119 
120 	/**
121 	 * Returns true if no item is set
122 	 */
empty()123 	bool empty() const { return _id == 0; }
124 
125 	/**
126 	 * Returns true if the item is cursed or broken
127 	 */
isBad()128 	bool isBad() const { return _state._cursed || _state._broken; }
129 
130 	/**
131 	 * Returns true for weapons if it's equipped
132 	 */
isEquipped()133 	bool isEquipped() const { return _frame != 0; }
134 
135 	/**
136 	 * Synchronizes the data for the item
137 	 */
138 	void synchronize(Common::Serializer &s);
139 
140 	/**
141 	 * Gets the elemental category for the item
142 	 */
143 	ElementalCategory getElementalCategory() const;
144 
145 	/**
146 	 * Gets the elemental category for a given material
147 	 */
148 	static ElementalCategory getElementalCategory(int material);
149 
150 	/**
151 	 * Gets the attribute category for the item
152 	 */
153 	AttributeCategory getAttributeCategory() const;
154 };
155 
156 class InventoryItems : public Common::Array<XeenItem> {
157 protected:
158 	Character *_character;
159 	ItemCategory _category;
160 	const char **_names;
161 
162 	XeenEngine *getVm();
163 	void equipError(int itemIndex1, ItemCategory category1, int itemIndex2,
164 		ItemCategory category2);
165 
166 	/**
167 	 * Returns a text string listing all the stats/attributes of a given item
168 	 */
169 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes) = 0;
170 
171 	/**
172 	 * Capitalizes a passed description string that includes embedded formatting for the Items dialog
173 	 */
174 	void capitalizeItem(Common::String &name);
175 public:
176 	InventoryItems(Character *character, ItemCategory category);
~InventoryItems()177 	virtual ~InventoryItems() {}
178 
179 	/**
180 	 * Clears the set of items
181 	 */
182 	void clear();
183 
184 	/**
185 	 * Handles copying items from one character to another
186 	 */
187 	InventoryItems &operator=(const InventoryItems &src);
188 
189 	/**
190 	 * Return whether a given item passes class-based usage restrictions
191 	 * @param itemId		Item Index
192 	 * @param suppressError	If true, no dialog is shown if the item doesn't pass restrictions
193 	 */
194 	bool passRestrictions(int itemId, bool suppressError = false) const;
195 
196 	/**
197 	 * Return the bare name of a given inventory item
198 	 */
199 	Common::String getName(int itemIndex);
200 
201 	virtual Common::String getFullDescription(int itemIndex, int displayNum = 15) = 0;
202 
203 	/**
204 	 * Returns the identified details for an item
205 	 */
206 	Common::String getIdentifiedDetails(int itemIndex);
207 
208 	/**
209 	 * Discard an item from the inventory
210 	 */
211 	bool discardItem(int itemIndex);
212 
213 	/**
214 	 * Equips an item
215 	 */
equipItem(int itemIndex)216 	virtual void equipItem(int itemIndex) {}
217 
218 	/**
219 	 * Un-equips the given item
220 	 */
221 	void removeItem(int itemIndex);
222 
223 	/**
224 	 * Sorts the items list, removing any empty item slots to the end of the array
225 	 */
226 	void sort();
227 
228 	/**
229 	 * Enchants an item
230 	 */
231 	virtual void enchantItem(int itemIndex, int amount);
232 
233 	/**
234 	 * Return if the given inventory items list is full
235 	 */
236 	bool isFull() const;
237 };
238 
239 class WeaponItems: public InventoryItems {
240 protected:
241 	/**
242 	 * Returns a text string listing all the stats/attributes of a given item
243 	 */
244 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
245 public:
WeaponItems(Character * character)246 	WeaponItems(Character *character) : InventoryItems(character, CATEGORY_WEAPON) {}
~WeaponItems()247 	virtual ~WeaponItems() {}
248 
249 	/**
250 	 * Equip a given weapon
251 	 */
252 	virtual void equipItem(int itemIndex);
253 
254 	/**
255 	 * Assembles a full lines description for a specified item for use in
256 	 * the Items dialog
257 	 */
258 	virtual Common::String getFullDescription(int itemIndex, int displayNum);
259 
260 	/**
261 	 * Enchants a weapon
262 	 */
263 	virtual void enchantItem(int itemIndex, int amount);
264 
265 	/**
266 	 * Returns true if the character has an Elder weapon in Swords of Xeen
267 	 */
268 	bool hasElderWeapon() const;
269 };
270 
271 class ArmorItems : public InventoryItems {
272 protected:
273 	/**
274 	 * Returns a text string listing all the stats/attributes of a given item
275 	 */
276 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
277 public:
ArmorItems(Character * character)278 	ArmorItems(Character *character) : InventoryItems(character, CATEGORY_ARMOR) {}
~ArmorItems()279 	virtual ~ArmorItems() {}
280 
281 	/**
282 	 * Equip a given piece of armor
283 	 */
284 	virtual void equipItem(int itemIndex);
285 
286 	/**
287 	 * Assembles a full lines description for a specified item for use in
288 	 * the Items dialog
289 	 */
290 	virtual Common::String getFullDescription(int itemIndex, int displayNum);
291 
292 	/**
293 	 * Enchants an armor
294 	 */
295 	virtual void enchantItem(int itemIndex, int amount);
296 };
297 
298 class AccessoryItems : public InventoryItems {
299 protected:
300 	/**
301 	 * Returns a text string listing all the stats/attributes of a given item
302 	 */
303 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
304 public:
AccessoryItems(Character * character)305 	AccessoryItems(Character *character) : InventoryItems(character, CATEGORY_ACCESSORY) {}
306 
307 	/**
308 	 * Equip a given accessory
309 	 */
310 	virtual void equipItem(int itemIndex);
311 
312 	/**
313 	 * Assembles a full lines description for a specified item for use in
314 	 * the Items dialog
315 	 */
316 	virtual Common::String getFullDescription(int itemIndex, int displayNum);
317 };
318 
319 class MiscItems : public InventoryItems {
320 protected:
321 	/**
322 	 * Returns a text string listing all the stats/attributes of a given item
323 	 */
324 	virtual Common::String getAttributes(XeenItem &item, const Common::String &classes);
325 public:
MiscItems(Character * character)326 	MiscItems(Character *character) : InventoryItems(character, CATEGORY_MISC) {}
~MiscItems()327 	virtual ~MiscItems() {}
328 
329 	/**
330 	 * Assembles a full lines description for a specified item for use in
331 	 * the Items dialog
332 	 */
333 	virtual Common::String getFullDescription(int itemIndex, int displayNum);
334 };
335 
336 class InventoryItemsGroup {
337 private:
338 	Character *_owner;
339 public:
InventoryItemsGroup(Character * owner)340 	InventoryItemsGroup(Character *owner) : _owner(owner) {}
341 
342 	/**
343 	 * Returns the inventory items for a given category
344 	 */
345 	InventoryItems &operator[](ItemCategory category);
346 
347 	/**
348 	 * Returns the inventory items for a given category
349 	 */
350 	const InventoryItems &operator[](ItemCategory category) const;
351 
352 	/**
353 	 * Breaks all the items in a given character's inventory
354 	 */
355 	void breakAllItems();
356 
357 	/**
358 	 * Curses or curses all the items
359 	 */
360 	void curseUncurse(bool curse);
361 
362 	/**
363 	 * Returns true if the character has any cursed items
364 	 */
365 	bool hasCursedItems() const;
366 };
367 
368 } // End of namespace Xeen
369 
370 #endif /* XEEN_CHARACTER_H */
371