Improve Drop command behavior. (Fixes #1544)

coverity_scan
Jordan Ayers 9 years ago
parent c82d9a1e87
commit 1ff49cc637

@ -21,6 +21,7 @@
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/cellstore.hpp"
@ -509,13 +510,43 @@ namespace MWScript
if (amount == 0)
return;
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr);
// Prefer dropping unequipped items first; re-stack if possible by unequipping items before dropping them.
MWWorld::InventoryStore *invStorePtr = 0;
if (ptr.getClass().hasInventoryStore(ptr)) {
invStorePtr = &ptr.getClass().getInventoryStore(ptr);
int numNotEquipped = invStorePtr->count(item);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
MWWorld::ContainerStoreIterator it = invStorePtr->getSlot (slot);
if (it != invStorePtr->end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
{
numNotEquipped -= it->getRefData().getCount();
}
}
for (int slot = 0; slot < MWWorld::InventoryStore::Slots && amount > numNotEquipped; ++slot)
{
MWWorld::ContainerStoreIterator it = invStorePtr->getSlot (slot);
if (it != invStorePtr->end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
{
int numToRemove = it->getRefData().getCount();
if (numToRemove > amount - numNotEquipped)
{
numToRemove = amount - numNotEquipped;
}
invStorePtr->unequipItemQuantity(*it, ptr, numToRemove);
numNotEquipped += numToRemove;
}
}
}
int toRemove = amount;
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr);
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
{
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item)
&& (!invStorePtr || !invStorePtr->isEquipped(*iter)))
{
int removed = store.remove(*iter, toRemove, ptr);
MWWorld::Ptr dropped = MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed);

Loading…
Cancel
Save