Remove fixed size reads

macos_ci_fix
Evil Eye 1 year ago
parent ec480db9ac
commit a9e6e63c4e

@ -1169,19 +1169,23 @@ namespace EsmTool
std::cout << " Description: " << mData.mDescription << std::endl;
std::cout << " Flags: " << raceFlags(mData.mData.mFlags) << std::endl;
for (int i = 0; i < 2; ++i)
std::cout << " Male:" << std::endl;
for (int j = 0; j < ESM::Attribute::Length; ++j)
{
bool male = i == 0;
std::cout << (male ? " Male:" : " Female:") << std::endl;
for (int j = 0; j < ESM::Attribute::Length; ++j)
std::cout << " " << ESM::Attribute::indexToRefId(j) << ": "
<< mData.mData.mAttributeValues[j].getValue(male) << std::endl;
ESM::RefId id = ESM::Attribute::indexToRefId(j);
std::cout << " " << id << ": " << mData.mData.getAttribute(id, true) << std::endl;
}
std::cout << " Height: " << mData.mData.mMaleHeight << std::endl;
std::cout << " Weight: " << mData.mData.mMaleWeight << std::endl;
std::cout << " Height: " << mData.mData.mHeight.getValue(male) << std::endl;
std::cout << " Weight: " << mData.mData.mWeight.getValue(male) << std::endl;
std::cout << " Female:" << std::endl;
for (int j = 0; j < ESM::Attribute::Length; ++j)
{
ESM::RefId id = ESM::Attribute::indexToRefId(j);
std::cout << " " << id << ": " << mData.mData.getAttribute(id, false) << std::endl;
}
std::cout << " Height: " << mData.mData.mFemaleHeight << std::endl;
std::cout << " Weight: " << mData.mData.mFemaleWeight << std::endl;
for (const auto& bonus : mData.mData.mBonus)
// Not all races have 7 skills.

@ -41,17 +41,17 @@ void CSMTools::RaceCheckStage::performPerRecord(int stage, CSMDoc::Messages& mes
messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning);
// test for positive height
if (race.mData.mHeight.mMale <= 0)
if (race.mData.mMaleHeight <= 0)
messages.add(id, "Male height is non-positive", "", CSMDoc::Message::Severity_Error);
if (race.mData.mHeight.mFemale <= 0)
if (race.mData.mFemaleHeight <= 0)
messages.add(id, "Female height is non-positive", "", CSMDoc::Message::Severity_Error);
// test for non-negative weight
if (race.mData.mWeight.mMale < 0)
if (race.mData.mMaleWeight < 0)
messages.add(id, "Male weight is negative", "", CSMDoc::Message::Severity_Error);
if (race.mData.mWeight.mFemale < 0)
if (race.mData.mFemaleWeight < 0)
messages.add(id, "Female weight is negative", "", CSMDoc::Message::Severity_Error);
/// \todo check data members that can't be edited in the table view

@ -570,19 +570,34 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
const ESM::Race::MaleFemaleF& value = mWeight ? record.get().mData.mWeight : record.get().mData.mHeight;
return mMale ? value.mMale : value.mFemale;
if (mWeight)
{
if (mMale)
return record.get().mData.mMaleWeight;
return record.get().mData.mFemaleWeight;
}
if (mMale)
return record.get().mData.mMaleHeight;
return record.get().mData.mFemaleHeight;
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
ESM::Race::MaleFemaleF& value = mWeight ? record2.mData.mWeight : record2.mData.mHeight;
(mMale ? value.mMale : value.mFemale) = data.toFloat();
if (mWeight)
{
if (mMale)
record2.mData.mMaleWeight = data.toFloat();
else
record2.mData.mFemaleWeight = data.toFloat();
}
else
{
if (mMale)
record2.mData.mMaleHeight = data.toFloat();
else
record2.mData.mFemaleHeight = data.toFloat();
}
record.setModified(record2);
}

@ -741,8 +741,8 @@ namespace CSMWorld
QVariant RaceAttributeAdapter::getData(const Record<ESM::Race>& record, int subRowIndex, int subColIndex) const
{
ESM::Race race = record.get();
if (subRowIndex < 0 || subRowIndex >= ESM::Attribute::Length)
ESM::RefId attribute = ESM::Attribute::indexToRefId(subRowIndex);
if (attribute.empty())
throw std::runtime_error("index out of range");
switch (subColIndex)
@ -750,9 +750,9 @@ namespace CSMWorld
case 0:
return subRowIndex;
case 1:
return race.mData.mAttributeValues[subRowIndex].mMale;
return race.mData.getAttribute(attribute, true);
case 2:
return race.mData.mAttributeValues[subRowIndex].mFemale;
return race.mData.getAttribute(attribute, false);
default:
throw std::runtime_error("Race Attribute subcolumn index out of range");
}
@ -762,8 +762,8 @@ namespace CSMWorld
Record<ESM::Race>& record, const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Race race = record.get();
if (subRowIndex < 0 || subRowIndex >= ESM::Attribute::Length)
ESM::RefId attribute = ESM::Attribute::indexToRefId(subRowIndex);
if (attribute.empty())
throw std::runtime_error("index out of range");
switch (subColIndex)
@ -771,10 +771,10 @@ namespace CSMWorld
case 0:
return; // throw an exception here?
case 1:
race.mData.mAttributeValues[subRowIndex].mMale = value.toInt();
race.mData.setAttribute(attribute, true, value.toInt());
break;
case 2:
race.mData.mAttributeValues[subRowIndex].mFemale = value.toInt();
race.mData.setAttribute(attribute, false, value.toInt());
break;
default:
throw std::runtime_error("Race Attribute subcolumn index out of range");

@ -92,13 +92,7 @@ namespace
const auto& attributes = MWBase::Environment::get().getESMStore()->get<ESM::Attribute>();
int level = creatureStats.getLevel();
for (const ESM::Attribute& attribute : attributes)
{
auto index = ESM::Attribute::refIdToIndex(attribute.mId);
assert(index >= 0);
const ESM::Race::MaleFemale& value = race->mData.mAttributeValues[static_cast<size_t>(index)];
creatureStats.setAttribute(attribute.mId, male ? value.mMale : value.mFemale);
}
creatureStats.setAttribute(attribute.mId, race->mData.getAttribute(attribute.mId, male));
// class bonus
const ESM::Class* class_ = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(npc->mClass);
@ -1199,24 +1193,24 @@ namespace MWClass
if (ptr == MWMechanics::getPlayer() && ptr.isInCell() && MWBase::Environment::get().getWorld()->isFirstPerson())
{
if (ref->mBase->isMale())
scale *= race->mData.mHeight.mMale;
scale *= race->mData.mMaleHeight;
else
scale *= race->mData.mHeight.mFemale;
scale *= race->mData.mFemaleHeight;
return;
}
if (ref->mBase->isMale())
{
scale.x() *= race->mData.mWeight.mMale;
scale.y() *= race->mData.mWeight.mMale;
scale.z() *= race->mData.mHeight.mMale;
scale.x() *= race->mData.mMaleWeight;
scale.y() *= race->mData.mMaleWeight;
scale.z() *= race->mData.mMaleHeight;
}
else
{
scale.x() *= race->mData.mWeight.mFemale;
scale.y() *= race->mData.mWeight.mFemale;
scale.z() *= race->mData.mHeight.mFemale;
scale.x() *= race->mData.mFemaleWeight;
scale.y() *= race->mData.mFemaleWeight;
scale.z() *= race->mData.mFemaleHeight;
}
}

@ -1966,7 +1966,7 @@ namespace MWMechanics
{
const ESM::NPC* npc = mPtr.get<ESM::NPC>()->mBase;
const ESM::Race* race = world->getStore().get<ESM::Race>().find(npc->mRace);
float weight = npc->isMale() ? race->mData.mWeight.mMale : race->mData.mWeight.mFemale;
float weight = npc->isMale() ? race->mData.mMaleWeight : race->mData.mFemaleWeight;
scale *= weight;
}

@ -152,13 +152,7 @@ namespace MWMechanics
bool male = (player->mFlags & ESM::NPC::Female) == 0;
for (const ESM::Attribute& attribute : esmStore.get<ESM::Attribute>())
{
auto index = ESM::Attribute::refIdToIndex(attribute.mId);
assert(index >= 0);
const ESM::Race::MaleFemale& value = race->mData.mAttributeValues[static_cast<size_t>(index)];
creatureStats.setAttribute(attribute.mId, male ? value.mMale : value.mFemale);
}
creatureStats.setAttribute(attribute.mId, race->mData.getAttribute(attribute.mId, male));
for (const ESM::Skill& skill : esmStore.get<ESM::Skill>())
{

@ -453,7 +453,7 @@ namespace MWWorld
{
const auto npc = caster.get<ESM::NPC>()->mBase;
const auto race = store.get<ESM::Race>().find(npc->mRace);
speed *= npc->isMale() ? race->mData.mWeight.mMale : race->mData.mWeight.mFemale;
speed *= npc->isMale() ? race->mData.mMaleWeight : race->mData.mFemaleWeight;
}
osg::Vec3f direction = orient * osg::Vec3f(0, 1, 0);
direction.normalize();

@ -18,9 +18,9 @@ namespace ESM
struct EpochTimeStamp
{
float mGameHour;
int mDay;
int mMonth;
int mYear;
int32_t mDay;
int32_t mMonth;
int32_t mYear;
};
// Pixel color value. Standard four-byte rr,gg,bb,aa format.

@ -116,7 +116,7 @@ namespace ESM
cellRef.mTeleport = true;
}
else
esm.skipHTSized<24, ESM::Position>();
esm.skipHSub();
break;
case fourCC("DNAM"):
getHStringOrSkip(cellRef.mDestCell);
@ -134,7 +134,7 @@ namespace ESM
if constexpr (load)
esm.getHT(cellRef.mPos.pos, cellRef.mPos.rot);
else
esm.skipHTSized<24, decltype(cellRef.mPos)>();
esm.skipHSub();
break;
case fourCC("NAM0"):
{

@ -263,7 +263,7 @@ namespace ESM
{
FormId res;
if (wide)
getHNTSized<8>(res, tag);
getHNT(tag, res.mIndex, res.mContentFile);
else
getHNT(res.mIndex, tag);
return res;
@ -496,7 +496,8 @@ namespace ESM
case RefIdType::FormId:
{
FormId formId{};
getTSized<8>(formId);
getT(formId.mIndex);
getT(formId.mContentFile);
if (applyContentFileMapping(formId))
return RefId(formId);
else

@ -333,7 +333,7 @@ namespace ESM
mEsm->read(static_cast<char*>(x), static_cast<std::streamsize>(size));
}
void getName(NAME& name) { getTSized<4>(name); }
void getName(NAME& name) { getT(name.mData); }
void getUint(uint32_t& u) { getT(u); }
std::string getMaybeFixedStringSize(std::size_t size);

@ -17,6 +17,47 @@ namespace ESM
return mSkills.at(index);
}
void RankData::load(ESMReader& esm)
{
esm.getT(mAttribute1);
esm.getT(mAttribute2);
esm.getT(mPrimarySkill);
esm.getT(mFavouredSkill);
esm.getT(mFactReaction);
}
void RankData::save(ESMWriter& esm) const
{
esm.writeT(mAttribute1);
esm.writeT(mAttribute2);
esm.writeT(mPrimarySkill);
esm.writeT(mFavouredSkill);
esm.writeT(mFactReaction);
}
void Faction::FADTstruct::load(ESMReader& esm)
{
esm.getSubHeader();
esm.getT(mAttribute);
for (auto& rank : mRankData)
rank.load(esm);
esm.getT(mSkills);
esm.getT(mIsHidden);
if (mIsHidden > 1)
esm.fail("Unknown flag!");
}
void Faction::FADTstruct::save(ESMWriter& esm) const
{
esm.startSubRecord("FADT");
esm.writeT(mAttribute);
for (const auto& rank : mRankData)
rank.save(esm);
esm.writeT(mSkills);
esm.writeT(mIsHidden);
esm.endRecord("FADT");
}
void Faction::load(ESMReader& esm, bool& isDeleted)
{
isDeleted = false;
@ -47,9 +88,7 @@ namespace ESM
mRanks[rankCounter++] = esm.getHString();
break;
case fourCC("FADT"):
esm.getHTSized<240>(mData);
if (mData.mIsHidden > 1)
esm.fail("Unknown flag!");
mData.load(esm);
hasData = true;
break;
case fourCC("ANAM"):
@ -101,7 +140,7 @@ namespace ESM
esm.writeHNString("RNAM", rank, 32);
}
esm.writeHNT("FADT", mData, 240);
mData.save(esm);
for (auto it = mReactions.begin(); it != mReactions.end(); ++it)
{

@ -30,6 +30,9 @@ namespace ESM
int32_t mPrimarySkill, mFavouredSkill;
int32_t mFactReaction; // Reaction from faction members
void load(ESMReader& esm);
void save(ESMWriter& esm) const;
};
struct Faction
@ -60,6 +63,9 @@ namespace ESM
int32_t getSkill(size_t index, bool ignored = false) const;
///< Throws an exception for invalid values of \a index.
void load(ESMReader& esm);
void save(ESMWriter& esm) const;
}; // 240 bytes
FADTstruct mData;

@ -3,16 +3,61 @@
#include "esmreader.hpp"
#include "esmwriter.hpp"
#include <components/esm/attr.hpp>
namespace ESM
{
int Race::MaleFemale::getValue(bool male) const
int32_t Race::RADTstruct::getAttribute(ESM::RefId attribute, bool male) const
{
int index = ESM::Attribute::refIdToIndex(attribute);
if (index < 0)
return 0;
if (!male)
index++;
return mAttributeValues[static_cast<size_t>(index)];
}
void Race::RADTstruct::setAttribute(ESM::RefId attribute, bool male, int32_t value)
{
int index = ESM::Attribute::refIdToIndex(attribute);
if (index < 0)
return;
if (!male)
index++;
mAttributeValues[static_cast<size_t>(index)] = value;
}
void Race::RADTstruct::load(ESMReader& esm)
{
return male ? mMale : mFemale;
esm.getSubHeader();
for (auto& bonus : mBonus)
{
esm.getT(bonus.mSkill);
esm.getT(bonus.mBonus);
}
esm.getT(mAttributeValues);
esm.getT(mMaleHeight);
esm.getT(mFemaleHeight);
esm.getT(mMaleWeight);
esm.getT(mFemaleWeight);
esm.getT(mFlags);
}
float Race::MaleFemaleF::getValue(bool male) const
void Race::RADTstruct::save(ESMWriter& esm) const
{
return male ? mMale : mFemale;
esm.startSubRecord("RADT");
for (const auto& bonus : mBonus)
{
esm.writeT(bonus.mSkill);
esm.writeT(bonus.mBonus);
}
esm.writeT(mAttributeValues);
esm.writeT(mMaleHeight);
esm.writeT(mFemaleHeight);
esm.writeT(mMaleWeight);
esm.writeT(mFemaleWeight);
esm.writeT(mFlags);
esm.endRecord("RADT");
}
void Race::load(ESMReader& esm, bool& isDeleted)
@ -37,7 +82,7 @@ namespace ESM
mName = esm.getHString();
break;
case fourCC("RADT"):
esm.getHTSized<140>(mData);
mData.load(esm);
hasData = true;
break;
case fourCC("DESC"):
@ -71,7 +116,7 @@ namespace ESM
}
esm.writeHNOCString("FNAM", mName);
esm.writeHNT("RADT", mData, 140);
mData.save(esm);
mPowers.save(esm);
esm.writeHNOString("DESC", mDescription);
}
@ -90,11 +135,10 @@ namespace ESM
bonus.mBonus = 0;
}
for (auto& attribute : mData.mAttributeValues)
attribute.mMale = attribute.mFemale = 1;
mData.mAttributeValues.fill(1);
mData.mHeight.mMale = mData.mHeight.mFemale = 1;
mData.mWeight.mMale = mData.mWeight.mFemale = 1;
mData.mMaleHeight = mData.mFemaleHeight = 1;
mData.mMaleWeight = mData.mFemaleWeight = 1;
mData.mFlags = 0;
}

@ -31,20 +31,6 @@ namespace ESM
int32_t mBonus;
};
struct MaleFemale
{
int32_t mMale, mFemale;
int getValue(bool male) const;
};
struct MaleFemaleF
{
float mMale, mFemale;
float getValue(bool male) const;
};
enum Flags
{
Playable = 0x01,
@ -57,14 +43,20 @@ namespace ESM
std::array<SkillBonus, 7> mBonus;
// Attribute values for male/female
std::array<MaleFemale, 8> mAttributeValues;
std::array<int32_t, 16> mAttributeValues;
// The actual eye level height (in game units) is (probably) given
// as 'height' times 128. This has not been tested yet.
MaleFemaleF mHeight, mWeight;
float mMaleHeight, mFemaleHeight, mMaleWeight, mFemaleWeight;
int32_t mFlags; // 0x1 - playable, 0x2 - beast race
int32_t getAttribute(ESM::RefId attribute, bool male) const;
void setAttribute(ESM::RefId attribute, bool male, int32_t value);
void load(ESMReader& esm);
void save(ESMWriter& esm) const;
}; // Size = 140 bytes
RADTstruct mData;

@ -45,7 +45,8 @@ namespace ESM
if (esm.isNextSub("GMDT"))
{
esm.getHTSized<124>(mGameData);
esm.getHT(mGameData.mCurrentHealth, mGameData.mMaximumHealth, mGameData.mHour, mGameData.unknown1,
mGameData.mCurrentCell.mData, mGameData.unknown2, mGameData.mPlayerName.mData);
}
if (esm.isNextSub("SCRD"))
{

@ -11,9 +11,6 @@ namespace ESM
class ESMReader;
class ESMWriter;
#pragma pack(push)
#pragma pack(1)
struct Data
{
/* File format version. This is actually a float, the supported
@ -38,8 +35,6 @@ namespace ESM
NAME32 mPlayerName;
};
#pragma pack(pop)
/// \brief File header record
struct Header
{

@ -13,12 +13,12 @@ namespace ESM
mCellId = esm.getCellId();
esm.getHNTSized<12>(mLastKnownExteriorPosition, "LKEP");
esm.getHNT("LKEP", mLastKnownExteriorPosition);
if (esm.isNextSub("MARK"))
{
mHasMark = true;
esm.getHTSized<24>(mMarkedPosition);
esm.getHT(mMarkedPosition.pos, mMarkedPosition.rot);
mMarkedCell = esm.getCellId();
}
else

@ -17,8 +17,8 @@ namespace ESM
void BaseProjectileState::load(ESMReader& esm)
{
mId = esm.getHNRefId("ID__");
esm.getHNTSized<12>(mPosition, "VEC3");
esm.getHNTSized<16>(mOrientation, "QUAT");
esm.getHNT("VEC3", mPosition.mValues);
esm.getHNT("QUAT", mOrientation.mValues);
esm.getHNT(mActorId, "ACTO");
}
@ -58,7 +58,7 @@ namespace ESM
BaseProjectileState::load(esm);
mBowId = esm.getHNRefId("BOW_");
esm.getHNTSized<12>(mVelocity, "VEL_");
esm.getHNT("VEL_", mVelocity.mValues);
mAttackStrength = 1.f;
esm.getHNOT(mAttackStrength, "STR_");

@ -17,7 +17,7 @@ namespace ESM
mPlayerCellName = esm.getHNRefId("PLCE").toString();
else
mPlayerCellName = esm.getHNString("PLCE");
esm.getHNTSized<16>(mInGameTime, "TSTM");
esm.getHNT("TSTM", mInGameTime.mGameHour, mInGameTime.mDay, mInGameTime.mMonth, mInGameTime.mYear);
esm.getHNT(mTimePlayed, "TIME");
mDescription = esm.getHNString("DESC");

Loading…
Cancel
Save