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

353 lines
13 KiB
C++
Raw Normal View History

2012-04-15 15:52:39 +00:00
#include "container.hpp"
#include <boost/lexical_cast.hpp>
2012-04-15 15:52:39 +00:00
2012-05-11 09:52:07 +00:00
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/dialoguemanager.hpp"
2014-01-07 18:49:16 +00:00
#include "../mwbase/mechanicsmanager.hpp"
2013-05-11 16:38:27 +00:00
#include "../mwworld/class.hpp"
2014-01-07 18:49:16 +00:00
#include "../mwworld/containerstore.hpp"
#include "../mwmechanics/pickpocket.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "countdialog.hpp"
#include "tradewindow.hpp"
#include "inventorywindow.hpp"
2012-04-15 15:52:39 +00:00
2013-05-11 16:38:27 +00:00
#include "itemview.hpp"
#include "itemwidget.hpp"
2013-05-11 16:38:27 +00:00
#include "inventoryitemmodel.hpp"
#include "sortfilteritemmodel.hpp"
#include "pickpocketitemmodel.hpp"
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
void DragAndDrop::startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count)
2013-04-17 22:56:48 +00:00
{
2013-05-11 16:38:27 +00:00
mItem = sourceModel->getItem(index);
mDraggedCount = count;
mSourceModel = sourceModel;
mSourceView = sourceView;
mSourceSortModel = sortModel;
mIsOnDragAndDrop = true;
mDragAndDropWidget->setVisible(true);
std::string sound = mItem.mBase.getClass().getUpSoundId(mItem.mBase);
2013-04-17 22:56:48 +00:00
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
2013-05-11 16:38:27 +00:00
if (mSourceSortModel)
2013-04-17 22:56:48 +00:00
{
2013-05-11 16:38:27 +00:00
mSourceSortModel->clearDragItems();
mSourceSortModel->addDragItem(mItem.mBase, count);
2013-04-17 22:56:48 +00:00
}
ItemWidget* baseWidget = mDragAndDropWidget->createWidget<ItemWidget>
("MW_ItemIcon", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
2013-05-11 16:38:27 +00:00
mDraggedWidget = baseWidget;
baseWidget->setItem(mItem.mBase);
baseWidget->setNeedMouseFocus(false);
2013-05-11 16:38:27 +00:00
// text widget that shows item count
// TODO: move to ItemWidget
MyGUI::TextBox* text = baseWidget->createWidget<MyGUI::TextBox>("SandBrightText",
2013-05-11 16:38:27 +00:00
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(ItemView::getCountString(count));
2013-05-11 16:38:27 +00:00
sourceView->update();
2013-04-17 22:56:48 +00:00
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
}
2013-05-11 16:38:27 +00:00
void DragAndDrop::drop(ItemModel *targetModel, ItemView *targetView)
2012-05-12 11:12:37 +00:00
{
std::string sound = mItem.mBase.getClass().getDownSoundId(mItem.mBase);
2013-05-11 16:38:27 +00:00
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
2012-05-12 12:29:49 +00:00
2013-05-11 16:38:27 +00:00
mDragAndDropWidget->setVisible(false);
2013-08-25 15:40:08 +00:00
// If item is dropped where it was taken from, we don't need to do anything -
// otherwise, do the transfer
if (targetModel != mSourceModel)
{
mSourceModel->moveItem(mItem, mDraggedCount, targetModel);
2013-08-25 15:40:08 +00:00
}
2013-03-31 11:13:46 +00:00
2013-05-11 16:38:27 +00:00
mSourceModel->update();
2013-05-11 16:38:27 +00:00
finish();
if (targetView)
targetView->update();
// We need to update the view since an other item could be auto-equipped.
mSourceView->update();
2012-05-12 11:12:37 +00:00
}
2012-05-12 18:35:50 +00:00
2013-05-11 16:38:27 +00:00
void DragAndDrop::finish()
{
2013-05-11 16:38:27 +00:00
mIsOnDragAndDrop = false;
mSourceSortModel->clearDragItems();
2012-05-12 19:28:04 +00:00
2013-05-11 16:38:27 +00:00
MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget);
mDraggedWidget = 0;
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
}
2013-05-11 16:38:27 +00:00
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
: WindowBase("openmw_container_window.layout")
, mDragAndDrop(dragAndDrop)
, mSelectedItem(-1)
, mModel(NULL)
, mSortModel(NULL)
, mPickpocketDetected(false)
{
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);
2014-01-10 23:24:21 +00:00
mCloseButton->eventKeyButtonPressed += MyGUI::newDelegate(this, &ContainerWindow::onKeyPressed);
2013-05-11 16:38:27 +00:00
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)
2013-04-17 22:56:48 +00:00
{
2013-05-11 16:38:27 +00:00
if (!dynamic_cast<PickpocketItemModel*>(mModel))
dropItem();
return;
2013-04-17 22:56:48 +00:00
}
2013-03-16 18:00:14 +00:00
2013-05-11 16:38:27 +00:00
const ItemStack& item = mSortModel->getItem(index);
2013-04-17 22:56:48 +00:00
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->open(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
}
2013-04-17 22:56:48 +00:00
else
2013-05-11 16:38:27 +00:00
dragItem (NULL, count);
}
2013-05-11 16:38:27 +00:00
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
{
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
{
2013-05-11 16:38:27 +00:00
if (mPtr.getTypeName() == typeid(ESM::Container).name())
{
2013-05-11 16:38:27 +00: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)
2013-05-11 16:38:27 +00:00
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}");
return;
}
2012-05-12 11:12:37 +00:00
2013-05-11 16:38:27 +00:00
// check container organic flag
MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
if (ref->mBase->mFlags & ESM::Container::Organic)
2013-04-17 22:56:48 +00:00
{
2013-05-11 16:38:27 +00:00
MWBase::Environment::get().getWindowManager()->
messageBox("#{sContentsMessage2}");
return;
2013-04-17 22:56:48 +00:00
}
}
2012-05-12 20:44:12 +00:00
2013-05-11 16:38:27 +00:00
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
{
2013-05-11 16:38:27 +00:00
if (mDragAndDrop->mIsOnDragAndDrop && !dynamic_cast<PickpocketItemModel*>(mModel))
dropItem();
2012-04-30 11:01:18 +00:00
}
2012-04-15 15:52:39 +00:00
2013-05-11 16:38:27 +00:00
void ContainerWindow::open(const MWWorld::Ptr& container, bool loot)
2012-05-11 14:58:07 +00:00
{
mPickpocketDetected = false;
2013-05-11 16:38:27 +00:00
mPtr = container;
2012-05-12 12:01:59 +00:00
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
2013-04-17 22:56:48 +00:00
{
// we are stealing stuff
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
2013-05-11 16:38:27 +00:00
mModel = new PickpocketItemModel(player, new InventoryItemModel(container));
2013-04-17 22:56:48 +00:00
}
2013-05-11 16:38:27 +00:00
else
mModel = new InventoryItemModel(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);
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton);
2014-01-10 23:24:21 +00:00
// Careful here. setTitle may cause size updates, causing itemview redraw, so make sure to do it last
// or we end up using a possibly invalid model.
setTitle(container.getClass().getName(container));
2013-04-17 22:56:48 +00:00
}
2014-01-10 23:24:21 +00: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);
}
void ContainerWindow::close()
{
WindowBase::close();
2014-01-07 17:11:19 +00: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
)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
2014-01-07 18:49:16 +00:00
MWMechanics::Pickpocket pickpocket(player, mPtr);
if (pickpocket.finish())
{
2014-01-07 18:49:16 +00:00
MWBase::Environment::get().getMechanicsManager()->reportCrime(
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket);
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief");
mPickpocketDetected = true;
return;
}
}
}
void ContainerWindow::exit()
2013-04-17 22:56:48 +00:00
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
2012-05-12 12:01:59 +00:00
{
2013-04-17 22:56:48 +00:00
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
}
}
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
exit();
}
2013-04-17 22:56:48 +00:00
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
{
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
// transfer everything into the player's inventory
2013-05-11 16:38:27 +00:00
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
2013-05-19 16:40:37 +00:00
mModel->update();
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
{
2013-04-17 22:56:48 +00:00
if (i==0)
{
// play the sound of the first object
2013-05-11 16:38:27 +00:00
MWWorld::Ptr item = mModel->getItem(i).mBase;
std::string sound = item.getClass().getUpSoundId(item);
2013-04-17 22:56:48 +00:00
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
}
2012-05-12 12:01:59 +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)
{
2013-04-17 22:56:48 +00:00
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
{
onTakeAllButtonClicked(mTakeButton);
if (mPtr.getClass().isPersistent(mPtr))
2013-05-16 16:50:26 +00:00
MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
else
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)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
if (dynamic_cast<PickpocketItemModel*>(mModel))
{
2014-01-07 18:49:16 +00:00
MWMechanics::Pickpocket pickpocket(player, mPtr);
if (pickpocket.pick(item.mBase, count))
{
2014-01-07 18:49:16 +00:00
int value = item.mBase.getClass().getValue(item.mBase) * count;
MWBase::Environment::get().getMechanicsManager()->reportCrime(
player, MWWorld::Ptr(), MWBase::MechanicsManager::OT_Theft, value);
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
MWBase::Environment::get().getDialogueManager()->say(mPtr, "Thief");
mPickpocketDetected = true;
return false;
}
else
player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1);
}
2014-01-07 18:49:16 +00:00
else
{
// Looting a dead corpse is considered OK
if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead())
return true;
else
MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, count);
2014-01-07 18:49:16 +00:00
}
return true;
}
}