#include "inventorywindow.hpp" #include #include #include #include #include #include #include "../mwclass/container.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/world.hpp" #include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwworld/manualref.hpp" #include "../mwscript/scriptmanager.hpp" #include "../mwscript/compilercontext.hpp" #include "../mwscript/interpretercontext.hpp" #include "../mwscript/extensions.hpp" #include "../mwscript/globalscripts.hpp" #include "window_manager.hpp" #include "widgets.hpp" #include "bookwindow.hpp" #include "scrollwindow.hpp" namespace MWGui { InventoryWindow::InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop) : ContainerBase(dragAndDrop) , WindowPinnableBase("openmw_inventory_window_layout.xml", parWindowManager) { static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); getWidget(mAvatar, "Avatar"); getWidget(mEncumbranceBar, "EncumbranceBar"); getWidget(mEncumbranceText, "EncumbranceBarT"); getWidget(mFilterAll, "AllButton"); getWidget(mFilterWeapon, "WeaponButton"); getWidget(mFilterApparel, "ApparelButton"); getWidget(mFilterMagic, "MagicButton"); getWidget(mFilterMisc, "MiscButton"); getWidget(mLeftPane, "LeftPane"); getWidget(mRightPane, "RightPane"); mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked); MyGUI::ScrollView* itemView; MyGUI::Widget* containerWidget; getWidget(containerWidget, "Items"); getWidget(itemView, "ItemView"); setWidgets(containerWidget, itemView); mFilterAll->setCaption (MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sAllTab")->str); mFilterWeapon->setCaption (MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sWeaponTab")->str); mFilterApparel->setCaption (MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sApparelTab")->str); mFilterMagic->setCaption (MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sMagicTab")->str); mFilterMisc->setCaption (MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sMiscTab")->str); // adjust size of buttons to fit text int curX = 0; mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height ); curX += mFilterAll->getTextSize().width + 24 + 4; mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top); mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height ); curX += mFilterWeapon->getTextSize().width + 24 + 4; mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top); mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height ); curX += mFilterApparel->getTextSize().width + 24 + 4; mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top); mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height ); curX += mFilterMagic->getTextSize().width + 24 + 4; mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top); mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height ); mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterAll->setStateSelected(true); setCoord(0, 342, 600, 258); } void InventoryWindow::openInventory() { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); openContainer(player); onWindowResize(static_cast(mMainWidget)); updateEncumbranceBar(); } void InventoryWindow::onWindowResize(MyGUI::Window* _sender) { const float aspect = 0.5; // fixed aspect ratio for the left pane mLeftPane->setSize( (_sender->getSize().height-44) * aspect, _sender->getSize().height-44 ); mRightPane->setCoord( mLeftPane->getPosition().left + (_sender->getSize().height-44) * aspect + 4, mRightPane->getPosition().top, _sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15, _sender->getSize().height-44 ); drawItems(); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) { if (_sender == mFilterAll) setFilter(ContainerBase::Filter_All); else if (_sender == mFilterWeapon) setFilter(ContainerBase::Filter_Weapon); else if (_sender == mFilterApparel) setFilter(ContainerBase::Filter_Apparel); else if (_sender == mFilterMagic) setFilter(ContainerBase::Filter_Magic); else if (_sender == mFilterMisc) setFilter(ContainerBase::Filter_Misc); mFilterAll->setStateSelected(false); mFilterWeapon->setStateSelected(false); mFilterApparel->setStateSelected(false); mFilterMagic->setStateSelected(false); mFilterMisc->setStateSelected(false); static_cast(_sender)->setStateSelected(true); } void InventoryWindow::onPinToggled() { mWindowManager.setWeaponVisibility(!mPinned); } void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender) { if (mDragAndDrop->mIsOnDragAndDrop) { MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData(); // can the object be equipped? std::pair, bool> slots = MWWorld::Class::get(ptr).getEquipmentSlots(ptr); if (slots.first.empty()) { // can't be equipped, try to use instead boost::shared_ptr action = MWWorld::Class::get(ptr).use(ptr); action->execute(); /// \todo scripts // this is necessary for books/scrolls: if they are already in the player's inventory, // the "Take" button should not be visible. // NOTE: the take button is "reset" when the window opens, so we can safely do the following // without screwing up future book windows if (mDragAndDrop->mWasInInventory) { mWindowManager.getBookWindow()->setTakeButtonShow(false); mWindowManager.getScrollWindow()->setTakeButtonShow(false); } } else { MWWorld::InventoryStore& invStore = static_cast(MWWorld::Class::get(mContainer).getContainerStore(mContainer)); MWWorld::ContainerStoreIterator it = invStore.begin(); if (mDragAndDrop->mDraggedFrom != this) { // add item to the player's inventory int origCount = ptr.getRefData().getCount(); ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount); it = invStore.add(ptr); (*it).getRefData().setCount(mDragAndDrop->mDraggedCount); } else { // retrieve iterator to the item for (; it != invStore.end(); ++it) { if (*it == ptr) { break; } } } assert(it != invStore.end()); // equip the item in the first free slot for (std::vector::const_iterator slot=slots.first.begin(); slot!=slots.first.end(); ++slot) { // if all slots are occupied, replace the last slot if (slot == --slots.first.end()) { invStore.equip(*slot, it); break; } if (invStore.getSlot(*slot) == invStore.end()) { // slot is not occupied invStore.equip(*slot, it); break; } } } mDragAndDrop->mIsOnDragAndDrop = false; MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget); mWindowManager.setDragDrop(false); drawItems(); } } std::vector InventoryWindow::getEquippedItems() { MWWorld::InventoryStore& invStore = static_cast(MWWorld::Class::get(mContainer).getContainerStore(mContainer)); std::vector items; for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) { MWWorld::ContainerStoreIterator it = invStore.getSlot(slot); if (it != invStore.end()) { items.push_back(*it); } } return items; } void InventoryWindow::_unequipItem(MWWorld::Ptr item) { MWWorld::InventoryStore& invStore = static_cast(MWWorld::Class::get(mContainer).getContainerStore(mContainer)); for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) { MWWorld::ContainerStoreIterator it = invStore.getSlot(slot); if (it != invStore.end() && *it == item) { invStore.equip(slot, invStore.end()); return; } } } void InventoryWindow::updateEncumbranceBar() { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); float capacity = MWWorld::Class::get(player).getCapacity(player); float encumbrance = MWWorld::Class::get(player).getEncumbrance(player); mEncumbranceBar->setProgressRange(capacity); mEncumbranceBar->setProgressPosition(encumbrance); mEncumbranceText->setCaption( boost::lexical_cast(int(encumbrance)) + "/" + boost::lexical_cast(int(capacity)) ); } void InventoryWindow::notifyContentChanged() { } void InventoryWindow::Update() { updateEncumbranceBar(); ContainerBase::Update(); } }