global.cpp

Go to the documentation of this file.
00001 
00002 //            Copyright (C) 2004-2007 by The Allacrost Project
00003 //                         All Rights Reserved
00004 //
00005 // This code is licensed under the GNU GPL version 2. It is free software
00006 // and you may modify it and/or redistribute it under the terms of this license.
00007 // See http://www.gnu.org/copyleft/gpl.html for details.
00009 
00016 #include <iostream>
00017 
00018 #include "utils.h"
00019 #include "global.h"
00020 
00021 #include "video.h"
00022 #include "script.h"
00023 #include "system.h"
00024 
00025 using namespace std;
00026 
00027 using namespace hoa_utils;
00028 
00029 using namespace hoa_video;
00030 using namespace hoa_script;
00031 using namespace hoa_system;
00032 
00033 template<> hoa_global::GameGlobal* Singleton<hoa_global::GameGlobal>::_singleton_reference = 0;
00034 
00035 namespace hoa_global {
00036 
00037 using namespace private_global;
00038 
00039 GameGlobal* GlobalManager = NULL;
00040 bool GLOBAL_DEBUG = false;
00041 
00042 // -----------------------------------------------------------------------------
00043 // GlobalEventGroup class
00044 // -----------------------------------------------------------------------------
00045 
00046 void GlobalEventGroup::AddNewEvent(const std::string& event_name, int32 event_value) {
00047   if (DoesEventExist(event_name) == true) {
00048     if (GLOBAL_DEBUG)
00049       cerr << "GLOBAL WARNING: GlobalEventGroup::AddNewEvent() could not add the event because an event "
00050         << "with the name \"" << event_name  << "\" already existed in event group: " << _group_name << endl;
00051     return;
00052   }
00053   _events.insert(make_pair(event_name, event_value));
00054 }
00055 
00056 
00057 
00058 int32 GlobalEventGroup::GetEvent(const std::string& event_name) {
00059   map<string, int32>::iterator event_iter = _events.find(event_name);
00060   if (event_iter == _events.end()) {
00061     if (GLOBAL_DEBUG)
00062       cerr << "GLOBAL WARNING: GlobalEventGroup::GetEvent() could not retrieve the event value because "
00063         << "the event name \"" << event_name  << "\" did not exist in event group: " << _group_name << endl;
00064     return GLOBAL_BAD_EVENT;
00065   }
00066   return event_iter->second;
00067 }
00068 
00069 
00070 
00071 void GlobalEventGroup::SetEvent(const std::string& event_name, int32 event_value) {
00072   map<string, int32>::iterator event_iter = _events.find(event_name);
00073   if (event_iter == _events.end()) {
00074     if (GLOBAL_DEBUG)
00075       cerr << "GLOBAL WARNING: GlobalEventGroup::SetEvent() could not set the event value because "
00076         << "the event name \"" << event_name  << "\" did not exist in event group: " << _group_name << endl;
00077     return;
00078   }
00079   event_iter->second = event_value;
00080 }
00081 
00082 // -----------------------------------------------------------------------------
00083 // GameGlobal class - Initialization and Destruction
00084 // -----------------------------------------------------------------------------
00085 
00086 GameGlobal::GameGlobal() {
00087   if (GLOBAL_DEBUG)
00088     cout << "GLOBAL: GameGlobal constructor invoked" << endl;
00089 }
00090 
00091 
00092 
00093 GameGlobal::~GameGlobal() {
00094   if (GLOBAL_DEBUG)
00095     cout << "GLOBAL: GameGlobal destructor invoked" << endl;
00096 
00097   ClearAllData();
00098 
00099   // Close all persistent script files
00100   _items_script.CloseTable();
00101   _weapons_script.CloseTable();
00102   _head_armor_script.CloseTable();
00103   _torso_armor_script.CloseTable();
00104   _arm_armor_script.CloseTable();
00105   _leg_armor_script.CloseTable();
00106   _attack_skills_script.CloseTable();
00107 
00108   _items_script.CloseFile();
00109   _weapons_script.CloseFile();
00110   _head_armor_script.CloseFile();
00111   _torso_armor_script.CloseFile();
00112   _arm_armor_script.CloseFile();
00113   _leg_armor_script.CloseFile();
00114   _attack_skills_script.CloseFile();
00115 }
00116 
00117 
00118 
00119 bool GameGlobal::SingletonInitialize() {
00120   // Open up the persistent script files
00121   if (_items_script.OpenFile("dat/objects/items.lua") == false) {
00122     return false;
00123   }
00124   _items_script.OpenTable("items");
00125 
00126   if (_weapons_script.OpenFile("dat/objects/weapons.lua") == false) {
00127     return false;
00128   }
00129   _weapons_script.OpenTable("weapons");
00130 
00131   if (_head_armor_script.OpenFile("dat/objects/head_armor.lua") == false) {
00132     return false;
00133   }
00134   _head_armor_script.OpenTable("armor");
00135 
00136   if (_torso_armor_script.OpenFile("dat/objects/torso_armor.lua") == false) {
00137     return false;
00138   }
00139   _torso_armor_script.OpenTable("armor");
00140 
00141   if (_arm_armor_script.OpenFile("dat/objects/arm_armor.lua") == false) {
00142     return false;
00143   }
00144   _arm_armor_script.OpenTable("armor");
00145 
00146   if (_leg_armor_script.OpenFile("dat/objects/leg_armor.lua") == false) {
00147     return false;
00148   }
00149   _leg_armor_script.OpenTable("armor");
00150 
00151   if (_attack_skills_script.OpenFile("dat/skills/attack.lua") == false) {
00152     return false;
00153   }
00154   _attack_skills_script.OpenTable("skills");
00155 
00156   return true;
00157 }
00158 
00159 
00160 
00161 void GameGlobal::ClearAllData() {
00162   // Delete all inventory objects
00163   for (map<uint32, GlobalObject*>::iterator i = _inventory.begin(); i != _inventory.end(); i++) {
00164     delete i->second;
00165   }
00166   _inventory.clear();
00167   _inventory_items.clear();
00168   _inventory_weapons.clear();
00169   _inventory_head_armor.clear();
00170   _inventory_torso_armor.clear();
00171   _inventory_arm_armor.clear();
00172   _inventory_leg_armor.clear();
00173   _inventory_shards.clear();
00174   _inventory_key_items.clear();
00175 
00176   // Delete all characters
00177   for (map<uint32, GlobalCharacter*>::iterator i = _characters.begin(); i != _characters.end(); i++) {
00178     delete i->second;
00179   }
00180   _characters.clear();
00181   _character_order.clear();
00182   _active_party.RemoveAllActors();
00183 
00184   // Delete all event groups
00185   for (map<string, GlobalEventGroup*>::iterator i = _event_groups.begin(); i != _event_groups.end(); i++) {
00186     delete (i->second);
00187   }
00188   _event_groups.clear();
00189 } // void GameGlobal::ClearAllData()
00190 
00191 // -----------------------------------------------------------------------------
00192 // GameGlobal class - Character Functions
00193 // -----------------------------------------------------------------------------
00194 
00195 void GameGlobal::AddCharacter(uint32 id) {
00196   if (_characters.find(id) != _characters.end()) {
00197     if (GLOBAL_DEBUG)
00198       cerr << "GLOBAL WARNING: attempted to add a character that already existed" << endl;
00199     return;
00200   }
00201 
00202   GlobalCharacter *ch = new GlobalCharacter(id);
00203   _characters.insert(make_pair(id, ch));
00204 
00205   // Add the new character to the active party if the active party contains less than four characters
00206   if (_character_order.size() < 4)
00207     _active_party.AddActor(ch);
00208 
00209   _character_order.push_back(ch);
00210 } // void GameGlobal::AddCharacter(uint32 id)
00211 
00212 
00213 
00214 void GameGlobal::AddCharacter(GlobalCharacter* ch) {
00215   if (_characters.find(ch->GetID()) != _characters.end()) {
00216     if (GLOBAL_DEBUG)
00217       cerr << "GLOBAL WARNING: attempted to add a character that already existed" << endl;
00218     return;
00219   }
00220 
00221   _characters.insert(make_pair(ch->GetID(), ch));
00222 
00223   // Add the new character to the active party if the active party contains less than four characters
00224   if (_character_order.size() < 4)
00225     _active_party.AddActor(ch);
00226 
00227   _character_order.push_back(ch);
00228 } // void GameGlobal::AddCharacter(GlobalCharacter* ch)
00229 
00230 
00231 
00232 void GameGlobal::RemoveCharacter(uint32 id) {
00233   map<uint32, GlobalCharacter*>::iterator ch = _characters.find(id);
00234 
00235   if (ch == _characters.end()) {
00236     if (GLOBAL_DEBUG)
00237       cerr << "GLOBAL WARNING: attempted to remove a character that did not exist" << endl;
00238     return;
00239   }
00240 
00241   delete(ch->second);
00242   _characters.erase(ch);
00243 
00244   for (vector<GlobalCharacter*>::iterator i = _character_order.begin(); i != _character_order.end(); i++) {
00245     if ((*i)->GetID() == id) {
00246       _character_order.erase(i);
00247 
00248       // Reform the active party, in case the removed character was a member of it
00249       _active_party.RemoveAllActors();
00250       for (uint32 j = 0; j < 4 || j >= _character_order.size(); j++) {
00251         _active_party.AddActor(_character_order[j]);
00252       }
00253     }
00254   }
00255 } // void GameGlobal::RemoveCharacter(uint32 id)
00256 
00257 
00258 
00259 GlobalCharacter* GameGlobal::GetCharacter(uint32 id) {
00260   map<uint32, GlobalCharacter*>::iterator ch = _characters.find(id);
00261   if (ch == _characters.end()) {
00262     if (GLOBAL_DEBUG)
00263       cerr << "GLOBAL WARNING: No character matching id #" << id << " found in party" << endl;
00264     return NULL;
00265   }
00266 
00267   return (ch->second);
00268 
00269 }
00270 
00271 // -----------------------------------------------------------------------------
00272 // GameGlobal class - Inventory Functions
00273 // -----------------------------------------------------------------------------
00274 
00275 void GameGlobal::AddToInventory(uint32 obj_id, uint32 obj_count) {
00276   // If the object is already in the inventory, increment the count of the object
00277   if (_inventory.find(obj_id) != _inventory.end()) {
00278     _inventory[obj_id]->IncrementCount(obj_count);
00279     return;
00280   }
00281 
00282   // Otherwise create a new object instance and add it to the inventory
00283   if (obj_id == 0) {
00284     cerr << "GLOBAL ERROR: Attempted to add invalid object to inventory with id: " << obj_id << endl;
00285   } else if (obj_id <= MAX_ITEM_ID) {
00286     GlobalItem *new_obj = new GlobalItem(obj_id, obj_count);
00287     _inventory.insert(make_pair(obj_id, new_obj));
00288     _inventory_items.push_back(new_obj);
00289   } else if (obj_id <= MAX_WEAPON_ID) {
00290     GlobalWeapon *new_obj = new GlobalWeapon(obj_id, obj_count);
00291     _inventory.insert(make_pair(obj_id, new_obj));
00292     _inventory_weapons.push_back(new_obj);
00293   } else if (obj_id <= MAX_HEAD_ARMOR_ID) {
00294     GlobalArmor *new_obj = new GlobalArmor(obj_id, obj_count);
00295     _inventory.insert(make_pair(obj_id, new_obj));
00296     _inventory_head_armor.push_back(new_obj);
00297   } else if (obj_id <= MAX_TORSO_ARMOR_ID) {
00298     GlobalArmor *new_obj = new GlobalArmor(obj_id, obj_count);
00299     _inventory.insert(make_pair(obj_id, new_obj));
00300     _inventory_torso_armor.push_back(new_obj);
00301   } else if (obj_id <= MAX_ARM_ARMOR_ID) {
00302     GlobalArmor *new_obj = new GlobalArmor(obj_id, obj_count);
00303     _inventory.insert(make_pair(obj_id, new_obj));
00304     _inventory_arm_armor.push_back(new_obj);
00305   } else if (obj_id <= MAX_LEG_ARMOR_ID) {
00306     GlobalArmor *new_obj = new GlobalArmor(obj_id, obj_count);
00307     _inventory.insert(make_pair(obj_id, new_obj));
00308     _inventory_leg_armor.push_back(new_obj);
00309   } else if (obj_id <= MAX_SHARD_ID) {
00310 //    GlobalShard *new_obj = new GlobalShard(obj_id, obj_count);
00311 //    _inventory.insert(make_pair(obj_id, new_obj));
00312 //    _inventory_shards.push_back(new_obj);
00313   } else if (obj_id <= MAX_KEY_ITEM_ID) {
00314 //    GlobalKeyItem *new_obj = new GlobalKeyItem(obj_id, obj_count);
00315 //    _inventory.insert(make_pair(obj_id, new_obj));
00316 //    _inventory_key_items.push_back(new_obj);
00317   } else {
00318     cerr << "GLOBAL ERROR: Attempted to add invalid object to inventory with id: " << obj_id << endl;
00319   }
00320 } // void GameGlobal::AddToInventory(uint32 obj_id)
00321 
00322 
00323 
00324 void GameGlobal::AddToInventory(GlobalObject* object) {
00325   if (object == NULL) {
00326     if (GLOBAL_DEBUG)
00327       cerr << "GLOBAL WARNING: GameGlobal::AddToInventory() invoked with a NULL object pointer" << endl;
00328     return;
00329   }
00330 
00331   uint32 obj_id = object->GetID();
00332   uint32 obj_count = object->GetCount();
00333 
00334   // If an instance of the same object is already inside the inventory, just increment the count and delete the object
00335   if (_inventory.find(obj_id) != _inventory.end()) {
00336     _inventory[obj_id]->IncrementCount(obj_count);
00337     delete object;
00338     return;
00339   }
00340 
00341   // Figure out which type of object this is, cast it to the correct type, and add it to the inventory
00342   if (obj_id == 0) {
00343     cerr << "GLOBAL ERROR: Attempted to add invalid object to inventory with id: " << obj_id << endl;
00344     delete object;
00345   } else if (obj_id <= MAX_ITEM_ID) {
00346     GlobalItem *new_obj = dynamic_cast<GlobalItem*>(object);
00347     _inventory.insert(make_pair(obj_id, new_obj));
00348     _inventory_items.push_back(new_obj);
00349   } else if (obj_id <= MAX_WEAPON_ID) {
00350     GlobalWeapon *new_obj = dynamic_cast<GlobalWeapon*>(object);
00351     _inventory.insert(make_pair(obj_id, new_obj));
00352     _inventory_weapons.push_back(new_obj);
00353   } else if (obj_id <= MAX_HEAD_ARMOR_ID) {
00354     GlobalArmor *new_obj = dynamic_cast<GlobalArmor*>(object);
00355     _inventory.insert(make_pair(obj_id, new_obj));
00356     _inventory_head_armor.push_back(new_obj);
00357   } else if (obj_id <= MAX_TORSO_ARMOR_ID) {
00358     GlobalArmor *new_obj = dynamic_cast<GlobalArmor*>(object);
00359     _inventory.insert(make_pair(obj_id, new_obj));
00360     _inventory_torso_armor.push_back(new_obj);
00361   } else if (obj_id <= MAX_ARM_ARMOR_ID) {
00362     GlobalArmor *new_obj = dynamic_cast<GlobalArmor*>(object);
00363     _inventory.insert(make_pair(obj_id, new_obj));
00364     _inventory_arm_armor.push_back(new_obj);
00365   } else if (obj_id <= MAX_LEG_ARMOR_ID) {
00366     GlobalArmor *new_obj = dynamic_cast<GlobalArmor*>(object);
00367     _inventory.insert(make_pair(obj_id, new_obj));
00368     _inventory_leg_armor.push_back(new_obj);
00369   } else if (obj_id <= MAX_SHARD_ID) {
00370 //    GlobalShard *new_obj = dynamic_cast<GlobalShard*>(object);
00371 //    _inventory.insert(make_pair(obj_id, new_obj));
00372 //    _inventory_shards.push_back(new_obj);
00373   } else if (obj_id <= MAX_KEY_ITEM_ID) {
00374 //    GlobalKeyItem *new_obj = dynamic_cast<GlobalKeyItem*>(object);
00375 //    _inventory.insert(make_pair(obj_id, new_obj));
00376 //    _inventory_key_items.push_back(new_obj);
00377   } else {
00378     cerr << "GLOBAL ERROR: Attempted to add invalid object to inventory with id: " << obj_id << endl;
00379     delete object;
00380   }
00381 } // void GameGlobal::AddToInventory(GlobalObject* object)
00382 
00383 
00384 
00385 void GameGlobal::RemoveFromInventory(uint32 obj_id) {
00386   if (_inventory.find(obj_id) == _inventory.end()) {
00387     cerr << "GLOBAL WARNING: attempted to delete an object from inventory that didn't exist, with id: " << obj_id << endl;
00388   }
00389 
00390   // Use the id value to figure out what type of object it is, and remove it from the object vector
00391   if (obj_id == 0) {
00392     cerr << "GLOBAL WARNING: attempted to remove invalid object to inventory with id: " << obj_id << endl;
00393   } else if (obj_id <= MAX_ITEM_ID) {
00394     if (_RemoveFromInventory(obj_id, _inventory_items) == false && GLOBAL_DEBUG)
00395       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_items vector" << endl;
00396   } else if (obj_id <= MAX_WEAPON_ID) {
00397     if (_RemoveFromInventory(obj_id, _inventory_weapons) == false && GLOBAL_DEBUG)
00398       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_weapons vector" << endl;
00399   } else if (obj_id <= MAX_HEAD_ARMOR_ID) {
00400     if (_RemoveFromInventory(obj_id, _inventory_head_armor) == false && GLOBAL_DEBUG)
00401       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_head_armor vector" << endl;
00402   } else if (obj_id <= MAX_TORSO_ARMOR_ID) {
00403     if (_RemoveFromInventory(obj_id, _inventory_torso_armor) == false && GLOBAL_DEBUG)
00404       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_torso_armor vector" << endl;
00405   } else if (obj_id <= MAX_ARM_ARMOR_ID) {
00406     if (_RemoveFromInventory(obj_id, _inventory_arm_armor) == false && GLOBAL_DEBUG)
00407       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_arm_armor vector" << endl;
00408   } else if (obj_id <= MAX_LEG_ARMOR_ID) {
00409     if (_RemoveFromInventory(obj_id, _inventory_leg_armor) == false && GLOBAL_DEBUG)
00410       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_leg_armor vector" << endl;
00411   } else if (obj_id <= MAX_SHARD_ID) {
00412     if (_RemoveFromInventory(obj_id, _inventory_shards) == false && GLOBAL_DEBUG)
00413       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_shards vector" << endl;
00414   } else if (obj_id < MAX_KEY_ITEM_ID) {
00415     if (_RemoveFromInventory(obj_id, _inventory_key_items) == false && GLOBAL_DEBUG)
00416       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_key_items vector" << endl;
00417   } else {
00418     cerr << "GLOBAL WARNING: attempted to remove invalid object from inventory with id: " << obj_id << endl;
00419   }
00420 } // void GameGlobal::RemoveFromInventory(uint32 obj_id)
00421 
00422 
00423 
00424 GlobalObject* GameGlobal::RetrieveFromInventory(uint32 obj_id, bool all_counts) {
00425   if (_inventory.find(obj_id) == _inventory.end()) {
00426     cerr << "GLOBAL WARNING: attempted to remove an object from inventory that didn't exist, with id: " << obj_id << endl;
00427     return NULL;
00428   }
00429 
00430   GlobalObject* return_object = NULL;
00431   // Use the id value to figure out what type of object it is, and remove it from the object vector
00432   if (obj_id == 0) {
00433     cerr << "GLOBAL WARNING: attempted to remove invalid object to inventory with id: " << obj_id << endl;
00434   } else if (obj_id <= MAX_ITEM_ID) {
00435     return_object = _RetrieveFromInventory(obj_id, _inventory_items, all_counts);
00436     if (return_object == NULL && GLOBAL_DEBUG)
00437       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_items vector" << endl;
00438   } else if (obj_id <= MAX_WEAPON_ID) {
00439     return_object = _RetrieveFromInventory(obj_id, _inventory_weapons, all_counts);
00440     if (return_object == NULL && GLOBAL_DEBUG)
00441       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_weapons vector" << endl;
00442   } else if (obj_id <= MAX_HEAD_ARMOR_ID) {
00443     return_object = _RetrieveFromInventory(obj_id, _inventory_head_armor, all_counts);
00444     if (return_object == NULL && GLOBAL_DEBUG)
00445       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_head_armor vector" << endl;
00446   } else if (obj_id <= MAX_TORSO_ARMOR_ID) {
00447     return_object = _RetrieveFromInventory(obj_id, _inventory_torso_armor, all_counts);
00448     if (return_object == NULL && GLOBAL_DEBUG)
00449       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_torso_armor vector" << endl;
00450   } else if (obj_id <= MAX_ARM_ARMOR_ID) {
00451     return_object = _RetrieveFromInventory(obj_id, _inventory_arm_armor, all_counts);
00452     if (return_object == NULL && GLOBAL_DEBUG)
00453       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_arm_armor vector" << endl;
00454   } else if (obj_id <= MAX_LEG_ARMOR_ID) {
00455     return_object = _RetrieveFromInventory(obj_id, _inventory_leg_armor, all_counts);
00456     if (return_object == NULL && GLOBAL_DEBUG)
00457       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_leg_armor vector" << endl;
00458   } else if (obj_id <= MAX_SHARD_ID) {
00459     return_object = _RetrieveFromInventory(obj_id, _inventory_shards, all_counts);
00460     if (return_object == NULL && GLOBAL_DEBUG)
00461       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_shards vector" << endl;
00462   } else if (obj_id <= MAX_KEY_ITEM_ID) {
00463     return_object = _RetrieveFromInventory(obj_id, _inventory_key_items, all_counts);
00464     if (return_object == NULL && GLOBAL_DEBUG)
00465       cerr << "GLOBAL WARNING: object to remove was not found in _inventory_key_items vector" << endl;
00466   } else {
00467     cerr << "GLOBAL WARNING: attempted to remove invalid object from inventory with id: " << obj_id << endl;
00468   }
00469 
00470   return return_object;
00471 } // GlobalObject* GameGlobal::RetrieveFromInventory(uint32 obj_id, bool all_counts)
00472 
00473 
00474 
00475 void GameGlobal::IncrementObjectCount(uint32 obj_id, uint32 count) {
00476   // Do nothing if the item does not exist in the inventory
00477   if (_inventory.find(obj_id) == _inventory.end()) {
00478     if (GLOBAL_DEBUG)
00479       cerr << "GLOBAL ERROR: attempted to increment object count for an object that wasn't in the inventory, id: " << obj_id << endl;
00480     return;
00481   }
00482 
00483   _inventory[obj_id]->IncrementCount(count);
00484 } // void GameGlobal::IncrementObjectCount(uint32 obj_id, uint32 count)
00485 
00486 
00487 
00488 void GameGlobal::DecrementObjectCount(uint32 obj_id, uint32 count) {
00489   // Do nothing if the item does not exist in the inventory
00490   if (_inventory.find(obj_id) == _inventory.end()) {
00491     if (GLOBAL_DEBUG)
00492       cerr << "GLOBAL WARNING: attempted to decrement object count for an object that wasn't in the inventory, id: " << obj_id << endl;
00493     return;
00494   }
00495 
00496   // Decrement the number of objects so long as the number to decrement by does not equal or exceed the count
00497   if (count < _inventory[obj_id]->GetCount()) {
00498     _inventory[obj_id]->DecrementCount(count);
00499   }
00500   // Remove the object from the inventory otherwise
00501   else {
00502     RemoveFromInventory(obj_id);
00503   }
00504 } // void GameGlobal::DecrementObjectCount(uint32 obj_id, uint32 count)
00505 
00506 // -----------------------------------------------------------------------------
00507 // GameGlobal class - Event Group Functions
00508 // -----------------------------------------------------------------------------
00509 
00510 bool GameGlobal::DoesEventExist(const string& group_name, const string& event_name) const {
00511   map<string, GlobalEventGroup*>::const_iterator group_iter = _event_groups.find(group_name);
00512   if (group_iter == _event_groups.end())
00513     return false;
00514 
00515   map<string, int32>::const_iterator event_iter = group_iter->second->_events.find(event_name);
00516   if (event_iter == group_iter->second->_events.end())
00517     return false;
00518 
00519   return true;
00520 } // bool GameGlobal::DoesEventExist(const std::string& group_name, const std::string& event_name) const
00521 
00522 
00523 
00524 void GameGlobal::AddNewEventGroup(const std::string& group_name) {
00525   if (DoesEventGroupExist(group_name) == true) {
00526     if (GLOBAL_DEBUG)
00527       cerr << "GLOBAL WARNING: GameGlobal::AddNewEventGroup() failed because there was already an event group "
00528         << "name that existed for the requested group name: " << group_name << endl;
00529     return;
00530   }
00531 
00532   GlobalEventGroup* geg = new GlobalEventGroup(group_name);
00533   _event_groups.insert(make_pair(group_name, geg));
00534 }
00535 
00536 
00537 
00538 GlobalEventGroup* GameGlobal::GetEventGroup(const std::string& group_name) const {
00539   map<string, GlobalEventGroup*>::const_iterator group_iter = _event_groups.find(group_name);
00540   if (group_iter == _event_groups.end()) {
00541     if (GLOBAL_DEBUG)
00542       cerr << "GLOBAL WARNING: GameGlobal::GetEventGroup() could not retrieve the event group because "
00543         << "there was no group event corresponding to the group name: " << group_name << endl;
00544     return NULL;
00545   }
00546   return (group_iter->second);
00547 }
00548 
00549 
00550 int32 GameGlobal::GetEventValue(const std::string& group_name, const std::string& event_name) const {
00551   map<string, GlobalEventGroup*>::const_iterator group_iter = _event_groups.find(group_name);
00552   if (group_iter == _event_groups.end())
00553     return GLOBAL_BAD_EVENT;
00554 
00555   map<string, int32>::const_iterator event_iter = group_iter->second->_events.find(event_name);
00556   if (event_iter == group_iter->second->_events.end())
00557     return GLOBAL_BAD_EVENT;
00558 
00559   return event_iter->second;
00560 } // int32 GameGlobal::GetEventValue(const std::string& group_name, const std::string& event_name) const
00561 
00562 
00563 
00564 uint32 GameGlobal::GetNumberEvents(const string& group_name) const {
00565   map<string, GlobalEventGroup*>::const_iterator group_iter = _event_groups.find(group_name);
00566   if (group_iter == _event_groups.end())
00567     return 0;
00568 
00569   return group_iter->second->GetNumberEvents();
00570 }
00571 
00572 // -----------------------------------------------------------------------------
00573 // GameGlobal class - Other Functions
00574 // -----------------------------------------------------------------------------
00575 
00576 void GameGlobal::SetLocation(const hoa_utils::ustring& location_name, const std::string& location_graphic_filename) {
00577   _location_name = location_name;
00578 
00579   VideoManager->DeleteImage(_location_graphic);
00580   _location_graphic.SetFilename(location_graphic_filename);
00581   if (VideoManager->LoadImage(_location_graphic) == false) {
00582     if (GLOBAL_DEBUG)
00583       cerr << "GLOBAL WARNING: GameGlobal::SetLocation() failed to load location graphic"
00584         << location_graphic_filename << endl;
00585   }
00586 }
00587 
00588 bool GameGlobal::SaveGame(string& filename) {
00589   WriteScriptDescriptor file;
00590   if (file.OpenFile(filename) == false) {
00591     return false;
00592   }
00593 
00594   // ----- (1) Save simple play data
00595   file.InsertNewLine();
00596   file.WriteString("location_name", MakeStandardString(_location_name));
00597   file.WriteString("location_graphic", _location_graphic.GetFilename());
00598   file.WriteUInt("play_hours", SystemManager->GetPlayHours());
00599   file.WriteUInt("play_minutes", SystemManager->GetPlayMinutes());
00600   file.WriteUInt("play_seconds", SystemManager->GetPlaySeconds());
00601   file.WriteUInt("drunes", _drunes);
00602 
00603   // ----- (2) Save the inventory (object id + object count pairs)
00604   // NOTE: This does not save any weapons/armor that are equipped on the characters. That data
00605   // is stored alongside the character data when it is saved
00606   _SaveInventory(file, "items", _inventory_items);
00607   _SaveInventory(file, "weapons", _inventory_weapons);
00608   _SaveInventory(file, "head_armor", _inventory_head_armor);
00609   _SaveInventory(file, "torso_armor", _inventory_torso_armor);
00610   _SaveInventory(file, "arm_armor", _inventory_arm_armor);
00611   _SaveInventory(file, "leg_armor", _inventory_leg_armor);
00612   _SaveInventory(file, "shards", _inventory_shards);
00613   _SaveInventory(file, "key_items", _inventory_key_items);
00614 
00615   // ----- (3) Save character data
00616   file.InsertNewLine();
00617   file.WriteLine("characters = {");
00618   // First save the order of the characters in the party
00619   file.WriteLine("\t[\"order\"] = {");
00620   for (uint32 i = 0; i < _character_order.size(); i++) {
00621     if (i == 0)
00622       file.WriteLine("\t\t" + NumberToString(_character_order[i]->GetID()), false);
00623     else
00624       file.WriteLine(", " + NumberToString(_character_order[i]->GetID()), false);
00625   }
00626   file.WriteLine("\n\t},");
00627 
00628   // Now save each individual character's data
00629   for (uint32 i = 0; i < _character_order.size(); i++) {
00630     if ((i + 1) == _character_order.size())
00631       _SaveCharacter(file, _character_order[i], true);
00632     else
00633       _SaveCharacter(file, _character_order[i], false);
00634   }
00635   file.WriteLine("}");
00636 
00637   // ----- (4) Save event data
00638   file.InsertNewLine();
00639   file.WriteLine("event_groups = {");
00640   for (map<string, GlobalEventGroup*>::iterator i = _event_groups.begin(); i != _event_groups.end(); i++) {
00641     _SaveEvents(file, i->second);
00642   }
00643   file.WriteLine("}");
00644 
00645   file.InsertNewLine();
00646   file.CloseFile();
00647   return true;
00648 } // bool GameGlobal::SaveGame(string& filename)
00649 
00650 
00651 
00652 bool GameGlobal::LoadGame(const string& filename) {
00653   ReadScriptDescriptor file;
00654   if (file.OpenFile(filename) == false) {
00655     return false;
00656   }
00657 
00658   // ----- (1) Load play data
00659   _location_name = MakeUnicodeString(file.ReadString("location_name"));
00660   _location_graphic.SetFilename(file.ReadString("location_graphic"));
00661   if (_location_graphic.Load() == false) {
00662     if (GLOBAL_DEBUG)
00663       cerr << "GLOBAL WARNING: GameGlobal::LoadGame() failed to load the location graphic: "
00664         << _location_graphic.GetFilename() << endl;
00665   }
00666   uint8 hours, minutes, seconds;
00667   hours = file.ReadUInt("play_hours");
00668   minutes = file.ReadUInt("play_minutes");
00669   seconds = file.ReadUInt("play_seconds");
00670   SystemManager->SetPlayTime(hours, minutes, seconds);
00671   _drunes = file.ReadUInt("drunes");
00672 
00673   // ----- (2) Load inventory
00674   _LoadInventory(file, "items");
00675   _LoadInventory(file, "weapons");
00676   _LoadInventory(file, "head_armor");
00677   _LoadInventory(file, "torso_armor");
00678   _LoadInventory(file, "arm_armor");
00679   _LoadInventory(file, "leg_armor");
00680   _LoadInventory(file, "shards");
00681   _LoadInventory(file, "key_items");
00682 
00683   // ----- (3) Load characters into the party in the correct order
00684   file.OpenTable("characters");
00685   vector<uint32> char_ids;
00686   file.ReadUIntVector("order", char_ids);
00687   for (uint32 i = 0; i < char_ids.size(); i++) {
00688     _LoadCharacter(file, char_ids[i]);
00689   }
00690   file.CloseTable();
00691 
00692   // ----- (4) Load event data
00693   vector<string> group_names;
00694   file.OpenTable("event_groups");
00695   file.ReadTableKeys(group_names);
00696   for (uint32 i = 0; i < group_names.size(); i++)
00697     _LoadEvents(file, group_names[i]);
00698   file.CloseTable();
00699 
00700   // ----- (5) Report any errors detected from the previous read operations
00701   if (file.IsErrorDetected()) {
00702     if (GLOBAL_DEBUG) {
00703       cerr << "GLOBAL WARNING: GameGlobal::LoadGame ran into errors when reading the game file. They are as follows:" << endl;
00704       cerr << file.GetErrorMessages() << endl;
00705       file.ClearErrors();
00706     }
00707   }
00708 
00709   file.CloseFile();
00710   
00711   return true;
00712 } // bool GameGlobal::LoadGame(string& filename)
00713 
00714 // -----------------------------------------------------------------------------
00715 // GameGlobal class - Private Methods
00716 // -----------------------------------------------------------------------------
00717 
00718 void GameGlobal::_SaveCharacter(WriteScriptDescriptor& file, GlobalCharacter* character, bool last) {
00719   if (file.IsFileOpen() == false) {
00720     if (GLOBAL_DEBUG)
00721       cerr << "GLOBAL WARNING: GameGlobal::_SaveCharacter() failed because the file argument was not an open file" << endl;
00722     return;
00723   }
00724   if (character == NULL) {
00725     if (GLOBAL_DEBUG)
00726       cerr << "GLOBAL WARNING: GameGlobal::_SaveCharacter() failed because the character argument was NULL" << endl;
00727     return;
00728   }
00729 
00730   file.WriteLine("\t[" + NumberToString(character->GetID()) + "] = {");
00731 
00732   // ----- (1): Write out the character's stats
00733   file.WriteLine("\t\texperience_level = " + NumberToString(character->GetExperienceLevel()) + ",");
00734   file.WriteLine("\t\texperience_points = " + NumberToString(character->GetExperiencePoints()) + ",");
00735   file.WriteLine("\t\texperience_points_next = " + NumberToString(character->GetExperienceForNextLevel()) + ", ");
00736 
00737   file.WriteLine("\t\tmax_hit_points = " + NumberToString(character->GetMaxHitPoints()) + ",");
00738   file.WriteLine("\t\thit_points = " + NumberToString(character->GetHitPoints()) + ",");
00739   file.WriteLine("\t\tmax_skill_points = " + NumberToString(character->GetMaxSkillPoints()) + ",");
00740   file.WriteLine("\t\tskill_points = " + NumberToString(character->GetSkillPoints()) + ",");
00741 
00742   file.WriteLine("\t\tstrength = " + NumberToString(character->GetStrength()) + ",");
00743   file.WriteLine("\t\tvigor = " + NumberToString(character->GetVigor()) + ",");
00744   file.WriteLine("\t\tfortitude = " + NumberToString(character->GetFortitude()) + ",");
00745   file.WriteLine("\t\tprotection = " + NumberToString(character->GetProtection()) + ",");
00746   file.WriteLine("\t\tagility = " + NumberToString(character->GetAgility()) + ",");
00747   file.WriteLine("\t\tevade = " + NumberToString(character->GetEvade()) + ",");
00748 
00749   // ----- (2): Write out the character's equipment
00750   uint32 weapon_id = 0;
00751   uint32 head_id = 0;
00752   uint32 torso_id = 0;
00753   uint32 arm_id = 0;
00754   uint32 leg_id = 0;
00755   GlobalObject *obj_tmp = NULL;
00756 
00757   obj_tmp = character->GetWeaponEquipped();
00758   if (obj_tmp != NULL)
00759     weapon_id = obj_tmp->GetID();
00760 
00761   obj_tmp = character->GetHeadArmorEquipped();
00762   if (obj_tmp != NULL)
00763     head_id = obj_tmp->GetID();
00764 
00765   obj_tmp = character->GetTorsoArmorEquipped();
00766   if (obj_tmp != NULL)
00767     torso_id = obj_tmp->GetID();
00768 
00769   obj_tmp = character->GetArmArmorEquipped();
00770   if (obj_tmp != NULL)
00771     arm_id = obj_tmp->GetID();
00772 
00773   obj_tmp = character->GetLegArmorEquipped();
00774   if (obj_tmp != NULL)
00775     leg_id = obj_tmp->GetID();
00776 
00777   file.InsertNewLine();
00778   file.WriteLine("\t\tequipment = {");
00779   file.WriteLine("\t\t\tweapon = " + NumberToString(weapon_id) + ",");
00780   file.WriteLine("\t\t\thead_armor = " + NumberToString(head_id) + ",");
00781   file.WriteLine("\t\t\ttorso_armor = " + NumberToString(torso_id) + ",");
00782   file.WriteLine("\t\t\tarm_armor = " + NumberToString(arm_id) + ",");
00783   file.WriteLine("\t\t\tleg_armor = " + NumberToString(leg_id));
00784   file.WriteLine("\t\t},");
00785 
00786   // ----- (3): Write out the character's skills
00787   std::vector<GlobalSkill*>* skill_vector;
00788 
00789   file.InsertNewLine();
00790   file.WriteLine("\t\tattack_skills = {");
00791   skill_vector = character->GetAttackSkills();
00792   for (uint32 i = 0; i < skill_vector->size(); i++) {
00793     if (i == 0)
00794       file.WriteLine("\t\t\t", false);
00795     else
00796       file.WriteLine(", ", false);
00797     file.WriteLine(NumberToString(skill_vector->at(i)->GetID()), false);
00798   }
00799   file.WriteLine("\n\t\t},");
00800 
00801   file.InsertNewLine();
00802   file.WriteLine("\t\tdefense_skills = {");
00803   skill_vector = character->GetDefenseSkills();
00804   for (uint32 i = 0; i < skill_vector->size(); i++) {
00805     if (i == 0)
00806       file.WriteLine("\t\t\t", false);
00807     else
00808       file.WriteLine(", ", false);
00809     file.WriteLine(NumberToString(skill_vector->at(i)->GetID()), false);
00810   }
00811   file.WriteLine("\n\t\t},");
00812 
00813   file.InsertNewLine();
00814   file.WriteLine("\t\tsupport_skills = {");
00815   skill_vector = character->GetSupportSkills();
00816   for (uint32 i = 0; i < skill_vector->size(); i++) {
00817     if (i == 0)
00818       file.WriteLine("\t\t\t", false);
00819     else
00820       file.WriteLine(", ", false);
00821     file.WriteLine(NumberToString(skill_vector->at(i)->GetID()), false);
00822   }
00823   file.WriteLine("\n\t\t}");
00824 
00825   if (last)
00826     file.WriteLine("\t}");
00827   else
00828     file.WriteLine("\t},");
00829 } // void GameGlobal::_SaveCharacter(WriteScriptDescriptor& file, GlobalCharacter* character, bool last)
00830 
00831 
00832 
00833 void GameGlobal::_SaveEvents(hoa_script::WriteScriptDescriptor& file, GlobalEventGroup* event_group) {
00834   if (file.IsFileOpen() == false) {
00835     if (GLOBAL_DEBUG)
00836       cerr << "GLOBAL WARNING: GameGlobal::_SaveEvents() failed because the file passed to it was not open" << endl;
00837     return;
00838   }
00839 
00840   if (event_group == NULL) {
00841     if (GLOBAL_DEBUG)
00842       cerr << "GLOBAL WARNING: GameGlobal::_SaveEvents() failed because the a NULL event group was passed to it" << endl;
00843     return;
00844   }
00845 
00846   file.WriteLine("\t" + event_group->GetGroupName() + " = {");
00847 
00848   for (map<string, int32>::iterator i = event_group->_events.begin(); i != event_group->_events.end(); i++) {
00849     if (i == event_group->_events.begin())
00850       file.WriteLine("\t\t", false);
00851     else
00852       file.WriteLine(", ", false);
00853     file.WriteLine("[\"" + i->first + "\"] = " + NumberToString(i->second), false);
00854   }
00855   file.WriteLine("\t}");
00856 } // GameGlobal::_SaveEvents(hoa_script::WriteScriptDescriptor& file, GlobalEventGroup* event_group)
00857 
00858 
00859 
00860 void GameGlobal::_LoadInventory(hoa_script::ReadScriptDescriptor& file, std::string category_name) {
00861   if (file.IsFileOpen() == false) {
00862     if (GLOBAL_DEBUG)
00863       cerr << "GLOBAL WARNING: GameGlobal::_LoadInventory() failed because the file passed to it was not open" << endl;
00864     return;
00865   }
00866 
00867   vector<uint32> object_ids;
00868 
00869   // The table keys are the inventory object ID numbers. The value of each key is the count of that object
00870   file.OpenTable(category_name);
00871   file.ReadTableKeys(object_ids);
00872   for (uint32 i = 0; i < object_ids.size(); i++) {
00873     AddToInventory(object_ids[i], file.ReadUInt(object_ids[i]));
00874   }
00875   file.CloseTable();
00876 } // void GameGlobal::_LoadInventory(hoa_script::ReadScriptDescriptor& file, std::string category_name)
00877 
00878 
00879 
00880 void GameGlobal::_LoadCharacter(hoa_script::ReadScriptDescriptor& file, uint32 id) {
00881   if (file.IsFileOpen() == false) {
00882     if (GLOBAL_DEBUG)
00883       cerr << "GLOBAL WARNING: GameGlobal::_LoadCharacter() failed because the file passed to it was not open" << endl;
00884     return;
00885   }
00886 
00887   // ----- (1): Create a new GlobalCharacter object using the provided id
00888   // This loads all of the character's "static" data, such as their name, etc.
00889   GlobalCharacter* character = new GlobalCharacter(id);
00890 
00891   // This function assumes that the characters table in the saved game file is already open.
00892   // So all we need to open is the character's table
00893   file.OpenTable(id);
00894 
00895   // ----- (2): Read in all of the character's stats data
00896   character->SetExperienceLevel(file.ReadUInt("experience_level"));
00897   character->SetExperiencePoints(file.ReadUInt("experience_points"));
00898 //  character->SetExperienceNextLevel(file.ReadUInt("experience_points_next"));
00899 
00900   character->SetMaxHitPoints(file.ReadUInt("max_hit_points"));
00901   character->SetHitPoints(file.ReadUInt("hit_points"));
00902   character->SetMaxSkillPoints(file.ReadUInt("max_skill_points"));
00903   character->SetSkillPoints(file.ReadUInt("skill_points"));
00904 
00905   character->SetStrength(file.ReadUInt("strength"));
00906   character->SetVigor(file.ReadUInt("vigor"));
00907   character->SetFortitude(file.ReadUInt("fortitude"));
00908   character->SetProtection(file.ReadUInt("protection"));
00909   character->SetAgility(file.ReadUInt("agility"));
00910   character->SetEvade(file.ReadUInt("evade"));
00911 
00912   // ----- (3): Read the character's equipment and load it onto the character
00913   file.OpenTable("equipment");
00914   uint32 equip_id;
00915 
00916   // Equip the objects on the character as long as valid equipment IDs were read
00917   equip_id = file.ReadUInt("weapon");
00918   if (equip_id != 0) {
00919     character->EquipWeapon(new GlobalWeapon(equip_id));
00920   }
00921 
00922   equip_id = file.ReadUInt("head_armor");
00923   if (equip_id != 0) {
00924     character->EquipHeadArmor(new GlobalArmor(equip_id));
00925   }
00926 
00927   equip_id = file.ReadUInt("torso_armor");
00928   if (equip_id != 0) {
00929     character->EquipTorsoArmor(new GlobalArmor(equip_id));
00930   }
00931 
00932   equip_id = file.ReadUInt("arm_armor");
00933   if (equip_id != 0) {
00934     character->EquipArmArmor(new GlobalArmor(equip_id));
00935   }
00936 
00937   equip_id = file.ReadUInt("leg_armor");
00938   if (equip_id != 0) {
00939     character->EquipLegArmor(new GlobalArmor(equip_id));
00940   }
00941 
00942   file.CloseTable();
00943 
00944   // ----- (4): Read the character's skills and pass those onto the character object
00945   vector<uint32> skill_ids;
00946 
00947   skill_ids.clear();
00948   file.ReadUIntVector("attack_skills", skill_ids);
00949   for (uint32 i = 0; i < skill_ids.size(); i++) {
00950     character->AddSkill(skill_ids[i]);
00951   }
00952 
00953   skill_ids.clear();
00954   file.ReadUIntVector("defense_skills", skill_ids);
00955   for (uint32 i = 0; i < skill_ids.size(); i++) {
00956     character->AddSkill(skill_ids[i]);
00957   }
00958 
00959   skill_ids.clear();
00960   file.ReadUIntVector("support_skills", skill_ids);
00961   for (uint32 i = 0; i < skill_ids.size(); i++) {
00962     character->AddSkill(skill_ids[i]);
00963   }
00964 
00965   file.CloseTable();
00966 
00967   AddCharacter(character);
00968 } // void GameGlobal::_LoadCharacter(hoa_script::ReadScriptDescriptor& file, uint32 id);
00969 
00970 
00971 
00972 void GameGlobal::_LoadEvents(hoa_script::ReadScriptDescriptor& file, const std::string& group_name) {
00973   if (file.IsFileOpen() == false) {
00974     if (GLOBAL_DEBUG)
00975       cerr << "GLOBAL WARNING: GameGlobal::_LoadEvents() failed because the file passed to it was not open" << endl;
00976     return;
00977   }
00978 
00979   AddNewEventGroup(group_name);
00980   GlobalEventGroup* new_group = GetEventGroup(group_name); // new_group is guaranteed not to be NULL
00981 
00982   vector<string> event_names;
00983 
00984   file.OpenTable(group_name);
00985   file.ReadTableKeys(event_names);
00986   for (uint32 i = 0; i < event_names.size(); i++) {
00987     new_group->AddNewEvent(event_names[i], file.ReadInt(event_names[i]));
00988   }
00989   file.CloseTable();
00990 } // void GameGlobal::_LoadEvents(hoa_script::ReadScriptDescriptor& file, const std::string& group_name)
00991 
00992 } // namespace hoa_global

Generated on Fri Jul 6 23:11:14 2007 for Hero of Allacrost by  doxygen 1.5.1