ESSImport: some fixes

openmw-35
scrawl 10 years ago
parent 69676906ae
commit acf8461841

@ -27,6 +27,8 @@ namespace
objstate.mEnabled = cellref.mEnabled; objstate.mEnabled = cellref.mEnabled;
objstate.mPosition = cellref.mPos; objstate.mPosition = cellref.mPos;
objstate.mRef.mRefNum = cellref.mRefNum; objstate.mRef.mRefNum = cellref.mRefNum;
if (cellref.mDeleted)
objstate.mCount = 0;
} }
bool isIndexedRefId(const std::string& indexedRefId) bool isIndexedRefId(const std::string& indexedRefId)
@ -34,6 +36,10 @@ namespace
if (indexedRefId.size() <= 8) if (indexedRefId.size() <= 8)
return false; return false;
if (indexedRefId.find_first_not_of("0123456789") == std::string::npos)
return false; // entirely numeric refid, this is a reference to
// a dynamically created record e.g. player-enchanted weapon
std::string index = indexedRefId.substr(indexedRefId.size()-8); std::string index = indexedRefId.substr(indexedRefId.size()-8);
if(index.find_first_not_of("0123456789ABCDEF") == std::string::npos ) if(index.find_first_not_of("0123456789ABCDEF") == std::string::npos )
return true; return true;
@ -136,13 +142,6 @@ namespace ESSImport
{ {
CellRef ref; CellRef ref;
ref.load (esm); ref.load (esm);
if (esm.isNextSub("DELE"))
{
// TODO
// strangely this can be e.g. 52 instead of just 1,
//std::cout << "deleted ref " << ref.mIndexedRefId << std::endl;
esm.skipHSub();
}
cellrefs.push_back(ref); cellrefs.push_back(ref);
} }
@ -201,8 +200,7 @@ namespace ESSImport
for (std::vector<CellRef>::const_iterator refIt = cell.mRefs.begin(); refIt != cell.mRefs.end(); ++refIt) for (std::vector<CellRef>::const_iterator refIt = cell.mRefs.begin(); refIt != cell.mRefs.end(); ++refIt)
{ {
const CellRef& cellref = *refIt; const CellRef& cellref = *refIt;
ESM::CellRef out; ESM::CellRef out (cellref);
out.blank();
if (!isIndexedRefId(cellref.mIndexedRefId)) if (!isIndexedRefId(cellref.mIndexedRefId))
{ {
@ -241,8 +239,8 @@ namespace ESSImport
objstate.mRef.mRefID = idLower; objstate.mRef.mRefID = idLower;
// probably need more micromanagement here so we don't overwrite values // probably need more micromanagement here so we don't overwrite values
// from the ESM with default values // from the ESM with default values
convertACDT(cellref.mActorData.mACDT, objstate.mCreatureStats); convertACDT(cellref.mACDT, objstate.mCreatureStats);
convertNpcData(cellref.mActorData, objstate.mNpcStats); convertNpcData(cellref, objstate.mNpcStats);
convertNPCC(npccIt->second, objstate); convertNPCC(npccIt->second, objstate);
convertCellRef(cellref, objstate); convertCellRef(cellref, objstate);
esm.writeHNT ("OBJE", ESM::REC_NPC_); esm.writeHNT ("OBJE", ESM::REC_NPC_);
@ -273,7 +271,7 @@ namespace ESSImport
objstate.blank(); objstate.blank();
objstate.mRef = out; objstate.mRef = out;
objstate.mRef.mRefID = idLower; objstate.mRef.mRefID = idLower;
convertACDT(cellref.mActorData.mACDT, objstate.mCreatureStats); convertACDT(cellref.mACDT, objstate.mCreatureStats);
// probably need more micromanagement here so we don't overwrite values // probably need more micromanagement here so we don't overwrite values
// from the ESM with default values // from the ESM with default values
convertCREC(crecIt->second, objstate); convertCREC(crecIt->second, objstate);

@ -90,14 +90,19 @@ public:
ESM::NPC npc; ESM::NPC npc;
std::string id = esm.getHNString("NAME"); std::string id = esm.getHNString("NAME");
npc.load(esm); npc.load(esm);
if (id != "player") // seems to occur sometimes, with "chargen X" names if (id != "player")
{
// this handles changes to the NPC struct, but since there is no index here
// it will apply to ALL instances of the class. seems to be the reason for the
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
std::cerr << "non-player NPC record: " << id << std::endl; std::cerr << "non-player NPC record: " << id << std::endl;
}
else else
{ {
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel; mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel;
mContext->mPlayerBase = npc; mContext->mPlayerBase = npc;
std::map<const int, float> empty; std::map<const int, float> empty;
// FIXME: player start spells, racial spells and birthsign spells aren't listed here, // FIXME: player start spells and birthsign spells aren't listed here,
// need to fix openmw to account for this // need to fix openmw to account for this
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it) for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it)
mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells[*it] = empty; mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells[*it] = empty;

@ -9,18 +9,16 @@ namespace ESSImport
void ActorData::load(ESM::ESMReader &esm) void ActorData::load(ESM::ESMReader &esm)
{ {
// unsure at which point between NAME and ESM::CellRef
if (esm.isNextSub("MNAM"))
esm.skipHSub();
if (esm.isNextSub("ACTN")) if (esm.isNextSub("ACTN"))
esm.skipHSub(); esm.skipHSub();
if (esm.isNextSub("STPR")) if (esm.isNextSub("STPR"))
esm.skipHSub(); esm.skipHSub();
ESM::CellRef bla; if (esm.isNextSub("MNAM"))
bla.ESM::CellRef::loadData(esm); esm.skipHSub();
ESM::CellRef::loadData(esm);
// FIXME: not all actors have this, add flag // FIXME: not all actors have this, add flag
esm.getHNOT(mACDT, "ACDT"); esm.getHNOT(mACDT, "ACDT");

@ -3,6 +3,8 @@
#include <string> #include <string>
#include <components/esm/cellref.hpp>
namespace ESM namespace ESM
{ {
struct ESMReader; struct ESMReader;
@ -37,7 +39,7 @@ namespace ESSImport
}; };
#pragma pack(pop) #pragma pack(pop)
struct ActorData struct ActorData : public ESM::CellRef
{ {
ACDT mACDT; ACDT mACDT;

@ -7,6 +7,8 @@ namespace ESSImport
void CellRef::load(ESM::ESMReader &esm) void CellRef::load(ESM::ESMReader &esm)
{ {
blank();
// (FRMR subrecord name is already read by the loop in ConvertCell) // (FRMR subrecord name is already read by the loop in ConvertCell)
esm.getHT(mRefNum.mIndex); // FRMR esm.getHT(mRefNum.mIndex); // FRMR
@ -25,17 +27,26 @@ namespace ESSImport
esm.getHT(lvcr); esm.getHT(lvcr);
//std::cout << "LVCR: " << (int)lvcr << std::endl; //std::cout << "LVCR: " << (int)lvcr << std::endl;
} }
mActorData.load(esm); ActorData::load(esm);
mEnabled = true; mEnabled = true;
esm.getHNOT(mEnabled, "ZNAM"); esm.getHNOT(mEnabled, "ZNAM");
// should occur for all references but not levelled creature spawners // DATA should occur for all references, except leveled creature spawners
esm.getHNOT(mPos, "DATA", 24); // I've seen DATA *twice* on a creature record, and with the exact same content too! weird
// i've seen DATA record TWICE on a creature record - and with the exact same content too! weird
// alarmvoi0000.ess // alarmvoi0000.ess
esm.getHNOT(mPos, "DATA", 24); esm.getHNOT(mPos, "DATA", 24);
esm.getHNOT(mPos, "DATA", 24);
mDeleted = 0;
if (esm.isNextSub("DELE"))
{
int deleted;
esm.getHT(deleted);
// Neither of this seems to work right...
//mDeleted = (deleted != 0);
//mDeleted = (deleted&0x1);
}
if (esm.isNextSub("MVRF")) if (esm.isNextSub("MVRF"))
{ {

@ -15,20 +15,16 @@ namespace ESM
namespace ESSImport namespace ESSImport
{ {
// Not sure if we can share any code with ESM::CellRef here struct CellRef : public ActorData
struct CellRef
{ {
std::string mIndexedRefId; std::string mIndexedRefId;
ESM::RefNum mRefNum;
ActorData mActorData;
ESM::Position mPos;
std::string mScript; std::string mScript;
bool mEnabled; bool mEnabled;
bool mDeleted;
void load(ESM::ESMReader& esm); void load(ESM::ESMReader& esm);
}; };

@ -14,6 +14,16 @@ namespace ESSImport
float scale; float scale;
esm.getHNOT(scale, "XSCL"); esm.getHNOT(scale, "XSCL");
// FIXME: use AiPackageList, need to fix getSubName()
if (esm.isNextSub("AI_W"))
esm.skipHSub();
if (esm.isNextSub("AI_E"))
esm.skipHSub();
if (esm.isNextSub("AI_T"))
esm.skipHSub();
if (esm.isNextSub("AI_F"))
esm.skipHSub();
mInventory.load(esm); mInventory.load(esm);
} }

@ -9,6 +9,9 @@ namespace ESSImport
{ {
esm.getHNT(mNPDT, "NPDT"); esm.getHNT(mNPDT, "NPDT");
// FIXME: use AiPackageList, need to fix getSubName()
if (esm.isNextSub("AI_W"))
esm.skipHSub();
if (esm.isNextSub("AI_E")) if (esm.isNextSub("AI_E"))
esm.skipHSub(); esm.skipHSub();
if (esm.isNextSub("AI_T")) if (esm.isNextSub("AI_T"))

Loading…
Cancel
Save