mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2024-12-29 03:19:44 +00:00
Add getCompositeSize and handle NPC data
This commit is contained in:
parent
cef59e8928
commit
1499dd2654
@ -5,6 +5,13 @@ namespace ESM
|
|||||||
{
|
{
|
||||||
template <class T>
|
template <class T>
|
||||||
void decompose(T&& value, const auto& apply) = delete;
|
void decompose(T&& value, const auto& apply) = delete;
|
||||||
|
|
||||||
|
std::size_t getCompositeSize(const auto& value)
|
||||||
|
{
|
||||||
|
std::size_t result = 0;
|
||||||
|
decompose(value, [&](const auto&... args) { result = (0 + ... + sizeof(args)); });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,8 +3,34 @@
|
|||||||
#include "esmreader.hpp"
|
#include "esmreader.hpp"
|
||||||
#include "esmwriter.hpp"
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/concepts.hpp>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct NPDTstruct12
|
||||||
|
{
|
||||||
|
NPC::NPDTstruct52& mStruct;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Misc::SameAsWithoutCvref<NPC::NPDTstruct52> T>
|
||||||
|
void decompose(T&& v, const auto& f)
|
||||||
|
{
|
||||||
|
char padding1 = 0;
|
||||||
|
char padding2 = 0;
|
||||||
|
f(v.mLevel, v.mAttributes, v.mSkills, padding1, v.mHealth, v.mMana, v.mFatigue, v.mDisposition, v.mReputation,
|
||||||
|
v.mRank, padding2, v.mGold);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Misc::SameAsWithoutCvref<NPDTstruct12> T>
|
||||||
|
void decompose(T&& v, const auto& f)
|
||||||
|
{
|
||||||
|
char padding[] = { 0, 0, 0 };
|
||||||
|
f(v.mStruct.mLevel, v.mStruct.mDisposition, v.mStruct.mReputation, v.mStruct.mRank, padding, v.mStruct.mGold);
|
||||||
|
}
|
||||||
|
|
||||||
void NPC::load(ESMReader& esm, bool& isDeleted)
|
void NPC::load(ESMReader& esm, bool& isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
@ -56,37 +82,25 @@ namespace ESM
|
|||||||
case fourCC("NPDT"):
|
case fourCC("NPDT"):
|
||||||
hasNpdt = true;
|
hasNpdt = true;
|
||||||
esm.getSubHeader();
|
esm.getSubHeader();
|
||||||
if (esm.getSubSize() == 52)
|
if (esm.getSubSize() == getCompositeSize(mNpdt))
|
||||||
{
|
{
|
||||||
mNpdtType = NPC_DEFAULT;
|
mNpdtType = NPC_DEFAULT;
|
||||||
esm.getT(mNpdt.mLevel);
|
esm.getComposite(mNpdt);
|
||||||
esm.getT(mNpdt.mAttributes);
|
|
||||||
esm.getT(mNpdt.mSkills);
|
|
||||||
esm.getT(mNpdt.mUnknown1);
|
|
||||||
esm.getT(mNpdt.mHealth);
|
|
||||||
esm.getT(mNpdt.mMana);
|
|
||||||
esm.getT(mNpdt.mFatigue);
|
|
||||||
esm.getT(mNpdt.mDisposition);
|
|
||||||
esm.getT(mNpdt.mReputation);
|
|
||||||
esm.getT(mNpdt.mRank);
|
|
||||||
esm.getT(mNpdt.mUnknown2);
|
|
||||||
esm.getT(mNpdt.mGold);
|
|
||||||
}
|
|
||||||
else if (esm.getSubSize() == 12)
|
|
||||||
{
|
|
||||||
mNpdtType = NPC_WITH_AUTOCALCULATED_STATS;
|
|
||||||
|
|
||||||
// Clearing the mNdpt struct to initialize all values
|
|
||||||
blankNpdt();
|
|
||||||
esm.getT(mNpdt.mLevel);
|
|
||||||
esm.getT(mNpdt.mDisposition);
|
|
||||||
esm.getT(mNpdt.mReputation);
|
|
||||||
esm.getT(mNpdt.mRank);
|
|
||||||
esm.skip(3);
|
|
||||||
esm.getT(mNpdt.mGold);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
esm.fail("NPC_NPDT must be 12 or 52 bytes long");
|
{
|
||||||
|
NPDTstruct12 data{ mNpdt };
|
||||||
|
if (esm.getSubSize() == getCompositeSize(data))
|
||||||
|
{
|
||||||
|
mNpdtType = NPC_WITH_AUTOCALCULATED_STATS;
|
||||||
|
|
||||||
|
// Clearing the mNdpt struct to initialize all values
|
||||||
|
blankNpdt();
|
||||||
|
esm.getComposite(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esm.fail("NPC_NPDT must be 12 or 52 bytes long");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case fourCC("FLAG"):
|
case fourCC("FLAG"):
|
||||||
hasFlags = true;
|
hasFlags = true;
|
||||||
@ -154,32 +168,11 @@ namespace ESM
|
|||||||
|
|
||||||
if (mNpdtType == NPC_DEFAULT)
|
if (mNpdtType == NPC_DEFAULT)
|
||||||
{
|
{
|
||||||
esm.startSubRecord("NPDT");
|
esm.writeNamedComposite("NPDT", mNpdt);
|
||||||
esm.writeT(mNpdt.mLevel);
|
|
||||||
esm.writeT(mNpdt.mAttributes);
|
|
||||||
esm.writeT(mNpdt.mSkills);
|
|
||||||
esm.writeT(mNpdt.mUnknown1);
|
|
||||||
esm.writeT(mNpdt.mHealth);
|
|
||||||
esm.writeT(mNpdt.mMana);
|
|
||||||
esm.writeT(mNpdt.mFatigue);
|
|
||||||
esm.writeT(mNpdt.mDisposition);
|
|
||||||
esm.writeT(mNpdt.mReputation);
|
|
||||||
esm.writeT(mNpdt.mRank);
|
|
||||||
esm.writeT(mNpdt.mUnknown2);
|
|
||||||
esm.writeT(mNpdt.mGold);
|
|
||||||
esm.endRecord("NPDT");
|
|
||||||
}
|
}
|
||||||
else if (mNpdtType == NPC_WITH_AUTOCALCULATED_STATS)
|
else if (mNpdtType == NPC_WITH_AUTOCALCULATED_STATS)
|
||||||
{
|
{
|
||||||
esm.startSubRecord("NPDT");
|
esm.writeNamedComposite("NPDT", NPDTstruct12{ const_cast<NPDTstruct52&>(mNpdt) });
|
||||||
esm.writeT(mNpdt.mLevel);
|
|
||||||
esm.writeT(mNpdt.mDisposition);
|
|
||||||
esm.writeT(mNpdt.mReputation);
|
|
||||||
esm.writeT(mNpdt.mRank);
|
|
||||||
constexpr char padding[] = { 0, 0, 0 };
|
|
||||||
esm.writeT(padding);
|
|
||||||
esm.writeT(mNpdt.mGold);
|
|
||||||
esm.endRecord("NPDT");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.writeHNT("FLAG", ((mBloodType << 10) + mFlags));
|
esm.writeHNT("FLAG", ((mBloodType << 10) + mFlags));
|
||||||
@ -238,9 +231,7 @@ namespace ESM
|
|||||||
mNpdt.mReputation = 0;
|
mNpdt.mReputation = 0;
|
||||||
mNpdt.mHealth = mNpdt.mMana = mNpdt.mFatigue = 0;
|
mNpdt.mHealth = mNpdt.mMana = mNpdt.mFatigue = 0;
|
||||||
mNpdt.mDisposition = 0;
|
mNpdt.mDisposition = 0;
|
||||||
mNpdt.mUnknown1 = 0;
|
|
||||||
mNpdt.mRank = 0;
|
mNpdt.mRank = 0;
|
||||||
mNpdt.mUnknown2 = 0;
|
|
||||||
mNpdt.mGold = 0;
|
mNpdt.mGold = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +83,8 @@ namespace ESM
|
|||||||
// mSkill can grow up to 200, it must be unsigned
|
// mSkill can grow up to 200, it must be unsigned
|
||||||
std::array<unsigned char, Skill::Length> mSkills;
|
std::array<unsigned char, Skill::Length> mSkills;
|
||||||
|
|
||||||
char mUnknown1;
|
|
||||||
uint16_t mHealth, mMana, mFatigue;
|
uint16_t mHealth, mMana, mFatigue;
|
||||||
unsigned char mDisposition, mReputation, mRank;
|
unsigned char mDisposition, mReputation, mRank;
|
||||||
char mUnknown2;
|
|
||||||
int32_t mGold;
|
int32_t mGold;
|
||||||
}; // 52 bytes
|
}; // 52 bytes
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ namespace ESM
|
|||||||
{
|
{
|
||||||
esm.getSubHeader();
|
esm.getSubHeader();
|
||||||
uint32_t size = esm.getSubSize();
|
uint32_t size = esm.getSubSize();
|
||||||
if (size != 16u * mData.mPoints)
|
if (size != getCompositeSize(Point{}) * mData.mPoints)
|
||||||
esm.fail("Path point subrecord size mismatch");
|
esm.fail("Path point subrecord size mismatch");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user