using items via the inventory is now possible by dragging them on the avatar (only implemented for books right now)

This commit is contained in:
scrawl 2012-05-15 18:05:53 +02:00
parent b18ee198b4
commit ab6336b745
15 changed files with 144 additions and 35 deletions

View file

@ -437,25 +437,11 @@ void OMW::Engine::activate()
return; return;
} }
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
boost::shared_ptr<MWWorld::Action> action = boost::shared_ptr<MWWorld::Action> action =
MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
interpreterContext.activate (ptr, action); // execute action and script
MWBase::Environment::get().getWorld()->executeActionScript(ptr, action);
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
if (!script.empty())
{
MWBase::Environment::get().getWorld()->getLocalScripts().setIgnore (ptr);
MWBase::Environment::get().getScriptManager()->run (script, interpreterContext);
}
if (!interpreterContext.hasActivationBeenHandled())
{
interpreterContext.executeActivation();
}
} }
void OMW::Engine::screenshot() void OMW::Engine::screenshot()

View file

@ -148,4 +148,10 @@ namespace MWClass
return ref->base->enchant; return ref->base->enchant;
} }
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
{
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
}
} }

View file

@ -47,6 +47,9 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
///< Generate action for using via inventory menu
}; };
} }

View file

@ -52,7 +52,7 @@ void BookWindow::open (MWWorld::Ptr book)
clearPages(); clearPages();
mCurrentPage = 0; mCurrentPage = 0;
MWBase::Environment::get().getSoundManager()->playSound3D (book, "book open", 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
mBook.get<ESM::Book>(); mBook.get<ESM::Book>();
@ -77,18 +77,26 @@ void BookWindow::open (MWWorld::Ptr book)
} }
updatePages(); updatePages();
setTakeButtonShow(true);
}
void BookWindow::setTakeButtonShow(bool show)
{
mTakeButton->setVisible(show);
} }
void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender) void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{ {
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "book close", 1.0, 1.0); // no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game); MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game);
} }
void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{ {
MWBase::Environment::get().getSoundManager()->playSound3D (mBook, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack); MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWWorld::ActionTake take(mBook); MWWorld::ActionTake take(mBook);
take.execute(); take.execute();

View file

@ -11,7 +11,9 @@ namespace MWGui
{ {
public: public:
BookWindow(WindowManager& parWindowManager); BookWindow(WindowManager& parWindowManager);
void open(MWWorld::Ptr book); void open(MWWorld::Ptr book);
void setTakeButtonShow(bool show);
protected: protected:
void onNextPageButtonClicked (MyGUI::Widget* _sender); void onNextPageButtonClicked (MyGUI::Widget* _sender);

View file

@ -92,6 +92,9 @@ void ContainerBase::onSelectedItemImpl(MyGUI::Widget* _sender, int count)
mDragAndDrop->mDraggedWidget = mSelectedItem; mDragAndDrop->mDraggedWidget = mSelectedItem;
static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption( static_cast<MyGUI::TextBox*>(mSelectedItem->getChildAt(0)->getChildAt(0))->setCaption(
getCountString((*mDragAndDrop->mStore.begin()).getRefData().getCount())); getCountString((*mDragAndDrop->mStore.begin()).getRefData().getCount()));
mDragAndDrop->mWasInInventory = isInventory();
drawItems(); drawItems();
MWBase::Environment::get().getWindowManager()->setDragDrop(true); MWBase::Environment::get().getWindowManager()->setDragDrop(true);
@ -111,9 +114,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
containerStore.add(*mDragAndDrop->mStore.begin()); containerStore.add(*mDragAndDrop->mStore.begin());
mDragAndDrop->mStore.clear(); mDragAndDrop->mStore.clear();
mDragAndDrop->mIsOnDragAndDrop = false; mDragAndDrop->mIsOnDragAndDrop = false;
mDragAndDrop->mDraggedWidget->detachFromWidget(); MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
mDragAndDrop->mDraggedWidget->attachToWidget(mContainerWidget);
mDragAndDrop->mDraggedWidget = 0;
drawItems(); drawItems();
MWBase::Environment::get().getWindowManager()->setDragDrop(false); MWBase::Environment::get().getWindowManager()->setDragDrop(false);

View file

@ -36,10 +36,16 @@ namespace MWGui
class DragAndDrop class DragAndDrop
{ {
public: public:
DragAndDrop() :
mWasInInventory(false)
{
}
bool mIsOnDragAndDrop; bool mIsOnDragAndDrop;
MyGUI::Widget* mDraggedWidget; MyGUI::Widget* mDraggedWidget;
MyGUI::Widget* mDragAndDropWidget; MyGUI::Widget* mDragAndDropWidget;
MWWorld::ContainerStore mStore; MWWorld::ContainerStore mStore;
bool mWasInInventory; // was the item in inventory before it was dragged
}; };
class ContainerBase class ContainerBase
@ -81,6 +87,8 @@ namespace MWGui
std::string getCountString(const int count); std::string getCountString(const int count);
virtual bool isInventory() { return false; }
void drawItems(); void drawItems();
}; };

View file

@ -1,23 +1,33 @@
#include "inventorywindow.hpp" #include "inventorywindow.hpp"
#include <iterator>
#include <algorithm>
#include "window_manager.hpp"
#include "widgets.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/manualref.hpp"
#include <cmath> #include <cmath>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <assert.h> #include <assert.h>
#include <iostream> #include <iostream>
#include <boost/lexical_cast.hpp>
#include "../mwclass/container.hpp" #include "../mwclass/container.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwscript/scriptmanager.hpp"
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include "../mwscript/extensions.hpp"
#include "../mwscript/globalscripts.hpp"
#include "window_manager.hpp"
#include "widgets.hpp"
#include "bookwindow.hpp"
#include "scrollwindow.hpp"
namespace MWGui namespace MWGui
{ {
@ -38,6 +48,8 @@ namespace MWGui
getWidget(mLeftPane, "LeftPane"); getWidget(mLeftPane, "LeftPane");
getWidget(mRightPane, "RightPane"); getWidget(mRightPane, "RightPane");
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
MyGUI::ScrollView* itemView; MyGUI::ScrollView* itemView;
MyGUI::Widget* containerWidget; MyGUI::Widget* containerWidget;
getWidget(containerWidget, "Items"); getWidget(containerWidget, "Items");
@ -126,4 +138,38 @@ namespace MWGui
mWindowManager.setWeaponVisibility(!mPinned); mWindowManager.setWeaponVisibility(!mPinned);
} }
void InventoryWindow::onAvatarClicked(MyGUI::Widget* _sender)
{
if (mDragAndDrop->mIsOnDragAndDrop)
{
MWWorld::Ptr ptr = *mDragAndDrop->mStore.begin();
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
// execute action and script
MWBase::Environment::get().getWorld()->executeActionScript(ptr, action);
// this is necessary for books/scrolls: if they are already in the player's inventory,
// the "Take" button should not be visible.
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
// without screwing up future book windows
if (mDragAndDrop->mWasInInventory)
{
mWindowManager.getBookWindow()->setTakeButtonShow(false);
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
}
// put back in inventory
MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer);
containerStore.add(ptr);
drawItems();
mDragAndDrop->mStore.clear();
mDragAndDrop->mIsOnDragAndDrop = false;
MyGUI::Gui::getInstance().destroyWidget(mDragAndDrop->mDraggedWidget);
mWindowManager.setDragDrop(false);
}
}
} }

View file

@ -47,7 +47,10 @@ namespace MWGui
void onWindowResize(MyGUI::Window* _sender); void onWindowResize(MyGUI::Window* _sender);
void onFilterChanged(MyGUI::Widget* _sender); void onFilterChanged(MyGUI::Widget* _sender);
void onAvatarClicked(MyGUI::Widget* _sender);
void onPinToggled(); void onPinToggled();
virtual bool isInventory() { return true; }
}; };
} }
#endif // Inventory_H #endif // Inventory_H

View file

@ -25,7 +25,8 @@ ScrollWindow::ScrollWindow (WindowManager& parWindowManager) :
void ScrollWindow::open (MWWorld::Ptr scroll) void ScrollWindow::open (MWWorld::Ptr scroll)
{ {
MWBase::Environment::get().getSoundManager()->playSound3D (scroll, "scroll", 1.0, 1.0); // no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
mScroll = scroll; mScroll = scroll;
@ -41,18 +42,25 @@ void ScrollWindow::open (MWWorld::Ptr scroll)
mTextView->setCanvasSize(410, mTextView->getSize().height); mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setViewOffset(MyGUI::IntPoint(0,0)); mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(true);
}
void ScrollWindow::setTakeButtonShow(bool show)
{
mTakeButton->setVisible(show);
} }
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender) void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{ {
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "scroll", 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game); MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game);
} }
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{ {
MWBase::Environment::get().getSoundManager()->playSound3D (mScroll, "Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack); MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack);
MWWorld::ActionTake take(mScroll); MWWorld::ActionTake take(mScroll);
take.execute(); take.execute();

View file

@ -11,7 +11,9 @@ namespace MWGui
{ {
public: public:
ScrollWindow (WindowManager& parWindowManager); ScrollWindow (WindowManager& parWindowManager);
void open (MWWorld::Ptr scroll); void open (MWWorld::Ptr scroll);
void setTakeButtonShow(bool show);
protected: protected:
void onCloseButtonClicked (MyGUI::Widget* _sender); void onCloseButtonClicked (MyGUI::Widget* _sender);

View file

@ -18,7 +18,8 @@ namespace MWWorld
MWWorld::Class::get (player).getContainerStore (player).add (mObject); MWWorld::Class::get (player).getContainerStore (player).add (mObject);
// remove from world // remove from world, if the item is currently in the world (it could also be in a container)
MWBase::Environment::get().getWorld()->deleteObject (mObject); if (mObject.isInCell())
MWBase::Environment::get().getWorld()->deleteObject (mObject);
} }
} }

View file

@ -77,6 +77,11 @@ namespace MWWorld
return mCell; return mCell;
} }
bool isInCell() const
{
return (mCell != 0);
}
void setContainerStore (ContainerStore *store); void setContainerStore (ContainerStore *store);
///< Must not be called on references that are in a cell. ///< Must not be called on references that are in a cell.

View file

@ -17,6 +17,13 @@
#include "../mwgui/window_manager.hpp" #include "../mwgui/window_manager.hpp"
#include "../mwscript/scriptmanager.hpp"
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include "../mwscript/extensions.hpp"
#include "../mwscript/globalscripts.hpp"
#include "ptr.hpp" #include "ptr.hpp"
#include "class.hpp" #include "class.hpp"
#include "player.hpp" #include "player.hpp"
@ -1018,4 +1025,24 @@ namespace MWWorld
mWorldScene->insertObject(object, cell); mWorldScene->insertObject(object, cell);
} }
void World::executeActionScript(MWWorld::Ptr ptr, boost::shared_ptr<Action> action)
{
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
action->execute();
// execute script
interpreterContext.activate (ptr, action);
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
if (!script.empty())
{
getLocalScripts().setIgnore (ptr);
MWBase::Environment::get().getScriptManager()->run (script, interpreterContext);
}
if (!interpreterContext.hasActivationBeenHandled())
{
interpreterContext.executeActivation();
}
}
} }

View file

@ -274,6 +274,9 @@ namespace MWWorld
bool canPlaceObject(float cursorX, float cursorY); bool canPlaceObject(float cursorX, float cursorY);
///< @return true if it is possible to place on object at specified cursor location ///< @return true if it is possible to place on object at specified cursor location
void executeActionScript(MWWorld::Ptr ptr, boost::shared_ptr<Action> action);
///< execute the activation script of an object (when activating the object with space, or when activating it via the inventory)
}; };
} }