mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-18 10:16:39 +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_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 50)
|
set(OPENMW_VERSION_MINOR 50)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
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_POSTPROCESSING_API_REVISION 3)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
|
|
@ -44,7 +44,7 @@ add_openmw_dir (mwgui
|
||||||
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
|
||||||
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
|
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
|
||||||
draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation textcolours statswatcher
|
draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation textcolours statswatcher
|
||||||
postprocessorhud settings controllerbuttonsoverlay inventorytabsoverlay
|
postprocessorhud settings worlditemmodel itemtransfer controllerbuttonsoverlay inventorytabsoverlay
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "companionitemmodel.hpp"
|
#include "companionitemmodel.hpp"
|
||||||
#include "countdialog.hpp"
|
#include "countdialog.hpp"
|
||||||
#include "draganddrop.hpp"
|
#include "draganddrop.hpp"
|
||||||
#include "inventorywindow.hpp"
|
#include "itemtransfer.hpp"
|
||||||
#include "itemview.hpp"
|
#include "itemview.hpp"
|
||||||
#include "messagebox.hpp"
|
#include "messagebox.hpp"
|
||||||
#include "sortfilteritemmodel.hpp"
|
#include "sortfilteritemmodel.hpp"
|
||||||
|
@ -41,13 +41,14 @@ namespace
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
CompanionWindow::CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager)
|
CompanionWindow::CompanionWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, MessageBoxManager* manager)
|
||||||
: WindowBase("openmw_companion_window.layout")
|
: WindowBase("openmw_companion_window.layout")
|
||||||
, mSortModel(nullptr)
|
, mSortModel(nullptr)
|
||||||
, mModel(nullptr)
|
, mModel(nullptr)
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
, mUpdateNextFrame(false)
|
, mUpdateNextFrame(false)
|
||||||
, mDragAndDrop(dragAndDrop)
|
, mDragAndDrop(&dragAndDrop)
|
||||||
|
, mItemTransfer(&itemTransfer)
|
||||||
, mMessageBoxManager(manager)
|
, mMessageBoxManager(manager)
|
||||||
{
|
{
|
||||||
getWidget(mCloseButton, "CloseButton");
|
getWidget(mCloseButton, "CloseButton");
|
||||||
|
@ -102,13 +103,13 @@ namespace MWGui
|
||||||
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
||||||
dialog->openCountDialog(name, "#{sTake}", count);
|
dialog->openCountDialog(name, "#{sTake}", count);
|
||||||
dialog->eventOkClicked.clear();
|
dialog->eventOkClicked.clear();
|
||||||
if (Settings::gui().mControllerMenus)
|
if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::takeItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::transferItem);
|
||||||
else
|
else
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem);
|
||||||
}
|
}
|
||||||
else if (Settings::gui().mControllerMenus)
|
else if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||||
takeItem(nullptr, count);
|
transferItem(nullptr, count);
|
||||||
else
|
else
|
||||||
dragItem(nullptr, count);
|
dragItem(nullptr, count);
|
||||||
}
|
}
|
||||||
|
@ -119,32 +120,14 @@ namespace MWGui
|
||||||
mItemView->update();
|
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);
|
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)
|
mItemTransfer->apply(mModel->getItem(mSelectedItem), count, *mItemView);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompanionWindow::onBackgroundSelected()
|
void CompanionWindow::onBackgroundSelected()
|
||||||
|
@ -257,6 +240,16 @@ namespace MWGui
|
||||||
mUpdateNextFrame = true;
|
mUpdateNextFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompanionWindow::onOpen()
|
||||||
|
{
|
||||||
|
mItemTransfer->addTarget(*mItemView);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompanionWindow::onClose()
|
||||||
|
{
|
||||||
|
mItemTransfer->removeTarget(*mItemView);
|
||||||
|
}
|
||||||
|
|
||||||
bool CompanionWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
|
bool CompanionWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)
|
||||||
{
|
{
|
||||||
if (arg.button == SDL_CONTROLLER_BUTTON_A)
|
if (arg.button == SDL_CONTROLLER_BUTTON_A)
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/notnullptr.hpp>
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
namespace Widgets
|
namespace Widgets
|
||||||
|
@ -20,11 +22,12 @@ namespace MWGui
|
||||||
class DragAndDrop;
|
class DragAndDrop;
|
||||||
class SortFilterItemModel;
|
class SortFilterItemModel;
|
||||||
class CompanionItemModel;
|
class CompanionItemModel;
|
||||||
|
class ItemTransfer;
|
||||||
|
|
||||||
class CompanionWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
|
class CompanionWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager);
|
explicit CompanionWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, MessageBoxManager* manager);
|
||||||
|
|
||||||
bool exit() override;
|
bool exit() override;
|
||||||
|
|
||||||
|
@ -52,7 +55,8 @@ namespace MWGui
|
||||||
int mSelectedItem;
|
int mSelectedItem;
|
||||||
bool mUpdateNextFrame;
|
bool mUpdateNextFrame;
|
||||||
|
|
||||||
DragAndDrop* mDragAndDrop;
|
Misc::NotNullPtr<DragAndDrop> mDragAndDrop;
|
||||||
|
Misc::NotNullPtr<ItemTransfer> mItemTransfer;
|
||||||
|
|
||||||
MyGUI::Button* mCloseButton;
|
MyGUI::Button* mCloseButton;
|
||||||
MyGUI::EditBox* mFilterEdit;
|
MyGUI::EditBox* mFilterEdit;
|
||||||
|
@ -63,8 +67,8 @@ namespace MWGui
|
||||||
void onItemSelected(int index);
|
void onItemSelected(int index);
|
||||||
void onNameFilterChanged(MyGUI::EditBox* _sender);
|
void onNameFilterChanged(MyGUI::EditBox* _sender);
|
||||||
void onBackgroundSelected();
|
void onBackgroundSelected();
|
||||||
void dragItem(MyGUI::Widget* sender, int count);
|
void dragItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
void takeItem(MyGUI::Widget* sender, int count);
|
void transferItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
|
|
||||||
void onMessageBoxButtonClicked(int button);
|
void onMessageBoxButtonClicked(int button);
|
||||||
|
|
||||||
|
@ -73,6 +77,10 @@ namespace MWGui
|
||||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||||
|
|
||||||
void onReferenceUnavailable() override;
|
void onReferenceUnavailable() override;
|
||||||
|
|
||||||
|
void onOpen() override;
|
||||||
|
|
||||||
|
void onClose() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,12 @@
|
||||||
|
|
||||||
#include "../mwscript/interpretercontext.hpp"
|
#include "../mwscript/interpretercontext.hpp"
|
||||||
|
|
||||||
#include "countdialog.hpp"
|
|
||||||
#include "inventorywindow.hpp"
|
|
||||||
|
|
||||||
#include "containeritemmodel.hpp"
|
#include "containeritemmodel.hpp"
|
||||||
|
#include "countdialog.hpp"
|
||||||
#include "draganddrop.hpp"
|
#include "draganddrop.hpp"
|
||||||
#include "inventoryitemmodel.hpp"
|
#include "inventoryitemmodel.hpp"
|
||||||
|
#include "inventorywindow.hpp"
|
||||||
|
#include "itemtransfer.hpp"
|
||||||
#include "itemview.hpp"
|
#include "itemview.hpp"
|
||||||
#include "pickpocketitemmodel.hpp"
|
#include "pickpocketitemmodel.hpp"
|
||||||
#include "sortfilteritemmodel.hpp"
|
#include "sortfilteritemmodel.hpp"
|
||||||
|
@ -34,9 +34,10 @@
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop)
|
ContainerWindow::ContainerWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer)
|
||||||
: WindowBase("openmw_container_window.layout")
|
: WindowBase("openmw_container_window.layout")
|
||||||
, mDragAndDrop(dragAndDrop)
|
, mDragAndDrop(&dragAndDrop)
|
||||||
|
, mItemTransfer(&itemTransfer)
|
||||||
, mSortModel(nullptr)
|
, mSortModel(nullptr)
|
||||||
, mModel(nullptr)
|
, mModel(nullptr)
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
|
@ -97,54 +98,46 @@ namespace MWGui
|
||||||
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
||||||
dialog->openCountDialog(name, "#{sTake}", count);
|
dialog->openCountDialog(name, "#{sTake}", count);
|
||||||
dialog->eventOkClicked.clear();
|
dialog->eventOkClicked.clear();
|
||||||
if (Settings::gui().mControllerMenus)
|
if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::takeItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::transferItem);
|
||||||
else
|
else
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem);
|
||||||
}
|
}
|
||||||
else if (Settings::gui().mControllerMenus)
|
else if (Settings::gui().mControllerMenus || MyGUI::InputManager::getInstance().isAltPressed())
|
||||||
takeItem(nullptr, count);
|
transferItem(nullptr, count);
|
||||||
else
|
else
|
||||||
dragItem(nullptr, count);
|
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;
|
return;
|
||||||
|
|
||||||
if (!onTakeItem(mModel->getItem(mSelectedItem), count))
|
const ItemStack item = mModel->getItem(mSelectedItem);
|
||||||
|
|
||||||
|
if (!mModel->onTakeItem(item.mBase, count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count);
|
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;
|
return;
|
||||||
|
|
||||||
const ItemStack& item = mModel->getItem(mSelectedItem);
|
const ItemStack item = mModel->getItem(mSelectedItem);
|
||||||
if (!onTakeItem(item, count))
|
|
||||||
|
if (!mModel->onTakeItem(item.mBase, count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWGui::InventoryWindow* inventoryWindow = MWBase::Environment::get().getWindowManager()->getInventoryWindow();
|
mItemTransfer->apply(item, count, *mItemView);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContainerWindow::dropItem()
|
void ContainerWindow::dropItem()
|
||||||
{
|
{
|
||||||
if (!mModel)
|
if (mModel == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount);
|
bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount);
|
||||||
|
@ -209,10 +202,13 @@ namespace MWGui
|
||||||
mSortModel = nullptr;
|
mSortModel = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContainerWindow::onOpen()
|
||||||
|
{
|
||||||
|
mItemTransfer->addTarget(*mItemView);
|
||||||
|
}
|
||||||
|
|
||||||
void ContainerWindow::onClose()
|
void ContainerWindow::onClose()
|
||||||
{
|
{
|
||||||
WindowBase::onClose();
|
|
||||||
|
|
||||||
// Make sure the window was actually closed and not temporarily hidden.
|
// Make sure the window was actually closed and not temporarily hidden.
|
||||||
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container))
|
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container))
|
||||||
return;
|
return;
|
||||||
|
@ -223,6 +219,8 @@ namespace MWGui
|
||||||
if (!mPtr.isEmpty())
|
if (!mPtr.isEmpty())
|
||||||
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
|
MWBase::Environment::get().getMechanicsManager()->onClose(mPtr);
|
||||||
resetReference();
|
resetReference();
|
||||||
|
|
||||||
|
mItemTransfer->removeTarget(*mItemView);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
@ -270,9 +268,9 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->playSound(sound);
|
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;
|
break;
|
||||||
|
|
||||||
mModel->moveItem(item, item.mCount, playerModel);
|
mModel->moveItem(item, item.mCount, playerModel);
|
||||||
|
@ -349,11 +347,6 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container);
|
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)
|
void ContainerWindow::onDeleteCustomData(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
if (mModel && mModel->usesContainer(ptr))
|
if (mModel && mModel->usesContainer(ptr))
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#ifndef MGUI_CONTAINER_H
|
#ifndef MGUI_CONTAINER_H
|
||||||
#define MGUI_CONTAINER_H
|
#define MGUI_CONTAINER_H
|
||||||
|
|
||||||
|
#include "itemmodel.hpp"
|
||||||
#include "referenceinterface.hpp"
|
#include "referenceinterface.hpp"
|
||||||
#include "windowbase.hpp"
|
#include "windowbase.hpp"
|
||||||
|
|
||||||
#include "itemmodel.hpp"
|
#include <components/misc/notnullptr.hpp>
|
||||||
|
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
|
||||||
|
@ -19,17 +20,19 @@ namespace MWGui
|
||||||
class ContainerWindow;
|
class ContainerWindow;
|
||||||
class ItemView;
|
class ItemView;
|
||||||
class SortFilterItemModel;
|
class SortFilterItemModel;
|
||||||
}
|
class ItemTransfer;
|
||||||
|
|
||||||
namespace MWGui
|
|
||||||
{
|
|
||||||
class ContainerWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
|
class ContainerWindow : public WindowBase, public ReferenceInterface, public MWWorld::ContainerStoreListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContainerWindow(DragAndDrop* dragAndDrop);
|
explicit ContainerWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer);
|
||||||
|
|
||||||
void setPtr(const MWWorld::Ptr& container) override;
|
void setPtr(const MWWorld::Ptr& container) override;
|
||||||
|
|
||||||
|
void onOpen() override;
|
||||||
|
|
||||||
void onClose() override;
|
void onClose() override;
|
||||||
|
|
||||||
void clear() override { resetReference(); }
|
void clear() override { resetReference(); }
|
||||||
|
|
||||||
void onFrame(float dt) override;
|
void onFrame(float dt) override;
|
||||||
|
@ -53,7 +56,8 @@ namespace MWGui
|
||||||
ItemModel* getModel() { return mModel; }
|
ItemModel* getModel() { return mModel; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DragAndDrop* mDragAndDrop;
|
Misc::NotNullPtr<DragAndDrop> mDragAndDrop;
|
||||||
|
Misc::NotNullPtr<ItemTransfer> mItemTransfer;
|
||||||
|
|
||||||
MWGui::ItemView* mItemView;
|
MWGui::ItemView* mItemView;
|
||||||
SortFilterItemModel* mSortModel;
|
SortFilterItemModel* mSortModel;
|
||||||
|
@ -67,16 +71,13 @@ namespace MWGui
|
||||||
|
|
||||||
void onItemSelected(int index);
|
void onItemSelected(int index);
|
||||||
void onBackgroundSelected();
|
void onBackgroundSelected();
|
||||||
void dragItem(MyGUI::Widget* sender, int count);
|
void dragItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
void takeItem(MyGUI::Widget* sender, int count);
|
void transferItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
void dropItem();
|
void dropItem();
|
||||||
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
void onCloseButtonClicked(MyGUI::Widget* _sender);
|
||||||
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
void onTakeAllButtonClicked(MyGUI::Widget* _sender);
|
||||||
void onDisposeCorpseButtonClicked(MyGUI::Widget* sender);
|
void onDisposeCorpseButtonClicked(MyGUI::Widget* sender);
|
||||||
|
|
||||||
/// @return is taking the item allowed?
|
|
||||||
bool onTakeItem(const ItemStack& item, int count);
|
|
||||||
|
|
||||||
void onReferenceUnavailable() override;
|
void onReferenceUnavailable() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,10 @@ namespace MWGui
|
||||||
void openCountDialog(const std::string& item, const std::string& message, const int maxCount);
|
void openCountDialog(const std::string& item, const std::string& message, const int maxCount);
|
||||||
void setCount(int count);
|
void setCount(int count);
|
||||||
|
|
||||||
typedef MyGUI::delegates::MultiDelegate<MyGUI::Widget*, int> EventHandle_WidgetInt;
|
|
||||||
|
|
||||||
/** Event : Ok button was clicked.\n
|
/** 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:
|
private:
|
||||||
Gui::ScrollBar* mSlider;
|
Gui::ScrollBar* mSlider;
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragAndDrop::startDrag(
|
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);
|
mItem = sourceModel->getItem(index);
|
||||||
mDraggedCount = count;
|
mDraggedCount = count;
|
||||||
|
@ -125,18 +125,18 @@ namespace MWGui
|
||||||
|
|
||||||
void DragAndDrop::update()
|
void DragAndDrop::update()
|
||||||
{
|
{
|
||||||
if (mIsOnDragAndDrop)
|
if (!mIsOnDragAndDrop)
|
||||||
{
|
return;
|
||||||
int count = mItem.mBase.getCellRef().getCount();
|
|
||||||
if (count < mDraggedCount)
|
const unsigned count = mItem.mBase.getCellRef().getAbsCount();
|
||||||
{
|
if (count >= mDraggedCount)
|
||||||
mItem.mCount = count;
|
return;
|
||||||
mDraggedCount = count;
|
|
||||||
mDraggedWidget->setCount(mDraggedCount);
|
mItem.mCount = count;
|
||||||
mSourceSortModel->clearDragItems();
|
mDraggedCount = count;
|
||||||
mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount);
|
mDraggedWidget->setCount(mDraggedCount);
|
||||||
}
|
mSourceSortModel->clearDragItems();
|
||||||
}
|
mSourceSortModel->addDragItem(mItem.mBase, mDraggedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragAndDrop::onFrame()
|
void DragAndDrop::onFrame()
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "itemmodel.hpp"
|
#include "itemmodel.hpp"
|
||||||
#include "itemwidget.hpp"
|
#include "itemwidget.hpp"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace MyGUI
|
namespace MyGUI
|
||||||
{
|
{
|
||||||
class Widget;
|
class Widget;
|
||||||
|
@ -24,12 +26,12 @@ namespace MWGui
|
||||||
ItemView* mSourceView;
|
ItemView* mSourceView;
|
||||||
SortFilterItemModel* mSourceSortModel;
|
SortFilterItemModel* mSourceSortModel;
|
||||||
ItemStack mItem;
|
ItemStack mItem;
|
||||||
int mDraggedCount;
|
std::size_t mDraggedCount;
|
||||||
|
|
||||||
DragAndDrop();
|
DragAndDrop();
|
||||||
|
|
||||||
void startDrag(
|
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 drop(ItemModel* targetModel, ItemView* targetView);
|
||||||
void update();
|
void update();
|
||||||
void onFrame();
|
void onFrame();
|
||||||
|
|
|
@ -25,67 +25,12 @@
|
||||||
|
|
||||||
#include "draganddrop.hpp"
|
#include "draganddrop.hpp"
|
||||||
#include "inventorywindow.hpp"
|
#include "inventorywindow.hpp"
|
||||||
#include "itemmodel.hpp"
|
|
||||||
#include "spellicons.hpp"
|
|
||||||
|
|
||||||
#include "itemwidget.hpp"
|
#include "itemwidget.hpp"
|
||||||
|
#include "spellicons.hpp"
|
||||||
|
#include "worlditemmodel.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
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)
|
HUD::HUD(CustomMarkerCollection& customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender)
|
||||||
: WindowBase("openmw_hud.layout")
|
: WindowBase("openmw_hud.layout")
|
||||||
, LocalMapBase(customMarkers, localMapRender, Settings::map().mLocalMapHudFogOfWar)
|
, LocalMapBase(customMarkers, localMapRender, Settings::map().mLocalMapHudFogOfWar)
|
||||||
|
@ -262,13 +207,14 @@ namespace MWGui
|
||||||
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
|
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
|
||||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||||
{
|
{
|
||||||
// drop item into the gameworld
|
const MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
const MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
||||||
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
|
const float cursorX = cursorPosition.left / static_cast<float>(viewSize.width);
|
||||||
float mouseX = cursorPosition.left / float(viewSize.width);
|
const float cursorY = cursorPosition.top / static_cast<float>(viewSize.height);
|
||||||
float mouseY = cursorPosition.top / float(viewSize.height);
|
|
||||||
|
|
||||||
dropDraggedItem(mouseX, mouseY);
|
// drop item into the gameworld
|
||||||
|
WorldItemModel worldItemModel(cursorX, cursorY);
|
||||||
|
mDragAndDrop->drop(&worldItemModel, nullptr);
|
||||||
|
|
||||||
winMgr->changePointer("arrow");
|
winMgr->changePointer("arrow");
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "draganddrop.hpp"
|
#include "draganddrop.hpp"
|
||||||
#include "hud.hpp"
|
#include "hud.hpp"
|
||||||
#include "inventoryitemmodel.hpp"
|
#include "inventoryitemmodel.hpp"
|
||||||
|
#include "itemtransfer.hpp"
|
||||||
#include "itemview.hpp"
|
#include "itemview.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "sortfilteritemmodel.hpp"
|
#include "sortfilteritemmodel.hpp"
|
||||||
|
@ -78,10 +79,11 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryWindow::InventoryWindow(
|
InventoryWindow::InventoryWindow(DragAndDrop& dragAndDrop, ItemTransfer& itemTransfer, osg::Group* parent,
|
||||||
DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem)
|
Resource::ResourceSystem* resourceSystem)
|
||||||
: WindowPinnableBase("openmw_inventory_window.layout")
|
: WindowPinnableBase("openmw_inventory_window.layout")
|
||||||
, mDragAndDrop(dragAndDrop)
|
, mDragAndDrop(&dragAndDrop)
|
||||||
|
, mItemTransfer(&itemTransfer)
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
, mSortModel(nullptr)
|
, mSortModel(nullptr)
|
||||||
, mTradeModel(nullptr)
|
, mTradeModel(nullptr)
|
||||||
|
@ -346,14 +348,16 @@ namespace MWGui
|
||||||
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
name += MWGui::ToolTips::getSoulString(object.getCellRef());
|
||||||
dialog->openCountDialog(name, message, count);
|
dialog->openCountDialog(name, message, count);
|
||||||
dialog->eventOkClicked.clear();
|
dialog->eventOkClicked.clear();
|
||||||
if (mPendingControllerAction == ControllerAction::Give)
|
if (mPendingControllerAction == ControllerAction::Drop)
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::giveItem);
|
|
||||||
else if (mPendingControllerAction == ControllerAction::Drop)
|
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dropItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dropItem);
|
||||||
else if (mTrading || mPendingControllerAction == ControllerAction::Sell)
|
else if (mTrading || mPendingControllerAction == ControllerAction::Sell)
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::sellItem);
|
||||||
|
else if (MyGUI::InputManager::getInstance().isAltPressed()
|
||||||
|
|| mPendingControllerAction == ControllerAction::Transfer)
|
||||||
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::transferItem);
|
||||||
else
|
else
|
||||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dragItem);
|
dialog->eventOkClicked += MyGUI::newDelegate(this, &InventoryWindow::dragItem);
|
||||||
|
|
||||||
mSelectedItem = index;
|
mSelectedItem = index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -369,12 +373,13 @@ namespace MWGui
|
||||||
// stack of items; we only want to use the first item.
|
// stack of items; we only want to use the first item.
|
||||||
onBackgroundSelected();
|
onBackgroundSelected();
|
||||||
}
|
}
|
||||||
else if (mPendingControllerAction == ControllerAction::Give)
|
|
||||||
giveItem(nullptr, count);
|
|
||||||
else if (mPendingControllerAction == ControllerAction::Drop)
|
else if (mPendingControllerAction == ControllerAction::Drop)
|
||||||
dropItem(nullptr, count);
|
dropItem(nullptr, count);
|
||||||
else if (mTrading || mPendingControllerAction == ControllerAction::Sell)
|
else if (mTrading || mPendingControllerAction == ControllerAction::Sell)
|
||||||
sellItem(nullptr, count);
|
sellItem(nullptr, count);
|
||||||
|
else if (MyGUI::InputManager::getInstance().isAltPressed()
|
||||||
|
|| mPendingControllerAction == ControllerAction::Transfer)
|
||||||
|
transferItem(nullptr, count);
|
||||||
else
|
else
|
||||||
dragItem(nullptr, count);
|
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);
|
ensureSelectedItemUnequipped(count);
|
||||||
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count);
|
mDragAndDrop->startDrag(mSelectedItem, mSortModel, mTradeModel, mItemView, count);
|
||||||
notifyContentChanged();
|
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);
|
ensureSelectedItemUnequipped(count);
|
||||||
const ItemStack& item = mTradeModel->getItem(mSelectedItem);
|
const ItemStack& item = mTradeModel->getItem(mSelectedItem);
|
||||||
|
@ -446,32 +458,7 @@ namespace MWGui
|
||||||
notifyContentChanged();
|
notifyContentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::giveItem(MyGUI::Widget* sender, int count)
|
void InventoryWindow::dropItem(MyGUI::Widget* sender, size_t 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)
|
|
||||||
{
|
{
|
||||||
if (mGuiMode != MWGui::GM_Inventory)
|
if (mGuiMode != MWGui::GM_Inventory)
|
||||||
return;
|
return;
|
||||||
|
@ -507,6 +494,13 @@ namespace MWGui
|
||||||
notifyContentChanged();
|
notifyContentChanged();
|
||||||
}
|
}
|
||||||
adjustPanes();
|
adjustPanes();
|
||||||
|
|
||||||
|
mItemTransfer->addTarget(*mItemView);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InventoryWindow::onClose()
|
||||||
|
{
|
||||||
|
mItemTransfer->removeTarget(*mItemView);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||||
|
@ -868,7 +862,16 @@ namespace MWGui
|
||||||
if (mDragAndDrop->mIsOnDragAndDrop)
|
if (mDragAndDrop->mIsOnDragAndDrop)
|
||||||
mDragAndDrop->finish();
|
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();
|
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1020,7 @@ namespace MWGui
|
||||||
if (mGuiMode == MWGui::GM_Inventory)
|
if (mGuiMode == MWGui::GM_Inventory)
|
||||||
mPendingControllerAction = ControllerAction::Use;
|
mPendingControllerAction = ControllerAction::Use;
|
||||||
else if (mGuiMode == MWGui::GM_Companion || mGuiMode == MWGui::GM_Container)
|
else if (mGuiMode == MWGui::GM_Companion || mGuiMode == MWGui::GM_Container)
|
||||||
mPendingControllerAction = ControllerAction::Give;
|
mPendingControllerAction = ControllerAction::Transfer;
|
||||||
else if (mGuiMode == MWGui::GM_Barter)
|
else if (mGuiMode == MWGui::GM_Barter)
|
||||||
mPendingControllerAction = ControllerAction::Sell;
|
mPendingControllerAction = ControllerAction::Sell;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/notnullptr.hpp>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Group;
|
class Group;
|
||||||
|
@ -30,14 +32,18 @@ namespace MWGui
|
||||||
class TradeItemModel;
|
class TradeItemModel;
|
||||||
class DragAndDrop;
|
class DragAndDrop;
|
||||||
class ItemModel;
|
class ItemModel;
|
||||||
|
class ItemTransfer;
|
||||||
|
|
||||||
class InventoryWindow : public WindowPinnableBase, public MWWorld::ContainerStoreListener
|
class InventoryWindow : public WindowPinnableBase, public MWWorld::ContainerStoreListener
|
||||||
{
|
{
|
||||||
public:
|
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 onOpen() override;
|
||||||
|
|
||||||
|
void onClose() override;
|
||||||
|
|
||||||
/// start trading, disables item drag&drop
|
/// start trading, disables item drag&drop
|
||||||
void setTrading(bool trading);
|
void setTrading(bool trading);
|
||||||
|
|
||||||
|
@ -79,7 +85,8 @@ namespace MWGui
|
||||||
void setActiveControllerWindow(bool active) override;
|
void setActiveControllerWindow(bool active) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DragAndDrop* mDragAndDrop;
|
Misc::NotNullPtr<DragAndDrop> mDragAndDrop;
|
||||||
|
Misc::NotNullPtr<ItemTransfer> mItemTransfer;
|
||||||
|
|
||||||
int mSelectedItem;
|
int mSelectedItem;
|
||||||
std::optional<int> mEquippedStackableCount;
|
std::optional<int> mEquippedStackableCount;
|
||||||
|
@ -128,16 +135,16 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
Use,
|
Use,
|
||||||
Give,
|
Transfer,
|
||||||
Sell,
|
Sell,
|
||||||
Drop,
|
Drop,
|
||||||
};
|
};
|
||||||
ControllerAction mPendingControllerAction;
|
ControllerAction mPendingControllerAction;
|
||||||
|
|
||||||
void sellItem(MyGUI::Widget* sender, int count);
|
void sellItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
void dragItem(MyGUI::Widget* sender, int count);
|
void dragItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
void giveItem(MyGUI::Widget* sender, int count);
|
void transferItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
void dropItem(MyGUI::Widget* sender, int count);
|
void dropItem(MyGUI::Widget* sender, std::size_t count);
|
||||||
|
|
||||||
void onWindowResize(MyGUI::Window* _sender);
|
void onWindowResize(MyGUI::Window* _sender);
|
||||||
void onFilterChanged(MyGUI::Widget* _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
|
/// Register needed components with MyGUI's factory manager
|
||||||
static void registerComponents();
|
static void registerComponents();
|
||||||
|
|
||||||
|
ItemModel* getModel() { return mModel.get(); }
|
||||||
|
|
||||||
/// Takes ownership of \a model
|
/// Takes ownership of \a model
|
||||||
void setModel(std::unique_ptr<ItemModel> 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 ItemStack& item = mTradeModel->getItem(mItemToSell);
|
||||||
const ESM::RefId& sound = item.mBase.getClass().getUpSoundId(item.mBase);
|
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();
|
updateLabels();
|
||||||
onOfferButtonClicked(mOfferButton);
|
onOfferButtonClicked(mOfferButton);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace MWGui
|
||||||
void updateOffer();
|
void updateOffer();
|
||||||
|
|
||||||
void onItemSelected(int index);
|
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 borrowItem(int index, size_t count);
|
||||||
void returnItem(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 onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||||
void onBalanceValueChanged(int value);
|
void onBalanceValueChanged(int value);
|
||||||
void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller);
|
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);
|
void addRepeatController(MyGUI::Widget* widget);
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#include "hud.hpp"
|
#include "hud.hpp"
|
||||||
#include "inventorywindow.hpp"
|
#include "inventorywindow.hpp"
|
||||||
#include "itemchargeview.hpp"
|
#include "itemchargeview.hpp"
|
||||||
|
#include "itemtransfer.hpp"
|
||||||
#include "itemview.hpp"
|
#include "itemview.hpp"
|
||||||
#include "itemwidget.hpp"
|
#include "itemwidget.hpp"
|
||||||
#include "jailscreen.hpp"
|
#include "jailscreen.hpp"
|
||||||
|
@ -314,6 +315,7 @@ namespace MWGui
|
||||||
mTextColours.loadColours();
|
mTextColours.loadColours();
|
||||||
|
|
||||||
mDragAndDrop = std::make_unique<DragAndDrop>();
|
mDragAndDrop = std::make_unique<DragAndDrop>();
|
||||||
|
mItemTransfer = std::make_unique<ItemTransfer>(*this);
|
||||||
|
|
||||||
auto recharge = std::make_unique<Recharge>();
|
auto recharge = std::make_unique<Recharge>();
|
||||||
mGuiModeStates[GM_Recharge] = GuiModeState(recharge.get());
|
mGuiModeStates[GM_Recharge] = GuiModeState(recharge.get());
|
||||||
|
@ -336,7 +338,7 @@ namespace MWGui
|
||||||
trackWindow(mStatsWindow, makeStatsWindowSettingValues());
|
trackWindow(mStatsWindow, makeStatsWindowSettingValues());
|
||||||
|
|
||||||
auto inventoryWindow = std::make_unique<InventoryWindow>(
|
auto inventoryWindow = std::make_unique<InventoryWindow>(
|
||||||
mDragAndDrop.get(), mViewer->getSceneData()->asGroup(), mResourceSystem);
|
*mDragAndDrop, *mItemTransfer, mViewer->getSceneData()->asGroup(), mResourceSystem);
|
||||||
mInventoryWindow = inventoryWindow.get();
|
mInventoryWindow = inventoryWindow.get();
|
||||||
mWindows.push_back(std::move(inventoryWindow));
|
mWindows.push_back(std::move(inventoryWindow));
|
||||||
|
|
||||||
|
@ -383,7 +385,7 @@ namespace MWGui
|
||||||
mGuiModeStates[GM_Dialogue] = GuiModeState(mDialogueWindow);
|
mGuiModeStates[GM_Dialogue] = GuiModeState(mDialogueWindow);
|
||||||
mTradeWindow->eventTradeDone += MyGUI::newDelegate(mDialogueWindow, &DialogueWindow::onTradeComplete);
|
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();
|
mContainerWindow = containerWindow.get();
|
||||||
mWindows.push_back(std::move(containerWindow));
|
mWindows.push_back(std::move(containerWindow));
|
||||||
trackWindow(mContainerWindow, makeContainerWindowSettingValues());
|
trackWindow(mContainerWindow, makeContainerWindowSettingValues());
|
||||||
|
@ -459,7 +461,8 @@ namespace MWGui
|
||||||
|
|
||||||
mSoulgemDialog = std::make_unique<SoulgemDialog>(mMessageBoxManager.get());
|
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());
|
trackWindow(companionWindow.get(), makeCompanionWindowSettingValues());
|
||||||
mGuiModeStates[GM_Companion] = GuiModeState({ mInventoryWindow, companionWindow.get() });
|
mGuiModeStates[GM_Companion] = GuiModeState({ mInventoryWindow, companionWindow.get() });
|
||||||
mWindows.push_back(std::move(companionWindow));
|
mWindows.push_back(std::move(companionWindow));
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stack>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
@ -120,6 +119,7 @@ namespace MWGui
|
||||||
class PostProcessorHud;
|
class PostProcessorHud;
|
||||||
class JailScreen;
|
class JailScreen;
|
||||||
class KeyboardNavigation;
|
class KeyboardNavigation;
|
||||||
|
class ItemTransfer;
|
||||||
class ControllerButtonsOverlay;
|
class ControllerButtonsOverlay;
|
||||||
class InventoryTabsOverlay;
|
class InventoryTabsOverlay;
|
||||||
|
|
||||||
|
@ -446,6 +446,7 @@ namespace MWGui
|
||||||
Console* mConsole;
|
Console* mConsole;
|
||||||
DialogueWindow* mDialogueWindow;
|
DialogueWindow* mDialogueWindow;
|
||||||
std::unique_ptr<DragAndDrop> mDragAndDrop;
|
std::unique_ptr<DragAndDrop> mDragAndDrop;
|
||||||
|
std::unique_ptr<ItemTransfer> mItemTransfer;
|
||||||
InventoryWindow* mInventoryWindow;
|
InventoryWindow* mInventoryWindow;
|
||||||
ScrollWindow* mScrollWindow;
|
ScrollWindow* mScrollWindow;
|
||||||
BookWindow* mBookWindow;
|
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 "../birthsignbindings.hpp"
|
||||||
#include "../luamanagerimp.hpp"
|
#include "../luamanagerimp.hpp"
|
||||||
|
|
||||||
|
#include "apps/openmw/mwbase/dialoguemanager.hpp"
|
||||||
#include "apps/openmw/mwbase/inputmanager.hpp"
|
#include "apps/openmw/mwbase/inputmanager.hpp"
|
||||||
#include "apps/openmw/mwbase/journal.hpp"
|
#include "apps/openmw/mwbase/journal.hpp"
|
||||||
#include "apps/openmw/mwbase/mechanicsmanager.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.");
|
throw std::runtime_error("Only player and global scripts can toggle teleportation.");
|
||||||
MWBase::Environment::get().getWorld()->enableTeleporting(state);
|
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) {
|
player["sendMenuEvent"] = [context](const Object& player, std::string eventName, const sol::object& eventData) {
|
||||||
verifyPlayer(player);
|
verifyPlayer(player);
|
||||||
context.mLuaEvents->addMenuEvent({ std::move(eventName), LuaUtil::serialize(eventData) });
|
context.mLuaEvents->addMenuEvent({ std::move(eventName), LuaUtil::serialize(eventData) });
|
||||||
|
|
|
@ -244,6 +244,18 @@ namespace MWWorld
|
||||||
return std::abs(count);
|
return std::abs(count);
|
||||||
return 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);
|
void setCount(int value);
|
||||||
|
|
||||||
// Write the content of this CellRef into the given ObjectState
|
// Write the content of this CellRef into the given ObjectState
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
#ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
#ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
||||||
#define OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
#define OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "niffile.hpp"
|
#include "niffile.hpp"
|
||||||
|
@ -19,7 +17,7 @@ namespace Nif
|
||||||
InterpolationType_Unknown = 0,
|
InterpolationType_Unknown = 0,
|
||||||
InterpolationType_Linear = 1,
|
InterpolationType_Linear = 1,
|
||||||
InterpolationType_Quadratic = 2,
|
InterpolationType_Quadratic = 2,
|
||||||
InterpolationType_TCB = 3,
|
InterpolationType_TBC = 3,
|
||||||
InterpolationType_XYZ = 4,
|
InterpolationType_XYZ = 4,
|
||||||
InterpolationType_Constant = 5
|
InterpolationType_Constant = 5
|
||||||
};
|
};
|
||||||
|
@ -30,19 +28,18 @@ namespace Nif
|
||||||
T mValue;
|
T mValue;
|
||||||
T mInTan; // Only for Quadratic interpolation, and never for QuaternionKeyList
|
T mInTan; // Only for Quadratic interpolation, and never for QuaternionKeyList
|
||||||
T mOutTan; // Only for Quadratic interpolation, and never for QuaternionKeyList
|
T mOutTan; // Only for Quadratic interpolation, and never for QuaternionKeyList
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
// FIXME: Implement TBC interpolation
|
||||||
struct TCBKey
|
/*
|
||||||
{
|
float mTension; // Only for TBC interpolation
|
||||||
float mTime;
|
float mBias; // Only for TBC interpolation
|
||||||
T mValue{};
|
float mContinuity; // Only for TBC interpolation
|
||||||
T mInTan{};
|
*/
|
||||||
T mOutTan{};
|
|
||||||
float mTension;
|
|
||||||
float mContinuity;
|
|
||||||
float mBias;
|
|
||||||
};
|
};
|
||||||
|
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)()>
|
template <typename T, T (NIFStream::*getValue)()>
|
||||||
struct KeyMapT
|
struct KeyMapT
|
||||||
|
@ -104,20 +101,15 @@ namespace Nif
|
||||||
mKeys[time] = key;
|
mKeys[time] = key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInterpolationType == InterpolationType_TCB)
|
else if (mInterpolationType == InterpolationType_TBC)
|
||||||
{
|
{
|
||||||
std::vector<TCBKey<T>> tcbKeys(count);
|
for (size_t i = 0; i < count; i++)
|
||||||
for (TCBKey<T>& key : tcbKeys)
|
|
||||||
{
|
{
|
||||||
nif->read(key.mTime);
|
float time;
|
||||||
key.mValue = ((*nif).*getValue)();
|
nif->read(time);
|
||||||
nif->read(key.mTension);
|
readTBC(*nif, key);
|
||||||
nif->read(key.mContinuity);
|
mKeys[time] = key;
|
||||||
nif->read(key.mBias);
|
|
||||||
}
|
}
|
||||||
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)
|
else if (mInterpolationType == InterpolationType_XYZ)
|
||||||
{
|
{
|
||||||
|
@ -148,52 +140,12 @@ namespace Nif
|
||||||
|
|
||||||
static void readQuadratic(NIFStream& nif, KeyT<osg::Quat>& key) { readValue(nif, key); }
|
static void readQuadratic(NIFStream& nif, KeyT<osg::Quat>& key) { readValue(nif, key); }
|
||||||
|
|
||||||
template <typename U>
|
static void readTBC(NIFStream& nif, KeyT<T>& key)
|
||||||
static void generateTCBTangents(std::vector<TCBKey<U>>& keys)
|
|
||||||
{
|
{
|
||||||
if (keys.size() <= 1)
|
readValue(nif, key);
|
||||||
return;
|
/*key.mTension = */ nif.get<float>();
|
||||||
|
/*key.mBias = */ nif.get<float>();
|
||||||
std::sort(keys.begin(), keys.end(), [](const auto& a, const auto& b) { return a.mTime < b.mTime; });
|
/*key.mContinuity = */ nif.get<float>();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
using FloatKeyMap = KeyMapT<float, &NIFStream::get<float>>;
|
using FloatKeyMap = KeyMapT<float, &NIFStream::get<float>>;
|
||||||
|
|
|
@ -131,7 +131,6 @@ namespace NifOsg
|
||||||
case Nif::InterpolationType_Constant:
|
case Nif::InterpolationType_Constant:
|
||||||
return fraction > 0.5f ? b.mValue : a.mValue;
|
return fraction > 0.5f ? b.mValue : a.mValue;
|
||||||
case Nif::InterpolationType_Quadratic:
|
case Nif::InterpolationType_Quadratic:
|
||||||
case Nif::InterpolationType_TCB:
|
|
||||||
{
|
{
|
||||||
// Using a cubic Hermite spline.
|
// Using a cubic Hermite spline.
|
||||||
// b1(t) = 2t^3 - 3t^2 + 1
|
// b1(t) = 2t^3 - 3t^2 + 1
|
||||||
|
@ -148,6 +147,7 @@ namespace NifOsg
|
||||||
const float b4 = t3 - t2;
|
const float b4 = t3 - t2;
|
||||||
return a.mValue * b1 + b.mValue * b2 + a.mOutTan * b3 + b.mInTan * b4;
|
return a.mValue * b1 + b.mValue * b2 + a.mOutTan * b3 + b.mInTan * b4;
|
||||||
}
|
}
|
||||||
|
// TODO: Implement TBC interpolation
|
||||||
default:
|
default:
|
||||||
return a.mValue + ((b.mValue - a.mValue) * fraction);
|
return a.mValue + ((b.mValue - a.mValue) * fraction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
|
|
||||||
#include <MyGUI_Colour.h>
|
#include <MyGUI_Colour.h>
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
namespace Settings
|
namespace Settings
|
||||||
|
|
|
@ -98,7 +98,7 @@ GUI Settings
|
||||||
:type: boolean
|
:type: boolean
|
||||||
:range: true, false
|
:range: true, false
|
||||||
:default: true
|
:default: true
|
||||||
|
|
||||||
|
|
||||||
Enables or disables the red flash overlay when the character takes damage.
|
Enables or disables the red flash overlay when the character takes damage.
|
||||||
Disabling causes the player to "bleed" like NPCs.
|
Disabling causes the player to "bleed" like NPCs.
|
||||||
|
@ -108,7 +108,7 @@ GUI Settings
|
||||||
:type: boolean
|
:type: boolean
|
||||||
:range: true, false
|
:range: true, false
|
||||||
:default: true
|
:default: true
|
||||||
|
|
||||||
|
|
||||||
Enable or disable the werewolf visual effect in first-person mode.
|
Enable or disable the werewolf visual effect in first-person mode.
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ GUI Settings
|
||||||
:type: color
|
:type: color
|
||||||
:range: [0, 1]
|
:range: [0, 1]
|
||||||
:default: 0.15 0.0 0.0 1.0
|
:default: 0.15 0.0 0.0 1.0
|
||||||
|
|
||||||
|
|
||||||
Background color of tooltip and crosshair when hovering over an NPC-owned item.
|
Background color of tooltip and crosshair when hovering over an NPC-owned item.
|
||||||
Four floating point values: red, green, blue, alpha (alpha ignored).
|
Four floating point values: red, green, blue, alpha (alpha ignored).
|
||||||
|
@ -128,7 +128,7 @@ GUI Settings
|
||||||
:type: color
|
:type: color
|
||||||
:range: [0, 1]
|
:range: [0, 1]
|
||||||
:default: 1.0 0.15 0.15 1.0
|
:default: 1.0 0.15 0.15 1.0
|
||||||
|
|
||||||
|
|
||||||
Crosshair color when hovering over an NPC-owned item.
|
Crosshair color when hovering over an NPC-owned item.
|
||||||
Four floating point values: red, green, blue, alpha (alpha ignored).
|
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).
|
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
|
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>
|
(.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,
|
(see 'specular map pattern', t.ex. för en bastextur foo.dds,
|
||||||
ska spekularitetskartan heta foo_spec.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>
|
(.nif eller .osg fil). Påverkar objekt.</p></body></html></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -378,8 +378,8 @@ unarmed creature attacks damage armor = false
|
||||||
# 2 = Cylinder
|
# 2 = Cylinder
|
||||||
actor collision shape type = 0
|
actor collision shape type = 0
|
||||||
|
|
||||||
# When false the player character will base movement on animations. This will sway the camera
|
# 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
|
# while moving in third person like in vanilla, and reproduce movement bugs caused by glitchy
|
||||||
# vanilla animations.
|
# vanilla animations.
|
||||||
player movement ignores animation = false
|
player movement ignores animation = false
|
||||||
|
|
||||||
|
@ -1142,7 +1142,7 @@ xargonianswimknakf = meshes/xargonian_swimkna.kf
|
||||||
# Sky atmosphere mesh
|
# Sky atmosphere mesh
|
||||||
skyatmosphere = meshes/sky_atmosphere.nif
|
skyatmosphere = meshes/sky_atmosphere.nif
|
||||||
|
|
||||||
# Sky clouds mesh
|
# Sky clouds mesh
|
||||||
skyclouds = meshes/sky_clouds_01.nif
|
skyclouds = meshes/sky_clouds_01.nif
|
||||||
|
|
||||||
# Sky stars mesh 01
|
# Sky stars mesh 01
|
||||||
|
@ -1275,7 +1275,7 @@ right eye fov down = -0.8
|
||||||
|
|
||||||
[Post Processing]
|
[Post Processing]
|
||||||
|
|
||||||
# Enables post-processing
|
# Enables post-processing
|
||||||
enabled = false
|
enabled = false
|
||||||
|
|
||||||
# List of active shaders. This is more easily with the in-game shader HUD, by default accessible with the F2 key.
|
# 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