mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
ESM storage, take two
This commit is contained in:
parent
e534431022
commit
8c21616ce5
4 changed files with 223 additions and 154 deletions
88
game/esm_reclists.hpp
Normal file
88
game/esm_reclists.hpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#ifndef _GAME_ESM_RECLISTS_H
|
||||||
|
#define _GAME_ESM_RECLISTS_H
|
||||||
|
|
||||||
|
#include "esm/records.hpp"
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ESMS
|
||||||
|
{
|
||||||
|
using namespace ESM;
|
||||||
|
|
||||||
|
struct RecList
|
||||||
|
{
|
||||||
|
virtual void load(ESMReader &esm) = 0;
|
||||||
|
virtual int getSize() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<int,RecList*> RecListList;
|
||||||
|
|
||||||
|
template <typename X>
|
||||||
|
struct RecListT : RecList
|
||||||
|
{
|
||||||
|
typedef std::map<std::string,X> MapType;
|
||||||
|
|
||||||
|
MapType list;
|
||||||
|
|
||||||
|
void load(ESMReader &esm)
|
||||||
|
{
|
||||||
|
std::string id = esm.getHNString("NAME");
|
||||||
|
|
||||||
|
X &ref = list[id];
|
||||||
|
ref.load(esm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSize() { return list.size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 <typename X>
|
||||||
|
struct RecIDListT : RecList
|
||||||
|
{
|
||||||
|
typedef std::map<std::string,X> MapType;
|
||||||
|
|
||||||
|
MapType list;
|
||||||
|
|
||||||
|
void load(ESMReader &esm)
|
||||||
|
{
|
||||||
|
std::string id = esm.getHNString("NAME");
|
||||||
|
|
||||||
|
X &ref = list[id];
|
||||||
|
ref.id = id;
|
||||||
|
ref.load(esm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSize() { return list.size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cells aren't simply indexed by name. Exterior cells are treated
|
||||||
|
// separately.
|
||||||
|
struct CellList : RecList
|
||||||
|
{
|
||||||
|
// Just count them for now
|
||||||
|
int count;
|
||||||
|
|
||||||
|
void load(ESMReader &esm)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
esm.skipRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSize() { return count; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* We need special lists for:
|
||||||
|
|
||||||
|
Cells (in progress)
|
||||||
|
Magic effects
|
||||||
|
Skills
|
||||||
|
Dialog / Info combo
|
||||||
|
Scripts
|
||||||
|
Land
|
||||||
|
Path grids
|
||||||
|
Land textures
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1,163 +1,23 @@
|
||||||
#include <map>
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "esm_store.hpp"
|
#include "esm_store.hpp"
|
||||||
|
|
||||||
using namespace ESM;
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace ESM;
|
||||||
|
using namespace ESMS;
|
||||||
|
|
||||||
struct RecList
|
static string toStr(int i)
|
||||||
{
|
{
|
||||||
virtual void load(ESMReader &esm) = 0;
|
char name[5];
|
||||||
virtual int getSize() = 0;
|
*((int*)name) = i;
|
||||||
virtual const string& getName() = 0;
|
name[4] = 0;
|
||||||
};
|
return std::string(name);
|
||||||
|
}
|
||||||
|
|
||||||
/* Lists all the list types. Mostly used for quick lookup on
|
void ESMStore::load(ESMReader &esm)
|
||||||
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<int,RecList*> RecListList;
|
|
||||||
RecListList recLists;
|
|
||||||
|
|
||||||
template <int RecID>
|
|
||||||
struct RecListIDT : RecList
|
|
||||||
{
|
{
|
||||||
// Store ourselves in the list of all lists
|
set<string> missing;
|
||||||
RecListIDT() { recLists[RecID] = this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int RecID, typename X>
|
|
||||||
struct RecListT : RecListIDT<RecID>
|
|
||||||
{
|
|
||||||
typedef map<string,X> 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 <int RecID, typename X>
|
|
||||||
struct RecIDListT : RecListIDT<RecID>
|
|
||||||
{
|
|
||||||
typedef map<string,X> 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<REC_CELL>
|
|
||||||
{
|
|
||||||
// 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<REC_ACTI, Activator> activators ("Activators");
|
|
||||||
RecListT<REC_ALCH, Potion> potions ("Potions");
|
|
||||||
RecListT<REC_APPA, Apparatus> appas ("Apparatuses");
|
|
||||||
RecListT<REC_ARMO, Armor> armors ("Armors");
|
|
||||||
RecListT<REC_BODY, BodyPart> bodyParts ("Body parts");
|
|
||||||
RecListT<REC_BOOK, Book> books ("Books");
|
|
||||||
RecListT<REC_BSGN, BirthSign> birthSigns ("Birth signs");
|
|
||||||
CellList cells;
|
|
||||||
RecListT<REC_CLAS, Class> classes ("Classes");
|
|
||||||
RecListT<REC_CLOT, Clothing> clothes ("Clothes");
|
|
||||||
RecListT<REC_CNTC, LoadCNTC> contChange ("Container changes");
|
|
||||||
RecListT<REC_CONT, Container> containers ("Containers");
|
|
||||||
RecListT<REC_CREA, Creature> creatures ("Creatures");
|
|
||||||
RecListT<REC_CREC, LoadCREC> creaChange ("Creature changes");
|
|
||||||
RecListT<REC_DIAL, Dialogue> dialogs ("Dialogues");
|
|
||||||
RecListT<REC_DOOR, Door> doors ("Doors");
|
|
||||||
RecListT<REC_ENCH, Enchantment> enchants ("Enchantments");
|
|
||||||
RecListT<REC_FACT, Faction> factions ("Factions");
|
|
||||||
RecListT<REC_GLOB, Global> globals ("Globals");
|
|
||||||
RecIDListT<REC_GMST,GameSetting>gameSettings ("Game settings");
|
|
||||||
//RecListT<REC_INFO, DialInfo> dialInfos ("Dialog entries");
|
|
||||||
RecListT<REC_INGR, Ingredient> ingreds ("Ingredients");
|
|
||||||
//RecListT<REC_LAND, Land> lands ("Land data");
|
|
||||||
RecListT<REC_LEVC, CreatureLevList> creatureLists("Creature leveled lists");
|
|
||||||
RecListT<REC_LEVI, ItemLevList> itemLists ("Item leveled lists");
|
|
||||||
RecListT<REC_LIGH, Light> lights ("Lights");
|
|
||||||
RecListT<REC_LOCK, Tool> lockpicks ("Lockpicks");
|
|
||||||
//RecListT<REC_LTEX, LandTexture> landTexts ("Land textures");
|
|
||||||
//RecListT<REC_MGEF, MagicEffect> magicEffects ("Magic effects");
|
|
||||||
RecListT<REC_MISC, Misc> miscItems ("Misc items");
|
|
||||||
RecListT<REC_NPC_, NPC> npcs ("NPCs");
|
|
||||||
RecListT<REC_NPCC, LoadNPCC> npcChange ("NPC changes");
|
|
||||||
//RecListT<REC_PGRD, PathGrid> pathgrids ("Path grids");
|
|
||||||
RecListT<REC_PROB, Tool> probes ("Probes");
|
|
||||||
RecListT<REC_RACE, Race> races ("Races");
|
|
||||||
RecListT<REC_REGN, Region> regions ("Regions");
|
|
||||||
RecListT<REC_REPA, Tool> repairs ("Repair items");
|
|
||||||
//RecListT<REC_SCPT, Script> scripts ("Scripts");
|
|
||||||
//RecListT<REC_SKIL, Skill> skills ("Skills");
|
|
||||||
RecListT<REC_SNDG, SoundGenerator> soundGens ("Sound generators");
|
|
||||||
RecListT<REC_SOUN, Sound> sounds ("Sounds");
|
|
||||||
RecListT<REC_SPEL, Spell> spells ("Spells");
|
|
||||||
RecListT<REC_SSCR, StartScript> startScripts ("Start scripts");
|
|
||||||
RecListT<REC_STAT, Static> statics ("Statics");
|
|
||||||
RecListT<REC_WEAP, Weapon> weapons ("Weapons");
|
|
||||||
|
|
||||||
void storeESM(ESMReader &esm)
|
|
||||||
{
|
|
||||||
// Loop through all records
|
// Loop through all records
|
||||||
while(esm.hasMoreRecs())
|
while(esm.hasMoreRecs())
|
||||||
{
|
{
|
||||||
|
@ -171,6 +31,7 @@ void storeESM(ESMReader &esm)
|
||||||
{
|
{
|
||||||
// Not found (this would be an error later)
|
// Not found (this would be an error later)
|
||||||
esm.skipRecord();
|
esm.skipRecord();
|
||||||
|
missing.insert(n.toString());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,5 +41,10 @@ void storeESM(ESMReader &esm)
|
||||||
|
|
||||||
cout << "\n" << recLists.size() << " record types:\n";
|
cout << "\n" << recLists.size() << " record types:\n";
|
||||||
for(RecListList::iterator it = recLists.begin(); it != recLists.end(); it++)
|
for(RecListList::iterator it = recLists.begin(); it != recLists.end(); it++)
|
||||||
cout << " " << it->second->getName() << ": " << it->second->getSize() << endl;
|
cout << " " << toStr(it->first) << ": " << it->second->getSize() << endl;
|
||||||
|
cout << "\nNot implemented yet: ";
|
||||||
|
for(set<string>::iterator it = missing.begin();
|
||||||
|
it != missing.end(); it++ )
|
||||||
|
cout << *it << " ";
|
||||||
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,121 @@
|
||||||
#define _GAME_ESM_STORE_H
|
#define _GAME_ESM_STORE_H
|
||||||
|
|
||||||
#include "esm/records.hpp"
|
#include "esm/records.hpp"
|
||||||
|
#include "esm_reclists.hpp"
|
||||||
|
|
||||||
void storeESM(ESM::ESMReader &esm);
|
namespace ESMS
|
||||||
|
{
|
||||||
|
using namespace ESM;
|
||||||
|
|
||||||
|
struct ESMStore
|
||||||
|
{
|
||||||
|
/* Lists all the list types. Mostly used for quick lookup on
|
||||||
|
loading. The key is the record name (4 chars) parsed as a 32
|
||||||
|
bit int. See esm/records.hpp for the complete list.
|
||||||
|
*/
|
||||||
|
RecListList recLists;
|
||||||
|
|
||||||
|
// Each individual list
|
||||||
|
RecListT<Activator> activators;
|
||||||
|
RecListT<Potion> potions;
|
||||||
|
RecListT<Apparatus> appas;
|
||||||
|
RecListT<Armor> armors;
|
||||||
|
RecListT<BodyPart> bodyParts;
|
||||||
|
RecListT<Book> books;
|
||||||
|
RecListT<BirthSign> birthSigns;
|
||||||
|
RecListT<Class> classes;
|
||||||
|
RecListT<Clothing> clothes;
|
||||||
|
RecListT<LoadCNTC> contChange;
|
||||||
|
RecListT<Container> containers;
|
||||||
|
RecListT<Creature> creatures;
|
||||||
|
RecListT<LoadCREC> creaChange;
|
||||||
|
RecListT<Dialogue> dialogs;
|
||||||
|
RecListT<Door> doors;
|
||||||
|
RecListT<Enchantment> enchants;
|
||||||
|
RecListT<Faction> factions;
|
||||||
|
RecListT<Global> globals;
|
||||||
|
RecListT<Ingredient> ingreds;
|
||||||
|
RecListT<CreatureLevList> creatureLists;
|
||||||
|
RecListT<ItemLevList> itemLists;
|
||||||
|
RecListT<Light> lights;
|
||||||
|
RecListT<Tool> lockpicks;
|
||||||
|
RecListT<Misc> miscItems;
|
||||||
|
RecListT<NPC> npcs;
|
||||||
|
RecListT<LoadNPCC> npcChange;
|
||||||
|
RecListT<Tool> probes;
|
||||||
|
RecListT<Race> races;
|
||||||
|
RecListT<Region> regions;
|
||||||
|
RecListT<Tool> repairs;
|
||||||
|
RecListT<SoundGenerator> soundGens;
|
||||||
|
RecListT<Sound> sounds;
|
||||||
|
RecListT<Spell> spells;
|
||||||
|
RecListT<StartScript> startScripts;
|
||||||
|
RecListT<Static> statics;
|
||||||
|
RecListT<Weapon> weapons;
|
||||||
|
|
||||||
|
// Lists that need special rules
|
||||||
|
CellList cells;
|
||||||
|
RecIDListT<GameSetting> gameSettings;
|
||||||
|
//RecListT<DialInfo> dialInfos;
|
||||||
|
//RecListT<Land> lands;
|
||||||
|
//RecListT<LandTexture> landTexts;
|
||||||
|
//RecListT<MagicEffect> magicEffects;
|
||||||
|
//RecListT<Script> scripts;
|
||||||
|
//RecListT<Skill> skills;
|
||||||
|
//RecListT<PathGrid> pathgrids;
|
||||||
|
|
||||||
|
ESMStore()
|
||||||
|
{
|
||||||
|
recLists[REC_ACTI] = &activators;
|
||||||
|
recLists[REC_ACTI] = &activators;
|
||||||
|
recLists[REC_ALCH] = &potions;
|
||||||
|
recLists[REC_APPA] = &appas;
|
||||||
|
recLists[REC_ARMO] = &armors;
|
||||||
|
recLists[REC_BODY] = &bodyParts;
|
||||||
|
recLists[REC_BOOK] = &books;
|
||||||
|
recLists[REC_BSGN] = &birthSigns;
|
||||||
|
recLists[REC_CELL] = &cells;
|
||||||
|
recLists[REC_CLAS] = &classes;
|
||||||
|
recLists[REC_CLOT] = &clothes;
|
||||||
|
recLists[REC_CNTC] = &contChange;
|
||||||
|
recLists[REC_CONT] = &containers;
|
||||||
|
recLists[REC_CREA] = &creatures;
|
||||||
|
recLists[REC_CREC] = &creaChange;
|
||||||
|
recLists[REC_DIAL] = &dialogs;
|
||||||
|
recLists[REC_DOOR] = &doors;
|
||||||
|
recLists[REC_ENCH] = &enchants;
|
||||||
|
recLists[REC_FACT] = &factions;
|
||||||
|
recLists[REC_GLOB] = &globals;
|
||||||
|
recLists[REC_GMST] = &gameSettings;
|
||||||
|
//recLists[REC_INFO] = &dialInfos;
|
||||||
|
recLists[REC_INGR] = &ingreds;
|
||||||
|
//recLists[REC_LAND] = &lands;
|
||||||
|
recLists[REC_LEVC] = &creatureLists;
|
||||||
|
recLists[REC_LEVI] = &itemLists;
|
||||||
|
recLists[REC_LIGH] = &lights;
|
||||||
|
recLists[REC_LOCK] = &lockpicks;
|
||||||
|
//recLists[REC_LTEX] = &landTexts;
|
||||||
|
//recLists[REC_MGEF] = &magicEffects;
|
||||||
|
recLists[REC_MISC] = &miscItems;
|
||||||
|
recLists[REC_NPC_] = &npcs;
|
||||||
|
recLists[REC_NPCC] = &npcChange;
|
||||||
|
//recLists[REC_PGRD] = &pathgrids;
|
||||||
|
recLists[REC_PROB] = &probes;
|
||||||
|
recLists[REC_RACE] = &races;
|
||||||
|
recLists[REC_REGN] = ®ions;
|
||||||
|
recLists[REC_REPA] = &repairs;
|
||||||
|
//recLists[REC_SCPT] = &scripts;
|
||||||
|
//recLists[REC_SKIL] = &skills;
|
||||||
|
recLists[REC_SNDG] = &soundGens;
|
||||||
|
recLists[REC_SOUN] = &sounds;
|
||||||
|
recLists[REC_SPEL] = &spells;
|
||||||
|
recLists[REC_SSCR] = &startScripts;
|
||||||
|
recLists[REC_STAT] = &statics;
|
||||||
|
recLists[REC_WEAP] = &weapons;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load(ESMReader &esm);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,7 +37,8 @@ void maintest()
|
||||||
cout << "Loading ESM " << esmFile << "\n";
|
cout << "Loading ESM " << esmFile << "\n";
|
||||||
ESM::ESMReader esm;
|
ESM::ESMReader esm;
|
||||||
esm.open(esmFile);
|
esm.open(esmFile);
|
||||||
storeESM(esm);
|
ESMS::ESMStore store;
|
||||||
|
store.load(esm);
|
||||||
esm.close();
|
esm.close();
|
||||||
|
|
||||||
cout << "\nThat's all for now!\n";
|
cout << "\nThat's all for now!\n";
|
||||||
|
|
Loading…
Reference in a new issue