diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index 028080d7af..748e30cebc 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -17,7 +17,7 @@ MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSo MWWorld::Action::~Action() {} -void MWWorld::Action::execute (const Ptr& actor, float distanceToObject, bool useDistance) +void MWWorld::Action::execute (const Ptr& actor, float distanceToObject) { if(!mSoundId.empty()) { @@ -41,7 +41,7 @@ void MWWorld::Action::execute (const Ptr& actor, float distanceToObject, bool us ); } } - if (useDistance) + if (distanceToObject != 0) executeImp(actor, distanceToObject); else executeImp(actor); diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index 39df539cd3..e363927ff7 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -37,7 +37,7 @@ namespace MWWorld virtual bool isNullAction() { return false; } ///< Is running this action a no-op? (default false) - void execute (const Ptr& actor, float distanceToObject = 0, bool useDistance = false); + void execute (const Ptr& actor, float distanceToObject = 0); void setSound (const std::string& id); void setSoundOffset(float offset); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index a8b937c0a0..86e2323022 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -7,30 +7,36 @@ namespace MWWorld { - void ActionTrap::executeImp(const Ptr &actor, float distance) + // actor activated object without telekinesis, so trap will hit + void ActionTrap::executeImp(const Ptr &actor) { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); + + MWMechanics::CastSpell cast(mTrapSource, actor); + cast.mHitPosition = actorPosition; + cast.cast(mSpellId); + + mTrapSource.getCellRef().setTrap(""); + } + + // actor activated object with telekinesis, so trap may or may not hit + void ActionTrap::executeImp(const Ptr &actor, float distance) + { osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); // Note: can't just detonate the trap at the trapped object's location and use the blast // radius, because for most trap spells this is 1 foot, much less than the activation distance. - // Using the activation distance as the trap range. + // Using activation distance as the trap range. - if (distance < activationDistance) + if (distance < activationDistance) // actor activated object within range of trap + executeImp(actor); + else // actor activated object outside range of trap { - // actor activated object within range of trap - MWMechanics::CastSpell cast(mTrapSource, actor); - cast.mHitPosition = actorPosition; - cast.cast(mSpellId); - } - else - { - // actor activated object outside range of trap MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; cast.cast(mSpellId); - } - mTrapSource.getCellRef().setTrap(""); + mTrapSource.getCellRef().setTrap(""); + } } } diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 7fd6f2bccb..73a43b3545 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -13,7 +13,11 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - virtual void executeImp (const Ptr& actor, float distance); + /// Activating trapped object without telekinesis active or within trap range + virtual void executeImp (const Ptr& actor); + + /// Activating trapped object with telekinesis active + virtual void executeImp (const Ptr& actor, float distanceToObject); public: diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e54c75afe9..a6ea308e8a 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1036,7 +1036,6 @@ namespace MWWorld } mDistanceToFacedObject = distanceToObject; - mFacedObject = facedObject; return facedObject; } @@ -3213,19 +3212,11 @@ namespace MWWorld if (object.getRefData().activate()) { boost::shared_ptr action = (object.getClass().activate(object, actor)); - if (object.getCellRef().getTrap() != "") - { - // For the distance check to a trapped object, use the raycast-derived distance if we have it - if (actor == getPlayerPtr() && (object == mFacedObject)) - action->execute (actor, mDistanceToFacedObject, true); - else // Otherwise use a position comparison - { - osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); - osg::Vec3f objectPosition(object.getRefData().getPosition().asVec3()); - action->execute (actor, (objectPosition - actorPosition).length(), true); - } - } - else + // If the player is opening a trap with telekinesis on, use the raycast-derived distance to check if the trap should hit + if (object.getCellRef().getTrap() != "" && actor == getPlayerPtr() && mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects() + .get(ESM::MagicEffect::Telekinesis).getMagnitude() > 0) + action->execute (actor, mDistanceToFacedObject); + else // Otherwise just activate, and if it's trapped it will always hit action->execute (actor); } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index b1cc081203..64160018f5 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -158,7 +158,6 @@ namespace MWWorld float mSwimHeightScale; float mDistanceToFacedObject; - MWWorld::Ptr mFacedObject; bool isUnderwater(const MWWorld::ConstPtr &object, const float heightRatio) const; ///< helper function for implementing isSwimming(), isSubmerged(), isWading()