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