diff --git a/components/esm4/loadammo.cpp b/components/esm4/loadammo.cpp index a30189aa97..d0ad2e1709 100644 --- a/components/esm4/loadammo.cpp +++ b/components/esm4/loadammo.cpp @@ -36,8 +36,6 @@ void ESM4::Ammunition::load(ESM4::Reader& reader) mFormId = reader.hdr().record.id; reader.adjustFormId(mFormId); mFlags = reader.hdr().record.flags; - std::uint32_t esmVer = reader.esmVersion(); - bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134; while (reader.getSubRecordHeader()) { @@ -52,36 +50,52 @@ void ESM4::Ammunition::load(ESM4::Reader& reader) break; case ESM4::SUB_DATA: { - // if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170) - if (subHdr.dataSize == 16) // FO3 has 13 bytes even though VER_094 + // FO3/FNV or TES4 + if (subHdr.dataSize == 13 || subHdr.dataSize == 18) { - FormId projectile; - reader.get(projectile); // FIXME: add to mData - reader.get(mData.flags); - reader.get(mData.weight); - float damageInFloat; - reader.get(damageInFloat); // FIXME: add to mData + reader.get(mData.mSpeed); + reader.get(mData.mFlags); + mData.mFlags &= 0xFF; + reader.get(mData.mValue); + if (subHdr.dataSize == 13) + reader.get(mData.mClipRounds); + else + { + reader.get(mData.mWeight); + std::uint16_t damageInt; + reader.get(damageInt); + mData.mDamage = static_cast(damageInt); + } } - else if (isFONV || subHdr.dataSize == 13) + // TES5/SSE + else if (subHdr.dataSize == 16 || subHdr.dataSize == 20) { - reader.get(mData.speed); - std::uint8_t flags; - reader.get(flags); - mData.flags = flags; - static std::uint8_t dummy; - reader.get(dummy); - reader.get(dummy); - reader.get(dummy); - reader.get(mData.value); - reader.get(mData.clipRounds); + reader.getFormId(mData.mProjectile); + reader.get(mData.mFlags); + reader.get(mData.mDamage); + reader.get(mData.mValue); + if (subHdr.dataSize == 20) + reader.get(mData.mWeight); } - else // TES4 + else { - reader.get(mData.speed); - reader.get(mData.flags); - reader.get(mData.value); - reader.get(mData.weight); - reader.get(mData.damage); + reader.skipSubRecordData(); + } + break; + } + case ESM4::SUB_DAT2: + { + if (subHdr.dataSize == 20) + { + reader.get(mData.mProjPerShot); + reader.getFormId(mData.mProjectile); + reader.get(mData.mWeight); + reader.getFormId(mData.mConsumedAmmo); + reader.get(mData.mConsumedPercentage); + } + else + { + reader.skipSubRecordData(); } break; } @@ -112,15 +126,28 @@ void ESM4::Ammunition::load(ESM4::Reader& reader) case ESM4::SUB_ZNAM: reader.getFormId(mDropSound); break; + case ESM4::SUB_ONAM: + reader.getLocalizedString(mShortName); + break; + case ESM4::SUB_QNAM: // FONV + reader.getLocalizedString(mAbbrev); + break; + case ESM4::SUB_RCIL: + { + FormId effect; + reader.getFormId(effect); + mAmmoEffects.push_back(effect); + break; + } + case ESM4::SUB_SCRI: + { + reader.getFormId(mScript); + break; + } case ESM4::SUB_MODT: case ESM4::SUB_OBND: case ESM4::SUB_KSIZ: case ESM4::SUB_KWDA: - case ESM4::SUB_ONAM: // FO3 - case ESM4::SUB_DAT2: // FONV - case ESM4::SUB_QNAM: // FONV - case ESM4::SUB_RCIL: // FONV - case ESM4::SUB_SCRI: // FONV { // std::cout << "AMMO " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl; reader.skipSubRecordData(); diff --git a/components/esm4/loadammo.hpp b/components/esm4/loadammo.hpp index d23cc3c547..42c430c7f3 100644 --- a/components/esm4/loadammo.hpp +++ b/components/esm4/loadammo.hpp @@ -29,6 +29,7 @@ #include #include +#include #include "formid.hpp" @@ -39,24 +40,18 @@ namespace ESM4 struct Ammunition { - struct Data // FIXME: TES5 projectile, damage (float) + struct Data { - float speed; - std::uint32_t flags; - std::uint32_t value; // gold - float weight; - std::uint16_t damage; - std::uint8_t clipRounds; // only in FO3/FONV - - Data() - : speed(0.f) - , flags(0) - , value(0) - , weight(0.f) - , damage(0) - , clipRounds(0) - { - } + float mSpeed{ 0.f }; + std::uint32_t mFlags{ 0u }; + std::uint32_t mValue{ 0u }; + float mWeight{ 0.f }; + float mDamage{ 0.f }; + std::uint8_t mClipRounds{ 0u }; + std::uint32_t mProjPerShot{ 0u }; + FormId mProjectile; + FormId mConsumedAmmo; + float mConsumedPercentage{ 0.f }; }; FormId mFormId; // from the header @@ -64,6 +59,8 @@ namespace ESM4 std::string mEditorId; std::string mFullName; + std::string mShortName; + std::string mAbbrev; std::string mModel; std::string mText; std::string mIcon; // inventory @@ -77,6 +74,10 @@ namespace ESM4 std::uint16_t mEnchantmentPoints; FormId mEnchantment; + std::vector mAmmoEffects; + + FormId mScript; + Data mData; void load(ESM4::Reader& reader);