1 ////////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ////////////////////////////////////////////////////////////////////////////////
9 
10 /** ****************************************************************************
11 *** \file    global_objects.h
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Header file for global game objects
14 ***
15 *** This file contains several representations of inventory "objects" used
16 *** throughout the game. Objects include items, weapons, armor, etc.
17 *** ***************************************************************************/
18 
19 #ifndef __GLOBAL_OBJECTS_HEADER__
20 #define __GLOBAL_OBJECTS_HEADER__
21 
22 #include "defs.h"
23 #include "utils.h"
24 
25 #include "script.h"
26 #include "video.h"
27 
28 #include "global_utils.h"
29 
30 namespace hoa_global {
31 
32 /** ****************************************************************************
33 *** \brief An abstract base class for representing a game object
34 ***
35 *** All game objects inherit from this class. This allows objects of all types to
36 *** be stored in the same container (an inventory list for instance) and promotes
37 *** efficient code reuse for all game objects. The class is designed so that a
38 *** single class object can represent multiple instances of the same game object.
39 *** In other words, you can represent 50 healing potions with a single GlobalObject
40 *** class object rather than having to create and managed 50 class objects, one for
41 *** each potion. The _count member achieves this convenient function.
42 ***
43 *** A GlobalObject with an ID value of zero is considered invalid. Most of the
44 *** protected members of this class can only be set by the constructors or methods
45 *** of deriving classes.
46 ***
47 *** \note The price of an object is not actually the price it is bought or sold
48 *** at in the game. It is a "base price" from which all levels of buy and sell
49 *** prices are derived from.
50 ***
51 *** \todo The "lore" for an object is a feature that we have discussed but not
52 *** yet decided if we wish to implement. Placeholders exist in this class for now,
53 *** but if lore is not to be implemented as a game feature they should be removed.
54 *** ***************************************************************************/
55 class GlobalObject {
56 public:
GlobalObject()57 	GlobalObject() :
58 		_id(0), _count(0), _price(0) {}
59 
60 	GlobalObject(uint32 id, uint32 count = 1) :
_id(id)61 		_id(id), _count(count), _price(0) {}
62 
~GlobalObject()63 	virtual ~GlobalObject()
64 		{}
65 
66 	//! \brief Returns true if the object is properly initialized and ready to be used
IsValid()67 	bool IsValid() const
68 		{ return (_id != 0); }
69 
70 	/** \brief Purely virtual function used to distinguish between object types
71 	*** \return A value that represents the type of object
72 	**/
73 	virtual GLOBAL_OBJECT GetObjectType() const = 0;
74 
75 	/** \brief Increments the number of objects represented by this class
76 	*** \param count The count increment value (default value == 1)
77 	**/
78 	void IncrementCount(uint32 count = 1)
79 		{ _count += count; }
80 
81 	/** \brief Decrements the number of objects represented by this class
82 	*** \param count The count decrement value (default value == 1)
83 	*** \note When the count reaches zero, this class object does <i>not</i> self-destruct. It is the user's
84 	*** responsiblity to check if the count becomes zero, and to destroy the object if it is appropriate to do so.
85 	**/
86 	void DecrementCount(uint32 count = 1)
87 		{ if (count > _count) _count = 0; else _count -= count; }
88 
89 	//! \name Class Member Access Functions
90 	//@{
GetID()91 	uint32 GetID() const
92 		{ return _id; }
93 
GetName()94 	const hoa_utils::ustring& GetName() const
95 		{ return _name; }
96 
GetDescription()97 	const hoa_utils::ustring& GetDescription() const
98 		{ return _description; }
99 
GetLore()100 	const hoa_utils::ustring& GetLore() const
101 		{ return _lore; }
102 
SetCount(uint32 count)103 	void SetCount(uint32 count)
104 		{ _count = count; }
105 
GetCount()106 	uint32 GetCount() const
107 		{ return _count; }
108 
GetPrice()109 	uint32 GetPrice() const
110 		{ return _price; }
111 
GetIconImage()112 	const hoa_video::StillImage& GetIconImage() const
113 		{ return _icon_image; }
114 	//@}
115 
116 protected:
117 	/** \brief An identification number for each unique item
118 	*** \note An ID number of zero indicates an invalid object
119 	**/
120 	uint32 _id;
121 
122 	//! \brief The name of the object as it would be displayed on a screen
123 	hoa_utils::ustring _name;
124 
125 	//! \brief A short description of the item to display on the screen
126 	hoa_utils::ustring _description;
127 
128 	//! \brief A detailed description of the object's history, culture, and how it fits into the game world
129 	hoa_utils::ustring _lore;
130 
131 	//! \brief Retains how many occurences of the object are represented by this class object instance
132 	uint32 _count;
133 
134 	//! \brief The base price of the object for purchase/sale in the game
135 	uint32 _price;
136 
137 	//! \brief A loaded icon image of the object at its original size of 60x60 pixels
138 	hoa_video::StillImage _icon_image;
139 
140 	//! \brief Causes the object to become invalid due to a loading error or other significant issue
_InvalidateObject()141 	void _InvalidateObject()
142 		{ _id = 0; }
143 
144 	/** \brief Reads object data from an open script file
145 	*** \param script A reference to a script file that has been opened and prepared
146 	***
147 	*** This method does not do any of its own error case checking. Only dervied classes may call this
148 	*** protected function and they are expected to have the script file successfully opened and the correct
149 	*** table context prepared. This function will do nothing more but read the expected key/values of
150 	*** the open table in the script file and return.
151 	**/
152 	void _LoadObjectData(hoa_script::ReadScriptDescriptor& script);
153 }; // class GlobalObject
154 
155 
156 /** ****************************************************************************
157 *** \brief Represents items used throughout the game
158 ***
159 *** This class is for general use items such as healing potions. Each item has a
160 *** different effect when it is used, implemented by a Lua function written
161 *** specifically for the item which calls it. Some items may be used only in certain
162 *** scenarios (in battles, on the field, etc.). All items may be used by any
163 *** character or enemy in the game.
164 *** ***************************************************************************/
165 class GlobalItem : public GlobalObject {
166 public:
167 	/** \param id The unique ID number of the item
168 	*** \param count The number of items to initialize this class object as representing (default value == 1)
169 	**/
170 	GlobalItem(uint32 id, uint32 count = 1);
171 
172 	~GlobalItem();
173 
174 	GlobalItem(const GlobalItem& copy);
175 
176 	GlobalItem& operator=(const GlobalItem& copy);
177 
GetObjectType()178 	GLOBAL_OBJECT GetObjectType() const
179 		{ return GLOBAL_OBJECT_ITEM; }
180 
181 	//! \brief Returns true if the item can be used in battle
IsUsableInBattle()182 	bool IsUsableInBattle()
183 		{ return (_battle_use_function != NULL); }
184 
185 	//! \brief Returns true if the item can be used in the field
IsUsableInField()186 	bool IsUsableInField()
187 		{ return (_field_use_function != NULL); }
188 
189 	//! \name Class Member Access Functions
190 	//@{
GetTargetType()191 	GLOBAL_TARGET GetTargetType() const
192 		{ return _target_type; }
193 
194 	/** \brief Returns a pointer to the ScriptObject of the battle use function
195 	*** \note This function will return NULL if the skill is not usable in battle
196 	**/
GetBattleUseFunction()197 	const ScriptObject* GetBattleUseFunction() const
198 		{ return _battle_use_function; }
199 
200 	/** \brief Returns a pointer to the ScriptObject of the field use function
201 	*** \note This function will return NULL if the skill is not usable in the field
202 	**/
GetFieldUseFunction()203 	const ScriptObject* GetFieldUseFunction() const
204 		{ return _field_use_function; }
205 	//@}
206 
207 private:
208 	//! \brief The type of target for the item
209 	GLOBAL_TARGET _target_type;
210 
211 	//! \brief A pointer to the script function that performs the item's effect while in battle
212 	ScriptObject* _battle_use_function;
213 
214 	//! \brief A pointer to the script function that performs the item's effect while in a menu
215 	ScriptObject* _field_use_function;
216 }; // class GlobalItem : public GlobalObject
217 
218 
219 /** ****************************************************************************
220 *** \brief Represents weapon that may be equipped by characters or enemies
221 ***
222 *** All classes of weapons (swords, bows, spears, etc.) are represented by this
223 *** class. Typically, a weapon may only be used by a select few and can not be
224 *** equipped on every character. Weapons have two attack ratings: physical
225 *** and metaphysical, both of which are included in the damage calculation
226 *** formulae when a character or enemy attacks using the weapon. Weapons may also
227 *** have a small number of "sockets" in which shards can be inserted to improve
228 *** or alter the weapon's properties. Some weapons have zero sockets available.
229 *** Finally, weapons may come imbued with certain elemental or status effect
230 *** properties that are inflicted on a target.
231 *** ***************************************************************************/
232 class GlobalWeapon : public GlobalObject {
233 public:
234 	/** \param id The unique ID number of the weapon
235 	*** \param count The number of weapons to initialize this class object as representing (default value == 1)
236 	**/
237 	GlobalWeapon(uint32 id, uint32 count = 1);
238 
~GlobalWeapon()239 	~GlobalWeapon()
240 		{}
241 
GetObjectType()242 	GLOBAL_OBJECT GetObjectType() const
243 		{ return GLOBAL_OBJECT_WEAPON; }
244 
245 	//! \name Class Member Access Functions
246 	//@{
GetPhysicalAttack()247 	uint32 GetPhysicalAttack() const
248 		{ return _physical_attack; }
249 
GetMetaphysicalAttack()250 	uint32 GetMetaphysicalAttack() const
251 		{ return _metaphysical_attack; }
252 
GetUsableBy()253 	uint32 GetUsableBy() const
254 		{ return _usable_by; }
255 
GetSockets()256 	const std::vector<GlobalShard*>& GetSockets() const
257 		{ return _sockets; }
258 
GetElementalEffects()259 	const std::map<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>& GetElementalEffects() const
260 		{ return _elemental_effects; }
261 	//@}
262 
263 private:
264 	//! \brief The amount of physical damage that the weapon causes
265 	uint32 _physical_attack;
266 
267 	//! \brief The amount of metaphysical damage that the weapon causes
268 	uint32 _metaphysical_attack;
269 
270 	/** \brief A bit-mask that determines which characters can use or equip the object
271 	*** See the game character ID constants in global_actors.h for more information
272 	**/
273 	uint32 _usable_by;
274 
275 	/** \brief Sockets which may be used to place shards on the weapon
276 	*** Weapons may have no sockets, so it is not uncommon for the size of this vector to be zero.
277 	*** When a socket is available but empty (has no attached shard), the pointer at that index
278 	*** will be NULL.
279 	**/
280 	std::vector<GlobalShard*> _sockets;
281 
282 	/** \brief Container that holds the intensity of each type of elemental effect of the weapon
283 	*** Elements with an intensity of GLOBAL_INTENSITY_NEUTRAL indicate no elemental bonus
284 	**/
285 	std::map<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY> _elemental_effects;
286 
287 	// TODO: Add status effects to weapons
288 	// std::map<GLOBAL_STATUS, GLOBAL_INTENSITY> _status_effects;
289 }; // class GlobalWeapon : public GlobalObject
290 
291 
292 /** ****************************************************************************
293 *** \brief Represents all types of armor that may be equipped on characters and enemies
294 ***
295 *** There are actually four types of armor: head, torso, arm, and leg. However all
296 *** four types are represented by this single class. The only functional difference
297 *** between different types of armor is where they may be equipped on an actor. Not
298 *** all armor can be equipped by any character or enemy. Typically, armor may only
299 *** be used by a select few and can not be equipped on every character. Armor have
300 *** two defense ratings: physical and metaphysical, both of which are included in
301 *** the damage calculation formulae when a character or enemy is attacked at the
302 *** location where the armor is equipped. Armor may also have a small number of
303 *** "sockets" in which shards can be inserted to improve or alter the armor's
304 *** properties. Some armor will have zero sockets available. Finally, armor may
305 *** come imbued with certain elemental or status effect properties that bolster
306 *** and protect the user.
307 *** ***************************************************************************/
308 class GlobalArmor : public GlobalObject {
309 public:
310 	GlobalArmor(uint32 id, uint32 count = 1);
311 
~GlobalArmor()312 	~GlobalArmor()
313 		{}
314 
315 	//! \brief Returns the approriate armor type (head, torso, arm, leg) depending on the object ID
316 	GLOBAL_OBJECT GetObjectType() const;
317 
GetPhysicalDefense()318 	uint32 GetPhysicalDefense() const
319 		{ return _physical_defense; }
320 
GetMetaphysicalDefense()321 	uint32 GetMetaphysicalDefense() const
322 		{ return _metaphysical_defense; }
323 
GetUsableBy()324 	uint32 GetUsableBy() const
325 		{ return _usable_by; }
326 
GetSockets()327 	const std::vector<GlobalShard*>& GetSockets() const
328 		{ return _sockets; }
329 
GetElementalEffects()330 	const std::map<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY>& GetElementalEffects() const
331 		{ return _elemental_effects; }
332 
333 private:
334 	//! \brief The amount of physical defense that the armor provides
335 	uint32 _physical_defense;
336 
337 	//! \brief The amount of metaphysical defense that the armor provides
338 	uint32 _metaphysical_defense;
339 
340 	/** \brief A bit-mask that determines which characters can use or equip the object
341 	*** See the game character ID constants in global_actors.h for more information
342 	**/
343 	uint32 _usable_by;
344 
345 	/** \brief Sockets which may be used to place shards on the armor
346 	*** Armor may have no sockets, so it is not uncommon for the size of this vector to be zero.
347 	*** When a socket is available but empty (has no attached shard), the pointer at that index
348 	*** will be NULL.
349 	**/
350 	std::vector<GlobalShard*> _sockets;
351 
352 	/** \brief Container that holds the intensity of each type of elemental effect of the armor
353 	*** Elements with an intensity of GLOBAL_INTENSITY_NEUTRAL indicate no elemental bonus
354 	**/
355 	std::map<GLOBAL_ELEMENTAL, GLOBAL_INTENSITY> _elemental_effects;
356 
357 	// TODO: Add status effects to weapons
358 	// std::map<GLOBAL_STATUS, GLOBAL_INTENSITY> _status_effects;
359 }; // class GlobalArmor : public GlobalObject
360 
361 
362 /** ****************************************************************************
363 *** \brief Represents any type of shard that can be attached to weapons and armor
364 ***
365 *** Shards are small gems or stones that can be placed into sockets available on
366 *** weapons and armor. Shards have the ability to enhance the properties of
367 *** equipment it is attached to, allowing the player a degree of customization
368 *** in the weapons and armor that their character use.
369 ***
370 *** \todo This class is not yet implemented
371 *** ***************************************************************************/
372 class GlobalShard : public GlobalObject {
373 public:
374 	GlobalShard(uint32 id, uint32 count = 1);
375 
GetObjectType()376 	GLOBAL_OBJECT GetObjectType() const
377 		{ return GLOBAL_OBJECT_SHARD; }
378 }; // class GlobalShard : public GlobalObject
379 
380 
381 /** ****************************************************************************
382 *** \brief Represents key items found throughout the game
383 ***
384 *** Key items are special items which can not be used directly used nor sold by
385 *** the player. Their primary function is to for use in game logic. For example,
386 *** a copper key may be needed to open a certain door in a dungeon. Key items
387 *** have no need for further data  nor logic beyond what is provided in the
388 *** GlobalObject base class is necessary for key items.
389 *** ***************************************************************************/
390 class GlobalKeyItem : public GlobalObject {
391 public:
392 	GlobalKeyItem(uint32 id, uint32 count = 1);
393 
GetObjectType()394 	GLOBAL_OBJECT GetObjectType() const
395 		{ return GLOBAL_OBJECT_KEY_ITEM; }
396 }; // class GlobalKeyItem : public GlobalObject
397 
398 } // namespace hoa_global
399 
400 #endif // __GLOBAL_OBJECTS_HEADER__
401