1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-15 22:19:54 +00:00
openmw-tes3mp/apps/openmw/mwgui/container.cpp

271 lines
8.8 KiB
C++
Raw Normal View History

2012-04-15 15:52:39 +00:00
#include "container.hpp"
2015-01-10 01:50:43 +00:00
#include <MyGUI_InputManager.h>
#include <MyGUI_Button.h>
2012-05-11 09:52:07 +00:00
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
2014-01-07 18:49:16 +00:00
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/scriptmanager.hpp"
2013-05-11 16:38:27 +00:00
#include "../mwworld/class.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwscript/interpretercontext.hpp"
#include "countdialog.hpp"
#include "inventorywindow.hpp"
2012-04-15 15:52:39 +00:00
2013-05-11 16:38:27 +00:00
#include "itemview.hpp"
#include "inventoryitemmodel.hpp"
#include "containeritemmodel.hpp"
2013-05-11 16:38:27 +00:00
#include "sortfilteritemmodel.hpp"
#include "pickpocketitemmodel.hpp"
#include "draganddrop.hpp"
2013-05-11 16:38:27 +00:00
2013-04-17 22:56:48 +00:00
namespace MWGui
2012-04-15 15:52:39 +00:00
{
2012-05-12 20:44:12 +00:00
2013-05-11 16:38:27 +00:00
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
: WindowBase("openmw_container_window.layout")
, mDragAndDrop(dragAndDrop)
2018-10-09 06:21:12 +00:00
, mSortModel(nullptr)
, mModel(nullptr)
, mSelectedItem(-1)
{
2013-05-11 16:38:27 +00:00
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
getWidget(mTakeButton, "TakeButton");
getWidget(mCloseButton, "CloseButton");
2013-05-11 16:38:27 +00:00
getWidget(mItemView, "ItemView");
mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &ContainerWindow::onBackgroundSelected);
mItemView->eventItemClicked += MyGUI::newDelegate(this, &ContainerWindow::onItemSelected);
2013-03-16 18:00:14 +00:00
2013-05-11 16:38:27 +00:00
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
2013-03-16 18:00:14 +00:00
2013-05-11 16:38:27 +00:00
setCoord(200,0,600,300);
}
2013-03-16 18:00:14 +00:00
2013-05-11 16:38:27 +00:00
void ContainerWindow::onItemSelected(int index)
{
if (mDragAndDrop->mIsOnDragAndDrop)
{
dropItem();
return;
}
const ItemStack& item = mSortModel->getItem(index);
// We can't take a conjured item from a container (some NPC we're pickpocketing, a box, etc)
if (item.mFlags & ItemStack::Flag_Bound)
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage1}");
return;
}
2013-05-11 16:38:27 +00:00
MWWorld::Ptr object = item.mBase;
int count = item.mCount;
bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
if (MyGUI::InputManager::getInstance().isControlPressed())
count = 1;
2013-05-11 16:38:27 +00:00
mSelectedItem = mSortModel->mapToSource(index);
2012-04-15 15:52:39 +00:00
2013-05-11 16:38:27 +00:00
if (count > 1 && !shift)
2013-04-17 22:56:48 +00:00
{
2013-05-11 16:38:27 +00:00
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->openCountDialog(object.getClass().getName(object), "#{sTake}", count);
2013-05-11 16:38:27 +00:00
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
2012-05-06 09:04:07 +00:00
}
else
2018-10-09 06:21:12 +00:00
dragItem (nullptr, count);
}
2013-05-11 16:38:27 +00:00
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
{
if (!mModel)
return;
if (!onTakeItem(mModel->getItem(mSelectedItem), count))
return;
2013-05-11 16:38:27 +00:00
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
}
2013-05-11 16:38:27 +00:00
void ContainerWindow::dropItem()
2013-04-17 22:56:48 +00:00
{
if (!mModel)
return;
2017-10-04 18:37:08 +00:00
bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount);
2012-05-12 20:44:12 +00:00
2017-10-04 18:37:08 +00:00
if (success)
mDragAndDrop->drop(mModel, mItemView);
2013-04-17 22:56:48 +00:00
}
2012-05-12 20:44:12 +00:00
2013-05-11 16:38:27 +00:00
void ContainerWindow::onBackgroundSelected()
2012-04-30 11:01:18 +00:00
{
if (mDragAndDrop->mIsOnDragAndDrop)
2013-05-11 16:38:27 +00:00
dropItem();
2012-04-30 11:01:18 +00:00
}
2012-04-15 15:52:39 +00:00
void ContainerWindow::setPtr(const MWWorld::Ptr& container)
2012-05-11 14:58:07 +00:00
{
2013-05-11 16:38:27 +00:00
mPtr = container;
2012-05-12 12:01:59 +00:00
bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead();
if (mPtr.getClass().hasInventoryStore(mPtr))
2013-04-17 22:56:48 +00:00
{
if (mPtr.getClass().isNpc() && !loot)
{
// we are stealing stuff
2017-10-04 17:25:22 +00:00
mModel = new PickpocketItemModel(mPtr, new InventoryItemModel(container),
!mPtr.getClass().getCreatureStats(mPtr).getKnockedDown());
}
else
mModel = new InventoryItemModel(container);
2013-04-17 22:56:48 +00:00
}
2013-05-11 16:38:27 +00:00
else
{
mModel = new ContainerItemModel(container);
}
2013-04-17 22:56:48 +00:00
mDisposeCorpseButton->setVisible(loot);
2012-05-12 12:01:59 +00:00
2013-05-11 16:38:27 +00:00
mSortModel = new SortFilterItemModel(mModel);
mItemView->setModel (mSortModel);
mItemView->resetScrollBars();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
2014-01-10 23:24:21 +00:00
setTitle(container.getClass().getName(container));
2013-04-17 22:56:48 +00:00
}
void ContainerWindow::resetReference()
{
ReferenceInterface::resetReference();
2018-10-09 06:21:12 +00:00
mItemView->setModel(nullptr);
mModel = nullptr;
mSortModel = nullptr;
}
void ContainerWindow::onClose()
{
WindowBase::onClose();
if (mModel)
mModel->onClose();
if (!mPtr.isEmpty())
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
}
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
2017-09-23 10:18:39 +00:00
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
2013-04-17 22:56:48 +00:00
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{
2018-10-09 06:21:12 +00:00
if(mDragAndDrop != nullptr && mDragAndDrop->mIsOnDragAndDrop)
return;
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
// 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))
2013-04-17 22:56:48 +00:00
{
MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr);
2013-05-11 16:38:27 +00:00
for (size_t i=0; i<mModel->getItemCount(); ++i)
2012-05-16 12:30:02 +00:00
{
const ItemStack& item = mModel->getItem(i);
if (invStore.isEquipped(item.mBase) == false)
continue;
invStore.unequipItem(item.mBase, mPtr);
}
}
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);
2013-04-17 22:56:48 +00:00
}
const ItemStack& item = mModel->getItem(i);
if (!onTakeItem(item, item.mCount))
break;
mModel->moveItem(item, item.mCount, playerModel);
2013-04-17 22:56:48 +00:00
}
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
2012-05-11 14:58:07 +00:00
}
2013-04-17 22:56:48 +00:00
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
{
2018-10-09 06:21:12 +00:00
if(mDragAndDrop == nullptr || !mDragAndDrop->mIsOnDragAndDrop)
2013-04-17 22:56:48 +00:00
{
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
2013-04-17 22:56:48 +00:00
onTakeAllButtonClicked(mTakeButton);
if (mPtr.getClass().isPersistent(mPtr))
2013-05-16 16:50:26 +00:00
MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
else
{
MWMechanics::CreatureStats& creatureStats = mPtr.getClass().getCreatureStats(mPtr);
// If we dispose corpse before end of death animation, we should update death counter counter manually.
// Also we should run actor's script - it may react on actor's death.
if (creatureStats.isDead() && !creatureStats.isDeathAnimationFinished())
{
creatureStats.setDeathAnimationFinished(true);
MWBase::Environment::get().getMechanicsManager()->notifyDied(mPtr);
const std::string script = mPtr.getClass().getScript(mPtr);
if (!script.empty() && MWBase::Environment::get().getWorld()->getScriptsEnabled())
{
MWScript::InterpreterContext interpreterContext (&mPtr.getRefData().getLocals(), mPtr);
MWBase::Environment::get().getScriptManager()->run (script, interpreterContext);
}
}
2013-04-17 22:56:48 +00:00
MWBase::Environment::get().getWorld()->deleteObject(mPtr);
}
2013-04-17 22:56:48 +00:00
mPtr = MWWorld::Ptr();
}
}
void ContainerWindow::onReferenceUnavailable()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
bool ContainerWindow::onTakeItem(const ItemStack &item, int count)
{
2017-10-04 17:25:22 +00:00
return mModel->onTakeItem(item.mBase, count);
}
}