2012-04-15 17:52:39 +02:00
|
|
|
#include "container.hpp"
|
|
|
|
|
2015-01-10 02:50:43 +01:00
|
|
|
#include <MyGUI_InputManager.h>
|
|
|
|
#include <MyGUI_Button.h>
|
|
|
|
|
2012-05-11 11:52:07 +02:00
|
|
|
#include "../mwbase/environment.hpp"
|
2012-07-03 12:30:50 +02:00
|
|
|
#include "../mwbase/world.hpp"
|
2012-08-09 14:33:21 +02:00
|
|
|
#include "../mwbase/soundmanager.hpp"
|
2012-08-12 18:11:09 +02:00
|
|
|
#include "../mwbase/windowmanager.hpp"
|
2014-01-07 03:01:33 +01:00
|
|
|
#include "../mwbase/dialoguemanager.hpp"
|
2014-01-07 19:49:16 +01:00
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
2015-08-21 21:12:39 +12:00
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
2012-07-03 12:30:50 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
#include "../mwworld/class.hpp"
|
2012-07-03 12:30:50 +02:00
|
|
|
|
2014-01-07 03:01:33 +01:00
|
|
|
#include "../mwmechanics/pickpocket.hpp"
|
2014-04-27 05:40:07 +02:00
|
|
|
#include "../mwmechanics/creaturestats.hpp"
|
2014-01-07 03:01:33 +01:00
|
|
|
|
2012-05-15 12:51:51 +02:00
|
|
|
#include "countdialog.hpp"
|
2012-05-18 17:27:55 +02:00
|
|
|
#include "inventorywindow.hpp"
|
2012-04-15 17:52:39 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
#include "itemview.hpp"
|
2014-06-05 22:13:18 +02:00
|
|
|
#include "itemwidget.hpp"
|
2013-05-11 18:38:27 +02:00
|
|
|
#include "inventoryitemmodel.hpp"
|
|
|
|
#include "sortfilteritemmodel.hpp"
|
|
|
|
#include "pickpocketitemmodel.hpp"
|
2015-01-10 01:21:17 +01:00
|
|
|
#include "draganddrop.hpp"
|
2013-05-11 18:38:27 +02:00
|
|
|
|
2013-04-17 18:56:48 -04:00
|
|
|
namespace MWGui
|
2012-04-15 17:52:39 +02:00
|
|
|
{
|
2012-05-12 22:44:12 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
|
|
|
|
: WindowBase("openmw_container_window.layout")
|
|
|
|
, mDragAndDrop(dragAndDrop)
|
2014-01-07 03:01:33 +01:00
|
|
|
, mPickpocketDetected(false)
|
2015-04-30 19:24:27 -05:00
|
|
|
, mSortModel(NULL)
|
|
|
|
, mModel(NULL)
|
|
|
|
, mSelectedItem(-1)
|
2012-05-15 20:33:34 +02:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
|
|
|
|
getWidget(mTakeButton, "TakeButton");
|
|
|
|
getWidget(mCloseButton, "CloseButton");
|
2012-05-15 21:44:57 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
getWidget(mItemView, "ItemView");
|
|
|
|
mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &ContainerWindow::onBackgroundSelected);
|
|
|
|
mItemView->eventItemClicked += MyGUI::newDelegate(this, &ContainerWindow::onItemSelected);
|
2013-03-16 19:00:14 +01:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
|
|
|
|
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
2014-01-11 00:24:21 +01:00
|
|
|
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ContainerWindow::onKeyPressed);
|
2013-05-11 18:38:27 +02:00
|
|
|
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
2013-03-16 19:00:14 +01:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
setCoord(200,0,600,300);
|
|
|
|
}
|
2013-03-16 19:00:14 +01:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
void ContainerWindow::onItemSelected(int index)
|
|
|
|
{
|
2014-09-11 01:00:39 -04:00
|
|
|
if (mDragAndDrop->mIsOnDragAndDrop)
|
|
|
|
{
|
2016-03-05 19:53:24 +01:00
|
|
|
if (mModel && mModel->allowedToInsertItems())
|
2014-09-11 01:00:39 -04:00
|
|
|
dropItem();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-09-10 23:38:38 -04:00
|
|
|
const ItemStack& item = mSortModel->getItem(index);
|
|
|
|
|
|
|
|
// We can't take a conjured item from a container (some NPC we're pickpocketing, a box, etc)
|
2014-09-13 18:48:41 -04:00
|
|
|
if (item.mFlags & ItemStack::Flag_Bound)
|
2014-09-10 23:38:38 -04:00
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage1}");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
MWWorld::Ptr object = item.mBase;
|
|
|
|
int count = item.mCount;
|
|
|
|
bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
|
|
|
|
if (MyGUI::InputManager::getInstance().isControlPressed())
|
|
|
|
count = 1;
|
2012-05-15 20:33:34 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
mSelectedItem = mSortModel->mapToSource(index);
|
2012-04-15 17:52:39 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
if (count > 1 && !shift)
|
2013-04-17 18:56:48 -04:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
2015-06-04 20:31:28 +02:00
|
|
|
dialog->openCountDialog(object.getClass().getName(object), "#{sTake}", count);
|
2013-05-11 18:38:27 +02:00
|
|
|
dialog->eventOkClicked.clear();
|
|
|
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
|
2012-05-06 11:04:07 +02:00
|
|
|
}
|
2013-04-17 18:56:48 -04:00
|
|
|
else
|
2013-05-11 18:38:27 +02:00
|
|
|
dragItem (NULL, count);
|
2012-05-18 20:53:24 +02:00
|
|
|
}
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
|
2012-05-18 20:53:24 +02:00
|
|
|
{
|
2014-01-07 03:01:33 +01:00
|
|
|
if (!onTakeItem(mModel->getItem(mSelectedItem), count))
|
|
|
|
return;
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
2012-05-18 17:27:55 +02:00
|
|
|
}
|
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
void ContainerWindow::dropItem()
|
2013-04-17 18:56:48 -04:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
if (mPtr.getTypeName() == typeid(ESM::Container).name())
|
2013-03-07 14:00:13 +01:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
// check container organic flag
|
|
|
|
MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
|
|
|
|
if (ref->mBase->mFlags & ESM::Container::Organic)
|
2013-04-17 18:56:48 -04:00
|
|
|
{
|
2013-05-11 18:38:27 +02:00
|
|
|
MWBase::Environment::get().getWindowManager()->
|
|
|
|
messageBox("#{sContentsMessage2}");
|
|
|
|
return;
|
2013-04-17 18:56:48 -04:00
|
|
|
}
|
2014-07-14 17:27:36 +02:00
|
|
|
|
|
|
|
// check that we don't exceed container capacity
|
|
|
|
MWWorld::Ptr item = mDragAndDrop->mItem.mBase;
|
|
|
|
float weight = item.getClass().getWeight(item) * mDragAndDrop->mDraggedCount;
|
|
|
|
if (mPtr.getClass().getCapacity(mPtr) < mPtr.getClass().getEncumbrance(mPtr) + weight)
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}");
|
|
|
|
return;
|
|
|
|
}
|
2013-04-17 18:56:48 -04:00
|
|
|
}
|
2012-05-12 22:44:12 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
mDragAndDrop->drop(mModel, mItemView);
|
2013-04-17 18:56:48 -04:00
|
|
|
}
|
2012-05-12 22:44:12 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
void ContainerWindow::onBackgroundSelected()
|
2012-04-30 13:01:18 +02:00
|
|
|
{
|
2016-03-05 19:53:24 +01:00
|
|
|
if (mDragAndDrop->mIsOnDragAndDrop && mModel && mModel->allowedToInsertItems())
|
2013-05-11 18:38:27 +02:00
|
|
|
dropItem();
|
2012-04-30 13:01:18 +02:00
|
|
|
}
|
2012-04-15 17:52:39 +02:00
|
|
|
|
2015-06-04 20:31:28 +02:00
|
|
|
void ContainerWindow::openContainer(const MWWorld::Ptr& container, bool loot)
|
2012-05-11 16:58:07 +02:00
|
|
|
{
|
2014-01-07 03:01:33 +01:00
|
|
|
mPickpocketDetected = false;
|
2013-05-11 18:38:27 +02:00
|
|
|
mPtr = container;
|
2012-05-12 14:01:59 +02:00
|
|
|
|
2013-05-17 14:11:02 +02:00
|
|
|
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
|
2013-04-17 18:56:48 -04:00
|
|
|
{
|
|
|
|
// we are stealing stuff
|
2015-08-21 21:12:39 +12:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
2014-08-25 17:01:02 +02:00
|
|
|
mModel = new PickpocketItemModel(player, new InventoryItemModel(container),
|
|
|
|
!mPtr.getClass().getCreatureStats(mPtr).getKnockedDown());
|
2013-04-17 18:56:48 -04:00
|
|
|
}
|
2013-05-11 18:38:27 +02:00
|
|
|
else
|
|
|
|
mModel = new InventoryItemModel(container);
|
2013-03-17 22:28:28 +01:00
|
|
|
|
2013-04-17 18:56:48 -04:00
|
|
|
mDisposeCorpseButton->setVisible(loot);
|
2012-05-12 14:01:59 +02:00
|
|
|
|
2013-05-11 18:38:27 +02:00
|
|
|
mSortModel = new SortFilterItemModel(mModel);
|
|
|
|
|
|
|
|
mItemView->setModel (mSortModel);
|
2015-06-04 23:09:40 +03:00
|
|
|
mItemView->resetScrollBars();
|
2013-11-16 22:29:40 +01:00
|
|
|
|
2014-01-29 17:26:18 +01:00
|
|
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
|
2014-01-11 00:24:21 +01:00
|
|
|
|
2014-05-22 20:37:22 +02:00
|
|
|
setTitle(container.getClass().getName(container));
|
2013-04-17 18:56:48 -04:00
|
|
|
}
|
|
|
|
|
2014-01-11 00:24:21 +01:00
|
|
|
void ContainerWindow::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
|
|
|
{
|
|
|
|
if (_key == MyGUI::KeyCode::Space)
|
|
|
|
onCloseButtonClicked(mCloseButton);
|
|
|
|
if (_key == MyGUI::KeyCode::Return || _key == MyGUI::KeyCode::NumpadEnter)
|
|
|
|
onTakeAllButtonClicked(mTakeButton);
|
|
|
|
}
|
|
|
|
|
2014-07-07 23:37:59 +02:00
|
|
|
void ContainerWindow::resetReference()
|
|
|
|
{
|
|
|
|
ReferenceInterface::resetReference();
|
|
|
|
mItemView->setModel(NULL);
|
2014-07-14 16:53:58 +02:00
|
|
|
mModel = NULL;
|
|
|
|
mSortModel = NULL;
|
2014-07-07 23:37:59 +02:00
|
|
|
}
|
|
|
|
|
2014-01-07 03:01:33 +01:00
|
|
|
void ContainerWindow::close()
|
|
|
|
{
|
|
|
|
WindowBase::close();
|
|
|
|
|
2014-01-07 18:11:19 +01:00
|
|
|
if (dynamic_cast<PickpocketItemModel*>(mModel)
|
|
|
|
// Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened)
|
|
|
|
&& !MWBase::Environment::get().getWindowManager()->containsMode(GM_Container)
|
|
|
|
// If it was already detected while taking an item, no need to check now
|
|
|
|
&& !mPickpocketDetected
|
2014-01-07 03:01:33 +01:00
|
|
|
)
|
|
|
|
{
|
2015-08-21 21:12:39 +12:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
2014-01-07 19:49:16 +01:00
|
|
|
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
2014-01-07 03:01:33 +01:00
|
|
|
if (pickpocket.finish())
|
|
|
|
{
|
2014-12-19 21:45:26 +01:00
|
|
|
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
|
|
|
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true);
|
2014-01-07 03:01:33 +01:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
|
|
|
mPickpocketDetected = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-26 23:13:37 -04:00
|
|
|
void ContainerWindow::exit()
|
2013-04-17 18:56:48 -04:00
|
|
|
{
|
|
|
|
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
2012-05-12 14:01:59 +02:00
|
|
|
{
|
2013-04-17 18:56:48 -04:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-26 23:13:37 -04:00
|
|
|
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
|
|
|
{
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
|
2013-04-17 18:56:48 -04:00
|
|
|
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
|
|
|
{
|
|
|
|
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
|
|
|
{
|
|
|
|
// transfer everything into the player's inventory
|
2013-05-11 18:38:27 +02:00
|
|
|
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
|
2013-05-19 18:40:37 +02:00
|
|
|
mModel->update();
|
2013-05-11 18:38:27 +02:00
|
|
|
for (size_t i=0; i<mModel->getItemCount(); ++i)
|
2012-05-16 14:30:02 +02:00
|
|
|
{
|
2013-04-17 18:56:48 -04:00
|
|
|
if (i==0)
|
|
|
|
{
|
|
|
|
// play the sound of the first object
|
2013-05-11 18:38:27 +02:00
|
|
|
MWWorld::Ptr item = mModel->getItem(i).mBase;
|
2014-05-22 20:37:22 +02:00
|
|
|
std::string sound = item.getClass().getUpSoundId(item);
|
2013-04-17 18:56:48 -04:00
|
|
|
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
|
|
|
}
|
2012-05-12 14:01:59 +02:00
|
|
|
|
2014-01-07 03:01:33 +01:00
|
|
|
const ItemStack& item = mModel->getItem(i);
|
|
|
|
|
|
|
|
if (!onTakeItem(item, item.mCount))
|
|
|
|
break;
|
|
|
|
|
2014-04-27 05:40:07 +02:00
|
|
|
mModel->moveItem(item, item.mCount, playerModel);
|
2013-04-17 18:56:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
|
|
|
}
|
2012-05-11 16:58:07 +02:00
|
|
|
}
|
2012-05-27 01:14:33 +02:00
|
|
|
|
2013-04-17 18:56:48 -04:00
|
|
|
void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender)
|
2013-03-07 14:00:13 +01:00
|
|
|
{
|
2013-04-17 18:56:48 -04:00
|
|
|
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
|
|
|
{
|
|
|
|
onTakeAllButtonClicked(mTakeButton);
|
2013-03-07 14:00:13 +01:00
|
|
|
|
2014-05-22 20:37:22 +02:00
|
|
|
if (mPtr.getClass().isPersistent(mPtr))
|
2013-05-16 18:50:26 +02:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
|
|
|
|
else
|
2013-04-17 18:56:48 -04:00
|
|
|
MWBase::Environment::get().getWorld()->deleteObject(mPtr);
|
2013-03-07 14:00:13 +01:00
|
|
|
|
2013-04-17 18:56:48 -04:00
|
|
|
mPtr = MWWorld::Ptr();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContainerWindow::onReferenceUnavailable()
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
2013-03-07 14:00:13 +01:00
|
|
|
}
|
|
|
|
|
2014-01-07 03:01:33 +01:00
|
|
|
bool ContainerWindow::onTakeItem(const ItemStack &item, int count)
|
|
|
|
{
|
2015-08-21 21:12:39 +12:00
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
2014-08-25 17:01:02 +02:00
|
|
|
// TODO: move to ItemModels
|
|
|
|
if (dynamic_cast<PickpocketItemModel*>(mModel)
|
|
|
|
&& !mPtr.getClass().getCreatureStats(mPtr).getKnockedDown())
|
2014-01-07 03:01:33 +01:00
|
|
|
{
|
2014-01-07 19:49:16 +01:00
|
|
|
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
2014-01-07 03:01:33 +01:00
|
|
|
if (pickpocket.pick(item.mBase, count))
|
|
|
|
{
|
2014-01-07 19:49:16 +01:00
|
|
|
int value = item.mBase.getClass().getValue(item.mBase) * count;
|
2014-12-19 21:45:26 +01:00
|
|
|
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
2016-06-06 23:50:22 +02:00
|
|
|
player, mPtr, MWBase::MechanicsManager::OT_Theft, value, true);
|
2014-01-07 03:01:33 +01:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
|
|
|
mPickpocketDetected = true;
|
|
|
|
return false;
|
|
|
|
}
|
2014-01-13 07:27:08 +01:00
|
|
|
else
|
|
|
|
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1);
|
2014-01-07 03:01:33 +01:00
|
|
|
}
|
2014-01-07 19:49:16 +01:00
|
|
|
else
|
|
|
|
{
|
2014-04-27 05:40:07 +02:00
|
|
|
// Looting a dead corpse is considered OK
|
|
|
|
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
|
|
|
|
return true;
|
|
|
|
else
|
2015-02-03 23:43:56 +01:00
|
|
|
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, mPtr, count);
|
2014-01-07 19:49:16 +01:00
|
|
|
}
|
2014-01-07 03:01:33 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-27 01:14:33 +02:00
|
|
|
}
|