#include "tradeitemmodel.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/inventorystore.hpp" namespace MWGui { TradeItemModel::TradeItemModel(ItemModel *sourceModel, const MWWorld::Ptr& merchant) : mMerchant(merchant) { mSourceModel = sourceModel; } ItemStack TradeItemModel::getItem (ModelIndex index) { if (index < 0) throw std::runtime_error("Invalid index supplied"); if (mItems.size() <= static_cast(index)) throw std::runtime_error("Item index out of range"); return mItems[index]; } size_t TradeItemModel::getItemCount() { return mItems.size(); } void TradeItemModel::borrowImpl(const ItemStack &item, std::vector &out) { std::vector::iterator it = out.begin(); bool found = false; for (; it != out.end(); ++it) { if (it->stacks(item)) { it->mCount += item.mCount; found = true; break; } } if (!found) out.push_back(item); } void TradeItemModel::unborrowImpl(const ItemStack &item, size_t count, std::vector &out) { std::vector::iterator it = out.begin(); bool found = false; for (; it != out.end(); ++it) { if (it->stacks(item)) { if (it->mCount < count) throw std::runtime_error("Not enough borrowed items to return"); it->mCount -= count; if (it->mCount == 0) out.erase(it); found = true; break; } } if (!found) throw std::runtime_error("Can't find borrowed item to return"); } void TradeItemModel::borrowItemFromUs (ModelIndex itemIndex, size_t count) { ItemStack item = getItem(itemIndex); item.mCount = count; borrowImpl(item, mBorrowedFromUs); } void TradeItemModel::borrowItemToUs (ModelIndex itemIndex, ItemModel* source, size_t count) { ItemStack item = source->getItem(itemIndex); item.mCount = count; borrowImpl(item, mBorrowedToUs); } void TradeItemModel::returnItemBorrowedToUs (ModelIndex itemIndex, size_t count) { ItemStack item = getItem(itemIndex); unborrowImpl(item, count, mBorrowedToUs); } void TradeItemModel::returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count) { ItemStack item = source->getItem(itemIndex); unborrowImpl(item, count, mBorrowedFromUs); } void TradeItemModel::abort() { mBorrowedFromUs.clear(); mBorrowedToUs.clear(); } std::vector TradeItemModel::getItemsBorrowedToUs() { return mBorrowedToUs; } void TradeItemModel::transferItems() { std::vector::iterator it = mBorrowedToUs.begin(); for (; it != mBorrowedToUs.end(); ++it) { // get index in the source model ItemModel* sourceModel = it->mCreator; size_t i=0; for (; igetItemCount(); ++i) { if (it->stacks(sourceModel->getItem(i))) break; } if (i == sourceModel->getItemCount()) throw std::runtime_error("The borrowed item disappeared"); // reset owner before copying const ItemStack& item = sourceModel->getItem(i); std::string owner = item.mBase.getCellRef().mOwner; if (mMerchant.isEmpty()) // only for items bought by player item.mBase.getCellRef().mOwner = ""; // copy the borrowed items to our model copyItem(item, it->mCount); item.mBase.getCellRef().mOwner = owner; // then remove them from the source model sourceModel->removeItem(item, it->mCount); } mBorrowedToUs.clear(); mBorrowedFromUs.clear(); } void TradeItemModel::update() { mSourceModel->update(); int services = 0; if (!mMerchant.isEmpty()) services = MWWorld::Class::get(mMerchant).getServices(mMerchant); mItems.clear(); // add regular items for (size_t i=0; igetItemCount(); ++i) { ItemStack item = mSourceModel->getItem(i); if(!mMerchant.isEmpty()) { MWWorld::Ptr base = item.mBase; if(Misc::StringUtils::ciEqual(base.getCellRef().mRefID, MWWorld::ContainerStore::sGoldId)) continue; if(!MWWorld::Class::get(base).canSell(base, services)) continue; // Bound items may not be bought if (item.mBase.getCellRef().mRefID.size() > 6 && item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") { continue; } // don't show equipped items if(mMerchant.getClass().hasInventoryStore(mMerchant)) { bool isEquipped = false; MWWorld::InventoryStore& store = MWWorld::Class::get(mMerchant).getInventoryStore(mMerchant); for (int slot=0; slot::iterator it = mBorrowedFromUs.begin(); for (; it != mBorrowedFromUs.end(); ++it) { if (it->stacks(item)) { if (item.mCount < it->mCount) throw std::runtime_error("Lent more items than present"); item.mCount -= it->mCount; } } if (item.mCount > 0) mItems.push_back(item); } // add items borrowed to us std::vector::iterator it = mBorrowedToUs.begin(); for (; it != mBorrowedToUs.end(); ++it) { ItemStack item = *it; item.mType = ItemStack::Type_Barter; mItems.push_back(item); } } }