mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-01 20:06:40 +00:00
Use ESM::decompose to handle WPDTstruct
This commit is contained in:
parent
ec1c6ee171
commit
7d7e8939ab
7 changed files with 82 additions and 32 deletions
|
@ -316,11 +316,11 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
const unsigned char* attack = nullptr;
|
const unsigned char* attack = nullptr;
|
||||||
if (type == ESM::Weapon::AT_Chop)
|
if (type == ESM::Weapon::AT_Chop)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop.data();
|
||||||
else if (type == ESM::Weapon::AT_Slash)
|
else if (type == ESM::Weapon::AT_Slash)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash.data();
|
||||||
else if (type == ESM::Weapon::AT_Thrust)
|
else if (type == ESM::Weapon::AT_Thrust)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust.data();
|
||||||
if (attack)
|
if (attack)
|
||||||
{
|
{
|
||||||
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
||||||
|
|
|
@ -635,11 +635,11 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
const unsigned char* attack = nullptr;
|
const unsigned char* attack = nullptr;
|
||||||
if (type == ESM::Weapon::AT_Chop)
|
if (type == ESM::Weapon::AT_Chop)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop.data();
|
||||||
else if (type == ESM::Weapon::AT_Slash)
|
else if (type == ESM::Weapon::AT_Slash)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mSlash.data();
|
||||||
else if (type == ESM::Weapon::AT_Thrust)
|
else if (type == ESM::Weapon::AT_Thrust)
|
||||||
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust;
|
attack = weapon.get<ESM::Weapon>()->mBase->mData.mThrust.data();
|
||||||
if (attack)
|
if (attack)
|
||||||
{
|
{
|
||||||
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
||||||
|
|
|
@ -246,14 +246,16 @@ namespace MWMechanics
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char* attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
|
{
|
||||||
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength); // Bow/crossbow damage
|
const auto& attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
|
||||||
|
damage = attack[0] + ((attack[1] - attack[0]) * attackStrength); // Bow/crossbow damage
|
||||||
// Arrow/bolt damage
|
}
|
||||||
// NB in case of thrown weapons, we are applying the damage twice since projectile == weapon
|
{
|
||||||
attack = projectile.get<ESM::Weapon>()->mBase->mData.mChop;
|
// Arrow/bolt damage
|
||||||
damage += attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
// NB in case of thrown weapons, we are applying the damage twice since projectile == weapon
|
||||||
|
const auto& attack = projectile.get<ESM::Weapon>()->mBase->mData.mChop;
|
||||||
|
damage += attack[0] + ((attack[1] - attack[0]) * attackStrength);
|
||||||
|
}
|
||||||
adjustWeaponDamage(damage, weapon, attacker);
|
adjustWeaponDamage(damage, weapon, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <components/esm3/loaddial.hpp>
|
#include <components/esm3/loaddial.hpp>
|
||||||
#include <components/esm3/loadregn.hpp>
|
#include <components/esm3/loadregn.hpp>
|
||||||
#include <components/esm3/loadscpt.hpp>
|
#include <components/esm3/loadscpt.hpp>
|
||||||
|
#include <components/esm3/loadweap.hpp>
|
||||||
#include <components/esm3/player.hpp>
|
#include <components/esm3/player.hpp>
|
||||||
#include <components/esm3/quickkeys.hpp>
|
#include <components/esm3/quickkeys.hpp>
|
||||||
|
|
||||||
|
@ -554,6 +555,53 @@ namespace ESM
|
||||||
EXPECT_EQ(result.mList[0].mMagnMax, record.mList[0].mMagnMax);
|
EXPECT_EQ(result.mList[0].mMagnMax, record.mList[0].mMagnMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(Esm3SaveLoadRecordTest, weaponShouldNotChange)
|
||||||
|
{
|
||||||
|
Weapon record = {
|
||||||
|
.mData = {
|
||||||
|
.mWeight = 0,
|
||||||
|
.mValue = 1,
|
||||||
|
.mType = 2,
|
||||||
|
.mHealth = 3,
|
||||||
|
.mSpeed = 4,
|
||||||
|
.mReach = 5,
|
||||||
|
.mEnchant = 6,
|
||||||
|
.mChop = { 7, 8 },
|
||||||
|
.mSlash = { 9, 10 },
|
||||||
|
.mThrust = { 11, 12 },
|
||||||
|
.mFlags = 13,
|
||||||
|
},
|
||||||
|
.mRecordFlags = 0,
|
||||||
|
.mId = generateRandomRefId(32),
|
||||||
|
.mEnchant = generateRandomRefId(32),
|
||||||
|
.mScript = generateRandomRefId(32),
|
||||||
|
.mName = generateRandomString(32),
|
||||||
|
.mModel = generateRandomString(32),
|
||||||
|
.mIcon = generateRandomString(32),
|
||||||
|
};
|
||||||
|
|
||||||
|
Weapon result;
|
||||||
|
saveAndLoadRecord(record, GetParam(), result);
|
||||||
|
|
||||||
|
EXPECT_EQ(result.mData.mWeight, record.mData.mWeight);
|
||||||
|
EXPECT_EQ(result.mData.mValue, record.mData.mValue);
|
||||||
|
EXPECT_EQ(result.mData.mType, record.mData.mType);
|
||||||
|
EXPECT_EQ(result.mData.mHealth, record.mData.mHealth);
|
||||||
|
EXPECT_EQ(result.mData.mSpeed, record.mData.mSpeed);
|
||||||
|
EXPECT_EQ(result.mData.mReach, record.mData.mReach);
|
||||||
|
EXPECT_EQ(result.mData.mEnchant, record.mData.mEnchant);
|
||||||
|
EXPECT_EQ(result.mData.mChop, record.mData.mChop);
|
||||||
|
EXPECT_EQ(result.mData.mSlash, record.mData.mSlash);
|
||||||
|
EXPECT_EQ(result.mData.mThrust, record.mData.mThrust);
|
||||||
|
EXPECT_EQ(result.mData.mFlags, record.mData.mFlags);
|
||||||
|
EXPECT_EQ(result.mId, record.mId);
|
||||||
|
EXPECT_EQ(result.mEnchant, record.mEnchant);
|
||||||
|
EXPECT_EQ(result.mScript, record.mScript);
|
||||||
|
EXPECT_EQ(result.mName, record.mName);
|
||||||
|
EXPECT_EQ(result.mModel, record.mModel);
|
||||||
|
EXPECT_EQ(result.mIcon, record.mIcon);
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(FormatVersions, Esm3SaveLoadRecordTest, ValuesIn(getFormats()));
|
INSTANTIATE_TEST_SUITE_P(FormatVersions, Esm3SaveLoadRecordTest, ValuesIn(getFormats()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,13 +191,7 @@ namespace ESM
|
||||||
|
|
||||||
void getSubComposite(auto& value)
|
void getSubComposite(auto& value)
|
||||||
{
|
{
|
||||||
decompose(value, [&](auto&... args) {
|
decompose(value, [&](auto&... args) { getHT(args...); });
|
||||||
constexpr size_t size = (0 + ... + sizeof(decltype(args)));
|
|
||||||
getSubHeader();
|
|
||||||
if (mCtx.leftSub != size)
|
|
||||||
reportSubSizeMismatch(size, mCtx.leftSub);
|
|
||||||
(getT(args), ...);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename = std::enable_if_t<IsReadable<T>>>
|
template <typename T, typename = std::enable_if_t<IsReadable<T>>>
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
#include "loadweap.hpp"
|
#include "loadweap.hpp"
|
||||||
|
|
||||||
#include "components/esm/defs.hpp"
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/misc/concepts.hpp>
|
||||||
|
|
||||||
#include "esmreader.hpp"
|
#include "esmreader.hpp"
|
||||||
#include "esmwriter.hpp"
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
template <Misc::SameAsWithoutCvref<Weapon::WPDTstruct> T>
|
||||||
|
void decompose(T&& v, const auto& f)
|
||||||
|
{
|
||||||
|
f(v.mWeight, v.mValue, v.mType, v.mHealth, v.mSpeed, v.mReach, v.mEnchant, v.mChop, v.mSlash, v.mThrust,
|
||||||
|
v.mFlags);
|
||||||
|
}
|
||||||
|
|
||||||
void Weapon::load(ESMReader& esm, bool& isDeleted)
|
void Weapon::load(ESMReader& esm, bool& isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
@ -29,8 +38,7 @@ namespace ESM
|
||||||
mName = esm.getHString();
|
mName = esm.getHString();
|
||||||
break;
|
break;
|
||||||
case fourCC("WPDT"):
|
case fourCC("WPDT"):
|
||||||
esm.getHT(mData.mWeight, mData.mValue, mData.mType, mData.mHealth, mData.mSpeed, mData.mReach,
|
esm.getSubComposite(mData);
|
||||||
mData.mEnchant, mData.mChop, mData.mSlash, mData.mThrust, mData.mFlags);
|
|
||||||
hasData = true;
|
hasData = true;
|
||||||
break;
|
break;
|
||||||
case fourCC("SCRI"):
|
case fourCC("SCRI"):
|
||||||
|
@ -68,7 +76,7 @@ namespace ESM
|
||||||
|
|
||||||
esm.writeHNCString("MODL", mModel);
|
esm.writeHNCString("MODL", mModel);
|
||||||
esm.writeHNOCString("FNAM", mName);
|
esm.writeHNOCString("FNAM", mName);
|
||||||
esm.writeHNT("WPDT", mData, 32);
|
esm.writeNamedComposite("WPDT", mData);
|
||||||
esm.writeHNOCRefId("SCRI", mScript);
|
esm.writeHNOCRefId("SCRI", mScript);
|
||||||
esm.writeHNOCString("ITEX", mIcon);
|
esm.writeHNOCString("ITEX", mIcon);
|
||||||
esm.writeHNOCRefId("ENAM", mEnchant);
|
esm.writeHNOCRefId("ENAM", mEnchant);
|
||||||
|
@ -84,9 +92,9 @@ namespace ESM
|
||||||
mData.mSpeed = 0;
|
mData.mSpeed = 0;
|
||||||
mData.mReach = 0;
|
mData.mReach = 0;
|
||||||
mData.mEnchant = 0;
|
mData.mEnchant = 0;
|
||||||
mData.mChop[0] = mData.mChop[1] = 0;
|
mData.mChop.fill(0);
|
||||||
mData.mSlash[0] = mData.mSlash[1] = 0;
|
mData.mSlash.fill(0);
|
||||||
mData.mThrust[0] = mData.mThrust[1] = 0;
|
mData.mThrust.fill(0);
|
||||||
mData.mFlags = 0;
|
mData.mFlags = 0;
|
||||||
|
|
||||||
mName.clear();
|
mName.clear();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef OPENMW_ESM_WEAP_H
|
#ifndef OPENMW_ESM_WEAP_H
|
||||||
#define OPENMW_ESM_WEAP_H
|
#define OPENMW_ESM_WEAP_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "components/esm/refid.hpp"
|
#include "components/esm/refid.hpp"
|
||||||
|
@ -59,8 +60,6 @@ namespace ESM
|
||||||
Silver = 0x02
|
Silver = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1)
|
|
||||||
struct WPDTstruct
|
struct WPDTstruct
|
||||||
{
|
{
|
||||||
float mWeight;
|
float mWeight;
|
||||||
|
@ -69,10 +68,9 @@ namespace ESM
|
||||||
uint16_t mHealth;
|
uint16_t mHealth;
|
||||||
float mSpeed, mReach;
|
float mSpeed, mReach;
|
||||||
uint16_t mEnchant; // Enchantment points. The real value is mEnchant/10.f
|
uint16_t mEnchant; // Enchantment points. The real value is mEnchant/10.f
|
||||||
unsigned char mChop[2], mSlash[2], mThrust[2]; // Min and max
|
std::array<unsigned char, 2> mChop, mSlash, mThrust; // Min and max
|
||||||
int32_t mFlags;
|
int32_t mFlags;
|
||||||
}; // 32 bytes
|
}; // 32 bytes
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
WPDTstruct mData;
|
WPDTstruct mData;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue