1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-11-08 18:16:40 +00:00

Merge branch 'preserve-refnum-on-drop' into 'master'

Preserve refnum when dropping items from inventory to ground.

Closes #6148

See merge request OpenMW/openmw!3207
This commit is contained in:
psi29a 2023-07-18 10:25:28 +00:00
commit 5a31320d8d
17 changed files with 148 additions and 51 deletions

View file

@ -337,14 +337,17 @@ namespace MWBase
///< Toggle a render mode. ///< Toggle a render mode.
///< \return Resulting mode ///< \return Resulting mode
virtual MWWorld::Ptr placeObject(const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) = 0; virtual MWWorld::Ptr placeObject(
const MWWorld::Ptr& object, float cursorX, float cursorY, int amount, bool copy = true)
= 0;
///< copy and place an object into the gameworld at the specified cursor position ///< copy and place an object into the gameworld at the specified cursor position
/// @param object /// @param object
/// @param cursor X (relative 0-1) /// @param cursor X (relative 0-1)
/// @param cursor Y (relative 0-1) /// @param cursor Y (relative 0-1)
/// @param number of objects to place /// @param number of objects to place
virtual MWWorld::Ptr dropObjectOnGround(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object, int amount) virtual MWWorld::Ptr dropObjectOnGround(
const MWWorld::Ptr& actor, const MWWorld::Ptr& object, int amount, bool copy = true)
= 0; = 0;
///< copy and place an object into the gameworld at the given actor's position ///< copy and place an object into the gameworld at the given actor's position
/// @param actor giving the dropped object position /// @param actor giving the dropped object position

View file

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

View file

@ -13,6 +13,7 @@ namespace MWGui
public: public:
CompanionItemModel(const MWWorld::Ptr& actor); 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; MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override; void removeItem(const ItemStack& item, size_t count) override;

View file

@ -99,13 +99,22 @@ namespace MWGui
return -1; return -1;
} }
MWWorld::Ptr ContainerItemModel::addItem(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 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) MWWorld::Ptr ContainerItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{ {
auto& source = mItemSources[0]; auto& source = mItemSources[0];
MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first);
if (item.mBase.getContainerStore() == &store) if (item.mBase.getContainerStore() == &store)
throw std::runtime_error("Item to copy needs to be from a different container!"); throw std::runtime_error("Item to copy needs to be from a different container!");
return *store.add(item.mBase, count, allowAutoEquip); return *store.add(item.mBase.getCellRef().getRefId(), count, allowAutoEquip);
} }
void ContainerItemModel::removeItem(const ItemStack& item, size_t count) void ContainerItemModel::removeItem(const ItemStack& item, size_t count)

View file

@ -32,6 +32,7 @@ namespace MWGui
ModelIndex getIndex(const ItemStack& item) override; ModelIndex getIndex(const ItemStack& item) override;
size_t getItemCount() override; 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; MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override; void removeItem(const ItemStack& item, size_t count) override;

View file

@ -45,20 +45,31 @@ namespace MWGui
{ {
} }
virtual ~WorldItemModel() override {} virtual ~WorldItemModel() override {}
MWWorld::Ptr copyItem(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(); MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::Ptr dropped; MWWorld::Ptr dropped;
if (world->canPlaceObject(mLeft, mTop)) if (world->canPlaceObject(mLeft, mTop))
dropped = world->placeObject(item.mBase, mLeft, mTop, count); dropped = world->placeObject(item.mBase, mLeft, mTop, count, copy);
else else
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count); dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count, copy);
dropped.getCellRef().setOwner(ESM::RefId()); dropped.getCellRef().setOwner(ESM::RefId());
return dropped; 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 void removeItem(const ItemStack& item, size_t count) override
{ {
throw std::runtime_error("removeItem not implemented"); throw std::runtime_error("removeItem not implemented");

View file

@ -8,6 +8,7 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
@ -46,11 +47,19 @@ namespace MWGui
return -1; return -1;
} }
MWWorld::Ptr InventoryItemModel::addItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
throw std::runtime_error("Item to add needs to be from a different container!");
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, allowAutoEquip);
}
MWWorld::Ptr InventoryItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) MWWorld::Ptr InventoryItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{ {
if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor)) if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor))
throw std::runtime_error("Item to copy needs to be from a different container!"); throw std::runtime_error("Item to copy needs to be from a different container!");
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, allowAutoEquip); return *mActor.getClass().getContainerStore(mActor).add(
item.mBase.getCellRef().getRefId(), count, allowAutoEquip);
} }
void InventoryItemModel::removeItem(const ItemStack& item, size_t count) void InventoryItemModel::removeItem(const ItemStack& item, size_t count)
@ -83,16 +92,15 @@ namespace MWGui
} }
} }
MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack& item, size_t count, ItemModel* otherModel) MWWorld::Ptr InventoryItemModel::moveItem(
const ItemStack& item, size_t count, ItemModel* otherModel, bool allowAutoEquip)
{ {
// Can't move conjured items: This is a general fix that also takes care of issues with taking conjured items // Can't move conjured items: This is a general fix that also takes care of issues with taking conjured items
// via the 'Take All' button. // via the 'Take All' button.
if (item.mFlags & ItemStack::Flag_Bound) if (item.mFlags & ItemStack::Flag_Bound)
return MWWorld::Ptr(); return MWWorld::Ptr();
MWWorld::Ptr ret = otherModel->copyItem(item, count); return ItemModel::moveItem(item, count, otherModel, allowAutoEquip);
removeItem(item, count);
return ret;
} }
void InventoryItemModel::update() void InventoryItemModel::update()

View file

@ -17,11 +17,13 @@ namespace MWGui
bool onTakeItem(const MWWorld::Ptr& item, int count) override; 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; MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override; void removeItem(const ItemStack& item, size_t count) override;
/// Move items from this model to \a otherModel. /// Move items from this model to \a otherModel.
MWWorld::Ptr moveItem(const ItemStack& item, size_t count, ItemModel* otherModel) override; MWWorld::Ptr moveItem(
const ItemStack& item, size_t count, ItemModel* otherModel, bool allowAutoEquip = true) override;
void update() override; void update() override;

View file

@ -2,10 +2,13 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/worldmodel.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include <components/debug/debuglog.hpp>
namespace MWGui namespace MWGui
{ {
@ -55,12 +58,22 @@ namespace MWGui
ItemModel::ItemModel() {} ItemModel::ItemModel() {}
MWWorld::Ptr ItemModel::moveItem(const ItemStack& item, size_t count, ItemModel* otherModel) MWWorld::Ptr ItemModel::moveItem(const ItemStack& item, size_t count, ItemModel* otherModel, bool allowAutoEquip)
{ {
// TODO(#6148): moving an item should preserve RefNum and Lua scripts (unless the item stack is merged with MWWorld::Ptr ret = MWWorld::Ptr();
// already existing stack). if (static_cast<size_t>(item.mBase.getRefData().getCount()) <= count)
MWWorld::Ptr ret = otherModel->copyItem(item, count); {
// We are moving the full stack
ret = otherModel->addItem(item, count, allowAutoEquip);
removeItem(item, count); removeItem(item, count);
}
else
{
// 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; return ret;
} }
@ -143,6 +156,11 @@ namespace MWGui
return mSourceModel->onTakeItem(item, count); return mSourceModel->onTakeItem(item, count);
} }
MWWorld::Ptr ProxyItemModel::addItem(const ItemStack& item, size_t count, bool allowAutoEquip)
{
return mSourceModel->addItem(item, count, allowAutoEquip);
}
bool ProxyItemModel::usesContainer(const MWWorld::Ptr& container) bool ProxyItemModel::usesContainer(const MWWorld::Ptr& container)
{ {
return mSourceModel->usesContainer(container); return mSourceModel->usesContainer(container);

View file

@ -63,8 +63,10 @@ namespace MWGui
/// Move items from this model to \a otherModel. /// Move items from this model to \a otherModel.
/// @note Derived implementations may return an empty Ptr if the move was unsuccessful. /// @note Derived implementations may return an empty Ptr if the move was unsuccessful.
virtual MWWorld::Ptr moveItem(const ItemStack& item, size_t count, ItemModel* otherModel); virtual MWWorld::Ptr moveItem(
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 MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) = 0;
virtual void removeItem(const ItemStack& item, size_t count) = 0; virtual void removeItem(const ItemStack& item, size_t count) = 0;
@ -95,6 +97,7 @@ namespace MWGui
bool onDropItem(const MWWorld::Ptr& item, int count) override; bool onDropItem(const MWWorld::Ptr& item, int count) override;
bool onTakeItem(const MWWorld::Ptr& item, int count) override; 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; MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override;
void removeItem(const ItemStack& item, size_t count) override; void removeItem(const ItemStack& item, size_t count) override;
ModelIndex getIndex(const ItemStack& item) override; ModelIndex getIndex(const ItemStack& item) override;

View file

@ -139,11 +139,8 @@ namespace MWGui
if (i == sourceModel->getItemCount()) if (i == sourceModel->getItemCount())
throw std::runtime_error("The borrowed item disappeared"); throw std::runtime_error("The borrowed item disappeared");
const ItemStack& item = sourceModel->getItem(i); sourceModel->moveItem(
// copy the borrowed items to our model sourceModel->getItem(i), itemStack.mCount, this, !Settings::game().mPreventMerchantEquipping);
copyItem(item, itemStack.mCount, !Settings::game().mPreventMerchantEquipping);
// then remove them from the source model
sourceModel->removeItem(item, itemStack.mCount);
} }
mBorrowedToUs.clear(); mBorrowedToUs.clear();
mBorrowedFromUs.clear(); mBorrowedFromUs.clear();

View file

@ -391,10 +391,20 @@ namespace MWWorld
return newPtr; return newPtr;
} }
Ptr Class::moveToCell(const Ptr& ptr, CellStore& cell, const ESM::Position& pos, int count) const
{
Ptr newPtr = moveToCell(ptr, cell);
newPtr.getRefData().setPosition(pos);
newPtr.getCellRef().setPosition(pos);
newPtr.getRefData().setCount(count);
return newPtr;
}
MWWorld::Ptr Class::copyToCell(const ConstPtr& ptr, CellStore& cell, const ESM::Position& pos, int count) const MWWorld::Ptr Class::copyToCell(const ConstPtr& ptr, CellStore& cell, const ESM::Position& pos, int count) const
{ {
Ptr newPtr = copyToCell(ptr, cell, count); Ptr newPtr = copyToCell(ptr, cell, count);
newPtr.getRefData().setPosition(pos); newPtr.getRefData().setPosition(pos);
newPtr.getCellRef().setPosition(pos);
return newPtr; return newPtr;
} }

View file

@ -317,6 +317,7 @@ namespace MWWorld
// The original is expected to be removed after calling this function, // The original is expected to be removed after calling this function,
// but this function itself doesn't remove the original. // but this function itself doesn't remove the original.
virtual Ptr moveToCell(const Ptr& ptr, CellStore& cell) const; virtual Ptr moveToCell(const Ptr& ptr, CellStore& cell) const;
Ptr moveToCell(const Ptr& ptr, CellStore& cell, const ESM::Position& pos, int count) const;
Ptr copyToCell(const ConstPtr& ptr, CellStore& cell, const ESM::Position& pos, int count) const; Ptr copyToCell(const ConstPtr& ptr, CellStore& cell, const ESM::Position& pos, int count) const;

View file

@ -300,10 +300,10 @@ bool MWWorld::ContainerStore::stacks(const ConstPtr& ptr1, const ConstPtr& ptr2)
&& cls2.getItemHealth(ptr2) == cls2.getItemMaxHealth(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); 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( MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(

View file

@ -198,7 +198,7 @@ namespace MWWorld
/// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to
/// the newly inserted item. /// 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) ///< 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); int remove(const ESM::RefId& itemId, int count, bool equipReplacement = 0, bool resolve = true);

View file

@ -2001,7 +2001,7 @@ namespace MWWorld
item.getRefData().getLocals().setVarByInt(script, "onpcdrop", 1); item.getRefData().getLocals().setVarByInt(script, "onpcdrop", 1);
} }
MWWorld::Ptr World::placeObject(const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) MWWorld::Ptr World::placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY, int amount, bool copy)
{ {
const float maxDist = 200.f; const float maxDist = 200.f;
@ -2022,7 +2022,8 @@ namespace MWWorld
pos.rot[1] = 0; pos.rot[1] = 0;
// copy the object and set its count // copy the object and set its count
Ptr dropped = copyObjectToCell(object, cell, pos, amount, true); Ptr dropped = copy ? copyObjectToCell(object, cell, pos, amount, true)
: moveObjectToCell(object, cell, pos, amount, true);
// only the player place items in the world, so no need to check actor // only the player place items in the world, so no need to check actor
PCDropped(dropped); PCDropped(dropped);
@ -2062,33 +2063,55 @@ namespace MWWorld
MWWorld::Ptr dropped = object.getClass().copyToCell(object, *cell, pos, count); MWWorld::Ptr dropped = object.getClass().copyToCell(object, *cell, pos, count);
// Reset some position values that could be uninitialized if this item came from a container initObjectInCell(dropped, *cell, adjustPos);
dropped.getCellRef().setPosition(pos);
dropped.getCellRef().unsetRefNum();
if (mWorldScene->isCellActive(*cell)) return dropped;
{
if (dropped.getRefData().isEnabled())
{
mWorldScene->addObjectToScene(dropped);
} }
const auto& script = dropped.getClass().getScript(dropped);
Ptr World::moveObjectToCell(const Ptr& object, CellStore* cell, ESM::Position pos, int count, bool adjustPos)
{
if (!cell)
throw std::runtime_error("moveObjectToCell(): cannot move object to null cell");
if (cell->isExterior())
{
const ESM::ExteriorCellLocation index
= ESM::positionToExteriorCellLocation(pos.pos[0], pos.pos[1], cell->getCell()->getWorldSpace());
cell = &mWorldModel.getExterior(index);
}
MWWorld::Ptr dropped = object.getClass().moveToCell(object, *cell, pos, count);
initObjectInCell(dropped, *cell, adjustPos);
return dropped;
}
void World::initObjectInCell(const Ptr& object, CellStore& cell, bool adjustPos)
{
if (mWorldScene->isCellActive(cell))
{
if (object.getRefData().isEnabled())
{
mWorldScene->addObjectToScene(object);
}
const auto& script = object.getClass().getScript(object);
if (!script.empty()) if (!script.empty())
{ {
mLocalScripts.add(script, dropped); mLocalScripts.add(script, object);
} }
addContainerScripts(dropped, cell); addContainerScripts(object, &cell);
} }
if (!object.getClass().isActor() && adjustPos && dropped.getRefData().getBaseNode()) if (!object.getClass().isActor() && adjustPos && object.getRefData().getBaseNode())
{ {
// Adjust position so the location we wanted ends up in the middle of the object bounding box // Adjust position so the location we wanted ends up in the middle of the object bounding box
osg::ComputeBoundsVisitor computeBounds; osg::ComputeBoundsVisitor computeBounds;
computeBounds.setTraversalMask(~MWRender::Mask_ParticleSystem); computeBounds.setTraversalMask(~MWRender::Mask_ParticleSystem);
dropped.getRefData().getBaseNode()->accept(computeBounds); object.getRefData().getBaseNode()->accept(computeBounds);
osg::BoundingBox bounds = computeBounds.getBoundingBox(); osg::BoundingBox bounds = computeBounds.getBoundingBox();
if (bounds.valid()) if (bounds.valid())
{ {
ESM::Position pos = object.getRefData().getPosition();
bounds.set(bounds._min - pos.asVec3(), bounds._max - pos.asVec3()); bounds.set(bounds._min - pos.asVec3(), bounds._max - pos.asVec3());
osg::Vec3f adjust( osg::Vec3f adjust(
@ -2096,14 +2119,12 @@ namespace MWWorld
pos.pos[0] -= adjust.x(); pos.pos[0] -= adjust.x();
pos.pos[1] -= adjust.y(); pos.pos[1] -= adjust.y();
pos.pos[2] -= adjust.z(); pos.pos[2] -= adjust.z();
moveObject(dropped, pos.asVec3()); moveObject(object, pos.asVec3());
}
} }
} }
return dropped; MWWorld::Ptr World::dropObjectOnGround(const Ptr& actor, const Ptr& object, int amount, bool copy)
}
MWWorld::Ptr World::dropObjectOnGround(const Ptr& actor, const ConstPtr& object, int amount)
{ {
MWWorld::CellStore* cell = actor.getCell(); MWWorld::CellStore* cell = actor.getCell();
@ -2123,7 +2144,8 @@ namespace MWWorld
pos.pos[2] = result.mHitPointWorld.z(); pos.pos[2] = result.mHitPointWorld.z();
// copy the object and set its count // copy the object and set its count
Ptr dropped = copyObjectToCell(object, cell, pos, amount, true); Ptr dropped = copy ? copyObjectToCell(object, cell, pos, amount, true)
: moveObjectToCell(object, cell, pos, amount, true);
if (actor == mPlayer->getPlayer()) // Only call if dropped by player if (actor == mPlayer->getPlayer()) // Only call if dropped by player
PCDropped(dropped); PCDropped(dropped);

View file

@ -143,6 +143,8 @@ namespace MWWorld
void updateWeather(float duration, bool paused = false); void updateWeather(float duration, bool paused = false);
void initObjectInCell(const Ptr& ptr, CellStore& cell, bool adjustPos);
Ptr moveObjectToCell(const Ptr& ptr, CellStore* cell, ESM::Position pos, int count, bool adjustPos);
Ptr copyObjectToCell(const ConstPtr& ptr, CellStore* cell, ESM::Position pos, int count, bool adjustPos); Ptr copyObjectToCell(const ConstPtr& ptr, CellStore* cell, ESM::Position pos, int count, bool adjustPos);
void updateSoundListener(); void updateSoundListener();
@ -425,7 +427,8 @@ namespace MWWorld
void updateWindowManager(); void updateWindowManager();
MWWorld::Ptr placeObject(const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) override; MWWorld::Ptr placeObject(
const MWWorld::Ptr& object, float cursorX, float cursorY, int amount, bool copy = true) override;
///< copy and place an object into the gameworld at the specified cursor position ///< copy and place an object into the gameworld at the specified cursor position
/// @param object /// @param object
/// @param cursor X (relative 0-1) /// @param cursor X (relative 0-1)
@ -433,7 +436,7 @@ namespace MWWorld
/// @param number of objects to place /// @param number of objects to place
MWWorld::Ptr dropObjectOnGround( MWWorld::Ptr dropObjectOnGround(
const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object, int amount) override; const MWWorld::Ptr& actor, const MWWorld::Ptr& object, int amount, bool copy = true) override;
///< copy and place an object into the gameworld at the given actor's position ///< copy and place an object into the gameworld at the given actor's position
/// @param actor giving the dropped object position /// @param actor giving the dropped object position
/// @param object /// @param object