mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-18 00:46:38 +00:00
Merge branch 'master' of https://gitlab.com/OpenMW/openmw
This commit is contained in:
commit
6a02e6a4bc
27 changed files with 398 additions and 302 deletions
|
@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
|
|||
set(OPENMW_VERSION_MAJOR 0)
|
||||
set(OPENMW_VERSION_MINOR 50)
|
||||
set(OPENMW_VERSION_RELEASE 0)
|
||||
set(OPENMW_LUA_API_REVISION 80)
|
||||
set(OPENMW_LUA_API_REVISION 81)
|
||||
set(OPENMW_POSTPROCESSING_API_REVISION 3)
|
||||
|
||||
set(OPENMW_VERSION_COMMITHASH "")
|
||||
|
|
|
@ -44,7 +44,7 @@ add_openmw_dir (mwgui
|
|||
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
||||
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
|
||||
draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation textcolours statswatcher
|
||||
postprocessorhud settings controllerbuttonsoverlay inventorytabsoverlay
|
||||
postprocessorhud settings worlditemmodel itemtransfer controllerbuttonsoverlay inventorytabsoverlay
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "companionitemmodel.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "draganddrop.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemtransfer.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "messagebox.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
@ -41,13 +41,14 @@ namespace
|
|||
namespace MWGui
|
||||
{
|
||||
|
||||
CompanionWindow::CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager)
|
||||
CompanionWindow::CompanionWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, MessageBoxManager* manager)
|
||||
: WindowBase("openmw_companion_window.layout")
|
||||
, mSortModel(nullptr)
|
||||
, mModel(nullptr)
|
||||
, mSelectedItem(-1)
|
||||
, mUpdateNextFrame(false)
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mDragAndDrop(&dragAndDrop)
|
||||
, mItemTransfer(&itemTransfer)
|
||||
, mMessageBoxManager(manager)
|
||||
{
|
||||
getWidget(mCloseButton, "CloseButton");
|
||||
|
@ -102,13 +103,13 @@ namespace MWGui
|
|||
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
||||
dialog->openCountDialog(name, "#{sTake}", count);
|
||||
dialog->eventOkClicked.clear();
|
||||
if (Settings::gui().mControllerMenus)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::takeItem);
|
||||
if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::transferItem);
|
||||
else
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem);
|
||||
}
|
||||
else if (Settings::gui().mControllerMenus)
|
||||
takeItem(nullptr, count);
|
||||
else if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||
transferItem(nullptr, count);
|
||||
else
|
||||
dragItem(nullptr, count);
|
||||
}
|
||||
|
@ -119,32 +120,14 @@ namespace MWGui
|
|||
mItemView->update();
|
||||
}
|
||||
|
||||
void CompanionWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
void CompanionWindow::dragItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
||||
}
|
||||
|
||||
void CompanionWindow::takeItem(MyGUI::Widget* sender, int count)
|
||||
void CompanionWindow::transferItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
if (!mModel)
|
||||
return;
|
||||
|
||||
const ItemStack& item = mModel->getItem(mSelectedItem);
|
||||
if (!mModel->onTakeItem(item.mBase, count))
|
||||
return;
|
||||
|
||||
MWGui::InventoryWindow* inventoryWindow = MWBase::Environment::get().getWindowManager()->getInventoryWindow();
|
||||
ItemModel* playerModel = inventoryWindow->getModel();
|
||||
|
||||
mModel->moveItem(item, count, playerModel);
|
||||
|
||||
inventoryWindow->updateItemView();
|
||||
mItemView->update();
|
||||
|
||||
// play the item's sound
|
||||
MWWorld::Ptr itemBase = item.mBase;
|
||||
const ESM::RefId& sound = itemBase.getClass().getUpSoundId(itemBase);
|
||||
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
||||
mItemTransfer->apply(mModel->getItem(mSelectedItem), count, *mItemView);
|
||||
}
|
||||
|
||||
void CompanionWindow::onBackgroundSelected()
|
||||
|
@ -257,6 +240,16 @@ namespace MWGui
|
|||
mUpdateNextFrame = true;
|
||||
}
|
||||
|
||||
void CompanionWindow::onOpen()
|
||||
{
|
||||
mItemTransfer->addTarget(*mItemView);
|
||||
}
|
||||
|
||||
void CompanionWindow::onClose()
|
||||
{
|
||||
mItemTransfer->removeTarget(*mItemView);
|
||||
}
|
||||
|
||||
bool CompanionWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
|
||||
{
|
||||
if (arg.button == SDL_CONTROLLER_BUTTON_A)
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include <components/misc/notnullptr.hpp>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
namespace Widgets
|
||||
|
@ -20,11 +22,12 @@ namespace MWGui
|
|||
class DragAndDrop;
|
||||
class SortFilterItemModel;
|
||||
class CompanionItemModel;
|
||||
class ItemTransfer;
|
||||
|
||||
class CompanionWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
|
||||
{
|
||||
public:
|
||||
CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager);
|
||||
explicit CompanionWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, MessageBoxManager* manager);
|
||||
|
||||
bool exit() override;
|
||||
|
||||
|
@ -52,7 +55,8 @@ namespace MWGui
|
|||
int mSelectedItem;
|
||||
bool mUpdateNextFrame;
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
Misc::NotNullPtr<DragAndDrop> mDragAndDrop;
|
||||
Misc::NotNullPtr<ItemTransfer> mItemTransfer;
|
||||
|
||||
MyGUI::Button* mCloseButton;
|
||||
MyGUI::EditBox* mFilterEdit;
|
||||
|
@ -63,8 +67,8 @@ namespace MWGui
|
|||
void onItemSelected(int index);
|
||||
void onNameFilterChanged(MyGUI::EditBox* _sender);
|
||||
void onBackgroundSelected();
|
||||
void dragItem(MyGUI::Widget* sender, int count);
|
||||
void takeItem(MyGUI::Widget* sender, int count);
|
||||
void dragItem(MyGUI::Widget* sender, std::size_t count);
|
||||
void transferItem(MyGUI::Widget* sender, std::size_t count);
|
||||
|
||||
void onMessageBoxButtonClicked(int button);
|
||||
|
||||
|
@ -73,6 +77,10 @@ namespace MWGui
|
|||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
|
||||
void onReferenceUnavailable() override;
|
||||
|
||||
void onOpen() override;
|
||||
|
||||
void onClose() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
|
||||
#include "countdialog.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
#include "containeritemmodel.hpp"
|
||||
#include "countdialog.hpp"
|
||||
#include "draganddrop.hpp"
|
||||
#include "inventoryitemmodel.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemtransfer.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "pickpocketitemmodel.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
@ -34,9 +34,10 @@
|
|||
namespace MWGui
|
||||
{
|
||||
|
||||
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
|
||||
ContainerWindow::ContainerWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer)
|
||||
: WindowBase("openmw_container_window.layout")
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mDragAndDrop(&dragAndDrop)
|
||||
, mItemTransfer(&itemTransfer)
|
||||
, mSortModel(nullptr)
|
||||
, mModel(nullptr)
|
||||
, mSelectedItem(-1)
|
||||
|
@ -97,54 +98,46 @@ namespace MWGui
|
|||
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
||||
dialog->openCountDialog(name, "#{sTake}", count);
|
||||
dialog->eventOkClicked.clear();
|
||||
if (Settings::gui().mControllerMenus)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::takeItem);
|
||||
if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::transferItem);
|
||||
else
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
|
||||
}
|
||||
else if (Settings::gui().mControllerMenus)
|
||||
takeItem(nullptr, count);
|
||||
else if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||
transferItem(nullptr, count);
|
||||
else
|
||||
dragItem(nullptr, count);
|
||||
}
|
||||
|
||||
void ContainerWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
void ContainerWindow::dragItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
if (!mModel)
|
||||
if (mModel == nullptr)
|
||||
return;
|
||||
|
||||
if (!onTakeItem(mModel->getItem(mSelectedItem), count))
|
||||
const ItemStack item = mModel->getItem(mSelectedItem);
|
||||
|
||||
if (!mModel->onTakeItem(item.mBase, count))
|
||||
return;
|
||||
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
||||
}
|
||||
|
||||
void ContainerWindow::takeItem(MyGUI::Widget* sender, int count)
|
||||
void ContainerWindow::transferItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
if (!mModel)
|
||||
if (mModel == nullptr)
|
||||
return;
|
||||
|
||||
const ItemStack& item = mModel->getItem(mSelectedItem);
|
||||
if (!onTakeItem(item, count))
|
||||
const ItemStack item = mModel->getItem(mSelectedItem);
|
||||
|
||||
if (!mModel->onTakeItem(item.mBase, count))
|
||||
return;
|
||||
|
||||
MWGui::InventoryWindow* inventoryWindow = MWBase::Environment::get().getWindowManager()->getInventoryWindow();
|
||||
ItemModel* playerModel = inventoryWindow->getModel();
|
||||
|
||||
mModel->moveItem(item, count, playerModel);
|
||||
|
||||
inventoryWindow->updateItemView();
|
||||
mItemView->update();
|
||||
|
||||
// play the item's sound
|
||||
MWWorld::Ptr itemBase = item.mBase;
|
||||
const ESM::RefId& sound = itemBase.getClass().getUpSoundId(itemBase);
|
||||
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
||||
mItemTransfer->apply(item, count, *mItemView);
|
||||
}
|
||||
|
||||
void ContainerWindow::dropItem()
|
||||
{
|
||||
if (!mModel)
|
||||
if (mModel == nullptr)
|
||||
return;
|
||||
|
||||
bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount);
|
||||
|
@ -209,10 +202,13 @@ namespace MWGui
|
|||
mSortModel = nullptr;
|
||||
}
|
||||
|
||||
void ContainerWindow::onOpen()
|
||||
{
|
||||
mItemTransfer->addTarget(*mItemView);
|
||||
}
|
||||
|
||||
void ContainerWindow::onClose()
|
||||
{
|
||||
WindowBase::onClose();
|
||||
|
||||
// Make sure the window was actually closed and not temporarily hidden.
|
||||
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container))
|
||||
return;
|
||||
|
@ -223,6 +219,8 @@ namespace MWGui
|
|||
if (!mPtr.isEmpty())
|
||||
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
|
||||
resetReference();
|
||||
|
||||
mItemTransfer->removeTarget(*mItemView);
|
||||
}
|
||||
|
||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -270,9 +268,9 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
||||
}
|
||||
|
||||
const ItemStack& item = mModel->getItem(i);
|
||||
const ItemStack item = mModel->getItem(i);
|
||||
|
||||
if (!onTakeItem(item, item.mCount))
|
||||
if (!mModel->onTakeItem(item.mBase, item.mCount))
|
||||
break;
|
||||
|
||||
mModel->moveItem(item, item.mCount, playerModel);
|
||||
|
@ -349,11 +347,6 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
||||
}
|
||||
|
||||
bool ContainerWindow::onTakeItem(const ItemStack& item, int count)
|
||||
{
|
||||
return mModel->onTakeItem(item.mBase, count);
|
||||
}
|
||||
|
||||
void ContainerWindow::onDeleteCustomData(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
if (mModel && mModel->usesContainer(ptr))
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef MGUI_CONTAINER_H
|
||||
#define MGUI_CONTAINER_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
#include "referenceinterface.hpp"
|
||||
#include "windowbase.hpp"
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
#include <components/misc/notnullptr.hpp>
|
||||
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
|
@ -19,17 +20,19 @@ namespace MWGui
|
|||
class ContainerWindow;
|
||||
class ItemView;
|
||||
class SortFilterItemModel;
|
||||
}
|
||||
class ItemTransfer;
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class ContainerWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
|
||||
{
|
||||
public:
|
||||
ContainerWindow(DragAndDrop* dragAndDrop);
|
||||
explicit ContainerWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer);
|
||||
|
||||
void setPtr(const MWWorld::Ptr& container) override;
|
||||
|
||||
void onOpen() override;
|
||||
|
||||
void onClose() override;
|
||||
|
||||
void clear() override { resetReference(); }
|
||||
|
||||
void onFrame(float dt) override;
|
||||
|
@ -53,7 +56,8 @@ namespace MWGui
|
|||
ItemModel* getModel() { return mModel; }
|
||||
|
||||
private:
|
||||
DragAndDrop* mDragAndDrop;
|
||||
Misc::NotNullPtr<DragAndDrop> mDragAndDrop;
|
||||
Misc::NotNullPtr<ItemTransfer> mItemTransfer;
|
||||
|
||||
MWGui::ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
|
@ -67,16 +71,13 @@ namespace MWGui
|
|||
|
||||
void onItemSelected(int index);
|
||||
void onBackgroundSelected();
|
||||
void dragItem(MyGUI::Widget* sender, int count);
|
||||
void takeItem(MyGUI::Widget* sender, int count);
|
||||
void dragItem(MyGUI::Widget* sender, std::size_t count);
|
||||
void transferItem(MyGUI::Widget* sender, std::size_t count);
|
||||
void dropItem();
|
||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||
void onDisposeCorpseButtonClicked(MyGUI::Widget* sender);
|
||||
|
||||
/// @return is taking the item allowed?
|
||||
bool onTakeItem(const ItemStack& item, int count);
|
||||
|
||||
void onReferenceUnavailable() override;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,12 +19,10 @@ namespace MWGui
|
|||
void openCountDialog(const std::string& item, const std::string& message, const int maxCount);
|
||||
void setCount(int count);
|
||||
|
||||
typedef MyGUI::delegates::MultiDelegate<MyGUI::Widget*, int> EventHandle_WidgetInt;
|
||||
|
||||
/** Event : Ok button was clicked.\n
|
||||
signature : void method(MyGUI::Widget* _sender, int _count)\n
|
||||
signature : void method(MyGUI::Widget* sender, std::size_t count)\n
|
||||
*/
|
||||
EventHandle_WidgetInt eventOkClicked;
|
||||
MyGUI::delegates::MultiDelegate<MyGUI::Widget*, std::size_t> eventOkClicked;
|
||||
|
||||
private:
|
||||
Gui::ScrollBar* mSlider;
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
void DragAndDrop::startDrag(
|
||||
int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count)
|
||||
int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, std::size_t count)
|
||||
{
|
||||
mItem = sourceModel->getItem(index);
|
||||
mDraggedCount = count;
|
||||
|
@ -125,18 +125,18 @@ namespace MWGui
|
|||
|
||||
void DragAndDrop::update()
|
||||
{
|
||||
if (mIsOnDragAndDrop)
|
||||
{
|
||||
int count = mItem.mBase.getCellRef().getCount();
|
||||
if (count < mDraggedCount)
|
||||
{
|
||||
mItem.mCount = count;
|
||||
mDraggedCount = count;
|
||||
mDraggedWidget->setCount(mDraggedCount);
|
||||
mSourceSortModel->clearDragItems();
|
||||
mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount);
|
||||
}
|
||||
}
|
||||
if (!mIsOnDragAndDrop)
|
||||
return;
|
||||
|
||||
const unsigned count = mItem.mBase.getCellRef().getAbsCount();
|
||||
if (count >= mDraggedCount)
|
||||
return;
|
||||
|
||||
mItem.mCount = count;
|
||||
mDraggedCount = count;
|
||||
mDraggedWidget->setCount(mDraggedCount);
|
||||
mSourceSortModel->clearDragItems();
|
||||
mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount);
|
||||
}
|
||||
|
||||
void DragAndDrop::onFrame()
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "itemmodel.hpp"
|
||||
#include "itemwidget.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Widget;
|
||||
|
@ -24,12 +26,12 @@ namespace MWGui
|
|||
ItemView* mSourceView;
|
||||
SortFilterItemModel* mSourceSortModel;
|
||||
ItemStack mItem;
|
||||
int mDraggedCount;
|
||||
std::size_t mDraggedCount;
|
||||
|
||||
DragAndDrop();
|
||||
|
||||
void startDrag(
|
||||
int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count);
|
||||
int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, std::size_t count);
|
||||
void drop(ItemModel* targetModel, ItemView* targetView);
|
||||
void update();
|
||||
void onFrame();
|
||||
|
|
|
@ -25,67 +25,12 @@
|
|||
|
||||
#include "draganddrop.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemmodel.hpp"
|
||||
#include "spellicons.hpp"
|
||||
|
||||
#include "itemwidget.hpp"
|
||||
#include "spellicons.hpp"
|
||||
#include "worlditemmodel.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
/**
|
||||
* Makes it possible to use ItemModel::moveItem to move an item from an inventory to the world.
|
||||
*/
|
||||
class WorldItemModel : public ItemModel
|
||||
{
|
||||
public:
|
||||
WorldItemModel(float left, float top)
|
||||
: mLeft(left)
|
||||
, mTop(top)
|
||||
{
|
||||
}
|
||||
virtual ~WorldItemModel() override {}
|
||||
|
||||
MWWorld::Ptr dropItemImpl(const ItemStack& item, size_t count, bool copy)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
MWWorld::Ptr dropped;
|
||||
if (world->canPlaceObject(mLeft, mTop))
|
||||
dropped = world->placeObject(item.mBase, mLeft, mTop, count, copy);
|
||||
else
|
||||
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count, copy);
|
||||
dropped.getCellRef().setOwner(ESM::RefId());
|
||||
|
||||
return dropped;
|
||||
}
|
||||
|
||||
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
|
||||
{
|
||||
return dropItemImpl(item, count, false);
|
||||
}
|
||||
|
||||
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
|
||||
{
|
||||
return dropItemImpl(item, count, true);
|
||||
}
|
||||
|
||||
void removeItem(const ItemStack& item, size_t count) override
|
||||
{
|
||||
throw std::runtime_error("removeItem not implemented");
|
||||
}
|
||||
ModelIndex getIndex(const ItemStack& item) override { throw std::runtime_error("getIndex not implemented"); }
|
||||
void update() override {}
|
||||
size_t getItemCount() override { return 0; }
|
||||
ItemStack getItem(ModelIndex index) override { throw std::runtime_error("getItem not implemented"); }
|
||||
bool usesContainer(const MWWorld::Ptr&) override { return false; }
|
||||
|
||||
private:
|
||||
// Where to drop the item
|
||||
float mLeft;
|
||||
float mTop;
|
||||
};
|
||||
|
||||
HUD::HUD(CustomMarkerCollection& customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender)
|
||||
: WindowBase("openmw_hud.layout")
|
||||
, LocalMapBase(customMarkers, localMapRender, Settings::map().mLocalMapHudFogOfWar)
|
||||
|
@ -262,13 +207,14 @@ namespace MWGui
|
|||
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
|
||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// drop item into the gameworld
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
float mouseX = cursorPosition.left / float(viewSize.width);
|
||||
float mouseY = cursorPosition.top / float(viewSize.height);
|
||||
const MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
const MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||
const float cursorX = cursorPosition.left / static_cast<float>(viewSize.width);
|
||||
const float cursorY = cursorPosition.top / static_cast<float>(viewSize.height);
|
||||
|
||||
dropDraggedItem(mouseX, mouseY);
|
||||
// drop item into the gameworld
|
||||
WorldItemModel worldItemModel(cursorX, cursorY);
|
||||
mDragAndDrop->drop(&worldItemModel, nullptr);
|
||||
|
||||
winMgr->changePointer("arrow");
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "draganddrop.hpp"
|
||||
#include "hud.hpp"
|
||||
#include "inventoryitemmodel.hpp"
|
||||
#include "itemtransfer.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "sortfilteritemmodel.hpp"
|
||||
|
@ -78,10 +79,11 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
InventoryWindow::InventoryWindow(
|
||||
DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem)
|
||||
InventoryWindow::InventoryWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, osg::Group* parent,
|
||||
Resource::ResourceSystem* resourceSystem)
|
||||
: WindowPinnableBase("openmw_inventory_window.layout")
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mDragAndDrop(&dragAndDrop)
|
||||
, mItemTransfer(&itemTransfer)
|
||||
, mSelectedItem(-1)
|
||||
, mSortModel(nullptr)
|
||||
, mTradeModel(nullptr)
|
||||
|
@ -346,14 +348,16 @@ namespace MWGui
|
|||
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
||||
dialog->openCountDialog(name, message, count);
|
||||
dialog->eventOkClicked.clear();
|
||||
if (mPendingControllerAction == ControllerAction::Give)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::giveItem);
|
||||
else if (mPendingControllerAction == ControllerAction::Drop)
|
||||
if (mPendingControllerAction == ControllerAction::Drop)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dropItem);
|
||||
else if (mTrading || mPendingControllerAction == ControllerAction::Sell)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem);
|
||||
else if (MyGUI::InputManager::getInstance().isAltPressed()
|
||||
|| mPendingControllerAction == ControllerAction::Transfer)
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::transferItem);
|
||||
else
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dragItem);
|
||||
|
||||
mSelectedItem = index;
|
||||
}
|
||||
else
|
||||
|
@ -369,12 +373,13 @@ namespace MWGui
|
|||
// stack of items; we only want to use the first item.
|
||||
onBackgroundSelected();
|
||||
}
|
||||
else if (mPendingControllerAction == ControllerAction::Give)
|
||||
giveItem(nullptr, count);
|
||||
else if (mPendingControllerAction == ControllerAction::Drop)
|
||||
dropItem(nullptr, count);
|
||||
else if (mTrading || mPendingControllerAction == ControllerAction::Sell)
|
||||
sellItem(nullptr, count);
|
||||
else if (MyGUI::InputManager::getInstance().isAltPressed()
|
||||
|| mPendingControllerAction == ControllerAction::Transfer)
|
||||
transferItem(nullptr, count);
|
||||
else
|
||||
dragItem(nullptr, count);
|
||||
}
|
||||
|
@ -415,14 +420,21 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
void InventoryWindow::dragItem(MyGUI::Widget* sender, int count)
|
||||
void InventoryWindow::dragItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
ensureSelectedItemUnequipped(count);
|
||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count);
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
void InventoryWindow::sellItem(MyGUI::Widget* sender, int count)
|
||||
void InventoryWindow::transferItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
ensureSelectedItemUnequipped(count);
|
||||
mItemTransfer->apply(mTradeModel->getItem(mSelectedItem), count, *mItemView);
|
||||
notifyContentChanged();
|
||||
}
|
||||
|
||||
void InventoryWindow::sellItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
ensureSelectedItemUnequipped(count);
|
||||
const ItemStack& item = mTradeModel->getItem(mSelectedItem);
|
||||
|
@ -446,32 +458,7 @@ namespace MWGui
|
|||
notifyContentChanged();
|
||||
}
|
||||
|
||||
void InventoryWindow::giveItem(MyGUI::Widget* sender, int count)
|
||||
{
|
||||
if (!mDragAndDrop->mIsOnDragAndDrop)
|
||||
dragItem(sender, count);
|
||||
|
||||
if (mGuiMode == MWGui::GM_Companion && mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// Drag and drop the item on the companion's window.
|
||||
MWGui::CompanionWindow* companionWindow = (MWGui::CompanionWindow*)MWBase::Environment::get()
|
||||
.getWindowManager()
|
||||
->getGuiModeWindows(mGuiMode)
|
||||
.at(1);
|
||||
mDragAndDrop->drop(companionWindow->getModel(), companionWindow->getItemView());
|
||||
}
|
||||
else if (mGuiMode == MWGui::GM_Container && mDragAndDrop->mIsOnDragAndDrop)
|
||||
{
|
||||
// Drag and drop the item on the container window.
|
||||
MWGui::ContainerWindow* containerWindow = (MWGui::ContainerWindow*)MWBase::Environment::get()
|
||||
.getWindowManager()
|
||||
->getGuiModeWindows(mGuiMode)
|
||||
.at(0);
|
||||
mDragAndDrop->drop(containerWindow->getModel(), containerWindow->getItemView());
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryWindow::dropItem(MyGUI::Widget* sender, int count)
|
||||
void InventoryWindow::dropItem(MyGUI::Widget* sender, size_t count)
|
||||
{
|
||||
if (mGuiMode != MWGui::GM_Inventory)
|
||||
return;
|
||||
|
@ -507,6 +494,13 @@ namespace MWGui
|
|||
notifyContentChanged();
|
||||
}
|
||||
adjustPanes();
|
||||
|
||||
mItemTransfer->addTarget(*mItemView);
|
||||
}
|
||||
|
||||
void InventoryWindow::onClose()
|
||||
{
|
||||
mItemTransfer->removeTarget(*mItemView);
|
||||
}
|
||||
|
||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
|
@ -868,7 +862,16 @@ namespace MWGui
|
|||
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||
mDragAndDrop->finish();
|
||||
|
||||
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
||||
if (MyGUI::InputManager::getInstance().isAltPressed())
|
||||
{
|
||||
const MWWorld::Ptr item = mTradeModel->getItem(i).mBase;
|
||||
MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item));
|
||||
mItemView->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count);
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
|
||||
}
|
||||
|
@ -1017,7 +1020,7 @@ namespace MWGui
|
|||
if (mGuiMode == MWGui::GM_Inventory)
|
||||
mPendingControllerAction = ControllerAction::Use;
|
||||
else if (mGuiMode == MWGui::GM_Companion || mGuiMode == MWGui::GM_Container)
|
||||
mPendingControllerAction = ControllerAction::Give;
|
||||
mPendingControllerAction = ControllerAction::Transfer;
|
||||
else if (mGuiMode == MWGui::GM_Barter)
|
||||
mPendingControllerAction = ControllerAction::Sell;
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include <components/misc/notnullptr.hpp>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Group;
|
||||
|
@ -30,14 +32,18 @@ namespace MWGui
|
|||
class TradeItemModel;
|
||||
class DragAndDrop;
|
||||
class ItemModel;
|
||||
class ItemTransfer;
|
||||
|
||||
class InventoryWindow : public WindowPinnableBase, public MWWorld::ContainerStoreListener
|
||||
{
|
||||
public:
|
||||
InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem);
|
||||
explicit InventoryWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, osg::Group* parent,
|
||||
Resource::ResourceSystem* resourceSystem);
|
||||
|
||||
void onOpen() override;
|
||||
|
||||
void onClose() override;
|
||||
|
||||
/// start trading, disables item drag&drop
|
||||
void setTrading(bool trading);
|
||||
|
||||
|
@ -79,7 +85,8 @@ namespace MWGui
|
|||
void setActiveControllerWindow(bool active) override;
|
||||
|
||||
private:
|
||||
DragAndDrop* mDragAndDrop;
|
||||
Misc::NotNullPtr<DragAndDrop> mDragAndDrop;
|
||||
Misc::NotNullPtr<ItemTransfer> mItemTransfer;
|
||||
|
||||
int mSelectedItem;
|
||||
std::optional<int> mEquippedStackableCount;
|
||||
|
@ -128,16 +135,16 @@ namespace MWGui
|
|||
{
|
||||
None = 0,
|
||||
Use,
|
||||
Give,
|
||||
Transfer,
|
||||
Sell,
|
||||
Drop,
|
||||
};
|
||||
ControllerAction mPendingControllerAction;
|
||||
|
||||
void sellItem(MyGUI::Widget* sender, int count);
|
||||
void dragItem(MyGUI::Widget* sender, int count);
|
||||
void giveItem(MyGUI::Widget* sender, int count);
|
||||
void dropItem(MyGUI::Widget* sender, int count);
|
||||
void sellItem(MyGUI::Widget* sender, std::size_t count);
|
||||
void dragItem(MyGUI::Widget* sender, std::size_t count);
|
||||
void transferItem(MyGUI::Widget* sender, std::size_t count);
|
||||
void dropItem(MyGUI::Widget* sender, std::size_t count);
|
||||
|
||||
void onWindowResize(MyGUI::Window* _sender);
|
||||
void onFilterChanged(MyGUI::Widget* _sender);
|
||||
|
|
78
apps/openmw/mwgui/itemtransfer.hpp
Normal file
78
apps/openmw/mwgui/itemtransfer.hpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef OPENMW_APPS_OPENMW_MWGUI_ITEMTRANSFER_H
|
||||
#define OPENMW_APPS_OPENMW_MWGUI_ITEMTRANSFER_H
|
||||
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemmodel.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "windowmanagerimp.hpp"
|
||||
#include "worlditemmodel.hpp"
|
||||
|
||||
#include <apps/openmw/mwbase/windowmanager.hpp>
|
||||
#include <apps/openmw/mwworld/class.hpp>
|
||||
|
||||
#include <components/misc/notnullptr.hpp>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class ItemTransfer
|
||||
{
|
||||
public:
|
||||
explicit ItemTransfer(WindowManager& windowManager)
|
||||
: mWindowManager(&windowManager)
|
||||
{
|
||||
}
|
||||
|
||||
void addTarget(ItemView& view) { mTargets.insert(&view); }
|
||||
|
||||
void removeTarget(ItemView& view) { mTargets.erase(&view); }
|
||||
|
||||
void apply(const ItemStack& item, std::size_t count, ItemView& sourceView)
|
||||
{
|
||||
if (item.mFlags & ItemStack::Flag_Bound)
|
||||
{
|
||||
mWindowManager->messageBox("#{sBarterDialog12}");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemView* targetView = nullptr;
|
||||
|
||||
for (ItemView* const view : mTargets)
|
||||
{
|
||||
if (view == &sourceView)
|
||||
continue;
|
||||
|
||||
if (targetView != nullptr)
|
||||
{
|
||||
mWindowManager->messageBox("#{sContentsMessage2}");
|
||||
return;
|
||||
}
|
||||
|
||||
targetView = view;
|
||||
}
|
||||
|
||||
WorldItemModel worldItemModel(0.5f, 0.5f);
|
||||
ItemModel* const targetModel = targetView == nullptr ? &worldItemModel : targetView->getModel();
|
||||
|
||||
if (!targetModel->onDropItem(item.mBase, count))
|
||||
return;
|
||||
|
||||
sourceView.getModel()->moveItem(item, count, targetModel);
|
||||
|
||||
if (targetView != nullptr)
|
||||
targetView->update();
|
||||
|
||||
sourceView.update();
|
||||
|
||||
mWindowManager->getInventoryWindow()->updateItemView();
|
||||
mWindowManager->playSound(item.mBase.getClass().getDownSoundId(item.mBase));
|
||||
}
|
||||
|
||||
private:
|
||||
Misc::NotNullPtr<WindowManager> mWindowManager;
|
||||
std::unordered_set<ItemView*> mTargets;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,6 +18,8 @@ namespace MWGui
|
|||
/// Register needed components with MyGUI's factory manager
|
||||
static void registerComponents();
|
||||
|
||||
ItemModel* getModel() { return mModel.get(); }
|
||||
|
||||
/// Takes ownership of \a model
|
||||
void setModel(std::unique_ptr<ItemModel> model);
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
void TradeWindow::sellItem(MyGUI::Widget* sender, int count)
|
||||
void TradeWindow::sellItem(MyGUI::Widget* /*sender*/, std::size_t count)
|
||||
{
|
||||
const ItemStack& item = mTradeModel->getItem(mItemToSell);
|
||||
const ESM::RefId& sound = item.mBase.getClass().getUpSoundId(item.mBase);
|
||||
|
@ -382,9 +382,9 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
void TradeWindow::onOfferSubmitted(MyGUI::Widget* _sender, int offerAmount)
|
||||
void TradeWindow::onOfferSubmitted(MyGUI::Widget* _sender, size_t offerAmount)
|
||||
{
|
||||
mCurrentBalance = mCurrentBalance < 0 ? -offerAmount : offerAmount;
|
||||
mCurrentBalance = offerAmount * (mCurrentBalance < 0 ? -1 : 1);
|
||||
updateLabels();
|
||||
onOfferButtonClicked(mOfferButton);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ namespace MWGui
|
|||
void updateOffer();
|
||||
|
||||
void onItemSelected(int index);
|
||||
void sellItem(MyGUI::Widget* sender, int count);
|
||||
void sellItem(MyGUI::Widget* sender, std::size_t count);
|
||||
|
||||
void borrowItem(int index, size_t count);
|
||||
void returnItem(int index, size_t count);
|
||||
|
@ -116,7 +116,7 @@ namespace MWGui
|
|||
void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||
void onBalanceValueChanged(int value);
|
||||
void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller);
|
||||
void onOfferSubmitted(MyGUI::Widget* _sender, int offerAmount);
|
||||
void onOfferSubmitted(MyGUI::Widget* _sender, size_t offerAmount);
|
||||
|
||||
void addRepeatController(MyGUI::Widget* widget);
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#include "hud.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "itemchargeview.hpp"
|
||||
#include "itemtransfer.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "itemwidget.hpp"
|
||||
#include "jailscreen.hpp"
|
||||
|
@ -314,6 +315,7 @@ namespace MWGui
|
|||
mTextColours.loadColours();
|
||||
|
||||
mDragAndDrop = std::make_unique<DragAndDrop>();
|
||||
mItemTransfer = std::make_unique<ItemTransfer>(*this);
|
||||
|
||||
auto recharge = std::make_unique<Recharge>();
|
||||
mGuiModeStates[GM_Recharge] = GuiModeState(recharge.get());
|
||||
|
@ -336,7 +338,7 @@ namespace MWGui
|
|||
trackWindow(mStatsWindow, makeStatsWindowSettingValues());
|
||||
|
||||
auto inventoryWindow = std::make_unique<InventoryWindow>(
|
||||
mDragAndDrop.get(), mViewer->getSceneData()->asGroup(), mResourceSystem);
|
||||
*mDragAndDrop, *mItemTransfer, mViewer->getSceneData()->asGroup(), mResourceSystem);
|
||||
mInventoryWindow = inventoryWindow.get();
|
||||
mWindows.push_back(std::move(inventoryWindow));
|
||||
|
||||
|
@ -383,7 +385,7 @@ namespace MWGui
|
|||
mGuiModeStates[GM_Dialogue] = GuiModeState(mDialogueWindow);
|
||||
mTradeWindow->eventTradeDone += MyGUI::newDelegate(mDialogueWindow, &DialogueWindow::onTradeComplete);
|
||||
|
||||
auto containerWindow = std::make_unique<ContainerWindow>(mDragAndDrop.get());
|
||||
auto containerWindow = std::make_unique<ContainerWindow>(*mDragAndDrop, *mItemTransfer);
|
||||
mContainerWindow = containerWindow.get();
|
||||
mWindows.push_back(std::move(containerWindow));
|
||||
trackWindow(mContainerWindow, makeContainerWindowSettingValues());
|
||||
|
@ -459,7 +461,8 @@ namespace MWGui
|
|||
|
||||
mSoulgemDialog = std::make_unique<SoulgemDialog>(mMessageBoxManager.get());
|
||||
|
||||
auto companionWindow = std::make_unique<CompanionWindow>(mDragAndDrop.get(), mMessageBoxManager.get());
|
||||
auto companionWindow
|
||||
= std::make_unique<CompanionWindow>(*mDragAndDrop, *mItemTransfer, mMessageBoxManager.get());
|
||||
trackWindow(companionWindow.get(), makeCompanionWindowSettingValues());
|
||||
mGuiModeStates[GM_Companion] = GuiModeState({ mInventoryWindow, companionWindow.get() });
|
||||
mWindows.push_back(std::move(companionWindow));
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
**/
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
|
@ -120,6 +119,7 @@ namespace MWGui
|
|||
class PostProcessorHud;
|
||||
class JailScreen;
|
||||
class KeyboardNavigation;
|
||||
class ItemTransfer;
|
||||
class ControllerButtonsOverlay;
|
||||
class InventoryTabsOverlay;
|
||||
|
||||
|
@ -446,6 +446,7 @@ namespace MWGui
|
|||
Console* mConsole;
|
||||
DialogueWindow* mDialogueWindow;
|
||||
std::unique_ptr<DragAndDrop> mDragAndDrop;
|
||||
std::unique_ptr<ItemTransfer> mItemTransfer;
|
||||
InventoryWindow* mInventoryWindow;
|
||||
ScrollWindow* mScrollWindow;
|
||||
BookWindow* mBookWindow;
|
||||
|
|
82
apps/openmw/mwgui/worlditemmodel.hpp
Normal file
82
apps/openmw/mwgui/worlditemmodel.hpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
#ifndef OPENMW_APPS_OPENMW_MWGUI_WORLDITEMMODEL_H
|
||||
#define OPENMW_APPS_OPENMW_MWGUI_WORLDITEMMODEL_H
|
||||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
#include <apps/openmw/mwbase/environment.hpp>
|
||||
#include <apps/openmw/mwbase/world.hpp>
|
||||
|
||||
#include <components/esm/refid.hpp>
|
||||
|
||||
#include <MyGUI_InputManager.h>
|
||||
#include <MyGUI_RenderManager.h>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
// Makes it possible to use ItemModel::moveItem to move an item from an inventory to the world.
|
||||
class WorldItemModel : public ItemModel
|
||||
{
|
||||
public:
|
||||
explicit WorldItemModel(float cursorX, float cursorY)
|
||||
: mCursorX(cursorX)
|
||||
, mCursorY(cursorY)
|
||||
{
|
||||
}
|
||||
|
||||
MWWorld::Ptr dropItemImpl(const ItemStack& item, size_t count, bool copy)
|
||||
{
|
||||
MWBase::World& world = *MWBase::Environment::get().getWorld();
|
||||
|
||||
const MWWorld::Ptr player = world.getPlayerPtr();
|
||||
|
||||
world.breakInvisibility(player);
|
||||
|
||||
const MWWorld::Ptr dropped = world.canPlaceObject(mCursorX, mCursorY)
|
||||
? world.placeObject(item.mBase, mCursorX, mCursorY, count, copy)
|
||||
: world.dropObjectOnGround(player, item.mBase, count, copy);
|
||||
|
||||
dropped.getCellRef().setOwner(ESM::RefId());
|
||||
|
||||
return dropped;
|
||||
}
|
||||
|
||||
MWWorld::Ptr addItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
|
||||
{
|
||||
return dropItemImpl(item, count, false);
|
||||
}
|
||||
|
||||
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
|
||||
{
|
||||
return dropItemImpl(item, count, true);
|
||||
}
|
||||
|
||||
void removeItem(const ItemStack& /*item*/, size_t /*count*/) override
|
||||
{
|
||||
throw std::runtime_error("WorldItemModel::removeItem is not implemented");
|
||||
}
|
||||
|
||||
ModelIndex getIndex(const ItemStack& /*item*/) override
|
||||
{
|
||||
throw std::runtime_error("WorldItemModel::getIndex is not implemented");
|
||||
}
|
||||
|
||||
void update() override {}
|
||||
|
||||
size_t getItemCount() override { return 0; }
|
||||
|
||||
ItemStack getItem(ModelIndex /*index*/) override
|
||||
{
|
||||
throw std::runtime_error("WorldItemModel::getItem is not implemented");
|
||||
}
|
||||
|
||||
bool usesContainer(const MWWorld::Ptr&) override { return false; }
|
||||
|
||||
private:
|
||||
float mCursorX;
|
||||
float mCursorY;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
#include "../birthsignbindings.hpp"
|
||||
#include "../luamanagerimp.hpp"
|
||||
|
||||
#include "apps/openmw/mwbase/dialoguemanager.hpp"
|
||||
#include "apps/openmw/mwbase/inputmanager.hpp"
|
||||
#include "apps/openmw/mwbase/journal.hpp"
|
||||
#include "apps/openmw/mwbase/mechanicsmanager.hpp"
|
||||
|
@ -195,6 +196,22 @@ namespace MWLua
|
|||
throw std::runtime_error("Only player and global scripts can toggle teleportation.");
|
||||
MWBase::Environment::get().getWorld()->enableTeleporting(state);
|
||||
};
|
||||
player["addTopic"] = [](const Object& player, std::string_view topicId) {
|
||||
verifyPlayer(player);
|
||||
|
||||
ESM::RefId topic = ESM::RefId::deserializeText(topicId);
|
||||
const ESM::Dialogue* dialogueRecord
|
||||
= MWBase::Environment::get().getESMStore()->get<ESM::Dialogue>().search(topic);
|
||||
|
||||
if (!dialogueRecord)
|
||||
throw std::runtime_error(
|
||||
"Failed to add topic \"" + std::string(topicId) + "\": topic record not found");
|
||||
|
||||
if (dialogueRecord->mType != ESM::Dialogue::Topic)
|
||||
throw std::runtime_error("Failed to add topic \"" + std::string(topicId) + "\": record is not a topic");
|
||||
|
||||
MWBase::Environment::get().getDialogueManager()->addTopic(topic);
|
||||
};
|
||||
player["sendMenuEvent"] = [context](const Object& player, std::string eventName, const sol::object& eventData) {
|
||||
verifyPlayer(player);
|
||||
context.mLuaEvents->addMenuEvent({ std::move(eventName), LuaUtil::serialize(eventData) });
|
||||
|
|
|
@ -244,6 +244,18 @@ namespace MWWorld
|
|||
return std::abs(count);
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned getAbsCount() const
|
||||
{
|
||||
struct Visitor
|
||||
{
|
||||
int operator()(const ESM::CellRef& ref) { return ref.mCount; }
|
||||
int operator()(const ESM4::Reference& ref) { return ref.mCount; }
|
||||
int operator()(const ESM4::ActorCharacter& ref) { return ref.mCount; }
|
||||
};
|
||||
return static_cast<unsigned>(std::abs(std::visit(Visitor(), mCellRef.mVariant)));
|
||||
}
|
||||
|
||||
void setCount(int value);
|
||||
|
||||
// Write the content of this CellRef into the given ObjectState
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
#ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
||||
#define OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "exception.hpp"
|
||||
#include "niffile.hpp"
|
||||
|
@ -19,7 +17,7 @@ namespace Nif
|
|||
InterpolationType_Unknown = 0,
|
||||
InterpolationType_Linear = 1,
|
||||
InterpolationType_Quadratic = 2,
|
||||
InterpolationType_TCB = 3,
|
||||
InterpolationType_TBC = 3,
|
||||
InterpolationType_XYZ = 4,
|
||||
InterpolationType_Constant = 5
|
||||
};
|
||||
|
@ -30,19 +28,18 @@ namespace Nif
|
|||
T mValue;
|
||||
T mInTan; // Only for Quadratic interpolation, and never for QuaternionKeyList
|
||||
T mOutTan; // Only for Quadratic interpolation, and never for QuaternionKeyList
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TCBKey
|
||||
{
|
||||
float mTime;
|
||||
T mValue{};
|
||||
T mInTan{};
|
||||
T mOutTan{};
|
||||
float mTension;
|
||||
float mContinuity;
|
||||
float mBias;
|
||||
// FIXME: Implement TBC interpolation
|
||||
/*
|
||||
float mTension; // Only for TBC interpolation
|
||||
float mBias; // Only for TBC interpolation
|
||||
float mContinuity; // Only for TBC interpolation
|
||||
*/
|
||||
};
|
||||
using FloatKey = KeyT<float>;
|
||||
using Vector3Key = KeyT<osg::Vec3f>;
|
||||
using Vector4Key = KeyT<osg::Vec4f>;
|
||||
using QuaternionKey = KeyT<osg::Quat>;
|
||||
|
||||
template <typename T, T (NIFStream::*getValue)()>
|
||||
struct KeyMapT
|
||||
|
@ -104,20 +101,15 @@ namespace Nif
|
|||
mKeys[time] = key;
|
||||
}
|
||||
}
|
||||
else if (mInterpolationType == InterpolationType_TCB)
|
||||
else if (mInterpolationType == InterpolationType_TBC)
|
||||
{
|
||||
std::vector<TCBKey<T>> tcbKeys(count);
|
||||
for (TCBKey<T>& key : tcbKeys)
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
nif->read(key.mTime);
|
||||
key.mValue = ((*nif).*getValue)();
|
||||
nif->read(key.mTension);
|
||||
nif->read(key.mContinuity);
|
||||
nif->read(key.mBias);
|
||||
float time;
|
||||
nif->read(time);
|
||||
readTBC(*nif, key);
|
||||
mKeys[time] = key;
|
||||
}
|
||||
generateTCBTangents(tcbKeys);
|
||||
for (TCBKey<T>& key : tcbKeys)
|
||||
mKeys[key.mTime] = KeyType{ std::move(key.mValue), std::move(key.mInTan), std::move(key.mOutTan) };
|
||||
}
|
||||
else if (mInterpolationType == InterpolationType_XYZ)
|
||||
{
|
||||
|
@ -148,52 +140,12 @@ namespace Nif
|
|||
|
||||
static void readQuadratic(NIFStream& nif, KeyT<osg::Quat>& key) { readValue(nif, key); }
|
||||
|
||||
template <typename U>
|
||||
static void generateTCBTangents(std::vector<TCBKey<U>>& keys)
|
||||
static void readTBC(NIFStream& nif, KeyT<T>& key)
|
||||
{
|
||||
if (keys.size() <= 1)
|
||||
return;
|
||||
|
||||
std::sort(keys.begin(), keys.end(), [](const auto& a, const auto& b) { return a.mTime < b.mTime; });
|
||||
for (size_t i = 0; i < keys.size(); ++i)
|
||||
{
|
||||
TCBKey<U>& curr = keys[i];
|
||||
const TCBKey<U>& prev = (i == 0) ? curr : keys[i - 1];
|
||||
const TCBKey<U>& next = (i == keys.size() - 1) ? curr : keys[i + 1];
|
||||
const float prevLen = curr.mTime - prev.mTime;
|
||||
const float nextLen = next.mTime - curr.mTime;
|
||||
if (prevLen + nextLen <= 0.f)
|
||||
continue;
|
||||
|
||||
const U prevDelta = curr.mValue - prev.mValue;
|
||||
const U nextDelta = next.mValue - curr.mValue;
|
||||
const float t = curr.mTension;
|
||||
const float c = curr.mContinuity;
|
||||
const float b = curr.mBias;
|
||||
|
||||
U x{}, y{}, z{}, w{};
|
||||
if (prevLen > 0.f)
|
||||
x = prevDelta / prevLen * (1 - t) * (1 - c) * (1 + b);
|
||||
if (nextLen > 0.f)
|
||||
y = nextDelta / nextLen * (1 - t) * (1 + c) * (1 - b);
|
||||
if (prevLen > 0.f)
|
||||
z = prevDelta / prevLen * (1 - t) * (1 + c) * (1 + b);
|
||||
if (nextLen > 0.f)
|
||||
w = nextDelta / nextLen * (1 - t) * (1 - c) * (1 - b);
|
||||
|
||||
curr.mInTan = (x + y) * prevLen / (prevLen + nextLen);
|
||||
curr.mOutTan = (z + w) * nextLen / (prevLen + nextLen);
|
||||
}
|
||||
}
|
||||
|
||||
static void generateTCBTangents(std::vector<TCBKey<bool>>& keys)
|
||||
{
|
||||
// TODO: is this even legal?
|
||||
}
|
||||
|
||||
static void generateTCBTangents(std::vector<TCBKey<osg::Quat>>& keys)
|
||||
{
|
||||
// TODO: implement TCB interpolation for quaternions
|
||||
readValue(nif, key);
|
||||
/*key.mTension = */ nif.get<float>();
|
||||
/*key.mBias = */ nif.get<float>();
|
||||
/*key.mContinuity = */ nif.get<float>();
|
||||
}
|
||||
};
|
||||
using FloatKeyMap = KeyMapT<float, &NIFStream::get<float>>;
|
||||
|
|
|
@ -131,7 +131,6 @@ namespace NifOsg
|
|||
case Nif::InterpolationType_Constant:
|
||||
return fraction > 0.5f ? b.mValue : a.mValue;
|
||||
case Nif::InterpolationType_Quadratic:
|
||||
case Nif::InterpolationType_TCB:
|
||||
{
|
||||
// Using a cubic Hermite spline.
|
||||
// b1(t) = 2t^3 - 3t^2 + 1
|
||||
|
@ -148,6 +147,7 @@ namespace NifOsg
|
|||
const float b4 = t3 - t2;
|
||||
return a.mValue * b1 + b.mValue * b2 + a.mOutTan * b3 + b.mInTan * b4;
|
||||
}
|
||||
// TODO: Implement TBC interpolation
|
||||
default:
|
||||
return a.mValue + ((b.mValue - a.mValue) * fraction);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include <MyGUI_Colour.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace Settings
|
||||
|
|
|
@ -98,7 +98,7 @@ GUI Settings
|
|||
:type: boolean
|
||||
:range: true, false
|
||||
:default: true
|
||||
|
||||
|
||||
|
||||
Enables or disables the red flash overlay when the character takes damage.
|
||||
Disabling causes the player to "bleed" like NPCs.
|
||||
|
@ -108,7 +108,7 @@ GUI Settings
|
|||
:type: boolean
|
||||
:range: true, false
|
||||
:default: true
|
||||
|
||||
|
||||
|
||||
Enable or disable the werewolf visual effect in first-person mode.
|
||||
|
||||
|
@ -117,7 +117,7 @@ GUI Settings
|
|||
:type: color
|
||||
:range: [0, 1]
|
||||
:default: 0.15 0.0 0.0 1.0
|
||||
|
||||
|
||||
|
||||
Background color of tooltip and crosshair when hovering over an NPC-owned item.
|
||||
Four floating point values: red, green, blue, alpha (alpha ignored).
|
||||
|
@ -128,7 +128,7 @@ GUI Settings
|
|||
:type: color
|
||||
:range: [0, 1]
|
||||
:default: 1.0 0.15 0.15 1.0
|
||||
|
||||
|
||||
|
||||
Crosshair color when hovering over an NPC-owned item.
|
||||
Four floating point values: red, green, blue, alpha (alpha ignored).
|
||||
|
|
|
@ -767,10 +767,10 @@ de ordinarie fonterna i Morrowind. Bocka denna ruta om du ändå föredrar ordin
|
|||
the specular map texture would have to be named foo_spec.dds).
|
||||
If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file
|
||||
(.osg file, not supported in .nif files). Affects objects.</p></body></html></source>
|
||||
<translation><html><head/><body><p>Om den här funktionen är aktiverad kommer spekularitetskartor (specular maps) att hittas och användas
|
||||
<translation><html><head/><body><p>Om den här funktionen är aktiverad kommer spekularitetskartor (specular maps) att hittas och användas
|
||||
(see 'specular map pattern', t.ex. för en bastextur foo.dds,
|
||||
ska spekularitetskartan heta foo_spec.dds).
|
||||
Om funktionen är inaktiverad kommer normalkartor bara användas om texturerna är explicit listade i 3D-modell-filen
|
||||
Om funktionen är inaktiverad kommer normalkartor bara användas om texturerna är explicit listade i 3D-modell-filen
|
||||
(.nif eller .osg fil). Påverkar objekt.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -378,8 +378,8 @@ unarmed creature attacks damage armor = false
|
|||
# 2 = Cylinder
|
||||
actor collision shape type = 0
|
||||
|
||||
# When false the player character will base movement on animations. This will sway the camera
|
||||
# while moving in third person like in vanilla, and reproduce movement bugs caused by glitchy
|
||||
# When false the player character will base movement on animations. This will sway the camera
|
||||
# while moving in third person like in vanilla, and reproduce movement bugs caused by glitchy
|
||||
# vanilla animations.
|
||||
player movement ignores animation = false
|
||||
|
||||
|
@ -1142,7 +1142,7 @@ xargonianswimknakf = meshes/xargonian_swimkna.kf
|
|||
# Sky atmosphere mesh
|
||||
skyatmosphere = meshes/sky_atmosphere.nif
|
||||
|
||||
# Sky clouds mesh
|
||||
# Sky clouds mesh
|
||||
skyclouds = meshes/sky_clouds_01.nif
|
||||
|
||||
# Sky stars mesh 01
|
||||
|
@ -1275,7 +1275,7 @@ right eye fov down = -0.8
|
|||
|
||||
[Post Processing]
|
||||
|
||||
# Enables post-processing
|
||||
# Enables post-processing
|
||||
enabled = false
|
||||
|
||||
# List of active shaders. This is more easily with the in-game shader HUD, by default accessible with the F2 key.
|
||||
|
|
Loading…
Reference in a new issue