mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 18:45:38 +00:00
essimporter: refactor ESSImport::CellRef and fix doubled actors
This commit is contained in:
parent
79cdc08253
commit
9f49682d01
9 changed files with 144 additions and 189 deletions
|
@ -5,7 +5,6 @@ set(ESSIMPORTER_FILES
|
|||
importnpcc.cpp
|
||||
importcrec.cpp
|
||||
importcellref.cpp
|
||||
importacdt.cpp
|
||||
importinventory.cpp
|
||||
importklst.cpp
|
||||
importcntc.cpp
|
||||
|
|
|
@ -35,11 +35,11 @@ namespace
|
|||
objstate.mRef.mRefNum = cellref.mRefNum;
|
||||
if (cellref.mDeleted)
|
||||
objstate.mCount = 0;
|
||||
convertSCRI(cellref.mSCRI, objstate.mLocals);
|
||||
convertSCRI(cellref.mActorData.mSCRI, objstate.mLocals);
|
||||
objstate.mHasLocals = !objstate.mLocals.mVariables.empty();
|
||||
|
||||
if (cellref.mHasANIS)
|
||||
convertANIS(cellref.mANIS, objstate.mAnimationState);
|
||||
if (cellref.mActorData.mHasANIS)
|
||||
convertANIS(cellref.mActorData.mANIS, objstate.mAnimationState);
|
||||
}
|
||||
|
||||
bool isIndexedRefId(const std::string& indexedRefId)
|
||||
|
@ -268,7 +268,7 @@ namespace ESSImport
|
|||
}
|
||||
|
||||
std::vector<CellRef> cellrefs;
|
||||
while (esm.hasMoreSubs() && esm.isNextSub("FRMR"))
|
||||
while (esm.hasMoreSubs() && esm.peekNextSub("FRMR"))
|
||||
{
|
||||
CellRef ref;
|
||||
ref.load (esm);
|
||||
|
@ -369,13 +369,13 @@ namespace ESSImport
|
|||
objstate.mRef.mRefID = idLower;
|
||||
// TODO: need more micromanagement here so we don't overwrite values
|
||||
// from the ESM with default values
|
||||
if (cellref.mHasACDT)
|
||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||
if (cellref.mActorData.mHasACDT)
|
||||
convertACDT(cellref.mActorData.mACDT, objstate.mCreatureStats);
|
||||
else
|
||||
objstate.mCreatureStats.mMissingACDT = true;
|
||||
if (cellref.mHasACSC)
|
||||
convertACSC(cellref.mACSC, objstate.mCreatureStats);
|
||||
convertNpcData(cellref, objstate.mNpcStats);
|
||||
if (cellref.mActorData.mHasACSC)
|
||||
convertACSC(cellref.mActorData.mACSC, objstate.mCreatureStats);
|
||||
convertNpcData(cellref.mActorData, objstate.mNpcStats);
|
||||
convertNPCC(npccIt->second, objstate);
|
||||
convertCellRef(cellref, objstate);
|
||||
|
||||
|
@ -412,12 +412,12 @@ namespace ESSImport
|
|||
objstate.mRef.mRefID = idLower;
|
||||
// TODO: need more micromanagement here so we don't overwrite values
|
||||
// from the ESM with default values
|
||||
if (cellref.mHasACDT)
|
||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||
if (cellref.mActorData.mHasACDT)
|
||||
convertACDT(cellref.mActorData.mACDT, objstate.mCreatureStats);
|
||||
else
|
||||
objstate.mCreatureStats.mMissingACDT = true;
|
||||
if (cellref.mHasACSC)
|
||||
convertACSC(cellref.mACSC, objstate.mCreatureStats);
|
||||
if (cellref.mActorData.mHasACSC)
|
||||
convertACSC(cellref.mActorData.mACSC, objstate.mCreatureStats);
|
||||
convertCREC(crecIt->second, objstate);
|
||||
convertCellRef(cellref, objstate);
|
||||
|
||||
|
|
|
@ -235,9 +235,9 @@ class ConvertREFR : public Converter
|
|||
public:
|
||||
void read(ESM::ESMReader &esm) override
|
||||
{
|
||||
REFR refr;
|
||||
CellRef refr;
|
||||
refr.load(esm);
|
||||
assert(refr.mRefID == "PlayerSaveGame");
|
||||
assert(refr.mIndexedRefID == "PlayerSaveGame");
|
||||
mContext->mPlayer.mObject.mPosition = refr.mPos;
|
||||
|
||||
ESM::CreatureStats& cStats = mContext->mPlayer.mObject.mCreatureStats;
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
#include "importacdt.hpp"
|
||||
|
||||
#include <components/esm3/esmreader.hpp>
|
||||
|
||||
#include <components/esm3/cellref.hpp>
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
||||
void ActorData::load(ESM::ESMReader &esm)
|
||||
{
|
||||
blank();
|
||||
|
||||
if (esm.isNextSub("ACTN"))
|
||||
{
|
||||
/*
|
||||
Activation flags:
|
||||
ActivationFlag_UseEnabled = 1
|
||||
ActivationFlag_OnActivate = 2
|
||||
ActivationFlag_OnDeath = 10h
|
||||
ActivationFlag_OnKnockout = 20h
|
||||
ActivationFlag_OnMurder = 40h
|
||||
ActivationFlag_DoorOpening = 100h
|
||||
ActivationFlag_DoorClosing = 200h
|
||||
ActivationFlag_DoorJammedOpening = 400h
|
||||
ActivationFlag_DoorJammedClosing = 800h
|
||||
*/
|
||||
esm.skipHSub();
|
||||
}
|
||||
|
||||
if (esm.isNextSub("STPR"))
|
||||
esm.skipHSub();
|
||||
|
||||
if (esm.isNextSub("MNAM"))
|
||||
esm.skipHSub();
|
||||
|
||||
bool isDeleted = false;
|
||||
ESM::CellRef::loadData(esm, isDeleted);
|
||||
|
||||
mHasACDT = false;
|
||||
if (esm.isNextSub("ACDT"))
|
||||
{
|
||||
mHasACDT = true;
|
||||
esm.getHT(mACDT);
|
||||
}
|
||||
|
||||
mHasACSC = false;
|
||||
if (esm.isNextSub("ACSC"))
|
||||
{
|
||||
mHasACSC = true;
|
||||
esm.getHT(mACSC);
|
||||
}
|
||||
|
||||
if (esm.isNextSub("ACSL"))
|
||||
esm.skipHSubSize(112);
|
||||
|
||||
if (esm.isNextSub("CSTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
if (esm.isNextSub("LSTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
// unsure at which point between LSTN and TGTN
|
||||
if (esm.isNextSub("CSHN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
// unsure if before or after CSTN/LSTN
|
||||
if (esm.isNextSub("LSHN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
while (esm.isNextSub("TGTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
while (esm.isNextSub("FGTN"))
|
||||
esm.getHString(); // fight target?
|
||||
|
||||
// unsure at which point between TGTN and CRED
|
||||
if (esm.isNextSub("AADT"))
|
||||
{
|
||||
// occurred when a creature was in the middle of its attack, 44 bytes
|
||||
esm.skipHSub();
|
||||
}
|
||||
|
||||
// unsure at which point between FGTN and CHRD
|
||||
if (esm.isNextSub("PWPC"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("PWPS"))
|
||||
esm.skipHSub();
|
||||
|
||||
if (esm.isNextSub("WNAM"))
|
||||
{
|
||||
std::string id = esm.getHString();
|
||||
|
||||
if (esm.isNextSub("XNAM"))
|
||||
mSelectedEnchantItem = esm.getHString();
|
||||
else
|
||||
mSelectedSpell = id;
|
||||
|
||||
if (esm.isNextSub("YNAM"))
|
||||
esm.skipHSub(); // 4 byte, 0
|
||||
}
|
||||
|
||||
while (esm.isNextSub("APUD"))
|
||||
{
|
||||
// used power
|
||||
esm.getSubHeader();
|
||||
std::string id = esm.getString(32);
|
||||
(void)id;
|
||||
// timestamp can't be used: this is the total hours passed, calculated by
|
||||
// timestamp = 24 * (365 * year + cumulativeDays[month] + day)
|
||||
// unfortunately cumulativeDays[month] is not clearly defined,
|
||||
// in the (non-MCP) vanilla version the first month was missing, but MCP added it.
|
||||
double timestamp;
|
||||
esm.getT(timestamp);
|
||||
}
|
||||
|
||||
// FIXME: not all actors have this, add flag
|
||||
if (esm.isNextSub("CHRD")) // npc only
|
||||
esm.getHExact(mSkills, 27*2*sizeof(int));
|
||||
|
||||
if (esm.isNextSub("CRED")) // creature only
|
||||
esm.getHExact(mCombatStats, 3*2*sizeof(int));
|
||||
|
||||
mSCRI.load(esm);
|
||||
|
||||
if (esm.isNextSub("ND3D"))
|
||||
esm.skipHSub();
|
||||
|
||||
mHasANIS = false;
|
||||
if (esm.isNextSub("ANIS"))
|
||||
{
|
||||
mHasANIS = true;
|
||||
esm.getHT(mANIS);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <components/esm3/cellref.hpp>
|
||||
|
||||
#include "importscri.hpp"
|
||||
|
||||
namespace ESM
|
||||
|
@ -63,7 +61,7 @@ namespace ESSImport
|
|||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct ActorData : public ESM::CellRef
|
||||
struct ActorData
|
||||
{
|
||||
bool mHasACDT;
|
||||
ACDT mACDT;
|
||||
|
@ -85,10 +83,6 @@ namespace ESSImport
|
|||
|
||||
bool mHasANIS;
|
||||
ANIS mANIS; // scripted animation state
|
||||
|
||||
virtual void load(ESM::ESMReader& esm);
|
||||
|
||||
virtual ~ActorData() = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@ namespace ESSImport
|
|||
{
|
||||
blank();
|
||||
|
||||
// (FRMR subrecord name is already read by the loop in ConvertCell)
|
||||
esm.getHT(mRefNum.mIndex); // FRMR
|
||||
esm.getHNT(mRefNum.mIndex, "FRMR");
|
||||
|
||||
// this is required since openmw supports more than 255 content files
|
||||
int pluginIndex = (mRefNum.mIndex & 0xff000000) >> 24;
|
||||
|
@ -19,7 +18,128 @@ namespace ESSImport
|
|||
|
||||
mIndexedRefId = esm.getHNString("NAME");
|
||||
|
||||
ActorData::load(esm);
|
||||
if (esm.isNextSub("ACTN"))
|
||||
{
|
||||
/*
|
||||
Activation flags:
|
||||
ActivationFlag_UseEnabled = 1
|
||||
ActivationFlag_OnActivate = 2
|
||||
ActivationFlag_OnDeath = 10h
|
||||
ActivationFlag_OnKnockout = 20h
|
||||
ActivationFlag_OnMurder = 40h
|
||||
ActivationFlag_DoorOpening = 100h
|
||||
ActivationFlag_DoorClosing = 200h
|
||||
ActivationFlag_DoorJammedOpening = 400h
|
||||
ActivationFlag_DoorJammedClosing = 800h
|
||||
*/
|
||||
esm.skipHSub();
|
||||
}
|
||||
|
||||
if (esm.isNextSub("STPR"))
|
||||
esm.skipHSub();
|
||||
|
||||
if (esm.isNextSub("MNAM"))
|
||||
esm.skipHSub();
|
||||
|
||||
bool isDeleted = false;
|
||||
ESM::CellRef::loadData(esm, isDeleted);
|
||||
|
||||
mActorData.mHasACDT = false;
|
||||
if (esm.isNextSub("ACDT"))
|
||||
{
|
||||
mActorData.mHasACDT = true;
|
||||
esm.getHT(mActorData.mACDT);
|
||||
}
|
||||
|
||||
mActorData.mHasACSC = false;
|
||||
if (esm.isNextSub("ACSC"))
|
||||
{
|
||||
mActorData.mHasACSC = true;
|
||||
esm.getHT(mActorData.mACSC);
|
||||
}
|
||||
|
||||
if (esm.isNextSub("ACSL"))
|
||||
esm.skipHSubSize(112);
|
||||
|
||||
if (esm.isNextSub("CSTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
if (esm.isNextSub("LSTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
// unsure at which point between LSTN and TGTN
|
||||
if (esm.isNextSub("CSHN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
// unsure if before or after CSTN/LSTN
|
||||
if (esm.isNextSub("LSHN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
while (esm.isNextSub("TGTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
||||
while (esm.isNextSub("FGTN"))
|
||||
esm.getHString(); // fight target?
|
||||
|
||||
// unsure at which point between TGTN and CRED
|
||||
if (esm.isNextSub("AADT"))
|
||||
{
|
||||
// occurred when a creature was in the middle of its attack, 44 bytes
|
||||
esm.skipHSub();
|
||||
}
|
||||
|
||||
// unsure at which point between FGTN and CHRD
|
||||
if (esm.isNextSub("PWPC"))
|
||||
esm.skipHSub();
|
||||
if (esm.isNextSub("PWPS"))
|
||||
esm.skipHSub();
|
||||
|
||||
if (esm.isNextSub("WNAM"))
|
||||
{
|
||||
std::string id = esm.getHString();
|
||||
|
||||
if (esm.isNextSub("XNAM"))
|
||||
mActorData.mSelectedEnchantItem = esm.getHString();
|
||||
else
|
||||
mActorData.mSelectedSpell = id;
|
||||
|
||||
if (esm.isNextSub("YNAM"))
|
||||
esm.skipHSub(); // 4 byte, 0
|
||||
}
|
||||
|
||||
while (esm.isNextSub("APUD"))
|
||||
{
|
||||
// used power
|
||||
esm.getSubHeader();
|
||||
std::string id = esm.getString(32);
|
||||
(void)id;
|
||||
// timestamp can't be used: this is the total hours passed, calculated by
|
||||
// timestamp = 24 * (365 * year + cumulativeDays[month] + day)
|
||||
// unfortunately cumulativeDays[month] is not clearly defined,
|
||||
// in the (non-MCP) vanilla version the first month was missing, but MCP added it.
|
||||
double timestamp;
|
||||
esm.getT(timestamp);
|
||||
}
|
||||
|
||||
// FIXME: not all actors have this, add flag
|
||||
if (esm.isNextSub("CHRD")) // npc only
|
||||
esm.getHExact(mActorData.mSkills, 27*2*sizeof(int));
|
||||
|
||||
if (esm.isNextSub("CRED")) // creature only
|
||||
esm.getHExact(mActorData.mCombatStats, 3*2*sizeof(int));
|
||||
|
||||
mActorData.mSCRI.load(esm);
|
||||
|
||||
if (esm.isNextSub("ND3D"))
|
||||
esm.skipHSub();
|
||||
|
||||
mActorData.mHasANIS = false;
|
||||
if (esm.isNextSub("ANIS"))
|
||||
{
|
||||
mActorData.mHasANIS = true;
|
||||
esm.getHT(mActorData.mANIS);
|
||||
}
|
||||
|
||||
if (esm.isNextSub("LVCR"))
|
||||
{
|
||||
// occurs on levelled creature spawner references
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace ESM
|
|||
namespace ESSImport
|
||||
{
|
||||
|
||||
struct CellRef : public ActorData
|
||||
struct CellRef : public ESM::CellRef
|
||||
{
|
||||
std::string mIndexedRefId;
|
||||
|
||||
|
@ -25,9 +25,11 @@ namespace ESSImport
|
|||
|
||||
bool mDeleted;
|
||||
|
||||
void load(ESM::ESMReader& esm) override;
|
||||
ActorData mActorData;
|
||||
|
||||
~CellRef() override = default;
|
||||
void load(ESM::ESMReader& esm);
|
||||
|
||||
~CellRef() = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -5,17 +5,6 @@
|
|||
namespace ESSImport
|
||||
{
|
||||
|
||||
void REFR::load(ESM::ESMReader &esm)
|
||||
{
|
||||
esm.getHNT(mRefNum.mIndex, "FRMR");
|
||||
|
||||
mRefID = esm.getHNString("NAME");
|
||||
|
||||
mActorData.load(esm);
|
||||
|
||||
esm.getHNOTSized<24>(mPos, "DATA");
|
||||
}
|
||||
|
||||
void PCDT::load(ESM::ESMReader &esm)
|
||||
{
|
||||
while (esm.isNextSub("DNAM"))
|
||||
|
|
|
@ -18,18 +18,6 @@ namespace ESM
|
|||
namespace ESSImport
|
||||
{
|
||||
|
||||
/// Player-agnostic player data
|
||||
struct REFR
|
||||
{
|
||||
ActorData mActorData;
|
||||
|
||||
std::string mRefID;
|
||||
ESM::Position mPos;
|
||||
ESM::RefNum mRefNum;
|
||||
|
||||
void load(ESM::ESMReader& esm);
|
||||
};
|
||||
|
||||
/// Other player data
|
||||
struct PCDT
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue