diff options
author | psi29a <psi29a@gmail.com> | 2022-01-04 10:27:48 +0000 |
---|---|---|
committer | psi29a <psi29a@gmail.com> | 2022-01-04 10:27:48 +0000 |
commit | 0766e1310b899d4323ccfd704c1d0fcb2b9148c0 (patch) | |
tree | 20d17fd60ca21e3926aefcbe8ef282f7fbe9f9f8 | |
parent | e16245278e7ebd9325087cec883df78914b383d3 (diff) | |
parent | debdcf29539d0ed9edecdb87aa07bf3e6979fa31 (diff) |
Merge branch 'lunacy' into 'master'
Don't touch base stats when turning into a werewolf
Closes #6333
See merge request OpenMW/openmw!1511
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 | ||||
-rw-r--r-- | apps/openmw/mwworld/player.cpp | 63 | ||||
-rw-r--r-- | apps/openmw/mwworld/player.hpp | 4 | ||||
-rw-r--r-- | components/esm/player.cpp | 48 | ||||
-rw-r--r-- | components/esm/player.hpp | 5 | ||||
-rw-r--r-- | components/esm/savedgame.cpp | 2 |
7 files changed, 83 insertions, 44 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 02d86f8802..419727c87d 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<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); 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<ESM::Skill::Length; ++i) - mSaveSkills[i] = stats.getSkill(i); + mSaveSkills[i] = stats.getSkill(i).getModified(); for (int i=0; i<ESM::Attribute::Length; ++i) - mSaveAttributes[i] = stats.getAttribute(i); + mSaveAttributes[i] = stats.getAttribute(i).getModified(); } void Player::restoreStats() @@ -69,11 +69,20 @@ namespace MWWorld MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer()); MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer()); MWMechanics::DynamicStat<float> 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<ESM::Skill::Length; ++i) - npcStats.setSkill(i, mSaveSkills[i]); + { + auto& skill = npcStats.getSkill(i); + skill.restore(skill.getDamage()); + skill.setModifier(mSaveSkills[i] - skill.getBase()); + } for (int i=0; i<ESM::Attribute::Length; ++i) - npcStats.setAttribute(i, mSaveAttributes[i]); + { + auto attribute = npcStats.getAttribute(i); + attribute.restore(attribute.getDamage()); + attribute.setModifier(mSaveAttributes[i] - attribute.getBase()); + npcStats.setAttribute(i, attribute); + } } void Player::setWerewolfStats() @@ -82,7 +91,7 @@ namespace MWWorld MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer()); MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer()); MWMechanics::DynamicStat<float> 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; i<ESM::Skill::Length; ++i) { - mSaveSkills[i].setBase(0); - mSaveSkills[i].setModifier(0); + mSaveSkills[i] = 0.f; } for (int i=0; i<ESM::Attribute::Length; ++i) { - mSaveAttributes[i].setBase(0); - mSaveAttributes[i].setModifier(0); + mSaveAttributes[i] = 0.f; } mMarkedPosition.pos[0] = 0; @@ -360,9 +366,9 @@ namespace MWWorld player.mHasMark = false; for (int i=0; i<ESM::Attribute::Length; ++i) - mSaveAttributes[i].writeState(player.mSaveAttributes[i]); + player.mSaveAttributes[i] = mSaveAttributes[i]; for (int i=0; i<ESM::Skill::Length; ++i) - mSaveSkills[i].writeState(player.mSaveSkills[i]); + player.mSaveSkills[i] = mSaveSkills[i]; player.mPreviousItems = mPreviousItems; @@ -384,13 +390,7 @@ namespace MWWorld throw std::runtime_error ("invalid player state record (object state)"); } if (reader.getFormat() < 17) - { convertMagicEffects(player.mObject.mCreatureStats, player.mObject.mInventory, &player.mObject.mNpcStats); - for(std::size_t i = 0; i < ESM::Attribute::Length; ++i) - player.mSaveAttributes[i].mMod = 0.f; - for(std::size_t i = 0; i < ESM::Skill::Length; ++i) - player.mSaveSkills[i].mMod = 0.f; - } if (!player.mObject.mEnabled) { @@ -401,14 +401,23 @@ namespace MWWorld mPlayer.load (player.mObject); for (int i=0; i<ESM::Attribute::Length; ++i) - mSaveAttributes[i].readState(player.mSaveAttributes[i]); + mSaveAttributes[i] = player.mSaveAttributes[i]; for (int i=0; i<ESM::Skill::Length; ++i) - mSaveSkills[i].readState(player.mSaveSkills[i]); + mSaveSkills[i] = player.mSaveSkills[i]; - if (player.mObject.mNpcStats.mWerewolfDeprecatedData && player.mObject.mNpcStats.mIsWerewolf) + if (player.mObject.mNpcStats.mIsWerewolf) { - saveStats(); - setWerewolfStats(); + if (player.mObject.mNpcStats.mWerewolfDeprecatedData) + { + saveStats(); + setWerewolfStats(); + } + else if (reader.getFormat() < 19) + { + setWerewolfStats(); + if (player.mSetWerewolfAcrobatics) + MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(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<ESM::Attribute::Length; ++i) - mSaveAttributes[i].load(esm, intFallback); - for (int i=0; i<ESM::Skill::Length; ++i) - mSaveSkills[i].load(esm, intFallback); + bool intFallback = esm.getFormat() < 11; + bool clearModified = esm.getFormat() < 17 && !mObject.mNpcStats.mIsWerewolf; + if (esm.hasMoreSubs()) + { + for (int i=0; i<ESM::Attribute::Length; ++i) + { + StatState<float> 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<ESM::Skill::Length; ++i) + { + StatState<float> 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<ESM::Attribute::Length; ++i) - mSaveAttributes[i].save(esm); - for (int i=0; i<ESM::Skill::Length; ++i) - mSaveSkills[i].save(esm); + esm.writeHNT("WWAT", mSaveAttributes); + esm.writeHNT("WWSK", mSaveSkills); } diff --git a/components/esm/player.hpp b/components/esm/player.hpp index 78bd5ab6e7..bea29cf74a 100644 --- a/components/esm/player.hpp +++ b/components/esm/player.hpp @@ -23,6 +23,7 @@ namespace ESM CellId mCellId; float mLastKnownExteriorPosition[3]; unsigned char mHasMark; + bool mSetWerewolfAcrobatics; ESM::Position mMarkedPosition; CellId mMarkedCell; std::string mBirthsign; @@ -30,8 +31,8 @@ namespace ESM int mCurrentCrimeId; int mPaidCrimeId; - StatState<float> mSaveAttributes[ESM::Attribute::Length]; - StatState<float> mSaveSkills[ESM::Skill::Length]; + float mSaveAttributes[ESM::Attribute::Length]; + float mSaveSkills[ESM::Skill::Length]; typedef std::map<std::string, std::string> 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) { |