#include #include #include "esm_store.hpp" using namespace ESM; using namespace std; struct RecList { virtual void load(ESMReader &esm) = 0; virtual int getSize() = 0; virtual const string& getName() = 0; }; /* Lists all the list types. Mostly used for quick lookup on loading. The index is the record name (4 chars) parsed as a 32 bit int. Eg. REC_ACTI, REC_BOOK etc. See esm/records.hpp for the complete list. */ typedef map RecListList; RecListList recLists; template struct RecListIDT : RecList { // Store ourselves in the list of all lists RecListIDT() { recLists[RecID] = this; } }; template struct RecListT : RecListIDT { typedef map MapType; MapType list; string listName; RecListT(const string &name) : listName(name) {} void load(ESMReader &esm) { string id = esm.getHNString("NAME"); X &ref = list[id]; ref.load(esm); } int getSize() { return list.size(); } const string& getName() { return listName; } }; // The only difference to the above is a slight change to the load() // function. We might merge these together later, and store the id in // all the structs. template struct RecIDListT : RecListIDT { typedef map MapType; MapType list; string listName; RecIDListT(const string &name) : listName(name) {} void load(ESMReader &esm) { string id = esm.getHNString("NAME"); X &ref = list[id]; ref.id = id; ref.load(esm); } int getSize() { return list.size(); } const string& getName() { return listName; } }; // Cells aren't simply indexed by name. Exterior cells are treated // separately. struct CellList : RecListIDT { // Just count them for now int count; string listName; CellList() { listName = "Cells"; } void load(ESMReader &esm) { count++; esm.skipRecord(); } int getSize() { return count; } const string& getName() { return listName; } }; /* We need special lists for: Cells (partially done) Magic effects Skills Dialog / Info combo Scripts Land Path grids Land textures */ RecListT activators ("Activators"); RecListT potions ("Potions"); RecListT appas ("Apparatuses"); RecListT armors ("Armors"); RecListT bodyParts ("Body parts"); RecListT books ("Books"); RecListT birthSigns ("Birth signs"); CellList cells; RecListT classes ("Classes"); RecListT clothes ("Clothes"); RecListT contChange ("Container changes"); RecListT containers ("Containers"); RecListT creatures ("Creatures"); RecListT creaChange ("Creature changes"); RecListT dialogs ("Dialogues"); RecListT doors ("Doors"); RecListT enchants ("Enchantments"); RecListT factions ("Factions"); RecListT globals ("Globals"); RecIDListTgameSettings ("Game settings"); //RecListT dialInfos ("Dialog entries"); RecListT ingreds ("Ingredients"); //RecListT lands ("Land data"); RecListT creatureLists("Creature leveled lists"); RecListT itemLists ("Item leveled lists"); RecListT lights ("Lights"); RecListT lockpicks ("Lockpicks"); //RecListT landTexts ("Land textures"); //RecListT magicEffects ("Magic effects"); RecListT miscItems ("Misc items"); RecListT npcs ("NPCs"); RecListT npcChange ("NPC changes"); //RecListT pathgrids ("Path grids"); RecListT probes ("Probes"); RecListT races ("Races"); RecListT regions ("Regions"); RecListT repairs ("Repair items"); //RecListT scripts ("Scripts"); //RecListT skills ("Skills"); RecListT soundGens ("Sound generators"); RecListT sounds ("Sounds"); RecListT spells ("Spells"); RecListT startScripts ("Start scripts"); RecListT statics ("Statics"); RecListT weapons ("Weapons"); void storeESM(ESMReader &esm) { // Loop through all records while(esm.hasMoreRecs()) { NAME n = esm.getRecName(); esm.getRecHeader(); // Look up the record type. RecListList::iterator it = recLists.find(n.val); if(it == recLists.end()) { // Not found (this would be an error later) esm.skipRecord(); continue; } // Load it it->second->load(esm); } cout << "\n" << recLists.size() << " record types:\n"; for(RecListList::iterator it = recLists.begin(); it != recLists.end(); it++) cout << " " << it->second->getName() << ": " << it->second->getSize() << endl; }