forked from teamnwah/openmw-tes3coop
Security skill
This commit is contained in:
parent
c7805e7dd2
commit
7a2d1cd8ce
12 changed files with 205 additions and 8 deletions
|
@ -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);
|
||||
|
|
118
apps/openmw/mwmechanics/security.cpp
Normal file
118
apps/openmw/mwmechanics/security.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
19
apps/openmw/mwmechanics/security.hpp
Normal file
19
apps/openmw/mwmechanics/security.hpp
Normal file
|
@ -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,7 +204,7 @@ namespace MWRender
|
|||
|
||||
void InventoryPreview::onSetup ()
|
||||
{
|
||||
if (!mSelectionBuffer)
|
||||
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…
Reference in a new issue