Implement pickpocket detection. Play a voiced dialogue entry when detected.
parent
ea3ee4407f
commit
780bf5a2cd
@ -0,0 +1,67 @@
|
|||||||
|
#include "pickpocket.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
|
||||||
|
Pickpocket::Pickpocket(const MWWorld::Ptr &thief, const MWWorld::Ptr &victim)
|
||||||
|
: mThief(thief)
|
||||||
|
, mVictim(victim)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float Pickpocket::getChanceModifier(const MWWorld::Ptr &ptr, float add)
|
||||||
|
{
|
||||||
|
NpcStats& stats = ptr.getClass().getNpcStats(ptr);
|
||||||
|
float agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||||
|
float luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
|
float sneak = stats.getSkill(ESM::Skill::Sneak).getModified();
|
||||||
|
return (add + 0.2 * agility + 0.1 * luck + sneak) * stats.getFatigueTerm();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pickpocket::getDetected(float valueTerm)
|
||||||
|
{
|
||||||
|
float x = getChanceModifier(mThief);
|
||||||
|
float y = getChanceModifier(mVictim, valueTerm);
|
||||||
|
|
||||||
|
float t = 2*x - y;
|
||||||
|
|
||||||
|
NpcStats& pcStats = mThief.getClass().getNpcStats(mThief);
|
||||||
|
float pcSneak = pcStats.getSkill(ESM::Skill::Sneak).getModified();
|
||||||
|
int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
|
.find("iPickMinChance")->getInt();
|
||||||
|
int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
|
.find("iPickMaxChance")->getInt();
|
||||||
|
|
||||||
|
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||||
|
if (t < pcSneak / iPickMinChance)
|
||||||
|
{
|
||||||
|
return (roll > int(pcSneak / iPickMinChance));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = std::min(float(iPickMaxChance), t);
|
||||||
|
return (roll > int(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pickpocket::pick(MWWorld::Ptr item, int count)
|
||||||
|
{
|
||||||
|
float stackValue = item.getClass().getValue(item) * count;
|
||||||
|
float fPickPocketMod = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
|
.find("fPickPocketMod")->getFloat();
|
||||||
|
float valueTerm = 10 * fPickPocketMod * stackValue;
|
||||||
|
|
||||||
|
return getDetected(valueTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pickpocket::finish()
|
||||||
|
{
|
||||||
|
return getDetected(0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef OPENMW_MECHANICS_PICKPOCKET_H
|
||||||
|
#define OPENMW_MECHANICS_PICKPOCKET_H
|
||||||
|
|
||||||
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
|
||||||
|
class Pickpocket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Pickpocket (const MWWorld::Ptr& thief, const MWWorld::Ptr& victim);
|
||||||
|
|
||||||
|
/// Steal some items
|
||||||
|
/// @return Was the thief detected?
|
||||||
|
bool pick (MWWorld::Ptr item, int count);
|
||||||
|
/// End the pickpocketing process
|
||||||
|
/// @return Was the thief detected?
|
||||||
|
bool finish ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool getDetected(float valueTerm);
|
||||||
|
float getChanceModifier(const MWWorld::Ptr& ptr, float add=0);
|
||||||
|
MWWorld::Ptr mThief;
|
||||||
|
MWWorld::Ptr mVictim;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue