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.h
12 *** \author Tyler Olsen, roots@allacrost.org
13 *** \brief Header file for the global game manager
14 ***
15 *** This file contains the GameGlobal class, which is used to manage all data
16 *** that is shared "globally" by the various game modes. For example, it
17 *** contains the current characters in the party, the party's inventory, etc.
18 *** The definition of characters, items, and other related global data are
19 *** implemented in the other global header files (e.g. global_actors.h). All
20 *** of these global files share the same hoa_global namespace.
21 *** ***************************************************************************/
22
23 #ifndef __GLOBAL_HEADER__
24 #define __GLOBAL_HEADER__
25
26 #include "defs.h"
27 #include "utils.h"
28 #include "script.h"
29
30 #include "global_actors.h"
31 #include "global_effects.h"
32 #include "global_objects.h"
33 #include "global_skills.h"
34 #include "global_utils.h"
35
36 //! \brief All calls to global code are wrapped inside this namespace.
37 namespace hoa_global {
38
39 //! \brief The singleton pointer responsible for the management of global game data.
40 extern GameGlobal* GlobalManager;
41
42 //! \brief Determines whether the code in the hoa_global namespace should print debug statements or not.
43 extern bool GLOBAL_DEBUG;
44
45 /** ****************************************************************************
46 *** \brief A container that manages the occurences of several related game events
47 ***
48 *** Events in Allacrost are nothing more than a string-integer pair. The string
49 *** represents the name of the event while the integer takes on various meanings
50 *** about the event. One example of an event could be if the player has already
51 *** seen a certain piece of dialogue, and the integer would be set to zero or
52 *** non-zero to emulate a boolean value. Another example could be whether the
53 *** player previous chose option A, B, C, or D when presented with a list of
54 *** possible actions to take, in which the integer value would represent the
55 *** option taken.
56 ***
57 *** Because we want to continually look-up whether or not an event has occured,
58 *** it is not efficient to store all game events in a single container (the
59 *** larger the number of events, the longer the event search time). Instead,
60 *** this class collectively represents a group of related events. A typical
61 *** event group could represent all of the events that occured on a particular
62 *** map, for instance.
63 ***
64 *** \note Other parts of the code should not have a need to construct objects of
65 *** this class. The GameGlobal class maintains a container of GlobalEventGroup
66 *** objects and provides methods to allow the creation, modification, and
67 *** retrieval of these objects.
68 *** ***************************************************************************/
69 class GlobalEventGroup {
70 public:
71 //! \param group_name The name of the group to create (this can not be changed)
GlobalEventGroup(const std::string & group_name)72 GlobalEventGroup(const std::string& group_name) :
73 _group_name(group_name) {}
74
~GlobalEventGroup()75 ~GlobalEventGroup() {}
76
77 /** \brief Queries whether or not an event of a given name exists in the group
78 *** \param event_name The name of the event to check for
79 *** \return True if the event name was found in the group, false if it was not
80 **/
DoesEventExist(const std::string & event_name)81 bool DoesEventExist(const std::string& event_name)
82 { if (_events.find(event_name) != _events.end()) return true; else return false; }
83
84 /** \brief Adds a new event to the group
85 *** \param event_name The name of the event to add
86 *** \param event_value The value of the event to add (default value is zero)
87 *** \note If an event by the given name already exists, a warning will be printed and no addition
88 *** or modification of any kind will take place
89 **/
90 void AddNewEvent(const std::string& event_name, int32 event_value = 0);
91
92 /** \brief Retrieves the value of a specific event in the group
93 *** \param event_name The name of the event to retrieve
94 *** \return The value of the event, or GLOBAL_BAD_EVENT if there is no event corresponding to
95 *** the requested event named
96 **/
97 int32 GetEvent(const std::string& event_name);
98
99 /** \brief Sets the value for an existing event
100 *** \param event_name The name of the event whose value should be changed
101 *** \param event_value The value to set for the event
102 *** \note If the event by the given name is not found, a warning will be printed and no change will be made
103 **/
104 void SetEvent(const std::string& event_name, int32 event_value);
105
106 //! \brief Returns the number of events currently stored within the group
GetNumberEvents()107 uint32 GetNumberEvents() const
108 { return _events.size(); }
109
110 //! \brief Returns a copy of the name of this group
GetGroupName()111 std::string GetGroupName() const
112 { return _group_name; }
113
114 //! \brief Returns an immutable reference to the private _events container
GetEvents()115 const std::map<std::string, int32>& GetEvents() const
116 { return _events; }
117
118 private:
119 //! \brief The name given to this group of events
120 std::string _group_name;
121
122 /** \brief The map container for all the events in the group
123 *** The string is the name of the event, which is unique within the group. The integer value
124 *** represents the event's state and can take on multiple meanings depending on the context
125 *** of this specific event.
126 **/
127 std::map<std::string, int32> _events;
128 }; // class GlobalEventGroup
129
130
131 /** ****************************************************************************
132 *** \brief Retains all the state information about the active game
133 ***
134 *** This class is a resource manager for the current state of the game that is
135 *** being played. It retains all of the characters in the player's party, the
136 *** party's inventory, game events, etc. Nearly every game mode will need to
137 *** interact with this class in some form or another, whether it is to retrieve a
138 *** specific set of data or t
139 ***
140 *** \note This class is a singleton, even though it is technically not an engine
141 *** manager class. There can only be one game instance that the player is playing
142 *** at any given time.
143 *** ***************************************************************************/
144 class GameGlobal : public hoa_utils::Singleton<GameGlobal> {
145 friend class hoa_utils::Singleton<GameGlobal>;
146
147 public:
148 ~GameGlobal();
149
150 bool SingletonInitialize();
151
152 /** \brief Deletes all data stored within the GameGlobal class object
153 *** This function is meant to be called when the user quits the current game instance
154 *** and returns to the boot screen. It will delete all characters, inventory, and other
155 *** data relevant to the current game.
156 **/
157 void ClearAllData();
158
159 //! \name Character Functions
160 //@{
161 /** \brief Adds a new character to the party with its initial settings
162 *** \param id The ID number of the character to add to the party.
163 ***
164 *** Only use this function for when you wish the character to be constructed using
165 *** its initial stats, equipment, and skills. Otherwise, you should construct the
166 *** GlobalCharacter externally and invoke the other AddCharacter function with a
167 *** pointer to it.
168 ***
169 *** \note If the number of characters is less than four when this function is called,
170 *** the new character will automatically be added to the active party.
171 **/
172 void AddCharacter(uint32 id);
173
174 /** \brief Adds a new pre-initialized character to the party
175 *** \param ch A pointer to the initialized GlobalCharacter object to add
176 ***
177 *** The GlobalCharacter argument must be created -and- properly initalized (stats
178 *** members all set, equipment added, skills added) prior to making this call.
179 *** Adding an uninitialized character will likely result in a segmentation fault
180 *** or other run-time error somewhere down the road.
181 ***
182 *** \note If the number of characters is less than four when this function is called,
183 *** the new character will automatically be added to the active party.
184 **/
185 void AddCharacter(GlobalCharacter* ch);
186
187 /** \brief Removes a character from the party.
188 *** \param id The ID number of the character to remove from the party.
189 **/
190 void RemoveCharacter(uint32 id);
191
192 /** \brief Returns a pointer to a character currently in the party.
193 *** \param id The ID number of the character to retrieve.
194 *** \return A pointer to the character, or NULL if the character was not found.
195 ***/
196 GlobalCharacter* GetCharacter(uint32 id);
197
198 /** \brief Checks whether or not a character is in the party
199 *** \param id The id of the character to check for
200 *** \return True if the character was found to be in the party, or false if they were not found.
201 **/
IsCharacterInParty(uint32 id)202 bool IsCharacterInParty(uint32 id)
203 { if (_characters.find(id) != _characters.end()) return true; else return false; }
204 //@}
205
206 //! \name Inventory Methods
207 //@{
208 /** \brief Adds a new object to the inventory
209 *** \param obj_id The identifier value of the object to add
210 *** \param obj_count The number of instances of the object to add (default == 1)
211 *** If the item already exists in the inventory, then instead the GlobalObject#_count member is used to
212 *** increment the count of the stored item.
213 **/
214 void AddToInventory(uint32 obj_id, uint32 obj_count = 1);
215
216 /** \brief Adds a new object to the inventory
217 *** \param object A pointer to the pre-created GlobalObject-type class to add
218 ***
219 *** Once you call this function, GameGlobal assumes it is now responsible for memory management of this
220 *** object. Therefore, you should <b>never</b> attempt to reference the argument pointer after it is
221 *** passed to this function, because it may very well now point to an invalid location in memory. You
222 *** should also never use this function to pass a pointer to an object that was <b>not</b> created with
223 *** the new operator, because it is guaranteed that sooner or later GameGlobal will invoke delete on
224 *** this object.
225 **/
226 void AddToInventory(GlobalObject* object);
227
228 /** \brief Removes an object from the inventory
229 *** \param obj_id The identifier value of the object to remove
230 *** \note If the object is not in the inventory, the function will do nothing.
231 ***
232 *** This function removes the item regardless of what the GlobalObject#_count member is set to.
233 *** If you want to remove only a certain number of instances of the object, use the function
234 *** GameGlobal#DecrementObjectCount.
235 **/
236 void RemoveFromInventory(uint32 obj_id);
237
238 /** \brief Retries a single copy of an object from the inventory
239 *** \param obj_id The identifier value of the item to remove
240 *** \param all_counts If set to true, all counts of the object will be removed from the inventory (default value == false)
241 *** \return A newly instantiated copy of the object, or NULL if the object was not found in the inventory
242 ***
243 *** If all_counts is false, the returned object will have a count of one and the count of the object inside the inventory
244 *** will be decremented by one. If all_counts is ture, the returned object will have the same count as was previously in
245 *** the inventory, and the object will be removed from the inventory alltogether. Note that the pointer returned will need
246 *** to be deleted by the user code, unless the object is re-added to the inventory or equipped on a character.
247 **/
248 GlobalObject* RetrieveFromInventory(uint32 obj_id, bool all_counts = false);
249
250 /** \brief Increments the number (count) of an object in the inventory
251 *** \param item_id The integer identifier of the item that will have its count incremented
252 *** \param count The amount to increase the object's count by (default value == 1)
253 ***
254 *** If the item does not exist in the inventory, this function will do nothing. If the count parameter
255 *** is set to zero, no change will take place.
256 ***
257 *** \note The callee can not assume that the function call succeeded, but rather has to check this themselves.
258 **/
259 void IncrementObjectCount(uint32 obj_id, uint32 obj_count = 1);
260
261 /** \brief Decrements the number (count) of an object in the inventory
262 *** \param item_id The integer identifier of the item that will have its count decremented
263 *** \param count The amount to decrease the object's count by (default value == 1)
264 ***
265 *** If the item does not exist in the inventory, this function will do nothing. If the count parameter
266 *** is set to zero, no change will take place. If the count parameter is greater than or equal to the
267 *** current count of the object, the object will be completely removed from the inventory.
268 ***
269 *** \note The callee can not assume that the function call succeeded, but rather has to check this themselves.
270 **/
271 void DecrementObjectCount(uint32 obj_id, uint32 obj_count = 1);
272
273 /** \brief Checks whether or a given object is currently stored in the inventory
274 *** \param id The id of the object (item, weapon, armor, etc.) to check for
275 *** \return True if the object was found in the inventor, or false if it was not found
276 **/
IsObjectInInventory(uint32 id)277 bool IsObjectInInventory(uint32 id)
278 { if (_inventory.find(id) != _inventory.end()) return true; else return false; }
279 //@}
280
281 //! \name Event Group Methods
282 //@{
283 /** \brief Queries whether or not an event group of a given name exists
284 *** \param group_name The name of the event group to check for
285 *** \return True if the event group name was found, false if it was not
286 **/
DoesEventGroupExist(const std::string & group_name)287 bool DoesEventGroupExist(const std::string& group_name) const
288 { if (_event_groups.find(group_name) != _event_groups.end()) return true; else return false; }
289
290 /** \brief Determines if an event of a given name exists within a given group
291 *** \param group_name The name of the event group where the event to check is contained
292 *** \param event_name The name of the event to check for
293 *** \return True if the event was found, or false if the event name or group name was not found
294 **/
295 bool DoesEventExist(const std::string& group_name, const std::string& event_name) const;
296
297 /** \brief Adds a new event group for the class to manage
298 *** \param group_name The name of the new event group to add
299 *** \note If an event group by the given name already exists, the function will abort
300 *** and not add the new event group. Otherwise, this class will automatically construct
301 *** a new event group of the given name and place it in its map of event groups.
302 **/
303 void AddNewEventGroup(const std::string& group_name);
304
305 /** \brief Returns a pointer to an event group of the specified name
306 *** \param group_name The name of the event group to retreive
307 *** \return A pointer to the GlobalEventGroup that represents the event group, or NULL if no event group
308 *** of the specifed name was found
309 ***
310 *** You can use this method to invoke the public methods of the GlobalEventGroup class. For example, if
311 *** we wanted to add a new event "cave_collapse" with a value of 1 to the group event "cave_map", we
312 *** would do the following: GlobalManager->GetEventGroup("cave_map")->AddNewEvent("cave_collapse", 1);
313 *** Be careful, however, because since this function returns NULL if the event group was not found, the
314 *** example code above would produce a segmentation fault if no event group by the name "cave_map" existed.
315 **/
316 GlobalEventGroup* GetEventGroup(const std::string& group_name) const;
317
318 /** \brief Returns the value of an event inside of a specified group
319 *** \param group_name The name of the event group where the event is contained
320 *** \param event_name The name of the event whose value should be retrieved
321 *** \return The value of the requested event, or GLOBAL_BAD_EVENT if the event was not found
322 **/
323 int32 GetEventValue(const std::string& group_name, const std::string& event_name) const;
324
325 //! \brief Returns the number of event groups stored in the class
GetNumberEventGroups()326 uint32 GetNumberEventGroups() const
327 { return _event_groups.size(); }
328
329 /** \brief Returns the number of events for a specified group name
330 *** \param group_name The name of the event group to retrieve the number of events for
331 *** \return The number of events in the group, or zero if no such group name existed
332 **/
333 uint32 GetNumberEvents(const std::string& group_name) const;
334 //@}
335
336 //! \note The overflow condition is not checked here: we just assume it will never occur
AddDrunes(uint32 amount)337 void AddDrunes(uint32 amount)
338 { _drunes += amount; }
339
340 //! \note The amount is only subtracted if the current funds is equal to or exceeds the amount to subtract
SubtractDrunes(uint32 amount)341 void SubtractDrunes(uint32 amount)
342 { if (_drunes >= amount) _drunes -= amount; }
343
344 /** \brief Calculates the average experience level of members in the active party
345 *** \return The average (integer) experience level of all members in the active party
346 *** This is used for determining the level of growth for enemies in battle.
347 **/
AverageActivePartyExperienceLevel()348 uint32 AverageActivePartyExperienceLevel() const
349 { return static_cast<uint32>(_active_party.AverageExperienceLevel()); }
350
351 /** \brief Sets the name and graphic for the current location
352 *** \param location_name The ustring that contains the name of the current map
353 *** \param location_graphic_filename The filename of the graphic image that represents this location
354 **/
355 void SetLocation(const hoa_utils::ustring& location_name, const std::string& location_graphic_filename);
356
357 /** \brief Set the location
358 *** \param this is really only used when starting a new game, as we don't know the what the location graphic is yet
359 *** the location graphic filename is loaded during map loading.
360 **/
SetLocation(const hoa_utils::ustring & location_name)361 void SetLocation(const hoa_utils::ustring& location_name)
362 { _location_name = location_name; }
363
364 /** \brief Sets the location
365 *** \param location_name The string that contains the name of the current map
366 **/
SetLocation(const std::string & location_name)367 void SetLocation(const std::string& location_name)
368 { _location_name = hoa_utils::MakeUnicodeString(location_name); }
369
370 //! \brief Executes function NewGame() from global script
NewGame()371 void NewGame()
372 { ScriptCallFunction<void>(_global_script.GetLuaState(), "NewGame"); }
373
374 /** \brief Saves all global data to a saved game file
375 *** \param filename The filename of the saved game file where to write the data to
376 *** \return True if the game was successfully saved, false if it was not
377 **/
378 bool SaveGame(const std::string& filename);
379
380 /** \brief Loads all global data from a saved game file
381 *** \param filename The filename of the saved game file where to read the data from
382 *** \return True if the game was successfully loaded, false if it was not
383 **/
384 bool LoadGame(const std::string& filename);
385
386 //! \name Class Member Access Functions
387 //@{
SetDrunes(uint32 amount)388 void SetDrunes(uint32 amount)
389 { _drunes = amount; }
390
GetDrunes()391 uint32 GetDrunes() const
392 { return _drunes; }
393
GetLocationName()394 hoa_utils::ustring& GetLocationName()
395 { return _location_name; }
396
GetLocationGraphic()397 hoa_video::StillImage& GetLocationGraphic()
398 { return _location_graphic; }
399
GetCharacterOrder()400 std::vector<GlobalCharacter*>* GetCharacterOrder()
401 { return &_character_order; };
402
GetActiveParty()403 GlobalParty* GetActiveParty()
404 { return &_active_party; }
405
GetInventory()406 std::map<uint32, GlobalObject*>* GetInventory()
407 { return &_inventory; }
408
GetInventoryItems()409 std::vector<GlobalItem*>* GetInventoryItems()
410 { return &_inventory_items; }
411
GetInventoryWeapons()412 std::vector<GlobalWeapon*>* GetInventoryWeapons()
413 { return &_inventory_weapons; }
414
GetInventoryHeadArmor()415 std::vector<GlobalArmor*>* GetInventoryHeadArmor()
416 { return &_inventory_head_armor; }
417
GetInventoryTorsoArmor()418 std::vector<GlobalArmor*>* GetInventoryTorsoArmor()
419 { return &_inventory_torso_armor; }
420
GetInventoryArmArmor()421 std::vector<GlobalArmor*>* GetInventoryArmArmor()
422 { return &_inventory_arm_armor; }
423
GetInventoryLegArmor()424 std::vector<GlobalArmor*>* GetInventoryLegArmor()
425 { return &_inventory_leg_armor; }
426
GetInventoryShards()427 std::vector<GlobalShard*>* GetInventoryShards()
428 { return &_inventory_shards; }
429
GetInventoryKeyItems()430 std::vector<GlobalKeyItem*>* GetInventoryKeyItems()
431 { return &_inventory_key_items; }
432
GetItemsScript()433 hoa_script::ReadScriptDescriptor& GetItemsScript()
434 { return _items_script; }
435
GetWeaponsScript()436 hoa_script::ReadScriptDescriptor& GetWeaponsScript()
437 { return _weapons_script; }
438
GetHeadArmorScript()439 hoa_script::ReadScriptDescriptor& GetHeadArmorScript()
440 { return _head_armor_script; }
441
GetTorsoArmorScript()442 hoa_script::ReadScriptDescriptor& GetTorsoArmorScript()
443 { return _torso_armor_script; }
444
GetArmArmorScript()445 hoa_script::ReadScriptDescriptor& GetArmArmorScript()
446 { return _arm_armor_script; }
447
GetLegArmorScript()448 hoa_script::ReadScriptDescriptor& GetLegArmorScript()
449 { return _leg_armor_script; }
450
GetAttackSkillsScript()451 hoa_script::ReadScriptDescriptor& GetAttackSkillsScript()
452 { return _attack_skills_script; }
453
GetDefendSkillsScript()454 hoa_script::ReadScriptDescriptor& GetDefendSkillsScript()
455 { return _defend_skills_script; }
456
GetSupportSkillsScript()457 hoa_script::ReadScriptDescriptor& GetSupportSkillsScript()
458 { return _support_skills_script; }
459
GetStatusEffectsScript()460 hoa_script::ReadScriptDescriptor& GetStatusEffectsScript()
461 { return _status_effects_script; }
462
GetBattleEventScript()463 hoa_script::ReadScriptDescriptor* GetBattleEventScript()
464 { return &_battle_events_script; }
465 //@}
466
467 private:
468 GameGlobal();
469
470 //! \brief The amount of financial resources (drunes) that the party currently has
471 uint32 _drunes;
472
473 //! \brief The name of the map that the current party is on
474 hoa_utils::ustring _location_name;
475
476 //! \brief The graphical image which represents the current location
477 hoa_video::StillImage _location_graphic;
478
479 /** \brief A map containing all characters that the player has discovered
480 *** This map contains all characters that the player has met with, regardless of whether or not they are in the active party.
481 *** The map key is the character's unique ID number.
482 **/
483 std::map<uint32, GlobalCharacter*> _characters;
484
485 /** \brief A vector whose purpose is to maintain the order of characters
486 *** The first four characters in this vector are in the active party; the rest are in reserve.
487 **/
488 std::vector<GlobalCharacter*> _character_order;
489
490 /** \brief The active party of characters
491 *** The active party contains the group of characters that will fight when a battle begins.
492 *** This party can be up to four characters, and should always contain at least one character.
493 **/
494 GlobalParty _active_party;
495
496 /** \brief Retains a list of all of the objects currently stored in the player's inventory
497 *** This map is used to quickly check if an item is in the inventory or not. The key to the map is the object's
498 *** identification number. When an object is added to the inventory, if it already exists then the object counter
499 *** is simply increased instead of adding an entire new class object. When the object count becomes zero, the object
500 *** is removed from the inventory. Duplicates of all objects are retained in the various inventory containers below.
501 **/
502 std::map<uint32, GlobalObject*> _inventory;
503
504 /** \brief Inventory containers
505 *** These vectors contain the inventory of the entire party. The vectors are sorted according to the player's personal preferences.
506 *** When a new object is added to the inventory, by default it will be placed at the end of the vector.
507 **/
508 //@{
509 std::vector<GlobalItem*> _inventory_items;
510 std::vector<GlobalWeapon*> _inventory_weapons;
511 std::vector<GlobalArmor*> _inventory_head_armor;
512 std::vector<GlobalArmor*> _inventory_torso_armor;
513 std::vector<GlobalArmor*> _inventory_arm_armor;
514 std::vector<GlobalArmor*> _inventory_leg_armor;
515 std::vector<GlobalShard*> _inventory_shards;
516 std::vector<GlobalKeyItem*> _inventory_key_items;
517 //@}
518
519 //! \name Global data and function script files
520 //@{
521 //! \brief Contains character ID definitions and a number of useful functions
522 hoa_script::ReadScriptDescriptor _global_script;
523
524 //! \brief Contains data definitions for all items
525 hoa_script::ReadScriptDescriptor _items_script;
526
527 //! \brief Contains data definitions for all weapons
528 hoa_script::ReadScriptDescriptor _weapons_script;
529
530 //! \brief Contains data definitions for all armor that are equipped on the head
531 hoa_script::ReadScriptDescriptor _head_armor_script;
532
533 //! \brief Contains data definitions for all armor that are equipped on the torso
534 hoa_script::ReadScriptDescriptor _torso_armor_script;
535
536 //! \brief Contains data definitions for all armor that are equipped on the arms
537 hoa_script::ReadScriptDescriptor _arm_armor_script;
538
539 //! \brief Contains data definitions for all armor that are equipped on the legs
540 hoa_script::ReadScriptDescriptor _leg_armor_script;
541
542 //! \brief Contains data definitions for all shards
543 // hoa_script::ReadScriptDescriptor _shard_script;
544
545 //! \brief Contains data definitions for all key items
546 // hoa_script::ReadScriptDescriptor _key_items_script;
547
548 //! \brief Contains data and functional definitions for all attack skills
549 hoa_script::ReadScriptDescriptor _attack_skills_script;
550
551 //! \brief Contains data and functional definitions for all defense skills
552 hoa_script::ReadScriptDescriptor _defend_skills_script;
553
554 //! \brief Contains data and functional definitions for all support skills
555 hoa_script::ReadScriptDescriptor _support_skills_script;
556
557 //! \brief Contains functional definitions for all status effects
558 hoa_script::ReadScriptDescriptor _status_effects_script;
559
560 //! \brief Contains data and functional definitions for sprites seen in game maps
561 hoa_script::ReadScriptDescriptor _map_sprites_script;
562
563 //! \brief Contains data and functional definitions for scripted events in key game battles
564 hoa_script::ReadScriptDescriptor _battle_events_script;
565 //@}
566
567 /** \brief The container which stores all of the groups of events that have occured in the game
568 *** The name of each GlobalEventGroup object serves as its key in this map data structure.
569 **/
570 std::map<std::string, GlobalEventGroup*> _event_groups;
571
572 // ----- Private methods
573
574 /** \brief A helper template function that finds and removes an object from the inventory
575 *** \param obj_id The ID of the object to remove from the inventory
576 *** \param inv The vector container of the appropriate inventory type
577 *** \return True if the object was successfully removed, or false if it was not
578 **/
579 template <class T> bool _RemoveFromInventory(uint32 obj_id, std::vector<T*>& inv);
580
581 /** \brief A helper template function that finds and returns a copy of an object from the inventory
582 *** \param obj_id The ID of the object to remove from the inventory
583 *** \param inv The vector container of the appropriate inventory type
584 *** \param all_counts If false the object's count is decremented by one from the inventory, otherwise all counts are removed completely
585 *** \return A pointer to the newly created copy of the object, or NULL if the object could not be found
586 **/
587 template <class T> T* _RetrieveFromInventory(uint32 obj_id, std::vector<T*>& inv, bool all_counts);
588
589 /** \brief A helper function to GameGlobal::SaveGame() that stores the contents of a type of inventory to the saved game file
590 *** \param file A reference to the open and valid file where to write the inventory list
591 *** \param name The name under which this set of inventory data should be categorized (ie "items", "weapons", etc)
592 *** \param inv A reference to the inventory vector to store
593 *** \note The class type T must be a derived class of GlobalObject
594 **/
595 template <class T> void _SaveInventory(hoa_script::WriteScriptDescriptor& file, std::string name, std::vector<T*>& inv);
596
597 /** \brief A helper function to GameGlobal::SaveGame() that writes character data to the saved game file
598 *** \param file A reference to the open and valid file where to write the character data
599 *** \param objects A ponter to the character whose data should be saved
600 *** \param last Set to true if this is the final character that needs to be saved
601 *** This method will need to be called once for each character in the player's party
602 **/
603 void _SaveCharacter(hoa_script::WriteScriptDescriptor& file, GlobalCharacter* character, bool last);
604
605 /** \brief A helper function to GameGlobal::SaveGame() that writes a group of event data to the saved game file
606 *** \param file A reference to the open and valid file where to write the event data
607 *** \param event_group A pointer to the group of events to store
608 *** This method will need to be called once for each GlobalEventGroup contained by this class.
609 **/
610 void _SaveEvents(hoa_script::WriteScriptDescriptor& file, GlobalEventGroup* event_group);
611
612 /** \brief A helper function to GameGlobal::LoadGame() that restores the contents of the inventory from a saved game file
613 *** \param file A reference to the open and valid file from where to read the inventory list
614 *** \param category_name The name of the table in the file that should contain the inventory for a specific category
615 **/
616 void _LoadInventory(hoa_script::ReadScriptDescriptor& file, std::string category_name);
617
618 /** \brief A helper function to GameGlobal::LoadGame() that loads a saved game character and adds it to the party
619 *** \param file A reference to the open and valid file from where to read the character from
620 *** \param id The character's integer ID, used to find and restore the character data
621 **/
622 void _LoadCharacter(hoa_script::ReadScriptDescriptor& file, uint32 id);
623
624 /** \brief A helper function to GameGlobal::LoadGame() that loads a group of game events from a saved game file
625 *** \param file A reference to the open and valid file from where to read the event data from
626 *** \param group_name The name of the event group to load
627 **/
628 void _LoadEvents(hoa_script::ReadScriptDescriptor& file, const std::string& group_name);
629 }; // class GameGlobal : public hoa_utils::Singleton<GameGlobal>
630
631 //-----------------------------------------------------------------------------
632 // Template Function Definitions
633 //-----------------------------------------------------------------------------
634
_RemoveFromInventory(uint32 obj_id,std::vector<T * > & inv)635 template <class T> bool GameGlobal::_RemoveFromInventory(uint32 obj_id, std::vector<T*>& inv) {
636 for (typename std::vector<T*>::iterator i = inv.begin(); i != inv.end(); i++) {
637 if ((*i)->GetID() == obj_id) {
638 // Delete the object, remove it from the vector container, and remove it from the _inventory map
639 delete _inventory[obj_id];
640 inv.erase(i);
641 _inventory.erase(obj_id);
642 return true;
643 }
644 }
645
646 return false;
647 } // template <class T> bool GameGlobal::_RemoveFromInventory(uint32 obj_id, std::vector<T*>& inv)
648
649
650
_RetrieveFromInventory(uint32 obj_id,std::vector<T * > & inv,bool all_counts)651 template <class T> T* GameGlobal::_RetrieveFromInventory(uint32 obj_id, std::vector<T*>& inv, bool all_counts) {
652 for (typename std::vector<T*>::iterator i = inv.begin(); i != inv.end(); i++) {
653 if ((*i)->GetID() == obj_id) {
654 T* return_object;
655 if (all_counts == true || _inventory[obj_id]->GetCount() == 1) {
656 return_object = *i;
657 _inventory.erase(obj_id);
658 inv.erase(i);
659 }
660 else {
661 return_object = new T(**i);
662 return_object->SetCount(1);
663 _inventory[obj_id]->DecrementCount();
664 }
665 return return_object;
666 }
667 }
668
669 return NULL;
670 } // template <class T> T* GameGlobal::_RetrieveFromInventory(uint32 obj_id, std::vector<T*>& inv, bool all_counts)
671
672
673
_SaveInventory(hoa_script::WriteScriptDescriptor & file,std::string name,std::vector<T * > & inv)674 template <class T> void GameGlobal::_SaveInventory(hoa_script::WriteScriptDescriptor& file, std::string name, std::vector<T*>& inv) {
675 if (file.IsFileOpen() == false) {
676 IF_PRINT_WARNING(GLOBAL_DEBUG) << "failed because the argument file was not open" << std::endl;
677 return;
678 }
679
680 file.InsertNewLine();
681 file.WriteLine(name + " = {");
682 for (uint32 i = 0; i < inv.size(); i++) {
683 if (i == 0)
684 file.WriteLine("\t", false);
685 else
686 file.WriteLine(", ", false);
687 file.WriteLine("[" + hoa_utils::NumberToString(inv[i]->GetID()) + "] = "
688 + hoa_utils::NumberToString(inv[i]->GetCount()), false);
689 }
690 file.InsertNewLine();
691 file.WriteLine("}");
692 } // template <class T> void GameGlobal::_SaveInventory(hoa_script::WriteScriptDescriptor& file, std::string name, std::vector<T*>& inv)
693
694 } // namespace hoa_global
695
696 #endif // __GLOBAL_HEADER__
697