mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 23:49:55 +00:00
1e4a854433
It was just adding a level of indirection to Ptr.getClass(). All the call were replaced by that instead. The number of lines changed is important, but the change itself is trivial, so everything should be fine. :)
168 lines
5.3 KiB
C++
168 lines
5.3 KiB
C++
#include "containeritemmodel.hpp"
|
|
|
|
#include "../mwworld/containerstore.hpp"
|
|
#include "../mwworld/class.hpp"
|
|
|
|
#include "../mwbase/world.hpp"
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
namespace
|
|
{
|
|
|
|
bool stacks (const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
|
{
|
|
if (left == right)
|
|
return true;
|
|
|
|
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
|
if (left.getContainerStore() && right.getContainerStore())
|
|
return left.getContainerStore()->stacks(left, right)
|
|
&& right.getContainerStore()->stacks(left, right);
|
|
|
|
if (left.getContainerStore())
|
|
return left.getContainerStore()->stacks(left, right);
|
|
if (right.getContainerStore())
|
|
return right.getContainerStore()->stacks(left, right);
|
|
|
|
MWWorld::ContainerStore store;
|
|
return store.stacks(left, right);
|
|
}
|
|
|
|
}
|
|
|
|
namespace MWGui
|
|
{
|
|
|
|
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems)
|
|
: mItemSources(itemSources)
|
|
, mWorldItems(worldItems)
|
|
{
|
|
assert (mItemSources.size());
|
|
}
|
|
|
|
ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source)
|
|
{
|
|
mItemSources.push_back(source);
|
|
}
|
|
|
|
ItemStack ContainerItemModel::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 ContainerItemModel::getItemCount()
|
|
{
|
|
return mItems.size();
|
|
}
|
|
|
|
ItemModel::ModelIndex ContainerItemModel::getIndex (ItemStack item)
|
|
{
|
|
size_t i = 0;
|
|
for (std::vector<ItemStack>::iterator it = mItems.begin(); it != mItems.end(); ++it)
|
|
{
|
|
if (*it == item)
|
|
return i;
|
|
++i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
MWWorld::Ptr ContainerItemModel::copyItem (const ItemStack& item, size_t count, bool setNewOwner)
|
|
{
|
|
const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1];
|
|
if (item.mBase.getContainerStore() == &source.getClass().getContainerStore(source))
|
|
throw std::runtime_error("Item to copy needs to be from a different container!");
|
|
return *source.getClass().getContainerStore(source).add(item.mBase, count, source);
|
|
}
|
|
|
|
void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
|
{
|
|
int toRemove = count;
|
|
|
|
for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
|
|
{
|
|
MWWorld::ContainerStore& store = source->getClass().getContainerStore(*source);
|
|
|
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
|
{
|
|
if (stacks(*it, item.mBase))
|
|
{
|
|
toRemove -= store.remove(*it, toRemove, *source);
|
|
if (toRemove <= 0)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
|
{
|
|
if (stacks(*source, item.mBase))
|
|
{
|
|
int refCount = source->getRefData().getCount();
|
|
if (refCount - toRemove <= 0)
|
|
MWBase::Environment::get().getWorld()->deleteObject(*source);
|
|
else
|
|
source->getRefData().setCount(std::max(0, refCount - toRemove));
|
|
toRemove -= refCount;
|
|
if (toRemove <= 0)
|
|
return;
|
|
}
|
|
}
|
|
|
|
throw std::runtime_error("Not enough items to remove could be found");
|
|
}
|
|
|
|
void ContainerItemModel::update()
|
|
{
|
|
mItems.clear();
|
|
for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
|
|
{
|
|
MWWorld::ContainerStore& store = source->getClass().getContainerStore(*source);
|
|
|
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
|
{
|
|
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
|
for (; itemStack != mItems.end(); ++itemStack)
|
|
{
|
|
if (stacks(*it, itemStack->mBase))
|
|
{
|
|
// we already have an item stack of this kind, add to it
|
|
itemStack->mCount += it->getRefData().getCount();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (itemStack == mItems.end())
|
|
{
|
|
// no stack yet, create one
|
|
ItemStack newItem (*it, this, it->getRefData().getCount());
|
|
mItems.push_back(newItem);
|
|
}
|
|
}
|
|
}
|
|
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
|
{
|
|
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
|
for (; itemStack != mItems.end(); ++itemStack)
|
|
{
|
|
if (stacks(*source, itemStack->mBase))
|
|
{
|
|
// we already have an item stack of this kind, add to it
|
|
itemStack->mCount += source->getRefData().getCount();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (itemStack == mItems.end())
|
|
{
|
|
// no stack yet, create one
|
|
ItemStack newItem (*source, this, source->getRefData().getCount());
|
|
mItems.push_back(newItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|