mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-20 18:39:39 +00:00
Merge remote-tracking branch 'zini/master' into animations
This commit is contained in:
commit
822f130f79
93 changed files with 2333 additions and 1114 deletions
|
@ -655,12 +655,12 @@ endif (APPLE)
|
|||
if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
||||
## Non Debian based Linux building
|
||||
# paths
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/usr/bin" CACHE PATH "Where to install binaries")
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Where to install binaries")
|
||||
set(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE PATH "Sets the root of data directories to a non-default location")
|
||||
set(DATADIR "${DATAROOTDIR}/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
set(DATADIR "${DATAROOTDIR}/games/openmw" CACHE PATH "Sets the openmw data directories to a non-default location")
|
||||
set(DOCDIR "${DATAROOTDIR}/doc/openmw" CACHE PATH "Sets the doc directory to a non-default location.")
|
||||
set(MANDIR "${DATAROOTDIR}/man" CACHE PATH "Where to install manpages")
|
||||
set(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/etc/openmw" CACHE PATH "Set config dir")
|
||||
set(SYSCONFDIR "/etc/openmw" CACHE PATH "Set config dir")
|
||||
set(ICONDIR "${DATAROOTDIR}/pixmaps" CACHE PATH "Set icon dir")
|
||||
|
||||
# Install binaries
|
||||
|
@ -684,6 +684,10 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
|||
# Install icon and .desktop
|
||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications")
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/opencs.png" DESTINATION "${ICONDIR}")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.desktop" DESTINATION "${DATAROOTDIR}/applications")
|
||||
ENDIF(BUILD_OPENCS)
|
||||
|
||||
# Install global configuration files
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" )
|
||||
|
|
|
@ -32,7 +32,8 @@ add_openmw_dir (mwgui
|
|||
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
|
||||
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
|
||||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||
keywordsearch
|
||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||
tradeitemmodel companionitemmodel pickpocketitemmodel
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
|
|
@ -200,7 +200,7 @@ namespace MWBase
|
|||
virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
|
||||
///< Hides dialog and schedules dialog to be deleted.
|
||||
|
||||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>()) = 0;
|
||||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>(), bool showInDialogueModeOnly = false) = 0;
|
||||
virtual void staticMessageBox(const std::string& message) = 0;
|
||||
virtual void removeStaticMessageBox() = 0;
|
||||
|
||||
|
|
|
@ -338,6 +338,9 @@ namespace MWBase
|
|||
virtual bool getActorStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if any actor is standing on \a object
|
||||
virtual float getWindSpeed() = 0;
|
||||
|
||||
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||
///< get all containers in active cells owned by this Npc
|
||||
|
||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
||||
|
||||
virtual int canRest() = 0;
|
||||
|
|
|
@ -164,4 +164,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Apparatus;
|
||||
}
|
||||
|
||||
float Apparatus::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
|
||||
ptr.get<ESM::Apparatus>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace MWClass
|
|||
|
||||
public:
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
|
|
|
@ -387,4 +387,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Armor;
|
||||
}
|
||||
|
||||
float Armor::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Armor> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace MWClass
|
|||
|
||||
public:
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
|
|
|
@ -188,4 +188,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Books;
|
||||
}
|
||||
|
||||
float Book::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Book> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ namespace MWClass
|
|||
|
||||
virtual float getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -307,4 +307,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Clothing;
|
||||
}
|
||||
|
||||
float Clothing::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Clothing> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ namespace MWClass
|
|||
|
||||
virtual float getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -225,6 +225,16 @@ namespace MWClass
|
|||
return weight;
|
||||
}
|
||||
|
||||
|
||||
int Creature::getServices(const MWWorld::Ptr &actor) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature>* ref = actor.get<ESM::Creature>();
|
||||
if (ref->mBase->mHasAI)
|
||||
return ref->mBase->mAiData.mServices;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
MWWorld::Ptr
|
||||
Creature::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
||||
{
|
||||
|
|
|
@ -62,6 +62,8 @@ namespace MWClass
|
|||
virtual bool isEssential (const MWWorld::Ptr& ptr) const;
|
||||
///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable)
|
||||
|
||||
virtual int getServices (const MWWorld::Ptr& actor) const;
|
||||
|
||||
static void registerSelf();
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
|
|
@ -202,4 +202,12 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Ingredients;
|
||||
}
|
||||
|
||||
|
||||
float Ingredient::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
|
||||
ptr.get<ESM::Ingredient>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
|||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -208,4 +208,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Lights;
|
||||
}
|
||||
|
||||
float Light::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Light> *ref =
|
||||
ptr.get<ESM::Light>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@ namespace MWClass
|
|||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -189,4 +189,11 @@ namespace MWClass
|
|||
|
||||
return ref->mBase->mData.mUses;
|
||||
}
|
||||
|
||||
float Lockpick::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ namespace MWClass
|
|||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||
///< Return item max health or throw an exception, if class does not have item health
|
||||
};
|
||||
|
|
|
@ -254,4 +254,11 @@ namespace MWClass
|
|||
return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc);
|
||||
}
|
||||
|
||||
float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace MWClass
|
|||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -648,6 +648,15 @@ namespace MWClass
|
|||
scale *= race->mData.mHeight.mFemale;
|
||||
}
|
||||
|
||||
int Npc::getServices(const MWWorld::Ptr &actor) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::NPC>* ref = actor.get<ESM::NPC>();
|
||||
if (ref->mBase->mHasAI)
|
||||
return ref->mBase->mAiData.mServices;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
MWWorld::Ptr
|
||||
Npc::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
||||
{
|
||||
|
|
|
@ -127,6 +127,8 @@ namespace MWClass
|
|||
|
||||
virtual bool isEssential (const MWWorld::Ptr& ptr) const;
|
||||
///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable)
|
||||
|
||||
virtual int getServices (const MWWorld::Ptr& actor) const;
|
||||
|
||||
static void registerSelf();
|
||||
|
||||
|
|
|
@ -199,4 +199,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Potions;
|
||||
}
|
||||
|
||||
float Potion::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Potion> *ref =
|
||||
ptr.get<ESM::Potion>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace MWClass
|
|||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -188,4 +188,11 @@ namespace MWClass
|
|||
|
||||
return ref->mBase->mData.mUses;
|
||||
}
|
||||
|
||||
float Probe::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Probe> *ref =
|
||||
ptr.get<ESM::Probe>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ namespace MWClass
|
|||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||
///< Return item max health or throw an exception, if class does not have item health
|
||||
};
|
||||
|
|
|
@ -180,4 +180,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::RepairItem;
|
||||
}
|
||||
|
||||
float Repair::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Repair> *ref =
|
||||
ptr.get<ESM::Repair>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,8 @@ namespace MWClass
|
|||
///< Return item max health or throw an exception, if class does not have item health
|
||||
/// (default implementation: throw an exceoption)
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -440,4 +440,11 @@ namespace MWClass
|
|||
{
|
||||
return npcServices & ESM::NPC::Weapon;
|
||||
}
|
||||
|
||||
float Weapon::getWeight(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Weapon> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
return ref->mBase->mData.mWeight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,8 @@ namespace MWClass
|
|||
|
||||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual float getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "alchemywindow.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -8,6 +9,11 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "inventoryitemmodel.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
#include "itemview.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -20,13 +26,25 @@ namespace
|
|||
path.append(".dds");
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
AlchemyWindow::AlchemyWindow()
|
||||
: WindowBase("openmw_alchemy_window.layout")
|
||||
, ContainerBase(0), mApparatus (4), mIngredients (4)
|
||||
, mApparatus (4)
|
||||
, mIngredients (4)
|
||||
{
|
||||
getWidget(mCreateButton, "CreateButton");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
@ -40,6 +58,13 @@ namespace MWGui
|
|||
getWidget(mApparatus[3], "Apparatus4");
|
||||
getWidget(mEffectsBox, "CreatedEffects");
|
||||
getWidget(mNameEdit, "NameEdit");
|
||||
getWidget(mItemView, "ItemView");
|
||||
|
||||
InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mSortModel = new SortFilterItemModel(model);
|
||||
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
|
||||
mItemView->setModel (mSortModel);
|
||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &AlchemyWindow::onSelectedItem);
|
||||
|
||||
mIngredients[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
|
||||
mIngredients[1]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
|
||||
|
@ -49,12 +74,6 @@ namespace MWGui
|
|||
mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked);
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
center();
|
||||
}
|
||||
|
||||
|
@ -126,12 +145,9 @@ namespace MWGui
|
|||
|
||||
void AlchemyWindow::open()
|
||||
{
|
||||
openContainer (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr
|
||||
setFilter (ContainerBase::Filter_Ingredients);
|
||||
|
||||
mNameEdit->setCaption("");
|
||||
|
||||
mAlchemy.setAlchemist (mPtr);
|
||||
mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
|
||||
int index = 0;
|
||||
|
||||
|
@ -155,8 +171,9 @@ namespace MWGui
|
|||
update();
|
||||
}
|
||||
|
||||
void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item)
|
||||
void AlchemyWindow::onSelectedItem(int index)
|
||||
{
|
||||
MWWorld::Ptr item = mSortModel->getItem(index).mBase;
|
||||
int res = mAlchemy.addIngredient(item);
|
||||
|
||||
if (res != -1)
|
||||
|
@ -168,19 +185,10 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> AlchemyWindow::itemsToIgnore()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> ignore;
|
||||
// don't show ingredients that are currently selected in the "available ingredients" box.
|
||||
for (int i=0; i<4; ++i)
|
||||
if (mIngredients[i]->isUserString("ToolTipType"))
|
||||
ignore.push_back(*mIngredients[i]->getUserData<MWWorld::Ptr>());
|
||||
|
||||
return ignore;
|
||||
}
|
||||
|
||||
void AlchemyWindow::update()
|
||||
{
|
||||
mSortModel->clearDragItems();
|
||||
|
||||
MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients ();
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
|
@ -193,6 +201,9 @@ namespace MWGui
|
|||
++it;
|
||||
}
|
||||
|
||||
if (!item.isEmpty())
|
||||
mSortModel->addDragItem(item, item.getRefData().getCount());
|
||||
|
||||
if (ingredient->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
|
||||
|
||||
|
@ -214,7 +225,7 @@ namespace MWGui
|
|||
text->setCaption(getCountString(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount()));
|
||||
}
|
||||
|
||||
drawItems();
|
||||
mItemView->update();
|
||||
|
||||
std::vector<ESM::ENAMstruct> effects;
|
||||
ESM::EffectList list;
|
||||
|
|
|
@ -5,19 +5,25 @@
|
|||
|
||||
#include "../mwmechanics/alchemy.hpp"
|
||||
|
||||
#include "container.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "windowbase.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class AlchemyWindow : public WindowBase, public ContainerBase
|
||||
class ItemView;
|
||||
class SortFilterItemModel;
|
||||
|
||||
class AlchemyWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
AlchemyWindow();
|
||||
|
||||
virtual void open();
|
||||
|
||||
protected:
|
||||
private:
|
||||
ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
|
||||
MyGUI::Button* mCreateButton;
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
|
@ -29,17 +35,12 @@ namespace MWGui
|
|||
void onCreateButtonClicked(MyGUI::Widget* _sender);
|
||||
void onIngredientSelected(MyGUI::Widget* _sender);
|
||||
|
||||
virtual void onSelectedItemImpl(MWWorld::Ptr item);
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
|
||||
void onSelectedItem(int index);
|
||||
|
||||
void removeIngredient(MyGUI::Widget* ingredient);
|
||||
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
|
||||
MWMechanics::Alchemy mAlchemy;
|
||||
|
||||
std::vector<MyGUI::ImageBox *> mApparatus;
|
||||
|
|
34
apps/openmw/mwgui/companionitemmodel.cpp
Normal file
34
apps/openmw/mwgui/companionitemmodel.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "companionitemmodel.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
CompanionItemModel::CompanionItemModel(const MWWorld::Ptr &actor)
|
||||
: InventoryItemModel(actor)
|
||||
{
|
||||
}
|
||||
|
||||
void CompanionItemModel::copyItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
if (mActor.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
MWMechanics::NpcStats& stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
|
||||
stats.modifyProfit(MWWorld::Class::get(item.mBase).getValue(item.mBase) * count);
|
||||
}
|
||||
|
||||
InventoryItemModel::copyItem(item, count);
|
||||
}
|
||||
|
||||
void CompanionItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
if (mActor.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
MWMechanics::NpcStats& stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
|
||||
stats.modifyProfit(-MWWorld::Class::get(item.mBase).getValue(item.mBase) * count);
|
||||
}
|
||||
|
||||
InventoryItemModel::removeItem(item, count);
|
||||
}
|
||||
}
|
22
apps/openmw/mwgui/companionitemmodel.hpp
Normal file
22
apps/openmw/mwgui/companionitemmodel.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef MWGUI_COMPANION_ITEM_MODEL_H
|
||||
#define MWGUI_COMPANION_ITEM_MODEL_H
|
||||
|
||||
#include "inventoryitemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
/// @brief The companion item model keeps track of the companion's profit by
|
||||
/// monitoring which items are being added to and removed from the model.
|
||||
class CompanionItemModel : public InventoryItemModel
|
||||
{
|
||||
public:
|
||||
CompanionItemModel (const MWWorld::Ptr& actor);
|
||||
|
||||
virtual void copyItem (const ItemStack& item, size_t count);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,51 +7,102 @@
|
|||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "messagebox.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
#include "companionitemmodel.hpp"
|
||||
#include "container.hpp"
|
||||
#include "countdialog.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
CompanionWindow::CompanionWindow(DragAndDrop *dragAndDrop, MessageBoxManager* manager)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowBase("openmw_companion_window.layout")
|
||||
: WindowBase("openmw_companion_window.layout")
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mMessageBoxManager(manager)
|
||||
, mSelectedItem(-1)
|
||||
, mModel(NULL)
|
||||
, mSortModel(NULL)
|
||||
{
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
getWidget(mProfitLabel, "ProfitLabel");
|
||||
getWidget(mEncumbranceBar, "EncumbranceBar");
|
||||
getWidget(mItemView, "ItemView");
|
||||
mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &CompanionWindow::onBackgroundSelected);
|
||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &CompanionWindow::onItemSelected);
|
||||
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CompanionWindow::onCloseButtonClicked);
|
||||
|
||||
setCoord(200,0,600,300);
|
||||
}
|
||||
|
||||
void CompanionWindow::open(MWWorld::Ptr npc)
|
||||
void CompanionWindow::onItemSelected(int index)
|
||||
{
|
||||
openContainer(npc);
|
||||
setTitle(MWWorld::Class::get(npc).getName(npc));
|
||||
drawItems();
|
||||
updateEncumbranceBar();
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
mDragAndDrop->drop(mModel, mItemView);
|
||||
updateEncumbranceBar();
|
||||
return;
|
||||
}
|
||||
|
||||
const ItemStack& item = mSortModel->getItem(index);
|
||||
|
||||
MWWorld::Ptr object = item.mBase;
|
||||
int count = item.mCount;
|
||||
bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
|
||||
if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
count = 1;
|
||||
|
||||
mSelectedItem = mSortModel->mapToSource(index);
|
||||
|
||||
if (count > 1 && !shift)
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), "#{sTake}", count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem);
|
||||
}
|
||||
else
|
||||
dragItem (NULL, count);
|
||||
}
|
||||
|
||||
void CompanionWindow::notifyItemDragged(MWWorld::Ptr item, int count)
|
||||
void CompanionWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
||||
}
|
||||
|
||||
void CompanionWindow::onBackgroundSelected()
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWMechanics::NpcStats& stats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
|
||||
stats.modifyProfit(MWWorld::Class::get(item).getValue(item) * count);
|
||||
mDragAndDrop->drop(mModel, mItemView);
|
||||
updateEncumbranceBar();
|
||||
}
|
||||
}
|
||||
|
||||
void CompanionWindow::open(const MWWorld::Ptr& npc)
|
||||
{
|
||||
mPtr = npc;
|
||||
setTitle(MWWorld::Class::get(npc).getName(npc));
|
||||
updateEncumbranceBar();
|
||||
|
||||
mModel = new CompanionItemModel(npc);
|
||||
mSortModel = new SortFilterItemModel(mModel);
|
||||
mItemView->setModel(mSortModel);
|
||||
}
|
||||
|
||||
void CompanionWindow::onFrame()
|
||||
{
|
||||
updateEncumbranceBar();
|
||||
}
|
||||
|
||||
void CompanionWindow::updateEncumbranceBar()
|
||||
{
|
||||
if (mPtr.isEmpty())
|
||||
return;
|
||||
float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr);
|
||||
float encumbrance = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
|
||||
mEncumbranceBar->setValue(encumbrance, capacity);
|
||||
|
@ -65,11 +116,6 @@ void CompanionWindow::updateEncumbranceBar()
|
|||
}
|
||||
}
|
||||
|
||||
void CompanionWindow::onWindowResize(MyGUI::Window* window)
|
||||
{
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && MWWorld::Class::get(mPtr).getNpcStats(mPtr).getProfit() < 0)
|
||||
|
|
|
@ -1,34 +1,47 @@
|
|||
#ifndef OPENMW_MWGUI_COMPANIONWINDOW_H
|
||||
#define OPENMW_MWGUI_COMPANIONWINDOW_H
|
||||
|
||||
#include "container.hpp"
|
||||
#include "widgets.hpp"
|
||||
#include "windowbase.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class MessageBoxManager;
|
||||
class ItemView;
|
||||
class DragAndDrop;
|
||||
class SortFilterItemModel;
|
||||
class CompanionItemModel;
|
||||
|
||||
class CompanionWindow : public ContainerBase, public WindowBase
|
||||
class CompanionWindow : public WindowBase, public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager);
|
||||
virtual ~CompanionWindow() {}
|
||||
|
||||
void open(MWWorld::Ptr npc);
|
||||
void open(const MWWorld::Ptr& npc);
|
||||
void onFrame ();
|
||||
|
||||
virtual void notifyItemDragged(MWWorld::Ptr item, int count);
|
||||
private:
|
||||
ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
CompanionItemModel* mModel;
|
||||
size_t mSelectedItem;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mCloseButton;
|
||||
MyGUI::TextBox* mProfitLabel;
|
||||
Widgets::MWDynamicStat* mEncumbranceBar;
|
||||
MessageBoxManager* mMessageBoxManager;
|
||||
|
||||
void onItemSelected(int index);
|
||||
void onBackgroundSelected();
|
||||
void dragItem(MyGUI::Widget* sender, int count);
|
||||
|
||||
void onMessageBoxButtonClicked(int button);
|
||||
|
||||
void updateEncumbranceBar();
|
||||
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
|
|
@ -7,558 +7,21 @@
|
|||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
#include "itemview.hpp"
|
||||
#include "inventoryitemmodel.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
#include "pickpocketitemmodel.hpp"
|
||||
|
||||
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::Lockpick).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());
|
||||
}
|
||||
}
|
||||
|
||||
bool isChargedSoulstone (MWWorld::Ptr ptr)
|
||||
{
|
||||
if (ptr.getTypeName() != typeid(ESM::Miscellaneous).name())
|
||||
return false;
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
return (ref->mRef.mSoul != "");
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ContainerBase::ContainerBase(DragAndDrop* dragAndDrop)
|
||||
: mDragAndDrop(dragAndDrop)
|
||||
, mFilter(ContainerBase::Filter_All)
|
||||
, mDisplayEquippedItems(true)
|
||||
, mHighlightEquippedItems(true)
|
||||
{
|
||||
}
|
||||
|
||||
void ContainerBase::setWidgets(MyGUI::Widget* containerWidget, MyGUI::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 = "#{sTake}";
|
||||
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 if (isTrading())
|
||||
{
|
||||
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
|
||||
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object))
|
||||
{
|
||||
// user notification "i don't buy this item"
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sBarterDialog4}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool buying = isTradeWindow(); // buying or selling?
|
||||
std::string message = buying ? "#{sQuanityMenuMessage02}" : "#{sQuanityMenuMessage01}";
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>());
|
||||
}
|
||||
}
|
||||
|
||||
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()->sellToNpc(object, count, true);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count, true);
|
||||
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()->sellToNpc(object, count, false);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->drawItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->addBarteredItem(object, count);
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->buyFromNpc(object, count, false);
|
||||
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(mPtr).getContainerStore(mPtr);
|
||||
|
||||
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 (mPtr.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
|
||||
if (ref->mBase->mFlags & ESM::Container::Organic)
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sContentsMessage2}");
|
||||
|
||||
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(mPtr).getCapacity(mPtr);
|
||||
|
||||
// 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(mPtr).getEncumbrance(mPtr);
|
||||
if (curWeight > capacity)
|
||||
{
|
||||
it->getRefData().setCount(0);
|
||||
object.getRefData().setCount(origCount);
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sContentsMessage3}");
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
||||
mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount);
|
||||
notifyItemDragged(object, mDragAndDrop->mDraggedCount);
|
||||
|
||||
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(int filter)
|
||||
{
|
||||
mFilter = filter;
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void ContainerBase::openContainer(MWWorld::Ptr container)
|
||||
{
|
||||
mPtr = container;
|
||||
}
|
||||
|
||||
void ContainerBase::drawItems()
|
||||
{
|
||||
while (mContainerWidget->getChildCount())
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0));
|
||||
}
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int maxHeight = mItemView->getSize().height - 58;
|
||||
|
||||
bool onlyMagic = false;
|
||||
bool noMagic = false;
|
||||
int categories = 0;
|
||||
if (mFilter & Filter_All)
|
||||
categories |= MWWorld::ContainerStore::Type_All;
|
||||
if (mFilter & Filter_Weapon)
|
||||
categories |= MWWorld::ContainerStore::Type_Weapon;
|
||||
if (mFilter & Filter_Apparel)
|
||||
categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor;
|
||||
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;
|
||||
}
|
||||
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 | MWWorld::ContainerStore::Type_Probe;
|
||||
}
|
||||
if (mFilter & Filter_Ingredients)
|
||||
categories |= MWWorld::ContainerStore::Type_Ingredient;
|
||||
if (mFilter & Filter_ChargedSoulstones)
|
||||
categories |= MWWorld::ContainerStore::Type_Miscellaneous;
|
||||
if (mFilter & Filter_NoMagic)
|
||||
noMagic = true;
|
||||
|
||||
/// \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 (mDisplayEquippedItems && mHighlightEquippedItems)
|
||||
{
|
||||
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()
|
||||
|| (!mHighlightEquippedItems && mDisplayEquippedItems))
|
||||
&& 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)
|
||||
{
|
||||
const MWWorld::Ptr* iter = &((*it).first);
|
||||
|
||||
|
||||
if (onlyMagic
|
||||
&& it->second != ItemState_Barter
|
||||
&& MWWorld::Class::get(*iter).getEnchantment(*iter) == ""
|
||||
&& iter->getTypeName() != typeid(ESM::Potion).name())
|
||||
continue;
|
||||
|
||||
if (noMagic
|
||||
&& it->second != ItemState_Barter
|
||||
&& (MWWorld::Class::get(*iter).getEnchantment(*iter) != ""
|
||||
|| iter->getTypeName() == typeid(ESM::Potion).name()))
|
||||
continue;
|
||||
|
||||
if ( (mFilter & Filter_ChargedSoulstones)
|
||||
&& !isChargedSoulstone(*iter))
|
||||
continue;
|
||||
|
||||
int displayCount = iter->getRefData().getCount();
|
||||
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
|
||||
{
|
||||
displayCount -= mDragAndDrop->mDraggedCount;
|
||||
}
|
||||
if(displayCount > 0)
|
||||
{
|
||||
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<MyGUI::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
|
||||
MyGUI::ImageBox* image = backgroundWidget->createWidget<MyGUI::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));
|
||||
text->setCaption(getCountString(displayCount));
|
||||
|
||||
y += 42;
|
||||
if (y > maxHeight)
|
||||
{
|
||||
x += 42;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height);
|
||||
mItemView->setCanvasSize(size);
|
||||
mContainerWidget->setSize(size);
|
||||
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
std::string ContainerBase::getCountString(const int count)
|
||||
std::string getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
|
@ -567,121 +30,193 @@ namespace MWGui
|
|||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count)
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
void DragAndDrop::startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count)
|
||||
{
|
||||
int origCount = item.getRefData().getCount();
|
||||
item.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = mBoughtItems.add(item);
|
||||
item.getRefData().setCount(origCount - count);
|
||||
}
|
||||
mItem = sourceModel->getItem(index);
|
||||
mDraggedCount = count;
|
||||
mSourceModel = sourceModel;
|
||||
mSourceView = sourceView;
|
||||
mSourceSortModel = sortModel;
|
||||
mIsOnDragAndDrop = true;
|
||||
mDragAndDropWidget->setVisible(true);
|
||||
|
||||
void ContainerBase::addItem(MWWorld::Ptr item, int count)
|
||||
{
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
std::string sound = MWWorld::Class::get(mItem.mBase).getUpSoundId(mItem.mBase);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
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(mPtr).getContainerStore(mPtr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
if (mSourceSortModel)
|
||||
{
|
||||
containerStore.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store)
|
||||
{
|
||||
for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it)
|
||||
{
|
||||
store.add(*it);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> ContainerBase::getEquippedItems()
|
||||
{
|
||||
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
|
||||
return std::vector<MWWorld::Ptr>();
|
||||
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
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);
|
||||
}
|
||||
mSourceSortModel->clearDragItems();
|
||||
mSourceSortModel->addDragItem(mItem.mBase, count);
|
||||
}
|
||||
|
||||
return items;
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(mItem.mBase).getInventoryIcon(mItem.mBase);
|
||||
MyGUI::ImageBox* baseWidget = mDragAndDropWidget->createWidget<MyGUI::ImageBox>
|
||||
("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
|
||||
mDraggedWidget = baseWidget;
|
||||
MyGUI::ImageBox* image = baseWidget->createWidget<MyGUI::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));
|
||||
text->setCaption(getCountString(count));
|
||||
|
||||
sourceView->update();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(true);
|
||||
}
|
||||
|
||||
MWWorld::ContainerStore& ContainerBase::getContainerStore()
|
||||
void DragAndDrop::drop(ItemModel *targetModel, ItemView *targetView)
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
return store;
|
||||
std::string sound = MWWorld::Class::get(mItem.mBase).getDownSoundId(mItem.mBase);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
mDragAndDropWidget->setVisible(false);
|
||||
|
||||
targetModel->copyItem(mItem, mDraggedCount);
|
||||
mSourceModel->removeItem(mItem, mDraggedCount);
|
||||
|
||||
mSourceModel->update();
|
||||
|
||||
finish();
|
||||
targetView->update();
|
||||
}
|
||||
|
||||
void DragAndDrop::finish()
|
||||
{
|
||||
mIsOnDragAndDrop = false;
|
||||
mSourceSortModel->clearDragItems();
|
||||
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget);
|
||||
mDraggedWidget = 0;
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowBase("openmw_container_window.layout")
|
||||
: WindowBase("openmw_container_window.layout")
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mSelectedItem(-1)
|
||||
, mModel(NULL)
|
||||
, mSortModel(NULL)
|
||||
{
|
||||
getWidget(mDisposeCorpseButton, "DisposeCorpseButton");
|
||||
getWidget(mTakeButton, "TakeButton");
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
getWidget(mItemView, "ItemView");
|
||||
mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &ContainerWindow::onBackgroundSelected);
|
||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &ContainerWindow::onItemSelected);
|
||||
|
||||
mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked);
|
||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked);
|
||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked);
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ContainerWindow::onWindowResize);
|
||||
|
||||
setCoord(200,0,600,300);
|
||||
}
|
||||
|
||||
ContainerWindow::~ContainerWindow()
|
||||
void ContainerWindow::onItemSelected(int index)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
if (!dynamic_cast<PickpocketItemModel*>(mModel))
|
||||
dropItem();
|
||||
return;
|
||||
}
|
||||
|
||||
const ItemStack& item = mSortModel->getItem(index);
|
||||
|
||||
MWWorld::Ptr object = item.mBase;
|
||||
int count = item.mCount;
|
||||
bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
|
||||
if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
count = 1;
|
||||
|
||||
mSelectedItem = mSortModel->mapToSource(index);
|
||||
|
||||
if (count > 1 && !shift)
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), "#{sTake}", count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
|
||||
}
|
||||
else
|
||||
dragItem (NULL, count);
|
||||
}
|
||||
|
||||
void ContainerWindow::onWindowResize(MyGUI::Window* window)
|
||||
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
drawItems();
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
||||
}
|
||||
|
||||
void ContainerWindow::open(MWWorld::Ptr container, bool loot)
|
||||
void ContainerWindow::dropItem()
|
||||
{
|
||||
mDisplayEquippedItems = true;
|
||||
mHighlightEquippedItems = false;
|
||||
if (mPtr.getTypeName() == typeid(ESM::Container).name())
|
||||
{
|
||||
// check that we don't exceed container capacity
|
||||
MWWorld::Ptr item = mDragAndDrop->mItem.mBase;
|
||||
float weight = MWWorld::Class::get(item).getWeight(item) * mDragAndDrop->mDraggedCount;
|
||||
if (MWWorld::Class::get(mPtr).getCapacity(mPtr) < MWWorld::Class::get(mPtr).getEncumbrance(mPtr) + weight)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}");
|
||||
return;
|
||||
}
|
||||
|
||||
// check container organic flag
|
||||
MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
|
||||
if (ref->mBase->mFlags & ESM::Container::Organic)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sContentsMessage2}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mDragAndDrop->drop(mModel, mItemView);
|
||||
}
|
||||
|
||||
void ContainerWindow::onBackgroundSelected()
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop && !dynamic_cast<PickpocketItemModel*>(mModel))
|
||||
dropItem();
|
||||
}
|
||||
|
||||
void ContainerWindow::open(const MWWorld::Ptr& container, bool loot)
|
||||
{
|
||||
mPtr = container;
|
||||
|
||||
if (container.getTypeName() == typeid(ESM::NPC).name() && !loot)
|
||||
{
|
||||
// we are stealing stuff
|
||||
mDisplayEquippedItems = false;
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
mModel = new PickpocketItemModel(player, new InventoryItemModel(container));
|
||||
}
|
||||
else
|
||||
mModel = new InventoryItemModel(container);
|
||||
|
||||
mDisposeCorpseButton->setVisible(loot);
|
||||
|
||||
openContainer(container);
|
||||
setTitle(MWWorld::Class::get(container).getName(container));
|
||||
drawItems();
|
||||
|
||||
mSortModel = new SortFilterItemModel(mModel);
|
||||
|
||||
mItemView->setModel (mSortModel);
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -697,32 +232,19 @@ namespace MWGui
|
|||
if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// transfer everything into the player's inventory
|
||||
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
std::vector<MWWorld::Ptr> equippedItems = getEquippedItems();
|
||||
|
||||
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)
|
||||
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
|
||||
for (size_t i=0; i<mModel->getItemCount(); ++i)
|
||||
{
|
||||
if (std::find(equippedItems.begin(), equippedItems.end(), *iter) != equippedItems.end()
|
||||
&& !mDisplayEquippedItems)
|
||||
continue;
|
||||
|
||||
playerStore.add(*iter);
|
||||
|
||||
if (i==0)
|
||||
{
|
||||
// play the sound of the first object
|
||||
std::string sound = MWWorld::Class::get(*iter).getUpSoundId(*iter);
|
||||
MWWorld::Ptr item = mModel->getItem(i).mBase;
|
||||
std::string sound = MWWorld::Class::get(item).getUpSoundId(item);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
}
|
||||
|
||||
iter->getRefData().setCount(0);
|
||||
|
||||
++i;
|
||||
playerModel->copyItem(mModel->getItem(i), mModel->getItem(i).mCount);
|
||||
mModel->removeItem(mModel->getItem(i), mModel->getItem(i).mCount);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
|
@ -735,10 +257,10 @@ namespace MWGui
|
|||
{
|
||||
onTakeAllButtonClicked(mTakeButton);
|
||||
|
||||
/// \todo I don't think this is the correct flag to check
|
||||
if (MWWorld::Class::get(mPtr).isEssential(mPtr))
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
|
||||
else
|
||||
/// \todo if corpse is non-disposable: messagebox #{sDisposeCorpseFail}
|
||||
//if ()
|
||||
// MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
|
||||
//else
|
||||
MWBase::Environment::get().getWorld()->deleteObject(mPtr);
|
||||
|
||||
mPtr = MWWorld::Ptr();
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
#include "windowbase.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
|
||||
#include "../mwclass/container.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
@ -23,7 +21,8 @@ namespace MWGui
|
|||
{
|
||||
class WindowManager;
|
||||
class ContainerWindow;
|
||||
class ContainerBase;
|
||||
class ItemView;
|
||||
class SortFilterItemModel;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,114 +34,41 @@ namespace MWGui
|
|||
bool mIsOnDragAndDrop;
|
||||
MyGUI::Widget* mDraggedWidget;
|
||||
MyGUI::Widget* mDragAndDropWidget;
|
||||
ContainerBase* mDraggedFrom;
|
||||
ItemModel* mSourceModel;
|
||||
ItemView* mSourceView;
|
||||
SortFilterItemModel* mSourceSortModel;
|
||||
ItemStack mItem;
|
||||
int mDraggedCount;
|
||||
|
||||
void startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count);
|
||||
void drop (ItemModel* targetModel, ItemView* targetView);
|
||||
|
||||
void finish();
|
||||
};
|
||||
|
||||
class ContainerBase : public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ContainerBase(DragAndDrop* dragAndDrop);
|
||||
virtual ~ContainerBase();
|
||||
|
||||
// basic types (inclusive)
|
||||
static const int Filter_All = (1<<0);
|
||||
static const int Filter_Weapon = (1<<1);
|
||||
static const int Filter_Apparel = (1<<2);
|
||||
static const int Filter_Ingredients = (1<<3);
|
||||
static const int Filter_Misc = (1<<4);
|
||||
|
||||
// special filtering (exclusive)
|
||||
static const int Filter_Magic = (1<<5);
|
||||
static const int Filter_NoMagic = (1<<6);
|
||||
static const int Filter_ChargedSoulstones = (1<<7);
|
||||
|
||||
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(int filter); ///< set category filter
|
||||
void drawItems();
|
||||
|
||||
/// fired when an item was moved by drag&drop. \n
|
||||
/// if it was removed from this container, count will be negative.
|
||||
virtual void notifyItemDragged(MWWorld::Ptr item, int count) {}
|
||||
|
||||
protected:
|
||||
bool mDisplayEquippedItems;
|
||||
bool mHighlightEquippedItems;
|
||||
|
||||
MyGUI::ScrollView* mItemView;
|
||||
MyGUI::Widget* mContainerWidget;
|
||||
|
||||
MyGUI::Widget* mSelectedItem;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
int 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();
|
||||
virtual void _unequipItem(MWWorld::Ptr item) { ; }
|
||||
|
||||
virtual bool isTrading() { return false; }
|
||||
|
||||
virtual void onSelectedItemImpl(MWWorld::Ptr item) { ; }
|
||||
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); }
|
||||
|
||||
virtual void notifyContentChanged() { ; }
|
||||
};
|
||||
|
||||
class ContainerWindow : public ContainerBase, public WindowBase
|
||||
class ContainerWindow : public WindowBase, public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
ContainerWindow(DragAndDrop* dragAndDrop);
|
||||
|
||||
virtual ~ContainerWindow();
|
||||
void open(const MWWorld::Ptr& container, bool loot=false);
|
||||
|
||||
void open(MWWorld::Ptr container, bool loot=false);
|
||||
private:
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
MWGui::ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
ItemModel* mModel;
|
||||
size_t mSelectedItem;
|
||||
|
||||
protected:
|
||||
MyGUI::Button* mDisposeCorpseButton;
|
||||
MyGUI::Button* mTakeButton;
|
||||
MyGUI::Button* mCloseButton;
|
||||
|
||||
void onWindowResize(MyGUI::Window* window);
|
||||
void onItemSelected(int index);
|
||||
void onBackgroundSelected();
|
||||
void dragItem(MyGUI::Widget* sender, int count);
|
||||
void dropItem();
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
void onDisposeCorpseButtonClicked(MyGUI::Widget* sender);
|
||||
|
|
113
apps/openmw/mwgui/containeritemmodel.cpp
Normal file
113
apps/openmw/mwgui/containeritemmodel.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "containeritemmodel.hpp"
|
||||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources)
|
||||
: mItemSources(itemSources)
|
||||
{
|
||||
assert (mItemSources.size());
|
||||
}
|
||||
|
||||
ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source)
|
||||
{
|
||||
mItemSources.push_back(source);
|
||||
}
|
||||
|
||||
ItemStack ContainerItemModel::getItem (ModelIndex index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw std::runtime_error("Invalid index supplied");
|
||||
if (mItems.size() <= static_cast<size_t>(index))
|
||||
throw std::runtime_error("Item index out of range");
|
||||
return mItems[index];
|
||||
}
|
||||
|
||||
size_t ContainerItemModel::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
ItemModel::ModelIndex ContainerItemModel::getIndex (ItemStack item)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (std::vector<ItemStack>::iterator it = mItems.begin(); it != mItems.end(); ++it)
|
||||
{
|
||||
if (*it == item)
|
||||
return i;
|
||||
++i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ContainerItemModel::copyItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1];
|
||||
int origCount = item.mBase.getRefData().getCount();
|
||||
item.mBase.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = MWWorld::Class::get(source).getContainerStore(source).add(item.mBase);
|
||||
if (*it != item.mBase)
|
||||
item.mBase.getRefData().setCount(origCount);
|
||||
else
|
||||
item.mBase.getRefData().setCount(origCount + count); // item copied onto itself
|
||||
}
|
||||
|
||||
void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
int toRemove = count;
|
||||
|
||||
for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(*source).getContainerStore(*source);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||
{
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (*it == item.mBase || (store.stacks(*it, item.mBase) && item.mBase.getContainerStore()->stacks(*it, item.mBase)))
|
||||
{
|
||||
int refCount = it->getRefData().getCount();
|
||||
it->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||
toRemove -= refCount;
|
||||
if (toRemove <= 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Not enough items to remove could be found");
|
||||
}
|
||||
|
||||
void ContainerItemModel::update()
|
||||
{
|
||||
mItems.clear();
|
||||
for (std::vector<MWWorld::Ptr>::iterator source = mItemSources.begin(); source != mItemSources.end(); ++source)
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(*source).getContainerStore(*source);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||
{
|
||||
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||
for (; itemStack != mItems.end(); ++itemStack)
|
||||
{
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (store.stacks(itemStack->mBase, *it) && it->getContainerStore()->stacks(itemStack->mBase, *it))
|
||||
{
|
||||
// we already have an item stack of this kind, add to it
|
||||
itemStack->mCount += it->getRefData().getCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemStack == mItems.end())
|
||||
{
|
||||
// no stack yet, create one
|
||||
ItemStack newItem (*it, this, it->getRefData().getCount());
|
||||
mItems.push_back(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
37
apps/openmw/mwgui/containeritemmodel.hpp
Normal file
37
apps/openmw/mwgui/containeritemmodel.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef MWGUI_CONTAINER_ITEM_MODEL_H
|
||||
#define MWGUI_CONTAINER_ITEM_MODEL_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
/// @brief The container item model supports multiple item sources, which are needed for
|
||||
/// making NPCs sell items from containers owned by them
|
||||
class ContainerItemModel : public ItemModel
|
||||
{
|
||||
public:
|
||||
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources);
|
||||
///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal,
|
||||
/// while the last element will be used to add new items to.
|
||||
|
||||
ContainerItemModel (const MWWorld::Ptr& source);
|
||||
|
||||
virtual ItemStack getItem (ModelIndex index);
|
||||
virtual ModelIndex getIndex (ItemStack item);
|
||||
virtual size_t getItemCount();
|
||||
|
||||
virtual void copyItem (const ItemStack& item, size_t count);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
|
||||
virtual void update();
|
||||
|
||||
private:
|
||||
std::vector<MWWorld::Ptr> mItemSources;
|
||||
|
||||
std::vector<ItemStack> mItems;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwdialogue/dialoguemanagerimp.hpp"
|
||||
|
||||
#include "widgets.hpp"
|
||||
|
|
|
@ -6,11 +6,14 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "itemselection.hpp"
|
||||
#include "container.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -139,13 +142,12 @@ namespace MWGui
|
|||
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
|
||||
{
|
||||
delete mItemSelectionDialog;
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}",
|
||||
ContainerBase::Filter_Apparel|ContainerBase::Filter_Weapon|ContainerBase::Filter_NoMagic);
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}");
|
||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->drawItems ();
|
||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyEnchantable);
|
||||
}
|
||||
|
||||
void EnchantingDialog::onItemSelected(MWWorld::Ptr item)
|
||||
|
@ -227,13 +229,12 @@ namespace MWGui
|
|||
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
|
||||
{
|
||||
delete mItemSelectionDialog;
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}",
|
||||
ContainerBase::Filter_Misc|ContainerBase::Filter_ChargedSoulstones);
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}");
|
||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->drawItems ();
|
||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones);
|
||||
|
||||
//MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}");
|
||||
}
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "console.hpp"
|
||||
#include "spellicons.hpp"
|
||||
#include "itemmodel.hpp"
|
||||
#include "container.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -195,7 +198,7 @@ namespace MWGui
|
|||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// drop item into the gameworld
|
||||
MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::Ptr object = mDragAndDrop->mItem.mBase;
|
||||
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
|
@ -217,16 +220,11 @@ namespace MWGui
|
|||
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
object.getRefData().setCount(origCount);
|
||||
|
||||
// remove object from the container it was coming from
|
||||
object.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
mDragAndDrop->mDraggedWidget = 0;
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
mDragAndDrop->mDraggedFrom->drawItems();
|
||||
mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount);
|
||||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||
mDragAndDrop->finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
97
apps/openmw/mwgui/inventoryitemmodel.cpp
Normal file
97
apps/openmw/mwgui/inventoryitemmodel.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include "inventoryitemmodel.hpp"
|
||||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
InventoryItemModel::InventoryItemModel(const MWWorld::Ptr &actor)
|
||||
: mActor(actor)
|
||||
{
|
||||
}
|
||||
|
||||
ItemStack InventoryItemModel::getItem (ModelIndex index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw std::runtime_error("Invalid index supplied");
|
||||
if (mItems.size() <= static_cast<size_t>(index))
|
||||
throw std::runtime_error("Item index out of range");
|
||||
return mItems[index];
|
||||
}
|
||||
|
||||
size_t InventoryItemModel::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
ItemModel::ModelIndex InventoryItemModel::getIndex (ItemStack item)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (std::vector<ItemStack>::iterator it = mItems.begin(); it != mItems.end(); ++it)
|
||||
{
|
||||
if (*it == item)
|
||||
return i;
|
||||
++i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void InventoryItemModel::copyItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
int origCount = item.mBase.getRefData().getCount();
|
||||
item.mBase.getRefData().setCount(count);
|
||||
MWWorld::ContainerStoreIterator it = MWWorld::Class::get(mActor).getContainerStore(mActor).add(item.mBase);
|
||||
if (*it != item.mBase)
|
||||
item.mBase.getRefData().setCount(origCount);
|
||||
else
|
||||
item.mBase.getRefData().setCount(origCount + count); // item copied onto itself
|
||||
}
|
||||
|
||||
|
||||
void InventoryItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mActor).getContainerStore(mActor);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||
{
|
||||
if (*it == item.mBase)
|
||||
{
|
||||
if (it->getRefData().getCount() < static_cast<int>(count))
|
||||
throw std::runtime_error("Not enough items in the stack to remove");
|
||||
it->getRefData().setCount(it->getRefData().getCount() - count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Item to remove not found in container store");
|
||||
}
|
||||
|
||||
void InventoryItemModel::update()
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(mActor).getContainerStore(mActor);
|
||||
|
||||
mItems.clear();
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||
{
|
||||
ItemStack newItem (*it, this, it->getRefData().getCount());
|
||||
|
||||
if (mActor.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(mActor).getInventoryStore(mActor);
|
||||
for (int slot=0; slot<MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator equipped = store.getSlot(slot);
|
||||
if (equipped == store.end())
|
||||
continue;
|
||||
if (*equipped == newItem.mBase)
|
||||
newItem.mType = ItemStack::Type_Equipped;
|
||||
}
|
||||
}
|
||||
|
||||
mItems.push_back(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
31
apps/openmw/mwgui/inventoryitemmodel.hpp
Normal file
31
apps/openmw/mwgui/inventoryitemmodel.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef MWGUI_INVENTORY_ITEM_MODEL_H
|
||||
#define MWGUI_INVENTORY_ITEM_MODEL_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class InventoryItemModel : public ItemModel
|
||||
{
|
||||
public:
|
||||
InventoryItemModel (const MWWorld::Ptr& actor);
|
||||
|
||||
virtual ItemStack getItem (ModelIndex index);
|
||||
virtual ModelIndex getIndex (ItemStack item);
|
||||
virtual size_t getItemCount();
|
||||
|
||||
virtual void copyItem (const ItemStack& item, size_t count);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
MWWorld::Ptr mActor;
|
||||
private:
|
||||
std::vector<ItemStack> mItems;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,5 +1,7 @@
|
|||
#include "inventorywindow.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -9,22 +11,31 @@
|
|||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/action.hpp"
|
||||
|
||||
#include "bookwindow.hpp"
|
||||
#include "scrollwindow.hpp"
|
||||
#include "spellwindow.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "inventoryitemmodel.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
#include "tradeitemmodel.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
#include "container.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop)
|
||||
: ContainerBase(dragAndDrop)
|
||||
, WindowPinnableBase("openmw_inventory_window.layout")
|
||||
: WindowPinnableBase("openmw_inventory_window.layout")
|
||||
, mTrading(false)
|
||||
, mLastXSize(0)
|
||||
, mLastYSize(0)
|
||||
, mPreview(MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ())
|
||||
, mPreviewDirty(true)
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
|
||||
|
||||
|
@ -42,11 +53,14 @@ namespace MWGui
|
|||
|
||||
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
|
||||
|
||||
getWidget(mItemView, "ItemView");
|
||||
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||
mItemView->setModel(mSortModel);
|
||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &InventoryWindow::onItemSelected);
|
||||
mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &InventoryWindow::onBackgroundSelected);
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged);
|
||||
|
@ -57,23 +71,127 @@ namespace MWGui
|
|||
mFilterAll->setStateSelected(true);
|
||||
|
||||
setCoord(0, 342, 498, 258);
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
|
||||
mPreview.setup();
|
||||
}
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
openContainer(player);
|
||||
TradeItemModel* InventoryWindow::getTradeModel()
|
||||
{
|
||||
return mTradeModel;
|
||||
}
|
||||
|
||||
ItemModel* InventoryWindow::getModel()
|
||||
{
|
||||
return mTradeModel;
|
||||
}
|
||||
|
||||
void InventoryWindow::onBackgroundSelected()
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
mDragAndDrop->drop(mTradeModel, mItemView);
|
||||
}
|
||||
|
||||
void InventoryWindow::onItemSelected (int index)
|
||||
{
|
||||
onItemSelectedFromSourceModel (mSortModel->mapToSource(index));
|
||||
}
|
||||
|
||||
void InventoryWindow::onItemSelectedFromSourceModel (int index)
|
||||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
mDragAndDrop->drop(mTradeModel, mItemView);
|
||||
return;
|
||||
}
|
||||
|
||||
const ItemStack& item = mTradeModel->getItem(index);
|
||||
|
||||
unequipItem(item.mBase);
|
||||
|
||||
MWWorld::Ptr object = item.mBase;
|
||||
int count = item.mCount;
|
||||
bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
|
||||
if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
count = 1;
|
||||
|
||||
if (mTrading)
|
||||
{
|
||||
// check if merchant accepts item
|
||||
int services = MWBase::Environment::get().getWindowManager()->getTradeWindow()->getMerchantServices();
|
||||
if (!MWWorld::Class::get(object).canSell(object, services))
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sBarterDialog4}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 1 && !shift)
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
std::string message = mTrading ? "#{sQuanityMenuMessage01}" : "#{sTake}";
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
if (mTrading)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem);
|
||||
else
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dragItem);
|
||||
mSelectedItem = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelectedItem = index;
|
||||
if (mTrading)
|
||||
sellItem (NULL, count);
|
||||
else
|
||||
dragItem (NULL, count);
|
||||
}
|
||||
|
||||
// item might have been unequipped
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
void InventoryWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count);
|
||||
}
|
||||
|
||||
void InventoryWindow::sellItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
const ItemStack& item = mTradeModel->getItem(mSelectedItem);
|
||||
std::string sound = MWWorld::Class::get(item.mBase).getDownSoundId(item.mBase);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
if (item.mType == ItemStack::Type_Barter)
|
||||
{
|
||||
// this was an item borrowed to us by the merchant
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->returnItem(mSelectedItem, count);
|
||||
mTradeModel->returnItemBorrowedToUs(mSelectedItem, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
// borrow item to the merchant
|
||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->borrowItem(mSelectedItem, count);
|
||||
mTradeModel->borrowItemFromUs(mSelectedItem, count);
|
||||
}
|
||||
|
||||
mItemView->update();
|
||||
}
|
||||
|
||||
void InventoryWindow::updateItemView()
|
||||
{
|
||||
mItemView->update();
|
||||
mPreviewDirty = true;
|
||||
}
|
||||
|
||||
void InventoryWindow::open()
|
||||
{
|
||||
updateEncumbranceBar();
|
||||
|
||||
mTrading = false;
|
||||
mItemView->update();
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
drawItems();
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
|
@ -87,24 +205,24 @@ namespace MWGui
|
|||
|
||||
if (mMainWidget->getSize().width != mLastXSize || mMainWidget->getSize().height != mLastYSize)
|
||||
{
|
||||
drawItems();
|
||||
mLastXSize = mMainWidget->getSize().width;
|
||||
mLastYSize = mMainWidget->getSize().height;
|
||||
mPreviewDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
|
@ -112,6 +230,8 @@ namespace MWGui
|
|||
mFilterMagic->setStateSelected(false);
|
||||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
mItemView->update();
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
}
|
||||
|
||||
|
@ -124,23 +244,23 @@ namespace MWGui
|
|||
{
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::Ptr ptr = mDragAndDrop->mItem.mBase;
|
||||
mDragAndDrop->finish();
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
if (mDragAndDrop->mSourceModel != mTradeModel)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
ptr.getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
mDragAndDrop->mDraggedFrom->notifyItemDragged(ptr, -mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
ptr.getRefData().setCount(origCount);
|
||||
|
||||
/// \todo scripts
|
||||
mDragAndDrop->mSourceModel->removeItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount);
|
||||
ptr = *it;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
|
@ -153,12 +273,7 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->getBookWindow()->setTakeButtonShow(false);
|
||||
MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
|
||||
|
||||
drawItems();
|
||||
mItemView->update();
|
||||
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
@ -173,16 +288,15 @@ namespace MWGui
|
|||
if (itemSelected.isEmpty ())
|
||||
return;
|
||||
|
||||
for (unsigned int i=0; i < mContainerWidget->getChildCount (); ++i)
|
||||
for (size_t i=0; i < mTradeModel->getItemCount (); ++i)
|
||||
{
|
||||
MyGUI::Widget* w = mContainerWidget->getChildAt (i);
|
||||
|
||||
if (*w->getUserData<MWWorld::Ptr>() == itemSelected)
|
||||
if (mTradeModel->getItem(i).mBase == itemSelected)
|
||||
{
|
||||
onSelectedItem(w);
|
||||
onItemSelectedFromSourceModel(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Can't find clicked item");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +315,7 @@ namespace MWGui
|
|||
return MWWorld::Ptr();
|
||||
}
|
||||
|
||||
void InventoryWindow::_unequipItem(MWWorld::Ptr item)
|
||||
void InventoryWindow::unequipItem(const MWWorld::Ptr& item)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr);
|
||||
|
||||
|
@ -252,9 +366,9 @@ namespace MWGui
|
|||
return 0;
|
||||
}
|
||||
|
||||
void InventoryWindow::startTrade()
|
||||
void InventoryWindow::setTrading(bool trading)
|
||||
{
|
||||
mTrading = true;
|
||||
mTrading = trading;
|
||||
}
|
||||
|
||||
void InventoryWindow::doRenderUpdate ()
|
||||
|
@ -282,7 +396,7 @@ namespace MWGui
|
|||
if (weaponSlot == invStore.end())
|
||||
MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon();
|
||||
else
|
||||
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*weaponSlot); /// \todo track weapon durability
|
||||
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*weaponSlot);
|
||||
|
||||
mPreviewDirty = true;
|
||||
|
||||
|
@ -292,8 +406,6 @@ namespace MWGui
|
|||
|
||||
void InventoryWindow::pickUpObject (MWWorld::Ptr object)
|
||||
{
|
||||
/// \todo scripts
|
||||
|
||||
// make sure the object is of a type that can be picked up
|
||||
std::string type = object.getTypeName();
|
||||
if ( (type != typeid(ESM::Apparatus).name())
|
||||
|
@ -313,11 +425,9 @@ namespace MWGui
|
|||
if (MWWorld::Class::get(object).getName(object) == "") // objects without name presented to user can never be picked up
|
||||
return;
|
||||
|
||||
// sound
|
||||
std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
|
||||
MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1);
|
||||
|
||||
int count = object.getRefData().getCount();
|
||||
if (object.getCellRef().mGoldValue > 1)
|
||||
count = object.getCellRef().mGoldValue;
|
||||
|
||||
// add to player inventory
|
||||
// can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
|
||||
|
@ -326,31 +436,17 @@ namespace MWGui
|
|||
// remove from world
|
||||
MWBase::Environment::get().getWorld()->deleteObject (object);
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = true;
|
||||
mDragAndDrop->mDraggedCount = count;
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(newObject).getInventoryIcon(newObject);
|
||||
MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
|
||||
baseWidget->detachFromWidget();
|
||||
baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget);
|
||||
baseWidget->setUserData(newObject);
|
||||
mDragAndDrop->mDraggedWidget = baseWidget;
|
||||
MyGUI::ImageBox* image = baseWidget->createWidget<MyGUI::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));
|
||||
text->setCaption(getCountString(count));
|
||||
mDragAndDrop->mDraggedFrom = this;
|
||||
// get ModelIndex to the item
|
||||
mTradeModel->update();
|
||||
size_t i=0;
|
||||
for (; i<mTradeModel->getItemCount(); ++i)
|
||||
{
|
||||
if (mTradeModel->getItem(i).mBase == newObject)
|
||||
break;
|
||||
}
|
||||
if (i == mTradeModel->getItemCount())
|
||||
throw std::runtime_error("Added item not found");
|
||||
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
||||
}
|
||||
|
||||
MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord ()
|
||||
|
|
|
@ -3,13 +3,18 @@
|
|||
|
||||
#include "../mwrender/characterpreview.hpp"
|
||||
|
||||
#include "container.hpp"
|
||||
#include "windowpinnablebase.hpp"
|
||||
#include "widgets.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class InventoryWindow : public ContainerBase, public WindowPinnableBase
|
||||
class ItemView;
|
||||
class SortFilterItemModel;
|
||||
class TradeItemModel;
|
||||
class DragAndDrop;
|
||||
class ItemModel;
|
||||
|
||||
class InventoryWindow : public WindowPinnableBase
|
||||
{
|
||||
public:
|
||||
InventoryWindow(DragAndDrop* dragAndDrop);
|
||||
|
@ -19,7 +24,7 @@ namespace MWGui
|
|||
void doRenderUpdate();
|
||||
|
||||
/// start trading, disables item drag&drop
|
||||
void startTrade();
|
||||
void setTrading(bool trading);
|
||||
|
||||
void onFrame();
|
||||
|
||||
|
@ -35,8 +40,22 @@ namespace MWGui
|
|||
mPreview.rebuild();
|
||||
}
|
||||
|
||||
protected:
|
||||
TradeItemModel* getTradeModel();
|
||||
ItemModel* getModel();
|
||||
|
||||
void updateItemView();
|
||||
|
||||
private:
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
bool mPreviewDirty;
|
||||
size_t mSelectedItem;
|
||||
|
||||
MWWorld::Ptr mPtr;
|
||||
|
||||
MWGui::ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
TradeItemModel* mTradeModel;
|
||||
|
||||
MyGUI::Widget* mAvatar;
|
||||
MyGUI::ImageBox* mAvatarImage;
|
||||
|
@ -59,20 +78,22 @@ namespace MWGui
|
|||
|
||||
bool mTrading;
|
||||
|
||||
void onItemSelected(int index);
|
||||
void onItemSelectedFromSourceModel(int index);
|
||||
|
||||
void onBackgroundSelected();
|
||||
|
||||
void sellItem(MyGUI::Widget* sender, int count);
|
||||
void dragItem(MyGUI::Widget* sender, int count);
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onAvatarClicked(MyGUI::Widget* _sender);
|
||||
void onPinToggled();
|
||||
|
||||
void unequipItem(const MWWorld::Ptr& item);
|
||||
void updateEncumbranceBar();
|
||||
|
||||
virtual bool isTrading() { return mTrading; }
|
||||
virtual bool isInventory() { return true; }
|
||||
virtual void _unequipItem(MWWorld::Ptr item);
|
||||
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
|
||||
virtual void notifyContentChanged();
|
||||
void notifyContentChanged();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
98
apps/openmw/mwgui/itemmodel.cpp
Normal file
98
apps/openmw/mwgui/itemmodel.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include "itemmodel.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ItemStack::ItemStack(const MWWorld::Ptr &base, ItemModel *creator, size_t count)
|
||||
: mCreator(creator)
|
||||
, mCount(count)
|
||||
, mFlags(0)
|
||||
, mType(Type_Normal)
|
||||
, mBase(base)
|
||||
{
|
||||
assert(base.getContainerStore());
|
||||
|
||||
if (MWWorld::Class::get(base).getEnchantment(base) != "")
|
||||
mFlags |= Flag_Enchanted;
|
||||
}
|
||||
|
||||
ItemStack::ItemStack()
|
||||
: mCreator(NULL)
|
||||
, mCount(0)
|
||||
, mFlags(0)
|
||||
, mType(Type_Normal)
|
||||
{
|
||||
}
|
||||
|
||||
bool ItemStack::stacks(const ItemStack &other)
|
||||
{
|
||||
if(mBase == other.mBase)
|
||||
return true;
|
||||
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
||||
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||
}
|
||||
|
||||
bool operator == (const ItemStack& left, const ItemStack& right)
|
||||
{
|
||||
if (left.mType != right.mType)
|
||||
return false;
|
||||
if(left.mBase == right.mBase)
|
||||
return true;
|
||||
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
||||
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||
}
|
||||
|
||||
ItemModel::ItemModel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ProxyItemModel::~ProxyItemModel()
|
||||
{
|
||||
delete mSourceModel;
|
||||
}
|
||||
|
||||
void ProxyItemModel::copyItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
// no need to use mapToSource since itemIndex refers to an index in the sourceModel
|
||||
mSourceModel->copyItem (item, count);
|
||||
}
|
||||
|
||||
void ProxyItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
mSourceModel->removeItem (item, count);
|
||||
}
|
||||
|
||||
ItemModel::ModelIndex ProxyItemModel::mapToSource (ModelIndex index)
|
||||
{
|
||||
const ItemStack& itemToSearch = getItem(index);
|
||||
for (size_t i=0; i<mSourceModel->getItemCount(); ++i)
|
||||
{
|
||||
const ItemStack& item = mSourceModel->getItem(i);
|
||||
if (item == itemToSearch)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ItemModel::ModelIndex ProxyItemModel::mapFromSource (ModelIndex index)
|
||||
{
|
||||
const ItemStack& itemToSearch = mSourceModel->getItem(index);
|
||||
for (size_t i=0; i<getItemCount(); ++i)
|
||||
{
|
||||
const ItemStack& item = getItem(i);
|
||||
if (item == itemToSearch)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ItemModel::ModelIndex ProxyItemModel::getIndex (ItemStack item)
|
||||
{
|
||||
return mSourceModel->getIndex(item);
|
||||
}
|
||||
|
||||
}
|
84
apps/openmw/mwgui/itemmodel.hpp
Normal file
84
apps/openmw/mwgui/itemmodel.hpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef MWGUI_ITEM_MODEL_H
|
||||
#define MWGUI_ITEM_MODEL_H
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class ItemModel;
|
||||
|
||||
/// @brief A single item stack managed by an item model
|
||||
struct ItemStack
|
||||
{
|
||||
ItemStack (const MWWorld::Ptr& base, ItemModel* creator, size_t count);
|
||||
ItemStack();
|
||||
bool stacks (const ItemStack& other);
|
||||
///< like operator==, only without checking mType
|
||||
|
||||
enum Type
|
||||
{
|
||||
Type_Barter,
|
||||
Type_Equipped,
|
||||
Type_Normal
|
||||
};
|
||||
Type mType;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
Flag_Enchanted = (1<<0)
|
||||
};
|
||||
int mFlags;
|
||||
|
||||
ItemModel* mCreator;
|
||||
size_t mCount;
|
||||
MWWorld::Ptr mBase;
|
||||
};
|
||||
|
||||
bool operator == (const ItemStack& left, const ItemStack& right);
|
||||
|
||||
|
||||
/// @brief The base class that all item models should derive from.
|
||||
class ItemModel
|
||||
{
|
||||
public:
|
||||
ItemModel();
|
||||
virtual ~ItemModel() {}
|
||||
|
||||
typedef int ModelIndex;
|
||||
|
||||
virtual ItemStack getItem (ModelIndex index) = 0;
|
||||
///< throws for invalid index
|
||||
virtual size_t getItemCount() = 0;
|
||||
|
||||
virtual ModelIndex getIndex (ItemStack item) = 0;
|
||||
|
||||
virtual void update() = 0;
|
||||
|
||||
virtual void copyItem (const ItemStack& item, size_t count) = 0;
|
||||
virtual void removeItem (const ItemStack& item, size_t count) = 0;
|
||||
|
||||
private:
|
||||
ItemModel(const ItemModel&);
|
||||
ItemModel& operator=(const ItemModel&);
|
||||
};
|
||||
|
||||
/// @brief A proxy item model can be used to filter or rearrange items from a source model (or even add new items to it).
|
||||
/// The neat thing is that this does not actually alter the source model.
|
||||
class ProxyItemModel : public ItemModel
|
||||
{
|
||||
public:
|
||||
virtual ~ProxyItemModel();
|
||||
virtual void copyItem (const ItemStack& item, size_t count);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
virtual ModelIndex getIndex (ItemStack item);
|
||||
|
||||
ModelIndex mapToSource (ModelIndex index);
|
||||
ModelIndex mapFromSource (ModelIndex index);
|
||||
protected:
|
||||
ItemModel* mSourceModel;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,19 +1,17 @@
|
|||
#include "itemselection.hpp"
|
||||
|
||||
#include "itemview.hpp"
|
||||
#include "inventoryitemmodel.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ItemSelectionDialog::ItemSelectionDialog(const std::string &label, int filter)
|
||||
: ContainerBase(NULL)
|
||||
, WindowModal("openmw_itemselection_dialog.layout")
|
||||
ItemSelectionDialog::ItemSelectionDialog(const std::string &label)
|
||||
: WindowModal("openmw_itemselection_dialog.layout")
|
||||
{
|
||||
mFilter = filter;
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
getWidget(mItemView, "ItemView");
|
||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &ItemSelectionDialog::onSelectedItem);
|
||||
|
||||
MyGUI::TextBox* l;
|
||||
getWidget(l, "Label");
|
||||
|
@ -26,9 +24,29 @@ namespace MWGui
|
|||
center();
|
||||
}
|
||||
|
||||
void ItemSelectionDialog::onSelectedItemImpl(MWWorld::Ptr item)
|
||||
void ItemSelectionDialog::openContainer(const MWWorld::Ptr& container)
|
||||
{
|
||||
eventItemSelected(item);
|
||||
mModel = new InventoryItemModel(container);
|
||||
mSortModel = new SortFilterItemModel(mModel);
|
||||
mItemView->setModel(mSortModel);
|
||||
}
|
||||
|
||||
void ItemSelectionDialog::setCategory(int category)
|
||||
{
|
||||
mSortModel->setCategory(category);
|
||||
mItemView->update();
|
||||
}
|
||||
|
||||
void ItemSelectionDialog::setFilter(int filter)
|
||||
{
|
||||
mSortModel->setFilter(filter);
|
||||
mItemView->update();
|
||||
}
|
||||
|
||||
void ItemSelectionDialog::onSelectedItem(int index)
|
||||
{
|
||||
ItemStack item = mSortModel->getItem(index);
|
||||
eventItemSelected(item.mBase);
|
||||
}
|
||||
|
||||
void ItemSelectionDialog::onCancelButtonClicked(MyGUI::Widget* sender)
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
namespace MWGui
|
||||
{
|
||||
class ItemView;
|
||||
class SortFilterItemModel;
|
||||
class InventoryItemModel;
|
||||
|
||||
class ItemSelectionDialog : public ContainerBase, public WindowModal
|
||||
class ItemSelectionDialog : public WindowModal
|
||||
{
|
||||
public:
|
||||
ItemSelectionDialog(const std::string& label, int filter);
|
||||
ItemSelectionDialog(const std::string& label);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||
typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item;
|
||||
|
@ -14,11 +17,16 @@ namespace MWGui
|
|||
EventHandle_Item eventItemSelected;
|
||||
EventHandle_Void eventDialogCanceled;
|
||||
|
||||
void openContainer (const MWWorld::Ptr& container);
|
||||
void setCategory(int category);
|
||||
void setFilter(int filter);
|
||||
|
||||
private:
|
||||
virtual void onReferenceUnavailable() { ; }
|
||||
ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
InventoryItemModel* mModel;
|
||||
|
||||
virtual void onSelectedItemImpl(MWWorld::Ptr item);
|
||||
void onSelectedItem(int index);
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* sender);
|
||||
};
|
||||
|
|
200
apps/openmw/mwgui/itemview.cpp
Normal file
200
apps/openmw/mwgui/itemview.cpp
Normal file
|
@ -0,0 +1,200 @@
|
|||
#include "itemview.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <MyGUI_FactoryManager.h>
|
||||
#include <MyGUI_Gui.h>
|
||||
#include <MyGUI_ImageBox.h>
|
||||
#include <MyGUI_TextBox.h>
|
||||
#include <MyGUI_ScrollView.h>
|
||||
#include <MyGUI_Button.h>
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ItemView::ItemView()
|
||||
: mModel(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ItemView::~ItemView()
|
||||
{
|
||||
delete mModel;
|
||||
}
|
||||
|
||||
void ItemView::setModel(ItemModel *model)
|
||||
{
|
||||
delete mModel;
|
||||
mModel = model;
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemView::initialiseOverride()
|
||||
{
|
||||
Base::initialiseOverride();
|
||||
|
||||
assignWidget(mScrollView, "ScrollView");
|
||||
if (mScrollView == NULL)
|
||||
throw std::runtime_error("Item view needs a scroll view");
|
||||
|
||||
mScrollView->setCanvasAlign(MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
}
|
||||
|
||||
void ItemView::update()
|
||||
{
|
||||
while (mScrollView->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
|
||||
|
||||
if (!mModel)
|
||||
return;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int maxHeight = mScrollView->getSize().height - 58;
|
||||
|
||||
mModel->update();
|
||||
|
||||
MyGUI::Widget* dragArea = mScrollView->createWidget<MyGUI::Widget>("",0,0,mScrollView->getWidth(),mScrollView->getHeight(),
|
||||
MyGUI::Align::Stretch);
|
||||
dragArea->setNeedMouseFocus(true);
|
||||
dragArea->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedBackground);
|
||||
dragArea->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheel);
|
||||
|
||||
for (ItemModel::ModelIndex i=0; i<static_cast<int>(mModel->getItemCount()); ++i)
|
||||
{
|
||||
const ItemStack& item = mModel->getItem(i);
|
||||
|
||||
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(item.mBase).getInventoryIcon(item.mBase);
|
||||
|
||||
// background widget (for the "equipped" frame and magic item background image)
|
||||
bool isMagic = (item.mFlags & ItemStack::Flag_Enchanted);
|
||||
MyGUI::ImageBox* backgroundWidget = dragArea->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
MyGUI::IntCoord(x, y, 42, 42), MyGUI::Align::Default);
|
||||
backgroundWidget->setUserString("ToolTipType", "ItemModelIndex");
|
||||
backgroundWidget->setUserData(std::make_pair(i, mModel));
|
||||
|
||||
std::string backgroundTex = "textures\\menu_icon";
|
||||
if (isMagic)
|
||||
backgroundTex += "_magic";
|
||||
if (item.mType == ItemStack::Type_Normal)
|
||||
{
|
||||
if (!isMagic)
|
||||
backgroundTex = "";
|
||||
}
|
||||
else if (item.mType == ItemStack::Type_Equipped)
|
||||
backgroundTex += "_equip";
|
||||
else if (item.mType == ItemStack::Type_Barter)
|
||||
backgroundTex += "_barter";
|
||||
|
||||
if (backgroundTex != "")
|
||||
backgroundTex += ".dds";
|
||||
|
||||
backgroundWidget->setImageTexture(backgroundTex);
|
||||
if ((item.mType == ItemStack::Type_Barter) && !isMagic)
|
||||
backgroundWidget->setProperty("ImageCoord", "2 2 42 42");
|
||||
else
|
||||
backgroundWidget->setProperty("ImageCoord", "0 0 42 42");
|
||||
backgroundWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem);
|
||||
backgroundWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheel);
|
||||
|
||||
// image
|
||||
MyGUI::ImageBox* image = backgroundWidget->createWidget<MyGUI::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));
|
||||
text->setCaption(getCountString(item.mCount));
|
||||
|
||||
y += 42;
|
||||
if (y > maxHeight)
|
||||
{
|
||||
x += 42;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
x += 42;
|
||||
MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height);
|
||||
mScrollView->setCanvasSize(size);
|
||||
dragArea->setSize(size);
|
||||
}
|
||||
|
||||
void ItemView::onSelectedItem(MyGUI::Widget *sender)
|
||||
{
|
||||
ItemModel::ModelIndex index = (*sender->getUserData<std::pair<ItemModel::ModelIndex, ItemModel*> >()).first;
|
||||
eventItemClicked(index);
|
||||
}
|
||||
|
||||
void ItemView::onSelectedBackground(MyGUI::Widget *sender)
|
||||
{
|
||||
eventBackgroundClicked();
|
||||
}
|
||||
|
||||
void ItemView::onMouseWheel(MyGUI::Widget *_sender, int _rel)
|
||||
{
|
||||
if (mScrollView->getViewOffset().left + _rel*0.3 > 0)
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mScrollView->setViewOffset(MyGUI::IntPoint(mScrollView->getViewOffset().left + _rel*0.3, 0));
|
||||
}
|
||||
|
||||
void ItemView::setSize(const MyGUI::IntSize &_value)
|
||||
{
|
||||
Base::setSize(_value);
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemView::setSize(int _width, int _height)
|
||||
{
|
||||
Base::setSize(_width, _height);
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemView::setCoord(const MyGUI::IntCoord &_value)
|
||||
{
|
||||
Base::setCoord(_value);
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemView::setCoord(int _left, int _top, int _width, int _height)
|
||||
{
|
||||
Base::setCoord(_left, _top, _width, _height);
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemView::registerComponents()
|
||||
{
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ItemView>("Widget");
|
||||
}
|
||||
|
||||
}
|
52
apps/openmw/mwgui/itemview.hpp
Normal file
52
apps/openmw/mwgui/itemview.hpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef MWGUI_ITEMVIEW_H
|
||||
#define MWGUI_ITEMVIEW_H
|
||||
|
||||
#include <MyGUI_Widget.h>
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class ItemView : public MyGUI::Widget
|
||||
{
|
||||
MYGUI_RTTI_DERIVED(ItemView)
|
||||
public:
|
||||
ItemView();
|
||||
virtual ~ItemView();
|
||||
|
||||
/// Register needed components with MyGUI's factory manager
|
||||
static void registerComponents ();
|
||||
|
||||
/// Takes ownership of \a model
|
||||
void setModel (ItemModel* model);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate1<ItemModel::ModelIndex> EventHandle_ModelIndex;
|
||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||
/// Fired when an item was clicked
|
||||
EventHandle_ModelIndex eventItemClicked;
|
||||
/// Fired when the background was clicked (useful for drag and drop)
|
||||
EventHandle_Void eventBackgroundClicked;
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
virtual void initialiseOverride();
|
||||
|
||||
virtual void setSize(const MyGUI::IntSize& _value);
|
||||
virtual void setCoord(const MyGUI::IntCoord& _value);
|
||||
void setSize(int _width, int _height);
|
||||
void setCoord(int _left, int _top, int _width, int _height);
|
||||
|
||||
void onSelectedItem (MyGUI::Widget* sender);
|
||||
void onSelectedBackground (MyGUI::Widget* sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
ItemModel* mModel;
|
||||
MyGUI::ScrollView* mScrollView;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,6 +9,8 @@
|
|||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
|
|
55
apps/openmw/mwgui/pickpocketitemmodel.cpp
Normal file
55
apps/openmw/mwgui/pickpocketitemmodel.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "pickpocketitemmodel.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
|
||||
{
|
||||
mSourceModel = sourceModel;
|
||||
int chance = MWWorld::Class::get(thief).getNpcStats(thief).getSkill(ESM::Skill::Sneak).getModified();
|
||||
|
||||
mSourceModel->update();
|
||||
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
||||
{
|
||||
if (std::rand() / static_cast<float>(RAND_MAX) * 100 > chance)
|
||||
mHiddenItems.push_back(mSourceModel->getItem(i));
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack PickpocketItemModel::getItem (ModelIndex index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw std::runtime_error("Invalid index supplied");
|
||||
if (mItems.size() <= static_cast<size_t>(index))
|
||||
throw std::runtime_error("Item index out of range");
|
||||
return mItems[index];
|
||||
}
|
||||
|
||||
size_t PickpocketItemModel::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
void PickpocketItemModel::update()
|
||||
{
|
||||
mSourceModel->update();
|
||||
mItems.clear();
|
||||
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
||||
{
|
||||
const ItemStack& item = mSourceModel->getItem(i);
|
||||
if (std::find(mHiddenItems.begin(), mHiddenItems.end(), item) == mHiddenItems.end()
|
||||
&& item.mType != ItemStack::Type_Equipped)
|
||||
mItems.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
void PickpocketItemModel::removeItem (const ItemStack &item, size_t count)
|
||||
{
|
||||
ProxyItemModel::removeItem(item, count);
|
||||
/// \todo check if player is detected
|
||||
}
|
||||
|
||||
}
|
26
apps/openmw/mwgui/pickpocketitemmodel.hpp
Normal file
26
apps/openmw/mwgui/pickpocketitemmodel.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef MWGUI_PICKPOCKET_ITEM_MODEL_H
|
||||
#define MWGUI_PICKPOCKET_ITEM_MODEL_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
/// @brief The pickpocket item model randomly hides item stacks based on a specified chance. Equipped items are always hidden.
|
||||
class PickpocketItemModel : public ProxyItemModel
|
||||
{
|
||||
public:
|
||||
PickpocketItemModel (const MWWorld::Ptr& thief, ItemModel* sourceModel);
|
||||
virtual ItemStack getItem (ModelIndex index);
|
||||
virtual size_t getItemCount();
|
||||
virtual void update();
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
|
||||
private:
|
||||
std::vector<ItemStack> mHiddenItems;
|
||||
std::vector<ItemStack> mItems;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -120,13 +120,12 @@ namespace MWGui
|
|||
{
|
||||
if (!mItemSelectionDialog )
|
||||
{
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sQuickMenu6}", ContainerBase::Filter_All);
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sQuickMenu6}");
|
||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItem);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItemCancel);
|
||||
}
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->drawItems ();
|
||||
|
||||
mAssignDialog->setVisible (false);
|
||||
}
|
||||
|
@ -303,7 +302,7 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->getScrollWindow()->setTakeButtonShow(false);
|
||||
|
||||
// since we changed equipping status, update the inventory window
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||
}
|
||||
else if (type == Type_MagicItem)
|
||||
{
|
||||
|
@ -337,7 +336,7 @@ namespace MWGui
|
|||
action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ());
|
||||
|
||||
// since we changed equipping status, update the inventory window
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||
}
|
||||
|
||||
store.setSelectedEnchantItem(it);
|
||||
|
|
170
apps/openmw/mwgui/sortfilteritemmodel.cpp
Normal file
170
apps/openmw/mwgui/sortfilteritemmodel.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
#include "sortfilteritemmodel.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool compareType(const std::string& type1, const 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::Lockpick).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 compare (const MWGui::ItemStack& left, const MWGui::ItemStack& right)
|
||||
{
|
||||
if (left.mType != right.mType)
|
||||
return left.mType < right.mType;
|
||||
|
||||
if (left.mBase.getTypeName() == right.mBase.getTypeName())
|
||||
{
|
||||
int cmp = MWWorld::Class::get(left.mBase).getName(left.mBase).compare(
|
||||
MWWorld::Class::get(right.mBase).getName(right.mBase));
|
||||
return cmp < 0;
|
||||
}
|
||||
else
|
||||
return compareType(left.mBase.getTypeName(), right.mBase.getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
SortFilterItemModel::SortFilterItemModel(ItemModel *sourceModel)
|
||||
: mCategory(Category_All)
|
||||
, mShowEquipped(true)
|
||||
, mFilter(0)
|
||||
{
|
||||
mSourceModel = sourceModel;
|
||||
}
|
||||
|
||||
void SortFilterItemModel::addDragItem (const MWWorld::Ptr& dragItem, size_t count)
|
||||
{
|
||||
mDragItems.push_back(std::make_pair(dragItem, count));
|
||||
}
|
||||
|
||||
void SortFilterItemModel::clearDragItems()
|
||||
{
|
||||
mDragItems.clear();
|
||||
}
|
||||
|
||||
bool SortFilterItemModel::filterAccepts (const ItemStack& item)
|
||||
{
|
||||
MWWorld::Ptr base = item.mBase;
|
||||
|
||||
if (item.mType == ItemStack::Type_Equipped && !mShowEquipped)
|
||||
return false;
|
||||
|
||||
int category;
|
||||
if (base.getTypeName() == typeid(ESM::Armor).name()
|
||||
|| base.getTypeName() == typeid(ESM::Clothing).name())
|
||||
category = Category_Apparel;
|
||||
else if (base.getTypeName() == typeid(ESM::Weapon).name())
|
||||
category = Category_Weapon;
|
||||
else if (base.getTypeName() == typeid(ESM::Ingredient).name()
|
||||
|| base.getTypeName() == typeid(ESM::Potion).name())
|
||||
category = Category_Magic;
|
||||
else if (base.getTypeName() == typeid(ESM::Miscellaneous).name()
|
||||
|| base.getTypeName() == typeid(ESM::Ingredient).name()
|
||||
|| base.getTypeName() == typeid(ESM::Repair).name()
|
||||
|| base.getTypeName() == typeid(ESM::Lockpick).name()
|
||||
|| base.getTypeName() == typeid(ESM::Light).name()
|
||||
|| base.getTypeName() == typeid(ESM::Apparatus).name()
|
||||
|| base.getTypeName() == typeid(ESM::Book).name()
|
||||
|| base.getTypeName() == typeid(ESM::Probe).name())
|
||||
category = Category_Misc;
|
||||
|
||||
if (item.mFlags & ItemStack::Flag_Enchanted)
|
||||
category |= Category_Magic;
|
||||
|
||||
if (!(category & mCategory))
|
||||
return false;
|
||||
|
||||
if ((mFilter & Filter_OnlyIngredients) && base.getTypeName() != typeid(ESM::Ingredient).name())
|
||||
return false;
|
||||
if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted))
|
||||
return false;
|
||||
if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name()
|
||||
|| base.getCellRef().mSoul == ""))
|
||||
return false;
|
||||
if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted
|
||||
|| (base.getTypeName() != typeid(ESM::Armor).name()
|
||||
&& base.getTypeName() != typeid(ESM::Clothing).name()
|
||||
&& base.getTypeName() != typeid(ESM::Book).name())))
|
||||
return false;
|
||||
if ((mFilter & Filter_OnlyEnchantable) && base.getTypeName() == typeid(ESM::Book).name()
|
||||
&& !base.get<ESM::Book>()->mBase->mData.mIsScroll)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack SortFilterItemModel::getItem (ModelIndex index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw std::runtime_error("Invalid index supplied");
|
||||
if (mItems.size() <= static_cast<size_t>(index))
|
||||
throw std::runtime_error("Item index out of range");
|
||||
return mItems[index];
|
||||
}
|
||||
|
||||
size_t SortFilterItemModel::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
void SortFilterItemModel::setCategory (int category)
|
||||
{
|
||||
mCategory = category;
|
||||
}
|
||||
|
||||
void SortFilterItemModel::setFilter (int filter)
|
||||
{
|
||||
mFilter = filter;
|
||||
}
|
||||
|
||||
void SortFilterItemModel::update()
|
||||
{
|
||||
mSourceModel->update();
|
||||
|
||||
size_t count = mSourceModel->getItemCount();
|
||||
|
||||
mItems.clear();
|
||||
for (size_t i=0; i<count; ++i)
|
||||
{
|
||||
ItemStack item = mSourceModel->getItem(i);
|
||||
|
||||
for (std::vector<std::pair<MWWorld::Ptr, size_t> >::iterator it = mDragItems.begin(); it != mDragItems.end(); ++it)
|
||||
{
|
||||
if (item.mBase == it->first)
|
||||
{
|
||||
if (item.mCount < it->second)
|
||||
throw std::runtime_error("Dragging more than present in the model");
|
||||
item.mCount -= it->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (item.mCount > 0 && filterAccepts(item))
|
||||
mItems.push_back(item);
|
||||
}
|
||||
|
||||
std::sort(mItems.begin(), mItems.end(), compare);
|
||||
}
|
||||
|
||||
}
|
53
apps/openmw/mwgui/sortfilteritemmodel.hpp
Normal file
53
apps/openmw/mwgui/sortfilteritemmodel.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef MWGUI_SORT_FILTER_ITEM_MODEL_H
|
||||
#define MWGUI_SORT_FILTER_ITEM_MODEL_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class SortFilterItemModel : public ProxyItemModel
|
||||
{
|
||||
public:
|
||||
SortFilterItemModel (ItemModel* sourceModel);
|
||||
|
||||
virtual void update();
|
||||
|
||||
bool filterAccepts (const ItemStack& item);
|
||||
|
||||
virtual ItemStack getItem (ModelIndex index);
|
||||
virtual size_t getItemCount();
|
||||
|
||||
/// Dragged items are not displayed.
|
||||
void addDragItem (const MWWorld::Ptr& dragItem, size_t count);
|
||||
void clearDragItems();
|
||||
|
||||
void setCategory (int category);
|
||||
void setFilter (int filter);
|
||||
void setShowEquipped (bool show) { mShowEquipped = show; }
|
||||
|
||||
static const int Category_Weapon = (1<<1);
|
||||
static const int Category_Apparel = (1<<2);
|
||||
static const int Category_Misc = (1<<3);
|
||||
static const int Category_Magic = (1<<4);
|
||||
static const int Category_All = 255;
|
||||
|
||||
static const int Filter_OnlyIngredients = (1<<0);
|
||||
static const int Filter_OnlyEnchanted = (1<<1);
|
||||
static const int Filter_OnlyEnchantable = (1<<2);
|
||||
static const int Filter_OnlyChargedSoulstones = (1<<3);
|
||||
|
||||
|
||||
private:
|
||||
std::vector<ItemStack> mItems;
|
||||
|
||||
std::vector<std::pair<MWWorld::Ptr, size_t> > mDragItems;
|
||||
|
||||
int mCategory;
|
||||
int mFilter;
|
||||
bool mShowEquipped;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9,6 +9,7 @@
|
|||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ namespace MWGui
|
|||
action.execute (MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ());
|
||||
|
||||
// since we changed equipping status, update the inventory window
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems();
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||
}
|
||||
|
||||
store.setSelectedEnchantItem(it);
|
||||
|
|
|
@ -6,9 +6,13 @@
|
|||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "mapwindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -176,6 +180,16 @@ namespace MWGui
|
|||
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
|
||||
tooltipSize = getToolTipViaPtr(false);
|
||||
}
|
||||
else if (type == "ItemModelIndex")
|
||||
{
|
||||
std::pair<ItemModel::ModelIndex, ItemModel*> pair = *focus->getUserData<std::pair<ItemModel::ModelIndex, ItemModel*> >();
|
||||
mFocusObject = pair.second->getItem(pair.first).mBase;
|
||||
// HACK: To get the correct count for multiple item stack sources
|
||||
int oldCount = mFocusObject.getRefData().getCount();
|
||||
mFocusObject.getRefData().setCount(pair.second->getItem(pair.first).mCount);
|
||||
tooltipSize = getToolTipViaPtr(false);
|
||||
mFocusObject.getRefData().setCount(oldCount);
|
||||
}
|
||||
else if (type == "ToolTipInfo")
|
||||
{
|
||||
tooltipSize = createToolTip(*focus->getUserData<MWGui::ToolTipInfo>());
|
||||
|
|
198
apps/openmw/mwgui/tradeitemmodel.cpp
Normal file
198
apps/openmw/mwgui/tradeitemmodel.cpp
Normal file
|
@ -0,0 +1,198 @@
|
|||
#include "tradeitemmodel.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
TradeItemModel::TradeItemModel(ItemModel *sourceModel, const MWWorld::Ptr& merchant)
|
||||
: mMerchant(merchant)
|
||||
{
|
||||
mSourceModel = sourceModel;
|
||||
}
|
||||
|
||||
ItemStack TradeItemModel::getItem (ModelIndex index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw std::runtime_error("Invalid index supplied");
|
||||
if (mItems.size() <= static_cast<size_t>(index))
|
||||
throw std::runtime_error("Item index out of range");
|
||||
return mItems[index];
|
||||
}
|
||||
|
||||
size_t TradeItemModel::getItemCount()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
void TradeItemModel::borrowImpl(const ItemStack &item, std::vector<ItemStack> &out)
|
||||
{
|
||||
std::vector<ItemStack>::iterator it = out.begin();
|
||||
bool found = false;
|
||||
for (; it != out.end(); ++it)
|
||||
{
|
||||
if (it->stacks(item))
|
||||
{
|
||||
it->mCount += item.mCount;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
out.push_back(item);
|
||||
}
|
||||
|
||||
void TradeItemModel::unborrowImpl(const ItemStack &item, size_t count, std::vector<ItemStack> &out)
|
||||
{
|
||||
std::vector<ItemStack>::iterator it = out.begin();
|
||||
bool found = false;
|
||||
for (; it != out.end(); ++it)
|
||||
{
|
||||
if (it->stacks(item))
|
||||
{
|
||||
if (it->mCount < count)
|
||||
throw std::runtime_error("Not enough borrowed items to return");
|
||||
it->mCount -= count;
|
||||
if (it->mCount == 0)
|
||||
out.erase(it);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
throw std::runtime_error("Can't find borrowed item to return");
|
||||
}
|
||||
|
||||
void TradeItemModel::borrowItemFromUs (ModelIndex itemIndex, size_t count)
|
||||
{
|
||||
ItemStack item = getItem(itemIndex);
|
||||
item.mCount = count;
|
||||
borrowImpl(item, mBorrowedFromUs);
|
||||
}
|
||||
|
||||
void TradeItemModel::borrowItemToUs (ModelIndex itemIndex, ItemModel* source, size_t count)
|
||||
{
|
||||
ItemStack item = source->getItem(itemIndex);
|
||||
item.mCount = count;
|
||||
borrowImpl(item, mBorrowedToUs);
|
||||
}
|
||||
|
||||
void TradeItemModel::returnItemBorrowedToUs (ModelIndex itemIndex, size_t count)
|
||||
{
|
||||
ItemStack item = getItem(itemIndex);
|
||||
unborrowImpl(item, count, mBorrowedToUs);
|
||||
}
|
||||
|
||||
void TradeItemModel::returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count)
|
||||
{
|
||||
ItemStack item = source->getItem(itemIndex);
|
||||
unborrowImpl(item, count, mBorrowedFromUs);
|
||||
}
|
||||
|
||||
void TradeItemModel::abort()
|
||||
{
|
||||
mBorrowedFromUs.clear();
|
||||
mBorrowedToUs.clear();
|
||||
}
|
||||
|
||||
std::vector<ItemStack> TradeItemModel::getItemsBorrowedToUs()
|
||||
{
|
||||
return mBorrowedToUs;
|
||||
}
|
||||
|
||||
void TradeItemModel::transferItems()
|
||||
{
|
||||
std::vector<ItemStack>::iterator it = mBorrowedToUs.begin();
|
||||
for (; it != mBorrowedToUs.end(); ++it)
|
||||
{
|
||||
// get index in the source model
|
||||
ItemModel* sourceModel = it->mCreator;
|
||||
size_t i=0;
|
||||
for (; i<sourceModel->getItemCount(); ++i)
|
||||
{
|
||||
if (it->stacks(sourceModel->getItem(i)))
|
||||
break;
|
||||
}
|
||||
if (i == sourceModel->getItemCount())
|
||||
throw std::runtime_error("The borrowed item disappeared");
|
||||
|
||||
// reset owner before copying
|
||||
const ItemStack& item = sourceModel->getItem(i);
|
||||
std::string owner = item.mBase.getCellRef().mOwner;
|
||||
if (mMerchant.isEmpty()) // only for items bought by player
|
||||
item.mBase.getCellRef().mOwner = "";
|
||||
// copy the borrowed items to our model
|
||||
copyItem(item, it->mCount);
|
||||
item.mBase.getCellRef().mOwner = owner;
|
||||
// then remove them from the source model
|
||||
sourceModel->removeItem(item, it->mCount);
|
||||
}
|
||||
mBorrowedToUs.clear();
|
||||
mBorrowedFromUs.clear();
|
||||
}
|
||||
|
||||
void TradeItemModel::update()
|
||||
{
|
||||
mSourceModel->update();
|
||||
|
||||
int services = 0;
|
||||
if (!mMerchant.isEmpty())
|
||||
services = MWWorld::Class::get(mMerchant).getServices(mMerchant);
|
||||
|
||||
mItems.clear();
|
||||
// add regular items
|
||||
for (size_t i=0; i<mSourceModel->getItemCount(); ++i)
|
||||
{
|
||||
ItemStack item = mSourceModel->getItem(i);
|
||||
MWWorld::Ptr base = item.mBase;
|
||||
if (!mMerchant.isEmpty() && Misc::StringUtils::ciEqual(base.getCellRef().mRefID, "gold_001"))
|
||||
continue;
|
||||
if (!mMerchant.isEmpty() && !MWWorld::Class::get(base).canSell(base, services))
|
||||
continue;
|
||||
|
||||
// don't show equipped items
|
||||
if (mMerchant.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
bool isEquipped = false;
|
||||
MWWorld::InventoryStore& store = MWWorld::Class::get(mMerchant).getInventoryStore(mMerchant);
|
||||
for (int slot=0; slot<MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator equipped = store.getSlot(slot);
|
||||
if (equipped == store.end())
|
||||
continue;
|
||||
if (*equipped == base)
|
||||
isEquipped = true;
|
||||
}
|
||||
if (isEquipped)
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't show items that we borrowed to someone else
|
||||
std::vector<ItemStack>::iterator it = mBorrowedFromUs.begin();
|
||||
for (; it != mBorrowedFromUs.end(); ++it)
|
||||
{
|
||||
if (it->stacks(item))
|
||||
{
|
||||
if (item.mCount < it->mCount)
|
||||
throw std::runtime_error("Lent more items than present");
|
||||
item.mCount -= it->mCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (item.mCount > 0)
|
||||
mItems.push_back(item);
|
||||
}
|
||||
|
||||
// add items borrowed to us
|
||||
std::vector<ItemStack>::iterator it = mBorrowedToUs.begin();
|
||||
for (; it != mBorrowedToUs.end(); ++it)
|
||||
{
|
||||
ItemStack item = *it;
|
||||
item.mType = ItemStack::Type_Barter;
|
||||
mItems.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
53
apps/openmw/mwgui/tradeitemmodel.hpp
Normal file
53
apps/openmw/mwgui/tradeitemmodel.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef MWGUI_TRADE_ITEM_MODEL_H
|
||||
#define MWGUI_TRADE_ITEM_MODEL_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class ItemModel;
|
||||
|
||||
/// @brief An item model that allows 'borrowing' items from another item model. Used for previewing barter offers.
|
||||
/// Also filters items that the merchant does not sell.
|
||||
class TradeItemModel : public ProxyItemModel
|
||||
{
|
||||
public:
|
||||
TradeItemModel (ItemModel* sourceModel, const MWWorld::Ptr& merchant);
|
||||
|
||||
virtual ItemStack getItem (ModelIndex index);
|
||||
virtual size_t getItemCount();
|
||||
|
||||
virtual void update();
|
||||
|
||||
void borrowItemFromUs (ModelIndex itemIndex, size_t count);
|
||||
|
||||
void borrowItemToUs (ModelIndex itemIndex, ItemModel* source, size_t count);
|
||||
///< @note itemIndex points to an item in \a source
|
||||
|
||||
void returnItemBorrowedToUs (ModelIndex itemIndex, size_t count);
|
||||
|
||||
void returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count);
|
||||
|
||||
/// Permanently transfers items that were borrowed to us from another model to this model
|
||||
void transferItems ();
|
||||
/// Aborts trade
|
||||
void abort();
|
||||
|
||||
std::vector<ItemStack> getItemsBorrowedToUs();
|
||||
|
||||
private:
|
||||
void borrowImpl(const ItemStack& item, std::vector<ItemStack>& out);
|
||||
void unborrowImpl(const ItemStack& item, size_t count, std::vector<ItemStack>& out);
|
||||
|
||||
std::vector<ItemStack> mItems;
|
||||
|
||||
std::vector<ItemStack> mBorrowedToUs;
|
||||
std::vector<ItemStack> mBorrowedFromUs;
|
||||
|
||||
MWWorld::Ptr mMerchant;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -10,6 +10,8 @@
|
|||
#include "../mwbase/dialoguemanager.hpp"
|
||||
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
@ -17,28 +19,24 @@
|
|||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
#include "containeritemmodel.hpp"
|
||||
#include "tradeitemmodel.hpp"
|
||||
#include "countdialog.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
const float TradeWindow::sBalanceChangeInitialPause = 0.5;
|
||||
const float TradeWindow::sBalanceChangeInterval = 0.1;
|
||||
|
||||
TradeWindow::TradeWindow() :
|
||||
WindowBase("openmw_trade_window.layout")
|
||||
, ContainerBase(NULL) // no drag&drop
|
||||
TradeWindow::TradeWindow()
|
||||
: WindowBase("openmw_trade_window.layout")
|
||||
, mCurrentBalance(0)
|
||||
, mBalanceButtonsState(BBS_None)
|
||||
, mBalanceChangePause(0.0)
|
||||
, mItemToSell(-1)
|
||||
{
|
||||
// items the NPC is wearing should not be for trade
|
||||
mDisplayEquippedItems = false;
|
||||
|
||||
MyGUI::ScrollView* itemView;
|
||||
MyGUI::Widget* containerWidget;
|
||||
getWidget(containerWidget, "Items");
|
||||
getWidget(itemView, "ItemView");
|
||||
setWidgets(containerWidget, itemView);
|
||||
|
||||
getWidget(mFilterAll, "AllButton");
|
||||
getWidget(mFilterWeapon, "WeaponButton");
|
||||
getWidget(mFilterApparel, "ApparelButton");
|
||||
|
@ -56,6 +54,9 @@ namespace MWGui
|
|||
getWidget(mTotalBalanceLabel, "TotalBalanceLabel");
|
||||
getWidget(mBottomPane, "BottomPane");
|
||||
|
||||
getWidget(mItemView, "ItemView");
|
||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &TradeWindow::onItemSelected);
|
||||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onFilterChanged);
|
||||
|
@ -73,40 +74,40 @@ namespace MWGui
|
|||
mDecreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased);
|
||||
|
||||
setCoord(400, 0, 400, 300);
|
||||
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &TradeWindow::onWindowResize);
|
||||
}
|
||||
|
||||
void TradeWindow::startTrade(MWWorld::Ptr actor)
|
||||
void TradeWindow::startTrade(const MWWorld::Ptr& actor)
|
||||
{
|
||||
mPtr = actor;
|
||||
setTitle(MWWorld::Class::get(actor).getName(actor));
|
||||
|
||||
mCurrentBalance = 0;
|
||||
mCurrentMerchantOffer = 0;
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->startTrade();
|
||||
std::vector<MWWorld::Ptr> itemSources;
|
||||
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
|
||||
// Important: actor goes last, so that items purchased by the merchant go into his inventory
|
||||
itemSources.push_back(actor);
|
||||
|
||||
mBoughtItems.clear();
|
||||
|
||||
ContainerBase::openContainer(actor);
|
||||
mTradeModel = new TradeItemModel(new ContainerItemModel(itemSources), mPtr);
|
||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||
mItemView->setModel (mSortModel);
|
||||
|
||||
updateLabels();
|
||||
|
||||
drawItems();
|
||||
}
|
||||
|
||||
void TradeWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||
{
|
||||
if (_sender == mFilterAll)
|
||||
setFilter(ContainerBase::Filter_All);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_All);
|
||||
else if (_sender == mFilterWeapon)
|
||||
setFilter(ContainerBase::Filter_Weapon);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Weapon);
|
||||
else if (_sender == mFilterApparel)
|
||||
setFilter(ContainerBase::Filter_Apparel);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Apparel);
|
||||
else if (_sender == mFilterMagic)
|
||||
setFilter(ContainerBase::Filter_Magic);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Magic);
|
||||
else if (_sender == mFilterMisc)
|
||||
setFilter(ContainerBase::Filter_Misc);
|
||||
mSortModel->setCategory(SortFilterItemModel::Category_Misc);
|
||||
|
||||
mFilterAll->setStateSelected(false);
|
||||
mFilterWeapon->setStateSelected(false);
|
||||
|
@ -115,18 +116,91 @@ namespace MWGui
|
|||
mFilterMisc->setStateSelected(false);
|
||||
|
||||
static_cast<MyGUI::Button*>(_sender)->setStateSelected(true);
|
||||
|
||||
mItemView->update();
|
||||
}
|
||||
|
||||
void TradeWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
int TradeWindow::getMerchantServices()
|
||||
{
|
||||
drawItems();
|
||||
return MWWorld::Class::get(mPtr).getServices(mPtr);
|
||||
}
|
||||
|
||||
void TradeWindow::onItemSelected (int index)
|
||||
{
|
||||
const ItemStack& item = mSortModel->getItem(index);
|
||||
|
||||
MWWorld::Ptr object = item.mBase;
|
||||
int count = item.mCount;
|
||||
bool shift = MyGUI::InputManager::getInstance().isShiftPressed();
|
||||
if (MyGUI::InputManager::getInstance().isControlPressed())
|
||||
count = 1;
|
||||
|
||||
if (count > 1 && !shift)
|
||||
{
|
||||
CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog();
|
||||
std::string message = "#{sQuanityMenuMessage02}";
|
||||
dialog->open(MWWorld::Class::get(object).getName(object), message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &TradeWindow::sellItem);
|
||||
mItemToSell = mSortModel->mapToSource(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
mItemToSell = mSortModel->mapToSource(index);
|
||||
sellItem (NULL, count);
|
||||
}
|
||||
}
|
||||
|
||||
void TradeWindow::sellItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
const ItemStack& item = mTradeModel->getItem(mItemToSell);
|
||||
std::string sound = MWWorld::Class::get(item.mBase).getDownSoundId(item.mBase);
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
|
||||
TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel();
|
||||
|
||||
if (item.mType == ItemStack::Type_Barter)
|
||||
{
|
||||
// this was an item borrowed to us by the player
|
||||
mTradeModel->returnItemBorrowedToUs(mItemToSell, count);
|
||||
playerTradeModel->returnItemBorrowedFromUs(mItemToSell, mTradeModel, count);
|
||||
buyFromNpc(item.mBase, count, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// borrow item to player
|
||||
playerTradeModel->borrowItemToUs(mItemToSell, mTradeModel, count);
|
||||
mTradeModel->borrowItemFromUs(mItemToSell, count);
|
||||
buyFromNpc(item.mBase, count, false);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
|
||||
mItemView->update();
|
||||
}
|
||||
|
||||
void TradeWindow::borrowItem (int index, size_t count)
|
||||
{
|
||||
TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel();
|
||||
mTradeModel->borrowItemToUs(index, playerTradeModel, count);
|
||||
mItemView->update();
|
||||
sellToNpc(playerTradeModel->getItem(index).mBase, count, false);
|
||||
}
|
||||
|
||||
void TradeWindow::returnItem (int index, size_t count)
|
||||
{
|
||||
TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel();
|
||||
const ItemStack& item = playerTradeModel->getItem(index);
|
||||
mTradeModel->returnItemBorrowedFromUs(index, playerTradeModel, count);
|
||||
mItemView->update();
|
||||
sellToNpc(item.mBase, count, true);
|
||||
}
|
||||
|
||||
void TradeWindow::addOrRemoveGold(int amount)
|
||||
{
|
||||
bool goldFound = false;
|
||||
MWWorld::Ptr gold;
|
||||
MWWorld::ContainerStore& playerStore = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getContainerStore();
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = playerStore.begin();
|
||||
it != playerStore.end(); ++it)
|
||||
|
@ -167,13 +241,15 @@ namespace MWGui
|
|||
|
||||
void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
TradeItemModel* playerItemModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel();
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
// were there any items traded at all?
|
||||
MWWorld::ContainerStore& playerBought = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getBoughtItems();
|
||||
MWWorld::ContainerStore& merchantBought = getBoughtItems();
|
||||
if (playerBought.begin() == playerBought.end() && merchantBought.begin() == merchantBought.end())
|
||||
std::vector<ItemStack> playerBought = playerItemModel->getItemsBorrowedToUs();
|
||||
std::vector<ItemStack> merchantBought = mTradeModel->getItemsBorrowedToUs();
|
||||
if (!playerBought.size() && !merchantBought.size())
|
||||
{
|
||||
// user notification
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
|
@ -212,8 +288,10 @@ namespace MWGui
|
|||
int a = abs(mCurrentMerchantOffer);
|
||||
int b = abs(mCurrentBalance);
|
||||
int d = 0;
|
||||
if (mCurrentMerchantOffer<0) d = int(100 * (a - b) / a);
|
||||
else d = int(100 * (b - a) / a);
|
||||
if (mCurrentBalance<0)
|
||||
d = int(100 * (a - b) / a);
|
||||
else
|
||||
d = int(100 * (b - a) / a);
|
||||
|
||||
float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
|
||||
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()),100));
|
||||
|
@ -234,8 +312,10 @@ namespace MWGui
|
|||
float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
||||
float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
|
||||
float x = gmst.find("fBargainOfferMulti")->getFloat() * d + gmst.find("fBargainOfferBase")->getFloat();
|
||||
if (mCurrentMerchantOffer<0) x += abs(int(pcTerm - npcTerm));
|
||||
else x += abs(int(npcTerm - pcTerm));
|
||||
if (mCurrentBalance<0)
|
||||
x += abs(int(pcTerm - npcTerm));
|
||||
else
|
||||
x += abs(int(npcTerm - pcTerm));
|
||||
|
||||
int roll = std::rand()%100 + 1;
|
||||
if(roll > x) //trade refused
|
||||
|
@ -250,21 +330,14 @@ namespace MWGui
|
|||
|
||||
//skill use!
|
||||
MWWorld::Class::get(playerPtr).skillUsageSucceeded(playerPtr, ESM::Skill::Mercantile, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt();
|
||||
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterSuccessDisposition);
|
||||
|
||||
// success! make the item transfer.
|
||||
MWWorld::ContainerStore& playerBoughtItems =
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getBoughtItems();
|
||||
for (MWWorld::ContainerStoreIterator it = playerBoughtItems.begin(); it != playerBoughtItems.end(); ++it)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(it->getCellRef().mOwner, MWWorld::Class::get(mPtr).getId(mPtr)))
|
||||
it->getCellRef().mOwner = "";
|
||||
}
|
||||
transferBoughtItems();
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->transferBoughtItems();
|
||||
// make the item transfer
|
||||
mTradeModel->transferItems();
|
||||
playerItemModel->transferItems();
|
||||
|
||||
// add or remove gold from the player.
|
||||
if (mCurrentBalance != 0)
|
||||
|
@ -278,11 +351,8 @@ namespace MWGui
|
|||
|
||||
void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
|
||||
{
|
||||
// i give you back your stuff!
|
||||
returnBoughtItems(MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getContainerStore());
|
||||
// now gimme back my stuff!
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mPtr).getContainerStore(mPtr));
|
||||
|
||||
mTradeModel->abort();
|
||||
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel()->abort();
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Barter);
|
||||
}
|
||||
|
||||
|
@ -343,44 +413,7 @@ namespace MWGui
|
|||
mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(getMerchantGold()));
|
||||
}
|
||||
|
||||
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001"))
|
||||
return false;
|
||||
|
||||
int services = 0;
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>();
|
||||
if (ref->mBase->mHasAI)
|
||||
services = ref->mBase->mAiData.mServices;
|
||||
}
|
||||
else if (mPtr.getTypeName() == typeid(ESM::Creature).name())
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>();
|
||||
if (ref->mBase->mHasAI)
|
||||
services = ref->mBase->mAiData.mServices;
|
||||
}
|
||||
|
||||
return MWWorld::Class::get(item).canSell(item, services);
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore()
|
||||
{
|
||||
std::vector<MWWorld::Ptr> items;
|
||||
MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
|
||||
|
||||
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, bool boughtItem)
|
||||
void TradeWindow::sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem)
|
||||
{
|
||||
int diff = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count, boughtItem);
|
||||
|
||||
|
@ -390,7 +423,7 @@ namespace MWGui
|
|||
updateLabels();
|
||||
}
|
||||
|
||||
void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count, bool soldItem)
|
||||
void TradeWindow::buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem)
|
||||
{
|
||||
int diff = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count, !soldItem);
|
||||
|
||||
|
|
|
@ -17,23 +17,32 @@ namespace MWGui
|
|||
|
||||
namespace MWGui
|
||||
{
|
||||
class TradeWindow : public ContainerBase, public WindowBase
|
||||
class ItemView;
|
||||
class SortFilterItemModel;
|
||||
class TradeItemModel;
|
||||
|
||||
class TradeWindow : public WindowBase, public ReferenceInterface
|
||||
{
|
||||
public:
|
||||
TradeWindow();
|
||||
|
||||
void startTrade(MWWorld::Ptr actor);
|
||||
|
||||
void sellToNpc(MWWorld::Ptr item, int count, bool boughtItem); ///< only used for adjusting the gold balance
|
||||
void buyFromNpc(MWWorld::Ptr item, int count, bool soldItem); ///< only used for adjusting the gold balance
|
||||
|
||||
bool npcAcceptsItem(MWWorld::Ptr item);
|
||||
void startTrade(const MWWorld::Ptr& actor);
|
||||
|
||||
void addOrRemoveGold(int gold);
|
||||
|
||||
void onFrame(float frameDuration);
|
||||
|
||||
protected:
|
||||
void borrowItem (int index, size_t count);
|
||||
void returnItem (int index, size_t count);
|
||||
|
||||
int getMerchantServices();
|
||||
|
||||
|
||||
private:
|
||||
ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
TradeItemModel* mTradeModel;
|
||||
|
||||
static const float sBalanceChangeInitialPause; // in seconds
|
||||
static const float sBalanceChangeInterval; // in seconds
|
||||
|
||||
|
@ -56,6 +65,8 @@ namespace MWGui
|
|||
MyGUI::TextBox* mPlayerGold;
|
||||
MyGUI::TextBox* mMerchantGold;
|
||||
|
||||
int mItemToSell;
|
||||
|
||||
int mCurrentBalance;
|
||||
int mCurrentMerchantOffer;
|
||||
|
||||
|
@ -67,7 +78,12 @@ namespace MWGui
|
|||
/// pause before next balance change will trigger while user holds +/- button pressed
|
||||
float mBalanceChangePause;
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance
|
||||
void buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance
|
||||
|
||||
void onItemSelected (int index);
|
||||
void sellItem (MyGUI::Widget* sender, int count);
|
||||
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
void onOfferButtonClicked(MyGUI::Widget* _sender);
|
||||
void onCancelButtonClicked(MyGUI::Widget* _sender);
|
||||
|
@ -79,16 +95,10 @@ namespace MWGui
|
|||
void onIncreaseButtonTriggered();
|
||||
void onDecreaseButtonTriggered();
|
||||
|
||||
virtual bool isTrading() { return true; }
|
||||
virtual bool isTradeWindow() { return true; }
|
||||
|
||||
virtual std::vector<MWWorld::Ptr> itemsToIgnore();
|
||||
|
||||
void updateLabels();
|
||||
|
||||
virtual void onReferenceUnavailable();
|
||||
|
||||
private:
|
||||
int getMerchantGold();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "../mwbase/inputmanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "console.hpp"
|
||||
#include "journalwindow.hpp"
|
||||
#include "journalviewmodel.hpp"
|
||||
|
@ -39,6 +41,7 @@
|
|||
#include "companionwindow.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "bookpage.hpp"
|
||||
#include "itemview.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -123,6 +126,7 @@ namespace MWGui
|
|||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollView>("Widget");
|
||||
BookPage::registerMyGUIComponents ();
|
||||
ItemView::registerComponents();
|
||||
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
|
||||
MyGUI::ResourceManager::getInstance().load("core.xml");
|
||||
|
@ -302,6 +306,7 @@ namespace MWGui
|
|||
mMerchantRepair->setVisible(false);
|
||||
mRepair->setVisible(false);
|
||||
mCompanionWindow->setVisible(false);
|
||||
mInventoryWindow->setTrading(false);
|
||||
|
||||
mHud->setVisible(mHudEnabled);
|
||||
|
||||
|
@ -411,6 +416,7 @@ namespace MWGui
|
|||
break;
|
||||
case GM_Barter:
|
||||
mInventoryWindow->setVisible(true);
|
||||
mInventoryWindow->setTrading(true);
|
||||
mTradeWindow->setVisible(true);
|
||||
break;
|
||||
case GM_SpellBuying:
|
||||
|
@ -584,18 +590,21 @@ namespace MWGui
|
|||
mGarbageDialogs.push_back(dialog);
|
||||
}
|
||||
|
||||
void WindowManager::messageBox (const std::string& message, const std::vector<std::string>& buttons)
|
||||
void WindowManager::messageBox (const std::string& message, const std::vector<std::string>& buttons, bool showInDialogueModeOnly)
|
||||
{
|
||||
if(buttons.empty()){
|
||||
if (buttons.empty()) {
|
||||
/* If there are no buttons, and there is a dialogue window open, messagebox goes to the dialogue window */
|
||||
if(!mGuiModes.empty() && mGuiModes.back() == GM_Dialogue)
|
||||
if (getMode() == GM_Dialogue) {
|
||||
mDialogueWindow->addMessageBox(MyGUI::LanguageManager::getInstance().replaceTags(message));
|
||||
else
|
||||
mMessageBoxManager->createMessageBox(message);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (showInDialogueModeOnly) {
|
||||
if (getMode() == GM_Dialogue)
|
||||
mMessageBoxManager->createMessageBox(message);
|
||||
} else {
|
||||
mMessageBoxManager->createMessageBox(message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mMessageBoxManager->createInteractiveMessageBox(message, buttons);
|
||||
MWBase::Environment::get().getInputManager()->changeInputMode(isGuiMode());
|
||||
}
|
||||
|
@ -632,17 +641,6 @@ namespace MWGui
|
|||
return default_;
|
||||
}
|
||||
|
||||
void WindowManager::onDialogueWindowBye()
|
||||
{
|
||||
if (mDialogueWindow)
|
||||
{
|
||||
//FIXME set some state and stuff?
|
||||
//removeDialog(dialogueWindow);
|
||||
mDialogueWindow->setVisible(false);
|
||||
}
|
||||
removeGuiMode(GM_Dialogue);
|
||||
}
|
||||
|
||||
void WindowManager::onFrame (float frameDuration)
|
||||
{
|
||||
mMessageBoxManager->onFrame(frameDuration);
|
||||
|
@ -677,6 +675,7 @@ namespace MWGui
|
|||
mContainerWindow->checkReferenceAvailable();
|
||||
mCompanionWindow->checkReferenceAvailable();
|
||||
mConsole->checkReferenceAvailable();
|
||||
mCompanionWindow->onFrame();
|
||||
}
|
||||
|
||||
void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace MWGui
|
|||
|
||||
virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
|
||||
|
||||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>());
|
||||
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>(), bool showInDialogueModeOnly = false);
|
||||
virtual void staticMessageBox(const std::string& message);
|
||||
virtual void removeStaticMessageBox();
|
||||
virtual void enterPressed ();
|
||||
|
@ -327,8 +327,6 @@ namespace MWGui
|
|||
unsigned int mTriangleCount;
|
||||
unsigned int mBatchCount;
|
||||
|
||||
void onDialogueWindowBye();
|
||||
|
||||
/**
|
||||
* Called when MyGUI tries to retrieve a tag. This usually corresponds to a GMST string,
|
||||
* so this method will retrieve the GMST with the name \a _tag and place the result in \a _result
|
||||
|
|
|
@ -181,11 +181,10 @@ namespace MWScript
|
|||
runtime.pop();
|
||||
|
||||
std::vector<int> idleList;
|
||||
idleList.push_back (0); // why MW, why?
|
||||
|
||||
for (int i=2; i<10 && arg0; ++i)
|
||||
{
|
||||
Interpreter::Type_Integer idleValue = runtime[0].mFloat;
|
||||
Interpreter::Type_Integer idleValue = runtime[0].mInteger;
|
||||
idleList.push_back(idleValue);
|
||||
runtime.pop();
|
||||
--arg0;
|
||||
|
|
|
@ -66,8 +66,8 @@ namespace MWScript
|
|||
|
||||
MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr());
|
||||
|
||||
// Spawn a messagebox (only for items added to player's inventory)
|
||||
if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer())
|
||||
// Spawn a messagebox (only for items added to player's inventory and if player is talking to someone)
|
||||
if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer() )
|
||||
{
|
||||
// The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory
|
||||
std::string msgBox;
|
||||
|
@ -82,8 +82,8 @@ namespace MWScript
|
|||
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage61}");
|
||||
msgBox = boost::str(boost::format(msgBox) % count % itemName);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(msgBox);
|
||||
std::vector <std::string> noButtons;
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(msgBox, noButtons, /*showInDialogueModeOnly*/ true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -161,12 +161,15 @@ namespace MWScript
|
|||
}
|
||||
}
|
||||
|
||||
// Spawn a messagebox (only for items added to player's inventory)
|
||||
// Spawn a messagebox (only for items removed from player's inventory)
|
||||
if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer())
|
||||
{
|
||||
// The two GMST entries below expand to strings informing the player of what, and how many of it has been removed from their inventory
|
||||
std::string msgBox;
|
||||
int numRemoved = (originalCount - count);
|
||||
if (numRemoved == 0)
|
||||
return;
|
||||
|
||||
if(numRemoved > 1)
|
||||
{
|
||||
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage63}");
|
||||
|
@ -177,9 +180,8 @@ namespace MWScript
|
|||
msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage62}");
|
||||
msgBox = boost::str (boost::format(msgBox) % itemName);
|
||||
}
|
||||
|
||||
if (numRemoved > 0)
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(msgBox);
|
||||
std::vector <std::string> noButtons;
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(msgBox, noButtons, /*showInDialogueModeOnly*/ true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,6 +52,11 @@ namespace MWWorld
|
|||
return false;
|
||||
}
|
||||
|
||||
int Class::getServices(const Ptr &actor) const
|
||||
{
|
||||
throw std::runtime_error ("class does not have services");
|
||||
}
|
||||
|
||||
MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("class does not have creature stats");
|
||||
|
@ -172,6 +177,11 @@ namespace MWWorld
|
|||
throw std::runtime_error ("capacity not supported by this class");
|
||||
}
|
||||
|
||||
float Class::getWeight(const Ptr &ptr) const
|
||||
{
|
||||
throw std::runtime_error ("weight not supported by this class");
|
||||
}
|
||||
|
||||
float Class::getEncumbrance (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("encumbrance not supported by class");
|
||||
|
|
|
@ -241,6 +241,8 @@ namespace MWWorld
|
|||
virtual bool canSell (const MWWorld::Ptr& item, int npcServices) const;
|
||||
///< Determine whether or not \a item can be sold to an npc with the given \a npcServices
|
||||
|
||||
virtual int getServices (const MWWorld::Ptr& actor) const;
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual void applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
@ -249,6 +251,8 @@ namespace MWWorld
|
|||
///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that.
|
||||
/// Second item in the pair specifies the error message
|
||||
|
||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual Ptr
|
||||
copyToCell(const Ptr &ptr, CellStore &cell) const;
|
||||
|
||||
|
|
|
@ -60,8 +60,8 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
|
|||
{
|
||||
/// \todo add current enchantment charge here when it is implemented
|
||||
if ( ptr1.mCellRef->mRefID == ptr2.mCellRef->mRefID
|
||||
&& MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks
|
||||
&& MWWorld::Class::get(ptr1).getEnchantment(ptr1) == "" // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier)
|
||||
&& MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks
|
||||
&& MWWorld::Class::get(ptr1).getEnchantment(ptr1) == "" // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier)
|
||||
&& ptr1.mCellRef->mOwner == ptr2.mCellRef->mOwner
|
||||
&& ptr1.mCellRef->mSoul == ptr2.mCellRef->mSoul
|
||||
// item that is already partly used up never stacks
|
||||
|
|
|
@ -79,11 +79,10 @@ namespace MWWorld
|
|||
ContainerStoreIterator addImpl (const Ptr& ptr);
|
||||
///< Add the item to this container (no stacking)
|
||||
|
||||
public:
|
||||
|
||||
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);
|
||||
///< @return true if the two specified objects can stack with each other
|
||||
/// @note ptr1 is the item that is already in this container
|
||||
|
||||
public:
|
||||
|
||||
void fill (const ESM::InventoryList& items, const std::string& owner, const MWWorld::ESMStore& store);
|
||||
///< Insert items into *this.
|
||||
|
|
|
@ -276,6 +276,8 @@ bool MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
|
|||
{
|
||||
if (*iter != end() && ptr1 == **iter)
|
||||
return false;
|
||||
if (*iter != end() && ptr2 == **iter)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -90,8 +90,6 @@ namespace MWWorld
|
|||
///< \attention This function is internal to the world model and should not be called from
|
||||
/// outside.
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool stacks (const Ptr& ptr1, const Ptr& ptr2);
|
||||
///< @return true if the two specified objects can stack with each other
|
||||
/// @note ptr1 is the item that is already in this container
|
||||
|
|
|
@ -68,11 +68,12 @@ float WeatherManager::calculateHourFade (const std::string& moonName) const
|
|||
float fadeOutStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Out_Start");
|
||||
float fadeInStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Start");
|
||||
float fadeInFinish=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Finish");
|
||||
float fadeOutFinish=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Out_Finish");
|
||||
|
||||
if (mHour >= fadeOutStart && mHour <= fadeInStart)
|
||||
return (1 - (mHour - fadeOutStart));
|
||||
if (mHour >= fadeOutStart && mHour <= fadeOutFinish)
|
||||
return (1 / (mHour - fadeOutStart));
|
||||
else if (mHour >= fadeInStart && mHour <= fadeInFinish)
|
||||
return (mHour - fadeInStart);
|
||||
return (1 / (mHour - fadeInStart));
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
@ -82,7 +83,7 @@ float WeatherManager::calculateAngleFade (const std::string& moonName, float ang
|
|||
float endAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_End_Angle");
|
||||
float startAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Start_Angle");
|
||||
if (angle >= endAngle && angle <= startAngle)
|
||||
return (angle - endAngle);
|
||||
return ((angle - endAngle)/(startAngle-endAngle));
|
||||
else if (angle < endAngle)
|
||||
return 0.f;
|
||||
else
|
||||
|
@ -430,7 +431,7 @@ void WeatherManager::update(float duration)
|
|||
else //if (mHour > 0 && mHour < 6)
|
||||
height = 1 - (mHour / mSunriseTime);
|
||||
|
||||
int facing = (mHour > dayDuration) ? 1 : -1;
|
||||
int facing = (mHour > 13.f) ? 1 : -1;
|
||||
|
||||
Vector3 final(
|
||||
-(1 - height) * facing,
|
||||
|
|
|
@ -1653,4 +1653,22 @@ namespace MWWorld
|
|||
else
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
void World::getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out)
|
||||
{
|
||||
std::string refId = npc.getCellRef().mRefID;
|
||||
|
||||
const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells();
|
||||
for (Scene::CellStoreCollection::const_iterator cellIt = collection.begin(); cellIt != collection.end(); ++cellIt)
|
||||
{
|
||||
MWWorld::CellRefList<ESM::Container>& containers = (*cellIt)->mContainers;
|
||||
CellRefList<ESM::Container>::List& refList = containers.mList;
|
||||
for (CellRefList<ESM::Container>::List::iterator container = refList.begin(); container != refList.end(); ++container)
|
||||
{
|
||||
MWWorld::Ptr ptr (&*container, *cellIt);
|
||||
if (Misc::StringUtils::ciEqual(ptr.getCellRef().mOwner, npc.getCellRef().mRefID))
|
||||
out.push_back(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -390,6 +390,9 @@ namespace MWWorld
|
|||
virtual bool getActorStandingOn (const MWWorld::Ptr& object); ///< @return true if any actor is standing on \a object
|
||||
virtual float getWindSpeed();
|
||||
|
||||
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out);
|
||||
///< get all containers in active cells owned by this Npc
|
||||
|
||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||
|
||||
virtual int canRest();
|
||||
|
|
|
@ -372,7 +372,18 @@ namespace Compiler
|
|||
else if (c==')')
|
||||
special = S_close;
|
||||
else if (c=='.')
|
||||
{
|
||||
// check, if this starts a float literal
|
||||
if (get (c))
|
||||
{
|
||||
putback (c);
|
||||
|
||||
if (std::isdigit (c))
|
||||
return scanFloat ("", parser, cont);
|
||||
}
|
||||
|
||||
special = S_member;
|
||||
}
|
||||
else if (c=='=')
|
||||
{
|
||||
if (get (c))
|
||||
|
|
|
@ -59,11 +59,7 @@
|
|||
</Widget>
|
||||
|
||||
<!-- Available ingredients -->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 126 247 238" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 239 230" name="ItemView" align="Left Top Stretch">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Widget type="Button" skin="" name="Items" position="0 0 239 230" name="Items" align="Left Top Stretch"/>
|
||||
</Widget>
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="8 126 247 238" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<!-- Created effects -->
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
<Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 600 300" name="_Main">
|
||||
|
||||
<!-- Items -->
|
||||
<Widget type="Widget" skin="MW_Box" position="5 5 575 225" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 567 217" name="ItemView" align="Left Top Stretch">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Widget type="Button" skin="" name="Items" position="0 0 567 217" name="Items" align="Left Top Stretch"/>
|
||||
</Widget>
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="5 5 575 225" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<Widget type="HBox" position="5 235 575 24" align="Bottom HStretch">
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
<Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 600 300" name="_Main">
|
||||
|
||||
<!-- Items -->
|
||||
<Widget type="Widget" skin="MW_Box" position="5 5 575 225" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 567 217" name="ItemView" align="Left Top Stretch">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Widget type="Button" skin="" name="Items" position="0 0 567 217" name="Items" align="Left Top Stretch"/>
|
||||
</Widget>
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="5 5 575 225" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<Widget type="HBox" position="0 235 580 24" align="Right Bottom">
|
||||
|
|
|
@ -25,11 +25,7 @@
|
|||
<Widget type="Widget" skin="" position="228 0 350 223" align="Left Top" name="RightPane">
|
||||
|
||||
<!-- Items in inventory -->
|
||||
<Widget type="Widget" skin="MW_Box" position="0 38 350 185" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 342 177" align="Left Top Stretch" name="ItemView">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Widget type="Button" skin="" name="Items" position="0 0 342 177" name="Items" align="Left Top Stretch"/>
|
||||
</Widget>
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="0 38 350 185" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<!-- Categories -->
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
|
||||
<Widget type="TextBox" skin="SandText" position="8 8 300 18" name="Label"/>
|
||||
|
||||
<Widget type="Widget" skin="MW_Box" position="8 34 355 70" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 347 62" name="ItemView" align="Left Top Stretch">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Widget type="Button" skin="" name="Items" position="0 0 347 62" name="Items" align="Left Top Stretch"/>
|
||||
</Widget>
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="8 34 355 70" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="340 110 24 24" name="CancelButton">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<Layer name="Console" overlapped="false" peek="true"/>
|
||||
<Layer name="Notification" overlapped="false" peek="false"/>
|
||||
<Layer name="Popup" overlapped="true" peek="true"/>
|
||||
<Layer name="DragAndDrop" overlapped="false" peek="true"/>
|
||||
<Layer name="DragAndDrop" overlapped="false" peek="false"/>
|
||||
<Layer name="LoadingScreen" overlapped="false" peek="true"/>
|
||||
<Layer name="Pointer" overlapped="false" peek="false"/>
|
||||
</MyGUI>
|
||||
|
|
|
@ -126,6 +126,15 @@
|
|||
|
||||
</Skin>
|
||||
|
||||
<Skin name="MW_ItemView" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
|
||||
<Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
|
||||
|
||||
<Child type="ScrollView" skin="MW_ScrollViewH" offset="3 3 509 509" align="ALIGN_STRETCH" name="ScrollView">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Property key="NeedMouse" value="true"/>
|
||||
</Child>
|
||||
</Skin>
|
||||
|
||||
<Skin name="MW_SimpleList" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
|
||||
|
||||
<Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
|
||||
|
|
|
@ -24,11 +24,7 @@
|
|||
</Widget>
|
||||
|
||||
<!-- Items -->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 38 566 185" name="box" align="Left Top Stretch">
|
||||
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 558 181" align="Left Top Stretch" name="ItemView">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
<Widget type="Button" skin="" name="Items" position="0 0 558 181" name="Items" align="Left Top Stretch"/>
|
||||
</Widget>
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="8 38 566 185" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<Widget type="Widget" skin="" position="8 231 566 92" name="BottomPane" align="Left Bottom HStretch">
|
||||
|
|
|
@ -612,10 +612,13 @@ namespace Physic
|
|||
|
||||
float d1 = 10000.;
|
||||
btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to);
|
||||
if(raycastingObjectOnly) resultCallback1.m_collisionFilterMask = CollisionType_Raycasting;
|
||||
else resultCallback1.m_collisionFilterMask = CollisionType_World;
|
||||
if(raycastingObjectOnly)
|
||||
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting;
|
||||
else
|
||||
resultCallback1.m_collisionFilterMask = CollisionType_World;
|
||||
|
||||
if(!ignoreHeightMap) resultCallback1.m_collisionFilterMask = resultCallback1.m_collisionFilterMask|| CollisionType_HeightMap;
|
||||
if(!ignoreHeightMap)
|
||||
resultCallback1.m_collisionFilterMask = resultCallback1.m_collisionFilterMask | CollisionType_HeightMap;
|
||||
dynamicsWorld->rayTest(from, to, resultCallback1);
|
||||
if (resultCallback1.hasHit())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue