diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp
index 49ac5bc15..29f326a1b 100644
--- a/apps/openmw/mwbase/world.hpp
+++ b/apps/openmw/mwbase/world.hpp
@@ -398,8 +398,9 @@ namespace MWBase
 
             /// open or close a non-teleport door (depending on current state)
             virtual void activateDoor(const MWWorld::Ptr& door) = 0;
-            /// open or close a non-teleport door as specified
-            virtual void activateDoor(const MWWorld::Ptr& door, bool open) = 0;
+            /// update movement state of a non-teleport door as specified
+            /// @param state see MWClass::setDoorState
+            virtual void activateDoor(const MWWorld::Ptr& door, int state) = 0;
 
             virtual bool getPlayerStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if the player is standing on \a object
             virtual bool getActorStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if any actor is standing on \a object
diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp
index e75eda726..5e7534660 100644
--- a/apps/openmw/mwclass/door.cpp
+++ b/apps/openmw/mwclass/door.cpp
@@ -62,7 +62,7 @@ namespace MWClass
             const DoorCustomData& customData = dynamic_cast<const DoorCustomData&>(*ptr.getRefData().getCustomData());
             if (customData.mDoorState > 0)
             {
-                MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState == 1 ? true : false);
+                MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState);
             }
         }
     }
diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp
index a4c74be6b..4e0257d82 100644
--- a/apps/openmw/mwscript/miscextensions.cpp
+++ b/apps/openmw/mwscript/miscextensions.cpp
@@ -147,6 +147,14 @@ namespace MWScript
                     }
 
                     ptr.getClass().lock (ptr, lockLevel);
+
+                    // Instantly reset door to closed state
+                    // This is done when using Lock in scripts, but not when using Lock spells.
+                    if (ptr.getTypeName() == typeid(ESM::Door).name())
+                    {
+                        MWBase::Environment::get().getWorld()->activateDoor(ptr, 0);
+                        MWBase::Environment::get().getWorld()->localRotateObject(ptr, 0, 0, 0);
+                    }
                 }
         };
 
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index 80ff0fdfa..fb520dae4 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -1123,6 +1123,9 @@ namespace MWWorld
 
         ptr.getRefData().setPosition(pos);
 
+        if(ptr.getRefData().getBaseNode() == 0)
+            return;
+
         if (ptr.getClass().isActor())
             mWorldScene->updateObjectRotation(ptr);
         else
@@ -1131,19 +1134,19 @@ namespace MWWorld
 
     void World::localRotateObject (const Ptr& ptr, float x, float y, float z)
     {
+        LocalRotation rot = ptr.getRefData().getLocalRotation();
+        rot.rot[0]=Ogre::Degree(x).valueRadians();
+        rot.rot[1]=Ogre::Degree(y).valueRadians();
+        rot.rot[2]=Ogre::Degree(z).valueRadians();
+
+        wrap(rot.rot[0]);
+        wrap(rot.rot[1]);
+        wrap(rot.rot[2]);
+
+        ptr.getRefData().setLocalRotation(rot);
+
         if (ptr.getRefData().getBaseNode() != 0)
         {
-            LocalRotation rot = ptr.getRefData().getLocalRotation();
-            rot.rot[0]=Ogre::Degree(x).valueRadians();
-            rot.rot[1]=Ogre::Degree(y).valueRadians();
-            rot.rot[2]=Ogre::Degree(z).valueRadians();
-
-            wrap(rot.rot[0]);
-            wrap(rot.rot[1]);
-            wrap(rot.rot[2]);
-
-            ptr.getRefData().setLocalRotation(rot);
-
             mWorldScene->updateObjectLocalRotation(ptr);
         }
     }
@@ -1983,11 +1986,12 @@ namespace MWWorld
         mDoorStates[door] = state;
     }
 
-    void World::activateDoor(const Ptr &door, bool open)
+    void World::activateDoor(const Ptr &door, int state)
     {
-        int state = open ? 1 : 2;
         door.getClass().setDoorState(door, state);
         mDoorStates[door] = state;
+        if (state == 0)
+            mDoorStates.erase(door);
     }
 
     bool World::getPlayerStandingOn (const MWWorld::Ptr& object)
diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp
index 08d7eb42d..dda442963 100644
--- a/apps/openmw/mwworld/worldimp.hpp
+++ b/apps/openmw/mwworld/worldimp.hpp
@@ -473,8 +473,9 @@ namespace MWWorld
             /// open or close a non-teleport door (depending on current state)
             virtual void activateDoor(const MWWorld::Ptr& door);
 
-            /// open or close a non-teleport door as specified
-            virtual void activateDoor(const MWWorld::Ptr& door, bool open);
+            /// update movement state of a non-teleport door as specified
+            /// @param state see MWClass::setDoorState
+            virtual void activateDoor(const MWWorld::Ptr& door, int state);
 
             virtual bool getPlayerStandingOn (const MWWorld::Ptr& object); ///< @return true if the player is standing on \a object
             virtual bool getActorStandingOn (const MWWorld::Ptr& object); ///< @return true if any actor is standing on \a object