diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 71158299aa..044fbf9f93 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1084,14 +1084,8 @@ namespace EsmTool std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; std::cout << " Attributes:" << std::endl; - std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl; - std::cout << " Intelligence: " << (int)mData.mNpdt.mIntelligence << std::endl; - std::cout << " Willpower: " << (int)mData.mNpdt.mWillpower << std::endl; - std::cout << " Agility: " << (int)mData.mNpdt.mAgility << std::endl; - std::cout << " Speed: " << (int)mData.mNpdt.mSpeed << std::endl; - std::cout << " Endurance: " << (int)mData.mNpdt.mEndurance << std::endl; - std::cout << " Personality: " << (int)mData.mNpdt.mPersonality << std::endl; - std::cout << " Luck: " << (int)mData.mNpdt.mLuck << std::endl; + for (size_t i = 0; i != mData.mNpdt.mAttributes.size(); i++) + std::cout << " " << attributeLabel(i) << ": " << int(mData.mNpdt.mAttributes[i]) << std::endl; std::cout << " Skills:" << std::endl; for (size_t i = 0; i != mData.mNpdt.mSkills.size(); i++) diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index e2e178f90a..d25568fd0a 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -693,22 +693,12 @@ void CSMTools::ReferenceableCheckStage::npcCheck( } else if (npc.mNpdt.mHealth != 0) { - if (npc.mNpdt.mStrength == 0) - messages.add(id, "Strength is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mIntelligence == 0) - messages.add(id, "Intelligence is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mWillpower == 0) - messages.add(id, "Willpower is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mAgility == 0) - messages.add(id, "Agility is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mSpeed == 0) - messages.add(id, "Speed is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mEndurance == 0) - messages.add(id, "Endurance is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mPersonality == 0) - messages.add(id, "Personality is equal to zero", "", CSMDoc::Message::Severity_Warning); - if (npc.mNpdt.mLuck == 0) - messages.add(id, "Luck is equal to zero", "", CSMDoc::Message::Severity_Warning); + for (size_t i = 0; i < npc.mNpdt.mAttributes.size(); ++i) + { + if (npc.mNpdt.mAttributes[i] == 0) + messages.add(id, ESM::Attribute::indexToRefId(i).getRefIdString() + " is equal to zero", {}, + CSMDoc::Message::Severity_Warning); + } } if (level <= 0) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 0ddfbbb051..c6179facb8 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -938,30 +938,9 @@ QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData( if (subColIndex == 0) return subRowIndex; - else if (subColIndex == 1) - switch (subRowIndex) - { - case 0: - return static_cast(npcStruct.mStrength); - case 1: - return static_cast(npcStruct.mIntelligence); - case 2: - return static_cast(npcStruct.mWillpower); - case 3: - return static_cast(npcStruct.mAgility); - case 4: - return static_cast(npcStruct.mSpeed); - case 5: - return static_cast(npcStruct.mEndurance); - case 6: - return static_cast(npcStruct.mPersonality); - case 7: - return static_cast(npcStruct.mLuck); - default: - return QVariant(); // throw an exception here? - } - else - return QVariant(); // throw an exception here? + else if (subColIndex == 1 && subRowIndex >= 0 && subRowIndex < ESM::Attribute::Length) + return static_cast(npcStruct.mAttributes[subRowIndex]); + return QVariant(); // throw an exception here? } void CSMWorld::NpcAttributesRefIdAdapter::setNestedData( @@ -972,36 +951,8 @@ void CSMWorld::NpcAttributesRefIdAdapter::setNestedData( ESM::NPC npc = record.get(); ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt; - if (subColIndex == 1) - switch (subRowIndex) - { - case 0: - npcStruct.mStrength = static_cast(value.toInt()); - break; - case 1: - npcStruct.mIntelligence = static_cast(value.toInt()); - break; - case 2: - npcStruct.mWillpower = static_cast(value.toInt()); - break; - case 3: - npcStruct.mAgility = static_cast(value.toInt()); - break; - case 4: - npcStruct.mSpeed = static_cast(value.toInt()); - break; - case 5: - npcStruct.mEndurance = static_cast(value.toInt()); - break; - case 6: - npcStruct.mPersonality = static_cast(value.toInt()); - break; - case 7: - npcStruct.mLuck = static_cast(value.toInt()); - break; - default: - return; // throw an exception here? - } + if (subColIndex == 1 && subRowIndex >= 0 && subRowIndex < ESM::Attribute::Length) + npcStruct.mAttributes[subRowIndex] = static_cast(value.toInt()); else return; // throw an exception here? diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index c6276753de..7c6f16b06f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -313,14 +313,8 @@ namespace MWClass for (size_t i = 0; i < ref->mBase->mNpdt.mSkills.size(); ++i) data->mNpcStats.getSkill(ESM::Skill::indexToRefId(i)).setBase(ref->mBase->mNpdt.mSkills[i]); - data->mNpcStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mNpdt.mStrength); - data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt.mIntelligence); - data->mNpcStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mNpdt.mWillpower); - data->mNpcStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mNpdt.mAgility); - data->mNpcStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mNpdt.mSpeed); - data->mNpcStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mNpdt.mEndurance); - data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt.mPersonality); - data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt.mLuck); + for (size_t i = 0; i < ref->mBase->mNpdt.mAttributes.size(); ++i) + data->mNpcStats.setAttribute(ESM::Attribute::indexToRefId(i), ref->mBase->mNpdt.mAttributes[i]); data->mNpcStats.setHealth(ref->mBase->mNpdt.mHealth); data->mNpcStats.setMagicka(ref->mBase->mNpdt.mMana); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 9a5b09ffe2..39b5286139 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -134,14 +134,9 @@ namespace MWMechanics for (size_t i = 0; i < player->mNpdt.mSkills.size(); ++i) npcStats.getSkill(ESM::Skill::indexToRefId(i)).setBase(player->mNpdt.mSkills[i]); - creatureStats.setAttribute(ESM::Attribute::Strength, player->mNpdt.mStrength); - creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt.mIntelligence); - creatureStats.setAttribute(ESM::Attribute::Willpower, player->mNpdt.mWillpower); - creatureStats.setAttribute(ESM::Attribute::Agility, player->mNpdt.mAgility); - creatureStats.setAttribute(ESM::Attribute::Speed, player->mNpdt.mSpeed); - creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt.mEndurance); - creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt.mPersonality); - creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt.mLuck); + for (size_t i = 0; i < player->mNpdt.mAttributes.size(); ++i) + npcStats.setAttribute(ESM::Attribute::indexToRefId(i), player->mNpdt.mSkills[i]); + const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore(); // race diff --git a/components/esm3/loadnpc.cpp b/components/esm3/loadnpc.cpp index d844f7d2bc..8a86780fe2 100644 --- a/components/esm3/loadnpc.cpp +++ b/components/esm3/loadnpc.cpp @@ -59,23 +59,31 @@ namespace ESM if (esm.getSubSize() == 52) { mNpdtType = NPC_DEFAULT; - esm.getExact(&mNpdt, 52); + esm.getT(mNpdt.mLevel); + 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) { - // Reading into temporary NPDTstruct12 object - NPDTstruct12 npdt12; mNpdtType = NPC_WITH_AUTOCALCULATED_STATS; - esm.getExact(&npdt12, 12); // Clearing the mNdpt struct to initialize all values blankNpdt(); - // Swiching to an internal representation - mNpdt.mLevel = npdt12.mLevel; - mNpdt.mDisposition = npdt12.mDisposition; - mNpdt.mReputation = npdt12.mReputation; - mNpdt.mRank = npdt12.mRank; - mNpdt.mGold = npdt12.mGold; + esm.getT(mNpdt.mLevel); + esm.getT(mNpdt.mDisposition); + esm.getT(mNpdt.mReputation); + esm.getT(mNpdt.mRank); + esm.skip(3); + esm.getT(mNpdt.mGold); } else esm.fail("NPC_NPDT must be 12 or 52 bytes long"); @@ -213,8 +221,7 @@ namespace ESM void NPC::blankNpdt() { mNpdt.mLevel = 0; - mNpdt.mStrength = mNpdt.mIntelligence = mNpdt.mWillpower = mNpdt.mAgility = mNpdt.mSpeed = mNpdt.mEndurance - = mNpdt.mPersonality = mNpdt.mLuck = 0; + mNpdt.mAttributes.fill(0); mNpdt.mSkills.fill(0); mNpdt.mReputation = 0; mNpdt.mHealth = mNpdt.mMana = mNpdt.mFatigue = 0; diff --git a/components/esm3/loadnpc.hpp b/components/esm3/loadnpc.hpp index af8c2a8574..c50dd3414d 100644 --- a/components/esm3/loadnpc.hpp +++ b/components/esm3/loadnpc.hpp @@ -6,6 +6,7 @@ #include #include "aipackage.hpp" +#include "components/esm/attr.hpp" #include "components/esm/defs.hpp" #include "components/esm/refid.hpp" #include "loadcont.hpp" @@ -80,7 +81,7 @@ namespace ESM struct NPDTstruct52 { int16_t mLevel; - unsigned char mStrength, mIntelligence, mWillpower, mAgility, mSpeed, mEndurance, mPersonality, mLuck; + std::array mAttributes; // mSkill can grow up to 200, it must be unsigned std::array mSkills; diff --git a/components/esm3/loadpgrd.cpp b/components/esm3/loadpgrd.cpp index 8d60d25524..4f0a62a9d4 100644 --- a/components/esm3/loadpgrd.cpp +++ b/components/esm3/loadpgrd.cpp @@ -70,7 +70,12 @@ namespace ESM for (uint16_t i = 0; i < mData.mPoints; ++i) { Point p; - esm.getExact(&p, sizeof(Point)); + esm.getT(p.mX); + esm.getT(p.mY); + esm.getT(p.mZ); + esm.getT(p.mAutogenerated); + esm.getT(p.mConnectionNum); + esm.getT(p.mUnknown); mPoints.push_back(p); edgeCount += p.mConnectionNum; } diff --git a/components/esm3/loadrace.cpp b/components/esm3/loadrace.cpp index 8c7b89d07d..0996a5ac48 100644 --- a/components/esm3/loadrace.cpp +++ b/components/esm3/loadrace.cpp @@ -12,6 +12,7 @@ namespace ESM int index = ESM::Attribute::refIdToIndex(attribute); if (index < 0) return 0; + index *= 2; if (!male) index++; return mAttributeValues[static_cast(index)]; @@ -22,6 +23,7 @@ namespace ESM int index = ESM::Attribute::refIdToIndex(attribute); if (index < 0) return; + index *= 2; if (!male) index++; mAttributeValues[static_cast(index)] = value;