From 56b6a7ada490662c4b5af5e98aace2d1180920f1 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 9 Sep 2019 22:29:59 +0200 Subject: [PATCH 1/4] Fix #5155 --- CHANGELOG.md | 1 + apps/openmw/mwclass/container.cpp | 3 ++- apps/openmw/mwmechanics/security.cpp | 3 +-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa84ec10a..32254d65b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,7 @@ Bug #5134: Doors rotation by "Lock" console command is inconsistent Bug #5137: Textures with Clamp Mode set to Clamp instead of Wrap are too dark outside the boundaries Bug #5149: Failing lock pick attempts isn't always a crime + Bug #5155: Shouldn't be able to magically lock organic containers Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 2b36f2339..b7da1960e 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -321,7 +321,8 @@ namespace MWClass bool Container::canLock(const MWWorld::ConstPtr &ptr) const { - return true; + const MWWorld::LiveCellRef *ref = ptr.get(); + return !(ref->mBase->mFlags & ESM::Container::Organic); } MWWorld::Ptr Container::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index d09355cca..65fab8819 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -29,8 +29,7 @@ namespace MWMechanics std::string& resultMessage, std::string& resultSound) { if (lock.getCellRef().getLockLevel() <= 0 || - lock.getCellRef().getLockLevel() == ESM::UnbreakableLock || - !lock.getClass().canLock(lock)) //If it's unlocked or can not be unlocked back out immediately + lock.getCellRef().getLockLevel() == ESM::UnbreakableLock) //If it's unlocked or can not be unlocked back out immediately return; int lockStrength = lock.getCellRef().getLockLevel(); From a86a8ecc0eeef23efff358134e593cf4337b9a55 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 10 Sep 2019 21:53:26 +0200 Subject: [PATCH 2/4] Allow locking/picking just about everything --- CHANGELOG.md | 2 +- apps/openmw/mwclass/container.cpp | 14 -------------- apps/openmw/mwclass/container.hpp | 6 ------ apps/openmw/mwclass/door.cpp | 14 -------------- apps/openmw/mwclass/door.hpp | 6 ------ apps/openmw/mwmechanics/security.cpp | 3 ++- apps/openmw/mwworld/class.cpp | 10 +++++++--- 7 files changed, 10 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32254d65b..a12d695f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,7 +138,7 @@ Bug #5134: Doors rotation by "Lock" console command is inconsistent Bug #5137: Textures with Clamp Mode set to Clamp instead of Wrap are too dark outside the boundaries Bug #5149: Failing lock pick attempts isn't always a crime - Bug #5155: Shouldn't be able to magically lock organic containers + Bug #5155: Lock/unlock behavior differs from vanilla Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index b7da1960e..f77a9307c 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -305,20 +305,6 @@ namespace MWClass return getContainerStore (ptr).getWeight(); } - void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const - { - if(lockLevel != 0) - ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, if positive - else - ptr.getCellRef().setLockLevel(ESM::UnbreakableLock); // If zero, set to max lock level - } - - void Container::unlock (const MWWorld::Ptr& ptr) const - { - int lockLevel = ptr.getCellRef().getLockLevel(); - ptr.getCellRef().setLockLevel(-abs(lockLevel)); //Makes lockLevel negative - } - bool Container::canLock(const MWWorld::ConstPtr &ptr) const { const MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index b13741187..8eae46353 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -47,12 +47,6 @@ namespace MWClass ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. - virtual void lock (const MWWorld::Ptr& ptr, int lockLevel = 0) const; - ///< Lock object - - virtual void unlock (const MWWorld::Ptr& ptr) const; - ///< Unlock object - virtual bool canLock(const MWWorld::ConstPtr &ptr) const; virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 4f144e1f7..b98a8cc99 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -240,20 +240,6 @@ namespace MWClass } } - void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const - { - if(lockLevel != 0) - ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, if positive - else - ptr.getCellRef().setLockLevel(ESM::UnbreakableLock); // If zero, set to max lock level - } - - void Door::unlock (const MWWorld::Ptr& ptr) const - { - int lockLevel = ptr.getCellRef().getLockLevel(); - ptr.getCellRef().setLockLevel(-abs(lockLevel)); //Makes lockLevel negative - } - bool Door::canLock(const MWWorld::ConstPtr &ptr) const { return true; diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index b3e4e383c..46acdec72 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -41,12 +41,6 @@ namespace MWClass static std::string getDestination (const MWWorld::LiveCellRef& door); ///< @return destination cell name or token - virtual void lock (const MWWorld::Ptr& ptr, int lockLevel = 0) const; - ///< Lock object - - virtual void unlock (const MWWorld::Ptr& ptr) const; - ///< Unlock object - virtual bool canLock(const MWWorld::ConstPtr &ptr) const; virtual bool allowTelekinesis(const MWWorld::ConstPtr &ptr) const; diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 65fab8819..62169c84a 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -29,7 +29,8 @@ namespace MWMechanics std::string& resultMessage, std::string& resultSound) { if (lock.getCellRef().getLockLevel() <= 0 || - lock.getCellRef().getLockLevel() == ESM::UnbreakableLock) //If it's unlocked or can not be unlocked back out immediately + lock.getCellRef().getLockLevel() == ESM::UnbreakableLock || + !lock.getClass().hasToolTip(lock)) //If it's unlocked or can not be unlocked back out immediately return; int lockStrength = lock.getCellRef().getLockLevel(); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 191552bc5..d7e422006 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -146,17 +146,21 @@ namespace MWWorld void Class::lock (const Ptr& ptr, int lockLevel) const { - throw std::runtime_error ("class does not support locking"); + if(lockLevel != 0) + ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, if positive + else + ptr.getCellRef().setLockLevel(ESM::UnbreakableLock); // If zero, set to max lock level } void Class::unlock (const Ptr& ptr) const { - throw std::runtime_error ("class does not support unlocking"); + int lockLevel = ptr.getCellRef().getLockLevel(); + ptr.getCellRef().setLockLevel(-abs(lockLevel)); //Makes lockLevel negative } bool Class::canLock(const ConstPtr &ptr) const { - return false; + return hasToolTip(ptr); } void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const From 85d52ec18327e635dd262a0442ef9438c44469cf Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 11 Sep 2019 22:05:24 +0200 Subject: [PATCH 3/4] oops --- apps/openmw/mwworld/class.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index d7e422006..3efc00491 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -160,7 +160,7 @@ namespace MWWorld bool Class::canLock(const ConstPtr &ptr) const { - return hasToolTip(ptr); + return false; } void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const From 7c8b82f45cb8228b9366aedb714ed7e0114794d0 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 17 Sep 2019 20:30:37 +0200 Subject: [PATCH 4/4] move locking behaviour to cellref --- apps/openmw/mwclass/container.cpp | 2 +- apps/openmw/mwclass/door.cpp | 2 +- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwmechanics/security.cpp | 2 +- apps/openmw/mwmechanics/spellcasting.cpp | 4 ++-- apps/openmw/mwscript/miscextensions.cpp | 4 ++-- apps/openmw/mwworld/cellref.cpp | 13 +++++++++++++ apps/openmw/mwworld/cellref.hpp | 2 ++ apps/openmw/mwworld/class.cpp | 14 -------------- apps/openmw/mwworld/class.hpp | 6 ------ 10 files changed, 23 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index f77a9307c..818f91735 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -181,7 +181,7 @@ namespace MWClass { MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); if(isLocked) - unlock(ptr); + ptr.getCellRef().unlock(); // using a key disarms the trap if(isTrapped) { diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index b98a8cc99..ecb6ececf 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -162,7 +162,7 @@ namespace MWClass if(actor == MWMechanics::getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}"); if(isLocked) - unlock(ptr); //Call the function here. because that makes sense. + ptr.getCellRef().unlock(); //Call the function here. because that makes sense. // using a key disarms the trap if(isTrapped) { diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 7547f086b..a1994da02 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1150,7 +1150,7 @@ namespace MWMechanics store.remove(*it, toMove, player); } // TODO: unhardcode the locklevel - targetContainer.getClass().lock(targetContainer,50); + targetContainer.getCellRef().lock(50); } void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, const MWWorld::Ptr& container, diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 62169c84a..cafc65b99 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -50,7 +50,7 @@ namespace MWMechanics { if (Misc::Rng::roll0to99() <= x) { - lock.getClass().unlock(lock); + lock.getCellRef().unlock(); resultMessage = "#{sLockSuccess}"; resultSound = "Open Lock"; mActor.getClass().skillUsageSucceeded(mActor, ESM::Skill::Security, 1); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 359e74fc6..2d979e034 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -696,7 +696,7 @@ namespace MWMechanics { if (caster == getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicLockSuccess}"); - target.getClass().lock(target, static_cast(magnitude)); + target.getCellRef().lock(static_cast(magnitude)); } return true; } @@ -716,7 +716,7 @@ namespace MWMechanics if (caster == getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}"); } - target.getClass().unlock(target); + target.getCellRef().unlock(); } else MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 29a25c997..e2506edb8 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -182,7 +182,7 @@ namespace MWScript runtime.pop(); } - ptr.getClass().lock (ptr, lockLevel); + ptr.getCellRef().lock (lockLevel); // Instantly reset door to closed state // This is done when using Lock in scripts, but not when using Lock spells. @@ -202,7 +202,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - ptr.getClass().unlock (ptr); + ptr.getCellRef().unlock (); } }; diff --git a/apps/openmw/mwworld/cellref.cpp b/apps/openmw/mwworld/cellref.cpp index 094669bdd..fb9fd592a 100644 --- a/apps/openmw/mwworld/cellref.cpp +++ b/apps/openmw/mwworld/cellref.cpp @@ -225,6 +225,19 @@ namespace MWWorld } } + void CellRef::lock(int lockLevel) + { + if(lockLevel != 0) + setLockLevel(abs(lockLevel)); //Changes lock to locklevel, if positive + else + setLockLevel(ESM::UnbreakableLock); // If zero, set to max lock level + } + + void CellRef::unlock() + { + setLockLevel(-abs(mCellRef.mLockLevel)); //Makes lockLevel negative + } + std::string CellRef::getKey() const { return mCellRef.mKey; diff --git a/apps/openmw/mwworld/cellref.hpp b/apps/openmw/mwworld/cellref.hpp index 5646bafb0..04e807ce5 100644 --- a/apps/openmw/mwworld/cellref.hpp +++ b/apps/openmw/mwworld/cellref.hpp @@ -99,6 +99,8 @@ namespace MWWorld // For an unlocked door, it is set to -(previous locklevel) int getLockLevel() const; void setLockLevel(int lockLevel); + void lock(int lockLevel); + void unlock(); // Key and trap ID names, if any std::string getKey() const; std::string getTrap() const; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 3efc00491..cd1f719d6 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -144,20 +144,6 @@ namespace MWWorld return false; } - void Class::lock (const Ptr& ptr, int lockLevel) const - { - if(lockLevel != 0) - ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, if positive - else - ptr.getCellRef().setLockLevel(ESM::UnbreakableLock); // If zero, set to max lock level - } - - void Class::unlock (const Ptr& ptr) const - { - int lockLevel = ptr.getCellRef().getLockLevel(); - ptr.getCellRef().setLockLevel(-abs(lockLevel)); //Makes lockLevel negative - } - bool Class::canLock(const ConstPtr &ptr) const { return false; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 964ef19a5..0d3a0e807 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -163,12 +163,6 @@ namespace MWWorld virtual bool hasInventoryStore (const Ptr& ptr) const; ///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false) - virtual void lock (const Ptr& ptr, int lockLevel) const; - ///< Lock object (default implementation: throw an exception) - - virtual void unlock (const Ptr& ptr) const; - ///< Unlock object (default implementation: throw an exception) - virtual bool canLock (const ConstPtr& ptr) const; virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const;