Seperated locked and lock level, to allow for relocking doors to previous lock level.

The data is stored in the esm as -lockLevel if unlocked; lockLevel if locked. While not tested, it should not present any problems.
This commit is contained in:
Thomas 2014-04-23 05:12:07 -04:00
parent e71a119c23
commit cac8e52154
10 changed files with 51 additions and 21 deletions

View file

@ -111,7 +111,7 @@ namespace MWClass
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player); MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);
bool needKey = ptr.getCellRef().mLockLevel>0; bool needKey = ptr.getCellRef().mLocked;
bool hasKey = false; bool hasKey = false;
std::string keyName; std::string keyName;
@ -132,7 +132,7 @@ namespace MWClass
if (needKey && hasKey) if (needKey && hasKey)
{ {
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
ptr.getCellRef().mLockLevel = 0; unlock(ptr);
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().mTrap = "";
} }
@ -209,7 +209,7 @@ namespace MWClass
info.caption = ref->mBase->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
if (ref->mRef.mLockLevel > 0) if (ref->mRef.mLocked)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "") if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";
@ -240,15 +240,22 @@ namespace MWClass
void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{ {
if (lockLevel<0) ptr.getCellRef().mLocked = true;
lockLevel = 0; if(lockLevel>=0) //Lock level setting left as most of the code relies on this
ptr.getCellRef().mLockLevel = lockLevel;
ptr.getCellRef().mLockLevel = lockLevel;
} }
void Container::unlock (const MWWorld::Ptr& ptr) const void Container::unlock (const MWWorld::Ptr& ptr) const
{ {
ptr.getCellRef().mLockLevel = 0; ptr.getCellRef().mLocked= false;
}
void Container::changeLockLevel(const MWWorld::Ptr& ptr, int lockLevel, bool doLock) {
if (lockLevel<0)
lockLevel = 0;
ptr.getCellRef().mLockLevel = lockLevel;
if(doLock) lock(ptr);
} }
MWWorld::Ptr MWWorld::Ptr

View file

@ -48,12 +48,15 @@ namespace MWClass
///< Returns total weight of objects inside this object (including modifications from magic ///< Returns total weight of objects inside this object (including modifications from magic
/// effects). Throws an exception, if the object can't hold other objects. /// effects). Throws an exception, if the object can't hold other objects.
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const; virtual void lock (const MWWorld::Ptr& ptr, int lockLevel = -999) const;
///< Lock object ///< Lock object
virtual void unlock (const MWWorld::Ptr& ptr) const; virtual void unlock (const MWWorld::Ptr& ptr) const;
///< Unlock object ///< Unlock object
///Changes the lock level of the object
virtual void changeLockLevel(const MWWorld::Ptr& ptr, int lockLevel, bool lock=true);
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
const; const;
///< Read additional state from \a state into \a ptr. ///< Read additional state from \a state into \a ptr.

View file

@ -76,7 +76,7 @@ namespace MWClass
MWWorld::ContainerStore &invStore = get(actor).getContainerStore(actor); MWWorld::ContainerStore &invStore = get(actor).getContainerStore(actor);
bool needKey = ptr.getCellRef().mLockLevel>0; bool needKey = ptr.getCellRef().mLocked;
bool hasKey = false; bool hasKey = false;
std::string keyName; std::string keyName;
@ -98,7 +98,7 @@ namespace MWClass
{ {
if(actor == MWBase::Environment::get().getWorld()->getPlayerPtr()) if(actor == MWBase::Environment::get().getWorld()->getPlayerPtr())
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}"); MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
ptr.getCellRef().mLockLevel = 0; unlock(ptr); //Call the function here. because that makes sense.
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().mTrap = "";
} }
@ -158,15 +158,22 @@ namespace MWClass
void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{ {
ptr.getCellRef().mLocked = true;
if(lockLevel>=0) //Lock level setting left as most of the code relies on this
ptr.getCellRef().mLockLevel = lockLevel;
}
void Door::changeLockLevel(const MWWorld::Ptr& ptr, int lockLevel, bool doLock) const{
if (lockLevel<0) if (lockLevel<0)
lockLevel = 0; lockLevel = 0;
ptr.getCellRef().mLockLevel = lockLevel; ptr.getCellRef().mLockLevel = lockLevel;
if(doLock) lock(ptr); //A change in lock level almost always nesesitates a lock
} }
void Door::unlock (const MWWorld::Ptr& ptr) const void Door::unlock (const MWWorld::Ptr& ptr) const
{ {
ptr.getCellRef().mLockLevel = 0; ptr.getCellRef().mLocked = false;
} }
std::string Door::getScript (const MWWorld::Ptr& ptr) const std::string Door::getScript (const MWWorld::Ptr& ptr) const
@ -208,7 +215,7 @@ namespace MWClass
text += "\n" + getDestination(*ref); text += "\n" + getDestination(*ref);
} }
if (ref->mRef.mLockLevel > 0) if (ref->mRef.mLocked == true)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "") if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";

View file

@ -36,18 +36,22 @@ namespace MWClass
static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door); static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door);
///< @return destination cell name or token ///< @return destination cell name or token
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const; virtual void lock (const MWWorld::Ptr& ptr, int lockLevel = -999) const;
///< Lock object ///< Lock object
virtual void unlock (const MWWorld::Ptr& ptr) const; virtual void unlock (const MWWorld::Ptr& ptr) const;
///< Unlock object ///< Unlock object
///Change the lock level
virtual void changeLockLevel(const MWWorld::Ptr& ptr, int lockLevel, bool lock=true) const;
virtual std::string getScript (const MWWorld::Ptr& ptr) const; virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr ///< Return name of the script attached to ptr
static void registerSelf(); static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
private:
}; };
} }

View file

@ -29,7 +29,7 @@ namespace MWMechanics
void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick,
std::string& resultMessage, std::string& resultSound) std::string& resultMessage, std::string& resultSound)
{ {
if (lock.getCellRef().mLockLevel <= 0) if (!lock.getCellRef().mLocked)
return; return;
int lockStrength = lock.getCellRef().mLockLevel; int lockStrength = lock.getCellRef().mLockLevel;

View file

@ -420,6 +420,7 @@ namespace MWMechanics
{ {
if (effectId == ESM::MagicEffect::Lock) if (effectId == ESM::MagicEffect::Lock)
{ {
target.getCellRef().mLocked = true;
if (target.getCellRef().mLockLevel < magnitude) if (target.getCellRef().mLockLevel < magnitude)
target.getCellRef().mLockLevel = magnitude; target.getCellRef().mLockLevel = magnitude;
} }
@ -427,12 +428,12 @@ namespace MWMechanics
{ {
if (target.getCellRef().mLockLevel <= magnitude) if (target.getCellRef().mLockLevel <= magnitude)
{ {
if (target.getCellRef().mLockLevel > 0) if (target.getCellRef().mLocked)
{ {
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target); MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
} }
target.getCellRef().mLockLevel = 0; target.getCellRef().mLocked=false;
} }
else else
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f);

View file

@ -131,7 +131,7 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer lockLevel = 100; Interpreter::Type_Integer lockLevel = ptr.getCellRef().mLockLevel;
if (arg0==1) if (arg0==1)
{ {
@ -283,7 +283,7 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
// We are ignoring the DontSaveObject statement for now. Probably not worth // We are ignoring the DontSaveObject statement for now. Probably not worth
/// bothering with. The incompatibility we are creating should be marginal at most. // bothering with. The incompatibility we are creating should be marginal at most.
} }
}; };
@ -320,7 +320,7 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
runtime.push (ptr.getCellRef ().mLockLevel > 0); runtime.push (ptr.getCellRef().mLocked);
} }
}; };

View file

@ -137,6 +137,11 @@ namespace MWWorld
throw std::runtime_error ("class does not support locking"); throw std::runtime_error ("class does not support locking");
} }
void Class::setLockLevel (const Ptr& ptr, int lockLevel) const
{
throw std::runtime_error ("class does not support setting lock level");
}
void Class::unlock (const Ptr& ptr) const void Class::unlock (const Ptr& ptr) const
{ {
throw std::runtime_error ("class does not support unlocking"); throw std::runtime_error ("class does not support unlocking");
@ -397,7 +402,7 @@ namespace MWWorld
void Class::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) const {} void Class::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) const {}
int Class::getBaseGold(const MWWorld::Ptr& ptr) const int Class::getBaseGold(const MWWorld::Ptr& ptr) const
{ {
throw std::runtime_error("class does not support base gold"); throw std::runtime_error("class does not support base gold");
} }

View file

@ -165,6 +165,8 @@ namespace MWWorld
virtual void lock (const Ptr& ptr, int lockLevel) const; virtual void lock (const Ptr& ptr, int lockLevel) const;
///< Lock object (default implementation: throw an exception) ///< Lock object (default implementation: throw an exception)
virtual void setLockLevel(const Ptr& ptr, int lockLevel) const;
virtual void unlock (const Ptr& ptr) const; virtual void unlock (const Ptr& ptr) const;
///< Unlock object (default implementation: throw an exception) ///< Unlock object (default implementation: throw an exception)

View file

@ -76,6 +76,7 @@ namespace MWWorld
cellRef.mEnchantmentCharge = -1; cellRef.mEnchantmentCharge = -1;
cellRef.mTeleport = false; cellRef.mTeleport = false;
cellRef.mLockLevel = 0; cellRef.mLockLevel = 0;
cellRef.mLocked = false;
cellRef.mReferenceBlocked = 0; cellRef.mReferenceBlocked = 0;
mPtr.getRefData().setCount(count); mPtr.getRefData().setCount(count);
} }