mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
Merge pull request #1446 from akortunov/takeallfix
Do not allow to equip a replacement, when take all items from a dead corpse
This commit is contained in:
commit
0e648222b8
7 changed files with 74 additions and 29 deletions
|
@ -11,6 +11,7 @@
|
||||||
#include "../mwmechanics/actorutil.hpp"
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/pickpocket.hpp"
|
#include "../mwmechanics/pickpocket.hpp"
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
@ -211,31 +212,48 @@ namespace MWGui
|
||||||
|
|
||||||
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
if(mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// transfer everything into the player's inventory
|
||||||
|
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
|
||||||
|
mModel->update();
|
||||||
|
|
||||||
|
// unequip all items to avoid unequipping/reequipping
|
||||||
|
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||||
{
|
{
|
||||||
// transfer everything into the player's inventory
|
MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr);
|
||||||
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
|
|
||||||
mModel->update();
|
|
||||||
for (size_t i=0; i<mModel->getItemCount(); ++i)
|
for (size_t i=0; i<mModel->getItemCount(); ++i)
|
||||||
{
|
{
|
||||||
if (i==0)
|
|
||||||
{
|
|
||||||
// play the sound of the first object
|
|
||||||
MWWorld::Ptr item = mModel->getItem(i).mBase;
|
|
||||||
std::string sound = item.getClass().getUpSoundId(item);
|
|
||||||
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ItemStack& item = mModel->getItem(i);
|
const ItemStack& item = mModel->getItem(i);
|
||||||
|
if (invStore.isEquipped(item.mBase) == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!onTakeItem(item, item.mCount))
|
invStore.unequipItem(item.mBase, mPtr);
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mModel->moveItem(item, item.mCount, playerModel);
|
mModel->update();
|
||||||
|
|
||||||
|
for (size_t i=0; i<mModel->getItemCount(); ++i)
|
||||||
|
{
|
||||||
|
if (i==0)
|
||||||
|
{
|
||||||
|
// play the sound of the first object
|
||||||
|
MWWorld::Ptr item = mModel->getItem(i).mBase;
|
||||||
|
std::string sound = item.getClass().getUpSoundId(item);
|
||||||
|
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
const ItemStack& item = mModel->getItem(i);
|
||||||
|
|
||||||
|
if (!onTakeItem(item, item.mCount))
|
||||||
|
break;
|
||||||
|
|
||||||
|
mModel->moveItem(item, item.mCount, playerModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
|
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
#include "inventoryitemmodel.hpp"
|
#include "inventoryitemmodel.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
@ -45,16 +50,33 @@ MWWorld::Ptr InventoryItemModel::copyItem (const ItemStack& item, size_t count,
|
||||||
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, mActor, setNewOwner);
|
return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, mActor, setNewOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InventoryItemModel::removeItem (const ItemStack& item, size_t count)
|
void InventoryItemModel::removeItem (const ItemStack& item, size_t count)
|
||||||
{
|
{
|
||||||
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
|
int removed = 0;
|
||||||
int removed = store.remove(item.mBase, count, mActor);
|
// Re-equipping makes sense only if a target has inventory
|
||||||
|
if (mActor.getClass().hasInventoryStore(mActor))
|
||||||
|
{
|
||||||
|
MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor);
|
||||||
|
removed = store.remove(item.mBase, count, mActor, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor);
|
||||||
|
removed = store.remove(item.mBase, count, mActor);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream error;
|
||||||
|
|
||||||
if (removed == 0)
|
if (removed == 0)
|
||||||
throw std::runtime_error("Item to remove not found in container store");
|
{
|
||||||
|
error << "Item '" << item.mBase.getCellRef().getRefId() << "' was not found in container store to remove";
|
||||||
|
throw std::runtime_error(error.str());
|
||||||
|
}
|
||||||
else if (removed < static_cast<int>(count))
|
else if (removed < static_cast<int>(count))
|
||||||
throw std::runtime_error("Not enough items in the stack to remove");
|
{
|
||||||
|
error << "Not enough items '" << item.mBase.getCellRef().getRefId() << "' in the stack to remove (" << static_cast<int>(count) << " requested, " << removed << " found)";
|
||||||
|
throw std::runtime_error(error.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, ItemModel *otherModel)
|
MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, ItemModel *otherModel)
|
||||||
|
|
|
@ -143,8 +143,7 @@ namespace MWScript
|
||||||
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
|
if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
|
||||||
itemName = iter->getClass().getName(*iter);
|
itemName = iter->getClass().getName(*iter);
|
||||||
|
|
||||||
// Actors should not equip a replacement when items are removed with RemoveItem
|
int numRemoved = store.remove(item, count, ptr);
|
||||||
int numRemoved = store.remove(item, count, ptr, false);
|
|
||||||
|
|
||||||
// Spawn a messagebox (only for items removed from player's inventory)
|
// Spawn a messagebox (only for items removed from player's inventory)
|
||||||
if ((numRemoved > 0)
|
if ((numRemoved > 0)
|
||||||
|
|
|
@ -408,13 +408,13 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack (const Cons
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const Ptr& actor, bool equipReplacement)
|
int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const Ptr& actor)
|
||||||
{
|
{
|
||||||
int toRemove = count;
|
int toRemove = count;
|
||||||
|
|
||||||
for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter)
|
for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter)
|
||||||
if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), itemId))
|
if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), itemId))
|
||||||
toRemove -= remove(*iter, toRemove, actor, equipReplacement);
|
toRemove -= remove(*iter, toRemove, actor);
|
||||||
|
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const
|
||||||
return count - toRemove;
|
return count - toRemove;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement)
|
int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor)
|
||||||
{
|
{
|
||||||
assert(this == item.getContainerStore());
|
assert(this == item.getContainerStore());
|
||||||
|
|
||||||
|
|
|
@ -142,12 +142,12 @@ namespace MWWorld
|
||||||
ContainerStoreIterator add(const std::string& id, int count, const Ptr& actorPtr);
|
ContainerStoreIterator add(const std::string& id, int count, const Ptr& actorPtr);
|
||||||
///< 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 std::string& itemId, int count, const Ptr& actor, bool equipReplacement = true);
|
int remove(const std::string& itemId, int count, const Ptr& actor);
|
||||||
///< Remove \a count item(s) designated by \a itemId from this container.
|
///< Remove \a count item(s) designated by \a itemId from this container.
|
||||||
///
|
///
|
||||||
/// @return the number of items actually removed
|
/// @return the number of items actually removed
|
||||||
|
|
||||||
virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement = true);
|
virtual int remove(const Ptr& item, int count, const Ptr& actor);
|
||||||
///< Remove \a count item(s) designated by \a item from this inventory.
|
///< Remove \a count item(s) designated by \a item from this inventory.
|
||||||
///
|
///
|
||||||
/// @return the number of items actually removed
|
/// @return the number of items actually removed
|
||||||
|
|
|
@ -654,6 +654,11 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSelectedEnchantItem(
|
||||||
return mSelectedEnchantItem;
|
return mSelectedEnchantItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor)
|
||||||
|
{
|
||||||
|
return remove(item, count, actor, false);
|
||||||
|
}
|
||||||
|
|
||||||
int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement)
|
int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement)
|
||||||
{
|
{
|
||||||
int retCount = ContainerStore::remove(item, count, actor);
|
int retCount = ContainerStore::remove(item, count, actor);
|
||||||
|
|
|
@ -177,7 +177,8 @@ namespace MWWorld
|
||||||
virtual bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const;
|
virtual bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const;
|
||||||
///< @return true if the two specified objects can stack with each other
|
///< @return true if the two specified objects can stack with each other
|
||||||
|
|
||||||
virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement = true);
|
virtual int remove(const Ptr& item, int count, const Ptr& actor);
|
||||||
|
virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement);
|
||||||
///< Remove \a count item(s) designated by \a item from this inventory.
|
///< Remove \a count item(s) designated by \a item from this inventory.
|
||||||
///
|
///
|
||||||
/// @return the number of items actually removed
|
/// @return the number of items actually removed
|
||||||
|
|
Loading…
Reference in a new issue