mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 06:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			681 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			681 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "container.hpp"
 | 
						|
 | 
						|
#include <cmath>
 | 
						|
#include <algorithm>
 | 
						|
#include <iterator>
 | 
						|
#include <assert.h>
 | 
						|
#include <iostream>
 | 
						|
 | 
						|
#include <boost/lexical_cast.hpp>
 | 
						|
 | 
						|
#include "../mwbase/environment.hpp"
 | 
						|
#include "../mwworld/manualref.hpp"
 | 
						|
#include "../mwworld/world.hpp"
 | 
						|
#include "../mwworld/containerstore.hpp"
 | 
						|
#include "../mwworld/class.hpp"
 | 
						|
#include "../mwworld/player.hpp"
 | 
						|
#include "../mwclass/container.hpp"
 | 
						|
#include "../mwinput/inputmanager.hpp"
 | 
						|
#include "../mwsound/soundmanager.hpp"
 | 
						|
 | 
						|
#include "window_manager.hpp"
 | 
						|
#include "widgets.hpp"
 | 
						|
#include "countdialog.hpp"
 | 
						|
#include "tradewindow.hpp"
 | 
						|
#include "inventorywindow.hpp"
 | 
						|
 | 
						|
using namespace MWGui;
 | 
						|
using namespace Widgets;
 | 
						|
 | 
						|
 | 
						|
namespace
 | 
						|
{
 | 
						|
    bool compareType(std::string type1, std::string type2)
 | 
						|
    {
 | 
						|
        // this defines the sorting order of types. types that are first in the vector, appear before other types.
 | 
						|
        std::vector<std::string> mapping;
 | 
						|
        mapping.push_back( typeid(ESM::Weapon).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Armor).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Clothing).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Potion).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Ingredient).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Apparatus).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Book).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Light).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Miscellaneous).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Tool).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Repair).name() );
 | 
						|
        mapping.push_back( typeid(ESM::Probe).name() );
 | 
						|
 | 
						|
        assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() );
 | 
						|
        assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() );
 | 
						|
 | 
						|
        return std::find(mapping.begin(), mapping.end(), type1) < std::find(mapping.begin(), mapping.end(), type2);
 | 
						|
    }
 | 
						|
 | 
						|
    bool sortItems(MWWorld::Ptr left, MWWorld::Ptr right)
 | 
						|
    {
 | 
						|
        if (left.getTypeName() == right.getTypeName())
 | 
						|
        {
 | 
						|
            int cmp = MWWorld::Class::get(left).getName(left).compare(
 | 
						|
                        MWWorld::Class::get(right).getName(right));
 | 
						|
            return cmp < 0;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            return compareType(left.getTypeName(), right.getTypeName());
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop) :
 | 
						|
    mDragAndDrop(dragAndDrop),
 | 
						|
    mFilter(ContainerBase::Filter_All)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::setWidgets(Widget* containerWidget, ScrollView* itemView)
 | 
						|
{
 | 
						|
    mContainerWidget = containerWidget;
 | 
						|
    mItemView = itemView;
 | 
						|
 | 
						|
    mContainerWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onContainerClicked);
 | 
						|
    mContainerWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerWindow::onMouseWheel);
 | 
						|
}
 | 
						|
 | 
						|
ContainerBase::~ContainerBase()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
 | 
						|
{
 | 
						|
    mSelectedItem = _sender;
 | 
						|
 | 
						|
    if (mDragAndDrop && !isTrading())
 | 
						|
    {
 | 
						|
        if(!mDragAndDrop->mIsOnDragAndDrop)
 | 
						|
        {
 | 
						|
            MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
 | 
						|
            int count = object.getRefData().getCount();
 | 
						|
 | 
						|
            if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
 | 
						|
            {
 | 
						|
                startDragItem(_sender, count);
 | 
						|
            }
 | 
						|
            else if (MyGUI::InputManager::getInstance().isControlPressed())
 | 
						|
            {
 | 
						|
                startDragItem(_sender, 1);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                std::string message = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTake")->str;
 | 
						|
                CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
 | 
						|
                dialog->open(MWWorld::Class::get(object).getName(object), message, count);
 | 
						|
                dialog->eventOkClicked.clear();
 | 
						|
                dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
            onContainerClicked(mContainerWidget);
 | 
						|
    }
 | 
						|
    else if (isTrading())
 | 
						|
    {
 | 
						|
        MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
 | 
						|
        int count = object.getRefData().getCount();
 | 
						|
 | 
						|
        if (isInventory())
 | 
						|
        {
 | 
						|
            // the player is trying to sell an item, check if the merchant accepts it
 | 
						|
            // also, don't allow selling gold (let's be better than Morrowind at this, can we?)
 | 
						|
            if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object)
 | 
						|
                || MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
 | 
						|
            {
 | 
						|
                // user notification "i don't buy this item"
 | 
						|
                MWBase::Environment::get().getWindowManager()->
 | 
						|
                    messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog4")->str, std::vector<std::string>());
 | 
						|
                return;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        bool buying = isTradeWindow(); // buying or selling?
 | 
						|
        std::string message = buying ? MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage02")->str
 | 
						|
                :  MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage01")->str;
 | 
						|
 | 
						|
        if (std::find(mBoughtItems.begin(), mBoughtItems.end(), object) != mBoughtItems.end())
 | 
						|
        {
 | 
						|
            if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
 | 
						|
            {
 | 
						|
                sellAlreadyBoughtItem(NULL, count);
 | 
						|
            }
 | 
						|
            else if (MyGUI::InputManager::getInstance().isControlPressed())
 | 
						|
            {
 | 
						|
                sellAlreadyBoughtItem(NULL, 1);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
 | 
						|
                dialog->open(MWWorld::Class::get(object).getName(object), message, count);
 | 
						|
                dialog->eventOkClicked.clear();
 | 
						|
                dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellAlreadyBoughtItem);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
 | 
						|
            {
 | 
						|
                sellItem(NULL, count);
 | 
						|
            }
 | 
						|
            else if (MyGUI::InputManager::getInstance().isControlPressed())
 | 
						|
            {
 | 
						|
                sellItem(NULL, 1);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
 | 
						|
                dialog->open(MWWorld::Class::get(object).getName(object), message, count);
 | 
						|
                dialog->eventOkClicked.clear();
 | 
						|
                dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellItem);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>());
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
 | 
						|
{
 | 
						|
    MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
 | 
						|
 | 
						|
    if (isInventory())
 | 
						|
    {
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->addItem(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addItem(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
 | 
						|
    }
 | 
						|
 | 
						|
    std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
 | 
						|
    MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
 | 
						|
 | 
						|
    drawItems();
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
 | 
						|
{
 | 
						|
    MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
 | 
						|
 | 
						|
    if (isInventory())
 | 
						|
    {
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->addBarteredItem(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
 | 
						|
        MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
 | 
						|
    }
 | 
						|
 | 
						|
    std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
 | 
						|
    MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
 | 
						|
 | 
						|
    drawItems();
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
 | 
						|
{
 | 
						|
    mDragAndDrop->mIsOnDragAndDrop = true;
 | 
						|
    mSelectedItem->detachFromWidget();
 | 
						|
    mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
 | 
						|
 | 
						|
    MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
 | 
						|
    _unequipItem(object);
 | 
						|
 | 
						|
    mDragAndDrop->mDraggedCount = count;
 | 
						|
 | 
						|
    mDragAndDrop->mDraggedFrom = this;
 | 
						|
 | 
						|
    std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
 | 
						|
    MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
 | 
						|
 | 
						|
    mDragAndDrop->mDraggedWidget = mSelectedItem;
 | 
						|
    static_cast<MyGUI::ImageBox*>(mSelectedItem)->setImageTexture(""); // remove the background texture (not visible during drag)
 | 
						|
    static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
 | 
						|
        getCountString(mDragAndDrop->mDraggedCount));
 | 
						|
 | 
						|
    drawItems();
 | 
						|
 | 
						|
    MWBase::Environment::get().getWindowManager()->setDragDrop(true);
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
 | 
						|
{
 | 
						|
    if (mDragAndDrop == NULL) return;
 | 
						|
 | 
						|
    if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
 | 
						|
    {
 | 
						|
        MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
 | 
						|
        MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
 | 
						|
 | 
						|
        if (mDragAndDrop->mDraggedFrom != this)
 | 
						|
        {
 | 
						|
            assert(object.getContainerStore() && "Item is not in a container!");
 | 
						|
 | 
						|
            // check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
 | 
						|
            if (mPtr.getTypeName() == typeid(ESM::Container).name())
 | 
						|
            {
 | 
						|
                ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mPtr.get<ESM::Container>();
 | 
						|
                if (ref->base->flags & ESM::Container::Organic)
 | 
						|
                {
 | 
						|
                    // user notification
 | 
						|
                    MWBase::Environment::get().getWindowManager()->
 | 
						|
                        messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage2")->str, std::vector<std::string>());
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            int origCount = object.getRefData().getCount();
 | 
						|
 | 
						|
            // check that we don't exceed the allowed weight (only for containers, not for inventory)
 | 
						|
            if (!isInventory())
 | 
						|
            {
 | 
						|
                float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr);
 | 
						|
 | 
						|
                // try adding the item, and if weight is exceeded, just remove it again.
 | 
						|
                object.getRefData().setCount(mDragAndDrop->mDraggedCount);
 | 
						|
                MWWorld::ContainerStoreIterator it = containerStore.add(object);
 | 
						|
 | 
						|
                float curWeight = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
 | 
						|
                if (curWeight > capacity)
 | 
						|
                {
 | 
						|
                    it->getRefData().setCount(0);
 | 
						|
                    object.getRefData().setCount(origCount);
 | 
						|
                    // user notification
 | 
						|
                    MWBase::Environment::get().getWindowManager()->
 | 
						|
                        messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage3")->str, std::vector<std::string>());
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
 | 
						|
                }
 | 
						|
                std::cout << "container weight " << curWeight << "/" << capacity << std::endl;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                object.getRefData().setCount (mDragAndDrop->mDraggedCount);
 | 
						|
                containerStore.add(object);
 | 
						|
                object.getRefData().setCount (origCount - mDragAndDrop->mDraggedCount);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        mDragAndDrop->mIsOnDragAndDrop = false;
 | 
						|
        MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
 | 
						|
        drawItems();
 | 
						|
        mDragAndDrop->mDraggedFrom->drawItems();
 | 
						|
 | 
						|
        MWBase::Environment::get().getWindowManager()->setDragDrop(false);
 | 
						|
 | 
						|
        std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
 | 
						|
        MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
 | 
						|
{
 | 
						|
    if (mItemView->getViewOffset().left + _rel*0.3 > 0)
 | 
						|
        mItemView->setViewOffset(MyGUI::IntPoint(0, 0));
 | 
						|
    else
 | 
						|
        mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::setFilter(ContainerBase::Filter filter)
 | 
						|
{
 | 
						|
    mFilter = filter;
 | 
						|
    drawItems();
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::openContainer(MWWorld::Ptr container)
 | 
						|
{
 | 
						|
    mPtr = container;
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::drawItems()
 | 
						|
{
 | 
						|
    while (mContainerWidget->getChildCount())
 | 
						|
    {
 | 
						|
        MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
 | 
						|
    }
 | 
						|
    MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
 | 
						|
 | 
						|
    int x = 0;
 | 
						|
    int y = 0;
 | 
						|
    int maxHeight = mItemView->getSize().height - 58;
 | 
						|
 | 
						|
    bool onlyMagic = false;
 | 
						|
    int categories;
 | 
						|
    if (mFilter == Filter_All)
 | 
						|
        categories = MWWorld::ContainerStore::Type_All;
 | 
						|
    else if (mFilter == Filter_Weapon)
 | 
						|
        categories = MWWorld::ContainerStore::Type_Weapon;
 | 
						|
    else if (mFilter == Filter_Apparel)
 | 
						|
        categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
 | 
						|
    else if (mFilter == Filter_Magic)
 | 
						|
    {
 | 
						|
        categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
 | 
						|
                    + MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
 | 
						|
                    + MWWorld::ContainerStore::Type_Potion;
 | 
						|
        onlyMagic = true;
 | 
						|
    }
 | 
						|
    else if (mFilter == Filter_Misc)
 | 
						|
    {
 | 
						|
        categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
 | 
						|
                    + MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
 | 
						|
                    + MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
 | 
						|
                    + MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe;
 | 
						|
    }
 | 
						|
    else if (mFilter == Filter_Ingredients)
 | 
						|
        categories = MWWorld::ContainerStore::Type_Ingredient;
 | 
						|
 | 
						|
    /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
 | 
						|
 | 
						|
    std::vector< std::pair<MWWorld::Ptr, ItemState> > items;
 | 
						|
 | 
						|
    std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
 | 
						|
 | 
						|
    // add bought items (always at the beginning)
 | 
						|
    std::vector<MWWorld::Ptr> boughtItems;
 | 
						|
    for (MWWorld::ContainerStoreIterator it (mBoughtItems.begin()); it!=mBoughtItems.end(); ++it)
 | 
						|
    {
 | 
						|
        boughtItems.push_back(*it);
 | 
						|
    }
 | 
						|
    std::sort(boughtItems.begin(), boughtItems.end(), sortItems);
 | 
						|
 | 
						|
    for (std::vector<MWWorld::Ptr>::iterator it=boughtItems.begin();
 | 
						|
        it != boughtItems.end(); ++it)
 | 
						|
    {
 | 
						|
        items.push_back( std::make_pair(*it, ItemState_Barter) );
 | 
						|
    }
 | 
						|
 | 
						|
    // filter out the equipped items of categories we don't want
 | 
						|
    std::vector<MWWorld::Ptr> unwantedItems = equippedItems;
 | 
						|
    for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
 | 
						|
    {
 | 
						|
        std::vector<MWWorld::Ptr>::iterator found = std::find(unwantedItems.begin(), unwantedItems.end(), *iter);
 | 
						|
        if (found != unwantedItems.end())
 | 
						|
        {
 | 
						|
            unwantedItems.erase(found);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    // now erase everything that's still in unwantedItems.
 | 
						|
    for (std::vector<MWWorld::Ptr>::iterator it=unwantedItems.begin();
 | 
						|
        it != unwantedItems.end(); ++it)
 | 
						|
    {
 | 
						|
        std::vector<MWWorld::Ptr>::iterator found = std::find(equippedItems.begin(), equippedItems.end(), *it);
 | 
						|
        assert(found != equippedItems.end());
 | 
						|
        equippedItems.erase(found);
 | 
						|
    }
 | 
						|
    // and add the items that are left (= have the correct category)
 | 
						|
    if (!ignoreEquippedItems())
 | 
						|
    {
 | 
						|
        for (std::vector<MWWorld::Ptr>::const_iterator it=equippedItems.begin();
 | 
						|
            it != equippedItems.end(); ++it)
 | 
						|
        {
 | 
						|
            items.push_back( std::make_pair(*it, ItemState_Equipped) );
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    std::vector<MWWorld::Ptr> ignoreItems = itemsToIgnore();
 | 
						|
 | 
						|
    // now add the regular items
 | 
						|
    std::vector<MWWorld::Ptr> regularItems;
 | 
						|
    for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
 | 
						|
    {
 | 
						|
        if (std::find(equippedItems.begin(), equippedItems.end(), *iter) == equippedItems.end()
 | 
						|
            && std::find(ignoreItems.begin(), ignoreItems.end(), *iter) == ignoreItems.end()
 | 
						|
            && std::find(mBoughtItems.begin(), mBoughtItems.end(), *iter) == mBoughtItems.end())
 | 
						|
            regularItems.push_back(*iter);
 | 
						|
    }
 | 
						|
 | 
						|
    // sort them and add
 | 
						|
    std::sort(regularItems.begin(), regularItems.end(), sortItems);
 | 
						|
    for (std::vector<MWWorld::Ptr>::const_iterator it=regularItems.begin(); it!=regularItems.end(); ++it)
 | 
						|
    {
 | 
						|
        items.push_back( std::make_pair(*it, ItemState_Normal) );
 | 
						|
    }
 | 
						|
 | 
						|
    for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
 | 
						|
        it != items.end(); ++it)
 | 
						|
    {
 | 
						|
        const MWWorld::Ptr* iter = &((*it).first);
 | 
						|
 | 
						|
        int displayCount = iter->getRefData().getCount();
 | 
						|
        if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
 | 
						|
        {
 | 
						|
            displayCount -= mDragAndDrop->mDraggedCount;
 | 
						|
        }
 | 
						|
        if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
 | 
						|
        {
 | 
						|
            std::string path = std::string("icons\\");
 | 
						|
            path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
 | 
						|
 | 
						|
            // background widget (for the "equipped" frame and magic item background image)
 | 
						|
            bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != "");
 | 
						|
            MyGUI::ImageBox* backgroundWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
 | 
						|
            backgroundWidget->setUserString("ToolTipType", "ItemPtr");
 | 
						|
            backgroundWidget->setUserData(*iter);
 | 
						|
 | 
						|
            std::string backgroundTex = "textures\\menu_icon";
 | 
						|
            if (isMagic)
 | 
						|
                backgroundTex += "_magic";
 | 
						|
            if (it->second == ItemState_Normal)
 | 
						|
            {
 | 
						|
                if (!isMagic)
 | 
						|
                    backgroundTex = "";
 | 
						|
            }
 | 
						|
            else if (it->second == ItemState_Equipped)
 | 
						|
            {
 | 
						|
                backgroundTex += "_equip";
 | 
						|
            }
 | 
						|
            else if (it->second == ItemState_Barter)
 | 
						|
            {
 | 
						|
                backgroundTex += "_barter";
 | 
						|
            }
 | 
						|
            if (backgroundTex != "")
 | 
						|
                backgroundTex += ".dds";
 | 
						|
 | 
						|
            backgroundWidget->setImageTexture(backgroundTex);
 | 
						|
            if (it->second == ItemState_Barter && !isMagic)
 | 
						|
                backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
 | 
						|
            else
 | 
						|
                backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
 | 
						|
            backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onSelectedItem);
 | 
						|
            backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerBase::onMouseWheel);
 | 
						|
 | 
						|
            // image
 | 
						|
            ImageBox* image = backgroundWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
 | 
						|
            int pos = path.rfind(".");
 | 
						|
            path.erase(pos);
 | 
						|
            path.append(".dds");
 | 
						|
            image->setImageTexture(path);
 | 
						|
            image->setNeedMouseFocus(false);
 | 
						|
 | 
						|
            // text widget that shows item count
 | 
						|
            MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
 | 
						|
            text->setTextAlign(MyGUI::Align::Right);
 | 
						|
            text->setNeedMouseFocus(false);
 | 
						|
            text->setTextShadow(true);
 | 
						|
            text->setTextShadowColour(MyGUI::Colour(0,0,0));
 | 
						|
            text->setCaption(getCountString(displayCount));
 | 
						|
 | 
						|
            y += 42;
 | 
						|
            if (y > maxHeight)
 | 
						|
            {
 | 
						|
                x += 42;
 | 
						|
                y = 0;
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height);
 | 
						|
    mItemView->setCanvasSize(size);
 | 
						|
    mContainerWidget->setSize(size);
 | 
						|
 | 
						|
    notifyContentChanged();
 | 
						|
}
 | 
						|
 | 
						|
std::string ContainerBase::getCountString(const int count)
 | 
						|
{
 | 
						|
    if (count == 1)
 | 
						|
        return "";
 | 
						|
    if (count > 9999)
 | 
						|
        return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
 | 
						|
    else
 | 
						|
        return boost::lexical_cast<std::string>(count);
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
 | 
						|
{
 | 
						|
    int origCount = item.getRefData().getCount();
 | 
						|
    item.getRefData().setCount(count);
 | 
						|
    MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
 | 
						|
    item.getRefData().setCount(origCount - count);
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::addItem(MWWorld::Ptr item, int count)
 | 
						|
{
 | 
						|
    MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
 | 
						|
 | 
						|
    int origCount = item.getRefData().getCount();    
 | 
						|
 | 
						|
    item.getRefData().setCount(count);
 | 
						|
    MWWorld::ContainerStoreIterator it = containerStore.add(item);
 | 
						|
 | 
						|
    item.getRefData().setCount(origCount - count);
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::transferBoughtItems()
 | 
						|
{
 | 
						|
    MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
 | 
						|
 | 
						|
    for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
 | 
						|
    {
 | 
						|
        containerStore.add(*it);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
 | 
						|
{
 | 
						|
    for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
 | 
						|
    {
 | 
						|
        store.add(*it);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
MWWorld::ContainerStore& ContainerBase::getContainerStore()
 | 
						|
{
 | 
						|
    MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
 | 
						|
    return store;
 | 
						|
}
 | 
						|
 | 
						|
// ------------------------------------------------------------------------------------------------
 | 
						|
 | 
						|
ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
 | 
						|
    : ContainerBase(dragAndDrop)
 | 
						|
    , WindowBase("openmw_container_window_layout.xml", parWindowManager)
 | 
						|
{
 | 
						|
    getWidget(mTakeButton, "TakeButton");
 | 
						|
    getWidget(mCloseButton, "CloseButton");
 | 
						|
 | 
						|
    MyGUI::ScrollView* itemView;
 | 
						|
    MyGUI::Widget* containerWidget;
 | 
						|
    getWidget(containerWidget, "Items");
 | 
						|
    getWidget(itemView, "ItemView");
 | 
						|
    setWidgets(containerWidget, itemView);
 | 
						|
 | 
						|
    mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
 | 
						|
    mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
 | 
						|
 | 
						|
    // adjust buttons size to fit text
 | 
						|
    int closeButtonWidth = mCloseButton->getTextSize().width+24;
 | 
						|
    int takeButtonWidth = mTakeButton->getTextSize().width+24;
 | 
						|
    mCloseButton->setCoord(600-20-closeButtonWidth, mCloseButton->getCoord().top, closeButtonWidth, mCloseButton->getCoord().height);
 | 
						|
    mTakeButton->setCoord(600-20-closeButtonWidth-takeButtonWidth-8, mTakeButton->getCoord().top, takeButtonWidth, mTakeButton->getCoord().height);
 | 
						|
 | 
						|
    int w = MyGUI::RenderManager::getInstance().getViewSize().width;
 | 
						|
    //int h = MyGUI::RenderManager::getInstance().getViewSize().height;
 | 
						|
 | 
						|
    static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
 | 
						|
 | 
						|
    setCoord(w-600,0,600,300);
 | 
						|
}
 | 
						|
 | 
						|
ContainerWindow::~ContainerWindow()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void ContainerWindow::onWindowResize(MyGUI::Window* window)
 | 
						|
{
 | 
						|
    drawItems();
 | 
						|
}
 | 
						|
 | 
						|
void ContainerWindow::open(MWWorld::Ptr container)
 | 
						|
{
 | 
						|
    openContainer(container);
 | 
						|
    setTitle(MWWorld::Class::get(container).getName(container));
 | 
						|
    drawItems();
 | 
						|
}
 | 
						|
 | 
						|
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
 | 
						|
{
 | 
						|
    if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
 | 
						|
    {
 | 
						|
        MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
 | 
						|
{
 | 
						|
    if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
 | 
						|
    {
 | 
						|
        // transfer everything into the player's inventory
 | 
						|
        MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
 | 
						|
 | 
						|
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
 | 
						|
        MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
 | 
						|
 | 
						|
        int i=0;
 | 
						|
        for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter)
 | 
						|
        {
 | 
						|
            playerStore.add(*iter);
 | 
						|
 | 
						|
            if (i==0)
 | 
						|
            {
 | 
						|
                // play the sound of the first object
 | 
						|
                std::string sound = MWWorld::Class::get(*iter).getUpSoundId(*iter);
 | 
						|
                MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
 | 
						|
            }
 | 
						|
 | 
						|
            ++i;
 | 
						|
        }
 | 
						|
 | 
						|
        containerStore.clear();
 | 
						|
 | 
						|
        MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ContainerWindow::onReferenceUnavailable()
 | 
						|
{
 | 
						|
    MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
 | 
						|
}
 |