forked from teamnwah/openmw-tes3coop
Merge pull request #1549 from akortunov/itemmodels
Item models reworking
This commit is contained in:
commit
98b4f9c596
15 changed files with 265 additions and 130 deletions
|
@ -140,7 +140,7 @@ namespace MWBase
|
|||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||
/// @param container The container the item is in; may be empty for an item in the world
|
||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
|
||||
int count) = 0;
|
||||
int count, bool alarm = true) = 0;
|
||||
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0;
|
||||
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
||||
|
@ -238,6 +238,7 @@ namespace MWBase
|
|||
/// Has the player stolen this item from the given owner?
|
||||
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
|
||||
|
||||
virtual bool isBoundItem(const MWWorld::Ptr& item) = 0;
|
||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0;
|
||||
|
||||
/// Turn actor into werewolf or normal form.
|
||||
|
@ -250,7 +251,6 @@ namespace MWBase
|
|||
virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) = 0;
|
||||
|
||||
virtual void confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) = 0;
|
||||
|
||||
virtual bool isAttackPrepairing(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual bool isRunning(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0;
|
||||
|
|
|
@ -8,12 +8,10 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/dialoguemanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
#include "../mwmechanics/pickpocket.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "countdialog.hpp"
|
||||
|
@ -33,7 +31,6 @@ namespace MWGui
|
|||
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
|
||||
: WindowBase("openmw_container_window.layout")
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mPickpocketDetected(false)
|
||||
, mSortModel(NULL)
|
||||
, mModel(NULL)
|
||||
, mSelectedItem(-1)
|
||||
|
@ -55,9 +52,8 @@ namespace MWGui
|
|||
|
||||
void ContainerWindow::onItemSelected(int index)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
if (mDragAndDrop->mIsOnDragAndDrop && mModel)
|
||||
{
|
||||
if (mModel && mModel->allowedToInsertItems())
|
||||
dropItem();
|
||||
return;
|
||||
}
|
||||
|
@ -100,39 +96,20 @@ namespace MWGui
|
|||
|
||||
void ContainerWindow::dropItem()
|
||||
{
|
||||
if (mPtr.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
// check container organic flag
|
||||
MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
|
||||
if (ref->mBase->mFlags & ESM::Container::Organic)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sContentsMessage2}");
|
||||
return;
|
||||
}
|
||||
|
||||
// check that we don't exceed container capacity
|
||||
MWWorld::Ptr item = mDragAndDrop->mItem.mBase;
|
||||
float weight = item.getClass().getWeight(item) * mDragAndDrop->mDraggedCount;
|
||||
if (mPtr.getClass().getCapacity(mPtr) < mPtr.getClass().getEncumbrance(mPtr) + weight)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount);
|
||||
|
||||
if (success)
|
||||
mDragAndDrop->drop(mModel, mItemView);
|
||||
}
|
||||
|
||||
void ContainerWindow::onBackgroundSelected()
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop && mModel && mModel->allowedToInsertItems())
|
||||
if (mDragAndDrop->mIsOnDragAndDrop && mModel)
|
||||
dropItem();
|
||||
}
|
||||
|
||||
void ContainerWindow::setPtr(const MWWorld::Ptr& container)
|
||||
{
|
||||
mPickpocketDetected = false;
|
||||
mPtr = container;
|
||||
|
||||
bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead();
|
||||
|
@ -142,8 +119,7 @@ namespace MWGui
|
|||
if (mPtr.getClass().isNpc() && !loot)
|
||||
{
|
||||
// we are stealing stuff
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
mModel = new PickpocketItemModel(player, new InventoryItemModel(container),
|
||||
mModel = new PickpocketItemModel(mPtr, new InventoryItemModel(container),
|
||||
!mPtr.getClass().getCreatureStats(mPtr).getKnockedDown());
|
||||
}
|
||||
else
|
||||
|
@ -178,24 +154,7 @@ namespace MWGui
|
|||
{
|
||||
WindowBase::onClose();
|
||||
|
||||
if (dynamic_cast<PickpocketItemModel*>(mModel)
|
||||
// Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened)
|
||||
&& !MWBase::Environment::get().getWindowManager()->containsMode(GM_Container)
|
||||
// If it was already detected while taking an item, no need to check now
|
||||
&& !mPickpocketDetected
|
||||
)
|
||||
{
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
||||
if (pickpocket.finish())
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
||||
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||
mPickpocketDetected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
mModel->onClose();
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -271,32 +230,7 @@ namespace MWGui
|
|||
|
||||
bool ContainerWindow::onTakeItem(const ItemStack &item, int count)
|
||||
{
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
// TODO: move to ItemModels
|
||||
if (dynamic_cast<PickpocketItemModel*>(mModel)
|
||||
&& !mPtr.getClass().getCreatureStats(mPtr).getKnockedDown())
|
||||
{
|
||||
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
||||
if (pickpocket.pick(item.mBase, count))
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
||||
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||
mPickpocketDetected = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Looting a dead corpse is considered OK
|
||||
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
|
||||
return true;
|
||||
else
|
||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, mPtr, count);
|
||||
}
|
||||
return true;
|
||||
return mModel->onTakeItem(item.mBase, count);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,8 +44,6 @@ namespace MWGui
|
|||
private:
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
bool mPickpocketDetected;
|
||||
|
||||
MWGui::ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
ItemModel* mModel;
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
|
@ -185,5 +189,51 @@ void ContainerItemModel::update()
|
|||
}
|
||||
}
|
||||
}
|
||||
bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
if (mItemSources.empty())
|
||||
return false;
|
||||
|
||||
MWWorld::Ptr target = mItemSources[0];
|
||||
|
||||
if (target.getTypeName() != typeid(ESM::Container).name())
|
||||
return true;
|
||||
|
||||
// check container organic flag
|
||||
MWWorld::LiveCellRef<ESM::Container>* ref = target.get<ESM::Container>();
|
||||
if (ref->mBase->mFlags & ESM::Container::Organic)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sContentsMessage2}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check that we don't exceed container capacity
|
||||
float weight = item.getClass().getWeight(item) * count;
|
||||
if (target.getClass().getCapacity(target) < target.getClass().getEncumbrance(target) + weight)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
if (mItemSources.empty())
|
||||
return false;
|
||||
|
||||
MWWorld::Ptr target = mItemSources[0];
|
||||
|
||||
// Looting a dead corpse is considered OK
|
||||
if (target.getClass().isActor() && target.getClass().getCreatureStats(target).isDead())
|
||||
return true;
|
||||
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, target, count);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ namespace MWGui
|
|||
ContainerItemModel (const MWWorld::Ptr& source);
|
||||
|
||||
virtual bool allowedToUseItems() const;
|
||||
|
||||
virtual bool onDropItem(const MWWorld::Ptr &item, int count);
|
||||
virtual bool onTakeItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
virtual ItemStack getItem (ModelIndex index);
|
||||
virtual ModelIndex getIndex (ItemStack item);
|
||||
virtual size_t getItemCount();
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -116,4 +119,16 @@ void InventoryItemModel::update()
|
|||
}
|
||||
}
|
||||
|
||||
bool InventoryItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
// Looting a dead corpse is considered OK
|
||||
if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead())
|
||||
return true;
|
||||
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace MWGui
|
|||
virtual ModelIndex getIndex (ItemStack item);
|
||||
virtual size_t getItemCount();
|
||||
|
||||
virtual bool onTakeItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -23,38 +24,7 @@ namespace MWGui
|
|||
if (base.getClass().getEnchantment(base) != "")
|
||||
mFlags |= Flag_Enchanted;
|
||||
|
||||
static std::set<std::string> boundItemIDCache;
|
||||
|
||||
// If this is empty then we haven't executed the GMST cache logic yet; or there isn't any sMagicBound* GMST's for some reason
|
||||
if (boundItemIDCache.empty())
|
||||
{
|
||||
// Build a list of known bound item ID's
|
||||
const MWWorld::Store<ESM::GameSetting> &gameSettings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
for (MWWorld::Store<ESM::GameSetting>::iterator currentIteration = gameSettings.begin(); currentIteration != gameSettings.end(); ++currentIteration)
|
||||
{
|
||||
const ESM::GameSetting ¤tSetting = *currentIteration;
|
||||
std::string currentGMSTID = currentSetting.mId;
|
||||
Misc::StringUtils::lowerCaseInPlace(currentGMSTID);
|
||||
|
||||
// Don't bother checking this GMST if it's not a sMagicBound* one.
|
||||
const std::string& toFind = "smagicbound";
|
||||
if (currentGMSTID.compare(0, toFind.length(), toFind) != 0)
|
||||
continue;
|
||||
|
||||
// All sMagicBound* GMST's should be of type string
|
||||
std::string currentGMSTValue = currentSetting.getString();
|
||||
Misc::StringUtils::lowerCaseInPlace(currentGMSTValue);
|
||||
|
||||
boundItemIDCache.insert(currentGMSTValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform bound item check and assign the Flag_Bound bit if it passes
|
||||
std::string tempItemID = base.getCellRef().getRefId();
|
||||
Misc::StringUtils::lowerCaseInPlace(tempItemID);
|
||||
|
||||
if (boundItemIDCache.count(tempItemID) != 0)
|
||||
if (MWBase::Environment::get().getMechanicsManager()->isBoundItem(base))
|
||||
mFlags |= Flag_Bound;
|
||||
}
|
||||
|
||||
|
@ -124,7 +94,12 @@ namespace MWGui
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ItemModel::allowedToInsertItems() const
|
||||
bool ItemModel::onDropItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -198,4 +173,18 @@ namespace MWGui
|
|||
mSourceModel = sourceModel;
|
||||
}
|
||||
|
||||
void ProxyItemModel::onClose()
|
||||
{
|
||||
mSourceModel->onClose();
|
||||
}
|
||||
|
||||
bool ProxyItemModel::onDropItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
return mSourceModel->onDropItem(item, count);
|
||||
}
|
||||
|
||||
bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
return mSourceModel->onTakeItem(item, count);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,9 +72,11 @@ namespace MWGui
|
|||
|
||||
/// Is the player allowed to use items from this item model? (default true)
|
||||
virtual bool allowedToUseItems() const;
|
||||
|
||||
/// Is the player allowed to insert items into this model? (default true)
|
||||
virtual bool allowedToInsertItems() const;
|
||||
virtual void onClose()
|
||||
{
|
||||
}
|
||||
virtual bool onDropItem(const MWWorld::Ptr &item, int count);
|
||||
virtual bool onTakeItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
private:
|
||||
ItemModel(const ItemModel&);
|
||||
|
@ -91,6 +93,10 @@ namespace MWGui
|
|||
|
||||
bool allowedToUseItems() const;
|
||||
|
||||
virtual void onClose();
|
||||
virtual bool onDropItem(const MWWorld::Ptr &item, int count);
|
||||
virtual bool onTakeItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
virtual ModelIndex getIndex (ItemStack item);
|
||||
|
|
|
@ -3,15 +3,26 @@
|
|||
#include <components/misc/rng.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/pickpocket.hpp"
|
||||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel, bool hideItems)
|
||||
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& actor, ItemModel *sourceModel, bool hideItems)
|
||||
: mActor(actor), mPickpocketDetected(false)
|
||||
{
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
mSourceModel = sourceModel;
|
||||
int chance = thief.getClass().getSkill(thief, ESM::Skill::Sneak);
|
||||
int chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
|
||||
|
||||
mSourceModel->update();
|
||||
|
||||
|
@ -66,13 +77,63 @@ namespace MWGui
|
|||
void PickpocketItemModel::removeItem (const ItemStack &item, size_t count)
|
||||
{
|
||||
ProxyItemModel::removeItem(item, count);
|
||||
/// \todo check if player is detected
|
||||
}
|
||||
|
||||
bool PickpocketItemModel::allowedToInsertItems() const
|
||||
bool PickpocketItemModel::onDropItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
// don't allow "reverse pickpocket" (yet)
|
||||
// don't allow "reverse pickpocket" (it will be handled by scripts after 1.0)
|
||||
return false;
|
||||
}
|
||||
|
||||
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, 0, true);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||
mPickpocketDetected = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool PickpocketItemModel::stealItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
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, 0, true);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||
mPickpocketDetected = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@ namespace MWGui
|
|||
virtual size_t getItemCount();
|
||||
virtual void update();
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
virtual bool allowedToInsertItems() const;
|
||||
virtual void onClose();
|
||||
virtual bool onDropItem(const MWWorld::Ptr &item, int count);
|
||||
virtual bool onTakeItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
protected:
|
||||
MWWorld::Ptr mActor;
|
||||
bool mPickpocketDetected;
|
||||
bool stealItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
private:
|
||||
std::vector<ItemStack> mHiddenItems;
|
||||
|
|
|
@ -311,4 +311,18 @@ namespace MWGui
|
|||
std::sort(mItems.begin(), mItems.end(), cmp);
|
||||
}
|
||||
|
||||
void SortFilterItemModel::onClose()
|
||||
{
|
||||
mSourceModel->onClose();
|
||||
}
|
||||
|
||||
bool SortFilterItemModel::onDropItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
return mSourceModel->onDropItem(item, count);
|
||||
}
|
||||
|
||||
bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count)
|
||||
{
|
||||
return mSourceModel->onTakeItem(item, count);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace MWGui
|
|||
/// Use ItemStack::Type for sorting?
|
||||
void setSortByType(bool sort) { mSortByType = sort; }
|
||||
|
||||
void onClose();
|
||||
bool onDropItem(const MWWorld::Ptr &item, int count);
|
||||
bool onTakeItem(const MWWorld::Ptr &item, int count);
|
||||
|
||||
static const int Category_Weapon = (1<<1);
|
||||
static const int Category_Apparel = (1<<2);
|
||||
static const int Category_Misc = (1<<3);
|
||||
|
|
|
@ -840,6 +840,45 @@ namespace MWMechanics
|
|||
mAI = true;
|
||||
}
|
||||
|
||||
bool MechanicsManager::isBoundItem(const MWWorld::Ptr& item)
|
||||
{
|
||||
static std::set<std::string> boundItemIDCache;
|
||||
|
||||
// If this is empty then we haven't executed the GMST cache logic yet; or there isn't any sMagicBound* GMST's for some reason
|
||||
if (boundItemIDCache.empty())
|
||||
{
|
||||
// Build a list of known bound item ID's
|
||||
const MWWorld::Store<ESM::GameSetting> &gameSettings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
for (MWWorld::Store<ESM::GameSetting>::iterator currentIteration = gameSettings.begin(); currentIteration != gameSettings.end(); ++currentIteration)
|
||||
{
|
||||
const ESM::GameSetting ¤tSetting = *currentIteration;
|
||||
std::string currentGMSTID = currentSetting.mId;
|
||||
Misc::StringUtils::lowerCaseInPlace(currentGMSTID);
|
||||
|
||||
// Don't bother checking this GMST if it's not a sMagicBound* one.
|
||||
const std::string& toFind = "smagicbound";
|
||||
if (currentGMSTID.compare(0, toFind.length(), toFind) != 0)
|
||||
continue;
|
||||
|
||||
// All sMagicBound* GMST's should be of type string
|
||||
std::string currentGMSTValue = currentSetting.getString();
|
||||
Misc::StringUtils::lowerCaseInPlace(currentGMSTValue);
|
||||
|
||||
boundItemIDCache.insert(currentGMSTValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform bound item check and assign the Flag_Bound bit if it passes
|
||||
std::string tempItemID = item.getCellRef().getRefId();
|
||||
Misc::StringUtils::lowerCaseInPlace(tempItemID);
|
||||
|
||||
if (boundItemIDCache.count(tempItemID) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim)
|
||||
{
|
||||
if (target.isEmpty())
|
||||
|
@ -1024,7 +1063,7 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, const MWWorld::Ptr& container,
|
||||
int count)
|
||||
int count, bool alarm)
|
||||
{
|
||||
if (ptr != getPlayer())
|
||||
return;
|
||||
|
@ -1053,18 +1092,28 @@ namespace MWMechanics
|
|||
return;
|
||||
|
||||
Owner owner;
|
||||
owner.first = ownerCellRef->getOwner();
|
||||
owner.second = false;
|
||||
if (!container.isEmpty() && container.getClass().isActor())
|
||||
{
|
||||
// "container" is an actor inventory, so just take actor's ID
|
||||
owner.first = ownerCellRef->getRefId();
|
||||
}
|
||||
else
|
||||
{
|
||||
owner.first = ownerCellRef->getOwner();
|
||||
if (owner.first.empty())
|
||||
{
|
||||
owner.first = ownerCellRef->getFaction();
|
||||
owner.second = true;
|
||||
}
|
||||
}
|
||||
|
||||
Misc::StringUtils::lowerCaseInPlace(owner.first);
|
||||
|
||||
if (!Misc::StringUtils::ciEqual(item.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId))
|
||||
mStolenItems[Misc::StringUtils::lowerCase(item.getCellRef().getRefId())][owner] += count;
|
||||
|
||||
if (alarm)
|
||||
commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count);
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace MWMechanics
|
|||
/// Utility to check if taking this item is illegal and calling commitCrime if so
|
||||
/// @param container The container the item is in; may be empty for an item in the world
|
||||
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container,
|
||||
int count);
|
||||
int count, bool alarm = true);
|
||||
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
|
||||
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item);
|
||||
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
|
||||
|
@ -204,6 +204,8 @@ namespace MWMechanics
|
|||
/// Has the player stolen this item from the given owner?
|
||||
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid);
|
||||
|
||||
virtual bool isBoundItem(const MWWorld::Ptr& item);
|
||||
|
||||
/// @return is \a ptr allowed to take/use \a target or is it a crime?
|
||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim);
|
||||
|
||||
|
|
Loading…
Reference in a new issue