1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-17 19:10:24 +00:00
OpenMW/apps/openmw/mwgui/pickpocketitemmodel.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

142 lines
4.7 KiB
C++
Raw Normal View History

2013-05-11 16:38:27 +00:00
#include "pickpocketitemmodel.hpp"
#include <components/esm3/loadskil.hpp>
2015-04-22 15:58:55 +00:00
#include <components/misc/rng.hpp>
2017-10-04 17:25:22 +00:00
#include "../mwmechanics/actorutil.hpp"
2017-10-04 18:37:08 +00:00
#include "../mwmechanics/creaturestats.hpp"
2017-10-04 17:25:22 +00:00
#include "../mwmechanics/pickpocket.hpp"
2013-05-11 16:38:27 +00:00
#include "../mwworld/class.hpp"
2017-10-04 17:25:22 +00:00
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
2017-10-04 17:25:22 +00:00
2013-05-11 16:38:27 +00:00
namespace MWGui
{
2022-08-31 16:49:50 +00:00
PickpocketItemModel::PickpocketItemModel(
const MWWorld::Ptr& actor, std::unique_ptr<ItemModel> sourceModel, bool hideItems)
2017-10-04 19:26:06 +00:00
: mActor(actor)
, mPickpocketDetected(false)
2013-05-11 16:38:27 +00:00
{
2017-10-04 17:25:22 +00:00
MWWorld::Ptr player = MWMechanics::getPlayer();
2022-08-31 16:49:50 +00:00
mSourceModel = std::move(sourceModel);
float chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
2013-05-11 16:38:27 +00:00
mSourceModel->update();
// build list of items that player is unable to find when attempts to pickpocket.
if (hideItems)
2013-05-11 16:38:27 +00:00
{
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
for (size_t i = 0; i < mSourceModel->getItemCount(); ++i)
{
if (Misc::Rng::roll0to99(prng) > chance)
mHiddenItems.push_back(mSourceModel->getItem(i));
}
2013-05-11 16:38:27 +00:00
}
}
bool PickpocketItemModel::allowedToUseItems() const
{
return false;
}
2013-05-11 16:38:27 +00: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);
// Bound items may not be stolen
if (item.mFlags & ItemStack::Flag_Bound)
continue;
2013-05-11 16:38:27 +00: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 18:37:08 +00: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 18:53:24 +00:00
return false;
}
2017-10-04 19:26:06 +00: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(
player, mActor, MWBase::MechanicsManager::OT_Pickpocket, ESM::RefId(), 0, true);
2017-10-04 19:26:06 +00:00
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
mPickpocketDetected = true;
}
}
bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr& item, int count)
2017-10-04 17:25:22 +00:00
{
2017-10-04 18:37:08 +00:00
if (mActor.getClass().getCreatureStats(mActor).getKnockedDown())
return mSourceModel->onTakeItem(item, count);
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 19:26:06 +00:00
}
bool PickpocketItemModel::stealItem(const MWWorld::Ptr& item, int count)
{
2017-10-04 17:25:22 +00:00
MWWorld::Ptr player = MWMechanics::getPlayer();
MWMechanics::Pickpocket pickpocket(player, mActor);
if (pickpocket.pick(item, count))
{
MWBase::Environment::get().getMechanicsManager()->commitCrime(
player, mActor, MWBase::MechanicsManager::OT_Pickpocket, ESM::RefId(), 0, true);
2017-10-04 17:25:22 +00:00
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
2017-10-04 19:26:06 +00:00
mPickpocketDetected = true;
2017-10-04 17:25:22 +00:00
return false;
}
else
2024-01-14 19:33:23 +00:00
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, ESM::Skill::Sneak_PickPocket);
2017-10-04 17:25:22 +00:00
return true;
}
2013-05-11 16:38:27 +00:00
}