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