diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9b371b69f..328a67ecb 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1020,12 +1020,7 @@ namespace MWWorld facedObject = getFacedObject(getMaxActivationDistance() * 50, false); else { - float telekinesisRangeBonus = - mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects() - .get(ESM::MagicEffect::Telekinesis).getMagnitude(); - telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); - - float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; + float activationDistance = getActivationDistancePlusTelekinesis(); facedObject = getFacedObject(activationDistance, true); @@ -2642,7 +2637,7 @@ namespace MWWorld // Get the target to use for "on touch" effects, using the facing direction from Head node MWWorld::Ptr target; - float distance = getMaxActivationDistance(); + float distance = getActivationDistancePlusTelekinesis(); osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3(); osg::Vec3f origin = getActorHeadTransform(actor).getTrans(); @@ -2674,11 +2669,15 @@ namespace MWWorld { target = result1.mHitObject; hitPosition = result1.mHitPos; + if (dist1 > getMaxActivationDistance() && !target.isEmpty() && (target.getClass().isActor() || !target.getClass().canBeActivated(target))) + target = NULL; } else if (result2.mHit) { target = result2.mHitObject; hitPosition = result2.mHitPointWorld; + if (dist2 > getMaxActivationDistance() && !target.isEmpty() && (target.getClass().isActor() || !target.getClass().canBeActivated(target))) + target = NULL; } // When targeting an actor that is in combat with an "on touch" spell, @@ -3011,6 +3010,18 @@ namespace MWWorld return feet * 22; } + float World::getActivationDistancePlusTelekinesis() + { + float telekinesisRangeBonus = + mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects() + .get(ESM::MagicEffect::Telekinesis).getMagnitude(); + telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); + + float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; + + return activationDistance; + } + MWWorld::Ptr World::getPlayerPtr() { return mPlayer->getPlayer(); @@ -3176,6 +3187,9 @@ namespace MWWorld if (effectIt->mRange != rangeType || (effectIt->mArea <= 0 && !ignore.isEmpty() && ignore.getClass().isActor())) continue; // Not right range type, or not area effect and hit an actor + if (effectIt->mRange == ESM::RT_Touch && (!ignore.isEmpty()) && (!ignore.getClass().isActor() && !ignore.getClass().canBeActivated(ignore))) + continue; // Don't play explosion for touch spells on non-activatable objects + // Spawn the explosion orb effect const ESM::Static* areaStatic; if (!effect->mArea.empty()) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 8774e549f..3508c0b46 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -168,6 +168,7 @@ namespace MWWorld int mDaysInPrison; float feetToGameUnits(float feet); + float getActivationDistancePlusTelekinesis(); MWWorld::ConstPtr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ); MWWorld::ConstPtr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id );