diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8c29b221d..0d8e3d009 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -77,12 +77,12 @@ opencs_units (view/widget opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget - previewwidget terrainstorage + previewwidget ) opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright object cell + lightingbright object cell terrainstorage ) opencs_hdrs_noqt (view/render diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 152854af9..cc8279b1e 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -166,10 +166,18 @@ namespace MWMechanics { const CreatureStats& stats = actor.getClass().getCreatureStats(actor); - // Never casting racial spells (ST_Power and F_Always) - if (spell->mData.mType != ESM::Spell::ST_Spell || spell->mData.mFlags & ESM::Spell::F_Always) + if (spell->mData.mType != ESM::Spell::ST_Spell) return 0.f; + // Don't make use of racial bonus spells, like MW. Can be made optional later + if (actor.getClass().isNpc()) + { + std::string raceid = actor.get()->mBase->mRace; + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(raceid); + if (race->mPowers.exists(spell->mId)) + return 0.f; + } + if (spell->mData.mCost > stats.getMagicka().getCurrent()) return 0.f; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 35432e979..d33bb6ad1 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -292,6 +292,7 @@ namespace MWMechanics , mTarget(target) , mStack(false) , mHitPosition(0,0,0) + , mAlwaysSucceed(false) { } @@ -761,7 +762,7 @@ namespace MWMechanics int school = 0; - if (mCaster.getClass().isActor()) + if (mCaster.getClass().isActor() && !mAlwaysSucceed) { school = getSpellSchool(spell, mCaster); diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index c01fede37..395ae043b 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -68,6 +68,7 @@ namespace MWMechanics std::string mId; // ID of spell, potion, item etc std::string mSourceName; // Display name for spell, potion, etc Ogre::Vector3 mHitPosition; // Used for spawning area orb + bool mAlwaysSucceed; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false) public: CastSpell(const MWWorld::Ptr& caster, const MWWorld::Ptr& target); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index ef879a95a..0de8f3b91 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -854,6 +854,7 @@ namespace MWScript MWMechanics::CastSpell cast(ptr, target); cast.mHitPosition = Ogre::Vector3(target.getRefData().getPosition().pos); + cast.mAlwaysSucceed = true; cast.cast(spell); } }; @@ -871,6 +872,7 @@ namespace MWScript MWMechanics::CastSpell cast(ptr, ptr); cast.mHitPosition = Ogre::Vector3(ptr.getRefData().getPosition().pos); + cast.mAlwaysSucceed = true; cast.cast(spell); } }; diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 812e49a64..781bfb5d5 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -454,6 +454,7 @@ namespace MWSound while(snditer != mActiveSounds.end()) { if(snditer->second.first != MWWorld::Ptr() && + snditer->second.first.getCellRef().getRefId() != "player" && snditer->second.first.getCell() == cell) { snditer->first->stop();