diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt
index e2cb0e5c4..e8b498de1 100644
--- a/apps/openmw/CMakeLists.txt
+++ b/apps/openmw/CMakeLists.txt
@@ -41,7 +41,7 @@ add_openmw_dir (mwscript
     locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions
     guiextensions soundextensions skyextensions statsextensions containerextensions
     aiextensions controlextensions extensions globalscripts ref dialogueextensions
-    animationextensions transformationextensions consoleextensions userextensions
+    animationextensions transformationextensions consoleextensions userextensions locals
     )
 
 add_openmw_dir (mwsound
diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp
index 5390f1602..40771af16 100644
--- a/apps/openmw/mwgui/inventorywindow.cpp
+++ b/apps/openmw/mwgui/inventorywindow.cpp
@@ -7,6 +7,8 @@
 
 #include <boost/lexical_cast.hpp>
 
+#include <components/compiler/locals.hpp>
+
 #include "../mwbase/world.hpp"
 #include "../mwbase/environment.hpp"
 #include "../mwbase/soundmanager.hpp"
@@ -240,6 +242,12 @@ namespace MWGui
             if (it != invStore.end() && *it == item)
             {
                 invStore.equip(slot, invStore.end());
+                std::string script = MWWorld::Class::get(*it).getScript(*it);
+                
+                // Unset OnPCEquip Variable on item's script, if it has a script with that variable declared
+                if(script != "")
+                    (*it).mRefData->getLocals().setVarByInt(script, "onpcequip", 0);
+                
                 return;
             }
         }
diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp
index 1fa69d1fd..4cce19b86 100644
--- a/apps/openmw/mwscript/containerextensions.cpp
+++ b/apps/openmw/mwscript/containerextensions.cpp
@@ -50,6 +50,14 @@ namespace MWScript
                     MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item);
 
                     ref.getPtr().getRefData().setCount (count);
+                    
+                    // Configure item's script variables
+                    std::string script = MWWorld::Class::get(ref.getPtr()).getScript(ref.getPtr());
+                    if (script != "")
+                    {
+                        const ESM::Script *esmscript = MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (script);
+                        ref.getPtr().getRefData().setLocals(*esmscript);
+                    }
 
                     MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());
                 }
diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp
new file mode 100644
index 000000000..53f744323
--- /dev/null
+++ b/apps/openmw/mwscript/locals.cpp
@@ -0,0 +1,41 @@
+#include "locals.hpp"
+
+#include "../mwbase/environment.hpp"
+#include "../mwbase/scriptmanager.hpp"
+#include <components/compiler/locals.hpp>
+
+namespace MWScript
+{
+    void Locals::configure (const ESM::Script& script)
+    {
+        mShorts.clear();
+        mShorts.resize (script.mData.mNumShorts, 0);
+        mLongs.clear();
+        mLongs.resize (script.mData.mNumLongs, 0);
+        mFloats.clear();
+        mFloats.resize (script.mData.mNumFloats, 0);
+    }
+        
+    bool Locals::setVarByInt(const std::string& script, const std::string& var, int val)
+    {    
+        Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
+        int index = locals.getIndex(var);
+        char type = locals.getType(var);
+        if(index != -1)
+        {
+            switch(type)
+            {
+                case 's':
+                    mShorts.at (index) = val; break;
+                
+                case 'l':
+                    mLongs.at (index) = val; break;
+                
+                case 'f':
+                    mFloats.at (index) = val; break;
+            }
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/apps/openmw/mwscript/locals.hpp b/apps/openmw/mwscript/locals.hpp
index ec02e2f12..e933c727f 100644
--- a/apps/openmw/mwscript/locals.hpp
+++ b/apps/openmw/mwscript/locals.hpp
@@ -8,21 +8,16 @@
 
 namespace MWScript
 {
-    struct Locals
+    class Locals
     {
-        std::vector<Interpreter::Type_Short> mShorts;
-        std::vector<Interpreter::Type_Integer> mLongs;
-        std::vector<Interpreter::Type_Float> mFloats;
+        public:
+            std::vector<Interpreter::Type_Short> mShorts;
+            std::vector<Interpreter::Type_Integer> mLongs;
+            std::vector<Interpreter::Type_Float> mFloats;
+            
+            void configure (const ESM::Script& script);
+            bool setVarByInt(const std::string& script, const std::string& var, int val);
         
-        void configure (const ESM::Script& script)
-        {
-            mShorts.clear();
-            mShorts.resize (script.mData.mNumShorts, 0);
-            mLongs.clear();
-            mLongs.resize (script.mData.mNumLongs, 0);
-            mFloats.clear();
-            mFloats.resize (script.mData.mNumFloats, 0);
-        }
     };
 }
 
diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp
index f3191e8bb..2d257aa61 100644
--- a/apps/openmw/mwworld/actionequip.cpp
+++ b/apps/openmw/mwworld/actionequip.cpp
@@ -4,6 +4,8 @@
 #include "../mwbase/world.hpp"
 #include "../mwbase/windowmanager.hpp"
 
+#include <components/compiler/locals.hpp>
+
 #include "inventorystore.hpp"
 #include "player.hpp"
 #include "class.hpp"
@@ -35,6 +37,8 @@ namespace MWWorld
 
         std::string npcRace = actor.get<ESM::NPC>()->mBase->mRace;
 
+        bool equipped = false;
+
         // equip the item in the first free slot
         for (std::vector<int>::const_iterator slot=slots.first.begin();
             slot!=slots.first.end(); ++slot)
@@ -91,6 +95,7 @@ namespace MWWorld
             if (slot == --slots.first.end())
             {
                 invStore.equip(*slot, it);
+                equipped = true;
                 break;
             }
 
@@ -98,8 +103,15 @@ namespace MWWorld
             {
                 // slot is not occupied
                 invStore.equip(*slot, it);
+                equipped = true;
                 break;
             }
         }
+
+        std::string script = MWWorld::Class::get(*it).getScript(*it);
+        
+        /* Set OnPCEquip Variable on item's script, if the player is equipping it, and it has a script with that variable declared */
+        if(equipped && actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() && script != "")
+            (*it).mRefData->getLocals().setVarByInt(script, "onpcequip", 1);
     }
 }
diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp
index bca4073b5..eb2a14d5b 100644
--- a/apps/openmw/mwworld/containerstore.cpp
+++ b/apps/openmw/mwworld/containerstore.cpp
@@ -8,9 +8,11 @@
 #include <boost/algorithm/string.hpp>
 
 #include <components/esm/loadcont.hpp>
+#include <components/compiler/locals.hpp>
 
 #include "../mwbase/environment.hpp"
 #include "../mwbase/world.hpp"
+#include "../mwbase/scriptmanager.hpp"
 
 #include "manualref.hpp"
 #include "refdata.hpp"
@@ -83,9 +85,14 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
         CellStore *cell;
 
         Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
-        // Items in players inventory have cell set to 0, so their scripts will never be removed
+        
         if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
-            cell = 0;
+        {
+            cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed
+           
+            // Set OnPCAdd special variable, if it is declared 
+            item.mRefData->getLocals().setVarByInt(script, "onpcadd", 1);
+        }
         else
             cell = player.getCell();
 
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index 24d139b37..2926b76f8 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -2,11 +2,13 @@
 
 #include <components/bsa/bsa_archive.hpp>
 #include <components/files/collections.hpp>
+#include <components/compiler/locals.hpp>
 
 #include "../mwbase/environment.hpp"
 #include "../mwbase/soundmanager.hpp"
 #include "../mwbase/mechanicsmanager.hpp"
 #include "../mwbase/windowmanager.hpp"
+#include "../mwbase/scriptmanager.hpp"
 
 #include "../mwrender/sky.hpp"
 #include "../mwrender/player.hpp"
@@ -694,10 +696,11 @@ namespace MWWorld
         bool isPlayer = ptr == mPlayer->getPlayer();
         bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
         
-        removeContainerScripts(ptr);
 
         if (*currCell != newCell)
         {
+        removeContainerScripts(ptr);
+
             if (isPlayer)
                 if (!newCell.isExterior())
                     changeToInteriorCell(Misc::StringUtils::lowerCase(newCell.mCell->mName), pos);
@@ -1270,6 +1273,15 @@ namespace MWWorld
         mRendering->toggleWater();
     }
 
+    void World::PCDropped (const Ptr& item)
+    {
+        std::string script = MWWorld::Class::get(item).getScript(item);
+        
+        // Set OnPCDrop Variable on item's script, if it has a script with that variable declared 
+        if(script != "")
+            item.mRefData->getLocals().setVarByInt(script, "onpcdrop", 1);
+    }
+
     bool World::placeObject (const Ptr& object, float cursorX, float cursorY)
     {
         std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
@@ -1292,9 +1304,10 @@ namespace MWWorld
         pos.pos[1] = -result.second[2];
         pos.pos[2] = result.second[1];
 
-        copyObjectToCell(object, *cell, pos);
+        Ptr dropped = copyObjectToCell(object, *cell, pos);
+        PCDropped(dropped);
         object.getRefData().setCount(0);
-
+        
         return true;
     }
 
@@ -1309,8 +1322,8 @@ namespace MWWorld
         return true;
     }
 
-    void
-    World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos)
+    
+    Ptr World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos)
     {
         /// \todo add searching correct cell for position specified
         MWWorld::Ptr dropped =
@@ -1334,6 +1347,8 @@ namespace MWWorld
             }
             addContainerScripts(dropped, &cell);
         }
+
+        return dropped;
     }
 
     void World::dropObjectOnGround (const Ptr& actor, const Ptr& object)
@@ -1354,7 +1369,9 @@ namespace MWWorld
             mPhysics->castRay(orig, dir, len);
         pos.pos[2] = hit.second.z;
 
-        copyObjectToCell(object, *cell, pos);
+        Ptr dropped = copyObjectToCell(object, *cell, pos);
+        if(actor == mPlayer->getPlayer()) // Only call if dropped by player
+            PCDropped(dropped);
         object.getRefData().setCount(0);
     }
 
diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp
index fa5b41038..e8efb6a67 100644
--- a/apps/openmw/mwworld/worldimp.hpp
+++ b/apps/openmw/mwworld/worldimp.hpp
@@ -91,8 +91,8 @@ namespace MWWorld
             bool moveObjectImp (const Ptr& ptr, float x, float y, float z);
             ///< @return true if the active cell (cell player is in) changed
 
-            virtual void
-            copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos);
+            
+            Ptr copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos);
 
             void updateWindowManager ();
             void performUpdateSceneQueries ();
@@ -107,6 +107,7 @@ namespace MWWorld
 
             void removeContainerScripts(const Ptr& reference);
             void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell);
+            void PCDropped (const Ptr& item);
 
         public: