From ffe8bbd2ddd39de83ce87cfaf7e04a439991bec8 Mon Sep 17 00:00:00 2001 From: bzzt Date: Wed, 29 May 2019 13:37:00 +0000 Subject: [PATCH 01/32] racingcrashfix #4766 --- components/nifosg/nifloader.cpp | 12 ++++++++++-- components/shader/shadervisitor.cpp | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index d6a459b1b1..f5f7c37047 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -400,7 +400,10 @@ namespace NifOsg return; } - osg::ref_ptr texture2d (new osg::Texture2D(handleSourceTexture(textureEffect->texture.getPtr(), imageManager))); + osg::ref_ptr image (handleSourceTexture(textureEffect->texture.getPtr(), imageManager)); + osg::ref_ptr texture2d (new osg::Texture2D(image)); + if (image) + texture2d->setTextureSize(image->s(), image->t()); texture2d->setName("envMap"); unsigned int clamp = static_cast(textureEffect->clamp); int wrapT = (clamp) & 0x1; @@ -770,7 +773,10 @@ namespace NifOsg wrapT = inherit->getWrap(osg::Texture2D::WRAP_T); } - osg::ref_ptr texture (new osg::Texture2D(handleSourceTexture(st.getPtr(), imageManager))); + osg::ref_ptr image (handleSourceTexture(st.getPtr(), imageManager)); + osg::ref_ptr texture (new osg::Texture2D(image)); + if (image) + texture->setTextureSize(image->s(), image->t()); texture->setWrap(osg::Texture::WRAP_S, wrapS); texture->setWrap(osg::Texture::WRAP_T, wrapT); textures.push_back(texture); @@ -1337,6 +1343,8 @@ namespace NifOsg const Nif::NiSourceTexture *st = tex.texture.getPtr(); osg::ref_ptr image = handleSourceTexture(st, imageManager); texture2d = new osg::Texture2D(image); + if (image) + texture2d->setTextureSize(image->s(), image->t()); } else texture2d = new osg::Texture2D; diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 63c6761188..e40cc255b9 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -163,6 +163,7 @@ namespace Shader if (image) { osg::ref_ptr normalMapTex (new osg::Texture2D(image)); + normalMapTex->setTextureSize(image->s(), image->t()); normalMapTex->setWrap(osg::Texture::WRAP_S, diffuseMap->getWrap(osg::Texture::WRAP_S)); normalMapTex->setWrap(osg::Texture::WRAP_T, diffuseMap->getWrap(osg::Texture::WRAP_T)); normalMapTex->setFilter(osg::Texture::MIN_FILTER, diffuseMap->getFilter(osg::Texture::MIN_FILTER)); @@ -186,7 +187,9 @@ namespace Shader boost::replace_last(specularMapFileName, ".", mSpecularMapPattern + "."); if (mImageManager.getVFS()->exists(specularMapFileName)) { - osg::ref_ptr specularMapTex (new osg::Texture2D(mImageManager.getImage(specularMapFileName))); + osg::ref_ptr image (mImageManager.getImage(specularMapFileName)); + osg::ref_ptr specularMapTex (new osg::Texture2D(image)); + specularMapTex->setTextureSize(image->s(), image->t()); specularMapTex->setWrap(osg::Texture::WRAP_S, diffuseMap->getWrap(osg::Texture::WRAP_S)); specularMapTex->setWrap(osg::Texture::WRAP_T, diffuseMap->getWrap(osg::Texture::WRAP_T)); specularMapTex->setFilter(osg::Texture::MIN_FILTER, diffuseMap->getFilter(osg::Texture::MIN_FILTER)); From ebe5448816532c55b9c19ded462b8e65701bd8bb Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 16 May 2019 00:15:21 +0300 Subject: [PATCH 02/32] Content selector: drop duplicates of the added file (bug #2395) --- CHANGELOG.md | 1 + components/contentselector/model/contentmodel.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5c6a08853..3658b839a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ------ Bug #1515: Opening console masks dialogue, inventory menu + Bug #2395: Duplicated plugins in the launcher when multiple data directories provide the same plugin Bug #2969: Scripted items can stack Bug #2987: Editor: some chance and AI data fields can overflow Bug #3006: 'else if' operator breaks script compilation diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 7a4558d57a..ef27f938d2 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -408,6 +408,17 @@ bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt: void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { + for (int row = 0; row < mFiles.size(); row++) + { + if (mFiles.at(row)->fileName() == file->fileName()) + { + beginRemoveRows(QModelIndex(), row, row); + mFiles.removeAt(row); + endRemoveRows(); + emit dataChanged(index(row, 0), index(mFiles.size(), 0)); + break; + } + } beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); From e14ada8f364ffa77a9e01997ca83b2ffc9ba6173 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 16 May 2019 14:06:33 +0300 Subject: [PATCH 03/32] Make file name comparison case-insensitive --- components/contentselector/model/contentmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index ef27f938d2..d39df8ce62 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -410,7 +410,7 @@ void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { for (int row = 0; row < mFiles.size(); row++) { - if (mFiles.at(row)->fileName() == file->fileName()) + if (!mFiles.at(row)->fileName().compare(file->fileName(), Qt::CaseInsensitive)) { beginRemoveRows(QModelIndex(), row, row); mFiles.removeAt(row); From 2fbed21f83bc6c3af9f06b07e30ce306f1589111 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 18 May 2019 14:17:18 +0300 Subject: [PATCH 04/32] Avoid a memory leak --- components/contentselector/model/contentmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index d39df8ce62..3e5afc76da 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -413,7 +413,7 @@ void ContentSelectorModel::ContentModel::addFile(EsmFile *file) if (!mFiles.at(row)->fileName().compare(file->fileName(), Qt::CaseInsensitive)) { beginRemoveRows(QModelIndex(), row, row); - mFiles.removeAt(row); + delete mFiles.takeAt(row); endRemoveRows(); emit dataChanged(index(row, 0), index(mFiles.size(), 0)); break; From 5cd781b3ebc462bffbb32c10d437985bcc1d57c8 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 18 May 2019 17:21:27 +0300 Subject: [PATCH 05/32] Experimental folder handling rewrite --- apps/launcher/datafilespage.cpp | 9 ++++----- apps/opencs/editor.cpp | 19 +++---------------- apps/opencs/editor.hpp | 2 -- .../contentselector/model/contentmodel.cpp | 9 ++------- 4 files changed, 9 insertions(+), 30 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 055426f30f..8554b620bb 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -109,15 +109,14 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName) { QStringList paths = mGameSettings.getDataDirs(); - foreach(const QString &path, paths) - mSelector->addFiles(path); - mDataLocal = mGameSettings.getDataLocal(); if (!mDataLocal.isEmpty()) - mSelector->addFiles(mDataLocal); + paths.insert(0, mDataLocal); + + foreach(const QString &path, paths) + mSelector->addFiles(path); - paths.insert(0, mDataLocal); PathIterator pathIterator(paths); mSelector->setProfileContent(filesInProfile(contentModelName, pathIterator)); diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 7b5c3f7ab2..b22f5464d8 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -28,8 +28,6 @@ CS::Editor::Editor (int argc, char **argv) mViewManager = new CSVDoc::ViewManager(mDocumentManager); - setupDataFiles (config.first); - NifOsg::Loader::setShowMarkers(true); mDocumentManager.setFileData(mFsStrict, config.first, config.second); @@ -79,15 +77,6 @@ CS::Editor::~Editor () remove(mPid.string().c_str())); // ignore any error } -void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) -{ - for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) - { - QString path = QString::fromUtf8 (iter->string().c_str()); - mFileDialog.addFiles(path); - } -} - std::pair > CS::Editor::readConfig(bool quiet) { boost::program_options::variables_map variables; @@ -160,7 +149,7 @@ std::pair > CS::Editor::readConfi dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); //iterate the data directories and add them to the file dialog for loading - for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) + for (Files::PathContainer::const_reverse_iterator iter = dataDirs.rbegin(); iter != dataDirs.rend(); ++iter) { QString path = QString::fromUtf8 (iter->string().c_str()); mFileDialog.addFiles(path); @@ -199,8 +188,7 @@ void CS::Editor::createAddon() mStartup.hide(); mFileDialog.clearFiles(); - std::pair > config = readConfig(/*quiet*/true); - setupDataFiles (config.first); + readConfig(/*quiet*/true); mFileDialog.showDialog (CSVDoc::ContentAction_New); } @@ -224,8 +212,7 @@ void CS::Editor::loadDocument() mStartup.hide(); mFileDialog.clearFiles(); - std::pair > config = readConfig(/*quiet*/true); - setupDataFiles (config.first); + readConfig(/*quiet*/true); mFileDialog.showDialog (CSVDoc::ContentAction_Edit); } diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 2c2e88aefc..0c3ece9059 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -55,8 +55,6 @@ namespace CS CSVTools::Merge mMerge; CSVDoc::ViewManager* mViewManager; - void setupDataFiles (const Files::PathContainer& dataDirs); - std::pair > readConfig(bool quiet=false); ///< \return data paths diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 3e5afc76da..6ac074b4db 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -411,14 +411,9 @@ void ContentSelectorModel::ContentModel::addFile(EsmFile *file) for (int row = 0; row < mFiles.size(); row++) { if (!mFiles.at(row)->fileName().compare(file->fileName(), Qt::CaseInsensitive)) - { - beginRemoveRows(QModelIndex(), row, row); - delete mFiles.takeAt(row); - endRemoveRows(); - emit dataChanged(index(row, 0), index(mFiles.size(), 0)); - break; - } + return; } + beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); From 0fcb75fb213f33107271fea26f712a6828d1ac9c Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 22 May 2019 20:55:30 +0300 Subject: [PATCH 06/32] Achieve CHIM and get rid of the loop --- components/contentselector/model/contentmodel.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 6ac074b4db..390dde223c 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -408,12 +408,6 @@ bool ContentSelectorModel::ContentModel::dropMimeData(const QMimeData *data, Qt: void ContentSelectorModel::ContentModel::addFile(EsmFile *file) { - for (int row = 0; row < mFiles.size(); row++) - { - if (!mFiles.at(row)->fileName().compare(file->fileName(), Qt::CaseInsensitive)) - return; - } - beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count()); mFiles.append(file); endInsertRows(); @@ -434,7 +428,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) { QFileInfo info(dir.absoluteFilePath(path2)); - if (item(info.absoluteFilePath()) != 0) + if (item(info.fileName())) continue; try { From 596dbbe70b872ba766aacdbb6536b48e11fa9f90 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 3 Jun 2019 20:04:40 +0300 Subject: [PATCH 07/32] Make sure fade operations properly end (bug #4639) --- CHANGELOG.md | 1 + apps/openmw/mwgui/screenfader.cpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82621d794b..cc0c8c6deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Bug #4384: Resist Normal Weapons only checks ammunition for ranged weapons Bug #4411: Reloading a saved game while falling prevents damage in some cases Bug #4540: Rain delay when exiting water + Bug #4639: Black screen after completing first mages guild mission + training Bug #4701: PrisonMarker record is not hardcoded like other markers Bug #4703: Editor: it's possible to preview levelled list records Bug #4705: Editor: unable to open exterior cell views from Instances table diff --git a/apps/openmw/mwgui/screenfader.cpp b/apps/openmw/mwgui/screenfader.cpp index e75e4954e4..619852a22b 100644 --- a/apps/openmw/mwgui/screenfader.cpp +++ b/apps/openmw/mwgui/screenfader.cpp @@ -38,12 +38,20 @@ namespace MWGui if (!mRunning) return; - if (mRemainingTime <= 0 || mStartAlpha == mTargetAlpha) + if (mStartAlpha == mTargetAlpha) { finish(); return; } + if (mRemainingTime <= 0) + { + // Make sure the target alpha is applied + mFader->notifyAlphaChanged(mTargetAlpha); + finish(); + return; + } + if (mRemainingTime > mTargetTime) { mRemainingTime -= dt; @@ -162,7 +170,7 @@ namespace MWGui if (time < 0.f) return; - if (time == 0.f) + if (time == 0.f && delay == 0.f) { mCurrentAlpha = targetAlpha; applyAlpha(); From ef2a7160fa21142fe0f4d6fdac2cafa40a651c08 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sat, 8 Jun 2019 15:06:04 +0300 Subject: [PATCH 08/32] Fix automovement toggling on "joystick used" flag --- apps/openmw/mwinput/inputmanagerimp.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 4b11d9af4a..d66cc65776 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -623,11 +623,7 @@ namespace MWInput mPlayer->setAutoMove (false); mPlayer->setForwardBackward((yAxis - 0.5f) * 2 * -1); } - else if(mPlayer->getAutoMove()) - { - triedToMove = true; - mPlayer->setForwardBackward (1); - } + if (triedToMove) mJoystickLastUsed = true; @@ -649,7 +645,8 @@ namespace MWInput mPlayer->setAutoMove (false); mPlayer->setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); } - else if(mPlayer->getAutoMove()) + + if (mPlayer->getAutoMove()) { alwaysRunAllowed = true; triedToMove = true; From 295ee11063f27e1faa826dd9117a79cdd051b338 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 8 Jun 2019 17:06:34 +0300 Subject: [PATCH 09/32] Make Player->Cast select the spell instead (bug #5056) --- CHANGELOG.md | 1 + apps/openmw/mwscript/miscextensions.cpp | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7b3464149..fb6b9d5adb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,6 +99,7 @@ Bug #5038: Enchanting success chance calculations are blatantly wrong Bug #5047: # in cell names sets color Bug #5050: Invalid spell effects are not handled gracefully + Bug #5056: Calling Cast function on player doesn't equip the spell but casts it Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index d74893a0f9..65c684fc5c 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -1096,21 +1096,29 @@ namespace MWScript std::string targetId = ::Misc::StringUtils::lowerCase(runtime.getStringLiteral (runtime[0].mInteger)); runtime.pop(); - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find (spellId); + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(spellId); if (!spell) { - runtime.getContext().report("spellcasting failed: can not find spell \""+spellId+"\""); + runtime.getContext().report("spellcasting failed: cannot find spell \""+spellId+"\""); return; } if (spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power) { - runtime.getContext().report("spellcasting failed: you can cast only spells and powers."); + runtime.getContext().report("spellcasting failed: you can only cast spells and powers."); return; } - // Obviously we can not use casting animation for player here - if (ptr.getClass().isActor() && ptr != MWMechanics::getPlayer()) + if (ptr == MWMechanics::getPlayer()) + { + MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); + store.setSelectedEnchantItem(store.end()); + MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, ptr))); + MWBase::Environment::get().getWindowManager()->updateSpellWindow(); + return; + } + + if (ptr.getClass().isActor()) { MWMechanics::AiCast castPackage(targetId, spellId, true); ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(castPackage, ptr); From 7c8360d0f32f14c93fc8343a1c0f01ebedf5fb4c Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 9 Jun 2019 01:58:02 +0300 Subject: [PATCH 10/32] Use NiSwitchNode initial index field --- components/nif/node.hpp | 4 +++- components/nifosg/nifloader.cpp | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/nif/node.hpp b/components/nif/node.hpp index d9afbbed71..cc1871d83a 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -238,10 +238,12 @@ struct NiRotatingParticles : Node // A node used as the base to switch between child nodes, such as for LOD levels. struct NiSwitchNode : public NiNode { + unsigned int initialIndex; + void read(NIFStream *nif) { NiNode::read(nif); - nif->getInt(); // unknown + initialIndex = nif->getUInt(); } }; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index d6a459b1b1..9945eefb20 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -629,10 +629,8 @@ namespace NifOsg if (nifNode->recType == Nif::RC_NiSwitchNode) { - // show only first child by default - node->asSwitch()->setSingleChildOn(0); - const Nif::NiSwitchNode* niSwitchNode = static_cast(nifNode); + node->asSwitch()->setSingleChildOn(niSwitchNode->initialIndex); if (niSwitchNode->name == Constants::NightDayLabel && !SceneUtil::hasUserDescription(rootNode, Constants::NightDayLabel)) rootNode->getOrCreateUserDataContainer()->addDescription(Constants::NightDayLabel); else if (niSwitchNode->name == Constants::HerbalismLabel && !SceneUtil::hasUserDescription(rootNode, Constants::HerbalismLabel)) From 56539fee4fa0203f2ede8251d6fc2bd413346096 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 9 Jun 2019 02:08:09 +0300 Subject: [PATCH 11/32] Partially revert "Get rid of redundant setKeyFocusWidget() method" --- apps/openmw/mwbase/windowmanager.hpp | 3 +++ apps/openmw/mwgui/alchemywindow.cpp | 3 +-- apps/openmw/mwgui/birth.cpp | 3 +-- apps/openmw/mwgui/bookwindow.cpp | 6 +++--- apps/openmw/mwgui/class.cpp | 7 +++---- apps/openmw/mwgui/confirmationdialog.cpp | 3 +-- apps/openmw/mwgui/console.cpp | 5 ++--- apps/openmw/mwgui/container.cpp | 6 +++--- apps/openmw/mwgui/countdialog.cpp | 3 +-- apps/openmw/mwgui/dialogue.cpp | 7 +++---- apps/openmw/mwgui/enchantingdialog.cpp | 3 +-- apps/openmw/mwgui/journalwindow.cpp | 6 +++--- apps/openmw/mwgui/keyboardnavigation.cpp | 12 ++++++------ apps/openmw/mwgui/mainmenu.cpp | 7 +++---- apps/openmw/mwgui/mapwindow.cpp | 2 +- apps/openmw/mwgui/race.cpp | 3 +-- apps/openmw/mwgui/savegamedialog.cpp | 12 ++++++------ apps/openmw/mwgui/scrollwindow.cpp | 3 +-- apps/openmw/mwgui/settingswindow.cpp | 3 +-- apps/openmw/mwgui/spellcreationdialog.cpp | 3 +-- apps/openmw/mwgui/spellwindow.cpp | 2 +- apps/openmw/mwgui/textinput.cpp | 7 +++---- apps/openmw/mwgui/tradewindow.cpp | 2 +- apps/openmw/mwgui/waitdialog.cpp | 6 +++--- apps/openmw/mwgui/windowmanagerimp.cpp | 13 ++++++++++--- apps/openmw/mwgui/windowmanagerimp.hpp | 3 +++ 26 files changed, 66 insertions(+), 67 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index bbf7a21c41..e8ae61fe59 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -289,6 +289,9 @@ namespace MWBase virtual const Translation::Storage& getTranslationDataStorage() const = 0; + /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. + virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0; + virtual void loadUserFonts() = 0; virtual Loading::Listener* getLoadingScreen() = 0; diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index c1bdd023f4..ad66735bfd 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -169,7 +168,7 @@ namespace MWGui update(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mNameEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit); } void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 8955606d29..6f6a621adf 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -72,7 +71,7 @@ namespace MWGui WindowModal::onOpen(); updateBirths(); updateSpells(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mBirthList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mBirthList); // Show the current birthsign by default const std::string &signId = diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index e4cf254e22..86089051d6 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -101,7 +101,7 @@ namespace MWGui setTakeButtonShow(showTakeButton); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); } void BookWindow::setTakeButtonShow(bool show) @@ -161,9 +161,9 @@ namespace MWGui mPrevPageButton->setVisible(prevPageVisible); if (focus == mNextPageButton && !nextPageVisible && prevPageVisible) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mPrevPageButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mPrevPageButton); else if (focus == mPrevPageButton && !prevPageVisible && nextPageVisible) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mNextPageButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNextPageButton); if (mPages.empty()) return; diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index 94c493be73..a92ad934cd 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -136,7 +135,7 @@ namespace MWGui WindowModal::onOpen (); updateClasses(); updateStats(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mClassList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mClassList); // Show the current class by default MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -437,7 +436,7 @@ namespace MWGui getWidget(mEditName, "EditName"); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mEditName); MyGUI::Button* descriptionButton; getWidget(descriptionButton, "DescriptionButton"); @@ -903,7 +902,7 @@ namespace MWGui okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", "")); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } DescriptionDialog::~DescriptionDialog() diff --git a/apps/openmw/mwgui/confirmationdialog.cpp b/apps/openmw/mwgui/confirmationdialog.cpp index c5a50c2e63..65b079d85b 100644 --- a/apps/openmw/mwgui/confirmationdialog.cpp +++ b/apps/openmw/mwgui/confirmationdialog.cpp @@ -2,7 +2,6 @@ #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -34,7 +33,7 @@ namespace MWGui mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height + 24); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mOkButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton); center(); } diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 705e281381..1633b92db5 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -1,7 +1,6 @@ #include "console.hpp" #include -#include #include #include @@ -153,7 +152,7 @@ namespace MWGui { // Give keyboard focus to the combo box whenever the console is // turned on and place it over other widgets - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCommandLine); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine); MyGUI::LayerManager::getInstance().upLayerItem(mMainWidget); } @@ -450,7 +449,7 @@ namespace MWGui mPtr = object; } // User clicked on an object. Restore focus to the console command line. - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCommandLine); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine); } else { diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 5aa5d01435..bfe93f6ed9 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -141,7 +141,7 @@ namespace MWGui mItemView->setModel (mSortModel); mItemView->resetScrollBars(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); setTitle(container.getClass().getName(container)); } @@ -175,7 +175,7 @@ namespace MWGui if(mDragAndDrop != nullptr && mDragAndDrop->mIsOnDragAndDrop) return; - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); // transfer everything into the player's inventory ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel(); @@ -222,7 +222,7 @@ namespace MWGui { if(mDragAndDrop == nullptr || !mDragAndDrop->mIsOnDragAndDrop) { - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); onTakeAllButtonClicked(mTakeButton); diff --git a/apps/openmw/mwgui/countdialog.cpp b/apps/openmw/mwgui/countdialog.cpp index 30ef507590..baf3a43abd 100644 --- a/apps/openmw/mwgui/countdialog.cpp +++ b/apps/openmw/mwgui/countdialog.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include @@ -48,7 +47,7 @@ namespace MWGui mMainWidget->getHeight()); // by default, the text edit field has the focus of the keyboard - MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit); mSlider->setScrollPosition(maxCount-1); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 4c9e6b230e..6b400c1724 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -381,7 +380,7 @@ namespace MWGui { onTopicActivated(topic); if (mGoodbyeButton->getEnabled()) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mGoodbyeButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton); } else if (topic == sPersuasion) mPersuasionDialog.setVisible(true); @@ -444,7 +443,7 @@ namespace MWGui return; } - MyGUI::InputManager::getInstance().setKeyFocusWidget(mGoodbyeButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton); setTitle(mPtr.getClass().getName(mPtr)); @@ -623,7 +622,7 @@ namespace MWGui bool goodbyeWasEnabled = mGoodbyeButton->getEnabled(); mGoodbyeButton->setEnabled(goodbyeEnabled); if (goodbyeEnabled && !goodbyeWasEnabled) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mGoodbyeButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton); bool topicsEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye; mTopicsList->setEnabled(topicsEnabled); diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 41f82bd2f6..d0d2118c6e 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -68,7 +67,7 @@ namespace MWGui void EnchantingDialog::onOpen() { center(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mName); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mName); } void EnchantingDialog::setSoulGem(const MWWorld::Ptr &gem) diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 34c0fa8e15..43e7edf1e4 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -254,7 +254,7 @@ namespace } updateShowingPages(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(getWidget(CloseBTN)); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(getWidget(CloseBTN)); } void onClose() @@ -377,9 +377,9 @@ namespace prevPageBtn->setVisible(prevPageVisible); if (focus == nextPageBtn && !nextPageVisible && prevPageVisible) - MyGUI::InputManager::getInstance().setKeyFocusWidget(prevPageBtn); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(prevPageBtn); else if (focus == prevPageBtn && !prevPageVisible && nextPageVisible) - MyGUI::InputManager::getInstance().setKeyFocusWidget(nextPageBtn); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nextPageBtn); setVisible (PageOneNum, relPages > 0); setVisible (PageTwoNum, relPages > 1); diff --git a/apps/openmw/mwgui/keyboardnavigation.cpp b/apps/openmw/mwgui/keyboardnavigation.cpp index 79b9e8457e..7355dc1f4c 100644 --- a/apps/openmw/mwgui/keyboardnavigation.cpp +++ b/apps/openmw/mwgui/keyboardnavigation.cpp @@ -83,7 +83,7 @@ void KeyboardNavigation::restoreFocus(int mode) { MyGUI::Widget* w = found->second; if (w && w->getVisible() && w->getEnabled()) - MyGUI::InputManager::getInstance().setKeyFocusWidget(found->second); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(found->second); } } @@ -130,7 +130,7 @@ void KeyboardNavigation::onFrame() // workaround incorrect key focus resets (fix in MyGUI TBD) if (!shouldAcceptKeyFocus(focus) && shouldAcceptKeyFocus(mCurrentFocus) && (!mModalWindow || isRootParent(mCurrentFocus, mModalWindow))) { - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCurrentFocus); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCurrentFocus); focus = mCurrentFocus; } @@ -154,12 +154,12 @@ void KeyboardNavigation::setDefaultFocus(MyGUI::Widget *window, MyGUI::Widget *d MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); if (!focus || !shouldAcceptKeyFocus(focus)) { - MyGUI::InputManager::getInstance().setKeyFocusWidget(defaultFocus); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus); } else { if (!isRootParent(focus, window)) - MyGUI::InputManager::getInstance().setKeyFocusWidget(defaultFocus); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus); } } @@ -276,7 +276,7 @@ bool KeyboardNavigation::switchFocus(int direction, bool wrap) else if (direction == D_Up && (vertdiff >= 0 || !isVertical)) return false; - MyGUI::InputManager::getInstance().setKeyFocusWidget(keyFocusList[index]); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[index]); return true; } @@ -291,7 +291,7 @@ bool KeyboardNavigation::selectFirstWidget() if (!keyFocusList.empty()) { - MyGUI::InputManager::getInstance().setKeyFocusWidget(keyFocusList[0]); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[0]); return true; } return false; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 782162d32f..4778ee7b09 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -68,12 +67,12 @@ namespace MWGui if (isMainMenu) { if (mButtons["loadgame"]->getVisible()) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mButtons["loadgame"]); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["loadgame"]); else - MyGUI::InputManager::getInstance().setKeyFocusWidget(mButtons["newgame"]); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["newgame"]); } else - MyGUI::InputManager::getInstance().setKeyFocusWidget(mButtons["return"]); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["return"]); } Layout::setVisible (visible); diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 7d622ab542..02d2be5770 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -1123,7 +1123,7 @@ namespace MWGui { WindowModal::onOpen(); center(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } void EditNoteDialog::onCancelButtonClicked(MyGUI::Widget *sender) diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 9d3e1e0a99..cf69ecca38 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include @@ -166,7 +165,7 @@ namespace MWGui mHeadRotate->setScrollPosition(initialPos); onHeadRotate(mHeadRotate, initialPos); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mRaceList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mRaceList); } void RaceDialog::setRaceId(const std::string &raceId) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 903fdf69dd..e9fb2a9642 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -94,7 +94,7 @@ namespace MWGui MWBase::Environment::get().getStateManager()->deleteGame (mCurrentCharacter, mCurrentSlot); mSaveList->removeItemAt(mSaveList->getIndexSelected()); onSlotSelected(mSaveList, mSaveList->getIndexSelected()); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); if (mSaveList->getItemCount() == 0) { @@ -114,7 +114,7 @@ namespace MWGui void SaveGameDialog::onDeleteSlotCancel() { - MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); } void SaveGameDialog::onSaveNameChanged(MyGUI::EditBox *sender) @@ -138,9 +138,9 @@ namespace MWGui mSaveNameEdit->setCaption (""); if (mSaving) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveNameEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveNameEdit); else - MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); center(); @@ -244,7 +244,7 @@ namespace MWGui void SaveGameDialog::onConfirmationCancel() { - MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); } void SaveGameDialog::accept(bool reallySure) @@ -331,7 +331,7 @@ namespace MWGui void SaveGameDialog::onCharacterAccept(MyGUI::ComboBox* sender, size_t pos) { // Give key focus to save list so we can confirm the selection with Enter - MyGUI::InputManager::getInstance().setKeyFocusWidget(mSaveList); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); } void SaveGameDialog::fillSaveList() diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index adbbaba15f..f2c967da4e 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -1,7 +1,6 @@ #include "scrollwindow.hpp" #include -#include #include #include @@ -67,7 +66,7 @@ namespace MWGui setTakeButtonShow(showTakeButton); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mCloseButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); } void ScrollWindow::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 1cdc67f6a1..dc89e61343 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include @@ -616,7 +615,7 @@ namespace MWGui highlightCurrentResolution(); updateControlsBox(); resetScrollbars(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mOkButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton); } void SettingsWindow::onWindowResize(MyGUI::Window *_sender) diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 03e6c77f8a..23f24e321f 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -432,7 +431,7 @@ namespace MWGui void SpellCreationDialog::onOpen() { center(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mNameEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit); } void SpellCreationDialog::onReferenceUnavailable () diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 3f39bd11dc..d0be05dfbb 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -83,7 +83,7 @@ namespace MWGui // Reset the filter focus when opening the window MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); if (focus == mFilterEdit) - MyGUI::InputManager::getInstance().resetKeyFocusWidget(); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr); updateSpells(); } diff --git a/apps/openmw/mwgui/textinput.cpp b/apps/openmw/mwgui/textinput.cpp index 4cc7a576be..54f2d3be9b 100644 --- a/apps/openmw/mwgui/textinput.cpp +++ b/apps/openmw/mwgui/textinput.cpp @@ -5,7 +5,6 @@ #include #include -#include namespace MWGui { @@ -24,7 +23,7 @@ namespace MWGui okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } void TextInputDialog::setNextButtonShow(bool shown) @@ -47,7 +46,7 @@ namespace MWGui { WindowModal::onOpen(); // Make sure the edit box has focus - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } // widget controls @@ -57,7 +56,7 @@ namespace MWGui if (mTextEdit->getCaption() == "") { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}"); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit); } else eventDone(this); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 83096140e6..0c9b31b650 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -136,7 +136,7 @@ namespace MWGui onFilterChanged(mFilterAll); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mTotalBalance); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTotalBalance); } void TradeWindow::onFrame(float dt) diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index eb36e3cb24..d18eaebdd0 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -93,9 +93,9 @@ namespace MWGui } if (mUntilHealedButton->getVisible()) - MyGUI::InputManager::getInstance().setKeyFocusWidget(mUntilHealedButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton); else - MyGUI::InputManager::getInstance().setKeyFocusWidget(mWaitButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mWaitButton); } bool WaitDialog::exit() @@ -222,7 +222,7 @@ namespace MWGui { mHourText->setCaptionWithReplacing (MyGUI::utility::toString(position+1) + " #{sRestMenu2}"); mManualHours = position+1; - MyGUI::InputManager::getInstance().setKeyFocusWidget(mWaitButton); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mWaitButton); } void WaitDialog::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index ffcf1323db..4a17dea7bc 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -697,7 +697,7 @@ namespace MWGui setCursorVisible(!gameMode); if (gameMode) - MyGUI::InputManager::getInstance().resetKeyFocusWidget(); + setKeyFocusWidget (nullptr); // Icons of forced hidden windows are displayed setMinimapVisibility((mAllowed & GW_Map) && (!mMap->pinned() || (mForceHidden & GW_Map))); @@ -1675,6 +1675,13 @@ namespace MWGui } } + // Remove this wrapper once onKeyFocusChanged call is rendered unnecessary + void WindowManager::setKeyFocusWidget(MyGUI::Widget *widget) + { + MyGUI::InputManager::getInstance().setKeyFocusWidget(widget); + onKeyFocusChanged(widget); + } + void WindowManager::onKeyFocusChanged(MyGUI::Widget *widget) { if (widget && widget->castType(false)) @@ -1868,7 +1875,7 @@ namespace MWGui sizeVideo(screenSize.width, screenSize.height); MyGUI::Widget* oldKeyFocus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(mVideoWidget); + setKeyFocusWidget(mVideoWidget); mVideoBackground->setVisible(true); @@ -1906,7 +1913,7 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->resumeSounds(); - MyGUI::InputManager::getInstance().setKeyFocusWidget(oldKeyFocus); + setKeyFocusWidget(oldKeyFocus); setCursorVisible(cursorWasVisible); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 91c61a1e96..e7fc8109d8 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -147,6 +147,9 @@ namespace MWGui /// (and will continually update the window while doing so) virtual void playVideo(const std::string& name, bool allowSkipping); + /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. + virtual void setKeyFocusWidget (MyGUI::Widget* widget); + virtual void setNewGame(bool newgame); virtual void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg); From 6622e36226cd9fe349fcf696fd1f77a909bf52d0 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 9 Jun 2019 11:47:43 +0300 Subject: [PATCH 12/32] Only merge pure osg::Groups in the optimizer --- components/sceneutil/optimizer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp index 7c568ff9d7..e8ebed8686 100644 --- a/components/sceneutil/optimizer.cpp +++ b/components/sceneutil/optimizer.cpp @@ -1802,12 +1802,11 @@ bool Optimizer::MergeGeometryVisitor::mergePrimitive(osg::DrawElementsUInt& lhs, bool Optimizer::MergeGroupsVisitor::isOperationPermissible(osg::Group& node) { - return !node.asSwitch() && - !node.asTransform() && - !node.getCullCallback() && + return !node.getCullCallback() && !node.getEventCallback() && !node.getUpdateCallback() && - isOperationPermissibleForObject(&node); + isOperationPermissibleForObject(&node) && + typeid(node)==typeid(osg::Group); } void Optimizer::MergeGroupsVisitor::apply(osg::LOD &lod) From 347b1e58a1c318443420ccfdc0e983e169c2374f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 10 Jun 2019 08:35:41 +0400 Subject: [PATCH 13/32] Add a changelog entry about cell transitions --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7b3464149..b256125081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,7 @@ Feature #5051: Provide a separate textures for scrollbars Task #4686: Upgrade media decoder to a more current FFmpeg API Task #4695: Optimize Distant Terrain memory consumption + Task #4789: Optimize cell transitions Task #4721: Add NMake support to the Windows prebuild script 0.45.0 From 19b0b056e500d5291749f7dcf0646d3c6efc5ea2 Mon Sep 17 00:00:00 2001 From: Alexander Perepechko Date: Thu, 13 Jun 2019 21:42:25 +0000 Subject: [PATCH 14/32] Remove spell FX and VFX after playing the death animation (bug #5060) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/actors.cpp | 10 +++++----- apps/openmw/mwmechanics/character.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab11f95aa..a4881cf431 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ Bug #5047: # in cell names sets color Bug #5050: Invalid spell effects are not handled gracefully Bug #5056: Calling Cast function on player doesn't equip the spell but casts it + Bug #5060: Magic effect visuals stop when death animation begins instead of when it ends Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0317e7dde7..5cca894e6c 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -551,7 +551,7 @@ namespace MWMechanics void Actors::adjustMagicEffects (const MWWorld::Ptr& creature) { CreatureStats& creatureStats = creature.getClass().getCreatureStats (creature); - if (creatureStats.isDead()) + if (creatureStats.isDeathAnimationFinished()) return; MagicEffects now = creatureStats.getSpells().getMagicEffects(); @@ -1665,10 +1665,6 @@ namespace MWMechanics stats.getActiveSpells().visitEffectSources(soulTrap); } - // Reset magic effects and recalculate derived effects - // One case where we need this is to make sure bound items are removed upon death - stats.modifyMagicEffects(MWMechanics::MagicEffects()); - stats.getActiveSpells().clear(); calculateCreatureStatModifiers(iter->first, 0); if (cls.isEssential(iter->first)) @@ -1680,6 +1676,10 @@ namespace MWMechanics ++mDeathCount[Misc::StringUtils::lowerCase(iter->first.getCellRef().getRefId())]; + // Reset magic effects and recalculate derived effects + // One case where we need this is to make sure bound items are removed upon death + stats.modifyMagicEffects(MWMechanics::MagicEffects()); + stats.getActiveSpells().clear(); // Make sure spell effects are removed purgeSpellEffects(stats.getActorId()); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c3eadff599..65013eee9f 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2648,7 +2648,7 @@ void CharacterController::updateContinuousVfx() for (std::vector::iterator it = effects.begin(); it != effects.end(); ++it) { - if (mPtr.getClass().getCreatureStats(mPtr).isDead() + if (mPtr.getClass().getCreatureStats(mPtr).isDeathAnimationFinished() || mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(MWMechanics::EffectKey(*it)).getMagnitude() <= 0) mAnimation->removeEffect(*it); } From 698c90b3ee01bb4e8be7f8ac72ce2029bb681dae Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sun, 16 Jun 2019 14:41:34 +0200 Subject: [PATCH 15/32] fix builds against MyGUI master --- components/esm/custommarkerstate.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esm/custommarkerstate.hpp b/components/esm/custommarkerstate.hpp index fc9286bfe2..2be43c53bf 100644 --- a/components/esm/custommarkerstate.hpp +++ b/components/esm/custommarkerstate.hpp @@ -16,7 +16,7 @@ struct CustomMarker std::string mNote; - bool operator == (const CustomMarker& other) + bool operator == (const CustomMarker& other) const { return mNote == other.mNote && mCell == other.mCell && mWorldX == other.mWorldX && mWorldY == other.mWorldY; } From 3aa65273c538f8eb146586bff3c1cf4c0bfdbc80 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 18 Jun 2019 14:47:10 +0300 Subject: [PATCH 16/32] Signedness fixes --- apps/openmw/mwworld/esmstore.cpp | 4 ++-- components/esm/loadclot.hpp | 2 +- components/esm/loadweap.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 56b46d8569..8333531748 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -169,8 +169,8 @@ void ESMStore::validate() if (!fact) { Log(Debug::Verbose) << "NPC '" << npc.mId << "' (" << npc.mName << ") has nonexistent faction '" << npc.mFaction << "', ignoring it."; - npc.mFaction = ""; - npc.mNpdt.mRank = -1; + npc.mFaction.clear(); + npc.mNpdt.mRank = 0; changed = true; } } diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index a9ea3e70a6..4db791c0c1 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -40,7 +40,7 @@ struct Clothing int mType; float mWeight; unsigned short mValue; - short mEnchant; + unsigned short mEnchant; }; CTDTstruct mData; diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index 8b48b71b7f..dfe2b695a0 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -59,7 +59,7 @@ struct Weapon short mType; unsigned short mHealth; float mSpeed, mReach; - short mEnchant; // Enchantment points. The real value is mEnchant/10.f + unsigned short mEnchant; // Enchantment points. The real value is mEnchant/10.f unsigned char mChop[2], mSlash[2], mThrust[2]; // Min and max int mFlags; }; // 32 bytes From f984f61055c0fbe77250a1759d3af5c4068c70d7 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Thu, 20 Jun 2019 14:18:12 +0300 Subject: [PATCH 17/32] Ignore any fourth AITravel argument for now --- components/compiler/extensions0.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index e66f051d78..5b60f9d6d5 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -33,7 +33,7 @@ namespace Compiler { extensions.registerInstruction ("aiactivate", "c/l", opcodeAIActivate, opcodeAIActivateExplicit); - extensions.registerInstruction ("aitravel", "fff/lx", opcodeAiTravel, + extensions.registerInstruction ("aitravel", "fff/zx", opcodeAiTravel, opcodeAiTravelExplicit); extensions.registerInstruction ("aiescort", "cffff/l", opcodeAiEscort, opcodeAiEscortExplicit); From df89c6b6ce6399c408ccf5538944bee5c34a6338 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 20 Jun 2019 20:45:52 +0300 Subject: [PATCH 18/32] Make unarmed creature attacks affect shield condition again (bug #5069) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/combat.cpp | 15 ++++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4881cf431..f1e2614e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ Bug #5050: Invalid spell effects are not handled gracefully Bug #5056: Calling Cast function on player doesn't equip the spell but casts it Bug #5060: Magic effect visuals stop when death animation begins instead of when it ends + Bug #5069: Blocking creatures' attacks doesn't degrade shields Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index da62f6c08f..68c94b9ee8 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -115,16 +115,13 @@ namespace MWMechanics if (Misc::Rng::roll0to99() < x) { - if (!(weapon.isEmpty() && !attacker.getClass().isNpc())) // Unarmed creature attacks don't affect armor condition - { - // Reduce shield durability by incoming damage - int shieldhealth = shield->getClass().getItemHealth(*shield); + // Reduce shield durability by incoming damage + int shieldhealth = shield->getClass().getItemHealth(*shield); - shieldhealth -= std::min(shieldhealth, int(damage)); - shield->getCellRef().setCharge(shieldhealth); - if (shieldhealth == 0) - inv.unequipItem(*shield, blocker); - } + shieldhealth -= std::min(shieldhealth, int(damage)); + shield->getCellRef().setCharge(shieldhealth); + if (shieldhealth == 0) + inv.unequipItem(*shield, blocker); // Reduce blocker fatigue const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->mValue.getFloat(); const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->mValue.getFloat(); From d9439389e6005e439480a7088a96a5131042ec7b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Jun 2019 21:37:38 +0200 Subject: [PATCH 19/32] fix #4665 --- files/mygui/openmw_list.skin.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index ccaeb0319d..db2c722d7e 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -19,6 +19,11 @@ + + + + + @@ -27,11 +32,6 @@ - - - - - @@ -61,6 +61,11 @@ + + + + + @@ -69,11 +74,6 @@ - - - - - From e06178bf0f3cdbbfb55a46f10b0522cf19aa1920 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 15 Jun 2019 14:30:42 +0300 Subject: [PATCH 20/32] Make sure shadow shapes aren't visible (bug #5063) --- CHANGELOG.md | 1 + components/nifosg/nifloader.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1e2614e68..4770d0a247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ Bug #5050: Invalid spell effects are not handled gracefully Bug #5056: Calling Cast function on player doesn't equip the spell but casts it Bug #5060: Magic effect visuals stop when death animation begins instead of when it ends + Bug #5063: Shape named "Tri Shadow" in creature mesh is visible if it isn't hidden Bug #5069: Blocking creatures' attacks doesn't degrade shields Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 9945eefb20..7105147e6d 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -585,8 +585,11 @@ namespace NifOsg { const Nif::NiTriShape* triShape = static_cast(nifNode); const std::string nodeName = Misc::StringUtils::lowerCase(triShape->name); - static const std::string pattern = "tri editormarker"; - if (!hasMarkers || nodeName.compare(0, pattern.size(), pattern) != 0) + static const std::string markerName = "tri editormarker"; + static const std::string shadowName = "shadow"; + static const std::string shadowName2 = "tri shadow"; + const bool isMarker = hasMarkers && !nodeName.compare(0, markerName.size(), markerName); + if (!isMarker && nodeName.compare(0, shadowName.size(), shadowName) && nodeName.compare(0, shadowName2.size(), shadowName2)) { if (triShape->skin.empty()) handleTriShape(triShape, node, composite, boundTextures, animflags); From 3cbe4ab85dbed561cd24e86bab767fda6b07c67f Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sat, 22 Jun 2019 23:05:20 +0300 Subject: [PATCH 21/32] Fix idlestorm blend mask (bugs #4240, #5071) --- apps/openmw/mwmechanics/character.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 65013eee9f..03382a8887 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1135,8 +1135,8 @@ void CharacterController::updateIdleStormState(bool inwater) { if (!mAnimation->isPlaying("idlestorm")) { - mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, true, - 1.0f, "start", "stop", 0.0f, ~0ul); + int mask = MWRender::Animation::BlendMask_Torso | MWRender::Animation::BlendMask_RightArm; + mAnimation->play("idlestorm", Priority_Storm, mask, true, 1.0f, "start", "stop", 0.0f, ~0ul); } else { From 453068cc7d5f73cbae5f3087dbfa4b28aeea684d Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 27 Jun 2019 19:50:54 +0300 Subject: [PATCH 22/32] Disallow actors to start combat with themselves (bug #3550) Allow creatures to play initial attack dialogue Don't add combat package to dead actors --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/aicombat.cpp | 3 +++ .../mwmechanics/mechanicsmanagerimp.cpp | 21 +++++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4770d0a247..c9002fcb0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Bug #3006: 'else if' operator breaks script compilation Bug #3109: SetPos/Position handles actors differently Bug #3282: Unintended behaviour when assigning F3 and Windows keys + Bug #3550: Companion from mod attacks the air after combat has ended Bug #3623: Display scaling breaks mouse recognition Bug #3725: Using script function in a non-conditional expression breaks script compilation Bug #3733: Normal maps are inverted on mirrored UVs diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 32b3f9f2b5..78e65ce155 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -116,6 +116,9 @@ namespace MWMechanics || target.getClass().getCreatureStats(target).isDead()) return true; + if (actor == target) // This should never happen. + return true; + if (!storage.isFleeing()) { if (storage.mCurrentAction.get()) // need to wait to init action with its attack range diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 234c39aaa4..23f5ea01da 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1647,18 +1647,28 @@ namespace MWMechanics void MechanicsManager::startCombat(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target) { - MWMechanics::AiSequence& aiSequence = ptr.getClass().getCreatureStats(ptr).getAiSequence(); + CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - if (aiSequence.isInCombat(target)) + // Don't add duplicate packages nor add packages to dead actors. + if (stats.isDead() || stats.getAiSequence().isInCombat(target)) return; - aiSequence.stack(MWMechanics::AiCombat(target), ptr); + // The target is somehow the same as the actor. Early-out. + if (ptr == target) + { + // We don't care about dialogue filters since the target is invalid. + // We still want to play the combat taunt. + MWBase::Environment::get().getDialogueManager()->say(ptr, "attack"); + return; + } + + stats.getAiSequence().stack(MWMechanics::AiCombat(target), ptr); if (target == getPlayer()) { // if guard starts combat with player, guards pursuing player should do the same if (ptr.getClass().isClass(ptr, "Guard")) { - ptr.getClass().getCreatureStats(ptr).setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); // Stops guard from ending combat if player is unreachable + stats.setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); // Stops guard from ending combat if player is unreachable for (Actors::PtrActorMap::const_iterator iter = mActors.begin(); iter != mActors.end(); ++iter) { if (iter->first.getClass().isClass(iter->first, "Guard")) @@ -1676,8 +1686,7 @@ namespace MWMechanics } // Must be done after the target is set up, so that CreatureTargetted dialogue filter works properly - if (ptr.getClass().isNpc() && !ptr.getClass().getCreatureStats(ptr).isDead()) - MWBase::Environment::get().getDialogueManager()->say(ptr, "attack"); + MWBase::Environment::get().getDialogueManager()->say(ptr, "attack"); } void MechanicsManager::getObjectsInRange(const osg::Vec3f &position, float radius, std::vector &objects) From cbb22f0f63deac9f263cd3aebaadf34f0b244281 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 28 Jun 2019 15:52:37 +0300 Subject: [PATCH 23/32] Correct cast style behavior when there's no object (bug #5075) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/enchanting.cpp | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4770d0a247..f55284fab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,7 @@ Bug #5060: Magic effect visuals stop when death animation begins instead of when it ends Bug #5063: Shape named "Tri Shadow" in creature mesh is visible if it isn't hidden Bug #5069: Blocking creatures' attacks doesn't degrade shields + Bug #5075: Enchanting cast style can be changed if there's no object Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 0e7fa5ec01..20ba99825a 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -102,10 +102,7 @@ namespace MWMechanics void Enchanting::nextCastStyle() { if (itemEmpty()) - { - mCastStyle = ESM::Enchantment::WhenUsed; return; - } const bool powerfulSoul = getGemCharge() >= \ MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->mValue.getInteger(); @@ -267,6 +264,8 @@ namespace MWMechanics void Enchanting::setEnchanter(const MWWorld::Ptr& enchanter) { mEnchanter = enchanter; + // Reset cast style + mCastStyle = ESM::Enchantment::CastOnce; } int Enchanting::getEnchantChance() const From b8afe142069c05657031f139e10ee213aec4a38d Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 28 Jun 2019 16:03:18 +0300 Subject: [PATCH 24/32] Disallow paralyzed actors to greet the player (bug #5074) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/aiwander.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0263daffe..989a49acc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,6 +106,7 @@ Bug #5060: Magic effect visuals stop when death animation begins instead of when it ends Bug #5063: Shape named "Tri Shadow" in creature mesh is visible if it isn't hidden Bug #5069: Blocking creatures' attacks doesn't degrade shields + Bug #5074: Paralyzed actors greet the player Bug #5075: Enchanting cast style can be changed if there's no object Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index dc225ac238..d00bbeb5fa 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -527,7 +527,8 @@ namespace MWMechanics if (greetingState == AiWanderStorage::Greet_None) { if ((playerPos - actorPos).length2() <= helloDistance*helloDistance && - !player.getClass().getCreatureStats(player).isDead() && MWBase::Environment::get().getWorld()->getLOS(player, actor) + !player.getClass().getCreatureStats(player).isDead() && !actor.getClass().getCreatureStats(actor).isParalyzed() + && MWBase::Environment::get().getWorld()->getLOS(player, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor)) greetingTimer++; From 19dc01232c0585231891c303964f3690e211a7de Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 30 Jun 2019 16:03:24 +0300 Subject: [PATCH 25/32] Fix CenterOnCell target rotation --- apps/openmw/mwworld/worldimp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6020572bc3..3426e91159 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2808,6 +2808,7 @@ namespace MWWorld /// \note Using _any_ door pointed to the interior, /// not the one pointed to current door. pos = destDoor.mRef.getDoorDest(); + pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; return true; } } @@ -2818,6 +2819,7 @@ namespace MWWorld if (!statics.empty()) { pos = statics.begin()->mRef.getPosition(); + pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; return true; } From 9dfee1dfe20918e56bfed34311556c4d889e1a6d Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 30 Jun 2019 16:13:11 +0300 Subject: [PATCH 26/32] Fix invisibility/chameleon alpha (thanks Hrnchamd) --- apps/openmw/mwmechanics/character.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 03382a8887..7966526f2e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2675,14 +2675,14 @@ void CharacterController::setVisibility(float visibility) if (mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Invisibility).getModifier()) // Ignore base magnitude (see bug #3555). { if (mPtr == getPlayer()) - alpha = 0.4f; + alpha = 0.25f; else - alpha = 0.f; + alpha = 0.05f; } float chameleon = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude(); if (chameleon) { - alpha *= std::max(0.2f, (100.f - chameleon)/100.f); + alpha *= std::min(0.75f, std::max(0.25f, (100.f - chameleon)/100.f)); } visibility = std::min(visibility, alpha); From 8a6a8086da370021d1812cfc956cd082c8a41757 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 1 Jul 2019 00:07:44 +0100 Subject: [PATCH 27/32] Make in-memory buffers seekable to fix fog of war --- components/files/memorystream.hpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/components/files/memorystream.hpp b/components/files/memorystream.hpp index 9a35100440..b4c7b76758 100644 --- a/components/files/memorystream.hpp +++ b/components/files/memorystream.hpp @@ -9,11 +9,31 @@ namespace Files struct MemBuf : std::streambuf { MemBuf(char const* buffer, size_t size) - { // a streambuf isn't specific to istreams, so we need a non-const pointer :/ - char* nonconstBuffer = (const_cast(buffer)); - this->setg(nonconstBuffer, nonconstBuffer, nonconstBuffer + size); + : bufferStart(const_cast(buffer)) + , bufferEnd(bufferStart + size) + { + this->setg(bufferStart, bufferStart, bufferEnd); } + + pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) override + { + if (dir == std::ios_base::cur) + gbump(off); + else + setg(bufferStart, (dir == std::ios_base::beg ? bufferStart : bufferEnd) + off, bufferEnd); + + return gptr() - bufferStart; + } + + pos_type seekpos(pos_type pos, std::ios_base::openmode which) override + { + return seekoff(pos, std::ios_base::beg, which); + } + + protected: + char* bufferStart; + char* bufferEnd; }; /// @brief A variant of std::istream that reads from a constant in-memory buffer. From 49f2615d2b63d326fcb4fc0382eeb60c0689c9c0 Mon Sep 17 00:00:00 2001 From: Justin Ivany <1406666+jrivany@users.noreply.github.com> Date: Mon, 1 Jul 2019 17:32:20 -0300 Subject: [PATCH 28/32] Fix scrolling with controller on gui --- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index d66cc65776..6a6ac20a8e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -560,7 +560,7 @@ namespace MWInput // game mode does not move the position of the GUI cursor float xmove = xAxis * dt * 1500.0f * mInvUiScalingFactor; float ymove = yAxis * dt * 1500.0f * mInvUiScalingFactor; - if (xmove != 0|| ymove != 0) + if (xmove != 0|| ymove != 0 || zAxis != 0) { mGuiCursorX += xmove; mGuiCursorY += ymove; From af1e5e01b43c6e5ff2728ef74f8afa08ff8ac53e Mon Sep 17 00:00:00 2001 From: Nat Meo Date: Mon, 1 Jul 2019 23:26:05 +0000 Subject: [PATCH 29/32] Issue #5005: Instance window via Scene window --- CHANGELOG.md | 1 + apps/opencs/model/prefs/state.cpp | 4 +++ apps/opencs/view/doc/view.cpp | 28 +++++++++++++++++++ apps/opencs/view/doc/view.hpp | 4 +++ apps/opencs/view/render/editmode.cpp | 2 ++ apps/opencs/view/render/editmode.hpp | 3 ++ apps/opencs/view/render/instancemode.cpp | 14 ++++++++++ apps/opencs/view/render/instancemode.hpp | 6 ++++ apps/opencs/view/render/pathgridmode.cpp | 4 +++ apps/opencs/view/render/pathgridmode.hpp | 2 ++ .../opencs/view/render/terraintexturemode.cpp | 4 +++ .../opencs/view/render/terraintexturemode.hpp | 2 ++ apps/opencs/view/render/worldspacewidget.cpp | 10 +++++++ apps/opencs/view/render/worldspacewidget.hpp | 5 ++++ apps/opencs/view/world/scenesubview.cpp | 6 ++++ apps/opencs/view/world/scenesubview.hpp | 4 +++ apps/opencs/view/world/table.cpp | 7 ++++- apps/opencs/view/world/tablesubview.cpp | 5 ++++ apps/opencs/view/world/tablesubview.hpp | 4 +++ 19 files changed, 114 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 989a49acc5..7954731282 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -135,6 +135,7 @@ Feature #4968: Scalable UI widget skins Feature #4994: Persistent pinnable windows hiding Feature #5000: Compressed BSA format support + Feature #5005: Editor: Instance window via Scene window Feature #5010: Native graphics herbalism support Feature #5031: Make GetWeaponType function return different values for tools Feature #5033: Magic armor mitigation for creatures diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 9bc0e08774..a206fad6f1 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -247,6 +247,9 @@ void CSMPrefs::State::declare() addValues (landeditOutsideVisibleCell); declareInt ("texturebrush-maximumsize", "Maximum texture brush size", 50). setMin (1); + declareBool ("open-list-view", "Open displays list view", false). + setTooltip ("When opening a reference from the scene view, it will open the" + " instance list view instead of the individual instance record view."); declareCategory ("Key Bindings"); @@ -331,6 +334,7 @@ void CSMPrefs::State::declare() 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)); diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 42dbe51ac3..343495518a 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -22,6 +22,7 @@ #include "../../model/world/idtable.hpp" #include "../world/subviews.hpp" +#include "../world/scenesubview.hpp" #include "../world/tablesubview.hpp" #include "../tools/subviews.hpp" @@ -626,6 +627,20 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin connect (view, SIGNAL (updateSubViewIndices (SubView *)), this, SLOT (updateSubViewIndices (SubView *))); + CSVWorld::TableSubView* tableView = dynamic_cast(view); + if (tableView) + { + connect (this, SIGNAL (requestFocus (const std::string&)), + tableView, SLOT (requestFocus (const std::string&))); + } + + CSVWorld::SceneSubView* sceneView = dynamic_cast(view); + if (sceneView) + { + connect(sceneView, SIGNAL(requestFocus(const std::string&)), + this, SLOT(onRequestFocus(const std::string&))); + } + view->show(); if (!hint.empty()) @@ -1065,3 +1080,16 @@ void CSVDoc::View::createScrollArea() mScroll->setWidget(&mSubViewWindow); setCentralWidget(mScroll); } + +void CSVDoc::View::onRequestFocus (const std::string& id) +{ + if(CSMPrefs::get()["3D Scene Editing"]["open-list-view"].isTrue()) + { + addReferencesSubView(); + emit requestFocus(id); + } + else + { + addSubView(CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Reference, id)); + } +} diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index c4046a7a16..52057ab375 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -140,6 +140,8 @@ namespace CSVDoc void mergeDocument (CSMDoc::Document *document); + void requestFocus (const std::string& id); + public slots: void addSubView (const CSMWorld::UniversalId& id, const std::string& hint = ""); @@ -262,6 +264,8 @@ namespace CSVDoc void moveScrollBarToEnd(int min, int max); void merge(); + + void onRequestFocus (const std::string& id); }; } diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index 5f0852c909..03451bc1b1 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -29,6 +29,8 @@ void CSVRender::EditMode::setEditLock (bool locked) } +void CSVRender::EditMode::primaryOpenPressed (const WorldspaceHitResult& hit) {} + void CSVRender::EditMode::primaryEditPressed (const WorldspaceHitResult& hit) {} void CSVRender::EditMode::secondaryEditPressed (const WorldspaceHitResult& hit) {} diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index f9b7027f98..9f3b289578 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -39,6 +39,9 @@ namespace CSVRender /// Default-implementation: Ignored. virtual void setEditLock (bool locked); + /// Default-implementation: Ignored. + virtual void primaryOpenPressed (const WorldspaceHitResult& hit); + /// Default-implementation: Ignored. virtual void primaryEditPressed (const WorldspaceHitResult& hit); diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 1cf8a56983..0cf58038dc 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -94,6 +94,8 @@ CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidg parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None), mDragAxis (-1), mLocked (false), mUnitScaleDist(1) { + connect(this, SIGNAL(requestFocus(const std::string&)), + worldspaceWidget, SIGNAL(requestFocus(const std::string&))); } void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) @@ -174,6 +176,18 @@ void CSVRender::InstanceMode::primaryEditPressed (const WorldspaceHitResult& hit primarySelectPressed (hit); } +void CSVRender::InstanceMode::primaryOpenPressed (const WorldspaceHitResult& hit) +{ + if(hit.tag) + { + if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) + { + const std::string refId = objectTag->mObject->getReferenceId(); + emit requestFocus(refId); + } + } +} + void CSVRender::InstanceMode::secondaryEditPressed (const WorldspaceHitResult& hit) { if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 933cae5297..6ddaa254fd 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -55,6 +55,8 @@ namespace CSVRender virtual void setEditLock (bool locked); + virtual void primaryOpenPressed (const WorldspaceHitResult& hit); + virtual void primaryEditPressed (const WorldspaceHitResult& hit); virtual void secondaryEditPressed (const WorldspaceHitResult& hit); @@ -83,6 +85,10 @@ namespace CSVRender virtual int getSubMode() const; + signals: + + void requestFocus (const std::string& id); + private slots: void subModeChanged (const std::string& id); diff --git a/apps/opencs/view/render/pathgridmode.cpp b/apps/opencs/view/render/pathgridmode.cpp index a9cce02007..8863ad235c 100644 --- a/apps/opencs/view/render/pathgridmode.cpp +++ b/apps/opencs/view/render/pathgridmode.cpp @@ -63,6 +63,10 @@ namespace CSVRender } } + void PathgridMode::primaryOpenPressed(const WorldspaceHitResult& hitResult) + { + } + void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult) { if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue() && diff --git a/apps/opencs/view/render/pathgridmode.hpp b/apps/opencs/view/render/pathgridmode.hpp index e34208f8c2..a012a67e4a 100644 --- a/apps/opencs/view/render/pathgridmode.hpp +++ b/apps/opencs/view/render/pathgridmode.hpp @@ -21,6 +21,8 @@ namespace CSVRender virtual void deactivate(CSVWidget::SceneToolbar* toolbar); + virtual void primaryOpenPressed(const WorldspaceHitResult& hit); + virtual void primaryEditPressed(const WorldspaceHitResult& hit); virtual void secondaryEditPressed(const WorldspaceHitResult& hit); diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index 274e647426..4205188e40 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -77,6 +77,10 @@ void CSVRender::TerrainTextureMode::deactivate(CSVWidget::SceneToolbar* toolbar) EditMode::deactivate(toolbar); } +void CSVRender::TerrainTextureMode::primaryOpenPressed(const WorldspaceHitResult& hit) // Apply changes here +{ +} + void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult& hit) // Apply changes here { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index 5184f0f734..10ea842c98 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -35,6 +35,8 @@ namespace CSVRender /// \brief Editmode for terrain texture grid TerrainTextureMode(WorldspaceWidget*, QWidget* parent = nullptr); + void primaryOpenPressed (const WorldspaceHitResult& hit); + /// \brief Create single command for one-click texture editing void primaryEditPressed (const WorldspaceHitResult& hit); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 7e405266ee..1eca61e73a 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -101,6 +101,9 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg // Shortcuts CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", "scene-speed-modifier", CSMPrefs::Shortcut::SM_Detach, this); + CSMPrefs::Shortcut* primaryOpenShortcut = new CSMPrefs::Shortcut("scene-open-primary", this); + + connect(primaryOpenShortcut, SIGNAL(activated(bool)), this, SLOT(primaryOpen(bool))); connect(primaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool))); connect(primaryEditShortcut, SIGNAL(secondary(bool)), this, SLOT(speedMode(bool))); @@ -696,6 +699,8 @@ void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitRes editMode.primarySelectPressed (hit); else if (type == InteractionType_SecondarySelect) editMode.secondarySelectPressed (hit); + else if (type == InteractionType_PrimaryOpen) + editMode.primaryOpenPressed (hit); } CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() @@ -703,6 +708,11 @@ CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() return dynamic_cast (mEditMode->getCurrent()); } +void CSVRender::WorldspaceWidget::primaryOpen(bool activate) +{ + handleInteraction(InteractionType_PrimaryOpen, activate); +} + void CSVRender::WorldspaceWidget::primaryEdit(bool activate) { handleInteraction(InteractionType_PrimaryEdit, activate); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 9160ca47e5..06c182b0c5 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -91,6 +91,7 @@ namespace CSVRender InteractionType_PrimarySelect, InteractionType_SecondaryEdit, InteractionType_SecondarySelect, + InteractionType_PrimaryOpen, InteractionType_None }; @@ -263,6 +264,8 @@ namespace CSVRender void showToolTip(); + void primaryOpen(bool activate); + void primaryEdit(bool activate); void secondaryEdit(bool activate); @@ -283,6 +286,8 @@ namespace CSVRender void dataDropped(const std::vector& data); + void requestFocus (const std::string& id); + friend class MouseState; }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 4b129d32aa..44542c5297 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -83,6 +83,9 @@ void CSVWorld::SceneSubView::makeConnections (CSVRender::UnpagedWorldspaceWidget connect(widget, SIGNAL(cellChanged(const CSMWorld::UniversalId&)), this, SLOT(cellSelectionChanged(const CSMWorld::UniversalId&))); + + connect(widget, SIGNAL(requestFocus (const std::string&)), + this, SIGNAL(requestFocus (const std::string&))); } void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* widget) @@ -94,6 +97,9 @@ void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&))); + + connect(widget, SIGNAL(requestFocus (const std::string&)), + this, SIGNAL(requestFocus (const std::string&))); } CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget, widgetType type) diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 0f18e8c303..85f7d09257 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -82,6 +82,10 @@ namespace CSVWorld void cellSelectionChanged (const CSMWorld::UniversalId& id); void handleDrop(const std::vector& data); + + signals: + + void requestFocus (const std::string& id); }; } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index eb7b8e334b..11c2be5fc9 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -737,7 +737,12 @@ void CSVWorld::Table::requestFocus (const std::string& id) QModelIndex index = mProxyModel->getModelIndex (id, 0); if (index.isValid()) - scrollTo (index, QAbstractItemView::PositionAtTop); + { + // This will scroll to the row. + selectRow (index.row()); + // This will actually select it. + selectionModel()->select (index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + } } void CSVWorld::Table::recordFilterChanged (std::shared_ptr filter) diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index 12e29995da..b0bae7fdf5 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -165,3 +165,8 @@ bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event) } return false; } + +void CSVWorld::TableSubView::requestFocus (const std::string& id) +{ + mTable->requestFocus(id); +} diff --git a/apps/opencs/view/world/tablesubview.hpp b/apps/opencs/view/world/tablesubview.hpp index 7d143d927c..1adf862d5b 100644 --- a/apps/opencs/view/world/tablesubview.hpp +++ b/apps/opencs/view/world/tablesubview.hpp @@ -60,6 +60,10 @@ namespace CSVWorld void cloneRequest (const CSMWorld::UniversalId& toClone); void createFilterRequest(std::vector< CSMWorld::UniversalId >& types, Qt::DropAction action); + + public slots: + + void requestFocus (const std::string& id); }; } From 643f259cbfd01d0daa3fbe21cb2acc24d2ef302e Mon Sep 17 00:00:00 2001 From: Justin Ivany Date: Tue, 2 Jul 2019 11:19:10 +0000 Subject: [PATCH 30/32] Adding option for cursor speed when using gamepad --- apps/openmw/mwinput/inputmanagerimp.cpp | 5 +++-- apps/openmw/mwinput/inputmanagerimp.hpp | 1 + docs/source/reference/modding/settings/input.rst | 13 +++++++++++++ files/settings-default.cfg | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 6a6ac20a8e..581a96e7b9 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -77,6 +77,7 @@ namespace MWInput , mSneaking(false) , mAttemptJump(false) , mInvUiScalingFactor(1.f) + , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) , mFakeDeviceID(1) { mInputManager = new SDLUtil::InputWrapper(window, viewer, grab); @@ -558,8 +559,8 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - float xmove = xAxis * dt * 1500.0f * mInvUiScalingFactor; - float ymove = yAxis * dt * 1500.0f * mInvUiScalingFactor; + float xmove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; + float ymove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; if (xmove != 0|| ymove != 0 || zAxis != 0) { mGuiCursorX += xmove; diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 8b3253dcd1..caf57681da 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -209,6 +209,7 @@ namespace MWInput std::map mControlSwitch; float mInvUiScalingFactor; + float mGamepadCursorSpeed; private: void convertMousePosForMyGUI(int& x, int& y); diff --git a/docs/source/reference/modding/settings/input.rst b/docs/source/reference/modding/settings/input.rst index 51c72e15dd..d481321c2e 100644 --- a/docs/source/reference/modding/settings/input.rst +++ b/docs/source/reference/modding/settings/input.rst @@ -133,3 +133,16 @@ which are always sent if a controller is present and detected. Disabling this setting can be useful for working around controller-related issues or for setting up split-screen gameplay configurations. This setting can be toggled in game with the Enable Joystick button in the Controls panel of the Options menu. + +gamepad cursor speed +-------------------- + +:Type: float +:Range: >0 +:Default: 1.0 + +This setting controls the speed of the cursor within GUI mode when using the joystick. +This setting has no effect on the camera rotation speed, which is controlled by the +camera sensitivity setting. + +This setting can only be configured by editing the settings configuration file. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index d3776e92f5..d16e8c92c2 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -364,6 +364,9 @@ invert y axis = false # Enable controller support. enable controller = true +# Emulated gamepad cursor sensitivity. +gamepad cursor speed = 1.0 + [Saves] # Name of last character played, and default for loading save files. From 8a463b30d63ec94225de381bdbb4de941df16bb3 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 2 Jul 2019 14:52:50 +0300 Subject: [PATCH 31/32] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7954731282..e6c55a525a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,7 @@ Bug #5069: Blocking creatures' attacks doesn't degrade shields Bug #5074: Paralyzed actors greet the player Bug #5075: Enchanting cast style can be changed if there's no object + Bug #5082: Scrolling with controller in GUI mode is broken Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls @@ -141,6 +142,7 @@ Feature #5033: Magic armor mitigation for creatures Feature #5034: Make enchanting window stay open after a failed attempt Feature #5036: Allow scripted faction leaving + Feature #5046: Gamepad thumbstick cursor speed Feature #5051: Provide a separate textures for scrollbars Task #4686: Upgrade media decoder to a more current FFmpeg API Task #4695: Optimize Distant Terrain memory consumption From bcc5142b32ad7f4e7fb2c1f036011a1063be4e96 Mon Sep 17 00:00:00 2001 From: Nat Meo Date: Tue, 2 Jul 2019 16:07:38 +0000 Subject: [PATCH 32/32] Issue #4202: Open .omwaddon files without needing to open openmw-cs first. --- CHANGELOG.md | 1 + apps/opencs/editor.cpp | 72 ++++++++++++++++++++++++++++---- apps/opencs/editor.hpp | 5 ++- components/files/linuxpath.cpp | 21 +++++++++- components/files/windowspath.cpp | 18 +++++++- 5 files changed, 106 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c55a525a..3ba7febd1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Bug #3765: DisableTeleporting makes Mark/Recall/Intervention effects undetectable Bug #3778: [Mod] Improved Thrown Weapon Projectiles - weapons have wrong transformation during throw animation Bug #3812: Wrong multiline tooltips width when word-wrapping is enabled + Bug #4202: Open .omwaddon files without needing toopen openmw-cs first Bug #4240: Ash storm origin coordinates and hand shielding animation behavior are incorrect Bug #4329: Removed birthsign abilities are restored after reloading the save Bug #4341: Error message about missing GDB is too vague diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index b22f5464d8..0ce0315480 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -27,6 +27,11 @@ CS::Editor::Editor (int argc, char **argv) std::pair > config = readConfig(); mViewManager = new CSVDoc::ViewManager(mDocumentManager); + if (argc > 1) + { + mFileToLoad = argv[1]; + mDataDirs = config.first; + } NifOsg::Loader::setShowMarkers(true); @@ -103,9 +108,9 @@ std::pair > CS::Editor::readConfi Fallback::Map::init(variables["fallback"].as().mMap); - const std::string encoding = variables["encoding"].as().toStdString(); - mDocumentManager.setEncoding (ToUTF8::calculateEncoding (encoding)); - mFileDialog.setEncoding (QString::fromUtf8(encoding.c_str())); + mEncodingName = variables["encoding"].as().toStdString(); + mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName)); + mFileDialog.setEncoding (QString::fromUtf8(mEncodingName.c_str())); mDocumentManager.setResourceDir (mResources = variables["resources"].as().toStdString()); @@ -217,12 +222,19 @@ void CS::Editor::loadDocument() mFileDialog.showDialog (CSVDoc::ContentAction_Edit); } -void CS::Editor::openFiles (const boost::filesystem::path &savePath) +void CS::Editor::openFiles (const boost::filesystem::path &savePath, const std::vector &discoveredFiles) { std::vector files; - foreach (const QString &path, mFileDialog.selectedFilePaths()) - files.push_back(path.toUtf8().constData()); + if(discoveredFiles.empty()) + { + foreach(const QString &path, mFileDialog.selectedFilePaths()) + files.push_back(path.toUtf8().constData()); + } + else + { + files = discoveredFiles; + } mDocumentManager.addDocument (files, savePath, false); @@ -348,9 +360,53 @@ int CS::Editor::run() Misc::Rng::init(); - mStartup.show(); + QApplication::setQuitOnLastWindowClosed(true); - QApplication::setQuitOnLastWindowClosed (true); + if (mFileToLoad.empty()) + { + mStartup.show(); + } + else + { + ESM::ESMReader fileReader; + ToUTF8::Utf8Encoder encoder = ToUTF8::calculateEncoding(mEncodingName); + fileReader.setEncoder(&encoder); + fileReader.open(mFileToLoad.string()); + + std::vector discoveredFiles; + + for (std::vector::const_iterator itemIter = fileReader.getGameFiles().begin(); + itemIter != fileReader.getGameFiles().end(); ++itemIter) + { + for (Files::PathContainer::const_iterator pathIter = mDataDirs.begin(); + pathIter != mDataDirs.end(); ++pathIter) + { + const boost::filesystem::path masterPath = *pathIter / itemIter->name; + if (boost::filesystem::exists(masterPath)) + { + discoveredFiles.push_back(masterPath); + break; + } + } + } + discoveredFiles.push_back(mFileToLoad); + + QString extension = QString::fromStdString(mFileToLoad.extension().string()).toLower(); + if (extension == ".esm") + { + mFileToLoad.replace_extension(".omwgame"); + mDocumentManager.addDocument(discoveredFiles, mFileToLoad, false); + } + else if (extension == ".esp") + { + mFileToLoad.replace_extension(".omwaddon"); + mDocumentManager.addDocument(discoveredFiles, mFileToLoad, false); + } + else + { + openFiles(mFileToLoad, discoveredFiles); + } + } return QApplication::exec(); } diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 0c3ece9059..1c93427613 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -54,6 +54,9 @@ namespace CS bool mFsStrict; CSVTools::Merge mMerge; CSVDoc::ViewManager* mViewManager; + boost::filesystem::path mFileToLoad; + Files::PathContainer mDataDirs; + std::string mEncodingName; std::pair > readConfig(bool quiet=false); ///< \return data paths @@ -81,7 +84,7 @@ namespace CS void cancelFileDialog(); void loadDocument(); - void openFiles (const boost::filesystem::path &path); + void openFiles (const boost::filesystem::path &path, const std::vector &discoveredFiles = std::vector()); void createNewFile (const boost::filesystem::path& path); void createNewGame (const boost::filesystem::path& file); diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp index 3743eef4c9..f2ecb7c132 100644 --- a/components/files/linuxpath.cpp +++ b/components/files/linuxpath.cpp @@ -4,8 +4,10 @@ #include #include +#include #include +#include #include @@ -50,6 +52,9 @@ namespace Files LinuxPath::LinuxPath(const std::string& application_name) : mName(application_name) { + boost::filesystem::path localPath = getLocalPath(); + if (chdir(localPath.string().c_str()) != 0) + Log(Debug::Warning) << "Error " << errno << " when changing current directory"; } boost::filesystem::path LinuxPath::getUserConfigPath() const @@ -75,7 +80,21 @@ boost::filesystem::path LinuxPath::getGlobalConfigPath() const boost::filesystem::path LinuxPath::getLocalPath() const { - return boost::filesystem::path("./"); + boost::filesystem::path localPath("./"); + char binPath[PATH_MAX]; + memset(binPath, 0, sizeof(binPath)); + const char *statusPaths[] = {"/proc/self/exe", "/proc/self/file", "/proc/curproc/exe", "/proc/curproc/file"}; + + for(const char *path : statusPaths) + { + if (readlink(path, binPath, sizeof(binPath)) != -1) + { + localPath = boost::filesystem::path(binPath).parent_path(); + break; + } + } + + return localPath; } boost::filesystem::path LinuxPath::getGlobalDataPath() const diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp index 2354e6f31c..516f260219 100644 --- a/components/files/windowspath.cpp +++ b/components/files/windowspath.cpp @@ -11,6 +11,8 @@ #include namespace bconv = boost::locale::conv; +#include + /** * FIXME: Someone with Windows system should check this and correct if necessary * FIXME: MAX_PATH is irrelevant for extended-length paths, i.e. \\?\... @@ -33,6 +35,10 @@ WindowsPath::WindowsPath(const std::string& application_name) See boost::filesystem and boost::locale reference for details. */ boost::filesystem::path::imbue(boost::locale::generator().generate("")); + + boost::filesystem::path localPath = getLocalPath(); + if (!SetCurrentDirectoryA(localPath.string().c_str())) + Log(Debug::Warning) << "Error " << GetLastError() << " when changing current directory"; } boost::filesystem::path WindowsPath::getUserConfigPath() const @@ -73,7 +79,17 @@ boost::filesystem::path WindowsPath::getGlobalConfigPath() const boost::filesystem::path WindowsPath::getLocalPath() const { - return boost::filesystem::path("./"); + boost::filesystem::path localPath("./"); + WCHAR path[MAX_PATH + 1]; + memset(path, 0, sizeof(path)); + + if (GetModuleFileNameW(nullptr, path, MAX_PATH + 1) > 0) + { + localPath = boost::filesystem::path(bconv::utf_to_utf(path)).parent_path(); + } + + // lookup exe path + return localPath; } boost::filesystem::path WindowsPath::getGlobalDataPath() const