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;
}
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);
boost::shared_ptr<MWWorld::Action> action =
MWWorld::Class::get (ptr).activate (ptr, MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
interpreterContext.activate (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();
}
// execute action and script
MWBase::Environment::get().getWorld()->executeActionScript(ptr, action);
}
void OMW::Engine::screenshot()

View file

@ -148,4 +148,10 @@ namespace MWClass
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;
///< @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();
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 =
mBook.get<ESM::Book>();
@ -77,18 +77,26 @@ void BookWindow::open (MWWorld::Ptr book)
}
updatePages();
setTakeButtonShow(true);
}
void BookWindow::setTakeButtonShow(bool show)
{
mTakeButton->setVisible(show);
}
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);
}
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);
take.execute();

View file

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

View file

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

View file

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

View file

@ -1,23 +1,33 @@
#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 <algorithm>
#include <iterator>
#include <assert.h>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "../mwclass/container.hpp"
#include "../mwworld/containerstore.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwworld/class.hpp"
#include "../mwworld/world.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
{
@ -38,6 +48,8 @@ namespace MWGui
getWidget(mLeftPane, "LeftPane");
getWidget(mRightPane, "RightPane");
mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
MyGUI::ScrollView* itemView;
MyGUI::Widget* containerWidget;
getWidget(containerWidget, "Items");
@ -126,4 +138,38 @@ namespace MWGui
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 onFilterChanged(MyGUI::Widget* _sender);
void onAvatarClicked(MyGUI::Widget* _sender);
void onPinToggled();
virtual bool isInventory() { return true; }
};
}
#endif // Inventory_H

View file

@ -25,7 +25,8 @@ ScrollWindow::ScrollWindow (WindowManager& parWindowManager) :
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;
@ -41,18 +42,25 @@ void ScrollWindow::open (MWWorld::Ptr scroll)
mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(true);
}
void ScrollWindow::setTakeButtonShow(bool show)
{
mTakeButton->setVisible(show);
}
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);
}
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);
take.execute();

View file

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

View file

@ -18,7 +18,8 @@ namespace MWWorld
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)
if (mObject.isInCell())
MWBase::Environment::get().getWorld()->deleteObject (mObject);
}
}

View file

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

View file

@ -17,6 +17,13 @@
#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 "class.hpp"
#include "player.hpp"
@ -1018,4 +1025,24 @@ namespace MWWorld
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);
///< @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)
};
}