From debdcf29539d0ed9edecdb87aa07bf3e6979fa31 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 27 Dec 2021 00:47:33 +0100 Subject: [PATCH] Don't touch base stats when turning into a werewolf --- CHANGELOG.md | 1 + .../mwmechanics/mechanicsmanagerimp.cpp | 4 +- apps/openmw/mwworld/player.cpp | 63 +++++++++++-------- apps/openmw/mwworld/player.hpp | 4 +- components/esm/player.cpp | 48 +++++++++++--- components/esm/player.hpp | 5 +- components/esm/savedgame.cpp | 2 +- 7 files changed, 83 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d239717d0a..6127c24154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ Bug #6324: Special Slave Companions: Can't buy the slave companions Bug #6326: Detect Enchantment/Key should detect items in unresolved containers Bug #6327: Blocking roots the character in place + Bug #6333: Werewolf stat changes should be implemented as damage/fortifications Bug #6343: Magic projectile speed doesn't take race weight into account Bug #6347: PlaceItem/PlaceItemCell/PlaceAt should work with levelled creatures Bug #6354: SFX abruptly cut off after crossing max distance; implement soft fading of sound effects diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index fa5aaa82ef..e0d2da497b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1865,8 +1865,8 @@ namespace MWMechanics { const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor); - - stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->mValue.getInteger()); + auto& skill = stats.getSkill(ESM::Skill::Acrobatics); + skill.setModifier(gmst.find("fWerewolfAcrobatics")->mValue.getFloat() - skill.getModified()); } void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr &caster, int creatureActorId) diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 4687a4eddd..270889a23e 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -58,9 +58,9 @@ namespace MWWorld MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer()); for (int i=0; i health = creatureStats.getDynamic(0); - creatureStats.setHealth(int(health.getBase() / gmst.find("fWereWolfHealth")->mValue.getFloat())); + creatureStats.setHealth(health.getBase() / gmst.find("fWereWolfHealth")->mValue.getFloat()); for (int i=0; i health = creatureStats.getDynamic(0); - creatureStats.setHealth(int(health.getBase() * gmst.find("fWereWolfHealth")->mValue.getFloat())); + creatureStats.setHealth(health.getBase() * gmst.find("fWereWolfHealth")->mValue.getFloat()); for(size_t i = 0;i < ESM::Attribute::Length;++i) { // Oh, Bethesda. It's "Intelligence". @@ -90,7 +99,7 @@ namespace MWWorld ESM::Attribute::sAttributeNames[i]); MWMechanics::AttributeValue value = npcStats.getAttribute(i); - value.setBase(int(gmst.find(name)->mValue.getFloat())); + value.setModifier(gmst.find(name)->mValue.getFloat() - value.getModified()); npcStats.setAttribute(i, value); } @@ -104,9 +113,8 @@ namespace MWWorld std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") : ESM::Skill::sSkillNames[i]); - MWMechanics::SkillValue value = npcStats.getSkill(i); - value.setBase(int(gmst.find(name)->mValue.getFloat())); - npcStats.setSkill(i, value); + MWMechanics::SkillValue& value = npcStats.getSkill(i); + value.setModifier(gmst.find(name)->mValue.getFloat() - value.getModified()); } } @@ -316,14 +324,12 @@ namespace MWWorld for (int i=0; iapplyWerewolfAcrobatics(getPlayer()); + } } getPlayer().getClass().getCreatureStats(getPlayer()).getAiSequence().clear(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index a7e42d95e1..1a9744e8a3 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -53,8 +53,8 @@ namespace MWWorld PreviousItems mPreviousItems; // Saved stats prior to becoming a werewolf - MWMechanics::SkillValue mSaveSkills[ESM::Skill::Length]; - MWMechanics::AttributeValue mSaveAttributes[ESM::Attribute::Length]; + float mSaveSkills[ESM::Skill::Length]; + float mSaveAttributes[ESM::Attribute::Length]; bool mAttackingOrSpell; bool mJumping; diff --git a/components/esm/player.cpp b/components/esm/player.cpp index e2e9219e22..028a042809 100644 --- a/components/esm/player.cpp +++ b/components/esm/player.cpp @@ -44,13 +44,43 @@ void ESM::Player::load (ESMReader &esm) checkPrevItems = false; } - bool intFallback = esm.getFormat() < 11; - if (esm.hasMoreSubs()) + if(esm.getFormat() < 19) { - for (int i=0; i attribute; + attribute.load(esm, intFallback); + if (clearModified) + attribute.mMod = 0.f; + mSaveAttributes[i] = attribute.mBase + attribute.mMod - attribute.mDamage; + if (mObject.mNpcStats.mIsWerewolf) + mObject.mCreatureStats.mAttributes[i] = attribute; + } + for (int i=0; i skill; + skill.load(esm, intFallback); + if (clearModified) + skill.mMod = 0.f; + mSaveSkills[i] = skill.mBase + skill.mMod - skill.mDamage; + if (mObject.mNpcStats.mIsWerewolf) + { + if(i == ESM::Skill::Acrobatics) + mSetWerewolfAcrobatics = mObject.mNpcStats.mSkills[i].mBase != skill.mBase; + mObject.mNpcStats.mSkills[i] = skill; + } + } + } + } + else + { + mSetWerewolfAcrobatics = false; + esm.getHNT(mSaveAttributes, "WWAT"); + esm.getHNT(mSaveSkills, "WWSK"); } } @@ -79,8 +109,6 @@ void ESM::Player::save (ESMWriter &esm) const esm.writeHNString ("PREV", it->second); } - for (int i=0; i mSaveAttributes[ESM::Attribute::Length]; - StatState mSaveSkills[ESM::Skill::Length]; + float mSaveAttributes[ESM::Attribute::Length]; + float mSaveSkills[ESM::Skill::Length]; typedef std::map PreviousItems; // previous equipped items, needed for bound spells PreviousItems mPreviousItems; diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index 4ce0876bb8..6cecf26489 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -4,7 +4,7 @@ #include "esmwriter.hpp" unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; -int ESM::SavedGame::sCurrentFormat = 18; +int ESM::SavedGame::sCurrentFormat = 19; void ESM::SavedGame::load (ESMReader &esm) {