|
|
|
@ -15,6 +15,7 @@
|
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
|
#include "../mwbase/windowmanager.hpp"
|
|
|
|
|
#include "../mwbase/scriptmanager.hpp"
|
|
|
|
|
#include "../mwbase/soundmanager.hpp"
|
|
|
|
|
#include "../mwbase/world.hpp"
|
|
|
|
|
|
|
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
@ -23,6 +24,7 @@
|
|
|
|
|
#include "../mwworld/inventorystore.hpp"
|
|
|
|
|
#include "../mwworld/esmstore.hpp"
|
|
|
|
|
#include "../mwworld/cellstore.hpp"
|
|
|
|
|
#include "../mwworld/manualref.hpp"
|
|
|
|
|
|
|
|
|
|
#include "../mwmechanics/aicast.hpp"
|
|
|
|
|
#include "../mwmechanics/npcstats.hpp"
|
|
|
|
@ -469,6 +471,9 @@ namespace MWScript
|
|
|
|
|
std::string gem = runtime.getStringLiteral (runtime[0].mInteger);
|
|
|
|
|
runtime.pop();
|
|
|
|
|
|
|
|
|
|
if (!ptr.getClass().hasInventoryStore(ptr))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
|
store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature
|
|
|
|
|
|
|
|
|
@ -499,7 +504,10 @@ namespace MWScript
|
|
|
|
|
for (unsigned int i=0; i<arg0; ++i)
|
|
|
|
|
runtime.pop();
|
|
|
|
|
|
|
|
|
|
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr);
|
|
|
|
|
if (!ptr.getClass().hasInventoryStore(ptr))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
|
|
|
|
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), soul))
|
|
|
|
@ -534,16 +542,18 @@ namespace MWScript
|
|
|
|
|
if (amount == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
if (!ptr.getClass().isActor())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int numNotEquipped = invStorePtr->count(item);
|
|
|
|
|
if (ptr.getClass().hasInventoryStore(ptr))
|
|
|
|
|
{
|
|
|
|
|
// Prefer dropping unequipped items first; re-stack if possible by unequipping items before dropping them.
|
|
|
|
|
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
|
|
|
|
|
int numNotEquipped = store.count(item);
|
|
|
|
|
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
|
|
|
|
{
|
|
|
|
|
MWWorld::ConstContainerStoreIterator it = invStorePtr->getSlot (slot);
|
|
|
|
|
if (it != invStorePtr->end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
|
|
|
|
|
MWWorld::ConstContainerStoreIterator it = store.getSlot (slot);
|
|
|
|
|
if (it != store.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
|
|
|
|
|
{
|
|
|
|
|
numNotEquipped -= it->getRefData().getCount();
|
|
|
|
|
}
|
|
|
|
@ -551,37 +561,48 @@ namespace MWScript
|
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
MWWorld::ContainerStoreIterator it = store.getSlot (slot);
|
|
|
|
|
if (it != store.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);
|
|
|
|
|
int numToRemove = std::min(amount - numNotEquipped, it->getRefData().getCount());
|
|
|
|
|
store.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)
|
|
|
|
|
&& (!invStorePtr || !invStorePtr->isEquipped(*iter)))
|
|
|
|
|
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
|
|
|
|
{
|
|
|
|
|
int removed = store.remove(*iter, toRemove, ptr);
|
|
|
|
|
MWWorld::Ptr dropped = MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed);
|
|
|
|
|
dropped.getCellRef().setOwner("");
|
|
|
|
|
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item) && !store.isEquipped(*iter))
|
|
|
|
|
{
|
|
|
|
|
int removed = store.remove(*iter, amount, ptr);
|
|
|
|
|
MWWorld::Ptr dropped = MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed);
|
|
|
|
|
dropped.getCellRef().setOwner("");
|
|
|
|
|
|
|
|
|
|
toRemove -= removed;
|
|
|
|
|
amount -= removed;
|
|
|
|
|
|
|
|
|
|
if (toRemove <= 0)
|
|
|
|
|
break;
|
|
|
|
|
if (amount <= 0)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1);
|
|
|
|
|
MWWorld::Ptr itemPtr(ref.getPtr());
|
|
|
|
|
if (amount > 0)
|
|
|
|
|
{
|
|
|
|
|
if (itemPtr.getClass().getScript(itemPtr).empty())
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, itemPtr, amount);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Dropping one item per time to prevent making stacks of scripted items
|
|
|
|
|
for (int i = 0; i < amount; i++)
|
|
|
|
|
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, itemPtr, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, itemPtr.getClass().getDownSoundId(itemPtr), 1.f, 1.f);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -598,8 +619,10 @@ namespace MWScript
|
|
|
|
|
std::string soul = runtime.getStringLiteral (runtime[0].mInteger);
|
|
|
|
|
runtime.pop();
|
|
|
|
|
|
|
|
|
|
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr);
|
|
|
|
|
if (!ptr.getClass().hasInventoryStore(ptr))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
|
|
|
|
|
|
|
|
|
|
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
|
|
|
|
{
|
|
|
|
|