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 "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "countdialog.hpp" #include "countdialog.hpp"
#include "tradewindow.hpp"
#include "inventorywindow.hpp"
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
@ -88,37 +90,120 @@ ContainerBase::~ContainerBase()
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{ {
if (mDragAndDrop) mSelectedItem = _sender;
if (mDragAndDrop && !isTrading())
{ {
if(!mDragAndDrop->mIsOnDragAndDrop) if(!mDragAndDrop->mIsOnDragAndDrop)
{ {
mSelectedItem = _sender;
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>()); MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
int count = object.getRefData().getCount(); int count = object.getRefData().getCount();
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1) if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
{ {
onSelectedItemImpl(_sender, count); startDragItem(_sender, count);
} }
else if (MyGUI::InputManager::getInstance().isControlPressed()) else if (MyGUI::InputManager::getInstance().isControlPressed())
{ {
onSelectedItemImpl(_sender, 1); startDragItem(_sender, 1);
} }
else else
{ {
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
dialog->open(MWWorld::Class::get(object).getName(object), count); dialog->open(MWWorld::Class::get(object).getName(object), count);
dialog->eventOkClicked.clear(); dialog->eventOkClicked.clear();
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::onSelectedItemImpl); dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
} }
} }
else else
onContainerClicked(mContainerWidget); 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; mDragAndDrop->mIsOnDragAndDrop = true;
mSelectedItem->detachFromWidget(); mSelectedItem->detachFromWidget();
@ -281,6 +366,14 @@ void ContainerBase::drawItems()
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems(); 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 // filter out the equipped items of categories we don't want
std::vector<MWWorld::Ptr> unwantedItems = equippedItems; std::vector<MWWorld::Ptr> unwantedItems = equippedItems;
for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter) 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) for (MWWorld::ContainerStoreIterator iter (containerStore.begin(categories)); iter!=containerStore.end(); ++iter)
{ {
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) == equippedItems.end() 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); regularItems.push_back(*iter);
} }
@ -338,7 +432,7 @@ void ContainerBase::drawItems()
{ {
displayCount -= mDragAndDrop->mDraggedCount; 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\\"); std::string path = std::string("icons\\");
path+=MWWorld::Class::get(*iter).getInventoryIcon(*iter); path+=MWWorld::Class::get(*iter).getInventoryIcon(*iter);
@ -361,10 +455,17 @@ void ContainerBase::drawItems()
{ {
backgroundTex += "_equip"; backgroundTex += "_equip";
} }
else if (it->second == ItemState_Barter)
{
backgroundTex += "_barter";
}
backgroundTex += ".dds"; backgroundTex += ".dds";
backgroundWidget->setImageTexture(backgroundTex); 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->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onSelectedItem);
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerBase::onMouseWheel); 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) ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)

View file

@ -62,13 +62,15 @@ namespace MWGui
{ {
ItemState_Normal = 0x01, ItemState_Normal = 0x01,
ItemState_Equipped = 0x02, ItemState_Equipped = 0x02,
// unimplemented
ItemState_Barter = 0x03 ItemState_Barter = 0x03
}; };
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once 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 openContainer(MWWorld::Ptr container);
void setFilter(Filter filter); ///< set category filter void setFilter(Filter filter); ///< set category filter
virtual void Update(); virtual void Update();
@ -87,17 +89,31 @@ namespace MWGui
Filter mFilter; Filter mFilter;
std::vector<MWWorld::Ptr> mBoughtItems;
std::vector<MWWorld::Ptr> mSoldItems;
void onSelectedItem(MyGUI::Widget* _sender); void onSelectedItem(MyGUI::Widget* _sender);
void onSelectedItemImpl(MyGUI::Widget* _sender, int count);
void onContainerClicked(MyGUI::Widget* _sender); void onContainerClicked(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel); 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); std::string getCountString(const int count);
virtual bool isTradeWindow() { return false; }
virtual bool isInventory() { return false; } virtual bool isInventory() { return false; }
virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); } virtual std::vector<MWWorld::Ptr> getEquippedItems() { return std::vector<MWWorld::Ptr>(); }
virtual void _unequipItem(MWWorld::Ptr item) { ; } virtual void _unequipItem(MWWorld::Ptr item) { ; }
virtual bool isTrading() { return false; }
virtual bool ignoreEquippedItems() { return false; } virtual bool ignoreEquippedItems() { return false; }
virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); } 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()); history->eraseText(0,history->getTextLength());
updateOptions(); updateOptions();
setVisible(true); setVisible(true);
// hide all sub-dialogues of the dialog window (trade window, persuasion, etc)
mWindowManager.getTradeWindow()->setVisible(false);
} }
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) 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) 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)? /// \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.setGuiMode(GM_Barter);
mWindowManager.getTradeWindow()->startTrade(mActor);
} }
else else
@ -150,8 +147,7 @@ void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
mEnabled = true; mEnabled = true;
mActor = actor; mActor = actor;
topicsList->setEnabled(true); topicsList->setEnabled(true);
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(npcName); setTitle(npcName);
adjustWindowCaption();
} }
void DialogueWindow::setKeywords(std::list<std::string> keyWords) void DialogueWindow::setKeywords(std::list<std::string> keyWords)

View file

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

View file

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

View file

@ -121,8 +121,7 @@ MapWindow::MapWindow(WindowManager& parWindowManager) :
void MapWindow::setCellName(const std::string& cellName) void MapWindow::setCellName(const std::string& cellName)
{ {
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName); setTitle(cellName);
adjustWindowCaption();
} }
void MapWindow::setPlayerPos(const float x, const float y) 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) void StatsWindow::setPlayerName(const std::string& playerName)
{ {
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(playerName); setTitle(playerName);
adjustWindowCaption();
} }
void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat<int>& value) 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) void TradeWindow::startTrade(MWWorld::Ptr actor)
{ {
ContainerBase::openContainer(actor);
setTitle(MWWorld::Class::get(actor).getName(actor)); setTitle(MWWorld::Class::get(actor).getName(actor));
adjustWindowCaption();
mCurrentBalance = 0; mCurrentBalance = 0;
mWindowManager.getInventoryWindow()->startTrade();
mBoughtItems.clear();
mSoldItems.clear();
ContainerBase::openContainer(actor);
updateLabels(); updateLabels();
} }

View file

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