From cb621939fdbb9c54390deb7ec6b8713fb274ae33 Mon Sep 17 00:00:00 2001
From: Allofich <rickywd@gmail.com>
Date: Thu, 7 Jul 2016 04:03:56 +0900
Subject: [PATCH] Streamline trap code

---
 apps/openmw/mwworld/action.cpp     |  6 +++---
 apps/openmw/mwworld/action.hpp     |  2 +-
 apps/openmw/mwworld/actiontrap.cpp | 28 ++++++++++------------------
 apps/openmw/mwworld/actiontrap.hpp |  8 ++------
 apps/openmw/mwworld/worldimp.cpp   |  7 +------
 5 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp
index 748e30ceb..e76ff8105 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)
+void MWWorld::Action::execute (const Ptr& actor, float distanceToFacedObject)
 {
     if(!mSoundId.empty())
     {
@@ -41,8 +41,8 @@ void MWWorld::Action::execute (const Ptr& actor, float distanceToObject)
                 );
         }
     }
-    if (distanceToObject != 0)
-        executeImp(actor, distanceToObject);
+    if (mTarget.getCellRef().getTrap() != "")
+        executeImp(actor, distanceToFacedObject);
     else
         executeImp(actor);
 }
diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp
index e363927ff..d61e72551 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);
+            void execute (const Ptr& actor, float distanceToObject = -1);
 
             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 86e232302..991e05313 100644
--- a/apps/openmw/mwworld/actiontrap.cpp
+++ b/apps/openmw/mwworld/actiontrap.cpp
@@ -7,36 +7,28 @@
 
 namespace MWWorld
 {
-    // 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 actorPosition(actor.getRefData().getPosition().asVec3());
         osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3());
-        float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance();
+        float trapRange = 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 activation distance as the trap range.
 
-        if (distance < activationDistance) // actor activated object within range of trap
-            executeImp(actor);
-        else // actor activated object outside range of trap
+        if (distance > trapRange) // actor activated object outside range of trap
         {
             MWMechanics::CastSpell cast(mTrapSource, mTrapSource);
             cast.mHitPosition = trapPosition;
+            cast.cast(mSpellId);    
+        }
+        else // actor activated object within range of trap
+        {
+            MWMechanics::CastSpell cast(mTrapSource, actor);
+            cast.mHitPosition = actorPosition;
             cast.cast(mSpellId);
-            mTrapSource.getCellRef().setTrap("");
         }   
+        mTrapSource.getCellRef().setTrap("");
     }
 }
diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp
index 73a43b354..5fb76eb5d 100644
--- a/apps/openmw/mwworld/actiontrap.hpp
+++ b/apps/openmw/mwworld/actiontrap.hpp
@@ -13,11 +13,7 @@ namespace MWWorld
             std::string mSpellId;
             MWWorld::Ptr mTrapSource;
 
-            /// 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);
+            virtual void executeImp (const Ptr& actor, float distanceToObject = -1);
 
         public:
 
@@ -25,7 +21,7 @@ namespace MWWorld
             /// @param actor Actor that activated the trap
             /// @param trapSource
             ActionTrap (const Ptr& actor, const std::string& spellId, const Ptr& trapSource)
-                : Action(false, actor), mSpellId(spellId), mTrapSource(trapSource) {}
+                : Action(false, trapSource), mSpellId(spellId), mTrapSource(trapSource) {}
     };
 }
 
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index 869ccdfe5..3b53e8cac 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -3205,12 +3205,7 @@ namespace MWWorld
         if (object.getRefData().activate())
         {
             boost::shared_ptr<MWWorld::Action> action = (object.getClass().activate(object, actor));
-            // 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);
+            action->execute (actor, mDistanceToFacedObject);
         }
     }