From 7a2d1cd8ceb0e0fc3fd92d29d6f10dd2908625b1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 May 2013 18:40:37 +0200 Subject: [PATCH 1/3] Security skill --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/container.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 6 ++ apps/openmw/mwmechanics/security.cpp | 118 ++++++++++++++++++++++ apps/openmw/mwmechanics/security.hpp | 19 ++++ apps/openmw/mwrender/animation.cpp | 8 ++ apps/openmw/mwrender/animation.hpp | 3 + apps/openmw/mwrender/characterpreview.cpp | 5 +- apps/openmw/mwrender/characterpreview.hpp | 2 - apps/openmw/mwrender/npcanimation.cpp | 2 - apps/openmw/mwworld/player.cpp | 43 ++++++++ apps/openmw/mwworld/player.hpp | 3 + 12 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 apps/openmw/mwmechanics/security.cpp create mode 100644 apps/openmw/mwmechanics/security.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 306ef4173..660e45115 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -67,7 +67,7 @@ add_openmw_dir (mwclass add_openmw_dir (mwmechanics mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow - aiescort aiactivate repair enchanting pathfinding + aiescort aiactivate repair enchanting pathfinding security ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 60cb186e2..85c2cf5fb 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -233,6 +233,7 @@ namespace MWGui { // transfer everything into the player's inventory ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel(); + mModel->update(); for (size_t i=0; igetItemCount(); ++i) { if (i==0) @@ -257,7 +258,6 @@ namespace MWGui { onTakeAllButtonClicked(mTakeButton); - /// \todo if corpse is non-disposable: messagebox #{sDisposeCorpseFail} if (MWWorld::Class::get(mPtr).isPersistent(mPtr)) MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}"); else diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index b31d51e6e..00c520de9 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -241,6 +241,10 @@ namespace MWInput case A_ToggleHUD: mWindows.toggleHud(); break; + case A_Use: + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + mPlayer.use(); + break; } } } @@ -803,6 +807,7 @@ namespace MWInput { std::map descriptions; + descriptions[A_Use] = "sUse"; descriptions[A_Activate] = "sActivate"; descriptions[A_MoveBackward] = "sBack"; descriptions[A_MoveForward] = "sForward"; @@ -865,6 +870,7 @@ namespace MWInput ret.push_back(A_AlwaysRun); ret.push_back(A_Sneak); ret.push_back(A_Activate); + ret.push_back(A_Use); ret.push_back(A_ToggleWeapon); ret.push_back(A_ToggleSpell); ret.push_back(A_AutoMove); diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp new file mode 100644 index 000000000..818412b8e --- /dev/null +++ b/apps/openmw/mwmechanics/security.cpp @@ -0,0 +1,118 @@ +#include "security.hpp" + +#include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "npcstats.hpp" +#include "creaturestats.hpp" + +namespace MWMechanics +{ + + void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick) + { + if (lock.getCellRef().mLockLevel <= 0) + return; + + int lockStrength = lock.getCellRef().mLockLevel; + + float pickQuality = lockpick.get()->mBase->mData.mQuality; + + CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); + float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); + float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); + float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); + float fatigueTerm = creatureStats.getFatigueTerm(); + + float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->getFloat(); + + float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; + x *= pickQuality * fatigueTerm; + x += fPickLockMult * lockStrength; + + bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + if (x <= 0) + { + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLockImpossible}"); + } + else + { + int roll = static_cast (std::rand()) / RAND_MAX * 100; + if (roll <= x) + { + MWWorld::Class::get(lock).unlock(lock); + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLockSuccess}"); + MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 1); + } + else if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLockFail}"); + } + + if (lockpick.getCellRef().mCharge == -1) + lockpick.getCellRef().mCharge = lockpick.get()->mBase->mData.mUses; + --lockpick.getCellRef().mCharge; + if (!lockpick.getCellRef().mCharge) + lockpick.getRefData().setCount(0); + } + + void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe) + { + if (trap.getCellRef().mTrap == "") + return; + + CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); + + float probeQuality = probe.get()->mBase->mData.mQuality; + + const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().mTrap); + float trapSpellPoints = trapSpell->mData.mCost; + + float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); + float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); + float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); + float fatigueTerm = creatureStats.getFatigueTerm(); + + float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->getFloat(); + + float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; + x += fTrapCostMult * trapSpellPoints; + x *= probeQuality * fatigueTerm; + + bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + if (x <= 0) + { + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapImpossible}"); + } + else + { + int roll = static_cast (std::rand()) / RAND_MAX * 100; + if (roll <= x) + { + trap.getCellRef().mTrap = ""; + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapSuccess}"); + MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 0); + } + else if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapFail}"); + } + + if (probe.getCellRef().mCharge == -1) + probe.getCellRef().mCharge = probe.get()->mBase->mData.mUses; + --probe.getCellRef().mCharge; + if (!probe.getCellRef().mCharge) + probe.getRefData().setCount(0); + } + +} diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp new file mode 100644 index 000000000..4d655f6e0 --- /dev/null +++ b/apps/openmw/mwmechanics/security.hpp @@ -0,0 +1,19 @@ +#ifndef MWMECHANICS_SECURITY_H +#define MWMECHANICS_SECURITY_H + +#include "../mwworld/ptr.hpp" + +namespace MWMechanics +{ + + /// @brief implementation of Security skill + class Security + { + public: + static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick); + static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe); + }; + +} + +#endif diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 7dc6cfc13..853ffc375 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -728,4 +728,12 @@ void Animation::showWeapons(bool showWeapon) { } +bool Animation::isPriorityActive(int priority) const +{ + for (AnimStateMap::const_iterator it = mStates.begin(); it != mStates.end(); ++it) + if (it->second.mPriority == priority) + return true; + return false; +} + } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 443b5b7b4..31be0fb2a 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -148,6 +148,9 @@ public: bool hasAnimation(const std::string &anim); + bool isPriorityActive (int priority) const; + ///< Is there an animation playing with the given priority? + // Specifies the axis' to accumulate on. Non-accumulated axis will just // move visually, but not affect the actual movement. Each x/y/z value // should be on the scale of 0 to 1. diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index c931c8e00..e4bba289f 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -193,6 +193,7 @@ namespace MWRender mNode->setOrientation (Ogre::Quaternion::IDENTITY); mRenderTarget->update(); + mSelectionBuffer->update(); } @@ -203,8 +204,8 @@ namespace MWRender void InventoryPreview::onSetup () { - if (!mSelectionBuffer) - mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); + delete mSelectionBuffer; + mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); mAnimation->showWeapons(true); diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index d8f43f71b..562cb3784 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -73,8 +73,6 @@ namespace MWRender int getSlotSelected(int posX, int posY); - void setNpcAnimation (NpcAnimation* anim); - private: OEngine::Render::SelectionBuffer* mSelectionBuffer; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index f0df1ba4b..b5f2ea031 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -128,8 +128,6 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) assert(viewMode != VM_HeadOnly); mViewMode = viewMode; - Ogre::SceneNode *node = mInsert->getParentSceneNode(); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const ESM::Race *race = store.get().find(mNpc->mRace); bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 08d908e62..ca604f55d 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -2,11 +2,18 @@ #include "player.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwworld/ptr.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/character.hpp" +#include "../mwmechanics/security.hpp" + +#include "../mwrender/animation.hpp" #include "class.hpp" @@ -133,6 +140,42 @@ namespace MWWorld MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] = roll; } + void Player::use() + { + MWWorld::InventoryStore& store = MWWorld::Class::get(getPlayer()).getInventoryStore(getPlayer()); + MWWorld::ContainerStoreIterator equipped = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + + if (getDrawState() == MWMechanics::DrawState_Weapon) + { + if (equipped != store.end()) + { + MWWorld::Ptr item = *equipped; + MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(getPlayer()); + MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject(); + + if (anim->isPriorityActive(MWMechanics::Priority_Weapon)) + return; + + if (item.getTypeName() == typeid(ESM::Lockpick).name()) + { + if (!target.isEmpty()) + MWMechanics::Security::pickLock(getPlayer(), target, item); + anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); + } + else if (item.getTypeName() == typeid(ESM::Probe).name()) + { + if (!target.isEmpty()) + MWMechanics::Security::probeTrap(getPlayer(), target, item); + anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); + } + + // tool used up? + if (!item.getRefData().getCount()) + MWBase::Environment::get().getWindowManager()->setSelectedWeapon(MWWorld::Ptr()); + } + } + } + MWMechanics::DrawState_ Player::getDrawState() { MWWorld::Ptr ptr = getPlayer(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index f51d8f890..fd25f749f 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -58,6 +58,9 @@ namespace MWWorld void setForwardBackward (int value); void setUpDown(int value); + void use (); + ///< Use item equipped on right hand, or fists + void setRunState(bool run); void setSneak(bool sneak); From 5173779f4b20925a40b9835711b4b6884d412886 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 May 2013 19:48:51 +0200 Subject: [PATCH 2/3] Add sounds for security skill --- apps/openmw/mwmechanics/security.cpp | 39 ++++++++++++---------------- apps/openmw/mwmechanics/security.hpp | 6 +++-- apps/openmw/mwworld/player.cpp | 12 +++++++-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 818412b8e..11edc6450 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -13,7 +13,8 @@ namespace MWMechanics { - void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick) + void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, + std::string& resultMessage, std::string& resultSound) { if (lock.getCellRef().mLockLevel <= 0) return; @@ -35,25 +36,21 @@ namespace MWMechanics x *= pickQuality * fatigueTerm; x += fPickLockMult * lockStrength; - bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + resultSound = "Open Lock Fail"; if (x <= 0) - { - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLockImpossible}"); - } + resultMessage = "#{sLockImpossible}"; else { int roll = static_cast (std::rand()) / RAND_MAX * 100; if (roll <= x) { MWWorld::Class::get(lock).unlock(lock); - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLockSuccess}"); + resultMessage = "#{sLockSuccess}"; + resultSound = "Open Lock"; MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 1); } - else if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLockFail}"); + else + resultMessage = "#{sLockFail}"; } if (lockpick.getCellRef().mCharge == -1) @@ -63,7 +60,8 @@ namespace MWMechanics lockpick.getRefData().setCount(0); } - void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe) + void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, + std::string& resultMessage, std::string& resultSound) { if (trap.getCellRef().mTrap == "") return; @@ -87,25 +85,22 @@ namespace MWMechanics x += fTrapCostMult * trapSpellPoints; x *= probeQuality * fatigueTerm; - bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + resultSound = "Disarm Trap Fail"; if (x <= 0) - { - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapImpossible}"); - } + resultMessage = "#{sTrapImpossible}"; else { int roll = static_cast (std::rand()) / RAND_MAX * 100; if (roll <= x) { trap.getCellRef().mTrap = ""; - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapSuccess}"); + + resultSound = "Disarm Trap"; + resultMessage = "#{sTrapSuccess}"; MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 0); } - else if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapFail}"); + else + resultMessage = "#{sTrapFail}"; } if (probe.getCellRef().mCharge == -1) diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index 4d655f6e0..17a914459 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -10,8 +10,10 @@ namespace MWMechanics class Security { public: - static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick); - static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe); + static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, + std::string& resultMessage, std::string& resultSound); + static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, + std::string& resultMessage, std::string& resultSound); }; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index ca604f55d..b597dccf3 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -4,6 +4,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/inventorystore.hpp" @@ -156,19 +157,26 @@ namespace MWWorld if (anim->isPriorityActive(MWMechanics::Priority_Weapon)) return; + std::string resultMessage, resultSound; + if (item.getTypeName() == typeid(ESM::Lockpick).name()) { if (!target.isEmpty()) - MWMechanics::Security::pickLock(getPlayer(), target, item); + MWMechanics::Security::pickLock(getPlayer(), target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); } else if (item.getTypeName() == typeid(ESM::Probe).name()) { if (!target.isEmpty()) - MWMechanics::Security::probeTrap(getPlayer(), target, item); + MWMechanics::Security::probeTrap(getPlayer(), target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); } + if (!resultMessage.empty()) + MWBase::Environment::get().getWindowManager()->messageBox(resultMessage); + if (!resultSound.empty()) + MWBase::Environment::get().getSoundManager()->playSound(resultSound,1,1); + // tool used up? if (!item.getRefData().getCount()) MWBase::Environment::get().getWindowManager()->setSelectedWeapon(MWWorld::Ptr()); From 2715520d6fba458d0e0549de51b5ddccd4e68a68 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 May 2013 23:19:48 +0200 Subject: [PATCH 3/3] Cleanup Security class --- apps/openmw/mwmechanics/security.cpp | 41 ++++++++++++---------------- apps/openmw/mwmechanics/security.hpp | 10 +++++-- apps/openmw/mwworld/player.cpp | 4 +-- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 11edc6450..090e8ced3 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -13,7 +13,17 @@ namespace MWMechanics { - void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, + Security::Security(const MWWorld::Ptr &actor) + { + CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); + mAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); + mLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); + mSecuritySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); + mFatigueTerm = creatureStats.getFatigueTerm(); + } + + void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, std::string& resultMessage, std::string& resultSound) { if (lock.getCellRef().mLockLevel <= 0) @@ -23,17 +33,10 @@ namespace MWMechanics float pickQuality = lockpick.get()->mBase->mData.mQuality; - CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); - NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); - float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); - float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); - float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); - float fatigueTerm = creatureStats.getFatigueTerm(); - float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->getFloat(); - float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; - x *= pickQuality * fatigueTerm; + float x = 0.2 * mAgility + 0.1 * mLuck + mSecuritySkill; + x *= pickQuality * mFatigueTerm; x += fPickLockMult * lockStrength; resultSound = "Open Lock Fail"; @@ -47,7 +50,7 @@ namespace MWMechanics MWWorld::Class::get(lock).unlock(lock); resultMessage = "#{sLockSuccess}"; resultSound = "Open Lock"; - MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 1); + MWWorld::Class::get(mActor).skillUsageSucceeded(mActor, ESM::Skill::Security, 1); } else resultMessage = "#{sLockFail}"; @@ -60,30 +63,22 @@ namespace MWMechanics lockpick.getRefData().setCount(0); } - void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, + void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, std::string& resultMessage, std::string& resultSound) { if (trap.getCellRef().mTrap == "") return; - CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); - NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); - float probeQuality = probe.get()->mBase->mData.mQuality; const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().mTrap); float trapSpellPoints = trapSpell->mData.mCost; - float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); - float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); - float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); - float fatigueTerm = creatureStats.getFatigueTerm(); - float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->getFloat(); - float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; + float x = 0.2 * mAgility + 0.1 * mLuck + mSecuritySkill; x += fTrapCostMult * trapSpellPoints; - x *= probeQuality * fatigueTerm; + x *= probeQuality * mFatigueTerm; resultSound = "Disarm Trap Fail"; if (x <= 0) @@ -97,7 +92,7 @@ namespace MWMechanics resultSound = "Disarm Trap"; resultMessage = "#{sTrapSuccess}"; - MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 0); + MWWorld::Class::get(mActor).skillUsageSucceeded(mActor, ESM::Skill::Security, 0); } else resultMessage = "#{sTrapFail}"; diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index 17a914459..f3efb04ed 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -10,10 +10,16 @@ namespace MWMechanics class Security { public: - static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, + Security (const MWWorld::Ptr& actor); + + void pickLock (const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, std::string& resultMessage, std::string& resultSound); - static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, + void probeTrap (const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, std::string& resultMessage, std::string& resultSound); + + private: + float mAgility, mLuck, mSecuritySkill, mFatigueTerm; + MWWorld::Ptr mActor; }; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index b597dccf3..ebc9cd86d 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -162,13 +162,13 @@ namespace MWWorld if (item.getTypeName() == typeid(ESM::Lockpick).name()) { if (!target.isEmpty()) - MWMechanics::Security::pickLock(getPlayer(), target, item, resultMessage, resultSound); + MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); } else if (item.getTypeName() == typeid(ESM::Probe).name()) { if (!target.isEmpty()) - MWMechanics::Security::probeTrap(getPlayer(), target, item, resultMessage, resultSound); + MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); }