From b31664a78ff10a97c9f59993985bb660e4301b86 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Mon, 1 Jan 2024 12:47:01 -0600 Subject: [PATCH 1/6] Fix(CS): Scale actors according to their race's stats --- CHANGELOG.md | 1 + apps/opencs/model/world/actoradapter.cpp | 5 +++++ apps/opencs/model/world/actoradapter.hpp | 2 ++ apps/opencs/view/render/actor.cpp | 14 +++++++++++++- apps/opencs/view/render/actor.hpp | 3 ++- 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c473f068dd..b649ebcb90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,6 +133,7 @@ Bug #7724: Guards don't help vs werewolves Bug #7733: Launcher shows incorrect data paths when there's two plugins with the same name Bug #7742: Governing attribute training limit should use the modified attribute + Bug #7753: Editor: Actors Don't Scale According to Their Race Bug #7758: Water walking is not taken into account to compute path cost on the water Bug #7761: Rain and ambient loop sounds are mutually exclusive Bug #7765: OpenMW-CS: Touch Record option is broken diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index 37aaf08445..e4b577480d 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -163,6 +163,11 @@ namespace CSMWorld return it->second.first; } + const ESM::RefId& ActorAdapter::ActorData::getActorRaceName() const + { + return mRaceData->getId(); + } + bool ActorAdapter::ActorData::hasDependency(const ESM::RefId& id) const { return mDependencies.find(id) != mDependencies.end(); diff --git a/apps/opencs/model/world/actoradapter.hpp b/apps/opencs/model/world/actoradapter.hpp index 9747f448ae..5ab4da2e58 100644 --- a/apps/opencs/model/world/actoradapter.hpp +++ b/apps/opencs/model/world/actoradapter.hpp @@ -96,6 +96,8 @@ namespace CSMWorld std::string getSkeleton() const; /// Retrieves the associated actor part ESM::RefId getPart(ESM::PartReferenceType index) const; + + const ESM::RefId& getActorRaceName() const; /// Checks if the actor has a data dependency bool hasDependency(const ESM::RefId& id) const; diff --git a/apps/opencs/view/render/actor.cpp b/apps/opencs/view/render/actor.cpp index d1bfac0ec6..cfa06012ff 100644 --- a/apps/opencs/view/render/actor.cpp +++ b/apps/opencs/view/render/actor.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -20,6 +21,7 @@ #include #include +#include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" namespace CSVRender @@ -29,7 +31,7 @@ namespace CSVRender Actor::Actor(const ESM::RefId& id, CSMWorld::Data& data) : mId(id) , mData(data) - , mBaseNode(new osg::Group()) + , mBaseNode(new osg::PositionAttitudeTransform()) , mSkeleton(nullptr) { mActorData = mData.getActorAdapter()->getActorData(mId); @@ -60,6 +62,16 @@ namespace CSVRender // Attach parts to skeleton loadBodyParts(); + + const CSMWorld::IdCollection& races = mData.getRaces(); + const auto& targetRace = races.getRecord(mActorData->getActorRaceName()).get().mData; + osg::Vec3d scale; + + mActorData.get()->isFemale() + ? scale = osg::Vec3(targetRace.mFemaleWeight, targetRace.mFemaleWeight, targetRace.mFemaleHeight) + : scale = osg::Vec3(targetRace.mMaleWeight, targetRace.mMaleWeight, targetRace.mMaleHeight); + + mBaseNode->setScale(scale); } else { diff --git a/apps/opencs/view/render/actor.hpp b/apps/opencs/view/render/actor.hpp index 86c7e7ff2d..a9cc34b00d 100644 --- a/apps/opencs/view/render/actor.hpp +++ b/apps/opencs/view/render/actor.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -59,7 +60,7 @@ namespace CSVRender CSMWorld::Data& mData; CSMWorld::ActorAdapter::ActorDataPtr mActorData; - osg::ref_ptr mBaseNode; + osg::ref_ptr mBaseNode; SceneUtil::Skeleton* mSkeleton; SceneUtil::NodeMapVisitor::NodeMap mNodeMap; }; From 049550d73ef927fd76b596cef99fd2e483912846 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Mon, 1 Jan 2024 21:00:00 -0600 Subject: [PATCH 2/6] Cleanup(Actoradapter.cpp): Create new struct for race stats, use std::pair instead --- apps/opencs/model/world/actoradapter.cpp | 18 ++++++++++++---- apps/opencs/model/world/actoradapter.hpp | 27 ++++++++++++++++++++++-- apps/opencs/view/render/actor.cpp | 10 ++------- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index e4b577480d..f3c2161c73 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -67,6 +67,11 @@ namespace CSMWorld return mMaleParts[ESM::getMeshPart(index)]; } + const std::pair& ActorAdapter::RaceData::getRaceAttributes(bool isFemale) + { + return isFemale == true ? mHeightsWeights.mFemaleAttributes : mHeightsWeights.mMaleAttributes; + } + bool ActorAdapter::RaceData::hasDependency(const ESM::RefId& id) const { return mDependencies.find(id) != mDependencies.end(); @@ -90,10 +95,11 @@ namespace CSMWorld mDependencies.emplace(id); } - void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, bool isBeast) + void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, const BodyAttributes& raceStats, bool isBeast) { mId = id; mIsBeast = isBeast; + mHeightsWeights = raceStats; for (auto& str : mFemaleParts) str = ESM::RefId(); for (auto& str : mMaleParts) @@ -163,9 +169,9 @@ namespace CSMWorld return it->second.first; } - const ESM::RefId& ActorAdapter::ActorData::getActorRaceName() const + const std::pair& ActorAdapter::ActorData::getRaceHeightWeight() const { - return mRaceData->getId(); + return mRaceData->getRaceAttributes(isFemale()); } bool ActorAdapter::ActorData::hasDependency(const ESM::RefId& id) const @@ -509,7 +515,11 @@ namespace CSMWorld } auto& race = raceRecord.get(); - data->reset_data(id, race.mData.mFlags & ESM::Race::Beast); + + BodyAttributes scaleStats = BodyAttributes( + race.mData.mMaleHeight, race.mData.mMaleWeight, race.mData.mFemaleHeight, race.mData.mFemaleWeight); + + data->reset_data(id, scaleStats, race.mData.mFlags & ESM::Race::Beast); // Setup body parts for (int i = 0; i < mBodyParts.getSize(); ++i) diff --git a/apps/opencs/model/world/actoradapter.hpp b/apps/opencs/model/world/actoradapter.hpp index 5ab4da2e58..21298d33df 100644 --- a/apps/opencs/model/world/actoradapter.hpp +++ b/apps/opencs/model/world/actoradapter.hpp @@ -41,6 +41,25 @@ namespace CSMWorld /// Tracks unique strings using RefIdSet = std::unordered_set; + class BodyAttributes + { + public: + std::pair mMaleAttributes; + std::pair mFemaleAttributes; + + BodyAttributes() + : mMaleAttributes(std::make_pair(1.0f, 1.0f)) + , mFemaleAttributes(std::make_pair(1.0f, 1.0f)) + { + } + + BodyAttributes(float maleHeight, float maleWeight, float femaleHeight, float femaleWeight) + { + mMaleAttributes = std::make_pair(maleHeight, maleWeight); + mFemaleAttributes = std::make_pair(femaleHeight, femaleWeight); + } + }; + /// Contains base race data shared between actors class RaceData { @@ -57,6 +76,8 @@ namespace CSMWorld const ESM::RefId& getFemalePart(ESM::PartReferenceType index) const; /// Retrieves the associated body part const ESM::RefId& getMalePart(ESM::PartReferenceType index) const; + + const std::pair& getRaceAttributes(bool isFemale); /// Checks if the race has a data dependency bool hasDependency(const ESM::RefId& id) const; @@ -67,7 +88,8 @@ namespace CSMWorld /// Marks an additional dependency void addOtherDependency(const ESM::RefId& id); /// Clears parts and dependencies - void reset_data(const ESM::RefId& raceId, bool isBeast = false); + void reset_data( + const ESM::RefId& raceId, const BodyAttributes& raceStats = BodyAttributes(), bool isBeast = false); private: bool handles(ESM::PartReferenceType type) const; @@ -75,6 +97,7 @@ namespace CSMWorld bool mIsBeast; RacePartList mFemaleParts; RacePartList mMaleParts; + BodyAttributes mHeightsWeights; RefIdSet mDependencies; }; using RaceDataPtr = std::shared_ptr; @@ -97,7 +120,7 @@ namespace CSMWorld /// Retrieves the associated actor part ESM::RefId getPart(ESM::PartReferenceType index) const; - const ESM::RefId& getActorRaceName() const; + const std::pair& getRaceHeightWeight() const; /// Checks if the actor has a data dependency bool hasDependency(const ESM::RefId& id) const; diff --git a/apps/opencs/view/render/actor.cpp b/apps/opencs/view/render/actor.cpp index cfa06012ff..abe7b910de 100644 --- a/apps/opencs/view/render/actor.cpp +++ b/apps/opencs/view/render/actor.cpp @@ -63,15 +63,9 @@ namespace CSVRender // Attach parts to skeleton loadBodyParts(); - const CSMWorld::IdCollection& races = mData.getRaces(); - const auto& targetRace = races.getRecord(mActorData->getActorRaceName()).get().mData; - osg::Vec3d scale; + const std::pair attributes = mActorData.get()->getRaceHeightWeight(); - mActorData.get()->isFemale() - ? scale = osg::Vec3(targetRace.mFemaleWeight, targetRace.mFemaleWeight, targetRace.mFemaleHeight) - : scale = osg::Vec3(targetRace.mMaleWeight, targetRace.mMaleWeight, targetRace.mMaleHeight); - - mBaseNode->setScale(scale); + mBaseNode->setScale(osg::Vec3d(attributes.second, attributes.second, attributes.first)); } else { From 98ad059806e1ec7d8fb3ff15d55658d2640c3930 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Tue, 2 Jan 2024 16:08:25 -0600 Subject: [PATCH 3/6] Cleanup(actoradapter): Use more explicit names & vec2 for racial height/weight --- apps/opencs/model/world/actoradapter.cpp | 14 ++++++------- apps/opencs/model/world/actoradapter.hpp | 26 ++++++++++++------------ apps/opencs/view/render/actor.cpp | 4 ++-- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index f3c2161c73..40bfe17989 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -67,9 +67,9 @@ namespace CSMWorld return mMaleParts[ESM::getMeshPart(index)]; } - const std::pair& ActorAdapter::RaceData::getRaceAttributes(bool isFemale) + const osg::Vec2f& ActorAdapter::RaceData::getHeightWeight(bool isFemale) { - return isFemale == true ? mHeightsWeights.mFemaleAttributes : mHeightsWeights.mMaleAttributes; + return isFemale ? mHeightsWeights.mFemaleHeightWeight : mHeightsWeights.mMaleHeightWeight; } bool ActorAdapter::RaceData::hasDependency(const ESM::RefId& id) const @@ -95,7 +95,7 @@ namespace CSMWorld mDependencies.emplace(id); } - void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, const BodyAttributes& raceStats, bool isBeast) + void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, const HeightsWeights& raceStats, bool isBeast) { mId = id; mIsBeast = isBeast; @@ -169,9 +169,9 @@ namespace CSMWorld return it->second.first; } - const std::pair& ActorAdapter::ActorData::getRaceHeightWeight() const + const osg::Vec2f& ActorAdapter::ActorData::getRaceHeightWeight() const { - return mRaceData->getRaceAttributes(isFemale()); + return mRaceData->getHeightWeight(isFemale()); } bool ActorAdapter::ActorData::hasDependency(const ESM::RefId& id) const @@ -516,8 +516,8 @@ namespace CSMWorld auto& race = raceRecord.get(); - BodyAttributes scaleStats = BodyAttributes( - race.mData.mMaleHeight, race.mData.mMaleWeight, race.mData.mFemaleHeight, race.mData.mFemaleWeight); + HeightsWeights scaleStats = HeightsWeights(osg::Vec2f(race.mData.mMaleWeight, race.mData.mMaleHeight), + osg::Vec2f(race.mData.mFemaleWeight, race.mData.mFemaleHeight)); data->reset_data(id, scaleStats, race.mData.mFlags & ESM::Race::Beast); diff --git a/apps/opencs/model/world/actoradapter.hpp b/apps/opencs/model/world/actoradapter.hpp index 21298d33df..e516325455 100644 --- a/apps/opencs/model/world/actoradapter.hpp +++ b/apps/opencs/model/world/actoradapter.hpp @@ -41,22 +41,22 @@ namespace CSMWorld /// Tracks unique strings using RefIdSet = std::unordered_set; - class BodyAttributes + class HeightsWeights { public: - std::pair mMaleAttributes; - std::pair mFemaleAttributes; + osg::Vec2f mMaleHeightWeight; + osg::Vec2f mFemaleHeightWeight; - BodyAttributes() - : mMaleAttributes(std::make_pair(1.0f, 1.0f)) - , mFemaleAttributes(std::make_pair(1.0f, 1.0f)) + HeightsWeights() + : mMaleHeightWeight(osg::Vec2f(1.0f, 1.0f)) + , mFemaleHeightWeight(osg::Vec2f(1.0f, 1.0f)) { } - BodyAttributes(float maleHeight, float maleWeight, float femaleHeight, float femaleWeight) + HeightsWeights(const osg::Vec2f& maleHeightWeight, const osg::Vec2f& femaleHeightWeight) { - mMaleAttributes = std::make_pair(maleHeight, maleWeight); - mFemaleAttributes = std::make_pair(femaleHeight, femaleWeight); + mMaleHeightWeight = maleHeightWeight; + mFemaleHeightWeight = femaleHeightWeight; } }; @@ -77,7 +77,7 @@ namespace CSMWorld /// Retrieves the associated body part const ESM::RefId& getMalePart(ESM::PartReferenceType index) const; - const std::pair& getRaceAttributes(bool isFemale); + const osg::Vec2f& getHeightWeight(bool isFemale); /// Checks if the race has a data dependency bool hasDependency(const ESM::RefId& id) const; @@ -89,7 +89,7 @@ namespace CSMWorld void addOtherDependency(const ESM::RefId& id); /// Clears parts and dependencies void reset_data( - const ESM::RefId& raceId, const BodyAttributes& raceStats = BodyAttributes(), bool isBeast = false); + const ESM::RefId& raceId, const HeightsWeights& raceStats = HeightsWeights(), bool isBeast = false); private: bool handles(ESM::PartReferenceType type) const; @@ -97,7 +97,7 @@ namespace CSMWorld bool mIsBeast; RacePartList mFemaleParts; RacePartList mMaleParts; - BodyAttributes mHeightsWeights; + HeightsWeights mHeightsWeights; RefIdSet mDependencies; }; using RaceDataPtr = std::shared_ptr; @@ -120,7 +120,7 @@ namespace CSMWorld /// Retrieves the associated actor part ESM::RefId getPart(ESM::PartReferenceType index) const; - const std::pair& getRaceHeightWeight() const; + const osg::Vec2f& getRaceHeightWeight() const; /// Checks if the actor has a data dependency bool hasDependency(const ESM::RefId& id) const; diff --git a/apps/opencs/view/render/actor.cpp b/apps/opencs/view/render/actor.cpp index abe7b910de..e609efa5a1 100644 --- a/apps/opencs/view/render/actor.cpp +++ b/apps/opencs/view/render/actor.cpp @@ -63,9 +63,9 @@ namespace CSVRender // Attach parts to skeleton loadBodyParts(); - const std::pair attributes = mActorData.get()->getRaceHeightWeight(); + const osg::Vec2f& attributes = mActorData.get()->getRaceHeightWeight(); - mBaseNode->setScale(osg::Vec3d(attributes.second, attributes.second, attributes.first)); + mBaseNode->setScale(osg::Vec3d(attributes.x(), attributes.x(), attributes.y())); } else { From 1b1f0c4971a792622bff7f323b9642ceb0d17b4a Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Wed, 14 Feb 2024 16:41:24 -0600 Subject: [PATCH 4/6] Switch height/weight in names and make the stats a simple struct instead --- apps/opencs/model/world/actoradapter.cpp | 16 ++++++------- apps/opencs/model/world/actoradapter.hpp | 29 +++++++----------------- apps/opencs/view/render/actor.cpp | 3 +-- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index 40bfe17989..acbe6b5d38 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -67,9 +67,9 @@ namespace CSMWorld return mMaleParts[ESM::getMeshPart(index)]; } - const osg::Vec2f& ActorAdapter::RaceData::getHeightWeight(bool isFemale) + const osg::Vec2f& ActorAdapter::RaceData::getGenderWeightHeight(bool isFemale) { - return isFemale ? mHeightsWeights.mFemaleHeightWeight : mHeightsWeights.mMaleHeightWeight; + return isFemale ? mWeightsHeights.mFemaleWeightHeight : mWeightsHeights.mMaleWeightHeight; } bool ActorAdapter::RaceData::hasDependency(const ESM::RefId& id) const @@ -95,11 +95,11 @@ namespace CSMWorld mDependencies.emplace(id); } - void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, const HeightsWeights& raceStats, bool isBeast) + void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, const WeightsHeights& raceStats, bool isBeast) { mId = id; mIsBeast = isBeast; - mHeightsWeights = raceStats; + mWeightsHeights = raceStats; for (auto& str : mFemaleParts) str = ESM::RefId(); for (auto& str : mMaleParts) @@ -169,9 +169,9 @@ namespace CSMWorld return it->second.first; } - const osg::Vec2f& ActorAdapter::ActorData::getRaceHeightWeight() const + const osg::Vec2f& ActorAdapter::ActorData::getRaceWeightHeight() const { - return mRaceData->getHeightWeight(isFemale()); + return mRaceData->getGenderWeightHeight(isFemale()); } bool ActorAdapter::ActorData::hasDependency(const ESM::RefId& id) const @@ -516,8 +516,8 @@ namespace CSMWorld auto& race = raceRecord.get(); - HeightsWeights scaleStats = HeightsWeights(osg::Vec2f(race.mData.mMaleWeight, race.mData.mMaleHeight), - osg::Vec2f(race.mData.mFemaleWeight, race.mData.mFemaleHeight)); + WeightsHeights scaleStats = { osg::Vec2f(race.mData.mMaleWeight, race.mData.mMaleHeight), + osg::Vec2f(race.mData.mFemaleWeight, race.mData.mFemaleHeight) }; data->reset_data(id, scaleStats, race.mData.mFlags & ESM::Race::Beast); diff --git a/apps/opencs/model/world/actoradapter.hpp b/apps/opencs/model/world/actoradapter.hpp index e516325455..1650fc9006 100644 --- a/apps/opencs/model/world/actoradapter.hpp +++ b/apps/opencs/model/world/actoradapter.hpp @@ -41,23 +41,10 @@ namespace CSMWorld /// Tracks unique strings using RefIdSet = std::unordered_set; - class HeightsWeights + struct WeightsHeights { - public: - osg::Vec2f mMaleHeightWeight; - osg::Vec2f mFemaleHeightWeight; - - HeightsWeights() - : mMaleHeightWeight(osg::Vec2f(1.0f, 1.0f)) - , mFemaleHeightWeight(osg::Vec2f(1.0f, 1.0f)) - { - } - - HeightsWeights(const osg::Vec2f& maleHeightWeight, const osg::Vec2f& femaleHeightWeight) - { - mMaleHeightWeight = maleHeightWeight; - mFemaleHeightWeight = femaleHeightWeight; - } + osg::Vec2f mMaleWeightHeight; + osg::Vec2f mFemaleWeightHeight; }; /// Contains base race data shared between actors @@ -77,7 +64,7 @@ namespace CSMWorld /// Retrieves the associated body part const ESM::RefId& getMalePart(ESM::PartReferenceType index) const; - const osg::Vec2f& getHeightWeight(bool isFemale); + const osg::Vec2f& getGenderWeightHeight(bool isFemale); /// Checks if the race has a data dependency bool hasDependency(const ESM::RefId& id) const; @@ -88,8 +75,8 @@ namespace CSMWorld /// Marks an additional dependency void addOtherDependency(const ESM::RefId& id); /// Clears parts and dependencies - void reset_data( - const ESM::RefId& raceId, const HeightsWeights& raceStats = HeightsWeights(), bool isBeast = false); + void reset_data(const ESM::RefId& raceId, + const WeightsHeights& raceStats = { osg::Vec2f(1.f, 1.f), osg::Vec2f(1.f, 1.f) }, bool isBeast = false); private: bool handles(ESM::PartReferenceType type) const; @@ -97,7 +84,7 @@ namespace CSMWorld bool mIsBeast; RacePartList mFemaleParts; RacePartList mMaleParts; - HeightsWeights mHeightsWeights; + WeightsHeights mWeightsHeights; RefIdSet mDependencies; }; using RaceDataPtr = std::shared_ptr; @@ -120,7 +107,7 @@ namespace CSMWorld /// Retrieves the associated actor part ESM::RefId getPart(ESM::PartReferenceType index) const; - const osg::Vec2f& getRaceHeightWeight() const; + const osg::Vec2f& getRaceWeightHeight() const; /// Checks if the actor has a data dependency bool hasDependency(const ESM::RefId& id) const; diff --git a/apps/opencs/view/render/actor.cpp b/apps/opencs/view/render/actor.cpp index e609efa5a1..8aa08e443e 100644 --- a/apps/opencs/view/render/actor.cpp +++ b/apps/opencs/view/render/actor.cpp @@ -21,7 +21,6 @@ #include #include -#include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" namespace CSVRender @@ -63,7 +62,7 @@ namespace CSVRender // Attach parts to skeleton loadBodyParts(); - const osg::Vec2f& attributes = mActorData.get()->getRaceHeightWeight(); + const osg::Vec2f& attributes = mActorData->getRaceWeightHeight(); mBaseNode->setScale(osg::Vec3d(attributes.x(), attributes.x(), attributes.y())); } From 54e90b4ac2693eaeaebe5caeed96728286204d98 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Wed, 14 Feb 2024 20:00:22 -0600 Subject: [PATCH 5/6] Legacy(columnimp): Add TESCS limits for race weight/height scaling --- apps/opencs/model/world/columnimp.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index eba09bd8b1..099dd25983 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -585,19 +585,22 @@ namespace CSMWorld void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); + + float bodyAttr = std::max(0.5f, std::min(2.0f, data.toFloat())); + if (mWeight) { if (mMale) - record2.mData.mMaleWeight = data.toFloat(); + record2.mData.mMaleWeight = bodyAttr; else - record2.mData.mFemaleWeight = data.toFloat(); + record2.mData.mFemaleWeight = bodyAttr; } else { if (mMale) - record2.mData.mMaleHeight = data.toFloat(); + record2.mData.mMaleHeight = bodyAttr; else - record2.mData.mFemaleHeight = data.toFloat(); + record2.mData.mFemaleHeight = bodyAttr; } record.setModified(record2); } From 54f4c69d37795c9045221339b4dce602c6ff8cc7 Mon Sep 17 00:00:00 2001 From: Dave Corley Date: Thu, 15 Feb 2024 21:25:29 -0600 Subject: [PATCH 6/6] Cleanup(columnimp): Use std::clamp to limit race scaling --- apps/opencs/model/world/columnimp.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 099dd25983..0cd95b0ed2 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -586,7 +586,7 @@ namespace CSMWorld { ESXRecordT record2 = record.get(); - float bodyAttr = std::max(0.5f, std::min(2.0f, data.toFloat())); + float bodyAttr = std::clamp(data.toFloat(), 0.5f, 2.0f); if (mWeight) {