mirror of
https://github.com/OpenMW/openmw.git
synced 2025-11-08 22:46:39 +00:00
Merge branch 'master' of https://gitlab.com/OpenMW/openmw
This commit is contained in:
commit
64284063b3
11 changed files with 119 additions and 90 deletions
|
|
@ -39,8 +39,6 @@
|
||||||
#include "utils/profilescombobox.hpp"
|
#include "utils/profilescombobox.hpp"
|
||||||
#include "utils/textinputdialog.hpp"
|
#include "utils/textinputdialog.hpp"
|
||||||
|
|
||||||
#include "ui_directorypicker.h"
|
|
||||||
|
|
||||||
const char* Launcher::DataFilesPage::mDefaultContentListName = "Default";
|
const char* Launcher::DataFilesPage::mDefaultContentListName = "Default";
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
@ -155,6 +153,7 @@ namespace Launcher
|
||||||
Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
||||||
Config::LauncherSettings& launcherSettings, MainDialog* parent)
|
Config::LauncherSettings& launcherSettings, MainDialog* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
, mDirectoryPickerDialog(new QDialog(this))
|
||||||
, mMainDialog(parent)
|
, mMainDialog(parent)
|
||||||
, mCfgMgr(cfg)
|
, mCfgMgr(cfg)
|
||||||
, mGameSettings(gameSettings)
|
, mGameSettings(gameSettings)
|
||||||
|
|
@ -163,6 +162,7 @@ Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, C
|
||||||
, mReloadCellsThread(&DataFilesPage::reloadCells, this)
|
, mReloadCellsThread(&DataFilesPage::reloadCells, this)
|
||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
|
mDirectoryPicker.setupUi(mDirectoryPickerDialog);
|
||||||
setObjectName("DataFilesPage");
|
setObjectName("DataFilesPage");
|
||||||
mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true);
|
mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true);
|
||||||
const QString encoding = mGameSettings.value("encoding", { "win1252" }).value;
|
const QString encoding = mGameSettings.value("encoding", { "win1252" }).value;
|
||||||
|
|
@ -266,6 +266,7 @@ void Launcher::DataFilesPage::buildView()
|
||||||
|
|
||||||
buildArchiveContextMenu();
|
buildArchiveContextMenu();
|
||||||
buildDataFilesContextMenu();
|
buildDataFilesContextMenu();
|
||||||
|
buildDirectoryPickerContextMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotCopySelectedItemsPaths()
|
void Launcher::DataFilesPage::slotCopySelectedItemsPaths()
|
||||||
|
|
@ -298,8 +299,10 @@ void Launcher::DataFilesPage::buildArchiveContextMenu()
|
||||||
&DataFilesPage::slotShowArchiveContextMenu);
|
&DataFilesPage::slotShowArchiveContextMenu);
|
||||||
|
|
||||||
mArchiveContextMenu = new QMenu(ui.archiveListWidget);
|
mArchiveContextMenu = new QMenu(ui.archiveListWidget);
|
||||||
mArchiveContextMenu->addAction(tr("&Check Selected"), this, SLOT(slotCheckMultiSelectedItems()));
|
mArchiveContextMenu->addAction(tr("&Check Selected"), this,
|
||||||
mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this, SLOT(slotUncheckMultiSelectedItems()));
|
[this]() { setCheckStateForMultiSelectedItems(ui.archiveListWidget, Qt::Checked); });
|
||||||
|
mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this,
|
||||||
|
[this]() { setCheckStateForMultiSelectedItems(ui.archiveListWidget, Qt::Unchecked); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::buildDataFilesContextMenu()
|
void Launcher::DataFilesPage::buildDataFilesContextMenu()
|
||||||
|
|
@ -314,6 +317,18 @@ void Launcher::DataFilesPage::buildDataFilesContextMenu()
|
||||||
tr("&Open Path in File Explorer"), this, &Launcher::DataFilesPage::slotOpenSelectedItemsPaths);
|
tr("&Open Path in File Explorer"), this, &Launcher::DataFilesPage::slotOpenSelectedItemsPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::buildDirectoryPickerContextMenu()
|
||||||
|
{
|
||||||
|
connect(mDirectoryPicker.dirListWidget, &QListWidget::customContextMenuRequested, this,
|
||||||
|
&DataFilesPage::slotShowDirectoryPickerContextMenu);
|
||||||
|
|
||||||
|
mDirectoryPickerMenu = new QMenu(mDirectoryPicker.dirListWidget);
|
||||||
|
mDirectoryPickerMenu->addAction(tr("&Check Selected"), this,
|
||||||
|
[this]() { setCheckStateForMultiSelectedItems(mDirectoryPicker.dirListWidget, Qt::Checked); });
|
||||||
|
mDirectoryPickerMenu->addAction(tr("&Uncheck Selected"), this,
|
||||||
|
[this]() { setCheckStateForMultiSelectedItems(mDirectoryPicker.dirListWidget, Qt::Unchecked); });
|
||||||
|
}
|
||||||
|
|
||||||
bool Launcher::DataFilesPage::loadSettings()
|
bool Launcher::DataFilesPage::loadSettings()
|
||||||
{
|
{
|
||||||
ui.navMeshMaxSizeSpinBox->setValue(getMaxNavMeshDbFileSizeMiB());
|
ui.navMeshMaxSizeSpinBox->setValue(getMaxNavMeshDbFileSizeMiB());
|
||||||
|
|
@ -821,28 +836,22 @@ void Launcher::DataFilesPage::addSubdirectories(bool append)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog dialog;
|
mDirectoryPicker.dirListWidget->clear();
|
||||||
Ui::SelectSubdirs select;
|
|
||||||
|
|
||||||
select.setupUi(&dialog);
|
|
||||||
|
|
||||||
for (const auto& dir : subdirs)
|
for (const auto& dir : subdirs)
|
||||||
{
|
{
|
||||||
if (!ui.directoryListWidget->findItems(dir, Qt::MatchFixedString).isEmpty())
|
if (!ui.directoryListWidget->findItems(dir, Qt::MatchFixedString).isEmpty())
|
||||||
continue;
|
continue;
|
||||||
const auto lastRow = select.dirListWidget->count();
|
QListWidgetItem* newDir = new QListWidgetItem(dir, mDirectoryPicker.dirListWidget);
|
||||||
select.dirListWidget->addItem(dir);
|
newDir->setCheckState(Qt::Unchecked);
|
||||||
select.dirListWidget->item(lastRow)->setCheckState(Qt::Unchecked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.show();
|
if (mDirectoryPickerDialog->exec() == QDialog::Rejected)
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Rejected)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < select.dirListWidget->count(); ++i)
|
for (int i = 0; i < mDirectoryPicker.dirListWidget->count(); ++i)
|
||||||
{
|
{
|
||||||
const auto* dir = select.dirListWidget->item(i);
|
const auto* dir = mDirectoryPicker.dirListWidget->item(i);
|
||||||
if (dir->checkState() == Qt::Checked)
|
if (dir->checkState() == Qt::Checked)
|
||||||
{
|
{
|
||||||
ui.directoryListWidget->insertItem(selectedRow, dir->text());
|
ui.directoryListWidget->insertItem(selectedRow, dir->text());
|
||||||
|
|
@ -893,38 +902,35 @@ void Launcher::DataFilesPage::removeDirectory()
|
||||||
refreshDataFilesView();
|
refreshDataFilesView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::showContextMenu(QMenu* menu, QListWidget* list, const QPoint& pos)
|
||||||
|
{
|
||||||
|
QPoint globalPos = list->viewport()->mapToGlobal(pos);
|
||||||
|
menu->exec(globalPos);
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos)
|
void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
QPoint globalPos = ui.archiveListWidget->viewport()->mapToGlobal(pos);
|
showContextMenu(mArchiveContextMenu, ui.archiveListWidget, pos);
|
||||||
mArchiveContextMenu->exec(globalPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotShowDataFilesContextMenu(const QPoint& pos)
|
void Launcher::DataFilesPage::slotShowDataFilesContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
QPoint globalPos = ui.directoryListWidget->viewport()->mapToGlobal(pos);
|
showContextMenu(mDataFilesContextMenu, ui.directoryListWidget, pos);
|
||||||
mDataFilesContextMenu->exec(globalPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(bool checked)
|
void Launcher::DataFilesPage::slotShowDirectoryPickerContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
Qt::CheckState checkState = checked ? Qt::Checked : Qt::Unchecked;
|
showContextMenu(mDirectoryPickerMenu, mDirectoryPicker.dirListWidget, pos);
|
||||||
|
}
|
||||||
|
|
||||||
for (QListWidgetItem* selectedItem : ui.archiveListWidget->selectedItems())
|
void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(QListWidget* list, Qt::CheckState checkState)
|
||||||
|
{
|
||||||
|
for (QListWidgetItem* selectedItem : list->selectedItems())
|
||||||
{
|
{
|
||||||
selectedItem->setCheckState(checkState);
|
selectedItem->setCheckState(checkState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotUncheckMultiSelectedItems()
|
|
||||||
{
|
|
||||||
setCheckStateForMultiSelectedItems(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotCheckMultiSelectedItems()
|
|
||||||
{
|
|
||||||
setCheckStateForMultiSelectedItems(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::moveSources(QListWidget* sourceList, int step)
|
void Launcher::DataFilesPage::moveSources(QListWidget* sourceList, int step)
|
||||||
{
|
{
|
||||||
const QList<QPair<int, QListWidgetItem*>> sortedItems = sortedSelectedItems(sourceList, step > 0);
|
const QList<QPair<int, QListWidgetItem*>> sortedItems = sortedSelectedItems(sourceList, step > 0);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define DATAFILESPAGE_H
|
#define DATAFILESPAGE_H
|
||||||
|
|
||||||
#include "ui_datafilespage.h"
|
#include "ui_datafilespage.h"
|
||||||
|
#include "ui_directorypicker.h"
|
||||||
|
|
||||||
#include <components/process/processinvoker.hpp>
|
#include <components/process/processinvoker.hpp>
|
||||||
|
|
||||||
|
|
@ -46,8 +47,11 @@ namespace Launcher
|
||||||
|
|
||||||
ContentSelectorView::ContentSelector* mSelector;
|
ContentSelectorView::ContentSelector* mSelector;
|
||||||
Ui::DataFilesPage ui;
|
Ui::DataFilesPage ui;
|
||||||
|
QDialog* mDirectoryPickerDialog;
|
||||||
|
Ui::SelectSubdirs mDirectoryPicker;
|
||||||
QMenu* mArchiveContextMenu;
|
QMenu* mArchiveContextMenu;
|
||||||
QMenu* mDataFilesContextMenu;
|
QMenu* mDataFilesContextMenu;
|
||||||
|
QMenu* mDirectoryPickerMenu;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
||||||
|
|
@ -87,8 +91,7 @@ namespace Launcher
|
||||||
|
|
||||||
void slotShowArchiveContextMenu(const QPoint& pos);
|
void slotShowArchiveContextMenu(const QPoint& pos);
|
||||||
void slotShowDataFilesContextMenu(const QPoint& pos);
|
void slotShowDataFilesContextMenu(const QPoint& pos);
|
||||||
void slotCheckMultiSelectedItems();
|
void slotShowDirectoryPickerContextMenu(const QPoint& pos);
|
||||||
void slotUncheckMultiSelectedItems();
|
|
||||||
|
|
||||||
void on_newProfileAction_triggered();
|
void on_newProfileAction_triggered();
|
||||||
void on_cloneProfileAction_triggered();
|
void on_cloneProfileAction_triggered();
|
||||||
|
|
@ -145,7 +148,9 @@ namespace Launcher
|
||||||
void buildView();
|
void buildView();
|
||||||
void buildArchiveContextMenu();
|
void buildArchiveContextMenu();
|
||||||
void buildDataFilesContextMenu();
|
void buildDataFilesContextMenu();
|
||||||
void setCheckStateForMultiSelectedItems(bool checked);
|
void buildDirectoryPickerContextMenu();
|
||||||
|
void showContextMenu(QMenu* menu, QListWidget* list, const QPoint& pos);
|
||||||
|
void setCheckStateForMultiSelectedItems(QListWidget* list, Qt::CheckState checkState);
|
||||||
void setProfile(int index, bool savePrevious);
|
void setProfile(int index, bool savePrevious);
|
||||||
void setProfile(const QString& previous, const QString& current, bool savePrevious);
|
void setProfile(const QString& previous, const QString& current, bool savePrevious);
|
||||||
void removeProfile(const QString& profile);
|
void removeProfile(const QString& profile);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,14 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QListWidget" name="dirListWidget"/>
|
<widget class="QListWidget" name="dirListWidget">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
||||||
|
|
@ -406,17 +406,16 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||||
|
|
||||||
enum RestPermitted
|
enum RestFlags
|
||||||
{
|
{
|
||||||
Rest_Allowed = 0,
|
Rest_PlayerIsUnderwater = 1,
|
||||||
Rest_OnlyWaiting = 1,
|
|
||||||
Rest_PlayerIsInAir = 2,
|
Rest_PlayerIsInAir = 2,
|
||||||
Rest_PlayerIsUnderwater = 3,
|
Rest_EnemiesAreNearby = 4,
|
||||||
Rest_EnemiesAreNearby = 4
|
Rest_CanSleep = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// check if the player is allowed to rest
|
/// check if the player is allowed to rest
|
||||||
virtual RestPermitted canRest() const = 0;
|
virtual int canRest() const = 0;
|
||||||
|
|
||||||
/// \todo Probably shouldn't be here
|
/// \todo Probably shouldn't be here
|
||||||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr& ptr) = 0;
|
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,8 @@ namespace MWGui
|
||||||
|
|
||||||
mGuiMode = mode;
|
mGuiMode = mode;
|
||||||
const WindowSettingValues settings = getModeSettings(mGuiMode);
|
const WindowSettingValues settings = getModeSettings(mGuiMode);
|
||||||
setPinButtonVisible(mode == GM_Inventory && !Settings::gui().mControllerMenus);
|
setPinButtonVisible(
|
||||||
|
mode != GM_Container && mode != GM_Companion && mode != GM_Barter && !Settings::gui().mControllerMenus);
|
||||||
|
|
||||||
const WindowRectSettingValues& rect = settings.mIsMaximized ? settings.mMaximized : settings.mRegular;
|
const WindowRectSettingValues& rect = settings.mIsMaximized ? settings.mMaximized : settings.mRegular;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <MyGUI_Gui.h>
|
#include <MyGUI_Gui.h>
|
||||||
#include <MyGUI_ScrollView.h>
|
#include <MyGUI_ScrollView.h>
|
||||||
|
|
||||||
|
#include <components/debug/debuglog.hpp>
|
||||||
#include <components/esm3/loadcrea.hpp>
|
#include <components/esm3/loadcrea.hpp>
|
||||||
#include <components/esm3/loadgmst.hpp>
|
#include <components/esm3/loadgmst.hpp>
|
||||||
#include <components/misc/strings/conversion.hpp>
|
#include <components/misc/strings/conversion.hpp>
|
||||||
|
|
@ -71,9 +72,6 @@ namespace MWGui
|
||||||
price = static_cast<int>(d);
|
price = static_cast<int>(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
price = std::max(1, price);
|
|
||||||
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
|
||||||
|
|
||||||
// Add price for the travelling followers
|
// Add price for the travelling followers
|
||||||
std::set<MWWorld::Ptr> followers;
|
std::set<MWWorld::Ptr> followers;
|
||||||
MWWorld::ActionTeleport::getFollowers(player, followers, !interior);
|
MWWorld::ActionTeleport::getFollowers(player, followers, !interior);
|
||||||
|
|
@ -81,6 +79,9 @@ namespace MWGui
|
||||||
// Apply followers cost, unlike vanilla the first follower doesn't travel for free
|
// Apply followers cost, unlike vanilla the first follower doesn't travel for free
|
||||||
price *= 1 + static_cast<int>(followers.size());
|
price *= 1 + static_cast<int>(followers.size());
|
||||||
|
|
||||||
|
price = std::max(1, price);
|
||||||
|
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
|
||||||
|
|
||||||
const int lineHeight = Settings::gui().mFontSize + 2;
|
const int lineHeight = Settings::gui().mFontSize + 2;
|
||||||
|
|
||||||
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>(
|
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>(
|
||||||
|
|
@ -134,12 +135,23 @@ namespace MWGui
|
||||||
bool interior = true;
|
bool interior = true;
|
||||||
const ESM::ExteriorCellLocation cellIndex
|
const ESM::ExteriorCellLocation cellIndex
|
||||||
= ESM::positionToExteriorCellLocation(dest.mPos.pos[0], dest.mPos.pos[1]);
|
= ESM::positionToExteriorCellLocation(dest.mPos.pos[0], dest.mPos.pos[1]);
|
||||||
|
const MWWorld::WorldModel& worldModel = *MWBase::Environment::get().getWorldModel();
|
||||||
if (cellname.empty())
|
if (cellname.empty())
|
||||||
{
|
{
|
||||||
MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex);
|
MWWorld::CellStore& cell = worldModel.getExterior(cellIndex);
|
||||||
cellname = MWBase::Environment::get().getWorld()->getCellName(&cell);
|
cellname = MWBase::Environment::get().getWorld()->getCellName(&cell);
|
||||||
interior = false;
|
interior = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const MWWorld::CellStore* destCell = worldModel.findCell(cellname, false);
|
||||||
|
if (destCell == nullptr)
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "Failed to add travel destination: unknown cell (" << cellname << ")";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
interior = !destCell->getCell()->isExterior();
|
||||||
|
}
|
||||||
addDestination(ESM::RefId::stringRefId(cellname), dest.mPos, interior);
|
addDestination(ESM::RefId::stringRefId(cellname), dest.mPos, interior);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,15 +87,29 @@ namespace MWGui
|
||||||
|
|
||||||
void WaitDialog::setPtr(const MWWorld::Ptr& ptr)
|
void WaitDialog::setPtr(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
setCanRest(!ptr.isEmpty() || MWBase::Environment::get().getWorld()->canRest() == MWBase::World::Rest_Allowed);
|
const int restFlags = MWBase::Environment::get().getWorld()->canRest();
|
||||||
|
|
||||||
if (ptr.isEmpty() && MWBase::Environment::get().getWorld()->canRest() == MWBase::World::Rest_PlayerIsInAir)
|
const bool underwater = (restFlags & MWBase::World::Rest_PlayerIsUnderwater) != 0;
|
||||||
|
// Resting in air is allowed if you're using a bed
|
||||||
|
const bool inAir = ptr.isEmpty() && (restFlags & MWBase::World::Rest_PlayerIsInAir) != 0;
|
||||||
|
const bool enemiesNearby = (restFlags & MWBase::World::Rest_EnemiesAreNearby) != 0;
|
||||||
|
const bool solidGround = !underwater && !inAir;
|
||||||
|
|
||||||
|
if (!solidGround || enemiesNearby)
|
||||||
{
|
{
|
||||||
// Resting in air is not allowed unless you're using a bed
|
if (!solidGround)
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}");
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest);
|
|
||||||
|
if (enemiesNearby)
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}");
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool canSleep = !ptr.isEmpty() || (restFlags & MWBase::World::Rest_CanSleep) != 0;
|
||||||
|
setCanRest(canSleep);
|
||||||
|
|
||||||
if (mUntilHealedButton->getVisible())
|
if (mUntilHealedButton->getVisible())
|
||||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton);
|
||||||
else
|
else
|
||||||
|
|
@ -141,20 +155,6 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
MWBase::World::RestPermitted canRest = MWBase::Environment::get().getWorld()->canRest();
|
|
||||||
|
|
||||||
if (canRest == MWBase::World::Rest_EnemiesAreNearby)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}");
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
|
||||||
}
|
|
||||||
else if (canRest == MWBase::World::Rest_PlayerIsUnderwater)
|
|
||||||
{
|
|
||||||
// resting underwater not allowed
|
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}");
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
onHourSliderChangedPosition(mHourSlider, 0);
|
onHourSliderChangedPosition(mHourSlider, 0);
|
||||||
mHourSlider->setScrollPosition(0);
|
mHourSlider->setScrollPosition(0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -274,15 +274,15 @@ namespace MWMechanics
|
||||||
|
|
||||||
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
||||||
|
|
||||||
if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Silence).getMagnitude() && !godmode)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (spell->mData.mType == ESM::Spell::ST_Power)
|
if (spell->mData.mType == ESM::Spell::ST_Power)
|
||||||
return stats.getSpells().canUsePower(spell) ? 100 : 0;
|
return stats.getSpells().canUsePower(spell) ? 100 : 0;
|
||||||
|
|
||||||
if (godmode)
|
if (godmode)
|
||||||
return 100;
|
return 100;
|
||||||
|
|
||||||
|
if (stats.getMagicEffects().getOrDefault(ESM::MagicEffect::Silence).getMagnitude())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (spell->mData.mType != ESM::Spell::ST_Spell)
|
if (spell->mData.mType != ESM::Spell::ST_Spell)
|
||||||
return 100;
|
return 100;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -656,20 +656,18 @@ namespace MWPhysics
|
||||||
auto ptr = physicActor->getPtr();
|
auto ptr = physicActor->getPtr();
|
||||||
if (!ptr.getClass().isMobile(ptr))
|
if (!ptr.getClass().isMobile(ptr))
|
||||||
continue;
|
continue;
|
||||||
float waterlevel = -std::numeric_limits<float>::max();
|
|
||||||
const MWWorld::CellStore* cell = ptr.getCell();
|
|
||||||
if (cell->getCell()->hasWater())
|
|
||||||
waterlevel = cell->getWaterLevel();
|
|
||||||
|
|
||||||
|
const MWWorld::CellStore& cell = *ptr.getCell();
|
||||||
const auto& stats = ptr.getClass().getCreatureStats(ptr);
|
const auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
const MWMechanics::MagicEffects& effects = stats.getMagicEffects();
|
const MWMechanics::MagicEffects& effects = stats.getMagicEffects();
|
||||||
|
|
||||||
|
float waterlevel = -std::numeric_limits<float>::max();
|
||||||
bool waterCollision = false;
|
bool waterCollision = false;
|
||||||
if (cell->getCell()->hasWater() && effects.getOrDefault(ESM::MagicEffect::WaterWalking).getMagnitude())
|
if (cell.getCell()->hasWater())
|
||||||
{
|
{
|
||||||
if (physicActor->getCollisionMode()
|
waterlevel = cell.getWaterLevel();
|
||||||
|| !world->isUnderwater(ptr.getCell(), ptr.getRefData().getPosition().asVec3()))
|
if (physicActor->getCollisionMode())
|
||||||
waterCollision = true;
|
waterCollision = effects.getOrDefault(ESM::MagicEffect::WaterWalking).getMagnitude();
|
||||||
}
|
}
|
||||||
|
|
||||||
physicActor->setCanWaterWalk(waterCollision);
|
physicActor->setCanWaterWalk(waterCollision);
|
||||||
|
|
|
||||||
|
|
@ -2333,34 +2333,35 @@ namespace MWWorld
|
||||||
Log(Debug::Warning) << "Player agent bounds are not supported by navigator: " << agentBounds;
|
Log(Debug::Warning) << "Player agent bounds are not supported by navigator: " << agentBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
World::RestPermitted World::canRest() const
|
int World::canRest() const
|
||||||
{
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
CellStore* currentCell = mWorldScene->getCurrentCell();
|
CellStore* currentCell = mWorldScene->getCurrentCell();
|
||||||
|
|
||||||
Ptr player = mPlayer->getPlayer();
|
Ptr player = mPlayer->getPlayer();
|
||||||
RefData& refdata = player.getRefData();
|
|
||||||
osg::Vec3f playerPos(refdata.getPosition().asVec3());
|
|
||||||
|
|
||||||
const MWPhysics::Actor* actor = mPhysics->getActor(player);
|
const MWPhysics::Actor* actor = mPhysics->getActor(player);
|
||||||
if (!actor)
|
if (!actor)
|
||||||
throw std::runtime_error("can't find player");
|
throw std::runtime_error("can't find player");
|
||||||
|
|
||||||
if (mPlayer->enemiesNearby())
|
const osg::Vec3f playerPos(player.getRefData().getPosition().asVec3());
|
||||||
return Rest_EnemiesAreNearby;
|
|
||||||
|
|
||||||
if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
||||||
return Rest_PlayerIsUnderwater;
|
result |= Rest_PlayerIsUnderwater;
|
||||||
|
|
||||||
float fallHeight = player.getClass().getCreatureStats(player).getFallHeight();
|
float fallHeight = player.getClass().getCreatureStats(player).getFallHeight();
|
||||||
float epsilon = 1e-4;
|
float epsilon = 1e-4;
|
||||||
if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon))
|
if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon))
|
||||||
|| isFlying(player))
|
|| isFlying(player))
|
||||||
return Rest_PlayerIsInAir;
|
result |= Rest_PlayerIsInAir;
|
||||||
|
|
||||||
if (currentCell->getCell()->noSleep() || player.getClass().getNpcStats(player).isWerewolf())
|
if (mPlayer->enemiesNearby())
|
||||||
return Rest_OnlyWaiting;
|
result |= Rest_EnemiesAreNearby;
|
||||||
|
|
||||||
return Rest_Allowed;
|
if (!currentCell->getCell()->noSleep() && !player.getClass().getNpcStats(player).isWerewolf())
|
||||||
|
result |= Rest_CanSleep;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWRender::Animation* World::getAnimation(const MWWorld::Ptr& ptr)
|
MWRender::Animation* World::getAnimation(const MWWorld::Ptr& ptr)
|
||||||
|
|
|
||||||
|
|
@ -505,7 +505,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void enableActorCollision(const MWWorld::Ptr& actor, bool enable) override;
|
void enableActorCollision(const MWWorld::Ptr& actor, bool enable) override;
|
||||||
|
|
||||||
RestPermitted canRest() const override;
|
int canRest() const override;
|
||||||
///< check if the player is allowed to rest
|
///< check if the player is allowed to rest
|
||||||
|
|
||||||
void rest(double hours) override;
|
void rest(double hours) override;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue