Security skill

pull/16/head
scrawl 12 years ago
parent c7805e7dd2
commit 7a2d1cd8ce

@ -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

@ -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; i<mModel->getItemCount(); ++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

@ -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<int, std::string> 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);

@ -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<ESM::Lockpick>()->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<ESM::GameSetting>().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<float> (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<ESM::Lockpick>()->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<ESM::Probe>()->mBase->mData.mQuality;
const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().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<ESM::GameSetting>().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<float> (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<ESM::Probe>()->mBase->mData.mUses;
--probe.getCellRef().mCharge;
if (!probe.getCellRef().mCharge)
probe.getRefData().setCount(0);
}
}

@ -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

@ -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;
}
}

@ -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.

@ -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);

@ -73,8 +73,6 @@ namespace MWRender
int getSlotSelected(int posX, int posY);
void setNpcAnimation (NpcAnimation* anim);
private:
OEngine::Render::SelectionBuffer* mSelectionBuffer;

@ -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<ESM::Race>().find(mNpc->mRace);
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;

@ -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();

@ -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);

Loading…
Cancel
Save