From 1e5768170f9a5458310b673b45db3a4c84479096 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Fri, 8 Apr 2011 17:58:21 +0400 Subject: [PATCH] Refactored remaining headers in components/esm except defs.hpp. Removed obsolete *.cpp files. --- CMakeLists.txt | 31 +++- components/esm/class.cpp | 15 -- components/esm/load_impl.cpp | 175 ------------------- components/esm/loadclas.cpp | 12 ++ components/esm/loadcont.cpp | 33 ++++ components/esm/loadcont.hpp | 50 ++---- components/esm/loadcrea.cpp | 40 +++++ components/esm/loadcrea.hpp | 109 ++++-------- components/esm/loaddial.cpp | 25 +++ components/esm/loaddial.hpp | 39 ++--- components/esm/loaddoor.cpp | 15 ++ components/esm/loaddoor.hpp | 14 +- components/esm/loadench.cpp | 12 ++ components/esm/loadench.hpp | 40 +++-- components/esm/loadfact.cpp | 31 ++++ components/esm/loadfact.hpp | 76 +++------ components/esm/loadglob.cpp | 24 +++ components/esm/loadglob.hpp | 22 +-- components/esm/loadgmst.cpp | 172 +++++++++++++++++++ components/esm/loadgmst.hpp | 302 ++++++++------------------------- components/esm/loadinfo.cpp | 133 +++++++++++++++ components/esm/loadinfo.hpp | 135 +++++++-------- components/esm/loadingr.cpp | 15 ++ components/esm/loadingr.hpp | 32 ++-- components/esm/loadlevlist.cpp | 34 ++++ components/esm/loadlevlist.hpp | 90 +++++----- components/esm/loadligh.cpp | 17 ++ components/esm/loadligh.hpp | 62 +++---- components/esm/loadlocks.cpp | 30 ++++ components/esm/loadlocks.hpp | 53 ++---- components/esm/loadltex.cpp | 12 ++ components/esm/loadltex.hpp | 13 +- components/esm/loadmgef.cpp | 27 +++ components/esm/loadmgef.hpp | 93 ++++------ components/esm/loadmisc.cpp | 15 ++ components/esm/loadmisc.hpp | 32 ++-- components/esm/loadnpc.cpp | 48 ++++++ components/esm/loadpgrd.cpp | 35 ++++ components/esm/loadpgrd.hpp | 54 ++---- components/esm/loadrace.cpp | 14 ++ components/esm/loadrace.hpp | 75 ++++---- components/esm/loadregn.cpp | 29 ++++ components/esm/loadregn.hpp | 68 +++----- components/esm/loadscpt.cpp | 42 +++++ components/esm/loadscpt.hpp | 114 +++++-------- components/esm/loadskil.cpp | 93 +++++++--- components/esm/loadskil.hpp | 7 +- components/esm/loadsndg.cpp | 14 ++ components/esm/loadsndg.hpp | 8 +- components/esm/loadsoun.cpp | 18 ++ components/esm/loadsoun.hpp | 12 +- components/esm/loadspel.cpp | 13 ++ components/esm/loadspel.hpp | 51 +++--- components/esm/loadsscr.cpp | 13 ++ components/esm/loadsscr.hpp | 24 ++- components/esm/loadstat.cpp | 11 ++ components/esm/loadstat.hpp | 5 +- components/esm/loadweap.cpp | 16 ++ components/esm/loadweap.hpp | 75 ++++---- components/esm/skill.cpp | 63 ------- 60 files changed, 1589 insertions(+), 1343 deletions(-) delete mode 100644 components/esm/class.cpp delete mode 100644 components/esm/load_impl.cpp create mode 100644 components/esm/loadcont.cpp create mode 100644 components/esm/loadcrea.cpp create mode 100644 components/esm/loaddial.cpp create mode 100644 components/esm/loaddoor.cpp create mode 100644 components/esm/loadench.cpp create mode 100644 components/esm/loadfact.cpp create mode 100644 components/esm/loadglob.cpp create mode 100644 components/esm/loadgmst.cpp create mode 100644 components/esm/loadinfo.cpp create mode 100644 components/esm/loadingr.cpp create mode 100644 components/esm/loadlevlist.cpp create mode 100644 components/esm/loadligh.cpp create mode 100644 components/esm/loadlocks.cpp create mode 100644 components/esm/loadltex.cpp create mode 100644 components/esm/loadmgef.cpp create mode 100644 components/esm/loadmisc.cpp create mode 100644 components/esm/loadnpc.cpp create mode 100644 components/esm/loadpgrd.cpp create mode 100644 components/esm/loadrace.cpp create mode 100644 components/esm/loadregn.cpp create mode 100644 components/esm/loadscpt.cpp create mode 100644 components/esm/loadsndg.cpp create mode 100644 components/esm/loadsoun.cpp create mode 100644 components/esm/loadspel.cpp create mode 100644 components/esm/loadsscr.cpp create mode 100644 components/esm/loadstat.cpp create mode 100644 components/esm/loadweap.cpp delete mode 100644 components/esm/skill.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9aac8e11f..4f937f01d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,10 +127,7 @@ source_group(components\\esm_store FILES ${ESM_STORE} ${ESM_STORE_HEADER}) file(GLOB ESM_HEADER ${COMP_DIR}/esm/*.hpp) set(ESM - ${COMP_DIR}/esm/load_impl.cpp - ${COMP_DIR}/esm/skill.cpp ${COMP_DIR}/esm/attr.cpp - ${COMP_DIR}/esm/class.cpp ${COMP_DIR}/esm/esm_reader.cpp ${COMP_DIR}/esm/loadland.cpp ${COMP_DIR}/esm/loadacti.cpp @@ -143,6 +140,34 @@ set(ESM ${COMP_DIR}/esm/loadcell.cpp ${COMP_DIR}/esm/loadclas.cpp ${COMP_DIR}/esm/loadclot.cpp + ${COMP_DIR}/esm/loadcont.cpp + ${COMP_DIR}/esm/loadcrea.cpp + ${COMP_DIR}/esm/loaddial.cpp + ${COMP_DIR}/esm/loaddoor.cpp + ${COMP_DIR}/esm/loadench.cpp + ${COMP_DIR}/esm/loadfact.cpp + ${COMP_DIR}/esm/loadglob.cpp + ${COMP_DIR}/esm/loadgmst.cpp + ${COMP_DIR}/esm/loadinfo.cpp + ${COMP_DIR}/esm/loadingr.cpp + ${COMP_DIR}/esm/loadlevlist.cpp + ${COMP_DIR}/esm/loadligh.cpp + ${COMP_DIR}/esm/loadlocks.cpp + ${COMP_DIR}/esm/loadltex.cpp + ${COMP_DIR}/esm/loadmgef.cpp + ${COMP_DIR}/esm/loadmisc.cpp + ${COMP_DIR}/esm/loadnpc.cpp + ${COMP_DIR}/esm/loadpgrd.cpp + ${COMP_DIR}/esm/loadrace.cpp + ${COMP_DIR}/esm/loadregn.cpp + ${COMP_DIR}/esm/loadscpt.cpp + ${COMP_DIR}/esm/loadskil.cpp + ${COMP_DIR}/esm/loadsndg.cpp + ${COMP_DIR}/esm/loadsoun.cpp + ${COMP_DIR}/esm/loadspel.cpp + ${COMP_DIR}/esm/loadsscr.cpp + ${COMP_DIR}/esm/loadstat.cpp + ${COMP_DIR}/esm/loadweap.cpp ) source_group(components\\esm FILES ${ESM_HEADER} ${ESM}) diff --git a/components/esm/class.cpp b/components/esm/class.cpp deleted file mode 100644 index 5866205fa..000000000 --- a/components/esm/class.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "loadclas.hpp" - -using namespace ESM; - -const Class::Specialization Class::specializationIds[3] = { - Class::Combat, - Class::Magic, - Class::Stealth -}; - -const char *Class::gmstSpecializationIds[3] = { - "sSpecializationCombat", - "sSpecializationMagic", - "sSpecializationStealth" -}; diff --git a/components/esm/load_impl.cpp b/components/esm/load_impl.cpp deleted file mode 100644 index 28edbbe58..000000000 --- a/components/esm/load_impl.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "records.hpp" - -/** Implementation for some of the load() functions. Most are found in - the header files themselves, but this is a bit irritating to - compile if you're changing the functions often, as virtually the - entire engine depends on these headers. - */ - -/* -#include -using namespace std; -*/ - -namespace ESM -{ - void NPC::load(ESMReader &esm, const std::string& id) - { - mId = id; - - npdt52.gold = -10; - - model = esm.getHNOString("MODL"); - name = esm.getHNOString("FNAM"); - - race = esm.getHNString("RNAM"); - cls = esm.getHNString("CNAM"); - faction = esm.getHNString("ANAM"); - head = esm.getHNString("BNAM"); - hair = esm.getHNString("KNAM"); - - script = esm.getHNOString("SCRI"); - - esm.getSubNameIs("NPDT"); - esm.getSubHeader(); - if(esm.getSubSize() == 52) esm.getExact(&npdt52, 52); - else if(esm.getSubSize() == 12) esm.getExact(&npdt12, 12); - else esm.fail("NPC_NPDT must be 12 or 52 bytes long"); - - esm.getHNT(flags, "FLAG"); - - inventory.load(esm); - spells.load(esm); - - if(esm.isNextSub("AIDT")) - { - esm.getHExact(&AI, sizeof(AI)); - hasAI = true; - } - else hasAI = false; - - esm.skipRecord(); - } - - void DialInfo::load(ESMReader &esm) - { - id = esm.getHNString("INAM"); - prev = esm.getHNString("PNAM"); - next = esm.getHNString("NNAM"); - - // Not present if deleted - if(esm.isNextSub("DATA")) - esm.getHT(data, 12); - - // What follows is somewhat spaghetti-ish, but it's worth if for - // an extra speedup. INFO is by far the most common record type. - - // subName is a reference to the original, so it changes whenever - // a new sub name is read. esm.isEmptyOrGetName() will get the - // next name for us, or return true if there are no more records. - esm.getSubName(); - const NAME &subName = esm.retSubName(); - - if(subName.val == REC_ONAM) - { - actor = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - if(subName.val == REC_RNAM) - { - race = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - if(subName.val == REC_CNAM) - { - clas = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - - factionLess = false; - if(subName.val == REC_FNAM) - { - npcFaction = esm.getHString(); - if(npcFaction == "FFFF") factionLess = true; - if(esm.isEmptyOrGetName()) return; - } - if(subName.val == REC_ANAM) - { - cell = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - if(subName.val == REC_DNAM) - { - pcFaction = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - if(subName.val == REC_SNAM) - { - sound = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - if(subName.val == REC_NAME) - { - response = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - - while(subName.val == REC_SCVR) - { - SelectStruct ss; - - ss.selectRule = esm.getHString(); - esm.isEmptyOrGetName(); - - if(subName.val == REC_INTV) - { - ss.type = VT_Int; - esm.getHT(ss.i); - } - else if(subName.val == REC_FLTV) - { - ss.type = VT_Float; - esm.getHT(ss.f); - } - else - esm.fail("INFO.SCVR must precede INTV or FLTV, not " - + subName.toString()); - - selects.push_back(ss); - - if(esm.isEmptyOrGetName()) return; - } - - if(subName.val == REC_BNAM) - { - resultScript = esm.getHString(); - if(esm.isEmptyOrGetName()) return; - } - - questStatus = QS_None; - - if (subName.val == REC_QSTN) questStatus = QS_Name; - else if(subName.val == REC_QSTF) questStatus = QS_Finished; - else if(subName.val == REC_QSTR) questStatus = QS_Restart; - else if(subName.val == REC_DELE) questStatus = QS_Deleted; - else - esm.fail("Don't know what to do with " + subName.toString() + " in INFO " + id); - - if(questStatus != QS_None) - // Skip rest of record - esm.skipRecord(); - } - - void Sound::load(ESMReader &esm) - { - sound = esm.getHNString("FNAM"); - esm.getHNT(data, "DATA", 3); - /* - cout << "vol=" << (int)data.volume - << " min=" << (int)data.minRange - << " max=" << (int)data.maxRange - << endl; - */ - } - -} diff --git a/components/esm/loadclas.cpp b/components/esm/loadclas.cpp index 9a0b847ab..b15852cc2 100644 --- a/components/esm/loadclas.cpp +++ b/components/esm/loadclas.cpp @@ -3,6 +3,18 @@ namespace ESM { +const Class::Specialization Class::specializationIds[3] = { + Class::Combat, + Class::Magic, + Class::Stealth +}; + +const char *Class::gmstSpecializationIds[3] = { + "sSpecializationCombat", + "sSpecializationMagic", + "sSpecializationStealth" +}; + void Class::load(ESMReader &esm) { name = esm.getHNString("FNAM"); diff --git a/components/esm/loadcont.cpp b/components/esm/loadcont.cpp new file mode 100644 index 000000000..14699ccc5 --- /dev/null +++ b/components/esm/loadcont.cpp @@ -0,0 +1,33 @@ +#include "loadcont.hpp" + +namespace ESM +{ + +void InventoryList::load(ESMReader &esm) +{ + ContItem ci; + while (esm.isNextSub("NPCO")) + { + esm.getHT(ci, 36); + list.push_back(ci); + } +} + +void Container::load(ESMReader &esm) +{ + model = esm.getHNString("MODL"); + name = esm.getHNOString("FNAM"); + esm.getHNT(weight, "CNDT", 4); + esm.getHNT(flags, "FLAG", 4); + + if (flags & 0xf4) + esm.fail("Unknown flags"); + if (!(flags & 0x8)) + esm.fail("Flag 8 not set"); + + script = esm.getHNOString("SCRI"); + + inventory.load(esm); +} + +} diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index 3c7ed8598..4614c4230 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -3,7 +3,8 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* * Container definition @@ -11,54 +12,33 @@ namespace ESM { struct ContItem { - int count; - NAME32 item; + int count; + NAME32 item; }; struct InventoryList { - std::vector list; + std::vector list; - void load(ESMReader &esm) - { - ContItem ci; - while(esm.isNextSub("NPCO")) - { - esm.getHT(ci, 36); - list.push_back(ci); - } - } + void load(ESMReader &esm); }; struct Container { - enum Flags + enum Flags { - Organic = 1, // Objects cannot be placed in this container - Respawn = 2, // Respawns after 4 months - Unknown = 8 + Organic = 1, // Objects cannot be placed in this container + Respawn = 2, // Respawns after 4 months + Unknown = 8 }; - std::string name, model, script; - - float weight; // Not sure, might be max total weight allowed? - int flags; - InventoryList inventory; - - void load(ESMReader &esm) - { - model = esm.getHNString("MODL"); - name = esm.getHNOString("FNAM"); - esm.getHNT(weight, "CNDT", 4); - esm.getHNT(flags, "FLAG", 4); - - if(flags & 0xf4) esm.fail("Unknown flags"); - if(!(flags & 0x8)) esm.fail("Flag 8 not set"); + std::string name, model, script; - script = esm.getHNOString("SCRI"); + float weight; // Not sure, might be max total weight allowed? + int flags; + InventoryList inventory; - inventory.load(esm); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp new file mode 100644 index 000000000..651d9a318 --- /dev/null +++ b/components/esm/loadcrea.cpp @@ -0,0 +1,40 @@ +#include "loadcrea.hpp" + +namespace ESM { + +void Creature::load(ESMReader &esm, const std::string& id) +{ + mId = id; + + model = esm.getHNString("MODL"); + original = esm.getHNOString("CNAM"); + name = esm.getHNOString("FNAM"); + script = esm.getHNOString("SCRI"); + + esm.getHNT(data, "NPDT", 96); + + esm.getHNT(flags, "FLAG"); + scale = 1.0; + esm.getHNOT(scale, "XSCL"); + + inventory.load(esm); + + // More subrecords: + + // AIDT - data (12 bytes, unknown) + // AI_W - wander (14 bytes, i don't understand it) + // short distance + // byte duration + // byte timeOfDay + // byte idle[10] + // + // Rest is optional: + // AI_T - travel? + // AI_F - follow? + // AI_E - escort? + // AI_A - activate? + + esm.skipRecord(); +} + +} diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index df8578866..40c929213 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -4,7 +4,8 @@ #include "esm_reader.hpp" #include "loadcont.hpp" -namespace ESM { +namespace ESM +{ /* * Creature definition @@ -13,91 +14,53 @@ namespace ESM { struct Creature { - // Default is 0x48? - enum Flags + // Default is 0x48? + enum Flags { - Biped = 0x001, - Respawn = 0x002, - Weapon = 0x004, // Has weapon and shield - None = 0x008, // ?? - Swims = 0x010, - Flies = 0x020, // Don't know what happens if several - Walks = 0x040, // of these are set - Essential = 0x080, - Skeleton = 0x400, // Does not have normal blood - Metal = 0x800 // Has 'golden' blood + Biped = 0x001, Respawn = 0x002, Weapon = 0x004, // Has weapon and shield + None = 0x008, // ?? + Swims = 0x010, + Flies = 0x020, // Don't know what happens if several + Walks = 0x040, // of these are set + Essential = 0x080, + Skeleton = 0x400, // Does not have normal blood + Metal = 0x800 + // Has 'golden' blood }; - enum Type + enum Type { - Creatures = 0, - Deadra = 1, - Undead = 2, - Humanoid = 3 + Creatures = 0, Deadra = 1, Undead = 2, Humanoid = 3 }; - struct NPDTstruct - { - int type; - // For creatures we obviously have to use ints, not shorts and - // bytes like we use for NPCs.... this file format just makes so - // much sense! (Still, _much_ easier to decode than the NIFs.) - int level; - int strength, intelligence, willpower, agility, speed, endurance, - personality, luck, health, mana, fatigue; // Stats - int soul; // The creatures soul value (used with soul gems.) - int combat, magic, stealth; // Don't know yet. - int attack[6]; // AttackMin1, AttackMax1, ditto2, ditto3 - int gold; - }; // 96 bytes + struct NPDTstruct + { + int type; + // For creatures we obviously have to use ints, not shorts and + // bytes like we use for NPCs.... this file format just makes so + // much sense! (Still, _much_ easier to decode than the NIFs.) + int level; + int strength, intelligence, willpower, agility, speed, endurance, + personality, luck, health, mana, fatigue; // Stats + int soul; // The creatures soul value (used with soul gems.) + int combat, magic, stealth; // Don't know yet. + int attack[6]; // AttackMin1, AttackMax1, ditto2, ditto3 + int gold; + }; // 96 bytes - NPDTstruct data; + NPDTstruct data; - int flags; - float scale; + int flags; + float scale; - std::string model, name, script, - original; // Base creature that this is a modification of + std::string model, name, script, original; // Base creature that this is a modification of - // Defined in loadcont.hpp - InventoryList inventory; + // Defined in loadcont.hpp + InventoryList inventory; std::string mId; - void load(ESMReader &esm, const std::string& id) - { - mId = id; - - model = esm.getHNString("MODL"); - original = esm.getHNOString("CNAM"); - name = esm.getHNOString("FNAM"); - script = esm.getHNOString("SCRI"); - - esm.getHNT(data, "NPDT", 96); - - esm.getHNT(flags, "FLAG"); - scale = 1.0; - esm.getHNOT(scale, "XSCL"); - - inventory.load(esm); - - // More subrecords: - - // AIDT - data (12 bytes, unknown) - // AI_W - wander (14 bytes, i don't understand it) - // short distance - // byte duration - // byte timeOfDay - // byte idle[10] - // - // Rest is optional: - // AI_T - travel? - // AI_F - follow? - // AI_E - escort? - // AI_A - activate? - - esm.skipRecord(); - } + void load(ESMReader &esm, const std::string& id); }; } #endif diff --git a/components/esm/loaddial.cpp b/components/esm/loaddial.cpp new file mode 100644 index 000000000..d2283d351 --- /dev/null +++ b/components/esm/loaddial.cpp @@ -0,0 +1,25 @@ +#include "loaddial.hpp" + +namespace ESM +{ + +void Dialogue::load(ESMReader &esm) +{ + esm.getSubNameIs("DATA"); + esm.getSubHeader(); + int si = esm.getSubSize(); + if (si == 1) + esm.getT(type); + else if (si == 4) + { + // These are just markers, their values are not used. + int i; + esm.getT(i); + esm.getHNT(i, "DELE"); + type = Deleted; + } + else + esm.fail("Unknown sub record size"); +} + +} diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index 0cfba36eb..1f18a49d0 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -6,7 +6,8 @@ #include "esm_reader.hpp" #include "loadinfo.hpp" -namespace ESM { +namespace ESM +{ /* * Dialogue topic and journal entries. The actual data is contained in @@ -15,36 +16,20 @@ namespace ESM { struct Dialogue { - enum Type + enum Type { - Topic = 0, - Voice = 1, - Greeting = 2, - Persuasion = 3, - Journal = 4, - Deleted = -1 + Topic = 0, + Voice = 1, + Greeting = 2, + Persuasion = 3, + Journal = 4, + Deleted = -1 }; - char type; - std::vector mInfo; + char type; + std::vector mInfo; - void load(ESMReader &esm) - { - esm.getSubNameIs("DATA"); - esm.getSubHeader(); - int si = esm.getSubSize(); - if(si == 1) - esm.getT(type); - else if(si == 4) - { - // These are just markers, their values are not used. - int i; - esm.getT(i); - esm.getHNT(i,"DELE"); - type = Deleted; - } - else esm.fail("Unknown sub record size"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loaddoor.cpp b/components/esm/loaddoor.cpp new file mode 100644 index 000000000..d3cc69bd4 --- /dev/null +++ b/components/esm/loaddoor.cpp @@ -0,0 +1,15 @@ +#include "loaddoor.hpp" + +namespace ESM +{ + +void Door::load(ESMReader &esm) +{ + model = esm.getHNString("MODL"); + name = esm.getHNOString("FNAM"); + script = esm.getHNOString("SCRI"); + openSound = esm.getHNOString("SNAM"); + closeSound = esm.getHNOString("ANAM"); +} + +} diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index 7d76f20c8..2c0db4064 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -3,20 +3,14 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ struct Door { - std::string name, model, script, openSound, closeSound; + std::string name, model, script, openSound, closeSound; - void load(ESMReader &esm) - { - model = esm.getHNString("MODL"); - name = esm.getHNOString("FNAM"); - script = esm.getHNOString("SCRI"); - openSound = esm.getHNOString("SNAM"); - closeSound = esm.getHNOString("ANAM"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadench.cpp b/components/esm/loadench.cpp new file mode 100644 index 000000000..b2787492d --- /dev/null +++ b/components/esm/loadench.cpp @@ -0,0 +1,12 @@ +#include "loadench.hpp" + +namespace ESM +{ + +void Enchantment::load(ESMReader &esm) +{ + esm.getHNT(data, "ENDT", 16); + effects.load(esm); +} + +} diff --git a/components/esm/loadench.hpp b/components/esm/loadench.hpp index 15830c70c..449589e25 100644 --- a/components/esm/loadench.hpp +++ b/components/esm/loadench.hpp @@ -2,8 +2,10 @@ #define _ESM_ENCH_H #include "esm_reader.hpp" +#include "defs.hpp" -namespace ESM { +namespace ESM +{ /* * Enchantments @@ -11,31 +13,27 @@ namespace ESM { struct Enchantment { - enum Type + enum Type { - CastOnce = 0, - WhenStrikes = 1, - WhenUsed = 2, - ConstantEffect = 3 + CastOnce = 0, + WhenStrikes = 1, + WhenUsed = 2, + ConstantEffect = 3 }; - struct ENDTstruct - { - int type; - int cost; - int charge; - int autocalc; // Guessing this is 1 if we are supposed to auto - // calculate - }; + struct ENDTstruct + { + int type; + int cost; + int charge; + int autocalc; // Guessing this is 1 if we are supposed to auto + // calculate + }; - ENDTstruct data; - EffectList effects; + ENDTstruct data; + EffectList effects; - void load(ESMReader &esm) - { - esm.getHNT(data, "ENDT", 16); - effects.load(esm); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadfact.cpp b/components/esm/loadfact.cpp new file mode 100644 index 000000000..346ad2a2e --- /dev/null +++ b/components/esm/loadfact.cpp @@ -0,0 +1,31 @@ +#include "loadfact.hpp" + +namespace ESM +{ + +void Faction::load(ESMReader &esm) +{ + name = esm.getHNString("FNAM"); + + // Read rank names. These are optional. + int i = 0; + while (esm.isNextSub("RNAM") && i < 10) + ranks[i++] = esm.getHString(); + + // Main data struct + esm.getHNT(data, "FADT", 240); + + if (data.isHidden > 1) + esm.fail("Unknown flag!"); + + // Read faction response values + while (esm.hasMoreSubs()) + { + Reaction r; + r.faction = esm.getHNString("ANAM"); + esm.getHNT(r.reaction, "INTV"); + reactions.push_back(r); + } +} + +} diff --git a/components/esm/loadfact.hpp b/components/esm/loadfact.hpp index c938d912a..85874aa78 100644 --- a/components/esm/loadfact.hpp +++ b/components/esm/loadfact.hpp @@ -3,7 +3,8 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* * Faction definitions @@ -12,67 +13,46 @@ namespace ESM { // Requirements for each rank struct RankData { - int attribute1, attribute2; // Attribute level + int attribute1, attribute2; // Attribute level - int skill1, skill2; // Skill level (faction skills given in - // skillID below.) You need one skill at - // level 'skill1' and two skills at level - // 'skill2' to advance to this rank. + int skill1, skill2; // Skill level (faction skills given in + // skillID below.) You need one skill at + // level 'skill1' and two skills at level + // 'skill2' to advance to this rank. - int factReaction; // Reaction from faction members + int factReaction; // Reaction from faction members }; struct Faction { - std::string id, name; - - struct FADTstruct - { - // Which attributes we like - int attribute1, attribute2; - - RankData rankData[10]; - - int skillID[6]; // IDs of skills this faction require - int unknown; // Always -1? - int isHidden; // 1 - hidden from player - }; // 240 bytes - - FADTstruct data; + std::string id, name; - struct Reaction - { - std::string faction; - int reaction; - }; + struct FADTstruct + { + // Which attributes we like + int attribute1, attribute2; - std::vector reactions; + RankData rankData[10]; - // Name of faction ranks (may be empty for NPC factions) - std::string ranks[10]; + int skillID[6]; // IDs of skills this faction require + int unknown; // Always -1? + int isHidden; // 1 - hidden from player + }; // 240 bytes - void load(ESMReader &esm) - { - name = esm.getHNString("FNAM"); + FADTstruct data; - // Read rank names. These are optional. - int i = 0; - while(esm.isNextSub("RNAM") && i<10) ranks[i++] = esm.getHString(); + struct Reaction + { + std::string faction; + int reaction; + }; - // Main data struct - esm.getHNT(data, "FADT", 240); + std::vector reactions; - if(data.isHidden > 1) esm.fail("Unknown flag!"); + // Name of faction ranks (may be empty for NPC factions) + std::string ranks[10]; - // Read faction response values - while(esm.hasMoreSubs()) - { - Reaction r; - r.faction = esm.getHNString("ANAM"); - esm.getHNT(r.reaction, "INTV"); - reactions.push_back(r); - } - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadglob.cpp b/components/esm/loadglob.cpp new file mode 100644 index 000000000..c946b3fa0 --- /dev/null +++ b/components/esm/loadglob.cpp @@ -0,0 +1,24 @@ +#include "loadglob.hpp" + +namespace ESM +{ + +void Global::load(ESMReader &esm) +{ + VarType t; + std::string tmp = esm.getHNString("FNAM"); + if (tmp == "s") + t = VT_Short; + else if (tmp == "l") + t = VT_Int; + else if (tmp == "f") + t = VT_Float; + else + esm.fail("Illegal global variable type " + tmp); + type = t; + + // Note: Both floats and longs are represented as floats. + esm.getHNT(value, "FLTV"); +} + +} diff --git a/components/esm/loadglob.hpp b/components/esm/loadglob.hpp index 9de3e1a46..5028679dd 100644 --- a/components/esm/loadglob.hpp +++ b/components/esm/loadglob.hpp @@ -2,8 +2,10 @@ #define _ESM_GLOB_H #include "esm_reader.hpp" +#include "defs.hpp" -namespace ESM { +namespace ESM +{ /* * Global script variables @@ -11,22 +13,10 @@ namespace ESM { struct Global { - unsigned value; - VarType type; - - void load(ESMReader &esm) - { - VarType t; - std::string tmp = esm.getHNString("FNAM"); - if(tmp == "s") t = VT_Short; - else if(tmp == "l") t = VT_Int; - else if(tmp == "f") t = VT_Float; - else esm.fail("Illegal global variable type " + tmp); - type = t; + unsigned value; + VarType type; - // Note: Both floats and longs are represented as floats. - esm.getHNT(value, "FLTV"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadgmst.cpp b/components/esm/loadgmst.cpp new file mode 100644 index 000000000..677642e31 --- /dev/null +++ b/components/esm/loadgmst.cpp @@ -0,0 +1,172 @@ +#include "loadgmst.hpp" + +namespace ESM +{ + +// Some handy macros +#define cI(s,x) { if(id == (s)) return (i == (x)); } +#define cF(s,x) { if(id == (s)) return (f == (x)); } +#define cS(s,x) { if(id == (s)) return (str == (x)); } + +bool GameSetting::isDirtyTribunal() +{ + /* + Here, id contains the game setting name, and we check the + setting for certain values. If it matches, this is a "dirty" + entry. The correct entry (as defined in Tribunal and Bloodmoon + esms) are given in the comments. Many of the values are correct, + and are marked as 'same'. We still ignore them though, as they + are still in the wrong file and might override custom values + from other mods. + */ + + // Strings + cS("sProfitValue", "Profit Value"); // 'Profit:' + cS("sEditNote", "Edit Note"); // same + cS("sDeleteNote", "Delete Note?"); // same + cS("sMaxSale", "Max Sale"); // 'Seller Max' + cS("sMagicFabricantID", "Fabricant"); // 'Fabricant_summon' + cS("sTeleportDisabled", + "Teleportation magic does not work here.");// same + cS("sLevitateDisabled", + "Levitation magic does not work here."); // same + cS("sCompanionShare", "Companion Share"); // 'Share' + cS("sCompanionWarningButtonOne", + "Let the mercenary quit."); // same + cS("sCompanionWarningButtonTwo", + "Return to Companion Share display."); // same + cS("sCompanionWarningMessage", + "Your mercenary is poorer now than when he contracted with you. Your mercenary will quit if you do not give him gold or goods to bring his Profit Value to a positive value."); + // 'Your mercenary is poorer now than when he contracted with + // you. Your mercenary will quit if you do not give him gold + // or goods to bring his Profit to a positive value.' + // [The difference here is "Profit Value" -> "Profit"] + + // Strings that matches the id + cS("sEffectSummonFabricant", id);// 'Summon Fabricant' + return false; +} + +// Bloodmoon variant +bool GameSetting::isDirtyBloodmoon() +{ + // Strings + cS("sWerewolfPopup", "Werewolf"); // same + cS("sWerewolfRestMessage", + "You cannot rest in werewolf form."); // same + cS("sWerewolfRefusal", + "You cannot do this as a werewolf."); // same + cS("sWerewolfAlarmMessage", + "You have been detected changing from a werewolf state."); + // 'You have been detected as a known werewolf.' + + // Strings that matches the id + cS("sMagicCreature01ID", id); // 'BM_wolf_grey_summon' + cS("sMagicCreature02ID", id); // 'BM_bear_black_summon' + cS("sMagicCreature03ID", id); // 'BM_wolf_bone_summon' + cS("sMagicCreature04ID", id); // same + cS("sMagicCreature05ID", id); // same + cS("sEffectSummonCreature01", id); // 'Calf Wolf' + cS("sEffectSummonCreature02", id); // 'Calf Bear' + cS("sEffectSummonCreature03", id); // 'Summon Bonewolf' + cS("sEffectSummonCreature04", id); // same + cS("sEffectSummonCreature05", id); // same + + // Integers + cI("iWereWolfBounty", 10000); // 1000 + cI("iWereWolfFightMod", 100); // same + cI("iWereWolfFleeMod", 100); // same + cI("iWereWolfLevelToAttack", 20); // same + + // Floats + cF("fFleeDistance", 3000); // same + cF("fCombatDistanceWerewolfMod", 0.3); // same + cF("fWereWolfFatigue", 400); // same + cF("fWereWolfEnchant", 1); // 0 + cF("fWereWolfArmorer", 1); // 0 + cF("fWereWolfBlock", 1); // 0 + cF("fWereWolfSneak", 1); // 95 + cF("fWereWolfDestruction", 1); // 0 + cF("fWereWolfEndurance", 150); // same + cF("fWereWolfConjuration", 1); // 0 + cF("fWereWolfRestoration", 1); // 0 + cF("fWereWolfAthletics", 150); // 50 + cF("fWereWolfLuck", 1); // 25 + cF("fWereWolfSilverWeaponDamageMult", 1.5); // 2 + cF("fWereWolfMediumArmor", 1); // 0 + cF("fWereWolfShortBlade", 1); // 0 + cF("fWereWolfAcrobatics", 150); // 80 + cF("fWereWolfSpeechcraft", 1); // 0 + cF("fWereWolfAlteration", 1); // 0 + cF("fWereWolfIllusion", 1); // 0 + cF("fWereWolfLongBlade", 1); // 0 + cF("fWereWolfMarksman", 1); // 0 + cF("fWereWolfHandtoHand", 100); // same + cF("fWereWolfIntellegence", 1); // 0 + cF("fWereWolfAlchemy", 1); // 0 + cF("fWereWolfUnarmored", 100); // same + cF("fWereWolfAxe", 1); // 0 + cF("fWereWolfRunMult", 1.5); // 1.3 + cF("fWereWolfMagicka", 100); // same + cF("fWereWolfAgility", 150); // same + cF("fWereWolfBluntWeapon", 1); // 0 + cF("fWereWolfSecurity", 1); // 0 + cF("fWereWolfPersonality", 1); // 0 + cF("fWereWolfMerchantile", 1); // 0 + cF("fWereWolfHeavyArmor", 1); // 0 + cF("fWereWolfSpear", 1); // 0 + cF("fWereWolfStrength", 150); // same + cF("fWereWolfHealth", 2); // same + cF("fWereWolfMysticism", 1); // 0 + cF("fWereWolfLightArmor", 1); // 0 + cF("fWereWolfWillPower", 1); // 0 + cF("fWereWolfSpeed", 150); // 90 + return false; +} + +void GameSetting::load(ESMReader &esm) +{ + assert(id != ""); + + dirty = false; + + // We are apparently allowed to be empty + if (!esm.hasMoreSubs()) + { + type = VT_None; + return; + } + + // Load some data + esm.getSubName(); + NAME n = esm.retSubName(); + if (n == "STRV") + { + str = esm.getHString(); + type = VT_String; + } + else if (n == "INTV") + { + esm.getHT(i); + type = VT_Int; + } + else if (n == "FLTV") + { + esm.getHT(f); + type = VT_Float; + } + else + esm.fail("Unwanted subrecord type"); + + int spf = esm.getSpecial(); + + // Check if this is one of the dirty values mentioned above. If it + // is, we set the dirty flag. This will ONLY work if you've set + // the 'id' string correctly before calling load(). + + if ((spf != SF_Tribunal && isDirtyTribunal()) || (spf != SF_Bloodmoon + && isDirtyBloodmoon())) + dirty = true; +} + +} diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index 2e112ecb6..01fbc3067 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -4,7 +4,8 @@ #include "esm_reader.hpp" #include "defs.hpp" -namespace ESM { +namespace ESM +{ /* * Game setting, with automatic cleaning of "dirty" entries. @@ -13,238 +14,75 @@ namespace ESM { struct GameSetting { - std::string id; - - // One of these is used depending on the variable type - std::string str; - int i; - float f; - VarType type; - - // Set to true if this is a 'dirty' entry which should be ignored - bool dirty; - - /* - These functions check if this game setting is one of the "dirty" - GMST records found in many mods. These are due to a serious bug in - the official TES3 editor. It only occurs in the newer editor - versions that came with Tribunal and Bloodmoon, and only if a - modder tries to make a mod without loading the corresponding - expansion master file. For example, if you have Tribunal installed - and try to make a mod without loading Tribunal.esm, the editor - will insert these GMST records as a replacement for the entries it - cannot find in the ESMs. - - The values of these "dirty" records differ in general from their - values as defined in Tribunal.esm and Bloodmoon.esm, and are - always set to the same "default" values. Most of these values are - nonsensical, ie. changing the "Seller Max" string to "Max Sale", - or change the stats of werewolves to useless values like 1. Some - of them break certain spell effects. - - It is most likely that these values are just leftover values from - an early stage of development that are inserted as default values - by the editor code. They are supposed to be overridden when the - correct esm file is loaded. When it isn't loaded however, you get - stuck with the initial value, and this gets written to every mod - by the editor, for some reason. - - Bethesda themselves have fallen for this bug. If you install both - Tribunal and Bloodmoon, the updated Tribunal.esm will contain the - dirty GMST settings from Bloodmoon, and Bloodmoon.esm will contain - some of the dirty settings from Tribunal. In other words, this bug - affects the game EVEN IF YOU DO NOT USE ANY MODS! - - The guys at Bethesda are well aware of this bug (and many others), - as the mod community and fan base complained about them for a long - time. But unfortunately it was never fixed. - - There are several tools available to help modders remove these - records from their files, but not all modders use them, and they - really shouldn't have to. In this file we choose instead to reject - all the corrupt values at load time. - - These functions checks if the current game setting is one of the - "dirty" ones as described above. TODO: I have not checked this - against other sources yet, do that later. Currently recognizes 22 - values for tribunal and 50 for bloodmoon. Legitimate GMSTs in mods - (setting values other than the default "dirty" ones) are not - affected and will work correctly. - */ - - // Some handy macros -#define cI(s,x) { if(id == (s)) return (i == (x)); } -#define cF(s,x) { if(id == (s)) return (f == (x)); } -#define cS(s,x) { if(id == (s)) return (str == (x)); } - - /* - Checks for dirty tribunal values. These will be ignored if found - in any file except when they are found in "Tribunal.esm". - */ - bool isDirtyTribunal() - { + std::string id; + + // One of these is used depending on the variable type + std::string str; + int i; + float f; + VarType type; + + // Set to true if this is a 'dirty' entry which should be ignored + bool dirty; + /* - Here, id contains the game setting name, and we check the - setting for certain values. If it matches, this is a "dirty" - entry. The correct entry (as defined in Tribunal and Bloodmoon - esms) are given in the comments. Many of the values are correct, - and are marked as 'same'. We still ignore them though, as they - are still in the wrong file and might override custom values - from other mods. - */ - - // Strings - cS("sProfitValue", "Profit Value"); // 'Profit:' - cS("sEditNote", "Edit Note"); // same - cS("sDeleteNote", "Delete Note?"); // same - cS("sMaxSale", "Max Sale"); // 'Seller Max' - cS("sMagicFabricantID", "Fabricant"); // 'Fabricant_summon' - cS("sTeleportDisabled", - "Teleportation magic does not work here.");// same - cS("sLevitateDisabled", - "Levitation magic does not work here."); // same - cS("sCompanionShare", "Companion Share"); // 'Share' - cS("sCompanionWarningButtonOne", - "Let the mercenary quit."); // same - cS("sCompanionWarningButtonTwo", - "Return to Companion Share display."); // same - cS("sCompanionWarningMessage", - "Your mercenary is poorer now than when he contracted with you. Your mercenary will quit if you do not give him gold or goods to bring his Profit Value to a positive value."); - // 'Your mercenary is poorer now than when he contracted with - // you. Your mercenary will quit if you do not give him gold - // or goods to bring his Profit to a positive value.' - // [The difference here is "Profit Value" -> "Profit"] - - // Strings that matches the id - cS("sEffectSummonFabricant", id);// 'Summon Fabricant' - return false; - } - - // Bloodmoon variant - bool isDirtyBloodmoon() - { - // Strings - cS("sWerewolfPopup", "Werewolf"); // same - cS("sWerewolfRestMessage", - "You cannot rest in werewolf form."); // same - cS("sWerewolfRefusal", - "You cannot do this as a werewolf."); // same - cS("sWerewolfAlarmMessage", - "You have been detected changing from a werewolf state."); - // 'You have been detected as a known werewolf.' - - // Strings that matches the id - cS("sMagicCreature01ID", id); // 'BM_wolf_grey_summon' - cS("sMagicCreature02ID", id); // 'BM_bear_black_summon' - cS("sMagicCreature03ID", id); // 'BM_wolf_bone_summon' - cS("sMagicCreature04ID", id); // same - cS("sMagicCreature05ID", id); // same - cS("sEffectSummonCreature01", id); // 'Calf Wolf' - cS("sEffectSummonCreature02", id); // 'Calf Bear' - cS("sEffectSummonCreature03", id); // 'Summon Bonewolf' - cS("sEffectSummonCreature04", id); // same - cS("sEffectSummonCreature05", id); // same - - // Integers - cI("iWereWolfBounty", 10000); // 1000 - cI("iWereWolfFightMod", 100); // same - cI("iWereWolfFleeMod", 100); // same - cI("iWereWolfLevelToAttack", 20); // same - - // Floats - cF("fFleeDistance", 3000); // same - cF("fCombatDistanceWerewolfMod", 0.3); // same - cF("fWereWolfFatigue", 400); // same - cF("fWereWolfEnchant", 1); // 0 - cF("fWereWolfArmorer", 1); // 0 - cF("fWereWolfBlock", 1); // 0 - cF("fWereWolfSneak", 1); // 95 - cF("fWereWolfDestruction", 1); // 0 - cF("fWereWolfEndurance", 150); // same - cF("fWereWolfConjuration", 1); // 0 - cF("fWereWolfRestoration", 1); // 0 - cF("fWereWolfAthletics", 150); // 50 - cF("fWereWolfLuck", 1); // 25 - cF("fWereWolfSilverWeaponDamageMult", 1.5); // 2 - cF("fWereWolfMediumArmor", 1); // 0 - cF("fWereWolfShortBlade", 1); // 0 - cF("fWereWolfAcrobatics", 150); // 80 - cF("fWereWolfSpeechcraft", 1); // 0 - cF("fWereWolfAlteration", 1); // 0 - cF("fWereWolfIllusion", 1); // 0 - cF("fWereWolfLongBlade", 1); // 0 - cF("fWereWolfMarksman", 1); // 0 - cF("fWereWolfHandtoHand", 100); // same - cF("fWereWolfIntellegence", 1); // 0 - cF("fWereWolfAlchemy", 1); // 0 - cF("fWereWolfUnarmored", 100); // same - cF("fWereWolfAxe", 1); // 0 - cF("fWereWolfRunMult", 1.5); // 1.3 - cF("fWereWolfMagicka", 100); // same - cF("fWereWolfAgility", 150); // same - cF("fWereWolfBluntWeapon", 1); // 0 - cF("fWereWolfSecurity", 1); // 0 - cF("fWereWolfPersonality", 1); // 0 - cF("fWereWolfMerchantile", 1); // 0 - cF("fWereWolfHeavyArmor", 1); // 0 - cF("fWereWolfSpear", 1); // 0 - cF("fWereWolfStrength", 150); // same - cF("fWereWolfHealth", 2); // same - cF("fWereWolfMysticism", 1); // 0 - cF("fWereWolfLightArmor", 1); // 0 - cF("fWereWolfWillPower", 1); // 0 - cF("fWereWolfSpeed", 150); // 90 - return false; - } - -#undef cI -#undef cF -#undef cS - - void load(ESMReader &esm) - { - assert(id != ""); - - dirty = false; - - // We are apparently allowed to be empty - if(!esm.hasMoreSubs()) - { - type = VT_None; - return; - } - - // Load some data - esm.getSubName(); - NAME n = esm.retSubName(); - if(n == "STRV") - { - str = esm.getHString(); - type = VT_String; - } - else if(n == "INTV") - { - esm.getHT(i); - type = VT_Int; - } - else if(n == "FLTV") - { - esm.getHT(f); - type = VT_Float; - } - else - esm.fail("Unwanted subrecord type"); - - int spf = esm.getSpecial(); - - // Check if this is one of the dirty values mentioned above. If it - // is, we set the dirty flag. This will ONLY work if you've set - // the 'id' string correctly before calling load(). - - if( ( spf != SF_Tribunal && isDirtyTribunal() ) || - ( spf != SF_Bloodmoon && isDirtyBloodmoon() ) ) - dirty = true; - } + These functions check if this game setting is one of the "dirty" + GMST records found in many mods. These are due to a serious bug in + the official TES3 editor. It only occurs in the newer editor + versions that came with Tribunal and Bloodmoon, and only if a + modder tries to make a mod without loading the corresponding + expansion master file. For example, if you have Tribunal installed + and try to make a mod without loading Tribunal.esm, the editor + will insert these GMST records as a replacement for the entries it + cannot find in the ESMs. + + The values of these "dirty" records differ in general from their + values as defined in Tribunal.esm and Bloodmoon.esm, and are + always set to the same "default" values. Most of these values are + nonsensical, ie. changing the "Seller Max" string to "Max Sale", + or change the stats of werewolves to useless values like 1. Some + of them break certain spell effects. + + It is most likely that these values are just leftover values from + an early stage of development that are inserted as default values + by the editor code. They are supposed to be overridden when the + correct esm file is loaded. When it isn't loaded however, you get + stuck with the initial value, and this gets written to every mod + by the editor, for some reason. + + Bethesda themselves have fallen for this bug. If you install both + Tribunal and Bloodmoon, the updated Tribunal.esm will contain the + dirty GMST settings from Bloodmoon, and Bloodmoon.esm will contain + some of the dirty settings from Tribunal. In other words, this bug + affects the game EVEN IF YOU DO NOT USE ANY MODS! + + The guys at Bethesda are well aware of this bug (and many others), + as the mod community and fan base complained about them for a long + time. But unfortunately it was never fixed. + + There are several tools available to help modders remove these + records from their files, but not all modders use them, and they + really shouldn't have to. In this file we choose instead to reject + all the corrupt values at load time. + + These functions checks if the current game setting is one of the + "dirty" ones as described above. TODO: I have not checked this + against other sources yet, do that later. Currently recognizes 22 + values for tribunal and 50 for bloodmoon. Legitimate GMSTs in mods + (setting values other than the default "dirty" ones) are not + affected and will work correctly. + */ + + /* + Checks for dirty tribunal values. These will be ignored if found + in any file except when they are found in "Tribunal.esm". + */ + bool isDirtyTribunal(); + + // Bloodmoon variant + bool isDirtyBloodmoon(); + + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadinfo.cpp b/components/esm/loadinfo.cpp new file mode 100644 index 000000000..0f08b3c8a --- /dev/null +++ b/components/esm/loadinfo.cpp @@ -0,0 +1,133 @@ +#include "loadinfo.hpp" + +namespace ESM +{ + +void DialInfo::load(ESMReader &esm) +{ + id = esm.getHNString("INAM"); + prev = esm.getHNString("PNAM"); + next = esm.getHNString("NNAM"); + + // Not present if deleted + if (esm.isNextSub("DATA")) + esm.getHT(data, 12); + + // What follows is somewhat spaghetti-ish, but it's worth if for + // an extra speedup. INFO is by far the most common record type. + + // subName is a reference to the original, so it changes whenever + // a new sub name is read. esm.isEmptyOrGetName() will get the + // next name for us, or return true if there are no more records. + esm.getSubName(); + const NAME &subName = esm.retSubName(); + + if (subName.val == REC_ONAM) + { + actor = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + if (subName.val == REC_RNAM) + { + race = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + if (subName.val == REC_CNAM) + { + clas = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + + factionLess = false; + if (subName.val == REC_FNAM) + { + npcFaction = esm.getHString(); + if (npcFaction == "FFFF") + factionLess = true; + if (esm.isEmptyOrGetName()) + return; + } + if (subName.val == REC_ANAM) + { + cell = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + if (subName.val == REC_DNAM) + { + pcFaction = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + if (subName.val == REC_SNAM) + { + sound = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + if (subName.val == REC_NAME) + { + response = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + + while (subName.val == REC_SCVR) + { + SelectStruct ss; + + ss.selectRule = esm.getHString(); + esm.isEmptyOrGetName(); + + if (subName.val == REC_INTV) + { + ss.type = VT_Int; + esm.getHT(ss.i); + } + else if (subName.val == REC_FLTV) + { + ss.type = VT_Float; + esm.getHT(ss.f); + } + else + esm.fail( + "INFO.SCVR must precede INTV or FLTV, not " + + subName.toString()); + + selects.push_back(ss); + + if (esm.isEmptyOrGetName()) + return; + } + + if (subName.val == REC_BNAM) + { + resultScript = esm.getHString(); + if (esm.isEmptyOrGetName()) + return; + } + + questStatus = QS_None; + + if (subName.val == REC_QSTN) + questStatus = QS_Name; + else if (subName.val == REC_QSTF) + questStatus = QS_Finished; + else if (subName.val == REC_QSTR) + questStatus = QS_Restart; + else if (subName.val == REC_DELE) + questStatus = QS_Deleted; + else + esm.fail( + "Don't know what to do with " + subName.toString() + + " in INFO " + id); + + if (questStatus != QS_None) + // Skip rest of record + esm.skipRecord(); +} + +} diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index 480deda73..c47af341e 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -4,7 +4,8 @@ #include "esm_reader.hpp" #include "defs.hpp" -namespace ESM { +namespace ESM +{ // NOT DONE @@ -15,88 +16,88 @@ namespace ESM { struct DialInfo { - enum Gender + enum Gender + { + Male = 0, + Female = 1, + NA = -1 + }; + + struct DATAstruct + { + int unknown1; + int disposition; + char rank; // Rank of NPC + char gender; // See Gender enum + char PCrank; // Player rank + char unknown2; + }; // 12 bytes + DATAstruct data; + + // The rules for whether or not we will select this dialog item. + struct SelectStruct { - Male = 0, - Female = 1, - NA = -1 + std::string selectRule; // This has a complicated format + float f; // Only one of 'f' or 'i' is used + int i; + VarType type; }; - struct DATAstruct - { - int unknown1; - int disposition; - char rank; // Rank of NPC - char gender; // See Gender enum - char PCrank; // Player rank - char unknown2; - }; // 12 bytes - DATAstruct data; - - // The rules for whether or not we will select this dialog item. - struct SelectStruct - { - std::string selectRule; // This has a complicated format - float f; // Only one of 'f' or 'i' is used - int i; - VarType type; - }; - - // Journal quest indices (introduced with the quest system in Tribunal) - enum QuestStatus + // Journal quest indices (introduced with the quest system in Tribunal) + enum QuestStatus { - QS_None, - QS_Name, - QS_Finished, - QS_Restart, - QS_Deleted + QS_None, + QS_Name, + QS_Finished, + QS_Restart, + QS_Deleted }; - // Rules for when to include this item in the final list of options - // visible to the player. - std::vector selects; + // Rules for when to include this item in the final list of options + // visible to the player. + std::vector selects; - // Id of this, previous and next INFO items - std::string id, prev, next, + // Id of this, previous and next INFO items + std::string id, prev, next, - // Various references used in determining when to select this item. - actor, race, clas, npcFaction, pcFaction, cell, + // Various references used in determining when to select this item. + actor, race, clas, npcFaction, pcFaction, cell, - // Sound and text associated with this item - sound, response, + // Sound and text associated with this item + sound, response, - // Result script (uncomiled) to run whenever this dialog item is - // selected - resultScript; + // Result script (uncomiled) to run whenever this dialog item is + // selected + resultScript; - // ONLY include this item the NPC is not part of any faction. - bool factionLess; + // ONLY include this item the NPC is not part of any faction. + bool factionLess; - // Status of this quest item - QuestStatus questStatus; + // Status of this quest item + QuestStatus questStatus; - // Hexadecimal versions of the various subrecord names. - enum SubNames + // Hexadecimal versions of the various subrecord names. + enum SubNames { - REC_ONAM = 0x4d414e4f, - REC_RNAM = 0x4d414e52, - REC_CNAM = 0x4d414e43, - REC_FNAM = 0x4d414e46, - REC_ANAM = 0x4d414e41, - REC_DNAM = 0x4d414e44, - REC_SNAM = 0x4d414e53, - REC_NAME = 0x454d414e, - REC_SCVR = 0x52564353, - REC_INTV = 0x56544e49, - REC_FLTV = 0x56544c46, - REC_BNAM = 0x4d414e42, - REC_QSTN = 0x4e545351, - REC_QSTF = 0x46545351, - REC_QSTR = 0x52545351, - REC_DELE = 0x454c4544 + REC_ONAM = 0x4d414e4f, + REC_RNAM = 0x4d414e52, + REC_CNAM = 0x4d414e43, + REC_FNAM = 0x4d414e46, + REC_ANAM = 0x4d414e41, + REC_DNAM = 0x4d414e44, + REC_SNAM = 0x4d414e53, + REC_NAME = 0x454d414e, + REC_SCVR = 0x52564353, + REC_INTV = 0x56544e49, + REC_FLTV = 0x56544c46, + REC_BNAM = 0x4d414e42, + REC_QSTN = 0x4e545351, + REC_QSTF = 0x46545351, + REC_QSTR = 0x52545351, + REC_DELE = 0x454c4544 }; - void load(ESMReader &esm); + void load(ESMReader &esm); }; /* diff --git a/components/esm/loadingr.cpp b/components/esm/loadingr.cpp new file mode 100644 index 000000000..471f71780 --- /dev/null +++ b/components/esm/loadingr.cpp @@ -0,0 +1,15 @@ +#include "loadingr.hpp" + +namespace ESM +{ + +void Ingredient::load(ESMReader &esm) +{ + model = esm.getHNString("MODL"); + name = esm.getHNString("FNAM"); + esm.getHNT(data, "IRDT", 56); + script = esm.getHNOString("SCRI"); + icon = esm.getHNOString("ITEX"); +} + +} diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index 5845cb570..af9599ed0 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -3,7 +3,8 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* * Alchemy ingredient @@ -11,26 +12,19 @@ namespace ESM { struct Ingredient { - struct IRDTstruct - { - float weight; - int value; - int effectID[4]; // Effect, 0 or -1 means none - int skills[4]; // SkillEnum related to effect - int attributes[4]; // Attribute related to effect - }; + struct IRDTstruct + { + float weight; + int value; + int effectID[4]; // Effect, 0 or -1 means none + int skills[4]; // SkillEnum related to effect + int attributes[4]; // Attribute related to effect + }; - IRDTstruct data; - std::string name, model, icon, script; + IRDTstruct data; + std::string name, model, icon, script; - void load(ESMReader &esm) - { - model = esm.getHNString("MODL"); - name = esm.getHNString("FNAM"); - esm.getHNT(data, "IRDT", 56); - script = esm.getHNOString("SCRI"); - icon = esm.getHNOString("ITEX"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadlevlist.cpp b/components/esm/loadlevlist.cpp new file mode 100644 index 000000000..d1bff7972 --- /dev/null +++ b/components/esm/loadlevlist.cpp @@ -0,0 +1,34 @@ +#include "loadlevlist.hpp" + +namespace ESM +{ + +void LeveledListBase::load(ESMReader &esm) +{ + esm.getHNT(flags, "DATA"); + esm.getHNT(chanceNone, "NNAM"); + + if (esm.isNextSub("INDX")) + { + int len; + esm.getHT(len); + list.resize(len); + } + else + return; + + // TODO: Merge with an existing lists here. This can be done + // simply by adding the lists together, making sure that they are + // sorted by level. A better way might be to exclude repeated + // items. Also, some times we don't want to merge lists, just + // overwrite. Figure out a way to give the user this option. + + for (size_t i = 0; i < list.size(); i++) + { + LevelItem &li = list[i]; + li.id = esm.getHNString(recName); + esm.getHNT(li.level, "INTV"); + } +} + +} diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index 8b0ae45b2..4affce539 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -3,7 +3,8 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* * Leveled lists. Since these have identical layout, I only bothered @@ -15,65 +16,50 @@ namespace ESM { struct LeveledListBase { - enum Flags + enum Flags { - AllLevels = 0x01, // Calculate from all levels <= player - // level, not just the closest below - // player. - Each = 0x02 // Select a new item each time this - // list is instantiated, instead of - // giving several identical items - }; // (used when a container has more - // than one instance of one leveled - // list.) - int flags; - unsigned char chanceNone; // Chance that none are selected (0-255?) - - // Record name used to read references. Must be set before load() is - // called. - const char *recName; - - struct LevelItem - { - std::string id; - short level; - }; + AllLevels = 0x01, // Calculate from all levels <= player + // level, not just the closest below + // player. + Each = 0x02 // Select a new item each time this + // list is instantiated, instead of + // giving several identical items + }; // (used when a container has more + // than one instance of one leveled + // list.) + int flags; + unsigned char chanceNone; // Chance that none are selected (0-255?) - std::vector list; + // Record name used to read references. Must be set before load() is + // called. + const char *recName; - void load(ESMReader &esm) - { - esm.getHNT(flags, "DATA"); - esm.getHNT(chanceNone, "NNAM"); + struct LevelItem + { + std::string id; + short level; + }; - if(esm.isNextSub("INDX")) - { - int len; - esm.getHT(len); - list.resize(len); - } - else return; + std::vector list; - // TODO: Merge with an existing lists here. This can be done - // simply by adding the lists together, making sure that they are - // sorted by level. A better way might be to exclude repeated - // items. Also, some times we don't want to merge lists, just - // overwrite. Figure out a way to give the user this option. - - for(size_t i=0; i soundList; - - void load(ESMReader &esm) - { - name = esm.getHNString("FNAM"); - - if(esm.getVer() == VER_12) - esm.getHNExact(&data, sizeof(data)-2, "WEAT"); - else if(esm.getVer() == VER_13) - esm.getHNExact(&data, sizeof(data), "WEAT"); - else esm.fail("Don't know what to do in this version"); + WEATstruct data; + int mapColor; // RGBA - sleepList = esm.getHNOString("BNAM"); + // sleepList refers to a eveled list of creatures you can meet if + // you sleep outside in this region. + std::string name, sleepList; - esm.getHNT(mapColor, "CNAM"); + std::vector soundList; - while(esm.hasMoreSubs()) - { - SoundRef sr; - esm.getHNT(sr, "SNAM", 33); - soundList.push_back(sr); - } - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp new file mode 100644 index 000000000..9c0176725 --- /dev/null +++ b/components/esm/loadscpt.cpp @@ -0,0 +1,42 @@ +#include "loadscpt.hpp" + +namespace ESM +{ + +void Script::load(ESMReader &esm) +{ + esm.getHNT(data, "SCHD", 52); + + // List of local variables + if (esm.isNextSub("SCVR")) + { + int s = data.stringTableSize; + char* tmp = new char[s]; + esm.getHExact(tmp, s); + + // Set up the list of variable names + varNames.resize(data.numShorts + data.numLongs + data.numFloats); + + // The tmp buffer is a null-byte separated string list, we + // just have to pick out one string at a time. + char* str = tmp; + for (size_t i = 0; i < varNames.size(); i++) + { + varNames[i] = std::string(str); + str += varNames[i].size() + 1; + + if (str - tmp > s) + esm.fail("String table overflow"); + } + delete[] tmp; + } + + // Script data + scriptData.resize(data.scriptDataSize); + esm.getHNExact(&scriptData[0], scriptData.size(), "SCDT"); + + // Script text + scriptText = esm.getHNOString("SCTX"); +} + +} diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index aa189c888..3ce3d9636 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -3,7 +3,8 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* * Script definitions @@ -12,80 +13,43 @@ namespace ESM { class Script { public: - struct SCHDstruct - { - /* Script name. - - NOTE: You should handle the name "Main" (case insensitive) with - care. With tribunal, modders got the ability to add 'start - scripts' to their mods, which is a script that is run at - startup and which runs throughout the game (I think.) - - However, before Tribunal, there was only one startup script, - called "Main". If mods wanted to make their own start scripts, - they had to overwrite Main. This is obviously problem if - multiple mods to this at the same time. - - Although most mods have switched to using Trib-style startup - scripts, some legacy mods might still overwrite Main, and this - can cause problems if several mods do it. I think the best - course of action is to NEVER overwrite main, but instead add - each with a separate unique name and add them to the start - script list. But there might be other problems with this - approach though. - */ - - NAME32 name; - - // These describe the sizes we need to allocate for the script - // data. - int numShorts, numLongs, numFloats, - scriptDataSize, stringTableSize; - }; // 52 bytes - - SCHDstruct data; - - std::vector varNames; // Variable names - std::vector scriptData; // Compiled bytecode - std::string scriptText; // Uncompiled script - - void load(ESMReader &esm) - { - esm.getHNT(data, "SCHD", 52); - - // List of local variables - if(esm.isNextSub("SCVR")) - { - int s = data.stringTableSize; - char* tmp = new char[s]; - esm.getHExact(tmp, s); - - // Set up the list of variable names - varNames.resize(data.numShorts + - data.numLongs + - data.numFloats); - - // The tmp buffer is a null-byte separated string list, we - // just have to pick out one string at a time. - char* str = tmp; - for(size_t i=0; i< varNames.size(); i++) - { - varNames[i] = std::string(str); - str += varNames[i].size()+1; - - if(str - tmp > s) - esm.fail("String table overflow"); - } - delete[] tmp; - } - - // Script data - scriptData.resize(data.scriptDataSize); - esm.getHNExact(&scriptData[0], scriptData.size(), "SCDT"); - - // Script text - scriptText = esm.getHNOString("SCTX"); - } + struct SCHDstruct + { + /* Script name. + + NOTE: You should handle the name "Main" (case insensitive) with + care. With tribunal, modders got the ability to add 'start + scripts' to their mods, which is a script that is run at + startup and which runs throughout the game (I think.) + + However, before Tribunal, there was only one startup script, + called "Main". If mods wanted to make their own start scripts, + they had to overwrite Main. This is obviously problem if + multiple mods to this at the same time. + + Although most mods have switched to using Trib-style startup + scripts, some legacy mods might still overwrite Main, and this + can cause problems if several mods do it. I think the best + course of action is to NEVER overwrite main, but instead add + each with a separate unique name and add them to the start + script list. But there might be other problems with this + approach though. + */ + + NAME32 name; + + // These describe the sizes we need to allocate for the script + // data. + int numShorts, numLongs, numFloats, scriptDataSize, stringTableSize; + }; // 52 bytes + + SCHDstruct data; + + std::vector varNames; // Variable names + std::vector scriptData; // Compiled bytecode + std::string scriptText; // Uncompiled script + + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadskil.cpp b/components/esm/loadskil.cpp index 77ce2d368..aa7103efc 100644 --- a/components/esm/loadskil.cpp +++ b/components/esm/loadskil.cpp @@ -1,33 +1,70 @@ #include "loadskil.hpp" -namespace ESMS +namespace ESM { - const std::string Skill::sSkillNames[Length] = { - "Block", - "Armorer", - "Medium Armor", - "Heavy Armor", - "Blunt Weapon", - "Long Blade", - "Axe", - "Spear", - "Athletics", - "Enchant", - "Destruction", - "Alteration", - "Illusion", - "Conjuration", - "Mysticism", - "Restoration", - "Alchemy", - "Unarmored", - "Security", - "Sneak", - "Acrobatics", - "Light Armor", - "Short Blade", - "Marksman", - "Speechcraft", - "Hand To Hand", + const std::string Skill::sSkillNameIds[Length] = { + "sSkillBlock", + "sSkillArmorer", + "sSkillMediumarmor", + "sSkillHeavyarmor", + "sSkillBluntweapon", + "sSkillLongblade", + "sSkillAxe", + "sSkillSpear", + "sSkillAthletics", + "sSkillEnchant", + "sSkillDestruction", + "sSkillAlteration", + "sSkillIllusion", + "sSkillConjuration", + "sSkillMysticism", + "sSkillRestoration", + "sSkillAlchemy", + "sSkillUnarmored", + "sSkillSecurity", + "sSkillSneak", + "sSkillAcrobatics", + "sSkillLightarmor", + "sSkillShortblade", + "sSkillMarksman", + "sSkillMercantile", + "sSkillSpeechcraft", + "sSkillHandtohand", }; + const boost::array Skill::skillIds = {{ + Block, + Armorer, + MediumArmor, + HeavyArmor, + BluntWeapon, + LongBlade, + Axe, + Spear, + Athletics, + Enchant, + Destruction, + Alteration, + Illusion, + Conjuration, + Mysticism, + Restoration, + Alchemy, + Unarmored, + Security, + Sneak, + Acrobatics, + LightArmor, + ShortBlade, + Marksman, + Mercantile, + Speechcraft, + HandToHand + }}; + +void Skill::load(ESMReader &esm) +{ + esm.getHNT(index, "INDX"); + esm.getHNT(data, "SKDT", 24); + description = esm.getHNOString("DESC"); +} } diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index ffcbcbb31..836f70205 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -66,12 +66,7 @@ struct Skill static const std::string sSkillNameIds[Length]; static const boost::array skillIds; - void load(ESMReader &esm) - { - esm.getHNT(index, "INDX"); - esm.getHNT(data, "SKDT", 24); - description = esm.getHNOString("DESC"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadsndg.cpp b/components/esm/loadsndg.cpp new file mode 100644 index 000000000..b7b568132 --- /dev/null +++ b/components/esm/loadsndg.cpp @@ -0,0 +1,14 @@ +#include "loadsndg.hpp" + +namespace ESM +{ + +void SoundGenerator::load(ESMReader &esm) +{ + esm.getHNT(type, "DATA", 4); + + creature = esm.getHNOString("CNAM"); + sound = esm.getHNOString("SNAM"); +} + +} diff --git a/components/esm/loadsndg.hpp b/components/esm/loadsndg.hpp index 372b75085..f8803f8c0 100644 --- a/components/esm/loadsndg.hpp +++ b/components/esm/loadsndg.hpp @@ -28,13 +28,7 @@ struct SoundGenerator std::string creature, sound; - void load(ESMReader &esm) - { - esm.getHNT(type, "DATA", 4); - - creature = esm.getHNOString("CNAM"); - sound = esm.getHNOString("SNAM"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadsoun.cpp b/components/esm/loadsoun.cpp new file mode 100644 index 000000000..cd47f0f17 --- /dev/null +++ b/components/esm/loadsoun.cpp @@ -0,0 +1,18 @@ +#include "loadsoun.hpp" + +namespace ESM +{ + +void Sound::load(ESMReader &esm) +{ + sound = esm.getHNString("FNAM"); + esm.getHNT(data, "DATA", 3); + /* + cout << "vol=" << (int)data.volume + << " min=" << (int)data.minRange + << " max=" << (int)data.maxRange + << endl; + */ +} + +} diff --git a/components/esm/loadsoun.hpp b/components/esm/loadsoun.hpp index 597c91491..775a664be 100644 --- a/components/esm/loadsoun.hpp +++ b/components/esm/loadsoun.hpp @@ -3,20 +3,20 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ struct SOUNstruct { - unsigned char volume, minRange, maxRange; + unsigned char volume, minRange, maxRange; }; struct Sound { - SOUNstruct data; - std::string sound; + SOUNstruct data; + std::string sound; - // Body moved to load_impl.cpp - void load(ESMReader &esm); + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadspel.cpp b/components/esm/loadspel.cpp new file mode 100644 index 000000000..c3c928ce6 --- /dev/null +++ b/components/esm/loadspel.cpp @@ -0,0 +1,13 @@ +#include "loadspel.hpp" + +namespace ESM +{ + +void Spell::load(ESMReader &esm) +{ + name = esm.getHNOString("FNAM"); + esm.getHNT(data, "SPDT", 12); + effects.load(esm); +} + +} diff --git a/components/esm/loadspel.hpp b/components/esm/loadspel.hpp index a141e7dc1..c97d037cd 100644 --- a/components/esm/loadspel.hpp +++ b/components/esm/loadspel.hpp @@ -2,45 +2,42 @@ #define _ESM_SPEL_H #include "esm_reader.hpp" +#include "defs.hpp" -namespace ESM { +namespace ESM +{ struct Spell { - enum SpellType + enum SpellType { - ST_Spell = 0, // Normal spell, must be cast and costs mana - ST_Ability = 1, // Inert ability, always in effect - ST_Blight = 2, // Blight disease - ST_Disease = 3, // Common disease - ST_Curse = 4, // Curse (?) - ST_Power = 5 // Power, can use once a day + ST_Spell = 0, // Normal spell, must be cast and costs mana + ST_Ability = 1, // Inert ability, always in effect + ST_Blight = 2, // Blight disease + ST_Disease = 3, // Common disease + ST_Curse = 4, // Curse (?) + ST_Power = 5 // Power, can use once a day }; - enum Flags + enum Flags { - F_Autocalc = 1, - F_PCStart = 2, - F_Always = 4 // Casting always succeeds + F_Autocalc = 1, + F_PCStart = 2, + F_Always = 4 // Casting always succeeds }; - struct SPDTstruct - { - int type; // SpellType - int cost; // Mana cost - int flags; // Flags - }; + struct SPDTstruct + { + int type; // SpellType + int cost; // Mana cost + int flags; // Flags + }; - SPDTstruct data; - std::string name; - EffectList effects; + SPDTstruct data; + std::string name; + EffectList effects; - void load(ESMReader &esm) - { - name = esm.getHNOString("FNAM"); - esm.getHNT(data, "SPDT", 12); - effects.load(esm); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadsscr.cpp b/components/esm/loadsscr.cpp new file mode 100644 index 000000000..f4e79271c --- /dev/null +++ b/components/esm/loadsscr.cpp @@ -0,0 +1,13 @@ +#include "loadsscr.hpp" + +namespace ESM +{ + +void StartScript::load(ESMReader &esm) +{ + esm.getSubNameIs("DATA"); + esm.skipHSub(); + script = esm.getHNString("NAME"); +} + +} diff --git a/components/esm/loadsscr.hpp b/components/esm/loadsscr.hpp index e06fd6c70..d18bde101 100644 --- a/components/esm/loadsscr.hpp +++ b/components/esm/loadsscr.hpp @@ -3,27 +3,23 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* - Startup script. I think this is simply a 'main' script that is run - from the begining. The SSCR records contain a DATA identifier which - is totally useless (TODO: don't remember what it contains exactly, - document it below later.), and a NAME which is simply a script - reference. + Startup script. I think this is simply a 'main' script that is run + from the begining. The SSCR records contain a DATA identifier which + is totally useless (TODO: don't remember what it contains exactly, + document it below later.), and a NAME which is simply a script + reference. */ struct StartScript { - std::string script; + std::string script; - // Load a record and add it to the list - void load(ESMReader &esm) - { - esm.getSubNameIs("DATA"); - esm.skipHSub(); - script = esm.getHNString("NAME"); - } + // Load a record and add it to the list + void load(ESMReader &esm); }; } diff --git a/components/esm/loadstat.cpp b/components/esm/loadstat.cpp new file mode 100644 index 000000000..654bf290a --- /dev/null +++ b/components/esm/loadstat.cpp @@ -0,0 +1,11 @@ +#include "loadstat.hpp" + +namespace ESM +{ + +void Static::load(ESMReader &esm) +{ + model = esm.getHNString("MODL"); +} + +} diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index 7b00df406..4f3121d18 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -21,10 +21,7 @@ struct Static { std::string model; - void load(ESMReader &esm) - { - model = esm.getHNString("MODL"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/loadweap.cpp b/components/esm/loadweap.cpp new file mode 100644 index 000000000..1910631bc --- /dev/null +++ b/components/esm/loadweap.cpp @@ -0,0 +1,16 @@ +#include "loadweap.hpp" + +namespace ESM +{ + +void Weapon::load(ESMReader &esm) +{ + model = esm.getHNString("MODL"); + name = esm.getHNOString("FNAM"); + esm.getHNT(data, "WPDT", 32); + script = esm.getHNOString("SCRI"); + icon = esm.getHNOString("ITEX"); + enchant = esm.getHNOString("ENAM"); +} + +} diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index e6a848a59..8bd3b147c 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -3,7 +3,8 @@ #include "esm_reader.hpp" -namespace ESM { +namespace ESM +{ /* * Weapon definition @@ -11,58 +12,50 @@ namespace ESM { struct Weapon { - enum Type + enum Type { - ShortBladeOneHand = 0, - LongBladeOneHand = 1, - LongBladeTwoHand = 2, - BluntOneHand = 3, - BluntTwoClose = 4, - BluntTwoWide = 5, - SpearTwoWide = 6, - AxeOneHand = 7, - AxeTwoHand = 8, - MarksmanBow = 9, - MarksmanCrossbow = 10, - MarksmanThrown = 11, - Arrow = 12, - Bolt = 13 + ShortBladeOneHand = 0, + LongBladeOneHand = 1, + LongBladeTwoHand = 2, + BluntOneHand = 3, + BluntTwoClose = 4, + BluntTwoWide = 5, + SpearTwoWide = 6, + AxeOneHand = 7, + AxeTwoHand = 8, + MarksmanBow = 9, + MarksmanCrossbow = 10, + MarksmanThrown = 11, + Arrow = 12, + Bolt = 13 }; - enum Flags + enum Flags { - Magical = 0x01, - Silver = 0x02 + Magical = 0x01, + Silver = 0x02 }; #pragma pack(push) #pragma pack(1) - struct WPDTstruct - { - float weight; - int value; - short type; - short health; - float speed, reach; - short enchant; // Enchantment points - unsigned char chop[2], slash[2], thrust[2]; // Min and max - int flags; - }; // 32 bytes + struct WPDTstruct + { + float weight; + int value; + short type; + short health; + float speed, reach; + short enchant; // Enchantment points + unsigned char chop[2], slash[2], thrust[2]; // Min and max + int flags; + }; // 32 bytes #pragma pack(pop) - WPDTstruct data; + WPDTstruct data; - std::string name, model, icon, enchant, script; + std::string name, model, icon, enchant, script; - void load(ESMReader &esm) - { - model = esm.getHNString("MODL"); - name = esm.getHNOString("FNAM"); - esm.getHNT(data, "WPDT", 32); - script = esm.getHNOString("SCRI"); - icon = esm.getHNOString("ITEX"); - enchant = esm.getHNOString("ENAM"); - } + void load(ESMReader &esm); }; } #endif diff --git a/components/esm/skill.cpp b/components/esm/skill.cpp deleted file mode 100644 index 05c8c103a..000000000 --- a/components/esm/skill.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "loadskil.hpp" - -namespace ESM -{ - const std::string Skill::sSkillNameIds[Length] = { - "sSkillBlock", - "sSkillArmorer", - "sSkillMediumarmor", - "sSkillHeavyarmor", - "sSkillBluntweapon", - "sSkillLongblade", - "sSkillAxe", - "sSkillSpear", - "sSkillAthletics", - "sSkillEnchant", - "sSkillDestruction", - "sSkillAlteration", - "sSkillIllusion", - "sSkillConjuration", - "sSkillMysticism", - "sSkillRestoration", - "sSkillAlchemy", - "sSkillUnarmored", - "sSkillSecurity", - "sSkillSneak", - "sSkillAcrobatics", - "sSkillLightarmor", - "sSkillShortblade", - "sSkillMarksman", - "sSkillMercantile", - "sSkillSpeechcraft", - "sSkillHandtohand", - }; - const boost::array Skill::skillIds = {{ - Block, - Armorer, - MediumArmor, - HeavyArmor, - BluntWeapon, - LongBlade, - Axe, - Spear, - Athletics, - Enchant, - Destruction, - Alteration, - Illusion, - Conjuration, - Mysticism, - Restoration, - Alchemy, - Unarmored, - Security, - Sneak, - Acrobatics, - LightArmor, - ShortBlade, - Marksman, - Mercantile, - Speechcraft, - HandToHand - }}; -}