1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 21:23:52 +00:00

transfering items between player and merchant works and shows a red frame for bought/sold items.

This commit is contained in:
scrawl 2012-05-18 17:27:55 +02:00
parent e2400ca7b2
commit 50a8eb05d9
9 changed files with 201 additions and 26 deletions

View file

@ -21,6 +21,8 @@
#include "window_manager.hpp"
#include "widgets.hpp"
#include "countdialog.hpp"
#include "tradewindow.hpp"
#include "inventorywindow.hpp"
using namespace MWGui;
using namespace Widgets;
@ -88,37 +90,120 @@ ContainerBase::~ContainerBase()
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{
if (mDragAndDrop)
mSelectedItem = _sender;
if (mDragAndDrop && !isTrading())
{
if(!mDragAndDrop->mIsOnDragAndDrop)
{
mSelectedItem = _sender;
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
int count = object.getRefData().getCount();
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
{
onSelectedItemImpl(_sender, count);
startDragItem(_sender, count);
}
else if (MyGUI::InputManager::getInstance().isControlPressed())
{
onSelectedItemImpl(_sender, 1);
startDragItem(_sender, 1);
}
else
{
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->open(MWWorld::Class::get(object).getName(object), count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::onSelectedItemImpl);
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
}
}
else
onContainerClicked(mContainerWidget);
}
else
{
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
int count = object.getRefData().getCount();
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), 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), count);
dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellItem);
}
}
}
}
void ContainerBase::onSelectedItemImpl(MyGUI::Widget* _sender, int count)
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
{
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
assert( std::find(mBoughtItems.begin(), mBoughtItems.end(), object) != mBoughtItems.end() );
if (count == object.getRefData().getCount())
mBoughtItems.erase( std::find(mBoughtItems.begin(), mBoughtItems.end(), object) );
if (isInventory())
{
MWBase::Environment::get().getWindowManager()->getTradeWindow()->readdBarteredItem(*mSelectedItem->getUserData<MWWorld::Ptr>(), count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
}
else
{
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->readdBarteredItem(*mSelectedItem->getUserData<MWWorld::Ptr>(), count);
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
}
drawItems();
}
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
{
MWWorld::Ptr newPtr;
if (isInventory())
{
newPtr = MWBase::Environment::get().getWindowManager()->getTradeWindow()->addBarteredItem(*mSelectedItem->getUserData<MWWorld::Ptr>(), count);
mSoldItems.push_back(newPtr);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
}
else
{
newPtr = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(*mSelectedItem->getUserData<MWWorld::Ptr>(), count);
mSoldItems.push_back(newPtr);
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
}
drawItems();
}
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
{
mDragAndDrop->mIsOnDragAndDrop = true;
mSelectedItem->detachFromWidget();
@ -281,6 +366,14 @@ void ContainerBase::drawItems()
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
// add bartered items (always at the beginning)
std::sort(mBoughtItems.begin(), mBoughtItems.end(), sortItems);
for (std::vector<MWWorld::Ptr>::iterator it=mBoughtItems.begin();
it != mBoughtItems.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)
@ -316,7 +409,8 @@ void ContainerBase::drawItems()
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(ignoreItems.begin(), ignoreItems.end(), *iter) == ignoreItems.end()
&& std::find(mBoughtItems.begin(), mBoughtItems.end(), *iter) == mBoughtItems.end())
regularItems.push_back(*iter);
}
@ -338,7 +432,7 @@ void ContainerBase::drawItems()
{
displayCount -= mDragAndDrop->mDraggedCount;
}
if(displayCount > 0 && !(onlyMagic && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
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);
@ -361,10 +455,17 @@ void ContainerBase::drawItems()
{
backgroundTex += "_equip";
}
else if (it->second == ItemState_Barter)
{
backgroundTex += "_barter";
}
backgroundTex += ".dds";
backgroundWidget->setImageTexture(backgroundTex);
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
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);
@ -421,6 +522,47 @@ void ContainerBase::Update()
}
}
MWWorld::Ptr ContainerBase::readdBarteredItem(MWWorld::Ptr item, int count)
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
int origCount = item.getRefData().getCount();
item.getRefData().setCount(count);
MWWorld::ContainerStoreIterator it = containerStore.add(item);
item.getRefData().setCount(origCount - count);
if (origCount - count == 0)
mSoldItems.erase( std::find(mSoldItems.begin(), mSoldItems.end(), item) );
return *it;
}
MWWorld::Ptr ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
int origCount = item.getRefData().getCount();
item.getRefData().setCount(count);
MWWorld::ContainerStoreIterator it = containerStore.add(item);
item.getRefData().setCount(origCount - count);
mBoughtItems.push_back(*it);
return *it;
}
void ContainerBase::removeBarteredItem(MWWorld::Ptr item, int count)
{
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
for (MWWorld::ContainerStoreIterator it(containerStore.begin()); it != containerStore.end(); ++it)
{
if (*it == item)
{
item.getRefData().setCount(item.getRefData().getCount() - count);
}
}
}
// ------------------------------------------------------------------------------------------------
ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)

View file

@ -62,13 +62,15 @@ namespace MWGui
{
ItemState_Normal = 0x01,
ItemState_Equipped = 0x02,
// unimplemented
ItemState_Barter = 0x03
};
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once
MWWorld::Ptr addBarteredItem(MWWorld::Ptr item, int count);
MWWorld::Ptr readdBarteredItem(MWWorld::Ptr item, int count);
void removeBarteredItem(MWWorld::Ptr item, int count);
void openContainer(MWWorld::Ptr container);
void setFilter(Filter filter); ///< set category filter
virtual void Update();
@ -87,17 +89,31 @@ namespace MWGui
Filter mFilter;
std::vector<MWWorld::Ptr> mBoughtItems;
std::vector<MWWorld::Ptr> mSoldItems;
void onSelectedItem(MyGUI::Widget* _sender);
void onSelectedItemImpl(MyGUI::Widget* _sender, int count);
void onContainerClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
/// start dragging an item (drag & drop)
void startDragItem(MyGUI::Widget* _sender, int count);
/// sell an item from this container
void sellItem(MyGUI::Widget* _sender, int count);
/// sell an item from this container, that was previously just bought
void sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count);
std::string getCountString(const int count);
virtual bool isTradeWindow() { return false; }
virtual bool isInventory() { return false; }
virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); }
virtual void _unequipItem(MWWorld::Ptr item) { ; }
virtual bool isTrading() { return false; }
virtual bool ignoreEquippedItems() { return false; }
virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); }
};

View file

@ -120,9 +120,6 @@ void DialogueWindow::open()
history->eraseText(0,history->getTextLength());
updateOptions();
setVisible(true);
// hide all sub-dialogues of the dialog window (trade window, persuasion, etc)
mWindowManager.getTradeWindow()->setVisible(false);
}
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
@ -137,8 +134,8 @@ void DialogueWindow::onSelectTopic(std::string topic)
if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str)
{
/// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
mWindowManager.getTradeWindow()->startTrade(mActor);
mWindowManager.setGuiMode(GM_Barter);
mWindowManager.getTradeWindow()->startTrade(mActor);
}
else
@ -150,8 +147,7 @@ void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
mEnabled = true;
mActor = actor;
topicsList->setEnabled(true);
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName);
adjustWindowCaption();
setTitle(npcName);
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)

View file

@ -27,6 +27,7 @@ namespace MWGui
InventoryWindow::InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
: ContainerBase(dragAndDrop)
, WindowPinnableBase("openmw_inventory_window_layout.xml", parWindowManager)
, mTrading(false)
{
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
@ -94,6 +95,8 @@ namespace MWGui
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
updateEncumbranceBar();
mTrading = false;
}
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
@ -245,4 +248,11 @@ namespace MWGui
}
return 0;
}
void InventoryWindow::startTrade()
{
mTrading = true;
mBoughtItems.clear();
mSoldItems.clear();
}
}

View file

@ -13,6 +13,9 @@ namespace MWGui
void openInventory();
/// start trading, disables item drag&drop
void startTrade();
virtual void Update();
virtual void notifyContentChanged();
@ -33,6 +36,8 @@ namespace MWGui
MyGUI::Button* mFilterMagic;
MyGUI::Button* mFilterMisc;
bool mTrading;
void onWindowResize(MyGUI::Window* _sender);
void onFilterChanged(MyGUI::Widget* _sender);
void onAvatarClicked(MyGUI::Widget* _sender);
@ -40,6 +45,7 @@ namespace MWGui
void updateEncumbranceBar();
virtual bool isTrading() { return mTrading; }
virtual bool isInventory() { return true; }
virtual std::vector<MWWorld::Ptr> getEquippedItems();
virtual void _unequipItem(MWWorld::Ptr item);

View file

@ -121,8 +121,7 @@ MapWindow::MapWindow(WindowManager& parWindowManager) :
void MapWindow::setCellName(const std::string& cellName)
{
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
adjustWindowCaption();
setTitle(cellName);
}
void MapWindow::setPlayerPos(const float x, const float y)

View file

@ -128,8 +128,7 @@ void StatsWindow::setBar(const std::string& name, const std::string& tname, int
void StatsWindow::setPlayerName(const std::string& playerName)
{
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(playerName);
adjustWindowCaption();
setTitle(playerName);
}
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value)

View file

@ -103,13 +103,17 @@ namespace MWGui
void TradeWindow::startTrade(MWWorld::Ptr actor)
{
ContainerBase::openContainer(actor);
setTitle(MWWorld::Class::get(actor).getName(actor));
adjustWindowCaption();
mCurrentBalance = 0;
mWindowManager.getInventoryWindow()->startTrade();
mBoughtItems.clear();
mSoldItems.clear();
ContainerBase::openContainer(actor);
updateLabels();
}

View file

@ -63,6 +63,9 @@ namespace MWGui
virtual bool ignoreEquippedItems() { return true; }
virtual std::vector<MWWorld::Ptr> getEquippedItems();
virtual bool isTrading() { return true; }
virtual bool isTradeWindow() { return true; }
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
void updateLabels();