Merge remote branch 'scrawl/inventoryGUI'
Conflicts: apps/openmw/CMakeLists.txtactorid
commit
3e85151c9d
@ -0,0 +1,672 @@
|
||||
#include "container.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwinput/inputmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
using namespace Widgets;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
bool compareType(std::string type1, std::string type2)
|
||||
{
|
||||
// this defines the sorting order of types. types that are first in the vector, appear before other types.
|
||||
std::vector<std::string> mapping;
|
||||
mapping.push_back( typeid(ESM::Weapon).name() );
|
||||
mapping.push_back( typeid(ESM::Armor).name() );
|
||||
mapping.push_back( typeid(ESM::Clothing).name() );
|
||||
mapping.push_back( typeid(ESM::Potion).name() );
|
||||
mapping.push_back( typeid(ESM::Ingredient).name() );
|
||||
mapping.push_back( typeid(ESM::Apparatus).name() );
|
||||
mapping.push_back( typeid(ESM::Book).name() );
|
||||
mapping.push_back( typeid(ESM::Light).name() );
|
||||
mapping.push_back( typeid(ESM::Miscellaneous).name() );
|
||||
mapping.push_back( typeid(ESM::Tool).name() );
|
||||
mapping.push_back( typeid(ESM::Repair).name() );
|
||||
mapping.push_back( typeid(ESM::Probe).name() );
|
||||
|
||||
assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() );
|
||||
assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() );
|
||||
|
||||
return std::find(mapping.begin(), mapping.end(), type1) < std::find(mapping.begin(), mapping.end(), type2);
|
||||
}
|
||||
|
||||
bool sortItems(MWWorld::Ptr left, MWWorld::Ptr right)
|
||||
{
|
||||
if (left.getTypeName() == right.getTypeName())
|
||||
{
|
||||
int cmp = MWWorld::Class::get(left).getName(left).compare(
|
||||
MWWorld::Class::get(right).getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return compareType(left.getTypeName(), right.getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop) :
|
||||
mDragAndDrop(dragAndDrop),
|
||||
mFilter(ContainerBase::Filter_All)
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::setWidgets(Widget* containerWidget, ScrollView* itemView)
|
||||
{
|
||||
mContainerWidget = containerWidget;
|
||||
mItemView = itemView;
|
||||
|
||||
mContainerWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerBase::onContainerClicked);
|
||||
mContainerWidget->eventMouseWheel += MyGUI::newDelegate(this, &ContainerWindow::onMouseWheel);
|
||||
}
|
||||
|
||||
ContainerBase::~ContainerBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
|
||||
{
|
||||
mSelectedItem = _sender;
|
||||
|
||||
if (mDragAndDrop && !isTrading())
|
||||
{
|
||||
if(!mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
if (MyGUI::InputManager::getInstance().isShiftPressed() || count == 1)
|
||||
{
|
||||
startDragItem(_sender, count);
|
||||
}
|
||||
else if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
{
|
||||
startDragItem(_sender, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string message = MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTake")->str;
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::startDragItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
onContainerClicked(mContainerWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>());
|
||||
int count = object.getRefData().getCount();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
// the player is trying to sell an item, check if the merchant accepts it
|
||||
// also, don't allow selling gold (let's be better than Morrowind at this, can we?)
|
||||
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object)
|
||||
|| MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
// user notification "i don't buy this item"
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog4")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool buying = isTradeWindow(); // buying or selling?
|
||||
std::string message = buying ? MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage02")->str
|
||||
: MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sQuanityMenuMessage01")->str;
|
||||
|
||||
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), message, 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), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerBase::sellItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::sellItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (isInventory())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->sellToNpc(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
}
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::startDragItem(MyGUI::Widget* _sender, int count)
|
||||
{
|
||||
mDragAndDrop->mIsOnDragAndDrop = true;
|
||||
mSelectedItem->detachFromWidget();
|
||||
mSelectedItem->attachToWidget(mDragAndDrop->mDragAndDropWidget);
|
||||
|
||||
MWWorld::Ptr object = *mSelectedItem->getUserData<MWWorld::Ptr>();
|
||||
_unequipItem(object);
|
||||
|
||||
mDragAndDrop->mDraggedCount = count;
|
||||
|
||||
mDragAndDrop->mDraggedFrom = this;
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mDragAndDrop->mDraggedWidget = mSelectedItem;
|
||||
static_cast<MyGUI::ImageBox*>(mSelectedItem)->setImageTexture(""); // remove the background texture (not visible during drag)
|
||||
static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
|
||||
getCountString(mDragAndDrop->mDraggedCount));
|
||||
|
||||
drawItems();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
|
||||
}
|
||||
|
||||
void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop == NULL) return;
|
||||
|
||||
if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
|
||||
{
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
assert(object.getContainerStore() && "Item is not in a container!");
|
||||
|
||||
// check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
|
||||
if (mContainer.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mContainer.get<ESM::Container>();
|
||||
if (ref->base->flags & ESM::Container::Organic)
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage2")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int origCount = object.getRefData().getCount();
|
||||
|
||||
// check that we don't exceed the allowed weight (only for containers, not for inventory)
|
||||
if (!isInventory())
|
||||
{
|
||||
float capacity = MWWorld::Class::get(mContainer).getCapacity(mContainer);
|
||||
|
||||
// try adding the item, and if weight is exceeded, just remove it again.
|
||||
object.getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
MWWorld::ContainerStoreIterator it = containerStore.add(object);
|
||||
|
||||
float curWeight = MWWorld::Class::get(mContainer).getEncumbrance(mContainer);
|
||||
if (curWeight > capacity)
|
||||
{
|
||||
it->getRefData().setCount(0);
|
||||
object.getRefData().setCount(origCount);
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sContentsMessage3")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
std::cout << "container weight " << curWeight << "/" << capacity << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount (mDragAndDrop->mDraggedCount);
|
||||
containerStore.add(object);
|
||||
object.getRefData().setCount (origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
drawItems();
|
||||
mDragAndDrop->mDraggedFrom->drawItems();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
|
||||
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (mItemView->getViewOffset().left + _rel*0.3 > 0)
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
|
||||
}
|
||||
|
||||
void ContainerBase::setFilter(ContainerBase::Filter filter)
|
||||
{
|
||||
mFilter = filter;
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::openContainer(MWWorld::Ptr container)
|
||||
{
|
||||
mContainer = container;
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::drawItems()
|
||||
{
|
||||
while (mContainerWidget->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
|
||||
}
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int maxHeight = mItemView->getSize().height - 58;
|
||||
|
||||
int index = 0;
|
||||
|
||||
|
||||
bool onlyMagic = false;
|
||||
int categories;
|
||||
if (mFilter == Filter_All)
|
||||
categories = MWWorld::ContainerStore::Type_All;
|
||||
else if (mFilter == Filter_Weapon)
|
||||
categories = MWWorld::ContainerStore::Type_Weapon;
|
||||
else if (mFilter == Filter_Apparel)
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
|
||||
else if (mFilter == Filter_Magic)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
|
||||
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Potion;
|
||||
onlyMagic = true;
|
||||
}
|
||||
else if (mFilter == Filter_Misc)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
|
||||
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
|
||||
+ MWWorld::ContainerStore::Type_Apparatus;
|
||||
}
|
||||
|
||||
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
|
||||
|
||||
std::vector< std::pair<MWWorld::Ptr, ItemState> > items;
|
||||
|
||||
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
|
||||
|
||||
// add bought items (always at the beginning)
|
||||
std::vector<MWWorld::Ptr> boughtItems;
|
||||
for (MWWorld::ContainerStoreIterator it (mBoughtItems.begin()); it!=mBoughtItems.end(); ++it)
|
||||
{
|
||||
boughtItems.push_back(*it);
|
||||
}
|
||||
std::sort(boughtItems.begin(), boughtItems.end(), sortItems);
|
||||
|
||||
for (std::vector<MWWorld::Ptr>::iterator it=boughtItems.begin();
|
||||
it != boughtItems.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)
|
||||
{
|
||||
std::vector<MWWorld::Ptr>::iterator found = std::find(unwantedItems.begin(), unwantedItems.end(), *iter);
|
||||
if (found != unwantedItems.end())
|
||||
{
|
||||
unwantedItems.erase(found);
|
||||
}
|
||||
}
|
||||
// now erase everything that's still in unwantedItems.
|
||||
for (std::vector<MWWorld::Ptr>::iterator it=unwantedItems.begin();
|
||||
it != unwantedItems.end(); ++it)
|
||||
{
|
||||
std::vector<MWWorld::Ptr>::iterator found = std::find(equippedItems.begin(), equippedItems.end(), *it);
|
||||
assert(found != equippedItems.end());
|
||||
equippedItems.erase(found);
|
||||
}
|
||||
// and add the items that are left (= have the correct category)
|
||||
if (!ignoreEquippedItems())
|
||||
{
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it=equippedItems.begin();
|
||||
it != equippedItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Equipped) );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> ignoreItems = itemsToIgnore();
|
||||
|
||||
// now add the regular items
|
||||
std::vector<MWWorld::Ptr> regularItems;
|
||||
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(mBoughtItems.begin(), mBoughtItems.end(), *iter) == mBoughtItems.end())
|
||||
regularItems.push_back(*iter);
|
||||
}
|
||||
|
||||
// sort them and add
|
||||
std::sort(regularItems.begin(), regularItems.end(), sortItems);
|
||||
for (std::vector<MWWorld::Ptr>::const_iterator it=regularItems.begin(); it!=regularItems.end(); ++it)
|
||||
{
|
||||
items.push_back( std::make_pair(*it, ItemState_Normal) );
|
||||
}
|
||||
|
||||
for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin();
|
||||
it != items.end(); ++it)
|
||||
{
|
||||
index++;
|
||||
const MWWorld::Ptr* iter = &((*it).first);
|
||||
|
||||
int displayCount = iter->getRefData().getCount();
|
||||
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
|
||||
{
|
||||
displayCount -= mDragAndDrop->mDraggedCount;
|
||||
}
|
||||
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);
|
||||
|
||||
// background widget (for the "equipped" frame and magic item background image)
|
||||
bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != "");
|
||||
MyGUI::ImageBox* backgroundWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
|
||||
backgroundWidget->setUserString("ToolTipType", "ItemPtr");
|
||||
backgroundWidget->setUserData(*iter);
|
||||
|
||||
std::string backgroundTex = "textures\\menu_icon";
|
||||
if (isMagic)
|
||||
backgroundTex += "_magic";
|
||||
if (it->second == ItemState_Normal)
|
||||
{
|
||||
if (!isMagic)
|
||||
backgroundTex = "";
|
||||
}
|
||||
else if (it->second == ItemState_Equipped)
|
||||
{
|
||||
backgroundTex += "_equip";
|
||||
}
|
||||
else if (it->second == ItemState_Barter)
|
||||
{
|
||||
backgroundTex += "_barter";
|
||||
}
|
||||
if (backgroundTex != "")
|
||||
backgroundTex += ".dds";
|
||||
|
||||
backgroundWidget->setImageTexture(backgroundTex);
|
||||
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);
|
||||
|
||||
// image
|
||||
ImageBox* image = backgroundWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture(path);
|
||||
image->setNeedMouseFocus(false);
|
||||
|
||||
// text widget that shows item count
|
||||
MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", 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));
|
||||
|
||||
y += 42;
|
||||
if (y > maxHeight)
|
||||
{
|
||||
x += 42;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
text->setCaption(getCountString(displayCount));
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height);
|
||||
mItemView->setCanvasSize(size);
|
||||
mContainerWidget->setSize(size);
|
||||
}
|
||||
|
||||
std::string ContainerBase::getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
|
||||
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
int origCount = item.getRefData().getCount();
|
||||
item.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
|
||||
item.getRefData().setCount(origCount - count);
|
||||
}
|
||||
|
||||
void ContainerBase::addItem(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);
|
||||
}
|
||||
|
||||
void ContainerBase::transferBoughtItems()
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
containerStore.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
|
||||
{
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
store.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::ContainerStore& ContainerBase::getContainerStore()
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
return store;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
ContainerWindow::ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowBase("openmw_container_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
||||
|
||||
// adjust buttons size to fit text
|
||||
int closeButtonWidth = mCloseButton->getTextSize().width+24;
|
||||
int takeButtonWidth = mTakeButton->getTextSize().width+24;
|
||||
mCloseButton->setCoord(600-20-closeButtonWidth, mCloseButton->getCoord().top, closeButtonWidth, mCloseButton->getCoord().height);
|
||||
mTakeButton->setCoord(600-20-closeButtonWidth-takeButtonWidth-8, mTakeButton->getCoord().top, takeButtonWidth, mTakeButton->getCoord().height);
|
||||
|
||||
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
|
||||
//int h = MyGUI::RenderManager::getInstance().getViewSize().height;
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
|
||||
|
||||
setCoord(w-600,0,600,300);
|
||||
}
|
||||
|
||||
ContainerWindow::~ContainerWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerWindow::open(MWWorld::Ptr container)
|
||||
{
|
||||
openContainer(container);
|
||||
setTitle(MWWorld::Class::get(container).getName(container));
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// transfer everything into the player's inventory
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
|
||||
|
||||
int i=0;
|
||||
for (MWWorld::ContainerStoreIterator iter (containerStore.begin()); iter!=containerStore.end(); ++iter)
|
||||
{
|
||||
playerStore.add(*iter);
|
||||
|
||||
if (i==0)
|
||||
{
|
||||
// play the sound of the first object
|
||||
std::string sound = MWWorld::Class::get(*iter).getUpSoundId(*iter);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
containerStore.clear();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game);
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
#ifndef MGUI_CONTAINER_H
|
||||
#define MGUI_CONTAINER_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
#include "../mwclass/container.hpp"
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "window_base.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Environment;
|
||||
}
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Gui;
|
||||
class Widget;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
class ContainerWindow;
|
||||
class ContainerBase;
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class DragAndDrop
|
||||
{
|
||||
public:
|
||||
bool mIsOnDragAndDrop;
|
||||
MyGUI::Widget* mDraggedWidget;
|
||||
MyGUI::Widget* mDragAndDropWidget;
|
||||
ContainerBase* mDraggedFrom;
|
||||
int mDraggedCount;
|
||||
};
|
||||
|
||||
class ContainerBase
|
||||
{
|
||||
public:
|
||||
ContainerBase(DragAndDrop* dragAndDrop);
|
||||
virtual ~ContainerBase();
|
||||
|
||||
enum Filter
|
||||
{
|
||||
Filter_All = 0x01,
|
||||
Filter_Weapon = 0x02,
|
||||
Filter_Apparel = 0x03,
|
||||
Filter_Magic = 0x04,
|
||||
Filter_Misc = 0x05
|
||||
};
|
||||
|
||||
enum ItemState
|
||||
{
|
||||
ItemState_Normal = 0x01,
|
||||
ItemState_Equipped = 0x02,
|
||||
ItemState_Barter = 0x03
|
||||
};
|
||||
|
||||
void setWidgets(MyGUI::Widget* containerWidget, MyGUI::ScrollView* itemView); ///< only call once
|
||||
|
||||
void addBarteredItem(MWWorld::Ptr item, int count);
|
||||
void addItem(MWWorld::Ptr item, int count);
|
||||
|
||||
void transferBoughtItems(); ///< transfer bought items into the inventory
|
||||
void returnBoughtItems(MWWorld::ContainerStore& store); ///< return bought items into the specified ContainerStore
|
||||
|
||||
MWWorld::ContainerStore& getContainerStore();
|
||||
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
|
||||
|
||||
void openContainer(MWWorld::Ptr container);
|
||||
void setFilter(Filter filter); ///< set category filter
|
||||
void drawItems();
|
||||
|
||||
protected:
|
||||
MyGUI::ScrollView* mItemView;
|
||||
MyGUI::Widget* mContainerWidget;
|
||||
|
||||
MyGUI::Widget* mSelectedItem;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
MWWorld::Ptr mContainer;
|
||||
|
||||
Filter mFilter;
|
||||
|
||||
// bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
|
||||
MWWorld::ContainerStore mBoughtItems;
|
||||
|
||||
void onSelectedItem(MyGUI::Widget* _sender);
|
||||
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>(); }
|
||||
};
|
||||
|
||||
class ContainerWindow : public ContainerBase, public WindowBase
|
||||
{
|
||||
public:
|
||||
ContainerWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
virtual ~ContainerWindow();
|
||||
|
||||
void open(MWWorld::Ptr container);
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::Button* mCloseButton;
|
||||
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
};
|
||||
}
|
||||
#endif // CONTAINER_H
|
@ -0,0 +1,111 @@
|
||||
#include "countdialog.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
CountDialog::CountDialog(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_count_window_layout.xml", parWindowManager)
|
||||
{
|
||||
getWidget(mSlider, "CountSlider");
|
||||
getWidget(mItemEdit, "ItemEdit");
|
||||
getWidget(mItemText, "ItemText");
|
||||
getWidget(mLabelText, "LabelText");
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mOkButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sOk")->str);
|
||||
mCancelButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sCancel")->str);
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked);
|
||||
mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange);
|
||||
mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved);
|
||||
}
|
||||
|
||||
void CountDialog::open(const std::string& item, const std::string& message, const int maxCount)
|
||||
{
|
||||
setVisible(true);
|
||||
|
||||
mLabelText->setCaption(message);
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
mSlider->setScrollRange(maxCount);
|
||||
mItemText->setCaption(item);
|
||||
|
||||
int width = std::max(mItemText->getTextSize().width + 128, 320);
|
||||
setCoord(viewSize.width/2 - width/2,
|
||||
viewSize.height/2 - mMainWidget->getHeight()/2,
|
||||
width,
|
||||
mMainWidget->getHeight());
|
||||
|
||||
// make other gui elements inaccessible while this dialog is open
|
||||
MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget);
|
||||
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
|
||||
|
||||
mSlider->setScrollPosition(maxCount-1);
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
|
||||
|
||||
int okButtonWidth = mOkButton->getTextSize().width + 24;
|
||||
mOkButton->setCoord(width - 30 - okButtonWidth,
|
||||
mOkButton->getTop(),
|
||||
okButtonWidth,
|
||||
mOkButton->getHeight());
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(width - 30 - okButtonWidth - cancelButtonWidth - 8,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
}
|
||||
|
||||
void CountDialog::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void CountDialog::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
eventOkClicked(NULL, mSlider->getScrollPosition()+1);
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void CountDialog::onEditTextChange(MyGUI::EditBox* _sender)
|
||||
{
|
||||
if (_sender->getCaption() == "")
|
||||
return;
|
||||
|
||||
unsigned int count;
|
||||
try
|
||||
{
|
||||
count = boost::lexical_cast<unsigned int>(_sender->getCaption());
|
||||
}
|
||||
catch (std::bad_cast&)
|
||||
{
|
||||
count = 1;
|
||||
}
|
||||
if (count > mSlider->getScrollRange())
|
||||
{
|
||||
count = mSlider->getScrollRange();
|
||||
}
|
||||
mSlider->setScrollPosition(count-1);
|
||||
onSliderMoved(mSlider, count-1);
|
||||
}
|
||||
|
||||
void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position)
|
||||
{
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(_position+1));
|
||||
}
|
||||
|
||||
void CountDialog::close()
|
||||
{
|
||||
setVisible(false);
|
||||
MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#ifndef MWGUI_COUNTDIALOG_H
|
||||
#define MWGUI_COUNTDIALOG_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class CountDialog : public WindowBase
|
||||
{
|
||||
public:
|
||||
CountDialog(WindowManager& parWindowManager);
|
||||
void open(const std::string& item, const std::string& message, const int maxCount);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, int> EventHandle_WidgetInt;
|
||||
|
||||
/** Event : Ok button was clicked.\n
|
||||
signature : void method(MyGUI::Widget* _sender, int _count)\n
|
||||
*/
|
||||
EventHandle_WidgetInt eventOkClicked;
|
||||
|
||||
private:
|
||||
MyGUI::ScrollBar* mSlider;
|
||||
MyGUI::EditBox* mItemEdit;
|
||||
MyGUI::TextBox* mItemText;
|
||||
MyGUI::TextBox* mLabelText;
|
||||
MyGUI::Button* mOkButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
void onEditTextChange(MyGUI::EditBox* _sender);
|
||||
void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position);
|
||||
|
||||
void close();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,57 @@
|
||||
#include "map_window.hpp"
|
||||
|
||||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class DragAndDrop;
|
||||
|
||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
|
||||
void setWeapIcon(const char *str);
|
||||
void setSpellIcon(const char *str);
|
||||
void setWeapStatus(int s, int smax);
|
||||
void setSpellStatus(int s, int smax);
|
||||
void setEffect(const char *img);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setFPS(float fps);
|
||||
void setTriangleCount(size_t count);
|
||||
void setBatchCount(size_t count);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setPlayerPos(const float x, const float y);
|
||||
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||
void setFpsLevel(const int level);
|
||||
|
||||
MyGUI::ProgressPtr health, magicka, stamina;
|
||||
MyGUI::Widget *weapBox, *spellBox;
|
||||
MyGUI::ImageBox *weapImage, *spellImage;
|
||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||
MyGUI::Widget *effectBox, *minimapBox;
|
||||
MyGUI::ImageBox* effect1;
|
||||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
MyGUI::TextBox* trianglecounter;
|
||||
MyGUI::TextBox* batchcounter;
|
||||
|
||||
private:
|
||||
// bottom left elements
|
||||
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||
// bottom right elements
|
||||
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
void onWorldClicked(MyGUI::Widget* _sender);
|
||||
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
|
||||
void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new);
|
||||
};
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "bookwindow.hpp"
|
||||
#include "scrollwindow.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string toLower (const std::string& name)
|
||||
{
|
||||
std::string lowerCase;
|
||||
|
||||
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
|
||||
(int(*)(int)) std::tolower);
|
||||
|
||||
return lowerCase;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
getWidget(mAvatar, "Avatar");
|
||||
getWidget(mEncumbranceBar, "EncumbranceBar");
|
||||
getWidget(mEncumbranceText, "EncumbranceBarT");
|
||||
getWidget(mFilterAll, "AllButton");
|
||||
getWidget(mFilterWeapon, "WeaponButton");
|
||||
getWidget(mFilterApparel, "ApparelButton");
|
||||
getWidget(mFilterMagic, "MagicButton");
|
||||
getWidget(mFilterMisc, "MiscButton");
|
||||
getWidget(mLeftPane, "LeftPane");
|
||||
getWidget(mRightPane, "RightPane");
|
||||
|
||||
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
// adjust size of buttons to fit text
|
||||
int curX = 0;
|
||||
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
|
||||
curX += mFilterAll->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
|
||||
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
|
||||
curX += mFilterWeapon->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
|
||||
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
|
||||
curX += mFilterApparel->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
|
||||
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
|
||||
curX += mFilterMagic->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
|
||||
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
setCoord(0, 342, 600, 258);
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
openContainer(player);
|
||||
}
|
||||
|
||||
void InventoryWindow::openInventory()
|
||||
{
|
||||
updateEncumbranceBar();
|
||||
|
||||
mTrading = false;
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
}
|
||||
|
||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
const float aspect = 0.5; // fixed aspect ratio for the left pane
|
||||
mLeftPane->setSize( (_sender->getSize().height-44) * aspect, _sender->getSize().height-44 );
|
||||
mRightPane->setCoord( mLeftPane->getPosition().left + (_sender->getSize().height-44) * aspect + 4,
|
||||
mRightPane->getPosition().top,
|
||||
_sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15,
|
||||
_sender->getSize().height-44 );
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
mFilterApparel->setStateSelected(false);
|
||||
mFilterMagic->setStateSelected(false);
|
||||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
}
|
||||
|
||||
void InventoryWindow::onPinToggled()
|
||||
{
|
||||
mWindowManager.setWeaponVisibility(!mPinned);
|
||||
}
|
||||
|
||||
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
}
|
||||
|
||||
/// \todo scripts
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute();
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
if (mDragAndDrop->mDraggedFrom == this)
|
||||
{
|
||||
mWindowManager.getBookWindow()->setTakeButtonShow(false);
|
||||
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
|
||||
mWindowManager.setDragDrop(false);
|
||||
|
||||
drawItems();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end())
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end() && *it == item)
|
||||
{
|
||||
invStore.equip(slot, invStore.end());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryWindow::updateEncumbranceBar()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
float capacity = MWWorld::Class::get(player).getCapacity(player);
|
||||
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
|
||||
mEncumbranceBar->setProgressRange(capacity);
|
||||
mEncumbranceBar->setProgressPosition(encumbrance);
|
||||
mEncumbranceText->setCaption( boost::lexical_cast<std::string>(int(encumbrance)) + "/" + boost::lexical_cast<std::string>(int(capacity)) );
|
||||
}
|
||||
|
||||
void InventoryWindow::onFrame()
|
||||
{
|
||||
if (!mMainWidget->getVisible())
|
||||
return;
|
||||
|
||||
updateEncumbranceBar();
|
||||
}
|
||||
|
||||
int InventoryWindow::getPlayerGold()
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
{
|
||||
if (toLower(it->getCellRef().refID) == "gold_001")
|
||||
return it->getRefData().getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InventoryWindow::startTrade()
|
||||
{
|
||||
mTrading = true;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
#ifndef MGUI_Inventory_H
|
||||
#define MGUI_Inventory_H
|
||||
|
||||
#include "container.hpp"
|
||||
#include "window_pinnable_base.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class InventoryWindow : public ContainerBase, public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop);
|
||||
|
||||
void openInventory();
|
||||
|
||||
/// start trading, disables item drag&drop
|
||||
void startTrade();
|
||||
|
||||
void onFrame();
|
||||
|
||||
int getPlayerGold();
|
||||
|
||||
protected:
|
||||
MyGUI::Widget* mAvatar;
|
||||
MyGUI::TextBox* mArmorRating;
|
||||
MyGUI::ProgressBar* mEncumbranceBar;
|
||||
MyGUI::TextBox* mEncumbranceText;
|
||||
|
||||
MyGUI::Widget* mLeftPane;
|
||||
MyGUI::Widget* mRightPane;
|
||||
|
||||
MyGUI::Button* mFilterAll;
|
||||
MyGUI::Button* mFilterWeapon;
|
||||
MyGUI::Button* mFilterApparel;
|
||||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
bool mTrading;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onAvatarClicked(MyGUI::Widget* _sender);
|
||||
void onPinToggled();
|
||||
|
||||
void updateEncumbranceBar();
|
||||
|
||||
virtual bool isTrading() { return mTrading; }
|
||||
virtual bool isInventory() { return true; }
|
||||
virtual std::vector<MWWorld::Ptr> getEquippedItems();
|
||||
virtual void _unequipItem(MWWorld::Ptr item);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // Inventory_H
|
@ -1,236 +0,0 @@
|
||||
#ifndef MWGUI_LAYOUTS_H
|
||||
#define MWGUI_LAYOUTS_H
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
/*
|
||||
This file contains classes corresponding to window layouts
|
||||
defined in resources/mygui/ *.xml.
|
||||
|
||||
Each class inherites GUI::Layout and loads the XML file, and
|
||||
provides some helper functions to manipulate the elements of the
|
||||
window.
|
||||
|
||||
The windows are never created or destroyed (except at startup and
|
||||
shutdown), they are only hid. You can control visibility with
|
||||
setVisible().
|
||||
*/
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class LocalMapBase
|
||||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout);
|
||||
|
||||
void setCellPrefix(const std::string& prefix);
|
||||
void setActiveCell(const int x, const int y, bool interior=false);
|
||||
|
||||
void toggleFogOfWar();
|
||||
|
||||
protected:
|
||||
int mCurX, mCurY;
|
||||
bool mInterior;
|
||||
MyGUI::ScrollView* mLocalMap;
|
||||
std::string mPrefix;
|
||||
bool mChanged;
|
||||
bool mFogOfWar;
|
||||
|
||||
void applyFogOfWar();
|
||||
|
||||
OEngine::GUI::Layout* mLayout;
|
||||
|
||||
float mLastPositionX;
|
||||
float mLastPositionY;
|
||||
float mLastDirectionX;
|
||||
float mLastDirectionY;
|
||||
};
|
||||
|
||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||
{
|
||||
public:
|
||||
HUD(int width, int height, int fpsLevel);
|
||||
void setStats(int h, int hmax, int m, int mmax, int s, int smax);
|
||||
void setWeapIcon(const char *str);
|
||||
void setSpellIcon(const char *str);
|
||||
void setWeapStatus(int s, int smax);
|
||||
void setSpellStatus(int s, int smax);
|
||||
void setEffect(const char *img);
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value);
|
||||
void setFPS(float fps);
|
||||
void setTriangleCount(size_t count);
|
||||
void setBatchCount(size_t count);
|
||||
void setPlayerDir(const float x, const float y);
|
||||
void setPlayerPos(const float x, const float y);
|
||||
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||
void setFpsLevel(const int level);
|
||||
|
||||
MyGUI::ProgressPtr health, magicka, stamina;
|
||||
MyGUI::Widget *weapBox, *spellBox;
|
||||
MyGUI::ImageBox *weapImage, *spellImage;
|
||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||
MyGUI::Widget *effectBox, *minimapBox;
|
||||
MyGUI::ImageBox* effect1;
|
||||
MyGUI::ScrollView* minimap;
|
||||
MyGUI::ImageBox* compass;
|
||||
MyGUI::ImageBox* crosshair;
|
||||
|
||||
MyGUI::WidgetPtr fpsbox;
|
||||
MyGUI::TextBox* fpscounter;
|
||||
MyGUI::TextBox* trianglecounter;
|
||||
MyGUI::TextBox* batchcounter;
|
||||
|
||||
private:
|
||||
// bottom left elements
|
||||
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||
// bottom right elements
|
||||
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||
};
|
||||
|
||||
class MainMenu : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
MainMenu(int w, int h)
|
||||
: Layout("openmw_mainmenu_layout.xml")
|
||||
{
|
||||
setCoord(0,0,w,h);
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
class InventoryWindow : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
enum CategoryMode
|
||||
{
|
||||
CM_All = 0, // All items
|
||||
CM_Weapon = 1, // Only weapons
|
||||
CM_Apparel = 2, // Apparel
|
||||
CM_Magic = 3, // Magic
|
||||
CM_Misc = 4 // Misc
|
||||
};
|
||||
|
||||
InventoryWindow ()
|
||||
: Layout("openmw_inventory_window_layout.xml")
|
||||
, categoryMode(CM_All)
|
||||
|
||||
// color should be fetched from skin
|
||||
, activeColor(0, 0, 1)
|
||||
, inactiveColor(0.7, 0.7, 0.7)
|
||||
{
|
||||
setCoord(0, 200, 600, 400);
|
||||
|
||||
// These are just demo values, you should replace these with
|
||||
// real calls from outside the class later.
|
||||
|
||||
mMainWidget->setCaption("Glass Frostsword");
|
||||
setText("EncumbranceBarT", "176/210");
|
||||
|
||||
MyGUI::ProgressPtr pt;
|
||||
getWidget(pt, "EncumbranceBar");
|
||||
pt->setProgressRange(210);
|
||||
pt->setProgressPosition(176);
|
||||
|
||||
MyGUI::WidgetPtr avatar;
|
||||
getWidget(avatar, "Avatar");
|
||||
|
||||
// Adjust armor rating text to bottom of avatar widget
|
||||
MyGUI::TextBox* armor_rating;
|
||||
getWidget(armor_rating, "ArmorRating");
|
||||
armor_rating->setCaption("Armor: 11");
|
||||
MyGUI::IntCoord coord = armor_rating->getCoord();
|
||||
coord.top = avatar->getCoord().height - 4 - coord.height;
|
||||
armor_rating->setCoord(coord);
|
||||
|
||||
names[0] = "All";
|
||||
names[1] = "Weapon";
|
||||
names[2] = "Apparel";
|
||||
names[3] = "Magic";
|
||||
names[4] = "Misc";
|
||||
|
||||
boost::array<CategoryMode, 5> categories = { {
|
||||
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
|
||||
} };
|
||||
|
||||
// Initialize buttons with text and adjust sizes, also mark All as active button
|
||||
int margin = 2;
|
||||
int last_x = 0;
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
{
|
||||
CategoryMode mode = categories[i];
|
||||
std::string name = names[mode];
|
||||
name += "Button";
|
||||
setText(name, names[mode]);
|
||||
getWidget(buttons[mode], name);
|
||||
|
||||
MyGUI::ButtonPtr &button_pt = buttons[mode];
|
||||
if (mode == CM_All)
|
||||
button_pt->setTextColour(activeColor);
|
||||
else
|
||||
button_pt->setTextColour(inactiveColor);
|
||||
MyGUI::IntCoord coord = button_pt->getCoord();
|
||||
coord.left = last_x;
|
||||
last_x += coord.width + margin;
|
||||
button_pt->setCoord(coord);
|
||||
|
||||
button_pt->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected);
|
||||
}
|
||||
}
|
||||
|
||||
void setCategory(CategoryMode mode)
|
||||
{
|
||||
MyGUI::ButtonPtr pt = getCategoryButton(categoryMode);
|
||||
pt->setTextColour(inactiveColor);
|
||||
|
||||
pt = getCategoryButton(mode);
|
||||
pt->setTextColour(activeColor);
|
||||
categoryMode = mode;
|
||||
}
|
||||
|
||||
MyGUI::ButtonPtr getCategoryButton(CategoryMode mode)
|
||||
{
|
||||
return buttons[mode];
|
||||
}
|
||||
|
||||
void onCategorySelected(MyGUI::Widget *widget)
|
||||
{
|
||||
boost::array<CategoryMode, 5> categories = { {
|
||||
CM_All, CM_Weapon, CM_Apparel, CM_Magic, CM_Misc
|
||||
} };
|
||||
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
{
|
||||
CategoryMode mode = categories[i];
|
||||
if (widget == buttons[mode])
|
||||
{
|
||||
setCategory(mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CategoryMode categoryMode; // Current category filter
|
||||
MyGUI::ButtonPtr buttons[5]; // Button pointers
|
||||
std::string names[5]; // Names of category buttons
|
||||
|
||||
MyGUI::Colour activeColor;
|
||||
MyGUI::Colour inactiveColor;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
#endif
|
@ -0,0 +1,16 @@
|
||||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class MainMenu : public OEngine::GUI::Layout
|
||||
{
|
||||
public:
|
||||
MainMenu(int w, int h)
|
||||
: Layout("openmw_mainmenu_layout.xml")
|
||||
{
|
||||
setCoord(0,0,w,h);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,359 @@
|
||||
#include "tradewindow.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include "window_manager.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
TradeWindow::TradeWindow(WindowManager& parWindowManager) :
|
||||
WindowBase("openmw_trade_window_layout.xml", parWindowManager)
|
||||
, ContainerBase(NULL) // no drag&drop
|
||||
, mCurrentBalance(0)
|
||||
{
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
getWidget(mFilterAll, "AllButton");
|
||||
getWidget(mFilterWeapon, "WeaponButton");
|
||||
getWidget(mFilterApparel, "ApparelButton");
|
||||
getWidget(mFilterMagic, "MagicButton");
|
||||
getWidget(mFilterMisc, "MiscButton");
|
||||
|
||||
getWidget(mMaxSaleButton, "MaxSaleButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
getWidget(mOfferButton, "OfferButton");
|
||||
getWidget(mPlayerGold, "PlayerGold");
|
||||
getWidget(mMerchantGold, "MerchantGold");
|
||||
getWidget(mIncreaseButton, "IncreaseButton");
|
||||
getWidget(mDecreaseButton, "DecreaseButton");
|
||||
getWidget(mTotalBalance, "TotalBalance");
|
||||
getWidget(mTotalBalanceLabel, "TotalBalanceLabel");
|
||||
getWidget(mBottomPane, "BottomPane");
|
||||
|
||||
// adjust size of buttons to fit text
|
||||
int curX = 0;
|
||||
mFilterAll->setSize( mFilterAll->getTextSize().width + 24, mFilterAll->getSize().height );
|
||||
curX += mFilterAll->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterWeapon->setPosition(curX, mFilterWeapon->getPosition().top);
|
||||
mFilterWeapon->setSize( mFilterWeapon->getTextSize().width + 24, mFilterWeapon->getSize().height );
|
||||
curX += mFilterWeapon->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterApparel->setPosition(curX, mFilterApparel->getPosition().top);
|
||||
mFilterApparel->setSize( mFilterApparel->getTextSize().width + 24, mFilterApparel->getSize().height );
|
||||
curX += mFilterApparel->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMagic->setPosition(curX, mFilterMagic->getPosition().top);
|
||||
mFilterMagic->setSize( mFilterMagic->getTextSize().width + 24, mFilterMagic->getSize().height );
|
||||
curX += mFilterMagic->getTextSize().width + 24 + 4;
|
||||
|
||||
mFilterMisc->setPosition(curX, mFilterMisc->getPosition().top);
|
||||
mFilterMisc->setSize( mFilterMisc->getTextSize().width + 24, mFilterMisc->getSize().height );
|
||||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterMagic->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
mFilterMisc->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked);
|
||||
mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked);
|
||||
|
||||
mMaxSaleButton->setSize(MyGUI::IntSize(mMaxSaleButton->getTextSize().width + 24, mMaxSaleButton->getHeight()));
|
||||
|
||||
int cancelButtonWidth = mCancelButton->getTextSize().width + 24;
|
||||
mCancelButton->setCoord(mBottomPane->getWidth()-cancelButtonWidth,
|
||||
mCancelButton->getTop(),
|
||||
cancelButtonWidth,
|
||||
mCancelButton->getHeight());
|
||||
|
||||
int offerButtonWidth = mOfferButton->getTextSize().width + 24;
|
||||
mOfferButton->setCoord(mBottomPane->getWidth()-cancelButtonWidth-offerButtonWidth-8,
|
||||
mOfferButton->getTop(),
|
||||
offerButtonWidth,
|
||||
mOfferButton->getHeight());
|
||||
|
||||
setCoord(400, 0, 400, 300);
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &TradeWindow::onWindowResize);
|
||||
}
|
||||
|
||||
void TradeWindow::startTrade(MWWorld::Ptr actor)
|
||||
{
|
||||
setTitle(MWWorld::Class::get(actor).getName(actor));
|
||||
|
||||
mCurrentBalance = 0;
|
||||
|
||||
mWindowManager.getInventoryWindow()->startTrade();
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
ContainerBase::openContainer(actor);
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void TradeWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
mFilterApparel->setStateSelected(false);
|
||||
mFilterMagic->setStateSelected(false);
|
||||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
}
|
||||
|
||||
void TradeWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
// were there any items traded at all?
|
||||
MWWorld::ContainerStore& playerBought = mWindowManager.getInventoryWindow()->getBoughtItems();
|
||||
MWWorld::ContainerStore& merchantBought = getBoughtItems();
|
||||
if (playerBought.begin() == playerBought.end() && merchantBought.begin() == merchantBought.end())
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog11")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the player can afford this
|
||||
if (mCurrentBalance < 0 && mWindowManager.getInventoryWindow()->getPlayerGold() < std::abs(mCurrentBalance))
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog1")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the merchant can afford this
|
||||
int merchantgold;
|
||||
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
|
||||
if (ref->base->npdt52.gold == -10)
|
||||
merchantgold = ref->base->npdt12.gold;
|
||||
else
|
||||
merchantgold = ref->base->npdt52.gold;
|
||||
}
|
||||
else // ESM::Creature
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
|
||||
merchantgold = ref->base->data.gold;
|
||||
}
|
||||
if (mCurrentBalance > 0 && merchantgold < mCurrentBalance)
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarterDialog2")->str, std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
// success! make the item transfer.
|
||||
transferBoughtItems();
|
||||
mWindowManager.getInventoryWindow()->transferBoughtItems();
|
||||
|
||||
// add or remove gold from the player.
|
||||
bool goldFound = false;
|
||||
MWWorld::Ptr gold;
|
||||
MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore();
|
||||
for (MWWorld::ContainerStoreIterator it = playerStore.begin();
|
||||
it != playerStore.end(); ++it)
|
||||
{
|
||||
if (MWWorld::Class::get(*it).getName(*it) == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sGold")->str)
|
||||
{
|
||||
goldFound = true;
|
||||
gold = *it;
|
||||
}
|
||||
}
|
||||
if (goldFound)
|
||||
{
|
||||
gold.getRefData().setCount(gold.getRefData().getCount() + mCurrentBalance);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(mCurrentBalance > 0);
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), "Gold_001");
|
||||
ref.getPtr().getRefData().setCount(mCurrentBalance);
|
||||
playerStore.add(ref.getPtr());
|
||||
}
|
||||
|
||||
std::string sound = "Item Gold Up";
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mWindowManager.setGuiMode(GM_Game);
|
||||
}
|
||||
|
||||
void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
// i give you back your stuff!
|
||||
returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore());
|
||||
// now gimme back my stuff!
|
||||
mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
|
||||
|
||||
mWindowManager.setGuiMode(GM_Game);
|
||||
}
|
||||
|
||||
void TradeWindow::updateLabels()
|
||||
{
|
||||
mPlayerGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sYourGold")->str
|
||||
+ " " + boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
|
||||
|
||||
if (mCurrentBalance > 0)
|
||||
{
|
||||
mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalSold")->str);
|
||||
mTotalBalance->setCaption(boost::lexical_cast<std::string>(mCurrentBalance));
|
||||
}
|
||||
else
|
||||
{
|
||||
mTotalBalanceLabel->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sTotalCost")->str);
|
||||
mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance));
|
||||
}
|
||||
|
||||
int merchantgold;
|
||||
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
|
||||
if (ref->base->npdt52.gold == -10)
|
||||
merchantgold = ref->base->npdt12.gold;
|
||||
else
|
||||
merchantgold = ref->base->npdt52.gold;
|
||||
}
|
||||
else // ESM::Creature
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
|
||||
merchantgold = ref->base->data.gold;
|
||||
}
|
||||
|
||||
mMerchantGold->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sSellerGold")->str
|
||||
+ " " + boost::lexical_cast<std::string>(merchantgold));
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> TradeWindow::getEquippedItems()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
|
||||
if (mContainer.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
// creatures don't have equipment slots.
|
||||
return items;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer);
|
||||
|
||||
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
if (it != invStore.end())
|
||||
{
|
||||
items.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
|
||||
{
|
||||
int services = 0;
|
||||
if (mContainer.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
else if (mContainer.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>();
|
||||
if (ref->base->hasAI)
|
||||
services = ref->base->AI.services;
|
||||
}
|
||||
|
||||
if (item.getTypeName() == typeid(ESM::Weapon).name())
|
||||
return services & ESM::NPC::Weapon;
|
||||
else if (item.getTypeName() == typeid(ESM::Armor).name())
|
||||
return services & ESM::NPC::Armor;
|
||||
else if (item.getTypeName() == typeid(ESM::Clothing).name())
|
||||
return services & ESM::NPC::Clothing;
|
||||
else if (item.getTypeName() == typeid(ESM::Book).name())
|
||||
return services & ESM::NPC::Books;
|
||||
else if (item.getTypeName() == typeid(ESM::Ingredient).name())
|
||||
return services & ESM::NPC::Ingredients;
|
||||
else if (item.getTypeName() == typeid(ESM::Tool).name())
|
||||
return services & ESM::NPC::Picks;
|
||||
else if (item.getTypeName() == typeid(ESM::Probe).name())
|
||||
return services & ESM::NPC::Probes;
|
||||
else if (item.getTypeName() == typeid(ESM::Light).name())
|
||||
return services & ESM::NPC::Lights;
|
||||
else if (item.getTypeName() == typeid(ESM::Apparatus).name())
|
||||
return services & ESM::NPC::Apparatus;
|
||||
else if (item.getTypeName() == typeid(ESM::Repair).name())
|
||||
return services & ESM::NPC::RepairItem;
|
||||
else if (item.getTypeName() == typeid(ESM::Miscellaneous).name())
|
||||
return services & ESM::NPC::Misc;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
it != invStore.end(); ++it)
|
||||
{
|
||||
if (!npcAcceptsItem(*it))
|
||||
items.push_back(*it);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void TradeWindow::sellToNpc(MWWorld::Ptr item, int count)
|
||||
{
|
||||
/// \todo price adjustment depending on merchantile skill
|
||||
|
||||
mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count;
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count)
|
||||
{
|
||||
/// \todo price adjustment depending on merchantile skill
|
||||
|
||||
mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count;
|
||||
|
||||
updateLabels();
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
#ifndef MWGUI_TRADEWINDOW_H
|
||||
#define MWGUI_TRADEWINDOW_H
|
||||
|
||||
#include "container.hpp"
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Gui;
|
||||
class Widget;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class WindowManager;
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class TradeWindow : public ContainerBase, public WindowBase
|
||||
{
|
||||
public:
|
||||
TradeWindow(WindowManager& parWindowManager);
|
||||
|
||||
void startTrade(MWWorld::Ptr actor);
|
||||
|
||||
void sellToNpc(MWWorld::Ptr item, int count); ///< only used for adjusting the gold balance
|
||||
void buyFromNpc(MWWorld::Ptr item, int count); ///< only used for adjusting the gold balance
|
||||
|
||||
bool npcAcceptsItem(MWWorld::Ptr item);
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mFilterAll;
|
||||
MyGUI::Button* mFilterWeapon;
|
||||
MyGUI::Button* mFilterApparel;
|
||||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
MyGUI::Button* mIncreaseButton;
|
||||
MyGUI::Button* mDecreaseButton;
|
||||
MyGUI::TextBox* mTotalBalanceLabel;
|
||||
MyGUI::TextBox* mTotalBalance;
|
||||
|
||||
MyGUI::Widget* mBottomPane;
|
||||
|
||||
MyGUI::Button* mMaxSaleButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
MyGUI::Button* mOfferButton;
|
||||
MyGUI::TextBox* mPlayerGold;
|
||||
MyGUI::TextBox* mMerchantGold;
|
||||
|
||||
int mCurrentBalance;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onOfferButtonClicked(MyGUI::Widget* _sender);
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
// don't show items that the NPC has equipped in his trade-window.
|
||||
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();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
#include "actionequip.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
ActionEquip::ActionEquip (const MWWorld::Ptr& object) : mObject (object)
|
||||
{
|
||||
}
|
||||
|
||||
void ActionEquip::execute ()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(player).getContainerStore(player));
|
||||
|
||||
// slots that this item can be equipped in
|
||||
std::pair<std::vector<int>, bool> slots = MWWorld::Class::get(mObject).getEquipmentSlots(mObject);
|
||||
|
||||
// retrieve ContainerStoreIterator to the item
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
for (; it != invStore.end(); ++it)
|
||||
{
|
||||
if (*it == mObject)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(it != invStore.end());
|
||||
|
||||
// equip the item in the first free slot
|
||||
for (std::vector<int>::const_iterator slot=slots.first.begin();
|
||||
slot!=slots.first.end(); ++slot)
|
||||
{
|
||||
// if all slots are occupied, replace the last slot
|
||||
if (slot == --slots.first.end())
|
||||
{
|
||||
invStore.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
|
||||
if (invStore.getSlot(*slot) == invStore.end())
|
||||
{
|
||||
// slot is not occupied
|
||||
invStore.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
#ifndef GAME_MWWORLD_ACTIONEQUIP_H
|
||||
#define GAME_MWWORLD_ACTIONEQUIP_H
|
||||
|
||||
#include "action.hpp"
|
||||
#include "ptr.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class ActionEquip : public Action
|
||||
{
|
||||
Ptr mObject;
|
||||
|
||||
public:
|
||||
/// @param item to equip
|
||||
ActionEquip (const Ptr& object);
|
||||
|
||||
virtual void execute ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,22 @@
|
||||
#include "actionopen.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "class.hpp"
|
||||
#include "world.hpp"
|
||||
#include "containerstore.hpp"
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwgui/window_manager.hpp"
|
||||
#include "../mwgui/container.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
ActionOpen::ActionOpen (const MWWorld::Ptr& container) : mContainer (container) {
|
||||
mContainer = container;
|
||||
}
|
||||
|
||||
void ActionOpen::execute ()
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Container);
|
||||
MWBase::Environment::get().getWindowManager()->getContainerWindow()->open(mContainer);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
|
||||
#ifndef GAME_MWWORLD_ACTIONOPEN_H
|
||||
#define GAME_MWWORLD_ACTIONOPEN_H
|
||||
|
||||
#include "action.hpp"
|
||||
#include "ptr.hpp"
|
||||
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class ActionOpen : public Action
|
||||
{
|
||||
Ptr mContainer;
|
||||
|
||||
public:
|
||||
ActionOpen (const Ptr& container);
|
||||
///< \param The Container the Player has activated.
|
||||
virtual void execute ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ACTIONOPEN_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue