Refactored remaining headers in components/esm except defs.hpp.

Removed obsolete *.cpp files.
actorid
Nikolay Kasyanov 14 years ago
parent a2c42ab5a2
commit 1e5768170f

@ -127,10 +127,7 @@ source_group(components\\esm_store FILES ${ESM_STORE} ${ESM_STORE_HEADER})
file(GLOB ESM_HEADER ${COMP_DIR}/esm/*.hpp) file(GLOB ESM_HEADER ${COMP_DIR}/esm/*.hpp)
set(ESM set(ESM
${COMP_DIR}/esm/load_impl.cpp
${COMP_DIR}/esm/skill.cpp
${COMP_DIR}/esm/attr.cpp ${COMP_DIR}/esm/attr.cpp
${COMP_DIR}/esm/class.cpp
${COMP_DIR}/esm/esm_reader.cpp ${COMP_DIR}/esm/esm_reader.cpp
${COMP_DIR}/esm/loadland.cpp ${COMP_DIR}/esm/loadland.cpp
${COMP_DIR}/esm/loadacti.cpp ${COMP_DIR}/esm/loadacti.cpp
@ -143,6 +140,34 @@ set(ESM
${COMP_DIR}/esm/loadcell.cpp ${COMP_DIR}/esm/loadcell.cpp
${COMP_DIR}/esm/loadclas.cpp ${COMP_DIR}/esm/loadclas.cpp
${COMP_DIR}/esm/loadclot.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}) source_group(components\\esm FILES ${ESM_HEADER} ${ESM})

@ -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"
};

@ -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 <iostream>
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;
*/
}
}

@ -3,6 +3,18 @@
namespace ESM 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) void Class::load(ESMReader &esm)
{ {
name = esm.getHNString("FNAM"); name = esm.getHNString("FNAM");

@ -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);
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Container definition * Container definition
@ -19,15 +20,7 @@ struct InventoryList
{ {
std::vector<ContItem> list; std::vector<ContItem> list;
void load(ESMReader &esm) void load(ESMReader &esm);
{
ContItem ci;
while(esm.isNextSub("NPCO"))
{
esm.getHT(ci, 36);
list.push_back(ci);
}
}
}; };
struct Container struct Container
@ -45,20 +38,7 @@ struct Container
int flags; int flags;
InventoryList inventory; InventoryList inventory;
void load(ESMReader &esm) 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");
script = esm.getHNOString("SCRI");
inventory.load(esm);
}
}; };
} }
#endif #endif

@ -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();
}
}

@ -4,7 +4,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "loadcont.hpp" #include "loadcont.hpp"
namespace ESM { namespace ESM
{
/* /*
* Creature definition * Creature definition
@ -16,24 +17,20 @@ struct Creature
// Default is 0x48? // Default is 0x48?
enum Flags enum Flags
{ {
Biped = 0x001, Biped = 0x001, Respawn = 0x002, Weapon = 0x004, // Has weapon and shield
Respawn = 0x002,
Weapon = 0x004, // Has weapon and shield
None = 0x008, // ?? None = 0x008, // ??
Swims = 0x010, Swims = 0x010,
Flies = 0x020, // Don't know what happens if several Flies = 0x020, // Don't know what happens if several
Walks = 0x040, // of these are set Walks = 0x040, // of these are set
Essential = 0x080, Essential = 0x080,
Skeleton = 0x400, // Does not have normal blood Skeleton = 0x400, // Does not have normal blood
Metal = 0x800 // Has 'golden' blood Metal = 0x800
// Has 'golden' blood
}; };
enum Type enum Type
{ {
Creatures = 0, Creatures = 0, Deadra = 1, Undead = 2, Humanoid = 3
Deadra = 1,
Undead = 2,
Humanoid = 3
}; };
struct NPDTstruct struct NPDTstruct
@ -56,48 +53,14 @@ struct Creature
int flags; int flags;
float scale; float scale;
std::string model, name, script, std::string model, name, script, original; // Base creature that this is a modification of
original; // Base creature that this is a modification of
// Defined in loadcont.hpp // Defined in loadcont.hpp
InventoryList inventory; InventoryList inventory;
std::string mId; std::string mId;
void load(ESMReader &esm, const std::string& id) 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();
}
}; };
} }
#endif #endif

@ -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");
}
}

@ -6,7 +6,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "loadinfo.hpp" #include "loadinfo.hpp"
namespace ESM { namespace ESM
{
/* /*
* Dialogue topic and journal entries. The actual data is contained in * Dialogue topic and journal entries. The actual data is contained in
@ -28,23 +29,7 @@ struct Dialogue
char type; char type;
std::vector<DialInfo> mInfo; std::vector<DialInfo> mInfo;
void load(ESMReader &esm) 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");
}
}; };
} }
#endif #endif

@ -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");
}
}

@ -3,20 +3,14 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
struct Door struct Door
{ {
std::string name, model, script, openSound, closeSound; std::string name, model, script, openSound, closeSound;
void load(ESMReader &esm) void load(ESMReader &esm);
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
script = esm.getHNOString("SCRI");
openSound = esm.getHNOString("SNAM");
closeSound = esm.getHNOString("ANAM");
}
}; };
} }
#endif #endif

@ -0,0 +1,12 @@
#include "loadench.hpp"
namespace ESM
{
void Enchantment::load(ESMReader &esm)
{
esm.getHNT(data, "ENDT", 16);
effects.load(esm);
}
}

@ -2,8 +2,10 @@
#define _ESM_ENCH_H #define _ESM_ENCH_H
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "defs.hpp"
namespace ESM { namespace ESM
{
/* /*
* Enchantments * Enchantments
@ -31,11 +33,7 @@ struct Enchantment
ENDTstruct data; ENDTstruct data;
EffectList effects; EffectList effects;
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getHNT(data, "ENDT", 16);
effects.load(esm);
}
}; };
} }
#endif #endif

@ -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);
}
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Faction definitions * Faction definitions
@ -51,28 +52,7 @@ struct Faction
// Name of faction ranks (may be empty for NPC factions) // Name of faction ranks (may be empty for NPC factions)
std::string ranks[10]; std::string ranks[10];
void load(ESMReader &esm) void 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);
}
}
}; };
} }
#endif #endif

@ -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");
}
}

@ -2,8 +2,10 @@
#define _ESM_GLOB_H #define _ESM_GLOB_H
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "defs.hpp"
namespace ESM { namespace ESM
{
/* /*
* Global script variables * Global script variables
@ -14,19 +16,7 @@ struct Global
unsigned value; unsigned value;
VarType type; VarType type;
void load(ESMReader &esm) 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;
// Note: Both floats and longs are represented as floats.
esm.getHNT(value, "FLTV");
}
}; };
} }
#endif #endif

@ -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;
}
}

@ -4,7 +4,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "defs.hpp" #include "defs.hpp"
namespace ESM { namespace ESM
{
/* /*
* Game setting, with automatic cleaning of "dirty" entries. * Game setting, with automatic cleaning of "dirty" entries.
@ -72,179 +73,16 @@ struct GameSetting
affected and will work correctly. 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 Checks for dirty tribunal values. These will be ignored if found
in any file except when they are found in "Tribunal.esm". in any file except when they are found in "Tribunal.esm".
*/ */
bool isDirtyTribunal() bool 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 // Bloodmoon variant
bool isDirtyBloodmoon() 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 void load(ESMReader &esm);
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;
}
}; };
} }
#endif #endif

@ -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();
}
}

@ -4,7 +4,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "defs.hpp" #include "defs.hpp"
namespace ESM { namespace ESM
{
// NOT DONE // NOT DONE

@ -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");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Alchemy ingredient * Alchemy ingredient
@ -23,14 +24,7 @@ struct Ingredient
IRDTstruct data; IRDTstruct data;
std::string name, model, icon, script; std::string name, model, icon, script;
void load(ESMReader &esm) 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");
}
}; };
} }
#endif #endif

@ -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");
}
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Leveled lists. Since these have identical layout, I only bothered * Leveled lists. Since these have identical layout, I only bothered
@ -41,39 +42,24 @@ struct LeveledListBase
std::vector<LevelItem> list; std::vector<LevelItem> list;
void load(ESMReader &esm) void load(ESMReader &esm);
{ };
esm.getHNT(flags, "DATA");
esm.getHNT(chanceNone, "NNAM");
if(esm.isNextSub("INDX")) struct CreatureLevList: LeveledListBase
{ {
int len; CreatureLevList()
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]; recName = "CNAM";
li.id = esm.getHNString(recName);
esm.getHNT(li.level, "INTV");
}
} }
}; };
struct CreatureLevList : LeveledListBase
{ CreatureLevList() { recName = "CNAM"; } };
struct ItemLevList: LeveledListBase struct ItemLevList: LeveledListBase
{ ItemLevList() { recName = "INAM"; } }; {
ItemLevList()
{
recName = "INAM";
}
};
} }
#endif #endif

@ -0,0 +1,17 @@
#include "loadligh.hpp"
namespace ESM
{
void Light::load(ESMReader &esm)
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
icon = esm.getHNOString("ITEX");
assert(sizeof(data) == 24);
esm.getHNT(data, "LHDT", 24);
script = esm.getHNOString("SCRI");
sound = esm.getHNOString("SNAM");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Lights. Includes static light sources and also carryable candles * Lights. Includes static light sources and also carryable candles
@ -39,16 +40,7 @@ struct Light
std::string sound, script, model, icon, name; std::string sound, script, model, icon, name;
void load(ESMReader &esm) void load(ESMReader &esm);
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
icon = esm.getHNOString("ITEX");
assert(sizeof(data) == 24);
esm.getHNT(data, "LHDT", 24);
script = esm.getHNOString("SCRI");
sound = esm.getHNOString("SNAM");
}
}; };
} }
#endif #endif

@ -0,0 +1,30 @@
#include "loadlocks.hpp"
namespace ESM
{
void Tool::load(ESMReader &esm)
{
model = esm.getHNString("MODL");
name = esm.getHNString("FNAM");
esm.getSubName();
NAME n = esm.retSubName();
// The data name varies, RIDT for repair items, LKDT for lock
// picks, PBDT for probes
esm.getHT(data, 16);
if (n == "RIDT")
{
// Swap t.data.quality and t.data.uses for repair items (sigh)
float tmp = *((float*) &data.uses);
data.uses = *((int*) &data.quality);
data.quality = tmp;
}
script = esm.getHNOString("SCRI");
icon = esm.getHNOString("ITEX");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* This file covers lockpicks (LOCK), probes (PROB) and armor repair * This file covers lockpicks (LOCK), probes (PROB) and armor repair
@ -26,29 +27,7 @@ struct Tool
Data data; Data data;
std::string name, model, icon, script; std::string name, model, icon, script;
void load(ESMReader &esm) void load(ESMReader &esm);
{
model = esm.getHNString("MODL");
name = esm.getHNString("FNAM");
esm.getSubName();
NAME n = esm.retSubName();
// The data name varies, RIDT for repair items, LKDT for lock
// picks, PBDT for probes
esm.getHT(data, 16);
if(n == "RIDT")
{
// Swap t.data.quality and t.data.uses for repair items (sigh)
float tmp = *((float*)&data.uses);
data.uses = *((int*)&data.quality);
data.quality = tmp;
}
script = esm.getHNOString("SCRI");
icon = esm.getHNOString("ITEX");
}
}; };
struct Probe: Tool struct Probe: Tool

@ -0,0 +1,12 @@
#include "loadltex.hpp"
namespace ESM
{
void LandTexture::load(ESMReader &esm)
{
esm.getHNT(index, "INTV");
texture = esm.getHNString("DATA");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Texture used for texturing landscape. * Texture used for texturing landscape.
@ -26,11 +27,7 @@ struct LandTexture
std::string id, texture; std::string id, texture;
int index; int index;
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getHNT(index, "INTV");
texture = esm.getHNString("DATA");
}
}; };
} }
#endif #endif

@ -0,0 +1,27 @@
#include "loadmgef.hpp"
namespace ESM
{
void MagicEffect::load(ESMReader &esm)
{
esm.getHNT(index, "INDX");
esm.getHNT(data, "MEDT", 36);
icon = esm.getHNOString("ITEX");
particle = esm.getHNOString("PTEX");
boltSound = esm.getHNOString("BSND");
castSound = esm.getHNOString("CSND");
hitSound = esm.getHNOString("HSND");
areaSound = esm.getHNOString("ASND");
casting = esm.getHNOString("CVFX");
bolt = esm.getHNOString("BVFX");
hit = esm.getHNOString("HVFX");
area = esm.getHNOString("AVFX");
description = esm.getHNOString("DESC");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
struct MagicEffect struct MagicEffect
{ {
@ -30,8 +31,7 @@ struct MagicEffect
std::string icon, particle, // Textures std::string icon, particle, // Textures
casting, hit, area, // Statics casting, hit, area, // Statics
bolt, // Weapon bolt, // Weapon
castSound, boltSound, castSound, boltSound, hitSound, areaSound, // Sounds
hitSound, areaSound, // Sounds
description; description;
// Index of this magical effect. Corresponds to one of the // Index of this magical effect. Corresponds to one of the
@ -45,26 +45,7 @@ struct MagicEffect
// sMagicCreature04ID/05ID. // sMagicCreature04ID/05ID.
int index; int index;
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getHNT(index, "INDX");
esm.getHNT(data, "MEDT", 36);
icon = esm.getHNOString("ITEX");
particle = esm.getHNOString("PTEX");
boltSound = esm.getHNOString("BSND");
castSound = esm.getHNOString("CSND");
hitSound = esm.getHNOString("HSND");
areaSound = esm.getHNOString("ASND");
casting = esm.getHNOString("CVFX");
bolt = esm.getHNOString("BVFX");
hit = esm.getHNOString("HVFX");
area = esm.getHNOString("AVFX");
description = esm.getHNOString("DESC");
}
}; };
} }
#endif #endif

@ -0,0 +1,15 @@
#include "loadmisc.hpp"
namespace ESM
{
void Misc::load(ESMReader &esm)
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
esm.getHNT(data, "MCDT", 12);
script = esm.getHNOString("SCRI");
icon = esm.getHNOString("ITEX");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Misc inventory items, basically things that have no use but can be * Misc inventory items, basically things that have no use but can be
@ -24,14 +25,7 @@ struct Misc
std::string name, model, icon, script; std::string name, model, icon, script;
void load(ESMReader &esm) void load(ESMReader &esm);
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
esm.getHNT(data, "MCDT", 12);
script = esm.getHNOString("SCRI");
icon = esm.getHNOString("ITEX");
}
}; };
} }
#endif #endif

@ -0,0 +1,48 @@
#include "loadnpc.hpp"
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();
}
}

@ -0,0 +1,35 @@
#include "loadpgrd.hpp"
namespace ESM
{
void PathGrid::load(ESMReader &esm)
{
esm.getHNT(data, "DATA", 12);
cell = esm.getHNString("NAME");
// Remember this file position
context = esm.getContext();
// Check that the sizes match up. Size = 16 * s2 (path points?)
if (esm.isNextSub("PGRP"))
{
esm.skipHSub();
int size = esm.getSubSize();
if (size != 16 * data.s2)
esm.fail("Path grid table size mismatch");
}
// Size varies. Path grid chances? Connections? Multiples of 4
// suggest either int or two shorts, or perhaps a float. Study
// it later.
if (esm.isNextSub("PGRC"))
{
esm.skipHSub();
int size = esm.getSubSize();
if (size % 4 != 0)
esm.fail("PGRC size not a multiple of 4");
}
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Path grid. * Path grid.
@ -23,34 +24,7 @@ struct PathGrid
ESM_Context context; // Context so we can return here later and ESM_Context context; // Context so we can return here later and
// finish the job // finish the job
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getHNT(data, "DATA", 12);
cell = esm.getHNString("NAME");
// Remember this file position
context = esm.getContext();
// Check that the sizes match up. Size = 16 * s2 (path points?)
if(esm.isNextSub("PGRP"))
{
esm.skipHSub();
int size = esm.getSubSize();
if(size != 16*data.s2)
esm.fail("Path grid table size mismatch");
}
// Size varies. Path grid chances? Connections? Multiples of 4
// suggest either int or two shorts, or perhaps a float. Study
// it later.
if(esm.isNextSub("PGRC"))
{
esm.skipHSub();
int size = esm.getSubSize();
if(size % 4 != 0)
esm.fail("PGRC size not a multiple of 4");
}
}
}; };
} }
#endif #endif

@ -0,0 +1,14 @@
#include "loadrace.hpp"
namespace ESM
{
void Race::load(ESMReader &esm)
{
name = esm.getHNString("FNAM");
esm.getHNT(data, "RADT", 140);
powers.load(esm);
description = esm.getHNOString("DESC");
}
}

@ -2,8 +2,10 @@
#define _ESM_RACE_H #define _ESM_RACE_H
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "defs.hpp"
namespace ESM { namespace ESM
{
/* /*
* Race definition * Race definition
@ -39,8 +41,8 @@ struct Race
SkillBonus bonus[7]; SkillBonus bonus[7];
// Attribute values for male/female // Attribute values for male/female
MaleFemale strength, intelligence, willpower, agility, MaleFemale strength, intelligence, willpower, agility, speed,
speed, endurance, personality, luck; endurance, personality, luck;
// The actual eye level height (in game units) is (probably) given // The actual eye level height (in game units) is (probably) given
// as 'height' times 128. This has not been tested yet. // as 'height' times 128. This has not been tested yet.
@ -48,21 +50,14 @@ struct Race
int flags; // 0x1 - playable, 0x2 - beast race int flags; // 0x1 - playable, 0x2 - beast race
// Size = 140 bytes }; // Size = 140 bytes
};
RADTstruct data; RADTstruct data;
std::string name, description; std::string name, description;
SpellList powers; SpellList powers;
void load(ESMReader &esm) void load(ESMReader &esm);
{
name = esm.getHNString("FNAM");
esm.getHNT(data, "RADT", 140);
powers.load(esm);
description = esm.getHNOString("DESC");
}
}; };
} }
#endif #endif

@ -0,0 +1,29 @@
#include "loadregn.hpp"
namespace ESM
{
void Region::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");
sleepList = esm.getHNOString("BNAM");
esm.getHNT(mapColor, "CNAM");
while (esm.hasMoreSubs())
{
SoundRef sr;
esm.getHNT(sr, "SNAM", 33);
soundList.push_back(sr);
}
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Region data * Region data
@ -16,8 +17,7 @@ struct Region
struct WEATstruct struct WEATstruct
{ {
// I guess these are probabilities // I guess these are probabilities
char clear, cloudy, foggy, overcast, rain, thunder, ash, char clear, cloudy, foggy, overcast, rain, thunder, ash, blight,
blight,
// Unknown weather, probably snow and something. Only // Unknown weather, probably snow and something. Only
// present in file version 1.3. // present in file version 1.3.
a, b; a, b;
@ -40,27 +40,7 @@ struct Region
std::vector<SoundRef> soundList; std::vector<SoundRef> soundList;
void load(ESMReader &esm) 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");
sleepList = esm.getHNOString("BNAM");
esm.getHNT(mapColor, "CNAM");
while(esm.hasMoreSubs())
{
SoundRef sr;
esm.getHNT(sr, "SNAM", 33);
soundList.push_back(sr);
}
}
}; };
} }
#endif #endif

@ -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");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Script definitions * Script definitions
@ -39,8 +40,7 @@ public:
// These describe the sizes we need to allocate for the script // These describe the sizes we need to allocate for the script
// data. // data.
int numShorts, numLongs, numFloats, int numShorts, numLongs, numFloats, scriptDataSize, stringTableSize;
scriptDataSize, stringTableSize;
}; // 52 bytes }; // 52 bytes
SCHDstruct data; SCHDstruct data;
@ -49,43 +49,7 @@ public:
std::vector<char> scriptData; // Compiled bytecode std::vector<char> scriptData; // Compiled bytecode
std::string scriptText; // Uncompiled script std::string scriptText; // Uncompiled script
void load(ESMReader &esm) 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");
}
}; };
} }
#endif #endif

@ -1,33 +1,70 @@
#include "loadskil.hpp" #include "loadskil.hpp"
namespace ESMS namespace ESM
{ {
const std::string Skill::sSkillNames[Length] = { const std::string Skill::sSkillNameIds[Length] = {
"Block", "sSkillBlock",
"Armorer", "sSkillArmorer",
"Medium Armor", "sSkillMediumarmor",
"Heavy Armor", "sSkillHeavyarmor",
"Blunt Weapon", "sSkillBluntweapon",
"Long Blade", "sSkillLongblade",
"Axe", "sSkillAxe",
"Spear", "sSkillSpear",
"Athletics", "sSkillAthletics",
"Enchant", "sSkillEnchant",
"Destruction", "sSkillDestruction",
"Alteration", "sSkillAlteration",
"Illusion", "sSkillIllusion",
"Conjuration", "sSkillConjuration",
"Mysticism", "sSkillMysticism",
"Restoration", "sSkillRestoration",
"Alchemy", "sSkillAlchemy",
"Unarmored", "sSkillUnarmored",
"Security", "sSkillSecurity",
"Sneak", "sSkillSneak",
"Acrobatics", "sSkillAcrobatics",
"Light Armor", "sSkillLightarmor",
"Short Blade", "sSkillShortblade",
"Marksman", "sSkillMarksman",
"Speechcraft", "sSkillMercantile",
"Hand To Hand", "sSkillSpeechcraft",
"sSkillHandtohand",
}; };
const boost::array<Skill::SkillEnum, Skill::Length> 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");
}
} }

@ -66,12 +66,7 @@ struct Skill
static const std::string sSkillNameIds[Length]; static const std::string sSkillNameIds[Length];
static const boost::array<SkillEnum, Length> skillIds; static const boost::array<SkillEnum, Length> skillIds;
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getHNT(index, "INDX");
esm.getHNT(data, "SKDT", 24);
description = esm.getHNOString("DESC");
}
}; };
} }
#endif #endif

@ -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");
}
}

@ -28,13 +28,7 @@ struct SoundGenerator
std::string creature, sound; std::string creature, sound;
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getHNT(type, "DATA", 4);
creature = esm.getHNOString("CNAM");
sound = esm.getHNOString("SNAM");
}
}; };
} }
#endif #endif

@ -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;
*/
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
struct SOUNstruct struct SOUNstruct
{ {
@ -15,7 +16,6 @@ struct Sound
SOUNstruct data; SOUNstruct data;
std::string sound; std::string sound;
// Body moved to load_impl.cpp
void load(ESMReader &esm); void load(ESMReader &esm);
}; };
} }

@ -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);
}
}

@ -2,8 +2,10 @@
#define _ESM_SPEL_H #define _ESM_SPEL_H
#include "esm_reader.hpp" #include "esm_reader.hpp"
#include "defs.hpp"
namespace ESM { namespace ESM
{
struct Spell struct Spell
{ {
@ -35,12 +37,7 @@ struct Spell
std::string name; std::string name;
EffectList effects; EffectList effects;
void load(ESMReader &esm) void load(ESMReader &esm);
{
name = esm.getHNOString("FNAM");
esm.getHNT(data, "SPDT", 12);
effects.load(esm);
}
}; };
} }
#endif #endif

@ -0,0 +1,13 @@
#include "loadsscr.hpp"
namespace ESM
{
void StartScript::load(ESMReader &esm)
{
esm.getSubNameIs("DATA");
esm.skipHSub();
script = esm.getHNString("NAME");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
Startup script. I think this is simply a 'main' script that is run Startup script. I think this is simply a 'main' script that is run
@ -18,12 +19,7 @@ struct StartScript
std::string script; std::string script;
// Load a record and add it to the list // Load a record and add it to the list
void load(ESMReader &esm) void load(ESMReader &esm);
{
esm.getSubNameIs("DATA");
esm.skipHSub();
script = esm.getHNString("NAME");
}
}; };
} }

@ -0,0 +1,11 @@
#include "loadstat.hpp"
namespace ESM
{
void Static::load(ESMReader &esm)
{
model = esm.getHNString("MODL");
}
}

@ -21,10 +21,7 @@ struct Static
{ {
std::string model; std::string model;
void load(ESMReader &esm) void load(ESMReader &esm);
{
model = esm.getHNString("MODL");
}
}; };
} }
#endif #endif

@ -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");
}
}

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Weapon definition * Weapon definition
@ -54,15 +55,7 @@ struct Weapon
std::string name, model, icon, enchant, script; std::string name, model, icon, enchant, script;
void load(ESMReader &esm) 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");
}
}; };
} }
#endif #endif

@ -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::SkillEnum, Skill::Length> 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
}};
}
Loading…
Cancel
Save