2013-05-11 18:38:27 +02:00
|
|
|
#include "pickpocketitemmodel.hpp"
|
|
|
|
|
2015-04-22 17:58:55 +02:00
|
|
|
#include <components/misc/rng.hpp>
|
2015-07-18 19:40:31 +02:00
|
|
|
#include <components/esm/loadskil.hpp>
|
2015-03-15 14:07:47 +13:00
|
|
|
|
2017-10-04 21:25:22 +04:00
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
2017-10-04 22:37:08 +04:00
|
|
|
#include "../mwmechanics/creaturestats.hpp"
|
2017-10-04 21:25:22 +04:00
|
|
|
#include "../mwmechanics/pickpocket.hpp"
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
|
2017-10-04 21:25:22 +04:00
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
|
|
|
#include "../mwbase/windowmanager.hpp"
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
namespace MWGui
|
|
|
|
{
|
|
|
|
|
2017-10-04 21:25:22 +04:00
|
|
|
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& actor, ItemModel *sourceModel, bool hideItems)
|
2017-10-04 23:26:06 +04:00
|
|
|
: mActor(actor), mPickpocketDetected(false)
|
2013-05-11 18:38:27 +02:00
|
|
|
{
|
2017-10-04 21:25:22 +04:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
2013-05-11 18:38:27 +02:00
|
|
|
mSourceModel = sourceModel;
|
2018-12-23 15:18:33 +04:00
|
|
|
float chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
|
2013-05-11 18:38:27 +02:00
|
|
|
|
|
|
|
mSourceModel->update();
|
2015-03-15 14:07:47 +13:00
|
|
|
|
|
|
|
// build list of items that player is unable to find when attempts to pickpocket.
|
2014-08-25 17:01:02 +02:00
|
|
|
if (hideItems)
|
2013-05-11 18:38:27 +02:00
|
|
|
{
|
2014-08-25 17:01:02 +02:00
|
|
|
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
|
|
|
{
|
2015-05-23 20:33:44 +02:00
|
|
|
if (Misc::Rng::roll0to99() > chance)
|
2014-08-25 17:01:02 +02:00
|
|
|
mHiddenItems.push_back(mSourceModel->getItem(i));
|
|
|
|
}
|
2013-05-11 18:38:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-03 09:59:31 +04:00
|
|
|
bool PickpocketItemModel::allowedToUseItems() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
ItemStack PickpocketItemModel::getItem (ModelIndex index)
|
|
|
|
{
|
|
|
|
if (index < 0)
|
|
|
|
throw std::runtime_error("Invalid index supplied");
|
|
|
|
if (mItems.size() <= static_cast<size_t>(index))
|
|
|
|
throw std::runtime_error("Item index out of range");
|
|
|
|
return mItems[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t PickpocketItemModel::getItemCount()
|
|
|
|
{
|
|
|
|
return mItems.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PickpocketItemModel::update()
|
|
|
|
{
|
|
|
|
mSourceModel->update();
|
|
|
|
mItems.clear();
|
|
|
|
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
|
|
|
{
|
|
|
|
const ItemStack& item = mSourceModel->getItem(i);
|
2014-01-02 01:31:06 +01:00
|
|
|
|
|
|
|
// Bound items may not be stolen
|
2014-09-13 18:59:13 -04:00
|
|
|
if (item.mFlags & ItemStack::Flag_Bound)
|
2014-01-02 01:31:06 +01:00
|
|
|
continue;
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
if (std::find(mHiddenItems.begin(), mHiddenItems.end(), item) == mHiddenItems.end()
|
|
|
|
&& item.mType != ItemStack::Type_Equipped)
|
|
|
|
mItems.push_back(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PickpocketItemModel::removeItem (const ItemStack &item, size_t count)
|
|
|
|
{
|
|
|
|
ProxyItemModel::removeItem(item, count);
|
|
|
|
}
|
|
|
|
|
2017-10-04 22:37:08 +04:00
|
|
|
bool PickpocketItemModel::onDropItem(const MWWorld::Ptr &item, int count)
|
|
|
|
{
|
|
|
|
// don't allow "reverse pickpocket" (it will be handled by scripts after 1.0)
|
2016-03-05 19:53:24 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-10-04 23:26:06 +04:00
|
|
|
void PickpocketItemModel::onClose()
|
|
|
|
{
|
|
|
|
// Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened)
|
|
|
|
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container)
|
|
|
|
// If it was already detected while taking an item, no need to check now
|
|
|
|
|| mPickpocketDetected)
|
|
|
|
return;
|
|
|
|
|
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
|
|
MWMechanics::Pickpocket pickpocket(player, mActor);
|
|
|
|
if (pickpocket.finish())
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
2019-09-23 23:56:37 +03:00
|
|
|
player, mActor, MWBase::MechanicsManager::OT_Pickpocket, std::string(), 0, true);
|
2017-10-04 23:26:06 +04:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
|
|
|
mPickpocketDetected = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
2017-10-04 21:25:22 +04:00
|
|
|
{
|
2017-10-04 22:37:08 +04:00
|
|
|
if (mActor.getClass().getCreatureStats(mActor).getKnockedDown())
|
|
|
|
return mSourceModel->onTakeItem(item, count);
|
|
|
|
|
2017-10-05 11:12:43 +04:00
|
|
|
bool success = stealItem(item, count);
|
|
|
|
if (success)
|
|
|
|
{
|
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
|
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
2017-10-04 23:26:06 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool PickpocketItemModel::stealItem(const MWWorld::Ptr &item, int count)
|
|
|
|
{
|
2017-10-04 21:25:22 +04:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
|
|
MWMechanics::Pickpocket pickpocket(player, mActor);
|
|
|
|
if (pickpocket.pick(item, count))
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
2019-09-23 23:56:37 +03:00
|
|
|
player, mActor, MWBase::MechanicsManager::OT_Pickpocket, std::string(), 0, true);
|
2017-10-04 21:25:22 +04:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
2017-10-04 23:26:06 +04:00
|
|
|
mPickpocketDetected = true;
|
2017-10-04 21:25:22 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-05-11 18:38:27 +02:00
|
|
|
}
|