Refactored remaining headers in components/esm except defs.hpp.
Removed obsolete *.cpp files.actorid
parent
a2c42ab5a2
commit
1e5768170f
@ -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;
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#include "loadench.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void Enchantment::load(ESMReader &esm)
|
||||
{
|
||||
esm.getHNT(data, "ENDT", 16);
|
||||
effects.load(esm);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#include "loadltex.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void LandTexture::load(ESMReader &esm)
|
||||
{
|
||||
esm.getHNT(index, "INTV");
|
||||
texture = esm.getHNString("DATA");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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::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");
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
#include "loadsscr.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void StartScript::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");
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
@ -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…
Reference in New Issue