1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-31 04:06:40 +00:00

Merge branch 'master' into menuscripts

This commit is contained in:
uramer 2024-01-10 23:21:42 +01:00
commit 4ed2af7666
88 changed files with 521 additions and 595 deletions

View file

@ -64,6 +64,7 @@
Bug #7084: Resurrecting an actor doesn't take into account base record changes
Bug #7088: Deleting last save game of last character doesn't clear character name/details
Bug #7092: BSA archives from higher priority directories don't take priority
Bug #7103: Multiple paths pointing to the same plugin but with different cases lead to automatically removed config entries
Bug #7122: Teleportation to underwater should cancel active water walking effect
Bug #7131: MyGUI log spam when post processing HUD is open
Bug #7134: Saves with an invalid last generated RefNum can be loaded
@ -99,6 +100,7 @@
Bug #7604: Goblins Grunt becomes idle once injured
Bug #7609: ForceGreeting should not open dialogue for werewolves
Bug #7611: Beast races' idle animations slide after turning or jumping in place
Bug #7617: The death prompt asks the player if they wanted to load the character's last created save
Bug #7619: Long map notes may get cut off
Bug #7630: Charm can be cast on creatures
Bug #7631: Cannot trade with/talk to Creeper or Mudcrab Merchant when they're fleeing
@ -121,8 +123,10 @@
Bug #7712: Casting doesn't support spells and enchantments with no effects
Bug #7723: Assaulting vampires and werewolves shouldn't be a crime
Bug #7724: Guards don't help vs werewolves
Bug #7733: Launcher shows incorrect data paths when there's two plugins with the same name
Bug #7742: Governing attribute training limit should use the modified attribute
Bug #7758: Water walking is not taken into account to compute path cost on the water
Bug #7761: Rain and ambient loop sounds are mutually exclusive
Feature #2566: Handle NAM9 records for manual cell references
Feature #3537: Shader-based water ripples
Feature #5173: Support for NiFogProperty

View file

@ -19,9 +19,8 @@ command -v cmake >/dev/null 2>&1 || brew install cmake
command -v qmake >/dev/null 2>&1 || brew install qt@5
export PATH="/opt/homebrew/opt/qt@5/bin:$PATH"
# Install deps
brew install icu4c yaml-cpp sqlite
brew install openal-soft icu4c yaml-cpp sqlite
ccache --version
cmake --version

View file

@ -10,12 +10,13 @@ DEPENDENCIES_ROOT="/tmp/openmw-deps"
QT_PATH=$(brew --prefix qt@5)
ICU_PATH=$(brew --prefix icu4c)
OPENAL_PATH=$(brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
mkdir build
cd build
cmake \
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH" \
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH" \
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \
-D CMAKE_CXX_FLAGS="-stdlib=libc++" \

View file

@ -54,6 +54,7 @@ IF(NOT CMAKE_BUILD_TYPE)
ENDIF()
if (APPLE)
set(CMAKE_FIND_FRAMEWORK LAST) # prefer dylibs over frameworks
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")

View file

@ -125,27 +125,6 @@ namespace Launcher
{
return Settings::navigator().mMaxNavmeshdbFileSize / (1024 * 1024);
}
std::optional<QString> findFirstPath(const QStringList& directories, const QString& fileName)
{
for (const QString& directoryPath : directories)
{
const QString filePath = QDir(directoryPath).absoluteFilePath(fileName);
if (QFile::exists(filePath))
return filePath;
}
return std::nullopt;
}
QStringList findAllFilePaths(const QStringList& directories, const QStringList& fileNames)
{
QStringList result;
result.reserve(fileNames.size());
for (const QString& fileName : fileNames)
if (const auto filepath = findFirstPath(directories, fileName))
result.append(*filepath);
return result;
}
}
}
@ -366,8 +345,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
row++;
}
mSelector->setProfileContent(
findAllFilePaths(directories, mLauncherSettings.getContentListFiles(contentModelName)));
mSelector->setProfileContent(mLauncherSettings.getContentListFiles(contentModelName));
}
void Launcher::DataFilesPage::saveSettings(const QString& profile)

View file

@ -154,7 +154,7 @@ bool Launcher::GraphicsPage::loadSettings()
if (Settings::shadows().mEnableIndoorShadows)
indoorShadowsCheckBox->setCheckState(Qt::Checked);
auto boundMethod = Settings::shadows().mComputeSceneBounds.get();
const auto& boundMethod = Settings::shadows().mComputeSceneBounds.get();
if (boundMethod == "bounds")
shadowComputeSceneBoundsComboBox->setCurrentIndex(0);
else if (boundMethod == "primitives")

View file

@ -1,7 +1,7 @@
#include <cstring>
#include <vector>
#include <apps/openmw/mwsound/alext.h>
#include "apps/openmw/mwsound/alext.h"
#include "openalutil.hpp"

View file

@ -1,5 +1,4 @@
set (OPENCS_SRC
${CMAKE_SOURCE_DIR}/files/windows/opencs.rc
)
opencs_units (. editor)
@ -146,6 +145,9 @@ source_group (openmw-cs FILES main.cpp ${OPENCS_SRC} ${OPENCS_HDR})
if(WIN32)
set(QT_USE_QTMAIN TRUE)
set(OPENCS_RC_FILE ${CMAKE_SOURCE_DIR}/files/windows/opencs.rc)
else(WIN32)
set(OPENCS_RC_FILE "")
endif(WIN32)
if (QT_VERSION_MAJOR VERSION_EQUAL 5)
@ -186,6 +188,7 @@ if(BUILD_OPENCS)
${OPENCS_CFG}
${OPENCS_DEFAULT_FILTERS_FILE}
${OPENCS_OPENMW_CFG}
${OPENCS_RC_FILE}
main.cpp
)

View file

@ -14,7 +14,7 @@
#include "state.hpp"
CSMPrefs::ColourSetting::ColourSetting(
Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index)
Category* parent, QMutex* mutex, std::string_view key, const QString& label, Settings::Index& index)
: TypedSetting(parent, mutex, key, label, index)
, mWidget(nullptr)
{

View file

@ -6,6 +6,7 @@
#include <QColor>
#include <string>
#include <string_view>
#include <utility>
class QMutex;
@ -30,7 +31,7 @@ namespace CSMPrefs
public:
explicit ColourSetting(
Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index);
Category* parent, QMutex* mutex, std::string_view key, const QString& label, Settings::Index& index);
ColourSetting& setTooltip(const std::string& tooltip);

View file

@ -43,7 +43,7 @@ namespace CSMPrefs
mEventHandler->removeShortcut(shortcut);
}
bool ShortcutManager::getSequence(const std::string& name, QKeySequence& sequence) const
bool ShortcutManager::getSequence(std::string_view name, QKeySequence& sequence) const
{
SequenceMap::const_iterator item = mSequences.find(name);
if (item != mSequences.end())
@ -56,7 +56,7 @@ namespace CSMPrefs
return false;
}
void ShortcutManager::setSequence(const std::string& name, const QKeySequence& sequence)
void ShortcutManager::setSequence(std::string_view name, const QKeySequence& sequence)
{
// Add to map/modify
SequenceMap::iterator item = mSequences.find(name);

View file

@ -28,8 +28,8 @@ namespace CSMPrefs
/// The shortcut class will do this automatically
void removeShortcut(Shortcut* shortcut);
bool getSequence(const std::string& name, QKeySequence& sequence) const;
void setSequence(const std::string& name, const QKeySequence& sequence);
bool getSequence(std::string_view name, QKeySequence& sequence) const;
void setSequence(std::string_view name, const QKeySequence& sequence);
bool getModifier(const std::string& name, int& modifier) const;
void setModifier(std::string_view name, int modifier);
@ -50,7 +50,7 @@ namespace CSMPrefs
private:
// Need a multimap in case multiple shortcuts share the same name
typedef std::multimap<std::string, Shortcut*, std::less<>> ShortcutMap;
typedef std::map<std::string, QKeySequence> SequenceMap;
typedef std::map<std::string, QKeySequence, std::less<>> SequenceMap;
typedef std::map<std::string, int, std::less<>> ModifierMap;
typedef std::map<int, std::string> NameMap;
typedef std::map<std::string, int> KeyMap;

View file

@ -19,7 +19,7 @@
namespace CSMPrefs
{
ShortcutSetting::ShortcutSetting(
Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index)
Category* parent, QMutex* mutex, std::string_view key, const QString& label, Settings::Index& index)
: TypedSetting(parent, mutex, key, label, index)
, mButton(nullptr)
, mEditorActive(false)

View file

@ -2,6 +2,7 @@
#define CSM_PREFS_SHORTCUTSETTING_H
#include <string>
#include <string_view>
#include <utility>
#include <QKeySequence>
@ -24,7 +25,7 @@ namespace CSMPrefs
public:
explicit ShortcutSetting(
Category* parent, QMutex* mutex, const std::string& key, const QString& label, Settings::Index& index);
Category* parent, QMutex* mutex, std::string_view key, const QString& label, Settings::Index& index);
SettingWidgets makeWidgets(QWidget* parent) override;

View file

@ -126,14 +126,14 @@ void CSMPrefs::State::declare()
.setRange(0, 10000);
declareInt(mValues->mScripts.mErrorHeight, "Initial height of the error panel").setRange(100, 10000);
declareBool(mValues->mScripts.mHighlightOccurrences, "Highlight other occurrences of selected names");
declareColour("colour-highlight", "Colour of highlighted occurrences", QColor("lightcyan"));
declareColour("colour-int", "Highlight Colour: Integer Literals", QColor("darkmagenta"));
declareColour("colour-float", "Highlight Colour: Float Literals", QColor("magenta"));
declareColour("colour-name", "Highlight Colour: Names", QColor("grey"));
declareColour("colour-keyword", "Highlight Colour: Keywords", QColor("red"));
declareColour("colour-special", "Highlight Colour: Special Characters", QColor("darkorange"));
declareColour("colour-comment", "Highlight Colour: Comments", QColor("green"));
declareColour("colour-id", "Highlight Colour: IDs", QColor("blue"));
declareColour(mValues->mScripts.mColourHighlight, "Colour of highlighted occurrences");
declareColour(mValues->mScripts.mColourInt, "Highlight Colour: Integer Literals");
declareColour(mValues->mScripts.mColourFloat, "Highlight Colour: Float Literals");
declareColour(mValues->mScripts.mColourName, "Highlight Colour: Names");
declareColour(mValues->mScripts.mColourKeyword, "Highlight Colour: Keywords");
declareColour(mValues->mScripts.mColourSpecial, "Highlight Colour: Special Characters");
declareColour(mValues->mScripts.mColourComment, "Highlight Colour: Comments");
declareColour(mValues->mScripts.mColourId, "Highlight Colour: IDs");
declareCategory("General Input");
declareBool(mValues->mGeneralInput.mCycle, "Cyclic next/previous")
@ -185,18 +185,18 @@ void CSMPrefs::State::declare()
.setRange(10, 10000);
declareDouble(mValues->mRendering.mObjectMarkerAlpha, "Object Marker Transparency").setPrecision(2).setRange(0, 1);
declareBool(mValues->mRendering.mSceneUseGradient, "Use Gradient Background");
declareColour("scene-day-background-colour", "Day Background Colour", QColor(110, 120, 128, 255));
declareColour("scene-day-gradient-colour", "Day Gradient Colour", QColor(47, 51, 51, 255))
declareColour(mValues->mRendering.mSceneDayBackgroundColour, "Day Background Colour");
declareColour(mValues->mRendering.mSceneDayGradientColour, "Day Gradient Colour")
.setTooltip(
"Sets the gradient color to use in conjunction with the day background color. Ignored if "
"the gradient option is disabled.");
declareColour("scene-bright-background-colour", "Scene Bright Background Colour", QColor(79, 87, 92, 255));
declareColour("scene-bright-gradient-colour", "Scene Bright Gradient Colour", QColor(47, 51, 51, 255))
declareColour(mValues->mRendering.mSceneBrightBackgroundColour, "Scene Bright Background Colour");
declareColour(mValues->mRendering.mSceneBrightGradientColour, "Scene Bright Gradient Colour")
.setTooltip(
"Sets the gradient color to use in conjunction with the bright background color. Ignored if "
"the gradient option is disabled.");
declareColour("scene-night-background-colour", "Scene Night Background Colour", QColor(64, 77, 79, 255));
declareColour("scene-night-gradient-colour", "Scene Night Gradient Colour", QColor(47, 51, 51, 255))
declareColour(mValues->mRendering.mSceneNightBackgroundColour, "Scene Night Background Colour");
declareColour(mValues->mRendering.mSceneNightGradientColour, "Scene Night Gradient Colour")
.setTooltip(
"Sets the gradient color to use in conjunction with the night background color. Ignored if "
"the gradient option is disabled.");
@ -250,157 +250,154 @@ void CSMPrefs::State::declare()
declareCategory("Key Bindings");
declareSubcategory("Document");
declareShortcut("document-file-newgame", "New Game", QKeySequence(Qt::ControlModifier | Qt::Key_N));
declareShortcut("document-file-newaddon", "New Addon", QKeySequence());
declareShortcut("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O));
declareShortcut("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S));
declareShortcut("document-help-help", "Help", QKeySequence(Qt::Key_F1));
declareShortcut("document-help-tutorial", "Tutorial", QKeySequence());
declareShortcut("document-file-verify", "Verify", QKeySequence());
declareShortcut("document-file-merge", "Merge", QKeySequence());
declareShortcut("document-file-errorlog", "Open Load Error Log", QKeySequence());
declareShortcut("document-file-metadata", "Meta Data", QKeySequence());
declareShortcut("document-file-close", "Close Document", QKeySequence(Qt::ControlModifier | Qt::Key_W));
declareShortcut("document-file-exit", "Exit Application", QKeySequence(Qt::ControlModifier | Qt::Key_Q));
declareShortcut("document-edit-undo", "Undo", QKeySequence(Qt::ControlModifier | Qt::Key_Z));
declareShortcut("document-edit-redo", "Redo", QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Z));
declareShortcut("document-edit-preferences", "Open Preferences", QKeySequence());
declareShortcut("document-edit-search", "Search", QKeySequence(Qt::ControlModifier | Qt::Key_F));
declareShortcut("document-view-newview", "New View", QKeySequence());
declareShortcut("document-view-statusbar", "Toggle Status Bar", QKeySequence());
declareShortcut("document-view-filters", "Open Filter List", QKeySequence());
declareShortcut("document-world-regions", "Open Region List", QKeySequence());
declareShortcut("document-world-cells", "Open Cell List", QKeySequence());
declareShortcut("document-world-referencables", "Open Object List", QKeySequence());
declareShortcut("document-world-references", "Open Instance List", QKeySequence());
declareShortcut("document-world-lands", "Open Lands List", QKeySequence());
declareShortcut("document-world-landtextures", "Open Land Textures List", QKeySequence());
declareShortcut("document-world-pathgrid", "Open Pathgrid List", QKeySequence());
declareShortcut("document-world-regionmap", "Open Region Map", QKeySequence());
declareShortcut("document-mechanics-globals", "Open Global List", QKeySequence());
declareShortcut("document-mechanics-gamesettings", "Open Game Settings", QKeySequence());
declareShortcut("document-mechanics-scripts", "Open Script List", QKeySequence());
declareShortcut("document-mechanics-spells", "Open Spell List", QKeySequence());
declareShortcut("document-mechanics-enchantments", "Open Enchantment List", QKeySequence());
declareShortcut("document-mechanics-magiceffects", "Open Magic Effect List", QKeySequence());
declareShortcut("document-mechanics-startscripts", "Open Start Script List", QKeySequence());
declareShortcut("document-character-skills", "Open Skill List", QKeySequence());
declareShortcut("document-character-classes", "Open Class List", QKeySequence());
declareShortcut("document-character-factions", "Open Faction List", QKeySequence());
declareShortcut("document-character-races", "Open Race List", QKeySequence());
declareShortcut("document-character-birthsigns", "Open Birthsign List", QKeySequence());
declareShortcut("document-character-topics", "Open Topic List", QKeySequence());
declareShortcut("document-character-journals", "Open Journal List", QKeySequence());
declareShortcut("document-character-topicinfos", "Open Topic Info List", QKeySequence());
declareShortcut("document-character-journalinfos", "Open Journal Info List", QKeySequence());
declareShortcut("document-character-bodyparts", "Open Body Part List", QKeySequence());
declareShortcut("document-assets-reload", "Reload Assets", QKeySequence(Qt::Key_F5));
declareShortcut("document-assets-sounds", "Open Sound Asset List", QKeySequence());
declareShortcut("document-assets-soundgens", "Open Sound Generator List", QKeySequence());
declareShortcut("document-assets-meshes", "Open Mesh Asset List", QKeySequence());
declareShortcut("document-assets-icons", "Open Icon Asset List", QKeySequence());
declareShortcut("document-assets-music", "Open Music Asset List", QKeySequence());
declareShortcut("document-assets-soundres", "Open Sound File List", QKeySequence());
declareShortcut("document-assets-textures", "Open Texture Asset List", QKeySequence());
declareShortcut("document-assets-videos", "Open Video Asset List", QKeySequence());
declareShortcut("document-debug-run", "Run Debug", QKeySequence());
declareShortcut("document-debug-shutdown", "Stop Debug", QKeySequence());
declareShortcut("document-debug-profiles", "Debug Profiles", QKeySequence());
declareShortcut("document-debug-runlog", "Open Run Log", QKeySequence());
declareShortcut(mValues->mKeyBindings.mDocumentFileNewgame, "New Game");
declareShortcut(mValues->mKeyBindings.mDocumentFileNewaddon, "New Addon");
declareShortcut(mValues->mKeyBindings.mDocumentFileOpen, "Open");
declareShortcut(mValues->mKeyBindings.mDocumentFileSave, "Save");
declareShortcut(mValues->mKeyBindings.mDocumentHelpHelp, "Help");
declareShortcut(mValues->mKeyBindings.mDocumentHelpTutorial, "Tutorial");
declareShortcut(mValues->mKeyBindings.mDocumentFileVerify, "Verify");
declareShortcut(mValues->mKeyBindings.mDocumentFileMerge, "Merge");
declareShortcut(mValues->mKeyBindings.mDocumentFileErrorlog, "Open Load Error Log");
declareShortcut(mValues->mKeyBindings.mDocumentFileMetadata, "Meta Data");
declareShortcut(mValues->mKeyBindings.mDocumentFileClose, "Close Document");
declareShortcut(mValues->mKeyBindings.mDocumentFileExit, "Exit Application");
declareShortcut(mValues->mKeyBindings.mDocumentEditUndo, "Undo");
declareShortcut(mValues->mKeyBindings.mDocumentEditRedo, "Redo");
declareShortcut(mValues->mKeyBindings.mDocumentEditPreferences, "Open Preferences");
declareShortcut(mValues->mKeyBindings.mDocumentEditSearch, "Search");
declareShortcut(mValues->mKeyBindings.mDocumentViewNewview, "New View");
declareShortcut(mValues->mKeyBindings.mDocumentViewStatusbar, "Toggle Status Bar");
declareShortcut(mValues->mKeyBindings.mDocumentViewFilters, "Open Filter List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldRegions, "Open Region List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldCells, "Open Cell List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldReferencables, "Open Object List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldReferences, "Open Instance List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldLands, "Open Lands List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldLandtextures, "Open Land Textures List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldPathgrid, "Open Pathgrid List");
declareShortcut(mValues->mKeyBindings.mDocumentWorldRegionmap, "Open Region Map");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsGlobals, "Open Global List");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsGamesettings, "Open Game Settings");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsScripts, "Open Script List");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsSpells, "Open Spell List");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsEnchantments, "Open Enchantment List");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsMagiceffects, "Open Magic Effect List");
declareShortcut(mValues->mKeyBindings.mDocumentMechanicsStartscripts, "Open Start Script List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterSkills, "Open Skill List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterClasses, "Open Class List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterFactions, "Open Faction List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterRaces, "Open Race List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterBirthsigns, "Open Birthsign List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterTopics, "Open Topic List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterJournals, "Open Journal List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterTopicinfos, "Open Topic Info List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterJournalinfos, "Open Journal Info List");
declareShortcut(mValues->mKeyBindings.mDocumentCharacterBodyparts, "Open Body Part List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsReload, "Reload Assets");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsSounds, "Open Sound Asset List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsSoundgens, "Open Sound Generator List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsMeshes, "Open Mesh Asset List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsIcons, "Open Icon Asset List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsMusic, "Open Music Asset List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsSoundres, "Open Sound File List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsTextures, "Open Texture Asset List");
declareShortcut(mValues->mKeyBindings.mDocumentAssetsVideos, "Open Video Asset List");
declareShortcut(mValues->mKeyBindings.mDocumentDebugRun, "Run Debug");
declareShortcut(mValues->mKeyBindings.mDocumentDebugShutdown, "Stop Debug");
declareShortcut(mValues->mKeyBindings.mDocumentDebugProfiles, "Debug Profiles");
declareShortcut(mValues->mKeyBindings.mDocumentDebugRunlog, "Open Run Log");
declareSubcategory("Table");
declareShortcut("table-edit", "Edit Record", QKeySequence());
declareShortcut("table-add", "Add Row/Record", QKeySequence(Qt::ShiftModifier | Qt::Key_A));
declareShortcut("table-clone", "Clone Record", QKeySequence(Qt::ShiftModifier | Qt::Key_D));
declareShortcut("touch-record", "Touch Record", QKeySequence());
declareShortcut("table-revert", "Revert Record", QKeySequence());
declareShortcut("table-remove", "Remove Row/Record", QKeySequence(Qt::Key_Delete));
declareShortcut("table-moveup", "Move Record Up", QKeySequence());
declareShortcut("table-movedown", "Move Record Down", QKeySequence());
declareShortcut("table-view", "View Record", QKeySequence(Qt::ShiftModifier | Qt::Key_C));
declareShortcut("table-preview", "Preview Record", QKeySequence(Qt::ShiftModifier | Qt::Key_V));
declareShortcut("table-extendeddelete", "Extended Record Deletion", QKeySequence());
declareShortcut("table-extendedrevert", "Extended Record Revertion", QKeySequence());
declareShortcut(mValues->mKeyBindings.mTableEdit, "Edit Record");
declareShortcut(mValues->mKeyBindings.mTableAdd, "Add Row/Record");
declareShortcut(mValues->mKeyBindings.mTableClone, "Clone Record");
declareShortcut(mValues->mKeyBindings.mTouchRecord, "Touch Record");
declareShortcut(mValues->mKeyBindings.mTableRevert, "Revert Record");
declareShortcut(mValues->mKeyBindings.mTableRemove, "Remove Row/Record");
declareShortcut(mValues->mKeyBindings.mTableMoveup, "Move Record Up");
declareShortcut(mValues->mKeyBindings.mTableMovedown, "Move Record Down");
declareShortcut(mValues->mKeyBindings.mTableView, "View Record");
declareShortcut(mValues->mKeyBindings.mTablePreview, "Preview Record");
declareShortcut(mValues->mKeyBindings.mTableExtendeddelete, "Extended Record Deletion");
declareShortcut(mValues->mKeyBindings.mTableExtendedrevert, "Extended Record Revertion");
declareSubcategory("Report Table");
declareShortcut("reporttable-show", "Show Report", QKeySequence());
declareShortcut("reporttable-remove", "Remove Report", QKeySequence(Qt::Key_Delete));
declareShortcut("reporttable-replace", "Replace Report", QKeySequence());
declareShortcut("reporttable-refresh", "Refresh Report", QKeySequence());
declareShortcut(mValues->mKeyBindings.mReporttableShow, "Show Report");
declareShortcut(mValues->mKeyBindings.mReporttableRemove, "Remove Report");
declareShortcut(mValues->mKeyBindings.mReporttableReplace, "Replace Report");
declareShortcut(mValues->mKeyBindings.mReporttableRefresh, "Refresh Report");
declareSubcategory("Scene");
declareShortcut("scene-navi-primary", "Camera Rotation From Mouse Movement", QKeySequence(Qt::LeftButton));
declareShortcut("scene-navi-secondary", "Camera Translation From Mouse Movement",
QKeySequence(Qt::ControlModifier | (int)Qt::LeftButton));
declareShortcut("scene-open-primary", "Primary Open", QKeySequence(Qt::ShiftModifier | (int)Qt::LeftButton));
declareShortcut("scene-edit-primary", "Primary Edit", QKeySequence(Qt::RightButton));
declareShortcut("scene-edit-secondary", "Secondary Edit", QKeySequence(Qt::ControlModifier | (int)Qt::RightButton));
declareShortcut("scene-select-primary", "Primary Select", QKeySequence(Qt::MiddleButton));
declareShortcut(
"scene-select-secondary", "Secondary Select", QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton));
declareShortcut(
"scene-select-tertiary", "Tertiary Select", QKeySequence(Qt::ShiftModifier | (int)Qt::MiddleButton));
declareShortcut(mValues->mKeyBindings.mSceneNaviPrimary, "Camera Rotation From Mouse Movement");
declareShortcut(mValues->mKeyBindings.mSceneNaviSecondary, "Camera Translation From Mouse Movement");
declareShortcut(mValues->mKeyBindings.mSceneOpenPrimary, "Primary Open");
declareShortcut(mValues->mKeyBindings.mSceneEditPrimary, "Primary Edit");
declareShortcut(mValues->mKeyBindings.mSceneEditSecondary, "Secondary Edit");
declareShortcut(mValues->mKeyBindings.mSceneSelectPrimary, "Primary Select");
declareShortcut(mValues->mKeyBindings.mSceneSelectSecondary, "Secondary Select");
declareShortcut(mValues->mKeyBindings.mSceneSelectTertiary, "Tertiary Select");
declareModifier(mValues->mKeyBindings.mSceneSpeedModifier, "Speed Modifier");
declareShortcut("scene-delete", "Delete Instance", QKeySequence(Qt::Key_Delete));
declareShortcut("scene-instance-drop-terrain", "Drop to terrain level", QKeySequence(Qt::Key_G));
declareShortcut("scene-instance-drop-collision", "Drop to collision", QKeySequence(Qt::Key_H));
declareShortcut("scene-instance-drop-terrain-separately", "Drop to terrain level separately", QKeySequence());
declareShortcut("scene-instance-drop-collision-separately", "Drop to collision separately", QKeySequence());
declareShortcut("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5));
declareShortcut("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6));
declareShortcut("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8));
declareShortcut("scene-load-cam-westcell", "Load West Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_4));
declareShortcut("scene-load-cam-southcell", "Load South Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_2));
declareShortcut("scene-edit-abort", "Abort", QKeySequence(Qt::Key_Escape));
declareShortcut("scene-focus-toolbar", "Toggle Toolbar Focus", QKeySequence(Qt::Key_T));
declareShortcut("scene-render-stats", "Debug Rendering Stats", QKeySequence(Qt::Key_F3));
declareShortcut("scene-duplicate", "Duplicate Instance", QKeySequence(Qt::ShiftModifier | Qt::Key_C));
declareShortcut("scene-clear-selection", "Clear Selection", QKeySequence(Qt::Key_Space));
declareShortcut("scene-unhide-all", "Unhide All Objects", QKeySequence(Qt::AltModifier | Qt::Key_H));
declareShortcut("scene-toggle-visibility", "Toggle Selection Visibility", QKeySequence(Qt::Key_H));
declareShortcut("scene-group-1", "Select Group 1", QKeySequence(Qt::Key_1));
declareShortcut("scene-save-1", "Save Group 1", QKeySequence(Qt::ControlModifier | Qt::Key_1));
declareShortcut("scene-group-2", "Select Group 2", QKeySequence(Qt::Key_2));
declareShortcut("scene-save-2", "Save Group 2", QKeySequence(Qt::ControlModifier | Qt::Key_2));
declareShortcut("scene-group-3", "Select Group 3", QKeySequence(Qt::Key_3));
declareShortcut("scene-save-3", "Save Group 3", QKeySequence(Qt::ControlModifier | Qt::Key_3));
declareShortcut("scene-group-4", "Select Group 4", QKeySequence(Qt::Key_4));
declareShortcut("scene-save-4", "Save Group 4", QKeySequence(Qt::ControlModifier | Qt::Key_4));
declareShortcut("scene-group-5", "Selection Group 5", QKeySequence(Qt::Key_5));
declareShortcut("scene-save-5", "Save Group 5", QKeySequence(Qt::ControlModifier | Qt::Key_5));
declareShortcut("scene-group-6", "Selection Group 6", QKeySequence(Qt::Key_6));
declareShortcut("scene-save-6", "Save Group 6", QKeySequence(Qt::ControlModifier | Qt::Key_6));
declareShortcut("scene-group-7", "Selection Group 7", QKeySequence(Qt::Key_7));
declareShortcut("scene-save-7", "Save Group 7", QKeySequence(Qt::ControlModifier | Qt::Key_7));
declareShortcut("scene-group-8", "Selection Group 8", QKeySequence(Qt::Key_8));
declareShortcut("scene-save-8", "Save Group 8", QKeySequence(Qt::ControlModifier | Qt::Key_8));
declareShortcut("scene-group-9", "Selection Group 9", QKeySequence(Qt::Key_9));
declareShortcut("scene-save-9", "Save Group 9", QKeySequence(Qt::ControlModifier | Qt::Key_9));
declareShortcut("scene-group-0", "Selection Group 10", QKeySequence(Qt::Key_0));
declareShortcut("scene-save-0", "Save Group 10", QKeySequence(Qt::ControlModifier | Qt::Key_0));
declareShortcut(mValues->mKeyBindings.mSceneDelete, "Delete Instance");
declareShortcut(mValues->mKeyBindings.mSceneInstanceDropTerrain, "Drop to terrain level");
declareShortcut(mValues->mKeyBindings.mSceneInstanceDropCollision, "Drop to collision");
declareShortcut(mValues->mKeyBindings.mSceneInstanceDropTerrainSeparately, "Drop to terrain level separately");
declareShortcut(mValues->mKeyBindings.mSceneInstanceDropCollisionSeparately, "Drop to collision separately");
declareShortcut(mValues->mKeyBindings.mSceneLoadCamCell, "Load Camera Cell");
declareShortcut(mValues->mKeyBindings.mSceneLoadCamEastcell, "Load East Cell");
declareShortcut(mValues->mKeyBindings.mSceneLoadCamNorthcell, "Load North Cell");
declareShortcut(mValues->mKeyBindings.mSceneLoadCamWestcell, "Load West Cell");
declareShortcut(mValues->mKeyBindings.mSceneLoadCamSouthcell, "Load South Cell");
declareShortcut(mValues->mKeyBindings.mSceneEditAbort, "Abort");
declareShortcut(mValues->mKeyBindings.mSceneFocusToolbar, "Toggle Toolbar Focus");
declareShortcut(mValues->mKeyBindings.mSceneRenderStats, "Debug Rendering Stats");
declareShortcut(mValues->mKeyBindings.mSceneDuplicate, "Duplicate Instance");
declareShortcut(mValues->mKeyBindings.mSceneClearSelection, "Clear Selection");
declareShortcut(mValues->mKeyBindings.mSceneUnhideAll, "Unhide All Objects");
declareShortcut(mValues->mKeyBindings.mSceneToggleVisibility, "Toggle Selection Visibility");
declareShortcut(mValues->mKeyBindings.mSceneGroup0, "Selection Group 0");
declareShortcut(mValues->mKeyBindings.mSceneSave0, "Save Group 0");
declareShortcut(mValues->mKeyBindings.mSceneGroup1, "Select Group 1");
declareShortcut(mValues->mKeyBindings.mSceneSave1, "Save Group 1");
declareShortcut(mValues->mKeyBindings.mSceneGroup2, "Select Group 2");
declareShortcut(mValues->mKeyBindings.mSceneSave2, "Save Group 2");
declareShortcut(mValues->mKeyBindings.mSceneGroup3, "Select Group 3");
declareShortcut(mValues->mKeyBindings.mSceneSave3, "Save Group 3");
declareShortcut(mValues->mKeyBindings.mSceneGroup4, "Select Group 4");
declareShortcut(mValues->mKeyBindings.mSceneSave4, "Save Group 4");
declareShortcut(mValues->mKeyBindings.mSceneGroup5, "Selection Group 5");
declareShortcut(mValues->mKeyBindings.mSceneSave5, "Save Group 5");
declareShortcut(mValues->mKeyBindings.mSceneGroup6, "Selection Group 6");
declareShortcut(mValues->mKeyBindings.mSceneSave6, "Save Group 6");
declareShortcut(mValues->mKeyBindings.mSceneGroup7, "Selection Group 7");
declareShortcut(mValues->mKeyBindings.mSceneSave7, "Save Group 7");
declareShortcut(mValues->mKeyBindings.mSceneGroup8, "Selection Group 8");
declareShortcut(mValues->mKeyBindings.mSceneSave8, "Save Group 8");
declareShortcut(mValues->mKeyBindings.mSceneGroup9, "Selection Group 9");
declareShortcut(mValues->mKeyBindings.mSceneSave9, "Save Group 9");
declareSubcategory("1st/Free Camera");
declareShortcut("free-forward", "Forward", QKeySequence(Qt::Key_W));
declareShortcut("free-backward", "Backward", QKeySequence(Qt::Key_S));
declareShortcut("free-left", "Left", QKeySequence(Qt::Key_A));
declareShortcut("free-right", "Right", QKeySequence(Qt::Key_D));
declareShortcut("free-roll-left", "Roll Left", QKeySequence(Qt::Key_Q));
declareShortcut("free-roll-right", "Roll Right", QKeySequence(Qt::Key_E));
declareShortcut("free-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F));
declareShortcut(mValues->mKeyBindings.mFreeForward, "Forward");
declareShortcut(mValues->mKeyBindings.mFreeBackward, "Backward");
declareShortcut(mValues->mKeyBindings.mFreeLeft, "Left");
declareShortcut(mValues->mKeyBindings.mFreeRight, "Right");
declareShortcut(mValues->mKeyBindings.mFreeRollLeft, "Roll Left");
declareShortcut(mValues->mKeyBindings.mFreeRollRight, "Roll Right");
declareShortcut(mValues->mKeyBindings.mFreeSpeedMode, "Toggle Speed Mode");
declareSubcategory("Orbit Camera");
declareShortcut("orbit-up", "Up", QKeySequence(Qt::Key_W));
declareShortcut("orbit-down", "Down", QKeySequence(Qt::Key_S));
declareShortcut("orbit-left", "Left", QKeySequence(Qt::Key_A));
declareShortcut("orbit-right", "Right", QKeySequence(Qt::Key_D));
declareShortcut("orbit-roll-left", "Roll Left", QKeySequence(Qt::Key_Q));
declareShortcut("orbit-roll-right", "Roll Right", QKeySequence(Qt::Key_E));
declareShortcut("orbit-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F));
declareShortcut("orbit-center-selection", "Center On Selected", QKeySequence(Qt::Key_C));
declareShortcut(mValues->mKeyBindings.mOrbitUp, "Up");
declareShortcut(mValues->mKeyBindings.mOrbitDown, "Down");
declareShortcut(mValues->mKeyBindings.mOrbitLeft, "Left");
declareShortcut(mValues->mKeyBindings.mOrbitRight, "Right");
declareShortcut(mValues->mKeyBindings.mOrbitRollLeft, "Roll Left");
declareShortcut(mValues->mKeyBindings.mOrbitRollRight, "Roll Right");
declareShortcut(mValues->mKeyBindings.mOrbitSpeedMode, "Toggle Speed Mode");
declareShortcut(mValues->mKeyBindings.mOrbitCenterSelection, "Center On Selected");
declareSubcategory("Script Editor");
declareShortcut("script-editor-comment", "Comment Selection", QKeySequence());
declareShortcut("script-editor-uncomment", "Uncomment Selection", QKeySequence());
declareShortcut(mValues->mKeyBindings.mScriptEditorComment, "Comment Selection");
declareShortcut(mValues->mKeyBindings.mScriptEditorUncomment, "Uncomment Selection");
declareCategory("Models");
declareString(mValues->mModels.mBaseanim, "base animations").setTooltip("3rd person base model with textkeys-data");
@ -477,13 +474,14 @@ CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum(EnumSettingValue& value, con
return *setting;
}
CSMPrefs::ColourSetting& CSMPrefs::State::declareColour(const std::string& key, const QString& label, QColor default_)
CSMPrefs::ColourSetting& CSMPrefs::State::declareColour(
Settings::SettingValue<std::string>& value, const QString& label)
{
if (mCurrentCategory == mCategories.end())
throw std::logic_error("no category for setting");
CSMPrefs::ColourSetting* setting
= new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex);
= new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex);
mCurrentCategory->second.addSetting(setting);
@ -491,7 +489,7 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour(const std::string& key,
}
CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut(
const std::string& key, const QString& label, const QKeySequence& default_)
Settings::SettingValue<std::string>& value, const QString& label)
{
if (mCurrentCategory == mCategories.end())
throw std::logic_error("no category for setting");
@ -499,11 +497,11 @@ CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut(
// Setup with actual data
QKeySequence sequence;
getShortcutManager().convertFromString(mIndex->get<std::string>(mCurrentCategory->second.getKey(), key), sequence);
getShortcutManager().setSequence(key, sequence);
getShortcutManager().convertFromString(value, sequence);
getShortcutManager().setSequence(value.mName, sequence);
CSMPrefs::ShortcutSetting* setting
= new CSMPrefs::ShortcutSetting(&mCurrentCategory->second, &mMutex, key, label, *mIndex);
= new CSMPrefs::ShortcutSetting(&mCurrentCategory->second, &mMutex, value.mName, label, *mIndex);
mCurrentCategory->second.addSetting(setting);
return *setting;

View file

@ -72,9 +72,9 @@ namespace CSMPrefs
EnumSetting& declareEnum(EnumSettingValue& value, const QString& label);
ColourSetting& declareColour(const std::string& key, const QString& label, QColor default_);
ColourSetting& declareColour(Settings::SettingValue<std::string>& value, const QString& label);
ShortcutSetting& declareShortcut(const std::string& key, const QString& label, const QKeySequence& default_);
ShortcutSetting& declareShortcut(Settings::SettingValue<std::string>& value, const QString& label);
StringSetting& declareString(Settings::SettingValue<std::string>& value, const QString& label);

View file

@ -61,6 +61,23 @@
namespace
{
struct NpcParts
{
const ESM::RefId mSwimLeft = ESM::RefId::stringRefId("Swim Left");
const ESM::RefId mSwimRight = ESM::RefId::stringRefId("Swim Right");
const ESM::RefId mFootWaterLeft = ESM::RefId::stringRefId("FootWaterLeft");
const ESM::RefId mFootWaterRight = ESM::RefId::stringRefId("FootWaterRight");
const ESM::RefId mFootBareLeft = ESM::RefId::stringRefId("FootBareLeft");
const ESM::RefId mFootBareRight = ESM::RefId::stringRefId("FootBareRight");
const ESM::RefId mFootLightLeft = ESM::RefId::stringRefId("footLightLeft");
const ESM::RefId mFootLightRight = ESM::RefId::stringRefId("footLightRight");
const ESM::RefId mFootMediumRight = ESM::RefId::stringRefId("FootMedRight");
const ESM::RefId mFootMediumLeft = ESM::RefId::stringRefId("FootMedLeft");
const ESM::RefId mFootHeavyLeft = ESM::RefId::stringRefId("footHeavyLeft");
const ESM::RefId mFootHeavyRight = ESM::RefId::stringRefId("footHeavyRight");
};
const NpcParts npcParts;
int is_even(double d)
{
@ -1225,19 +1242,6 @@ namespace MWClass
ESM::RefId Npc::getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const
{
static const ESM::RefId swimLeft = ESM::RefId::stringRefId("Swim Left");
static const ESM::RefId swimRight = ESM::RefId::stringRefId("Swim Right");
static const ESM::RefId footWaterLeft = ESM::RefId::stringRefId("FootWaterLeft");
static const ESM::RefId footWaterRight = ESM::RefId::stringRefId("FootWaterRight");
static const ESM::RefId footBareLeft = ESM::RefId::stringRefId("FootBareLeft");
static const ESM::RefId footBareRight = ESM::RefId::stringRefId("FootBareRight");
static const ESM::RefId footLightLeft = ESM::RefId::stringRefId("footLightLeft");
static const ESM::RefId footLightRight = ESM::RefId::stringRefId("footLightRight");
static const ESM::RefId footMediumRight = ESM::RefId::stringRefId("FootMedRight");
static const ESM::RefId footMediumLeft = ESM::RefId::stringRefId("FootMedLeft");
static const ESM::RefId footHeavyLeft = ESM::RefId::stringRefId("footHeavyLeft");
static const ESM::RefId footHeavyRight = ESM::RefId::stringRefId("footHeavyRight");
if (name == "left" || name == "right")
{
MWBase::World* world = MWBase::Environment::get().getWorld();
@ -1245,9 +1249,9 @@ namespace MWClass
return ESM::RefId();
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
if (world->isSwimming(ptr))
return (name == "left") ? swimLeft : swimRight;
return (name == "left") ? npcParts.mSwimLeft : npcParts.mSwimRight;
if (world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
return (name == "left") ? footWaterLeft : footWaterRight;
return (name == "left") ? npcParts.mFootWaterLeft : npcParts.mFootWaterRight;
if (world->isOnGround(ptr))
{
if (getNpcStats(ptr).isWerewolf()
@ -1262,15 +1266,15 @@ namespace MWClass
const MWWorld::InventoryStore& inv = Npc::getInventoryStore(ptr);
MWWorld::ConstContainerStoreIterator boots = inv.getSlot(MWWorld::InventoryStore::Slot_Boots);
if (boots == inv.end() || boots->getType() != ESM::Armor::sRecordId)
return (name == "left") ? footBareLeft : footBareRight;
return (name == "left") ? npcParts.mFootBareLeft : npcParts.mFootBareRight;
ESM::RefId skill = boots->getClass().getEquipmentSkill(*boots);
if (skill == ESM::Skill::LightArmor)
return (name == "left") ? footLightLeft : footLightRight;
return (name == "left") ? npcParts.mFootLightLeft : npcParts.mFootLightRight;
else if (skill == ESM::Skill::MediumArmor)
return (name == "left") ? footMediumLeft : footMediumRight;
return (name == "left") ? npcParts.mFootMediumLeft : npcParts.mFootMediumRight;
else if (skill == ESM::Skill::HeavyArmor)
return (name == "left") ? footHeavyLeft : footHeavyRight;
return (name == "left") ? npcParts.mFootHeavyLeft : npcParts.mFootHeavyRight;
}
return ESM::RefId();
}
@ -1279,9 +1283,9 @@ namespace MWClass
if (name == "land")
return ESM::RefId();
if (name == "swimleft")
return swimLeft;
return npcParts.mSwimLeft;
if (name == "swimright")
return swimRight;
return npcParts.mSwimRight;
// TODO: I have no idea what these are supposed to do for NPCs since they use
// voiced dialog for various conditions like health loss and combat taunts. Maybe
// only for biped creatures?

View file

@ -395,8 +395,10 @@ namespace MWGui
{
std::string suggestedName = mAlchemy->suggestPotionName();
if (suggestedName != mSuggestedPotionName)
{
mNameEdit->setCaptionWithReplacing(suggestedName);
mSuggestedPotionName = suggestedName;
mSuggestedPotionName = std::move(suggestedName);
}
mSortModel->clearDragItems();

View file

@ -1065,7 +1065,7 @@ namespace MWGui
{
createActiveFormats(newBook);
mBook = newBook;
mBook = std::move(newBook);
setPage(newPage);
if (newPage < mBook->mPages.size())

View file

@ -333,10 +333,10 @@ namespace MWGui
if (!classId.empty())
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId);
const ESM::Class* klass = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(classId);
if (klass)
const ESM::Class* pickedClass = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(classId);
if (pickedClass)
{
mPlayerClass = *klass;
mPlayerClass = *pickedClass;
}
MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mPickClassDialog));
}
@ -454,30 +454,30 @@ namespace MWGui
{
if (mCreateClassDialog)
{
ESM::Class klass;
klass.mName = mCreateClassDialog->getName();
klass.mDescription = mCreateClassDialog->getDescription();
klass.mData.mSpecialization = mCreateClassDialog->getSpecializationId();
klass.mData.mIsPlayable = 0x1;
klass.mRecordFlags = 0;
ESM::Class createdClass;
createdClass.mName = mCreateClassDialog->getName();
createdClass.mDescription = mCreateClassDialog->getDescription();
createdClass.mData.mSpecialization = mCreateClassDialog->getSpecializationId();
createdClass.mData.mIsPlayable = 0x1;
createdClass.mRecordFlags = 0;
std::vector<ESM::RefId> attributes = mCreateClassDialog->getFavoriteAttributes();
assert(attributes.size() >= klass.mData.mAttribute.size());
for (size_t i = 0; i < klass.mData.mAttribute.size(); ++i)
klass.mData.mAttribute[i] = ESM::Attribute::refIdToIndex(attributes[i]);
assert(attributes.size() >= createdClass.mData.mAttribute.size());
for (size_t i = 0; i < createdClass.mData.mAttribute.size(); ++i)
createdClass.mData.mAttribute[i] = ESM::Attribute::refIdToIndex(attributes[i]);
std::vector<ESM::RefId> majorSkills = mCreateClassDialog->getMajorSkills();
std::vector<ESM::RefId> minorSkills = mCreateClassDialog->getMinorSkills();
assert(majorSkills.size() >= klass.mData.mSkills.size());
assert(minorSkills.size() >= klass.mData.mSkills.size());
for (size_t i = 0; i < klass.mData.mSkills.size(); ++i)
assert(majorSkills.size() >= createdClass.mData.mSkills.size());
assert(minorSkills.size() >= createdClass.mData.mSkills.size());
for (size_t i = 0; i < createdClass.mData.mSkills.size(); ++i)
{
klass.mData.mSkills[i][1] = ESM::Skill::refIdToIndex(majorSkills[i]);
klass.mData.mSkills[i][0] = ESM::Skill::refIdToIndex(minorSkills[i]);
createdClass.mData.mSkills[i][1] = ESM::Skill::refIdToIndex(majorSkills[i]);
createdClass.mData.mSkills[i][0] = ESM::Skill::refIdToIndex(minorSkills[i]);
}
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass);
mPlayerClass = klass;
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(createdClass);
mPlayerClass = std::move(createdClass);
// Do not delete dialog, so that choices are remembered in case we want to go back and adjust them later
mCreateClassDialog->setVisible(false);
@ -666,9 +666,10 @@ namespace MWGui
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
const ESM::Class* klass = MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(mGenerateClass);
const ESM::Class* generatedClass
= MWBase::Environment::get().getESMStore()->get<ESM::Class>().find(mGenerateClass);
mPlayerClass = *klass;
mPlayerClass = *generatedClass;
}
void CharacterCreation::onGenerateClassBack()

View file

@ -248,27 +248,27 @@ namespace MWGui
if (mCurrentClassId.empty())
return;
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
const ESM::Class* klass = store.get<ESM::Class>().search(mCurrentClassId);
if (!klass)
const ESM::Class* currentClass = store.get<ESM::Class>().search(mCurrentClassId);
if (!currentClass)
return;
ESM::Class::Specialization specialization
= static_cast<ESM::Class::Specialization>(klass->mData.mSpecialization);
= static_cast<ESM::Class::Specialization>(currentClass->mData.mSpecialization);
std::string specName{ MWBase::Environment::get().getWindowManager()->getGameSettingString(
ESM::Class::sGmstSpecializationIds[specialization], ESM::Class::sGmstSpecializationIds[specialization]) };
mSpecializationName->setCaption(specName);
ToolTips::createSpecializationToolTip(mSpecializationName, specName, specialization);
mFavoriteAttribute[0]->setAttributeId(ESM::Attribute::indexToRefId(klass->mData.mAttribute[0]));
mFavoriteAttribute[1]->setAttributeId(ESM::Attribute::indexToRefId(klass->mData.mAttribute[1]));
mFavoriteAttribute[0]->setAttributeId(ESM::Attribute::indexToRefId(currentClass->mData.mAttribute[0]));
mFavoriteAttribute[1]->setAttributeId(ESM::Attribute::indexToRefId(currentClass->mData.mAttribute[1]));
ToolTips::createAttributeToolTip(mFavoriteAttribute[0], mFavoriteAttribute[0]->getAttributeId());
ToolTips::createAttributeToolTip(mFavoriteAttribute[1], mFavoriteAttribute[1]->getAttributeId());
for (size_t i = 0; i < klass->mData.mSkills.size(); ++i)
for (size_t i = 0; i < currentClass->mData.mSkills.size(); ++i)
{
ESM::RefId minor = ESM::Skill::indexToRefId(klass->mData.mSkills[i][0]);
ESM::RefId major = ESM::Skill::indexToRefId(klass->mData.mSkills[i][1]);
ESM::RefId minor = ESM::Skill::indexToRefId(currentClass->mData.mSkills[i][0]);
ESM::RefId major = ESM::Skill::indexToRefId(currentClass->mData.mSkills[i][1]);
mMinorSkill[i]->setSkillId(minor);
mMajorSkill[i]->setSkillId(major);
ToolTips::createSkillToolTip(mMinorSkill[i], minor);

View file

@ -9,7 +9,6 @@
#include <fstream>
#include <regex>
#include <apps/openmw/mwgui/textcolours.hpp>
#include <components/compiler/exception.hpp>
#include <components/compiler/extensions0.hpp>
#include <components/compiler/lineparser.hpp>
@ -20,6 +19,8 @@
#include <components/misc/utf8stream.hpp>
#include <components/settings/values.hpp>
#include "apps/openmw/mwgui/textcolours.hpp"
#include "../mwscript/extensions.hpp"
#include "../mwscript/interpretercontext.hpp"
@ -439,7 +440,7 @@ namespace MWGui
// If new search term reset position, otherwise continue from current position
if (newSearchTerm != mCurrentSearchTerm)
{
mCurrentSearchTerm = newSearchTerm;
mCurrentSearchTerm = std::move(newSearchTerm);
mCurrentOccurrenceIndex = std::string::npos;
}

View file

@ -221,7 +221,7 @@ namespace MWGui::Formatting
}
}
mAttributes[key] = value;
mAttributes[key] = std::move(value);
}
}

View file

@ -300,11 +300,9 @@ namespace MWGui
return MyGUI::IntCoord(position.left - halfMarkerSize, position.top - halfMarkerSize, markerSize, markerSize);
}
MyGUI::Widget* LocalMapBase::createDoorMarker(
const std::string& name, const MyGUI::VectorString& notes, float x, float y) const
MyGUI::Widget* LocalMapBase::createDoorMarker(const std::string& name, float x, float y) const
{
MarkerUserData data(mLocalMapRender);
data.notes = notes;
data.caption = name;
MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>(
"MarkerButton", getMarkerCoordinates(x, y, data, 8), MyGUI::Align::Default);
@ -662,8 +660,9 @@ namespace MWGui
MarkerUserData* data;
if (mDoorMarkersToRecycle.empty())
{
markerWidget = createDoorMarker(marker.name, destNotes, marker.x, marker.y);
markerWidget = createDoorMarker(marker.name, marker.x, marker.y);
data = markerWidget->getUserData<MarkerUserData>();
data->notes = std::move(destNotes);
doorMarkerCreated(markerWidget);
}
else
@ -672,7 +671,7 @@ namespace MWGui
mDoorMarkersToRecycle.pop_back();
data = markerWidget->getUserData<MarkerUserData>();
data->notes = destNotes;
data->notes = std::move(destNotes);
data->caption = marker.name;
markerWidget->setCoord(getMarkerCoordinates(marker.x, marker.y, *data, 8));
markerWidget->setVisible(true);

View file

@ -170,8 +170,7 @@ namespace MWGui
MyGUI::IntPoint getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const;
MyGUI::IntCoord getMarkerCoordinates(
float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const;
MyGUI::Widget* createDoorMarker(
const std::string& name, const MyGUI::VectorString& notes, float x, float y) const;
MyGUI::Widget* createDoorMarker(const std::string& name, float x, float y) const;
MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const;
virtual void notifyPlayerUpdate() {}

View file

@ -148,11 +148,11 @@ namespace MWGui
mUpdateSkillArea = true;
}
void ReviewDialog::setClass(const ESM::Class& class_)
void ReviewDialog::setClass(const ESM::Class& playerClass)
{
mKlass = class_;
mClassWidget->setCaption(mKlass.mName);
ToolTips::createClassToolTip(mClassWidget, mKlass);
mClass = playerClass;
mClassWidget->setCaption(mClass.mName);
ToolTips::createClassToolTip(mClassWidget, mClass);
}
void ReviewDialog::setBirthSign(const ESM::RefId& signId)

View file

@ -30,7 +30,7 @@ namespace MWGui
void setPlayerName(const std::string& name);
void setRace(const ESM::RefId& raceId);
void setClass(const ESM::Class& class_);
void setClass(const ESM::Class& playerClass);
void setBirthSign(const ESM::RefId& signId);
void setHealth(const MWMechanics::DynamicStat<float>& value);
@ -96,7 +96,7 @@ namespace MWGui
std::map<ESM::RefId, MyGUI::TextBox*> mSkillWidgetMap;
ESM::RefId mRaceId, mBirthSignId;
std::string mName;
ESM::Class mKlass;
ESM::Class mClass;
std::vector<MyGUI::Widget*> mSkillWidgets; //< Skills and other information
bool mUpdateSkillArea;

View file

@ -472,7 +472,7 @@ namespace MWGui
ESM::EffectList effectList;
effectList.mList = mEffects;
mSpell.mEffects = effectList;
mSpell.mEffects = std::move(effectList);
mSpell.mData.mCost = int(y);
mSpell.mData.mType = ESM::Spell::ST_Spell;
mSpell.mData.mFlags = 0;

View file

@ -172,7 +172,7 @@ namespace MWGui
w += 16;
ToolTipInfo* tooltipInfo = image->getUserData<ToolTipInfo>();
tooltipInfo->text = sourcesDescription;
tooltipInfo->text = std::move(sourcesDescription);
// Fade out
if (totalDuration >= fadeTime && fadeTime > 0.f)

View file

@ -251,7 +251,7 @@ namespace MWGui
if (!cost.empty() && cost != "0")
info.text
+= MWGui::ToolTips::getValueString(MWMechanics::calcSpellCost(*spell), "#{sCastCost}");
info.effects = effects;
info.effects = std::move(effects);
tooltipSize = createToolTip(info);
}
else if (type == "Layout")

View file

@ -43,6 +43,8 @@
#include <components/esm4/loadtree.hpp>
#include <components/esm4/loadweap.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/worldmodel.hpp"

View file

@ -122,7 +122,8 @@ namespace MWLua
return "ESM3_FactionRank[" + rec.mFactionId.toDebugString() + ", " + std::to_string(rec.mRankIndex + 1)
+ "]";
};
rankT["name"] = sol::readonly_property([](const FactionRank& rec) { return rec.mRankName; });
rankT["name"]
= sol::readonly_property([](const FactionRank& rec) -> std::string_view { return rec.mRankName; });
rankT["primarySkillValue"] = sol::readonly_property([](const FactionRank& rec) { return rec.mPrimarySkill; });
rankT["favouredSkillValue"] = sol::readonly_property([](const FactionRank& rec) { return rec.mFavouredSkill; });
rankT["factionReaction"] = sol::readonly_property([](const FactionRank& rec) { return rec.mFactReaction; });

View file

@ -22,11 +22,13 @@
#include <components/lua_ui/util.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwrender/postprocessor.hpp"
#include "../mwworld/datetimemanager.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/scene.hpp"
#include "../mwworld/worldmodel.hpp"

View file

@ -769,8 +769,13 @@ namespace MWLua
sol::state_view lua(ts);
self.reset();
return sol::as_function([lua, self]() mutable -> std::pair<sol::object, sol::object> {
if (!self.isEnd())
while (!self.isEnd())
{
if (self.mIterator->second.getBase() == 0 && self.mIterator->second.getModifier() == 0.f)
{
self.advance();
continue;
}
ActiveEffect effect = ActiveEffect{ self.mIterator->first, self.mIterator->second };
auto result = sol::make_object(lua, effect);
@ -778,10 +783,7 @@ namespace MWLua
self.advance();
return { key, result };
}
else
{
return { sol::lua_nil, sol::lua_nil };
}
return { sol::lua_nil, sol::lua_nil };
});
};
@ -823,7 +825,7 @@ namespace MWLua
if (auto* store = effects.getStore())
if (auto effect = store->get(key))
return ActiveEffect{ key, effect.value() };
return sol::nullopt;
return ActiveEffect{ key, MWMechanics::EffectParam() };
};
// types.Actor.activeEffects(o):removeEffect(id, ?arg)

View file

@ -20,6 +20,9 @@
#include "../mwmechanics/creaturestats.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "luaevents.hpp"
#include "luamanagerimp.hpp"
#include "types/types.hpp"

View file

@ -5,10 +5,6 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
namespace sol
{
template <>

View file

@ -6,8 +6,10 @@
#include <components/lua/luastate.hpp>
#include <components/settings/values.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwbase/mechanicsmanager.hpp"
#include "apps/openmw/mwbase/windowmanager.hpp"
#include "apps/openmw/mwbase/world.hpp"
#include "apps/openmw/mwmechanics/actorutil.hpp"
#include "apps/openmw/mwmechanics/creaturestats.hpp"
#include "apps/openmw/mwmechanics/drawstate.hpp"

View file

@ -4,16 +4,15 @@
#include <sol/sol.hpp>
#include <components/esm/defs.hpp>
#include <components/lua/luastate.hpp>
#include "apps/openmw/mwworld/esmstore.hpp"
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <components/esm3/loadclas.hpp>
#include <components/esm3/loadnpc.hpp>
#include <components/lua/luastate.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
#include "../context.hpp"
#include "../object.hpp"
namespace MWLua
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -4,14 +4,12 @@
#include <components/misc/strings/lower.hpp>
#include <components/esm3/loadbook.hpp>
#include <components/esm3/loadskil.hpp>
#include <components/lua/luastate.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include <components/esm3/loadskil.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,7 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwworld/class.hpp>
#include "apps/openmw/mwworld/class.hpp"
namespace sol
{

View file

@ -6,10 +6,6 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
namespace sol
{
template <>

View file

@ -7,7 +7,6 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include "apps/openmw/mwworld/esmstore.hpp"
#include "apps/openmw/mwworld/worldmodel.hpp"
namespace sol

View file

@ -6,10 +6,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -1,11 +1,11 @@
#include "types.hpp"
#include <components/esm3/loadmisc.hpp>
#include <components/esm3/loadspel.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwworld/esmstore.hpp"
namespace MWLua
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -6,9 +6,8 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
namespace sol
{

View file

@ -5,12 +5,12 @@
#include <components/esm3/loadnpc.hpp>
#include <components/lua/luastate.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/mechanicsmanager.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwmechanics/npcstats.hpp>
#include <apps/openmw/mwworld/class.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwbase/mechanicsmanager.hpp"
#include "apps/openmw/mwbase/world.hpp"
#include "apps/openmw/mwmechanics/npcstats.hpp"
#include "apps/openmw/mwworld/class.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
#include "../classbindings.hpp"
#include "../localscripts.hpp"

View file

@ -1,12 +1,13 @@
#include "types.hpp"
#include "../luamanagerimp.hpp"
#include <apps/openmw/mwbase/inputmanager.hpp>
#include <apps/openmw/mwbase/journal.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwmechanics/npcstats.hpp>
#include <apps/openmw/mwworld/class.hpp>
#include <apps/openmw/mwworld/globals.hpp>
#include "apps/openmw/mwbase/inputmanager.hpp"
#include "apps/openmw/mwbase/journal.hpp"
#include "apps/openmw/mwbase/world.hpp"
#include "apps/openmw/mwmechanics/npcstats.hpp"
#include "apps/openmw/mwworld/class.hpp"
#include "apps/openmw/mwworld/globals.hpp"
namespace MWLua
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,7 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{

View file

@ -5,10 +5,6 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
namespace sol
{
template <>

View file

@ -7,7 +7,6 @@
#include <components/lua/luastate.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwbase/world.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
#include "apps/openmw/mwworld/store.hpp"

View file

@ -5,9 +5,7 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
namespace sol
{
@ -16,7 +14,6 @@ namespace sol
{
};
}
#include <components/resource/resourcesystem.hpp>
namespace
{

View file

@ -161,7 +161,8 @@ namespace MWLua
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
sol::usertype<FileHandle> handle = context.mLua->sol().new_usertype<FileHandle>("FileHandle");
handle["fileName"] = sol::readonly_property([](const FileHandle& self) { return self.mFileName; });
handle["fileName"]
= sol::readonly_property([](const FileHandle& self) -> std::string_view { return self.mFileName; });
handle[sol::meta_function::to_string] = [](const FileHandle& self) {
return "FileHandle{'" + self.mFileName + "'" + (!self.mFilePtr ? ", closed" : "") + "}";
};

View file

@ -2,7 +2,7 @@
#include "luamanagerimp.hpp"
#include <apps/openmw/profile.hpp>
#include "apps/openmw/profile.hpp"
#include <components/debug/debuglog.hpp>
#include <components/settings/values.hpp>

View file

@ -1,7 +1,7 @@
#ifndef OPENMW_MWRENDER_AGENTSPATHS_H
#define OPENMW_MWRENDER_AGENTSPATHS_H
#include <apps/openmw/mwworld/ptr.hpp>
#include "apps/openmw/mwworld/ptr.hpp"
#include <osg/ref_ptr>

View file

@ -9,7 +9,7 @@
#include <components/sceneutil/util.hpp>
#include <components/settings/values.hpp>
#include <apps/openmw/mwworld/cell.hpp>
#include "apps/openmw/mwworld/cell.hpp"
namespace MWRender
{

View file

@ -510,11 +510,15 @@ namespace MWRender
if (!isWerewolf)
addAnimSource(base, smodel);
if (smodel != defaultSkeleton && base != defaultSkeleton)
addAnimSource(defaultSkeleton, smodel);
if (!isBase)
{
addAnimSource(defaultSkeleton, smodel);
addAnimSource(smodel, smodel);
}
else if (base != defaultSkeleton)
{
addAnimSource(defaultSkeleton, smodel);
}
if (!isWerewolf && isBeast && mNpc->mRace.contains("argonian"))
addAnimSource("meshes\\xargonian_swimkna.nif", smodel);

View file

@ -65,6 +65,7 @@ namespace MWRender
bool mIsStorm;
ESM::RefId mAmbientLoopSoundID;
ESM::RefId mRainLoopSoundID;
float mAmbientSoundVolume;
std::string mParticleEffect;

View file

@ -1034,65 +1034,6 @@ namespace MWSound
return ret;
}
void OpenAL_Output::setHrtf(const std::string& hrtfname, HrtfMode hrtfmode)
{
if (!mDevice || !ALC.SOFT_HRTF)
{
Log(Debug::Info) << "HRTF extension not present";
return;
}
LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr;
getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT");
LPALCRESETDEVICESOFT alcResetDeviceSOFT = nullptr;
getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT");
std::vector<ALCint> attrs;
attrs.reserve(15);
attrs.push_back(ALC_HRTF_SOFT);
attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE
: hrtfmode == HrtfMode::Enable ? ALC_TRUE
:
/*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT);
if (!hrtfname.empty())
{
ALCint index = -1;
ALCint num_hrtf;
alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf);
for (ALCint i = 0; i < num_hrtf; ++i)
{
const ALCchar* entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i);
if (hrtfname == entry)
{
index = i;
break;
}
}
if (index < 0)
Log(Debug::Warning) << "Failed to find HRTF name \"" << hrtfname << "\", using default";
else
{
attrs.push_back(ALC_HRTF_ID_SOFT);
attrs.push_back(index);
}
}
attrs.push_back(0);
alcResetDeviceSOFT(mDevice, attrs.data());
ALCint hrtf_state;
alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state);
if (!hrtf_state)
Log(Debug::Info) << "HRTF disabled";
else
{
const ALCchar* hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT);
Log(Debug::Info) << "Enabled HRTF " << hrtf;
}
}
std::pair<Sound_Handle, size_t> OpenAL_Output::loadSound(const std::string& fname)
{
getALError();

View file

@ -84,7 +84,6 @@ namespace MWSound
void deinit() override;
std::vector<std::string> enumerateHrtf() override;
void setHrtf(const std::string& hrtfname, HrtfMode hrtfmode) override;
std::pair<Sound_Handle, size_t> loadSound(const std::string& fname) override;
size_t unloadSound(Sound_Handle data) override;

View file

@ -38,7 +38,6 @@ namespace MWSound
virtual void deinit() = 0;
virtual std::vector<std::string> enumerateHrtf() = 0;
virtual void setHrtf(const std::string& hrtfname, HrtfMode hrtfmode) = 0;
virtual std::pair<Sound_Handle, size_t> loadSound(const std::string& fname) = 0;
virtual size_t unloadSound(Sound_Handle data) = 0;

View file

@ -64,6 +64,7 @@ void MWState::StateManager::cleanup(bool force)
mState = State_NoGame;
mCharacterManager.setCurrentCharacter(nullptr);
mTimePlayed = 0;
mLastSavegame.clear();
MWMechanics::CreatureStats::cleanup();
}
@ -119,14 +120,27 @@ void MWState::StateManager::askLoadRecent()
if (!mAskLoadRecent)
{
const MWState::Character* character = getCurrentCharacter();
if (!character || character->begin() == character->end()) // no saves
if (mLastSavegame.empty()) // no saves
{
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu);
}
else
{
MWState::Slot lastSave = *character->begin();
std::string saveName = Files::pathToUnicodeString(mLastSavegame.filename());
// Assume the last saved game belongs to the current character's slot list.
const Character* character = getCurrentCharacter();
if (character)
{
for (const auto& slot : *character)
{
if (slot.mPath == mLastSavegame)
{
saveName = slot.mProfile.mDescription;
break;
}
}
}
std::vector<std::string> buttons;
buttons.emplace_back("#{Interface:Yes}");
buttons.emplace_back("#{Interface:No}");
@ -134,7 +148,7 @@ void MWState::StateManager::askLoadRecent()
= MWBase::Environment::get().getL10nManager()->getMessage("OMWEngine", "AskLoadLastSave");
std::string_view tag = "%s";
size_t pos = message.find(tag);
message.replace(pos, tag.length(), lastSave.mProfile.mDescription);
message.replace(pos, tag.length(), saveName);
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
mAskLoadRecent = true;
}
@ -324,6 +338,7 @@ void MWState::StateManager::saveGame(std::string_view description, const Slot* s
throw std::runtime_error("Write operation failed (file stream)");
Settings::saves().mCharacter.set(Files::pathToUnicodeString(slot->mPath.parent_path().filename()));
mLastSavegame = slot->mPath;
const auto finish = std::chrono::steady_clock::now();
@ -563,6 +578,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
if (character)
Settings::saves().mCharacter.set(Files::pathToUnicodeString(character->getPath().filename()));
mLastSavegame = filepath;
MWBase::Environment::get().getWindowManager()->setNewGame(false);
MWBase::Environment::get().getWorld()->saveLoaded();
@ -641,7 +657,15 @@ void MWState::StateManager::quickLoad()
void MWState::StateManager::deleteGame(const MWState::Character* character, const MWState::Slot* slot)
{
const std::filesystem::path savePath = slot->mPath;
mCharacterManager.deleteSlot(character, slot);
if (mLastSavegame == savePath)
{
if (character->begin() != character->end())
mLastSavegame = character->begin()->mPath;
else
mLastSavegame.clear();
}
}
MWState::Character* MWState::StateManager::getCurrentCharacter()
@ -672,9 +696,9 @@ void MWState::StateManager::update(float duration)
{
mAskLoadRecent = false;
// Load last saved game for current character
MWState::Slot lastSave = *curCharacter->begin();
loadGame(curCharacter, lastSave.mPath);
// loadGame resets the game state along with mLastSavegame so we want to preserve it
const std::filesystem::path filePath = std::move(mLastSavegame);
loadGame(curCharacter, filePath);
}
else if (iButton == 1)
{

View file

@ -19,6 +19,7 @@ namespace MWState
State mState;
CharacterManager mCharacterManager;
double mTimePlayed;
std::filesystem::path mLastSavegame;
private:
void cleanup(bool force = false);

View file

@ -8,10 +8,10 @@
#include <components/esm3/objectstate.hpp>
#include <components/esm4/loadrefr.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include <apps/openmw/mwbase/world.hpp>
#include <apps/openmw/mwmechanics/spellutil.hpp>
#include <apps/openmw/mwworld/esmstore.hpp>
#include "apps/openmw/mwbase/environment.hpp"
#include "apps/openmw/mwbase/world.hpp"
#include "apps/openmw/mwmechanics/spellutil.hpp"
#include "apps/openmw/mwworld/esmstore.hpp"
namespace MWWorld
{

View file

@ -9,8 +9,6 @@
#include <components/misc/strings/lower.hpp>
#include <components/resource/resourcesystem.hpp>
#include <apps/openmw/mwbase/environment.hpp>
#include "store.hpp"
namespace MWWorld

View file

@ -111,11 +111,16 @@ namespace
std::string model = getModel(ptr);
const auto rotation = makeDirectNodeRotation(ptr);
// Null node meant to distinguish objects that aren't in the scene from paged objects
// TODO: find a more clever way to make paging exclusion more reliable?
static const osg::ref_ptr<SceneUtil::PositionAttitudeTransform> pagedNode(
new SceneUtil::PositionAttitudeTransform);
ESM::RefNum refnum = ptr.getCellRef().getRefNum();
if (!refnum.hasContentFile() || !std::binary_search(pagedRefs.begin(), pagedRefs.end(), refnum))
ptr.getClass().insertObjectRendering(ptr, model, rendering);
else
ptr.getRefData().setBaseNode(nullptr);
ptr.getRefData().setBaseNode(pagedNode);
setNodeRotation(ptr, rendering, rotation);
if (ptr.getClass().useAnim())

View file

@ -195,21 +195,19 @@ namespace MWWorld
mThunderSoundID[3]
= ESM::RefId::stringRefId(Fallback::Map::getString("Weather_" + name + "_Thunder_Sound_ID_3"));
// TODO: support weathers that have both "Ambient Loop Sound ID" and "Rain Loop Sound ID", need to play both
// sounds at the same time.
if (!mRainEffect.empty()) // NOTE: in vanilla, the weathers with rain seem to be hardcoded; changing
// Using_Precip has no effect
{
mAmbientLoopSoundID
mRainLoopSoundID
= ESM::RefId::stringRefId(Fallback::Map::getString("Weather_" + name + "_Rain_Loop_Sound_ID"));
if (mAmbientLoopSoundID.empty()) // default to "rain" if not set
mAmbientLoopSoundID = ESM::RefId::stringRefId("rain");
if (mRainLoopSoundID.empty()) // default to "rain" if not set
mRainLoopSoundID = ESM::RefId::stringRefId("rain");
else if (mRainLoopSoundID == "None")
mRainLoopSoundID = ESM::RefId();
}
else
mAmbientLoopSoundID
= ESM::RefId::stringRefId(Fallback::Map::getString("Weather_" + name + "_Ambient_Loop_Sound_ID"));
mAmbientLoopSoundID
= ESM::RefId::stringRefId(Fallback::Map::getString("Weather_" + name + "_Ambient_Loop_Sound_ID"));
if (mAmbientLoopSoundID == "None")
mAmbientLoopSoundID = ESM::RefId();
}
@ -552,8 +550,6 @@ namespace MWWorld
, mQueuedWeather(0)
, mRegions()
, mResult()
, mAmbientSound(nullptr)
, mPlayingSoundID()
{
mTimeSettings.mNightStart = mSunsetTime + mSunsetDuration;
mTimeSettings.mNightEnd = mSunriseTime;
@ -794,24 +790,52 @@ namespace MWWorld
mRendering.getSkyManager()->setWeather(mResult);
// Play sounds
if (mPlayingSoundID != mResult.mAmbientLoopSoundID)
if (mPlayingAmbientSoundID != mResult.mAmbientLoopSoundID)
{
stopSounds();
if (mAmbientSound)
{
MWBase::Environment::get().getSoundManager()->stopSound(mAmbientSound);
mAmbientSound = nullptr;
}
if (!mResult.mAmbientLoopSoundID.empty())
mAmbientSound = MWBase::Environment::get().getSoundManager()->playSound(mResult.mAmbientLoopSoundID,
mResult.mAmbientSoundVolume, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::Loop);
mPlayingSoundID = mResult.mAmbientLoopSoundID;
mPlayingAmbientSoundID = mResult.mAmbientLoopSoundID;
}
else if (mAmbientSound)
mAmbientSound->setVolume(mResult.mAmbientSoundVolume);
if (mPlayingRainSoundID != mResult.mRainLoopSoundID)
{
if (mRainSound)
{
MWBase::Environment::get().getSoundManager()->stopSound(mRainSound);
mRainSound = nullptr;
}
if (!mResult.mRainLoopSoundID.empty())
mRainSound = MWBase::Environment::get().getSoundManager()->playSound(mResult.mRainLoopSoundID,
mResult.mAmbientSoundVolume, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::Loop);
mPlayingRainSoundID = mResult.mRainLoopSoundID;
}
else if (mRainSound)
mRainSound->setVolume(mResult.mAmbientSoundVolume);
}
void WeatherManager::stopSounds()
{
if (mAmbientSound)
{
MWBase::Environment::get().getSoundManager()->stopSound(mAmbientSound);
mAmbientSound = nullptr;
mPlayingSoundID = ESM::RefId();
mAmbientSound = nullptr;
}
mPlayingAmbientSoundID = ESM::RefId();
if (mRainSound)
{
MWBase::Environment::get().getSoundManager()->stopSound(mRainSound);
mRainSound = nullptr;
}
mPlayingRainSoundID = ESM::RefId();
}
float WeatherManager::getWindSpeed() const
@ -1118,6 +1142,7 @@ namespace MWWorld
mResult.mCloudSpeed = current.mCloudSpeed;
mResult.mGlareView = current.mGlareView;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mRainLoopSoundID = current.mRainLoopSoundID;
mResult.mAmbientSoundVolume = 1.f;
mResult.mPrecipitationAlpha = 1.f;
@ -1237,6 +1262,7 @@ namespace MWWorld
mResult.mAmbientSoundVolume = 1.f - factor / threshold;
mResult.mPrecipitationAlpha = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mRainLoopSoundID = current.mRainLoopSoundID;
mResult.mRainDiameter = current.mRainDiameter;
mResult.mRainMinHeight = current.mRainMinHeight;
mResult.mRainMaxHeight = current.mRainMaxHeight;
@ -1252,6 +1278,7 @@ namespace MWWorld
mResult.mAmbientSoundVolume = (factor - threshold) / (1 - threshold);
mResult.mPrecipitationAlpha = mResult.mAmbientSoundVolume;
mResult.mAmbientLoopSoundID = other.mAmbientLoopSoundID;
mResult.mRainLoopSoundID = other.mRainLoopSoundID;
mResult.mRainDiameter = other.mRainDiameter;
mResult.mRainMinHeight = other.mRainMinHeight;

View file

@ -156,9 +156,11 @@ namespace MWWorld
float FogOffset;
} mDL;
// Sound effect
// Sound effects
// This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
ESM::RefId mAmbientLoopSoundID;
// This is used for Rain and Thunderstorm
ESM::RefId mRainLoopSoundID;
// Is this an ash storm / blight storm? If so, the following will happen:
// - The particles and clouds will be oriented so they appear to come from the Red Mountain.
@ -369,8 +371,10 @@ namespace MWWorld
std::map<ESM::RefId, RegionWeather> mRegions;
MWRender::WeatherResult mResult;
MWBase::Sound* mAmbientSound;
ESM::RefId mPlayingSoundID;
MWBase::Sound* mAmbientSound{ nullptr };
ESM::RefId mPlayingAmbientSoundID;
MWBase::Sound* mRainSound{ nullptr };
ESM::RefId mPlayingRainSoundID;
void addWeather(
const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect = "");

View file

@ -1,4 +1,5 @@
#include "apps/openmw/mwdialogue/keywordsearch.hpp"
#include <gtest/gtest.h>
struct KeywordSearchTest : public ::testing::Test

View file

@ -1,4 +1,5 @@
#include <apps/openmw/options.hpp>
#include "apps/openmw/options.hpp"
#include <components/files/configurationmanager.hpp>
#include <components/files/conversion.hpp>

View file

@ -2,12 +2,15 @@
#include "esmfile.hpp"
#include <fstream>
#include <memory>
#include <stdexcept>
#include <unordered_set>
#include <QDataStream>
#include <QDebug>
#include <QDir>
#include <QFont>
#include <QIODevice>
#include <components/esm/format.hpp>
#include <components/esm3/esmreader.hpp>
@ -127,7 +130,7 @@ Qt::ItemFlags ContentSelectorModel::ContentModel::flags(const QModelIndex& index
continue;
noGameFiles = false;
if (isChecked(depFile->filePath()))
if (mCheckedFiles.contains(depFile))
{
gamefileChecked = true;
break;
@ -214,7 +217,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex& index, int
if (file == mGameFile)
return QVariant();
return mCheckStates[file->filePath()];
return mCheckedFiles.contains(file) ? Qt::Checked : Qt::Unchecked;
}
case Qt::UserRole:
@ -228,7 +231,7 @@ QVariant ContentSelectorModel::ContentModel::data(const QModelIndex& index, int
}
case Qt::UserRole + 1:
return isChecked(file->filePath());
return mCheckedFiles.contains(file);
}
return QVariant();
}
@ -276,12 +279,12 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const
{
int checkValue = value.toInt();
bool setState = false;
if ((checkValue == Qt::Checked) && !isChecked(file->filePath()))
if (checkValue == Qt::Checked && !mCheckedFiles.contains(file))
{
setState = true;
success = true;
}
else if ((checkValue == Qt::Checked) && isChecked(file->filePath()))
else if (checkValue == Qt::Checked && mCheckedFiles.contains(file))
setState = true;
else if (checkValue == Qt::Unchecked)
setState = true;
@ -314,34 +317,12 @@ bool ContentSelectorModel::ContentModel::setData(const QModelIndex& index, const
bool ContentSelectorModel::ContentModel::insertRows(int position, int rows, const QModelIndex& parent)
{
if (parent.isValid())
return false;
beginInsertRows(parent, position, position + rows - 1);
{
for (int row = 0; row < rows; ++row)
mFiles.insert(position, new EsmFile);
}
endInsertRows();
return true;
return false;
}
bool ContentSelectorModel::ContentModel::removeRows(int position, int rows, const QModelIndex& parent)
{
if (parent.isValid())
return false;
beginRemoveRows(parent, position, position + rows - 1);
{
for (int row = 0; row < rows; ++row)
delete mFiles.takeAt(position);
}
endRemoveRows();
// at this point we know that drag and drop has finished.
checkForLoadOrderErrors();
return true;
return false;
}
Qt::DropActions ContentSelectorModel::ContentModel::supportedDropActions() const
@ -357,13 +338,14 @@ QStringList ContentSelectorModel::ContentModel::mimeTypes() const
QMimeData* ContentSelectorModel::ContentModel::mimeData(const QModelIndexList& indexes) const
{
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
for (const QModelIndex& index : indexes)
{
if (!index.isValid())
continue;
encodedData.append(item(index.row())->encodedData());
stream << index.row();
}
QMimeData* mimeData = new QMimeData();
@ -395,26 +377,31 @@ bool ContentSelectorModel::ContentModel::dropMimeData(
QByteArray encodedData = data->data(mMimeType);
QDataStream stream(&encodedData, QIODevice::ReadOnly);
std::vector<EsmFile*> toMove;
while (!stream.atEnd())
{
QString value;
QStringList values;
QStringList gamefiles;
for (int i = 0; i < EsmFile::FileProperty_GameFile; ++i)
{
stream >> value;
values << value;
}
stream >> gamefiles;
insertRows(beginRow, 1);
QModelIndex idx = index(beginRow++, 0, QModelIndex());
setData(idx, QStringList() << values << gamefiles, Qt::EditRole);
int sourceRow;
stream >> sourceRow;
toMove.emplace_back(mFiles.at(sourceRow));
}
int minRow = mFiles.size();
int maxRow = 0;
for (EsmFile* file : toMove)
{
int from = mFiles.indexOf(file);
int to = beginRow;
if (from < beginRow)
to--;
else if (from > beginRow)
beginRow++;
minRow = std::min(minRow, std::min(to, from));
maxRow = std::max(maxRow, std::max(to, from));
mFiles.move(from, to);
}
dataChanged(index(minRow, 0), index(maxRow, 0));
// at this point we know that drag and drop has finished.
checkForLoadOrderErrors();
return true;
}
@ -447,26 +434,37 @@ void ContentSelectorModel::ContentModel::addFiles(const QString& path, bool newf
{
QFileInfo info(dir.absoluteFilePath(path2));
if (item(info.fileName()))
continue;
// Enabled by default in system openmw.cfg; shouldn't be shown in content list.
if (info.fileName().compare("builtin.omwscripts", Qt::CaseInsensitive) == 0)
continue;
EsmFile* file = const_cast<EsmFile*>(item(info.fileName()));
bool add = file == nullptr;
std::unique_ptr<EsmFile> newFile;
if (add)
{
newFile = std::make_unique<EsmFile>(path2);
file = newFile.get();
}
else
{
// We've found the same file in a higher priority dir, update our existing entry
file->setFileName(path2);
file->setGameFiles({});
}
if (info.fileName().endsWith(".omwscripts", Qt::CaseInsensitive))
{
EsmFile* file = new EsmFile(path2);
file->setDate(info.lastModified());
file->setFilePath(info.absoluteFilePath());
addFile(file);
if (add)
addFile(newFile.release());
setNew(file->fileName(), newfiles);
continue;
}
try
{
EsmFile* file = new EsmFile(path2);
file->setDate(info.lastModified());
file->setFilePath(info.absoluteFilePath());
std::filesystem::path filepath = Files::pathFromQString(info.absoluteFilePath());
@ -522,14 +520,14 @@ void ContentSelectorModel::ContentModel::addFiles(const QString& path, bool newf
}
// Put the file in the table
addFile(file);
if (add)
addFile(newFile.release());
setNew(file->fileName(), newfiles);
}
catch (std::runtime_error& e)
{
// An error occurred while reading the .esp
qWarning() << "Error reading addon file: " << e.what();
continue;
}
}
}
@ -554,6 +552,7 @@ void ContentSelectorModel::ContentModel::clearFiles()
if (filesCount > 0)
{
beginRemoveRows(QModelIndex(), 0, filesCount - 1);
qDeleteAll(mFiles);
mFiles.clear();
endRemoveRows();
}
@ -616,14 +615,6 @@ void ContentSelectorModel::ContentModel::sortFiles()
emit layoutChanged();
}
bool ContentSelectorModel::ContentModel::isChecked(const QString& filepath) const
{
const auto it = mCheckStates.find(filepath);
if (it == mCheckStates.end())
return false;
return it.value() == Qt::Checked;
}
bool ContentSelectorModel::ContentModel::isEnabled(const QModelIndex& index) const
{
return (flags(index) & Qt::ItemIsEnabled);
@ -684,7 +675,7 @@ void ContentSelectorModel::ContentModel::checkForLoadOrderErrors()
{
for (int row = 0; row < mFiles.count(); ++row)
{
EsmFile* file = item(row);
EsmFile* file = mFiles.at(row);
bool isRowInError = checkForLoadOrderErrors(file, row).count() != 0;
if (isRowInError)
{
@ -711,7 +702,7 @@ QList<ContentSelectorModel::LoadOrderError> ContentSelectorModel::ContentModel::
}
else
{
if (!isChecked(dependentFile->filePath()))
if (!mCheckedFiles.contains(dependentFile))
{
errors.append(LoadOrderError(LoadOrderError::ErrorCode_InactiveDependency, dependentfileName));
}
@ -761,19 +752,18 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath,
if (!file)
return false;
Qt::CheckState state = Qt::Unchecked;
if (checkState)
state = Qt::Checked;
mCheckedFiles.insert(file);
else
mCheckedFiles.erase(file);
mCheckStates[filepath] = state;
emit dataChanged(indexFromItem(item(filepath)), indexFromItem(item(filepath)));
if (file->isGameFile())
refreshModel();
// if we're checking an item, ensure all "upstream" files (dependencies) are checked as well.
if (state == Qt::Checked)
if (checkState)
{
for (const QString& upstreamName : file->gameFiles())
{
@ -782,14 +772,13 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath,
if (!upstreamFile)
continue;
if (!isChecked(upstreamFile->filePath()))
mCheckStates[upstreamFile->filePath()] = Qt::Checked;
mCheckedFiles.insert(upstreamFile);
emit dataChanged(indexFromItem(upstreamFile), indexFromItem(upstreamFile));
}
}
// otherwise, if we're unchecking an item (or the file is a game file) ensure all downstream files are unchecked.
if (state == Qt::Unchecked)
else
{
for (const EsmFile* downstreamFile : mFiles)
{
@ -798,8 +787,7 @@ bool ContentSelectorModel::ContentModel::setCheckState(const QString& filepath,
if (downstreamFile->gameFiles().contains(filename, Qt::CaseInsensitive))
{
if (mCheckStates.contains(downstreamFile->filePath()))
mCheckStates[downstreamFile->filePath()] = Qt::Unchecked;
mCheckedFiles.erase(downstreamFile);
emit dataChanged(indexFromItem(downstreamFile), indexFromItem(downstreamFile));
}
@ -817,7 +805,7 @@ ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checke
// First search for game files and next addons,
// so we get more or less correct game files vs addons order.
for (EsmFile* file : mFiles)
if (isChecked(file->filePath()))
if (mCheckedFiles.contains(file))
list << file;
return list;
@ -826,6 +814,6 @@ ContentSelectorModel::ContentFileList ContentSelectorModel::ContentModel::checke
void ContentSelectorModel::ContentModel::uncheckAll()
{
emit layoutAboutToBeChanged();
mCheckStates.clear();
mCheckedFiles.clear();
emit layoutChanged();
}

View file

@ -7,6 +7,8 @@
#include <QSet>
#include <QStringList>
#include <set>
namespace ContentSelectorModel
{
class EsmFile;
@ -57,7 +59,6 @@ namespace ContentSelectorModel
void setCurrentGameFile(const EsmFile* file);
bool isEnabled(const QModelIndex& index) const;
bool isChecked(const QString& filepath) const;
bool setCheckState(const QString& filepath, bool isChecked);
bool isNew(const QString& filepath) const;
void setNew(const QString& filepath, bool isChecked);
@ -85,7 +86,7 @@ namespace ContentSelectorModel
const EsmFile* mGameFile;
ContentFileList mFiles;
QStringList mArchives;
QHash<QString, Qt::CheckState> mCheckStates;
std::set<const EsmFile*> mCheckedFiles;
QHash<QString, bool> mNewFiles;
QSet<QString> mPluginsWithLoadOrderError;
QString mEncoding;

View file

@ -1,10 +1,5 @@
#include "esmfile.hpp"
#include <QDataStream>
#include <QIODevice>
int ContentSelectorModel::EsmFile::sPropertyCount = 7;
ContentSelectorModel::EsmFile::EsmFile(const QString& fileName, ModelItem* parent)
: ModelItem(parent)
, mFileName(fileName)
@ -46,17 +41,6 @@ void ContentSelectorModel::EsmFile::setDescription(const QString& description)
mDescription = description;
}
QByteArray ContentSelectorModel::EsmFile::encodedData() const
{
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
stream << mFileName << mAuthor << mVersion << mModified.toString(Qt::ISODate) << mPath << mDescription
<< mGameFiles;
return encodedData;
}
bool ContentSelectorModel::EsmFile::isGameFile() const
{
return (mGameFiles.size() == 0)

View file

@ -30,15 +30,11 @@ namespace ContentSelectorModel
};
EsmFile(const QString& fileName = QString(), ModelItem* parent = nullptr);
// EsmFile(const EsmFile &);
~EsmFile() {}
void setFileProperty(const FileProperty prop, const QString& value);
void setFileName(const QString& fileName);
void setAuthor(const QString& author);
void setSize(const int size);
void setDate(const QDateTime& modified);
void setFormat(const QString& format);
void setFilePath(const QString& path);
@ -68,10 +64,6 @@ namespace ContentSelectorModel
}
bool isGameFile() const;
QByteArray encodedData() const;
public:
static int sPropertyCount;
private:
QString mTooltipTemlate = tr(

View file

@ -108,6 +108,7 @@ void ContentSelectorView::ContentSelector::buildAddonView()
connect(ui->addonView, &QTableView::activated, this, &ContentSelector::slotAddonTableItemActivated);
connect(mContentModel, &ContentSelectorModel::ContentModel::dataChanged, this,
&ContentSelector::signalAddonDataChanged);
connect(mContentModel, &ContentSelectorModel::ContentModel::dataChanged, this, &ContentSelector::slotRowsMoved);
buildContextMenu();
}
@ -331,3 +332,8 @@ void ContentSelectorView::ContentSelector::slotSearchFilterTextChanged(const QSt
{
ui->addonView->setDragEnabled(newText.isEmpty());
}
void ContentSelectorView::ContentSelector::slotRowsMoved()
{
ui->addonView->selectionModel()->clearSelection();
}

View file

@ -85,6 +85,7 @@ namespace ContentSelectorView
void slotUncheckMultiSelectedItems();
void slotCopySelectedItemsPaths();
void slotSearchFilterTextChanged(const QString& newText);
void slotRowsMoved();
};
}

View file

@ -189,42 +189,18 @@ namespace DetourNavigator
void RecastMeshBuilder::addObject(const btBoxShape& shape, const btTransform& transform, const AreaType areaType)
{
constexpr std::array<int, 36> indices{ {
0,
2,
3,
3,
1,
0,
0,
4,
6,
6,
2,
0,
0,
1,
5,
5,
4,
0,
7,
5,
1,
1,
3,
7,
7,
3,
2,
2,
6,
7,
7,
6,
4,
4,
5,
7,
0, 2, 3, // triangle 0
3, 1, 0, // triangle 1
0, 4, 6, // triangle 2
6, 2, 0, // triangle 3
0, 1, 5, // triangle 4
5, 4, 0, // triangle 5
7, 5, 1, // triangle 6
1, 3, 7, // triangle 7
7, 3, 2, // triangle 8
2, 6, 7, // triangle 9
7, 6, 4, // triangle 10
4, 5, 7, // triangle 11
} };
for (std::size_t i = 0; i < indices.size(); i += 3)

View file

@ -47,6 +47,7 @@ namespace DetourNavigator
return position;
}
// Returns value in NavMesh coordinates
inline float getTileSize(const RecastSettings& settings)
{
return static_cast<float>(settings.mTileSize) * settings.mCellSize;
@ -62,16 +63,19 @@ namespace DetourNavigator
return static_cast<int>(v);
}
// Returns integer tile position for position in navmesh coordinates
inline TilePosition getTilePosition(const RecastSettings& settings, const osg::Vec2f& position)
{
return TilePosition(getTilePosition(settings, position.x()), getTilePosition(settings, position.y()));
}
// Returns integer tile position for position in navmesh coordinates
inline TilePosition getTilePosition(const RecastSettings& settings, const osg::Vec3f& position)
{
return getTilePosition(settings, osg::Vec2f(position.x(), position.z()));
}
// Returns tile bounds in navmesh coordinates
inline TileBounds makeTileBounds(const RecastSettings& settings, const TilePosition& tilePosition)
{
return TileBounds{
@ -80,6 +84,7 @@ namespace DetourNavigator
};
}
// Returns border size relative to cell size
inline float getBorderSize(const RecastSettings& settings)
{
return static_cast<float>(settings.mBorderSize) * settings.mCellSize;
@ -95,6 +100,7 @@ namespace DetourNavigator
return std::floor(std::sqrt(settings.mMaxTilesNumber / osg::PI)) - 1;
}
// Returns tile bounds in real coordinates
inline TileBounds makeRealTileBoundsWithBorder(const RecastSettings& settings, const TilePosition& tilePosition)
{
TileBounds result = makeTileBounds(settings, tilePosition);

View file

@ -288,6 +288,7 @@ namespace LuaUi
auto children = parent->children();
auto it = std::find(children.begin(), children.end(), mRoot);
mRoot = createWidget(layout(), 0);
assert(it != children.end());
*it = mRoot;
parent->setChildren(children);
mRoot->updateCoord();

View file

@ -315,8 +315,7 @@ namespace Stereo
else
{
auto* ds = osg::DisplaySettings::instance().get();
auto viewMatrix = mMainCamera->getViewMatrix();
auto projectionMatrix = mMainCamera->getProjectionMatrix();
const auto& projectionMatrix = mMainCamera->getProjectionMatrix();
auto s = ds->getEyeSeparation() * Constants::UnitsPerMeter;
mViewOffsetMatrix[0]
= osg::Matrixd(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, s, 0.0, 0.0, 1.0);

View file

@ -682,7 +682,6 @@
---
-- @type ActiveEffect
-- Magic effect that is currently active on an actor.
-- Note that when this effect expires or is removed, it will remain temporarily. Magnitude will be set to 0 for effects that expire.
-- @field #string affectedSkill Optional skill ID
-- @field #string affectedAttribute Optional attribute ID
-- @field #string id Effect id string

View file

@ -210,14 +210,14 @@
-- end
-- @usage -- Check for a specific effect
-- local effect = Actor.activeEffects(self):getEffect(core.magic.EFFECT_TYPE.Telekinesis)
-- if effect then
-- if effect.magnitude ~= 0 then
-- print(effect.id..', attribute='..tostring(effect.affectedAttribute)..', skill='..tostring(effect.affectedSkill)..', magnitude='..tostring(effect.magnitude))
-- else
-- print('No Telekinesis effect')
-- end
-- @usage -- Check for a specific effect targeting a specific attribute.
-- local effect = Actor.activeEffects(self):getEffect(core.magic.EFFECT_TYPE.FortifyAttribute, core.ATTRIBUTE.Luck)
-- if effect then
-- if effect.magnitude ~= 0 then
-- print(effect.id..', attribute='..tostring(effect.affectedAttribute)..', skill='..tostring(effect.affectedSkill)..', magnitude='..tostring(effect.magnitude))
-- else
-- print('No Fortify Luck effect')
@ -229,7 +229,7 @@
-- @param self
-- @param #string effectId effect ID
-- @param #string extraParam Optional skill or attribute ID
-- @return openmw.core#ActiveEffect if such an effect is active, nil otherwise
-- @return openmw.core#ActiveEffect
---
-- Completely removes the active effect from the actor.