From e32f38b939dbb8470a598d05a24f8bc310008a38 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 21 Mar 2018 00:19:44 +0300 Subject: [PATCH 01/11] Allow jumping when you're stuck on a slope (fixes #4221) --- apps/openmw/mwphysics/physicssystem.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index f3c34bc4e..77e836789 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -308,6 +308,7 @@ namespace MWPhysics float swimlevel = waterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale); ActorTracer tracer; + osg::Vec3f inertia = physicActor->getInertialForce(); osg::Vec3f velocity; @@ -320,10 +321,11 @@ namespace MWPhysics { velocity = (osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1))) * movement; - if (velocity.z() > 0.f && physicActor->getOnGround() && !physicActor->getOnSlope()) + if ((velocity.z() > 0.f && physicActor->getOnGround() && !physicActor->getOnSlope()) + || (velocity.z() > 0.f && velocity.z() + inertia.z() <= -velocity.z() && physicActor->getOnSlope())) inertia = velocity; - else if(!physicActor->getOnGround() || physicActor->getOnSlope()) - velocity = velocity + physicActor->getInertialForce(); + else if (!physicActor->getOnGround() || physicActor->getOnSlope()) + velocity = velocity + inertia; } // dead actors underwater will float to the surface, if the CharacterController tells us to do so From 1b9edbe119a16bb132d75380b62e3f4e0d02597c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 2 May 2018 14:13:49 +0400 Subject: [PATCH 02/11] Add unequip animation during stance switching (bug #4327) --- apps/openmw/mwmechanics/character.cpp | 93 +++++++++++++++++---------- apps/openmw/mwmechanics/character.hpp | 1 + 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 68dc17915..a0aad8b1b 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -749,6 +749,7 @@ void CharacterController::playRandomDeath(float startpoint) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim) : mPtr(ptr) + , mWeapon(MWWorld::Ptr()) , mAnimation(anim) , mIdleState(CharState_None) , mMovementState(CharState_None) @@ -1156,17 +1157,26 @@ bool CharacterController::updateWeaponState() const bool isWerewolf = cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf(); - std::string soundid; + std::string upSoundId; + std::string downSoundId; if (mPtr.getClass().hasInventoryStore(mPtr)) { MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype); - if(weapon != inv.end() && !(weaptype == WeapType_None && mWeaponType == WeapType_Spell)) - { - soundid = (weaptype == WeapType_None) ? - weapon->getClass().getDownSoundId(*weapon) : - weapon->getClass().getUpSoundId(*weapon); - } + MWWorld::ContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype); + if(stats.getDrawState() == DrawState_Spell) + weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + + if(weapon != inv.end() && mWeaponType != WeapType_HandToHand && weaptype > WeapType_HandToHand && weaptype < WeapType_Spell) + upSoundId = weapon->getClass().getUpSoundId(*weapon); + + if(weapon != inv.end() && mWeaponType > WeapType_HandToHand && mWeaponType < WeapType_Spell) + downSoundId = weapon->getClass().getDownSoundId(*weapon); + + // weapon->HtH switch: weapon is empty already, so we need to take sound from previous weapon + if(weapon == inv.end() && !mWeapon.isEmpty() && weaptype == WeapType_HandToHand && mWeaponType != WeapType_Spell) + downSoundId = mWeapon.getClass().getDownSoundId(mWeapon); + + mWeapon = weapon != inv.end() ? *weapon : MWWorld::Ptr(); } MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon); @@ -1181,34 +1191,51 @@ bool CharacterController::updateWeaponState() if(weaptype != mWeaponType && !isKnockedOut() && !isKnockedDown() && !isRecovery()) { - forcestateupdate = true; - - mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype)); - std::string weapgroup; - if(weaptype == WeapType_None) + if ((!isWerewolf || mWeaponType != WeapType_Spell) + && mUpperBodyState != UpperCharState_UnEquipingWeap + && !isStillWeapon) { - if (!isWerewolf || mWeaponType != WeapType_Spell) + // Note: we do not disable unequipping animation automatically to avoid body desync + getWeaponGroup(mWeaponType, weapgroup); + mAnimation->play(weapgroup, priorityWeapon, + MWRender::Animation::BlendMask_All, false, + 1.0f, "unequip start", "unequip stop", 0.0f, 0); + mUpperBodyState = UpperCharState_UnEquipingWeap; + + if(!downSoundId.empty()) { - getWeaponGroup(mWeaponType, weapgroup); - mAnimation->play(weapgroup, priorityWeapon, - MWRender::Animation::BlendMask_All, true, - 1.0f, "unequip start", "unequip stop", 0.0f, 0); - mUpperBodyState = UpperCharState_UnEquipingWeap; + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->playSound3D(mPtr, downSoundId, 1.0f, 1.0f); } } - else + + float complete; + bool animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); + if (!animPlaying || complete >= 1.0f) { + mUpperBodyState = UpperCharState_Nothing; + forcestateupdate = true; + mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype)); + getWeaponGroup(weaptype, weapgroup); mAnimation->setWeaponGroup(weapgroup); if (!isStillWeapon) { - mAnimation->showWeapons(false); - mAnimation->play(weapgroup, priorityWeapon, - MWRender::Animation::BlendMask_All, true, - 1.0f, "equip start", "equip stop", 0.0f, 0); - mUpperBodyState = UpperCharState_EquipingWeap; + if (weaptype == WeapType_None) + { + // Disable current weapon animation manually + mAnimation->disable(mCurrentWeapon); + } + else + { + mAnimation->showWeapons(false); + mAnimation->play(weapgroup, priorityWeapon, + MWRender::Animation::BlendMask_All, true, + 1.0f, "equip start", "equip stop", 0.0f, 0); + mUpperBodyState = UpperCharState_EquipingWeap; + } } if(isWerewolf) @@ -1221,16 +1248,16 @@ bool CharacterController::updateWeaponState() sndMgr->playSound3D(mPtr, sound->mId, 1.0f, 1.0f); } } - } - if(!soundid.empty() && !isStillWeapon) - { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - sndMgr->playSound3D(mPtr, soundid, 1.0f, 1.0f); - } + mWeaponType = weaptype; + getWeaponGroup(mWeaponType, mCurrentWeapon); - mWeaponType = weaptype; - getWeaponGroup(mWeaponType, mCurrentWeapon); + if(!upSoundId.empty() && !isStillWeapon) + { + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f); + } + } } if(isWerewolf) diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index cab51b82f..a172620b9 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -152,6 +152,7 @@ struct WeaponInfo; class CharacterController : public MWRender::Animation::TextKeyListener { MWWorld::Ptr mPtr; + MWWorld::Ptr mWeapon; MWRender::Animation *mAnimation; struct AnimationQueueEntry From 6eb531c6ace5411767ede50d4f1eec478a927533 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 7 Jun 2018 16:22:52 +0400 Subject: [PATCH 03/11] Add missing changelog entries --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cbef559d..3b38b6bde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ 0.45.0 ------ + Bug #2835: Player able to slowly move when overencumbered Bug #4293: Faction members are not aware of faction ownerships in barter + Bug #4327: Missing animations during spell/weapon stance switching Bug #4426: RotateWorld behavior is incorrect Bug #4433: Guard behaviour is incorrect with Alarm = 0 From a1ab1dc7fe19b231de3629cbaeb9467a2b9300e5 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 7 Jun 2018 15:28:45 +0100 Subject: [PATCH 04/11] Add easily understood error messages to the prebuild script instead of vague/silent failures. --- CI/before_script.msvc.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 16def0f8c..dd8d830b8 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -1,5 +1,23 @@ #!/bin/bash +MISSINGTOOLS=0 + +command -v 7z >/dev/null 2>&1 || { echo "Error: 7z (7zip) is not on the path."; MISSINGTOOLS=1; } +command -v cmake >/dev/null 2>&1 || { echo "Error: cmake (CMake) is not on the path."; MISSINGTOOLS=1; } + +if [ $MISSINGTOOLS -ne 0 ]; then + exit 1 +fi + +WORKINGDIR="$(pwd)" +case "$WORKINGDIR" in + *[[:space:]]*) + echo "Error: Working directory contains spaces." + exit 1 + ;; +esac + + set -euo pipefail APPVEYOR=${APPVEYOR:-} From 02f1f712219544e1e9a110492794c88466d0effd Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 7 Jun 2018 18:42:09 +0400 Subject: [PATCH 05/11] Use link to OpenMW Wiki page instead of direct NifSkope page --- docs/source/reference/modding/convert_bump_mapped_mods.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/source/reference/modding/convert_bump_mapped_mods.rst b/docs/source/reference/modding/convert_bump_mapped_mods.rst index 1891b5c4d..421fa67a7 100644 --- a/docs/source/reference/modding/convert_bump_mapped_mods.rst +++ b/docs/source/reference/modding/convert_bump_mapped_mods.rst @@ -22,7 +22,7 @@ General introduction to normal map conversion This page has general information and tutorials on how normal mapping works in OpenMW and how you can make mods using the old fake normal mapping technique (such as `Netch Bump mapped`_ and `Hlaalu Bump mapped`_, and maybe the most (in)famous one to give shiny rocks in OpenMW, the mod `On the Rocks`_!, featured in MGSO and Morrowind Rebirth) work in OpenMW. -*Note:* The conversion made in the `Converting Apel's Various Things - Sacks`_-part of this tutorial require the use of the application NifSkope. There are binaries available for Windows, but not for Mac or Linux. Reports say that NifSkope versions 1.X will compile on Linux as long as you have Qt packages installed, while the later 2.X versions will not compile. +*Note:* The conversion made in the `Converting Apel's Various Things - Sacks`_-part of this tutorial require the use of the application NifSkope_. *Another note:* I will use the terms bump mapping and normal mapping simultaneously. Normal mapping is one form of bump mapping. In other words, normal mapping is bump mapping, but bump mapping isn't necessarily normal mapping. There are several techniques for bump mapping, and normal mapping is the most common one today. @@ -160,8 +160,6 @@ Converting Apel's Various Things - Sacks In part one of this tutorial, we converted a mod that only included modified Morrowind model (``.nif``) files so that the normal maps could be loaded in Morrowind with MCP. We ignored those model files since they are not needed with OpenMW. In this tutorial however, we will convert a mod that includes new, custom made models. In other words, we cannot just ignore those files this time. -Before we begin, you need to know that unless you want to build the NifSkope application from source yourself, you will be needing a Windows OS to do this part, since the application only has binaries available for Windows. - Tutorial - MCP, Part 2 ********************** @@ -196,7 +194,7 @@ Since these models have one or two textures applied to them, the fix was not tha .. _`Multiple data folders`: https://wiki.openmw.org/index.php?title=Mod_installation .. _`Various Things - Sacks`: https://www.nexusmods.com/morrowind/mods/42558/? .. _Lead: https://imgur.com/bwpcYlc -.. _NifSkope: http://niftools.sourceforge.net/wiki/NifSkope +.. _NifSkope: https://wiki.openmw.org/index.php?title=Tools#NifSkope .. _Blocks: https://imgur.com/VmQC0WG .. _`no longer have shiny models`: https://imgur.com/vu1k7n1 .. _`we are done`: https://imgur.com/yyZxlTw From 937cbfa0a12ae3de5de08198472225cc1a3082bb Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Thu, 7 Jun 2018 17:09:39 +0200 Subject: [PATCH 06/11] small commit to rigger AV --- CI/before_script.msvc.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index dd8d830b8..38b304bf9 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -17,7 +17,6 @@ case "$WORKINGDIR" in ;; esac - set -euo pipefail APPVEYOR=${APPVEYOR:-} From 57b2948ee1f6a961cf44c4e5fd73dd82ea75c63b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 7 Jun 2018 20:34:34 +0400 Subject: [PATCH 07/11] Update AppVeyor build status link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d6a3323a1..cc600fdbe 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ OpenMW ====== -[![Build Status](https://api.travis-ci.org/OpenMW/openmw.svg)](https://travis-ci.org/OpenMW/openmw) [![Build status](https://ci.appveyor.com/api/projects/status/e6bqw8oouy8ufd46?svg=true)](https://ci.appveyor.com/project/scrawl/openmw) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3740/badge.svg)](https://scan.coverity.com/projects/3740) +[![Build Status](https://api.travis-ci.org/OpenMW/openmw.svg)](https://travis-ci.org/OpenMW/openmw) [![Build status](https://ci.appveyor.com/api/projects/status/github/openmw/openmw?svg=true)](https://ci.appveyor.com/project/psi29a/openmw) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3740/badge.svg)](https://scan.coverity.com/projects/3740) OpenMW is a recreation of the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. From 53e888236636d544bdc15353546aa102672bd6ca Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 8 Jun 2018 11:44:49 +0200 Subject: [PATCH 08/11] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cbef559d..d88fce1d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 0.45.0 ------ + Bug #4221: Characters get stuck in V-shaped terrain Bug #4293: Faction members are not aware of faction ownerships in barter Bug #4426: RotateWorld behavior is incorrect Bug #4433: Guard behaviour is incorrect with Alarm = 0 From 11103211c5e6a875e8d18743df71875b3dff087a Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 8 Jun 2018 14:56:09 +0300 Subject: [PATCH 09/11] Make Goodbye and Choice choices mutually exclusive --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index de9ca83ca..da6e80e79 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -431,9 +431,11 @@ namespace MWDialogue void DialogueManager::addChoice (const std::string& text, int choice) { - mIsInChoice = true; - - mChoices.push_back(std::make_pair(text, choice)); + if (!mGoodbye) + { + mIsInChoice = true; + mChoices.push_back(std::make_pair(text, choice)); + } } const std::vector >& DialogueManager::getChoices() @@ -448,8 +450,8 @@ namespace MWDialogue void DialogueManager::goodbye() { - mIsInChoice = false; - mGoodbye = true; + if (!mIsInChoice) + mGoodbye = true; } void DialogueManager::persuade(int type, ResponseCallback* callback) From 0db702dfa78ca04423bafbe8d8243695206a9d10 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 8 Jun 2018 15:05:00 +0300 Subject: [PATCH 10/11] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d88fce1d0..35d8ac4de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Bug #4293: Faction members are not aware of faction ownerships in barter Bug #4426: RotateWorld behavior is incorrect Bug #4433: Guard behaviour is incorrect with Alarm = 0 + Bug #4443: Goodbye option and dialogue choices are not mutually exclusive 0.44.0 ------ From fea34bd73f8302071d248f6f2fb199eb7afd3269 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 30 May 2018 08:54:43 +0400 Subject: [PATCH 11/11] Added support for per-group animation files --- CHANGELOG.md | 1 + apps/openmw/mwrender/animation.cpp | 41 +++++++++++++++++++ apps/openmw/mwrender/animation.hpp | 5 +++ .../reference/modding/settings/game.rst | 13 ++++++ files/settings-default.cfg | 3 ++ 5 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d88fce1d0..ff3feec75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Bug #4293: Faction members are not aware of faction ownerships in barter Bug #4426: RotateWorld behavior is incorrect Bug #4433: Guard behaviour is incorrect with Alarm = 0 + Feature #4444: Per-group KF-animation files support 0.44.0 ------ diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 1bd839ead..3ccc06665 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -31,6 +31,8 @@ #include #include +#include + #include #include "../mwbase/environment.hpp" @@ -466,6 +468,8 @@ namespace MWRender mAnimationTimePtr[i].reset(new AnimationTime); mLightListCallback = new SceneUtil::LightListCallback; + + mUseAdditionalSources = Settings::Manager::getBool ("use additional anim sources", "Game"); } Animation::~Animation() @@ -536,6 +540,35 @@ namespace MWRender return mKeyframes->mTextKeys; } + void Animation::loadAllAnimationsInFolder(const std::string &model, const std::string &baseModel) + { + const std::map& index = mResourceSystem->getVFS()->getIndex(); + + std::string animationPath = model; + if (animationPath.find("meshes") == 0) + { + animationPath.replace(0, 6, "animations"); + } + animationPath.replace(animationPath.size()-3, 3, "/"); + + mResourceSystem->getVFS()->normalizeFilename(animationPath); + + std::map::const_iterator found = index.lower_bound(animationPath); + while (found != index.end()) + { + const std::string& name = found->first; + if (name.size() >= animationPath.size() && name.substr(0, animationPath.size()) == animationPath) + { + size_t pos = name.find_last_of('.'); + if (pos != std::string::npos && name.compare(pos, name.size()-pos, ".kf") == 0) + addSingleAnimSource(name, baseModel); + } + else + break; + ++found; + } + } + void Animation::addAnimSource(const std::string &model, const std::string& baseModel) { std::string kfname = model; @@ -546,6 +579,14 @@ namespace MWRender else return; + addSingleAnimSource(kfname, baseModel); + + if (mUseAdditionalSources) + loadAllAnimationsInFolder(kfname, baseModel); + } + + void Animation::addSingleAnimSource(const std::string &kfname, const std::string& baseModel) + { if(!mResourceSystem->getVFS()->exists(kfname)) return; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index cff98a4b7..43a626899 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -275,6 +275,8 @@ protected: osg::ref_ptr mLightListCallback; + bool mUseAdditionalSources; + const NodeMap& getNodeMap() const; /* Sets the appropriate animations on the bone groups based on priority. @@ -309,12 +311,15 @@ protected: */ void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature); + void loadAllAnimationsInFolder(const std::string &model, const std::string &baseModel); + /** Adds the keyframe controllers in the specified model as a new animation source. * @note Later added animation sources have the highest priority when it comes to finding a particular animation. * @param model The file to add the keyframes for. Note that the .nif file extension will be replaced with .kf. * @param baseModel The filename of the mObjectRoot, only used for error messages. */ void addAnimSource(const std::string &model, const std::string& baseModel); + void addSingleAnimSource(const std::string &model, const std::string& baseModel); /** Adds an additional light to the given node using the specified ESM record. */ void addExtraLight(osg::ref_ptr parent, const ESM::Light *light); diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index 7a9b89295..416f1bc1a 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -157,3 +157,16 @@ Otherwise they wait for the enemies or the player to do an attack first. Please note this setting has not been extensively tested and could have side effects with certain quests. This setting can only be configured by editing the settings configuration file. + +use additional anim sources +--------------------------- + +:Type: boolean +:Range: True/False +:Default: False + +Allow to load additional animation sources when enabled. +For example, if the main animation mesh has name Meshes/x.nif, an engine will load all KF-files from Animations/x folder and its child folders. +Can be useful if you want to use several animation replacers without merging them. +Attention: animations from AnimKit have own format and are not supposed to be directly loaded in-game! +This setting can only be configured by editing the settings configuration file. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index b10b91eb1..09283bfc9 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -219,6 +219,9 @@ can loot during death animation = true # Makes the value of filled soul gems dependent only on soul magnitude (with formula from the Morrowind Code Patch) rebalance soul gem values = false +# Allow to load per-group KF-files from Animations folder +use additional anim sources = false + [General] # Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16).