2013-05-11 18:38:27 +02:00
|
|
|
#include "inventoryitemmodel.hpp"
|
|
|
|
|
2017-09-11 14:49:55 +04:00
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
|
|
|
#include "../mwmechanics/npcstats.hpp"
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
#include "../mwworld/containerstore.hpp"
|
|
|
|
#include "../mwworld/inventorystore.hpp"
|
|
|
|
|
2017-10-04 21:25:22 +04:00
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
namespace MWGui
|
|
|
|
{
|
|
|
|
|
|
|
|
InventoryItemModel::InventoryItemModel(const MWWorld::Ptr& actor)
|
2019-03-02 13:27:59 +04:00
|
|
|
: mActor(actor)
|
2013-05-11 18:38:27 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemStack InventoryItemModel::getItem(ModelIndex index)
|
2017-09-11 14:49:55 +04:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
if (index < 0)
|
2017-09-11 14:49:55 +04:00
|
|
|
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];
|
|
|
|
}
|
2022-09-22 21:26:05 +03:00
|
|
|
|
2017-09-11 14:49:55 +04:00
|
|
|
size_t InventoryItemModel::getItemCount()
|
|
|
|
{
|
|
|
|
return mItems.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemModel::ModelIndex InventoryItemModel::getIndex(const ItemStack& item)
|
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
for (ItemStack& itemStack : mItems)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2019-03-02 13:27:59 +04:00
|
|
|
if (itemStack == item)
|
2017-09-11 14:49:55 +04:00
|
|
|
return i;
|
2022-09-22 21:26:05 +03:00
|
|
|
++i;
|
|
|
|
}
|
2017-09-11 14:49:55 +04:00
|
|
|
return -1;
|
|
|
|
}
|
2022-09-22 21:26:05 +03:00
|
|
|
|
2023-07-08 17:10:07 +02:00
|
|
|
MWWorld::Ptr InventoryItemModel::addItem(const ItemStack& item, size_t count, bool allowAutoEquip)
|
2017-09-11 14:49:55 +04:00
|
|
|
{
|
|
|
|
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
|
2023-07-08 17:10:07 +02:00
|
|
|
throw std::runtime_error("Item to add needs to be from a different container!");
|
2023-01-16 23:51:04 +01:00
|
|
|
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, allowAutoEquip);
|
2017-09-11 14:49:55 +04:00
|
|
|
}
|
2014-09-10 23:38:38 -04:00
|
|
|
|
2019-10-05 16:47:41 +04:00
|
|
|
void InventoryItemModel::removeItem(const ItemStack& item, size_t count)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-09-11 14:49:55 +04:00
|
|
|
int removed = 0;
|
2019-10-05 16:47:41 +04:00
|
|
|
// Re-equipping makes sense only if a target has inventory
|
2017-09-11 14:49:55 +04:00
|
|
|
if (mActor.getClass().hasInventoryStore(mActor))
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2016-10-31 00:23:51 +09:00
|
|
|
MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor);
|
2023-01-16 23:51:04 +01:00
|
|
|
removed = store.remove(item.mBase, count, true);
|
2022-09-22 21:26:05 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-10-05 16:47:41 +04:00
|
|
|
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
|
2023-01-16 23:51:04 +01:00
|
|
|
removed = store.remove(item.mBase, count);
|
2014-04-27 05:40:07 +02:00
|
|
|
}
|
|
|
|
|
2014-05-22 20:37:22 +02:00
|
|
|
std::stringstream error;
|
2013-05-11 18:38:27 +02:00
|
|
|
|
2013-08-13 01:19:33 +02:00
|
|
|
if (removed == 0)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
error << "Item '" << item.mBase.getCellRef().getRefId() << "' was not found in container store to remove";
|
|
|
|
throw std::runtime_error(error.str());
|
2022-09-22 21:26:05 +03:00
|
|
|
}
|
2013-11-12 22:58:56 +01:00
|
|
|
else if (removed < static_cast<int>(count))
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
error << "Not enough items '" << item.mBase.getCellRef().getRefId() << "' in the stack to remove ("
|
2017-09-11 14:49:55 +04:00
|
|
|
<< static_cast<int>(count) << " requested, " << removed << " found)";
|
|
|
|
throw std::runtime_error(error.str());
|
2022-09-22 21:26:05 +03:00
|
|
|
}
|
|
|
|
}
|
2013-05-11 18:38:27 +02:00
|
|
|
|
2023-07-15 18:59:16 +02:00
|
|
|
MWWorld::Ptr InventoryItemModel::moveItem(
|
|
|
|
const ItemStack& item, size_t count, ItemModel* otherModel, bool allowAutoEquip)
|
2013-05-11 18:38:27 +02:00
|
|
|
{
|
2013-08-08 16:05:26 -07:00
|
|
|
// Can't move conjured items: This is a general fix that also takes care of issues with taking conjured items
|
2014-09-10 23:38:38 -04:00
|
|
|
// via the 'Take All' button.
|
2014-09-13 18:59:13 -04:00
|
|
|
if (item.mFlags & ItemStack::Flag_Bound)
|
2014-09-10 23:38:38 -04:00
|
|
|
return MWWorld::Ptr();
|
2022-09-22 21:26:05 +03:00
|
|
|
|
2023-07-15 18:19:52 +02:00
|
|
|
return ItemModel::moveItem(item, count, otherModel, allowAutoEquip);
|
2022-09-22 21:26:05 +03:00
|
|
|
}
|
2016-09-24 18:01:31 +02:00
|
|
|
|
|
|
|
void InventoryItemModel::update()
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2016-09-24 18:01:31 +02:00
|
|
|
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
|
2013-08-08 16:05:26 -07:00
|
|
|
|
|
|
|
mItems.clear();
|
2013-05-11 18:38:27 +02:00
|
|
|
|
2014-01-19 11:42:58 +01:00
|
|
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
2013-05-11 18:38:27 +02:00
|
|
|
{
|
2016-10-31 00:23:51 +09:00
|
|
|
MWWorld::Ptr item = *it;
|
2022-09-22 21:26:05 +03:00
|
|
|
|
2016-10-31 00:23:51 +09:00
|
|
|
if (!item.getClass().showsInInventory(item))
|
|
|
|
continue;
|
2013-05-11 18:38:27 +02:00
|
|
|
|
2013-08-08 16:05:26 -07:00
|
|
|
ItemStack newItem(item, this, item.getRefData().getCount());
|
2022-09-22 21:26:05 +03:00
|
|
|
|
2017-09-11 14:49:55 +04:00
|
|
|
if (mActor.getClass().hasInventoryStore(mActor))
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-09-11 14:49:55 +04:00
|
|
|
MWWorld::InventoryStore& invStore = mActor.getClass().getInventoryStore(mActor);
|
2016-10-31 00:23:51 +09:00
|
|
|
if (invStore.isEquipped(newItem.mBase))
|
2014-12-15 13:47:34 +01:00
|
|
|
newItem.mType = ItemStack::Type_Equipped;
|
2022-09-22 21:26:05 +03:00
|
|
|
}
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
mItems.push_back(newItem);
|
2022-09-22 21:26:05 +03:00
|
|
|
}
|
2013-05-11 18:38:27 +02:00
|
|
|
}
|
|
|
|
|
2017-10-04 23:26:06 +04:00
|
|
|
bool InventoryItemModel::onTakeItem(const MWWorld::Ptr& item, int count)
|
2017-10-04 21:25:22 +04:00
|
|
|
{
|
|
|
|
// Looting a dead corpse is considered OK
|
|
|
|
if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead())
|
|
|
|
return true;
|
2017-10-04 22:37:08 +04:00
|
|
|
|
2017-10-04 21:25:22 +04:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
|
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-07-15 22:31:26 +02:00
|
|
|
bool InventoryItemModel::usesContainer(const MWWorld::Ptr& container)
|
|
|
|
{
|
|
|
|
return mActor == container;
|
|
|
|
}
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
}
|