Use copyItem() when not moving full stack.

revert-6246b479
Mads Buvik Sandvei 1 year ago
parent b8a9fcad68
commit fe0b640f85

@ -33,6 +33,14 @@ namespace MWGui
return InventoryItemModel::addItem(item, count, allowAutoEquip);
}
MWWorld::Ptr CompanionItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{
if (hasProfit(mActor))
modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count);
return InventoryItemModel::copyItem(item, count, allowAutoEquip);
}
void CompanionItemModel::removeItem(const ItemStack& item, size_t count)
{
if (hasProfit(mActor))

@ -14,6 +14,7 @@ namespace MWGui
CompanionItemModel(const MWWorld::Ptr& actor);
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override;
bool hasProfit(const MWWorld::Ptr& actor);

@ -104,10 +104,19 @@ namespace MWGui
auto& source = mItemSources[0];
MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first);
if (item.mBase.getContainerStore() == &store)
throw std::runtime_error("Item needs to be from a different container!");
throw std::runtime_error("Item to add needs to be from a different container!");
return *store.add(item.mBase, count, allowAutoEquip);
}
MWWorld::Ptr ContainerItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{
auto& source = mItemSources[0];
MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first);
if (item.mBase.getContainerStore() == &store)
throw std::runtime_error("Item to copy needs to be from a different container!");
return *store.add(item.mBase.getCellRef().getRefId(), count, allowAutoEquip);
}
void ContainerItemModel::removeItem(const ItemStack& item, size_t count)
{
int toRemove = count;

@ -33,6 +33,7 @@ namespace MWGui
size_t getItemCount() override;
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override;
void update() override;

@ -46,20 +46,30 @@ namespace MWGui
}
virtual ~WorldItemModel() override {}
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
MWWorld::Ptr dropItemImpl(const ItemStack& item, size_t count, bool copy)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::Ptr dropped;
if (world->canPlaceObject(mLeft, mTop))
dropped = world->placeObject(item.mBase, mLeft, mTop, count, false);
dropped = world->placeObject(item.mBase, mLeft, mTop, count, copy);
else
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count, false);
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count, copy);
dropped.getCellRef().setOwner(ESM::RefId());
return dropped;
}
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
{
return dropItemImpl(item, count, false);
}
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
{
return dropItemImpl(item, count, true);
}
void removeItem(const ItemStack& item, size_t count) override
{
throw std::runtime_error("removeItem not implemented");

@ -8,6 +8,7 @@
#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
@ -53,6 +54,14 @@ namespace MWGui
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, allowAutoEquip);
}
MWWorld::Ptr InventoryItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
throw std::runtime_error("Item to copy needs to be from a different container!");
return *mActor.getClass().getContainerStore(mActor).add(
item.mBase.getCellRef().getRefId(), count, allowAutoEquip);
}
void InventoryItemModel::removeItem(const ItemStack& item, size_t count)
{
int removed = 0;

@ -18,6 +18,7 @@ namespace MWGui
bool onTakeItem(const MWWorld::Ptr& item, int count) override;
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override;
/// Move items from this model to \a otherModel.

@ -7,6 +7,8 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include <components/debug/debuglog.hpp>
namespace MWGui
{
@ -58,16 +60,19 @@ namespace MWGui
MWWorld::Ptr ItemModel::moveItem(const ItemStack& item, size_t count, ItemModel* otherModel, bool allowAutoEquip)
{
MWWorld::Ptr ret = otherModel->addItem(item, count, allowAutoEquip);
removeItem(item, count);
// Although logically the same as an unstack, to avoid unneccesarily allocating a new stack
// and then immediately removing it, we assign a new refnum here instead of calling unstack()
if (!item.mBase.getRefData().isDeleted())
MWWorld::Ptr ret = MWWorld::Ptr();
if (item.mBase.getRefData().getCount() <= count)
{
// We are moving the full stack
ret = otherModel->addItem(item, count, allowAutoEquip);
removeItem(item, count);
}
else
{
ret.getCellRef().unsetRefNum();
ret.getRefData().setLuaScripts(nullptr);
MWBase::Environment::get().getWorldModel()->registerPtr(ret);
MWBase::Environment::get().getWorldModel()->registerPtr(item.mBase);
// We are moving only part of the stack, so create a copy in the other model
// and then remove count from this model.
ret = otherModel->copyItem(item, count, allowAutoEquip);
removeItem(item, count);
}
return ret;
}
@ -92,6 +97,11 @@ namespace MWGui
return mSourceModel->allowedToUseItems();
}
MWWorld::Ptr ProxyItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{
return mSourceModel->copyItem(item, count, allowAutoEquip);
}
void ProxyItemModel::removeItem(const ItemStack& item, size_t count)
{
mSourceModel->removeItem(item, count);

@ -67,6 +67,7 @@ namespace MWGui
const ItemStack& item, size_t count, ItemModel* otherModel, bool allowAutoEquip = true);
virtual MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) = 0;
virtual MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) = 0;
virtual void removeItem(const ItemStack& item, size_t count) = 0;
/// Is the player allowed to use items from this item model? (default true)
@ -97,6 +98,7 @@ namespace MWGui
bool onTakeItem(const MWWorld::Ptr& item, int count) override;
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override;
ModelIndex getIndex(const ItemStack& item) override;

@ -300,10 +300,10 @@ bool MWWorld::ContainerStore::stacks(const ConstPtr& ptr1, const ConstPtr& ptr2)
&& cls2.getItemHealth(ptr2) == cls2.getItemMaxHealth(ptr2)));
}
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const ESM::RefId& id, int count)
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const ESM::RefId& id, int count, bool allowAutoEquip)
{
MWWorld::ManualRef ref(*MWBase::Environment::get().getESMStore(), id, count);
return add(ref.getPtr(), count);
return add(ref.getPtr(), count, allowAutoEquip);
}
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(

@ -198,7 +198,7 @@ namespace MWWorld
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to
/// the newly inserted item.
ContainerStoreIterator add(const ESM::RefId& id, int count);
ContainerStoreIterator add(const ESM::RefId& id, int count, bool allowAutoEquip = true);
///< Utility to construct a ManualRef and call add(ptr, count, actorPtr, true)
int remove(const ESM::RefId& itemId, int count, bool equipReplacement = 0, bool resolve = true);

Loading…
Cancel
Save