From 3d917fcbadac599d9acacb4624c62c169312582f Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 25 Oct 2018 00:07:01 +0100 Subject: [PATCH 001/224] Add basic OpenGL debug callback --- apps/openmw/engine.cpp | 4 +++ components/CMakeLists.txt | 2 +- components/misc/gldebug.cpp | 60 +++++++++++++++++++++++++++++++++++++ components/misc/gldebug.hpp | 16 ++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 components/misc/gldebug.cpp create mode 100644 components/misc/gldebug.hpp diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2a4145c98..015ff635c 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -365,6 +366,7 @@ void OMW::Engine::createWindow(Settings::Manager& settings) checkSDLError(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)); + checkSDLError(SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG)); if (antialiasing > 0) { @@ -425,6 +427,8 @@ void OMW::Engine::createWindow(Settings::Manager& settings) camera->setGraphicsContext(graphicsWindow); camera->setViewport(0, 0, width, height); + mViewer->setRealizeOperation(new EnableGLDebugOperation()); + mViewer->realize(); mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index d26a92d44..ec0e511ca 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -86,7 +86,7 @@ add_component_dir (esmterrain ) add_component_dir (misc - constants utf8stream stringops resourcehelpers rng messageformatparser weakcache + constants utf8stream stringops resourcehelpers rng messageformatparser weakcache gldebug ) add_component_dir (debug diff --git a/components/misc/gldebug.cpp b/components/misc/gldebug.cpp new file mode 100644 index 000000000..71d75fa73 --- /dev/null +++ b/components/misc/gldebug.cpp @@ -0,0 +1,60 @@ +#include "gldebug.hpp" + +#include + +// OpenGL constants not provided by OSG: +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_TYPE_ERROR 0x824C + +void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) +{ + Log(Debug::Error) << message; +} + +void enableGLDebugExtension(unsigned int contextID) +{ + typedef void (GL_APIENTRY *DEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + typedef void (GL_APIENTRY *GLDebugMessageControlFunction)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); + typedef void (GL_APIENTRY *GLDebugMessageCallbackFunction)(DEBUGPROC, const void* userParam); + + GLDebugMessageControlFunction glDebugMessageControl = nullptr; + GLDebugMessageCallbackFunction glDebugMessageCallback = nullptr; + + if (osg::isGLExtensionSupported(contextID, "GL_KHR_debug")) + { + osg::setGLExtensionFuncPtr(glDebugMessageCallback, "glDebugMessageCallback"); + osg::setGLExtensionFuncPtr(glDebugMessageControl, "glDebugMessageControl"); + } + else if (osg::isGLExtensionSupported(contextID, "GL_ARB_debug_output")) + { + osg::setGLExtensionFuncPtr(glDebugMessageCallback, "glDebugMessageCallbackARB"); + osg::setGLExtensionFuncPtr(glDebugMessageControl, "glDebugMessageControlARB"); + } + else if (osg::isGLExtensionSupported(contextID, "GL_AMD_debug_output")) + { + osg::setGLExtensionFuncPtr(glDebugMessageCallback, "glDebugMessageCallbackAMD"); + osg::setGLExtensionFuncPtr(glDebugMessageControl, "glDebugMessageControlAMD"); + } + + if (glDebugMessageCallback && glDebugMessageControl) + { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, true); + glDebugMessageCallback(debugCallback, nullptr); + + Log(Debug::Info) << "OpenGL debug callback attached."; + } +} + +EnableGLDebugOperation::EnableGLDebugOperation() : osg::GraphicsOperation("EnableGLDebugOperation", false) +{ +} + +void EnableGLDebugOperation::operator()(osg::GraphicsContext* graphicsContext) +{ + OpenThreads::ScopedLock lock(mMutex); + + unsigned int contextID = graphicsContext->getState()->getContextID(); + enableGLDebugExtension(contextID); +} diff --git a/components/misc/gldebug.hpp b/components/misc/gldebug.hpp new file mode 100644 index 000000000..2401a53a4 --- /dev/null +++ b/components/misc/gldebug.hpp @@ -0,0 +1,16 @@ +#ifndef OPENMW_COMPONENTS_MISC_GLDEBUG_H +#define OPENMW_COMPONENTS_MISC_GLDEBUG_H + +#include + +class EnableGLDebugOperation : public osg::GraphicsOperation +{ +public: + EnableGLDebugOperation(); + + virtual void operator()(osg::GraphicsContext* graphicsContext); + +private: + OpenThreads::Mutex mMutex; +}; +#endif From aaa3eedf990d4988c328c107d8d33c4c21483959 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 26 Oct 2018 15:09:08 +0100 Subject: [PATCH 002/224] Move gldebug from components/misc to components/debug --- components/{misc => debug}/gldebug.cpp | 0 components/{misc => debug}/gldebug.hpp | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename components/{misc => debug}/gldebug.cpp (100%) rename components/{misc => debug}/gldebug.hpp (100%) diff --git a/components/misc/gldebug.cpp b/components/debug/gldebug.cpp similarity index 100% rename from components/misc/gldebug.cpp rename to components/debug/gldebug.cpp diff --git a/components/misc/gldebug.hpp b/components/debug/gldebug.hpp similarity index 100% rename from components/misc/gldebug.hpp rename to components/debug/gldebug.hpp From d42c97685284df35a34d419d258ae15fc02ae96b Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 26 Oct 2018 15:11:50 +0100 Subject: [PATCH 003/224] Add detailed OpenGL debug messages --- components/debug/gldebug.cpp | 63 +++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/components/debug/gldebug.cpp b/components/debug/gldebug.cpp index 71d75fa73..52a1bb5a6 100644 --- a/components/debug/gldebug.cpp +++ b/components/debug/gldebug.cpp @@ -3,13 +3,66 @@ #include // OpenGL constants not provided by OSG: -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_TYPE_ERROR 0x824C +#include void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { - Log(Debug::Error) << message; + std::string srcStr; + switch (source) + { + case GL_DEBUG_SOURCE_API: + srcStr = "API"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + srcStr = "WINDOW_SYSTEM"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: + srcStr = "SHADER_COMPILER"; + break; + case GL_DEBUG_SOURCE_THIRD_PARTY: + srcStr = "THIRD_PARTY"; + break; + case GL_DEBUG_SOURCE_APPLICATION: + srcStr = "APPLICATION"; + break; + case GL_DEBUG_SOURCE_OTHER: + srcStr = "OTHER"; + break; + default: + srcStr = "UNDEFINED"; + break; + } + + std::string typeStr; + + Debug::Level logSeverity = Debug::Warning; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + typeStr = "ERROR"; + logSeverity = Debug::Error; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + typeStr = "DEPRECATED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + typeStr = "UNDEFINED_BEHAVIOR"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + typeStr = "PORTABILITY"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + typeStr = "PERFORMANCE"; + break; + case GL_DEBUG_TYPE_OTHER: + typeStr = "OTHER"; + break; + default: + typeStr = "UNDEFINED"; + break; + } + + Log(logSeverity) << "OpenGL " << typeStr << " [" << srcStr << "]: " << message; } void enableGLDebugExtension(unsigned int contextID) @@ -45,6 +98,8 @@ void enableGLDebugExtension(unsigned int contextID) Log(Debug::Info) << "OpenGL debug callback attached."; } + else + Log(Debug::Error) << "Unable to attach OpenGL debug callback."; } EnableGLDebugOperation::EnableGLDebugOperation() : osg::GraphicsOperation("EnableGLDebugOperation", false) From ac18983f37733d0d93d2e6f64d8211c41678222f Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 26 Oct 2018 15:18:38 +0100 Subject: [PATCH 004/224] Finish gldebug location move --- apps/openmw/engine.cpp | 4 ++-- components/CMakeLists.txt | 4 ++-- components/debug/gldebug.hpp | 21 ++++++++++++--------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 015ff635c..96fac86bc 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -11,9 +11,9 @@ #include #include +#include #include -#include #include #include @@ -427,7 +427,7 @@ void OMW::Engine::createWindow(Settings::Manager& settings) camera->setGraphicsContext(graphicsWindow); camera->setViewport(0, 0, width, height); - mViewer->setRealizeOperation(new EnableGLDebugOperation()); + mViewer->setRealizeOperation(new Debug::EnableGLDebugOperation()); mViewer->realize(); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index ec0e511ca..d57a61f46 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -86,11 +86,11 @@ add_component_dir (esmterrain ) add_component_dir (misc - constants utf8stream stringops resourcehelpers rng messageformatparser weakcache gldebug + constants utf8stream stringops resourcehelpers rng messageformatparser weakcache ) add_component_dir (debug - debugging debuglog + debugging debuglog gldebug ) IF(NOT WIN32 AND NOT APPLE) diff --git a/components/debug/gldebug.hpp b/components/debug/gldebug.hpp index 2401a53a4..77d6c82a8 100644 --- a/components/debug/gldebug.hpp +++ b/components/debug/gldebug.hpp @@ -1,16 +1,19 @@ -#ifndef OPENMW_COMPONENTS_MISC_GLDEBUG_H -#define OPENMW_COMPONENTS_MISC_GLDEBUG_H +#ifndef OPENMW_COMPONENTS_DEBUG_GLDEBUG_H +#define OPENMW_COMPONENTS_DEBUG_GLDEBUG_H #include -class EnableGLDebugOperation : public osg::GraphicsOperation +namespace Debug { -public: - EnableGLDebugOperation(); + class EnableGLDebugOperation : public osg::GraphicsOperation + { + public: + EnableGLDebugOperation(); - virtual void operator()(osg::GraphicsContext* graphicsContext); + virtual void operator()(osg::GraphicsContext* graphicsContext); -private: - OpenThreads::Mutex mMutex; -}; + private: + OpenThreads::Mutex mMutex; + }; +} #endif From e147f6fed9d9a2545c2aa2aa935ba0a08f4e7373 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 26 Oct 2018 15:19:31 +0100 Subject: [PATCH 005/224] Finsih gldebug move completely this time --- components/debug/gldebug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/debug/gldebug.cpp b/components/debug/gldebug.cpp index 52a1bb5a6..2c5b38845 100644 --- a/components/debug/gldebug.cpp +++ b/components/debug/gldebug.cpp @@ -102,11 +102,11 @@ void enableGLDebugExtension(unsigned int contextID) Log(Debug::Error) << "Unable to attach OpenGL debug callback."; } -EnableGLDebugOperation::EnableGLDebugOperation() : osg::GraphicsOperation("EnableGLDebugOperation", false) +Debug::EnableGLDebugOperation::EnableGLDebugOperation() : osg::GraphicsOperation("EnableGLDebugOperation", false) { } -void EnableGLDebugOperation::operator()(osg::GraphicsContext* graphicsContext) +void Debug::EnableGLDebugOperation::operator()(osg::GraphicsContext* graphicsContext) { OpenThreads::ScopedLock lock(mMutex); From 6de1deeb2d0555480f2fbf56fe56ccc86ca8bc53 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 26 Oct 2018 15:25:12 +0100 Subject: [PATCH 006/224] Include gldebug attribution and licence --- components/debug/gldebug.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/components/debug/gldebug.cpp b/components/debug/gldebug.cpp index 2c5b38845..76e7a4bb9 100644 --- a/components/debug/gldebug.cpp +++ b/components/debug/gldebug.cpp @@ -1,3 +1,34 @@ +// This file is based heavily on code from https://github.com/ThermalPixel/osgdemos/blob/master/osgdebug/EnableGLDebugOperation.cpp +// The original licence is included below: +/* +Copyright (c) 2014, Andreas Klein +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + #include "gldebug.hpp" #include From 8aa57a745a121ac3c7dc32007aa425d6a381e557 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Tue, 14 Jul 2020 13:19:51 +0200 Subject: [PATCH 007/224] Fix --- components/sdlutil/sdlvideowrapper.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index c2963be86..c64c651bc 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -88,6 +88,14 @@ namespace SDLUtil { SDL_SetWindowSize(mWindow, width, height); SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE); + + // Some display managers will automatically maximize windows whose resolution matches its current display. + // This breaks the SDL window if we don't move the window to the corner of that display. + auto index = SDL_GetWindowDisplayIndex(mWindow); + SDL_Rect rect{}; + SDL_GetDisplayBounds(index, &rect); + if (width == rect.w && height == rect.h) + SDL_SetWindowPosition(mWindow, rect.x, rect.y); } } From 8323f7f68dfd9cfff1cbfcc39c471ece67590f90 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Tue, 14 Jul 2020 19:54:50 +0200 Subject: [PATCH 008/224] Alternative fix --- components/sdlutil/sdlvideowrapper.cpp | 37 +++++++++++++++++++++----- components/sdlutil/sdlvideowrapper.hpp | 2 ++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index c64c651bc..462afc075 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -89,14 +89,37 @@ namespace SDLUtil SDL_SetWindowSize(mWindow, width, height); SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE); - // Some display managers will automatically maximize windows whose resolution matches its current display. - // This breaks the SDL window if we don't move the window to the corner of that display. - auto index = SDL_GetWindowDisplayIndex(mWindow); - SDL_Rect rect{}; - SDL_GetDisplayBounds(index, &rect); - if (width == rect.w && height == rect.h) - SDL_SetWindowPosition(mWindow, rect.x, rect.y); + centerWindow(); } } + void VideoWrapper::centerWindow() + { + + SDL_Rect rect{}; + int x = 0; + int y = 0; + int w = 0; + int h = 0; + auto index = SDL_GetWindowDisplayIndex(mWindow); + bool reposition = false; + SDL_GetDisplayBounds(index, &rect); + SDL_GetWindowSize(mWindow, &w, &h); + + x = rect.x; + y = rect.y; + + // Center dimensions that do not fill the screen + if (w < rect.w) + { + x = rect.x + rect.w / 2 - w / 2; + } + if (h < rect.h) + { + y = rect.y + rect.h / 2 - h / 2; + } + + SDL_SetWindowPosition(mWindow, x, y); + } + } diff --git a/components/sdlutil/sdlvideowrapper.hpp b/components/sdlutil/sdlvideowrapper.hpp index 77f0b8039..3866c3ec3 100644 --- a/components/sdlutil/sdlvideowrapper.hpp +++ b/components/sdlutil/sdlvideowrapper.hpp @@ -27,6 +27,8 @@ namespace SDLUtil void setVideoMode(int width, int height, bool fullscreen, bool windowBorder); + void centerWindow(); + private: SDL_Window* mWindow; osg::ref_ptr mViewer; From e40b309d83aa0c3995c3186c58ab0604b44ccb53 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 17 Jul 2020 16:23:12 +0200 Subject: [PATCH 009/224] move project/cmake to top; set OpenGL_GL_PREFERENCE to LEGACY since we use GL2 and GLNVD is for GL3 and up (https://github.com/openscenegraph/OpenSceneGraph/issues/639); set our RTD to point to stable and not master, stable follows our latest stable release --- CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe28fd84..a3b02a65c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,6 @@ +project(OpenMW) +cmake_minimum_required(VERSION 3.1.0) + # Apps and tools option(BUILD_OPENMW "Build OpenMW" ON) option(BUILD_LAUNCHER "Build Launcher" ON) @@ -13,17 +16,14 @@ option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF) option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest" OFF) option(BULLET_USE_DOUBLES "Use double precision for Bullet" OFF) +set(OpenGL_GL_PREFERENCE LEGACY) # Use LEGACY as we use GL2; GLNVD is for GL3 and up. + if (NOT BUILD_LAUNCHER AND NOT BUILD_OPENCS AND NOT BUILD_WIZARD) set(USE_QT FALSE) else() set(USE_QT TRUE) endif() -# set the minimum required version across the board -cmake_minimum_required(VERSION 3.1.0) - -project(OpenMW) - # If the user doesn't supply a CMAKE_BUILD_TYPE via command line, choose one for them. IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING @@ -58,7 +58,7 @@ set(OPENMW_VERSION_COMMITDATE "") set(OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") -set(OPENMW_DOC_BASEURL "https://openmw.readthedocs.io/en/master/") +set(OPENMW_DOC_BASEURL "https://openmw.readthedocs.io/en/stable/") set(GIT_CHECKOUT FALSE) if(EXISTS ${PROJECT_SOURCE_DIR}/.git) From 90c30893709113cc2705e0eb6913c653b53095fc Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Wed, 22 Jul 2020 12:17:03 +0000 Subject: [PATCH 010/224] Update sdlvideowrapper.cpp --- components/sdlutil/sdlvideowrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index 462afc075..57d1e2985 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -95,7 +95,7 @@ namespace SDLUtil void VideoWrapper::centerWindow() { - + // Resize breaks the sdl window in some cases; see issue: #5539 SDL_Rect rect{}; int x = 0; int y = 0; From 3be1cdef33cde567939bf02262e386e62fb5ed25 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Wed, 22 Jul 2020 21:54:18 +0200 Subject: [PATCH 011/224] [macOS, CI] Use Xcode 11.6 (#2970) * [macOS, CI] Use Xcode 11.6 * [macOS, CI] Enable OpenCs build and see how it goes * [macOS, CI] Re-enable package build and check --- .travis.yml | 8 ++++---- CI/before_script.osx.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index cd0e6e713..36b15d794 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,9 +37,9 @@ addons: build_command: "make VERBOSE=1 -j3" matrix: include: - - name: OpenMW (all) on MacOS 10.15 with Xcode 12 + - name: OpenMW (all) on MacOS 10.15 with Xcode 11.6 os: osx - osx_image: xcode12 + osx_image: xcode11.6 if: branch != coverity_scan - name: OpenMW (all) on Ubuntu Focal with GCC os: linux @@ -71,8 +71,8 @@ before_script: script: - cd ./build - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ${ANALYZE} make -j3; fi -# - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi -# - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi - cd "${TRAVIS_BUILD_DIR}" diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 15d6862db..993de79fe 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -20,7 +20,7 @@ cmake \ -D CMAKE_BUILD_TYPE=RELEASE \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_OPENMW=TRUE \ --D BUILD_OPENCS=FALSE \ +-D BUILD_OPENCS=TRUE \ -D BUILD_ESMTOOL=TRUE \ -D BUILD_BSATOOL=TRUE \ -D BUILD_ESSIMPORTER=TRUE \ From 8cdc7031f54f9ab92a0bb7cb8736cd3d3751f9fa Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Fri, 24 Jul 2020 21:47:49 +0200 Subject: [PATCH 012/224] Support vectors in settings.cfg --- apps/openmw/mwrender/viewovershoulder.cpp | 10 +++---- components/settings/settings.cpp | 36 +++++++++++++++++++++++ components/settings/settings.hpp | 6 ++++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwrender/viewovershoulder.cpp b/apps/openmw/mwrender/viewovershoulder.cpp index 4d708afe0..39599bfea 100644 --- a/apps/openmw/mwrender/viewovershoulder.cpp +++ b/apps/openmw/mwrender/viewovershoulder.cpp @@ -21,14 +21,14 @@ namespace MWRender mAutoSwitchShoulder(Settings::Manager::getBool("auto switch shoulder", "Camera")), mOverShoulderHorizontalOffset(30.f), mOverShoulderVerticalOffset(-10.f) { - std::stringstream offset(Settings::Manager::getString("view over shoulder offset", "Camera")); - offset >> mOverShoulderHorizontalOffset >> mOverShoulderVerticalOffset; - mDefaultShoulderIsRight = mOverShoulderHorizontalOffset >= 0; - mOverShoulderHorizontalOffset = std::abs(mOverShoulderHorizontalOffset); + osg::Vec2f offset = Settings::Manager::getVector2("view over shoulder offset", "Camera"); + mOverShoulderHorizontalOffset = std::abs(offset.x()); + mOverShoulderVerticalOffset = offset.y(); + mDefaultShoulderIsRight = offset.x() >= 0; mCamera->enableDynamicCameraDistance(true); mCamera->enableCrosshairInThirdPersonMode(true); - mCamera->setFocalPointTargetOffset({mOverShoulderHorizontalOffset, mOverShoulderVerticalOffset}); + mCamera->setFocalPointTargetOffset(offset); } void ViewOverShoulderController::update() diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp index 540af4d19..b29dadcdc 100644 --- a/components/settings/settings.cpp +++ b/components/settings/settings.cpp @@ -76,6 +76,28 @@ bool Manager::getBool (const std::string& setting, const std::string& category) return Misc::StringUtils::ciEqual(string, "true"); } +osg::Vec2f Manager::getVector2 (const std::string& setting, const std::string& category) +{ + const std::string& value = getString(setting, category); + std::stringstream stream(value); + float x, y; + stream >> x >> y; + if (stream.fail()) + throw std::runtime_error(std::string("Can't parse 2d vector: " + value)); + return osg::Vec2f(x, y); +} + +osg::Vec3f Manager::getVector3 (const std::string& setting, const std::string& category) +{ + const std::string& value = getString(setting, category); + std::stringstream stream(value); + float x, y, z; + stream >> x >> y >> z; + if (stream.fail()) + throw std::runtime_error(std::string("Can't parse 3d vector: " + value)); + return osg::Vec3f(x, y, z); +} + void Manager::setString(const std::string &setting, const std::string &category, const std::string &value) { CategorySettingValueMap::key_type key = std::make_pair(category, setting); @@ -111,6 +133,20 @@ void Manager::setBool(const std::string &setting, const std::string &category, c setString(setting, category, value ? "true" : "false"); } +void Manager::setVector2 (const std::string &setting, const std::string &category, const osg::Vec2f value) +{ + std::ostringstream stream; + stream << value.x() << " " << value.y(); + setString(setting, category, stream.str()); +} + +void Manager::setVector3 (const std::string &setting, const std::string &category, const osg::Vec3f value) +{ + std::ostringstream stream; + stream << value.x() << ' ' << value.y() << ' ' << value.z(); + setString(setting, category, stream.str()); +} + void Manager::resetPendingChange(const std::string &setting, const std::string &category) { CategorySettingValueMap::key_type key = std::make_pair(category, setting); diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index 17d237fc3..ecc5aa5fd 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace Settings { @@ -44,11 +46,15 @@ namespace Settings static float getFloat (const std::string& setting, const std::string& category); static std::string getString (const std::string& setting, const std::string& category); static bool getBool (const std::string& setting, const std::string& category); + static osg::Vec2f getVector2 (const std::string& setting, const std::string& category); + static osg::Vec3f getVector3 (const std::string& setting, const std::string& category); static void setInt (const std::string& setting, const std::string& category, const int value); static void setFloat (const std::string& setting, const std::string& category, const float value); static void setString (const std::string& setting, const std::string& category, const std::string& value); static void setBool (const std::string& setting, const std::string& category, const bool value); + static void setVector2 (const std::string& setting, const std::string& category, const osg::Vec2f value); + static void setVector3 (const std::string& setting, const std::string& category, const osg::Vec3f value); }; } From e6036e13b92a46310cc9a387f73422dfb88f541d Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 25 Jul 2020 15:54:49 +0400 Subject: [PATCH 013/224] Use more C++11 loops in game mechanics code --- apps/openmw/mwmechanics/aiavoiddoor.cpp | 15 +++-- apps/openmw/mwmechanics/aifollow.cpp | 4 +- apps/openmw/mwmechanics/aisequence.cpp | 46 ++++++------- apps/openmw/mwmechanics/aiwander.cpp | 6 +- apps/openmw/mwmechanics/autocalcspell.cpp | 82 ++++++++++------------- apps/openmw/mwmechanics/character.cpp | 6 +- apps/openmw/mwmechanics/levelledlist.hpp | 18 ++--- apps/openmw/mwmechanics/objects.cpp | 21 +++--- apps/openmw/mwmechanics/obstacle.cpp | 6 +- 9 files changed, 94 insertions(+), 110 deletions(-) diff --git a/apps/openmw/mwmechanics/aiavoiddoor.cpp b/apps/openmw/mwmechanics/aiavoiddoor.cpp index 47f72efce..ce2553756 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.cpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.cpp @@ -60,13 +60,14 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterCont // Make all nearby actors also avoid the door std::vector actors; MWBase::Environment::get().getMechanicsManager()->getActorsInRange(pos.asVec3(),100,actors); - for(std::vector::iterator it = actors.begin(); it != actors.end(); ++it) { - if(*it != getPlayer()) { //Not the player - MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence(); - if(seq.getTypeId() != MWMechanics::AiPackageTypeId::AvoidDoor) { //Only add it once - seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr),*it); - } - } + for(auto& actor : actors) + { + if (actor == getPlayer()) + continue; + + MWMechanics::AiSequence& seq = actor.getClass().getCreatureStats(actor).getAiSequence(); + if (seq.getTypeId() != MWMechanics::AiPackageTypeId::AvoidDoor) + seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr), actor); } return false; diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index a9e43b3c3..b3c308d75 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -124,9 +124,9 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte followDistance = 313; short i = 0; followers.sort(); - for (std::list::iterator it = followers.begin(); it != followers.end(); ++it) + for (int followIndex : followers) { - if (*it == mFollowIndex) + if (followIndex == mFollowIndex) followDistance += 130 * i; ++i; } diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index f747b16f2..57d32898c 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -406,36 +406,36 @@ void AiSequence::fill(const ESM::AIPackageList &list) if (!list.mList.empty() && list.mList.begin() != (list.mList.end()-1)) mRepeat = true; - for (std::vector::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it) + for (const auto& esmPackage : list.mList) { std::unique_ptr package; - if (it->mType == ESM::AI_Wander) + if (esmPackage.mType == ESM::AI_Wander) { - ESM::AIWander data = it->mWander; + ESM::AIWander data = esmPackage.mWander; std::vector idles; idles.reserve(8); for (int i=0; i<8; ++i) idles.push_back(data.mIdle[i]); package = std::make_unique(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat != 0); } - else if (it->mType == ESM::AI_Escort) + else if (esmPackage.mType == ESM::AI_Escort) { - ESM::AITarget data = it->mTarget; + ESM::AITarget data = esmPackage.mTarget; package = std::make_unique(data.mId.toString(), data.mDuration, data.mX, data.mY, data.mZ); } - else if (it->mType == ESM::AI_Travel) + else if (esmPackage.mType == ESM::AI_Travel) { - ESM::AITravel data = it->mTravel; + ESM::AITravel data = esmPackage.mTravel; package = std::make_unique(data.mX, data.mY, data.mZ); } - else if (it->mType == ESM::AI_Activate) + else if (esmPackage.mType == ESM::AI_Activate) { - ESM::AIActivate data = it->mActivate; + ESM::AIActivate data = esmPackage.mActivate; package = std::make_unique(data.mName.toString()); } - else //if (it->mType == ESM::AI_Follow) + else //if (esmPackage.mType == ESM::AI_Follow) { - ESM::AITarget data = it->mTarget; + ESM::AITarget data = esmPackage.mTarget; package = std::make_unique(data.mId.toString(), data.mDuration, data.mX, data.mY, data.mZ); } mPackages.push_back(std::move(package)); @@ -457,10 +457,9 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence) // If there is more than one non-combat, non-pursue package in the list, enable repeating. int count = 0; - for (std::vector::const_iterator it = sequence.mPackages.begin(); - it != sequence.mPackages.end(); ++it) + for (auto& container : sequence.mPackages) { - if (isActualAiPackage(static_cast(it->mType))) + if (isActualAiPackage(static_cast(container.mType))) count++; } @@ -468,20 +467,19 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence) mRepeat = true; // Load packages - for (std::vector::const_iterator it = sequence.mPackages.begin(); - it != sequence.mPackages.end(); ++it) + for (auto& container : sequence.mPackages) { std::unique_ptr package; - switch (it->mType) + switch (container.mType) { case ESM::AiSequence::Ai_Wander: { - package.reset(new AiWander(static_cast(it->mPackage))); + package.reset(new AiWander(static_cast(container.mPackage))); break; } case ESM::AiSequence::Ai_Travel: { - const auto source = static_cast(it->mPackage); + const auto source = static_cast(container.mPackage); if (source->mHidden) package.reset(new AiInternalTravel(source)); else @@ -490,27 +488,27 @@ void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence) } case ESM::AiSequence::Ai_Escort: { - package.reset(new AiEscort(static_cast(it->mPackage))); + package.reset(new AiEscort(static_cast(container.mPackage))); break; } case ESM::AiSequence::Ai_Follow: { - package.reset(new AiFollow(static_cast(it->mPackage))); + package.reset(new AiFollow(static_cast(container.mPackage))); break; } case ESM::AiSequence::Ai_Activate: { - package.reset(new AiActivate(static_cast(it->mPackage))); + package.reset(new AiActivate(static_cast(container.mPackage))); break; } case ESM::AiSequence::Ai_Combat: { - package.reset(new AiCombat(static_cast(it->mPackage))); + package.reset(new AiCombat(static_cast(container.mPackage))); break; } case ESM::AiSequence::Ai_Pursue: { - package.reset(new AiPursue(static_cast(it->mPackage))); + package.reset(new AiPursue(static_cast(container.mPackage))); break; } default: diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 11c50dc09..9e179edeb 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -809,11 +809,11 @@ namespace MWMechanics void AiWander::AddNonPathGridAllowedPoints(osg::Vec3f npcPos, const ESM::Pathgrid * pathGrid, int pointIndex, AiWanderStorage& storage) { storage.mAllowedNodes.push_back(PathFinder::makePathgridPoint(npcPos)); - for (std::vector::const_iterator it = pathGrid->mEdges.begin(); it != pathGrid->mEdges.end(); ++it) + for (auto& edge : pathGrid->mEdges) { - if (it->mV0 == pointIndex) + if (edge.mV0 == pointIndex) { - AddPointBetweenPathGridPoints(pathGrid->mPoints[it->mV0], pathGrid->mPoints[it->mV1], storage); + AddPointBetweenPathGridPoints(pathGrid->mPoints[edge.mV0], pathGrid->mPoints[edge.mV1], storage); } } } diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index 9cee1aa31..662cfe473 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -61,38 +61,36 @@ namespace MWMechanics // Note: the algorithm heavily depends on the traversal order of the spells. For vanilla-compatible results the // Store must preserve the record ordering as it was in the content files. - for (MWWorld::Store::iterator iter = spells.begin(); iter != spells.end(); ++iter) + for (const ESM::Spell& spell : spells) { - const ESM::Spell* spell = &*iter; - - if (spell->mData.mType != ESM::Spell::ST_Spell) + if (spell.mData.mType != ESM::Spell::ST_Spell) continue; - if (!(spell->mData.mFlags & ESM::Spell::F_Autocalc)) + if (!(spell.mData.mFlags & ESM::Spell::F_Autocalc)) continue; static const int iAutoSpellTimesCanCast = gmst.find("iAutoSpellTimesCanCast")->mValue.getInteger(); - if (baseMagicka < iAutoSpellTimesCanCast * spell->mData.mCost) + if (baseMagicka < iAutoSpellTimesCanCast * spell.mData.mCost) continue; - if (race && race->mPowers.exists(spell->mId)) + if (race && race->mPowers.exists(spell.mId)) continue; - if (!attrSkillCheck(spell, actorSkills, actorAttributes)) + if (!attrSkillCheck(&spell, actorSkills, actorAttributes)) continue; int school; float skillTerm; - calcWeakestSchool(spell, actorSkills, school, skillTerm); + calcWeakestSchool(&spell, actorSkills, school, skillTerm); assert(school >= 0 && school < 6); SchoolCaps& cap = schoolCaps[school]; - if (cap.mReachedLimit && spell->mData.mCost <= cap.mMinCost) + if (cap.mReachedLimit && spell.mData.mCost <= cap.mMinCost) continue; static const float fAutoSpellChance = gmst.find("fAutoSpellChance")->mValue.getFloat(); - if (calcAutoCastChance(spell, actorSkills, actorAttributes, school) < fAutoSpellChance) + if (calcAutoCastChance(&spell, actorSkills, actorAttributes, school) < fAutoSpellChance) continue; - selectedSpells.push_back(spell->mId); + selectedSpells.push_back(spell.mId); if (cap.mReachedLimit) { @@ -101,9 +99,9 @@ namespace MWMechanics selectedSpells.erase(found); cap.mMinCost = std::numeric_limits::max(); - for (std::vector::iterator weakIt = selectedSpells.begin(); weakIt != selectedSpells.end(); ++weakIt) + for (const std::string& testSpellName : selectedSpells) { - const ESM::Spell* testSpell = spells.find(*weakIt); + const ESM::Spell* testSpell = spells.find(testSpellName); //int testSchool; //float dummySkillTerm; @@ -130,10 +128,10 @@ namespace MWMechanics if (cap.mCount == cap.mLimit) cap.mReachedLimit = true; - if (spell->mData.mCost < cap.mMinCost) + if (spell.mData.mCost < cap.mMinCost) { - cap.mWeakestSpell = spell->mId; - cap.mMinCost = spell->mData.mCost; + cap.mWeakestSpell = spell.mId; + cap.mMinCost = spell.mData.mCost; } } } @@ -154,32 +152,28 @@ namespace MWMechanics std::vector selectedSpells; - - const MWWorld::Store &spells = - esmStore.get(); - for (MWWorld::Store::iterator iter = spells.begin(); iter != spells.end(); ++iter) + const MWWorld::Store &spells = esmStore.get(); + for (const ESM::Spell& spell : spells) { - const ESM::Spell* spell = &*iter; - - if (spell->mData.mType != ESM::Spell::ST_Spell) + if (spell.mData.mType != ESM::Spell::ST_Spell) continue; - if (!(spell->mData.mFlags & ESM::Spell::F_PCStart)) + if (!(spell.mData.mFlags & ESM::Spell::F_PCStart)) continue; - if (reachedLimit && spell->mData.mCost <= minCost) + if (reachedLimit && spell.mData.mCost <= minCost) continue; - if (race && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell->mId) != race->mPowers.mList.end()) + if (race && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell.mId) != race->mPowers.mList.end()) continue; - if (baseMagicka < spell->mData.mCost) + if (baseMagicka < spell.mData.mCost) continue; static const float fAutoPCSpellChance = esmStore.get().find("fAutoPCSpellChance")->mValue.getFloat(); - if (calcAutoCastChance(spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance) + if (calcAutoCastChance(&spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance) continue; - if (!attrSkillCheck(spell, actorSkills, actorAttributes)) + if (!attrSkillCheck(&spell, actorSkills, actorAttributes)) continue; - selectedSpells.push_back(spell->mId); + selectedSpells.push_back(spell.mId); if (reachedLimit) { @@ -188,9 +182,9 @@ namespace MWMechanics selectedSpells.erase(it); minCost = std::numeric_limits::max(); - for (std::vector::iterator weakIt = selectedSpells.begin(); weakIt != selectedSpells.end(); ++weakIt) + for (const std::string& testSpellName : selectedSpells) { - const ESM::Spell* testSpell = esmStore.get().find(*weakIt); + const ESM::Spell* testSpell = esmStore.get().find(testSpellName); if (testSpell->mData.mCost < minCost) { minCost = testSpell->mData.mCost; @@ -200,9 +194,9 @@ namespace MWMechanics } else { - if (spell->mData.mCost < minCost) + if (spell.mData.mCost < minCost) { - weakestSpell = spell; + weakestSpell = &spell; minCost = weakestSpell->mData.mCost; } static const unsigned int iAutoPCSpellMax = esmStore.get().find("iAutoPCSpellMax")->mValue.getInteger(); @@ -216,23 +210,22 @@ namespace MWMechanics bool attrSkillCheck (const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes) { - const std::vector& effects = spell->mEffects.mList; - for (std::vector::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt) + for (const auto& spellEffect : spell->mEffects.mList) { - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); + const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(spellEffect.mEffectID); static const int iAutoSpellAttSkillMin = MWBase::Environment::get().getWorld()->getStore().get().find("iAutoSpellAttSkillMin")->mValue.getInteger(); if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)) { - assert (effectIt->mSkill >= 0 && effectIt->mSkill < ESM::Skill::Length); - if (actorSkills[effectIt->mSkill] < iAutoSpellAttSkillMin) + assert (spellEffect.mSkill >= 0 && spellEffect.mSkill < ESM::Skill::Length); + if (actorSkills[spellEffect.mSkill] < iAutoSpellAttSkillMin) return false; } if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)) { - assert (effectIt->mAttribute >= 0 && effectIt->mAttribute < ESM::Attribute::Length); - if (actorAttributes[effectIt->mAttribute] < iAutoSpellAttSkillMin) + assert (spellEffect.mAttribute >= 0 && spellEffect.mAttribute < ESM::Attribute::Length); + if (actorAttributes[spellEffect.mAttribute] < iAutoSpellAttSkillMin) return false; } } @@ -244,11 +237,8 @@ namespace MWMechanics { // Morrowind for some reason uses a formula slightly different from magicka cost calculation float minChance = std::numeric_limits::max(); - - const ESM::EffectList& effects = spell->mEffects; - for (std::vector::const_iterator it = effects.mList.begin(); it != effects.mList.end(); ++it) + for (const ESM::ENAMstruct& effect : spell->mEffects.mList) { - const ESM::ENAMstruct& effect = *it; const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); int minMagn = 1; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index aed638895..c8e81aa49 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2653,11 +2653,11 @@ void CharacterController::updateContinuousVfx() std::vector effects; mAnimation->getLoopingEffects(effects); - for (std::vector::iterator it = effects.begin(); it != effects.end(); ++it) + for (int effectId : effects) { if (mPtr.getClass().getCreatureStats(mPtr).isDeathAnimationFinished() - || mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(MWMechanics::EffectKey(*it)).getMagnitude() <= 0) - mAnimation->removeEffect(*it); + || mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(MWMechanics::EffectKey(effectId)).getMagnitude() <= 0) + mAnimation->removeEffect(effectId); } } diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index 697e2eda8..f716f068d 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -31,10 +31,10 @@ namespace MWMechanics std::vector candidates; int highestLevel = 0; - for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + for (const auto& levelledItem : items) { - if (it->mLevel > highestLevel && it->mLevel <= playerLevel) - highestLevel = it->mLevel; + if (levelledItem.mLevel > highestLevel && levelledItem.mLevel <= playerLevel) + highestLevel = levelledItem.mLevel; } // For levelled creatures, the flags are swapped. This file format just makes so much sense. @@ -43,14 +43,14 @@ namespace MWMechanics allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels; std::pair highest = std::make_pair(-1, ""); - for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + for (const auto& levelledItem : items) { - if (playerLevel >= it->mLevel - && (allLevels || it->mLevel == highestLevel)) + if (playerLevel >= levelledItem.mLevel + && (allLevels || levelledItem.mLevel == highestLevel)) { - candidates.push_back(it->mId); - if (it->mLevel >= highest.first) - highest = std::make_pair(it->mLevel, it->mId); + candidates.push_back(levelledItem.mId); + if (levelledItem.mLevel >= highest.first) + highest = std::make_pair(levelledItem.mLevel, levelledItem.mId); } } if (candidates.empty()) diff --git a/apps/openmw/mwmechanics/objects.cpp b/apps/openmw/mwmechanics/objects.cpp index 9e05509f1..5b18fc2c3 100644 --- a/apps/openmw/mwmechanics/objects.cpp +++ b/apps/openmw/mwmechanics/objects.cpp @@ -19,11 +19,10 @@ Objects::Objects() Objects::~Objects() { - PtrControllerMap::iterator it(mObjects.begin()); - for (; it != mObjects.end();++it) + for(auto& object : mObjects) { - delete it->second; - it->second = nullptr; + delete object.second; + object.second = nullptr; } } @@ -77,8 +76,8 @@ void Objects::update(float duration, bool paused) { if(!paused) { - for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter) - iter->second->update(duration); + for(auto& object : mObjects) + object.second->update(duration); } else { @@ -87,15 +86,15 @@ void Objects::update(float duration, bool paused) if(mode != MWGui::GM_Container) return; - for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter) + for(auto& object : mObjects) { - if (iter->first.getTypeName() != typeid(ESM::Container).name()) + if (object.first.getTypeName() != typeid(ESM::Container).name()) continue; - if (iter->second->isAnimPlaying("containeropen")) + if (object.second->isAnimPlaying("containeropen")) { - iter->second->update(duration); - MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(iter->first); + object.second->update(duration); + MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.first); } } } diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index e30a2947f..715dfecd2 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -36,17 +36,13 @@ namespace MWMechanics // Check all the doors in this cell const MWWorld::CellRefList& doors = cell->getReadOnlyDoors(); - const MWWorld::CellRefList::List& refList = doors.mList; - MWWorld::CellRefList::List::const_iterator it = refList.begin(); osg::Vec3f pos(actor.getRefData().getPosition().asVec3()); pos.z() = 0; osg::Vec3f actorDir = (actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0)); - for (; it != refList.end(); ++it) + for (const auto& ref : doors.mList) { - const MWWorld::LiveCellRef& ref = *it; - osg::Vec3f doorPos(ref.mData.getPosition().asVec3()); // FIXME: cast From 2e27de027e642c7db06724fd54f2f7f6578e8092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Sat, 25 Jul 2020 13:58:42 +0000 Subject: [PATCH 014/224] Add members in AdvancedPage class to avoid memory leak when the list of cells names is updated as we recreated a completer at each notification event --- CHANGELOG.md | 1 + apps/launcher/advancedpage.cpp | 12 ++++++------ apps/launcher/advancedpage.hpp | 4 ++++ components/contentselector/view/combobox.cpp | 1 + 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c98dfbe3d..e75b20dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Feature #5524: Resume failed script execution after reload Feature #5525: Search fields tweaks (utf-8) Task #5480: Drop Qt4 support + Task #5520: Improve cell name autocompleter implementation 0.46.0 ------ diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index e9db74cae..00d0df048 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -19,15 +19,15 @@ Launcher::AdvancedPage::AdvancedPage(Files::ConfigurationManager &cfg, setupUi(this); loadSettings(); + mCellNameCompleter.setModel(&mCellNameCompleterModel); + startDefaultCharacterAtField->setCompleter(&mCellNameCompleter); } void Launcher::AdvancedPage::loadCellsForAutocomplete(QStringList cellNames) { - // Set up an auto-completer for the "Start default character at" field - auto *completer = new QCompleter(cellNames); - completer->setCompletionMode(QCompleter::PopupCompletion); - completer->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); - startDefaultCharacterAtField->setCompleter(completer); - + // Update the list of suggestions for the "Start default character at" field + mCellNameCompleterModel.setStringList(cellNames); + mCellNameCompleter.setCompletionMode(QCompleter::PopupCompletion); + mCellNameCompleter.setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); } void Launcher::AdvancedPage::on_skipMenuCheckBox_stateChanged(int state) { diff --git a/apps/launcher/advancedpage.hpp b/apps/launcher/advancedpage.hpp index 3f5e5bfa7..25cb66d9d 100644 --- a/apps/launcher/advancedpage.hpp +++ b/apps/launcher/advancedpage.hpp @@ -2,6 +2,8 @@ #define ADVANCEDPAGE_H #include +#include +#include #include "ui_advancedpage.h" @@ -35,6 +37,8 @@ namespace Launcher Files::ConfigurationManager &mCfgMgr; Config::GameSettings &mGameSettings; Settings::Manager &mEngineSettings; + QCompleter mCellNameCompleter; + QStringListModel mCellNameCompleterModel; /** * Load the cells associated with the given content files for use in autocomplete diff --git a/components/contentselector/view/combobox.cpp b/components/contentselector/view/combobox.cpp index 959eca289..1ef9f9bd7 100644 --- a/components/contentselector/view/combobox.cpp +++ b/components/contentselector/view/combobox.cpp @@ -8,6 +8,7 @@ ContentSelectorView::ComboBox::ComboBox(QWidget *parent) : { mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore setValidator(mValidator); + setEditable(true); setCompleter(0); setEnabled (true); From 1f4f10c72321e4c7f5023edeb3ac630f976d1fe0 Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Thu, 9 Jul 2020 14:56:13 +0200 Subject: [PATCH 015/224] Add a tab level in advanced settings --- apps/launcher/advancedpage.cpp | 337 ++++-- .../reference/modding/settings/camera.rst | 2 +- .../reference/modding/settings/game.rst | 2 +- files/ui/advancedpage.ui | 1073 +++++++++-------- 4 files changed, 791 insertions(+), 623 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 00d0df048..07fe8ddd6 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -4,9 +4,43 @@ #include #include #include +#include #include #include +#include + + +class HorizontalTextWestTabStyle : public QProxyStyle +{ +public: + QSize sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const + { + QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); + if (type == QStyle::CT_TabBarTab) + { + s.transpose(); + s.setHeight(s.height() + 20); + } + return s; + } + + void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const + { + if (element == CE_TabBarTabLabel) + { + if (const QStyleOptionTab* tab = qstyleoption_cast(option)) + { + QStyleOptionTab opt(*tab); + opt.shape = QTabBar::RoundedNorth; + QProxyStyle::drawControl(element, &opt, painter, widget); + return; + } + } + QProxyStyle::drawControl(element, option, painter, widget); + } +}; + Launcher::AdvancedPage::AdvancedPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, Settings::Manager &engineSettings, QWidget *parent) @@ -19,6 +53,7 @@ Launcher::AdvancedPage::AdvancedPage(Files::ConfigurationManager &cfg, setupUi(this); loadSettings(); + AdvancedTabWidget->tabBar()->setStyle(new HorizontalTextWestTabStyle); mCellNameCompleter.setModel(&mCellNameCompleterModel); startDefaultCharacterAtField->setCompleter(&mCellNameCompleter); } @@ -55,142 +90,220 @@ void Launcher::AdvancedPage::on_runScriptAfterStartupBrowseButton_clicked() runScriptAfterStartupField->setText(path); } +namespace +{ + constexpr double CellSizeInUnits = 8192; + + double convertToCells(double unitRadius) + { + return std::round((unitRadius / 0.93 + 1024) / CellSizeInUnits); + } + + double convertToUnits(double CellGridRadius) + { + return (CellSizeInUnits * CellGridRadius - 1024) * 0.93; + } +} + bool Launcher::AdvancedPage::loadSettings() { - // Testing - bool skipMenu = mGameSettings.value("skip-menu").toInt() == 1; - if (skipMenu) { - skipMenuCheckBox->setCheckState(Qt::Checked); - } - startDefaultCharacterAtLabel->setEnabled(skipMenu); - startDefaultCharacterAtField->setEnabled(skipMenu); - - startDefaultCharacterAtField->setText(mGameSettings.value("start")); - runScriptAfterStartupField->setText(mGameSettings.value("script-run")); - - // Game Settings - loadSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game"); - loadSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game"); - loadSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game"); - loadSettingBool(classicReflectedAbsorbSpellsCheckBox, "classic reflected absorb spells behavior", "Game"); - loadSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game"); - loadSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); - loadSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game"); - int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game"); - if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2) - unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); - loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); - loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); - loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); - connect(animSourcesCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAnimSourcesToggled(bool))); - loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); - if (animSourcesCheckBox->checkState()) + // Game mechanics { - loadSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); - loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); + loadSettingBool(toggleSneakCheckBox, "toggle sneak", "Input"); + loadSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game"); + loadSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game"); + loadSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game"); + loadSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); + loadSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game"); + loadSettingBool(classicReflectedAbsorbSpellsCheckBox, "classic reflected absorb spells behavior", "Game"); + loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); + loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); + loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); + int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game"); + if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2) + unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); } - loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); - loadSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); - // Input Settings - loadSettingBool(grabCursorCheckBox, "grab cursor", "Input"); - loadSettingBool(toggleSneakCheckBox, "toggle sneak", "Input"); + // Visuals + { + loadSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders"); + loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); + connect(animSourcesCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAnimSourcesToggled(bool))); + loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); + if (animSourcesCheckBox->checkState()) + { + loadSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); + loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); + } + loadSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); + loadSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); - // Saves Settings - loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); - maximumQuicksavesComboBox->setValue(mEngineSettings.getInt("max quicksaves", "Saves")); + const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); + const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain"); + if (distantTerrain && objectPaging) { + distantLandCheckBox->setCheckState(Qt::Checked); + } - // User Interface Settings - loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); - loadSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game"); - loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game"); - loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); - loadSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); - int showOwnedIndex = mEngineSettings.getInt("show owned", "Game"); - // Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid. - if (showOwnedIndex >= 0 && showOwnedIndex <= 3) - showOwnedComboBox->setCurrentIndex(showOwnedIndex); + loadSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain"); + viewingDistanceComboBox->setValue(convertToCells(mEngineSettings.getInt("viewing distance", "Camera"))); + } - // Other Settings - QString screenshotFormatString = QString::fromStdString(mEngineSettings.getString("screenshot format", "General")).toUpper(); - if (screenshotFormatComboBox->findText(screenshotFormatString) == -1) - screenshotFormatComboBox->addItem(screenshotFormatString); - screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString)); + // Interface Changes + { + loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); + loadSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game"); + loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game"); + loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); + loadSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); + int showOwnedIndex = mEngineSettings.getInt("show owned", "Game"); + // Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid. + if (showOwnedIndex >= 0 && showOwnedIndex <= 3) + showOwnedComboBox->setCurrentIndex(showOwnedIndex); + } + // Bug fixes + { + loadSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game"); + loadSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); + } + + // Miscellaneous + { + // Saves + loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); + maximumQuicksavesComboBox->setValue(mEngineSettings.getInt("max quicksaves", "Saves")); + + // Other Settings + QString screenshotFormatString = QString::fromStdString(mEngineSettings.getString("screenshot format", "General")).toUpper(); + if (screenshotFormatComboBox->findText(screenshotFormatString) == -1) + screenshotFormatComboBox->addItem(screenshotFormatString); + screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString)); + } + + // Testing + { + loadSettingBool(grabCursorCheckBox, "grab cursor", "Input"); + + bool skipMenu = mGameSettings.value("skip-menu").toInt() == 1; + if (skipMenu) + { + skipMenuCheckBox->setCheckState(Qt::Checked); + } + startDefaultCharacterAtLabel->setEnabled(skipMenu); + startDefaultCharacterAtField->setEnabled(skipMenu); + + startDefaultCharacterAtField->setText(mGameSettings.value("start")); + runScriptAfterStartupField->setText(mGameSettings.value("script-run")); + } return true; } void Launcher::AdvancedPage::saveSettings() { - // Ensure we only set the new settings if they changed. This is to avoid cluttering the - // user settings file (which by definition should only contain settings the user has touched) + // Game mechanics + { + saveSettingBool(toggleSneakCheckBox, "toggle sneak", "Input"); + saveSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game"); + saveSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game"); + saveSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game"); + saveSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); + saveSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game"); + saveSettingBool(classicReflectedAbsorbSpellsCheckBox, "classic reflected absorb spells behavior", "Game"); + saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); + saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); + saveSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); + int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex(); + if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game")) + mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); + } + + // Visuals + { + saveSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders"); + saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); + saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); + saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); + saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); + saveSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); + saveSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); + + const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); + const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain"); + const bool wantDistantLand = distantLandCheckBox->checkState(); + if (wantDistantLand != (distantTerrain && objectPaging)) { + mEngineSettings.setBool("distant terrain", "Terrain", wantDistantLand); + mEngineSettings.setBool("object paging", "Terrain", wantDistantLand); + } + + saveSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain"); + double viewingDistance = viewingDistanceComboBox->value(); + if (viewingDistance != convertToCells(mEngineSettings.getInt("viewing distance", "Camera"))) + { + mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance)); + } + } + + // Interface Changes + { + saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); + saveSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game"); + saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game"); + saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); + saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); + int showOwnedCurrentIndex = showOwnedComboBox->currentIndex(); + if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game")) + mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex); + } + + // Bug fixes + { + saveSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game"); + saveSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); + } + + // Miscellaneous + { + // Saves Settings + saveSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); + int maximumQuicksaves = maximumQuicksavesComboBox->value(); + if (maximumQuicksaves != mEngineSettings.getInt("max quicksaves", "Saves")) + { + mEngineSettings.setInt("max quicksaves", "Saves", maximumQuicksaves); + } + + // Other Settings + std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString(); + if (screenshotFormatString != mEngineSettings.getString("screenshot format", "General")) + mEngineSettings.setString("screenshot format", "General", screenshotFormatString); + } // Testing - int skipMenu = skipMenuCheckBox->checkState() == Qt::Checked; - if (skipMenu != mGameSettings.value("skip-menu").toInt()) - mGameSettings.setValue("skip-menu", QString::number(skipMenu)); + { + saveSettingBool(grabCursorCheckBox, "grab cursor", "Input"); - QString startCell = startDefaultCharacterAtField->text(); - if (startCell != mGameSettings.value("start")) { - mGameSettings.setValue("start", startCell); + int skipMenu = skipMenuCheckBox->checkState() == Qt::Checked; + if (skipMenu != mGameSettings.value("skip-menu").toInt()) + mGameSettings.setValue("skip-menu", QString::number(skipMenu)); + + QString startCell = startDefaultCharacterAtField->text(); + if (startCell != mGameSettings.value("start")) + { + mGameSettings.setValue("start", startCell); + } + QString scriptRun = runScriptAfterStartupField->text(); + if (scriptRun != mGameSettings.value("script-run")) + mGameSettings.setValue("script-run", scriptRun); } - QString scriptRun = runScriptAfterStartupField->text(); - if (scriptRun != mGameSettings.value("script-run")) - mGameSettings.setValue("script-run", scriptRun); - - // Game Settings - saveSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game"); - saveSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game"); - saveSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game"); - saveSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game"); - saveSettingBool(classicReflectedAbsorbSpellsCheckBox, "classic reflected absorb spells behavior", "Game"); - saveSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); - saveSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game"); - int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex(); - if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game")) - mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); - saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); - saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); - saveSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); - saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); - saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); - saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); - saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); - saveSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); - - // Input Settings - saveSettingBool(grabCursorCheckBox, "grab cursor", "Input"); - saveSettingBool(toggleSneakCheckBox, "toggle sneak", "Input"); - - // Saves Settings - saveSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); - int maximumQuicksaves = maximumQuicksavesComboBox->value(); - if (maximumQuicksaves != mEngineSettings.getInt("max quicksaves", "Saves")) { - mEngineSettings.setInt("max quicksaves", "Saves", maximumQuicksaves); - } - - // User Interface Settings - saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); - saveSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game"); - saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game"); - saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); - saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); - int showOwnedCurrentIndex = showOwnedComboBox->currentIndex(); - if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game")) - mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex); - - // Other Settings - std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString(); - if (screenshotFormatString != mEngineSettings.getString("screenshot format", "General")) - mEngineSettings.setString("screenshot format", "General", screenshotFormatString); } -void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) { +void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) +{ if (mEngineSettings.getBool(setting, group)) checkbox->setCheckState(Qt::Checked); } -void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) { +void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) +{ bool cValue = checkbox->checkState(); if (cValue != mEngineSettings.getBool(setting, group)) mEngineSettings.setBool(setting, group, cValue); diff --git a/docs/source/reference/modding/settings/camera.rst b/docs/source/reference/modding/settings/camera.rst index 18b6754a7..8d7078905 100644 --- a/docs/source/reference/modding/settings/camera.rst +++ b/docs/source/reference/modding/settings/camera.rst @@ -136,7 +136,7 @@ This setting controls third person view mode. False: View is centered on the character's head. Crosshair is hidden. True: In non-combat mode camera is positioned behind the character's shoulder. Crosshair is visible in third person mode as well. -This setting can only be configured by editing the settings configuration file. +This setting can be controlled in Advanced tab of the launcher. view over shoulder offset ------------------------- diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index 8d0b0dfc1..072c614d4 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -329,7 +329,7 @@ If disabled then the whole character's body is pointed to the direction of view. If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it also changes straight right and straight left movement. -This setting can only be configured by editing the settings configuration file. +This setting can be controlled in Advanced tab of the launcher. swim upward coef ---------------- diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 142cd7259..de8e3dfc0 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -4,280 +4,466 @@ - - - true + + + QTabWidget::West - + + 0 + + + + Game mechanics + + + + + + <html><head/><body><p>This setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. </p></body></html> + + + Toggle sneak + + + + + + + <html><head/><body><p>If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.</p><p>If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.</p></body></html> + + + Can loot during death animation + + + + + + + <html><head/><body><p>Make player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.</p></body></html> + + + Followers defend immediately + + + + + + + <html><head/><body><p>Make the value of filled soul gems dependent only on soul magnitude.</p></body></html> + + + Soulgem values rebalance + + + + + + + <html><head/><body><p>Make enchanted weaponry without Magical flag bypass normal weapons resistance, like in Morrowind.</p></body></html> + + + Enchanted weapons are magical + + + + + + + <html><head/><body><p>Make disposition change of merchants caused by trading permanent.</p></body></html> + + + Permanent barter disposition changes + + + + + + + <html><head/><body><p>Effects of reflected Absorb spells are not mirrored -- like in Morrowind.</p></body></html> + + + Classic reflected Absorb spells behavior + + + + + + + <html><head/><body><p>Allow non-standard ammunition solely to bypass normal weapon resistance or weakness.</p></body></html> + + + Only appropriate ammunition bypasses normal weapon resistance + + + + + + + <html><head/><body><p>Make Damage Fatigue magic effect uncapped like Drain Fatigue effect.</p><p>This means that unlike Morrowind you will be able to knock down actors using this effect.</p></body></html> + + + Uncapped Damage Fatigue + + + + + + + <html><head/><body><p>Don't use race weight in NPC movement speed calculations.</p></body></html> + + + Racial variation in speed fix + + + + + + + <html><head/><body><p>Factor strength into hand-to-hand damage calculations, as the MCP formula: damage * (strength / 40).</p><p>The default value is Off.</p></body></html> + + + + + + Factor strength into hand-to-hand combat: + + + + + + + 0 + + + + Off + + + + + Affect werewolves + + + + + Do not affect werewolves + + + + + + + + + + + Qt::Vertical + + + + + + + + Visuals + + + + + + <html><head/><body><p>Normally environment map reflections aren't affected by lighting, which makes environment-mapped (and thus bump-mapped objects) glow in the dark. +Morrowind Code Patch includes an option to remedy that by doing environment-mapping before applying lighting, this is the equivalent of that option. +Affected objects will use shaders. +</p></body></html> + + + Bump/reflect map local lighting + + + + + + + <html><head/><body><p>Use casting animations for magic items, just as for spells.</p></body></html> + + + Use magic item animation + + + + + + + <html><head/><body><p>Load per-group KF-files and skeleton files from Animations folder</p></body></html> + + + Use additional animation sources + + + + + + + + 20 + + + + + false + + + <html><head/><body><p>Render holstered weapons (with quivers and scabbards), requires modded assets.</p></body></html> + + + Weapon sheathing + + + + + + + false + + + <html><head/><body><p>Render holstered shield, requires modded assets.</p></body></html> + + + Shield sheathing + + + + + + + + + + <html><head/><body><p>This setting controls third person view mode.</p><p>False: View is centered on the character's head. Crosshair is hidden. +True: In non-combat mode camera is positioned behind the character's shoulder. Crosshair is visible in third person mode as well. +</p></body></html> + + + View over the shoulder + + + + + + + <html><head/><body><p>Affects side and diagonal movement. Enabling this setting makes movement more realistic.</p><p>If disabled then the whole character's body is pointed to the direction of view. Diagonal movement has no special animation and causes sliding.</p><p>If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it also changes straight right and straight left movement.</p></body></html> + + + Turn to movement direction + + + + + + + <html><head/><body><p>If true, use paging and LOD algorithms to display the entire terrain. If false, only display terrain of the loaded cells.</p></body></html> + + + Distant land + + + + + + + <html><head/><body><p>Use object paging for active cells grid.</p></body></html> + + + Active grid object paging + + + + + + + <html><head/><body><p>This value controls the maximum visible distance (in cell units). +Larger values significantly improve rendering in exterior spaces, +but also increase the amount of rendered geometry and significantly reduce the frame rate.</p></body></html> + + + + + + Viewing distance + + + + + + + 0.0 + + + 0.5 + + + Cells + + + + + + + + + + Qt::Vertical + + + + + + + + Interface changes + + + + + + <html><head/><body><p>Show the remaining duration of magic effects and lights if this setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. </p><p>The default value is false.</p></body></html> + + + Show effect duration + + + + + + + <html><head/><body><p>Whether or not the chance of success will be displayed in the enchanting menu.</p><p>The default value is false.</p></body></html> + + + Show enchant chance + + + + + + + <html><head/><body><p>If this setting is true, melee weapons reach and speed will be shown on item tooltip.</p><p>The default value is false.</p></body></html> + + + Show melee info + + + + + + + <html><head/><body><p>If this setting is true, damage bonus of arrows and bolts will be shown on item tooltip.</p><p>The default value is false.</p></body></html> + + + Show projectile damage + + + + + + + <html><head/><body><p>If this setting is true, dialogue topics will have a different color if the topic is specific to the NPC you're talking to or the topic was previously seen. Color can be changed in settings.cfg.</p><p>The default value is false.</p></body></html> + + + Change dialogue topic color + + + + + + + <html><head/><body><p>Enable visual clues for items owned by NPCs when the crosshair is on the object.</p><p>The default value is Off.</p></body></html> + + + + + + Show owned: + + + + + + + 1 + + + + Off + + + + + Tool Tip Only + + + + + Crosshair Only + + + + + Tool Tip and Crosshair + + + + + + + + + + + Qt::Vertical + + + + + + + + Bug fixes + + + + + + <html><head/><body><p>Prevents merchants from equipping items that are sold to them.</p></body></html> + + + Merchant equipping fix + + + + + + + <html><head/><body><p>Trainers now only choose which skills to train using their base skill points, allowing mercantile improving effects to be used without making mercantile an offered skill.</p></body></html> + + + Trainers choose their training skills based on their base skill points + + + + + + + Qt::Vertical + + + + + + + + Miscellaneous + - - - - Game Mechanics - - - - - - <html><head/><body><p>If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.</p><p>If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.</p></body></html> - - - Can loot during death animation - - - - - - - <html><head/><body><p>Make player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.</p></body></html> - - - Followers attack on sight - - - - - - - <html><head/><body><p>Prevents merchants from equipping items that are sold to them.</p></body></html> - - - Prevent merchant equipping - - - - - - - <html><head/><body><p>Make the value of filled soul gems dependent only on soul magnitude.</p></body></html> - - - Rebalance soul gem values - - - - - - - <html><head/><body><p>Make enchanted weaponry without Magical flag bypass normal weapons resistance, like in Morrowind.</p></body></html> - - - Enchanted weapons are magical - - - - - - - <html><head/><body><p>Make disposition change of merchants caused by trading permanent.</p></body></html> - - - Barter disposition change is permanent - - - - - - - <html><head/><body><p>Effects of reflected Absorb spells are not mirrored -- like in Morrowind.</p></body></html> - - - Classic reflected Absorb spells behavior - - - - - - - <html><head/><body><p>Allow non-standard ammunition solely to bypass normal weapon resistance or weakness.</p></body></html> - - - Only appropriate ammunition bypasses normal weapon resistance - - - - - - - <html><head/><body><p>Factor strength into hand-to-hand damage calculations, as the MCP formula: damage * (strength / 40).</p><p>The default value is Off.</p></body></html> - - - - -1 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Factor strength into hand-to-hand combat: - - - - - - - 0 - - - - Off - - - - - Affect werewolves - - - - - Do not affect werewolves - - - - - - - - - - - <html><head/><body><p>Use casting animations for magic items, just as for spells.</p></body></html> - - - Use magic item animation - - - - - - - <html><head/><body><p>Don't use race weight in NPC movement speed calculations.</p></body></html> - - - Normalise race speed - - - - - - - <html><head/><body><p>Load per-group KF-files and skeleton files from Animations folder</p></body></html> - - - Use additional animation sources - - - - - - - - 6 - - - 20 - - - 0 - - - 0 - - - 0 - - - - - false - - - <html><head/><body><p>Render holstered weapons (with quivers and scabbards), requires modded assets.</p></body></html> - - - Weapon sheathing - - - - - - - false - - - <html><head/><body><p>Render holstered shield, requires modded assets.</p></body></html> - - - Shield sheathing - - - - - - - - - - <html><head/><body><p>Make Damage Fatigue magic effect uncapped like Drain Fatigue effect.</p><p>This means that unlike Morrowind you will be able to knock down actors using this effect.</p></body></html> - - - Uncapped Damage Fatigue - - - - - - - <html><head/><body><p>Trainers now only choose which skills to train using their base skill points, allowing mercantile improving effects to be used without making mercantile an offered skill.</p></body></html> - - - Trainers choose their training skills based on their base skill points - - - - - - - - - - Input - - - - - - <html><head/><body><p>OpenMW will capture control of the cursor if this setting is true.</p><p>In “look mode”, OpenMW will center the cursor regardless of the value of this setting (since the cursor/crosshair is always centered in the OpenMW window). However, in GUI mode, this setting determines the behavior when the cursor is moved outside the OpenMW window. If true, the cursor movement stops at the edge of the window preventing access to other applications. If false, the cursor is allowed to move freely on the desktop.</p><p>This setting does not apply to the screen where escape has been pressed, where the cursor is never captured. Regardless of this setting “Alt-Tab” or some other operating system dependent key sequence can be used to allow the operating system to regain control of the mouse cursor. This setting interacts with the minimize on focus loss setting by affecting what counts as a focus loss. Specifically on a two-screen configuration it may be more convenient to access the second screen with setting disabled.</p><p>Note for developers: it’s desirable to have this setting disabled when running the game in a debugger, to prevent the mouse cursor from becoming unusable when the game pauses on a breakpoint.</p></body></html> - - - Grab cursor - - - - - - - <html><head/><body><p>This setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. </p></body></html> - - - Toggle sneak - - - - - - @@ -295,26 +481,11 @@ - + <html><head/><body><p>This setting determines how many quicksave and autosave slots you can have at a time. If greater than 1, quicksaves will be sequentially created each time you quicksave. Once the maximum number of quicksaves has been reached, the oldest quicksave will be recycled the next time you perform a quicksave.</p></body></html> - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -335,211 +506,6 @@ - - - - Testing - - - - - - These settings are intended for testing mods and will cause issues if used for normal gameplay. - - - true - - - - - - - Qt::Horizontal - - - - - - - Skip menu and generate default character - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - Start default character at - - - - - - - default cell - - - - - - - - - Run script after startup: - - - - - - - - - - - - Browse… - - - - - - - - - - - - User Interface - - - - - - <html><head/><body><p>Show the remaining duration of magic effects and lights if this setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. </p><p>The default value is false.</p></body></html> - - - Show effect duration - - - - - - - <html><head/><body><p>Whether or not the chance of success will be displayed in the enchanting menu.</p><p>The default value is false.</p></body></html> - - - Show enchant chance - - - - - - - <html><head/><body><p>If this setting is true, melee weapons reach and speed will be shown on item tooltip.</p><p>The default value is false.</p></body></html> - - - Show melee info - - - - - - - <html><head/><body><p>If this setting is true, damage bonus of arrows and bolts will be shown on item tooltip.</p><p>The default value is false.</p></body></html> - - - Show projectile damage - - - - - - - <html><head/><body><p>If this setting is true, dialogue topics will have a different color if the topic is specific to the NPC you're talking to or the topic was previously seen. Color can be changed in settings.cfg.</p><p>The default value is false.</p></body></html> - - - Change dialogue topic color - - - - - - - <html><head/><body><p>Enable visual clues for items owned by NPCs when the crosshair is on the object.</p><p>The default value is Off.</p></body></html> - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Show owned: - - - - - - - 1 - - - - Off - - - - - Tool Tip Only - - - - - Crosshair Only - - - - - Tool Tip and Crosshair - - - - - - - - - - @@ -547,26 +513,11 @@ - + <html><head/><body><p>Specify the format for screen shots taken by pressing the screen shot key (bound to F12 by default). This setting should be the file extension commonly associated with the desired format. The formats supported will be determined at compilation, but “jpg”, “png”, and “tga” should be allowed.</p></body></html> - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -599,6 +550,110 @@ + + + + Qt::Vertical + + + + + + + + Testing + + + + + + These settings are intended for testing mods and will cause issues if used for normal gameplay. + + + true + + + + + + + Qt::Horizontal + + + + + + + <html><head/><body><p>OpenMW will capture control of the cursor if this setting is true.</p><p>In “look mode”, OpenMW will center the cursor regardless of the value of this setting (since the cursor/crosshair is always centered in the OpenMW window). However, in GUI mode, this setting determines the behavior when the cursor is moved outside the OpenMW window. If true, the cursor movement stops at the edge of the window preventing access to other applications. If false, the cursor is allowed to move freely on the desktop.</p><p>This setting does not apply to the screen where escape has been pressed, where the cursor is never captured. Regardless of this setting “Alt-Tab” or some other operating system dependent key sequence can be used to allow the operating system to regain control of the mouse cursor. This setting interacts with the minimize on focus loss setting by affecting what counts as a focus loss. Specifically on a two-screen configuration it may be more convenient to access the second screen with setting disabled.</p><p>Note for developers: it’s desirable to have this setting disabled when running the game in a debugger, to prevent the mouse cursor from becoming unusable when the game pauses on a breakpoint.</p></body></html> + + + Grab cursor + + + + + + + Skip menu and generate default character + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + + + + Start default character at + + + + + + + default cell + + + + + + + + + Run script after startup: + + + + + + + + + + + + Browse… + + + + + + + + + Qt::Vertical + + + From 1ff2256bc1899cfdd9345027568c5aff8d573fa9 Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Thu, 16 Jul 2020 16:17:25 +0200 Subject: [PATCH 016/224] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e75b20dad..6fe149c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Feature #5445: Handle NiLines Feature #5457: Realistic diagonal movement Feature #5486: Fixes trainers to choose their training skills based on their base skill points + Feature #5519: Code Patch tab in launcher Feature #5524: Resume failed script execution after reload Feature #5525: Search fields tweaks (utf-8) Task #5480: Drop Qt4 support From 71b00da289c2f3ae44ef10786dcc313815b860e5 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sat, 25 Jul 2020 21:33:52 +0300 Subject: [PATCH 017/224] Update AUTHORS with project leader history & special mention for scrawl --- AUTHORS.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 0f0522c44..b662f0abf 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -10,7 +10,10 @@ If you feel your name is missing from this list, please notify a developer. Programmers ----------- - Marc Zinnschlag (Zini) - Lead Programmer/Project Manager + Bret Curtis (psi29a) - Project leader 2019-present + Marc Zinnschlag (Zini) - Project leader 2010-2018 + Nicolay Korslund - Project leader 2008-2010 + scrawl - Top contributor Adam Hogan (aurix) Aesylwinn @@ -39,7 +42,6 @@ Programmers Austin Salgat (Salgat) Ben Shealy (bentsherman) Berulacks - Bret Curtis (psi29a) Britt Mathis (galdor557) Capostrophic Carl Maxwell @@ -146,7 +148,6 @@ Programmers Nathan Jeffords (blunted2night) NeveHanter Nialsy - Nicolay Korslund Nikolay Kasyanov (corristo) nobrakal Nolan Poe (nopoe) @@ -175,7 +176,6 @@ Programmers Roman Siromakha (elsid) Sandy Carter (bwrsandman) Scott Howard (maqifrnswa) - scrawl Sebastian Wick (swick) Sergey Fukanchik Sergey Shambir (sergey-shambir) From 224923d6c8d34f0fa1639f97c52dc1399cc36dca Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 26 Jul 2020 01:56:55 +0200 Subject: [PATCH 018/224] update appdata license and dejavufont license file --- .../mygui/{DejaVu Font License.txt => DejaVuFontLicense.txt} | 0 files/openmw.appdata.xml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename files/mygui/{DejaVu Font License.txt => DejaVuFontLicense.txt} (100%) diff --git a/files/mygui/DejaVu Font License.txt b/files/mygui/DejaVuFontLicense.txt similarity index 100% rename from files/mygui/DejaVu Font License.txt rename to files/mygui/DejaVuFontLicense.txt diff --git a/files/openmw.appdata.xml b/files/openmw.appdata.xml index edbeb1a27..f4bdb5c91 100644 --- a/files/openmw.appdata.xml +++ b/files/openmw.appdata.xml @@ -5,8 +5,8 @@ Copyright 2020 Bret Curtis --> org.openmw.launcher.desktop - CC0-1.0 - GPL-3.0 and MIT + GPL-3+ + GPL-3+ OpenMW Unofficial open source engine re-implementation of the game Morrowind From 4c9cefefdd707bb2c0c41998dbf69a9dfb3d69a0 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 30 Jun 2020 21:53:59 +0300 Subject: [PATCH 019/224] Get rid of NifOsg::CollisionSwitch --- components/nifosg/nifloader.cpp | 40 ++++++------------------------ components/sceneutil/serialize.cpp | 1 - 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 8266b5e01..04aa91a1f 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -170,31 +170,6 @@ namespace namespace NifOsg { - class CollisionSwitch : public osg::MatrixTransform - { - public: - CollisionSwitch() : osg::MatrixTransform() - { - } - - CollisionSwitch(const CollisionSwitch& copy, const osg::CopyOp& copyop) - : osg::MatrixTransform(copy, copyop) - { - } - - META_Node(NifOsg, CollisionSwitch) - - CollisionSwitch(const osg::Matrixf& transformations, bool enabled) : osg::MatrixTransform(transformations) - { - setEnabled(enabled); - } - - void setEnabled(bool enabled) - { - setNodeMask(enabled ? ~0 : Loader::getIntersectionDisabledNodeMask()); - } - }; - bool Loader::sShowMarkers = false; void Loader::setShowMarkers(bool show) @@ -501,14 +476,6 @@ namespace NifOsg case Nif::RC_NiBillboardNode: dataVariance = osg::Object::DYNAMIC; break; - case Nif::RC_NiCollisionSwitch: - { - bool enabled = nifNode->flags & Nif::NiNode::Flag_ActiveCollision; - node = new CollisionSwitch(nifNode->trafo.toMatrix(), enabled); - // This matrix transform must not be combined with another matrix transform. - dataVariance = osg::Object::DYNAMIC; - break; - } default: // The Root node can be created as a Group if no transformation is required. // This takes advantage of the fact root nodes can't have additional controllers @@ -523,6 +490,13 @@ namespace NifOsg if (!node) node = new osg::MatrixTransform(nifNode->trafo.toMatrix()); + if (nifNode->recType == Nif::RC_NiCollisionSwitch && !(nifNode->flags & Nif::NiNode::Flag_ActiveCollision)) + { + node->setNodeMask(Loader::getIntersectionDisabledNodeMask()); + // This node must not be combined with another node. + dataVariance = osg::Object::DYNAMIC; + } + node->setDataVariance(dataVariance); return node; diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index 60f096a72..f84a19876 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -131,7 +131,6 @@ void registerSerializers() "NifOsg::StaticBoundingBoxCallback", "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", - "NifOsg::CollisionSwitch", "osgMyGUI::Drawable", "osg::DrawCallback", "osgOQ::ClearQueriesCallback", From a61267f57d8c2a4ca7341f127d6f0017a0692455 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 30 Jun 2020 23:27:46 +0300 Subject: [PATCH 020/224] Replace NodeUserData with a custom transform node --- components/CMakeLists.txt | 2 +- components/nifosg/controller.cpp | 14 ++++---- components/nifosg/controller.hpp | 6 +--- components/nifosg/matrixtransform.cpp | 20 +++++++++++ components/nifosg/matrixtransform.hpp | 34 +++++++++++++++++++ components/nifosg/nifloader.cpp | 14 ++------ components/nifosg/particle.cpp | 13 +++----- components/nifosg/userdata.hpp | 48 --------------------------- components/sceneutil/clone.cpp | 11 ------ components/sceneutil/clone.hpp | 2 -- components/sceneutil/serialize.cpp | 12 ++++++- 11 files changed, 79 insertions(+), 97 deletions(-) create mode 100644 components/nifosg/matrixtransform.cpp create mode 100644 components/nifosg/matrixtransform.hpp delete mode 100644 components/nifosg/userdata.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 86d657792..4627ea2f0 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -59,7 +59,7 @@ add_component_dir (nif ) add_component_dir (nifosg - nifloader controller particle userdata + nifloader controller particle matrixtransform ) add_component_dir (nifbullet diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 3c95394a6..a4db2cba3 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -4,14 +4,13 @@ #include #include #include -#include #include #include #include -#include "userdata.hpp" +#include "matrixtransform.hpp" namespace NifOsg { @@ -119,13 +118,12 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv) { if (hasInput()) { - osg::MatrixTransform* trans = static_cast(node); + NifOsg::MatrixTransform* trans = static_cast(node); osg::Matrix mat = trans->getMatrix(); float time = getInputValue(nv); - NodeUserData* userdata = static_cast(trans->getUserDataContainer()->getUserObject(0)); - Nif::Matrix3& rot = userdata->mRotationScale; + Nif::Matrix3& rot = trans->mRotationScale; bool setRot = false; if(!mRotations.empty()) @@ -140,18 +138,18 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv) } else { - // no rotation specified, use the previous value from the UserData + // no rotation specified, use the previous value for (int i=0;i<3;++i) for (int j=0;j<3;++j) mat(j,i) = rot.mValues[i][j]; // NB column/row major difference } - if (setRot) // copy the new values back to the UserData + if (setRot) // copy the new values back for (int i=0;i<3;++i) for (int j=0;j<3;++j) rot.mValues[i][j] = mat(j,i); // NB column/row major difference - float& scale = userdata->mScale; + float& scale = trans->mScale; if(!mScales.empty()) scale = mScales.interpKey(time); diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index c81f97a71..df1086f56 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -9,11 +9,9 @@ #include #include -#include //UVController +#include -// FlipController #include -#include #include #include @@ -22,8 +20,6 @@ namespace osg { - class Node; - class StateSet; class Material; } diff --git a/components/nifosg/matrixtransform.cpp b/components/nifosg/matrixtransform.cpp new file mode 100644 index 000000000..96450313d --- /dev/null +++ b/components/nifosg/matrixtransform.cpp @@ -0,0 +1,20 @@ +#include "matrixtransform.hpp" + +namespace NifOsg +{ + MatrixTransform::MatrixTransform(int recordIndex, const Nif::Transformation &trafo) + : osg::MatrixTransform(trafo.toMatrix()) + , mIndex(recordIndex) + , mScale(trafo.scale) + , mRotationScale(trafo.rotation) + { + } + + MatrixTransform::MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op) + : osg::MatrixTransform(copy, copyop) + , mIndex(copy.mIndex) + , mScale(copy.mScale) + , mRotationScale(copy.mRotationScale) + { + } +} diff --git a/components/nifosg/matrixtransform.hpp b/components/nifosg/matrixtransform.hpp new file mode 100644 index 000000000..61d2438de --- /dev/null +++ b/components/nifosg/matrixtransform.hpp @@ -0,0 +1,34 @@ +#ifndef OPENMW_COMPONENTS_NIFOSG_MATRIXTRANSFORM_H +#define OPENMW_COMPONENTS_NIFOSG_MATRIXTRANSFORM_H + +#include + +#include + +namespace NifOsg +{ + + class MatrixTransform : public osg::MatrixTransform + { + public: + using osg::MatrixTransform::MatrixTransform; + MatrixTransform(int recordIndex, const Nif::Transformation &trafo); + MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op); + + META_Node(NifOsg, MatrixTransform) + + // NIF record index + int mIndex{0}; + + // Hack: account for Transform differences between OSG and NIFs. + // OSG uses a 4x4 matrix, NIF's use a 3x3 rotationScale, float scale, and vec3 position. + // Decomposing the original components from the 4x4 matrix isn't possible, which causes + // problems when a KeyframeController wants to change only one of these components. So + // we store the scale and rotation components separately here. + float mScale{0.f}; + Nif::Matrix3 mRotationScale; + }; + +} + +#endif diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 04aa91a1f..68e3f9a9c 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -43,8 +42,8 @@ #include #include +#include "matrixtransform.hpp" #include "particle.hpp" -#include "userdata.hpp" namespace { @@ -488,7 +487,7 @@ namespace NifOsg break; } if (!node) - node = new osg::MatrixTransform(nifNode->trafo.toMatrix()); + node = new NifOsg::MatrixTransform(nifNode->recIndex, nifNode->trafo); if (nifNode->recType == Nif::RC_NiCollisionSwitch && !(nifNode->flags & Nif::NiNode::Flag_ActiveCollision)) { @@ -523,15 +522,6 @@ namespace NifOsg if (!rootNode) rootNode = node; - // UserData used for a variety of features: - // - finding the correct emitter node for a particle system - // - establishing connections to the animated collision shapes, which are handled in a separate loader - // - finding a random child NiNode in NiBspArrayController - // - storing the previous 3x3 rotation and scale values for when a KeyframeController wants to - // change only certain elements of the 4x4 transform - node->getOrCreateUserDataContainer()->addUserObject( - new NodeUserData(nifNode->recIndex, nifNode->trafo.scale, nifNode->trafo.rotation)); - for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) { if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index f71dcdd96..7c7277118 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -11,7 +11,7 @@ #include #include -#include "userdata.hpp" +#include "matrixtransform.hpp" namespace NifOsg { @@ -381,16 +381,11 @@ void FindGroupByRecIndex::apply(osg::Geometry &node) void FindGroupByRecIndex::applyNode(osg::Node &searchNode) { - if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) + if (NifOsg::MatrixTransform* trans = dynamic_cast(&searchNode)) { - NodeUserData* holder = dynamic_cast(searchNode.getUserDataContainer()->getUserObject(0)); - if (holder && holder->mIndex == mRecIndex) + if (trans->mIndex == mRecIndex) { - osg::Group* group = searchNode.asGroup(); - if (!group) - group = searchNode.getParent(0); - - mFound = group; + mFound = trans; mFoundPath = getNodePath(); return; } diff --git a/components/nifosg/userdata.hpp b/components/nifosg/userdata.hpp deleted file mode 100644 index 42fcaff47..000000000 --- a/components/nifosg/userdata.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef OPENMW_COMPONENTS_NIFOSG_USERDATA_H -#define OPENMW_COMPONENTS_NIFOSG_USERDATA_H - -#include - -#include - -namespace NifOsg -{ - - // Note if you are copying a scene graph with this user data you should use the DEEP_COPY_USERDATA copyop. - class NodeUserData : public osg::Object - { - public: - NodeUserData(int index, float scale, const Nif::Matrix3& rotationScale) - : mIndex(index), mScale(scale), mRotationScale(rotationScale) - { - } - NodeUserData() - : mIndex(0), mScale(0) - { - } - NodeUserData(const NodeUserData& copy, const osg::CopyOp& copyop) - : Object(copy, copyop) - , mIndex(copy.mIndex) - , mScale(copy.mScale) - , mRotationScale(copy.mRotationScale) - { - } - - META_Object(NifOsg, NodeUserData) - - // NIF record index - int mIndex; - - // Hack: account for Transform differences between OSG and NIFs. - // OSG uses a 4x4 matrix, NIF's use a 3x3 rotationScale, float scale, and vec3 position. - // Decomposing the original components from the 4x4 matrix isn't possible, which causes - // problems when a KeyframeController wants to change only one of these components. So - // we store the scale and rotation components separately here. - // Note for a cleaner solution it would be possible to write a custom Transform node - float mScale; - Nif::Matrix3 mRotationScale; - }; - -} - -#endif diff --git a/components/sceneutil/clone.cpp b/components/sceneutil/clone.cpp index c3261515d..1de7bfd91 100644 --- a/components/sceneutil/clone.cpp +++ b/components/sceneutil/clone.cpp @@ -6,8 +6,6 @@ #include #include -#include - #include #include @@ -22,15 +20,6 @@ namespace SceneUtil | osg::CopyOp::DEEP_COPY_USERDATA); } - osg::Object* CopyOp::operator ()(const osg::Object* node) const - { - // We should copy node transformations when we copy node - if (dynamic_cast(node)) - return static_cast(node->clone(*this)); - - return osg::CopyOp::operator()(node); - } - osg::Node* CopyOp::operator ()(const osg::Node* node) const { if (const osgParticle::ParticleProcessor* processor = dynamic_cast(node)) diff --git a/components/sceneutil/clone.hpp b/components/sceneutil/clone.hpp index cf6d79e68..8c5fbd351 100644 --- a/components/sceneutil/clone.hpp +++ b/components/sceneutil/clone.hpp @@ -30,8 +30,6 @@ namespace SceneUtil virtual osg::Node* operator() (const osg::Node* node) const; virtual osg::Drawable* operator() (const osg::Drawable* drawable) const; - virtual osg::Object* operator ()(const osg::Object* node) const; - private: // maps new pointers to their old pointers // a little messy, but I think this should be the most efficient way diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index f84a19876..398d9cc0c 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -1,5 +1,6 @@ #include "serialize.hpp" +#include #include #include @@ -74,6 +75,15 @@ public: } }; +class MatrixTransformSerializer : public osgDB::ObjectWrapper +{ +public: + MatrixTransformSerializer() + : osgDB::ObjectWrapper(createInstanceFunc, "NifOsg::MatrixTransform", "osg::Object osg::Node osg::Transform osg::MatrixTransform NifOsg::MatrixTransform") + { + } +}; + osgDB::ObjectWrapper* makeDummySerializer(const std::string& classname) { return new osgDB::ObjectWrapper(createInstanceFunc, classname, "osg::Object"); @@ -100,6 +110,7 @@ void registerSerializers() mgr->addWrapper(new MorphGeometrySerializer); mgr->addWrapper(new LightManagerSerializer); mgr->addWrapper(new CameraRelativeTransformSerializer); + mgr->addWrapper(new MatrixTransformSerializer); // Don't serialize Geometry data as we are more interested in the overall structure rather than tons of vertex data that would make the file large and hard to read. mgr->removeWrapper(mgr->findWrapper("osg::Geometry")); @@ -118,7 +129,6 @@ void registerSerializers() "SceneUtil::StateSetUpdater", "SceneUtil::DisableLight", "SceneUtil::MWShadowTechnique", - "NifOsg::NodeUserData", "NifOsg::FlipController", "NifOsg::KeyframeController", "NifOsg::TextKeyMapHolder", From 3b55d657e56780160a64f6d08b5446a30cbbe157 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 30 Jun 2020 23:30:22 +0300 Subject: [PATCH 021/224] CopyRigVisitor: Log the number of parents in multiple parents error --- components/sceneutil/attach.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sceneutil/attach.cpp b/components/sceneutil/attach.cpp index c438e705d..2a6ec84e5 100644 --- a/components/sceneutil/attach.cpp +++ b/components/sceneutil/attach.cpp @@ -64,7 +64,7 @@ namespace SceneUtil for (const osg::ref_ptr& node : mToCopy) { if (node->getNumParents() > 1) - Log(Debug::Error) << "Error CopyRigVisitor: node has multiple parents"; + Log(Debug::Error) << "Error CopyRigVisitor: node has " << node->getNumParents() << " parents"; while (node->getNumParents()) node->getParent(0)->removeChild(node); From cc791af0f5102445bb9a5547a03c8dc4edfe25c0 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 11 Jul 2020 17:55:15 +0300 Subject: [PATCH 022/224] Serialization fixes Make sure NifOsg::MatrixTransform serialization behaves as intended Add a dummy serializer for NifOsg::UVController --- components/sceneutil/serialize.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index 398d9cc0c..1577f080f 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -1,9 +1,10 @@ #include "serialize.hpp" -#include #include #include +#include + #include #include #include @@ -79,7 +80,7 @@ class MatrixTransformSerializer : public osgDB::ObjectWrapper { public: MatrixTransformSerializer() - : osgDB::ObjectWrapper(createInstanceFunc, "NifOsg::MatrixTransform", "osg::Object osg::Node osg::Transform osg::MatrixTransform NifOsg::MatrixTransform") + : osgDB::ObjectWrapper(createInstanceFunc, "NifOsg::MatrixTransform", "osg::Object osg::Node osg::Transform osg::MatrixTransform NifOsg::MatrixTransform") { } }; @@ -141,6 +142,7 @@ void registerSerializers() "NifOsg::StaticBoundingBoxCallback", "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", + "NifOsg::UVController", "osgMyGUI::Drawable", "osg::DrawCallback", "osgOQ::ClearQueriesCallback", From ad87289d59fc84306d67fb7d106e21f672dec905 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 11 Jul 2020 20:15:13 +0300 Subject: [PATCH 023/224] Fix NifOsg::MatrixTransform constructor inheritance --- components/nifosg/matrixtransform.cpp | 5 +++++ components/nifosg/matrixtransform.hpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/components/nifosg/matrixtransform.cpp b/components/nifosg/matrixtransform.cpp index 96450313d..b61df834b 100644 --- a/components/nifosg/matrixtransform.cpp +++ b/components/nifosg/matrixtransform.cpp @@ -2,6 +2,11 @@ namespace NifOsg { + MatrixTransform::MatrixTransform() + : osg::MatrixTransform() + { + } + MatrixTransform::MatrixTransform(int recordIndex, const Nif::Transformation &trafo) : osg::MatrixTransform(trafo.toMatrix()) , mIndex(recordIndex) diff --git a/components/nifosg/matrixtransform.hpp b/components/nifosg/matrixtransform.hpp index 61d2438de..86c903491 100644 --- a/components/nifosg/matrixtransform.hpp +++ b/components/nifosg/matrixtransform.hpp @@ -11,7 +11,7 @@ namespace NifOsg class MatrixTransform : public osg::MatrixTransform { public: - using osg::MatrixTransform::MatrixTransform; + MatrixTransform(); MatrixTransform(int recordIndex, const Nif::Transformation &trafo); MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op); From f93655e803d1b611f53477872f41a37eac5a8679 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 11 Jul 2020 20:59:21 +0300 Subject: [PATCH 024/224] Encapsulate NIF transform changes in NifOsg::MatrixTransform --- components/nifosg/controller.cpp | 47 +++++++-------------------- components/nifosg/matrixtransform.cpp | 33 +++++++++++++++++++ components/nifosg/matrixtransform.hpp | 13 ++++++++ 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index a4db2cba3..203951edd 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -119,48 +119,23 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv) if (hasInput()) { NifOsg::MatrixTransform* trans = static_cast(node); - osg::Matrix mat = trans->getMatrix(); float time = getInputValue(nv); - Nif::Matrix3& rot = trans->mRotationScale; - - bool setRot = false; - if(!mRotations.empty()) - { - mat.setRotate(mRotations.interpKey(time)); - setRot = true; - } + if (!mRotations.empty()) + trans->updateRotation(mRotations.interpKey(time)); else if (!mXRotations.empty() || !mYRotations.empty() || !mZRotations.empty()) - { - mat.setRotate(getXYZRotation(time)); - setRot = true; - } - else - { - // no rotation specified, use the previous value - for (int i=0;i<3;++i) - for (int j=0;j<3;++j) - mat(j,i) = rot.mValues[i][j]; // NB column/row major difference - } + trans->updateRotation(getXYZRotation(time)); + else // no rotation specified, use the previous value + trans->applyCurrentRotation(); - if (setRot) // copy the new values back - for (int i=0;i<3;++i) - for (int j=0;j<3;++j) - rot.mValues[i][j] = mat(j,i); // NB column/row major difference + if (!mScales.empty()) + trans->updateScale(mScales.interpKey(time)); + else // no scale specified, use the previous value + trans->applyCurrentScale(); - float& scale = trans->mScale; - if(!mScales.empty()) - scale = mScales.interpKey(time); - - for (int i=0;i<3;++i) - for (int j=0;j<3;++j) - mat(i,j) *= scale; - - if(!mTranslations.empty()) - mat.setTrans(mTranslations.interpKey(time)); - - trans->setMatrix(mat); + if (!mTranslations.empty()) + trans->setTranslation(mTranslations.interpKey(time)); } traverse(node, nv); diff --git a/components/nifosg/matrixtransform.cpp b/components/nifosg/matrixtransform.cpp index b61df834b..12144b62a 100644 --- a/components/nifosg/matrixtransform.cpp +++ b/components/nifosg/matrixtransform.cpp @@ -22,4 +22,37 @@ namespace NifOsg , mRotationScale(copy.mRotationScale) { } + + void MatrixTransform::applyCurrentRotation() + { + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + _matrix(j,i) = mRotationScale.mValues[i][j]; // NB column/row major difference + } + + void MatrixTransform::applyCurrentScale() + { + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + _matrix(i,j) *= mScale; + } + + void MatrixTransform::updateRotation(const osg::Quat& rotation) + { + _matrix.setRotate(rotation); + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + mRotationScale.mValues[i][j] = _matrix(j,i); // NB column/row major difference + } + + void MatrixTransform::updateScale(const float scale) + { + mScale = scale; + applyCurrentScale(); + } + + void MatrixTransform::setTranslation(const osg::Vec3f& translation) + { + _matrix.setTrans(translation); + } } diff --git a/components/nifosg/matrixtransform.hpp b/components/nifosg/matrixtransform.hpp index 86c903491..b633efaad 100644 --- a/components/nifosg/matrixtransform.hpp +++ b/components/nifosg/matrixtransform.hpp @@ -17,9 +17,22 @@ namespace NifOsg META_Node(NifOsg, MatrixTransform) + // Apply the current NIF rotation or scale to OSG matrix. + void applyCurrentRotation(); + void applyCurrentScale(); + + // Apply the given rotation to OSG matrix directly and update NIF rotation matrix. + void updateRotation(const osg::Quat& rotation); + // Update current NIF scale and apply it to OSG matrix. + void updateScale(const float scale); + + // Apply the given translation to OSG matrix. + void setTranslation(const osg::Vec3f& translation); + // NIF record index int mIndex{0}; + private: // Hack: account for Transform differences between OSG and NIFs. // OSG uses a 4x4 matrix, NIF's use a 3x3 rotationScale, float scale, and vec3 position. // Decomposing the original components from the 4x4 matrix isn't possible, which causes From 46825e8a4d4c09d293505954ed534f2f02955e69 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 12 Jul 2020 15:34:22 +0300 Subject: [PATCH 025/224] Move NIF record index back to a separate user object This makes sure it's never erroneously optimized out. NodeIndexHolders don't need to be cloned as their record index is never supposed to be changed. --- components/nifosg/matrixtransform.cpp | 4 +-- components/nifosg/matrixtransform.hpp | 5 +--- components/nifosg/nifloader.cpp | 9 ++++++- components/nifosg/nodeindexholder.hpp | 35 +++++++++++++++++++++++++++ components/nifosg/particle.cpp | 13 +++++++--- components/sceneutil/serialize.cpp | 1 + 6 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 components/nifosg/nodeindexholder.hpp diff --git a/components/nifosg/matrixtransform.cpp b/components/nifosg/matrixtransform.cpp index 12144b62a..72e12ecf8 100644 --- a/components/nifosg/matrixtransform.cpp +++ b/components/nifosg/matrixtransform.cpp @@ -7,9 +7,8 @@ namespace NifOsg { } - MatrixTransform::MatrixTransform(int recordIndex, const Nif::Transformation &trafo) + MatrixTransform::MatrixTransform(const Nif::Transformation &trafo) : osg::MatrixTransform(trafo.toMatrix()) - , mIndex(recordIndex) , mScale(trafo.scale) , mRotationScale(trafo.rotation) { @@ -17,7 +16,6 @@ namespace NifOsg MatrixTransform::MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op) : osg::MatrixTransform(copy, copyop) - , mIndex(copy.mIndex) , mScale(copy.mScale) , mRotationScale(copy.mRotationScale) { diff --git a/components/nifosg/matrixtransform.hpp b/components/nifosg/matrixtransform.hpp index b633efaad..ac2fbb57a 100644 --- a/components/nifosg/matrixtransform.hpp +++ b/components/nifosg/matrixtransform.hpp @@ -12,7 +12,7 @@ namespace NifOsg { public: MatrixTransform(); - MatrixTransform(int recordIndex, const Nif::Transformation &trafo); + MatrixTransform(const Nif::Transformation &trafo); MatrixTransform(const MatrixTransform ©, const osg::CopyOp ©op); META_Node(NifOsg, MatrixTransform) @@ -29,9 +29,6 @@ namespace NifOsg // Apply the given translation to OSG matrix. void setTranslation(const osg::Vec3f& translation); - // NIF record index - int mIndex{0}; - private: // Hack: account for Transform differences between OSG and NIFs. // OSG uses a 4x4 matrix, NIF's use a 3x3 rotationScale, float scale, and vec3 position. diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 68e3f9a9c..f88800e36 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -43,6 +43,7 @@ #include #include "matrixtransform.hpp" +#include "nodeindexholder.hpp" #include "particle.hpp" namespace @@ -487,7 +488,7 @@ namespace NifOsg break; } if (!node) - node = new NifOsg::MatrixTransform(nifNode->recIndex, nifNode->trafo); + node = new NifOsg::MatrixTransform(nifNode->trafo); if (nifNode->recType == Nif::RC_NiCollisionSwitch && !(nifNode->flags & Nif::NiNode::Flag_ActiveCollision)) { @@ -522,6 +523,12 @@ namespace NifOsg if (!rootNode) rootNode = node; + // The original NIF record index is used for a variety of features: + // - finding the correct emitter node for a particle system + // - establishing connections to the animated collision shapes, which are handled in a separate loader + // - finding a random child NiNode in NiBspArrayController + node->getOrCreateUserDataContainer()->addUserObject(new NodeIndexHolder(nifNode->recIndex)); + for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) { if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) diff --git a/components/nifosg/nodeindexholder.hpp b/components/nifosg/nodeindexholder.hpp new file mode 100644 index 000000000..e7d4f0db3 --- /dev/null +++ b/components/nifosg/nodeindexholder.hpp @@ -0,0 +1,35 @@ +#ifndef OPENMW_COMPONENTS_NIFOSG_NODEINDEXHOLDER_H +#define OPENMW_COMPONENTS_NIFOSG_NODEINDEXHOLDER_H + +#include + +namespace NifOsg +{ + + class NodeIndexHolder : public osg::Object + { + public: + NodeIndexHolder() = default; + NodeIndexHolder(int index) + : mIndex(index) + { + } + NodeIndexHolder(const NodeIndexHolder& copy, const osg::CopyOp& copyop) + : Object(copy, copyop) + , mIndex(copy.mIndex) + { + } + + META_Object(NifOsg, NodeIndexHolder) + + int getIndex() const { return mIndex; } + + private: + + // NIF record index + int mIndex{0}; + }; + +} + +#endif diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 7c7277118..0cbc3f22b 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -11,7 +11,7 @@ #include #include -#include "matrixtransform.hpp" +#include "nodeindexholder.hpp" namespace NifOsg { @@ -381,11 +381,16 @@ void FindGroupByRecIndex::apply(osg::Geometry &node) void FindGroupByRecIndex::applyNode(osg::Node &searchNode) { - if (NifOsg::MatrixTransform* trans = dynamic_cast(&searchNode)) + if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) { - if (trans->mIndex == mRecIndex) + NodeIndexHolder* holder = dynamic_cast(searchNode.getUserDataContainer()->getUserObject(0)); + if (holder && holder->getIndex() == mRecIndex) { - mFound = trans; + osg::Group* group = searchNode.asGroup(); + if (!group) + group = searchNode.getParent(0); + + mFound = group; mFoundPath = getNodePath(); return; } diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index 1577f080f..62325186c 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -143,6 +143,7 @@ void registerSerializers() "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", "NifOsg::UVController", + "NifOsg::NodeIndexHolder", "osgMyGUI::Drawable", "osg::DrawCallback", "osgOQ::ClearQueriesCallback", From c4eb50d17fe3425dbd7e381603ef7e1b2a9d103f Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Jul 2020 11:33:34 +0300 Subject: [PATCH 026/224] Update documentation Document distant fog Make colored topic functionality documentation clearer Update the status of screenshot format tweakability --- .../source/reference/modding/settings/GUI.rst | 11 +- .../source/reference/modding/settings/fog.rst | 115 ++++++++++++++++++ .../reference/modding/settings/general.rst | 4 +- .../reference/modding/settings/index.rst | 1 + 4 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 docs/source/reference/modding/settings/fog.rst diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index bbe6b8336..349a98697 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -148,7 +148,8 @@ color topic enable :Range: True/False :Default: False -Control wether additionnal formatting will be applied to dialogs topic. See 'color topic specific' and 'color topic exhausted' for details. +This setting controls whether the topics available in the dialogue topic list are coloured according to their state. +See 'color topic specific' and 'color topic exhausted' for details. color topic specific -------------------- @@ -157,11 +158,11 @@ color topic specific :Range: 0.0 to 1.0 :Default: empty -This setting overrides the color of keywords in the dialogue topic window. +This setting overrides the colour of dialogue topics that have a response unique to the actors speaking. The value is composed of four floating point values representing the red, green, blue and alpha channels. The alpha value is currently ignored. -The color is overriden if the actor is about to give an answer that is unique to him (that is, dialogue with their object ID in the Actor field) that wasn't seen yet. +A topic response is considered unique if its Actor filter field contains the speaking actor's object ID and hasn't yet been read. color topic exhausted --------------------- @@ -170,8 +171,8 @@ color topic exhausted :Range: 0.0 to 1.0 :Default: empty -This setting overrides the color of keywords in the dialogue topic window. +This setting overrides the colour of dialogue topics which have been "exhausted" by the player. The value is composed of four floating point values representing the red, green, blue and alpha channels. The alpha value is currently ignored. -The color is overridden if the next actor responses to the topic keyword has already been seen by the player. +A topic is considered "exhausted" if the response the player is about to see has already been seen. diff --git a/docs/source/reference/modding/settings/fog.rst b/docs/source/reference/modding/settings/fog.rst new file mode 100644 index 000000000..10ab0bbe3 --- /dev/null +++ b/docs/source/reference/modding/settings/fog.rst @@ -0,0 +1,115 @@ +Fog Settings +############ + +use distant fog +--------------- + +:Type: boolean +:Range: True/False +:Default: False + +This setting overhauls the behavior of fog calculations. + +Normally the fog start and end distance are proportional to the viewing distance +and use the fog depth set in the fallback settings. + +Enabling this setting separates the fog distance from the viewing distance and fallback settings and makes fog distance +and apparent density dependent on the weather and the current location according to the settings below. + +Unfortunately specific weather-dependent fog factor and offset parameters are currently hard-coded. +They are based off the default settings of MGE XE. + ++--------------+------------+--------+ +| Weather Type | Fog Factor | Offset | ++==============+============+========+ +| Clear | 1.0 | 0.0 | ++--------------+------------+--------+ +| Cloudy | 0.9 | 0.0 | ++--------------+------------+--------+ +| Foggy | 0.2 | 0.3 | ++--------------+------------+--------+ +| Overcast | 0.7 | 0.0 | ++--------------+------------+--------+ +| Rain | 0.5 | 0.1 | ++--------------+------------+--------+ +| Thunderstorm | 0.5 | 0.2 | ++--------------+------------+--------+ +| Ashstorm | 0.2 | 0.5 | ++--------------+------------+--------+ +| Blight | 0.2 | 0.6 | ++--------------+------------+--------+ +| Snow | 0.5 | 0.4 | ++--------------+------------+--------+ +| Blizzard | 0.16 | 0.7 | ++--------------+------------+--------+ + +Non-underwater fog start and end distance are calculated like this according to these parameters:: + + fog start distance = fog factor * (base fog start distance - fog offset * base fog end distance) + fog end distance = fog factor * (1.0 - fog offset) * base fog end distance + +Underwater fog distance is used as-is. + +A negative fog start distance means that the fog starts behind the camera +so the entirety of the scene will be at least partially fogged. + +A negative fog end distance means that the fog ends behind the camera +so the entirety of the scene will be completely submerged in the fog. + +Fog end distance should be larger than the fog start distance. + +This setting and all further settings can only be configured by editing the settings configuration file. + +distant land fog start +---------------------- + +:Type: floating point +:Range: The whole range of 32-bit floating point +:Default: 16384 (2 cells) + +This is the base fog start distance used for distant fog calculations in exterior locations. + +distant land fog end +-------------------- + +:Type: floating point +:Range: The whole range of 32-bit floating point +:Default: 40960 (5 cells) + +This is the base fog end distance used for distant fog calculations in exterior locations. + +distant underwater fog start +---------------------------- + +:Type: floating point +:Range: The whole range of 32-bit floating point +:Default: -4096 + +This is the base fog start distance used for distant fog calculations in underwater locations. + +distant underwater fog end +-------------------------- + +:Type: floating point +:Range: The whole range of 32-bit floating point +:Default: 2457.6 + +This is the base fog end distance used for distant fog calculations in underwater locations. + +distant interior fog start +-------------------------- + +:Type: floating point +:Range: The whole range of 32-bit floating point +:Default: 0 + +This is the base fog start distance used for distant fog calculations in interior locations. + +distant interior fog end +------------------------ + +:Type: floating point +:Range: The whole range of 32-bit floating point +:Default: 16384 (2 cells) + +This is the base fog end distance used for distant fog calculations in interior locations. diff --git a/docs/source/reference/modding/settings/general.rst b/docs/source/reference/modding/settings/general.rst index be253d613..c885f77aa 100644 --- a/docs/source/reference/modding/settings/general.rst +++ b/docs/source/reference/modding/settings/general.rst @@ -29,7 +29,7 @@ Specify the format for screen shots taken by pressing the screen shot key (bound This setting should be the file extension commonly associated with the desired format. The formats supported will be determined at compilation, but "jpg", "png", and "tga" should be allowed. -This setting can only be configured by editing the settings configuration file. +This setting can be configured in Advanced tab of the launcher. texture mag filter ------------------ @@ -58,4 +58,4 @@ texture mipmap Set the texture mipmap type to control the method mipmaps are created. Mipmapping is a way of reducing the processing power needed during minification -by pregenerating a series of smaller textures. \ No newline at end of file +by pregenerating a series of smaller textures. diff --git a/docs/source/reference/modding/settings/index.rst b/docs/source/reference/modding/settings/index.rst index 53b097a54..a31ce0d53 100644 --- a/docs/source/reference/modding/settings/index.rst +++ b/docs/source/reference/modding/settings/index.rst @@ -41,6 +41,7 @@ The ranges included with each setting are the physically possible ranges, not re camera cells + fog map GUI HUD From 040a92c373536403ef0177e2bb9b7d46962fcf79 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sun, 26 Jul 2020 11:07:18 +0200 Subject: [PATCH 027/224] implement additem/removeitem for non-unique actors --- apps/openmw/mwclass/creature.cpp | 5 ++ apps/openmw/mwclass/creature.hpp | 2 + apps/openmw/mwclass/npc.cpp | 5 ++ apps/openmw/mwclass/npc.hpp | 2 + apps/openmw/mwmechanics/actorutil.hpp | 28 +++++++++ apps/openmw/mwscript/containerextensions.cpp | 14 +++++ apps/openmw/mwworld/class.cpp | 5 ++ apps/openmw/mwworld/class.hpp | 2 + apps/openmw/mwworld/esmstore.cpp | 65 ++++++++++++++++++++ apps/openmw/mwworld/esmstore.hpp | 5 ++ 10 files changed, 133 insertions(+) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 24f25e508..4f411ad81 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -874,6 +874,11 @@ namespace MWClass MWMechanics::setBaseAISetting(id, setting, value); } + void Creature::modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const + { + MWMechanics::modifyBaseInventory(actorId, itemId, amount); + } + float Creature::getWalkSpeed(const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 9071b9a33..2d7aa5a19 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -132,6 +132,8 @@ namespace MWClass virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; + float getWalkSpeed(const MWWorld::Ptr& ptr) const final; float getRunSpeed(const MWWorld::Ptr& ptr) const final; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index edf0709db..d4e40032d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1447,6 +1447,11 @@ namespace MWClass MWMechanics::setBaseAISetting(id, setting, value); } + void Npc::modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const + { + MWMechanics::modifyBaseInventory(actorId, itemId, amount); + } + float Npc::getWalkSpeed(const MWWorld::Ptr& ptr) const { const GMST& gmst = getGmst(); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index d92293acb..d52afcd82 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -167,6 +167,8 @@ namespace MWClass virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; + float getWalkSpeed(const MWWorld::Ptr& ptr) const final; float getRunSpeed(const MWWorld::Ptr& ptr) const final; diff --git a/apps/openmw/mwmechanics/actorutil.hpp b/apps/openmw/mwmechanics/actorutil.hpp index cb77ef3ea..275a3a814 100644 --- a/apps/openmw/mwmechanics/actorutil.hpp +++ b/apps/openmw/mwmechanics/actorutil.hpp @@ -1,6 +1,8 @@ #ifndef OPENMW_MWMECHANICS_ACTORUTIL_H #define OPENMW_MWMECHANICS_ACTORUTIL_H +#include + #include #include @@ -53,8 +55,34 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->createOverrideRecord(copy); } + template + void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) + { + ESM::NPC copy = *MWBase::Environment::get().getWorld()->getStore().get().find(actorId); + for(auto& it : copy.mInventory.mList) + { + if(Misc::StringUtils::ciEqual(it.mItem, itemId)) + { + int sign = it.mCount < 1 ? -1 : 1; + it.mCount = sign * std::max(it.mCount * sign + amount, 0); + MWBase::Environment::get().getWorld()->createOverrideRecord(copy); + return; + } + } + if(amount > 0) + { + ESM::ContItem cont; + cont.mItem = itemId; + cont.mCount = amount; + copy.mInventory.mList.push_back(cont); + MWBase::Environment::get().getWorld()->createOverrideRecord(copy); + } + } + template void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value); template void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value); + template void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount); + template void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount); } #endif diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 7116b1c9f..9ed9204ad 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -60,6 +60,13 @@ namespace MWScript || ::Misc::StringUtils::ciEqual(item, "gold_100")) item = "gold_001"; + // Explicit calls to non-unique actors affect the base record + if(!R::implicit && ptr.getClass().isActor() && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, count); + return; + } + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); // Create a Ptr for the first added item to recover the item name later MWWorld::Ptr itemPtr = *store.add (item, 1, ptr); @@ -147,6 +154,13 @@ namespace MWScript || ::Misc::StringUtils::ciEqual(item, "gold_100")) item = "gold_001"; + // Explicit calls to non-unique actors affect the base record + if(!R::implicit && ptr.getClass().isActor() && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); + return; + } + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); std::string itemName; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index b59532f2a..ad8766d06 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -522,6 +522,11 @@ namespace MWWorld throw std::runtime_error ("class does not have creature stats"); } + void Class::modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const + { + throw std::runtime_error ("class does not have an inventory store"); + } + float Class::getWalkSpeed(const Ptr& /*ptr*/) const { return 0; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index f92dc0373..e82712220 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -363,6 +363,8 @@ namespace MWWorld virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; + virtual float getWalkSpeed(const Ptr& ptr) const; virtual float getRunSpeed(const Ptr& ptr) const; diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 278b8532e..f6fccba92 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -9,6 +9,45 @@ #include #include +namespace +{ + void readRefs(const ESM::Cell& cell, std::map& refs, std::vector& readers) + { + for (size_t i = 0; i < cell.mContextList.size(); i++) + { + size_t index = cell.mContextList[i].index; + if (readers.size() <= index) + readers.resize(index + 1); + cell.restore(readers[index], i); + ESM::CellRef ref; + ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile; + bool deleted = false; + while(cell.getNextRef(readers[index], ref, deleted)) + { + if(deleted) + refs.erase(ref.mRefNum); + else if (std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum) == cell.mMovedRefs.end()) + { + Misc::StringUtils::lowerCaseInPlace(ref.mRefID); + refs[ref.mRefNum] = ref.mRefID; + } + } + } + for(const auto& it : cell.mLeasedRefs) + { + bool deleted = it.second; + if(deleted) + refs.erase(it.first.mRefNum); + else + { + ESM::CellRef ref = it.first; + Misc::StringUtils::lowerCaseInPlace(ref.mRefID); + refs[ref.mRefNum] = ref.mRefID; + } + } + } +} + namespace MWWorld { @@ -146,7 +185,33 @@ void ESMStore::setUp(bool validateRecords) mDialogs.setUp(); if (validateRecords) + { validate(); + countRecords(); + } +} + +void ESMStore::countRecords() +{ + if(!mRefCount.empty()) + return; + std::map refs; + std::vector readers; + for(auto it = mCells.intBegin(); it != mCells.intEnd(); it++) + readRefs(*it, refs, readers); + for(auto it = mCells.extBegin(); it != mCells.extEnd(); it++) + readRefs(*it, refs, readers); + for(const auto& pair : refs) + mRefCount[pair.second]++; +} + +int ESMStore::getRefCount(const std::string& id) const +{ + const std::string lowerId = Misc::StringUtils::lowerCase(id); + auto it = mRefCount.find(lowerId); + if(it == mRefCount.end()) + return 0; + return it->second; } void ESMStore::validate() diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 24364bfb1..b6c78f042 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -70,6 +70,8 @@ namespace MWWorld std::map mIds; std::map mStaticIds; + std::map mRefCount; + std::map mStores; ESM::NPC mPlayerTemplate; @@ -79,6 +81,7 @@ namespace MWWorld /// Validate entries in store after setup void validate(); + void countRecords(); public: /// \todo replace with SharedIterator typedef std::map::const_iterator iterator; @@ -252,6 +255,8 @@ namespace MWWorld // To be called when we are done with dynamic record loading void checkPlayer(); + + int getRefCount(const std::string& id) const; }; template <> From cc6e4ad2155d7c115b25ee77ea9cd302b924e745 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Jul 2020 12:17:06 +0300 Subject: [PATCH 028/224] Fix pickpocketing sneaking stance check --- apps/openmw/mwclass/npc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index edf0709db..8e46b3fc5 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -904,7 +904,7 @@ namespace MWClass } else if (!stats.getAiSequence().isInCombat()) { - if(getCreatureStats(actor).getStance(MWMechanics::CreatureStats::Stance_Sneak) || stats.getKnockedDown()) + if (stats.getKnockedDown() || MWBase::Environment::get().getMechanicsManager()->isSneaking(actor)) return std::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing // Can't talk to werewolves From 9c930e38fab2626b424d2d828a8eb027b205b03b Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 26 Jul 2020 13:02:12 +0300 Subject: [PATCH 029/224] Add option to always allow stealing from KO'd actors (feature #5545) --- CHANGELOG.md | 1 + apps/launcher/advancedpage.cpp | 2 ++ apps/openmw/mwclass/npc.cpp | 15 ++++++++++++++- docs/source/reference/modding/settings/game.rst | 14 ++++++++++++++ files/settings-default.cfg | 3 +++ files/ui/advancedpage.ui | 10 ++++++++++ 6 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fe149c7a..d4fae3d26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Feature #5519: Code Patch tab in launcher Feature #5524: Resume failed script execution after reload Feature #5525: Search fields tweaks (utf-8) + Feature #5545: Option to allow stealing from an unconscious NPC during combat Task #5480: Drop Qt4 support Task #5520: Improve cell name autocompleter implementation diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 07fe8ddd6..2dd7d07c1 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -122,6 +122,7 @@ bool Launcher::AdvancedPage::loadSettings() int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game"); if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2) unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); + loadSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); } // Visuals @@ -215,6 +216,7 @@ void Launcher::AdvancedPage::saveSettings() int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex(); if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game")) mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); + saveSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); } // Visuals diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index edf0709db..d307f5da6 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -911,6 +911,12 @@ namespace MWClass if (!getNpcStats(ptr).isWerewolf()) return std::shared_ptr(new MWWorld::ActionTalk(ptr)); } + else // In combat + { + const bool stealingInCombat = Settings::Manager::getBool ("always allow stealing from knocked out actors", "Game"); + if (stealingInCombat && stats.getKnockedDown()) + return std::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing + } // Tribunal and some mod companions oddly enough must use open action as fallback if (!getScript(ptr).empty() && ptr.getRefData().getLocals().getIntVar(getScript(ptr), "companion")) @@ -1062,7 +1068,14 @@ namespace MWClass if (customData.mNpcStats.isDead() && customData.mNpcStats.isDeathAnimationFinished()) return true; - return !customData.mNpcStats.getAiSequence().isInCombat(); + if (!customData.mNpcStats.getAiSequence().isInCombat()) + return true; + + const bool stealingInCombat = Settings::Manager::getBool ("always allow stealing from knocked out actors", "Game"); + if (stealingInCombat && customData.mNpcStats.getKnockedDown()) + return true; + + return false; } MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index 072c614d4..5291fb0ed 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -356,3 +356,17 @@ If disabled then the 3 best skills of trainers and the training limits take into If enabled then the 3 best skills of trainers and the training limits are based on the trainer base skills. This setting can be controlled in Advanced tab of the launcher. + +always allow stealing from knocked out actors +--------------------------------------------- + +:Type: boolean +:Range: True/False +:Default: False + +By Bethesda's design, in the latest released version of Morrowind pickpocketing is impossible during combat, +even if the fighting NPC is knocked out. + +This setting allows the player to steal items from fighting NPCs that were knocked out if enabled. + +This setting can be controlled in Advanced tab of the launcher. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index a9777fc42..65e72c177 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -331,6 +331,9 @@ swim upward coef = 0.0 # Make the training skills proposed by a trainer based on its base attribute instead of its modified ones trainers training skills based on base skill = false +# Make stealing items from NPCs that were knocked down possible during combat. +always allow stealing from knocked out actors = false + [General] # Anisotropy reduces distortion in textures at low angles (e.g. 0 to 16). diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index de8e3dfc0..08ffe10ce 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -154,6 +154,16 @@ + + + + <html><head/><body><p>Make stealing items from NPCs that were knocked down possible during combat.</p></body></html> + + + Always allow stealing from knocked out actors + + + From b0c433657790bbfdc2eae32df7e269345019704f Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 26 Jul 2020 22:53:46 +0200 Subject: [PATCH 030/224] update DejaVuFontLicense entry --- AUTHORS.md | 2 +- CMakeLists.txt | 6 ++---- README.md | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 0f0522c44..b6e8c2d17 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -302,4 +302,4 @@ Thanks to Kevin Ryan, for creating the icon used for the Data Files tab of the OpenMW Launcher. Thanks to DejaVu team, -for their DejaVuLGCSansMono fontface, see DejaVu Font License.txt for their license terms. +for their DejaVuLGCSansMono fontface, see DejaVuFontLicense.txt for their license terms. diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe28fd84..f57cf17fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -451,7 +451,7 @@ IF(NOT WIN32 AND NOT APPLE) ENDIF(BUILD_WIZARD) # Install licenses - INSTALL(FILES "files/mygui/DejaVu Font License.txt" DESTINATION "${LICDIR}" ) + INSTALL(FILES "files/mygui/DejaVuFontLicense.txt" DESTINATION "${LICDIR}" ) # Install icon and desktop file INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.launcher.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw") @@ -487,9 +487,7 @@ if(WIN32) INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") - INSTALL(FILES - "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" - DESTINATION ".") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/settings-default.cfg" DESTINATION "." CONFIGURATIONS Debug) INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/settings-default.cfg" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Debug) diff --git a/README.md b/README.md index 07479933e..6aa0a8515 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set. * IRC: #openmw on irc.freenode.net Font Licenses: -* DejaVuLGCSansMono.ttf: custom (see [files/mygui/DejaVu Font License.txt](https://github.com/OpenMW/openmw/blob/master/files/mygui/DejaVu%20Font%20License.txt) for more information) +* DejaVuLGCSansMono.ttf: custom (see [files/mygui/DejaVuFontLicense.txt](https://github.com/OpenMW/openmw/blob/master/files/mygui/DejaVuFontLicense.txt) for more information) Current Status -------------- From 03f0bd3df6d71c0afbaad5f7e68b3ffab5538b22 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Mon, 27 Jul 2020 00:29:35 +0300 Subject: [PATCH 031/224] Make a horrible simple water hack less horrible --- apps/openmw/mwrender/renderingmanager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d9739e844..c6ac632e1 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -372,6 +372,7 @@ namespace MWRender mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("near", mNearClip)); mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("far", mViewDistance)); + mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("simpleWater", false)); mUniformNear = mRootNode->getOrCreateStateSet()->getUniform("near"); mUniformFar = mRootNode->getOrCreateStateSet()->getUniform("far"); From 65c92b648825c9a5f62205bf01011308ef56e0ea Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 25 Jul 2020 11:03:57 +0200 Subject: [PATCH 032/224] Add alignment="Qt::AlignTop" to files/ui/graphicspage.ui --- files/ui/graphicspage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/ui/graphicspage.ui b/files/ui/graphicspage.ui index cfa2c800c..5ec72611f 100644 --- a/files/ui/graphicspage.ui +++ b/files/ui/graphicspage.ui @@ -11,7 +11,7 @@ - + 0 From 6ad20ec9c782829694214a2f5702b8c985bd31b8 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 28 Jul 2020 08:33:28 +0200 Subject: [PATCH 033/224] Mutate base records when adding/removing spells --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwclass/creature.cpp | 14 +- apps/openmw/mwclass/npc.cpp | 39 +-- apps/openmw/mwmechanics/actors.cpp | 4 - apps/openmw/mwmechanics/disease.hpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 2 +- apps/openmw/mwmechanics/spells.cpp | 260 ++++++++++-------- apps/openmw/mwmechanics/spells.hpp | 50 ++-- apps/openmw/mwworld/esmstore.cpp | 21 ++ apps/openmw/mwworld/esmstore.hpp | 10 + apps/openmw_test_suite/mwworld/test_store.cpp | 6 + components/esm/savedgame.cpp | 2 +- 12 files changed, 231 insertions(+), 181 deletions(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 01d270f82..d8fdf7e33 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -82,7 +82,7 @@ add_openmw_dir (mwclass ) add_openmw_dir (mwmechanics - mechanicsmanagerimp stat creaturestats magiceffects movement actorutil + mechanicsmanagerimp stat creaturestats magiceffects movement actorutil spelllist drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellcasting spellresistance disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 4f411ad81..15e0fa6ab 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -141,14 +141,9 @@ namespace MWClass data->mCreatureStats.setDeathAnimationFinished(isPersistent(ptr)); // spells - for (std::vector::const_iterator iter (ref->mBase->mSpells.mList.begin()); - iter!=ref->mBase->mSpells.mList.end(); ++iter) - { - if (const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(*iter)) - data->mCreatureStats.getSpells().add (spell); - else /// \todo add option to make this a fatal error message pop-up, but default to warning for vanilla compatibility - Log(Debug::Warning) << "Warning: ignoring nonexistent spell '" << *iter << "' on creature '" << ref->mBase->mId << "'"; - } + bool spellsInitialised = data->mCreatureStats.getSpells().setSpells(ref->mBase->mId); + if (!spellsInitialised) + data->mCreatureStats.getSpells().addAllToInstance(ref->mBase->mSpells.mList); // inventory bool hasInventory = hasInventoryStore(ptr); @@ -781,6 +776,9 @@ namespace MWClass CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData(); const ESM::CreatureState& creatureState = state.asCreatureState(); customData.mContainerStore->readState (creatureState.mInventory); + bool spellsInitialised = customData.mCreatureStats.getSpells().setSpells(ptr.get()->mBase->mId); + if(spellsInitialised) + customData.mCreatureStats.getSpells().clear(); customData.mCreatureStats.readState (creatureState.mCreatureStats); } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index bc29d0973..0c00d3bd1 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -158,7 +158,7 @@ namespace * * and by adding class, race, specialization bonus. */ - void autoCalculateSkills(const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr) + void autoCalculateSkills(const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr, bool spellsInitialised) { const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); @@ -235,9 +235,11 @@ namespace for (int i=0; i spells = MWMechanics::autoCalcNpcSpells(skills, attributes, race); - for (std::vector::iterator it = spells.begin(); it != spells.end(); ++it) - npcStats.getSpells().add(*it); + if (!spellsInitialised) + { + std::vector spells = MWMechanics::autoCalcNpcSpells(skills, attributes, race); + npcStats.getSpells().addAllToInstance(spells); + } } } @@ -311,6 +313,8 @@ namespace MWClass MWWorld::LiveCellRef *ref = ptr.get(); + bool spellsInitialised = data->mNpcStats.getSpells().setSpells(ref->mBase->mId); + // creature stats int gold=0; if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) @@ -351,7 +355,7 @@ namespace MWClass data->mNpcStats.setReputation(ref->mBase->mNpdt.mReputation); autoCalculateAttributes(ref->mBase, data->mNpcStats); - autoCalculateSkills(ref->mBase, data->mNpcStats, ptr); + autoCalculateSkills(ref->mBase, data->mNpcStats, ptr, spellsInitialised); data->mNpcStats.setNeedRecalcDynamicStats(true); } @@ -362,14 +366,7 @@ namespace MWClass // race powers const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); - for (std::vector::const_iterator iter (race->mPowers.mList.begin()); - iter!=race->mPowers.mList.end(); ++iter) - { - if (const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(*iter)) - data->mNpcStats.getSpells().add (spell); - else - Log(Debug::Warning) << "Warning: ignoring nonexistent race power '" << *iter << "' on NPC '" << ref->mBase->mId << "'"; - } + data->mNpcStats.getSpells().addAllToInstance(race->mPowers.mList); if (!ref->mBase->mFaction.empty()) { @@ -390,17 +387,8 @@ namespace MWClass data->mNpcStats.setAiSetting (MWMechanics::CreatureStats::AI_Alarm, ref->mBase->mAiData.mAlarm); // spells - for (std::vector::const_iterator iter (ref->mBase->mSpells.mList.begin()); - iter!=ref->mBase->mSpells.mList.end(); ++iter) - { - if (const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(*iter)) - data->mNpcStats.getSpells().add (spell); - else - { - /// \todo add option to make this a fatal error message pop-up, but default to warning for vanilla compatibility - Log(Debug::Warning) << "Warning: ignoring nonexistent spell '" << *iter << "' on NPC '" << ref->mBase->mId << "'"; - } - } + if (!spellsInitialised) + data->mNpcStats.getSpells().addAllToInstance(ref->mBase->mSpells.mList); // inventory // setting ownership is used to make the NPC auto-equip his initial equipment only, and not bartered items @@ -1326,6 +1314,9 @@ namespace MWClass const ESM::NpcState& npcState = state.asNpcState(); customData.mInventoryStore.readState (npcState.mInventory); customData.mNpcStats.readState (npcState.mNpcStats); + bool spellsInitialised = customData.mNpcStats.getSpells().setSpells(ptr.get()->mBase->mId); + if(spellsInitialised) + customData.mNpcStats.getSpells().clear(); customData.mNpcStats.readState (npcState.mCreatureStats); } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 93b0e0a89..b91b01e4a 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1973,10 +1973,6 @@ namespace MWMechanics // One case where we need this is to make sure bound items are removed upon death stats.modifyMagicEffects(MWMechanics::MagicEffects()); stats.getActiveSpells().clear(); - - if (!isPlayer) - stats.getSpells().clear(); - // Make sure spell effects are removed purgeSpellEffects(stats.getActorId()); diff --git a/apps/openmw/mwmechanics/disease.hpp b/apps/openmw/mwmechanics/disease.hpp index 0c5706775..7933c927e 100644 --- a/apps/openmw/mwmechanics/disease.hpp +++ b/apps/openmw/mwmechanics/disease.hpp @@ -40,7 +40,7 @@ namespace MWMechanics continue; float resist = 0.f; - if (spells.hasCorprusEffect(spell)) + if (Spells::hasCorprusEffect(spell)) resist = 1.f - 0.01f * (actorEffects.get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude() - actorEffects.get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude()); else if (spell->mData.mType == ESM::Spell::ST_Disease) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index fd8902b37..466a3bcc8 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -83,7 +83,7 @@ namespace MWMechanics // reset creatureStats.setLevel(player->mNpdt.mLevel); - creatureStats.getSpells().clear(); + creatureStats.getSpells().clear(true); creatureStats.modifyMagicEffects(MagicEffects()); for (int i=0; i<27; ++i) diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index ae7454f19..4bffcab9b 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -1,8 +1,10 @@ #include "spells.hpp" +#include #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -22,46 +24,41 @@ namespace MWMechanics { } - Spells::TIterator Spells::begin() const + std::map::const_iterator Spells::begin() const { return mSpells.begin(); } - Spells::TIterator Spells::end() const + std::map::const_iterator Spells::end() const { return mSpells.end(); } - const ESM::Spell* Spells::getSpell(const std::string& id) const - { - return MWBase::Environment::get().getWorld()->getStore().get().find(id); - } - void Spells::rebuildEffects() const { mEffects = MagicEffects(); mSourcedEffects.clear(); - for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) + for (const auto& iter : mSpells) { - const ESM::Spell *spell = iter->first; + const ESM::Spell *spell = iter.first; if (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight || spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse) { int i=0; - for (std::vector::const_iterator it = spell->mEffects.mList.begin(); it != spell->mEffects.mList.end(); ++it) + for (const auto& effect : spell->mEffects.mList) { - if (iter->second.mPurgedEffects.find(i) != iter->second.mPurgedEffects.end()) + if (iter.second.mPurgedEffects.find(i) != iter.second.mPurgedEffects.end()) continue; // effect was purged float random = 1.f; - if (iter->second.mEffectRands.find(i) != iter->second.mEffectRands.end()) - random = iter->second.mEffectRands.at(i); + if (iter.second.mEffectRands.find(i) != iter.second.mEffectRands.end()) + random = iter.second.mEffectRands.at(i); - float magnitude = it->mMagnMin + (it->mMagnMax - it->mMagnMin) * random; - mEffects.add (*it, magnitude); - mSourcedEffects[spell].add(MWMechanics::EffectKey(*it), magnitude); + float magnitude = effect.mMagnMin + (effect.mMagnMax - effect.mMagnMin) * random; + mEffects.add (effect, magnitude); + mSourcedEffects[spell].add(MWMechanics::EffectKey(effect), magnitude); ++i; } @@ -71,7 +68,7 @@ namespace MWMechanics bool Spells::hasSpell(const std::string &spell) const { - return hasSpell(getSpell(spell)); + return hasSpell(SpellList::getSpell(spell)); } bool Spells::hasSpell(const ESM::Spell *spell) const @@ -80,6 +77,16 @@ namespace MWMechanics } void Spells::add (const ESM::Spell* spell) + { + mSpellList->add(spell); + } + + void Spells::add (const std::string& spellId) + { + add(SpellList::getSpell(spellId)); + } + + void Spells::addSpell(const ESM::Spell* spell) { if (mSpells.find (spell)==mSpells.end()) { @@ -106,26 +113,26 @@ namespace MWMechanics } } - void Spells::add (const std::string& spellId) - { - add(getSpell(spellId)); - } - void Spells::remove (const std::string& spellId) { - const ESM::Spell* spell = getSpell(spellId); - TContainer::iterator iter = mSpells.find (spell); - - if (iter!=mSpells.end()) - { - mSpells.erase (iter); - mSpellsChanged = true; - } + const auto spell = SpellList::getSpell(spellId); + removeSpell(spell); + mSpellList->remove(spell); if (spellId==mSelectedSpell) mSelectedSpell.clear(); } + void Spells::removeSpell(const ESM::Spell* spell) + { + const auto it = mSpells.find(spell); + if(it != mSpells.end()) + { + mSpells.erase(it); + mSpellsChanged = true; + } + } + MagicEffects Spells::getMagicEffects() const { if (mSpellsChanged) { @@ -135,12 +142,19 @@ namespace MWMechanics return mEffects; } - void Spells::clear() + void Spells::removeAllSpells() { mSpells.clear(); mSpellsChanged = true; } + void Spells::clear(bool modifyBase) + { + removeAllSpells(); + if(modifyBase) + mSpellList->clear(); + } + void Spells::setSelectedSpell (const std::string& spellId) { mSelectedSpell = spellId; @@ -166,101 +180,78 @@ namespace MWMechanics return false; } - bool Spells::hasCommonDisease() const + bool Spells::hasDisease(const ESM::Spell::SpellType type) const { - for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) + for (const auto& iter : mSpells) { - const ESM::Spell *spell = iter->first; - if (spell->mData.mType == ESM::Spell::ST_Disease) + const ESM::Spell *spell = iter.first; + if (spell->mData.mType == type) return true; } return false; } + bool Spells::hasCommonDisease() const + { + return hasDisease(ESM::Spell::ST_Disease); + } + bool Spells::hasBlightDisease() const { - for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) + return hasDisease(ESM::Spell::ST_Blight); + } + + void Spells::purge(const SpellFilter& filter) + { + std::vector purged; + for (auto iter = mSpells.begin(); iter!=mSpells.end();) { const ESM::Spell *spell = iter->first; - if (spell->mData.mType == ESM::Spell::ST_Blight) - return true; + if (filter(spell)) + { + mSpells.erase(iter++); + purged.push_back(spell->mId); + mSpellsChanged = true; + } + else + ++iter; } - - return false; + if(!purged.empty()) + mSpellList->removeAll(purged); } void Spells::purgeCommonDisease() { - for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) - { - const ESM::Spell *spell = iter->first; - if (spell->mData.mType == ESM::Spell::ST_Disease) - { - mSpells.erase(iter++); - mSpellsChanged = true; - } - else - ++iter; - } + purge([](auto spell) { return spell->mData.mType == ESM::Spell::ST_Disease; }); } void Spells::purgeBlightDisease() { - for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) - { - const ESM::Spell *spell = iter->first; - if (spell->mData.mType == ESM::Spell::ST_Blight && !hasCorprusEffect(spell)) - { - mSpells.erase(iter++); - mSpellsChanged = true; - } - else - ++iter; - } + purge([](auto spell) { return spell->mData.mType == ESM::Spell::ST_Blight && !hasCorprusEffect(spell); }); } void Spells::purgeCorprusDisease() { - for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) - { - const ESM::Spell *spell = iter->first; - if (hasCorprusEffect(spell)) - { - mSpells.erase(iter++); - mSpellsChanged = true; - } - else - ++iter; - } + purge(&hasCorprusEffect); } void Spells::purgeCurses() { - for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();) - { - const ESM::Spell *spell = iter->first; - if (spell->mData.mType == ESM::Spell::ST_Curse) - { - mSpells.erase(iter++); - mSpellsChanged = true; - } - else - ++iter; - } + purge([](auto spell) { return spell->mData.mType == ESM::Spell::ST_Curse; }); } void Spells::removeEffects(const std::string &id) { if (isSpellActive(id)) { - for (TContainer::iterator spell = mSpells.begin(); spell != mSpells.end(); ++spell) + for (auto& spell : mSpells) { - if (spell->first == getSpell(id)) + if (spell.first == SpellList::getSpell(id)) { - for (long unsigned int i = 0; i != spell->first->mEffects.mList.size(); i++) + for (long unsigned int i = 0; i != spell.first->mEffects.mList.size(); i++) { - spell->second.mPurgedEffects.insert(i); + spell.second.mPurgedEffects.insert(i); } } } @@ -276,23 +267,21 @@ namespace MWMechanics mSpellsChanged = false; } - for (std::map::const_iterator it = mSourcedEffects.begin(); - it != mSourcedEffects.end(); ++it) + for (const auto& it : mSourcedEffects) { - const ESM::Spell * spell = it->first; - for (MagicEffects::Collection::const_iterator effectIt = it->second.begin(); - effectIt != it->second.end(); ++effectIt) + const ESM::Spell * spell = it.first; + for (const auto& effectIt : it.second) { - visitor.visit(effectIt->first, spell->mName, spell->mId, -1, effectIt->second.getMagnitude()); + visitor.visit(effectIt.first, spell->mName, spell->mId, -1, effectIt.second.getMagnitude()); } } } bool Spells::hasCorprusEffect(const ESM::Spell *spell) { - for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + for (const auto& effectIt : spell->mEffects.mList) { - if (effectIt->mEffectID == ESM::MagicEffect::Corprus) + if (effectIt.mEffectID == ESM::MagicEffect::Corprus) { return true; } @@ -302,14 +291,14 @@ namespace MWMechanics void Spells::purgeEffect(int effectId) { - for (TContainer::iterator spellIt = mSpells.begin(); spellIt != mSpells.end(); ++spellIt) + for (auto& spellIt : mSpells) { int i = 0; - for (std::vector::const_iterator effectIt = spellIt->first->mEffects.mList.begin(); effectIt != spellIt->first->mEffects.mList.end(); ++effectIt) + for (auto& effectIt : spellIt.first->mEffects.mList) { - if (effectIt->mEffectID == effectId) + if (effectIt.mEffectID == effectId) { - spellIt->second.mPurgedEffects.insert(i); + spellIt.second.mPurgedEffects.insert(i); mSpellsChanged = true; } ++i; @@ -319,15 +308,15 @@ namespace MWMechanics void Spells::purgeEffect(int effectId, const std::string & sourceId) { - const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get().find(sourceId); - TContainer::iterator spellIt = mSpells.find(spell); + const ESM::Spell * spell = SpellList::getSpell(sourceId); + auto spellIt = mSpells.find(spell); if (spellIt == mSpells.end()) return; int i = 0; - for (std::vector::const_iterator effectIt = spellIt->first->mEffects.mList.begin(); effectIt != spellIt->first->mEffects.mList.end(); ++effectIt) + for (auto& effectIt : spellIt->first->mEffects.mList) { - if (effectIt->mEffectID == effectId) + if (effectIt.mEffectID == effectId) { spellIt->second.mPurgedEffects.insert(i); mSpellsChanged = true; @@ -338,11 +327,8 @@ namespace MWMechanics bool Spells::canUsePower(const ESM::Spell* spell) const { - std::map::const_iterator it = mUsedPowers.find(spell); - if (it == mUsedPowers.end() || it->second + 24 <= MWBase::Environment::get().getWorld()->getTimeStamp()) - return true; - else - return false; + const auto it = mUsedPowers.find(spell); + return it == mUsedPowers.end() || it->second + 24 <= MWBase::Environment::get().getWorld()->getTimeStamp(); } void Spells::usePower(const ESM::Spell* spell) @@ -352,6 +338,8 @@ namespace MWMechanics void Spells::readState(const ESM::SpellState &state, CreatureStats* creatureStats) { + const auto& baseSpells = mSpellList->getSpells(); + for (ESM::SpellState::TContainer::const_iterator it = state.mSpells.begin(); it != state.mSpells.end(); ++it) { // Discard spells that are no longer available due to changed content files @@ -365,6 +353,13 @@ namespace MWMechanics mSelectedSpell = it->first; } } + // Add spells from the base record + for(const std::string& id : baseSpells) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(id); + if(spell) + addSpell(spell); + } for (std::map::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it) { @@ -436,17 +431,50 @@ namespace MWMechanics void Spells::writeState(ESM::SpellState &state) const { - for (TContainer::const_iterator it = mSpells.begin(); it != mSpells.end(); ++it) + const auto& baseSpells = mSpellList->getSpells(); + for (const auto& it : mSpells) { - ESM::SpellState::SpellParams params; - params.mEffectRands = it->second.mEffectRands; - params.mPurgedEffects = it->second.mPurgedEffects; - state.mSpells.insert(std::make_pair(it->first->mId, params)); + //Don't save spells stored in the base record + if(std::find(baseSpells.begin(), baseSpells.end(), it.first->mId) == baseSpells.end()) + { + ESM::SpellState::SpellParams params; + params.mEffectRands = it.second.mEffectRands; + params.mPurgedEffects = it.second.mPurgedEffects; + state.mSpells.insert(std::make_pair(it.first->mId, params)); + } } state.mSelectedSpell = mSelectedSpell; - for (std::map::const_iterator it = mUsedPowers.begin(); it != mUsedPowers.end(); ++it) - state.mUsedPowers[it->first->mId] = it->second.toEsm(); + for (const auto& it : mUsedPowers) + state.mUsedPowers[it.first->mId] = it.second.toEsm(); + } + + bool Spells::setSpells(const std::string& actorId) + { + bool result; + std::tie(mSpellList, result) = MWBase::Environment::get().getWorld()->getStore().getSpellList(actorId); + mSpellList->addListener(this); + for(const auto& id : mSpellList->getSpells()) + addSpell(SpellList::getSpell(id)); + return result; + } + + void Spells::addAllToInstance(const std::vector& spells) + { + for(const std::string& id : spells) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(id); + if(spell) + addSpell(spell); + else + Log(Debug::Warning) << "Warning: ignoring nonexistent spell '" << id << "'"; + } + } + + Spells::~Spells() + { + if(mSpellList) + mSpellList->removeListener(this); } } diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index a4a599f8b..2f4049d2e 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -1,22 +1,19 @@ #ifndef GAME_MWMECHANICS_SPELLS_H #define GAME_MWMECHANICS_SPELLS_H +#include #include #include #include +#include -#include - -#include "../mwworld/ptr.hpp" #include "../mwworld/timestamp.hpp" #include "magiceffects.hpp" - +#include "spelllist.hpp" namespace ESM { - struct Spell; - struct SpellState; } @@ -32,37 +29,36 @@ namespace MWMechanics /// diseases. It also keeps track of used powers (which can only be used every 24h). class Spells { - public: - - typedef const ESM::Spell* SpellKey; - struct SpellParams - { - std::map mEffectRands; // - std::set mPurgedEffects; // indices of purged effects - }; - - typedef std::map TContainer; - typedef TContainer::const_iterator TIterator; - - private: - TContainer mSpells; + std::shared_ptr mSpellList; + std::map mSpells; // Note: this is the spell that's about to be cast, *not* the spell selected in the GUI (which may be different) std::string mSelectedSpell; - std::map mUsedPowers; + std::map mUsedPowers; mutable bool mSpellsChanged; mutable MagicEffects mEffects; - mutable std::map mSourcedEffects; + mutable std::map mSourcedEffects; void rebuildEffects() const; - /// Get spell from ID, throws exception if not found - const ESM::Spell* getSpell(const std::string& id) const; + bool hasDisease(const ESM::Spell::SpellType type) const; + using SpellFilter = bool (*)(const ESM::Spell*); + void purge(const SpellFilter& filter); + + void addSpell(const ESM::Spell* spell); + void removeSpell(const ESM::Spell* spell); + void removeAllSpells(); + + friend class SpellList; public: + using TIterator = std::map::const_iterator; + Spells(); + ~Spells(); + static bool hasCorprusEffect(const ESM::Spell *spell); void purgeEffect(int effectId); @@ -96,7 +92,7 @@ namespace MWMechanics MagicEffects getMagicEffects() const; ///< Return sum of magic effects resulting from abilities, blights, deseases and curses. - void clear(); + void clear(bool modifyBase = false); ///< Remove all spells of al types. void setSelectedSpell (const std::string& spellId); @@ -118,6 +114,10 @@ namespace MWMechanics void readState (const ESM::SpellState& state, CreatureStats* creatureStats); void writeState (ESM::SpellState& state) const; + + bool setSpells(const std::string& id); + + void addAllToInstance(const std::vector& spells); }; } diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index f6fccba92..aea9a5e4f 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -9,6 +9,8 @@ #include #include +#include "../mwmechanics/spelllist.hpp" + namespace { void readRefs(const ESM::Cell& cell, std::map& refs, std::vector& readers) @@ -409,4 +411,23 @@ void ESMStore::validate() throw std::runtime_error ("Invalid player record (race or class unavailable"); } + std::pair, bool> ESMStore::getSpellList(const std::string& originalId) const + { + const std::string id = Misc::StringUtils::lowerCase(originalId); + auto result = mSpellListCache.find(id); + std::shared_ptr ptr; + if (result != mSpellListCache.end()) + ptr = result->second.lock(); + if (!ptr) + { + int type = find(id); + ptr = std::make_shared(id, type); + if (result != mSpellListCache.end()) + result->second = ptr; + else + mSpellListCache.insert({id, ptr}); + return {ptr, false}; + } + return {ptr, true}; + } } // end namespace diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index b6c78f042..ceb05ca80 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_MWWORLD_ESMSTORE_H #define OPENMW_MWWORLD_ESMSTORE_H +#include #include #include @@ -12,6 +13,11 @@ namespace Loading class Listener; } +namespace MWMechanics +{ + class SpellList; +} + namespace MWWorld { class ESMStore @@ -78,6 +84,8 @@ namespace MWWorld unsigned int mDynamicCount; + mutable std::map > mSpellListCache; + /// Validate entries in store after setup void validate(); @@ -257,6 +265,8 @@ namespace MWWorld void checkPlayer(); int getRefCount(const std::string& id) const; + + std::pair, bool> getSpellList(const std::string& id) const; }; template <> diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index 63e4bd6af..60f60adb3 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -8,6 +8,12 @@ #include #include "apps/openmw/mwworld/esmstore.hpp" +#include "apps/openmw/mwmechanics/spelllist.hpp" + +namespace MWMechanics +{ + SpellList::SpellList(const std::string& id, int type) : mId(id), mType(type) {} +} static Loading::Listener dummyListener; diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index 76695dbe8..4b0529703 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -4,7 +4,7 @@ #include "esmwriter.hpp" unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; -int ESM::SavedGame::sCurrentFormat = 12; +int ESM::SavedGame::sCurrentFormat = 13; void ESM::SavedGame::load (ESMReader &esm) { From e27858cfabf2e8489787e93a32595cc63b16730b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jul 2020 18:24:09 +0200 Subject: [PATCH 034/224] these were supposed to be included --- apps/openmw/mwmechanics/spelllist.cpp | 175 ++++++++++++++++++++++++++ apps/openmw/mwmechanics/spelllist.hpp | 60 +++++++++ 2 files changed, 235 insertions(+) create mode 100644 apps/openmw/mwmechanics/spelllist.cpp create mode 100644 apps/openmw/mwmechanics/spelllist.hpp diff --git a/apps/openmw/mwmechanics/spelllist.cpp b/apps/openmw/mwmechanics/spelllist.cpp new file mode 100644 index 000000000..891b28619 --- /dev/null +++ b/apps/openmw/mwmechanics/spelllist.cpp @@ -0,0 +1,175 @@ +#include "spelllist.hpp" + +#include + +#include +#include + +#include "spells.hpp" + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/esmstore.hpp" + +namespace +{ + template + const std::vector getSpellList(const std::string& id) + { + return MWBase::Environment::get().getWorld()->getStore().get().find(id)->mSpells.mList; + } + + template + bool withBaseRecord(const std::string& id, const std::function&)>& function) + { + T copy = *MWBase::Environment::get().getWorld()->getStore().get().find(id); + bool changed = function(copy.mSpells.mList); + if(changed) + MWBase::Environment::get().getWorld()->createOverrideRecord(copy); + return changed; + } +} + +namespace MWMechanics +{ + SpellList::SpellList(const std::string& id, int type) : mId(id), mType(type) {} + + bool SpellList::withBaseRecord(const std::function&)>& function) + { + switch(mType) + { + case ESM::REC_CREA: + return ::withBaseRecord(mId, function); + case ESM::REC_NPC_: + return ::withBaseRecord(mId, function); + default: + throw std::logic_error("failed to update base record for " + mId); + } + } + + const std::vector SpellList::getSpells() const + { + switch(mType) + { + case ESM::REC_CREA: + return getSpellList(mId); + case ESM::REC_NPC_: + return getSpellList(mId); + default: + throw std::logic_error("failed to get spell list for " + mId); + } + } + + const ESM::Spell* SpellList::getSpell(const std::string& id) + { + return MWBase::Environment::get().getWorld()->getStore().get().find(id); + } + + void SpellList::add (const ESM::Spell* spell) + { + auto& id = spell->mId; + bool changed = withBaseRecord([&] (auto& spells) + { + for(auto it : spells) + { + if(Misc::StringUtils::ciEqual(id, it)) + return false; + } + spells.push_back(id); + return true; + }); + if(changed) + { + for(auto listener : mListeners) + listener->addSpell(spell); + } + } + + void SpellList::remove (const ESM::Spell* spell) + { + auto& id = spell->mId; + bool changed = withBaseRecord([&] (auto& spells) + { + for(auto it = spells.begin(); it != spells.end(); it++) + { + if(Misc::StringUtils::ciEqual(id, *it)) + { + spells.erase(it); + return true; + } + } + return false; + }); + if(changed) + { + for(auto listener : mListeners) + listener->removeSpell(spell); + } + } + + void SpellList::removeAll (const std::vector& ids) + { + bool changed = withBaseRecord([&] (auto& spells) + { + const auto it = std::remove_if(spells.begin(), spells.end(), [&] (const auto& spell) + { + const auto isSpell = [&] (const auto& id) { return Misc::StringUtils::ciEqual(spell, id); }; + return ids.end() != std::find_if(ids.begin(), ids.end(), isSpell); + }); + if (it == spells.end()) + return false; + spells.erase(it, spells.end()); + return true; + }); + if(changed) + { + for(auto listener : mListeners) + { + for(auto& id : ids) + { + const auto spell = getSpell(id); + listener->removeSpell(spell); + } + } + } + } + + void SpellList::clear() + { + bool changed = withBaseRecord([] (auto& spells) + { + if(spells.empty()) + return false; + spells.clear(); + return true; + }); + if(changed) + { + for(auto listener : mListeners) + listener->removeAllSpells(); + } + } + + void SpellList::addListener(Spells* spells) + { + for(const auto ptr : mListeners) + { + if(ptr == spells) + return; + } + mListeners.push_back(spells); + } + + void SpellList::removeListener(Spells* spells) + { + for(auto it = mListeners.begin(); it != mListeners.end(); it++) + { + if(*it == spells) + { + mListeners.erase(it); + break; + } + } + } +} diff --git a/apps/openmw/mwmechanics/spelllist.hpp b/apps/openmw/mwmechanics/spelllist.hpp new file mode 100644 index 000000000..87420082f --- /dev/null +++ b/apps/openmw/mwmechanics/spelllist.hpp @@ -0,0 +1,60 @@ +#ifndef GAME_MWMECHANICS_SPELLLIST_H +#define GAME_MWMECHANICS_SPELLLIST_H + +#include +#include +#include +#include +#include + +#include + +#include "magiceffects.hpp" + +namespace ESM +{ + struct SpellState; +} + +namespace MWMechanics +{ + struct SpellParams + { + std::map mEffectRands; // + std::set mPurgedEffects; // indices of purged effects + }; + + class Spells; + + class SpellList + { + const std::string mId; + const int mType; + std::vector mListeners; + + bool withBaseRecord(const std::function&)>& function); + public: + SpellList(const std::string& id, int type); + + /// Get spell from ID, throws exception if not found + static const ESM::Spell* getSpell(const std::string& id); + + void add (const ESM::Spell* spell); + ///< Adding a spell that is already listed in *this is a no-op. + + void remove (const ESM::Spell* spell); + + void removeAll(const std::vector& spells); + + void clear(); + ///< Remove all spells of all types. + + void addListener(Spells* spells); + + void removeListener(Spells* spells); + + const std::vector getSpells() const; + }; +} + +#endif From 12ee42c6f3b636da958d7039024cdf728288af3c Mon Sep 17 00:00:00 2001 From: Frederic Chardon Date: Tue, 28 Jul 2020 20:50:49 +0000 Subject: [PATCH 035/224] Update mLastTopic before executing scripts. In case the script contains ClearInfoActor it erase not the correct topic. Other correction not linked with the bug: - reset mActorKnownTopicsFlag at the same time as mActorKnownTopics - don't call updateTopics in addResponse, it is already handled by the response callback --- CHANGELOG.md | 1 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 6 ++++-- apps/openmw/mwgui/dialogue.cpp | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4fae3d26..321eb3c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Bug #5502: Dead zone for analogue stick movement is too small Bug #5507: Sound volume is not clamped on ingame settings update Bug #5531: Actors flee using current rotation by axis x + Bug #5548: Certain exhausted topics can be highlighted again even though there's no new dialogue Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 3e0cbbad2..e3f1796a4 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -121,6 +121,7 @@ namespace MWDialogue mTalkedTo = creatureStats.hasTalkedToPlayer(); mActorKnownTopics.clear(); + mActorKnownTopicsFlag.clear(); //greeting const MWWorld::Store &dialogs = @@ -300,11 +301,11 @@ namespace MWDialogue } } + mLastTopic = topic; + executeScript (info->mResultScript, mActor); parseText (info->mResponse); - - mLastTopic = topic; } } @@ -323,6 +324,7 @@ namespace MWDialogue updateGlobals(); mActorKnownTopics.clear(); + mActorKnownTopicsFlag.clear(); const auto& dialogs = MWBase::Environment::get().getWorld()->getStore().get(); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index a674dd36e..2527da374 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -678,7 +678,6 @@ namespace MWGui { mHistoryContents.push_back(new Response(text, title, needMargin)); updateHistory(); - updateTopics(); } void DialogueWindow::addMessageBox(const std::string& text) From b39f35d805c975334d80f4c04282467bc0dff444 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 29 Jul 2020 18:43:56 +0200 Subject: [PATCH 036/224] inherit variables --- apps/openmw/mwscript/globalscripts.cpp | 9 +++++++++ apps/openmw/mwscript/globalscripts.hpp | 2 ++ apps/openmw/mwscript/locals.cpp | 27 ++++++++++++++++++-------- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index a7865f0ae..41f153b28 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -299,6 +299,15 @@ namespace MWScript return iter->second->mLocals; } + const Locals* GlobalScripts::getLocalsIfPresent (const std::string& name) const + { + std::string name2 = ::Misc::StringUtils::lowerCase (name); + auto iter = mScripts.find (name2); + if (iter==mScripts.end()) + return nullptr; + return &iter->second->mLocals; + } + void GlobalScripts::updatePtrs(const MWWorld::Ptr& base, const MWWorld::Ptr& updated) { MatchPtrVisitor visitor(base); diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index 36d89a7eb..c5c5a9a45 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -82,6 +82,8 @@ namespace MWScript ///< If the script \a name has not been added as a global script yet, it is added /// automatically, but is not set to running state. + const Locals* getLocalsIfPresent (const std::string& name) const; + void updatePtrs(const MWWorld::Ptr& base, const MWWorld::Ptr& updated); ///< Update the Ptrs stored in mTarget. Should be called after the reference has been moved to a new cell. }; diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp index 699200590..381d73ec8 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -1,4 +1,5 @@ #include "locals.hpp" +#include "globalscripts.hpp" #include #include @@ -33,15 +34,25 @@ namespace MWScript if (mInitialised) return false; - const Compiler::Locals& locals = - MWBase::Environment::get().getScriptManager()->getLocals (script.mId); + const Locals* global = MWBase::Environment::get().getScriptManager()->getGlobalScripts().getLocalsIfPresent(script.mId); + if(global) + { + mShorts = global->mShorts; + mLongs = global->mLongs; + mFloats = global->mFloats; + } + else + { + const Compiler::Locals& locals = + MWBase::Environment::get().getScriptManager()->getLocals (script.mId); - mShorts.clear(); - mShorts.resize (locals.get ('s').size(), 0); - mLongs.clear(); - mLongs.resize (locals.get ('l').size(), 0); - mFloats.clear(); - mFloats.resize (locals.get ('f').size(), 0); + mShorts.clear(); + mShorts.resize (locals.get ('s').size(), 0); + mLongs.clear(); + mLongs.resize (locals.get ('l').size(), 0); + mFloats.clear(); + mFloats.resize (locals.get ('f').size(), 0); + } mInitialised = true; return true; From 3d31d21bc2376b786eb05c99c3e594264f4593a1 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 29 Jul 2020 20:42:29 +0300 Subject: [PATCH 037/224] Don't encapsulate NIF transformation changes Currently that causes issues --- components/nifosg/controller.cpp | 47 ++++++++++++++++++++------- components/nifosg/matrixtransform.cpp | 33 ------------------- components/nifosg/matrixtransform.hpp | 13 -------- 3 files changed, 36 insertions(+), 57 deletions(-) diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 203951edd..a4db2cba3 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -119,23 +119,48 @@ void KeyframeController::operator() (osg::Node* node, osg::NodeVisitor* nv) if (hasInput()) { NifOsg::MatrixTransform* trans = static_cast(node); + osg::Matrix mat = trans->getMatrix(); float time = getInputValue(nv); - if (!mRotations.empty()) - trans->updateRotation(mRotations.interpKey(time)); + Nif::Matrix3& rot = trans->mRotationScale; + + bool setRot = false; + if(!mRotations.empty()) + { + mat.setRotate(mRotations.interpKey(time)); + setRot = true; + } else if (!mXRotations.empty() || !mYRotations.empty() || !mZRotations.empty()) - trans->updateRotation(getXYZRotation(time)); - else // no rotation specified, use the previous value - trans->applyCurrentRotation(); + { + mat.setRotate(getXYZRotation(time)); + setRot = true; + } + else + { + // no rotation specified, use the previous value + for (int i=0;i<3;++i) + for (int j=0;j<3;++j) + mat(j,i) = rot.mValues[i][j]; // NB column/row major difference + } - if (!mScales.empty()) - trans->updateScale(mScales.interpKey(time)); - else // no scale specified, use the previous value - trans->applyCurrentScale(); + if (setRot) // copy the new values back + for (int i=0;i<3;++i) + for (int j=0;j<3;++j) + rot.mValues[i][j] = mat(j,i); // NB column/row major difference - if (!mTranslations.empty()) - trans->setTranslation(mTranslations.interpKey(time)); + float& scale = trans->mScale; + if(!mScales.empty()) + scale = mScales.interpKey(time); + + for (int i=0;i<3;++i) + for (int j=0;j<3;++j) + mat(i,j) *= scale; + + if(!mTranslations.empty()) + mat.setTrans(mTranslations.interpKey(time)); + + trans->setMatrix(mat); } traverse(node, nv); diff --git a/components/nifosg/matrixtransform.cpp b/components/nifosg/matrixtransform.cpp index 72e12ecf8..bc461b9c1 100644 --- a/components/nifosg/matrixtransform.cpp +++ b/components/nifosg/matrixtransform.cpp @@ -20,37 +20,4 @@ namespace NifOsg , mRotationScale(copy.mRotationScale) { } - - void MatrixTransform::applyCurrentRotation() - { - for (int i = 0; i < 3; ++i) - for (int j = 0; j < 3; ++j) - _matrix(j,i) = mRotationScale.mValues[i][j]; // NB column/row major difference - } - - void MatrixTransform::applyCurrentScale() - { - for (int i = 0; i < 3; ++i) - for (int j = 0; j < 3; ++j) - _matrix(i,j) *= mScale; - } - - void MatrixTransform::updateRotation(const osg::Quat& rotation) - { - _matrix.setRotate(rotation); - for (int i = 0; i < 3; ++i) - for (int j = 0; j < 3; ++j) - mRotationScale.mValues[i][j] = _matrix(j,i); // NB column/row major difference - } - - void MatrixTransform::updateScale(const float scale) - { - mScale = scale; - applyCurrentScale(); - } - - void MatrixTransform::setTranslation(const osg::Vec3f& translation) - { - _matrix.setTrans(translation); - } } diff --git a/components/nifosg/matrixtransform.hpp b/components/nifosg/matrixtransform.hpp index ac2fbb57a..975f71c62 100644 --- a/components/nifosg/matrixtransform.hpp +++ b/components/nifosg/matrixtransform.hpp @@ -17,19 +17,6 @@ namespace NifOsg META_Node(NifOsg, MatrixTransform) - // Apply the current NIF rotation or scale to OSG matrix. - void applyCurrentRotation(); - void applyCurrentScale(); - - // Apply the given rotation to OSG matrix directly and update NIF rotation matrix. - void updateRotation(const osg::Quat& rotation); - // Update current NIF scale and apply it to OSG matrix. - void updateScale(const float scale); - - // Apply the given translation to OSG matrix. - void setTranslation(const osg::Vec3f& translation); - - private: // Hack: account for Transform differences between OSG and NIFs. // OSG uses a 4x4 matrix, NIF's use a 3x3 rotationScale, float scale, and vec3 position. // Decomposing the original components from the 4x4 matrix isn't possible, which causes From 9f349e8d9109dd55f4f1d79cf64a29f46aba5b36 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 30 Jul 2020 20:57:25 +0400 Subject: [PATCH 038/224] Use more C++11 in the scripting system code --- apps/openmw/mwscript/interpretercontext.cpp | 20 +++++++++----------- apps/openmw/mwscript/miscextensions.cpp | 8 ++++---- apps/openmw/mwscript/scriptmanagerimp.cpp | 11 ++++++----- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 62febb33d..f3895c8b6 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -225,15 +225,13 @@ namespace MWScript std::vector InterpreterContext::getGlobals() const { - std::vector ids; - const MWWorld::Store& globals = MWBase::Environment::get().getWorld()->getStore().get(); - for (MWWorld::Store::iterator iter = globals.begin(); iter!=globals.end(); - ++iter) + std::vector ids; + for (auto& globalVariable : globals) { - ids.push_back (iter->mId); + ids.emplace_back(globalVariable.mId); } return ids; @@ -245,22 +243,22 @@ namespace MWScript return world->getGlobalVariableType(name); } - std::string InterpreterContext::getActionBinding(const std::string& action) const + std::string InterpreterContext::getActionBinding(const std::string& targetAction) const { MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); std::vector actions = input->getActionKeySorting (); - for (std::vector::const_iterator it = actions.begin(); it != actions.end(); ++it) + for (const int action : actions) { - std::string desc = input->getActionDescription (*it); + std::string desc = input->getActionDescription (action); if(desc == "") continue; - if(desc == action) + if(desc == targetAction) { if(input->joystickLastUsed()) - return input->getActionControllerBindingName(*it); + return input->getActionControllerBindingName(action); else - return input->getActionKeyBindingName (*it); + return input->getActionKeyBindingName(action); } } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 0dd0287a7..cbacd62df 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -45,9 +45,9 @@ namespace void addToLevList(ESM::LevelledListBase* list, const std::string& itemId, int level) { - for (std::vector::iterator it = list->mList.begin(); it != list->mList.end(); ++it) + for (auto& levelItem : list->mList) { - if (it->mLevel == level && itemId == it->mId) + if (levelItem.mLevel == level && itemId == levelItem.mId) return; } @@ -563,9 +563,9 @@ namespace MWScript effects += store.getMagicEffects(); } - for (MWMechanics::MagicEffects::Collection::const_iterator it = effects.begin(); it != effects.end(); ++it) + for (const auto& effect : effects) { - if (it->first.mId == key && it->second.getModifier() > 0) + if (effect.first.mId == key && effect.second.getModifier() > 0) { runtime.push(1); return; diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 0077b7cd0..8ff768c2d 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -151,16 +151,17 @@ namespace MWScript const MWWorld::Store& scripts = mStore.get(); - for (MWWorld::Store::iterator iter = scripts.begin(); - iter != scripts.end(); ++iter) + for (auto& script : mStore.get()) + { if (!std::binary_search (mScriptBlacklist.begin(), mScriptBlacklist.end(), - Misc::StringUtils::lowerCase (iter->mId))) + Misc::StringUtils::lowerCase(script.mId))) { ++count; - if (compile (iter->mId)) + if (compile(script.mId)) ++success; } + } return std::make_pair (count, success); } @@ -195,7 +196,7 @@ namespace MWScript scanner.scan (parser); std::map::iterator iter = - mOtherLocals.insert (std::make_pair (name2, locals)).first; + mOtherLocals.emplace(name2, locals).first; return iter->second; } From 073a7f2b2db447fba66b954f91923ea9faf8a14e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Jul 2020 21:39:04 +0200 Subject: [PATCH 039/224] Comments to explain the arcane workings of Morrowind --- apps/openmw/mwmechanics/spelllist.hpp | 8 ++++++++ apps/openmw/mwworld/esmstore.hpp | 3 +++ 2 files changed, 11 insertions(+) diff --git a/apps/openmw/mwmechanics/spelllist.hpp b/apps/openmw/mwmechanics/spelllist.hpp index 87420082f..b01722fe8 100644 --- a/apps/openmw/mwmechanics/spelllist.hpp +++ b/apps/openmw/mwmechanics/spelllist.hpp @@ -26,6 +26,14 @@ namespace MWMechanics class Spells; + /// Multiple instances of the same actor share the same spell list in Morrowind. + /// The most obvious result of this is that adding a spell or ability to one instance adds it to all instances. + /// @note The original game will only update visual effects associated with any added abilities for the originally targeted actor, + /// changing cells applies the update to all actors. + /// Aside from sharing the same active spell list, changes made to this list are also written to the actor's base record. + /// Interestingly, it is not just scripted changes that are persisted to the base record. Curing one instance's disease will cure all instances. + /// @note The original game is inconsistent in persisting this example; + /// saving and loading the game might reapply the cured disease depending on which instance was cured. class SpellList { const std::string mId; diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index ceb05ca80..99db96ac1 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -264,8 +264,11 @@ namespace MWWorld // To be called when we are done with dynamic record loading void checkPlayer(); + /// @return The number of instances defined in the base files. Excludes changes from the save file. int getRefCount(const std::string& id) const; + /// Actors with the same ID share spells, abilities, etc. + /// @return The shared spell list to use for this actor and whether or not it has already been initialized. std::pair, bool> getSpellList(const std::string& id) const; }; From f5638fec1e9af682a27cd559597c7472e500ad4c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 31 Jul 2020 19:08:49 +0200 Subject: [PATCH 040/224] add a changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 321eb3c0c..6974fd46c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Bug #3676: NiParticleColorModifier isn't applied properly Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects Bug #4021: Attributes and skills are not stored as floats + Bug #4055: Local scripts don't inherit variables from their base record Bug #4623: Corprus implementation is incorrect Bug #4764: Data race in osg ParticleSystem Bug #4774: Guards are ignorant of an invisible player that tries to attack them From 58e0b34adce8dc4caf4e0c59deb5e56bc7ffaec5 Mon Sep 17 00:00:00 2001 From: descawed Date: Mon, 3 Aug 2020 22:59:08 +0000 Subject: [PATCH 041/224] Verify certificates when downloading dependencies --- CI/before_script.msvc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index dc6eb7e44..616caf3fa 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -258,10 +258,10 @@ download() { if [ -z $VERBOSE ]; then RET=0 - curl --silent --retry 10 -kLy 5 -o $FILE $URL || RET=$? + curl --silent --retry 10 -Ly 5 -o $FILE $URL || RET=$? else RET=0 - curl --retry 10 -kLy 5 -o $FILE $URL || RET=$? + curl --retry 10 -Ly 5 -o $FILE $URL || RET=$? fi if [ $RET -ne 0 ]; then From 2ed12a398dc7002d26d7177d4d5b2927dbac1a03 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Tue, 4 Aug 2020 01:46:54 +0000 Subject: [PATCH 042/224] addLineDirectivesAfterConditionalBlocks move check for npos to catch all npos --- components/shader/shadermanager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index 490c9d438..be662990b 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -34,6 +34,9 @@ namespace Shader foundPos = source.find_first_of("\n\r", foundPos); foundPos = source.find_first_not_of("\n\r", foundPos); + if (foundPos == std::string::npos) + break; + size_t lineDirectivePosition = source.rfind("#line", foundPos); int lineNumber; if (lineDirectivePosition != std::string::npos) From 4bf24a955ee822024c17f276a08c2da07f765469 Mon Sep 17 00:00:00 2001 From: Perry Hugh Date: Tue, 4 Aug 2020 06:04:59 +0000 Subject: [PATCH 043/224] Restore Gamepad Zooming --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwinput/actionmanager.cpp | 5 +++++ apps/openmw/mwinput/actionmanager.hpp | 2 +- apps/openmw/mwinput/controllermanager.cpp | 4 ++-- apps/openmw/mwworld/worldimp.cpp | 5 +++++ apps/openmw/mwworld/worldimp.hpp | 1 + 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 17e233053..9709df362 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -416,6 +416,7 @@ namespace MWBase virtual void togglePOV(bool force = false) = 0; virtual bool isFirstPerson() const = 0; + virtual bool isPreviewModeEnabled() const = 0; virtual void togglePreviewMode(bool enable) = 0; virtual bool toggleVanityMode(bool enable) = 0; virtual void allowVanityMode(bool allow) = 0; diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index ec6c5cf7f..adb5a1c8a 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -167,6 +167,11 @@ namespace MWInput mAttemptJump = false; } + + bool ActionManager::isPreviewModeEnabled() + { + return MWBase::Environment::get().getWorld()->isPreviewModeEnabled(); + } void ActionManager::resetIdleTime() { diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 7aa73f520..eceac2e94 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -54,7 +54,7 @@ namespace MWInput void setAttemptJump(bool enabled) { mAttemptJump = enabled; } - float getPreviewDelay() const { return mPreviewPOVDelay; }; + bool isPreviewModeEnabled(); private: void handleGuiArrowKey(int action); diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index b0e769cc6..c9941c836 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -89,7 +89,7 @@ namespace MWInput bool ControllerManager::update(float dt) { - mGamepadPreviewMode = mActionManager->getPreviewDelay() == 1.f; + mGamepadPreviewMode = mActionManager->isPreviewModeEnabled(); if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) { @@ -287,7 +287,7 @@ namespace MWInput } else { - if (mGamepadPreviewMode && arg.value) // Preview Mode Gamepad Zooming + if (mGamepadPreviewMode) // Preview Mode Gamepad Zooming { if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 84f50cdef..2eec9bf0e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2394,6 +2394,11 @@ namespace MWWorld { return mRendering->getCamera()->isFirstPerson(); } + + bool World::isPreviewModeEnabled() const + { + return mRendering->getCamera()->getMode() == MWRender::Camera::Mode::Preview; + } void World::togglePreviewMode(bool enable) { diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index c08206600..5eae9608e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -524,6 +524,7 @@ namespace MWWorld void togglePOV(bool force = false) override; bool isFirstPerson() const override; + bool isPreviewModeEnabled() const override; void togglePreviewMode(bool enable) override; From 02167474cfc60b837c87b0dd6cb038dcbdeb8fb0 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Tue, 4 Aug 2020 13:18:40 +0000 Subject: [PATCH 044/224] Avoid using CMake 3.18.1 for Ninja builds to see if that fixes Windows_Ninja_CS_RelWithDebInfo --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e16aefcc1..e9da9f00a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,7 +59,7 @@ variables: &cs-targets - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y + - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' --version=3.18.0 -y - choco install vswhere -y - choco install ninja -y - choco install python -y From 144a7f330f2126b9a6ccbb0f62c4843e7c9c39c5 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 4 Aug 2020 18:28:10 +0200 Subject: [PATCH 045/224] Fix a regression that meant missing spells would prevent a save from being loaded --- apps/openmw/mwmechanics/spells.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 4bffcab9b..32cd19c5b 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -455,8 +455,7 @@ namespace MWMechanics bool result; std::tie(mSpellList, result) = MWBase::Environment::get().getWorld()->getStore().getSpellList(actorId); mSpellList->addListener(this); - for(const auto& id : mSpellList->getSpells()) - addSpell(SpellList::getSpell(id)); + addAllToInstance(mSpellList->getSpells()); return result; } From ca4330f753f9a213e651b2405d75e2f53b6a2bc8 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Wed, 5 Aug 2020 00:58:39 +0200 Subject: [PATCH 046/224] Tune algorithm of "auto switch shoulder" --- apps/openmw/mwrender/viewovershoulder.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/viewovershoulder.cpp b/apps/openmw/mwrender/viewovershoulder.cpp index 39599bfea..799e34c99 100644 --- a/apps/openmw/mwrender/viewovershoulder.cpp +++ b/apps/openmw/mwrender/viewovershoulder.cpp @@ -89,17 +89,21 @@ namespace MWRender MWBase::World* world = MWBase::Environment::get().getWorld(); osg::Vec3d sideOffset = orient * osg::Vec3d(world->getHalfExtents(mCamera->getTrackingPtr()).x() - 1, 0, 0); float rayRight = world->getDistToNearestRayHit( - playerPos + sideOffset, orient * osg::Vec3d(1, 1, 0), limitToSwitchBack + 1); + playerPos + sideOffset, orient * osg::Vec3d(1, 0, 0), limitToSwitchBack + 1); float rayLeft = world->getDistToNearestRayHit( - playerPos - sideOffset, orient * osg::Vec3d(-1, 1, 0), limitToSwitchBack + 1); - float rayForward = world->getDistToNearestRayHit( - playerPos, orient * osg::Vec3d(0, 1, 0), limitToSwitchBack + 1); + playerPos - sideOffset, orient * osg::Vec3d(-1, 0, 0), limitToSwitchBack + 1); + float rayRightForward = world->getDistToNearestRayHit( + playerPos + sideOffset, orient * osg::Vec3d(1, 3, 0), limitToSwitchBack + 1); + float rayLeftForward = world->getDistToNearestRayHit( + playerPos - sideOffset, orient * osg::Vec3d(-1, 3, 0), limitToSwitchBack + 1); + float distRight = std::min(rayRight, rayRightForward); + float distLeft = std::min(rayLeft, rayLeftForward); - if (rayLeft < limitToSwitch && rayRight > limitToSwitchBack) + if (distLeft < limitToSwitch && distRight > limitToSwitchBack) mMode = Mode::RightShoulder; - else if (rayRight < limitToSwitch && rayLeft > limitToSwitchBack) + else if (distRight < limitToSwitch && distLeft > limitToSwitchBack) mMode = Mode::LeftShoulder; - else if (rayLeft > limitToSwitchBack && rayRight > limitToSwitchBack && rayForward > limitToSwitchBack) + else if (distRight > limitToSwitchBack && distLeft > limitToSwitchBack) mMode = mDefaultShoulderIsRight ? Mode::RightShoulder : Mode::LeftShoulder; } From 243638665b61a066a72a02455325fd4c67edb9c8 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Wed, 5 Aug 2020 17:09:02 +0000 Subject: [PATCH 047/224] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6ec9cf57..13f1157a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Bug #5499: Faction advance is available when requirements not met Bug #5502: Dead zone for analogue stick movement is too small Bug #5507: Sound volume is not clamped on ingame settings update + Bug #5539: Window resize breaks when going from a lower resolution to full screen resolution Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher From 8c213cbfb164497bd3ec29b656faa2f225442660 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Wed, 5 Aug 2020 22:39:48 +0300 Subject: [PATCH 048/224] Avoid optimizing animated shapes once again (regression #5565) --- components/nifosg/nifloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index f88800e36..21ae49975 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -625,8 +625,8 @@ namespace NifOsg bool isAnimated = false; handleNodeControllers(nifNode, node, animflags, isAnimated); hasAnimatedParents |= isAnimated; - // Make sure empty nodes are not optimized away so the physics system can find them. - if (isAnimated || (hasAnimatedParents && (skipMeshes || hasMarkers))) + // Make sure empty nodes and animated shapes are not optimized away so the physics system can find them. + if (isAnimated || (hasAnimatedParents && ((skipMeshes || hasMarkers) || isGeometry))) node->setDataVariance(osg::Object::DYNAMIC); // LOD and Switch nodes must be wrapped by a transform (the current node) to support transformations properly From ed3426cf2f69e1e57eef52ab07ecfec040d298de Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 25 Jul 2020 21:12:50 +0200 Subject: [PATCH 049/224] Move third person camera collision check from World::updatePlayer() to Camera::updatePosition() --- apps/openmw/mwbase/world.hpp | 7 ++++ apps/openmw/mwphysics/physicssystem.cpp | 2 +- apps/openmw/mwphysics/physicssystem.hpp | 2 +- apps/openmw/mwrender/camera.cpp | 51 +++++++++++++++++++------ apps/openmw/mwrender/camera.hpp | 5 +-- apps/openmw/mwworld/worldimp.cpp | 31 --------------- apps/openmw/mwworld/worldimp.hpp | 2 + 7 files changed, 52 insertions(+), 48 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 9709df362..f5a8ae5b5 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -51,6 +51,11 @@ namespace ESM struct TimeStamp; } +namespace MWPhysics +{ + class PhysicsSystem; +} + namespace MWRender { class Animation; @@ -115,6 +120,8 @@ namespace MWBase virtual void readRecord (ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) = 0; + virtual const MWPhysics::PhysicsSystem* getPhysics() const = 0; + virtual MWWorld::CellStore *getExterior (int x, int y) = 0; virtual MWWorld::CellStore *getInterior (const std::string& name) = 0; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index d423830b1..133e0aeb0 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -311,7 +311,7 @@ namespace MWPhysics return result; } - PhysicsSystem::RayResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius) + PhysicsSystem::RayResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius) const { btCollisionWorld::ClosestConvexResultCallback callback(Misc::Convert::toBullet(from), Misc::Convert::toBullet(to)); callback.m_collisionFilterGroup = 0xff; diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 32d460b1d..c2a74cbd8 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -123,7 +123,7 @@ namespace MWPhysics std::vector targets = std::vector(), int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const; - RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius); + RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const; /// Return true if actor1 can see actor2. bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const; diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 328e53a79..47ef1f299 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -7,6 +7,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/ptr.hpp" @@ -16,6 +17,8 @@ #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwphysics/physicssystem.hpp" + #include "npcanimation.hpp" namespace @@ -195,6 +198,7 @@ namespace MWRender rotateCamera(0.f, osg::DegreesToRadians(3.f * duration), true); updateFocalPointOffset(duration); + updatePosition(); float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr); speed /= (1.f + speed / 500.f); @@ -205,6 +209,42 @@ namespace MWRender updateStandingPreviewMode(); } + void Camera::updatePosition() + { + mFocalPointAdjustment = osg::Vec3d(); + if (isFirstPerson()) + return; + + const float cameraObstacleLimit = 5.0f; + const float focalObstacleLimit = 10.f; + + const MWPhysics::PhysicsSystem* physics = MWBase::Environment::get().getWorld()->getPhysics(); + + // Adjust focal point to prevent clipping. + osg::Vec3d focal = getFocalPoint(); + osg::Vec3d focalOffset = getFocalPointOffset(); + float offsetLen = focalOffset.length(); + if (offsetLen > 0) + { + MWPhysics::PhysicsSystem::RayResult result = physics->castSphere(focal - focalOffset, focal, focalObstacleLimit); + if (result.mHit) + { + double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen; + mFocalPointAdjustment = focalOffset * std::max(-1.0, adjustmentCoef); + } + } + + // Calculate camera distance. + mCameraDistance = mBaseCameraDistance + getCameraDistanceCorrection(); + if (mDynamicCameraDistanceEnabled) + mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance); + osg::Vec3d cameraPos; + getPosition(focal, cameraPos); + MWPhysics::PhysicsSystem::RayResult result = physics->castSphere(focal, cameraPos, cameraObstacleLimit); + if (result.mHit) + mCameraDistance = (result.mHitPos + result.mHitNormal * cameraObstacleLimit - focal).length(); + } + void Camera::updateStandingPreviewMode() { if (!mStandingPreviewAllowed) @@ -389,7 +429,6 @@ namespace MWRender mIsNearest = dist <= mNearest; mBaseCameraDistance = osg::clampBetween(dist, mNearest, mFurthest); Settings::Manager::setFloat("third person camera distance", "Camera", mBaseCameraDistance); - setCameraDistance(); } void Camera::setCameraDistance(float dist, bool adjust) @@ -414,16 +453,6 @@ namespace MWRender return pitchCorrection + speedCorrection; } - void Camera::setCameraDistance() - { - mFocalPointAdjustment = osg::Vec3d(); - if (isFirstPerson()) - return; - mCameraDistance = mBaseCameraDistance + getCameraDistanceCorrection(); - if (mDynamicCameraDistanceEnabled) - mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance); - } - void Camera::setAnimation(NpcAnimation *anim) { mAnimation = anim; diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index f2e5c390d..bf54be715 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -73,6 +73,7 @@ namespace MWRender bool mShowCrosshairInThirdPersonMode; void updateFocalPointOffset(float duration); + void updatePosition(); float getCameraDistanceCorrection() const; osg::ref_ptr mUpdateCallback; @@ -144,16 +145,12 @@ namespace MWRender /// Default distance can be restored with setCameraDistance(). void setCameraDistance(float dist, bool adjust = false); - /// Restore default camera distance and offset for current mode. - void setCameraDistance(); - float getCameraDistance() const; void setAnimation(NpcAnimation *anim); osg::Vec3d getFocalPoint() const; osg::Vec3d getFocalPointOffset() const; - void adjustFocalPoint(osg::Vec3d adjustment) { mFocalPointAdjustment = adjustment; } /// Stores focal and camera world positions in passed arguments void getPosition(osg::Vec3d &focal, osg::Vec3d &camera) const; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2eec9bf0e..c111abc43 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1863,37 +1863,6 @@ namespace MWWorld int nightEye = static_cast(player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).getMagnitude()); mRendering->setNightEyeFactor(std::min(1.f, (nightEye/100.f))); - - auto* camera = mRendering->getCamera(); - camera->setCameraDistance(); - if(!mRendering->getCamera()->isFirstPerson()) - { - float cameraObstacleLimit = mRendering->getNearClipDistance() * 2.5f; - float focalObstacleLimit = std::max(cameraObstacleLimit, 10.0f); - - // Adjust focal point. - osg::Vec3d focal = camera->getFocalPoint(); - osg::Vec3d focalOffset = camera->getFocalPointOffset(); - float offsetLen = focalOffset.length(); - if (offsetLen > 0) - { - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castSphere(focal - focalOffset, focal, focalObstacleLimit); - if (result.mHit) - { - double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen; - if (adjustmentCoef < -1) - adjustmentCoef = -1; - camera->adjustFocalPoint(focalOffset * adjustmentCoef); - } - } - - // Adjust camera position. - osg::Vec3d cameraPos; - camera->getPosition(focal, cameraPos); - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castSphere(focal, cameraPos, cameraObstacleLimit); - if (result.mHit) - mRendering->getCamera()->setCameraDistance((result.mHitPos + result.mHitNormal * cameraObstacleLimit - focal).length(), false); - } } void World::preloadSpells() diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 5eae9608e..ade6c4a62 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -214,6 +214,8 @@ namespace MWWorld void readRecord (ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) override; + const MWPhysics::PhysicsSystem* getPhysics() const override { return mPhysics.get(); } + CellStore *getExterior (int x, int y) override; CellStore *getInterior (const std::string& name) override; From 694e0b5906dde97ea624cfc6e0397a4e1ec801bd Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 25 Jul 2020 22:42:58 +0200 Subject: [PATCH 050/224] Refactoring. Simplification of camera interface. --- apps/openmw/mwbase/world.hpp | 3 +-- apps/openmw/mwinput/actionmanager.cpp | 26 +++++++++--------- apps/openmw/mwinput/controllermanager.cpp | 9 +++---- apps/openmw/mwinput/mousemanager.cpp | 12 +++------ apps/openmw/mwrender/camera.cpp | 32 +++++++++++------------ apps/openmw/mwrender/camera.hpp | 10 ++----- apps/openmw/mwrender/renderingmanager.cpp | 27 ------------------- apps/openmw/mwrender/renderingmanager.hpp | 2 -- apps/openmw/mwworld/worldimp.cpp | 9 ++----- apps/openmw/mwworld/worldimp.hpp | 5 +--- 10 files changed, 42 insertions(+), 93 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f5a8ae5b5..1c63d982f 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -427,9 +427,8 @@ namespace MWBase virtual void togglePreviewMode(bool enable) = 0; virtual bool toggleVanityMode(bool enable) = 0; virtual void allowVanityMode(bool allow) = 0; - virtual void changeVanityModeScale(float factor) = 0; virtual bool vanityRotateCamera(float * rot) = 0; - virtual void setCameraDistance(float dist, bool adjust = false, bool override = true)=0; + virtual void adjustCameraDistance(float dist) = 0; virtual void applyDeferredPreviewRotationToPlayer(float dt) = 0; virtual void disableDeferredPreviewRotation() = 0; diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index adb5a1c8a..d2430a612 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -26,7 +26,7 @@ namespace MWInput { - const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out + const float ZOOM_SCALE = 10.f; /// Used for scrolling camera in and out ActionManager::ActionManager(BindingsManager* bindingsManager, osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, @@ -195,6 +195,8 @@ namespace MWInput void ActionManager::executeAction(int action) { + auto* inputManager = MWBase::Environment::get().getInputManager(); + auto* windowManager = MWBase::Environment::get().getWindowManager(); // trigger action activated switch (action) { @@ -211,7 +213,7 @@ namespace MWInput toggleConsole (); break; case A_Activate: - MWBase::Environment::get().getInputManager()->resetIdleTime(); + inputManager->resetIdleTime(); activate(); break; case A_MoveLeft: @@ -272,18 +274,18 @@ namespace MWInput showQuickKeysMenu(); break; case A_ToggleHUD: - MWBase::Environment::get().getWindowManager()->toggleHud(); + windowManager->toggleHud(); break; case A_ToggleDebug: - MWBase::Environment::get().getWindowManager()->toggleDebugWindow(); + windowManager->toggleDebugWindow(); break; case A_ZoomIn: - if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch") && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") && !MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->setCameraDistance(ZOOM_SCALE, true, true); + if (inputManager->getControlSwitch("playerviewswitch") && inputManager->getControlSwitch("playercontrols") && !windowManager->isGuiMode()) + MWBase::Environment::get().getWorld()->adjustCameraDistance(-ZOOM_SCALE); break; case A_ZoomOut: - if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch") && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") && !MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->setCameraDistance(-ZOOM_SCALE, true, true); + if (inputManager->getControlSwitch("playerviewswitch") && inputManager->getControlSwitch("playercontrols") && !windowManager->isGuiMode()) + MWBase::Environment::get().getWorld()->adjustCameraDistance(ZOOM_SCALE); break; case A_QuickSave: quickSave(); @@ -292,19 +294,19 @@ namespace MWInput quickLoad(); break; case A_CycleSpellLeft: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic)) + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) MWBase::Environment::get().getWindowManager()->cycleSpell(false); break; case A_CycleSpellRight: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic)) + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) MWBase::Environment::get().getWindowManager()->cycleSpell(true); break; case A_CycleWeaponLeft: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) MWBase::Environment::get().getWindowManager()->cycleWeapon(false); break; case A_CycleWeaponRight: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) MWBase::Environment::get().getWindowManager()->cycleWeapon(true); break; case A_Sneak: diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index c9941c836..48091541c 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -190,10 +190,7 @@ namespace MWInput mGamepadZoom = 0; if (mGamepadZoom) - { - MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom); - MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true); - } + MWBase::Environment::get().getWorld()->adjustCameraDistance(-mGamepadZoom); } return triedToMove; @@ -291,12 +288,12 @@ namespace MWInput { if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { - mGamepadZoom = arg.value * 0.85f / 1000.f; + mGamepadZoom = arg.value * 0.85f / 1000.f / 12.f; return; // Do not propagate event. } else if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) { - mGamepadZoom = -arg.value * 0.85f / 1000.f; + mGamepadZoom = -arg.value * 0.85f / 1000.f / 12.f; return; // Do not propagate event. } } diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index 84ab091c5..a3f436bfe 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -70,6 +70,7 @@ namespace MWInput mBindingsManager->mouseMoved(arg); MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); + MWBase::World* world = MWBase::Environment::get().getWorld(); input->setJoystickLastUsed(false); input->resetIdleTime(); @@ -102,19 +103,14 @@ namespace MWInput rot[2] = -x; // Only actually turn player when we're not in vanity mode - if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking")) + if (!world->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking")) { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + MWWorld::Player& player = world->getPlayer(); player.yaw(x); player.pitch(y); } else if (!input->getControlSwitch("playerlooking")) - MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation(); - - if (arg.zrel && input->getControlSwitch("playerviewswitch") && input->getControlSwitch("playercontrols")) //Check to make sure you are allowed to zoomout and there is a change - { - MWBase::Environment::get().getWorld()->changeVanityModeScale(static_cast(arg.zrel)); - } + world->disableDeferredPreviewRotation(); } } diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 47ef1f299..3b0ceb148 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -418,28 +418,26 @@ namespace MWRender return mCameraDistance; } - void Camera::updateBaseCameraDistance(float dist, bool adjust) + void Camera::adjustCameraDistance(float delta) { - if (isFirstPerson()) - return; + if (!isFirstPerson()) + { + if(isNearest() && delta < 0.f && getMode() != Mode::Preview && getMode() != Mode::Vanity) + toggleViewMode(); + else + mBaseCameraDistance = std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance) + delta; + } + else if (delta > 0.f) + { + toggleViewMode(); + mBaseCameraDistance = 0; + } - if (adjust) - dist += std::min(mCameraDistance - getCameraDistanceCorrection(), mBaseCameraDistance); - - mIsNearest = dist <= mNearest; - mBaseCameraDistance = osg::clampBetween(dist, mNearest, mFurthest); + mIsNearest = mBaseCameraDistance <= mNearest; + mBaseCameraDistance = osg::clampBetween(mBaseCameraDistance, mNearest, mFurthest); Settings::Manager::setFloat("third person camera distance", "Camera", mBaseCameraDistance); } - void Camera::setCameraDistance(float dist, bool adjust) - { - if (isFirstPerson()) - return; - if (adjust) - dist += mCameraDistance; - mCameraDistance = osg::clampBetween(dist, 10.f, mFurthest); - } - float Camera::getCameraDistanceCorrection() const { if (!mDynamicCameraDistanceEnabled) diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index bf54be715..b3f6026eb 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -136,14 +136,8 @@ namespace MWRender void update(float duration, bool paused=false); - /// Set base camera distance for current mode. Don't work on 1st person view. - /// \param adjust Indicates should distance be adjusted or set. - void updateBaseCameraDistance(float dist, bool adjust = false); - - /// Set camera distance for current mode. Don't work on 1st person view. - /// \param adjust Indicates should distance be adjusted or set. - /// Default distance can be restored with setCameraDistance(). - void setCameraDistance(float dist, bool adjust = false); + /// Adds distDelta to the camera distance. Switches 3rd/1st person view if distance is less than limit. + void adjustCameraDistance(float distDelta); float getCameraDistance() const; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c6ac632e1..0d75325d8 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1325,27 +1325,6 @@ namespace MWRender return true; } - void RenderingManager::setCameraDistance(float dist, bool adjust, bool override) - { - if(!mCamera->isVanityOrPreviewModeEnabled() && !mCamera->isFirstPerson()) - { - if(mCamera->isNearest() && dist > 0.f) - mCamera->toggleViewMode(); - else if (override) - mCamera->updateBaseCameraDistance(-dist / 120.f * 10, adjust); - else - mCamera->setCameraDistance(-dist / 120.f * 10, adjust); - } - else if(mCamera->isFirstPerson() && dist < 0.f) - { - mCamera->toggleViewMode(); - if (override) - mCamera->updateBaseCameraDistance(0.f, false); - else - mCamera->setCameraDistance(0.f, false); - } - } - void RenderingManager::resetCamera() { mCamera->reset(); @@ -1386,12 +1365,6 @@ namespace MWRender mCamera->allowVanityMode(allow); } - void RenderingManager::changeVanityModeScale(float factor) - { - if(mCamera->isVanityOrPreviewModeEnabled()) - mCamera->updateBaseCameraDistance(-factor/120.f*10, true); - } - void RenderingManager::overrideFieldOfView(float val) { if (mFieldOfViewOverridden != true || mFieldOfViewOverride != val) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index d6a0f89c3..c0b8f4293 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -210,7 +210,6 @@ namespace MWRender // camera stuff bool vanityRotateCamera(const float *rot); - void setCameraDistance(float dist, bool adjust, bool override); void resetCamera(); float getCameraDistance() const; Camera* getCamera(); @@ -219,7 +218,6 @@ namespace MWRender void togglePreviewMode(bool enable); bool toggleVanityMode(bool enable); void allowVanityMode(bool allow); - void changeVanityModeScale(float factor); /// temporarily override the field of view with given value. void overrideFieldOfView(float val); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c111abc43..b617183b9 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2394,19 +2394,14 @@ namespace MWWorld mRendering->allowVanityMode(allow); } - void World::changeVanityModeScale(float factor) - { - mRendering->changeVanityModeScale(factor); - } - bool World::vanityRotateCamera(float * rot) { return mRendering->vanityRotateCamera(rot); } - void World::setCameraDistance(float dist, bool adjust, bool override_) + void World::adjustCameraDistance(float dist) { - mRendering->setCameraDistance(dist, adjust, override_); + mRendering->getCamera()->adjustCameraDistance(dist); } void World::setupPlayer() diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index ade6c4a62..512c6ede3 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -533,11 +533,8 @@ namespace MWWorld bool toggleVanityMode(bool enable) override; void allowVanityMode(bool allow) override; - - void changeVanityModeScale(float factor) override; - bool vanityRotateCamera(float * rot) override; - void setCameraDistance(float dist, bool adjust = false, bool override = true) override; + void adjustCameraDistance(float dist) override; void applyDeferredPreviewRotationToPlayer(float dt) override; void disableDeferredPreviewRotation() override; From e9b2e9b4740de737b26a8d1be26c35c1b8dde3e3 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 25 Jul 2020 23:33:50 +0200 Subject: [PATCH 051/224] Remove camera stuff from RenderingManager --- apps/openmw/mwrender/renderingmanager.cpp | 49 ----------------------- apps/openmw/mwrender/renderingmanager.hpp | 11 +---- apps/openmw/mwworld/worldimp.cpp | 18 +++++---- 3 files changed, 13 insertions(+), 65 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 0d75325d8..5c79a4d26 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1316,55 +1316,6 @@ namespace MWRender return mTerrain->getHeightAt(pos); } - bool RenderingManager::vanityRotateCamera(const float *rot) - { - if(!mCamera->isVanityOrPreviewModeEnabled()) - return false; - - mCamera->rotateCamera(rot[0], rot[2], true); - return true; - } - - void RenderingManager::resetCamera() - { - mCamera->reset(); - } - - float RenderingManager::getCameraDistance() const - { - return mCamera->getCameraDistance(); - } - - Camera* RenderingManager::getCamera() - { - return mCamera.get(); - } - - const osg::Vec3f &RenderingManager::getCameraPosition() const - { - return mCurrentCameraPos; - } - - void RenderingManager::togglePOV(bool force) - { - mCamera->toggleViewMode(force); - } - - void RenderingManager::togglePreviewMode(bool enable) - { - mCamera->togglePreviewMode(enable); - } - - bool RenderingManager::toggleVanityMode(bool enable) - { - return mCamera->toggleVanityMode(enable); - } - - void RenderingManager::allowVanityMode(bool allow) - { - mCamera->allowVanityMode(allow); - } - void RenderingManager::overrideFieldOfView(float val) { if (mFieldOfViewOverridden != true || mFieldOfViewOverride != val) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index c0b8f4293..1f6f25ace 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -209,15 +209,8 @@ namespace MWRender float getTerrainHeightAt(const osg::Vec3f& pos); // camera stuff - bool vanityRotateCamera(const float *rot); - void resetCamera(); - float getCameraDistance() const; - Camera* getCamera(); - const osg::Vec3f& getCameraPosition() const; - void togglePOV(bool force = false); - void togglePreviewMode(bool enable); - bool toggleVanityMode(bool enable); - void allowVanityMode(bool allow); + Camera* getCamera() { return mCamera.get(); } + const osg::Vec3f& getCameraPosition() const { return mCurrentCameraPos; } /// temporarily override the field of view with given value. void overrideFieldOfView(float val); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index b617183b9..50242d7bd 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -225,7 +225,7 @@ namespace MWWorld setupPlayer(); renderPlayer(); - mRendering->resetCamera(); + mRendering->getCamera()->reset(); // we don't want old weather to persist on a new game // Note that if reset later, the initial ChangeWeather that the chargen script calls will be lost. @@ -1953,7 +1953,7 @@ namespace MWWorld MWWorld::Ptr World::getFacedObject(float maxDistance, bool ignorePlayer) { - const float camDist = mRendering->getCameraDistance(); + const float camDist = mRendering->getCamera()->getCameraDistance(); maxDistance += camDist; MWWorld::Ptr facedObject; MWRender::RenderingManager::RayResult rayToObject; @@ -2356,7 +2356,7 @@ namespace MWWorld void World::togglePOV(bool force) { - mRendering->togglePOV(force); + mRendering->getCamera()->toggleViewMode(force); } bool World::isFirstPerson() const @@ -2371,12 +2371,12 @@ namespace MWWorld void World::togglePreviewMode(bool enable) { - mRendering->togglePreviewMode(enable); + mRendering->getCamera()->togglePreviewMode(enable); } bool World::toggleVanityMode(bool enable) { - return mRendering->toggleVanityMode(enable); + return mRendering->getCamera()->toggleVanityMode(enable); } void World::disableDeferredPreviewRotation() @@ -2391,12 +2391,16 @@ namespace MWWorld void World::allowVanityMode(bool allow) { - mRendering->allowVanityMode(allow); + mRendering->getCamera()->allowVanityMode(allow); } bool World::vanityRotateCamera(float * rot) { - return mRendering->vanityRotateCamera(rot); + if(!mRendering->getCamera()->isVanityOrPreviewModeEnabled()) + return false; + + mRendering->getCamera()->rotateCamera(rot[0], rot[2], true); + return true; } void World::adjustCameraDistance(float dist) From 0d6be9bd18e8d41221efa3549bce21e672e6108b Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Thu, 6 Aug 2020 00:58:18 +0200 Subject: [PATCH 052/224] More accurate detection of cyclic includes --- components/shader/shadermanager.cpp | 77 ++++++++++++++++------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index be662990b..8523a2962 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -61,45 +61,39 @@ namespace Shader return true; } - bool parseIncludes(boost::filesystem::path shaderPath, std::string& source, const std::string& templateName) + // Recursively replaces include statements with the actual source of the included files. + // Adjusts #line statements accordingly and detects cyclic includes. + // includingFiles is the set of files that include this file directly or indirectly, and is intentionally not a reference to allow automatic cleanup. + static bool parseIncludes(boost::filesystem::path shaderPath, std::string& source, const std::string& fileName, int& fileNumber, std::set includingFiles) { + // An include is cyclic if it is being included by itself + if (includingFiles.insert(shaderPath/fileName).second == false) + { + Log(Debug::Error) << "Shader " << fileName << " error: Detected cyclic #includes"; + return false; + } + Misc::StringUtils::replaceAll(source, "\r\n", "\n"); - std::set includedFiles; size_t foundPos = 0; - int fileNumber = 1; while ((foundPos = source.find("#include")) != std::string::npos) { size_t start = source.find('"', foundPos); - if (start == std::string::npos || start == source.size()-1) + if (start == std::string::npos || start == source.size() - 1) { - Log(Debug::Error) << "Shader " << templateName << " error: Invalid #include"; + Log(Debug::Error) << "Shader " << fileName << " error: Invalid #include"; return false; } - size_t end = source.find('"', start+1); + size_t end = source.find('"', start + 1); if (end == std::string::npos) { - Log(Debug::Error) << "Shader " << templateName << " error: Invalid #include"; + Log(Debug::Error) << "Shader " << fileName << " error: Invalid #include"; return false; } - std::string includeFilename = source.substr(start+1, end-(start+1)); + std::string includeFilename = source.substr(start + 1, end - (start + 1)); boost::filesystem::path includePath = shaderPath / includeFilename; - boost::filesystem::ifstream includeFstream; - includeFstream.open(includePath); - if (includeFstream.fail()) - { - Log(Debug::Error) << "Shader " << templateName << " error: Failed to open include " << includePath.string(); - return false; - } - - std::stringstream buffer; - buffer << includeFstream.rdbuf(); - std::string stringRepresentation = buffer.str(); - addLineDirectivesAfterConditionalBlocks(stringRepresentation); - - // insert #line directives so we get correct line numbers in compiler errors - int includedFileNumber = fileNumber++; + // Determine the line number that will be used for the #line directive following the included source size_t lineDirectivePosition = source.rfind("#line", foundPos); int lineNumber; if (lineDirectivePosition != std::string::npos) @@ -116,16 +110,30 @@ namespace Shader } lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n'); + // Include the file recursively + boost::filesystem::ifstream includeFstream; + includeFstream.open(includePath); + if (includeFstream.fail()) + { + Log(Debug::Error) << "Shader " << fileName << " error: Failed to open include " << includePath.string(); + return false; + } + int includedFileNumber = fileNumber++; + + std::stringstream buffer; + buffer << includeFstream.rdbuf(); + std::string stringRepresentation = buffer.str(); + if (!addLineDirectivesAfterConditionalBlocks(stringRepresentation) + || !parseIncludes(shaderPath, stringRepresentation, includeFilename, fileNumber, includingFiles)) + { + Log(Debug::Error) << "In file included from " << fileName << "." << lineNumber; + return false; + } + std::stringstream toInsert; toInsert << "#line 0 " << includedFileNumber << "\n" << stringRepresentation << "\n#line " << lineNumber << " 0\n"; - source.replace(foundPos, (end-foundPos+1), toInsert.str()); - - if (includedFiles.insert(includePath).second == false) - { - Log(Debug::Error) << "Shader " << templateName << " error: Detected cyclic #includes"; - return false; - } + source.replace(foundPos, (end - foundPos + 1), toInsert.str()); } return true; } @@ -282,21 +290,22 @@ namespace Shader TemplateMap::iterator templateIt = mShaderTemplates.find(templateName); if (templateIt == mShaderTemplates.end()) { - boost::filesystem::path p = (boost::filesystem::path(mPath) / templateName); + boost::filesystem::path path = (boost::filesystem::path(mPath) / templateName); boost::filesystem::ifstream stream; - stream.open(p); + stream.open(path); if (stream.fail()) { - Log(Debug::Error) << "Failed to open " << p.string(); + Log(Debug::Error) << "Failed to open " << path.string(); return nullptr; } std::stringstream buffer; buffer << stream.rdbuf(); // parse includes + int fileNumber = 1; std::string source = buffer.str(); if (!addLineDirectivesAfterConditionalBlocks(source) - || !parseIncludes(boost::filesystem::path(mPath), source, templateName)) + || !parseIncludes(boost::filesystem::path(mPath), source, templateName, fileNumber, {})) return nullptr; templateIt = mShaderTemplates.insert(std::make_pair(templateName, source)).first; From 0de6650add395b08d6958c2173607ce0e889895d Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Mon, 3 Aug 2020 22:44:16 +0200 Subject: [PATCH 053/224] Add RayCastingInterface --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/world.hpp | 6 ++-- apps/openmw/mwphysics/physicssystem.cpp | 12 +++---- apps/openmw/mwphysics/physicssystem.hpp | 21 ++++-------- apps/openmw/mwphysics/raycasting.hpp | 41 +++++++++++++++++++++++ apps/openmw/mwrender/camera.cpp | 8 ++--- apps/openmw/mwworld/projectilemanager.cpp | 4 +-- apps/openmw/mwworld/worldimp.cpp | 11 ++++-- apps/openmw/mwworld/worldimp.hpp | 4 +-- 9 files changed, 74 insertions(+), 35 deletions(-) create mode 100644 apps/openmw/mwphysics/raycasting.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index d8fdf7e33..b718322ac 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -73,7 +73,7 @@ add_openmw_dir (mwworld add_openmw_dir (mwphysics physicssystem trace collisiontype actor convert object heightfield closestnotmerayresultcallback contacttestresultcallback deepestnotmecontacttestresultcallback stepper movementsolver - closestnotmeconvexresultcallback + closestnotmeconvexresultcallback raycasting ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 1c63d982f..70e65e0ea 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -53,7 +53,7 @@ namespace ESM namespace MWPhysics { - class PhysicsSystem; + class RayCastingInterface; } namespace MWRender @@ -120,8 +120,6 @@ namespace MWBase virtual void readRecord (ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) = 0; - virtual const MWPhysics::PhysicsSystem* getPhysics() const = 0; - virtual MWWorld::CellStore *getExterior (int x, int y) = 0; virtual MWWorld::CellStore *getInterior (const std::string& name) = 0; @@ -310,6 +308,8 @@ namespace MWBase virtual void updateAnimatedCollisionShape(const MWWorld::Ptr &ptr) = 0; + virtual const MWPhysics::RayCastingInterface* getRayCasting() const = 0; + virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0; ///< cast a Ray and return true if there is an object in the ray path. diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 133e0aeb0..91e7a9de0 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -179,7 +179,7 @@ namespace MWPhysics { // First of all, try to hit where you aim to int hitmask = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor; - RayResult result = castRay(origin, origin + (orient * osg::Vec3f(0.0f, queryDistance, 0.0f)), actor, targets, hitmask, CollisionType_Actor); + RayCastingResult result = castRay(origin, origin + (orient * osg::Vec3f(0.0f, queryDistance, 0.0f)), actor, targets, hitmask, CollisionType_Actor); if (result.mHit) { @@ -262,7 +262,7 @@ namespace MWPhysics return (point - Misc::Convert::toOsg(cb.m_hitPointWorld)).length(); } - PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector targets, int mask, int group) const + RayCastingResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector targets, int mask, int group) const { btVector3 btFrom = Misc::Convert::toBullet(from); btVector3 btTo = Misc::Convert::toBullet(to); @@ -299,7 +299,7 @@ namespace MWPhysics mCollisionWorld->rayTest(btFrom, btTo, resultCallback); - RayResult result; + RayCastingResult result; result.mHit = resultCallback.hasHit(); if (resultCallback.hasHit()) { @@ -311,7 +311,7 @@ namespace MWPhysics return result; } - PhysicsSystem::RayResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius) const + RayCastingResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius) const { btCollisionWorld::ClosestConvexResultCallback callback(Misc::Convert::toBullet(from), Misc::Convert::toBullet(to)); callback.m_collisionFilterGroup = 0xff; @@ -325,7 +325,7 @@ namespace MWPhysics mCollisionWorld->convexSweepTest(&shape, from_, to_, callback); - RayResult result; + RayCastingResult result; result.mHit = callback.hasHit(); if (result.mHit) { @@ -346,7 +346,7 @@ namespace MWPhysics osg::Vec3f pos1 (physactor1->getCollisionObjectPosition() + osg::Vec3f(0,0,physactor1->getHalfExtents().z() * 0.9)); // eye level osg::Vec3f pos2 (physactor2->getCollisionObjectPosition() + osg::Vec3f(0,0,physactor2->getHalfExtents().z() * 0.9)); - RayResult result = castRay(pos1, pos2, MWWorld::ConstPtr(), std::vector(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door); + RayCastingResult result = castRay(pos1, pos2, MWWorld::ConstPtr(), std::vector(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door); return !result.mHit; } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index c2a74cbd8..ade8775e6 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -13,6 +13,7 @@ #include "../mwworld/ptr.hpp" #include "collisiontype.hpp" +#include "raycasting.hpp" namespace osg { @@ -52,7 +53,7 @@ namespace MWPhysics class Object; class Actor; - class PhysicsSystem + class PhysicsSystem : public RayCastingInterface { public: PhysicsSystem (Resource::ResourceSystem* resourceSystem, osg::ref_ptr parentNode); @@ -108,25 +109,17 @@ namespace MWPhysics /// target vector hits the collision shape and then calculates distance from the intersection point. /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful. /// \note Only Actor targets are supported at the moment. - float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const; - - struct RayResult - { - bool mHit; - osg::Vec3f mHitPos; - osg::Vec3f mHitNormal; - MWWorld::Ptr mHitObject; - }; + float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const final; /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors. - RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), + RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), std::vector targets = std::vector(), - int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const; + int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const final; - RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const; + RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const final; /// Return true if actor1 can see actor2. - bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const; + bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const final; bool isOnGround (const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwphysics/raycasting.hpp b/apps/openmw/mwphysics/raycasting.hpp new file mode 100644 index 000000000..7afbe9321 --- /dev/null +++ b/apps/openmw/mwphysics/raycasting.hpp @@ -0,0 +1,41 @@ +#ifndef OPENMW_MWPHYSICS_RAYCASTING_H +#define OPENMW_MWPHYSICS_RAYCASTING_H + +#include + +#include "../mwworld/ptr.hpp" + +#include "collisiontype.hpp" + +namespace MWPhysics +{ + struct RayCastingResult + { + bool mHit; + osg::Vec3f mHitPos; + osg::Vec3f mHitNormal; + MWWorld::Ptr mHitObject; + }; + + class RayCastingInterface + { + public: + /// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the + /// target vector hits the collision shape and then calculates distance from the intersection point. + /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful. + /// \note Only Actor targets are supported at the moment. + virtual float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const = 0; + + /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors. + virtual RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), + std::vector targets = std::vector(), + int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const = 0; + + virtual RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const = 0; + + /// Return true if actor1 can see actor2. + virtual bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const = 0; + }; +} + +#endif diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 3b0ceb148..40cc9895d 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -17,7 +17,7 @@ #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwphysics/physicssystem.hpp" +#include "../mwphysics/raycasting.hpp" #include "npcanimation.hpp" @@ -218,7 +218,7 @@ namespace MWRender const float cameraObstacleLimit = 5.0f; const float focalObstacleLimit = 10.f; - const MWPhysics::PhysicsSystem* physics = MWBase::Environment::get().getWorld()->getPhysics(); + const auto* rayCasting = MWBase::Environment::get().getWorld()->getRayCasting(); // Adjust focal point to prevent clipping. osg::Vec3d focal = getFocalPoint(); @@ -226,7 +226,7 @@ namespace MWRender float offsetLen = focalOffset.length(); if (offsetLen > 0) { - MWPhysics::PhysicsSystem::RayResult result = physics->castSphere(focal - focalOffset, focal, focalObstacleLimit); + MWPhysics::RayCastingResult result = rayCasting->castSphere(focal - focalOffset, focal, focalObstacleLimit); if (result.mHit) { double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen; @@ -240,7 +240,7 @@ namespace MWRender mCameraDistance = std::min(mCameraDistance, mMaxNextCameraDistance); osg::Vec3d cameraPos; getPosition(focal, cameraPos); - MWPhysics::PhysicsSystem::RayResult result = physics->castSphere(focal, cameraPos, cameraObstacleLimit); + MWPhysics::RayCastingResult result = rayCasting->castSphere(focal, cameraPos, cameraObstacleLimit); if (result.mHit) mCameraDistance = (result.mHitPos + result.mHitNormal * cameraObstacleLimit - focal).length(); } diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 6ace82ea1..cc906e932 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -424,7 +424,7 @@ namespace MWWorld // Check for impact // TODO: use a proper btRigidBody / btGhostObject? - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile); + MWPhysics::RayCastingResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile); bool hit = false; if (result.mHit) @@ -500,7 +500,7 @@ namespace MWWorld // Check for impact // TODO: use a proper btRigidBody / btGhostObject? - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile); + MWPhysics::RayCastingResult result = mPhysics->castRay(pos, newPos, caster, targetActors, 0xff, MWPhysics::CollisionType_Projectile); bool underwater = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), newPos); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 50242d7bd..8bf97769f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1542,6 +1542,11 @@ namespace MWWorld return mNavigator->updateObject(DetourNavigator::ObjectId(object), shapes, object->getCollisionObject()->getWorldTransform()); } + const MWPhysics::RayCastingInterface* World::getRayCasting() const + { + return mPhysics.get(); + } + bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2) { int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_Door; @@ -1554,7 +1559,7 @@ namespace MWWorld osg::Vec3f a(x1,y1,z1); osg::Vec3f b(x2,y2,z2); - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector(), mask); + MWPhysics::RayCastingResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), std::vector(), mask); return result.mHit; } @@ -2728,7 +2733,7 @@ namespace MWWorld if (includeWater) { collisionTypes |= MWPhysics::CollisionType_Water; } - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from, to, MWWorld::Ptr(), std::vector(), collisionTypes); + MWPhysics::RayCastingResult result = mPhysics->castRay(from, to, MWWorld::Ptr(), std::vector(), collisionTypes); if (!result.mHit) return maxDist; @@ -3091,7 +3096,7 @@ namespace MWWorld actor.getClass().getCreatureStats(actor).getAiSequence().getCombatTargets(targetActors); // Check for impact, if yes, handle hit, if not, launch projectile - MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(sourcePos, worldPos, actor, targetActors, 0xff, MWPhysics::CollisionType_Projectile); + MWPhysics::RayCastingResult result = mPhysics->castRay(sourcePos, worldPos, actor, targetActors, 0xff, MWPhysics::CollisionType_Projectile); if (result.mHit) MWMechanics::projectileHit(actor, result.mHitObject, bow, projectile, result.mHitPos, attackStrength); else diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 512c6ede3..f1c8ed73a 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -214,8 +214,6 @@ namespace MWWorld void readRecord (ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) override; - const MWPhysics::PhysicsSystem* getPhysics() const override { return mPhysics.get(); } - CellStore *getExterior (int x, int y) override; CellStore *getInterior (const std::string& name) override; @@ -412,6 +410,8 @@ namespace MWWorld void updateAnimatedCollisionShape(const Ptr &ptr) override; + const MWPhysics::RayCastingInterface* getRayCasting() const override; + bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) override; ///< cast a Ray and return true if there is an object in the ray path. From a211527b4b247863042d1beec7fb4367a748b7c6 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 7 Aug 2020 09:58:36 +0300 Subject: [PATCH 054/224] Fix AppVeyor warnings --- apps/openmw/mwmechanics/aiavoiddoor.cpp | 8 ++++---- apps/openmw/mwscript/miscextensions.cpp | 4 ++-- apps/openmw/mwscript/scriptmanagerimp.cpp | 2 -- components/sdlutil/sdlvideowrapper.cpp | 1 - 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/aiavoiddoor.cpp b/apps/openmw/mwmechanics/aiavoiddoor.cpp index ce2553756..73a638563 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.cpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.cpp @@ -60,14 +60,14 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterCont // Make all nearby actors also avoid the door std::vector actors; MWBase::Environment::get().getMechanicsManager()->getActorsInRange(pos.asVec3(),100,actors); - for(auto& actor : actors) + for(auto& neighbor : actors) { - if (actor == getPlayer()) + if (neighbor == getPlayer()) continue; - MWMechanics::AiSequence& seq = actor.getClass().getCreatureStats(actor).getAiSequence(); + MWMechanics::AiSequence& seq = neighbor.getClass().getCreatureStats(neighbor).getAiSequence(); if (seq.getTypeId() != MWMechanics::AiPackageTypeId::AvoidDoor) - seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr), actor); + seq.stack(MWMechanics::AiAvoidDoor(mDoorPtr), neighbor); } return false; diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index cbacd62df..8ce891741 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -563,9 +563,9 @@ namespace MWScript effects += store.getMagicEffects(); } - for (const auto& effect : effects) + for (const auto& activeEffect : effects) { - if (effect.first.mId == key && effect.second.getModifier() > 0) + if (activeEffect.first.mId == key && activeEffect.second.getModifier() > 0) { runtime.push(1); return; diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 8ff768c2d..e1652b311 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -149,8 +149,6 @@ namespace MWScript int count = 0; int success = 0; - const MWWorld::Store& scripts = mStore.get(); - for (auto& script : mStore.get()) { if (!std::binary_search (mScriptBlacklist.begin(), mScriptBlacklist.end(), diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index 57d1e2985..b3ba98ee3 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -102,7 +102,6 @@ namespace SDLUtil int w = 0; int h = 0; auto index = SDL_GetWindowDisplayIndex(mWindow); - bool reposition = false; SDL_GetDisplayBounds(index, &rect); SDL_GetWindowSize(mWindow, &w, &h); From 35de34c01927dc74d13ea9e9bdcd34e6929677a9 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 7 Aug 2020 10:07:19 +0300 Subject: [PATCH 055/224] Don't clamp GeomMorpherController recovered weight value Seems that Morrowind doesn't do it. --- components/nifosg/controller.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index a4db2cba3..58f1c17a7 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -197,7 +197,6 @@ void GeomMorpherController::update(osg::NodeVisitor *nv, osg::Drawable *drawable float val = 0; if (!(*it).empty()) val = it->interpKey(input); - val = std::max(0.f, std::min(1.f, val)); SceneUtil::MorphGeometry::MorphTarget& target = morphGeom->getMorphTarget(i); if (target.getWeight() != val) From aa131262ea7efadf0cde9258b913d4c2ae95bc20 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Fri, 7 Aug 2020 10:22:54 +0300 Subject: [PATCH 056/224] Implement quadratic interpolation for scalars and vectors --- components/nif/nifkey.hpp | 10 +++++----- components/nifosg/controller.hpp | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/components/nif/nifkey.hpp b/components/nif/nifkey.hpp index 333d8a7cf..4c10327e1 100644 --- a/components/nif/nifkey.hpp +++ b/components/nif/nifkey.hpp @@ -26,11 +26,11 @@ enum InterpolationType template struct KeyT { T mValue; + T mInTan; // Only for Quadratic interpolation, and never for QuaternionKeyList + T mOutTan; // Only for Quadratic interpolation, and never for QuaternionKeyList - // FIXME: Implement Quadratic and TBC interpolation + // FIXME: Implement TBC interpolation /* - T mForwardValue; // Only for Quadratic interpolation, and never for QuaternionKeyList - T mBackwardValue; // Only for Quadratic interpolation, and never for QuaternionKeyList float mTension; // Only for TBC interpolation float mBias; // Only for TBC interpolation float mContinuity; // Only for TBC interpolation @@ -136,8 +136,8 @@ private: static void readQuadratic(NIFStream &nif, KeyT &key) { readValue(nif, key); - /*key.mForwardValue = */(nif.*getValue)(); - /*key.mBackwardValue = */(nif.*getValue)(); + key.mInTan = (nif.*getValue)(); + key.mOutTan = (nif.*getValue)(); } static void readQuadratic(NIFStream &nif, KeyT &key) diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index df1086f56..be1292359 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -110,6 +110,24 @@ namespace NifOsg { case Nif::InterpolationType_Constant: return fraction > 0.5f ? b.mValue : a.mValue; + case Nif::InterpolationType_Quadratic: + { + // Using a cubic Hermite spline. + // b1(t) = 2t^3 - 3t^2 + 1 + // b2(t) = -2t^3 + 3t^2 + // b3(t) = t^3 - 2t^2 + t + // b4(t) = t^3 - t^2 + // f(t) = a.mValue * b1(t) + b.mValue * b2(t) + a.mOutTan * b3(t) + b.mInTan * b4(t) + const float t = fraction; + const float t2 = t * t; + const float t3 = t2 * t; + const float b1 = 2.f * t3 - 3.f * t2 + 1; + const float b2 = -2.f * t3 + 3.f * t2; + const float b3 = t3 - 2.f * t2 + t; + const float b4 = t3 - t2; + return a.mValue * b1 + b.mValue * b2 + a.mOutTan * b3 + b.mInTan * b4; + } + // TODO: Implement TBC interpolation default: return a.mValue + ((b.mValue - a.mValue) * fraction); } @@ -120,6 +138,7 @@ namespace NifOsg { case Nif::InterpolationType_Constant: return fraction > 0.5f ? b.mValue : a.mValue; + // TODO: Implement Quadratic and TBC interpolation default: { osg::Quat result; From fb28d27d080c2c365be1d159d310a3f710289968 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Fri, 7 Aug 2020 16:36:59 +0200 Subject: [PATCH 057/224] don't discard purged effects --- apps/openmw/mwmechanics/spells.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 32cd19c5b..a66c267cc 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -434,8 +434,9 @@ namespace MWMechanics const auto& baseSpells = mSpellList->getSpells(); for (const auto& it : mSpells) { - //Don't save spells stored in the base record - if(std::find(baseSpells.begin(), baseSpells.end(), it.first->mId) == baseSpells.end()) + // Don't save spells and powers stored in the base record + if((it.first->mData.mType != ESM::Spell::ST_Spell && it.first->mData.mType != ESM::Spell::ST_Power) || + std::find(baseSpells.begin(), baseSpells.end(), it.first->mId) == baseSpells.end()) { ESM::SpellState::SpellParams params; params.mEffectRands = it.second.mEffectRands; From 6a4fa8a8b58e41fc4cf7e1a64a27d4e2ae838d27 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Fri, 7 Aug 2020 20:17:44 +0000 Subject: [PATCH 058/224] Add more settings to openmw-launcher --- apps/launcher/advancedpage.cpp | 51 ++++- apps/launcher/advancedpage.hpp | 1 + apps/openmw/mwmechanics/character.cpp | 3 +- .../reference/modding/settings/camera.rst | 7 +- .../reference/modding/settings/game.rst | 18 +- files/settings-default.cfg | 7 +- files/ui/advancedpage.ui | 207 ++++++++++++++++-- 7 files changed, 270 insertions(+), 24 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 2dd7d07c1..e82afc303 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -119,15 +119,22 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); + loadSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game"); if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2) unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); loadSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); + loadSettingBool(enableNavigatorCheckBox, "enable", "Navigator"); } // Visuals { + loadSettingBool(autoUseObjectNormalMapsCheckBox, "auto use object normal maps", "Shaders"); + loadSettingBool(autoUseObjectSpecularMapsCheckBox, "auto use object specular maps", "Shaders"); + loadSettingBool(autoUseTerrainNormalMapsCheckBox, "auto use terrain normal maps", "Shaders"); + loadSettingBool(autoUseTerrainSpecularMapsCheckBox, "auto use terrain specular maps", "Shaders"); loadSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders"); + loadSettingBool(radialFogCheckBox, "radial fog", "Shaders"); loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); connect(animSourcesCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotAnimSourcesToggled(bool))); loadSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); @@ -136,7 +143,6 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); } - loadSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); loadSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); @@ -149,6 +155,18 @@ bool Launcher::AdvancedPage::loadSettings() viewingDistanceComboBox->setValue(convertToCells(mEngineSettings.getInt("viewing distance", "Camera"))); } + // Camera + { + loadSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); + connect(viewOverShoulderCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotViewOverShoulderToggled(bool))); + viewOverShoulderGroup->setEnabled(viewOverShoulderCheckBox->checkState()); + loadSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); + loadSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); + loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); + defaultShoulderComboBox->setCurrentIndex( + mEngineSettings.getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1); + } + // Interface Changes { loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); @@ -213,20 +231,26 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); saveSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); + saveSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex(); if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game")) mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); saveSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); + saveSettingBool(enableNavigatorCheckBox, "enable", "Navigator"); } // Visuals { + saveSettingBool(autoUseObjectNormalMapsCheckBox, "auto use object normal maps", "Shaders"); + saveSettingBool(autoUseObjectSpecularMapsCheckBox, "auto use object specular maps", "Shaders"); + saveSettingBool(autoUseTerrainNormalMapsCheckBox, "auto use terrain normal maps", "Shaders"); + saveSettingBool(autoUseTerrainSpecularMapsCheckBox, "auto use terrain specular maps", "Shaders"); saveSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders"); + saveSettingBool(radialFogCheckBox, "radial fog", "Shaders"); saveSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); saveSettingBool(animSourcesCheckBox, "use additional anim sources", "Game"); saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); - saveSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); saveSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); @@ -245,6 +269,24 @@ void Launcher::AdvancedPage::saveSettings() } } + // Camera + { + saveSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); + saveSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); + saveSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); + saveSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); + + osg::Vec2f shoulderOffset = mEngineSettings.getVector2("view over shoulder offset", "Camera"); + if (defaultShoulderComboBox->currentIndex() != (shoulderOffset.x() >= 0 ? 0 : 1)) + { + if (defaultShoulderComboBox->currentIndex() == 0) + shoulderOffset.x() = std::abs(shoulderOffset.x()); + else + shoulderOffset.x() = -std::abs(shoulderOffset.x()); + mEngineSettings.setVector2("view over shoulder offset", "Camera", shoulderOffset); + } + } + // Interface Changes { saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); @@ -326,3 +368,8 @@ void Launcher::AdvancedPage::slotAnimSourcesToggled(bool checked) shieldSheathingCheckBox->setCheckState(Qt::Unchecked); } } + +void Launcher::AdvancedPage::slotViewOverShoulderToggled(bool checked) +{ + viewOverShoulderGroup->setEnabled(viewOverShoulderCheckBox->checkState()); +} diff --git a/apps/launcher/advancedpage.hpp b/apps/launcher/advancedpage.hpp index 25cb66d9d..bdf5af0c8 100644 --- a/apps/launcher/advancedpage.hpp +++ b/apps/launcher/advancedpage.hpp @@ -32,6 +32,7 @@ namespace Launcher void on_skipMenuCheckBox_stateChanged(int state); void on_runScriptAfterStartupBrowseButton_clicked(); void slotAnimSourcesToggled(bool checked); + void slotViewOverShoulderToggled(bool checked); private: Files::ConfigurationManager &mCfgMgr; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c8e81aa49..2ff8241f4 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2243,7 +2243,8 @@ void CharacterController::update(float duration, bool animationOnly) swimmingPitch += osg::clampBetween(targetSwimmingPitch - swimmingPitch, -maxSwimPitchDelta, maxSwimPitchDelta); mAnimation->setBodyPitchRadians(swimmingPitch); } - if (inwater && isPlayer && !isFirstPersonPlayer) + static const bool swimUpwardCorrection = Settings::Manager::getBool("swim upward correction", "Game"); + if (inwater && isPlayer && !isFirstPersonPlayer && swimUpwardCorrection) { static const float swimUpwardCoef = Settings::Manager::getFloat("swim upward coef", "Game"); static const float swimForwardCoef = sqrtf(1.0f - swimUpwardCoef * swimUpwardCoef); diff --git a/docs/source/reference/modding/settings/camera.rst b/docs/source/reference/modding/settings/camera.rst index 8d7078905..1025a2fbd 100644 --- a/docs/source/reference/modding/settings/camera.rst +++ b/docs/source/reference/modding/settings/camera.rst @@ -160,7 +160,7 @@ auto switch shoulder This setting makes difference only in third person mode if 'view over shoulder' is enabled. When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle. -This setting can only be configured by editing the settings configuration file. +This setting can be controlled in Advanced tab of the launcher. zoom out when move coef ----------------------- @@ -181,9 +181,10 @@ preview if stand still :Range: True/False :Default: False +Makes difference only in third person mode. If enabled then the character rotation is not synchonized with the camera rotation while the character doesn't move and not in combat mode. -This setting can only be configured by editing the settings configuration file. +This setting can be controlled in Advanced tab of the launcher. deferred preview rotation ------------------------- @@ -196,5 +197,5 @@ Makes difference only in third person mode. If enabled then the character smoothly rotates to the view direction after exiting preview or vanity mode. If disabled then the camera rotates rather than the character. -This setting can only be configured by editing the settings configuration file. +This setting can be controlled in Advanced tab of the launcher. diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index 5291fb0ed..46bd22e50 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -327,7 +327,18 @@ Affects side and diagonal movement. Enabling this setting makes movement more re If disabled then the whole character's body is pointed to the direction of view. Diagonal movement has no special animation and causes sliding. -If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it also changes straight right and straight left movement. +If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it changes straight right and straight left movement as well. Also turns the whole body up or down when swimming according to the movement direction. + +This setting can be controlled in Advanced tab of the launcher. + +swim upward correction +---------------- + +:Type: boolean +:Range: True/False +:Default: False + +Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving. This setting can be controlled in Advanced tab of the launcher. @@ -336,9 +347,10 @@ swim upward coef :Type: floating point :Range: -1.0 to 1.0 -:Default: 0.0 +:Default: 0.2 -Makes player swim a bit upward (or downward in case of negative value) from the line of sight. Intended to make simpler swimming without diving. Recommened range of values is from 0.0 to 0.2. +Regulates strength of the "swim upward correction" effect (if enabled). +Makes player swim a bit upward (or downward in case of negative value) from the line of sight. Recommened range of values is from 0.0 to 0.25. 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 65e72c177..ac5433f30 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -325,8 +325,11 @@ uncapped damage fatigue = false # Turn lower body to movement direction. 'true' makes diagonal movement more realistic. turn to movement direction = false -# Makes player swim a bit upward (or downward in case of negative value) from the line of sight. -swim upward coef = 0.0 +# Makes player swim a bit upward from the line of sight. +swim upward correction = false + +# Strength of the 'swim upward correction' effect (if enabled). +swim upward coef = 0.2 # Make the training skills proposed by a trainer based on its base attribute instead of its modified ones trainers training skills based on base skill = false diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 08ffe10ce..ca57e5dc8 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -116,6 +116,16 @@ + + + + <html><head/><body><p>Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.</p></body></html> + + + Swim upward correction + + + @@ -164,6 +174,16 @@ + + + + <html><head/><body><p>Enable navigator. When enabled background threads are started to build nav mesh for world geometry. Pathfinding system uses nav mesh to build paths. When disabled only pathgrid is used to build paths. Single-core CPU systems may have big performance impact on exiting interior location and moving across exterior world. May slightly affect performance on multi-core CPU systems. Multi-core CPU systems may have different latency for nav mesh update depending on other settings and system performance. Moving across external world, entering/exiting location produce nav mesh update. NPC and creatures may not be able to find path before nav mesh is built around them. Try to disable this if you want to have old fashioned AI which doesn’t know where to go when you stand behind that stone and casting a firebolt.</p></body></html> + + + Build nav mesh for world geometry + + + @@ -178,6 +198,52 @@ Visuals + + + + <html><head/><body><p>If this option is enabled, normal maps are automatically recognized and used if they are named appropriately +(see 'normal map pattern', e.g. for a base texture foo.dds, the normal map texture would have to be named foo_n.dds). +If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file (.nif or .osg file). Affects objects.</p></body></html> + + + Auto use object normal maps + + + + + + + <html><head/><body><p>If this option is enabled, specular maps are automatically recognized and used if they are named appropriately +(see 'specular map pattern', e.g. for a base texture foo.dds, +the specular map texture would have to be named foo_spec.dds). +If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file +(.osg file, not supported in .nif files). Affects objects.</p></body></html> + + + Auto use object specular maps + + + + + + + <html><head/><body><p>See 'auto use object normal maps'. Affects terrain.</p></body></html> + + + Auto use terrain normal maps + + + + + + + <html><head/><body><p>If a file with pattern 'terrain specular map pattern' exists, use that file as a 'diffuse specular' map. The texture must contain the layer colour in the RGB channel (as usual), and a specular multiplier in the alpha channel.</p></body></html> + + + Auto use terrain specular maps + + + @@ -191,6 +257,17 @@ Affected objects will use shaders. + + + + <html><head/><body><p>By default, the fog becomes thicker proportionally to your distance from the clipping plane set at the clipping distance, which causes distortion at the edges of the screen. +This setting makes the fog use the actual eye point distance (or so called Euclidean distance) to calculate the fog, which makes the fog look less artificial, especially if you have a wide FOV.</p></body></html> + + + Radial fog + + + @@ -246,22 +323,10 @@ Affected objects will use shaders. - - - - <html><head/><body><p>This setting controls third person view mode.</p><p>False: View is centered on the character's head. Crosshair is hidden. -True: In non-combat mode camera is positioned behind the character's shoulder. Crosshair is visible in third person mode as well. -</p></body></html> - - - View over the shoulder - - - - <html><head/><body><p>Affects side and diagonal movement. Enabling this setting makes movement more realistic.</p><p>If disabled then the whole character's body is pointed to the direction of view. Diagonal movement has no special animation and causes sliding.</p><p>If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it also changes straight right and straight left movement.</p></body></html> + <html><head/><body><p>Affects side and diagonal movement. Enabling this setting makes movement more realistic.</p><p>If disabled then the whole character's body is pointed to the direction of view. Diagonal movement has no special animation and causes sliding.</p><p>If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it changes straight right and straight left movement as well. Also turns the whole body up or down when swimming according to the movement direction.</p></body></html> Turn to movement direction @@ -328,6 +393,122 @@ but also increase the amount of rendered geometry and significantly reduce the f + + + Camera + + + + + + <html><head/><body><p>This setting controls third person view mode.</p><p>False: View is centered on the character's head. Crosshair is hidden. +True: In non-combat mode camera is positioned behind the character's shoulder. Crosshair is visible in third person mode as well. +</p></body></html> + + + View over the shoulder + + + + + + + + 20 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Default shoulder: + + + + + + + 0 + + + + Right + + + + + Left + + + + + + + + + + + <html><head/><body><p>When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle.</p></body></html> + + + Auto switch shoulder + + + + + + + + + + <html><head/><body><p>If enabled then the character rotation is not synchonized with the camera rotation while the character doesn't move and not in combat mode.</p></body></html> + + + Preview if stand still + + + + + + + <html><head/><body><p>If enabled then the character smoothly rotates to the view direction after exiting preview or vanity mode. If disabled then the camera rotates rather than the character.</p></body></html> + + + Deferred preview rotation + + + + + + + Qt::Vertical + + + + + Interface changes From a0ca7c4b4321fe3c1894553ec0c675b9e839be72 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 9 Aug 2020 12:48:59 +0300 Subject: [PATCH 059/224] AIPursue: don't do a LOS check Properly resolve #4774 --- apps/openmw/mwmechanics/aipursue.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aipursue.cpp b/apps/openmw/mwmechanics/aipursue.cpp index 7aa2a9554..bfe860d6d 100644 --- a/apps/openmw/mwmechanics/aipursue.cpp +++ b/apps/openmw/mwmechanics/aipursue.cpp @@ -39,8 +39,7 @@ bool AiPursue::execute (const MWWorld::Ptr& actor, CharacterController& characte if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) return true; - if (!MWBase::Environment::get().getWorld()->getLOS(target, actor) - || !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(target, actor)) + if (isTargetMagicallyHidden(target) && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(target, actor)) return false; if (target.getClass().getCreatureStats(target).isDead()) From c436f29a1efc1dd2ec04239618252180d1c1b9dd Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 9 Aug 2020 20:07:31 +0300 Subject: [PATCH 060/224] Make Advanced tab of the launcher look okay for everyone again --- apps/launcher/advancedpage.cpp | 32 -------------------------------- files/ui/advancedpage.ui | 11 ++++------- 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index e82afc303..1cc77ec6d 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -10,37 +10,6 @@ #include - -class HorizontalTextWestTabStyle : public QProxyStyle -{ -public: - QSize sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const - { - QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); - if (type == QStyle::CT_TabBarTab) - { - s.transpose(); - s.setHeight(s.height() + 20); - } - return s; - } - - void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const - { - if (element == CE_TabBarTabLabel) - { - if (const QStyleOptionTab* tab = qstyleoption_cast(option)) - { - QStyleOptionTab opt(*tab); - opt.shape = QTabBar::RoundedNorth; - QProxyStyle::drawControl(element, &opt, painter, widget); - return; - } - } - QProxyStyle::drawControl(element, option, painter, widget); - } -}; - Launcher::AdvancedPage::AdvancedPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, Settings::Manager &engineSettings, QWidget *parent) @@ -53,7 +22,6 @@ Launcher::AdvancedPage::AdvancedPage(Files::ConfigurationManager &cfg, setupUi(this); loadSettings(); - AdvancedTabWidget->tabBar()->setStyle(new HorizontalTextWestTabStyle); mCellNameCompleter.setModel(&mCellNameCompleterModel); startDefaultCharacterAtField->setCompleter(&mCellNameCompleter); } diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index ca57e5dc8..4f1a30d4c 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -5,15 +5,12 @@ - - QTabWidget::West - 0 - Game mechanics + Game Mechanics @@ -509,9 +506,9 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C - + - Interface changes + Interface @@ -618,7 +615,7 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C - Bug fixes + Bug Fixes From 3497dcce76ce016870b232f668628d661f30c81c Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 10 Aug 2020 17:33:11 +0100 Subject: [PATCH 061/224] Add OpenMW Chocolatey proxy as source --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e9da9f00a..8b4319495 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,6 +57,7 @@ variables: &cs-targets - windows before_script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" + - choco source add -n=openmw-proxy -s="https://repo.openmw.org/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' --version=3.18.0 -y @@ -146,6 +147,7 @@ Windows_Ninja_CS_RelWithDebInfo: - windows before_script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" + - choco source add -n=openmw-proxy -s="https://repo.openmw.org/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y From 35d9ef355afc7ae255287632a0572d2e3246ff4f Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 10 Aug 2020 17:38:17 +0100 Subject: [PATCH 062/224] Specify full repository URL --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8b4319495..15aaa339b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,7 +57,7 @@ variables: &cs-targets - windows before_script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" - - choco source add -n=openmw-proxy -s="https://repo.openmw.org/" --priority=1 + - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolatey/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' --version=3.18.0 -y @@ -147,7 +147,7 @@ Windows_Ninja_CS_RelWithDebInfo: - windows before_script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" - - choco source add -n=openmw-proxy -s="https://repo.openmw.org/" --priority=1 + - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolatey/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y From f7d28445f75021e9dd83f21ed92f427eaa1d31f0 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 10 Aug 2020 17:51:05 +0100 Subject: [PATCH 063/224] Add l to match typo in real URL --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 15aaa339b..b89b99ac8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,7 +57,7 @@ variables: &cs-targets - windows before_script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" - - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolatey/" --priority=1 + - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolately/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' --version=3.18.0 -y @@ -147,7 +147,7 @@ Windows_Ninja_CS_RelWithDebInfo: - windows before_script: - Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" - - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolatey/" --priority=1 + - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolately/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y From 7f342374fccc4d77e545588694d61708f3b8e6ff Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 12 Aug 2020 11:16:10 +0400 Subject: [PATCH 064/224] Fix crash when using 'showscenegraph 1' console command --- apps/openmw/mwworld/worldimp.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2eec9bf0e..54dbfa7b6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3633,8 +3633,11 @@ namespace MWWorld std::string World::exportSceneGraph(const Ptr &ptr) { std::string file = mUserDataPath + "/openmw.osgt"; - mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr); - mWorldScene->removeFromPagedRefs(ptr); + if (!ptr.isEmpty()) + { + mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr); + mWorldScene->removeFromPagedRefs(ptr); + } mRendering->exportSceneGraph(ptr, file, "Ascii"); return file; } From 215ddb910641f921dc3b8463d1590de4eafcd9d9 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 12 Aug 2020 11:16:37 +0400 Subject: [PATCH 065/224] Do not print warnings for VisController --- components/sceneutil/serialize.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index 62325186c..9e7aa83f6 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -143,6 +143,7 @@ void registerSerializers() "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry", "NifOsg::UVController", + "NifOsg::VisController", "NifOsg::NodeIndexHolder", "osgMyGUI::Drawable", "osg::DrawCallback", From 98b2d5d921a4f15f15921f4d6893b5d27685d642 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 19 Aug 2020 19:29:19 +0100 Subject: [PATCH 066/224] Make shadow debug HUD thread-safe * Double buffer the frustum uniforms. * Don't mess with the debug geometry's StateSet. * Change two-element vectors to arrays so the size is explicit. --- components/sceneutil/mwshadowtechnique.cpp | 20 +++++++++++--------- components/sceneutil/mwshadowtechnique.hpp | 5 +++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index fa38da54e..24ec190ba 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -3104,12 +3104,12 @@ SceneUtil::MWShadowTechnique::DebugHUD::DebugHUD(int numberOfShadowMapsPerLight) fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, debugFrustumFragmentShaderSource); frustumProgram->addShader(fragmentShader); - for (int i = 0; i < 2; ++i) + for (auto& frustumGeometry : mFrustumGeometries) { - mFrustumGeometries.emplace_back(new osg::Geometry()); - mFrustumGeometries[i]->setCullingActive(false); + frustumGeometry = new osg::Geometry(); + frustumGeometry->setCullingActive(false); - mFrustumGeometries[i]->getOrCreateStateSet()->setAttributeAndModes(frustumProgram, osg::StateAttribute::ON); + frustumGeometry->getOrCreateStateSet()->setAttributeAndModes(frustumProgram, osg::StateAttribute::ON); } osg::ref_ptr frustumDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP); @@ -3145,12 +3145,14 @@ void SceneUtil::MWShadowTechnique::DebugHUD::draw(osg::ref_ptr t // It might be possible to change shadow settings at runtime if (shadowMapNumber > mDebugCameras.size()) addAnotherShadowMap(); - - mFrustumUniforms[shadowMapNumber]->set(matrix); - osg::ref_ptr stateSet = mDebugGeometry[shadowMapNumber]->getOrCreateStateSet(); + osg::ref_ptr stateSet = new osg::StateSet(); stateSet->setTextureAttributeAndModes(sDebugTextureUnit, texture, osg::StateAttribute::ON); + auto frustumUniform = mFrustumUniforms[cv.getTraversalNumber() % 2][shadowMapNumber]; + frustumUniform->set(matrix); + stateSet->addUniform(frustumUniform); + // Some of these calls may be superfluous. unsigned int traversalMask = cv.getTraversalMask(); cv.setTraversalMask(mDebugGeometry[shadowMapNumber]->getNodeMask()); @@ -3205,6 +3207,6 @@ void SceneUtil::MWShadowTechnique::DebugHUD::addAnotherShadowMap() mFrustumTransforms[shadowMapNumber]->setCullingActive(false); mDebugCameras[shadowMapNumber]->addChild(mFrustumTransforms[shadowMapNumber]); - mFrustumUniforms.push_back(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "transform")); - mFrustumTransforms[shadowMapNumber]->getOrCreateStateSet()->addUniform(mFrustumUniforms[shadowMapNumber]); + for(auto& uniformVector : mFrustumUniforms) + uniformVector.push_back(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "transform")); } diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 77d0bd2b2..2078fc2d6 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -19,6 +19,7 @@ #ifndef COMPONENTS_SCENEUTIL_MWSHADOWTECHNIQUE_H #define COMPONENTS_SCENEUTIL_MWSHADOWTECHNIQUE_H 1 +#include #include #include @@ -282,8 +283,8 @@ namespace SceneUtil { osg::ref_ptr mDebugProgram; std::vector> mDebugGeometry; std::vector> mFrustumTransforms; - std::vector> mFrustumUniforms; - std::vector> mFrustumGeometries; + std::array>, 2> mFrustumUniforms; + std::array, 2> mFrustumGeometries; }; osg::ref_ptr _debugHud; From ce98d7053bc28913551f9188f575c432cb12ece8 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 19 Aug 2020 22:55:41 +0100 Subject: [PATCH 067/224] Double buffer view-dependent data stateset --- components/sceneutil/mwshadowtechnique.cpp | 17 +++++++++-------- components/sceneutil/mwshadowtechnique.hpp | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 24ec190ba..ae3a29295 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -749,7 +749,8 @@ MWShadowTechnique::ViewDependentData::ViewDependentData(MWShadowTechnique* vdsm) _viewDependentShadowMap(vdsm) { OSG_INFO<<"ViewDependentData::ViewDependentData()"<0) { - decoratorStateGraph->setStateSet(selectStateSetForRenderingShadow(*vdd)); + decoratorStateGraph->setStateSet(selectStateSetForRenderingShadow(*vdd, cv.getTraversalNumber())); } // OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()< stateset = vdd.getStateSet(); + osg::ref_ptr stateset = vdd.getStateSet(traversalNumber); std::lock_guard lock(_accessUniformsAndProgramMutex); - vdd.getStateSet()->clear(); + stateset->clear(); - vdd.getStateSet()->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); + stateset->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); for(Uniforms::const_iterator itr=_uniforms.begin(); itr!=_uniforms.end(); @@ -3047,7 +3048,7 @@ osg::StateSet* MWShadowTechnique::selectStateSetForRenderingShadow(ViewDependent stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON); } - return vdd.getStateSet(); + return stateset; } void MWShadowTechnique::resizeGLObjectBuffers(unsigned int /*maxSize*/) diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 2078fc2d6..95f1117c0 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -192,7 +192,7 @@ namespace SceneUtil { ShadowDataList& getShadowDataList() { return _shadowDataList; } - osg::StateSet* getStateSet() { return _stateset.get(); } + osg::StateSet* getStateSet(unsigned int traversalNumber) { return _stateset[traversalNumber % 2].get(); } virtual void releaseGLObjects(osg::State* = 0) const; @@ -201,7 +201,7 @@ namespace SceneUtil { MWShadowTechnique* _viewDependentShadowMap; - osg::ref_ptr _stateset; + std::array, 2> _stateset; LightDataList _lightDataList; ShadowDataList _shadowDataList; @@ -231,7 +231,7 @@ namespace SceneUtil { virtual void cullShadowCastingScene(osgUtil::CullVisitor* cv, osg::Camera* camera) const; - virtual osg::StateSet* selectStateSetForRenderingShadow(ViewDependentData& vdd) const; + virtual osg::StateSet* selectStateSetForRenderingShadow(ViewDependentData& vdd, unsigned int traversalNumber) const; protected: virtual ~MWShadowTechnique(); From 707204133d1f7c0932734ef893f289b52aa07f5a Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 20 Aug 2020 00:38:13 +0100 Subject: [PATCH 068/224] Double-buffer shadow uniforms that change each frame --- components/sceneutil/mwshadowtechnique.cpp | 41 +++++++++++----------- components/sceneutil/mwshadowtechnique.hpp | 3 +- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index ae3a29295..7a435fe90 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -1344,9 +1344,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i); osg::ref_ptr validRegionUniform; - std::lock_guard lock(_accessUniformsAndProgramMutex); - - for (auto uniform : _uniforms) + for (auto uniform : _uniforms[cv.getTraversalNumber() % 2]) { if (uniform->getName() == validRegionUniformName) validRegionUniform = uniform; @@ -1355,7 +1353,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) if (!validRegionUniform) { validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName); - _uniforms.push_back(validRegionUniform); + _uniforms[cv.getTraversalNumber() % 2].push_back(validRegionUniform); } validRegionUniform->set(validRegionMatrix); @@ -1468,8 +1466,6 @@ void MWShadowTechnique::createShaders() unsigned int _baseTextureUnit = 0; - std::lock_guard lock(_accessUniformsAndProgramMutex); - _shadowCastingStateSet = new osg::StateSet; ShadowSettings* settings = getShadowedScene()->getShadowSettings(); @@ -1502,15 +1498,20 @@ void MWShadowTechnique::createShaders() _shadowCastingStateSet->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); - _uniforms.clear(); osg::ref_ptr baseTextureSampler = new osg::Uniform("baseTexture",(int)_baseTextureUnit); - _uniforms.push_back(baseTextureSampler.get()); - osg::ref_ptr baseTextureUnit = new osg::Uniform("baseTextureUnit",(int)_baseTextureUnit); - _uniforms.push_back(baseTextureUnit.get()); - _uniforms.push_back(new osg::Uniform("maximumShadowMapDistance", (float)settings->getMaximumShadowMapDistance())); - _uniforms.push_back(new osg::Uniform("shadowFadeStart", (float)_shadowFadeStart)); + osg::ref_ptr maxDistance = new osg::Uniform("maximumShadowMapDistance", (float)settings->getMaximumShadowMapDistance()); + osg::ref_ptr fadeStart = new osg::Uniform("shadowFadeStart", (float)_shadowFadeStart); + + for (auto& perFrameUniformList : _uniforms) + { + perFrameUniformList.clear(); + perFrameUniformList.push_back(baseTextureSampler); + perFrameUniformList.push_back(baseTextureUnit.get()); + perFrameUniformList.push_back(maxDistance); + perFrameUniformList.push_back(fadeStart); + } for(unsigned int sm_i=0; sm_igetNumShadowMapsPerLight(); ++sm_i) { @@ -1518,14 +1519,16 @@ void MWShadowTechnique::createShaders() std::stringstream sstr; sstr<<"shadowTexture"< shadowTextureSampler = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i)); - _uniforms.push_back(shadowTextureSampler.get()); + for (auto& perFrameUniformList : _uniforms) + perFrameUniformList.push_back(shadowTextureSampler.get()); } { std::stringstream sstr; sstr<<"shadowTextureUnit"< shadowTextureUnit = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i)); - _uniforms.push_back(shadowTextureUnit.get()); + for (auto& perFrameUniformList : _uniforms) + perFrameUniformList.push_back(shadowTextureUnit.get()); } } @@ -2981,18 +2984,14 @@ osg::StateSet* MWShadowTechnique::selectStateSetForRenderingShadow(ViewDependent osg::ref_ptr stateset = vdd.getStateSet(traversalNumber); - std::lock_guard lock(_accessUniformsAndProgramMutex); - stateset->clear(); stateset->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); - for(Uniforms::const_iterator itr=_uniforms.begin(); - itr!=_uniforms.end(); - ++itr) + for(auto uniform : _uniforms[traversalNumber % 2]) { - OSG_INFO<<"addUniform("<<(*itr)->getName()<<")"<addUniform(itr->get()); + OSG_INFO<<"addUniform("<getName()<<")"<addUniform(uniform); } if (_program.valid()) diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 95f1117c0..bdfb44e46 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -248,8 +248,7 @@ namespace SceneUtil { osg::ref_ptr _fallbackShadowMapTexture; typedef std::vector< osg::ref_ptr > Uniforms; - mutable std::mutex _accessUniformsAndProgramMutex; - Uniforms _uniforms; + std::array _uniforms; osg::ref_ptr _program; bool _enableShadows; From fd14dad7897e0c80836b33d2ed281bb4da0b551a Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 20 Aug 2020 03:01:43 +0100 Subject: [PATCH 069/224] const osg::ref_ptf reference should be faster than value as constructor and destructor are non-trivial I played around in GodBolt and got into an argument to determine this. The difference will be immeasurably small, but my curiosity has been satisfied. --- components/sceneutil/mwshadowtechnique.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index 7a435fe90..dc22d4d80 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -2988,7 +2988,7 @@ osg::StateSet* MWShadowTechnique::selectStateSetForRenderingShadow(ViewDependent stateset->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); - for(auto uniform : _uniforms[traversalNumber % 2]) + for(const auto& uniform : _uniforms[traversalNumber % 2]) { OSG_INFO<<"addUniform("<getName()<<")"<addUniform(uniform); From 7c9497c4dec8063c34f8189ffe1169ed6bc0d619 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 21 Aug 2020 12:52:26 +0400 Subject: [PATCH 070/224] Use two columns when there is too many checkboxes in launcher's tab --- apps/launcher/advancedpage.cpp | 4 +- files/ui/advancedpage.ui | 1054 +++++++++++++++++--------------- 2 files changed, 564 insertions(+), 494 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 1cc77ec6d..bc14a9269 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -127,7 +127,7 @@ bool Launcher::AdvancedPage::loadSettings() { loadSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); connect(viewOverShoulderCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotViewOverShoulderToggled(bool))); - viewOverShoulderGroup->setEnabled(viewOverShoulderCheckBox->checkState()); + viewOverShoulderVerticalLayout->setEnabled(viewOverShoulderCheckBox->checkState()); loadSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); loadSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); @@ -339,5 +339,5 @@ void Launcher::AdvancedPage::slotAnimSourcesToggled(bool checked) void Launcher::AdvancedPage::slotViewOverShoulderToggled(bool checked) { - viewOverShoulderGroup->setEnabled(viewOverShoulderCheckBox->checkState()); + viewOverShoulderVerticalLayout->setEnabled(viewOverShoulderCheckBox->checkState()); } diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 4f1a30d4c..9084a7aba 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -2,6 +2,14 @@ AdvancedPage + + + 0 + 0 + 617 + 487 + + @@ -14,74 +22,128 @@ - - - <html><head/><body><p>This setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. </p></body></html> - - - Toggle sneak - - - - - - - <html><head/><body><p>If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.</p><p>If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.</p></body></html> - - - Can loot during death animation - - - - - - - <html><head/><body><p>Make player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.</p></body></html> - - - Followers defend immediately - - - - - - - <html><head/><body><p>Make the value of filled soul gems dependent only on soul magnitude.</p></body></html> - - - Soulgem values rebalance - - - - - - - <html><head/><body><p>Make enchanted weaponry without Magical flag bypass normal weapons resistance, like in Morrowind.</p></body></html> - - - Enchanted weapons are magical - - - - - - - <html><head/><body><p>Make disposition change of merchants caused by trading permanent.</p></body></html> - - - Permanent barter disposition changes - - - - - - - <html><head/><body><p>Effects of reflected Absorb spells are not mirrored -- like in Morrowind.</p></body></html> - - - Classic reflected Absorb spells behavior - - + + + + + <html><head/><body><p>Make enchanted weaponry without Magical flag bypass normal weapons resistance, like in Morrowind.</p></body></html> + + + Enchanted weapons are magical + + + + + + + <html><head/><body><p>Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.</p></body></html> + + + Swim upward correction + + + + + + + <html><head/><body><p>Enable navigator. When enabled background threads are started to build nav mesh for world geometry. Pathfinding system uses nav mesh to build paths. When disabled only pathgrid is used to build paths. Single-core CPU systems may have big performance impact on exiting interior location and moving across exterior world. May slightly affect performance on multi-core CPU systems. Multi-core CPU systems may have different latency for nav mesh update depending on other settings and system performance. Moving across external world, entering/exiting location produce nav mesh update. NPC and creatures may not be able to find path before nav mesh is built around them. Try to disable this if you want to have old fashioned AI which doesn’t know where to go when you stand behind that stone and casting a firebolt.</p></body></html> + + + Build nav mesh for world geometry + + + + + + + <html><head/><body><p>This setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. </p></body></html> + + + Toggle sneak + + + + + + + <html><head/><body><p>Make disposition change of merchants caused by trading permanent.</p></body></html> + + + Permanent barter disposition changes + + + + + + + <html><head/><body><p>Don't use race weight in NPC movement speed calculations.</p></body></html> + + + Racial variation in speed fix + + + + + + + <html><head/><body><p>Make Damage Fatigue magic effect uncapped like Drain Fatigue effect.</p><p>This means that unlike Morrowind you will be able to knock down actors using this effect.</p></body></html> + + + Uncapped Damage Fatigue + + + + + + + <html><head/><body><p>If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.</p><p>If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.</p></body></html> + + + Can loot during death animation + + + + + + + <html><head/><body><p>Make the value of filled soul gems dependent only on soul magnitude.</p></body></html> + + + Soulgem values rebalance + + + + + + + <html><head/><body><p>Make player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.</p></body></html> + + + Followers defend immediately + + + + + + + <html><head/><body><p>Effects of reflected Absorb spells are not mirrored -- like in Morrowind.</p></body></html> + + + Classic reflected Absorb spells behavior + + + + + + + <html><head/><body><p>Make stealing items from NPCs that were knocked down possible during combat.</p></body></html> + + + Always allow stealing from knocked out actors + + + + @@ -94,98 +156,62 @@ - - - <html><head/><body><p>Make Damage Fatigue magic effect uncapped like Drain Fatigue effect.</p><p>This means that unlike Morrowind you will be able to knock down actors using this effect.</p></body></html> - - - Uncapped Damage Fatigue - - - - - - - <html><head/><body><p>Don't use race weight in NPC movement speed calculations.</p></body></html> - - - Racial variation in speed fix - - - - - - - <html><head/><body><p>Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.</p></body></html> - - - Swim upward correction - - - - - - - <html><head/><body><p>Factor strength into hand-to-hand damage calculations, as the MCP formula: damage * (strength / 40).</p><p>The default value is Off.</p></body></html> - - - - + + + + + Factor strength into hand-to-hand combat: + + + + + + + 0 + + - Factor strength into hand-to-hand combat: + Off - - - - - - 0 + + + + Affect werewolves - - - Off - - - - - Affect werewolves - - - - - Do not affect werewolves - - - - - - + + + + Do not affect werewolves + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - <html><head/><body><p>Make stealing items from NPCs that were knocked down possible during combat.</p></body></html> - - - Always allow stealing from knocked out actors - - - - - - - <html><head/><body><p>Enable navigator. When enabled background threads are started to build nav mesh for world geometry. Pathfinding system uses nav mesh to build paths. When disabled only pathgrid is used to build paths. Single-core CPU systems may have big performance impact on exiting interior location and moving across exterior world. May slightly affect performance on multi-core CPU systems. Multi-core CPU systems may have different latency for nav mesh update depending on other settings and system performance. Moving across external world, entering/exiting location produce nav mesh update. NPC and creatures may not be able to find path before nav mesh is built around them. Try to disable this if you want to have old fashioned AI which doesn’t know where to go when you stand behind that stone and casting a firebolt.</p></body></html> - - - Build nav mesh for world geometry - - - - - + Qt::Vertical + + + 20 + 40 + + @@ -196,196 +222,197 @@ - - - <html><head/><body><p>If this option is enabled, normal maps are automatically recognized and used if they are named appropriately + + + + + <html><head/><body><p>Affects side and diagonal movement. Enabling this setting makes movement more realistic.</p><p>If disabled then the whole character's body is pointed to the direction of view. Diagonal movement has no special animation and causes sliding.</p><p>If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it changes straight right and straight left movement as well. Also turns the whole body up or down when swimming according to the movement direction.</p></body></html> + + + Turn to movement direction + + + + + + + <html><head/><body><p>If true, use paging and LOD algorithms to display the entire terrain. If false, only display terrain of the loaded cells.</p></body></html> + + + Distant land + + + + + + + <html><head/><body><p>See 'auto use object normal maps'. Affects terrain.</p></body></html> + + + Auto use terrain normal maps + + + + + + + <html><head/><body><p>If a file with pattern 'terrain specular map pattern' exists, use that file as a 'diffuse specular' map. The texture must contain the layer colour in the RGB channel (as usual), and a specular multiplier in the alpha channel.</p></body></html> + + + Auto use terrain specular maps + + + + + + + <html><head/><body><p>Use object paging for active cells grid.</p></body></html> + + + Active grid object paging + + + + + + + <html><head/><body><p>Use casting animations for magic items, just as for spells.</p></body></html> + + + Use magic item animation + + + + + + + <html><head/><body><p>Load per-group KF-files and skeleton files from Animations folder</p></body></html> + + + Use additional animation sources + + + + + + + <html><head/><body><p>If this option is enabled, normal maps are automatically recognized and used if they are named appropriately (see 'normal map pattern', e.g. for a base texture foo.dds, the normal map texture would have to be named foo_n.dds). If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file (.nif or .osg file). Affects objects.</p></body></html> - - - Auto use object normal maps - - - - - - - <html><head/><body><p>If this option is enabled, specular maps are automatically recognized and used if they are named appropriately + + + Auto use object normal maps + + + + + + + <html><head/><body><p>Normally environment map reflections aren't affected by lighting, which makes environment-mapped (and thus bump-mapped objects) glow in the dark. +Morrowind Code Patch includes an option to remedy that by doing environment-mapping before applying lighting, this is the equivalent of that option. +Affected objects will use shaders. +</p></body></html> + + + Bump/reflect map local lighting + + + + + + + + + Viewing distance + + + + + + + Cells + + + 0.000000000000000 + + + 0.500000000000000 + + + + + + + + + <html><head/><body><p>If this option is enabled, specular maps are automatically recognized and used if they are named appropriately (see 'specular map pattern', e.g. for a base texture foo.dds, the specular map texture would have to be named foo_spec.dds). If this option is disabled, normal maps are only used if they are explicitly listed within the mesh file (.osg file, not supported in .nif files). Affects objects.</p></body></html> - - - Auto use object specular maps - - - - - - - <html><head/><body><p>See 'auto use object normal maps'. Affects terrain.</p></body></html> - - - Auto use terrain normal maps - - - - - - - <html><head/><body><p>If a file with pattern 'terrain specular map pattern' exists, use that file as a 'diffuse specular' map. The texture must contain the layer colour in the RGB channel (as usual), and a specular multiplier in the alpha channel.</p></body></html> - - - Auto use terrain specular maps - - - - - - - <html><head/><body><p>Normally environment map reflections aren't affected by lighting, which makes environment-mapped (and thus bump-mapped objects) glow in the dark. -Morrowind Code Patch includes an option to remedy that by doing environment-mapping before applying lighting, this is the equivalent of that option. -Affected objects will use shaders. -</p></body></html> - - - Bump/reflect map local lighting - - - - - - - <html><head/><body><p>By default, the fog becomes thicker proportionally to your distance from the clipping plane set at the clipping distance, which causes distortion at the edges of the screen. + + + Auto use object specular maps + + + + + + + <html><head/><body><p>By default, the fog becomes thicker proportionally to your distance from the clipping plane set at the clipping distance, which causes distortion at the edges of the screen. This setting makes the fog use the actual eye point distance (or so called Euclidean distance) to calculate the fog, which makes the fog look less artificial, especially if you have a wide FOV.</p></body></html> - - - Radial fog - - + + + Radial fog + + + + - - - <html><head/><body><p>Use casting animations for magic items, just as for spells.</p></body></html> + + + 20 - - Use magic item animation - - + + + + false + + + <html><head/><body><p>Render holstered weapons (with quivers and scabbards), requires modded assets.</p></body></html> + + + Weapon sheathing + + + + + + + false + + + <html><head/><body><p>Render holstered shield, requires modded assets.</p></body></html> + + + Shield sheathing + + + + - - - <html><head/><body><p>Load per-group KF-files and skeleton files from Animations folder</p></body></html> - - - Use additional animation sources - - - - - - - - 20 - - - - - false - - - <html><head/><body><p>Render holstered weapons (with quivers and scabbards), requires modded assets.</p></body></html> - - - Weapon sheathing - - - - - - - false - - - <html><head/><body><p>Render holstered shield, requires modded assets.</p></body></html> - - - Shield sheathing - - - - - - - - - - <html><head/><body><p>Affects side and diagonal movement. Enabling this setting makes movement more realistic.</p><p>If disabled then the whole character's body is pointed to the direction of view. Diagonal movement has no special animation and causes sliding.</p><p>If enabled then the character turns lower body to the direction of movement. Upper body is turned partially. Head is always pointed to the direction of view. In combat mode it works only for diagonal movement. In non-combat mode it changes straight right and straight left movement as well. Also turns the whole body up or down when swimming according to the movement direction.</p></body></html> - - - Turn to movement direction - - - - - - - <html><head/><body><p>If true, use paging and LOD algorithms to display the entire terrain. If false, only display terrain of the loaded cells.</p></body></html> - - - Distant land - - - - - - - <html><head/><body><p>Use object paging for active cells grid.</p></body></html> - - - Active grid object paging - - - - - - - <html><head/><body><p>This value controls the maximum visible distance (in cell units). -Larger values significantly improve rendering in exterior spaces, -but also increase the amount of rendered geometry and significantly reduce the frame rate.</p></body></html> - - - - - - Viewing distance - - - - - - - 0.0 - - - 0.5 - - - Cells - - - - - - - - + Qt::Vertical + + + 20 + 40 + + @@ -408,75 +435,84 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C - - - - 20 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Default shoulder: - - - - - - - 0 - - - - Right - - - - - Left - - - - - - - - - - - <html><head/><body><p>When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle.</p></body></html> - - - Auto switch shoulder - - - - + + + <html><head/><body><p>When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle.</p></body></html> + + + Auto switch shoulder + + + + + 20 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Default shoulder: + + + + + + + 0 + + + + Right + + + + + Left + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -502,6 +538,12 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C Qt::Vertical + + + 0 + 0 + + @@ -511,6 +553,57 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C Interface + + + + + + Show owned: + + + + + + + 1 + + + + Off + + + + + Tool Tip Only + + + + + Crosshair Only + + + + + Tool Tip and Crosshair + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -561,54 +654,17 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C - - - - <html><head/><body><p>Enable visual clues for items owned by NPCs when the crosshair is on the object.</p><p>The default value is Off.</p></body></html> - - - - - - Show owned: - - - - - - - 1 - - - - Off - - - - - Tool Tip Only - - - - - Crosshair Only - - - - - Tool Tip and Crosshair - - - - - - - - + Qt::Vertical + + + 20 + 40 + + @@ -643,6 +699,12 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C Qt::Vertical + + + 0 + 0 + + @@ -668,28 +730,23 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C - - - - <html><head/><body><p>This setting determines how many quicksave and autosave slots you can have at a time. If greater than 1, quicksaves will be sequentially created each time you quicksave. Once the maximum number of quicksaves has been reached, the oldest quicksave will be recycled the next time you perform a quicksave.</p></body></html> - - - - - - Maximum Quicksaves - - - - - - - 1 - - - - - + + + + + + Maximum Quicksaves + + + + + + + 1 + + + + @@ -700,40 +757,35 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C Other - - - - <html><head/><body><p>Specify the format for screen shots taken by pressing the screen shot key (bound to F12 by default). This setting should be the file extension commonly associated with the desired format. The formats supported will be determined at compilation, but “jpg”, “png”, and “tga” should be allowed.</p></body></html> - - - - + + + + + + Screenshot Format + + + + + + - Screenshot Format + JPG - - - - - - - JPG - - - - - PNG - - - - - TGA - - - - - - + + + + PNG + + + + + TGA + + + + + @@ -743,6 +795,12 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C Qt::Vertical + + + 0 + 0 + + @@ -796,6 +854,12 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C QSizePolicy::Fixed + + + 0 + 0 + + @@ -840,6 +904,12 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C Qt::Vertical + + + 0 + 0 + + From b60d5904e2f6ea6e55096d0405b3e5754d94f6db Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 26 Aug 2020 00:16:14 +0100 Subject: [PATCH 071/224] Correct SDL_GetNumVideoDisplays error message It logged the wrong function --- apps/launcher/graphicspage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 45c093bee..01992dcce 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -65,7 +65,7 @@ bool Launcher::GraphicsPage::setupSDL() msgBox.setWindowTitle(tr("Error receiving number of screens")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
SDL_GetNumDisplayModes failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); + msgBox.setText(tr("
SDL_GetNumVideoDisplays failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); msgBox.exec(); return false; } From f9e667dd8c5e7311e05b3d3ed7d70011d91b0ad4 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 26 Aug 2020 12:34:27 +0400 Subject: [PATCH 072/224] Fix MSVC warnings --- apps/openmw/mwphysics/physicssystem.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index ade8775e6..26005b396 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -57,7 +57,7 @@ namespace MWPhysics { public: PhysicsSystem (Resource::ResourceSystem* resourceSystem, osg::ref_ptr parentNode); - ~PhysicsSystem (); + virtual ~PhysicsSystem (); void setUnrefQueue(SceneUtil::UnrefQueue* unrefQueue); @@ -109,17 +109,17 @@ namespace MWPhysics /// target vector hits the collision shape and then calculates distance from the intersection point. /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful. /// \note Only Actor targets are supported at the moment. - float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const final; + float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const override final; /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors. RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), std::vector targets = std::vector(), - int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const final; + int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const override final; - RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const final; + RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const override final; /// Return true if actor1 can see actor2. - bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const final; + bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const override final; bool isOnGround (const MWWorld::Ptr& actor); From 5538fea1d17d11ca632a6a306951c2f07791db34 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 26 Aug 2020 16:58:12 +0100 Subject: [PATCH 073/224] Display standard resolutions on single-monitor machines --- apps/launcher/graphicspage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 01992dcce..c1a946145 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -75,6 +75,7 @@ bool Launcher::GraphicsPage::setupSDL() { screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1)); } + screenChanged(0); // Disconnect from SDL processes quitSDL(); From a495888d3d56042423c8bd6f5b39c1168ee5aba0 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 26 Aug 2020 16:58:51 +0100 Subject: [PATCH 074/224] Get per-monitor resolution list while SDL is alive --- apps/launcher/graphicspage.cpp | 4 +++- apps/launcher/graphicspage.hpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index c1a946145..c745332dc 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -71,8 +71,10 @@ bool Launcher::GraphicsPage::setupSDL() } screenComboBox->clear(); + mResolutionsPerScreen.clear(); for (int i = 0; i < displays; i++) { + mResolutionsPerScreen.append(getAvailableResolutions(i)); screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1)); } screenChanged(0); @@ -332,7 +334,7 @@ void Launcher::GraphicsPage::screenChanged(int screen) { if (screen >= 0) { resolutionComboBox->clear(); - resolutionComboBox->addItems(getAvailableResolutions(screen)); + resolutionComboBox->addItems(mResolutionsPerScreen[screen]); } } diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 4ce5b584f..3b03a72bd 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -38,6 +38,8 @@ namespace Launcher Files::ConfigurationManager &mCfgMgr; Settings::Manager &mEngineSettings; + QVector mResolutionsPerScreen; + static QStringList getAvailableResolutions(int screen); static QRect getMaximumResolution(); From b71f13965a2773a8bad256cafed8b631d755ba91 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 27 Aug 2020 02:30:40 +0100 Subject: [PATCH 075/224] Don't set pipefail --- CI/activate_msvc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/activate_msvc.sh b/CI/activate_msvc.sh index 1641f6b3e..05925737a 100644 --- a/CI/activate_msvc.sh +++ b/CI/activate_msvc.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -euo pipefail +set -eu if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then echo "Error: Script not sourced." From 70384d8a83bac54e14c3446a914e726061f37786 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 27 Aug 2020 03:03:03 +0100 Subject: [PATCH 076/224] Restore previous bash settings on exit --- CI/activate_msvc.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/CI/activate_msvc.sh b/CI/activate_msvc.sh index 05925737a..47f2c246f 100644 --- a/CI/activate_msvc.sh +++ b/CI/activate_msvc.sh @@ -1,13 +1,24 @@ #!/bin/bash +oldSettings=$- set -eu +function restoreOldSettings { + if [[ $oldSettings != *e* ]]; then + set +e + fi + if [[ $oldSettings != *u* ]]; then + set +u + fi +} + if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then echo "Error: Script not sourced." echo "You must source this script for it to work, i.e. " echo "source ./activate_msvc.sh" echo "or" echo ". ./activate_msvc.sh" + restoreOldSettings exit 1 fi @@ -78,7 +89,10 @@ command -v mt >/dev/null 2>&1 || { echo "Error: mt (MS Windows Manifest Tool) mi if [ $MISSINGTOOLS -ne 0 ]; then echo "Some build tools were unavailable after activating MSVC in the shell. It's likely that your Visual Studio $MSVC_DISPLAY_YEAR installation needs repairing." + restoreOldSettings return 1 fi -IFS="$originalIFS" \ No newline at end of file +IFS="$originalIFS" + +restoreOldSettings \ No newline at end of file From f90a049702d1439267a2c7b78a39bfc16a874470 Mon Sep 17 00:00:00 2001 From: psi29a Date: Thu, 27 Aug 2020 11:48:59 +0000 Subject: [PATCH 077/224] Merge branch 'movement_refactoring' into 'master' Refactoring related to "smooth movement" See merge request OpenMW/openmw!285 (cherry picked from commit 6eaf0a389d5aed3b74ab1a7cf89574612f964bdf) e847b4c8 Split getSpeed() to getMaxSpeed() and getCurrentSpeed() a96c46bc Refactor calculation of movement.mSpeedFactor 03ee9090 Use getMaxSpeed instead of getCurrentSpeed where it makes sense. a178af5c Create helper functions `normalizeAngle` and `rotateVec2f` --- apps/openmw/mwclass/actor.cpp | 9 ++++++ apps/openmw/mwclass/actor.hpp | 5 +++- apps/openmw/mwclass/creature.cpp | 7 +---- apps/openmw/mwclass/creature.hpp | 2 +- apps/openmw/mwclass/npc.cpp | 7 +---- apps/openmw/mwclass/npc.hpp | 4 +-- apps/openmw/mwmechanics/actors.cpp | 12 ++++---- apps/openmw/mwmechanics/aipackage.cpp | 6 ++-- apps/openmw/mwmechanics/character.cpp | 41 +++++++++------------------ apps/openmw/mwmechanics/movement.hpp | 6 ++++ apps/openmw/mwmechanics/obstacle.cpp | 2 +- apps/openmw/mwmechanics/steering.cpp | 2 +- apps/openmw/mwrender/camera.cpp | 24 ++++------------ apps/openmw/mwworld/class.cpp | 7 ++++- apps/openmw/mwworld/class.hpp | 19 +++++++------ components/misc/mathutil.hpp | 27 ++++++++++++++++++ 16 files changed, 97 insertions(+), 83 deletions(-) create mode 100644 components/misc/mathutil.hpp diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 4eb9728a1..61d6e7347 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -91,4 +91,13 @@ namespace MWClass { return true; } + + float Actor::getCurrentSpeed(const MWWorld::Ptr& ptr) const + { + const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr); + float moveSpeed = this->getMaxSpeed(ptr) * movementSettings.mSpeedFactor; + if (movementSettings.mIsStrafing) + moveSpeed *= 0.75f; + return moveSpeed; + } } diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index 7cdee8061..6ccd552f9 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -31,7 +31,7 @@ namespace MWClass virtual void block(const MWWorld::Ptr &ptr) const; virtual osg::Vec3f getRotationVector(const MWWorld::Ptr& ptr) const; - ///< Return desired rotations, as euler angles. + ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. virtual float getEncumbrance(const MWWorld::Ptr& ptr) const; ///< Returns total weight of objects inside this object (including modifications from magic @@ -42,6 +42,9 @@ namespace MWClass virtual bool isActor() const; + /// Return current movement speed. + virtual float getCurrentSpeed(const MWWorld::Ptr& ptr) const; + // not implemented Actor(const Actor&); Actor& operator= (const Actor&); diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 15e0fa6ab..5c5524a12 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -500,7 +500,7 @@ namespace MWClass registerClass (typeid (ESM::Creature).name(), instance); } - float Creature::getSpeed(const MWWorld::Ptr &ptr) const + float Creature::getMaxSpeed(const MWWorld::Ptr &ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); @@ -532,11 +532,6 @@ namespace MWClass else moveSpeed = getWalkSpeed(ptr); - const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr); - if (movementSettings.mIsStrafing) - moveSpeed *= 0.75f; - moveSpeed *= movementSettings.mSpeedFactor; - return moveSpeed; } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 2d7aa5a19..ca991052b 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -94,7 +94,7 @@ namespace MWClass virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. - float getSpeed (const MWWorld::Ptr& ptr) const; + float getMaxSpeed (const MWWorld::Ptr& ptr) const; static void registerSelf(); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0c00d3bd1..b89d79fc9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -936,7 +936,7 @@ namespace MWClass return ref->mBase->mScript; } - float Npc::getSpeed(const MWWorld::Ptr& ptr) const + float Npc::getMaxSpeed(const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) @@ -979,11 +979,6 @@ namespace MWClass if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing) moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat(); - const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr); - if (movementSettings.mIsStrafing) - moveSpeed *= 0.75f; - moveSpeed *= movementSettings.mSpeedFactor; - return moveSpeed; } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index d52afcd82..1ed4e8cae 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -84,8 +84,8 @@ namespace MWClass virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; ///< Return name of the script attached to ptr - virtual float getSpeed (const MWWorld::Ptr& ptr) const; - ///< Return movement speed. + virtual float getMaxSpeed (const MWWorld::Ptr& ptr) const; + ///< Return maximal movement speed. virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index b91b01e4a..14a2e17c9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -472,9 +472,6 @@ namespace MWMechanics void Actors::updateMovementSpeed(const MWWorld::Ptr& actor) { - float previousSpeedFactor = actor.getClass().getMovementSettings(actor).mSpeedFactor; - float newSpeedFactor = 1.f; - CreatureStats &stats = actor.getClass().getCreatureStats(actor); MWMechanics::AiSequence& seq = stats.getAiSequence(); @@ -484,10 +481,13 @@ namespace MWMechanics osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); float distance = (targetPos - actorPos).length(); if (distance < DECELERATE_DISTANCE) - newSpeedFactor = std::max(0.7f, 0.1f * previousSpeedFactor * (distance/64.f + 2.f)); + { + float speedCoef = std::max(0.7f, 0.1f * (distance/64.f + 2.f)); + auto& movement = actor.getClass().getMovementSettings(actor); + movement.mPosition[0] *= speedCoef; + movement.mPosition[1] *= speedCoef; + } } - - actor.getClass().getMovementSettings(actor).mSpeedFactor = newSpeedFactor; } void Actors::updateGreetingState(const MWWorld::Ptr& actor, Actor& actorState, bool turnOnly) diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index f7c07bde0..53e366579 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -144,7 +144,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& mTimer = 0; } - const float actorTolerance = 2 * actor.getClass().getSpeed(actor) * duration + const float actorTolerance = 2 * actor.getClass().getMaxSpeed(actor) * duration + 1.2 * std::max(halfExtents.x(), halfExtents.y()); const float pointTolerance = std::max(MIN_TOLERANCE, actorTolerance); @@ -300,7 +300,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin if (canActorMoveByZAxis(actor)) return true; - const float actorSpeed = actor.getClass().getSpeed(actor); + const float actorSpeed = actor.getClass().getMaxSpeed(actor); const float maxAvoidDist = AI_REACTION_TIME * actorSpeed + actorSpeed / getAngularVelocity(actorSpeed) * 2; // *2 - for reliability const float distToTarget = osg::Vec2f(endPoint.x(), endPoint.y()).length(); @@ -360,7 +360,7 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position) bool MWMechanics::AiPackage::isReachableRotatingOnTheRun(const MWWorld::Ptr& actor, const osg::Vec3f& dest) { // get actor's shortest radius for moving in circle - float speed = actor.getClass().getSpeed(actor); + float speed = actor.getClass().getMaxSpeed(actor); speed += speed * 0.1f; // 10% real speed inaccuracy float radius = speed / getAngularVelocity(speed); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2ff8241f4..5d102f69e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -21,6 +21,7 @@ #include +#include #include #include @@ -51,15 +52,6 @@ namespace { -// Wraps a value to (-PI, PI] -void wrap(float& rad) -{ - if (rad>0) - rad = std::fmod(rad+osg::PI, 2.0f*osg::PI)-osg::PI; - else - rad = std::fmod(rad-osg::PI, 2.0f*osg::PI)+osg::PI; -} - std::string getBestAttack (const ESM::Weapon* weapon) { int slash = (weapon->mData.mSlash[0] + weapon->mData.mSlash[1])/2; @@ -1958,23 +1950,19 @@ void CharacterController::update(float duration, bool animationOnly) osg::Vec3f rot = cls.getRotationVector(mPtr); osg::Vec3f vec(movementSettings.asVec3()); - vec.normalize(); - float analogueMult = 1.0f; if (isPlayer) { // TODO: Move this code to mwinput. // Joystick analogue movement. - float xAxis = std::abs(movementSettings.mPosition[0]); - float yAxis = std::abs(movementSettings.mPosition[1]); - analogueMult = std::max(xAxis, yAxis); + movementSettings.mSpeedFactor = std::max(std::abs(vec.x()), std::abs(vec.y())); // Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a keyboard was used. - if(!isrunning && !sneak && !flying && analogueMult <= 0.5f) - analogueMult *= 2.f; - - movementSettings.mSpeedFactor = analogueMult; - } + if(!isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) + movementSettings.mSpeedFactor *= 2.f; + } else + movementSettings.mSpeedFactor = std::min(vec.length(), 1.f); + vec.normalize(); float effectiveRotation = rot.z(); static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); @@ -2007,7 +1995,7 @@ void CharacterController::update(float duration, bool animationOnly) else mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 4); - speed = cls.getSpeed(mPtr); + speed = cls.getCurrentSpeed(mPtr); vec.x() *= speed; vec.y() *= speed; @@ -2077,7 +2065,7 @@ void CharacterController::update(float duration, bool animationOnly) } } fatigueLoss *= duration; - fatigueLoss *= analogueMult; + fatigueLoss *= movementSettings.mSpeedFactor; DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); if (!godmode) @@ -2908,13 +2896,10 @@ void CharacterController::updateHeadTracking(float duration) zAngleRadians = std::atan2(direction.x(), direction.y()) - std::atan2(actorDirection.x(), actorDirection.y()); xAngleRadians = -std::asin(direction.z()); - wrap(zAngleRadians); - wrap(xAngleRadians); - - xAngleRadians = std::min(xAngleRadians, osg::DegreesToRadians(40.f)); - xAngleRadians = std::max(xAngleRadians, osg::DegreesToRadians(-40.f)); - zAngleRadians = std::min(zAngleRadians, osg::DegreesToRadians(30.f)); - zAngleRadians = std::max(zAngleRadians, osg::DegreesToRadians(-30.f)); + const double xLimit = osg::DegreesToRadians(40.0); + const double zLimit = osg::DegreesToRadians(30.0); + zAngleRadians = osg::clampBetween(Misc::normalizeAngle(zAngleRadians), -xLimit, xLimit); + xAngleRadians = osg::clampBetween(Misc::normalizeAngle(xAngleRadians), -zLimit, zLimit); } float factor = duration*5; diff --git a/apps/openmw/mwmechanics/movement.hpp b/apps/openmw/mwmechanics/movement.hpp index 86b970e60..57e106cde 100644 --- a/apps/openmw/mwmechanics/movement.hpp +++ b/apps/openmw/mwmechanics/movement.hpp @@ -8,8 +8,14 @@ namespace MWMechanics /// Desired movement for an actor struct Movement { + // Desired movement. Direction is relative to the current orientation. + // Length of the vector controls desired speed. 0 - stay, 0.5 - half-speed, 1.0 - max speed. float mPosition[3]; + // Desired rotation delta (euler angles). float mRotation[3]; + + // Controlled by CharacterController, should not be changed from other places. + // These fields can not be private fields in CharacterController, because Actor::getCurrentSpeed uses it. float mSpeedFactor; bool mIsStrafing; diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index 715dfecd2..88325ee7c 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -122,7 +122,7 @@ namespace MWMechanics if (mWalkState != WalkState::Evade) { - const float distSameSpot = DIST_SAME_SPOT * actor.getClass().getSpeed(actor) * duration; + const float distSameSpot = DIST_SAME_SPOT * actor.getClass().getCurrentSpeed(actor) * duration; const float prevDistance = (destination - mPrev).length(); const float currentDistance = (destination - position).length(); const float movedDistance = prevDistance - currentDistance; diff --git a/apps/openmw/mwmechanics/steering.cpp b/apps/openmw/mwmechanics/steering.cpp index b08a90220..d442085ea 100644 --- a/apps/openmw/mwmechanics/steering.cpp +++ b/apps/openmw/mwmechanics/steering.cpp @@ -32,7 +32,7 @@ bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, f if (absDiff < epsilonRadians) return true; - float limit = getAngularVelocity(actor.getClass().getSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); + float limit = getAngularVelocity(actor.getClass().getMaxSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); if (absDiff > limit) diff = osg::sign(diff) * limit; diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 40cc9895d..0d6ed262b 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -200,7 +201,7 @@ namespace MWRender updateFocalPointOffset(duration); updatePosition(); - float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr); + float speed = mTrackingPtr.getClass().getCurrentSpeed(mTrackingPtr); speed /= (1.f + speed / 500.f); float maxDelta = 300.f * duration; mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta); @@ -249,7 +250,7 @@ namespace MWRender { if (!mStandingPreviewAllowed) return; - float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr); + float speed = mTrackingPtr.getClass().getCurrentSpeed(mTrackingPtr); bool combat = mTrackingPtr.getClass().isActor() && mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).getDrawState() != MWMechanics::DrawState_Nothing; bool standingStill = speed == 0 && !combat && !mFirstPersonView; @@ -396,12 +397,7 @@ namespace MWRender void Camera::setYaw(float angle) { - if (angle > osg::PI) { - angle -= osg::PI*2; - } else if (angle < -osg::PI) { - angle += osg::PI*2; - } - mYaw = angle; + mYaw = Misc::normalizeAngle(angle); } void Camera::setPitch(float angle) @@ -538,16 +534,8 @@ namespace MWRender return; } - mDeferredRotation.x() = -ptr.getRefData().getPosition().rot[0] - mPitch; - mDeferredRotation.z() = -ptr.getRefData().getPosition().rot[2] - mYaw; - if (mDeferredRotation.x() > osg::PI) - mDeferredRotation.x() -= 2 * osg::PI; - if (mDeferredRotation.x() < -osg::PI) - mDeferredRotation.x() += 2 * osg::PI; - if (mDeferredRotation.z() > osg::PI) - mDeferredRotation.z() -= 2 * osg::PI; - if (mDeferredRotation.z() < -osg::PI) - mDeferredRotation.z() += 2 * osg::PI; + mDeferredRotation.x() = Misc::normalizeAngle(-ptr.getRefData().getPosition().rot[0] - mPitch); + mDeferredRotation.z() = Misc::normalizeAngle(-ptr.getRefData().getPosition().rot[2] - mYaw); } } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index ad8766d06..950c8a6d4 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -159,7 +159,12 @@ namespace MWWorld return ""; } - float Class::getSpeed (const Ptr& ptr) const + float Class::getMaxSpeed (const Ptr& ptr) const + { + return 0; + } + + float Class::getCurrentSpeed (const Ptr& ptr) const { return 0; } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index e82712220..445f2e986 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -172,8 +172,15 @@ namespace MWWorld ///< Return name of the script attached to ptr (default implementation: return an empty /// string). - virtual float getSpeed (const Ptr& ptr) const; - ///< Return movement speed. + virtual float getWalkSpeed(const Ptr& ptr) const; + virtual float getRunSpeed(const Ptr& ptr) const; + virtual float getSwimSpeed(const Ptr& ptr) const; + + /// Return maximal movement speed for the current state. + virtual float getMaxSpeed(const Ptr& ptr) const; + + /// Return current movement speed. + virtual float getCurrentSpeed(const Ptr& ptr) const; virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) @@ -182,7 +189,7 @@ namespace MWWorld ///< Return desired movement. virtual osg::Vec3f getRotationVector (const Ptr& ptr) const; - ///< Return desired rotations, as euler angles. + ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. virtual std::pair, bool> getEquipmentSlots (const ConstPtr& ptr) const; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object @@ -364,12 +371,6 @@ namespace MWWorld virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; - - virtual float getWalkSpeed(const Ptr& ptr) const; - - virtual float getRunSpeed(const Ptr& ptr) const; - - virtual float getSwimSpeed(const Ptr& ptr) const; }; } diff --git a/components/misc/mathutil.hpp b/components/misc/mathutil.hpp new file mode 100644 index 000000000..2f7f446b5 --- /dev/null +++ b/components/misc/mathutil.hpp @@ -0,0 +1,27 @@ +#ifndef MISC_MATHUTIL_H +#define MISC_MATHUTIL_H + +#include +#include + +namespace Misc +{ + + /// Normalizes given angle to the range [-PI, PI]. E.g. PI*3/2 -> -PI/2. + inline double normalizeAngle(double angle) + { + double fullTurns = angle / (2 * osg::PI) + 0.5; + return (fullTurns - floor(fullTurns) - 0.5) * (2 * osg::PI); + } + + /// Rotates given 2d vector counterclockwise. Angle is in radians. + inline osg::Vec2f rotateVec2f(osg::Vec2f vec, float angle) + { + float s = std::sin(angle); + float c = std::cos(angle); + return osg::Vec2f(vec.x() * c + vec.y() * -s, vec.x() * s + vec.y() * c); + } + +} + +#endif From c495c21923dcc08a8360555b274eebb1e93347ba Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Thu, 27 Aug 2020 11:48:59 +0000 Subject: [PATCH 078/224] Merge branch 'movement_refactoring' into 'master' Refactoring related to "smooth movement" See merge request OpenMW/openmw!285 (cherry picked from commit 6eaf0a389d5aed3b74ab1a7cf89574612f964bdf) e847b4c8 Split getSpeed() to getMaxSpeed() and getCurrentSpeed() a96c46bc Refactor calculation of movement.mSpeedFactor 03ee9090 Use getMaxSpeed instead of getCurrentSpeed where it makes sense. a178af5c Create helper functions `normalizeAngle` and `rotateVec2f` --- apps/openmw/mwclass/actor.cpp | 9 ++++++ apps/openmw/mwclass/actor.hpp | 5 +++- apps/openmw/mwclass/creature.cpp | 7 +---- apps/openmw/mwclass/creature.hpp | 2 +- apps/openmw/mwclass/npc.cpp | 7 +---- apps/openmw/mwclass/npc.hpp | 4 +-- apps/openmw/mwmechanics/actors.cpp | 12 ++++---- apps/openmw/mwmechanics/aipackage.cpp | 6 ++-- apps/openmw/mwmechanics/character.cpp | 41 +++++++++------------------ apps/openmw/mwmechanics/movement.hpp | 6 ++++ apps/openmw/mwmechanics/obstacle.cpp | 2 +- apps/openmw/mwmechanics/steering.cpp | 2 +- apps/openmw/mwrender/camera.cpp | 24 ++++------------ apps/openmw/mwworld/class.cpp | 7 ++++- apps/openmw/mwworld/class.hpp | 19 +++++++------ components/misc/mathutil.hpp | 27 ++++++++++++++++++ 16 files changed, 97 insertions(+), 83 deletions(-) create mode 100644 components/misc/mathutil.hpp diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 4eb9728a1..61d6e7347 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -91,4 +91,13 @@ namespace MWClass { return true; } + + float Actor::getCurrentSpeed(const MWWorld::Ptr& ptr) const + { + const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr); + float moveSpeed = this->getMaxSpeed(ptr) * movementSettings.mSpeedFactor; + if (movementSettings.mIsStrafing) + moveSpeed *= 0.75f; + return moveSpeed; + } } diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index 7cdee8061..6ccd552f9 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -31,7 +31,7 @@ namespace MWClass virtual void block(const MWWorld::Ptr &ptr) const; virtual osg::Vec3f getRotationVector(const MWWorld::Ptr& ptr) const; - ///< Return desired rotations, as euler angles. + ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. virtual float getEncumbrance(const MWWorld::Ptr& ptr) const; ///< Returns total weight of objects inside this object (including modifications from magic @@ -42,6 +42,9 @@ namespace MWClass virtual bool isActor() const; + /// Return current movement speed. + virtual float getCurrentSpeed(const MWWorld::Ptr& ptr) const; + // not implemented Actor(const Actor&); Actor& operator= (const Actor&); diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 15e0fa6ab..5c5524a12 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -500,7 +500,7 @@ namespace MWClass registerClass (typeid (ESM::Creature).name(), instance); } - float Creature::getSpeed(const MWWorld::Ptr &ptr) const + float Creature::getMaxSpeed(const MWWorld::Ptr &ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); @@ -532,11 +532,6 @@ namespace MWClass else moveSpeed = getWalkSpeed(ptr); - const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr); - if (movementSettings.mIsStrafing) - moveSpeed *= 0.75f; - moveSpeed *= movementSettings.mSpeedFactor; - return moveSpeed; } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 2d7aa5a19..ca991052b 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -94,7 +94,7 @@ namespace MWClass virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. - float getSpeed (const MWWorld::Ptr& ptr) const; + float getMaxSpeed (const MWWorld::Ptr& ptr) const; static void registerSelf(); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0c00d3bd1..b89d79fc9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -936,7 +936,7 @@ namespace MWClass return ref->mBase->mScript; } - float Npc::getSpeed(const MWWorld::Ptr& ptr) const + float Npc::getMaxSpeed(const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) @@ -979,11 +979,6 @@ namespace MWClass if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing) moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat(); - const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr); - if (movementSettings.mIsStrafing) - moveSpeed *= 0.75f; - moveSpeed *= movementSettings.mSpeedFactor; - return moveSpeed; } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index d52afcd82..1ed4e8cae 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -84,8 +84,8 @@ namespace MWClass virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; ///< Return name of the script attached to ptr - virtual float getSpeed (const MWWorld::Ptr& ptr) const; - ///< Return movement speed. + virtual float getMaxSpeed (const MWWorld::Ptr& ptr) const; + ///< Return maximal movement speed. virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index b91b01e4a..14a2e17c9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -472,9 +472,6 @@ namespace MWMechanics void Actors::updateMovementSpeed(const MWWorld::Ptr& actor) { - float previousSpeedFactor = actor.getClass().getMovementSettings(actor).mSpeedFactor; - float newSpeedFactor = 1.f; - CreatureStats &stats = actor.getClass().getCreatureStats(actor); MWMechanics::AiSequence& seq = stats.getAiSequence(); @@ -484,10 +481,13 @@ namespace MWMechanics osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); float distance = (targetPos - actorPos).length(); if (distance < DECELERATE_DISTANCE) - newSpeedFactor = std::max(0.7f, 0.1f * previousSpeedFactor * (distance/64.f + 2.f)); + { + float speedCoef = std::max(0.7f, 0.1f * (distance/64.f + 2.f)); + auto& movement = actor.getClass().getMovementSettings(actor); + movement.mPosition[0] *= speedCoef; + movement.mPosition[1] *= speedCoef; + } } - - actor.getClass().getMovementSettings(actor).mSpeedFactor = newSpeedFactor; } void Actors::updateGreetingState(const MWWorld::Ptr& actor, Actor& actorState, bool turnOnly) diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index f7c07bde0..53e366579 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -144,7 +144,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& mTimer = 0; } - const float actorTolerance = 2 * actor.getClass().getSpeed(actor) * duration + const float actorTolerance = 2 * actor.getClass().getMaxSpeed(actor) * duration + 1.2 * std::max(halfExtents.x(), halfExtents.y()); const float pointTolerance = std::max(MIN_TOLERANCE, actorTolerance); @@ -300,7 +300,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin if (canActorMoveByZAxis(actor)) return true; - const float actorSpeed = actor.getClass().getSpeed(actor); + const float actorSpeed = actor.getClass().getMaxSpeed(actor); const float maxAvoidDist = AI_REACTION_TIME * actorSpeed + actorSpeed / getAngularVelocity(actorSpeed) * 2; // *2 - for reliability const float distToTarget = osg::Vec2f(endPoint.x(), endPoint.y()).length(); @@ -360,7 +360,7 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position) bool MWMechanics::AiPackage::isReachableRotatingOnTheRun(const MWWorld::Ptr& actor, const osg::Vec3f& dest) { // get actor's shortest radius for moving in circle - float speed = actor.getClass().getSpeed(actor); + float speed = actor.getClass().getMaxSpeed(actor); speed += speed * 0.1f; // 10% real speed inaccuracy float radius = speed / getAngularVelocity(speed); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2ff8241f4..5d102f69e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -21,6 +21,7 @@ #include +#include #include #include @@ -51,15 +52,6 @@ namespace { -// Wraps a value to (-PI, PI] -void wrap(float& rad) -{ - if (rad>0) - rad = std::fmod(rad+osg::PI, 2.0f*osg::PI)-osg::PI; - else - rad = std::fmod(rad-osg::PI, 2.0f*osg::PI)+osg::PI; -} - std::string getBestAttack (const ESM::Weapon* weapon) { int slash = (weapon->mData.mSlash[0] + weapon->mData.mSlash[1])/2; @@ -1958,23 +1950,19 @@ void CharacterController::update(float duration, bool animationOnly) osg::Vec3f rot = cls.getRotationVector(mPtr); osg::Vec3f vec(movementSettings.asVec3()); - vec.normalize(); - float analogueMult = 1.0f; if (isPlayer) { // TODO: Move this code to mwinput. // Joystick analogue movement. - float xAxis = std::abs(movementSettings.mPosition[0]); - float yAxis = std::abs(movementSettings.mPosition[1]); - analogueMult = std::max(xAxis, yAxis); + movementSettings.mSpeedFactor = std::max(std::abs(vec.x()), std::abs(vec.y())); // Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a keyboard was used. - if(!isrunning && !sneak && !flying && analogueMult <= 0.5f) - analogueMult *= 2.f; - - movementSettings.mSpeedFactor = analogueMult; - } + if(!isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) + movementSettings.mSpeedFactor *= 2.f; + } else + movementSettings.mSpeedFactor = std::min(vec.length(), 1.f); + vec.normalize(); float effectiveRotation = rot.z(); static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); @@ -2007,7 +1995,7 @@ void CharacterController::update(float duration, bool animationOnly) else mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 4); - speed = cls.getSpeed(mPtr); + speed = cls.getCurrentSpeed(mPtr); vec.x() *= speed; vec.y() *= speed; @@ -2077,7 +2065,7 @@ void CharacterController::update(float duration, bool animationOnly) } } fatigueLoss *= duration; - fatigueLoss *= analogueMult; + fatigueLoss *= movementSettings.mSpeedFactor; DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); if (!godmode) @@ -2908,13 +2896,10 @@ void CharacterController::updateHeadTracking(float duration) zAngleRadians = std::atan2(direction.x(), direction.y()) - std::atan2(actorDirection.x(), actorDirection.y()); xAngleRadians = -std::asin(direction.z()); - wrap(zAngleRadians); - wrap(xAngleRadians); - - xAngleRadians = std::min(xAngleRadians, osg::DegreesToRadians(40.f)); - xAngleRadians = std::max(xAngleRadians, osg::DegreesToRadians(-40.f)); - zAngleRadians = std::min(zAngleRadians, osg::DegreesToRadians(30.f)); - zAngleRadians = std::max(zAngleRadians, osg::DegreesToRadians(-30.f)); + const double xLimit = osg::DegreesToRadians(40.0); + const double zLimit = osg::DegreesToRadians(30.0); + zAngleRadians = osg::clampBetween(Misc::normalizeAngle(zAngleRadians), -xLimit, xLimit); + xAngleRadians = osg::clampBetween(Misc::normalizeAngle(xAngleRadians), -zLimit, zLimit); } float factor = duration*5; diff --git a/apps/openmw/mwmechanics/movement.hpp b/apps/openmw/mwmechanics/movement.hpp index 86b970e60..57e106cde 100644 --- a/apps/openmw/mwmechanics/movement.hpp +++ b/apps/openmw/mwmechanics/movement.hpp @@ -8,8 +8,14 @@ namespace MWMechanics /// Desired movement for an actor struct Movement { + // Desired movement. Direction is relative to the current orientation. + // Length of the vector controls desired speed. 0 - stay, 0.5 - half-speed, 1.0 - max speed. float mPosition[3]; + // Desired rotation delta (euler angles). float mRotation[3]; + + // Controlled by CharacterController, should not be changed from other places. + // These fields can not be private fields in CharacterController, because Actor::getCurrentSpeed uses it. float mSpeedFactor; bool mIsStrafing; diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index 715dfecd2..88325ee7c 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -122,7 +122,7 @@ namespace MWMechanics if (mWalkState != WalkState::Evade) { - const float distSameSpot = DIST_SAME_SPOT * actor.getClass().getSpeed(actor) * duration; + const float distSameSpot = DIST_SAME_SPOT * actor.getClass().getCurrentSpeed(actor) * duration; const float prevDistance = (destination - mPrev).length(); const float currentDistance = (destination - position).length(); const float movedDistance = prevDistance - currentDistance; diff --git a/apps/openmw/mwmechanics/steering.cpp b/apps/openmw/mwmechanics/steering.cpp index b08a90220..d442085ea 100644 --- a/apps/openmw/mwmechanics/steering.cpp +++ b/apps/openmw/mwmechanics/steering.cpp @@ -32,7 +32,7 @@ bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, f if (absDiff < epsilonRadians) return true; - float limit = getAngularVelocity(actor.getClass().getSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); + float limit = getAngularVelocity(actor.getClass().getMaxSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); if (absDiff > limit) diff = osg::sign(diff) * limit; diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 40cc9895d..0d6ed262b 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -200,7 +201,7 @@ namespace MWRender updateFocalPointOffset(duration); updatePosition(); - float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr); + float speed = mTrackingPtr.getClass().getCurrentSpeed(mTrackingPtr); speed /= (1.f + speed / 500.f); float maxDelta = 300.f * duration; mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta); @@ -249,7 +250,7 @@ namespace MWRender { if (!mStandingPreviewAllowed) return; - float speed = mTrackingPtr.getClass().getSpeed(mTrackingPtr); + float speed = mTrackingPtr.getClass().getCurrentSpeed(mTrackingPtr); bool combat = mTrackingPtr.getClass().isActor() && mTrackingPtr.getClass().getCreatureStats(mTrackingPtr).getDrawState() != MWMechanics::DrawState_Nothing; bool standingStill = speed == 0 && !combat && !mFirstPersonView; @@ -396,12 +397,7 @@ namespace MWRender void Camera::setYaw(float angle) { - if (angle > osg::PI) { - angle -= osg::PI*2; - } else if (angle < -osg::PI) { - angle += osg::PI*2; - } - mYaw = angle; + mYaw = Misc::normalizeAngle(angle); } void Camera::setPitch(float angle) @@ -538,16 +534,8 @@ namespace MWRender return; } - mDeferredRotation.x() = -ptr.getRefData().getPosition().rot[0] - mPitch; - mDeferredRotation.z() = -ptr.getRefData().getPosition().rot[2] - mYaw; - if (mDeferredRotation.x() > osg::PI) - mDeferredRotation.x() -= 2 * osg::PI; - if (mDeferredRotation.x() < -osg::PI) - mDeferredRotation.x() += 2 * osg::PI; - if (mDeferredRotation.z() > osg::PI) - mDeferredRotation.z() -= 2 * osg::PI; - if (mDeferredRotation.z() < -osg::PI) - mDeferredRotation.z() += 2 * osg::PI; + mDeferredRotation.x() = Misc::normalizeAngle(-ptr.getRefData().getPosition().rot[0] - mPitch); + mDeferredRotation.z() = Misc::normalizeAngle(-ptr.getRefData().getPosition().rot[2] - mYaw); } } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index ad8766d06..950c8a6d4 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -159,7 +159,12 @@ namespace MWWorld return ""; } - float Class::getSpeed (const Ptr& ptr) const + float Class::getMaxSpeed (const Ptr& ptr) const + { + return 0; + } + + float Class::getCurrentSpeed (const Ptr& ptr) const { return 0; } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index e82712220..445f2e986 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -172,8 +172,15 @@ namespace MWWorld ///< Return name of the script attached to ptr (default implementation: return an empty /// string). - virtual float getSpeed (const Ptr& ptr) const; - ///< Return movement speed. + virtual float getWalkSpeed(const Ptr& ptr) const; + virtual float getRunSpeed(const Ptr& ptr) const; + virtual float getSwimSpeed(const Ptr& ptr) const; + + /// Return maximal movement speed for the current state. + virtual float getMaxSpeed(const Ptr& ptr) const; + + /// Return current movement speed. + virtual float getCurrentSpeed(const Ptr& ptr) const; virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) @@ -182,7 +189,7 @@ namespace MWWorld ///< Return desired movement. virtual osg::Vec3f getRotationVector (const Ptr& ptr) const; - ///< Return desired rotations, as euler angles. + ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. virtual std::pair, bool> getEquipmentSlots (const ConstPtr& ptr) const; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object @@ -364,12 +371,6 @@ namespace MWWorld virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; - - virtual float getWalkSpeed(const Ptr& ptr) const; - - virtual float getRunSpeed(const Ptr& ptr) const; - - virtual float getSwimSpeed(const Ptr& ptr) const; }; } diff --git a/components/misc/mathutil.hpp b/components/misc/mathutil.hpp new file mode 100644 index 000000000..2f7f446b5 --- /dev/null +++ b/components/misc/mathutil.hpp @@ -0,0 +1,27 @@ +#ifndef MISC_MATHUTIL_H +#define MISC_MATHUTIL_H + +#include +#include + +namespace Misc +{ + + /// Normalizes given angle to the range [-PI, PI]. E.g. PI*3/2 -> -PI/2. + inline double normalizeAngle(double angle) + { + double fullTurns = angle / (2 * osg::PI) + 0.5; + return (fullTurns - floor(fullTurns) - 0.5) * (2 * osg::PI); + } + + /// Rotates given 2d vector counterclockwise. Angle is in radians. + inline osg::Vec2f rotateVec2f(osg::Vec2f vec, float angle) + { + float s = std::sin(angle); + float c = std::cos(angle); + return osg::Vec2f(vec.x() * c + vec.y() * -s, vec.x() * s + vec.y() * c); + } + +} + +#endif From 297898182b3b448ca2c2286d528ee6336db3ba66 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 28 Aug 2020 15:28:26 +0400 Subject: [PATCH 079/224] Reset attached arrow in the beginning of unequipping animation --- apps/openmw/mwmechanics/character.cpp | 2 ++ apps/openmw/mwrender/animation.hpp | 1 + apps/openmw/mwrender/creatureanimation.cpp | 6 ++++++ apps/openmw/mwrender/creatureanimation.hpp | 1 + apps/openmw/mwrender/npcanimation.cpp | 6 ++++++ apps/openmw/mwrender/npcanimation.hpp | 1 + apps/openmw/mwrender/weaponanimation.cpp | 5 +++++ apps/openmw/mwrender/weaponanimation.hpp | 2 ++ 8 files changed, 24 insertions(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5d102f69e..0abf47807 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1306,6 +1306,8 @@ bool CharacterController::updateWeaponState(CharacterState& idle) 1.0f, "unequip start", "unequip stop", 0.0f, 0); mUpperBodyState = UpperCharState_UnEquipingWeap; + mAnimation->detachArrow(); + // If we do not have the "unequip detach" key, hide weapon manually. if (mAnimation->getTextKeyTime(weapgroup+": unequip detach") < 0) mAnimation->showWeapons(false); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index a04a3f999..8a1719db4 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -474,6 +474,7 @@ public: void setAlpha(float alpha); virtual void setPitchFactor(float factor) {} virtual void attachArrow() {} + virtual void detachArrow() {} virtual void releaseArrow(float attackStrength) {} virtual void enableHeadAnimation(bool enable) {} // TODO: move outside of this class diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 489a7a987..4a832c60c 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -208,6 +208,12 @@ bool CreatureWeaponAnimation::isArrowAttached() const return mAmmunition != nullptr; } +void CreatureWeaponAnimation::detachArrow() +{ + WeaponAnimation::detachArrow(mPtr); + updateQuiver(); +} + void CreatureWeaponAnimation::attachArrow() { WeaponAnimation::attachArrow(mPtr); diff --git a/apps/openmw/mwrender/creatureanimation.hpp b/apps/openmw/mwrender/creatureanimation.hpp index cdcdafe24..071500d74 100644 --- a/apps/openmw/mwrender/creatureanimation.hpp +++ b/apps/openmw/mwrender/creatureanimation.hpp @@ -40,6 +40,7 @@ namespace MWRender void updatePart(PartHolderPtr& scene, int slot); virtual void attachArrow(); + virtual void detachArrow(); virtual void releaseArrow(float attackStrength); // WeaponAnimation virtual osg::Group* getArrowBone(); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 468938d22..617a0a4ba 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -1051,6 +1051,12 @@ void NpcAnimation::attachArrow() updateQuiver(); } +void NpcAnimation::detachArrow() +{ + WeaponAnimation::detachArrow(mPtr); + updateQuiver(); +} + void NpcAnimation::releaseArrow(float attackStrength) { WeaponAnimation::releaseArrow(mPtr, attackStrength); diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 7edf35a5c..cf695c878 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -142,6 +142,7 @@ public: virtual void showCarriedLeft(bool show); virtual void attachArrow(); + virtual void detachArrow(); virtual void releaseArrow(float attackStrength); virtual osg::Group* getArrowBone(); diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index 2af5fdb41..0c2a11466 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -98,6 +98,11 @@ void WeaponAnimation::attachArrow(MWWorld::Ptr actor) } } +void WeaponAnimation::detachArrow(MWWorld::Ptr actor) +{ + mAmmunition.reset(); +} + void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) { MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); diff --git a/apps/openmw/mwrender/weaponanimation.hpp b/apps/openmw/mwrender/weaponanimation.hpp index a1988703c..dac1b663d 100644 --- a/apps/openmw/mwrender/weaponanimation.hpp +++ b/apps/openmw/mwrender/weaponanimation.hpp @@ -36,6 +36,8 @@ namespace MWRender /// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op. void attachArrow(MWWorld::Ptr actor); + void detachArrow(MWWorld::Ptr actor); + /// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op. void releaseArrow(MWWorld::Ptr actor, float attackStrength); From 47af221f101c1587374cbd6b6ed9f649fd60700e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 28 Aug 2020 15:57:11 +0400 Subject: [PATCH 080/224] Reset ammo when switching view to avoid warnings spam --- apps/openmw/mwrender/npcanimation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 617a0a4ba..31cf3f015 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -363,6 +363,7 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) mViewMode = viewMode; MWBase::Environment::get().getWorld()->scaleObject(mPtr, mPtr.getCellRef().getScale()); // apply race height after view change + mAmmunition.reset(); rebuild(); setRenderBin(); } From 924f634bda9c2b30504a728cd6821334e900ca9b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 8 Jun 2020 15:19:25 +0400 Subject: [PATCH 081/224] Support for multiple summons with same ID in the single spell --- apps/openmw/mwgui/spellicons.cpp | 4 ++-- apps/openmw/mwgui/spellicons.hpp | 4 ++-- apps/openmw/mwmechanics/activespells.cpp | 7 +++--- apps/openmw/mwmechanics/activespells.hpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 26 +++++++++++---------- apps/openmw/mwmechanics/creaturestats.hpp | 2 +- apps/openmw/mwmechanics/linkedeffects.cpp | 1 + apps/openmw/mwmechanics/magiceffects.hpp | 4 ++-- apps/openmw/mwmechanics/spellabsorption.cpp | 4 ++-- apps/openmw/mwmechanics/spellcasting.cpp | 6 +++-- apps/openmw/mwmechanics/spells.cpp | 22 +++++++++++------ apps/openmw/mwmechanics/summoning.cpp | 17 +++++++------- apps/openmw/mwmechanics/summoning.hpp | 6 ++--- apps/openmw/mwworld/inventorystore.cpp | 7 ++++-- apps/openmw/mwworld/inventorystore.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 2 +- components/esm/activespells.cpp | 3 +++ components/esm/activespells.hpp | 1 + components/esm/creaturestats.cpp | 13 +++++++---- components/esm/creaturestats.hpp | 2 +- components/esm/savedgame.cpp | 2 +- 21 files changed, 81 insertions(+), 56 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 8a501e598..e6a10ee32 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -25,8 +25,8 @@ namespace MWGui { - void EffectSourceVisitor::visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + void EffectSourceVisitor::visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime, float totalTime) { MagicEffectInfo newEffectSource; diff --git a/apps/openmw/mwgui/spellicons.hpp b/apps/openmw/mwgui/spellicons.hpp index 26761f2fc..67351688f 100644 --- a/apps/openmw/mwgui/spellicons.hpp +++ b/apps/openmw/mwgui/spellicons.hpp @@ -46,8 +46,8 @@ namespace MWGui virtual ~EffectSourceVisitor() {} - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1); }; diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 2ccffcc91..928293e64 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -210,9 +210,8 @@ namespace MWMechanics std::string name = it->second.mDisplayName; float magnitude = effectIt->mMagnitude; - if (magnitude) - visitor.visit(MWMechanics::EffectKey(effectIt->mEffectId, effectIt->mArg), name, it->first, it->second.mCasterActorId, magnitude, effectIt->mTimeLeft, effectIt->mDuration); + visitor.visit(MWMechanics::EffectKey(effectIt->mEffectId, effectIt->mArg), effectIt->mEffectIndex, name, it->first, it->second.mCasterActorId, magnitude, effectIt->mTimeLeft, effectIt->mDuration); } } } @@ -258,14 +257,14 @@ namespace MWMechanics mSpellsChanged = true; } - void ActiveSpells::purgeEffect(short effectId, const std::string& sourceId) + void ActiveSpells::purgeEffect(short effectId, const std::string& sourceId, int effectIndex) { for (TContainer::iterator it = mSpells.begin(); it != mSpells.end(); ++it) { for (std::vector::iterator effectIt = it->second.mEffects.begin(); effectIt != it->second.mEffects.end();) { - if (effectIt->mEffectId == effectId && it->first == sourceId) + if (effectIt->mEffectId == effectId && it->first == sourceId && (effectIndex < 0 || effectIndex == effectIt->mEffectIndex)) effectIt = it->second.mEffects.erase(effectIt); else ++effectIt; diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 9a1783bc9..4d36c717e 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -85,7 +85,7 @@ namespace MWMechanics void purgeEffect (short effectId); /// Remove all active effects with this effect id and source id - void purgeEffect (short effectId, const std::string& sourceId); + void purgeEffect (short effectId, const std::string& sourceId, int effectIndex=-1); /// Remove all active effects, if roll succeeds (for each effect) void purgeAll(float chance, bool spellOnly = false); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 14a2e17c9..21f71ce5d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -88,12 +88,13 @@ class CheckActorCommanded : public MWMechanics::EffectSourceVisitor MWWorld::Ptr mActor; public: bool mCommanded; + CheckActorCommanded(const MWWorld::Ptr& actor) : mActor(actor) - , mCommanded(false){} + , mCommanded(false){} - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) { if (((key.mId == ESM::MagicEffect::CommandHumanoid && mActor.getClass().isNpc()) @@ -156,8 +157,8 @@ namespace MWMechanics GetStuntedMagickaDuration(const MWWorld::Ptr& actor) : mRemainingTime(0.f){} - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) { if (mRemainingTime == -1) return; @@ -186,8 +187,8 @@ namespace MWMechanics { } - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) { if (magnitude <= 0) @@ -206,8 +207,8 @@ namespace MWMechanics { public: - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) { if (key.mId != ESM::MagicEffect::Corprus) @@ -231,8 +232,8 @@ namespace MWMechanics { } - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) { if (mTrapped) @@ -894,7 +895,7 @@ namespace MWMechanics { } - virtual void visit (MWMechanics::EffectKey key, + virtual void visit (MWMechanics::EffectKey key, int /*effectIndex*/, const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, float magnitude, float remainingTime = -1, float /*totalTime*/ = -1) { @@ -1196,6 +1197,7 @@ namespace MWMechanics { UpdateSummonedCreatures updateSummonedCreatures(ptr); creatureStats.getActiveSpells().visitEffectSources(updateSummonedCreatures); + creatureStats.getSpells().visitEffectSources(updateSummonedCreatures); if (ptr.getClass().hasInventoryStore(ptr)) ptr.getClass().getInventoryStore(ptr).visitEffectSources(updateSummonedCreatures); updateSummonedCreatures.process(mTimerDisposeSummonsCorpses == 0.f); diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 5e91a1b5a..9a1996ddb 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -84,7 +84,7 @@ namespace MWMechanics float mSideMovementAngle; public: - typedef std::pair SummonKey; // + typedef std::tuple SummonKey; // private: std::map mSummonedCreatures; // diff --git a/apps/openmw/mwmechanics/linkedeffects.cpp b/apps/openmw/mwmechanics/linkedeffects.cpp index 364358433..b0defac7d 100644 --- a/apps/openmw/mwmechanics/linkedeffects.cpp +++ b/apps/openmw/mwmechanics/linkedeffects.cpp @@ -58,6 +58,7 @@ namespace MWMechanics std::vector absorbEffects; ActiveSpells::ActiveEffect absorbEffect = appliedEffect; absorbEffect.mMagnitude *= -1; + absorbEffect.mEffectIndex = appliedEffect.mEffectIndex; absorbEffects.emplace_back(absorbEffect); // Morrowind negates reflected Absorb spells so the original caster won't be harmed. diff --git a/apps/openmw/mwmechanics/magiceffects.hpp b/apps/openmw/mwmechanics/magiceffects.hpp index 86f5a1804..12735a87f 100644 --- a/apps/openmw/mwmechanics/magiceffects.hpp +++ b/apps/openmw/mwmechanics/magiceffects.hpp @@ -74,8 +74,8 @@ namespace MWMechanics { virtual ~EffectSourceVisitor() { } - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1) = 0; }; diff --git a/apps/openmw/mwmechanics/spellabsorption.cpp b/apps/openmw/mwmechanics/spellabsorption.cpp index f38fd78e2..f22cef3f6 100644 --- a/apps/openmw/mwmechanics/spellabsorption.cpp +++ b/apps/openmw/mwmechanics/spellabsorption.cpp @@ -23,8 +23,8 @@ namespace MWMechanics GetAbsorptionProbability() = default; - virtual void visit (MWMechanics::EffectKey key, - const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, + virtual void visit (MWMechanics::EffectKey key, int /*effectIndex*/, + const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, float magnitude, float /*remainingTime*/, float /*totalTime*/) { if (key.mId == ESM::MagicEffect::SpellAbsorption) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 9f7108239..fb195bb6d 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -121,8 +121,9 @@ namespace MWMechanics // Try absorbing the spell. Some handling must still happen for absorbed effects. bool absorbed = absorbSpell(spell, caster, target); + int currentEffectIndex = 0; for (std::vector::const_iterator effectIt (effects.mList.begin()); - !target.isEmpty() && effectIt != effects.mList.end(); ++effectIt) + !target.isEmpty() && effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex) { if (effectIt->mRange != range) continue; @@ -189,6 +190,7 @@ namespace MWMechanics effect.mArg = MWMechanics::EffectKey(*effectIt).mArg; effect.mMagnitude = magnitude; effect.mTimeLeft = 0.f; + effect.mEffectIndex = currentEffectIndex; // Avoid applying absorb effects if the caster is the target // We still need the spell to be added @@ -268,7 +270,7 @@ namespace MWMechanics if (isSummoningEffect(effectIt->mEffectID) && !target.isEmpty() && target.getClass().isActor()) { CreatureStats& targetStats = target.getClass().getCreatureStats(target); - std::map::iterator findCreature = targetStats.getSummonedCreatureMap().find(std::make_pair(effectIt->mEffectID, mId)); + std::map::iterator findCreature = targetStats.getSummonedCreatureMap().find(std::make_tuple(effectIt->mEffectID, mId, currentEffectIndex)); if (findCreature != targetStats.getSummonedCreatureMap().end()) { MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(target, findCreature->second); diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index a66c267cc..d292c015d 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -50,7 +50,10 @@ namespace MWMechanics for (const auto& effect : spell->mEffects.mList) { if (iter.second.mPurgedEffects.find(i) != iter.second.mPurgedEffects.end()) + { + ++i; continue; // effect was purged + } float random = 1.f; if (iter.second.mEffectRands.find(i) != iter.second.mEffectRands.end()) @@ -108,7 +111,7 @@ namespace MWMechanics SpellParams params; params.mEffectRands = random; - mSpells.insert (std::make_pair (spell, params)); + mSpells.emplace(spell, params); mSpellsChanged = true; } } @@ -272,7 +275,8 @@ namespace MWMechanics const ESM::Spell * spell = it.first; for (const auto& effectIt : it.second) { - visitor.visit(effectIt.first, spell->mName, spell->mId, -1, effectIt.second.getMagnitude()); + // FIXME: since Spells merges effects with the same ID, there is no sense to use multiple effects with same ID here + visitor.visit(effectIt.first, -1, spell->mName, spell->mId, -1, effectIt.second.getMagnitude()); } } } @@ -308,20 +312,24 @@ namespace MWMechanics void Spells::purgeEffect(int effectId, const std::string & sourceId) { - const ESM::Spell * spell = SpellList::getSpell(sourceId); + // Effect source may be not a spell + const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get().search(sourceId); + if (spell == nullptr) + return; + auto spellIt = mSpells.find(spell); if (spellIt == mSpells.end()) return; - int i = 0; + int index = 0; for (auto& effectIt : spellIt->first->mEffects.mList) { if (effectIt.mEffectID == effectId) { - spellIt->second.mPurgedEffects.insert(i); + spellIt->second.mPurgedEffects.insert(index); mSpellsChanged = true; } - ++i; + ++index; } } @@ -441,7 +449,7 @@ namespace MWMechanics ESM::SpellState::SpellParams params; params.mEffectRands = it.second.mEffectRands; params.mPurgedEffects = it.second.mPurgedEffects; - state.mSpells.insert(std::make_pair(it.first->mId, params)); + state.mSpells.emplace(it.first->mId, params); } } diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index 03fd0d681..acb58ea8e 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -65,11 +65,11 @@ namespace MWMechanics { } - void UpdateSummonedCreatures::visit(EffectKey key, const std::string &sourceName, const std::string &sourceId, int casterActorId, float magnitude, float remainingTime, float totalTime) + void UpdateSummonedCreatures::visit(EffectKey key, int effectIndex, const std::string &sourceName, const std::string &sourceId, int casterActorId, float magnitude, float remainingTime, float totalTime) { if (isSummoningEffect(key.mId) && magnitude > 0) { - mActiveEffects.insert(std::make_pair(key.mId, sourceId)); + mActiveEffects.insert(std::make_tuple(key.mId, sourceId, effectIndex)); } } @@ -78,12 +78,12 @@ namespace MWMechanics MWMechanics::CreatureStats& creatureStats = mActor.getClass().getCreatureStats(mActor); std::map& creatureMap = creatureStats.getSummonedCreatureMap(); - for (std::set >::iterator it = mActiveEffects.begin(); it != mActiveEffects.end(); ++it) + for (std::set::iterator it = mActiveEffects.begin(); it != mActiveEffects.end(); ++it) { - bool found = creatureMap.find(std::make_pair(it->first, it->second)) != creatureMap.end(); + bool found = creatureMap.find(*it) != creatureMap.end(); if (!found) { - std::string creatureID = getSummonedCreature(it->first); + std::string creatureID = getSummonedCreature(std::get<0>(*it)); if (!creatureID.empty()) { int creatureActorId = -1; @@ -115,7 +115,7 @@ namespace MWMechanics // still insert into creatureMap so we don't try to spawn again every frame, that would spam the warning log } - creatureMap.insert(std::make_pair(*it, creatureActorId)); + creatureMap.emplace(*it, creatureActorId); } } } @@ -149,9 +149,10 @@ namespace MWMechanics if (ptr.isEmpty() || (ptr.getClass().getCreatureStats(ptr).isDead() && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished())) { // Purge the magic effect so a new creature can be summoned if desired - creatureStats.getActiveSpells().purgeEffect(it->first.first, it->first.second); + creatureStats.getActiveSpells().purgeEffect(std::get<0>(it->first), std::get<1>(it->first), std::get<2>(it->first)); + creatureStats.getSpells().purgeEffect(std::get<0>(it->first), std::get<1>(it->first)); if (mActor.getClass().hasInventoryStore(mActor)) - mActor.getClass().getInventoryStore(mActor).purgeEffect(it->first.first, it->first.second); + mActor.getClass().getInventoryStore(mActor).purgeEffect(std::get<0>(it->first), std::get<1>(it->first), false, std::get<2>(it->first)); MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mActor, it->second); creatureMap.erase(it++); diff --git a/apps/openmw/mwmechanics/summoning.hpp b/apps/openmw/mwmechanics/summoning.hpp index f24413120..78a1969a9 100644 --- a/apps/openmw/mwmechanics/summoning.hpp +++ b/apps/openmw/mwmechanics/summoning.hpp @@ -20,8 +20,8 @@ namespace MWMechanics UpdateSummonedCreatures(const MWWorld::Ptr& actor); virtual ~UpdateSummonedCreatures() = default; - virtual void visit (MWMechanics::EffectKey key, - const std::string& sourceName, const std::string& sourceId, int casterActorId, + virtual void visit (MWMechanics::EffectKey key, int effectIndex, + const std::string& sourceName, const std::string& sourceId, int casterActorId, float magnitude, float remainingTime = -1, float totalTime = -1); /// To call after all effect sources have been visited @@ -30,7 +30,7 @@ namespace MWMechanics private: MWWorld::Ptr mActor; - std::set > mActiveEffects; + std::set> mActiveEffects; }; } diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index ada211470..d67a22884 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -917,7 +917,7 @@ void MWWorld::InventoryStore::visitEffectSources(MWMechanics::EffectSourceVisito float magnitude = effect.mMagnMin + (effect.mMagnMax - effect.mMagnMin) * params.mRandom; magnitude *= params.mMultiplier; if (magnitude > 0) - visitor.visit(MWMechanics::EffectKey(effect), (**iter).getClass().getName(**iter), (**iter).getCellRef().getRefId(), -1, magnitude); + visitor.visit(MWMechanics::EffectKey(effect), i-1, (**iter).getClass().getName(**iter), (**iter).getCellRef().getRefId(), -1, magnitude); } } } @@ -931,7 +931,7 @@ void MWWorld::InventoryStore::purgeEffect(short effectId, bool wholeSpell) } } -void MWWorld::InventoryStore::purgeEffect(short effectId, const std::string &sourceId, bool wholeSpell) +void MWWorld::InventoryStore::purgeEffect(short effectId, const std::string &sourceId, bool wholeSpell, int effectIndex) { TEffectMagnitudes::iterator effectMagnitudeIt = mPermanentMagicEffectMagnitudes.find(sourceId); if (effectMagnitudeIt == mPermanentMagicEffectMagnitudes.end()) @@ -964,6 +964,9 @@ void MWWorld::InventoryStore::purgeEffect(short effectId, const std::string &sou if (effectIt->mEffectID != effectId) continue; + if (effectIndex >= 0 && effectIndex != i) + continue; + if (wholeSpell) { mPermanentMagicEffectMagnitudes.erase(sourceId); diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index d597e5f30..97ca931e7 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -206,7 +206,7 @@ namespace MWWorld void purgeEffect (short effectId, bool wholeSpell = false); ///< Remove a magic effect - void purgeEffect (short effectId, const std::string& sourceId, bool wholeSpell = false); + void purgeEffect (short effectId, const std::string& sourceId, bool wholeSpell = false, int effectIndex=-1); ///< Remove a magic effect virtual void clear(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index dafd84388..265a7663c 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3119,7 +3119,7 @@ namespace MWWorld { } - virtual void visit (MWMechanics::EffectKey key, + virtual void visit (MWMechanics::EffectKey key, int /*effectIndex*/, const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, float /*magnitude*/, float /*remainingTime*/ = -1, float /*totalTime*/ = -1) { diff --git a/components/esm/activespells.cpp b/components/esm/activespells.cpp index 46558ceb7..4017a4933 100644 --- a/components/esm/activespells.cpp +++ b/components/esm/activespells.cpp @@ -24,6 +24,7 @@ namespace ESM esm.writeHNT ("ARG_", effectIt->mArg); esm.writeHNT ("MAGN", effectIt->mMagnitude); esm.writeHNT ("DURA", effectIt->mDuration); + esm.writeHNT ("EIND", effectIt->mEffectIndex); esm.writeHNT ("LEFT", effectIt->mTimeLeft); } } @@ -53,6 +54,8 @@ namespace ESM esm.getHNOT(effect.mArg, "ARG_"); esm.getHNT (effect.mMagnitude, "MAGN"); esm.getHNT (effect.mDuration, "DURA"); + effect.mEffectIndex = -1; + esm.getHNOT (effect.mEffectIndex, "EIND"); if (format < 9) effect.mTimeLeft = effect.mDuration; else diff --git a/components/esm/activespells.hpp b/components/esm/activespells.hpp index 20b2f652d..1b7f8b319 100644 --- a/components/esm/activespells.hpp +++ b/components/esm/activespells.hpp @@ -22,6 +22,7 @@ namespace ESM int mArg; // skill or attribute float mDuration; float mTimeLeft; + int mEffectIndex; }; // format 0, saved games only diff --git a/components/esm/creaturestats.cpp b/components/esm/creaturestats.cpp index 6f0b36f8d..4ffe567c6 100644 --- a/components/esm/creaturestats.cpp +++ b/components/esm/creaturestats.cpp @@ -115,9 +115,11 @@ void ESM::CreatureStats::load (ESMReader &esm) int magicEffect; esm.getHT(magicEffect); std::string source = esm.getHNOString("SOUR"); + int effectIndex = -1; + esm.getHNOT (effectIndex, "EIND"); int actorId; esm.getHNT (actorId, "ACID"); - mSummonedCreatureMap[std::make_pair(magicEffect, source)] = actorId; + mSummonedCreatureMap[std::make_tuple(magicEffect, source, effectIndex)] = actorId; } while (esm.isNextSub("GRAV")) @@ -212,10 +214,13 @@ void ESM::CreatureStats::save (ESMWriter &esm) const mAiSequence.save(esm); mMagicEffects.save(esm); - for (std::map, int>::const_iterator it = mSummonedCreatureMap.begin(); it != mSummonedCreatureMap.end(); ++it) + for (std::map, int>::const_iterator it = mSummonedCreatureMap.begin(); it != mSummonedCreatureMap.end(); ++it) { - esm.writeHNT ("SUMM", it->first.first); - esm.writeHNString ("SOUR", it->first.second); + esm.writeHNT ("SUMM", std::get<0>(it->first)); + esm.writeHNString ("SOUR", std::get<1>(it->first)); + int effectIndex = std::get<2>(it->first); + if (effectIndex != -1) + esm.writeHNT ("EIND", effectIndex); esm.writeHNT ("ACID", it->second); } diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp index 79a576587..e79d430ce 100644 --- a/components/esm/creaturestats.hpp +++ b/components/esm/creaturestats.hpp @@ -39,7 +39,7 @@ namespace ESM bool mHasAiSettings; StatState mAiSettings[4]; - std::map, int> mSummonedCreatureMap; + std::map, int> mSummonedCreatureMap; std::vector mSummonGraveyard; ESM::TimeStamp mTradeTime; diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index 4b0529703..0fc84e309 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -4,7 +4,7 @@ #include "esmwriter.hpp" unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; -int ESM::SavedGame::sCurrentFormat = 13; +int ESM::SavedGame::sCurrentFormat = 14; void ESM::SavedGame::load (ESMReader &esm) { From 67eace10281f48556d18b389dfcddab1c6c9e173 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 28 Aug 2020 22:43:22 +0400 Subject: [PATCH 082/224] Use struct instead of tuple --- apps/openmw/mwgui/container.cpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/creaturestats.cpp | 2 +- apps/openmw/mwmechanics/creaturestats.hpp | 7 +++-- apps/openmw/mwmechanics/spellcasting.cpp | 3 ++- apps/openmw/mwmechanics/summoning.cpp | 19 +++++++------- apps/openmw/mwmechanics/summoning.hpp | 4 ++- components/esm/creaturestats.cpp | 22 ++++++++-------- components/esm/creaturestats.hpp | 2 +- components/esm/magiceffects.hpp | 32 +++++++++++++++++++++++ 10 files changed, 65 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 444ce4cb1..a68fddca1 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -252,7 +252,7 @@ namespace MWGui } // Clean up summoned creatures as well - std::map& creatureMap = creatureStats.getSummonedCreatureMap(); + std::map& creatureMap = creatureStats.getSummonedCreatureMap(); for (const auto& creature : creatureMap) MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mPtr, creature.second); creatureMap.clear(); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 21f71ce5d..271b352ea 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -2016,7 +2016,7 @@ namespace MWMechanics // Remove the summoned creature's summoned creatures as well MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - std::map& creatureMap = stats.getSummonedCreatureMap(); + std::map& creatureMap = stats.getSummonedCreatureMap(); for (const auto& creature : creatureMap) cleanupSummonedCreature(stats, creature.second); creatureMap.clear(); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 79b8e23de..1d5fe8347 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -683,7 +683,7 @@ namespace MWMechanics return mTimeOfDeath; } - std::map& CreatureStats::getSummonedCreatureMap() + std::map& CreatureStats::getSummonedCreatureMap() { return mSummonedCreatures; } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 9a1996ddb..b2c0aec98 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -13,6 +13,7 @@ #include "drawstate.hpp" #include +#include namespace ESM { @@ -83,10 +84,8 @@ namespace MWMechanics // The difference between view direction and lower body direction. float mSideMovementAngle; - public: - typedef std::tuple SummonKey; // private: - std::map mSummonedCreatures; // + std::map mSummonedCreatures; // // Contains ActorIds of summoned creatures with an expired lifetime that have not been deleted yet. // This may be necessary when the creature is in an inactive cell. @@ -235,7 +234,7 @@ namespace MWMechanics void setBlock(bool value); bool getBlock() const; - std::map& getSummonedCreatureMap(); // + std::map& getSummonedCreatureMap(); // std::vector& getSummonedCreatureGraveyard(); // ActorIds enum Flag diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index fb195bb6d..3767acb3f 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -270,7 +270,8 @@ namespace MWMechanics if (isSummoningEffect(effectIt->mEffectID) && !target.isEmpty() && target.getClass().isActor()) { CreatureStats& targetStats = target.getClass().getCreatureStats(target); - std::map::iterator findCreature = targetStats.getSummonedCreatureMap().find(std::make_tuple(effectIt->mEffectID, mId, currentEffectIndex)); + ESM::SummonKey key(effectIt->mEffectID, mId, currentEffectIndex); + auto findCreature = targetStats.getSummonedCreatureMap().find(key); if (findCreature != targetStats.getSummonedCreatureMap().end()) { MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(target, findCreature->second); diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index acb58ea8e..0f699ccad 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -69,21 +69,21 @@ namespace MWMechanics { if (isSummoningEffect(key.mId) && magnitude > 0) { - mActiveEffects.insert(std::make_tuple(key.mId, sourceId, effectIndex)); + mActiveEffects.insert(ESM::SummonKey(key.mId, sourceId, effectIndex)); } } void UpdateSummonedCreatures::process(bool cleanup) { MWMechanics::CreatureStats& creatureStats = mActor.getClass().getCreatureStats(mActor); - std::map& creatureMap = creatureStats.getSummonedCreatureMap(); + std::map& creatureMap = creatureStats.getSummonedCreatureMap(); - for (std::set::iterator it = mActiveEffects.begin(); it != mActiveEffects.end(); ++it) + for (std::set::iterator it = mActiveEffects.begin(); it != mActiveEffects.end(); ++it) { bool found = creatureMap.find(*it) != creatureMap.end(); if (!found) { - std::string creatureID = getSummonedCreature(std::get<0>(*it)); + std::string creatureID = getSummonedCreature(it->mEffectId); if (!creatureID.empty()) { int creatureActorId = -1; @@ -121,7 +121,7 @@ namespace MWMechanics } // Update summon effects - for (std::map::iterator it = creatureMap.begin(); it != creatureMap.end(); ) + for (std::map::iterator it = creatureMap.begin(); it != creatureMap.end(); ) { bool found = mActiveEffects.find(it->first) != mActiveEffects.end(); if (!found) @@ -143,16 +143,17 @@ namespace MWMechanics if (!cleanup) return; - for (std::map::iterator it = creatureMap.begin(); it != creatureMap.end(); ) + for (std::map::iterator it = creatureMap.begin(); it != creatureMap.end(); ) { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(it->second); if (ptr.isEmpty() || (ptr.getClass().getCreatureStats(ptr).isDead() && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished())) { // Purge the magic effect so a new creature can be summoned if desired - creatureStats.getActiveSpells().purgeEffect(std::get<0>(it->first), std::get<1>(it->first), std::get<2>(it->first)); - creatureStats.getSpells().purgeEffect(std::get<0>(it->first), std::get<1>(it->first)); + const ESM::SummonKey& key = it->first; + creatureStats.getActiveSpells().purgeEffect(key.mEffectId, key.mSourceId, key.mEffectIndex); + creatureStats.getSpells().purgeEffect(key.mEffectId, key.mSourceId); if (mActor.getClass().hasInventoryStore(mActor)) - mActor.getClass().getInventoryStore(mActor).purgeEffect(std::get<0>(it->first), std::get<1>(it->first), false, std::get<2>(it->first)); + mActor.getClass().getInventoryStore(mActor).purgeEffect(key.mEffectId, key.mSourceId, false, key.mEffectIndex); MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mActor, it->second); creatureMap.erase(it++); diff --git a/apps/openmw/mwmechanics/summoning.hpp b/apps/openmw/mwmechanics/summoning.hpp index 78a1969a9..ac820e32f 100644 --- a/apps/openmw/mwmechanics/summoning.hpp +++ b/apps/openmw/mwmechanics/summoning.hpp @@ -5,6 +5,8 @@ #include "../mwworld/ptr.hpp" +#include + #include "magiceffects.hpp" namespace MWMechanics @@ -30,7 +32,7 @@ namespace MWMechanics private: MWWorld::Ptr mActor; - std::set> mActiveEffects; + std::set mActiveEffects; }; } diff --git a/components/esm/creaturestats.cpp b/components/esm/creaturestats.cpp index 4ffe567c6..cb383992c 100644 --- a/components/esm/creaturestats.cpp +++ b/components/esm/creaturestats.cpp @@ -119,7 +119,7 @@ void ESM::CreatureStats::load (ESMReader &esm) esm.getHNOT (effectIndex, "EIND"); int actorId; esm.getHNT (actorId, "ACID"); - mSummonedCreatureMap[std::make_tuple(magicEffect, source, effectIndex)] = actorId; + mSummonedCreatureMap[SummonKey(magicEffect, source, effectIndex)] = actorId; } while (esm.isNextSub("GRAV")) @@ -214,19 +214,19 @@ void ESM::CreatureStats::save (ESMWriter &esm) const mAiSequence.save(esm); mMagicEffects.save(esm); - for (std::map, int>::const_iterator it = mSummonedCreatureMap.begin(); it != mSummonedCreatureMap.end(); ++it) + for (const auto& summon : mSummonedCreatureMap) { - esm.writeHNT ("SUMM", std::get<0>(it->first)); - esm.writeHNString ("SOUR", std::get<1>(it->first)); - int effectIndex = std::get<2>(it->first); + esm.writeHNT ("SUMM", summon.first.mEffectId); + esm.writeHNString ("SOUR", summon.first.mSourceId); + int effectIndex = summon.first.mEffectIndex; if (effectIndex != -1) esm.writeHNT ("EIND", effectIndex); - esm.writeHNT ("ACID", it->second); + esm.writeHNT ("ACID", summon.second); } - for (std::vector::const_iterator it = mSummonGraveyard.begin(); it != mSummonGraveyard.end(); ++it) + for (int key : mSummonGraveyard) { - esm.writeHNT ("GRAV", *it); + esm.writeHNT ("GRAV", key); } esm.writeHNT("AISE", mHasAiSettings); @@ -236,11 +236,11 @@ void ESM::CreatureStats::save (ESMWriter &esm) const mAiSettings[i].save(esm); } - for (std::map::const_iterator it = mCorprusSpells.begin(); it != mCorprusSpells.end(); ++it) + for (const auto& corprusSpell : mCorprusSpells) { - esm.writeHNString("CORP", it->first); + esm.writeHNString("CORP", corprusSpell.first); - const CorprusStats & stats = it->second; + const CorprusStats & stats = corprusSpell.second; esm.writeHNT("WORS", stats.mWorsenings); esm.writeHNT("TIME", stats.mNextWorsening); } diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp index e79d430ce..13bc50008 100644 --- a/components/esm/creaturestats.hpp +++ b/components/esm/creaturestats.hpp @@ -39,7 +39,7 @@ namespace ESM bool mHasAiSettings; StatState mAiSettings[4]; - std::map, int> mSummonedCreatureMap; + std::map mSummonedCreatureMap; std::vector mSummonGraveyard; ESM::TimeStamp mTradeTime; diff --git a/components/esm/magiceffects.hpp b/components/esm/magiceffects.hpp index 2a6052caa..94ae23a10 100644 --- a/components/esm/magiceffects.hpp +++ b/components/esm/magiceffects.hpp @@ -2,6 +2,7 @@ #define COMPONENTS_ESM_MAGICEFFECTS_H #include +#include namespace ESM { @@ -18,6 +19,37 @@ namespace ESM void save (ESMWriter &esm) const; }; + struct SummonKey + { + SummonKey(int effectId, const std::string& sourceId, int index) + { + mEffectId = effectId; + mSourceId = sourceId; + mEffectIndex = index; + } + + bool operator==(const SummonKey &other) const + { + return mEffectId == other.mEffectId && + mSourceId == other.mSourceId && + mEffectIndex == other.mEffectIndex; + } + + bool operator<(const SummonKey &other) const + { + if (mEffectId < other.mEffectId) + return true; + + if (mSourceId < other.mSourceId) + return true; + + return mEffectIndex < other.mEffectIndex; + } + + int mEffectId; + std::string mSourceId; + int mEffectIndex; + }; } #endif From 9189a42c4c317b3db4a40a7486f61e45abbdc93a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 29 Aug 2020 12:07:13 +0400 Subject: [PATCH 083/224] Fix failed assertion --- apps/openmw/mwinput/mousemanager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index a3f436bfe..ac30d4487 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -70,7 +70,6 @@ namespace MWInput mBindingsManager->mouseMoved(arg); MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); - MWBase::World* world = MWBase::Environment::get().getWorld(); input->setJoystickLastUsed(false); input->resetIdleTime(); @@ -94,6 +93,8 @@ namespace MWInput if (mMouseLookEnabled && !input->controlsDisabled()) { + MWBase::World* world = MWBase::Environment::get().getWorld(); + float x = arg.xrel * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f; float y = arg.yrel * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f; @@ -110,7 +111,7 @@ namespace MWInput player.pitch(y); } else if (!input->getControlSwitch("playerlooking")) - world->disableDeferredPreviewRotation(); + MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation(); } } From 131bd5c91deb7172ecd0ebb893845956cef502fd Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sun, 30 Aug 2020 22:10:49 +0200 Subject: [PATCH 084/224] Fix unused template argument --- apps/openmw/mwmechanics/actorutil.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actorutil.hpp b/apps/openmw/mwmechanics/actorutil.hpp index 275a3a814..490dc119a 100644 --- a/apps/openmw/mwmechanics/actorutil.hpp +++ b/apps/openmw/mwmechanics/actorutil.hpp @@ -58,7 +58,7 @@ namespace MWMechanics template void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) { - ESM::NPC copy = *MWBase::Environment::get().getWorld()->getStore().get().find(actorId); + T copy = *MWBase::Environment::get().getWorld()->getStore().get().find(actorId); for(auto& it : copy.mInventory.mList) { if(Misc::StringUtils::ciEqual(it.mItem, itemId)) From 7e3d19196d722e1bf150365c0af8fe8b7f47498d Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Tue, 1 Sep 2020 00:37:37 +0200 Subject: [PATCH 085/224] Fix #5586 --- apps/openmw/mwclass/npc.cpp | 2 ++ apps/openmw/mwmechanics/character.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index b89d79fc9..4aab95f9d 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -938,6 +938,8 @@ namespace MWClass float Npc::getMaxSpeed(const MWWorld::Ptr& ptr) const { + // TODO: This function is called several times per frame for each NPC. + // It would be better to calculate it only once per frame for each NPC and save the result in CreatureStats. const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) return 0.f; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 5d102f69e..32f8f6f2a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1965,8 +1965,11 @@ void CharacterController::update(float duration, bool animationOnly) vec.normalize(); float effectiveRotation = rot.z(); + bool canMove = cls.getMaxSpeed(mPtr) > 0; static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); - if (turnToMovementDirection && !isFirstPersonPlayer) + if (!turnToMovementDirection || isFirstPersonPlayer) + movementSettings.mIsStrafing = std::abs(vec.x()) > std::abs(vec.y()) * 2; + else if (canMove) { float targetMovementAngle = vec.y() >= 0 ? std::atan2(-vec.x(), vec.y()) : std::atan2(vec.x(), -vec.y()); movementSettings.mIsStrafing = (stats.getDrawState() != MWMechanics::DrawState_Nothing || inwater) @@ -1986,8 +1989,6 @@ void CharacterController::update(float duration, bool animationOnly) stats.setSideMovementAngle(stats.getSideMovementAngle() + delta); effectiveRotation += delta; } - else - movementSettings.mIsStrafing = std::abs(vec.x()) > std::abs(vec.y()) * 2; mAnimation->setLegsYawRadians(stats.getSideMovementAngle()); if (stats.getDrawState() == MWMechanics::DrawState_Nothing || inwater) From 7a4efe3979c687cc36c783382349731eef7aa1d4 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 1 Sep 2020 10:06:31 +0400 Subject: [PATCH 086/224] Avoid crash when object paging encounters an empty shape --- apps/openmw/mwrender/objectpaging.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 0f7e1c422..c756a3fc7 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -289,7 +289,9 @@ namespace MWRender } virtual void apply(osg::Geometry& geom) { - mResult.mNumVerts += geom.getVertexArray()->getNumElements(); + if (osg::Array* array = geom.getVertexArray()) + mResult.mNumVerts += array->getNumElements(); + ++mResult.mStateSetCounter[mCurrentStateSet]; ++mGlobalStateSetCounter[mCurrentStateSet]; } From 787ca06d558b6327b8cb8eb2f7dde1af57dc9dec Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 1 Sep 2020 19:36:59 +0400 Subject: [PATCH 087/224] Apply effects during rest before fast-forwarding spells state --- apps/openmw/mwmechanics/actors.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 271b352ea..0dfa7a9e6 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -2053,10 +2053,11 @@ namespace MWMechanics for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) { - iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().update(duration); - if (iter->first.getClass().getCreatureStats(iter->first).isDead()) + { + iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().update(duration); continue; + } if (!sleep || iter->first == player) restoreDynamicStats(iter->first, hours, sleep); @@ -2073,13 +2074,14 @@ namespace MWMechanics if (iter->first.getClass().isNpc()) calculateNpcStatModifiers(iter->first, duration); + iter->first.getClass().getCreatureStats(iter->first).getActiveSpells().update(duration); + MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first); if (animation) { animation->removeEffects(); MWBase::Environment::get().getWorld()->applyLoopingParticles(iter->first); } - } fastForwardAi(); From f9ca08a9843b4666180dececa4506659f250e375 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 3 Sep 2020 09:11:22 +0400 Subject: [PATCH 088/224] Do not use swish sound for ranged weapons --- apps/openmw/mwmechanics/character.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 32f8f6f2a..8087b499e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1788,7 +1788,9 @@ bool CharacterController::updateWeaponState(CharacterState& idle) mUpperBodyState = UpperCharState_MinAttackToMaxAttack; break; } - playSwishSound(0.0f); + + if(weapclass != ESM::WeaponType::Ranged && weapclass != ESM::WeaponType::Thrown) + playSwishSound(0.0f); } if(mAttackType == "shoot") From a251461045baf6115a56621c23da250dbcad75be Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 3 Sep 2020 13:50:24 +0000 Subject: [PATCH 089/224] Unpin CMake version now latest is fixed --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b89b99ac8..d171e8222 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,7 @@ variables: &cs-targets - choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolately/" --priority=1 - choco install git --force --params "/GitAndUnixToolsOnPath" -y - choco install 7zip -y - - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' --version=3.18.0 -y + - choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y - choco install vswhere -y - choco install ninja -y - choco install python -y From 257a6b462937e1173ccd052ca792314243c3d96d Mon Sep 17 00:00:00 2001 From: Eli2 Date: Fri, 31 Jan 2020 23:58:21 +0100 Subject: [PATCH 090/224] Use cmake method to enable interprocedural optimizations --- CMakeLists.txt | 32 ++++++++++++++++++-------- extern/recastnavigation/CMakeLists.txt | 5 ++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6e7e4ef3..5496b3145 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,11 @@ project(OpenMW) cmake_minimum_required(VERSION 3.1.0) +# for link time optimization, remove if cmake version is >= 3.9 +if(POLICY CMP0069) + cmake_policy(SET CMP0069 NEW) +endif() + # Apps and tools option(BUILD_OPENMW "Build OpenMW" ON) option(BUILD_LAUNCHER "Build Launcher" ON) @@ -97,6 +102,7 @@ option(OSG_STATIC "Link static build of OpenSceneGraph into the binaries" FALSE) option(QT_STATIC "Link static build of QT into the binaries" FALSE) option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE) +option(OPENMW_LTO_BUILD "Build OpenMW with Link-Time Optimization (Needs ~2GB of RAM)" OFF) # what is necessary to build documentation IF( BUILD_DOCS ) @@ -110,7 +116,6 @@ option(OPENMW_OSX_DEPLOYMENT OFF) if (MSVC) option(OPENMW_MP_BUILD "Build OpenMW with /MP flag" OFF) - option(OPENMW_LTO_BUILD "Build OpenMW with Link-Time Optimization (Needs ~2GB of RAM)" OFF) endif() # Set up common paths @@ -388,6 +393,23 @@ endif() # CXX Compiler settings set(CMAKE_CXX_STANDARD 14) + +if(OPENMW_LTO_BUILD) + if(NOT CMAKE_VERSION VERSION_LESS 3.9) + include(CheckIPOSupported) + check_ipo_supported(RESULT HAVE_IPO OUTPUT HAVE_IPO_OUTPUT) + if(HAVE_IPO) + message(STATUS "LTO enabled") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(WARNING "Requested option OPENMW_LTO_BUILD not supported by this compiler: ${HAVE_IPO_OUTPUT}") + endif() + else() + message(WARNING "Requested option OPENMW_LTO_BUILD not supported by this cmake version: ${CMAKE_VERSION}") + endif() +endif() + + if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef -Wno-unused-parameter -std=c++14 -pedantic -Wno-long-long") add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS=ON ) @@ -407,14 +429,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-parameter") endif() elseif (MSVC) - # Enable link-time code generation globally for all linking - if (OPENMW_LTO_BUILD) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL") - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") - set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") - set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG") - endif() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:MULTIPLE") endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) diff --git a/extern/recastnavigation/CMakeLists.txt b/extern/recastnavigation/CMakeLists.txt index 4952e51da..0d31c2e36 100644 --- a/extern/recastnavigation/CMakeLists.txt +++ b/extern/recastnavigation/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required(VERSION 3.0) +# for link time optimization, remove if cmake version is >= 3.9 +if(POLICY CMP0069) + cmake_policy(SET CMP0069 NEW) +endif() + project(RecastNavigation) # lib versions From 1dcea961c63442fa518759328b55c6b88b4cfa7c Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 3 Sep 2020 20:15:53 +0100 Subject: [PATCH 091/224] Only enable LTO for release This is how it was for the original implementation --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5496b3145..8822301cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -399,8 +399,8 @@ if(OPENMW_LTO_BUILD) include(CheckIPOSupported) check_ipo_supported(RESULT HAVE_IPO OUTPUT HAVE_IPO_OUTPUT) if(HAVE_IPO) - message(STATUS "LTO enabled") - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + message(STATUS "LTO enabled for Release configuration.") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE) else() message(WARNING "Requested option OPENMW_LTO_BUILD not supported by this compiler: ${HAVE_IPO_OUTPUT}") endif() From 643db61dfb7a4054e50de206c74bb121a88f2048 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 3 Sep 2020 20:38:02 +0100 Subject: [PATCH 092/224] Make warnings more informative. --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8822301cf..444743d28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -403,9 +403,12 @@ if(OPENMW_LTO_BUILD) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE) else() message(WARNING "Requested option OPENMW_LTO_BUILD not supported by this compiler: ${HAVE_IPO_OUTPUT}") + if(MSVC) + message(STATUS "Note: Flags used to be set manually for this setting with MSVC. We now rely on CMake for this. Upgrade CMake to at least 3.13 to re-enable this setting.") + endif() endif() else() - message(WARNING "Requested option OPENMW_LTO_BUILD not supported by this cmake version: ${CMAKE_VERSION}") + message(WARNING "Requested option OPENMW_LTO_BUILD not supported by this cmake version: ${CMAKE_VERSION}. Upgrade CMake to at least 3.9 to enable support for certain compilers. Newer CMake versions support more compilers.") endif() endif() From f4db29a717b2a05049a65bef02a9fdf5fafb5081 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 4 Sep 2020 00:45:41 +0100 Subject: [PATCH 093/224] Kill BUILD_CONFIG It was basically just CONFIGURATION but less confusing. CONFIGURATION could just be less confusing. --- CI/before_script.msvc.sh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 616caf3fa..7698dc877 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -380,17 +380,14 @@ esac case $CONFIGURATION in debug|Debug|DEBUG ) CONFIGURATION=Debug - BUILD_CONFIG=Debug ;; release|Release|RELEASE ) CONFIGURATION=Release - BUILD_CONFIG=Release ;; relwithdebinfo|RelWithDebInfo|RELWITHDEBINFO ) - CONFIGURATION=Release - BUILD_CONFIG=RelWithDebInfo + CONFIGURATION=RelWithDebInfo ;; esac @@ -422,7 +419,7 @@ else fi if [ -n "$SINGLE_CONFIG" ]; then - add_cmake_opts "-DCMAKE_BUILD_TYPE=${BUILD_CONFIG}" + add_cmake_opts "-DCMAKE_BUILD_TYPE=${CONFIGURATION}" fi if ! [ -z $UNITY_BUILD ]; then @@ -525,7 +522,7 @@ elif [ -n "$NINJA" ]; then fi if [ -n "$SINGLE_CONFIG" ]; then - BUILD_DIR="${BUILD_DIR}_${BUILD_CONFIG}" + BUILD_DIR="${BUILD_DIR}_${CONFIGURATION}" fi if [ -z $KEEP ]; then @@ -907,8 +904,8 @@ fi echo "- Copying Runtime DLLs..." DLL_PREFIX="" if [ -z $SINGLE_CONFIG ]; then - mkdir -p $BUILD_CONFIG - DLL_PREFIX="$BUILD_CONFIG/" + mkdir -p $CONFIGURATION + DLL_PREFIX="$CONFIGURATION/" fi for DLL in $RUNTIME_DLLS; do TARGET="$(basename "$DLL")" From 9f1fbd56a3aae38a683f44546bccf252ca575b28 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 4 Sep 2020 13:45:38 +0400 Subject: [PATCH 094/224] Fix SummonKey comparison function --- components/esm/magiceffects.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/esm/magiceffects.hpp b/components/esm/magiceffects.hpp index 94ae23a10..a931c68fa 100644 --- a/components/esm/magiceffects.hpp +++ b/components/esm/magiceffects.hpp @@ -39,9 +39,13 @@ namespace ESM { if (mEffectId < other.mEffectId) return true; + if (mEffectId > other.mEffectId) + return false; if (mSourceId < other.mSourceId) return true; + if (mSourceId > other.mSourceId) + return false; return mEffectIndex < other.mEffectIndex; } From 2d021430b87c28fbc947e3068d8e4708cc7bbb41 Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Sat, 5 Sep 2020 11:52:52 +0000 Subject: [PATCH 095/224] force static data variance for water geometry --- apps/openmw/mwrender/water.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index c9d16b728..a1691d5d1 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -443,6 +443,7 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem mWaterGeom = SceneUtil::createWaterGeometry(Constants::CellSizeInUnits*150, 40, 900); mWaterGeom->setDrawCallback(new DepthClampCallback); mWaterGeom->setNodeMask(Mask_Water); + mWaterGeom->setDataVariance(osg::Object::STATIC); mWaterNode = new osg::PositionAttitudeTransform; mWaterNode->setName("Water Root"); From 9e547e14d2bb9ba982764e9dca4144b6952cb1ef Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Tue, 8 Sep 2020 00:18:18 +0100 Subject: [PATCH 096/224] Allow setting up multiple build configurations at once Also fix some bugs discovered in the process. For multi-config generators, this basically just copies the DLLs for each configuration, and for single-config, due to there being separate build directories with separate extracted dependencies for each, it defaults to just one, and will run the script several times if you manually specify several. Details include: * Changing CONFIGURATION from a string to an array called CONFIGURATIONS. This gets iterated over in a bunch of places. * Fixing a typo of 'cannot' * Making the DLL lists arrays per-config, too. * Some handling for the recursive stuff and a warning if configurations are set with a multi-config generator. * Moving the configuration name sanitisation after they've been set. * Myriad changes to Google Test: - Build it in a directory specific to the build tools - previously, having an MSVC 2017 and MSVC 2019 build on the same machine was impossible if unit tests were on, even though it's allowed otherwise - Use either Debug or Release Google Test as its finder isn't looking for RelWithDebInfo or capable of dealing with it if we try and use it anyway. - Always build Google Test with MSBuild as it's much less hassle due to CMake setting up the environment for us. Currently, MSVC always comes with something that can build solution files, no matter how you get it, so this shouldn't upset anyone. - Use CMake's --install mode so we can set the install prefix in the place that uses it. - Pass CMake both Debug and Release Google Test instead of risking a C/C++ library configuration mismatch causing linker and runtime errors - it'll pick a suitable one for each configuration. - Pass the library type explicitly as CMake can't cope without a Release library if you only gave it Debug, due to accessing a Release-specific variable unconditionally. * Remove the -legacy flag from vswhere as it's only needed for MSVC 2015, which we don't support any more. * Fix the -version argument for vswhere as I'd massively cocked it up. I don't know how that happened as I did test it on a machine with multiple MSVC versions installed, which was the failure case, but it didn't fail then. --- CI/before_script.msvc.sh | 332 +++++++++++++++++++++++++-------------- 1 file changed, 215 insertions(+), 117 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 7698dc877..e43f5623f 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -69,7 +69,7 @@ NMAKE="" NINJA="" PDBS="" PLATFORM="" -CONFIGURATION="" +CONFIGURATIONS=() TEST_FRAMEWORK="" GOOGLE_INSTALL_ROOT="" INSTALL_PREFIX="." @@ -129,7 +129,7 @@ while [ $# -gt 0 ]; do PDBS=true ;; c ) - CONFIGURATION=$1 + CONFIGURATIONS+=( $1 ) shift ;; t ) @@ -143,8 +143,10 @@ while [ $# -gt 0 ]; do cat < + -c Set the configuration, can also be set with environment variable CONFIGURATION. + For mutli-config generators, this is ignored, and all configurations are set up. + For single-config generators, several configurations can be set up at once by specifying -c multiple times. -d Skip checking the downloads. -D @@ -164,7 +166,7 @@ Options: -v <2017/2019> Choose the Visual Studio version to use. -n - Produce NMake makefiles instead of a Visual Studio solution. Cannout be used with -N. + Produce NMake makefiles instead of a Visual Studio solution. Cannot be used with -N. -N Produce Ninja (multi-config if CMake is new enough to support it) files instead of a Visual Studio solution. Cannot be used with -n.. -P @@ -187,7 +189,7 @@ done if [ -n "$NMAKE" ] || [ -n "$NINJA" ]; then if [ -n "$NMAKE" ] && [ -n "$NINJA" ]; then - echo "Cannout run in NMake and Ninja mode at the same time." + echo "Cannot run in NMake and Ninja mode at the same time." wrappedExit 1 fi ACTIVATE_MSVC=true @@ -293,29 +295,40 @@ add_cmake_opts() { CMAKE_OPTS="$CMAKE_OPTS $@" } -RUNTIME_DLLS="" +declare -A RUNTIME_DLLS +RUNTIME_DLLS["Release"]="" +RUNTIME_DLLS["Debug"]="" +RUNTIME_DLLS["RelWithDebInfo"]="" add_runtime_dlls() { - RUNTIME_DLLS="$RUNTIME_DLLS $@" + local CONFIG=$1 + shift + RUNTIME_DLLS[$CONFIG]="${RUNTIME_DLLS[$CONFIG]} $@" } -OSG_PLUGINS="" +declare -A OSG_PLUGINS +OSG_PLUGINS["Release"]="" +OSG_PLUGINS["Debug"]="" +OSG_PLUGINS["RelWithDebInfo"]="" add_osg_dlls() { - OSG_PLUGINS="$OSG_PLUGINS $@" + local CONFIG=$1 + shift + OSG_PLUGINS[$CONFIG]="${OSG_PLUGINS[$CONFIG]} $@" } -QT_PLATFORMS="" +declare -A QT_PLATFORMS +QT_PLATFORMS["Release"]="" +QT_PLATFORMS["Debug"]="" +QT_PLATFORMS["RelWithDebInfo"]="" add_qt_platform_dlls() { - QT_PLATFORMS="$QT_PLATFORMS $@" + local CONFIG=$1 + shift + QT_PLATFORMS[$CONFIG]="${QT_PLATFORMS[$CONFIG]} $@" } if [ -z $PLATFORM ]; then PLATFORM="$(uname -m)" fi -if [ -z $CONFIGURATION ]; then - CONFIGURATION="Debug" -fi - if [ -z $VS_VERSION ]; then VS_VERSION="2017" fi @@ -377,20 +390,6 @@ case $PLATFORM in ;; esac -case $CONFIGURATION in - debug|Debug|DEBUG ) - CONFIGURATION=Debug - ;; - - release|Release|RELEASE ) - CONFIGURATION=Release - ;; - - relwithdebinfo|RelWithDebInfo|RELWITHDEBINFO ) - CONFIGURATION=RelWithDebInfo - ;; -esac - if [ $BITS -eq 64 ] && [ $MSVC_REAL_VER -lt 16 ]; then GENERATOR="${GENERATOR} Win64" fi @@ -408,6 +407,79 @@ if [ -n "$NINJA" ]; then fi fi +if [ -n "$SINGLE_CONFIG" ]; then + if [ ${#CONFIGURATIONS[@]} -eq 0 ]; then + if [ -n "${CONFIGURATION:-}" ]; then + CONFIGURATIONS=("$CONFIGURATION") + else + CONFIGURATIONS=("Debug") + fi + elif [ ${#CONFIGURATIONS[@]} -ne 1 ]; then + # It's simplest just to recursively call the script a few times. + RECURSIVE_OPTIONS=() + if [ -n "$VERBOSE" ]; then + RECURSIVE_OPTIONS+=("-V") + fi + if [ -n "$SKIP_DOWNLOAD" ]; then + RECURSIVE_OPTIONS+=("-d") + fi + if [ -n "$BULLET_DOUBLE" ]; then + RECURSIVE_OPTIONS+=("-D") + fi + if [ -n "$SKIP_EXTRACT" ]; then + RECURSIVE_OPTIONS+=("-e") + fi + if [ -n "$KEEP" ]; then + RECURSIVE_OPTIONS+=("-k") + fi + if [ -n "$UNITY_BUILD" ]; then + RECURSIVE_OPTIONS+=("-u") + fi + if [ -n "$NMAKE" ]; then + RECURSIVE_OPTIONS+=("-n") + fi + if [ -n "$NINJA" ]; then + RECURSIVE_OPTIONS+=("-N") + fi + if [ -n "$PDBS" ]; then + RECURSIVE_OPTIONS+=("-P") + fi + if [ -n "$TEST_FRAMEWORK" ]; then + RECURSIVE_OPTIONS+=("-t") + fi + RECURSIVE_OPTIONS+=("-v $VS_VERSION") + RECURSIVE_OPTIONS+=("-p $PLATFORM") + RECURSIVE_OPTIONS+=("-i '$INSTALL_PREFIX'") + + for config in ${CONFIGURATIONS[@]}; do + $0 ${RECURSIVE_OPTIONS[@]} -c $config + done + + wrappedExit 1 + fi +else + if [ ${#CONFIGURATIONS[@]} -ne 0 ]; then + echo "Ignoring configurations argument - generator is multi-config" + fi + CONFIGURATIONS=("Release" "Debug" "RelWithDebInfo") +fi + +for i in ${!CONFIGURATIONS[@]}; do + case ${CONFIGURATIONS[$i]} in + debug|Debug|DEBUG ) + CONFIGURATIONS[$i]=Debug + ;; + + release|Release|RELEASE ) + CONFIGURATIONS[$i]=Release + ;; + + relwithdebinfo|RelWithDebInfo|RELWITHDEBINFO ) + CONFIGURATIONS[$i]=RelWithDebInfo + ;; + esac +done + if [ $MSVC_REAL_VER -ge 16 ] && [ -z "$NMAKE" ] && [ -z "$NINJA" ]; then if [ $BITS -eq 64 ]; then add_cmake_opts "-G\"$GENERATOR\" -A x64" @@ -419,7 +491,7 @@ else fi if [ -n "$SINGLE_CONFIG" ]; then - add_cmake_opts "-DCMAKE_BUILD_TYPE=${CONFIGURATION}" + add_cmake_opts "-DCMAKE_BUILD_TYPE=${CONFIGURATIONS[0]}" fi if ! [ -z $UNITY_BUILD ]; then @@ -522,7 +594,7 @@ elif [ -n "$NINJA" ]; then fi if [ -n "$SINGLE_CONFIG" ]; then - BUILD_DIR="${BUILD_DIR}_${CONFIGURATION}" + BUILD_DIR="${BUILD_DIR}_${CONFIGURATIONS[0]}" fi if [ -z $KEEP ]; then @@ -623,7 +695,9 @@ printf "FFmpeg 4.2.2... " rm -rf "ffmpeg-4.2.2-win${BITS}-dev" fi export FFMPEG_HOME="$(real_pwd)/FFmpeg" - add_runtime_dlls "$(pwd)/FFmpeg/bin/"{avcodec-58,avformat-58,avutil-56,swresample-3,swscale-5}.dll + for config in ${CONFIGURATIONS[@]}; do + add_runtime_dlls $config "$(pwd)/FFmpeg/bin/"{avcodec-58,avformat-58,avutil-56,swresample-3,swscale-5}.dll + done if [ $BITS -eq 32 ]; then add_cmake_opts "-DCMAKE_EXE_LINKER_FLAGS=\"/machine:X86 /safeseh:no\"" fi @@ -648,14 +722,16 @@ printf "MyGUI 3.4.0... " mv "MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}" MyGUI fi export MYGUI_HOME="$(real_pwd)/MyGUI" - if [ $CONFIGURATION == "Debug" ]; then - SUFFIX="_d" - MYGUI_CONFIGURATION="Debug" - else - SUFFIX="" - MYGUI_CONFIGURATION="RelWithDebInfo" - fi - add_runtime_dlls "$(pwd)/MyGUI/bin/${MYGUI_CONFIGURATION}/MyGUIEngine${SUFFIX}.dll" + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + if [ $CONFIGURATION == "Debug" ]; then + SUFFIX="_d" + MYGUI_CONFIGURATION="Debug" + else + SUFFIX="" + MYGUI_CONFIGURATION="RelWithDebInfo" + fi + add_runtime_dlls $CONFIGURATION "$(pwd)/MyGUI/bin/${MYGUI_CONFIGURATION}/MyGUIEngine${SUFFIX}.dll" + done echo Done. } cd $DEPS @@ -672,7 +748,9 @@ printf "OpenAL-Soft 1.20.1... " OPENAL_SDK="$(real_pwd)/openal-soft-1.20.1-bin" add_cmake_opts -DOPENAL_INCLUDE_DIR="${OPENAL_SDK}/include/AL" \ -DOPENAL_LIBRARY="${OPENAL_SDK}/libs/Win${BITS}/OpenAL32.lib" - add_runtime_dlls "$(pwd)/openal-soft-1.20.1-bin/bin/WIN${BITS}/soft_oal.dll:OpenAL32.dll" + for config in ${CONFIGURATIONS[@]}; do + add_runtime_dlls $config "$(pwd)/openal-soft-1.20.1-bin/bin/WIN${BITS}/soft_oal.dll:OpenAL32.dll" + done echo Done. } cd $DEPS @@ -695,15 +773,17 @@ printf "OSG 3.6.5... " fi OSG_SDK="$(real_pwd)/OSG" add_cmake_opts -DOSG_DIR="$OSG_SDK" - if [ $CONFIGURATION == "Debug" ]; then - SUFFIX="d" - else - SUFFIX="" - fi - add_runtime_dlls "$(pwd)/OSG/bin/"{OpenThreads,zlib,libpng}${SUFFIX}.dll \ - "$(pwd)/OSG/bin/osg"{,Animation,DB,FX,GA,Particle,Text,Util,Viewer,Shadow}${SUFFIX}.dll - add_osg_dlls "$(pwd)/OSG/bin/osgPlugins-3.6.5/osgdb_"{bmp,dds,freetype,jpeg,osg,png,tga}${SUFFIX}.dll - add_osg_dlls "$(pwd)/OSG/bin/osgPlugins-3.6.5/osgdb_serializers_osg"{,animation,fx,ga,particle,text,util,viewer,shadow}${SUFFIX}.dll + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + if [ $CONFIGURATION == "Debug" ]; then + SUFFIX="d" + else + SUFFIX="" + fi + add_runtime_dlls $CONFIGURATION "$(pwd)/OSG/bin/"{OpenThreads,zlib,libpng}${SUFFIX}.dll \ + "$(pwd)/OSG/bin/osg"{,Animation,DB,FX,GA,Particle,Text,Util,Viewer,Shadow}${SUFFIX}.dll + add_osg_dlls $CONFIGURATION "$(pwd)/OSG/bin/osgPlugins-3.6.5/osgdb_"{bmp,dds,freetype,jpeg,osg,png,tga}${SUFFIX}.dll + add_osg_dlls $CONFIGURATION "$(pwd)/OSG/bin/osgPlugins-3.6.5/osgdb_serializers_osg"{,animation,fx,ga,particle,text,util,viewer,shadow}${SUFFIX}.dll + done echo Done. } cd $DEPS @@ -775,26 +855,30 @@ fi cd $QT_SDK add_cmake_opts -DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \ -DCMAKE_PREFIX_PATH="$QT_SDK" - if [ $CONFIGURATION == "Debug" ]; then - SUFFIX="d" - else - SUFFIX="" - fi - add_runtime_dlls "$(pwd)/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${SUFFIX}.dll - add_qt_platform_dlls "$(pwd)/plugins/platforms/qwindows${SUFFIX}.dll" + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + if [ $CONFIGURATION == "Debug" ]; then + DLLSUFFIX="d" + else + DLLSUFFIX="" + fi + add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${DLLSUFFIX}.dll + add_qt_platform_dlls $CONFIGURATION "$(pwd)/plugins/platforms/qwindows${DLLSUFFIX}.dll" + done echo Done. else QT_SDK="C:/Qt/5.13/msvc2017${SUFFIX}" add_cmake_opts -DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \ -DCMAKE_PREFIX_PATH="$QT_SDK" - if [ $CONFIGURATION == "Debug" ]; then - SUFFIX="d" - else - SUFFIX="" - fi - DIR=$(windowsPathAsUnix "${QT_SDK}") - add_runtime_dlls "${DIR}/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${SUFFIX}.dll - add_qt_platform_dlls "${DIR}/plugins/platforms/qwindows${SUFFIX}.dll" + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + if [ $CONFIGURATION == "Debug" ]; then + DLLSUFFIX="d" + else + DLLSUFFIX="" + fi + DIR=$(windowsPathAsUnix "${QT_SDK}") + add_runtime_dlls $CONFIGURATION "${DIR}/bin/Qt5"{Core,Gui,Network,OpenGL,Widgets}${DLLSUFFIX}.dll + add_qt_platform_dlls $CONFIGURATION "${DIR}/plugins/platforms/qwindows${DLLSUFFIX}.dll" + done echo Done. fi } @@ -810,7 +894,9 @@ printf "SDL 2.0.12... " eval 7z x -y SDL2-2.0.12.zip $STRIP fi export SDL2DIR="$(real_pwd)/SDL2-2.0.12" - add_runtime_dlls "$(pwd)/SDL2-2.0.12/lib/x${ARCHSUFFIX}/SDL2.dll" + for config in ${CONFIGURATIONS[@]}; do + add_runtime_dlls $config "$(pwd)/SDL2-2.0.12/lib/x${ARCHSUFFIX}/SDL2.dll" + done echo Done. } cd $DEPS @@ -820,41 +906,51 @@ if [ ! -z $TEST_FRAMEWORK ]; then printf "Google test 1.10.0 ..." cd googletest - if [ ! -d build ]; then - mkdir build - fi + mkdir -p build${MSVC_REAL_YEAR} - cd build + cd build${MSVC_REAL_YEAR} GOOGLE_INSTALL_ROOT="${DEPS_INSTALL}/GoogleTest" - if [ $CONFIGURATION == "Debug" ]; then + + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + # FindGMock.cmake mentions Release explicitly, but not RelWithDebInfo. Only one optimised library config can be used, so go for the safer one. + GTEST_CONFIG=$([ $CONFIGURATION == "RelWithDebInfo" ] && echo "Release" || echo "$CONFIGURATION" ) + if [ $GTEST_CONFIG == "Debug" ]; then DEBUG_SUFFIX="d" else DEBUG_SUFFIX="" - fi + fi - if [ ! -d $GOOGLE_INSTALL_ROOT ]; then + if [ ! -f "$GOOGLE_INSTALL_ROOT/lib/gtest${DEBUG_SUFFIX}.lib" ]; then + # Always use MSBuild solution files as they don't need the environment activating + cmake .. -DCMAKE_USE_WIN32_THREADS_INIT=1 -G "Visual Studio $MSVC_REAL_VER $MSVC_REAL_YEAR$([ $BITS -eq 64 ] && [ $MSVC_REAL_VER -lt 16 ] && echo " Win64")" $([ $MSVC_REAL_VER -ge 16 ] && echo "-A $([ $BITS -eq 64 ] && echo "x64" || echo "Win32")") -DBUILD_SHARED_LIBS=1 + cmake --build . --config "${GTEST_CONFIG}" + cmake --install . --config "${GTEST_CONFIG}" --prefix "${GOOGLE_INSTALL_ROOT}" + fi - cmake .. -DCMAKE_BUILD_TYPE="${CONFIGURATION}" -DCMAKE_INSTALL_PREFIX="${GOOGLE_INSTALL_ROOT}" -DCMAKE_USE_WIN32_THREADS_INIT=1 -G "${GENERATOR}" -DBUILD_SHARED_LIBS=1 - cmake --build . --config "${CONFIGURATION}" - cmake --build . --target install --config "${CONFIGURATION}" - - add_runtime_dlls "${GOOGLE_INSTALL_ROOT}\bin\gtest_main${DEBUG_SUFFIX}.dll" - add_runtime_dlls "${GOOGLE_INSTALL_ROOT}\bin\gtest${DEBUG_SUFFIX}.dll" - add_runtime_dlls "${GOOGLE_INSTALL_ROOT}\bin\gmock_main${DEBUG_SUFFIX}.dll" - add_runtime_dlls "${GOOGLE_INSTALL_ROOT}\bin\gmock${DEBUG_SUFFIX}.dll" - fi + add_runtime_dlls $CONFIGURATION "${GOOGLE_INSTALL_ROOT}\bin\gtest_main${DEBUG_SUFFIX}.dll" + add_runtime_dlls $CONFIGURATION "${GOOGLE_INSTALL_ROOT}\bin\gtest${DEBUG_SUFFIX}.dll" + add_runtime_dlls $CONFIGURATION "${GOOGLE_INSTALL_ROOT}\bin\gmock_main${DEBUG_SUFFIX}.dll" + add_runtime_dlls $CONFIGURATION "${GOOGLE_INSTALL_ROOT}\bin\gmock${DEBUG_SUFFIX}.dll" + done add_cmake_opts -DBUILD_UNITTESTS=yes # FindGTest and FindGMock do not work perfectly on Windows # but we can help them by telling them everything we know about installation add_cmake_opts -DGMOCK_ROOT="$GOOGLE_INSTALL_ROOT" add_cmake_opts -DGTEST_ROOT="$GOOGLE_INSTALL_ROOT" - add_cmake_opts -DGTEST_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gtest${DEBUG_SUFFIX}.lib" - add_cmake_opts -DGTEST_MAIN_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gtest_main${DEBUG_SUFFIX}.lib" - add_cmake_opts -DGMOCK_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gmock${DEBUG_SUFFIX}.lib" - add_cmake_opts -DGMOCK_MAIN_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gmock_main${DEBUG_SUFFIX}.lib" + add_cmake_opts -DGTEST_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gtest.lib" + add_cmake_opts -DGTEST_MAIN_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gtest_main.lib" + add_cmake_opts -DGMOCK_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gmock.lib" + add_cmake_opts -DGMOCK_MAIN_LIBRARY="$GOOGLE_INSTALL_ROOT/lib/gmock_main.lib" + add_cmake_opts -DGTEST_LIBRARY_DEBUG="$GOOGLE_INSTALL_ROOT/lib/gtestd.lib" + add_cmake_opts -DGTEST_MAIN_LIBRARY_DEBUG="$GOOGLE_INSTALL_ROOT/lib/gtest_maind.lib" + add_cmake_opts -DGMOCK_LIBRARY_DEBUG="$GOOGLE_INSTALL_ROOT/lib/gmockd.lib" + add_cmake_opts -DGMOCK_MAIN_LIBRARY_DEBUG="$GOOGLE_INSTALL_ROOT/lib/gmock_maind.lib" add_cmake_opts -DGTEST_LINKED_AS_SHARED_LIBRARY=True + add_cmake_opts -DGTEST_LIBRARY_TYPE=SHARED + add_cmake_opts -DGTEST_MAIN_LIBRARY_TYPE=SHARED + echo Done. fi @@ -901,45 +997,47 @@ if [ ! -z $CI ]; then fi # NOTE: Disable this when/if we want to run test cases #if [ -z $CI ]; then - echo "- Copying Runtime DLLs..." - DLL_PREFIX="" - if [ -z $SINGLE_CONFIG ]; then - mkdir -p $CONFIGURATION - DLL_PREFIX="$CONFIGURATION/" - fi - for DLL in $RUNTIME_DLLS; do - TARGET="$(basename "$DLL")" - if [[ "$DLL" == *":"* ]]; then - originalIFS="$IFS" - IFS=':'; SPLIT=( ${DLL} ); IFS=$originalIFS - DLL=${SPLIT[0]} - TARGET=${SPLIT[1]} + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + echo "- Copying Runtime DLLs for $CONFIGURATION..." + DLL_PREFIX="" + if [ -z $SINGLE_CONFIG ]; then + mkdir -p $CONFIGURATION + DLL_PREFIX="$CONFIGURATION/" fi - echo " ${TARGET}." - cp "$DLL" "${DLL_PREFIX}$TARGET" + for DLL in ${RUNTIME_DLLS[$CONFIGURATION]}; do + TARGET="$(basename "$DLL")" + if [[ "$DLL" == *":"* ]]; then + originalIFS="$IFS" + IFS=':'; SPLIT=( ${DLL} ); IFS=$originalIFS + DLL=${SPLIT[0]} + TARGET=${SPLIT[1]} + fi + echo " ${TARGET}." + cp "$DLL" "${DLL_PREFIX}$TARGET" + done + echo + echo "- OSG Plugin DLLs..." + mkdir -p ${DLL_PREFIX}osgPlugins-3.6.5 + for DLL in ${OSG_PLUGINS[$CONFIGURATION]}; do + echo " $(basename $DLL)." + cp "$DLL" ${DLL_PREFIX}osgPlugins-3.6.5 + done + echo + echo "- Qt Platform DLLs..." + mkdir -p ${DLL_PREFIX}platforms + for DLL in ${QT_PLATFORMS[$CONFIGURATION]}; do + echo " $(basename $DLL)" + cp "$DLL" "${DLL_PREFIX}platforms" + done + echo done - echo - echo "- OSG Plugin DLLs..." - mkdir -p ${DLL_PREFIX}osgPlugins-3.6.5 - for DLL in $OSG_PLUGINS; do - echo " $(basename $DLL)." - cp "$DLL" ${DLL_PREFIX}osgPlugins-3.6.5 - done - echo - echo "- Qt Platform DLLs..." - mkdir -p ${DLL_PREFIX}platforms - for DLL in $QT_PLATFORMS; do - echo " $(basename $DLL)" - cp "$DLL" "${DLL_PREFIX}platforms" - done - echo #fi if [ -n "$ACTIVATE_MSVC" ]; then echo -n "- Activating MSVC in the current shell... " command -v vswhere >/dev/null 2>&1 || { echo "Error: vswhere is not on the path."; wrappedExit 1; } - MSVC_INSTALLATION_PATH=$(vswhere -legacy -products '*' -version "[$MSVC_VER,$(awk "BEGIN { print $MSVC_REAL_VER + 1; exit }"))" -property installationPath) + MSVC_INSTALLATION_PATH=$(vswhere -products '*' -version "[$MSVC_REAL_VER,$(awk "BEGIN { print $MSVC_REAL_VER + 1; exit }"))" -property installationPath) if [ -z "$MSVC_INSTALLATION_PATH" ]; then echo "vswhere was unable to find MSVC $MSVC_DISPLAY_YEAR" wrappedExit 1 From 753ca915569b3531f9543b5806a47de87a273227 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 8 Sep 2020 16:55:12 +0400 Subject: [PATCH 097/224] Set a minimum 1gp cost for services (regression #5600) --- apps/openmw/mwgui/merchantrepair.cpp | 1 + apps/openmw/mwgui/spellbuyingwindow.cpp | 2 +- apps/openmw/mwgui/spellcreationdialog.cpp | 3 ++- apps/openmw/mwgui/trainingwindow.cpp | 5 +++-- apps/openmw/mwgui/travelwindow.cpp | 7 ++++++- apps/openmw/mwmechanics/enchanting.cpp | 2 +- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index 282c0e4ea..e737cb2b2 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -63,6 +63,7 @@ void MerchantRepair::setPtr(const MWWorld::Ptr &actor) int x = static_cast((maxDurability - durability) / r); x = static_cast(fRepairMult * x); + x = std::max(1, x); int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true); diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index eea98a768..eb51f560b 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -42,7 +42,7 @@ namespace MWGui const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - int price = static_cast(spell.mData.mCost*store.get().find("fSpellValueMult")->mValue.getFloat()); + int price = std::max(1, static_cast(spell.mData.mCost*store.get().find("fSpellValueMult")->mValue.getFloat())); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); MWWorld::Ptr player = MWMechanics::getPlayer(); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index a567d114b..bfdba8b2e 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -475,7 +475,8 @@ namespace MWGui float fSpellMakingValueMult = store.get().find("fSpellMakingValueMult")->mValue.getFloat(); - int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, static_cast(y * fSpellMakingValueMult),true); + int price = std::max(1, static_cast(y * fSpellMakingValueMult)); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); mPriceLabel->setCaption(MyGUI::utility::toString(int(price))); diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index d0176ece4..da3c7d186 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -99,8 +99,9 @@ namespace MWGui for (int i=0; i<3; ++i) { - int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer - (mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger(),true); + int price = static_cast(pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); + price = std::max(1, price); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); MyGUI::Button* button = mTrainingOptions->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 81cd76089..a730f95c6 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -62,9 +62,14 @@ namespace MWGui { ESM::Position PlayerPos = player.getRefData().getPosition(); float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2)); - price = static_cast(d / gmst.find("fTravelMult")->mValue.getFloat()); + float fTravelMult = gmst.find("fTravelMult")->mValue.getFloat(); + if (fTravelMult != 0) + price = static_cast(d / fTravelMult); + else + price = static_cast(d); } + price = std::max(1, price); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); // Add price for the travelling followers diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index c71516090..1717ba06f 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -281,7 +281,7 @@ namespace MWMechanics float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentValueMult")->mValue.getFloat(); int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, static_cast(getEnchantPoints() * priceMultipler), true); price *= getEnchantItemsCount() * getTypeMultiplier(); - return price; + return std::max(1, price); } int Enchanting::getGemCharge() const From 85b5fdee3573bbe215aee3455763b4de3f751323 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sat, 12 Sep 2020 00:20:44 +0100 Subject: [PATCH 098/224] Discard the alpha channel of 16-bit TGAs, just like Morrowind --- components/resource/imagemanager.cpp | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/components/resource/imagemanager.cpp b/components/resource/imagemanager.cpp index 41ce999e0..ff6fb04a6 100644 --- a/components/resource/imagemanager.cpp +++ b/components/resource/imagemanager.cpp @@ -115,6 +115,29 @@ namespace Resource return mWarningImage; } + bool killAlpha = false; + if (reader->supportedExtensions().count("tga")) + { + // Morrowind ignores the alpha channel of 16bpp TGA files even when the header says not to + unsigned char header[18]; + stream->read((char*)header, 18); + if (stream->gcount() != 18) + { + Log(Debug::Error) << "Error loading " << filename << ": couldn't read TGA header"; + mCache->addEntryToObjectCache(normalized, mWarningImage); + return mWarningImage; + } + int type = header[2]; + int depth; + if (type == 1 || type == 9) + depth = header[7]; + else + depth = header[16]; + int alphaBPP = header[17] & 0x0F; + killAlpha = depth == 16 && alphaBPP == 1; + stream->seekg(0); + } + osgDB::ReaderWriter::ReadResult result = reader->readImage(*stream, mOptions); if (!result.success()) { @@ -149,6 +172,18 @@ namespace Resource image = newImage; } } + else if (killAlpha) + { + osg::ref_ptr newImage = new osg::Image; + newImage->setFileName(image->getFileName()); + newImage->allocateImage(image->s(), image->t(), image->r(), GL_RGB, GL_UNSIGNED_BYTE); + // OSG just won't write the alpha as there's nowhere to put it. + for (int s = 0; s < image->s(); ++s) + for (int t = 0; t < image->t(); ++t) + for (int r = 0; r < image->r(); ++r) + newImage->setColor(image->getColor(s, t, r), s, t, r); + image = newImage; + } mCache->addEntryToObjectCache(normalized, image); return image; From 58b5249e8bf175916fa18f1c7bb5c5a716c455d9 Mon Sep 17 00:00:00 2001 From: tessa Date: Sun, 13 Sep 2020 10:46:27 -0500 Subject: [PATCH 099/224] fix typo in terrainstorage.hpp --- apps/openmw/mwrender/terrainstorage.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/terrainstorage.hpp b/apps/openmw/mwrender/terrainstorage.hpp index 14bed7b7b..c9ad94398 100644 --- a/apps/openmw/mwrender/terrainstorage.hpp +++ b/apps/openmw/mwrender/terrainstorage.hpp @@ -17,7 +17,7 @@ namespace MWRender { public: - TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern = "", const std::string& normalHeightMapPatteern = "", bool autoUseNormalMaps = false, const std::string& specularMapPattern = "", bool autoUseSpecularMaps = false); + TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern = "", const std::string& normalHeightMapPattern = "", bool autoUseNormalMaps = false, const std::string& specularMapPattern = "", bool autoUseSpecularMaps = false); ~TerrainStorage(); virtual osg::ref_ptr getLand (int cellX, int cellY) override; From 874c754b68b8af2f8cbf9c5937605e6a8d8237c3 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Mon, 31 Aug 2020 23:16:10 +0200 Subject: [PATCH 100/224] Fix #5557 --- CHANGELOG.md | 1 + apps/openmw/mwinput/actionmanager.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 19 +++++++------------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c68e7b0f5..00d7f3539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Bug #5531: Actors flee using current rotation by axis x Bug #5539: Window resize breaks when going from a lower resolution to full screen resolution Bug #5548: Certain exhausted topics can be highlighted again even though there's no new dialogue + Bug #5557: Diagonal movement is noticeably slower with analogue stick Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index d2430a612..b29aa58a2 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -141,7 +141,7 @@ namespace MWInput float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight); float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward); - bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; + bool isRunning = osg::Vec2f(xAxis * 2 - 1, yAxis * 2 - 1).length2() > 0.25f; if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning) player.setRunState(!mBindingsManager->actionIsActive(A_Run)); else diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 449ac69bb..ad30c16bd 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1954,20 +1954,15 @@ void CharacterController::update(float duration, bool animationOnly) osg::Vec3f rot = cls.getRotationVector(mPtr); osg::Vec3f vec(movementSettings.asVec3()); - - if (isPlayer) - { - // TODO: Move this code to mwinput. - // Joystick analogue movement. - movementSettings.mSpeedFactor = std::max(std::abs(vec.x()), std::abs(vec.y())); - - // Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a keyboard was used. - if(!isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) - movementSettings.mSpeedFactor *= 2.f; - } else - movementSettings.mSpeedFactor = std::min(vec.length(), 1.f); + movementSettings.mSpeedFactor = std::min(vec.length(), 1.f); vec.normalize(); + // TODO: Move this check to mwinput. + // Joystick analogue movement. + // Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a keyboard was used. + if (isPlayer && !isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) + movementSettings.mSpeedFactor *= 2.f; + float effectiveRotation = rot.z(); bool canMove = cls.getMaxSpeed(mPtr) > 0; static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); From fe82cd9f92a0d6aa7cf3a5f02932b6d8b7fd4490 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 15 Sep 2020 21:13:18 +0200 Subject: [PATCH 101/224] Don't search containers --- apps/openmw/mwworld/worldimp.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f1c8ed73a..9ba24541d 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -287,9 +287,9 @@ namespace MWWorld ///< Return a pointer to a liveCellRef with the given name. /// \param activeOnly do non search inactive cells. - Ptr searchPtr (const std::string& name, bool activeOnly, bool searchInContainers = true) override; + Ptr searchPtr (const std::string& name, bool activeOnly, bool searchInContainers = false) override; ///< Return a pointer to a liveCellRef with the given name. - /// \param activeOnly do non search inactive cells. + /// \param activeOnly do not search inactive cells. Ptr searchPtrViaActorId (int actorId) override; ///< Search is limited to the active cells. From b2cb98d30e62c78470c479f471f622835828299a Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 16 Sep 2020 23:03:42 +0100 Subject: [PATCH 102/224] Fix NiFlipController NiFlipControllers *always* affect the base texture, even if no base texture is bound. When no base texture is bound, they default to UV set zero and to having wrapped UV coordinates, instead of using the settings for the disabled base texture. --- components/nifosg/controller.cpp | 2 +- components/nifosg/nifloader.cpp | 77 +++++++++++++++++++------------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 58f1c17a7..b6610728a 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -449,7 +449,7 @@ void MaterialColorController::apply(osg::StateSet *stateset, osg::NodeVisitor *n } FlipController::FlipController(const Nif::NiFlipController *ctrl, const std::vector >& textures) - : mTexSlot(ctrl->mTexSlot) + : mTexSlot(0) // always affects diffuse , mDelta(ctrl->mDelta) , mTextures(textures) { diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 21ae49975..24184f2c8 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -799,22 +799,23 @@ namespace NifOsg { const Nif::NiFlipController* flipctrl = static_cast(ctrl.getPtr()); std::vector > textures; + + // inherit wrap settings from the target slot + osg::Texture2D* inherit = dynamic_cast(stateset->getTextureAttribute(0, osg::StateAttribute::TEXTURE)); + osg::Texture2D::WrapMode wrapS = osg::Texture2D::REPEAT; + osg::Texture2D::WrapMode wrapT = osg::Texture2D::REPEAT; + if (inherit) + { + wrapS = inherit->getWrap(osg::Texture2D::WRAP_S); + wrapT = inherit->getWrap(osg::Texture2D::WRAP_T); + } + for (unsigned int i=0; imSources.length(); ++i) { Nif::NiSourceTexturePtr st = flipctrl->mSources[i]; if (st.empty()) continue; - // inherit wrap settings from the target slot - osg::Texture2D* inherit = dynamic_cast(stateset->getTextureAttribute(flipctrl->mTexSlot, osg::StateAttribute::TEXTURE)); - osg::Texture2D::WrapMode wrapS = osg::Texture2D::CLAMP_TO_EDGE; - osg::Texture2D::WrapMode wrapT = osg::Texture2D::CLAMP_TO_EDGE; - if (inherit) - { - wrapS = inherit->getWrap(osg::Texture2D::WRAP_S); - wrapT = inherit->getWrap(osg::Texture2D::WRAP_T); - } - osg::ref_ptr image (handleSourceTexture(st.getPtr(), imageManager)); osg::ref_ptr texture (new osg::Texture2D(image)); if (image) @@ -1451,7 +1452,7 @@ namespace NifOsg // If this loop is changed such that the base texture isn't guaranteed to end up in texture unit 0, the shadow casting shader will need to be updated accordingly. for (size_t i=0; itextures.size(); ++i) { - if (texprop->textures[i].inUse) + if (texprop->textures[i].inUse || (i == Nif::NiTexturingProperty::BaseTexture && !texprop->controller.empty())) { switch(i) { @@ -1477,32 +1478,44 @@ namespace NifOsg } } - const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i]; - if(tex.texture.empty() && texprop->controller.empty()) - { - if (i == 0) - Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName << "\" in " << mFilename; - continue; - } - + unsigned int uvSet = 0; // create a new texture, will later attempt to share using the SharedStateManager osg::ref_ptr texture2d; - if (!tex.texture.empty()) + if (texprop->textures[i].inUse) { - 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()); + const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i]; + if(tex.texture.empty() && texprop->controller.empty()) + { + if (i == 0) + Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName << "\" in " << mFilename; + continue; + } + + if (!tex.texture.empty()) + { + 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; + + bool wrapT = tex.clamp & 0x1; + bool wrapS = (tex.clamp >> 1) & 0x1; + + texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); + texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); } else + { + // Texture only comes from NiFlipController, so tex is ignored, set defaults texture2d = new osg::Texture2D; - - bool wrapT = tex.clamp & 0x1; - bool wrapS = (tex.clamp >> 1) & 0x1; - - texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); - texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); + texture2d->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); + texture2d->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); + uvSet = 0; + } unsigned int texUnit = boundTextures.size(); @@ -1590,7 +1603,7 @@ namespace NifOsg break; } - boundTextures.push_back(tex.uvSet); + boundTextures.push_back(uvSet); } } handleTextureControllers(texprop, composite, imageManager, stateset, animflags); From f8f72ce4c4c24c5a1691629270fad64ed5eb1240 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 16 Sep 2020 23:08:01 +0100 Subject: [PATCH 103/224] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00d7f3539..026a65c24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Bug #1662: Qt4 and Windows binaries crash if there's a non-ASCII character in a file path/config path Bug #1952: Incorrect particle lighting + Bug #2069: Fireflies in Fireflies invade Morrowind look wrong Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs Bug #3676: NiParticleColorModifier isn't applied properly Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects From 3f61ff3a444edcff977ae8882ea9a45b8d67a5f8 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sat, 19 Sep 2020 23:30:34 +0100 Subject: [PATCH 104/224] Make OpenGL debugging optional --- apps/openmw/engine.cpp | 6 ++++-- components/debug/gldebug.cpp | 14 ++++++++++++++ components/debug/gldebug.hpp | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 93b371805..f42dfe3f7 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -516,7 +516,8 @@ void OMW::Engine::createWindow(Settings::Manager& settings) checkSDLError(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)); - checkSDLError(SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG)); + if (Debug::shouldDebugOpenGL()) + checkSDLError(SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG)); if (antialiasing > 0) { @@ -577,7 +578,8 @@ void OMW::Engine::createWindow(Settings::Manager& settings) camera->setGraphicsContext(graphicsWindow); camera->setViewport(0, 0, traits->width, traits->height); - mViewer->setRealizeOperation(new Debug::EnableGLDebugOperation()); + if (Debug::shouldDebugOpenGL()) + mViewer->setRealizeOperation(new Debug::EnableGLDebugOperation()); mViewer->realize(); diff --git a/components/debug/gldebug.cpp b/components/debug/gldebug.cpp index 76e7a4bb9..20448ccbb 100644 --- a/components/debug/gldebug.cpp +++ b/components/debug/gldebug.cpp @@ -31,6 +31,8 @@ either expressed or implied, of the FreeBSD Project. #include "gldebug.hpp" +#include + #include // OpenGL constants not provided by OSG: @@ -144,3 +146,15 @@ void Debug::EnableGLDebugOperation::operator()(osg::GraphicsContext* graphicsCon unsigned int contextID = graphicsContext->getState()->getContextID(); enableGLDebugExtension(contextID); } + +bool Debug::shouldDebugOpenGL() +{ + const char* env = std::getenv("OPENMW_DEBUG_OPENGL"); + if (!env) + return false; + std::string str(env); + if (str.length() == 0) + return true; + + return str.find("OFF") == std::string::npos && str.find("0") == std::string::npos && str.find("NO") == std::string::npos; +} diff --git a/components/debug/gldebug.hpp b/components/debug/gldebug.hpp index 77d6c82a8..823d4f36f 100644 --- a/components/debug/gldebug.hpp +++ b/components/debug/gldebug.hpp @@ -15,5 +15,7 @@ namespace Debug private: OpenThreads::Mutex mMutex; }; + + bool shouldDebugOpenGL(); } #endif From 22c3588d0d9ac14f449008232463af876e367c88 Mon Sep 17 00:00:00 2001 From: psi29a Date: Sun, 20 Sep 2020 12:22:31 +0000 Subject: [PATCH 105/224] Merge branch '4771-and-4631' into 'master' Try lower MSAA level if the requested value isn't available Closes #4471 and #4631 See merge request OpenMW/openmw!297 (cherry picked from commit b3db387512340a5e9a77427c2d7d9d88c2340056) da0aef7a Retrieve SDL OpenGL attributes after context creation a51e63b3 Try lower MSAA levels if OpenGL context doesn't have what we requested c4e92a0a Update CHANGELOG.md --- CHANGELOG.md | 1 + apps/openmw/engine.cpp | 103 +++++++++++++---------- components/sdlutil/sdlgraphicswindow.cpp | 23 +++++ 3 files changed, 83 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 026a65c24..dfb6532f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Bug #4021: Attributes and skills are not stored as floats Bug #4055: Local scripts don't inherit variables from their base record Bug #4623: Corprus implementation is incorrect + Bug #4631: Setting MSAA level too high doesn't fall back to highest supported level Bug #4764: Data race in osg ParticleSystem Bug #4774: Guards are ignorant of an invisible player that tries to attack them Bug #5108: Savegame bloating due to inefficient fog textures format diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f42dfe3f7..5f0884a9e 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -525,65 +525,80 @@ void OMW::Engine::createWindow(Settings::Manager& settings) checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); } - while (!mWindow) + osg::ref_ptr graphicsWindow; + while (!graphicsWindow || !graphicsWindow->valid()) { - mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags); - if (!mWindow) + while (!mWindow) { - // Try with a lower AA - if (antialiasing > 0) + mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags); + if (!mWindow) { - Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2; - antialiasing /= 2; - Settings::Manager::setInt("antialiasing", "Video", antialiasing); - checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); - continue; - } - else - { - std::stringstream error; - error << "Failed to create SDL window: " << SDL_GetError(); - throw std::runtime_error(error.str()); + // Try with a lower AA + if (antialiasing > 0) + { + Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2; + antialiasing /= 2; + Settings::Manager::setInt("antialiasing", "Video", antialiasing); + checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); + continue; + } + else + { + std::stringstream error; + error << "Failed to create SDL window: " << SDL_GetError(); + throw std::runtime_error(error.str()); + } } } + + setWindowIcon(); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + SDL_GetWindowPosition(mWindow, &traits->x, &traits->y); + SDL_GetWindowSize(mWindow, &traits->width, &traits->height); + traits->windowName = SDL_GetWindowTitle(mWindow); + traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS); + traits->screenNum = SDL_GetWindowDisplayIndex(mWindow); + traits->vsync = vsync; + traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow); + + graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits); + if (!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext"); + + if (traits->samples < antialiasing) + { + Log(Debug::Warning) << "Warning: Framebuffer MSAA level is only " << traits->samples << "x instead of " << antialiasing << "x. Trying " << antialiasing / 2 << "x instead."; + graphicsWindow->closeImplementation(); + SDL_DestroyWindow(mWindow); + mWindow = nullptr; + antialiasing /= 2; + Settings::Manager::setInt("antialiasing", "Video", antialiasing); + checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); + continue; + } + + if (traits->red < 8) + Log(Debug::Warning) << "Warning: Framebuffer only has a " << traits->red << " bit red channel."; + if (traits->green < 8) + Log(Debug::Warning) << "Warning: Framebuffer only has a " << traits->green << " bit green channel."; + if (traits->blue < 8) + Log(Debug::Warning) << "Warning: Framebuffer only has a " << traits->blue << " bit blue channel."; + if (traits->depth < 8) + Log(Debug::Warning) << "Warning: Framebuffer only has " << traits->red << " bits of depth precision."; + + traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel } - setWindowIcon(); - - osg::ref_ptr traits = new osg::GraphicsContext::Traits; - SDL_GetWindowPosition(mWindow, &traits->x, &traits->y); - SDL_GetWindowSize(mWindow, &traits->width, &traits->height); - traits->windowName = SDL_GetWindowTitle(mWindow); - traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS); - traits->screenNum = SDL_GetWindowDisplayIndex(mWindow); - // We tried to get rid of the hardcoding but failed: https://github.com/OpenMW/openmw/pull/1771 - // Here goes kcat's quote: - // It's ultimately a chicken and egg problem, and the reason why the code is like it was in the first place. - // It needs a context to get the current attributes, but it needs the attributes to set up the context. - // So it just specifies the same values that were given to SDL in the hopes that it's good enough to what the window eventually gets. - traits->red = 8; - traits->green = 8; - traits->blue = 8; - traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel - traits->depth = 24; - traits->stencil = 8; - traits->vsync = vsync; - traits->doubleBuffer = true; - traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow); - - osg::ref_ptr graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits); - if(!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext"); - osg::ref_ptr camera = mViewer->getCamera(); camera->setGraphicsContext(graphicsWindow); - camera->setViewport(0, 0, traits->width, traits->height); + camera->setViewport(0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height); if (Debug::shouldDebugOpenGL()) mViewer->setRealizeOperation(new Debug::EnableGLDebugOperation()); mViewer->realize(); - mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, traits->width, traits->height); + mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height); } void OMW::Engine::setWindowIcon() diff --git a/components/sdlutil/sdlgraphicswindow.cpp b/components/sdlutil/sdlgraphicswindow.cpp index cd5e80c31..0a1951700 100644 --- a/components/sdlutil/sdlgraphicswindow.cpp +++ b/components/sdlutil/sdlgraphicswindow.cpp @@ -118,6 +118,29 @@ void GraphicsWindowSDL2::init() setSwapInterval(_traits->vsync); + // Update traits with what we've actually been given + // Use intermediate to avoid signed/unsigned mismatch + int intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &intermediateLocation); + _traits->red = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &intermediateLocation); + _traits->green = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &intermediateLocation); + _traits->blue = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &intermediateLocation); + _traits->alpha = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &intermediateLocation); + _traits->depth = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &intermediateLocation); + _traits->stencil = intermediateLocation; + + SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &intermediateLocation); + _traits->doubleBuffer = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &intermediateLocation); + _traits->sampleBuffers = intermediateLocation; + SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &intermediateLocation); + _traits->samples = intermediateLocation; + SDL_GL_MakeCurrent(oldWin, oldCtx); mValid = true; From 390fb4f12e162e63a4a3028b240770943e6a4b87 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 21 Sep 2020 00:49:09 +0100 Subject: [PATCH 106/224] Disable OpenGL Debug stuff when SDL doesn't provide the necessary definitions --- components/debug/gldebug.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/debug/gldebug.cpp b/components/debug/gldebug.cpp index 20448ccbb..3c5ec728a 100644 --- a/components/debug/gldebug.cpp +++ b/components/debug/gldebug.cpp @@ -40,6 +40,7 @@ either expressed or implied, of the FreeBSD Project. void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { +#ifdef GL_DEBUG_OUTPUT std::string srcStr; switch (source) { @@ -96,10 +97,12 @@ void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsiz } Log(logSeverity) << "OpenGL " << typeStr << " [" << srcStr << "]: " << message; +#endif } void enableGLDebugExtension(unsigned int contextID) { +#ifdef GL_DEBUG_OUTPUT typedef void (GL_APIENTRY *DEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); typedef void (GL_APIENTRY *GLDebugMessageControlFunction)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (GL_APIENTRY *GLDebugMessageCallbackFunction)(DEBUGPROC, const void* userParam); @@ -132,6 +135,7 @@ void enableGLDebugExtension(unsigned int contextID) Log(Debug::Info) << "OpenGL debug callback attached."; } else +#endif Log(Debug::Error) << "Unable to attach OpenGL debug callback."; } From 7d776609c81daa0d60e899d0c27cb82592ecb371 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 21 Sep 2020 10:31:48 +0400 Subject: [PATCH 107/224] Fix unsugned/signed comparison warning --- apps/openmw/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 5f0884a9e..012ab8f59 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -490,7 +490,7 @@ void OMW::Engine::createWindow(Settings::Manager& settings) bool fullscreen = settings.getBool("fullscreen", "Video"); bool windowBorder = settings.getBool("window border", "Video"); bool vsync = settings.getBool("vsync", "Video"); - int antialiasing = settings.getInt("antialiasing", "Video"); + unsigned int antialiasing = std::max(0, settings.getInt("antialiasing", "Video")); int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen), pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen); From 387bda5e2207023dedf23630ca90775169ca8399 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 8 Sep 2020 22:49:02 +0300 Subject: [PATCH 108/224] Add inverse order rotation support to SetAngle (feature #5579) --- CHANGELOG.md | 1 + apps/openmw/mwscript/transformationextensions.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb6532f3..2287943ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Feature #5524: Resume failed script execution after reload Feature #5525: Search fields tweaks (utf-8) Feature #5545: Option to allow stealing from an unconscious NPC during combat + Feature #5579: MCP SetAngle enhancement Task #5480: Drop Qt4 support Task #5520: Improve cell name autocompleter implementation diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 7bb9093c1..3bc8cb1f0 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -159,12 +159,20 @@ namespace MWScript float ay = ptr.getRefData().getPosition().rot[1]; float az = ptr.getRefData().getPosition().rot[2]; + // XYZ axis use the inverse (XYZ) rotation order like vanilla SetAngle. + // UWV axis use the standard (ZYX) rotation order like TESCS/OpenMW-CS and the rest of the game. if (axis == "x") - MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az); + MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az,MWBase::RotationFlag_inverseOrder); else if (axis == "y") - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az); + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az,MWBase::RotationFlag_inverseOrder); else if (axis == "z") - MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle); + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle,MWBase::RotationFlag_inverseOrder); + else if (axis == "u") + MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az,MWBase::RotationFlag_none); + else if (axis == "w") + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az,MWBase::RotationFlag_none); + else if (axis == "v") + MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle,MWBase::RotationFlag_none); } }; From f8389c6c37d3658cee659bf8fa09623a72fc7ca0 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 22 Sep 2020 00:33:27 +0300 Subject: [PATCH 109/224] Support enchantment absorption --- apps/openmw/mwmechanics/spellabsorption.cpp | 23 +++++++++++++++++---- apps/openmw/mwmechanics/spellabsorption.hpp | 7 ++----- apps/openmw/mwmechanics/spellcasting.cpp | 2 +- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/spellabsorption.cpp b/apps/openmw/mwmechanics/spellabsorption.cpp index f22cef3f6..71e1d0aee 100644 --- a/apps/openmw/mwmechanics/spellabsorption.cpp +++ b/apps/openmw/mwmechanics/spellabsorption.cpp @@ -12,6 +12,7 @@ #include "../mwworld/inventorystore.hpp" #include "creaturestats.hpp" +#include "spellutil.hpp" namespace MWMechanics { @@ -43,9 +44,9 @@ namespace MWMechanics } }; - bool absorbSpell (const ESM::Spell* spell, const MWWorld::Ptr& caster, const MWWorld::Ptr& target) + bool absorbSpell (const std::string& spellId, const MWWorld::Ptr& caster, const MWWorld::Ptr& target) { - if (!spell || caster == target || !target.getClass().isActor()) + if (spellId.empty() || caster == target || !target.getClass().isActor()) return false; CreatureStats& stats = target.getClass().getCreatureStats(target); @@ -62,13 +63,27 @@ namespace MWMechanics if (Misc::Rng::roll0to99() >= chance) return false; - const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get().find("VFX_Absorb"); + const auto& esmStore = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Static* absorbStatic = esmStore.get().find("VFX_Absorb"); MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target); if (animation && !absorbStatic->mModel.empty()) animation->addEffect( "meshes\\" + absorbStatic->mModel, ESM::MagicEffect::SpellAbsorption, false, std::string()); + const ESM::Spell* spell = esmStore.get().search(spellId); + int spellCost = 0; + if (spell) + { + spellCost = spell->mData.mCost; + } + else + { + const ESM::Enchantment* enchantment = esmStore.get().search(spellId); + if (enchantment) + spellCost = getEffectiveEnchantmentCastCost(static_cast(enchantment->mData.mCost), caster); + } + // Magicka is increased by the cost of the spell DynamicStat magicka = stats.getMagicka(); - magicka.setCurrent(magicka.getCurrent() + spell->mData.mCost); + magicka.setCurrent(magicka.getCurrent() + spellCost); stats.setMagicka(magicka); return true; } diff --git a/apps/openmw/mwmechanics/spellabsorption.hpp b/apps/openmw/mwmechanics/spellabsorption.hpp index 147090d96..0fe501df9 100644 --- a/apps/openmw/mwmechanics/spellabsorption.hpp +++ b/apps/openmw/mwmechanics/spellabsorption.hpp @@ -1,10 +1,7 @@ #ifndef MWMECHANICS_SPELLABSORPTION_H #define MWMECHANICS_SPELLABSORPTION_H -namespace ESM -{ - struct Spell; -} +#include namespace MWWorld { @@ -14,7 +11,7 @@ namespace MWWorld namespace MWMechanics { // Try to absorb a spell based on the magnitude of every Spell Absorption effect source on the target. - bool absorbSpell(const ESM::Spell* spell, const MWWorld::Ptr& caster, const MWWorld::Ptr& target); + bool absorbSpell(const std::string& spellId, const MWWorld::Ptr& caster, const MWWorld::Ptr& target); } #endif diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 3767acb3f..81b3a353d 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -119,7 +119,7 @@ namespace MWMechanics // effects, we display a "can't re-cast" message // Try absorbing the spell. Some handling must still happen for absorbed effects. - bool absorbed = absorbSpell(spell, caster, target); + bool absorbed = absorbSpell(mId, caster, target); int currentEffectIndex = 0; for (std::vector::const_iterator effectIt (effects.mList.begin()); From 71ba94a89ad7f5980df6adb7db0abcf56a843f81 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 29 Aug 2020 10:33:57 +0200 Subject: [PATCH 110/224] Smooth turning; smooth stopping; combat headtracking --- apps/openmw/mwmechanics/actors.cpp | 24 ++++++++++++++++++----- apps/openmw/mwmechanics/aibreathe.cpp | 2 +- apps/openmw/mwmechanics/aipackage.cpp | 26 ++++++++++++++++++++++++- apps/openmw/mwmechanics/aiwander.cpp | 1 + apps/openmw/mwmechanics/pathfinding.cpp | 23 ++++++++++++++++++++++ apps/openmw/mwmechanics/steering.cpp | 24 ++++++++++------------- files/settings-default.cfg | 3 +++ 7 files changed, 82 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0dfa7a9e6..0b268214b 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -473,6 +473,10 @@ namespace MWMechanics void Actors::updateMovementSpeed(const MWWorld::Ptr& actor) { + static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); + if (smoothMovement) + return; + CreatureStats &stats = actor.getClass().getCreatureStats(actor); MWMechanics::AiSequence& seq = stats.getAiSequence(); @@ -481,9 +485,10 @@ namespace MWMechanics osg::Vec3f targetPos = seq.getActivePackage().getDestination(); osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); float distance = (targetPos - actorPos).length(); + if (distance < DECELERATE_DISTANCE) { - float speedCoef = std::max(0.7f, 0.1f * (distance/64.f + 2.f)); + float speedCoef = std::max(0.7f, 0.2f + 0.8f * distance / DECELERATE_DISTANCE); auto& movement = actor.getClass().getMovementSettings(actor); movement.mPosition[0] *= speedCoef; movement.mPosition[1] *= speedCoef; @@ -1769,14 +1774,12 @@ namespace MWMechanics MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first); bool firstPersonPlayer = isPlayer && world->isFirstPerson(); + bool inCombatOrPursue = stats.getAiSequence().isInCombat() || stats.getAiSequence().hasPackage(AiPackageTypeId::Pursue); // 1. Unconsious actor can not track target // 2. Actors in combat and pursue mode do not bother to headtrack // 3. Player character does not use headtracking in the 1st-person view - if (!stats.getKnockedDown() && - !stats.getAiSequence().isInCombat() && - !stats.getAiSequence().hasPackage(AiPackageTypeId::Pursue) && - !firstPersonPlayer) + if (!stats.getKnockedDown() && !firstPersonPlayer && !inCombatOrPursue) { for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it) { @@ -1786,6 +1789,17 @@ namespace MWMechanics } } + if (!stats.getKnockedDown() && !isPlayer && inCombatOrPursue) + { + // Actors in combat and pursue mode always look at their target. + for (const auto& package : stats.getAiSequence()) + { + headTrackTarget = package->getTarget(); + if (!headTrackTarget.isEmpty()) + break; + } + } + ctrl->setHeadTrackTarget(headTrackTarget); } diff --git a/apps/openmw/mwmechanics/aibreathe.cpp b/apps/openmw/mwmechanics/aibreathe.cpp index 15251e125..2740355b5 100644 --- a/apps/openmw/mwmechanics/aibreathe.cpp +++ b/apps/openmw/mwmechanics/aibreathe.cpp @@ -23,7 +23,7 @@ bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterContro actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); actorClass.getMovementSettings(actor).mPosition[1] = 1; - smoothTurn(actor, -180, 0); + smoothTurn(actor, -osg::PI / 2, 0); return false; } diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 53e366579..4bffd28ba 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" @@ -87,6 +88,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& //... But AI processing distance may increase in the future. if (isNearInactiveCell(position)) { + actor.getClass().getMovementSettings(actor).mPosition[0] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0; world->updateActorPath(actor, mPathFinder.getPath(), halfExtents, position, dest); return false; @@ -169,12 +171,34 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& } // turn to next path point by X,Z axes - zTurn(actor, mPathFinder.getZAngleToNext(position.x(), position.y())); + float zAngleToNext = mPathFinder.getZAngleToNext(position.x(), position.y()); + zTurn(actor, zAngleToNext); smoothTurn(actor, mPathFinder.getXAngleToNext(position.x(), position.y(), position.z()), 0); const auto destination = mPathFinder.getPath().empty() ? dest : mPathFinder.getPath().front(); mObstacleCheck.update(actor, destination, duration); + static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); + if (smoothMovement) + { + const float smoothTurnReservedDist = 150; + auto& movement = actor.getClass().getMovementSettings(actor); + float distToNextSqr = osg::Vec2f(destination.x() - position.x(), destination.y() - position.y()).length2(); + float diffAngle = zAngleToNext - actor.getRefData().getPosition().rot[2]; + if (std::cos(diffAngle) < -0.1) + movement.mPosition[0] = movement.mPosition[1] = 0; + else if (distToNextSqr > smoothTurnReservedDist * smoothTurnReservedDist) + { // Go forward (and slowly turn towards the next path point) + movement.mPosition[0] = 0; + movement.mPosition[1] = 1; + } + else + { // Next path point is near, so use diagonal movement to follow the path precisely. + movement.mPosition[0] = std::sin(diffAngle); + movement.mPosition[1] = std::max(std::cos(diffAngle), 0.f); + } + } + // handle obstacles on the way evadeObstacles(actor); diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 9e179edeb..73ede04fd 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -96,6 +96,7 @@ namespace MWMechanics void stopMovement(const MWWorld::Ptr& actor) { + actor.getClass().getMovementSettings(actor).mPosition[0] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0; } diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 4d4b5be51..a82dcf717 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -88,6 +88,24 @@ namespace const auto halfExtents = world->getHalfExtents(actor); return 2.0 * halfExtents.z(); } + + // Returns true if turn in `p2` is less than 10 degrees and all the 3 points are almost on one line. + bool isAlmostStraight(const osg::Vec3f& p1, const osg::Vec3f& p2, const osg::Vec3f& p3, float pointTolerance) { + osg::Vec3f v1 = p1 - p2; + osg::Vec3f v3 = p3 - p2; + v1.z() = v3.z() = 0; + float dotProduct = v1.x() * v3.x() + v1.y() * v3.y(); + float crossProduct = v1.x() * v3.y() - v1.y() * v3.x(); + + // Check that the angle between v1 and v3 is less or equal than 10 degrees. + static const float cos170 = std::cos(osg::PI / 180 * 170); + bool checkAngle = dotProduct <= cos170 * v1.length() * v3.length(); + + // Check that distance from p2 to the line (p1, p3) is less or equal than `pointTolerance`. + bool checkDist = std::abs(crossProduct) <= pointTolerance * (p3 - p1).length() * 2; + + return checkAngle && checkDist; + } } namespace MWMechanics @@ -286,6 +304,11 @@ namespace MWMechanics while (mPath.size() > 1 && sqrDistanceIgnoreZ(mPath.front(), position) < pointTolerance * pointTolerance) mPath.pop_front(); + while (mPath.size() > 2 && isAlmostStraight(mPath[0], mPath[1], mPath[2], pointTolerance)) + mPath.erase(mPath.begin() + 1); + if (mPath.size() > 1 && isAlmostStraight(position, mPath[0], mPath[1], pointTolerance)) + mPath.pop_front(); + if (mPath.size() == 1 && sqrDistanceIgnoreZ(mPath.front(), position) < destinationTolerance * destinationTolerance) mPath.pop_front(); } diff --git a/apps/openmw/mwmechanics/steering.cpp b/apps/openmw/mwmechanics/steering.cpp index d442085ea..eaf37fbd2 100644 --- a/apps/openmw/mwmechanics/steering.cpp +++ b/apps/openmw/mwmechanics/steering.cpp @@ -1,5 +1,8 @@ #include "steering.hpp" +#include +#include + #include "../mwworld/class.hpp" #include "../mwworld/ptr.hpp" @@ -12,19 +15,8 @@ namespace MWMechanics bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, float epsilonRadians) { - float currentAngle (actor.getRefData().getPosition().rot[axis]); - float diff (targetAngleRadians - currentAngle); - if (std::abs(diff) >= osg::DegreesToRadians(180.f)) - { - if (diff >= 0) - { - diff = diff - osg::DegreesToRadians(360.f); - } - else - { - diff = osg::DegreesToRadians(360.f) + diff; - } - } + MWMechanics::Movement& movement = actor.getClass().getMovementSettings(actor); + float diff = Misc::normalizeAngle(targetAngleRadians - actor.getRefData().getPosition().rot[axis]); float absDiff = std::abs(diff); // The turning animation actually moves you slightly, so the angle will be wrong again. @@ -33,10 +25,14 @@ bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, f return true; float limit = getAngularVelocity(actor.getClass().getMaxSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); + static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); + if (smoothMovement) + limit *= std::min(absDiff / osg::PI + 0.1, 0.5); + if (absDiff > limit) diff = osg::sign(diff) * limit; - actor.getClass().getMovementSettings(actor).mRotation[axis] = diff; + movement.mRotation[axis] = diff; return false; } diff --git a/files/settings-default.cfg b/files/settings-default.cfg index ac5433f30..63df884e5 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -325,6 +325,9 @@ uncapped damage fatigue = false # Turn lower body to movement direction. 'true' makes diagonal movement more realistic. turn to movement direction = false +# Makes all movements of NPCs and player more smooth. +smooth movement = false + # Makes player swim a bit upward from the line of sight. swim upward correction = false From bd6b984022458395a5672d1a680f0f18fb1a5c32 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Fri, 4 Sep 2020 15:03:33 +0200 Subject: [PATCH 111/224] Smoothing speed in CharacterController --- apps/openmw/mwmechanics/aiwander.cpp | 3 ++ apps/openmw/mwmechanics/character.cpp | 50 ++++++++++++++++++++++++--- apps/openmw/mwmechanics/character.hpp | 1 + 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 73ede04fd..cef97fa9b 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -469,6 +469,9 @@ namespace MWMechanics void AiWander::onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage) { + // Wait while fully stop before starting idle animation (important if "smooth movement" is enabled). + if (actor.getClass().getCurrentSpeed(actor) > 0) + return; unsigned short idleAnimation = getRandomIdle(); storage.mIdleAnimation = idleAnimation; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index ad30c16bd..2407788e7 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1963,6 +1963,50 @@ void CharacterController::update(float duration, bool animationOnly) if (isPlayer && !isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) movementSettings.mSpeedFactor *= 2.f; + static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); + if (smoothMovement && !isFirstPersonPlayer) + { + float angle = mPtr.getRefData().getPosition().rot[2]; + osg::Vec2f targetSpeed = Misc::rotateVec2f(osg::Vec2f(vec.x(), vec.y()), -angle) * movementSettings.mSpeedFactor; + osg::Vec2f delta = targetSpeed - mSmoothedSpeed; + float speedDelta = movementSettings.mSpeedFactor - mSmoothedSpeed.length(); + float deltaLen = delta.length(); + + float maxDelta; + if (std::abs(speedDelta) < deltaLen / 2) + // Turning is smooth for player and less smooth for NPCs (otherwise NPC can miss a path point). + maxDelta = duration * (isPlayer ? 3.f : 6.f); + else if (isPlayer && speedDelta < -deltaLen / 2) + // As soon as controls are released, mwinput switches player from running to walking. + // So stopping should be instant for player, otherwise it causes a small twitch. + maxDelta = 1; + else // In all other cases speeding up and stopping are smooth. + maxDelta = duration * 3.f; + + if (deltaLen > maxDelta) + delta *= maxDelta / deltaLen; + mSmoothedSpeed += delta; + + osg::Vec2f newSpeed = Misc::rotateVec2f(mSmoothedSpeed, angle); + movementSettings.mSpeedFactor = newSpeed.normalize(); + vec.x() = newSpeed.x(); + vec.y() = newSpeed.y(); + + const float eps = 0.001f; + if (movementSettings.mSpeedFactor < eps) + { + movementSettings.mSpeedFactor = 0; + vec.x() = 0; + vec.y() = 1; + } + else if ((vec.y() < 0) != mIsMovingBackward) + { + if (targetSpeed.length() < eps || (movementSettings.mPosition[1] < 0) == mIsMovingBackward) + vec.y() = mIsMovingBackward ? -eps : eps; + } + vec.normalize(); + } + float effectiveRotation = rot.z(); bool canMove = cls.getMaxSpeed(mPtr) > 0; static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); @@ -2185,13 +2229,11 @@ void CharacterController::update(float duration, bool animationOnly) : (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack))); } - else if (effectiveRotation != 0.0f) + else { // Do not play turning animation for player if rotation speed is very slow. // Actual threshold should take framerate in account. - float rotationThreshold = 0.f; - if (isPlayer) - rotationThreshold = 0.015 * 60 * duration; + float rotationThreshold = (isPlayer ? 0.015f : 0.001f) * 60 * duration; // It seems only bipedal actors use turning animations. // Also do not use turning animations in the first-person view and when sneaking. diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 6092ca724..0336c4e69 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -196,6 +196,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener float mTimeUntilWake; bool mIsMovingBackward; + osg::Vec2f mSmoothedSpeed; void setAttackTypeBasedOnMovement(); From 6a75942907e162cad9f22119d3b8d1bf7ef8eac1 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Mon, 31 Aug 2020 01:25:53 +0200 Subject: [PATCH 112/224] Fix CharacterController::setAttackTypeBasedOnMovement --- apps/openmw/mwmechanics/character.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2407788e7..f7d745250 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2737,10 +2737,9 @@ void CharacterController::setVisibility(float visibility) void CharacterController::setAttackTypeBasedOnMovement() { float *move = mPtr.getClass().getMovementSettings(mPtr).mPosition; - - if (move[1] && !move[0]) // forward-backward + if (std::abs(move[1]) > std::abs(move[0]) + 0.2f) // forward-backward mAttackType = "thrust"; - else if (move[0] && !move[1]) //sideway + else if (std::abs(move[0]) > std::abs(move[1]) + 0.2f) // sideway mAttackType = "slash"; else mAttackType = "chop"; From 79a72e4b44a3f873e61ce485bc1838985b16fb7e Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Fri, 4 Sep 2020 14:14:56 +0200 Subject: [PATCH 113/224] Slightly modify aicombat to make it more difficult to get around an enemy. The difference is visible only if turning is slow (i.e. if smooth movement enabled). --- apps/openmw/mwmechanics/aicombat.cpp | 58 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 1ae27a9cb..cbe161af1 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -5,6 +5,8 @@ #include +#include + #include #include "../mwphysics/collisiontype.hpp" @@ -240,10 +242,6 @@ namespace MWMechanics if (storage.mReadyToAttack) { - storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target); - // start new attack - storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat); - if (isRangedCombat) { // rotate actor taking into account target movement direction and projectile speed @@ -259,6 +257,10 @@ namespace MWMechanics storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); storage.mMovement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos)); // using vAimDir results in spastic movements since the head is animated } + + storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target); + // start new attack + storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat); } return false; } @@ -372,9 +374,13 @@ namespace MWMechanics void AiCombat::updateActorsMovement(const MWWorld::Ptr& actor, float duration, AiCombatStorage& storage) { // apply combat movement + float deltaAngle = storage.mMovement.mRotation[2] - actor.getRefData().getPosition().rot[2]; + osg::Vec2f movement = Misc::rotateVec2f( + osg::Vec2f(storage.mMovement.mPosition[0], storage.mMovement.mPosition[1]), -deltaAngle); + MWMechanics::Movement& actorMovementSettings = actor.getClass().getMovementSettings(actor); - actorMovementSettings.mPosition[0] = storage.mMovement.mPosition[0]; - actorMovementSettings.mPosition[1] = storage.mMovement.mPosition[1]; + actorMovementSettings.mPosition[0] = movement.x(); + actorMovementSettings.mPosition[1] = movement.y(); actorMovementSettings.mPosition[2] = storage.mMovement.mPosition[2]; rotateActorOnAxis(actor, 2, actorMovementSettings, storage); @@ -385,26 +391,11 @@ namespace MWMechanics MWMechanics::Movement& actorMovementSettings, AiCombatStorage& storage) { actorMovementSettings.mRotation[axis] = 0; - float& targetAngleRadians = storage.mMovement.mRotation[axis]; - if (targetAngleRadians != 0) - { - // Some attack animations contain small amount of movement. - // Since we use cone shapes for melee, we can use a threshold to avoid jittering - std::shared_ptr& currentAction = storage.mCurrentAction; - bool isRangedCombat = false; - currentAction->getCombatRange(isRangedCombat); - // Check if the actor now facing desired direction, no need to turn any more - if (isRangedCombat) - { - if (smoothTurn(actor, targetAngleRadians, axis)) - targetAngleRadians = 0; - } - else - { - if (smoothTurn(actor, targetAngleRadians, axis, osg::DegreesToRadians(3.f))) - targetAngleRadians = 0; - } - } + bool isRangedCombat = false; + storage.mCurrentAction->getCombatRange(isRangedCombat); + float eps = isRangedCombat ? osg::DegreesToRadians(0.5) : osg::DegreesToRadians(3.f); + float targetAngleRadians = storage.mMovement.mRotation[axis]; + smoothTurn(actor, targetAngleRadians, axis, eps); } MWWorld::Ptr AiCombat::getTarget() const @@ -489,12 +480,19 @@ namespace MWMechanics // Note: do not use for ranged combat yet since in couple with back up behaviour can move actor out of cliff else if (actor.getClass().isBipedal(actor)) { - // apply sideway movement (kind of dodging) with some probability - // if actor is within range of target's weapon - if (distToTarget <= rangeAttackOfTarget && Misc::Rng::rollClosedProbability() < 0.25) + float moveDuration = 0; + float angleToTarget = Misc::normalizeAngle(mMovement.mRotation[2] - actor.getRefData().getPosition().rot[2]); + // Apply a big side step if enemy tries to get around and come from behind. + // Otherwise apply a random side step (kind of dodging) with some probability + // if actor is within range of target's weapon. + if (std::abs(angleToTarget) > osg::PI / 4) + moveDuration = 0.2; + else if (distToTarget <= rangeAttackOfTarget && Misc::Rng::rollClosedProbability() < 0.25) + moveDuration = 0.1f + 0.1f * Misc::Rng::rollClosedProbability(); + if (moveDuration > 0) { mMovement.mPosition[0] = Misc::Rng::rollProbability() < 0.5 ? 1.0f : -1.0f; // to the left/right - mTimerCombatMove = 0.1f + 0.1f * Misc::Rng::rollClosedProbability(); + mTimerCombatMove = moveDuration; mCombatMove = true; } } From b8387825575a2cf78c619de7697187e98e5960cb Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Mon, 31 Aug 2020 01:12:52 +0200 Subject: [PATCH 114/224] Avoid collisions between actors. --- apps/openmw/mwmechanics/actors.cpp | 131 +++++++++++++++++++++++++++ apps/openmw/mwmechanics/actors.hpp | 2 + apps/openmw/mwmechanics/aiwander.cpp | 29 ++++-- apps/openmw/mwmechanics/aiwander.hpp | 7 +- files/settings-default.cfg | 6 ++ 5 files changed, 165 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0b268214b..02b71e3d5 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "../mwworld/esmstore.hpp" @@ -36,6 +37,7 @@ #include "aicombataction.hpp" #include "aifollow.hpp" #include "aipursue.hpp" +#include "aiwander.hpp" #include "actor.hpp" #include "summoning.hpp" #include "combat.hpp" @@ -1664,6 +1666,131 @@ namespace MWMechanics } + void Actors::predictAndAvoidCollisions() + { + const float minGap = 10.f; + const float maxDistToCheck = 100.f; + const float maxTimeToCheck = 1.f; + static const bool giveWayWhenIdle = Settings::Manager::getBool("NPCs give way", "Game"); + + MWWorld::Ptr player = getPlayer(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) + { + const MWWorld::Ptr& ptr = iter->first; + if (ptr == player) + continue; // Don't interfere with player controls. + + Movement& movement = ptr.getClass().getMovementSettings(ptr); + osg::Vec2f origMovement(movement.mPosition[0], movement.mPosition[1]); + bool isMoving = origMovement.length2() > 0.01; + + // Moving NPCs always should avoid collisions. + // Standing NPCs give way to moving ones if they are not in combat (or pursue) mode and either + // follow player or have a AIWander package with non-empty wander area. + bool shouldAvoidCollision = isMoving; + bool shouldTurnToApproachingActor = !isMoving; + MWWorld::Ptr currentTarget; // Combat or pursue target (NPCs should not avoid collision with their targets). + for (const auto& package : ptr.getClass().getCreatureStats(ptr).getAiSequence()) + { + if (package->getTypeId() == AiPackageTypeId::Follow) + shouldAvoidCollision = true; + else if (package->getTypeId() == AiPackageTypeId::Wander && giveWayWhenIdle) + { + if (!dynamic_cast(package.get())->isStationary()) + shouldAvoidCollision = true; + } + else if (package->getTypeId() == AiPackageTypeId::Combat || package->getTypeId() == AiPackageTypeId::Pursue) + { + currentTarget = package->getTarget(); + shouldAvoidCollision = isMoving; + shouldTurnToApproachingActor = false; + break; + } + } + if (!shouldAvoidCollision) + continue; + + float maxSpeed = ptr.getClass().getMaxSpeed(ptr); + osg::Vec2f baseSpeed = origMovement * maxSpeed; + osg::Vec3f basePos = ptr.getRefData().getPosition().asVec3(); + float baseRotZ = ptr.getRefData().getPosition().rot[2]; + osg::Vec3f halfExtents = world->getHalfExtents(ptr); + + float timeToCollision = maxTimeToCheck; + osg::Vec2f movementCorrection(0, 0); + float angleToApproachingActor = 0; + + // Iterate through all other actors and predict collisions. + for(PtrActorMap::iterator otherIter(mActors.begin()); otherIter != mActors.end(); ++otherIter) + { + const MWWorld::Ptr& otherPtr = otherIter->first; + if (otherPtr == ptr || otherPtr == currentTarget) + continue; + + osg::Vec3f otherHalfExtents = world->getHalfExtents(otherPtr); + osg::Vec3f deltaPos = otherPtr.getRefData().getPosition().asVec3() - basePos; + osg::Vec2f relPos = Misc::rotateVec2f(osg::Vec2f(deltaPos.x(), deltaPos.y()), baseRotZ); + + // Ignore actors which are not close enough or come from behind. + if (deltaPos.length2() > maxDistToCheck * maxDistToCheck || relPos.y() < 0) + continue; + + // Don't check for a collision if vertical distance is greater then the actor's height. + if (deltaPos.z() > halfExtents.z() * 2 || deltaPos.z() < -otherHalfExtents.z() * 2) + continue; + + osg::Vec3f speed = otherPtr.getClass().getMovementSettings(otherPtr).asVec3() * + otherPtr.getClass().getMaxSpeed(otherPtr); + float rotZ = otherPtr.getRefData().getPosition().rot[2]; + osg::Vec2f relSpeed = Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed; + + float collisionDist = minGap + world->getHalfExtents(ptr).x() + world->getHalfExtents(otherPtr).x(); + collisionDist = std::min(collisionDist, relPos.length()); + + // Find the earliest `t` when |relPos + relSpeed * t| == collisionDist. + float vr = relPos.x() * relSpeed.x() + relPos.y() * relSpeed.y(); + float v2 = relSpeed.length2(); + float Dh = vr * vr - v2 * (relPos.length2() - collisionDist * collisionDist); + if (Dh <= 0 || v2 == 0) + continue; // No solution; distance is always >= collisionDist. + float t = (-vr - std::sqrt(Dh)) / v2; + + if (t < 0 || t > timeToCollision) + continue; + + // Check visibility and awareness last as it's expensive. + if (!MWBase::Environment::get().getWorld()->getLOS(otherPtr, ptr)) + continue; + if (!MWBase::Environment::get().getMechanicsManager()->awarenessCheck(otherPtr, ptr)) + continue; + + timeToCollision = t; + angleToApproachingActor = std::atan2(deltaPos.x(), deltaPos.y()); + osg::Vec2f posAtT = relPos + relSpeed * t; + float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) / (collisionDist * maxSpeed); + movementCorrection = posAtT * coef; + // Step to the side rather than backward. Otherwise player will be able to push the NPC far away from it's original location. + movementCorrection.y() = std::max(0.f, movementCorrection.y()); + } + + if (timeToCollision < maxTimeToCheck) + { + // Try to evade the nearest collision. + osg::Vec2f newMovement = origMovement + movementCorrection; + if (isMoving) + { // Keep the original speed. + newMovement.normalize(); + newMovement *= origMovement.length(); + } + movement.mPosition[0] = newMovement.x(); + movement.mPosition[1] = newMovement.y(); + if (shouldTurnToApproachingActor) + zTurn(ptr, angleToApproachingActor); + } + } + } + void Actors::update (float duration, bool paused) { if(!paused) @@ -1838,6 +1965,10 @@ namespace MWMechanics } } + static const bool avoidCollisions = Settings::Manager::getBool("NPCs avoid collisions", "Game"); + if (avoidCollisions) + predictAndAvoidCollisions(); + timerUpdateAITargets += duration; timerUpdateHeadTrack += duration; timerUpdateEquippedLight += duration; diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index bd5a14c0d..2668a7131 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -63,6 +63,8 @@ namespace MWMechanics void purgeSpellEffects (int casterActorId); + void predictAndAvoidCollisions(); + public: Actors(); diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index cef97fa9b..375209a25 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -27,7 +27,7 @@ namespace MWMechanics { static const int COUNT_BEFORE_RESET = 10; - static const float DOOR_CHECK_INTERVAL = 1.5f; + static const float IDLE_POSITION_CHECK_INTERVAL = 1.5f; // to prevent overcrowding static const int DESTINATION_TOLERANCE = 64; @@ -425,15 +425,14 @@ namespace MWMechanics void AiWander::onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage) { - // Check if an idle actor is too close to a door - if so start walking - storage.mDoorCheckDuration += duration; + // Check if an idle actor is too far from all allowed nodes or too close to a door - if so start walking. + storage.mCheckIdlePositionTimer += duration; - if (storage.mDoorCheckDuration >= DOOR_CHECK_INTERVAL) + if (storage.mCheckIdlePositionTimer >= IDLE_POSITION_CHECK_INTERVAL && !isStationary()) { - storage.mDoorCheckDuration = 0; // restart timer - static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); - if (mDistance && // actor is not intended to be stationary - proximityToDoor(actor, distance*1.6f)) + storage.mCheckIdlePositionTimer = 0; // restart timer + static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance() * 1.6f; + if (proximityToDoor(actor, distance) || !isNearAllowedNode(actor, storage, distance)) { storage.setState(AiWanderStorage::Wander_MoveNow); storage.mTrimCurrentNode = false; // just in case @@ -452,6 +451,20 @@ namespace MWMechanics } } + bool AiWander::isNearAllowedNode(const MWWorld::Ptr& actor, const AiWanderStorage& storage, float distance) const + { + const osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); + auto cell = actor.getCell()->getCell(); + for (const ESM::Pathgrid::Point& node : storage.mAllowedNodes) + { + osg::Vec3f point(node.mX, node.mY, node.mZ); + Misc::CoordinateConverter(cell).toWorld(point); + if ((actorPos - point).length2() < distance * distance) + return true; + } + return false; + } + void AiWander::onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage) { // Is there no destination or are we there yet? diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 4138c3dea..4165cebbd 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -53,7 +53,7 @@ namespace MWMechanics ESM::Pathgrid::Point mCurrentNode; bool mTrimCurrentNode; - float mDoorCheckDuration; + float mCheckIdlePositionTimer; int mStuckCount; AiWanderStorage(): @@ -66,7 +66,7 @@ namespace MWMechanics mPopulateAvailableNodes(true), mAllowedNodes(), mTrimCurrentNode(false), - mDoorCheckDuration(0), // TODO: maybe no longer needed + mCheckIdlePositionTimer(0), mStuckCount(0) {}; @@ -117,6 +117,8 @@ namespace MWMechanics return mDestination; } + bool isStationary() const { return mDistance == 0; } + private: void stopWalking(const MWWorld::Ptr& actor); @@ -137,6 +139,7 @@ namespace MWMechanics void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance); bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination); void completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage); + bool isNearAllowedNode(const MWWorld::Ptr &actor, const AiWanderStorage& storage, float distance) const; const int mDistance; // how far the actor can wander from the spawn point const int mDuration; diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 63df884e5..fab5fe569 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -328,6 +328,12 @@ turn to movement direction = false # Makes all movements of NPCs and player more smooth. smooth movement = false +# All actors avoid collisions with other actors. +NPCs avoid collisions = false + +# Give way to moving actors when idle. Requires 'NPCs avoid collisions' to be enabled. +NPCs give way = true + # Makes player swim a bit upward from the line of sight. swim upward correction = false From ad51a4be2e71f49b5b24970f2a5fa6fa1e1030f8 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Tue, 15 Sep 2020 23:25:32 +0200 Subject: [PATCH 115/224] Changes in head tracking and greetings for "smooth movement". --- apps/openmw/mwmechanics/actors.cpp | 19 +++++++++---------- apps/openmw/mwmechanics/actors.hpp | 1 + apps/openmw/mwmechanics/character.cpp | 22 +++++++++++++--------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 02b71e3d5..3de1a3acc 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -426,7 +426,7 @@ namespace MWMechanics const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3()); float sqrDist = (actor1Pos - actor2Pos).length2(); - if (sqrDist > maxDistance*maxDistance) + if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance)) return; // stop tracking when target is behind the actor @@ -434,10 +434,7 @@ namespace MWMechanics osg::Vec3f targetDirection(actor2Pos - actor1Pos); actorDirection.z() = 0; targetDirection.z() = 0; - actorDirection.normalize(); - targetDirection.normalize(); - if (std::acos(actorDirection * targetDirection) < osg::DegreesToRadians(90.f) - && sqrDist <= sqrHeadTrackDistance + if (actorDirection * targetDirection > 0 && MWBase::Environment::get().getWorld()->getLOS(actor, targetActor) // check LOS and awareness last as it's the most expensive function && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(targetActor, actor)) { @@ -475,8 +472,7 @@ namespace MWMechanics void Actors::updateMovementSpeed(const MWWorld::Ptr& actor) { - static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); - if (smoothMovement) + if (mSmoothMovement) return; CreatureStats &stats = actor.getClass().getCreatureStats(actor); @@ -594,8 +590,11 @@ namespace MWMechanics if (!actorState.isTurningToPlayer()) { - actorState.setAngleToPlayer(std::atan2(dir.x(), dir.y())); - actorState.setTurningToPlayer(true); + float angle = std::atan2(dir.x(), dir.y()); + actorState.setAngleToPlayer(angle); + float deltaAngle = Misc::normalizeAngle(angle - actor.getRefData().getPosition().rot[2]); + if (!mSmoothMovement || std::abs(deltaAngle) > osg::DegreesToRadians(60.f)) + actorState.setTurningToPlayer(true); } } @@ -1467,7 +1466,7 @@ namespace MWMechanics } } - Actors::Actors() + Actors::Actors() : mSmoothMovement(Settings::Manager::getBool("smooth movement", "Game")) { mTimerDisposeSummonsCorpses = 0.2f; // We should add a delay between summoned creature death and its corpse despawning diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 2668a7131..9299d468c 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -211,6 +211,7 @@ namespace MWMechanics float mTimerDisposeSummonsCorpses; float mActorsProcessingRange; + bool mSmoothMovement; }; } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f7d745250..1dcccb888 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2038,6 +2038,8 @@ void CharacterController::update(float duration, bool animationOnly) mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 2); else mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 4); + if (smoothMovement && !isPlayer && !inwater) + mAnimation->setUpperBodyYawRadians(mAnimation->getUpperBodyYawRadians() + mAnimation->getHeadYaw() / 2); speed = cls.getCurrentSpeed(mPtr); vec.x() *= speed; @@ -2934,19 +2936,21 @@ void CharacterController::updateHeadTracking(float duration) return; const osg::Vec3f actorDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0); - zAngleRadians = std::atan2(direction.x(), direction.y()) - std::atan2(actorDirection.x(), actorDirection.y()); - xAngleRadians = -std::asin(direction.z()); - - const double xLimit = osg::DegreesToRadians(40.0); - const double zLimit = osg::DegreesToRadians(30.0); - zAngleRadians = osg::clampBetween(Misc::normalizeAngle(zAngleRadians), -xLimit, xLimit); - xAngleRadians = osg::clampBetween(Misc::normalizeAngle(xAngleRadians), -zLimit, zLimit); + zAngleRadians = std::atan2(actorDirection.x(), actorDirection.y()) - std::atan2(direction.x(), direction.y()); + xAngleRadians = std::asin(direction.z()); } + const double xLimit = osg::DegreesToRadians(40.0); + const double zLimit = osg::DegreesToRadians(30.0); + double zLimitOffset = mAnimation->getUpperBodyYawRadians(); + xAngleRadians = osg::clampBetween(Misc::normalizeAngle(xAngleRadians), -xLimit, xLimit); + zAngleRadians = osg::clampBetween(Misc::normalizeAngle(zAngleRadians), + -zLimit + zLimitOffset, zLimit + zLimitOffset); + float factor = duration*5; factor = std::min(factor, 1.f); - xAngleRadians = (1.f-factor) * mAnimation->getHeadPitch() + factor * (-xAngleRadians); - zAngleRadians = (1.f-factor) * mAnimation->getHeadYaw() + factor * (-zAngleRadians); + xAngleRadians = (1.f-factor) * mAnimation->getHeadPitch() + factor * xAngleRadians; + zAngleRadians = (1.f-factor) * mAnimation->getHeadYaw() + factor * zAngleRadians; mAnimation->setHeadPitch(xAngleRadians); mAnimation->setHeadYaw(zAngleRadians); From a17fb14b8a94f65338572f2712ad711a7de17299 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Tue, 15 Sep 2020 20:28:42 +0200 Subject: [PATCH 116/224] Add "smooth movement" and "NPCs avoid collisions" settings to openmw-launcher and to the docs; update CHANGELOG.md. --- CHANGELOG.md | 2 + apps/launcher/advancedpage.cpp | 4 ++ .../reference/modding/settings/game.rst | 37 ++++++++++++++++++- files/ui/advancedpage.ui | 22 ++++++++++- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb6532f3..7c8c6cc00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ Bug #5557: Diagonal movement is noticeably slower with analogue stick Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging + Feature #4894: Consider actors as obstacles for pathfinding Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher Feature #5362: Show the soul gems' trapped soul in count dialog Feature #5445: Handle NiLines @@ -58,6 +59,7 @@ Feature #5524: Resume failed script execution after reload Feature #5525: Search fields tweaks (utf-8) Feature #5545: Option to allow stealing from an unconscious NPC during combat + Feature #5610: Actors movement should be smoother Task #5480: Drop Qt4 support Task #5520: Improve cell name autocompleter implementation diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index bc14a9269..2e929faf5 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -88,6 +88,7 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); loadSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); + loadSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game"); int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game"); if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2) unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); @@ -112,6 +113,7 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); } loadSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); + loadSettingBool(smoothMovementCheckBox, "smooth movement", "Game"); const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain"); @@ -200,6 +202,7 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); saveSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); saveSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); + saveSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game"); int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex(); if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game")) mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); @@ -220,6 +223,7 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(weaponSheathingCheckBox, "weapon sheathing", "Game"); saveSettingBool(shieldSheathingCheckBox, "shield sheathing", "Game"); saveSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); + saveSettingBool(smoothMovementCheckBox, "smooth movement", "Game"); const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain"); diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index 46bd22e50..f942f6e7c 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -331,8 +331,43 @@ If enabled then the character turns lower body to the direction of movement. Upp This setting can be controlled in Advanced tab of the launcher. +smooth movement +--------------- + +:Type: boolean +:Range: True/False +:Default: False + +Makes NPCs and player movement more smooth. + +Recommended to use with "turn to movement direction" enabled. + +This setting can be controlled in Advanced tab of the launcher. + +NPCs avoid collisions +--------------------- + +:Type: boolean +:Range: True/False +:Default: False + +If enabled NPCs apply evasion maneuver to avoid collisions with others. + +This setting can be controlled in Advanced tab of the launcher. + +NPCs give way +------------- + +:Type: boolean +:Range: True/False +:Default: True + +Standing NPCs give way to moving ones. Works only if 'NPCs avoid collisions' is enabled. + +This setting can only be configured by editing the settings configuration file. + swim upward correction ----------------- +---------------------- :Type: boolean :Range: True/False diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 9084a7aba..3a91db791 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -43,6 +43,16 @@ + + + + <html><head/><body><p>If enabled NPCs apply evasion maneuver to avoid collisions with others.</p></body></html> + + + NPCs avoid collisions + + + @@ -233,6 +243,16 @@ + + + + <html><head/><body><p>Makes NPCs and player movement more smooth. Recommended to use with "turn to movement direction" enabled.</p></body></html> + + + Smooth movement + + + @@ -283,7 +303,7 @@ - + <html><head/><body><p>Load per-group KF-files and skeleton files from Animations folder</p></body></html> From 87290cf6d10819ad122949c8f704b9c29125d2bc Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 6 May 2020 23:26:16 +0200 Subject: [PATCH 117/224] Add support for multi configurations generators on unix Since version 3.17 cmake supports the Ninja Multi-Config No change for Xcode, VS and Ninja "single config" --- CMakeLists.txt | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 444743d28..ba56b5cc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -437,34 +437,40 @@ endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clan IF(NOT WIN32 AND NOT APPLE) # Linux installation + get_generator_is_multi_config(multi_config) + if (multi_config) + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}/$") + else () + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") + endif () # Install binaries IF(BUILD_OPENMW) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw" DESTINATION "${BINDIR}" ) ENDIF(BUILD_OPENMW) IF(BUILD_LAUNCHER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-launcher" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-launcher" DESTINATION "${BINDIR}" ) ENDIF(BUILD_LAUNCHER) IF(BUILD_BSATOOL) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/bsatool" DESTINATION "${BINDIR}" ) ENDIF(BUILD_BSATOOL) IF(BUILD_ESMTOOL) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/esmtool" DESTINATION "${BINDIR}" ) ENDIF(BUILD_ESMTOOL) IF(BUILD_NIFTEST) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/niftest" DESTINATION "${BINDIR}" ) ENDIF(BUILD_NIFTEST) IF(BUILD_MWINIIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-iniimporter" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-iniimporter" DESTINATION "${BINDIR}" ) ENDIF(BUILD_MWINIIMPORTER) IF(BUILD_ESSIMPORTER) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-essimporter" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-essimporter" DESTINATION "${BINDIR}" ) ENDIF(BUILD_ESSIMPORTER) IF(BUILD_OPENCS) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-cs" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-cs" DESTINATION "${BINDIR}" ) ENDIF(BUILD_OPENCS) IF(BUILD_WIZARD) - INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-wizard" DESTINATION "${BINDIR}" ) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-wizard" DESTINATION "${BINDIR}" ) ENDIF(BUILD_WIZARD) # Install licenses @@ -480,17 +486,17 @@ IF(NOT WIN32 AND NOT APPLE) ENDIF(BUILD_OPENCS) # Install global configuration files - INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") - INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw") - INSTALL(FILES "${OpenMW_BINARY_DIR}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") - INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") IF(BUILD_OPENCS) - INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs") + INSTALL(FILES "${INSTALL_SOURCE}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs") ENDIF(BUILD_OPENCS) # Install resources - INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources") + INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources") INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources") ENDIF(NOT WIN32 AND NOT APPLE) From db0f7c607fad78a5a7632377e37ebd97abc901b3 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 14 May 2020 14:04:42 +0100 Subject: [PATCH 118/224] Make Windows install target slightly less breakable --- CMakeLists.txt | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba56b5cc3..61e652455 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -501,31 +501,25 @@ IF(NOT WIN32 AND NOT APPLE) ENDIF(NOT WIN32 AND NOT APPLE) if(WIN32) - FILE(GLOB dll_files_debug "${OpenMW_BINARY_DIR}/Debug/*.dll") - FILE(GLOB dll_files_release "${OpenMW_BINARY_DIR}/Release/*.dll") - INSTALL(FILES ${dll_files_debug} DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES ${dll_files_release} DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg" CONFIGURATIONS Debug) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg" CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) + get_generator_is_multi_config(multi_config) + if (multi_config) + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}/$") + else () + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") + endif () + + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll") + INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".") - INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/settings-default.cfg" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/settings-default.cfg" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) + INSTALL(FILES + "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" + DESTINATION ".") + INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".") + INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".") - INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/platforms" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/platforms" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - - INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/resources" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/resources" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) - - FILE(GLOB plugin_dir_debug "${OpenMW_BINARY_DIR}/Debug/osgPlugins-*") - FILE(GLOB plugin_dir_release "${OpenMW_BINARY_DIR}/Release/osgPlugins-*") - INSTALL(DIRECTORY ${plugin_dir_debug} DESTINATION "." CONFIGURATIONS Debug) - INSTALL(DIRECTORY ${plugin_dir_release} DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) + INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION ".") SET(CPACK_GENERATOR "NSIS") SET(CPACK_PACKAGE_NAME "OpenMW") From d0ddf488dbb3406db29cecd41f94c365f06caa82 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 14 May 2020 14:10:13 +0100 Subject: [PATCH 119/224] Install PDBs when appropriate --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61e652455..f899d3a30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -509,6 +509,7 @@ if(WIN32) endif () INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll") + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb") INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") From 8dd820ba48668c58e5240a77effc200e6a905607 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 15 May 2020 17:30:12 +0000 Subject: [PATCH 120/224] Exclude deps --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f899d3a30..e65e1debe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -508,8 +508,8 @@ if(WIN32) SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") endif () - INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll") - INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb") + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll" EXCLUDE "deps/*") + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb" EXCLUDE "deps/*") INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") From 73708a6f2a56988ebc63ee43bf2f3ef3c0fad84b Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 15 May 2020 17:39:25 +0000 Subject: [PATCH 121/224] Install openmw-cs.cfg on single-config generators and from the right directory on multi-config --- apps/opencs/CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index dc9b98596..b20920904 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -233,8 +233,15 @@ target_link_libraries(openmw-cs Qt5::Widgets Qt5::Core Qt5::Network Qt5::OpenGL) if (WIN32) target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY}) INSTALL(TARGETS openmw-cs RUNTIME DESTINATION ".") - INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/openmw-cs.cfg" DESTINATION "." CONFIGURATIONS Debug) - INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/openmw-cs.cfg" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel) + + get_generator_is_multi_config(multi_config) + if (multi_config) + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}/$") + else () + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") + endif () + + INSTALL(FILES "${INSTALL_SOURCE}/openmw-cs.cfg" DESTINATION ".") endif() if (MSVC) From be5fd6fd03bc3f86ee8764ce33b1e10556fb5010 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 15 May 2020 21:43:41 +0100 Subject: [PATCH 122/224] Exclude directories correctly We don't need `/*` as we don't want the directory itself, not just its contents. We also need to list possible other directories explicitly as there's currently no way to skip directories without matches. It would be much nicer if CMake was tracking the DLLs we needed for us. --- CMakeLists.txt | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e65e1debe..41cb066e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -508,8 +508,24 @@ if(WIN32) SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") endif () - INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll" EXCLUDE "deps/*") - INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb" EXCLUDE "deps/*") + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll" + PATTERN "deps" EXCLUDE + PATTERN "apps" EXCLUDE + PATTERN "CMakeFiles" EXCLUDE + PATTERN "components" EXCLUDE + PATTERN "docs" EXCLUDE + PATTERN "extern" EXCLUDE + PATTERN "files" EXCLUDE + PATTERN "Testing" EXCLUDE) + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb" + PATTERN "deps" EXCLUDE + PATTERN "apps" EXCLUDE + PATTERN "CMakeFiles" EXCLUDE + PATTERN "components" EXCLUDE + PATTERN "docs" EXCLUDE + PATTERN "extern" EXCLUDE + PATTERN "files" EXCLUDE + PATTERN "Testing" EXCLUDE) INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") From ae38b3d9b223feea5e3dd033f5698dd4d6de5140 Mon Sep 17 00:00:00 2001 From: fredzio Date: Sun, 30 Aug 2020 11:29:44 +0200 Subject: [PATCH 123/224] Put the install logic in one place for all platforms --- CMakeLists.txt | 320 ++++++++++++++++++++++++------------------------- 1 file changed, 156 insertions(+), 164 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41cb066e4..0e7ea6800 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -435,169 +435,6 @@ elseif (MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:MULTIPLE") endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) -IF(NOT WIN32 AND NOT APPLE) - # Linux installation - get_generator_is_multi_config(multi_config) - if (multi_config) - SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}/$") - else () - SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") - endif () - - # Install binaries - IF(BUILD_OPENMW) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_OPENMW) - IF(BUILD_LAUNCHER) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-launcher" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_LAUNCHER) - IF(BUILD_BSATOOL) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/bsatool" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_BSATOOL) - IF(BUILD_ESMTOOL) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/esmtool" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_ESMTOOL) - IF(BUILD_NIFTEST) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/niftest" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_NIFTEST) - IF(BUILD_MWINIIMPORTER) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-iniimporter" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_MWINIIMPORTER) - IF(BUILD_ESSIMPORTER) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-essimporter" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_ESSIMPORTER) - IF(BUILD_OPENCS) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-cs" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_OPENCS) - IF(BUILD_WIZARD) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-wizard" DESTINATION "${BINDIR}" ) - ENDIF(BUILD_WIZARD) - - # Install licenses - INSTALL(FILES "files/mygui/DejaVuFontLicense.txt" DESTINATION "${LICDIR}" ) - - # Install icon and desktop file - INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.launcher.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}" COMPONENT "openmw") - INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.appdata.xml" DESTINATION "${DATAROOTDIR}/metainfo" COMPONENT "openmw") - IF(BUILD_OPENCS) - INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.cs.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "opencs") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/openmw-cs.png" DESTINATION "${ICONDIR}" COMPONENT "opencs") - ENDIF(BUILD_OPENCS) - - # Install global configuration files - INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") - INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw") - INSTALL(FILES "${INSTALL_SOURCE}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") - INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") - - IF(BUILD_OPENCS) - INSTALL(FILES "${INSTALL_SOURCE}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs") - ENDIF(BUILD_OPENCS) - - # Install resources - INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources") - INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources") -ENDIF(NOT WIN32 AND NOT APPLE) - -if(WIN32) - get_generator_is_multi_config(multi_config) - if (multi_config) - SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}/$") - else () - SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") - endif () - - INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll" - PATTERN "deps" EXCLUDE - PATTERN "apps" EXCLUDE - PATTERN "CMakeFiles" EXCLUDE - PATTERN "components" EXCLUDE - PATTERN "docs" EXCLUDE - PATTERN "extern" EXCLUDE - PATTERN "files" EXCLUDE - PATTERN "Testing" EXCLUDE) - INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb" - PATTERN "deps" EXCLUDE - PATTERN "apps" EXCLUDE - PATTERN "CMakeFiles" EXCLUDE - PATTERN "components" EXCLUDE - PATTERN "docs" EXCLUDE - PATTERN "extern" EXCLUDE - PATTERN "files" EXCLUDE - PATTERN "Testing" EXCLUDE) - INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") - INSTALL(FILES - "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" - DESTINATION ".") - INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".") - INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".") - - INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION ".") - - SET(CPACK_GENERATOR "NSIS") - SET(CPACK_PACKAGE_NAME "OpenMW") - SET(CPACK_PACKAGE_VENDOR "OpenMW.org") - SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) - SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) - SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINOR}) - SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW") - IF(BUILD_LAUNCHER) - SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-launcher;OpenMW Launcher") - ENDIF(BUILD_LAUNCHER) - IF(BUILD_OPENCS) - SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-cs;OpenMW Construction Set") - ENDIF(BUILD_OPENCS) - IF(BUILD_WIZARD) - SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-wizard;OpenMW Wizard") - ENDIF(BUILD_WIZARD) - SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\README.txt'") - SET(CPACK_NSIS_DELETE_ICONS_EXTRA " - !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP - Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\" - ") - SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/README.md") - SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/README.md") - SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") - SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}") - SET(CPACK_NSIS_HELP_LINK "https:\\\\\\\\www.openmw.org") - SET(CPACK_NSIS_URL_INFO_ABOUT "https:\\\\\\\\www.openmw.org") - SET(CPACK_NSIS_INSTALLED_ICON_NAME "openmw-launcher.exe") - SET(CPACK_NSIS_MUI_FINISHPAGE_RUN "openmw-launcher.exe") - SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico") - SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico") - SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp") - - SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe") - if(EXISTS ${VCREDIST32}) - INSTALL(FILES ${VCREDIST32} DESTINATION "redist") - SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q'" ) - endif(EXISTS ${VCREDIST32}) - - SET(VCREDIST64 "${OpenMW_BINARY_DIR}/vcredist_x64.exe") - if(EXISTS ${VCREDIST64}) - INSTALL(FILES ${VCREDIST64} DESTINATION "redist") - SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q'" ) - endif(EXISTS ${VCREDIST64}) - - SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe") - if(EXISTS ${OALREDIST}) - INSTALL(FILES ${OALREDIST} DESTINATION "redist") - SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} - ExecWait '\\\"$INSTDIR\\\\redist\\\\oalinst.exe\\\" /s'" ) - endif(EXISTS ${OALREDIST}) - - if(CMAKE_CL_64) - SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64") - endif() - - include(CPack) -endif(WIN32) - # Extern set(RECASTNAVIGATION_STATIC ON CACHE BOOL "Build recastnavigation static libraries") @@ -892,7 +729,162 @@ if (OPENMW_OSX_DEPLOYMENT AND APPLE) fixup_bundle(\"${INSTALLED_OPENCS_APP}\" \"${OPENCS_PLUGINS}\" \"\") " COMPONENT Runtime) include(CPack) -endif () +elseif(NOT APPLE) + get_generator_is_multi_config(multi_config) + if (multi_config) + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}/$") + else () + SET(INSTALL_SOURCE "${OpenMW_BINARY_DIR}") + endif () + + if(WIN32) + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." FILES_MATCHING PATTERN "*.dll" + PATTERN "deps" EXCLUDE + PATTERN "apps" EXCLUDE + PATTERN "CMakeFiles" EXCLUDE + PATTERN "components" EXCLUDE + PATTERN "docs" EXCLUDE + PATTERN "extern" EXCLUDE + PATTERN "files" EXCLUDE + PATTERN "Testing" EXCLUDE) + INSTALL(DIRECTORY "${INSTALL_SOURCE}/" DESTINATION "." CONFIGURATIONS Debug;RelWithDebInfo FILES_MATCHING PATTERN "*.pdb" + PATTERN "deps" EXCLUDE + PATTERN "apps" EXCLUDE + PATTERN "CMakeFiles" EXCLUDE + PATTERN "components" EXCLUDE + PATTERN "docs" EXCLUDE + PATTERN "extern" EXCLUDE + PATTERN "files" EXCLUDE + PATTERN "Testing" EXCLUDE) + INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") + INSTALL(FILES + "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" + DESTINATION ".") + INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".") + INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".") + + INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION ".") + + SET(CPACK_GENERATOR "NSIS") + SET(CPACK_PACKAGE_NAME "OpenMW") + SET(CPACK_PACKAGE_VENDOR "OpenMW.org") + SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) + SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) + SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINOR}) + SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW") + IF(BUILD_LAUNCHER) + SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-launcher;OpenMW Launcher") + ENDIF(BUILD_LAUNCHER) + IF(BUILD_OPENCS) + SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-cs;OpenMW Construction Set") + ENDIF(BUILD_OPENCS) + IF(BUILD_WIZARD) + SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-wizard;OpenMW Wizard") + ENDIF(BUILD_WIZARD) + SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\README.txt'") + SET(CPACK_NSIS_DELETE_ICONS_EXTRA " + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\" + ") + SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/README.md") + SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/README.md") + SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") + SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}") + SET(CPACK_NSIS_HELP_LINK "https:\\\\\\\\www.openmw.org") + SET(CPACK_NSIS_URL_INFO_ABOUT "https:\\\\\\\\www.openmw.org") + SET(CPACK_NSIS_INSTALLED_ICON_NAME "openmw-launcher.exe") + SET(CPACK_NSIS_MUI_FINISHPAGE_RUN "openmw-launcher.exe") + SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico") + SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico") + SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp") + + SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe") + if(EXISTS ${VCREDIST32}) + INSTALL(FILES ${VCREDIST32} DESTINATION "redist") + SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q'" ) + endif(EXISTS ${VCREDIST32}) + + SET(VCREDIST64 "${OpenMW_BINARY_DIR}/vcredist_x64.exe") + if(EXISTS ${VCREDIST64}) + INSTALL(FILES ${VCREDIST64} DESTINATION "redist") + SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q'" ) + endif(EXISTS ${VCREDIST64}) + + SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe") + if(EXISTS ${OALREDIST}) + INSTALL(FILES ${OALREDIST} DESTINATION "redist") + SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} + ExecWait '\\\"$INSTDIR\\\\redist\\\\oalinst.exe\\\" /s'" ) + endif(EXISTS ${OALREDIST}) + + if(CMAKE_CL_64) + SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64") + endif() + + include(CPack) + else(WIN32) + # Linux installation + + # Install binaries + IF(BUILD_OPENMW) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_OPENMW) + IF(BUILD_LAUNCHER) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-launcher" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_LAUNCHER) + IF(BUILD_BSATOOL) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/bsatool" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_BSATOOL) + IF(BUILD_ESMTOOL) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/esmtool" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_ESMTOOL) + IF(BUILD_NIFTEST) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/niftest" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_NIFTEST) + IF(BUILD_MWINIIMPORTER) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-iniimporter" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_MWINIIMPORTER) + IF(BUILD_ESSIMPORTER) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-essimporter" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_ESSIMPORTER) + IF(BUILD_OPENCS) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-cs" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_OPENCS) + IF(BUILD_WIZARD) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-wizard" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_WIZARD) + + # Install licenses + INSTALL(FILES "files/mygui/DejaVuFontLicense.txt" DESTINATION "${LICDIR}" ) + + # Install icon and desktop file + INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.launcher.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/launcher/images/openmw.png" DESTINATION "${ICONDIR}" COMPONENT "openmw") + INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.appdata.xml" DESTINATION "${DATAROOTDIR}/metainfo" COMPONENT "openmw") + IF(BUILD_OPENCS) + INSTALL(FILES "${OpenMW_BINARY_DIR}/org.openmw.cs.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "opencs") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/opencs/openmw-cs.png" DESTINATION "${ICONDIR}" COMPONENT "opencs") + ENDIF(BUILD_OPENCS) + + # Install global configuration files + INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") + INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") + + IF(BUILD_OPENCS) + INSTALL(FILES "${INSTALL_SOURCE}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs") + ENDIF(BUILD_OPENCS) + + # Install resources + INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources") + INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources") + endif(WIN32) +endif(NOT APPLE) # Doxygen Target -- simply run 'make doc' or 'make doc_pages' # output directory for 'make doc' is "${OpenMW_BINARY_DIR}/docs/Doxygen" From a338e8c56102b9cfb1b1213268b81ed6c64a6c00 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 24 Sep 2020 17:13:09 +0100 Subject: [PATCH 124/224] Actually set the uvSet value This got lost when uvSet was made into a local variable. --- components/nifosg/nifloader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 24184f2c8..f9274cebf 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1507,6 +1507,8 @@ namespace NifOsg texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE); + + uvSet = tex.uvSet; } else { From e0a5c24afe230e45c40ca3a64957de0318ca788a Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Mon, 21 Sep 2020 23:05:26 +0300 Subject: [PATCH 125/224] Handle 0-use items like vanilla (bug #5611) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/repair.cpp | 3 ++- apps/openmw/mwmechanics/security.cpp | 18 +++++++++++------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb6532f3..7259bd1b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Bug #5539: Window resize breaks when going from a lower resolution to full screen resolution Bug #5548: Certain exhausted topics can be highlighted again even though there's no new dialogue Bug #5557: Diagonal movement is noticeably slower with analogue stick + Bug #5611: Usable items with "0 Uses" should be used only once Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher diff --git a/apps/openmw/mwmechanics/repair.cpp b/apps/openmw/mwmechanics/repair.cpp index 389d00d85..81886ed9b 100644 --- a/apps/openmw/mwmechanics/repair.cpp +++ b/apps/openmw/mwmechanics/repair.cpp @@ -27,7 +27,8 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair) // reduce number of uses left int uses = mTool.getClass().getItemHealth(mTool); - mTool.getCellRef().setCharge(uses-1); + uses -= std::min(uses, 1); + mTool.getCellRef().setCharge(uses); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 001375feb..5b79d821c 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -33,6 +33,10 @@ namespace MWMechanics !lock.getClass().hasToolTip(lock)) //If it's unlocked or can not be unlocked back out immediately return; + int uses = lockpick.getClass().getItemHealth(lockpick); + if (uses == 0) + return; + int lockStrength = lock.getCellRef().getLockLevel(); float pickQuality = lockpick.get()->mBase->mData.mQuality; @@ -61,9 +65,7 @@ namespace MWMechanics resultMessage = "#{sLockFail}"; } - int uses = lockpick.getClass().getItemHealth(lockpick); - --uses; - lockpick.getCellRef().setCharge(uses); + lockpick.getCellRef().setCharge(uses-1); if (!uses) lockpick.getContainerStore()->remove(lockpick, 1, mActor); } @@ -71,7 +73,11 @@ namespace MWMechanics void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, std::string& resultMessage, std::string& resultSound) { - if (trap.getCellRef().getTrap() == "") + if (trap.getCellRef().getTrap().empty()) + return; + + int uses = probe.getClass().getItemHealth(probe); + if (uses == 0) return; float probeQuality = probe.get()->mBase->mData.mQuality; @@ -104,9 +110,7 @@ namespace MWMechanics resultMessage = "#{sTrapFail}"; } - int uses = probe.getClass().getItemHealth(probe); - --uses; - probe.getCellRef().setCharge(uses); + probe.getCellRef().setCharge(uses-1); if (!uses) probe.getContainerStore()->remove(probe, 1, mActor); } From f2af957647a83cc1d7a35db508f3bb2d251d77fd Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 25 Sep 2020 02:12:36 +0300 Subject: [PATCH 126/224] Reset enchant effects displayed range when they are constant (bug #5603) --- CHANGELOG.md | 1 + apps/openmw/mwgui/spellcreationdialog.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfb6532f3..74d0e048d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Bug #5539: Window resize breaks when going from a lower resolution to full screen resolution Bug #5548: Certain exhausted topics can be highlighted again even though there's no new dialogue Bug #5557: Diagonal movement is noticeably slower with analogue stick + Bug #5603: Setting constant effect cast style doesn't correct effects view Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index bfdba8b2e..1f086507f 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -739,5 +739,24 @@ namespace MWGui { mAddEffectDialog.setConstantEffect(constant); mConstantEffect = constant; + + if (!constant) + return; + + for (auto it = mEffects.begin(); it != mEffects.end();) + { + if (it->mRange != ESM::RT_Self) + { + auto& store = MWBase::Environment::get().getWorld()->getStore(); + auto magicEffect = store.get().find(it->mEffectID); + if ((magicEffect->mData.mFlags & ESM::MagicEffect::CastSelf) == 0) + { + it = mEffects.erase(it); + continue; + } + it->mRange = ESM::RT_Self; + } + ++it; + } } } From bf7e1bd32bc1d1e29d66c9bdf2eae19022b14f21 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 29 Sep 2020 12:21:25 +0200 Subject: [PATCH 127/224] make switch to using GL hosted windows deps --- CI/before_script.msvc.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index e43f5623f..e00e582d4 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -523,52 +523,52 @@ if [ -z $SKIP_DOWNLOAD ]; then # Boost if [ -z $APPVEYOR ]; then download "Boost ${BOOST_VER}" \ - "https://sourceforge.net/projects/boost/files/boost-binaries/${BOOST_VER}/boost_${BOOST_VER_URL}-msvc-${MSVC_VER}-${BITS}.exe" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/${BOOST_VER}/boost_${BOOST_VER_URL}-msvc-${MSVC_VER}-${BITS}.exe" \ "boost-${BOOST_VER}-msvc${MSVC_VER}-win${BITS}.exe" fi # Bullet download "Bullet 2.89 (${BULLET_DBL_DISPLAY})" \ - "https://rgw.ctrl-c.liu.se/openmw/Deps/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" \ "Bullet-2.89-msvc${MSVC_YEAR}-win${BITS}${BULLET_DBL}.7z" # FFmpeg download "FFmpeg 4.2.2" \ - "https://ffmpeg.zeranoe.com/builds/win${BITS}/shared/ffmpeg-4.2.2-win${BITS}-shared.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/ffmpeg-4.2.2-win${BITS}.zip" \ "ffmpeg-4.2.2-win${BITS}.zip" \ - "https://ffmpeg.zeranoe.com/builds/win${BITS}/dev/ffmpeg-4.2.2-win${BITS}-dev.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/ffmpeg-4.2.2-win${BITS}-dev.zip" \ "ffmpeg-4.2.2-dev-win${BITS}.zip" # MyGUI download "MyGUI 3.4.0" \ - "https://rgw.ctrl-c.liu.se/openmw/Deps/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" \ "MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" if [ -n "$PDBS" ]; then download "MyGUI symbols" \ - "https://rgw.ctrl-c.liu.se/openmw/Deps/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" \ "MyGUI-3.4.0-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" fi # OpenAL download "OpenAL-Soft 1.20.1" \ - "http://openal-soft.org/openal-binaries/openal-soft-1.20.1-bin.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/openal-soft-1.20.1-bin.zip" \ "OpenAL-Soft-1.20.1.zip" # OSG download "OpenSceneGraph 3.6.5" \ - "https://rgw.ctrl-c.liu.se/openmw/Deps/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" \ "OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}.7z" if [ -n "$PDBS" ]; then download "OpenSceneGraph symbols" \ - "https://rgw.ctrl-c.liu.se/openmw/Deps/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" \ "OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z" fi # SDL2 download "SDL 2.0.12" \ - "https://www.libsdl.org/release/SDL2-devel-2.0.12-VC.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/SDL2-devel-2.0.12-VC.zip" \ "SDL2-2.0.12.zip" # Google test and mock From 18899394c478f186f343830fa7bba16c6a275873 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 29 Sep 2020 13:13:26 +0200 Subject: [PATCH 128/224] typo in path --- CI/before_script.msvc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index e00e582d4..ee4cd839b 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -536,7 +536,7 @@ if [ -z $SKIP_DOWNLOAD ]; then download "FFmpeg 4.2.2" \ "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/ffmpeg-4.2.2-win${BITS}.zip" \ "ffmpeg-4.2.2-win${BITS}.zip" \ - "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/ffmpeg-4.2.2-win${BITS}-dev.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/ffmpeg-4.2.2-dev-win${BITS}.zip" \ "ffmpeg-4.2.2-dev-win${BITS}.zip" # MyGUI From c291bb169efea2a20fdc2e305c75679acd474818 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 29 Sep 2020 13:29:12 +0200 Subject: [PATCH 129/224] fixed indentation and additional diffs --- CI/before_script.msvc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index ee4cd839b..e8d65372d 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -552,7 +552,7 @@ if [ -z $SKIP_DOWNLOAD ]; then # OpenAL download "OpenAL-Soft 1.20.1" \ - "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/openal-soft-1.20.1-bin.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/OpenAL-Soft-1.20.1.zip" \ "OpenAL-Soft-1.20.1.zip" # OSG @@ -568,7 +568,7 @@ if [ -z $SKIP_DOWNLOAD ]; then # SDL2 download "SDL 2.0.12" \ - "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/SDL2-devel-2.0.12-VC.zip" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/SDL2-2.0.12.zip" \ "SDL2-2.0.12.zip" # Google test and mock From 5ab29f26e94f757a97c3f11234f3e80d9d3b00d2 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Thu, 1 Oct 2020 20:27:48 +0300 Subject: [PATCH 130/224] Put the main menu below other windows (bug #5622) --- CHANGELOG.md | 1 + files/mygui/openmw_layers.xml | 1 + files/mygui/openmw_mainmenu.layout | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a00716f96..5ecf9d85f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ Bug #5557: Diagonal movement is noticeably slower with analogue stick Bug #5603: Setting constant effect cast style doesn't correct effects view Bug #5611: Usable items with "0 Uses" should be used only once + Bug #5622: Can't properly interact with the console when in pause menu Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #4894: Consider actors as obstacles for pathfinding diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index a98efe07c..a090fb369 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -6,6 +6,7 @@ + diff --git a/files/mygui/openmw_mainmenu.layout b/files/mygui/openmw_mainmenu.layout index c4d88ff85..533ba1317 100644 --- a/files/mygui/openmw_mainmenu.layout +++ b/files/mygui/openmw_mainmenu.layout @@ -2,7 +2,7 @@ - + From 4e22c2687f1f1606ed91bc6237222dbd26b14f5d Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 2 Oct 2020 21:34:42 +0300 Subject: [PATCH 131/224] niffile.cpp cleanup --- components/nif/niffile.cpp | 165 ++++++++++++++++++------------------- 1 file changed, 78 insertions(+), 87 deletions(-) diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index b33f0c051..118a58299 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -16,105 +16,96 @@ NIFFile::NIFFile(Files::IStreamPtr stream, const std::string &name) NIFFile::~NIFFile() { - for (std::vector::iterator it = records.begin() ; it != records.end(); ++it) - { - delete *it; - } + for (Record* record : records) + delete record; } template static Record* construct() { return new NodeType; } struct RecordFactoryEntry { - typedef Record* (*create_t) (); + using create_t = Record* (*)(); create_t mCreate; RecordType mType; }; -///Helper function for adding records to the factory map -static std::pair makeEntry(std::string recName, Record* (*create_t) (), RecordType type) -{ - RecordFactoryEntry anEntry = {create_t,type}; - return std::make_pair(recName, anEntry); -} - ///These are all the record types we know how to read. static std::map makeFactory() { - std::map newFactory; - newFactory.insert(makeEntry("NiNode", &construct , RC_NiNode )); - newFactory.insert(makeEntry("NiSwitchNode", &construct , RC_NiSwitchNode )); - newFactory.insert(makeEntry("NiLODNode", &construct , RC_NiLODNode )); - newFactory.insert(makeEntry("AvoidNode", &construct , RC_AvoidNode )); - newFactory.insert(makeEntry("NiCollisionSwitch", &construct , RC_NiCollisionSwitch )); - newFactory.insert(makeEntry("NiBSParticleNode", &construct , RC_NiBSParticleNode )); - newFactory.insert(makeEntry("NiBSAnimationNode", &construct , RC_NiBSAnimationNode )); - newFactory.insert(makeEntry("NiBillboardNode", &construct , RC_NiBillboardNode )); - newFactory.insert(makeEntry("NiTriShape", &construct , RC_NiTriShape )); - newFactory.insert(makeEntry("NiTriStrips", &construct , RC_NiTriStrips )); - newFactory.insert(makeEntry("NiLines", &construct , RC_NiLines )); - newFactory.insert(makeEntry("NiRotatingParticles", &construct , RC_NiRotatingParticles )); - newFactory.insert(makeEntry("NiAutoNormalParticles", &construct , RC_NiAutoNormalParticles )); - newFactory.insert(makeEntry("NiCamera", &construct , RC_NiCamera )); - newFactory.insert(makeEntry("RootCollisionNode", &construct , RC_RootCollisionNode )); - newFactory.insert(makeEntry("NiTexturingProperty", &construct , RC_NiTexturingProperty )); - newFactory.insert(makeEntry("NiFogProperty", &construct , RC_NiFogProperty )); - newFactory.insert(makeEntry("NiMaterialProperty", &construct , RC_NiMaterialProperty )); - newFactory.insert(makeEntry("NiZBufferProperty", &construct , RC_NiZBufferProperty )); - newFactory.insert(makeEntry("NiAlphaProperty", &construct , RC_NiAlphaProperty )); - newFactory.insert(makeEntry("NiVertexColorProperty", &construct , RC_NiVertexColorProperty )); - newFactory.insert(makeEntry("NiShadeProperty", &construct , RC_NiShadeProperty )); - newFactory.insert(makeEntry("NiDitherProperty", &construct , RC_NiDitherProperty )); - newFactory.insert(makeEntry("NiWireframeProperty", &construct , RC_NiWireframeProperty )); - newFactory.insert(makeEntry("NiSpecularProperty", &construct , RC_NiSpecularProperty )); - newFactory.insert(makeEntry("NiStencilProperty", &construct , RC_NiStencilProperty )); - newFactory.insert(makeEntry("NiVisController", &construct , RC_NiVisController )); - newFactory.insert(makeEntry("NiGeomMorpherController", &construct , RC_NiGeomMorpherController )); - newFactory.insert(makeEntry("NiKeyframeController", &construct , RC_NiKeyframeController )); - newFactory.insert(makeEntry("NiAlphaController", &construct , RC_NiAlphaController )); - newFactory.insert(makeEntry("NiRollController", &construct , RC_NiRollController )); - newFactory.insert(makeEntry("NiUVController", &construct , RC_NiUVController )); - newFactory.insert(makeEntry("NiPathController", &construct , RC_NiPathController )); - newFactory.insert(makeEntry("NiMaterialColorController", &construct , RC_NiMaterialColorController )); - newFactory.insert(makeEntry("NiBSPArrayController", &construct , RC_NiBSPArrayController )); - newFactory.insert(makeEntry("NiParticleSystemController", &construct , RC_NiParticleSystemController )); - newFactory.insert(makeEntry("NiFlipController", &construct , RC_NiFlipController )); - newFactory.insert(makeEntry("NiAmbientLight", &construct , RC_NiLight )); - newFactory.insert(makeEntry("NiDirectionalLight", &construct , RC_NiLight )); - newFactory.insert(makeEntry("NiPointLight", &construct , RC_NiLight )); - newFactory.insert(makeEntry("NiSpotLight", &construct , RC_NiLight )); - newFactory.insert(makeEntry("NiTextureEffect", &construct , RC_NiTextureEffect )); - newFactory.insert(makeEntry("NiVertWeightsExtraData", &construct , RC_NiVertWeightsExtraData )); - newFactory.insert(makeEntry("NiTextKeyExtraData", &construct , RC_NiTextKeyExtraData )); - newFactory.insert(makeEntry("NiStringExtraData", &construct , RC_NiStringExtraData )); - newFactory.insert(makeEntry("NiGravity", &construct , RC_NiGravity )); - newFactory.insert(makeEntry("NiPlanarCollider", &construct , RC_NiPlanarCollider )); - newFactory.insert(makeEntry("NiSphericalCollider", &construct , RC_NiSphericalCollider )); - newFactory.insert(makeEntry("NiParticleGrowFade", &construct , RC_NiParticleGrowFade )); - newFactory.insert(makeEntry("NiParticleColorModifier", &construct , RC_NiParticleColorModifier )); - newFactory.insert(makeEntry("NiParticleRotation", &construct , RC_NiParticleRotation )); - newFactory.insert(makeEntry("NiFloatData", &construct , RC_NiFloatData )); - newFactory.insert(makeEntry("NiTriShapeData", &construct , RC_NiTriShapeData )); - newFactory.insert(makeEntry("NiTriStripsData", &construct , RC_NiTriStripsData )); - newFactory.insert(makeEntry("NiLinesData", &construct , RC_NiLinesData )); - newFactory.insert(makeEntry("NiVisData", &construct , RC_NiVisData )); - newFactory.insert(makeEntry("NiColorData", &construct , RC_NiColorData )); - newFactory.insert(makeEntry("NiPixelData", &construct , RC_NiPixelData )); - newFactory.insert(makeEntry("NiMorphData", &construct , RC_NiMorphData )); - newFactory.insert(makeEntry("NiKeyframeData", &construct , RC_NiKeyframeData )); - newFactory.insert(makeEntry("NiSkinData", &construct , RC_NiSkinData )); - newFactory.insert(makeEntry("NiUVData", &construct , RC_NiUVData )); - newFactory.insert(makeEntry("NiPosData", &construct , RC_NiPosData )); - newFactory.insert(makeEntry("NiRotatingParticlesData", &construct , RC_NiRotatingParticlesData )); - newFactory.insert(makeEntry("NiAutoNormalParticlesData", &construct , RC_NiAutoNormalParticlesData )); - newFactory.insert(makeEntry("NiSequenceStreamHelper", &construct , RC_NiSequenceStreamHelper )); - newFactory.insert(makeEntry("NiSourceTexture", &construct , RC_NiSourceTexture )); - newFactory.insert(makeEntry("NiSkinInstance", &construct , RC_NiSkinInstance )); - newFactory.insert(makeEntry("NiLookAtController", &construct , RC_NiLookAtController )); - newFactory.insert(makeEntry("NiPalette", &construct , RC_NiPalette )); - return newFactory; + std::map factory; + factory["NiNode"] = {&construct , RC_NiNode }; + factory["NiSwitchNode"] = {&construct , RC_NiSwitchNode }; + factory["NiLODNode"] = {&construct , RC_NiLODNode }; + factory["AvoidNode"] = {&construct , RC_AvoidNode }; + factory["NiCollisionSwitch"] = {&construct , RC_NiCollisionSwitch }; + factory["NiBSParticleNode"] = {&construct , RC_NiBSParticleNode }; + factory["NiBSAnimationNode"] = {&construct , RC_NiBSAnimationNode }; + factory["NiBillboardNode"] = {&construct , RC_NiBillboardNode }; + factory["NiTriShape"] = {&construct , RC_NiTriShape }; + factory["NiTriStrips"] = {&construct , RC_NiTriStrips }; + factory["NiLines"] = {&construct , RC_NiLines }; + factory["NiRotatingParticles"] = {&construct , RC_NiRotatingParticles }; + factory["NiAutoNormalParticles"] = {&construct , RC_NiAutoNormalParticles }; + factory["NiCamera"] = {&construct , RC_NiCamera }; + factory["RootCollisionNode"] = {&construct , RC_RootCollisionNode }; + factory["NiTexturingProperty"] = {&construct , RC_NiTexturingProperty }; + factory["NiFogProperty"] = {&construct , RC_NiFogProperty }; + factory["NiMaterialProperty"] = {&construct , RC_NiMaterialProperty }; + factory["NiZBufferProperty"] = {&construct , RC_NiZBufferProperty }; + factory["NiAlphaProperty"] = {&construct , RC_NiAlphaProperty }; + factory["NiVertexColorProperty"] = {&construct , RC_NiVertexColorProperty }; + factory["NiShadeProperty"] = {&construct , RC_NiShadeProperty }; + factory["NiDitherProperty"] = {&construct , RC_NiDitherProperty }; + factory["NiWireframeProperty"] = {&construct , RC_NiWireframeProperty }; + factory["NiSpecularProperty"] = {&construct , RC_NiSpecularProperty }; + factory["NiStencilProperty"] = {&construct , RC_NiStencilProperty }; + factory["NiVisController"] = {&construct , RC_NiVisController }; + factory["NiGeomMorpherController"] = {&construct , RC_NiGeomMorpherController }; + factory["NiKeyframeController"] = {&construct , RC_NiKeyframeController }; + factory["NiAlphaController"] = {&construct , RC_NiAlphaController }; + factory["NiRollController"] = {&construct , RC_NiRollController }; + factory["NiUVController"] = {&construct , RC_NiUVController }; + factory["NiPathController"] = {&construct , RC_NiPathController }; + factory["NiMaterialColorController"] = {&construct , RC_NiMaterialColorController }; + factory["NiBSPArrayController"] = {&construct , RC_NiBSPArrayController }; + factory["NiParticleSystemController"] = {&construct , RC_NiParticleSystemController }; + factory["NiFlipController"] = {&construct , RC_NiFlipController }; + factory["NiAmbientLight"] = {&construct , RC_NiLight }; + factory["NiDirectionalLight"] = {&construct , RC_NiLight }; + factory["NiPointLight"] = {&construct , RC_NiLight }; + factory["NiSpotLight"] = {&construct , RC_NiLight }; + factory["NiTextureEffect"] = {&construct , RC_NiTextureEffect }; + factory["NiVertWeightsExtraData"] = {&construct , RC_NiVertWeightsExtraData }; + factory["NiTextKeyExtraData"] = {&construct , RC_NiTextKeyExtraData }; + factory["NiStringExtraData"] = {&construct , RC_NiStringExtraData }; + factory["NiGravity"] = {&construct , RC_NiGravity }; + factory["NiPlanarCollider"] = {&construct , RC_NiPlanarCollider }; + factory["NiSphericalCollider"] = {&construct , RC_NiSphericalCollider }; + factory["NiParticleGrowFade"] = {&construct , RC_NiParticleGrowFade }; + factory["NiParticleColorModifier"] = {&construct , RC_NiParticleColorModifier }; + factory["NiParticleRotation"] = {&construct , RC_NiParticleRotation }; + factory["NiFloatData"] = {&construct , RC_NiFloatData }; + factory["NiTriShapeData"] = {&construct , RC_NiTriShapeData }; + factory["NiTriStripsData"] = {&construct , RC_NiTriStripsData }; + factory["NiLinesData"] = {&construct , RC_NiLinesData }; + factory["NiVisData"] = {&construct , RC_NiVisData }; + factory["NiColorData"] = {&construct , RC_NiColorData }; + factory["NiPixelData"] = {&construct , RC_NiPixelData }; + factory["NiMorphData"] = {&construct , RC_NiMorphData }; + factory["NiKeyframeData"] = {&construct , RC_NiKeyframeData }; + factory["NiSkinData"] = {&construct , RC_NiSkinData }; + factory["NiUVData"] = {&construct , RC_NiUVData }; + factory["NiPosData"] = {&construct , RC_NiPosData }; + factory["NiRotatingParticlesData"] = {&construct , RC_NiRotatingParticlesData }; + factory["NiAutoNormalParticlesData"] = {&construct , RC_NiAutoNormalParticlesData }; + factory["NiSequenceStreamHelper"] = {&construct , RC_NiSequenceStreamHelper }; + factory["NiSourceTexture"] = {&construct , RC_NiSourceTexture }; + factory["NiSkinInstance"] = {&construct , RC_NiSkinInstance }; + factory["NiLookAtController"] = {&construct , RC_NiLookAtController }; + factory["NiPalette"] = {&construct , RC_NiPalette }; + return factory; } @@ -149,7 +140,7 @@ void NIFFile::parse(Files::IStreamPtr stream) if(ver != NIFStream::generateVersion(4,0,0,0) && ver != VER_MW) fail("Unsupported NIF version: " + printVersion(ver)); // Number of records - size_t recNum = nif.getInt(); + size_t recNum = nif.getUInt(); records.resize(recNum); for(size_t i = 0;i < recNum;i++) @@ -201,8 +192,8 @@ void NIFFile::parse(Files::IStreamPtr stream) } // Once parsing is done, do post-processing. - for(size_t i=0; ipost(this); + for (Record* record : records) + record->post(this); } void NIFFile::setUseSkinning(bool skinning) From 1ddfb18cb35877fa3965b7dcb8f2cf075f1a722d Mon Sep 17 00:00:00 2001 From: psi29a Date: Fri, 2 Oct 2020 21:07:46 +0000 Subject: [PATCH 132/224] Update CI/before_script.msvc.sh --- CI/before_script.msvc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index e8d65372d..8b3ece2bd 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -523,7 +523,7 @@ if [ -z $SKIP_DOWNLOAD ]; then # Boost if [ -z $APPVEYOR ]; then download "Boost ${BOOST_VER}" \ - "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/${BOOST_VER}/boost_${BOOST_VER_URL}-msvc-${MSVC_VER}-${BITS}.exe" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/boost_${BOOST_VER_URL}-msvc-${MSVC_VER}-${BITS}.exe" \ "boost-${BOOST_VER}-msvc${MSVC_VER}-win${BITS}.exe" fi From 23fe60a06788352f6140a2570869d1352cf30c8b Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 2 Oct 2020 22:46:23 +0200 Subject: [PATCH 133/224] Run unit tests in a separate build --- .travis.yml | 8 +++++- CI/before_script.linux.sh | 51 +++++++++++++++++++++++++++------------ CI/build_googletest.sh | 12 ++++++--- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36b15d794..8d98d0dd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,6 +45,12 @@ matrix: os: linux dist: focal if: branch != coverity_scan + - name: OpenMW (tests only) on Ubuntu Focal with GCC + os: linux + dist: focal + if: branch != coverity_scan + env: + - BUILD_TESTS_ONLY: 1 - name: OpenMW (openmw) on Ubuntu Focal with Clang's Static Analysis os: linux dist: focal @@ -73,7 +79,7 @@ script: - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ${ANALYZE} make -j3; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ] && [ "${BUILD_TESTS_ONLY}" ]; then ./openmw_test_suite; fi - if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi - cd "${TRAVIS_BUILD_DIR}" - ccache -s diff --git a/CI/before_script.linux.sh b/CI/before_script.linux.sh index f4aaeecc9..6df3dc32e 100755 --- a/CI/before_script.linux.sh +++ b/CI/before_script.linux.sh @@ -2,22 +2,43 @@ free -m -env GENERATOR='Unix Makefiles' CONFIGURATION=Release CI/build_googletest.sh -GOOGLETEST_DIR="$(pwd)/googletest/build" +if [[ "${BUILD_TESTS_ONLY}" ]]; then + export GOOGLETEST_DIR="$(pwd)/googletest/build/install" + env GENERATOR='Unix Makefiles' CONFIGURATION=Release CI/build_googletest.sh +fi mkdir build cd build -${ANALYZE} cmake \ - -DCMAKE_C_COMPILER="${CC}" \ - -DCMAKE_CXX_COMPILER="${CXX}" \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DBUILD_UNITTESTS=TRUE \ - -DUSE_SYSTEM_TINYXML=TRUE \ - -DCMAKE_INSTALL_PREFIX="/usr" \ - -DBINDIR="/usr/games" \ - -DCMAKE_BUILD_TYPE="DEBUG" \ - -DGTEST_ROOT="${GOOGLETEST_DIR}" \ - -DGMOCK_ROOT="${GOOGLETEST_DIR}" \ - .. +if [[ "${BUILD_TESTS_ONLY}" ]]; then + ${ANALYZE} cmake \ + -D CMAKE_C_COMPILER="${CC}" \ + -D CMAKE_CXX_COMPILER="${CXX}" \ + -D CMAKE_C_COMPILER_LAUNCHER=ccache \ + -D CMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -D CMAKE_INSTALL_PREFIX=install \ + -D CMAKE_BUILD_TYPE=RelWithDebInfo \ + -D USE_SYSTEM_TINYXML=TRUE \ + -D BUILD_OPENMW=OFF \ + -D BUILD_BSATOOL=OFF \ + -D BUILD_ESMTOOL=OFF \ + -D BUILD_LAUNCHER=OFF \ + -D BUILD_MWINIIMPORTER=OFF \ + -D BUILD_ESSIMPORTER=OFF \ + -D BUILD_OPENCS=OFF \ + -D BUILD_WIZARD=OFF \ + -D BUILD_UNITTESTS=ON \ + -D GTEST_ROOT="${GOOGLETEST_DIR}" \ + -D GMOCK_ROOT="${GOOGLETEST_DIR}" \ + .. +else + ${ANALYZE} cmake \ + -D CMAKE_C_COMPILER="${CC}" \ + -D CMAKE_CXX_COMPILER="${CXX}" \ + -D CMAKE_C_COMPILER_LAUNCHER=ccache \ + -D CMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -D USE_SYSTEM_TINYXML=TRUE \ + -D CMAKE_INSTALL_PREFIX=install \ + -D CMAKE_BUILD_TYPE=Debug \ + .. +fi diff --git a/CI/build_googletest.sh b/CI/build_googletest.sh index 0ffda7f9b..a9a50fee7 100755 --- a/CI/build_googletest.sh +++ b/CI/build_googletest.sh @@ -1,13 +1,17 @@ -#!/bin/sh -e +#!/bin/sh -ex git clone -b release-1.10.0 https://github.com/google/googletest.git cd googletest mkdir build cd build cmake \ + -D CMAKE_C_COMPILER="${CC}" \ + -D CMAKE_CXX_COMPILER="${CXX}" \ + -D CMAKE_C_COMPILER_LAUNCHER=ccache \ + -D CMAKE_CXX_COMPILER_LAUNCHER=ccache \ -D CMAKE_BUILD_TYPE="${CONFIGURATION}" \ - -D CMAKE_INSTALL_PREFIX=. \ + -D CMAKE_INSTALL_PREFIX="${GOOGLETEST_DIR}" \ -G "${GENERATOR}" \ .. -cmake --build . --config "${CONFIGURATION}" -cmake --build . --target install --config "${CONFIGURATION}" +cmake --build . --config "${CONFIGURATION}" -- -j $(nproc) +cmake --install . --config "${CONFIGURATION}" From af95474670e88b3deb1b15ce0a396327169a0b97 Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 2 Oct 2020 20:58:03 +0200 Subject: [PATCH 134/224] Run unit tests in gitlab CI for linux build --- .gitlab-ci.yml | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d171e8222..97bd619c3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ stages: - build - -Debian: + +.Debian: tags: - docker - linux @@ -14,20 +14,34 @@ Debian: before_script: - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR - apt-get update -yq - - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev ccache + - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev ccache git stage: build script: - export CCACHE_BASEDIR="`pwd`" - export CCACHE_DIR="`pwd`/ccache" && mkdir -pv "$CCACHE_DIR" - - ccache -z -M 250M - - cores_to_use=$((`nproc`-2)); if (( $cores_to_use < 1 )); then cores_to_use=1; fi - - mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - - make -j$cores_to_use - - DESTDIR=artifacts make install + - ccache -z -M 1G + - CI/before_script.linux.sh + - cd build + - cmake --build . -- -j $(nproc) + - cmake --install . + - if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_test_suite; fi - ccache -s artifacts: paths: - - build/artifacts/ + - build/install/ + +Debian_GCC: + extends: .Debian + variables: + CC: gcc + CXX: g++ + +Debian_GCC_tests: + extends: .Debian + variables: + CC: gcc + CXX: g++ + BUILD_TESTS_ONLY: 1 MacOS: tags: @@ -228,4 +242,4 @@ Windows_MSBuild_CS_RelWithDebInfo: - .Windows_MSBuild_Base variables: <<: *cs-targets - config: "RelWithDebInfo" \ No newline at end of file + config: "RelWithDebInfo" From 322298e02a5f0367d610e13610afb214793f556c Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 2 Oct 2020 22:45:25 +0200 Subject: [PATCH 135/224] Build with clang in gitlab CI for linux --- .gitlab-ci.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 97bd619c3..2cb111a1a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,7 @@ stages: before_script: - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR - apt-get update -yq - - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev ccache git + - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev ccache git clang stage: build script: - export CCACHE_BASEDIR="`pwd`" @@ -43,6 +43,19 @@ Debian_GCC_tests: CXX: g++ BUILD_TESTS_ONLY: 1 +Debian_Clang: + extends: .Debian + variables: + CC: clang + CXX: clang++ + +Debian_Clang_tests: + extends: .Debian + variables: + CC: clang + CXX: clang++ + BUILD_TESTS_ONLY: 1 + MacOS: tags: - macos From 9e78f3d936c95b6add1d097f957e5a770beac813 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sat, 3 Oct 2020 02:19:38 +0100 Subject: [PATCH 136/224] Skip raycasting for zero-length rays Rays with no length can't intersect anything. This also prevents an assertion triggering with Bullet built in Debug mode. --- apps/openmw/mwphysics/physicssystem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 91e7a9de0..8b07fea4b 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -264,6 +264,8 @@ namespace MWPhysics RayCastingResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector targets, int mask, int group) const { + if (from == to) + return RayCastingResult { false }; btVector3 btFrom = Misc::Convert::toBullet(from); btVector3 btTo = Misc::Convert::toBullet(to); From 5215ce45d08623c4d16ab345d1b1613a59628d83 Mon Sep 17 00:00:00 2001 From: imkirkdouglacus Date: Sat, 3 Oct 2020 10:51:27 +0000 Subject: [PATCH 137/224] Update install-game-files.rst --- .../manuals/installation/install-game-files.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/source/manuals/installation/install-game-files.rst b/docs/source/manuals/installation/install-game-files.rst index ac3688e88..538cfd4c6 100644 --- a/docs/source/manuals/installation/install-game-files.rst +++ b/docs/source/manuals/installation/install-game-files.rst @@ -105,6 +105,19 @@ If you are running macOS, you can also download Morrowind through Steam: #. Launch the Steam client and let it download. You can then find ``Morrowind.esm`` at ``~/Library/Application Support/Steam/steamapps/common/The Elder Scrolls III - Morrowind/Data Files/`` +Linux +---- +Debian/Ubuntu - using "Steam Proton" & "OpenMW launcher". +---- +#. Install Steam from "Ubuntu Software" Center +#. Enable Proton (basically WINE under the hood). This is done in the Steam client menu drop down. Select, "Steam | Settings" then in the "SteamPlay" section check the box next to "enable steam play for all other titles" +#. Now Morrowind should be selectable in your game list (as long as you own it). You can install it like any other game, choose to install it and remember the directory path of the location you pick. +#. Once the game files are installed, we can now install the open OpenMW Engine. I used "OpenMW launcher" from "Ubuntu Software" Center this has a wizard to help with the basic setup of OpenMW. +#. Launch "OpenMW launcher" and follow the setup wizard, when asked, point it at the location you installed Morrowind to, we will be looking for the directory that contains the Morrowing.esm file, for example '/steam library/steamapps/common/Morrowind/Data Files/'. +#. Everything should now be in place, click that big "PLAY" button and fire up OpenMW. + +Nb. Bloodmoon.esm needs to be below Tribunal.esm in your datafiles list, if you dont have the right order a red "!" will apear next to the filename in the datafiles section of the OpenMW launcher, just drag bloodmoon below tribunal to fix it. + Wine ---- From 845049a166b2c3ea02186b85bdba54398a15006c Mon Sep 17 00:00:00 2001 From: Kyle Shrader Date: Sat, 3 Oct 2020 10:55:44 +0000 Subject: [PATCH 138/224] Prevent empty right page of journal having invisible topics (Fixes #5588) --- CHANGELOG.md | 1 + apps/openmw/mwgui/bookpage.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a00716f96..a89680a90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Bug #5539: Window resize breaks when going from a lower resolution to full screen resolution Bug #5548: Certain exhausted topics can be highlighted again even though there's no new dialogue Bug #5557: Diagonal movement is noticeably slower with analogue stick + Bug #5588: Randomly clicking on the journal's right-side page when it's empty shows random topics Bug #5603: Setting constant effect cast style doesn't correct effects view Bug #5611: Usable items with "0 Uses" should be used only once Feature #390: 3rd person look "over the shoulder" diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index 5724defcd..47027c2b7 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -941,6 +941,9 @@ public: if (!mBook) return; + if (mPage >= mBook->mPages.size()) + return; + dirtyFocusItem (); mFocusItem = 0; @@ -952,6 +955,9 @@ public: if (!mBook) return; + if (mPage >= mBook->mPages.size()) + return; + left -= mCroppedParent->getAbsoluteLeft (); top -= mCroppedParent->getAbsoluteTop (); @@ -988,6 +994,9 @@ public: if (!mBook) return; + if (mPage >= mBook->mPages.size()) + return; + // work around inconsistency in MyGUI where the mouse press coordinates aren't // transformed by the current Layer (even though mouse *move* events are). MyGUI::IntPoint pos (left, top); @@ -1013,6 +1022,9 @@ public: if (!mBook) return; + if (mPage >= mBook->mPages.size()) + return; + // work around inconsistency in MyGUI where the mouse release coordinates aren't // transformed by the current Layer (even though mouse *move* events are). MyGUI::IntPoint pos (left, top); From d5450a7d88c3cab9931cf14720dc286cb9ea288d Mon Sep 17 00:00:00 2001 From: Mads Buvik Sandvei Date: Sat, 3 Oct 2020 14:22:34 +0200 Subject: [PATCH 139/224] Correctly resetting line numbering during shader processing. --- apps/openmw_test_suite/shader/shadermanager.cpp | 2 +- components/shader/shadermanager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw_test_suite/shader/shadermanager.cpp b/apps/openmw_test_suite/shader/shadermanager.cpp index e823d5fe2..a25e5e9ba 100644 --- a/apps/openmw_test_suite/shader/shadermanager.cpp +++ b/apps/openmw_test_suite/shader/shadermanager.cpp @@ -92,7 +92,7 @@ namespace "\n" "void bar() { foo() }\n" "\n" - "#line 2 0\n" + "#line 1 0\n" "\n" "void main() { bar() }\n"; EXPECT_EQ(shader->getShaderSource(), expected); diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index 8523a2962..bfaa11282 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -106,7 +106,7 @@ namespace Shader else { lineDirectivePosition = 0; - lineNumber = 1; + lineNumber = 0; } lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n'); From 14aacb81c580b4581b90ffdca9db9264bfbcd644 Mon Sep 17 00:00:00 2001 From: Charles Calhoun <6294115-ccalhoun1999@users.noreply.gitlab.com> Date: Sat, 3 Oct 2020 20:05:17 +0000 Subject: [PATCH 140/224] Fix follower aggression when traveling. Summoning still has problems but less intrusive than current implementation. --- CHANGELOG.md | 1 + apps/openmw/mwgui/travelwindow.cpp | 2 +- apps/openmw/mwworld/actionteleport.cpp | 18 +++++++++++++----- apps/openmw/mwworld/actionteleport.hpp | 5 +++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a89680a90..fc0b2848c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Bug #4631: Setting MSAA level too high doesn't fall back to highest supported level Bug #4764: Data race in osg ParticleSystem Bug #4774: Guards are ignorant of an invisible player that tries to attack them + Bug #5101: Hostile followers travel with the player Bug #5108: Savegame bloating due to inefficient fog textures format Bug #5165: Active spells should use real time intead of timestamps Bug #5358: ForceGreeting always resets the dialogue window completely diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index a730f95c6..ed7a74b95 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -74,7 +74,7 @@ namespace MWGui // Add price for the travelling followers std::set followers; - MWWorld::ActionTeleport::getFollowersToTeleport(player, followers); + MWWorld::ActionTeleport::getFollowers(player, followers); // Apply followers cost, unlike vanilla the first follower doesn't travel for free price *= 1 + static_cast(followers.size()); diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index f54edc8cb..9cd8469a3 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -24,7 +24,7 @@ namespace MWWorld { // Find any NPCs that are following the actor and teleport them with him std::set followers; - getFollowersToTeleport(actor, followers); + getFollowers(actor, followers, true); for (std::set::iterator it = followers.begin(); it != followers.end(); ++it) teleport(*it); @@ -47,7 +47,9 @@ namespace MWWorld } else { - if (mCellName.empty()) + if (actor.getClass().getCreatureStats(actor).getAiSequence().isInCombat(world->getPlayerPtr())) + actor.getClass().getCreatureStats(actor).getAiSequence().stopCombat(); + else if (mCellName.empty()) { int cellX; int cellY; @@ -60,7 +62,7 @@ namespace MWWorld } } - void ActionTeleport::getFollowersToTeleport(const MWWorld::Ptr& actor, std::set& out) { + void ActionTeleport::getFollowers(const MWWorld::Ptr& actor, std::set& out, bool includeHostiles) { std::set followers; MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers); @@ -69,11 +71,17 @@ namespace MWWorld MWWorld::Ptr follower = *it; std::string script = follower.getClass().getScript(follower); + + if (!includeHostiles && follower.getClass().getCreatureStats(follower).getAiSequence().isInCombat(actor)) + continue; + if (!script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1) continue; - if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() <= 800*800) - out.insert(follower); + if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() > 800 * 800) + continue; + + out.emplace(follower); } } } diff --git a/apps/openmw/mwworld/actionteleport.hpp b/apps/openmw/mwworld/actionteleport.hpp index c58218750..bd7b236a4 100644 --- a/apps/openmw/mwworld/actionteleport.hpp +++ b/apps/openmw/mwworld/actionteleport.hpp @@ -28,8 +28,9 @@ namespace MWWorld /// @param teleportFollowers Whether to teleport any following actors of the target actor as well. ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers); - /// Outputs every actor follower who is in teleport range and wasn't ordered to not enter interiors - static void getFollowersToTeleport(const MWWorld::Ptr& actor, std::set& out); + /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the output, + /// e.g. so that the teleport action can calm them. + static void getFollowers(const MWWorld::Ptr& actor, std::set& out, bool includeHostiles = false); }; } From 2835ea1e21bc99623676f65d1552d93559dfec2b Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 3 Oct 2020 22:55:21 +0200 Subject: [PATCH 141/224] Update logic of "NPCs avoid collisions" --- apps/openmw/mwmechanics/actors.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3de1a3acc..822ed8d92 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1668,8 +1668,9 @@ namespace MWMechanics void Actors::predictAndAvoidCollisions() { const float minGap = 10.f; - const float maxDistToCheck = 100.f; - const float maxTimeToCheck = 1.f; + const float maxDistForPartialAvoiding = 200.f; + const float maxDistForStrictAvoiding = 100.f; + const float maxTimeToCheck = 2.0f; static const bool giveWayWhenIdle = Settings::Manager::getBool("NPCs give way", "Game"); MWWorld::Ptr player = getPlayer(); @@ -1680,9 +1681,15 @@ namespace MWMechanics if (ptr == player) continue; // Don't interfere with player controls. + float maxSpeed = ptr.getClass().getMaxSpeed(ptr); + if (maxSpeed == 0.0) + continue; // Can't move, so there is no sense to predict collisions. + Movement& movement = ptr.getClass().getMovementSettings(ptr); osg::Vec2f origMovement(movement.mPosition[0], movement.mPosition[1]); bool isMoving = origMovement.length2() > 0.01; + if (movement.mPosition[1] < 0) + continue; // Actors can not see others when move backward. // Moving NPCs always should avoid collisions. // Standing NPCs give way to moving ones if they are not in combat (or pursue) mode and either @@ -1710,11 +1717,11 @@ namespace MWMechanics if (!shouldAvoidCollision) continue; - float maxSpeed = ptr.getClass().getMaxSpeed(ptr); osg::Vec2f baseSpeed = origMovement * maxSpeed; osg::Vec3f basePos = ptr.getRefData().getPosition().asVec3(); float baseRotZ = ptr.getRefData().getPosition().rot[2]; osg::Vec3f halfExtents = world->getHalfExtents(ptr); + float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding; float timeToCollision = maxTimeToCheck; osg::Vec2f movementCorrection(0, 0); @@ -1730,9 +1737,10 @@ namespace MWMechanics osg::Vec3f otherHalfExtents = world->getHalfExtents(otherPtr); osg::Vec3f deltaPos = otherPtr.getRefData().getPosition().asVec3() - basePos; osg::Vec2f relPos = Misc::rotateVec2f(osg::Vec2f(deltaPos.x(), deltaPos.y()), baseRotZ); + float dist = deltaPos.length(); // Ignore actors which are not close enough or come from behind. - if (deltaPos.length2() > maxDistToCheck * maxDistToCheck || relPos.y() < 0) + if (dist > maxDistToCheck || relPos.y() < 0) continue; // Don't check for a collision if vertical distance is greater then the actor's height. @@ -1767,16 +1775,20 @@ namespace MWMechanics timeToCollision = t; angleToApproachingActor = std::atan2(deltaPos.x(), deltaPos.y()); osg::Vec2f posAtT = relPos + relSpeed * t; - float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) / (collisionDist * maxSpeed); + float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) / (collisionDist * collisionDist * maxSpeed); + coef *= osg::clampBetween((maxDistForPartialAvoiding - dist) / (maxDistForPartialAvoiding - maxDistForStrictAvoiding), 0.f, 1.f); movementCorrection = posAtT * coef; - // Step to the side rather than backward. Otherwise player will be able to push the NPC far away from it's original location. - movementCorrection.y() = std::max(0.f, movementCorrection.y()); + if (otherPtr.getClass().getCreatureStats(otherPtr).isDead()) + // In case of dead body still try to go around (it looks natural), but reduce the correction twice. + movementCorrection.y() *= 0.5f; } if (timeToCollision < maxTimeToCheck) { // Try to evade the nearest collision. osg::Vec2f newMovement = origMovement + movementCorrection; + // Step to the side rather than backward. Otherwise player will be able to push the NPC far away from it's original location. + newMovement.y() = std::max(newMovement.y(), 0.f); if (isMoving) { // Keep the original speed. newMovement.normalize(); From 29ccb09da5bc3ba2c1acb0af776f5f8ba59c85ce Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 4 Oct 2020 01:27:49 +0300 Subject: [PATCH 142/224] Introduce some extended NIF definitions --- .../nifloader/testbulletnifloader.cpp | 1 + components/nif/base.hpp | 17 ++- components/nif/controlled.cpp | 27 +++- components/nif/controller.cpp | 16 ++- components/nif/controller.hpp | 1 + components/nif/data.cpp | 135 ++++++++++++++---- components/nif/data.hpp | 13 +- components/nif/effect.cpp | 18 +-- components/nif/effect.hpp | 3 + components/nif/niffile.cpp | 75 +++++++++- components/nif/nifstream.cpp | 9 +- components/nif/node.hpp | 74 +++++++++- components/nif/property.cpp | 106 ++++++++++---- components/nif/property.hpp | 110 +++++++++++--- components/nifosg/nifloader.cpp | 7 +- 15 files changed, 505 insertions(+), 107 deletions(-) diff --git a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp index 30903b897..72dcd3066 100644 --- a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp +++ b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp @@ -244,6 +244,7 @@ namespace void init(Nif::Named& value) { value.extra = Nif::ExtraPtr(nullptr); + value.extralist = Nif::ExtraList(); value.controller = Nif::ControllerPtr(nullptr); } diff --git a/components/nif/base.hpp b/components/nif/base.hpp index 6e26f525e..0d42131e5 100644 --- a/components/nif/base.hpp +++ b/components/nif/base.hpp @@ -14,12 +14,18 @@ namespace Nif class Extra : public Record { public: + std::string name; ExtraPtr next; // Next extra data record in the list void read(NIFStream *nif) { - next.read(nif); - nif->getUInt(); // Size of the record + if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) + name = nif->getString(); + else if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0)) + { + next.read(nif); + nif->getUInt(); // Size of the record + } } void post(NIFFile *nif) { next.post(nif); } @@ -44,18 +50,23 @@ class Named : public Record public: std::string name; ExtraPtr extra; + ExtraList extralist; ControllerPtr controller; void read(NIFStream *nif) { name = nif->getString(); - extra.read(nif); + if (nif->getVersion() < NIFStream::generateVersion(10,0,1,0)) + extra.read(nif); + else + extralist.read(nif); controller.read(nif); } void post(NIFFile *nif) { extra.post(nif); + extralist.post(nif); controller.post(nif); } }; diff --git a/components/nif/controlled.cpp b/components/nif/controlled.cpp index 0b5c32a10..ab2b8dc17 100644 --- a/components/nif/controlled.cpp +++ b/components/nif/controlled.cpp @@ -14,16 +14,31 @@ namespace Nif if (external) filename = nif->getString(); else - internal = nif->getChar(); - - if (!external && internal) + { + if (nif->getVersion() <= NIFStream::generateVersion(10,0,1,3)) + internal = nif->getChar(); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + filename = nif->getString(); // Original file path of the internal texture + } + if (nif->getVersion() <= NIFStream::generateVersion(10,0,1,3)) + { + if (!external && internal) + data.read(nif); + } + else + { data.read(nif); + } pixel = nif->getUInt(); mipmap = nif->getUInt(); alpha = nif->getUInt(); nif->getChar(); // always 1 + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,103)) + nif->getBoolean(); // Direct rendering + if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,4)) + nif->getBoolean(); // NiPersistentSrcTextureRendererData is used instead of NiPixelData } void NiSourceTexture::post(NIFFile *nif) @@ -79,6 +94,12 @@ namespace Nif NiParticleModifier::read(nif); mBounceFactor = nif->getFloat(); + if (nif->getVersion() >= NIFStream::generateVersion(4,2,2,0)) + { + // Unused in NifSkope. Need to figure out what these do. + /*bool spawnOnCollision = */nif->getBoolean(); + /*bool dieOnCollision = */nif->getBoolean(); + } } void NiPlanarCollider::read(NIFStream *nif) diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index c63c83676..8d943b58a 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -97,7 +97,10 @@ namespace Nif // 01: Diffuse // 10: Specular // 11: Emissive - targetColor = (flags >> 4) & 3; + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + targetColor = nif->getUShort() & 3; + else + targetColor = (flags >> 4) & 3; data.read(nif); } @@ -110,6 +113,8 @@ namespace Nif void NiLookAtController::read(NIFStream *nif) { Controller::read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + lookAtFlags = nif->getUShort(); target.read(nif); } @@ -192,6 +197,8 @@ namespace Nif void NiGeomMorpherController::read(NIFStream *nif) { Controller::read(nif); + if (nif->getVersion() >= NIFFile::NIFVersion::VER_OB_OLD) + /*bool updateNormals = !!*/nif->getUShort(); data.read(nif); if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW) /*bool alwaysActive = */nif->getChar(); // Always 0 @@ -219,8 +226,11 @@ namespace Nif { Controller::read(nif); mTexSlot = nif->getUInt(); - /*unknown=*/nif->getUInt();/*0?*/ - mDelta = nif->getFloat(); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) + { + timeStart = nif->getFloat(); + mDelta = nif->getFloat(); + } mSources.read(nif); } diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index 41dd14fac..bf043fbdb 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -118,6 +118,7 @@ class NiLookAtController : public Controller { public: NodePtr target; + unsigned short lookAtFlags{0}; void read(NIFStream *nif); void post(NIFFile *nif); diff --git a/components/nif/data.cpp b/components/nif/data.cpp index afb304bad..e76541d5c 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -33,13 +33,33 @@ void NiSkinInstance::post(NIFFile *nif) void NiGeometryData::read(NIFStream *nif) { + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,114)) + nif->getInt(); // Group ID. (Almost?) always 0. + int verts = nif->getUShort(); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + nif->skip(2); // Keep flags and compress flags + if (nif->getBoolean()) nif->getVector3s(vertices, verts); + unsigned int dataFlags = 0; + if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) + dataFlags = nif->getUShort(); + + if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) + nif->getUInt(); // Material CRC + if (nif->getBoolean()) + { nif->getVector3s(normals, verts); + if (dataFlags & 0x1000) + { + nif->getVector3s(tangents, verts); + nif->getVector3s(bitangents, verts); + } + } center = nif->getVector3(); radius = nif->getFloat(); @@ -47,14 +67,27 @@ void NiGeometryData::read(NIFStream *nif) if (nif->getBoolean()) nif->getVector4s(colors, verts); - // In Morrowind this field only corresponds to the number of UV sets. - // NifTools research is inaccurate. - int uvs = nif->getUShort(); - - if(nif->getInt()) + // Only the first 6 bits are used as a count. I think the rest are + // flags of some sort. + unsigned int numUVs = dataFlags; + if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0)) { - uvlist.resize(uvs); - for(int i = 0;i < uvs;i++) + numUVs = nif->getUShort(); + // In Morrowind this field only corresponds to the number of UV sets. + // NifTools research is inaccurate. + if (nif->getVersion() > NIFFile::NIFVersion::VER_MW) + numUVs &= 0x3f; + } + if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0) + numUVs &= 0x1; + + bool hasUVs = true; + if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW) + hasUVs = nif->getBoolean(); + if (hasUVs) + { + uvlist.resize(numUVs); + for (unsigned int i = 0; i < numUVs; i++) { nif->getVector2s(uvlist[i], verts); // flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin @@ -64,6 +97,12 @@ void NiGeometryData::read(NIFStream *nif) } } } + + if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) + nif->getUShort(); // Consistency flags + + if (nif->getVersion() >= NIFStream::generateVersion(20,0,0,4)) + nif->skip(4); // Additional data } void NiTriShapeData::read(NIFStream *nif) @@ -75,13 +114,17 @@ void NiTriShapeData::read(NIFStream *nif) // We have three times as many vertices as triangles, so this // is always equal to tris*3. int cnt = nif->getInt(); - nif->getUShorts(triangles, cnt); + bool hasTriangles = true; + if (nif->getVersion() > NIFFile::NIFVersion::VER_OB_OLD) + hasTriangles = nif->getBoolean(); + if (hasTriangles) + nif->getUShorts(triangles, cnt); // Read the match list, which lists the vertices that are equal to // vertices. We don't actually need need this for anything, so // just skip it. - int verts = nif->getUShort(); - for(int i=0;i < verts;i++) + unsigned short verts = nif->getUShort(); + for (unsigned short i=0; i < verts; i++) { // Number of vertices matching vertex 'i' int num = nif->getUShort(); @@ -101,7 +144,11 @@ void NiTriStripsData::read(NIFStream *nif) std::vector lengths; nif->getUShorts(lengths, numStrips); - if (!numStrips) + // "Has Strips" flag. Exceptionally useful. + bool hasStrips = false; + if (nif->getVersion() > NIFFile::NIFVersion::VER_OB_OLD) + hasStrips = nif->getBoolean(); + if (!hasStrips || !numStrips) return; strips.resize(numStrips); @@ -140,27 +187,37 @@ void NiAutoNormalParticlesData::read(NIFStream *nif) NiGeometryData::read(nif); // Should always match the number of vertices - numParticles = nif->getUShort(); + if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW) + numParticles = nif->getUShort(); - particleRadius = nif->getFloat(); + if (nif->getVersion() <= NIFStream::generateVersion(10,0,1,0)) + std::fill(particleRadii.begin(), particleRadii.end(), nif->getFloat()); + else if (nif->getBoolean()) + nif->getFloats(particleRadii, vertices.size()); activeCount = nif->getUShort(); + // Particle sizes if (nif->getBoolean()) - { - // Particle sizes nif->getFloats(sizes, vertices.size()); + + if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0) && nif->getBoolean()) + nif->getQuaternions(rotations, vertices.size()); + if (nif->getVersion() >= NIFStream::generateVersion(20,0,0,4)) + { + if (nif->getBoolean()) + nif->getFloats(rotationAngles, vertices.size()); + if (nif->getBoolean()) + nif->getVector3s(rotationAxes, vertices.size()); } + } void NiRotatingParticlesData::read(NIFStream *nif) { NiAutoNormalParticlesData::read(nif); - if (nif->getBoolean()) - { - // Rotation quaternions. + if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0) && nif->getBoolean()) nif->getQuaternions(rotations, vertices.size()); - } } void NiPosData::read(NIFStream *nif) @@ -188,12 +245,27 @@ void NiPixelData::read(NIFStream *nif) { fmt = (Format)nif->getUInt(); - for (unsigned int i = 0; i < 4; ++i) - colorMask[i] = nif->getUInt(); - bpp = nif->getUInt(); + if (nif->getVersion() < NIFStream::generateVersion(10,4,0,2)) + { + for (unsigned int i = 0; i < 4; ++i) + colorMask[i] = nif->getUInt(); + bpp = nif->getUInt(); + nif->skip(8); // "Old Fast Compare". Whatever that means. + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + pixelTiling = nif->getUInt(); + } + else // TODO: see if anything from here needs to be implemented + { + bpp = nif->getChar(); + nif->skip(4); // Renderer hint + nif->skip(4); // Extra data + nif->skip(4); // Flags + pixelTiling = nif->getUInt(); + if (nif->getVersion() >= NIFStream::generateVersion(20,3,0,4)) + sRGB = nif->getBoolean(); + nif->skip(4*10); // Channel data + } - // 8 bytes of "Old Fast Compare". Whatever that means. - nif->skip(8); palette.read(nif); numberOfMipmaps = nif->getUInt(); @@ -213,8 +285,10 @@ void NiPixelData::read(NIFStream *nif) // Read the data unsigned int numPixels = nif->getUInt(); - if (numPixels) - nif->getUChars(data, numPixels); + bool hasFaces = nif->getVersion() >= NIFStream::generateVersion(10,4,0,2); + unsigned int numFaces = hasFaces ? nif->getUInt() : 1; + if (numPixels && numFaces) + nif->getUChars(data, numPixels * numFaces); } void NiPixelData::post(NIFFile *nif) @@ -249,6 +323,10 @@ void NiSkinData::read(NIFStream *nif) if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFStream::generateVersion(10,1,0,0)) nif->skip(4); // NiSkinPartition link + // Has vertex weights flag + if (nif->getVersion() > NIFStream::generateVersion(4,2,1,0) && !nif->getBoolean()) + return; + bones.resize(boneNum); for (BoneInfo &bi : bones) { @@ -272,7 +350,7 @@ void NiMorphData::read(NIFStream *nif) { int morphCount = nif->getInt(); int vertCount = nif->getInt(); - /*relative targets?*/nif->getChar(); + nif->getChar(); // Relative targets, always 1 mMorphs.resize(morphCount); for(int i = 0;i < morphCount;i++) @@ -290,7 +368,8 @@ void NiKeyframeData::read(NIFStream *nif) if(mRotations->mInterpolationType == InterpolationType_XYZ) { //Chomp unused float - nif->getFloat(); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,0)) + nif->getFloat(); mXRotations = std::make_shared(); mYRotations = std::make_shared(); mZRotations = std::make_shared(); diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 66b3f693a..1519bd1b3 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -35,7 +35,7 @@ namespace Nif class NiGeometryData : public Record { public: - std::vector vertices, normals; + std::vector vertices, normals, tangents, bitangents; std::vector colors; std::vector< std::vector > uvlist; osg::Vec3f center; @@ -73,13 +73,15 @@ struct NiLinesData : public NiGeometryData class NiAutoNormalParticlesData : public NiGeometryData { public: - int numParticles; + int numParticles{0}; float particleRadius; int activeCount; - std::vector sizes; + std::vector particleRadii, sizes, rotationAngles; + std::vector rotations; + std::vector rotationAxes; void read(NIFStream *nif); }; @@ -87,8 +89,6 @@ public: class NiRotatingParticlesData : public NiAutoNormalParticlesData { public: - std::vector rotations; - void read(NIFStream *nif); }; @@ -133,7 +133,8 @@ public: Format fmt; unsigned int colorMask[4]; - unsigned int bpp; + unsigned int bpp, pixelTiling{0}; + bool sRGB{false}; NiPalettePtr palette; unsigned int numberOfMipmaps; diff --git a/components/nif/effect.cpp b/components/nif/effect.cpp index 7947e301d..c12eb6c1b 100644 --- a/components/nif/effect.cpp +++ b/components/nif/effect.cpp @@ -28,6 +28,10 @@ void NiTextureEffect::read(NIFStream *nif) // Texture Filtering nif->skip(4); + // Max anisotropy samples + if (nif->getVersion() >= NIFStream::generateVersion(20,5,0,4)) + nif->skip(2); + clamp = nif->getUInt(); textureType = (TextureType)nif->getUInt(); @@ -36,14 +40,12 @@ void NiTextureEffect::read(NIFStream *nif) texture.read(nif); - /* - byte = 0 - vector4 = [1,0,0,0] - short = 0 - short = -75 - short = 0 - */ - nif->skip(23); + nif->skip(1); // Use clipping plane + nif->skip(16); // Clipping plane dimensions vector + if (nif->getVersion() <= NIFStream::generateVersion(10,2,0,0)) + nif->skip(4); // PS2-specific shorts + if (nif->getVersion() <= NIFStream::generateVersion(4,1,0,12)) + nif->skip(2); // Unknown short } void NiTextureEffect::post(NIFFile *nif) diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 453e4b04c..818df90a2 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -34,6 +34,9 @@ struct NiDynamicEffect : public Node void read(NIFStream *nif) { Node::read(nif); + if (nif->getVersion() >= nif->generateVersion(10,1,0,106) + && nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO4) + nif->getBoolean(); // Switch state unsigned int numAffectedNodes = nif->getUInt(); for (unsigned int i=0; igetUInt(); // ref to another Node diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 118a58299..31c959964 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -139,15 +139,77 @@ void NIFFile::parse(Files::IStreamPtr stream) // It's not used by Morrowind assets but Morrowind supports it. if(ver != NIFStream::generateVersion(4,0,0,0) && ver != VER_MW) fail("Unsupported NIF version: " + printVersion(ver)); + + // NIF data endianness + if (ver >= NIFStream::generateVersion(20,0,0,4)) + { + unsigned char endianness = nif.getChar(); + if (endianness == 0) + fail("Big endian NIF files are unsupported"); + } + + // User version + if (ver > NIFStream::generateVersion(10,0,1,8)) + userVer = nif.getUInt(); + // Number of records size_t recNum = nif.getUInt(); records.resize(recNum); + // Bethesda stream header + // It contains Bethesda format version and (useless) export information + if (ver == VER_OB_OLD || + (userVer >= 3 && ((ver == VER_OB || ver == VER_BGS) + || (ver >= NIFStream::generateVersion(10,1,0,0) && ver <= NIFStream::generateVersion(20,0,0,4) && userVer <= 11)))) + { + bethVer = nif.getUInt(); + nif.getExportString(); // Author + if (bethVer > BETHVER_FO4) + nif.getUInt(); // Unknown + nif.getExportString(); // Process script + nif.getExportString(); // Export script + if (bethVer == BETHVER_FO4) + nif.getExportString(); // Max file path + } + + std::vector recTypes; + std::vector recTypeIndices; + + const bool hasRecTypeListings = ver >= NIFStream::generateVersion(5,0,0,1); + if (hasRecTypeListings) + { + unsigned short recTypeNum = nif.getUShort(); + if (recTypeNum) // Record type list + nif.getSizedStrings(recTypes, recTypeNum); + if (recNum) // Record type mapping for each record + nif.getUShorts(recTypeIndices, recNum); + if (ver >= NIFStream::generateVersion(5,0,0,6)) // Groups + { + if (ver >= NIFStream::generateVersion(20,1,0,1)) // String table + { + if (ver >= NIFStream::generateVersion(20,2,0,5) && recNum) // Record sizes + { + std::vector recSizes; // Currently unused + nif.getUInts(recSizes, recNum); + } + unsigned int stringNum = nif.getUInt(); + nif.getUInt(); // Max string length + if (stringNum) + nif.getSizedStrings(strings, stringNum); + } + std::vector groups; // Currently unused + unsigned int groupNum = nif.getUInt(); + if (groupNum) + nif.getUInts(groups, groupNum); + } + } + + const bool hasRecordSeparators = ver >= NIFStream::generateVersion(10,0,0,0) && ver < NIFStream::generateVersion(10,2,0,0); for(size_t i = 0;i < recNum;i++) { Record *r = nullptr; - std::string rec = nif.getString(); + std::string rec = hasRecTypeListings ? recTypes[recTypeIndices[i]] : nif.getString(); if(rec.empty()) { std::stringstream error; @@ -155,6 +217,17 @@ void NIFFile::parse(Files::IStreamPtr stream) fail(error.str()); } + // Record separator. Some Havok records in Oblivion do not have it. + if (hasRecordSeparators && rec.compare(0, 3, "bhk")) + { + if (nif.getInt()) + { + std::stringstream warning; + warning << "Record number " << i << " out of " << recNum << " is preceded by a non-zero separator."; + warn(warning.str()); + } + } + std::map::const_iterator entry = factories.find(rec); if (entry != factories.end()) diff --git a/components/nif/nifstream.cpp b/components/nif/nifstream.cpp index 44be4b241..69f1a905b 100644 --- a/components/nif/nifstream.cpp +++ b/components/nif/nifstream.cpp @@ -25,18 +25,19 @@ namespace Nif return t; } - ///Currently specific for 4.0.0.2 and earlier + ///Booleans in 4.0.0.2 (Morrowind format) and earlier are 4 byte, while in 4.1.0.0+ they're 1 byte. bool NIFStream::getBoolean() { - return getInt() != 0; + return getVersion() < generateVersion(4,1,0,0) ? getInt() != 0 : getChar() != 0; } - ///Read in a string, either from the string table using the index (currently absent) or from the stream using the specified length + ///Read in a string, either from the string table using the index or from the stream using the specified length std::string NIFStream::getString() { - return getSizedString(); + return getVersion() < generateVersion(20,1,0,1) ? getSizedString() : file->getString(getUInt()); } + // Convenience utility functions: get the versions of the currently read file unsigned int NIFStream::getVersion() const { return file->getVersion(); } unsigned int NIFStream::getUserVersion() const { return file->getBethVersion(); } diff --git a/components/nif/node.hpp b/components/nif/node.hpp index e605df32a..4c57b2e81 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -30,7 +30,7 @@ public: PropertyList props; // Bounding box info - bool hasBounds; + bool hasBounds{false}; osg::Vec3f boundPos; Matrix3 boundRot; osg::Vec3f boundXYZ; // Box size @@ -39,12 +39,15 @@ public: { Named::read(nif); - flags = nif->getUShort(); + flags = nif->getBethVersion() <= 26 ? nif->getUShort() : nif->getUInt(); trafo = nif->getTrafo(); - velocity = nif->getVector3(); - props.read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0)) + velocity = nif->getVector3(); + if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3) + props.read(nif); - hasBounds = nif->getBoolean(); + if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0)) + hasBounds = nif->getBoolean(); if(hasBounds) { nif->getInt(); // always 1 @@ -52,6 +55,9 @@ public: boundRot = nif->getMatrix3(); boundXYZ = nif->getVector3(); } + // Reference to the collision object in Gamebryo files. + if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) + nif->skip(4); parent = nullptr; @@ -102,7 +108,8 @@ struct NiNode : Node { Node::read(nif); children.read(nif); - effects.read(nif); + if (nif->getBethVersion() < NIFFile::BethVersion::BETHVER_FO4) + effects.read(nif); // Discard transformations for the root node, otherwise some meshes // occasionally get wrong orientation. Only for NiNode-s for now, but @@ -130,7 +137,39 @@ struct NiNode : Node struct NiGeometry : Node { + struct MaterialData + { + std::vector materialNames; + std::vector materialExtraData; + unsigned int activeMaterial{0}; + bool materialNeedsUpdate{false}; + void read(NIFStream *nif) + { + if (nif->getVersion() <= NIFStream::generateVersion(10,0,1,0)) + return; + unsigned int numMaterials = 0; + if (nif->getVersion() <= NIFStream::generateVersion(20,1,0,3)) + numMaterials = nif->getBoolean(); // Has Shader + else if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,5)) + numMaterials = nif->getUInt(); + if (numMaterials) + { + nif->getStrings(materialNames, numMaterials); + nif->getInts(materialExtraData, numMaterials); + } + if (nif->getVersion() >= NIFStream::generateVersion(20,2,0,5)) + activeMaterial = nif->getUInt(); + if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS) + { + materialNeedsUpdate = nif->getBoolean(); + if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) + nif->skip(8); + } + } + }; + NiSkinInstancePtr skin; + MaterialData materialData; }; struct NiTriShape : NiGeometry @@ -149,6 +188,7 @@ struct NiTriShape : NiGeometry Node::read(nif); data.read(nif); skin.read(nif); + materialData.read(nif); } void post(NIFFile *nif) @@ -170,6 +210,7 @@ struct NiTriStrips : NiGeometry Node::read(nif); data.read(nif); skin.read(nif); + materialData.read(nif); } void post(NIFFile *nif) @@ -207,6 +248,8 @@ struct NiCamera : Node { struct Camera { + unsigned short cameraFlags{0}; + // Camera frustrum float left, right, top, bottom, nearDist, farDist; @@ -216,15 +259,21 @@ struct NiCamera : Node // Level of detail modifier float LOD; + // Orthographic projection usage flag + bool orthographic{false}; + void read(NIFStream *nif) { + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + cameraFlags = nif->getUShort(); left = nif->getFloat(); right = nif->getFloat(); top = nif->getFloat(); bottom = nif->getFloat(); nearDist = nif->getFloat(); farDist = nif->getFloat(); - + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + orthographic = nif->getBoolean(); vleft = nif->getFloat(); vright = nif->getFloat(); vtop = nif->getFloat(); @@ -243,6 +292,8 @@ struct NiCamera : Node nif->getInt(); // -1 nif->getInt(); // 0 + if (nif->getVersion() >= NIFStream::generateVersion(4,2,1,0)) + nif->getInt(); // 0 } }; @@ -285,11 +336,14 @@ 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 switchFlags{0}; unsigned int initialIndex; void read(NIFStream *nif) { NiNode::read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + switchFlags = nif->getUShort(); initialIndex = nif->getUInt(); } }; @@ -310,6 +364,12 @@ struct NiLODNode : public NiSwitchNode NiSwitchNode::read(nif); if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFStream::generateVersion(10,0,1,0)) lodCenter = nif->getVector3(); + else if (nif->getVersion() > NIFStream::generateVersion(10,0,1,0)) + { + nif->skip(4); // NiLODData, unsupported at the moment + return; + } + unsigned int numLodLevels = nif->getUInt(); for (unsigned int i=0; igetUShort(); -} - void NiTexturingProperty::Texture::read(NIFStream *nif) { inUse = nif->getBoolean(); if(!inUse) return; texture.read(nif); - clamp = nif->getUInt(); - nif->skip(4); // Filter mode. Ignoring because global filtering settings are more sensible - uvSet = nif->getUInt(); + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB) + { + clamp = nif->getInt(); + nif->skip(4); // Filter mode. Ignoring because global filtering settings are more sensible + } + else + { + clamp = nif->getUShort() & 0xF; + } + // Max anisotropy. I assume we'll always only use the global anisotropy setting. + if (nif->getVersion() >= NIFStream::generateVersion(20,5,0,4)) + nif->getUShort(); + + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB) + uvSet = nif->getUInt(); // Two PS2-specific shorts. - nif->skip(4); - nif->skip(2); // Unknown short + if (nif->getVersion() < NIFStream::generateVersion(10,4,0,2)) + nif->skip(4); + if (nif->getVersion() <= NIFStream::generateVersion(4,1,0,18)) + nif->skip(2); // Unknown short + else if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + { + if (nif->getBoolean()) // Has texture transform + { + nif->getVector2(); // UV translation + nif->getVector2(); // UV scale + nif->getFloat(); // W axis rotation + nif->getUInt(); // Transform method + nif->getVector2(); // Texture rotation origin + } + } } void NiTexturingProperty::Texture::post(NIFFile *nif) @@ -35,7 +54,10 @@ void NiTexturingProperty::Texture::post(NIFFile *nif) void NiTexturingProperty::read(NIFStream *nif) { Property::read(nif); - apply = nif->getUInt(); + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD || nif->getVersion() >= NIFStream::generateVersion(20,1,0,2)) + flags = nif->getUShort(); + if (nif->getVersion() <= NIFStream::generateVersion(20,1,0,1)) + apply = nif->getUInt(); unsigned int numTextures = nif->getUInt(); @@ -51,32 +73,53 @@ void NiTexturingProperty::read(NIFStream *nif) envMapLumaBias = nif->getVector2(); bumpMapMatrix = nif->getVector4(); } + else if (i == 7 && textures[7].inUse && nif->getVersion() >= NIFStream::generateVersion(20,2,0,5)) + /*float parallaxOffset = */nif->getFloat(); + } + + if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) + { + unsigned int numShaderTextures = nif->getUInt(); + shaderTextures.resize(numShaderTextures); + for (unsigned int i = 0; i < numShaderTextures; i++) + { + shaderTextures[i].read(nif); + if (shaderTextures[i].inUse) + nif->getUInt(); // Unique identifier + } } } void NiTexturingProperty::post(NIFFile *nif) { Property::post(nif); - for(int i = 0;i < 7;i++) + for (size_t i = 0; i < textures.size(); i++) textures[i].post(nif); + for (size_t i = 0; i < shaderTextures.size(); i++) + shaderTextures[i].post(nif); } void NiFogProperty::read(NIFStream *nif) { Property::read(nif); - + mFlags = nif->getUShort(); mFogDepth = nif->getFloat(); mColour = nif->getVector3(); } void S_MaterialProperty::read(NIFStream *nif) { - ambient = nif->getVector3(); - diffuse = nif->getVector3(); + if (nif->getBethVersion() < 26) + { + ambient = nif->getVector3(); + diffuse = nif->getVector3(); + } specular = nif->getVector3(); emissive = nif->getVector3(); glossiness = nif->getFloat(); alpha = nif->getFloat(); + if (nif->getBethVersion() > 21) + emissive *= nif->getFloat(); } void S_VertexColorProperty::read(NIFStream *nif) @@ -92,14 +135,29 @@ void S_AlphaProperty::read(NIFStream *nif) void S_StencilProperty::read(NIFStream *nif) { - enabled = nif->getChar(); - compareFunc = nif->getInt(); - stencilRef = nif->getUInt(); - stencilMask = nif->getUInt(); - failAction = nif->getInt(); - zFailAction = nif->getInt(); - zPassAction = nif->getInt(); - drawMode = nif->getInt(); + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB) + { + enabled = nif->getChar(); + compareFunc = nif->getInt(); + stencilRef = nif->getUInt(); + stencilMask = nif->getUInt(); + failAction = nif->getInt(); + zFailAction = nif->getInt(); + zPassAction = nif->getInt(); + drawMode = nif->getInt(); + } + else + { + unsigned short flags = nif->getUShort(); + enabled = flags & 0x1; + failAction = (flags >> 1) & 0x7; + zFailAction = (flags >> 4) & 0x7; + zPassAction = (flags >> 7) & 0x7; + drawMode = (flags >> 10) & 0x3; + compareFunc = (flags >> 12) & 0x7; + stencilRef = nif->getUInt(); + stencilMask = nif->getUInt(); + } } diff --git a/components/nif/property.hpp b/components/nif/property.hpp index c72dbf6ba..e20d948f0 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -29,18 +29,13 @@ namespace Nif { -class Property : public Named -{ -public: - // The meaning of these depends on the actual property type. - unsigned int flags; - - void read(NIFStream *nif); -}; +class Property : public Named { }; class NiTexturingProperty : public Property { public: + unsigned short flags{0u}; + // A sub-texture struct Texture { @@ -92,6 +87,7 @@ public: }; std::vector textures; + std::vector shaderTextures; osg::Vec2f envMapLumaBias; osg::Vec4f bumpMapMatrix; @@ -103,28 +99,81 @@ public: class NiFogProperty : public Property { public: + unsigned short mFlags; float mFogDepth; osg::Vec3f mColour; void read(NIFStream *nif); }; -// These contain no other data than the 'flags' field in Property -class NiShadeProperty : public Property { }; -class NiDitherProperty : public Property { }; -class NiZBufferProperty : public Property { }; -class NiSpecularProperty : public Property { }; -class NiWireframeProperty : public Property { }; +// These contain no other data than the 'flags' field +struct NiShadeProperty : public Property +{ + unsigned short flags{0u}; + void read(NIFStream *nif) + { + Property::read(nif); + if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3) + flags = nif->getUShort(); + } +}; + +struct NiDitherProperty : public Property +{ + unsigned short flags; + void read(NIFStream* nif) + { + Property::read(nif); + flags = nif->getUShort(); + } +}; + +struct NiZBufferProperty : public Property +{ + unsigned short flags; + unsigned int testFunction; + void read(NIFStream *nif) + { + Property::read(nif); + flags = nif->getUShort(); + testFunction = (flags >> 2) & 0x7; + if (nif->getVersion() >= NIFStream::generateVersion(4,1,0,12) && nif->getVersion() <= NIFFile::NIFVersion::VER_OB) + testFunction = nif->getUInt(); + } +}; + +struct NiSpecularProperty : public Property +{ + unsigned short flags; + void read(NIFStream* nif) + { + Property::read(nif); + flags = nif->getUShort(); + } +}; + +struct NiWireframeProperty : public Property +{ + unsigned short flags; + void read(NIFStream* nif) + { + Property::read(nif); + flags = nif->getUShort(); + } +}; + // The rest are all struct-based template struct StructPropT : Property { T data; + unsigned short flags; void read(NIFStream *nif) { Property::read(nif); + flags = nif->getUShort(); data.read(nif); } }; @@ -132,7 +181,8 @@ struct StructPropT : Property struct S_MaterialProperty { // The vector components are R,G,B - osg::Vec3f ambient, diffuse, specular, emissive; + osg::Vec3f ambient{1.f,1.f,1.f}, diffuse{1.f,1.f,1.f}; + osg::Vec3f specular, emissive; float glossiness, alpha; void read(NIFStream *nif); @@ -246,9 +296,35 @@ struct S_StencilProperty }; class NiAlphaProperty : public StructPropT { }; -class NiMaterialProperty : public StructPropT { }; class NiVertexColorProperty : public StructPropT { }; -class NiStencilProperty : public StructPropT { }; +struct NiStencilProperty : public Property +{ + S_StencilProperty data; + unsigned short flags{0u}; + + void read(NIFStream *nif) + { + Property::read(nif); + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD) + flags = nif->getUShort(); + data.read(nif); + } +}; + +struct NiMaterialProperty : public Property +{ + S_MaterialProperty data; + unsigned short flags{0u}; + + void read(NIFStream *nif) + { + Property::read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(3,0,0,0) + && nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD) + flags = nif->getUShort(); + data.read(nif); + } +}; } // Namespace #endif diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index f9274cebf..61a276dc1 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1732,7 +1732,7 @@ namespace NifOsg osg::StateSet* stateset = node->getOrCreateStateSet(); // Specular lighting is enabled by default, but there's a quirk... - int specFlags = 1; + bool specEnabled = true; osg::ref_ptr mat (new osg::Material); mat->setColorMode(hasVertexColors ? osg::Material::AMBIENT_AND_DIFFUSE : osg::Material::OFF); @@ -1751,7 +1751,8 @@ namespace NifOsg case Nif::RC_NiSpecularProperty: { // Specular property can turn specular lighting off. - specFlags = property->flags; + auto specprop = static_cast(property); + specEnabled = specprop->flags & 1; break; } case Nif::RC_NiMaterialProperty: @@ -1835,7 +1836,7 @@ namespace NifOsg } // While NetImmerse and Gamebryo support specular lighting, Morrowind has its support disabled. - if (mVersion <= Nif::NIFFile::NIFVersion::VER_MW || specFlags == 0) + if (mVersion <= Nif::NIFFile::NIFVersion::VER_MW || !specEnabled) mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f,0.f,0.f,0.f)); if (lightmode == 0) From 822764d0facaf5cc2787c5391cf90f1afa20ebd0 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 27 Sep 2020 13:00:41 +0400 Subject: [PATCH 143/224] Rework fixed strings handling --- .../esm/test_fixed_string.cpp | 2 -- components/esm/esmcommon.hpp | 25 ++++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/openmw_test_suite/esm/test_fixed_string.cpp b/apps/openmw_test_suite/esm/test_fixed_string.cpp index dc88a5f63..bd598cc93 100644 --- a/apps/openmw_test_suite/esm/test_fixed_string.cpp +++ b/apps/openmw_test_suite/esm/test_fixed_string.cpp @@ -97,7 +97,6 @@ TEST(EsmFixedString, struct_size) ASSERT_EQ(4, sizeof(ESM::NAME)); ASSERT_EQ(32, sizeof(ESM::NAME32)); ASSERT_EQ(64, sizeof(ESM::NAME64)); - ASSERT_EQ(256, sizeof(ESM::NAME256)); } TEST(EsmFixedString, is_pod) @@ -105,5 +104,4 @@ TEST(EsmFixedString, is_pod) ASSERT_TRUE(std::is_pod::value); ASSERT_TRUE(std::is_pod::value); ASSERT_TRUE(std::is_pod::value); - ASSERT_TRUE(std::is_pod::value); } diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index f7a8bf126..232a24fcf 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -6,7 +6,6 @@ #include #include -#include namespace ESM { @@ -57,11 +56,16 @@ public: } bool operator!=(const std::string& str) const { return !( (*this) == str ); } - size_t data_size() const { return size; } + static size_t data_size() { return size; } size_t length() const { return strnlen(self()->ro_data(), size); } std::string toString() const { return std::string(self()->ro_data(), this->length()); } - void assign(const std::string& value) { std::strncpy(self()->rw_data(), value.c_str(), size); } + void assign(const std::string& value) + { + std::strncpy(self()->rw_data(), value.c_str(), size-1); + self()->rw_data()[size-1] = '\0'; + } + void clear() { this->assign(""); } private: DERIVED const* self() const @@ -103,6 +107,20 @@ struct FIXED_STRING<4> : public FIXED_STRING_BASE bool operator==(uint32_t v) const { return v == intval; } bool operator!=(uint32_t v) const { return v != intval; } + void assign(const std::string& value) + { + intval = 0; + size_t length = value.size(); + if (length == 0) return; + data[0] = value[0]; + if (length == 1) return; + data[1] = value[1]; + if (length == 2) return; + data[2] = value[2]; + if (length == 3) return; + data[3] = value[3]; + } + char const* ro_data() const { return data; } char* rw_data() { return data; } }; @@ -110,7 +128,6 @@ struct FIXED_STRING<4> : public FIXED_STRING_BASE typedef FIXED_STRING<4> NAME; typedef FIXED_STRING<32> NAME32; typedef FIXED_STRING<64> NAME64; -typedef FIXED_STRING<256> NAME256; /* This struct defines a file 'context' which can be saved and later restored by an ESMReader instance. It will save the position within From 03b081137aa7a3170fdcf81f90917eba8caec5c2 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Mon, 5 Oct 2020 20:38:31 +0000 Subject: [PATCH 144/224] Correct screenshot paths in documentation These have been wrong since https://github.com/OpenMW/openmw/pull/2787 got merged --- docs/source/reference/modding/paths.rst | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/source/reference/modding/paths.rst b/docs/source/reference/modding/paths.rst index ea9b6c416..97cfe37a5 100644 --- a/docs/source/reference/modding/paths.rst +++ b/docs/source/reference/modding/paths.rst @@ -43,16 +43,16 @@ Savegames Screenshots ----------- -+--------------+-----------------------------------------------------------------------------------------------+ -| OS | Location | -+==============+===============================================================================================+ -| Linux | ``$HOME/.local/share/openmw`` | -+--------------+-----------------------------------------------------------------------------------------------+ -| Mac | ``$HOME/Library/Application\ Support/openmw`` | -+--------------+---------------+-------------------------------------------------------------------------------+ -| Windows | File Explorer | ``Documents\My Games\OpenMW`` | -| | | | -| | PowerShell | ``Join-Path ([environment]::GetFolderPath("mydocuments")) "My Games\OpenMW"`` | -| | | | -| | Example | ``C:\Users\Username\Documents\My Games\OpenMW`` | -+--------------+---------------+-------------------------------------------------------------------------------+ ++--------------+-----------------------------------------------------------------------------------------------------------+ +| OS | Location | ++==============+===========================================================================================================+ +| Linux | ``$HOME/.local/share/openmw/screenshots`` | ++--------------+-----------------------------------------------------------------------------------------------------------+ +| Mac | ``$HOME/Library/Application\ Support/openmw/screenshots`` | ++--------------+---------------+-------------------------------------------------------------------------------------------+ +| Windows | File Explorer | ``Documents\My Games\OpenMW\screenshots`` | +| | | | +| | PowerShell | ``Join-Path ([environment]::GetFolderPath("mydocuments")) "My Games\OpenMW\screenshots"`` | +| | | | +| | Example | ``C:\Users\Username\Documents\My Games\OpenMW\screenshots`` | ++--------------+---------------+-------------------------------------------------------------------------------------------+ From e2a603f6e849f04c03fec0044d191ce36b83e64a Mon Sep 17 00:00:00 2001 From: fredzio Date: Tue, 6 Oct 2020 09:08:49 +0200 Subject: [PATCH 145/224] Remove blank space --- CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e7ea6800..cd920b456 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -760,9 +760,7 @@ elseif(NOT APPLE) INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") - INSTALL(FILES - "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" - DESTINATION ".") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".") From 683cf8cad5d49f96124678aed701cab40737dff1 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Tue, 6 Oct 2020 16:56:55 +0000 Subject: [PATCH 146/224] Remove incorrect spaces from filename --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd920b456..8b6836237 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -760,7 +760,7 @@ elseif(NOT APPLE) INSTALL(FILES "${OpenMW_SOURCE_DIR}/CHANGELOG.md" DESTINATION "." RENAME "CHANGELOG.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVu Font License.txt" DESTINATION ".") + INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION ".") From e7c37f21b7a90bd89a67b5cae95fb62ce1c3ac5f Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 6 Oct 2020 20:24:05 +0300 Subject: [PATCH 147/224] Add NiFloatInterpController abstraction --- components/nif/controller.cpp | 16 ++-------------- components/nif/controller.hpp | 13 +++---------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/components/nif/controller.cpp b/components/nif/controller.cpp index 8d943b58a..07699239e 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -170,25 +170,13 @@ namespace Nif data.post(nif); } - void NiAlphaController::read(NIFStream *nif) + void NiFloatInterpController::read(NIFStream *nif) { Controller::read(nif); data.read(nif); } - void NiAlphaController::post(NIFFile *nif) - { - Controller::post(nif); - data.post(nif); - } - - void NiRollController::read(NIFStream *nif) - { - Controller::read(nif); - data.read(nif); - } - - void NiRollController::post(NIFFile *nif) + void NiFloatInterpController::post(NIFFile *nif) { Controller::post(nif); data.post(nif); diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index bf043fbdb..a527a4400 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -143,23 +143,16 @@ public: void post(NIFFile *nif); }; -class NiAlphaController : public Controller +struct NiFloatInterpController : public Controller { -public: NiFloatDataPtr data; void read(NIFStream *nif); void post(NIFFile *nif); }; -class NiRollController : public Controller -{ -public: - NiFloatDataPtr data; - - void read(NIFStream *nif); - void post(NIFFile *nif); -}; +class NiAlphaController : public NiFloatInterpController { }; +class NiRollController : public NiFloatInterpController { }; class NiGeomMorpherController : public Controller { From 0d02a3392a801c1367ae3d68337c0e2a7739f9e6 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 6 Oct 2020 20:36:10 +0300 Subject: [PATCH 148/224] Clean up --- components/nif/data.hpp | 2 -- components/nif/niffile.cpp | 1 - components/nif/property.hpp | 1 - 3 files changed, 4 deletions(-) diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 1519bd1b3..58d6cf755 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -75,8 +75,6 @@ class NiAutoNormalParticlesData : public NiGeometryData public: int numParticles{0}; - float particleRadius; - int activeCount; std::vector particleRadii, sizes, rotationAngles; diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 31c959964..550b5fafc 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -108,7 +108,6 @@ static std::map makeFactory() return factory; } - ///Make the factory map used for parsing the file static const std::map factories = makeFactory(); diff --git a/components/nif/property.hpp b/components/nif/property.hpp index e20d948f0..aeef0c027 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -162,7 +162,6 @@ struct NiWireframeProperty : public Property } }; - // The rest are all struct-based template struct StructPropT : Property From 302d8eed274351aaf09fc115868b8d17d1c5c8d3 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 6 Oct 2020 20:47:06 +0300 Subject: [PATCH 149/224] Clean up Roll- and FlipController implementation --- components/nifosg/controller.cpp | 13 +------------ components/nifosg/controller.hpp | 10 +++++----- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index b6610728a..0f4c4a5bd 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -310,11 +310,6 @@ void VisController::operator() (osg::Node* node, osg::NodeVisitor* nv) RollController::RollController(const Nif::NiFloatData *data) : mData(data->mKeyList, 1.f) - , mStartingTime(0) -{ -} - -RollController::RollController() : mStartingTime(0) { } @@ -322,7 +317,7 @@ RollController::RollController(const RollController ©, const osg::CopyOp &co : osg::NodeCallback(copy, copyop) , Controller(copy) , mData(copy.mData) - , mStartingTime(0) + , mStartingTime(copy.mStartingTime) { } @@ -462,12 +457,6 @@ FlipController::FlipController(int texSlot, float delta, const std::vector > mTextures; public: FlipController(const Nif::NiFlipController* ctrl, const std::vector >& textures); FlipController(int texSlot, float delta, const std::vector >& textures); - FlipController(); + FlipController() = default; FlipController(const FlipController& copy, const osg::CopyOp& copyop); META_Object(NifOsg, FlipController) From df1014303d5c2a2e2006f5f0753602bae3df0ee1 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 6 Oct 2020 20:52:21 +0300 Subject: [PATCH 150/224] Add more generic extra data NIF types --- components/nif/extra.cpp | 50 ++++++++++++++++++++++++++++++++++++++ components/nif/extra.hpp | 49 +++++++++++++++++++++++++++++++++++++ components/nif/niffile.cpp | 8 ++++++ components/nif/record.hpp | 10 +++++++- 4 files changed, 116 insertions(+), 1 deletion(-) diff --git a/components/nif/extra.cpp b/components/nif/extra.cpp index cb654d5a0..d08e5d738 100644 --- a/components/nif/extra.cpp +++ b/components/nif/extra.cpp @@ -29,6 +29,56 @@ void NiVertWeightsExtraData::read(NIFStream *nif) nif->skip(nif->getUShort() * sizeof(float)); // vertex weights I guess } +void NiIntegerExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + + data = nif->getUInt(); +} + +void NiIntegersExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + + unsigned int num = nif->getUInt(); + if (num) + nif->getUInts(data, num); +} + +void NiBinaryExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + unsigned int size = nif->getUInt(); + if (size) + nif->getChars(data, size); +} + +void NiBooleanExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + data = nif->getBoolean(); +} + +void NiVectorExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + data = nif->getVector4(); +} + +void NiFloatExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + + data = nif->getFloat(); +} + +void NiFloatsExtraData::read(NIFStream *nif) +{ + Extra::read(nif); + unsigned int num = nif->getUInt(); + if (num) + nif->getFloats(data, num); +} } diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index d935add55..0e8cc16bf 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -60,5 +60,54 @@ public: void read(NIFStream *nif); }; +struct NiIntegerExtraData : public Extra +{ + unsigned int data; + + void read(NIFStream *nif); +}; + +struct NiIntegersExtraData : public Extra +{ + std::vector data; + + void read(NIFStream *nif); +}; + +struct NiBinaryExtraData : public Extra +{ + std::vector data; + + void read(NIFStream *nif); +}; + +struct NiBooleanExtraData : public Extra +{ + bool data; + + void read(NIFStream *nif); +}; + +struct NiVectorExtraData : public Extra +{ + osg::Vec4f data; + + void read(NIFStream *nif); +}; + +struct NiFloatExtraData : public Extra +{ + float data; + + void read(NIFStream *nif); +}; + +struct NiFloatsExtraData : public Extra +{ + std::vector data; + + void read(NIFStream *nif); +}; + } // Namespace #endif diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 550b5fafc..8d65753d2 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -105,6 +105,14 @@ static std::map makeFactory() factory["NiSkinInstance"] = {&construct , RC_NiSkinInstance }; factory["NiLookAtController"] = {&construct , RC_NiLookAtController }; factory["NiPalette"] = {&construct , RC_NiPalette }; + factory["NiIntegerExtraData"] = {&construct , RC_NiIntegerExtraData }; + factory["NiIntegersExtraData"] = {&construct , RC_NiIntegersExtraData }; + factory["NiBinaryExtraData"] = {&construct , RC_NiBinaryExtraData }; + factory["NiBooleanExtraData"] = {&construct , RC_NiBooleanExtraData }; + factory["NiVectorExtraData"] = {&construct , RC_NiVectorExtraData }; + factory["NiColorExtraData"] = {&construct , RC_NiColorExtraData }; + factory["NiFloatExtraData"] = {&construct , RC_NiFloatExtraData }; + factory["NiFloatsExtraData"] = {&construct , RC_NiFloatsExtraData }; return factory; } diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 67202d2fe..f9bb613a0 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -101,7 +101,15 @@ enum RecordType RC_RootCollisionNode, RC_NiSphericalCollider, RC_NiLookAtController, - RC_NiPalette + RC_NiPalette, + RC_NiIntegerExtraData, + RC_NiIntegersExtraData, + RC_NiBinaryExtraData, + RC_NiBooleanExtraData, + RC_NiVectorExtraData, + RC_NiColorExtraData, + RC_NiFloatExtraData, + RC_NiFloatsExtraData }; /// Base class for all records From c34fd220db1f8002bad29078dee34f0cc0b4e046 Mon Sep 17 00:00:00 2001 From: psi29a Date: Wed, 7 Oct 2020 17:31:29 +0000 Subject: [PATCH 151/224] Update .gitlab-ci.yml --- .gitlab-ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2cb111a1a..27cc6d815 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,9 +59,6 @@ Debian_Clang_tests: MacOS: tags: - macos - - xcode - except: - - branches # because our CI VMs are not public, MRs can't use them and timeout stage: build allow_failure: true script: From a47d96ce0b06354f7b560b8d031cd507dfa0acf5 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 7 Oct 2020 19:06:28 +0000 Subject: [PATCH 152/224] Install CMake on MacOS if it's missing --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 27cc6d815..a04e347c4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,7 +60,8 @@ MacOS: tags: - macos stage: build - allow_failure: true + before_script: + - command -v cmake >/dev/null 2>&1 || brew install cmake script: - rm -fr build/* # remove anything in the build directory - CI/before_install.osx.sh From cfd9268a74ea088b4d34fef8dbebaed57f9768d3 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 7 Oct 2020 19:12:13 +0000 Subject: [PATCH 153/224] Install Qt if missing --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a04e347c4..8f53c6942 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -62,6 +62,7 @@ MacOS: stage: build before_script: - command -v cmake >/dev/null 2>&1 || brew install cmake + - brew list qt || brew install qt script: - rm -fr build/* # remove anything in the build directory - CI/before_install.osx.sh From 63a6541d0eff2932770e3de9a67b2a0b25e76278 Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 7 Oct 2020 22:11:05 +0200 Subject: [PATCH 154/224] Use separate caches for Debian builds Different builds cache different states. Each time cache file is written it erases the state created by a different type of build. --- .gitlab-ci.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2cb111a1a..0855633af 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,6 @@ stages: - linux image: debian:bullseye cache: - key: cache.002 paths: - apt-cache/ - ccache/ @@ -32,12 +31,16 @@ stages: Debian_GCC: extends: .Debian + cache: + key: Debian_GCC.v1 variables: CC: gcc CXX: g++ Debian_GCC_tests: extends: .Debian + cache: + key: Debian_GCC_tests.v1 variables: CC: gcc CXX: g++ @@ -45,12 +48,16 @@ Debian_GCC_tests: Debian_Clang: extends: .Debian + cache: + key: Debian_Clang.v1 variables: CC: clang CXX: clang++ Debian_Clang_tests: extends: .Debian + cache: + key: Debian_Clang_tests.v1 variables: CC: clang CXX: clang++ From 5515bc94b7b95b167e84c4b13fad6a8a3740af52 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 7 Oct 2020 21:04:36 +0000 Subject: [PATCH 155/224] Keep logs as artifacts --- .gitlab-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8f53c6942..77650aea5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,6 +71,15 @@ MacOS: artifacts: paths: - build/OpenMW-*.dmg + - "*.log" + - build/*.log + - build/*/*.log + - build/*/*/*.log + - build/*/*/*/*.log + - build/*/*/*/*/*.log + - build/*/*/*/*/*/*.log + - build/*/*/*/*/*/*/*.log + - build/*/*/*/*/*/*/*/*.log variables: &engine-targets targets: "openmw,openmw-essimporter,openmw-iniimporter,openmw-launcher,openmw-wizard" From be27b51279f6b38243e7fbbe624f6572b2e0aff4 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sun, 4 Oct 2020 20:12:45 +0200 Subject: [PATCH 156/224] Add head bobbing in first person mode --- CHANGELOG.md | 1 + apps/launcher/advancedpage.cpp | 2 + apps/openmw/mwrender/camera.cpp | 31 +++++++++++- apps/openmw/mwrender/camera.hpp | 8 +++- .../reference/modding/settings/camera.rst | 47 +++++++++++++++++++ files/settings-default.cfg | 12 +++++ files/ui/advancedpage.ui | 10 ++++ 7 files changed, 108 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc0b2848c..080627b82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #4894: Consider actors as obstacles for pathfinding + Feature #5043: Head Bobbing Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher Feature #5362: Show the soul gems' trapped soul in count dialog Feature #5445: Handle NiLines diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 2e929faf5..422f06ed4 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -133,6 +133,7 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); loadSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); + loadSettingBool(headBobbingCheckBox, "head bobbing", "Camera"); defaultShoulderComboBox->setCurrentIndex( mEngineSettings.getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1); } @@ -247,6 +248,7 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); saveSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); saveSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); + saveSettingBool(headBobbingCheckBox, "head bobbing", "Camera"); osg::Vec2f shoulderOffset = mEngineSettings.getVector2("view over shoulder offset", "Camera"); if (defaultShoulderComboBox->currentIndex() != (shoulderOffset.x() >= 0 ? 0 : 1)) diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 0d6ed262b..a42e06a41 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -80,6 +80,7 @@ namespace MWRender mZoomOutWhenMoveCoef(Settings::Manager::getFloat("zoom out when move coef", "Camera")), mDynamicCameraDistanceEnabled(false), mShowCrosshairInThirdPersonMode(false), + mHeadBobbingEnabled(Settings::Manager::getBool("head bobbing", "Camera")), mDeferredRotation(osg::Vec3f()), mDeferredRotationDisabled(false) { @@ -104,7 +105,9 @@ namespace MWRender osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]); osg::Vec3d position = worldMat.getTrans(); - if (!isFirstPerson()) + if (isFirstPerson()) + position.z() += mHeadBobbingOffset; + else { position.z() += mHeight * mHeightScale; @@ -143,13 +146,31 @@ namespace MWRender osg::Vec3d focal, position; getPosition(focal, position); - osg::Quat orient = osg::Quat(getPitch(), osg::Vec3d(1,0,0)) * osg::Quat(getYaw(), osg::Vec3d(0,0,1)); + osg::Quat orient = osg::Quat(mRoll, osg::Vec3d(0, 1, 0)) * osg::Quat(mPitch, osg::Vec3d(1, 0, 0)) * osg::Quat(mYaw, osg::Vec3d(0, 0, 1)); osg::Vec3d forward = orient * osg::Vec3d(0,1,0); osg::Vec3d up = orient * osg::Vec3d(0,0,1); cam->setViewMatrixAsLookAt(position, position + forward, up); } + void Camera::updateHeadBobbing(float duration) { + static const float doubleStepLength = Settings::Manager::getFloat("head bobbing step", "Camera") * 2; + static const float stepHeight = Settings::Manager::getFloat("head bobbing height", "Camera"); + static const float maxRoll = osg::DegreesToRadians(Settings::Manager::getFloat("head bobbing roll", "Camera")); + + if (MWBase::Environment::get().getWorld()->isOnGround(mTrackingPtr)) + mHeadBobbingWeight = std::min(mHeadBobbingWeight + duration * 5, 1.f); + else + mHeadBobbingWeight = std::max(mHeadBobbingWeight - duration * 5, 0.f); + + float doubleStepState = mTotalMovement / doubleStepLength - std::floor(mTotalMovement / doubleStepLength); // from 0 to 1 during 2 steps + float stepState = std::abs(doubleStepState * 4 - 2) - 1; // from -1 to 1 on even steps and from 1 to -1 on odd steps + float effect = (1 - std::cos(stepState * osg::DegreesToRadians(30.f))) * 7.5f; // range from 0 to 1 + float coef = std::min(mSmoothedSpeed / 300.f, 1.f) * mHeadBobbingWeight; + mHeadBobbingOffset = (0.5f - effect) * coef * stepHeight; // range from -stepHeight/2 to stepHeight/2 + mRoll = osg::sign(stepState) * effect * coef * maxRoll; // range from -maxRoll to maxRoll + } + void Camera::reset() { togglePreviewMode(false); @@ -198,10 +219,16 @@ namespace MWRender if(mMode == Mode::Vanity) rotateCamera(0.f, osg::DegreesToRadians(3.f * duration), true); + if (isFirstPerson() && mHeadBobbingEnabled) + updateHeadBobbing(duration); + else + mRoll = mHeadBobbingOffset = 0; + updateFocalPointOffset(duration); updatePosition(); float speed = mTrackingPtr.getClass().getCurrentSpeed(mTrackingPtr); + mTotalMovement += speed * duration; speed /= (1.f + speed / 500.f); float maxDelta = 300.f * duration; mSmoothedSpeed += osg::clampBetween(speed - mSmoothedSpeed, -maxDelta, maxDelta); diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index b3f6026eb..6fe392683 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -46,7 +46,7 @@ namespace MWRender bool mIsNearest; float mHeight, mBaseCameraDistance; - float mPitch, mYaw; + float mPitch, mYaw, mRoll; bool mVanityToggleQueued; bool mVanityToggleQueuedValue; @@ -72,6 +72,12 @@ namespace MWRender bool mDynamicCameraDistanceEnabled; bool mShowCrosshairInThirdPersonMode; + bool mHeadBobbingEnabled; + float mHeadBobbingOffset; + float mHeadBobbingWeight = 0; // Value from 0 to 1 for smooth enabling/disabling. + float mTotalMovement = 0; // Needed for head bobbing. + void updateHeadBobbing(float duration); + void updateFocalPointOffset(float duration); void updatePosition(); float getCameraDistanceCorrection() const; diff --git a/docs/source/reference/modding/settings/camera.rst b/docs/source/reference/modding/settings/camera.rst index 1025a2fbd..5701947dc 100644 --- a/docs/source/reference/modding/settings/camera.rst +++ b/docs/source/reference/modding/settings/camera.rst @@ -199,3 +199,50 @@ If disabled then the camera rotates rather than the character. This setting can be controlled in Advanced tab of the launcher. +head bobbing +------------ + +:Type: boolean +:Range: True/False +:Default: False + +Enables head bobbing when move in first person mode. + +This setting can be controlled in Advanced tab of the launcher. + +head bobbing step +----------------- + +:Type: floating point +:Range: >0 +:Default: 90.0 + +Makes diffence only in first person mode if 'head bobbing' is enabled. +Length of each step. + +This setting can only be configured by editing the settings configuration file. + +head bobbing height +------------------- + +:Type: floating point +:Range: Any +:Default: 3.0 + +Makes diffence only in first person mode if 'head bobbing' is enabled. +Amplitude of the head bobbing. + +This setting can only be configured by editing the settings configuration file. + +head bobbing roll +----------------- + +:Type: floating point +:Range: 0-90 +:Default: 0.2 + +Makes diffence only in first person mode if 'head bobbing' is enabled. +Maximum roll angle in degrees. + +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 fab5fe569..3f87907ae 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -54,6 +54,18 @@ preview if stand still = false # Rotate the character to the view direction after exiting preview mode. deferred preview rotation = true +# Enables head bobbing in first person mode +head bobbing = false + +# Length of each step +head bobbing step = 90.0 + +# Amplitude of the bobbing effect +head bobbing height = 3.0 + +# Maximum camera roll angle (degrees) +head bobbing roll = 0.2 + [Cells] # Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled. diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 3a91db791..0410d67fd 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -553,6 +553,16 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C + + + + <html><head/><body><p>Enables head bobbing when move in first person mode.</p></body></html> + + + Head bobbing in 1st person mode + + + From 6be808e3016d8b17865c43b065c89e2b59c8d569 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Wed, 7 Oct 2020 22:44:09 +0300 Subject: [PATCH 157/224] RigGeometry: convert some pairs to structs --- components/nifosg/nifloader.cpp | 8 ++--- components/sceneutil/riggeometry.cpp | 35 +++++++------------ components/sceneutil/riggeometry.hpp | 50 ++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 61a276dc1..4a2dac36c 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1239,15 +1239,13 @@ namespace NifOsg std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name); SceneUtil::RigGeometry::BoneInfluence influence; - const std::vector &weights = data->bones[i].weights; + const auto& weights = data->bones[i].weights; for(size_t j = 0;j < weights.size();j++) - { - influence.mWeights.emplace_back(weights[j].vertex, weights[j].weight); - } + influence.mWeights.push_back({weights[j].vertex, weights[j].weight}); influence.mInvBindMatrix = data->bones[i].trafo.toMatrix(); influence.mBoundSphere = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius); - map->mData.emplace_back(boneName, influence); + map->mData.push_back({boneName, influence}); } rig->setInfluenceMap(map); diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index b9201fdf6..c6ad7e9de 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -137,14 +137,13 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) } mBoneNodesVector.clear(); - for (auto& bonePair : mBoneSphereVector->mData) + for (auto& boundPair : mBoneSphereVector->mData) { - const std::string& boneName = bonePair.first; - Bone* bone = mSkeleton->getBone(boneName); + Bone* bone = mSkeleton->getBone(boundPair.name); if (!bone) { mBoneNodesVector.push_back(nullptr); - Log(Debug::Error) << "Error: RigGeometry did not find bone " << boneName; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << boundPair.name; continue; } @@ -155,12 +154,11 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) { for (auto &weight : pair.first) { - const std::string& boneName = weight.first.first; - Bone* bone = mSkeleton->getBone(boneName); + Bone* bone = mSkeleton->getBone(weight.boneName); if (!bone) { mBoneNodesVector.push_back(nullptr); - Log(Debug::Error) << "Error: RigGeometry did not find bone " << boneName; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << weight.boneName; continue; } @@ -218,7 +216,7 @@ void RigGeometry::cull(osg::NodeVisitor* nv) if (bone == nullptr) continue; - accumulateMatrix(weight.first.second, bone->mMatrixInSkeletonSpace, weight.second, resultMat); + accumulateMatrix(weight.bindMatrix, bone->mMatrixInSkeletonSpace, weight.value, resultMat); index++; } @@ -281,7 +279,7 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv) continue; index++; - osg::BoundingSpheref bs = boundPair.second; + osg::BoundingSpheref bs = boundPair.sphere; if (mGeomToSkelMatrix) transformBoundingSphere(bone->mMatrixInSkeletonSpace * (*mGeomToSkelMatrix), bs); else @@ -337,30 +335,21 @@ void RigGeometry::setInfluenceMap(osg::ref_ptr influenceMap) { mInfluenceMap = influenceMap; - typedef std::map > Vertex2BoneMap; + using Vertex2BoneMap = std::map>; Vertex2BoneMap vertex2BoneMap; mBoneSphereVector = new BoneSphereVector; mBoneSphereVector->mData.reserve(mInfluenceMap->mData.size()); mBone2VertexVector = new Bone2VertexVector; - for (auto& influencePair : mInfluenceMap->mData) + for (const BoneData& bone : mInfluenceMap->mData) { - const std::string& boneName = influencePair.first; - const BoneInfluence& bi = influencePair.second; - mBoneSphereVector->mData.emplace_back(boneName, bi.mBoundSphere); - - for (auto& weightPair: bi.mWeights) - { - std::vector& vec = vertex2BoneMap[weightPair.first]; - - vec.emplace_back(std::make_pair(boneName, bi.mInvBindMatrix), weightPair.second); - } + mBoneSphereVector->mData.push_back({bone.name, bone.influence.mBoundSphere}); + for (auto& weight : bone.influence.mWeights) + vertex2BoneMap[weight.vertex].push_back({bone.name, bone.influence.mInvBindMatrix, weight.value}); } Bone2VertexMap bone2VertexMap; for (auto& vertexPair : vertex2BoneMap) - { bone2VertexMap[vertexPair.second].emplace_back(vertexPair.first); - } mBone2VertexVector->mData.reserve(bone2VertexMap.size()); mBone2VertexVector->mData.assign(bone2VertexMap.begin(), bone2VertexMap.end()); diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 801c172b3..5f1decf5f 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -25,17 +25,32 @@ namespace SceneUtil // Currently empty as this is difficult to implement. Technically we would need to compile both internal geometries in separate frames but this method is only called once. Alternatively we could compile just the static parts of the model. virtual void compileGLObjects(osg::RenderInfo& renderInfo) const {} + struct VertexWeight + { + unsigned short vertex; + float value; + }; + struct BoneInfluence { osg::Matrixf mInvBindMatrix; osg::BoundingSpheref mBoundSphere; - // - std::vector> mWeights; + std::vector mWeights; + }; + + struct BoneData + { + std::string name; + BoneInfluence influence; + bool operator<(const BoneData& other) const + { + return name < other.name; + } }; struct InfluenceMap : public osg::Referenced { - std::vector> mData; + std::vector mData; }; void setInfluenceMap(osg::ref_ptr influenceMap); @@ -79,23 +94,36 @@ namespace SceneUtil osg::ref_ptr mInfluenceMap; - typedef std::pair BoneBindMatrixPair; + struct BoneWeight + { + std::string boneName; + osg::Matrixf bindMatrix; + float value; + bool operator<(const BoneWeight& other) const + { + return boneName < other.boneName; + } + }; - typedef std::pair BoneWeight; - - typedef std::vector VertexList; - - typedef std::map, VertexList> Bone2VertexMap; + using VertexList = std::vector; + using BoneWeightList = std::vector; + using Bone2VertexMap = std::map; struct Bone2VertexVector : public osg::Referenced { - std::vector, VertexList>> mData; + std::vector> mData; }; osg::ref_ptr mBone2VertexVector; + struct BoneSphere + { + std::string name; + osg::BoundingSpheref sphere; + }; + struct BoneSphereVector : public osg::Referenced { - std::vector> mData; + std::vector mData; }; osg::ref_ptr mBoneSphereVector; std::vector mBoneNodesVector; From 7d73e73cad545f1ae05536ca563baf394769ab45 Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 7 Oct 2020 23:47:59 +0200 Subject: [PATCH 158/224] Consider tile as not removed when it is not found --- components/detournavigator/navmeshcacheitem.hpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/detournavigator/navmeshcacheitem.hpp b/components/detournavigator/navmeshcacheitem.hpp index f13341397..d4d6418dc 100644 --- a/components/detournavigator/navmeshcacheitem.hpp +++ b/components/detournavigator/navmeshcacheitem.hpp @@ -143,7 +143,7 @@ namespace DetourNavigator UpdateNavMeshStatus removeTile(const TilePosition& position) { - const auto removed = dtStatusSucceed(removeTileImpl(position)); + const auto removed = removeTileImpl(position); if (removed) removeUsedTile(position); return UpdateNavMeshStatusBuilder().removed(removed).getResult(); @@ -181,13 +181,15 @@ namespace DetourNavigator return mImpl->addTile(data, size, doNotTransferOwnership, lastRef, result); } - dtStatus removeTileImpl(const TilePosition& position) + bool removeTileImpl(const TilePosition& position) { const int layer = 0; const auto tileRef = mImpl->getTileRefAt(position.x(), position.y(), layer); + if (tileRef == 0) + return false; unsigned char** const data = nullptr; int* const dataSize = nullptr; - return mImpl->removeTile(tileRef, data, dataSize); + return dtStatusSucceed(mImpl->removeTile(tileRef, data, dataSize)); } }; From eb140ed15fea0369be15705143d1a4669142e0cd Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 7 Oct 2020 23:54:32 +0200 Subject: [PATCH 159/224] Write unknown status numeric value --- components/detournavigator/asyncnavmeshupdater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 0683a43bc..7af3e0967 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -39,7 +39,7 @@ namespace DetourNavigator case UpdateNavMeshStatus::lost: return stream << "lost"; } - return stream << "unknown"; + return stream << "unknown(" << static_cast(value) << ")"; } AsyncNavMeshUpdater::AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager, From f637dc38bd15414716669a46e7fe09c76025f324 Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 8 Oct 2020 00:04:51 +0200 Subject: [PATCH 160/224] Add cached flag to update navmesh status --- .../detournavigator/asyncnavmeshupdater.cpp | 6 ++++++ components/detournavigator/makenavmesh.cpp | 6 +++++- components/detournavigator/navmeshcacheitem.hpp | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/components/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 7af3e0967..49339ebdf 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -38,6 +38,12 @@ namespace DetourNavigator return stream << "failed"; case UpdateNavMeshStatus::lost: return stream << "lost"; + case UpdateNavMeshStatus::cached: + return stream << "cached"; + case UpdateNavMeshStatus::unchanged: + return stream << "unchanged"; + case UpdateNavMeshStatus::restored: + return stream << "restored"; } return stream << "unknown(" << static_cast(value) << ")"; } diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index beee95113..7c7dcf186 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -559,6 +559,7 @@ namespace DetourNavigator } auto cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh, offMeshConnections); + bool cached = static_cast(cachedNavMeshData); if (!cachedNavMeshData) { @@ -584,6 +585,7 @@ namespace DetourNavigator { cachedNavMeshData = navMeshTilesCache.get(agentHalfExtents, changedTile, *recastMesh, offMeshConnections); + cached = static_cast(cachedNavMeshData); } if (!cachedNavMeshData) @@ -593,6 +595,8 @@ namespace DetourNavigator } } - return navMeshCacheItem->lock()->updateTile(changedTile, std::move(cachedNavMeshData)); + const auto updateStatus = navMeshCacheItem->lock()->updateTile(changedTile, std::move(cachedNavMeshData)); + + return UpdateNavMeshStatusBuilder(updateStatus).cached(cached).getResult(); } } diff --git a/components/detournavigator/navmeshcacheitem.hpp b/components/detournavigator/navmeshcacheitem.hpp index d4d6418dc..76f74f266 100644 --- a/components/detournavigator/navmeshcacheitem.hpp +++ b/components/detournavigator/navmeshcacheitem.hpp @@ -22,6 +22,9 @@ namespace DetourNavigator replaced = removed | added, failed = 1 << 2, lost = removed | failed, + cached = 1 << 3, + unchanged = replaced | cached, + restored = added | cached, }; inline bool isSuccess(UpdateNavMeshStatus value) @@ -34,6 +37,9 @@ namespace DetourNavigator public: UpdateNavMeshStatusBuilder() = default; + explicit UpdateNavMeshStatusBuilder(UpdateNavMeshStatus value) + : mResult(value) {} + UpdateNavMeshStatusBuilder removed(bool value) { if (value) @@ -61,6 +67,15 @@ namespace DetourNavigator return *this; } + UpdateNavMeshStatusBuilder cached(bool value) + { + if (value) + set(UpdateNavMeshStatus::cached); + else + unset(UpdateNavMeshStatus::cached); + return *this; + } + UpdateNavMeshStatus getResult() const { return mResult; From 7591d45008471d89bb2e4452221a86b2c09de518 Mon Sep 17 00:00:00 2001 From: elsid Date: Thu, 8 Oct 2020 00:58:11 +0200 Subject: [PATCH 161/224] Use memcpy to create navmesh key Implementation with memcpy is ~13 times faster. --- .../detournavigator/navmeshtilescache.cpp | 64 ++++++++----------- .../detournavigator/navmeshtilescache.hpp | 31 ++++++--- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/components/detournavigator/navmeshtilescache.cpp b/components/detournavigator/navmeshtilescache.cpp index 466d2e708..f554cd414 100644 --- a/components/detournavigator/navmeshtilescache.cpp +++ b/components/detournavigator/navmeshtilescache.cpp @@ -9,42 +9,32 @@ namespace DetourNavigator { namespace { - inline std::string makeNavMeshKey(const RecastMesh& recastMesh, + inline std::vector makeNavMeshKey(const RecastMesh& recastMesh, const std::vector& offMeshConnections) { - std::string result; - result.reserve( - recastMesh.getIndices().size() * sizeof(int) - + recastMesh.getVertices().size() * sizeof(float) - + recastMesh.getAreaTypes().size() * sizeof(AreaType) - + recastMesh.getWater().size() * sizeof(RecastMesh::Water) - + offMeshConnections.size() * sizeof(OffMeshConnection) - ); - std::copy( - reinterpret_cast(recastMesh.getIndices().data()), - reinterpret_cast(recastMesh.getIndices().data() + recastMesh.getIndices().size()), - std::back_inserter(result) - ); - std::copy( - reinterpret_cast(recastMesh.getVertices().data()), - reinterpret_cast(recastMesh.getVertices().data() + recastMesh.getVertices().size()), - std::back_inserter(result) - ); - std::copy( - reinterpret_cast(recastMesh.getAreaTypes().data()), - reinterpret_cast(recastMesh.getAreaTypes().data() + recastMesh.getAreaTypes().size()), - std::back_inserter(result) - ); - std::copy( - reinterpret_cast(recastMesh.getWater().data()), - reinterpret_cast(recastMesh.getWater().data() + recastMesh.getWater().size()), - std::back_inserter(result) - ); - std::copy( - reinterpret_cast(offMeshConnections.data()), - reinterpret_cast(offMeshConnections.data() + offMeshConnections.size()), - std::back_inserter(result) - ); + const std::size_t indicesSize = recastMesh.getIndices().size() * sizeof(int); + const std::size_t verticesSize = recastMesh.getVertices().size() * sizeof(float); + const std::size_t areaTypesSize = recastMesh.getAreaTypes().size() * sizeof(AreaType); + const std::size_t waterSize = recastMesh.getWater().size() * sizeof(RecastMesh::Water); + const std::size_t offMeshConnectionsSize = offMeshConnections.size() * sizeof(OffMeshConnection); + + std::vector result(indicesSize + verticesSize + areaTypesSize + waterSize + offMeshConnectionsSize); + unsigned char* dst = result.data(); + + std::memcpy(dst, recastMesh.getIndices().data(), indicesSize); + dst += indicesSize; + + std::memcpy(dst, recastMesh.getVertices().data(), verticesSize); + dst += verticesSize; + + std::memcpy(dst, recastMesh.getAreaTypes().data(), areaTypesSize); + dst += areaTypesSize; + + std::memcpy(dst, recastMesh.getWater().data(), waterSize); + dst += waterSize; + + std::memcpy(dst, offMeshConnections.data(), offMeshConnectionsSize); + return result; } } @@ -189,8 +179,8 @@ namespace DetourNavigator { struct CompareBytes { - const char* mRhsIt; - const char* mRhsEnd; + const unsigned char* mRhsIt; + const unsigned char* const mRhsEnd; template int operator ()(const std::vector& lhs) @@ -225,7 +215,7 @@ namespace DetourNavigator }; } - int NavMeshTilesCache::RecastMeshKeyView::compare(const std::string& other) const + int NavMeshTilesCache::RecastMeshKeyView::compare(const std::vector& other) const { CompareBytes compareBytes {other.data(), other.data() + other.size()}; diff --git a/components/detournavigator/navmeshtilescache.hpp b/components/detournavigator/navmeshtilescache.hpp index 57f57a56f..064d9e185 100644 --- a/components/detournavigator/navmeshtilescache.hpp +++ b/components/detournavigator/navmeshtilescache.hpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include namespace osg { @@ -33,10 +35,10 @@ namespace DetourNavigator std::atomic mUseCount; osg::Vec3f mAgentHalfExtents; TilePosition mChangedTile; - std::string mNavMeshKey; + std::vector mNavMeshKey; NavMeshData mNavMeshData; - Item(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile, std::string navMeshKey) + Item(const osg::Vec3f& agentHalfExtents, const TilePosition& changedTile, std::vector&& navMeshKey) : mUseCount(0) , mAgentHalfExtents(agentHalfExtents) , mChangedTile(changedTile) @@ -120,19 +122,32 @@ namespace DetourNavigator virtual ~KeyView() = default; - KeyView(const std::string& value) + KeyView(const std::vector& value) : mValue(&value) {} - const std::string& getValue() const + const std::vector& getValue() const { assert(mValue); return *mValue; } - virtual int compare(const std::string& other) const + virtual int compare(const std::vector& other) const { assert(mValue); - return mValue->compare(other); + + const auto valueSize = mValue->size(); + const auto otherSize = other.size(); + + if (const auto result = std::memcmp(mValue->data(), other.data(), std::min(valueSize, otherSize))) + return result; + + if (valueSize < otherSize) + return -1; + + if (valueSize > otherSize) + return 1; + + return 0; } virtual bool isLess(const KeyView& other) const @@ -147,7 +162,7 @@ namespace DetourNavigator } private: - const std::string* mValue = nullptr; + const std::vector* mValue = nullptr; }; class RecastMeshKeyView : public KeyView @@ -156,7 +171,7 @@ namespace DetourNavigator RecastMeshKeyView(const RecastMesh& recastMesh, const std::vector& offMeshConnections) : mRecastMesh(recastMesh), mOffMeshConnections(offMeshConnections) {} - int compare(const std::string& other) const override; + int compare(const std::vector& other) const override; bool isLess(const KeyView& other) const override { From 02861fa8e3a3d98d8354a83cdb9cedb4a55dc62d Mon Sep 17 00:00:00 2001 From: tessa Date: Thu, 8 Oct 2020 13:06:04 -0500 Subject: [PATCH 162/224] fix cmake warning --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b6836237..4918e31fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -882,7 +882,7 @@ elseif(NOT APPLE) INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources") INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources") endif(WIN32) -endif(NOT APPLE) +endif() # Doxygen Target -- simply run 'make doc' or 'make doc_pages' # output directory for 'make doc' is "${OpenMW_BINARY_DIR}/docs/Doxygen" From 38e567a7e4eb282c22c2ca4c1b99d7e4e7e0a7cc Mon Sep 17 00:00:00 2001 From: tess <2687892-TescoShoppah@users.noreply.gitlab.com> Date: Thu, 8 Oct 2020 19:34:03 +0000 Subject: [PATCH 163/224] match opening and closing if args --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4918e31fd..fecb589eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -882,7 +882,7 @@ elseif(NOT APPLE) INSTALL(DIRECTORY "${INSTALL_SOURCE}/resources" DESTINATION "${DATADIR}" COMPONENT "Resources") INSTALL(DIRECTORY DESTINATION "${DATADIR}/data" COMPONENT "Resources") endif(WIN32) -endif() +endif(OPENMW_OSX_DEPLOYMENT AND APPLE) # Doxygen Target -- simply run 'make doc' or 'make doc_pages' # output directory for 'make doc' is "${OpenMW_BINARY_DIR}/docs/Doxygen" From ec825b2510131d747b143e15cda4a2ca25d0824f Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Thu, 8 Oct 2020 22:44:46 +0300 Subject: [PATCH 164/224] Fix RayCastingResult warning --- apps/openmw/mwphysics/physicssystem.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 8b07fea4b..07859c1e2 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -265,7 +265,11 @@ namespace MWPhysics RayCastingResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector targets, int mask, int group) const { if (from == to) - return RayCastingResult { false }; + { + RayCastingResult result; + result.mHit = false; + return result; + } btVector3 btFrom = Misc::Convert::toBullet(from); btVector3 btTo = Misc::Convert::toBullet(to); From 2f1b7c4d2ff823ac6b2b490567429be64338054c Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 8 Oct 2020 21:35:37 +0000 Subject: [PATCH 165/224] Rename DMG file --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 77650aea5..d604e90c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,6 +68,7 @@ MacOS: - CI/before_install.osx.sh - CI/before_script.osx.sh - cd build; make -j2 package + - for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.dmg"; done artifacts: paths: - build/OpenMW-*.dmg From 3a39e1f8f8fd1dacf5c28a2d558c8dc8bc05f0d6 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 8 Oct 2020 22:25:16 +0000 Subject: [PATCH 166/224] config was from Windows CI --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d604e90c8..d335dfd91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,7 +68,7 @@ MacOS: - CI/before_install.osx.sh - CI/before_script.osx.sh - cd build; make -j2 package - - for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.dmg"; done + - for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.dmg"; done artifacts: paths: - build/OpenMW-*.dmg From 9f08dc99687eaf175ec2ff5f695dfae0decf04a3 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Thu, 8 Oct 2020 23:24:28 +0000 Subject: [PATCH 167/224] Revert "Merge branch 'skinning' into 'master'" This reverts merge request !327 --- components/nifosg/nifloader.cpp | 8 +++-- components/sceneutil/riggeometry.cpp | 35 ++++++++++++------- components/sceneutil/riggeometry.hpp | 50 ++++++---------------------- 3 files changed, 39 insertions(+), 54 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 4a2dac36c..61a276dc1 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1239,13 +1239,15 @@ namespace NifOsg std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name); SceneUtil::RigGeometry::BoneInfluence influence; - const auto& weights = data->bones[i].weights; + const std::vector &weights = data->bones[i].weights; for(size_t j = 0;j < weights.size();j++) - influence.mWeights.push_back({weights[j].vertex, weights[j].weight}); + { + influence.mWeights.emplace_back(weights[j].vertex, weights[j].weight); + } influence.mInvBindMatrix = data->bones[i].trafo.toMatrix(); influence.mBoundSphere = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius); - map->mData.push_back({boneName, influence}); + map->mData.emplace_back(boneName, influence); } rig->setInfluenceMap(map); diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index c6ad7e9de..b9201fdf6 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -137,13 +137,14 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) } mBoneNodesVector.clear(); - for (auto& boundPair : mBoneSphereVector->mData) + for (auto& bonePair : mBoneSphereVector->mData) { - Bone* bone = mSkeleton->getBone(boundPair.name); + const std::string& boneName = bonePair.first; + Bone* bone = mSkeleton->getBone(boneName); if (!bone) { mBoneNodesVector.push_back(nullptr); - Log(Debug::Error) << "Error: RigGeometry did not find bone " << boundPair.name; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << boneName; continue; } @@ -154,11 +155,12 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) { for (auto &weight : pair.first) { - Bone* bone = mSkeleton->getBone(weight.boneName); + const std::string& boneName = weight.first.first; + Bone* bone = mSkeleton->getBone(boneName); if (!bone) { mBoneNodesVector.push_back(nullptr); - Log(Debug::Error) << "Error: RigGeometry did not find bone " << weight.boneName; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << boneName; continue; } @@ -216,7 +218,7 @@ void RigGeometry::cull(osg::NodeVisitor* nv) if (bone == nullptr) continue; - accumulateMatrix(weight.bindMatrix, bone->mMatrixInSkeletonSpace, weight.value, resultMat); + accumulateMatrix(weight.first.second, bone->mMatrixInSkeletonSpace, weight.second, resultMat); index++; } @@ -279,7 +281,7 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv) continue; index++; - osg::BoundingSpheref bs = boundPair.sphere; + osg::BoundingSpheref bs = boundPair.second; if (mGeomToSkelMatrix) transformBoundingSphere(bone->mMatrixInSkeletonSpace * (*mGeomToSkelMatrix), bs); else @@ -335,21 +337,30 @@ void RigGeometry::setInfluenceMap(osg::ref_ptr influenceMap) { mInfluenceMap = influenceMap; - using Vertex2BoneMap = std::map>; + typedef std::map > Vertex2BoneMap; Vertex2BoneMap vertex2BoneMap; mBoneSphereVector = new BoneSphereVector; mBoneSphereVector->mData.reserve(mInfluenceMap->mData.size()); mBone2VertexVector = new Bone2VertexVector; - for (const BoneData& bone : mInfluenceMap->mData) + for (auto& influencePair : mInfluenceMap->mData) { - mBoneSphereVector->mData.push_back({bone.name, bone.influence.mBoundSphere}); - for (auto& weight : bone.influence.mWeights) - vertex2BoneMap[weight.vertex].push_back({bone.name, bone.influence.mInvBindMatrix, weight.value}); + const std::string& boneName = influencePair.first; + const BoneInfluence& bi = influencePair.second; + mBoneSphereVector->mData.emplace_back(boneName, bi.mBoundSphere); + + for (auto& weightPair: bi.mWeights) + { + std::vector& vec = vertex2BoneMap[weightPair.first]; + + vec.emplace_back(std::make_pair(boneName, bi.mInvBindMatrix), weightPair.second); + } } Bone2VertexMap bone2VertexMap; for (auto& vertexPair : vertex2BoneMap) + { bone2VertexMap[vertexPair.second].emplace_back(vertexPair.first); + } mBone2VertexVector->mData.reserve(bone2VertexMap.size()); mBone2VertexVector->mData.assign(bone2VertexMap.begin(), bone2VertexMap.end()); diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 5f1decf5f..801c172b3 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -25,32 +25,17 @@ namespace SceneUtil // Currently empty as this is difficult to implement. Technically we would need to compile both internal geometries in separate frames but this method is only called once. Alternatively we could compile just the static parts of the model. virtual void compileGLObjects(osg::RenderInfo& renderInfo) const {} - struct VertexWeight - { - unsigned short vertex; - float value; - }; - struct BoneInfluence { osg::Matrixf mInvBindMatrix; osg::BoundingSpheref mBoundSphere; - std::vector mWeights; - }; - - struct BoneData - { - std::string name; - BoneInfluence influence; - bool operator<(const BoneData& other) const - { - return name < other.name; - } + // + std::vector> mWeights; }; struct InfluenceMap : public osg::Referenced { - std::vector mData; + std::vector> mData; }; void setInfluenceMap(osg::ref_ptr influenceMap); @@ -94,36 +79,23 @@ namespace SceneUtil osg::ref_ptr mInfluenceMap; - struct BoneWeight - { - std::string boneName; - osg::Matrixf bindMatrix; - float value; - bool operator<(const BoneWeight& other) const - { - return boneName < other.boneName; - } - }; + typedef std::pair BoneBindMatrixPair; - using VertexList = std::vector; - using BoneWeightList = std::vector; - using Bone2VertexMap = std::map; + typedef std::pair BoneWeight; + + typedef std::vector VertexList; + + typedef std::map, VertexList> Bone2VertexMap; struct Bone2VertexVector : public osg::Referenced { - std::vector> mData; + std::vector, VertexList>> mData; }; osg::ref_ptr mBone2VertexVector; - struct BoneSphere - { - std::string name; - osg::BoundingSpheref sphere; - }; - struct BoneSphereVector : public osg::Referenced { - std::vector mData; + std::vector> mData; }; osg::ref_ptr mBoneSphereVector; std::vector mBoneNodesVector; From 1aa5e5cc52bb5bc18c204a7043cfdf906bba9275 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 9 Oct 2020 13:32:28 +0000 Subject: [PATCH 168/224] Increase CCache size for Debian where needed --- .gitlab-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0855633af..fb4263ee2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,7 +18,7 @@ stages: script: - export CCACHE_BASEDIR="`pwd`" - export CCACHE_DIR="`pwd`/ccache" && mkdir -pv "$CCACHE_DIR" - - ccache -z -M 1G + - ccache -z -M "${CCACHE_SIZE}" - CI/before_script.linux.sh - cd build - cmake --build . -- -j $(nproc) @@ -36,6 +36,7 @@ Debian_GCC: variables: CC: gcc CXX: g++ + CCACHE_SIZE: 3G Debian_GCC_tests: extends: .Debian @@ -44,6 +45,7 @@ Debian_GCC_tests: variables: CC: gcc CXX: g++ + CCACHE_SIZE: 1G BUILD_TESTS_ONLY: 1 Debian_Clang: @@ -53,6 +55,7 @@ Debian_Clang: variables: CC: clang CXX: clang++ + CCACHE_SIZE: 2G Debian_Clang_tests: extends: .Debian @@ -61,6 +64,7 @@ Debian_Clang_tests: variables: CC: clang CXX: clang++ + CCACHE_SIZE: 1G BUILD_TESTS_ONLY: 1 MacOS: From ef41edba9b6945ad50c8a3509d6bf0ddbf31b065 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 9 Oct 2020 13:56:21 +0000 Subject: [PATCH 169/224] Install tools in before_install.osx.sh --- .gitlab-ci.yml | 13 +------------ CI/before_install.osx.sh | 5 ++++- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d335dfd91..8edf66569 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,9 +60,6 @@ MacOS: tags: - macos stage: build - before_script: - - command -v cmake >/dev/null 2>&1 || brew install cmake - - brew list qt || brew install qt script: - rm -fr build/* # remove anything in the build directory - CI/before_install.osx.sh @@ -72,15 +69,7 @@ MacOS: artifacts: paths: - build/OpenMW-*.dmg - - "*.log" - - build/*.log - - build/*/*.log - - build/*/*/*.log - - build/*/*/*/*.log - - build/*/*/*/*/*.log - - build/*/*/*/*/*/*.log - - build/*/*/*/*/*/*/*.log - - build/*/*/*/*/*/*/*/*.log + - "build/**/*.log" variables: &engine-targets targets: "openmw,openmw-essimporter,openmw-iniimporter,openmw-launcher,openmw-wizard" diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 5dae1f102..c3514e25b 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -1,6 +1,9 @@ #!/bin/sh -e -brew install ccache +# Some of these tools can come from places other than brew, so check before installing +command -v ccache >/dev/null 2>&1 || brew install ccache +command -v cmake >/dev/null 2>&1 || brew install cmake +command -v qmake >/dev/null 2>&1 || brew install qt curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null From 0dcb8c6b699d3737f8a3ad2641fd42f75b2be41e Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 9 Oct 2020 19:20:50 +0300 Subject: [PATCH 170/224] Fix pick/probe uses decrement --- apps/openmw/mwmechanics/security.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 5b79d821c..e642a7bb4 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -65,7 +65,7 @@ namespace MWMechanics resultMessage = "#{sLockFail}"; } - lockpick.getCellRef().setCharge(uses-1); + lockpick.getCellRef().setCharge(--uses); if (!uses) lockpick.getContainerStore()->remove(lockpick, 1, mActor); } @@ -110,7 +110,7 @@ namespace MWMechanics resultMessage = "#{sTrapFail}"; } - probe.getCellRef().setCharge(uses-1); + probe.getCellRef().setCharge(--uses); if (!uses) probe.getContainerStore()->remove(probe, 1, mActor); } From 05cd005b30e911a74af9126b1ad09ac88b1be0d5 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 9 Oct 2020 19:37:54 +0300 Subject: [PATCH 171/224] Fix NiTriStripsData loading --- components/nif/data.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/nif/data.cpp b/components/nif/data.cpp index e76541d5c..91b3beba4 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -145,7 +145,7 @@ void NiTriStripsData::read(NIFStream *nif) nif->getUShorts(lengths, numStrips); // "Has Strips" flag. Exceptionally useful. - bool hasStrips = false; + bool hasStrips = true; if (nif->getVersion() > NIFFile::NIFVersion::VER_OB_OLD) hasStrips = nif->getBoolean(); if (!hasStrips || !numStrips) From 39678c74bfd073e9616b4af159ddea9983437c36 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 9 Oct 2020 20:34:36 +0300 Subject: [PATCH 172/224] Add many more godmode checks to harmful magic (bug #5633) --- apps/openmw/mwclass/npc.cpp | 6 ++-- apps/openmw/mwgui/inventorywindow.cpp | 3 +- apps/openmw/mwgui/quickkeysmenu.cpp | 3 +- apps/openmw/mwgui/spellwindow.cpp | 3 +- apps/openmw/mwmechanics/actors.cpp | 34 +++++++++++++++------ apps/openmw/mwmechanics/character.cpp | 2 +- apps/openmw/mwmechanics/tickableeffects.cpp | 31 ++++++++++++++----- apps/openmw/mwworld/player.cpp | 3 +- apps/openmw/mwworld/worldimp.cpp | 7 +++-- 9 files changed, 67 insertions(+), 25 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 4aab95f9d..f4a711432 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -941,7 +941,8 @@ namespace MWClass // TODO: This function is called several times per frame for each NPC. // It would be better to calculate it only once per frame for each NPC and save the result in CreatureStats. const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); - if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) + bool godmode = ptr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); + if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead()) return 0.f; const MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -990,7 +991,8 @@ namespace MWClass return 0.f; const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); - if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) + bool godmode = ptr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); + if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead()) return 0.f; const NpcCustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index d11ee4f0c..b0749d4bd 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -778,7 +778,8 @@ namespace MWGui return; const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player); - if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) + bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); + if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) return; ItemModel::ModelIndex selected = -1; diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 8449e6a5b..214e52942 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -340,7 +340,8 @@ namespace MWGui || playerStats.getKnockedDown() || playerStats.getHitRecovery(); - bool isReturnNeeded = playerStats.isParalyzed() || playerStats.isDead(); + bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); + bool isReturnNeeded = (!godmode && playerStats.isParalyzed()) || playerStats.isDead(); if (isReturnNeeded && key->type != Type_Item) { diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 7776b376a..d76a59820 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -241,8 +241,9 @@ namespace MWGui if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player)) return; + bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player); - if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) + if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) return; mSpellView->setModel(new SpellModel(MWMechanics::getPlayer(), "")); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3de1a3acc..b12518b7b 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -918,6 +918,7 @@ namespace MWMechanics { CreatureStats &creatureStats = ptr.getClass().getCreatureStats(ptr); const MagicEffects &effects = creatureStats.getMagicEffects(); + bool godmode = ptr == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); bool wasDead = creatureStats.isDead(); @@ -969,8 +970,11 @@ namespace MWMechanics for (int i = 0; i < 3; ++i) { DynamicStat stat = creatureStats.getDynamic(i); - stat.setCurrentModifier(effects.get(ESM::MagicEffect::FortifyHealth + i).getMagnitude() - - effects.get(ESM::MagicEffect::DrainHealth + i).getMagnitude(), + float fortify = effects.get(ESM::MagicEffect::FortifyHealth + i).getMagnitude(); + float drain = 0.f; + if (!godmode) + drain = effects.get(ESM::MagicEffect::DrainHealth + i).getMagnitude(); + stat.setCurrentModifier(fortify - drain, // Magicka can be decreased below zero due to a fortify effect wearing off // Fatigue can be decreased below zero meaning the actor will be knocked out i == 1 || i == 2); @@ -982,9 +986,14 @@ namespace MWMechanics for(int i = 0;i < ESM::Attribute::Length;++i) { AttributeValue stat = creatureStats.getAttribute(i); - stat.setModifier(static_cast(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).getMagnitude() - - effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).getMagnitude() - - effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).getMagnitude())); + float fortify = effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).getMagnitude(); + float drain = 0.f, absorb = 0.f; + if (!godmode) + { + drain = effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).getMagnitude(); + absorb = effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).getMagnitude(); + } + stat.setModifier(static_cast(fortify - drain - absorb)); creatureStats.setAttribute(i, stat); } @@ -1214,14 +1223,20 @@ namespace MWMechanics { NpcStats &npcStats = ptr.getClass().getNpcStats(ptr); const MagicEffects &effects = npcStats.getMagicEffects(); + bool godmode = ptr == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); // skills for(int i = 0;i < ESM::Skill::Length;++i) { SkillValue& skill = npcStats.getSkill(i); - skill.setModifier(static_cast(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).getMagnitude() - - effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).getMagnitude() - - effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).getMagnitude())); + float fortify = effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).getMagnitude(); + float drain = 0.f, absorb = 0.f; + if (!godmode) + { + drain = effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).getMagnitude(); + absorb = effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).getMagnitude(); + } + skill.setModifier(static_cast(fortify - drain - absorb)); } } @@ -1827,6 +1842,7 @@ namespace MWMechanics if (!playerHitAttemptActor.isInCell()) player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); } + bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); // AI and magic effects update for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) @@ -2007,7 +2023,7 @@ namespace MWMechanics iter->first.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor); const bool isDead = iter->first.getClass().getCreatureStats(iter->first).isDead(); - if (!isDead && iter->first.getClass().getCreatureStats(iter->first).isParalyzed()) + if (!isDead && (!godmode || !isPlayer) && iter->first.getClass().getCreatureStats(iter->first).isParalyzed()) ctrl->skipAnim(); // Handle player last, in case a cell transition occurs by casting a teleportation spell diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 1dcccb888..ad64f79d7 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1929,7 +1929,7 @@ void CharacterController::update(float duration, bool animationOnly) else if(!cls.getCreatureStats(mPtr).isDead()) { bool onground = world->isOnGround(mPtr); - bool incapacitated = (cls.getCreatureStats(mPtr).isParalyzed() || cls.getCreatureStats(mPtr).getKnockedDown()); + bool incapacitated = ((!godmode && cls.getCreatureStats(mPtr).isParalyzed()) || cls.getCreatureStats(mPtr).getKnockedDown()); bool inwater = world->isSwimming(mPtr); bool flying = world->isFlying(mPtr); bool solid = world->isActorCollisionEnabled(mPtr); diff --git a/apps/openmw/mwmechanics/tickableeffects.cpp b/apps/openmw/mwmechanics/tickableeffects.cpp index 31e8c150c..fa3b6ac20 100644 --- a/apps/openmw/mwmechanics/tickableeffects.cpp +++ b/apps/openmw/mwmechanics/tickableeffects.cpp @@ -68,11 +68,14 @@ namespace MWMechanics return false; bool receivedMagicDamage = false; + bool godmode = actor == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); switch (effectKey.mId) { case ESM::MagicEffect::DamageAttribute: { + if (godmode) + break; AttributeValue attr = creatureStats.getAttribute(effectKey.mArg); attr.damage(magnitude); creatureStats.setAttribute(effectKey.mArg, attr); @@ -91,6 +94,8 @@ namespace MWMechanics adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::RestoreHealth, magnitude); break; case ESM::MagicEffect::DamageHealth: + if (godmode) + break; receivedMagicDamage = true; adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::DamageHealth, -magnitude); break; @@ -98,25 +103,32 @@ namespace MWMechanics case ESM::MagicEffect::DamageMagicka: case ESM::MagicEffect::DamageFatigue: { + if (godmode) + break; int index = effectKey.mId-ESM::MagicEffect::DamageHealth; static const bool uncappedDamageFatigue = Settings::Manager::getBool("uncapped damage fatigue", "Game"); adjustDynamicStat(creatureStats, index, -magnitude, index == 2 && uncappedDamageFatigue); break; } case ESM::MagicEffect::AbsorbHealth: - if (magnitude > 0.f) - receivedMagicDamage = true; - adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude); - + if (!godmode || magnitude <= 0) + { + if (magnitude > 0.f) + receivedMagicDamage = true; + adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude); + } break; case ESM::MagicEffect::AbsorbMagicka: case ESM::MagicEffect::AbsorbFatigue: - adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude); + if (!godmode || magnitude <= 0) + adjustDynamicStat(creatureStats, effectKey.mId-ESM::MagicEffect::AbsorbHealth, -magnitude); break; case ESM::MagicEffect::DisintegrateArmor: { + if (godmode) + break; static const std::array priorities { MWWorld::InventoryStore::Slot_CarriedLeft, @@ -138,13 +150,14 @@ namespace MWMechanics break; } case ESM::MagicEffect::DisintegrateWeapon: - disintegrateSlot(actor, MWWorld::InventoryStore::Slot_CarriedRight, magnitude); + if (!godmode) + disintegrateSlot(actor, MWWorld::InventoryStore::Slot_CarriedRight, magnitude); break; case ESM::MagicEffect::SunDamage: { // isInCell shouldn't be needed, but updateActor called during game start - if (!actor.isInCell() || !actor.getCell()->isExterior()) + if (!actor.isInCell() || !actor.getCell()->isExterior() || godmode) break; float time = MWBase::Environment::get().getWorld()->getTimeStamp().getHour(); float timeDiff = std::min(7.f, std::max(0.f, std::abs(time - 13))); @@ -169,6 +182,8 @@ namespace MWMechanics case ESM::MagicEffect::FrostDamage: case ESM::MagicEffect::Poison: { + if (godmode) + break; adjustDynamicStat(creatureStats, 0, -magnitude); receivedMagicDamage = true; break; @@ -179,6 +194,8 @@ namespace MWMechanics { if (!actor.getClass().isNpc()) break; + if (godmode && effectKey.mId == ESM::MagicEffect::DamageSkill) + break; NpcStats &npcStats = actor.getClass().getNpcStats(actor); SkillValue& skill = npcStats.getSkill(effectKey.mArg); if (effectKey.mId == ESM::MagicEffect::RestoreSkill) diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 2b157f18a..66ae4e319 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -230,7 +230,8 @@ namespace MWWorld MWWorld::Ptr player = getPlayer(); const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player); - if (playerStats.isParalyzed() || playerStats.getKnockedDown() || playerStats.isDead()) + bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); + if ((!godmode && playerStats.isParalyzed()) || playerStats.getKnockedDown() || playerStats.isDead()) return; MWWorld::Ptr toActivate = MWBase::Environment::get().getWorld()->getFacedObject(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 265a7663c..127fbb45a 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1863,10 +1863,13 @@ namespace MWWorld else mRendering->getCamera()->setSneakOffset(0.f); - int blind = static_cast(player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).getMagnitude()); + int blind = 0; + auto& magicEffects = player.getClass().getCreatureStats(player).getMagicEffects(); + if (!mGodMode) + blind = static_cast(magicEffects.get(ESM::MagicEffect::Blind).getMagnitude()); MWBase::Environment::get().getWindowManager()->setBlindness(std::max(0, std::min(100, blind))); - int nightEye = static_cast(player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye).getMagnitude()); + int nightEye = static_cast(magicEffects.get(ESM::MagicEffect::NightEye).getMagnitude()); mRendering->setNightEyeFactor(std::min(1.f, (nightEye/100.f))); } From b85875a3542d152e7b9f719f697b771af12d336a Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Fri, 9 Oct 2020 21:30:24 +0300 Subject: [PATCH 173/224] Ignore Burden effect in god mode --- apps/openmw/mwclass/actor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 61d6e7347..33aeb26bb 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -6,6 +6,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/movement.hpp" #include "../mwmechanics/magiceffects.hpp" @@ -79,7 +80,8 @@ namespace MWClass float weight = getContainerStore(ptr).getWeight(); const MWMechanics::MagicEffects& effects = getCreatureStats(ptr).getMagicEffects(); weight -= effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Feather)).getMagnitude(); - weight += effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).getMagnitude(); + if (ptr != MWMechanics::getPlayer() || !MWBase::Environment::get().getWorld()->getGodModeState()) + weight += effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).getMagnitude(); return (weight < 0) ? 0.0f : weight; } From c6eb0dacd367d53035ee19374b0c2a2b95f68ece Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 9 Oct 2020 20:51:25 +0000 Subject: [PATCH 174/224] Bump Debian cache version numbers This should stop MR builds clobbering the increased size with their tiny size. --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fb4263ee2..75488b6b1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,7 +32,7 @@ stages: Debian_GCC: extends: .Debian cache: - key: Debian_GCC.v1 + key: Debian_GCC.v2 variables: CC: gcc CXX: g++ @@ -41,7 +41,7 @@ Debian_GCC: Debian_GCC_tests: extends: .Debian cache: - key: Debian_GCC_tests.v1 + key: Debian_GCC_tests.v2 variables: CC: gcc CXX: g++ @@ -51,7 +51,7 @@ Debian_GCC_tests: Debian_Clang: extends: .Debian cache: - key: Debian_Clang.v1 + key: Debian_Clang.v2 variables: CC: clang CXX: clang++ @@ -60,7 +60,7 @@ Debian_Clang: Debian_Clang_tests: extends: .Debian cache: - key: Debian_Clang_tests.v1 + key: Debian_Clang_tests.v2 variables: CC: clang CXX: clang++ From 460e69e92a74f2c2ebab9cf03e40e106afb8b6a2 Mon Sep 17 00:00:00 2001 From: fredzio Date: Sat, 10 Oct 2020 12:08:27 +0200 Subject: [PATCH 175/224] Get rid of warning: dynamic exception specifications are deprecated --- components/compiler/exception.hpp | 14 +++++++------- components/detournavigator/asyncnavmeshupdater.cpp | 2 +- components/detournavigator/asyncnavmeshupdater.hpp | 2 +- components/detournavigator/objectid.hpp | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/components/compiler/exception.hpp b/components/compiler/exception.hpp index 33bad7590..f21f2e586 100644 --- a/components/compiler/exception.hpp +++ b/components/compiler/exception.hpp @@ -10,8 +10,8 @@ namespace Compiler class SourceException : public std::exception { public: - - virtual const char *what() const throw() { return "Compile error";} + + const char *what() const noexcept override { return "Compile error";} ///< Return error message }; @@ -20,18 +20,18 @@ namespace Compiler class FileException : public SourceException { public: - - virtual const char *what() const throw() { return "Can't read file"; } + + const char *what() const noexcept final { return "Can't read file"; } ///< Return error message }; /// \brief Exception: EOF condition encountered class EOFException : public SourceException - { + { public: - - virtual const char *what() const throw() { return "End of file"; } + + const char *what() const noexcept final { return "End of file"; } ///< Return error message }; } diff --git a/components/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 0683a43bc..6279d68b7 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -126,7 +126,7 @@ namespace DetourNavigator mNavMeshTilesCache.reportStats(frameNumber, stats); } - void AsyncNavMeshUpdater::process() throw() + void AsyncNavMeshUpdater::process() noexcept { Log(Debug::Debug) << "Start process navigator jobs by thread=" << std::this_thread::get_id(); while (!mShouldStop) diff --git a/components/detournavigator/asyncnavmeshupdater.hpp b/components/detournavigator/asyncnavmeshupdater.hpp index 4debcd6cd..26f886512 100644 --- a/components/detournavigator/asyncnavmeshupdater.hpp +++ b/components/detournavigator/asyncnavmeshupdater.hpp @@ -113,7 +113,7 @@ namespace DetourNavigator std::map mThreadsQueues; std::vector mThreads; - void process() throw(); + void process() noexcept; bool processJob(const Job& job); diff --git a/components/detournavigator/objectid.hpp b/components/detournavigator/objectid.hpp index 6ddcc9169..9c4b5b271 100644 --- a/components/detournavigator/objectid.hpp +++ b/components/detournavigator/objectid.hpp @@ -10,22 +10,22 @@ namespace DetourNavigator { public: template - explicit ObjectId(T* value) throw() + explicit ObjectId(T* value) noexcept : mValue(reinterpret_cast(value)) { } - std::size_t value() const throw() + std::size_t value() const noexcept { return mValue; } - friend bool operator <(const ObjectId lhs, const ObjectId rhs) throw() + friend bool operator <(const ObjectId lhs, const ObjectId rhs) noexcept { return lhs.mValue < rhs.mValue; } - friend bool operator ==(const ObjectId lhs, const ObjectId rhs) throw() + friend bool operator ==(const ObjectId lhs, const ObjectId rhs) noexcept { return lhs.mValue == rhs.mValue; } @@ -40,7 +40,7 @@ namespace std template <> struct hash { - std::size_t operator ()(const DetourNavigator::ObjectId value) const throw() + std::size_t operator ()(const DetourNavigator::ObjectId value) const noexcept { return value.value(); } From 1842f546c3fca214828ada0bd7fe147692de5442 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sat, 10 Oct 2020 14:27:52 +0300 Subject: [PATCH 176/224] Restore empty target check in spell absorption --- apps/openmw/mwmechanics/spellabsorption.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/spellabsorption.cpp b/apps/openmw/mwmechanics/spellabsorption.cpp index 71e1d0aee..74df66780 100644 --- a/apps/openmw/mwmechanics/spellabsorption.cpp +++ b/apps/openmw/mwmechanics/spellabsorption.cpp @@ -46,7 +46,7 @@ namespace MWMechanics bool absorbSpell (const std::string& spellId, const MWWorld::Ptr& caster, const MWWorld::Ptr& target) { - if (spellId.empty() || caster == target || !target.getClass().isActor()) + if (spellId.empty() || target.isEmpty() || caster == target || !target.getClass().isActor()) return false; CreatureStats& stats = target.getClass().getCreatureStats(target); From 15078f5b3c0ca8c02989462662aec468993cdeff Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 10 Oct 2020 23:06:43 +0200 Subject: [PATCH 177/224] Fix #5630 "NPCs momentarily turn when the player character is moving backwards during combat" --- apps/openmw/mwmechanics/aicombat.cpp | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index cbe161af1..b98d5ef49 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -240,24 +240,24 @@ namespace MWMechanics storage.mReadyToAttack = (currentAction->isAttackingOrSpell() && distToTarget <= rangeAttack && storage.mLOS); + if (isRangedCombat) + { + // rotate actor taking into account target movement direction and projectile speed + osg::Vec3f& lastTargetPos = storage.mLastTargetPos; + vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, AI_REACTION_TIME, (weapon ? weapon->mData.mType : 0), storage.mStrength); + lastTargetPos = vTargetPos; + + storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); + storage.mMovement.mRotation[2] = getZAngleToDir(vAimDir); + } + else + { + storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); + storage.mMovement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos)); // using vAimDir results in spastic movements since the head is animated + } + if (storage.mReadyToAttack) { - if (isRangedCombat) - { - // rotate actor taking into account target movement direction and projectile speed - osg::Vec3f& lastTargetPos = storage.mLastTargetPos; - vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, AI_REACTION_TIME, (weapon ? weapon->mData.mType : 0), storage.mStrength); - lastTargetPos = vTargetPos; - - storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); - storage.mMovement.mRotation[2] = getZAngleToDir(vAimDir); - } - else - { - storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); - storage.mMovement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos)); // using vAimDir results in spastic movements since the head is animated - } - storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target); // start new attack storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat); From 3cadc16f88ed010afdf9fac1adadc7aabbbcc484 Mon Sep 17 00:00:00 2001 From: fredzio Date: Tue, 13 Oct 2020 09:59:02 +0200 Subject: [PATCH 178/224] Convert components to an OBJECT library. It saves space in the object directory (about 1G on an optimized build on Windows and BSD). Build should run somewhat fast as well. --- components/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7f44cf6fb..6e0f4a65f 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -212,7 +212,7 @@ endif () include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) -add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) +add_library(components OBJECT ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) target_link_libraries(components ${Boost_SYSTEM_LIBRARY} From 72549651e0b3afcbf2a481b8db2731281b760e41 Mon Sep 17 00:00:00 2001 From: Assumeru Date: Tue, 13 Oct 2020 17:46:32 +0200 Subject: [PATCH 179/224] Rework container resolution (#3006) * Rework container resolution * add optional argument to getCount * remove now-redundant changes * undo worldimp changes * move save-fixing code to InventoryState * replace Rng instances with Seeds --- CHANGELOG.md | 3 + apps/openmw/mwclass/container.cpp | 83 ++---- apps/openmw/mwclass/container.hpp | 25 +- apps/openmw/mwclass/creature.cpp | 8 - apps/openmw/mwclass/creature.hpp | 2 - apps/openmw/mwclass/npc.cpp | 8 - apps/openmw/mwclass/npc.hpp | 2 - apps/openmw/mwgui/container.cpp | 1 + apps/openmw/mwgui/containeritemmodel.cpp | 49 +-- apps/openmw/mwgui/containeritemmodel.hpp | 9 +- apps/openmw/mwgui/tradeitemmodel.cpp | 2 +- apps/openmw/mwgui/tradeitemmodel.hpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 35 +-- apps/openmw/mwgui/tradewindow.hpp | 3 +- apps/openmw/mwmechanics/levelledlist.hpp | 10 +- .../mwmechanics/mechanicsmanagerimp.cpp | 3 +- apps/openmw/mwworld/actionharvest.cpp | 1 + apps/openmw/mwworld/cellstore.cpp | 3 +- apps/openmw/mwworld/class.hpp | 2 - apps/openmw/mwworld/containerstore.cpp | 278 +++++++++--------- apps/openmw/mwworld/containerstore.hpp | 63 +++- apps/openmw/mwworld/inventorystore.cpp | 9 +- apps/openmw/mwworld/localscripts.cpp | 2 +- apps/openmw/mwworld/refdata.cpp | 4 +- apps/openmw/mwworld/refdata.hpp | 2 +- .../findrandompointaroundcircle.cpp | 2 +- components/esm/inventorystate.cpp | 15 + components/esm/savedgame.cpp | 2 +- components/misc/rng.cpp | 31 +- components/misc/rng.hpp | 20 +- 30 files changed, 371 insertions(+), 308 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9813cabff..80253e99c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,11 @@ Bug #1952: Incorrect particle lighting Bug #2069: Fireflies in Fireflies invade Morrowind look wrong Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs + Bug #2473: Unable to overstock merchants Bug #3676: NiParticleColorModifier isn't applied properly Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects + Bug #3862: Random container contents behave differently than vanilla + Bug #3929: Leveled list merchant containers respawn on barter Bug #4021: Attributes and skills are not stored as floats Bug #4055: Local scripts don't inherit variables from their base record Bug #4623: Corprus implementation is incorrect diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index b4b068c91..807f2299b 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -31,44 +31,41 @@ namespace MWClass { - class ContainerCustomData : public MWWorld::CustomData + ContainerCustomData::ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell) { - public: - MWWorld::ContainerStore mContainerStore; + unsigned int seed = Misc::Rng::rollDice(std::numeric_limits::max()); + // setting ownership not needed, since taking items from a container inherits the + // container's owner automatically + mStore.fillNonRandom(container.mInventory, "", seed); + } - virtual MWWorld::CustomData *clone() const; - - virtual ContainerCustomData& asContainerCustomData() - { - return *this; - } - virtual const ContainerCustomData& asContainerCustomData() const - { - return *this; - } - }; + ContainerCustomData::ContainerCustomData(const ESM::InventoryState& inventory) + { + mStore.readState(inventory); + } MWWorld::CustomData *ContainerCustomData::clone() const { return new ContainerCustomData (*this); } + ContainerCustomData& ContainerCustomData::asContainerCustomData() + { + return *this; + } + const ContainerCustomData& ContainerCustomData::asContainerCustomData() const + { + return *this; + } + void Container::ensureCustomData (const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) { - std::unique_ptr data (new ContainerCustomData); - - MWWorld::LiveCellRef *ref = - ptr.get(); - - // setting ownership not needed, since taking items from a container inherits the - // container's owner automatically - data->mContainerStore.fill( - ref->mBase->mInventory, ""); + MWWorld::LiveCellRef *ref = ptr.get(); // store - ptr.getRefData().setCustomData (data.release()); + ptr.getRefData().setCustomData (std::make_unique(*ref->mBase, ptr.getCell()).release()); MWBase::Environment::get().getWorld()->addContainerScripts(ptr, ptr.getCell()); } @@ -98,17 +95,6 @@ namespace MWClass } } - void Container::restock(const MWWorld::Ptr& ptr) const - { - MWWorld::LiveCellRef *ref = ptr.get(); - const ESM::InventoryList& list = ref->mBase->mInventory; - MWWorld::ContainerStore& store = getContainerStore(ptr); - - // setting ownership not needed, since taking items from a container inherits the - // container's owner automatically - store.restock(list, ptr, ""); - } - void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { if (!model.empty()) { @@ -228,12 +214,12 @@ namespace MWClass return !name.empty() ? name : ref->mBase->mId; } - MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr) - const + MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr) const { ensureCustomData (ptr); - - return ptr.getRefData().getCustomData()->asContainerCustomData().mContainerStore; + auto& data = ptr.getRefData().getCustomData()->asContainerCustomData(); + data.mStore.mPtr = ptr; + return data.mStore; } std::string Container::getScript (const MWWorld::ConstPtr& ptr) const @@ -253,8 +239,7 @@ namespace MWClass bool Container::hasToolTip (const MWWorld::ConstPtr& ptr) const { if (const MWWorld::CustomData* data = ptr.getRefData().getCustomData()) - return !canBeHarvested(ptr) || data->asContainerCustomData().mContainerStore.hasVisibleItems(); - + return !canBeHarvested(ptr) || data->asContainerCustomData().mStore.hasVisibleItems(); return true; } @@ -317,28 +302,20 @@ namespace MWClass if (!state.mHasCustomState) return; - if (!ptr.getRefData().getCustomData()) - { - // Create a CustomData, but don't fill it from ESM records (not needed) - std::unique_ptr data (new ContainerCustomData); - ptr.getRefData().setCustomData (data.release()); - } - - ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); const ESM::ContainerState& containerState = state.asContainerState(); - customData.mContainerStore.readState (containerState.mInventory); + ptr.getRefData().setCustomData(std::make_unique(containerState.mInventory).release()); } void Container::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { - if (!ptr.getRefData().getCustomData()) + const ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); + if (!ptr.getRefData().getCustomData() || !customData.mStore.isResolved()) { state.mHasCustomState = false; return; } - const ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); ESM::ContainerState& containerState = state.asContainerState(); - customData.mContainerStore.writeState (containerState.mInventory); + customData.mStore.writeState (containerState.mInventory); } } diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index b84c5787b..0ee549f81 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -2,9 +2,32 @@ #define GAME_MWCLASS_CONTAINER_H #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" +#include "../mwworld/customdata.hpp" + +namespace ESM +{ + struct Container; + struct InventoryState; +} namespace MWClass { + class ContainerCustomData : public MWWorld::CustomData + { + MWWorld::ContainerStore mStore; + public: + ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell); + ContainerCustomData(const ESM::InventoryState& inventory); + + virtual MWWorld::CustomData *clone() const; + + virtual ContainerCustomData& asContainerCustomData(); + virtual const ContainerCustomData& asContainerCustomData() const; + + friend class Container; + }; + class Container : public MWWorld::Class { void ensureCustomData (const MWWorld::Ptr& ptr) const; @@ -60,8 +83,6 @@ namespace MWClass virtual void respawn (const MWWorld::Ptr& ptr) const; - virtual void restock (const MWWorld::Ptr &ptr) const; - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; virtual bool useAnim() const; diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 5c5524a12..8e67498a1 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -842,14 +842,6 @@ namespace MWClass } } - void Creature::restock(const MWWorld::Ptr& ptr) const - { - MWWorld::LiveCellRef *ref = ptr.get(); - const ESM::InventoryList& list = ref->mBase->mInventory; - MWWorld::ContainerStore& store = getContainerStore(ptr); - store.restock(list, ptr, ptr.getCellRef().getRefId()); - } - int Creature::getBaseFightRating(const MWWorld::ConstPtr &ptr) const { const MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index ca991052b..21d25633a 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -123,8 +123,6 @@ namespace MWClass virtual void respawn (const MWWorld::Ptr& ptr) const; - virtual void restock (const MWWorld::Ptr &ptr) const; - virtual int getBaseFightRating(const MWWorld::ConstPtr &ptr) const; virtual void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index f4a711432..0187f2727 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1401,14 +1401,6 @@ namespace MWClass } } - void Npc::restock(const MWWorld::Ptr& ptr) const - { - MWWorld::LiveCellRef *ref = ptr.get(); - const ESM::InventoryList& list = ref->mBase->mInventory; - MWWorld::ContainerStore& store = getContainerStore(ptr); - store.restock(list, ptr, ptr.getCellRef().getRefId()); - } - int Npc::getBaseFightRating (const MWWorld::ConstPtr& ptr) const { const MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 1ed4e8cae..43340b8d7 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -158,8 +158,6 @@ namespace MWClass virtual void respawn (const MWWorld::Ptr& ptr) const; - virtual void restock (const MWWorld::Ptr& ptr) const; - virtual int getBaseFightRating (const MWWorld::ConstPtr& ptr) const; virtual std::string getPrimaryFaction(const MWWorld::ConstPtr &ptr) const; diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index a68fddca1..810a369d8 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -168,6 +168,7 @@ namespace MWGui if (!mPtr.isEmpty()) MWBase::Environment::get().getMechanicsManager()->onClose(mPtr); + resetReference(); } void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index 0cfa6ebf5..31439f349 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -39,22 +39,29 @@ namespace namespace MWGui { - ContainerItemModel::ContainerItemModel(const std::vector& itemSources, const std::vector& worldItems) - : mItemSources(itemSources) - , mWorldItems(worldItems) + : mWorldItems(worldItems) + , mTrading(true) { - assert (!mItemSources.empty()); + assert (!itemSources.empty()); + // Tie resolution lifetimes to the ItemModel + mItemSources.reserve(itemSources.size()); + for(const MWWorld::Ptr& source : itemSources) + { + MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); + mItemSources.push_back(std::make_pair(source, store.resolveTemporarily())); + } } -ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source) +ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source) : mTrading(false) { - mItemSources.push_back(source); + MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); + mItemSources.push_back(std::make_pair(source, store.resolveTemporarily())); } bool ContainerItemModel::allowedToUseItems() const { - if (mItemSources.size() == 0) + if (mItemSources.empty()) return true; MWWorld::Ptr ptr = MWMechanics::getPlayer(); @@ -62,7 +69,7 @@ bool ContainerItemModel::allowedToUseItems() const // Check if the player is allowed to use items from opened container MWBase::MechanicsManager* mm = MWBase::Environment::get().getMechanicsManager(); - return mm->isAllowedToUse(ptr, mItemSources[0], victim); + return mm->isAllowedToUse(ptr, mItemSources[0].first, victim); } ItemStack ContainerItemModel::getItem (ModelIndex index) @@ -93,25 +100,31 @@ ItemModel::ModelIndex ContainerItemModel::getIndex (ItemStack item) MWWorld::Ptr ContainerItemModel::copyItem (const ItemStack& item, size_t count, bool allowAutoEquip) { - const MWWorld::Ptr& source = mItemSources[mItemSources.size()-1]; - if (item.mBase.getContainerStore() == &source.getClass().getContainerStore(source)) + auto& source = mItemSources[0]; + MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); + if (item.mBase.getContainerStore() == &store) throw std::runtime_error("Item to copy needs to be from a different container!"); - return *source.getClass().getContainerStore(source).add(item.mBase, count, source, allowAutoEquip); + return *store.add(item.mBase, count, source.first, allowAutoEquip); } void ContainerItemModel::removeItem (const ItemStack& item, size_t count) { int toRemove = count; - for (MWWorld::Ptr& source : mItemSources) + for (auto& source : mItemSources) { - MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); + MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { if (stacks(*it, item.mBase)) { - toRemove -= store.remove(*it, toRemove, source); + int quantity = it->mRef->mData.getCount(false); + // If this is a restocking quantity, just don't remove it + if(quantity < 0 && mTrading) + toRemove += quantity; + else + toRemove -= store.remove(*it, toRemove, source.first); if (toRemove <= 0) return; } @@ -138,9 +151,9 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count) void ContainerItemModel::update() { mItems.clear(); - for (MWWorld::Ptr& source : mItemSources) + for (auto& source : mItemSources) { - MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); + MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { @@ -194,7 +207,7 @@ bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count) if (mItemSources.empty()) return false; - MWWorld::Ptr target = mItemSources[0]; + MWWorld::Ptr target = mItemSources[0].first; if (target.getTypeName() != typeid(ESM::Container).name()) return true; @@ -224,7 +237,7 @@ bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) if (mItemSources.empty()) return false; - MWWorld::Ptr target = mItemSources[0]; + MWWorld::Ptr target = mItemSources[0].first; // Looting a dead corpse is considered OK if (target.getClass().isActor() && target.getClass().getCreatureStats(target).isDead()) diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index 806cc0a73..d09bd7def 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -1,8 +1,13 @@ #ifndef MWGUI_CONTAINER_ITEM_MODEL_H #define MWGUI_CONTAINER_ITEM_MODEL_H +#include +#include + #include "itemmodel.hpp" +#include "../mwworld/containerstore.hpp" + namespace MWGui { @@ -32,9 +37,9 @@ namespace MWGui virtual void update(); private: - std::vector mItemSources; + std::vector> mItemSources; std::vector mWorldItems; - + const bool mTrading; std::vector mItems; }; diff --git a/apps/openmw/mwgui/tradeitemmodel.cpp b/apps/openmw/mwgui/tradeitemmodel.cpp index b1bab32dc..f5144ba81 100644 --- a/apps/openmw/mwgui/tradeitemmodel.cpp +++ b/apps/openmw/mwgui/tradeitemmodel.cpp @@ -119,7 +119,7 @@ namespace MWGui mBorrowedToUs.clear(); } - std::vector TradeItemModel::getItemsBorrowedToUs() + const std::vector TradeItemModel::getItemsBorrowedToUs() const { return mBorrowedToUs; } diff --git a/apps/openmw/mwgui/tradeitemmodel.hpp b/apps/openmw/mwgui/tradeitemmodel.hpp index cdb949c49..e349c225a 100644 --- a/apps/openmw/mwgui/tradeitemmodel.hpp +++ b/apps/openmw/mwgui/tradeitemmodel.hpp @@ -40,7 +40,7 @@ namespace MWGui /// and removing weight for items we've lent to someone else. void adjustEncumbrance (float& encumbrance); - std::vector getItemsBorrowedToUs(); + const std::vector getItemsBorrowedToUs() const; private: void borrowImpl(const ItemStack& item, std::vector& out); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 672ccbd06..e7dbd4447 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -99,20 +99,6 @@ namespace MWGui setCoord(400, 0, 400, 300); } - void TradeWindow::restock() - { - // Restock items on the actor inventory - mPtr.getClass().restock(mPtr); - - // Also restock any containers owned by this merchant, which are also available to buy in the trade window - std::vector itemSources; - MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources); - for (MWWorld::Ptr& source : itemSources) - { - source.getClass().restock(source); - } - } - void TradeWindow::setPtr(const MWWorld::Ptr& actor) { mPtr = actor; @@ -121,10 +107,10 @@ namespace MWGui mCurrentMerchantOffer = 0; std::vector itemSources; + // Important: actor goes first, so purchased items come out of the actor's pocket first + itemSources.push_back(actor); MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources); - // Important: actor goes last, so that items purchased by the merchant go into his inventory - itemSources.push_back(actor); std::vector worldItems; MWBase::Environment::get().getWorld()->getItemsOwnedBy(actor, worldItems); @@ -281,8 +267,8 @@ namespace MWGui MWBase::Environment::get().getWorld()->getStore().get(); // were there any items traded at all? - std::vector playerBought = playerItemModel->getItemsBorrowedToUs(); - std::vector merchantBought = mTradeModel->getItemsBorrowedToUs(); + const std::vector& playerBought = playerItemModel->getItemsBorrowedToUs(); + const std::vector& merchantBought = mTradeModel->getItemsBorrowedToUs(); if (playerBought.empty() && merchantBought.empty()) { // user notification @@ -313,7 +299,7 @@ namespace MWGui } // check if the player is attempting to sell back an item stolen from this actor - for (ItemStack& itemStack : merchantBought) + for (const ItemStack& itemStack : merchantBought) { if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(itemStack.mBase.getCellRef().getRefId(), mPtr)) { @@ -363,8 +349,6 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->playSound("Item Gold Up"); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Barter); - - restock(); } void TradeWindow::onAccept(MyGUI::EditBox *sender) @@ -478,7 +462,7 @@ namespace MWGui // connected to buying and selling the same item. // This value has been determined by researching the limitations of the vanilla formula // and may not be sufficient if getBarterOffer behavior has been changed. - std::vector playerBorrowed = playerTradeModel->getItemsBorrowedToUs(); + const std::vector& playerBorrowed = playerTradeModel->getItemsBorrowedToUs(); for (const ItemStack& itemStack : playerBorrowed) { const int basePrice = getEffectiveValue(itemStack.mBase, itemStack.mCount); @@ -487,7 +471,7 @@ namespace MWGui merchantOffer -= std::max(cap, buyingPrice); } - std::vector merchantBorrowed = mTradeModel->getItemsBorrowedToUs(); + const std::vector& merchantBorrowed = mTradeModel->getItemsBorrowedToUs(); for (const ItemStack& itemStack : merchantBorrowed) { const int basePrice = getEffectiveValue(itemStack.mBase, itemStack.mCount); @@ -532,4 +516,9 @@ namespace MWGui mTradeModel = nullptr; mSortModel = nullptr; } + + void TradeWindow::onClose() + { + resetReference(); + } } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 0730df04f..b211c6d09 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -29,6 +29,7 @@ namespace MWGui void setPtr(const MWWorld::Ptr& actor); + virtual void onClose() override; void onFrame(float dt); void clear() { resetReference(); } @@ -111,8 +112,6 @@ namespace MWGui virtual void onReferenceUnavailable(); int getMerchantGold(); - - void restock(); }; } diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index f716f068d..c8368101a 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -19,14 +19,14 @@ namespace MWMechanics { /// @return ID of resulting item, or empty if none - inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature) + inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Seed& seed = Misc::Rng::getSeed()) { const std::vector& items = levItem->mList; const MWWorld::Ptr& player = getPlayer(); int playerLevel = player.getClass().getCreatureStats(player).getLevel(); - if (Misc::Rng::roll0to99() < levItem->mChanceNone) + if (Misc::Rng::roll0to99(seed) < levItem->mChanceNone) return std::string(); std::vector candidates; @@ -55,7 +55,7 @@ namespace MWMechanics } if (candidates.empty()) return std::string(); - std::string item = candidates[Misc::Rng::rollDice(candidates.size())]; + std::string item = candidates[Misc::Rng::rollDice(candidates.size(), seed)]; // Vanilla doesn't fail on nonexistent items in levelled lists if (!MWBase::Environment::get().getWorld()->getStore().find(Misc::StringUtils::lowerCase(item))) @@ -74,9 +74,9 @@ namespace MWMechanics else { if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name()) - return getLevelledItem(ref.getPtr().get()->mBase, false); + return getLevelledItem(ref.getPtr().get()->mBase, false, seed); else - return getLevelledItem(ref.getPtr().get()->mBase, true); + return getLevelledItem(ref.getPtr().get()->mBase, true, seed); } } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 466a3bcc8..872a66799 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1045,6 +1045,7 @@ namespace MWMechanics void MechanicsManager::confiscateStolenItems(const MWWorld::Ptr &player, const MWWorld::Ptr &targetContainer) { MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); + MWWorld::ContainerStore& containerStore = targetContainer.getClass().getContainerStore(targetContainer); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { StolenItemsMap::iterator stolenIt = mStolenItems.find(Misc::StringUtils::lowerCase(it->getCellRef().getRefId())); @@ -1065,7 +1066,7 @@ namespace MWMechanics int toMove = it->getRefData().getCount() - itemCount; - targetContainer.getClass().getContainerStore(targetContainer).add(*it, toMove, targetContainer); + containerStore.add(*it, toMove, targetContainer); store.remove(*it, toMove, player); } // TODO: unhardcode the locklevel diff --git a/apps/openmw/mwworld/actionharvest.cpp b/apps/openmw/mwworld/actionharvest.cpp index ff35938b2..c9468c715 100644 --- a/apps/openmw/mwworld/actionharvest.cpp +++ b/apps/openmw/mwworld/actionharvest.cpp @@ -29,6 +29,7 @@ namespace MWWorld MWWorld::Ptr target = getTarget(); MWWorld::ContainerStore& store = target.getClass().getContainerStore (target); + store.resolve(); MWWorld::ContainerStore& actorStore = actor.getClass().getContainerStore(actor); std::map takenMap; for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 2cda83e17..14b96b27c 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -1030,7 +1030,8 @@ namespace MWWorld for (CellRefList::List::iterator it (mContainers.mList.begin()); it!=mContainers.mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); - if (!ptr.isEmpty() && ptr.getRefData().getCustomData() != nullptr && ptr.getRefData().getCount() > 0) + if (!ptr.isEmpty() && ptr.getRefData().getCustomData() != nullptr && ptr.getRefData().getCount() > 0 + && ptr.getClass().getContainerStore(ptr).isResolved()) { ptr.getClass().getContainerStore(ptr).rechargeItems(duration); } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 445f2e986..1b3d4029e 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -353,8 +353,6 @@ namespace MWWorld virtual void respawn (const MWWorld::Ptr& ptr) const {} - virtual void restock (const MWWorld::Ptr& ptr) const {} - /// Returns sound id virtual std::string getSound(const MWWorld::ConstPtr& ptr) const; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 6337ca440..5ecb3dd3a 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -23,6 +23,21 @@ namespace { + void addScripts(MWWorld::ContainerStore& store, MWWorld::CellStore* cell) + { + auto& scripts = MWBase::Environment::get().getWorld()->getLocalScripts(); + for(const MWWorld::Ptr& ptr : store) + { + const std::string& script = ptr.getClass().getScript(ptr); + if(!script.empty()) + { + MWWorld::Ptr item = ptr; + item.mCell = cell; + scripts.add(script, item); + } + } + } + template float getTotalWeight (const MWWorld::CellRefList& cellRefList) { @@ -44,6 +59,7 @@ namespace MWWorld::Ptr searchId (MWWorld::CellRefList& list, const std::string& id, MWWorld::ContainerStore *store) { + store->resolve(); std::string id2 = Misc::StringUtils::lowerCase (id); for (typename MWWorld::CellRefList::List::iterator iter (list.mList.begin()); @@ -61,6 +77,18 @@ namespace } } +MWWorld::ResolutionListener::~ResolutionListener() +{ + if(!mStore.mModified && mStore.mResolved && !mStore.mPtr.isEmpty()) + { + for(const MWWorld::Ptr& ptr : mStore) + ptr.getRefData().setCount(0); + mStore.fillNonRandom(mStore.mPtr.get()->mBase->mInventory, "", mStore.mSeed); + addScripts(mStore, mStore.mPtr.mCell); + mStore.mResolved = false; + } +} + template MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState (CellRefList& collection, const ESM::ObjectState& state) @@ -119,7 +147,11 @@ MWWorld::ContainerStore::ContainerStore() : mListener(nullptr) , mRechargingItemsUpToDate(false) , mCachedWeight (0) - , mWeightUpToDate (false) {} + , mWeightUpToDate (false) + , mModified(false) + , mResolved(false) + , mSeed() + , mPtr() {} MWWorld::ContainerStore::~ContainerStore() {} @@ -153,22 +185,12 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() return ContainerStoreIterator (this); } -int MWWorld::ContainerStore::count(const std::string &id) +int MWWorld::ContainerStore::count(const std::string &id) const { int total=0; - for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter) - if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), id)) - total += iter->getRefData().getCount(); - return total; -} - -int MWWorld::ContainerStore::restockCount(const std::string &id) -{ - int total=0; - for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter) - if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), id)) - if (iter->getCellRef().getSoul().empty()) - total += iter->getRefData().getCount(); + for (const auto& iter : *this) + if (Misc::StringUtils::ciEqual(iter.getCellRef().getRefId(), id)) + total += iter.getRefData().getCount(); return total; } @@ -185,9 +207,10 @@ void MWWorld::ContainerStore::setContListener(MWWorld::ContainerStoreListener* l MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container, int count) { + resolve(); if (ptr.getRefData().getCount() <= count) return end(); - MWWorld::ContainerStoreIterator it = addNewStack(ptr, ptr.getRefData().getCount()-count); + MWWorld::ContainerStoreIterator it = addNewStack(ptr, subtractItems(ptr.getRefData().getCount(false), count)); const std::string script = it->getClass().getScript(*it); if (!script.empty()) MWBase::Environment::get().getWorld()->getLocalScripts().add(script, *it); @@ -199,6 +222,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld::Ptr& item) { + resolve(); MWWorld::ContainerStoreIterator retval = end(); for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter) { @@ -216,7 +240,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld:: { if (stacks(*iter, item)) { - iter->getRefData().setCount(iter->getRefData().getCount() + item.getRefData().getCount()); + iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), item.getRefData().getCount(false))); item.getRefData().setCount(0); retval = iter; break; @@ -328,8 +352,10 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr return it; } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, int count) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, int count, bool markModified) { + if(markModified) + resolve(); int type = getType(ptr); const MWWorld::ESMStore &esmStore = @@ -345,7 +371,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, { if (Misc::StringUtils::ciEqual((*iter).getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) { - iter->getRefData().setCount(iter->getRefData().getCount() + realCount); + iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), realCount)); flagAsModified(); return iter; } @@ -361,7 +387,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, if (stacks(*iter, ptr)) { // stack - iter->getRefData().setCount( iter->getRefData().getCount() + count ); + iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), count)); flagAsModified(); return iter; @@ -439,6 +465,7 @@ void MWWorld::ContainerStore::updateRechargingItems() int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const Ptr& actor) { + resolve(); int toRemove = count; for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter) @@ -465,6 +492,7 @@ bool MWWorld::ContainerStore::hasVisibleItems() const int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor) { assert(this == item.getContainerStore()); + resolve(); int toRemove = count; RefData& itemRef = item.getRefData(); @@ -476,7 +504,7 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor } else { - itemRef.setCount(itemRef.getCount() - toRemove); + itemRef.setCount(subtractItems(itemRef.getCount(false), toRemove)); toRemove = 0; } @@ -490,20 +518,33 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor return count - toRemove; } -void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner) +void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Seed& seed) { - for (std::vector::const_iterator iter (items.mList.begin()); iter!=items.mList.end(); - ++iter) + for (const ESM::ContItem& iter : items.mList) { - std::string id = Misc::StringUtils::lowerCase(iter->mItem); - addInitialItem(id, owner, iter->mCount); + std::string id = Misc::StringUtils::lowerCase(iter.mItem); + addInitialItem(id, owner, iter.mCount, &seed); } flagAsModified(); + mResolved = true; } -void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, - int count, bool topLevel, const std::string& levItem) +void MWWorld::ContainerStore::fillNonRandom (const ESM::InventoryList& items, const std::string& owner, unsigned int seed) +{ + mSeed = seed; + for (const ESM::ContItem& iter : items.mList) + { + std::string id = Misc::StringUtils::lowerCase(iter.mItem); + addInitialItem(id, owner, iter.mCount, nullptr); + } + + flagAsModified(); + mResolved = false; +} + +void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count, + Misc::Rng::Seed* seed, bool topLevel, const std::string& levItem) { if (count == 0) return; //Don't restock with nothing. try @@ -511,13 +552,13 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count); if (ref.getPtr().getClass().getScript(ref.getPtr()).empty()) { - addInitialItemImp(ref.getPtr(), owner, count, topLevel, levItem); + addInitialItemImp(ref.getPtr(), owner, count, seed, topLevel, levItem); } else { // Adding just one item per time to make sure there isn't a stack of scripted items - for (int i = 0; i < abs(count); i++) - addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, topLevel, levItem); + for (int i = 0; i < std::abs(count); i++) + addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, seed, topLevel, levItem); } } catch (const std::exception& e) @@ -526,137 +567,43 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: } } -void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, - int count, bool topLevel, const std::string& levItem) +void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, int count, + Misc::Rng::Seed* seed, bool topLevel, const std::string& levItem) { if (ptr.getTypeName()==typeid (ESM::ItemLevList).name()) { + if(!seed) + return; const ESM::ItemLevList* levItemList = ptr.get()->mBase; if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each) { for (int i=0; i 0 ? 1 : -1, true, levItemList->mId); + addInitialItem(ptr.getCellRef().getRefId(), owner, count > 0 ? 1 : -1, seed, true, levItemList->mId); return; } else { - std::string itemId = MWMechanics::getLevelledItem(ptr.get()->mBase, false); + std::string itemId = MWMechanics::getLevelledItem(ptr.get()->mBase, false, *seed); if (itemId.empty()) return; - addInitialItem(itemId, owner, count, false, levItemList->mId); + addInitialItem(itemId, owner, count, seed, false, levItemList->mId); } } else { - // A negative count indicates restocking items - // For a restocking levelled item, remember what we spawned so we can delete it later when the merchant restocks - if (!levItem.empty() && count < 0) - { - //If there is no item in map, insert it - std::map, int>::iterator itemInMap = - mLevelledItemMap.insert(std::make_pair(std::make_pair(ptr.getCellRef().getRefId(), levItem), 0)).first; - //Update spawned count - itemInMap->second += std::abs(count); - } - count = std::abs(count); - ptr.getCellRef().setOwner(owner); - addImp (ptr, count); + addImp (ptr, count, false); } } -void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner) -{ - //allowedForReplace - Holds information about how many items from the list were not sold; - // Hence, tells us how many items we don't need to restock. - //allowedForReplace[list] <- How many items we should generate(how many of these were sold) - std::map allowedForReplace; - - //Check which lists need restocking: - for (std::map, int>::iterator it = mLevelledItemMap.begin(); it != mLevelledItemMap.end();) - { - int spawnedCount = it->second; //How many items should be in shop originally - int itemCount = restockCount(it->first.first); //How many items are there in shop now - //If something was not sold - if(itemCount >= spawnedCount) - { - const std::string& parent = it->first.second; - // Security check for old saves: - //If item is imported from old save(doesn't have an parent) and wasn't sold - if(parent == "") - { - //Remove it, from shop, - remove(it->first.first, itemCount, ptr);//ptr is the NPC - //And remove it from map, so that when we restock, the new item will have proper parent. - mLevelledItemMap.erase(it++); - continue; - } - //Create the entry if it does not exist yet - std::map::iterator listInMap = allowedForReplace.insert( - std::make_pair(it->first.second, 0)).first; - //And signal that we don't need to restock item from this list - listInMap->second += std::abs(itemCount); - } - //If every of the item was sold - else if (itemCount == 0) - { - mLevelledItemMap.erase(it++); - continue; - } - //If some was sold, but some remain - else - { - //Create entry if it does not exist yet - std::map::iterator listInMap = allowedForReplace.insert( - std::make_pair(it->first.second, 0)).first; - //And signal that we don't need to restock all items from this list - listInMap->second += std::abs(itemCount); - //And update itemCount so we don't mistake it next time. - it->second = itemCount; - } - ++it; - } - - //Restock: - //For every item that NPC could have - for (std::vector::const_iterator it = items.mList.begin(); it != items.mList.end(); ++it) - { - //If he shouldn't have it restocked, don't restock it. - if (it->mCount >= 0) - continue; - - std::string itemOrList = Misc::StringUtils::lowerCase(it->mItem); - - //If it's levelled list, restock if there's need to do so. - if (MWBase::Environment::get().getWorld()->getStore().get().search(it->mItem)) - { - std::map::iterator listInMap = allowedForReplace.find(itemOrList); - - int restockNum = std::abs(it->mCount); - //If we know we must restock less, take it into account - if(listInMap != allowedForReplace.end()) - restockNum -= std::min(restockNum, listInMap->second); - //restock - addInitialItem(itemOrList, owner, -restockNum, true); - } - else - { - //Restocking static item - just restock to the max count - int currentCount = restockCount(itemOrList); - if (currentCount < std::abs(it->mCount)) - addInitialItem(itemOrList, owner, -(std::abs(it->mCount) - currentCount), true); - } - } - flagAsModified(); -} - void MWWorld::ContainerStore::clear() { for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter) iter->getRefData().setCount (0); flagAsModified(); + mModified = true; } void MWWorld::ContainerStore::flagAsModified() @@ -665,6 +612,45 @@ void MWWorld::ContainerStore::flagAsModified() mRechargingItemsUpToDate = false; } +bool MWWorld::ContainerStore::isResolved() const +{ + return mResolved; +} + +void MWWorld::ContainerStore::resolve() +{ + if(!mResolved && !mPtr.isEmpty()) + { + for(const MWWorld::Ptr& ptr : *this) + ptr.getRefData().setCount(0); + Misc::Rng::Seed seed{mSeed}; + fill(mPtr.get()->mBase->mInventory, "", seed); + addScripts(*this, mPtr.mCell); + } + mModified = true; +} + +MWWorld::ResolutionHandle MWWorld::ContainerStore::resolveTemporarily() +{ + if(mModified) + return {}; + std::shared_ptr listener = mResolutionListener.lock(); + if(!listener) + { + listener = std::make_shared(*this); + mResolutionListener = listener; + } + if(!mResolved && !mPtr.isEmpty()) + { + for(const MWWorld::Ptr& ptr : *this) + ptr.getRefData().setCount(0); + Misc::Rng::Seed seed{mSeed}; + fill(mPtr.get()->mBase->mInventory, "", seed); + addScripts(*this, mPtr.mCell); + } + return {listener}; +} + float MWWorld::ContainerStore::getWeight() const { if (!mWeightUpToDate) @@ -761,6 +747,7 @@ MWWorld::Ptr MWWorld::ContainerStore::findReplacement(const std::string& id) MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id) { + resolve(); { Ptr ptr = searchId (potions, id, this); if (!ptr.isEmpty()) @@ -836,6 +823,22 @@ MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id) return Ptr(); } +int MWWorld::ContainerStore::addItems(int count1, int count2) +{ + int sum = std::abs(count1) + std::abs(count2); + if(count1 < 0 || count2 < 0) + return -sum; + return sum; +} + +int MWWorld::ContainerStore::subtractItems(int count1, int count2) +{ + int sum = std::abs(count1) - std::abs(count2); + if(count1 < 0 || count2 < 0) + return -sum; + return sum; +} + void MWWorld::ContainerStore::writeState (ESM::InventoryState& state) const { state.mItems.clear(); @@ -853,13 +856,13 @@ void MWWorld::ContainerStore::writeState (ESM::InventoryState& state) const storeStates (repairs, state, index); storeStates (weapons, state, index, true); storeStates (lights, state, index, true); - - state.mLevelledItemMap = mLevelledItemMap; } void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) { clear(); + mModified = true; + mResolved = true; int index = 0; for (std::vector::const_iterator @@ -893,9 +896,6 @@ void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) break; } } - - - mLevelledItemMap = inventory.mLevelledItemMap; } template diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index f2858c5aa..c89e855f9 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -18,6 +19,8 @@ #include #include +#include + #include "ptr.hpp" #include "cellreflist.hpp" @@ -27,6 +30,11 @@ namespace ESM struct InventoryState; } +namespace MWClass +{ + class Container; +} + namespace MWWorld { class ContainerStore; @@ -37,6 +45,21 @@ namespace MWWorld typedef ContainerStoreIteratorBase ContainerStoreIterator; typedef ContainerStoreIteratorBase ConstContainerStoreIterator; + class ResolutionListener + { + ContainerStore& mStore; + public: + ResolutionListener(ContainerStore& store) : mStore(store) {} + ~ResolutionListener(); + }; + + class ResolutionHandle + { + std::shared_ptr mListener; + public: + ResolutionHandle(std::shared_ptr listener) : mListener(listener) {} + ResolutionHandle() {} + }; class ContainerStoreListener { @@ -93,15 +116,18 @@ namespace MWWorld MWWorld::CellRefList repairs; MWWorld::CellRefList weapons; - std::map, int> mLevelledItemMap; - ///< Stores result of levelled item spawns. <(refId, spawningGroup), count> - /// This is used to restock levelled items(s) if the old item was sold. - mutable float mCachedWeight; mutable bool mWeightUpToDate; - ContainerStoreIterator addImp (const Ptr& ptr, int count); - void addInitialItem (const std::string& id, const std::string& owner, int count, bool topLevel=true, const std::string& levItem = ""); - void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, bool topLevel=true, const std::string& levItem = ""); + + bool mModified; + bool mResolved; + unsigned int mSeed; + MWWorld::Ptr mPtr; + std::weak_ptr mResolutionListener; + + ContainerStoreIterator addImp (const Ptr& ptr, int count, bool markModified = true); + void addInitialItem (const std::string& id, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true, const std::string& levItem = ""); + void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true, const std::string& levItem = ""); template ContainerStoreIterator getState (CellRefList& collection, @@ -175,31 +201,31 @@ namespace MWWorld /// If a compatible stack is found, the item's count is added to that stack, then the original is deleted. /// @return If the item was stacked, return the stack, otherwise return the old (untouched) item. - int count (const std::string& id); + int count (const std::string& id) const; ///< @return How many items with refID \a id are in this container? - int restockCount (const std::string& id); - ///< Item count with restock adjustments (such as ignoring filled soul gems). - /// @return How many items with refID \a id are in this container? - ContainerStoreListener* getContListener() const; void setContListener(ContainerStoreListener* listener); - protected: ContainerStoreIterator addNewStack (const ConstPtr& ptr, int count); ///< Add the item to this container (do not try to stack it onto existing items) virtual void flagAsModified(); + /// + and - operations that can deal with negative stacks + /// Note that negativity is infectious + static int addItems(int count1, int count2); + static int subtractItems(int count1, int count2); public: virtual bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const; ///< @return true if the two specified objects can stack with each other - void fill (const ESM::InventoryList& items, const std::string& owner); + void fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Seed& seed = Misc::Rng::getSeed()); ///< Insert items into *this. - void restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner); + void fillNonRandom (const ESM::InventoryList& items, const std::string& owner, unsigned int seed); + ///< Insert items into *this, excluding leveled items virtual void clear(); ///< Empty container. @@ -220,8 +246,15 @@ namespace MWWorld virtual void readState (const ESM::InventoryState& state); + bool isResolved() const; + + void resolve(); + ResolutionHandle resolveTemporarily(); + friend class ContainerStoreIteratorBase; friend class ContainerStoreIteratorBase; + friend class ResolutionListener; + friend class MWClass::Container; }; diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index d67a22884..cf2b97ce7 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -86,8 +86,9 @@ void MWWorld::InventoryStore::readEquipmentState(const MWWorld::ContainerStoreIt // unstack if required if (!allowedSlots.second && iter->getRefData().getCount() > 1) { - MWWorld::ContainerStoreIterator newIter = addNewStack(*iter, 1); - iter->getRefData().setCount(iter->getRefData().getCount()-1); + int count = iter->getRefData().getCount(false); + MWWorld::ContainerStoreIterator newIter = addNewStack(*iter, count > 0 ? 1 : -1); + iter->getRefData().setCount(subtractItems(count, 1)); mSlots[slot] = newIter; } else @@ -850,8 +851,8 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipItemQuantity(con { if (stacks(*iter, item) && !isEquipped(*iter)) { - iter->getRefData().setCount(iter->getRefData().getCount() + count); - item.getRefData().setCount(item.getRefData().getCount() - count); + iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), count)); + item.getRefData().setCount(subtractItems(item.getRefData().getCount(false), count)); return iter; } } diff --git a/apps/openmw/mwworld/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp index a727b4b3a..8a511030d 100644 --- a/apps/openmw/mwworld/localscripts.cpp +++ b/apps/openmw/mwworld/localscripts.cpp @@ -45,7 +45,7 @@ namespace // Ignore containers without generated content if (containerPtr.getTypeName() == typeid(ESM::Container).name() && containerPtr.getRefData().getCustomData() == nullptr) - return false; + return true; MWWorld::ContainerStore& container = containerPtr.getClass().getContainerStore(containerPtr); for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it) diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index f6fa3556f..a5f8ef4b1 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -146,8 +146,10 @@ namespace MWWorld return mBaseNode; } - int RefData::getCount() const + int RefData::getCount(bool absolute) const { + if(absolute) + return std::abs(mCount); return mCount; } diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 6a59d9797..738a6d53a 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -86,7 +86,7 @@ namespace MWWorld /// Set base node (can be a null pointer). void setBaseNode (SceneUtil::PositionAttitudeTransform* base); - int getCount() const; + int getCount(bool absolute = true) const; void setLocals (const ESM::Script& script); diff --git a/components/detournavigator/findrandompointaroundcircle.cpp b/components/detournavigator/findrandompointaroundcircle.cpp index 3888c59fe..263dba68e 100644 --- a/components/detournavigator/findrandompointaroundcircle.cpp +++ b/components/detournavigator/findrandompointaroundcircle.cpp @@ -36,7 +36,7 @@ namespace DetourNavigator dtPolyRef resultRef = 0; osg::Vec3f resultPosition; navMeshQuery.findRandomPointAroundCircle(startRef, start.ptr(), maxRadius, &queryFilter, - &Misc::Rng::rollProbability, &resultRef, resultPosition.ptr()); + []() { return Misc::Rng::rollProbability(); }, &resultRef, resultPosition.ptr()); if (resultRef == 0) return boost::optional(); diff --git a/components/esm/inventorystate.cpp b/components/esm/inventorystate.cpp index fe54762c5..2392d263f 100644 --- a/components/esm/inventorystate.cpp +++ b/components/esm/inventorystate.cpp @@ -3,6 +3,8 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +#include + void ESM::InventoryState::load (ESMReader &esm) { // obsolete @@ -106,6 +108,19 @@ void ESM::InventoryState::load (ESMReader &esm) mSelectedEnchantItem = -1; esm.getHNOT(mSelectedEnchantItem, "SELE"); + + // Old saves had restocking levelled items in a special map + // This turns items from that map into negative quantities + for(const auto& entry : mLevelledItemMap) + { + const std::string& id = entry.first.first; + const int count = entry.second; + for(auto& item : mItems) + { + if(item.mCount == count && Misc::StringUtils::ciEqual(id, item.mRef.mRefID)) + item.mCount = -count; + } + } } void ESM::InventoryState::save (ESMWriter &esm) const diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index 0fc84e309..9edcb1a67 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -4,7 +4,7 @@ #include "esmwriter.hpp" unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; -int ESM::SavedGame::sCurrentFormat = 14; +int ESM::SavedGame::sCurrentFormat = 15; void ESM::SavedGame::load (ESMReader &esm) { diff --git a/components/misc/rng.cpp b/components/misc/rng.cpp index 09279e85e..4189404b1 100644 --- a/components/misc/rng.cpp +++ b/components/misc/rng.cpp @@ -3,29 +3,44 @@ #include #include +namespace +{ + Misc::Rng::Seed sSeed; +} + namespace Misc { - std::mt19937 Rng::generator = std::mt19937(); + Rng::Seed::Seed() {} + + Rng::Seed::Seed(unsigned int seed) + { + mGenerator.seed(seed); + } + + Rng::Seed& Rng::getSeed() + { + return sSeed; + } void Rng::init(unsigned int seed) { - generator.seed(seed); + sSeed.mGenerator.seed(seed); } - float Rng::rollProbability() + float Rng::rollProbability(Seed& seed) { - return std::uniform_real_distribution(0, 1 - std::numeric_limits::epsilon())(generator); + return std::uniform_real_distribution(0, 1 - std::numeric_limits::epsilon())(sSeed.mGenerator); } - float Rng::rollClosedProbability() + float Rng::rollClosedProbability(Seed& seed) { - return std::uniform_real_distribution(0, 1)(generator); + return std::uniform_real_distribution(0, 1)(sSeed.mGenerator); } - int Rng::rollDice(int max) + int Rng::rollDice(int max, Seed& seed) { - return max > 0 ? std::uniform_int_distribution(0, max - 1)(generator) : 0; + return max > 0 ? std::uniform_int_distribution(0, max - 1)(sSeed.mGenerator) : 0; } unsigned int Rng::generateDefaultSeed() diff --git a/components/misc/rng.hpp b/components/misc/rng.hpp index 65a554cf2..8efca438d 100644 --- a/components/misc/rng.hpp +++ b/components/misc/rng.hpp @@ -13,24 +13,32 @@ namespace Misc class Rng { public: + class Seed + { + std::mt19937 mGenerator; + public: + Seed(); + Seed(const Seed&) = delete; + Seed(unsigned int seed); + friend class Rng; + }; - /// create a RNG - static std::mt19937 generator; + static Seed& getSeed(); /// seed the RNG static void init(unsigned int seed = generateDefaultSeed()); /// return value in range [0.0f, 1.0f) <- note open upper range. - static float rollProbability(); + static float rollProbability(Seed& seed = getSeed()); /// return value in range [0.0f, 1.0f] <- note closed upper range. - static float rollClosedProbability(); + static float rollClosedProbability(Seed& seed = getSeed()); /// return value in range [0, max) <- note open upper range. - static int rollDice(int max); + static int rollDice(int max, Seed& seed = getSeed()); /// return value in range [0, 99] - static int roll0to99() { return rollDice(100); } + static int roll0to99(Seed& seed = getSeed()) { return rollDice(100, seed); } /// returns default seed for RNG static unsigned int generateDefaultSeed(); From 4ea07639b87fc0787f55ec9717b4857f43e099c7 Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 14 Oct 2020 06:15:23 +0200 Subject: [PATCH 180/224] Unbreak build with cmake < 3.12 This reverts commit 3cadc16f88ed010afdf9fac1adadc7aabbbcc484. --- components/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 6e0f4a65f..7f44cf6fb 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -212,7 +212,7 @@ endif () include_directories(${BULLET_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) -add_library(components OBJECT ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) +add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS} ${ESM_UI_HDR}) target_link_libraries(components ${Boost_SYSTEM_LIBRARY} From 8e647aa72ae7e09eaa879039d8262a662de59f37 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 14 Oct 2020 09:16:01 +0400 Subject: [PATCH 181/224] Fix crash on saving --- apps/openmw/mwclass/container.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 807f2299b..9befa0636 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -308,8 +308,14 @@ namespace MWClass void Container::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { + if (!ptr.getRefData().getCustomData()) + { + state.mHasCustomState = false; + return; + } + const ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); - if (!ptr.getRefData().getCustomData() || !customData.mStore.isResolved()) + if (!customData.mStore.isResolved()) { state.mHasCustomState = false; return; From c3d84b2c7c8792c2d8c1687705905704ddf29149 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 9 Sep 2020 10:14:26 +0400 Subject: [PATCH 182/224] Ability to attach arrows to shooter's hands (feature #5642) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/weapontype.hpp | 2 +- apps/openmw/mwrender/creatureanimation.cpp | 14 +++-- apps/openmw/mwrender/npcanimation.cpp | 13 +++-- docs/source/reference/modding/extended.rst | 60 ++++++++++++---------- 5 files changed, 53 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80253e99c..51a9c7deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ Feature #5545: Option to allow stealing from an unconscious NPC during combat Feature #5579: MCP SetAngle enhancement Feature #5610: Actors movement should be smoother + Feature #5642: Ability to attach arrows to actor skeleton instead of bow mesh Task #5480: Drop Qt4 support Task #5520: Improve cell name autocompleter implementation diff --git a/apps/openmw/mwmechanics/weapontype.hpp b/apps/openmw/mwmechanics/weapontype.hpp index 32e321d45..056a1dbfd 100644 --- a/apps/openmw/mwmechanics/weapontype.hpp +++ b/apps/openmw/mwmechanics/weapontype.hpp @@ -239,7 +239,7 @@ namespace MWMechanics /* short group */ "", /* long group */ "", /* sound ID */ "Item Ammo", - /* attach bone */ "ArrowBone", + /* attach bone */ "Bip01 Arrow", /* sheath bone */ "", /* usage skill */ ESM::Skill::Marksman, /* weapon class*/ ESM::WeaponType::Ammo, diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 4a832c60c..f1df6c90f 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -252,11 +252,15 @@ osg::Group *CreatureWeaponAnimation::getArrowBone() int type = weapon->get()->mBase->mData.mType; int ammoType = MWMechanics::getWeaponType(type)->mAmmoType; - SceneUtil::FindByNameVisitor findVisitor (MWMechanics::getWeaponType(ammoType)->mAttachBone); - - mWeapon->getNode()->accept(findVisitor); - - return findVisitor.mFoundNode; + // Try to find and attachment bone in actor's skeleton, otherwise fall back to the ArrowBone in weapon's mesh + osg::Group* bone = getBoneByName(MWMechanics::getWeaponType(ammoType)->mAttachBone); + if (bone == nullptr) + { + SceneUtil::FindByNameVisitor findVisitor ("ArrowBone"); + mWeapon->getNode()->accept(findVisitor); + bone = findVisitor.mFoundNode; + } + return bone; } osg::Node *CreatureWeaponAnimation::getWeaponNode() diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 31cf3f015..30942d75f 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -1078,10 +1078,15 @@ osg::Group* NpcAnimation::getArrowBone() int type = weapon->get()->mBase->mData.mType; int ammoType = MWMechanics::getWeaponType(type)->mAmmoType; - SceneUtil::FindByNameVisitor findVisitor (MWMechanics::getWeaponType(ammoType)->mAttachBone); - part->getNode()->accept(findVisitor); - - return findVisitor.mFoundNode; + // Try to find and attachment bone in actor's skeleton, otherwise fall back to the ArrowBone in weapon's mesh + osg::Group* bone = getBoneByName(MWMechanics::getWeaponType(ammoType)->mAttachBone); + if (bone == nullptr) + { + SceneUtil::FindByNameVisitor findVisitor ("ArrowBone"); + part->getNode()->accept(findVisitor); + bone = findVisitor.mFoundNode; + } + return bone; } osg::Node* NpcAnimation::getWeaponNode() diff --git a/docs/source/reference/modding/extended.rst b/docs/source/reference/modding/extended.rst index bf2b2b74f..9e8db49fd 100644 --- a/docs/source/reference/modding/extended.rst +++ b/docs/source/reference/modding/extended.rst @@ -242,33 +242,39 @@ Every weapon type has an attack animation group and a suffix for the movement an For example, long blades use ``weapononehand`` attack animation group, ``idle1h`` idle animation group, ``jump1h`` jumping animation group, etc. This is the full table of supported animation groups: -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Weapon type | Animation group | Movement suffix | Attack (fallback) | Suffix (fallback) | -+===============+===================+==================+======================+=======================+ -| Short blade | shortbladeonehand | 1s | weapononehand | 1h | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Long blade 1H | weapononehand | 1h | | | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Long blade 2H | weapontwohand | 2c | | | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Blunt 1H | bluntonehand | 1b | weapononehand | 1h | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Blunt 2H | blunttwohand | 2b | weapontwohand | 2c | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Axe 1H | bluntonehand | 1b | weapononehand | 1h | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Axe 2H | blunttwohand | 2b | weapontwohand | 2c | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Blunt 2H wide | weapontwowide | 2w | weapontwohand | 2c | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Spear | weapontwowide | 2w | weapontwohand | 2c | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Bow | bowandarrow | bow | | 1h | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Crossbow | crossbow | crossbow | | 1h | -+---------------+-------------------+------------------+----------------------+-----------------------+ -| Thrown | throwweapon | 1t | | 1h | -+---------------+-------------------+------------------+----------------------+-----------------------+ ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Weapon type | Animation group | Movement suffix | Attack (fallback) | Suffix (fallback) | Attach bone | ++===============+===================+==================+======================+=======================+=======================+ +| Short blade | shortbladeonehand | 1s | weapononehand | 1h | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Long blade 1H | weapononehand | 1h | | | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Long blade 2H | weapontwohand | 2c | | | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Blunt 1H | bluntonehand | 1b | weapononehand | 1h | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Blunt 2H | blunttwohand | 2b | weapontwohand | 2c | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Axe 1H | bluntonehand | 1b | weapononehand | 1h | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Axe 2H | blunttwohand | 2b | weapontwohand | 2c | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Blunt 2H wide | weapontwowide | 2w | weapontwohand | 2c | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Spear | weapontwowide | 2w | weapontwohand | 2c | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Bow | bowandarrow | bow | | 1h | Weapon Bone Left | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Crossbow | crossbow | crossbow | | 1h | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ +| Thrown | throwweapon | 1t | | 1h | Weapon Bone | ++---------------+-------------------+------------------+----------------------+-----------------------+-----------------------+ + +Note that bows can be attached to the "Weapon Bone Left" bone if it is present in shooter's skeleton, and if it is not, "Weapon Bone" is used as a fallback. + +Also it is possible to add a "Bip01 Arrow" bone to actor skeletons. In this case OpenMW attaches arrows to this bone instead of ArrowBone in the bow mesh. +Such approach allows to implement better shooting animations (for example, beast races have tail, so quivers should be attached under different angle and +default arrow fetching animation does not look good). .. _`Graphic Herbalism`: https://www.nexusmods.com/morrowind/mods/46599 .. _`OpenMW Containers Animated`: https://www.nexusmods.com/morrowind/mods/46232 From 82da2045a99417c6b3cf0784cdcc467002f91a12 Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 14 Oct 2020 11:32:12 +0200 Subject: [PATCH 183/224] Non functionnal changes in preparation for async physics feature --- apps/openmw/mwphysics/actor.cpp | 18 ++-- apps/openmw/mwphysics/actor.hpp | 9 +- apps/openmw/mwphysics/object.cpp | 9 +- apps/openmw/mwphysics/object.hpp | 6 +- apps/openmw/mwphysics/physicssystem.cpp | 121 +++++++++++------------- apps/openmw/mwphysics/physicssystem.hpp | 27 +++--- apps/openmw/mwworld/worldimp.cpp | 22 ++--- 7 files changed, 101 insertions(+), 111 deletions(-) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 0f8814aca..0688b9869 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -17,32 +17,29 @@ namespace MWPhysics { -Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr shape, btCollisionWorld* world) +Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btCollisionWorld* world) : mCanWaterWalk(false), mWalkingOnWater(false) - , mCollisionObject(nullptr), mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) + , mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents) + , mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) , mInternalCollisionMode(true) , mExternalCollisionMode(true) , mCollisionWorld(world) { mPtr = ptr; - mHalfExtents = shape->mCollisionBoxHalfExtents; - mMeshTranslation = shape->mCollisionBoxTranslate; - // We can not create actor without collisions - he will fall through the ground. // In this case we should autogenerate collision box based on mesh shape // (NPCs have bodyparts and use a different approach) if (!ptr.getClass().isNpc() && mHalfExtents.length2() == 0.f) { - const Resource::BulletShape* collisionShape = shape.get(); - if (collisionShape && collisionShape->mCollisionShape) + if (shape->mCollisionShape) { btTransform transform; transform.setIdentity(); btVector3 min; btVector3 max; - collisionShape->mCollisionShape->getAabb(transform, min, max); + shape->mCollisionShape->getAabb(transform, min, max); mHalfExtents.x() = (max[0] - min[0])/2.f; mHalfExtents.y() = (max[1] - min[1])/2.f; mHalfExtents.z() = (max[2] - min[2])/2.f; @@ -83,7 +80,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr Actor::~Actor() { - if (mCollisionObject.get()) + if (mCollisionObject) mCollisionWorld->removeCollisionObject(mCollisionObject.get()); } @@ -112,7 +109,7 @@ void Actor::updateCollisionMask() addCollisionMask(getCollisionMask()); } -int Actor::getCollisionMask() +int Actor::getCollisionMask() const { int collisionMask = CollisionType_World | CollisionType_HeightMap; if (mExternalCollisionMode) @@ -120,7 +117,6 @@ int Actor::getCollisionMask() if (mCanWaterWalk) collisionMask |= CollisionType_Water; return collisionMask; - } void Actor::updatePosition() diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 8752f7fee..a6ff838ad 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -21,12 +21,13 @@ namespace Resource namespace MWPhysics { + class PhysicsTaskScheduler; - class Actor : public PtrHolder + class Actor final : public PtrHolder { public: - Actor(const MWWorld::Ptr& ptr, osg::ref_ptr shape, btCollisionWorld* world); - ~Actor(); + Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btCollisionWorld* world); + ~Actor() override; /** * Sets the collisionMode for this actor. If disabled, the actor can fly and clip geometry. @@ -136,7 +137,7 @@ namespace MWPhysics /// Removes then re-adds the collision object to the dynamics world void updateCollisionMask(); void addCollisionMask(int collisionMask); - int getCollisionMask(); + int getCollisionMask() const; bool mCanWaterWalk; bool mWalkingOnWater; diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index f95a67823..b21a3e3ca 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -14,9 +14,10 @@ namespace MWPhysics { - Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance) + Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, btCollisionWorld* world) : mShapeInstance(shapeInstance) , mSolid(true) + , mCollisionWorld(world) { mPtr = ptr; @@ -31,6 +32,12 @@ namespace MWPhysics setOrigin(btVector3(pos[0], pos[1], pos[2])); } + Object::~Object() + { + if (mCollisionObject) + mCollisionWorld->removeCollisionObject(mCollisionObject.get()); + } + const Resource::BulletShapeInstance* Object::getShapeInstance() const { return mShapeInstance.get(); diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp index b948433e3..87d1b0433 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -20,10 +20,11 @@ class btVector3; namespace MWPhysics { - class Object : public PtrHolder + class Object final : public PtrHolder { public: - Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance); + Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, btCollisionWorld* world); + ~Object() override; const Resource::BulletShapeInstance* getShapeInstance() const; void setScale(float scale); @@ -42,6 +43,7 @@ namespace MWPhysics osg::ref_ptr mShapeInstance; std::map mRecIndexToNodePath; bool mSolid; + btCollisionWorld* mCollisionWorld; }; } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 07859c1e2..58d96de28 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -65,11 +65,11 @@ namespace MWPhysics { mResourceSystem->addResourceManager(mShapeManager.get()); - mCollisionConfiguration = new btDefaultCollisionConfiguration(); - mDispatcher = new btCollisionDispatcher(mCollisionConfiguration); - mBroadphase = new btDbvtBroadphase(); + mCollisionConfiguration = std::make_unique(); + mDispatcher = std::make_unique(mCollisionConfiguration.get()); + mBroadphase = std::make_unique(); - mCollisionWorld = new btCollisionWorld(mDispatcher, mBroadphase, mCollisionConfiguration); + mCollisionWorld = std::make_shared(mDispatcher.get(), mBroadphase.get(), mCollisionConfiguration.get()); // Don't update AABBs of all objects every frame. Most objects in MW are static, so we don't need this. // Should a "static" object ever be moved, we have to update its AABB manually using DynamicsWorld::updateSingleAabb. @@ -92,7 +92,7 @@ namespace MWPhysics { mResourceSystem->removeResourceManager(mShapeManager.get()); - if (mWaterCollisionObject.get()) + if (mWaterCollisionObject) mCollisionWorld->removeCollisionObject(mWaterCollisionObject.get()); for (auto& heightField : mHeightFields) @@ -101,21 +101,9 @@ namespace MWPhysics delete heightField.second; } - for (auto& object : mObjects) - { - mCollisionWorld->removeCollisionObject(object.second->getCollisionObject()); - delete object.second; - } + mObjects.clear(); + mActors.clear(); - for (auto& actor : mActors) - { - delete actor.second; - } - - delete mCollisionWorld; - delete mCollisionConfiguration; - delete mDispatcher; - delete mBroadphase; } void PhysicsSystem::setUnrefQueue(SceneUtil::UnrefQueue *unrefQueue) @@ -132,13 +120,13 @@ namespace MWPhysics { mDebugDrawEnabled = !mDebugDrawEnabled; - if (mDebugDrawEnabled && !mDebugDrawer.get()) + if (mDebugDrawEnabled && !mDebugDrawer) { - mDebugDrawer.reset(new MWRender::DebugDrawer(mParentNode, mCollisionWorld)); + mDebugDrawer.reset(new MWRender::DebugDrawer(mParentNode, mCollisionWorld.get())); mCollisionWorld->setDebugDrawer(mDebugDrawer.get()); mDebugDrawer->setDebugMode(mDebugDrawEnabled); } - else if (mDebugDrawer.get()) + else if (mDebugDrawer) mDebugDrawer->setDebugMode(mDebugDrawEnabled); return mDebugDrawEnabled; } @@ -175,7 +163,7 @@ namespace MWPhysics std::pair PhysicsSystem::getHitContact(const MWWorld::ConstPtr& actor, const osg::Vec3f &origin, const osg::Quat &orient, - float queryDistance, std::vector targets) + float queryDistance, std::vector& targets) { // First of all, try to hit where you aim to int hitmask = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor; @@ -373,7 +361,7 @@ namespace MWPhysics const osg::Vec3f startingPosition(actorPosition.x(), actorPosition.y(), actorPosition.z() + halfZ); const osg::Vec3f destinationPosition(actorPosition.x(), actorPosition.y(), waterlevel + halfZ); ActorTracer tracer; - tracer.doTrace(physicActor->getCollisionObject(), startingPosition, destinationPosition, mCollisionWorld); + tracer.doTrace(physicActor->getCollisionObject(), startingPosition, destinationPosition, mCollisionWorld.get()); return (tracer.mFraction >= 1.0f); } @@ -444,7 +432,7 @@ namespace MWPhysics if (found == mActors.end()) return ptr.getRefData().getPosition().asVec3(); else - return MovementSolver::traceDown(ptr, position, found->second, mCollisionWorld, maxHeight); + return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight); } void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject) @@ -481,11 +469,11 @@ namespace MWPhysics if (!shapeInstance || !shapeInstance->getCollisionShape()) return; - Object *obj = new Object(ptr, shapeInstance); + auto obj = std::make_shared(ptr, shapeInstance, mCollisionWorld.get()); mObjects.emplace(ptr, obj); if (obj->isAnimated()) - mAnimatedObjects.insert(obj); + mAnimatedObjects.insert(obj.get()); mCollisionWorld->addCollisionObject(obj->getCollisionObject(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); @@ -496,21 +484,17 @@ namespace MWPhysics ObjectMap::iterator found = mObjects.find(ptr); if (found != mObjects.end()) { - mCollisionWorld->removeCollisionObject(found->second->getCollisionObject()); - if (mUnrefQueue.get()) mUnrefQueue->push(found->second->getShapeInstance()); - mAnimatedObjects.erase(found->second); + mAnimatedObjects.erase(found->second.get()); - delete found->second; mObjects.erase(found); } ActorMap::iterator foundActor = mActors.find(ptr); if (foundActor != mActors.end()) { - delete foundActor->second; mActors.erase(foundActor); } } @@ -536,19 +520,19 @@ namespace MWPhysics ObjectMap::iterator found = mObjects.find(old); if (found != mObjects.end()) { - Object* obj = found->second; + auto obj = found->second; obj->updatePtr(updated); mObjects.erase(found); - mObjects.emplace(updated, obj); + mObjects.emplace(updated, std::move(obj)); } ActorMap::iterator foundActor = mActors.find(old); if (foundActor != mActors.end()) { - Actor* actor = foundActor->second; + auto actor = foundActor->second; actor->updatePtr(updated); mActors.erase(foundActor); - mActors.emplace(updated, actor); + mActors.emplace(updated, std::move(actor)); } updateCollisionMapPtr(mStandingCollisions, old, updated); @@ -558,7 +542,7 @@ namespace MWPhysics { ActorMap::iterator found = mActors.find(ptr); if (found != mActors.end()) - return found->second; + return found->second.get(); return nullptr; } @@ -566,7 +550,7 @@ namespace MWPhysics { ActorMap::const_iterator found = mActors.find(ptr); if (found != mActors.end()) - return found->second; + return found->second.get(); return nullptr; } @@ -574,7 +558,7 @@ namespace MWPhysics { ObjectMap::const_iterator found = mObjects.find(ptr); if (found != mObjects.end()) - return found->second; + return found->second.get(); return nullptr; } @@ -639,11 +623,9 @@ namespace MWPhysics void PhysicsSystem::addActor (const MWWorld::Ptr& ptr, const std::string& mesh) { osg::ref_ptr shape = mShapeManager->getShape(mesh); - if (!shape) - return; // Try to get shape from basic model as fallback for creatures - if (!ptr.getClass().isNpc() && shape->mCollisionBoxHalfExtents.length2() == 0) + if (!ptr.getClass().isNpc() && shape && shape->mCollisionBoxHalfExtents.length2() == 0) { const std::string fallbackModel = ptr.getClass().getModel(ptr); if (fallbackModel != mesh) @@ -652,8 +634,11 @@ namespace MWPhysics } } - Actor* actor = new Actor(ptr, shape, mCollisionWorld); - mActors.emplace(ptr, actor); + if (!shape) + return; + + auto actor = std::make_shared(ptr, shape, mCollisionWorld.get()); + mActors.emplace(ptr, std::move(actor)); } bool PhysicsSystem::toggleCollisionMode() @@ -691,14 +676,14 @@ namespace MWPhysics mStandingCollisions.clear(); } - const PtrVelocityList& PhysicsSystem::applyQueuedMovement(float dt) + const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt) { mMovementResults.clear(); mTimeAccum += dt; const int maxAllowedSteps = 20; - int numSteps = mTimeAccum / (mPhysicsDt); + int numSteps = mTimeAccum / mPhysicsDt; numSteps = std::min(numSteps, maxAllowedSteps); mTimeAccum -= numSteps * mPhysicsDt; @@ -711,26 +696,28 @@ namespace MWPhysics const MWWorld::Ptr player = MWMechanics::getPlayer(); const MWBase::World *world = MWBase::Environment::get().getWorld(); - for(auto& movementItem : mMovementQueue) + for (const auto& m : mMovementQueue) { - ActorMap::iterator foundActor = mActors.find(movementItem.first); + const auto& character = m.first; + const auto& movement = m.second; + const auto foundActor = mActors.find(character); if (foundActor == mActors.end()) // actor was already removed from the scene continue; - Actor* physicActor = foundActor->second; + auto physicActor = foundActor->second; float waterlevel = -std::numeric_limits::max(); - const MWWorld::CellStore *cell = movementItem.first.getCell(); + const MWWorld::CellStore *cell = character.getCell(); if(cell->getCell()->hasWater()) waterlevel = cell->getWaterLevel(); - const MWMechanics::MagicEffects& effects = movementItem.first.getClass().getCreatureStats(movementItem.first).getMagicEffects(); + const MWMechanics::MagicEffects& effects = character.getClass().getCreatureStats(character).getMagicEffects(); bool waterCollision = false; if (cell->getCell()->hasWater() && effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()) { - if (!world->isUnderwater(movementItem.first.getCell(), osg::Vec3f(movementItem.first.getRefData().getPosition().asVec3()))) + if (!world->isUnderwater(character.getCell(), osg::Vec3f(character.getRefData().getPosition().asVec3()))) waterCollision = true; - else if (physicActor->getCollisionMode() && canMoveToWaterSurface(movementItem.first, waterlevel)) + else if (physicActor->getCollisionMode() && canMoveToWaterSurface(character, waterlevel)) { const osg::Vec3f actorPosition = physicActor->getPosition(); physicActor->setPosition(osg::Vec3f(actorPosition.x(), actorPosition.y(), waterlevel)); @@ -742,8 +729,8 @@ namespace MWPhysics // Slow fall reduces fall speed by a factor of (effect magnitude / 200) float slowFall = 1.f - std::max(0.f, std::min(1.f, effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f)); - bool flying = world->isFlying(movementItem.first); - bool swimming = world->isSwimming(movementItem.first); + bool flying = world->isFlying(character); + bool swimming = world->isSwimming(character); bool wasOnGround = physicActor->getOnGround(); osg::Vec3f position = physicActor->getPosition(); @@ -751,8 +738,8 @@ namespace MWPhysics bool positionChanged = false; for (int i=0; igetPtr(), physicActor, movementItem.second, mPhysicsDt, - flying, waterlevel, slowFall, mCollisionWorld, mStandingCollisions); + position = MovementSolver::move(position, physicActor->getPtr(), physicActor.get(), movement, mPhysicsDt, + flying, waterlevel, slowFall, mCollisionWorld.get(), mStandingCollisions); if (position != physicActor->getPosition()) positionChanged = true; physicActor->setPosition(position); // always set even if unchanged to make sure interpolation is correct @@ -765,25 +752,23 @@ namespace MWPhysics float heightDiff = position.z() - oldHeight; - MWMechanics::CreatureStats& stats = movementItem.first.getClass().getCreatureStats(movementItem.first); + MWMechanics::CreatureStats& stats = character.getClass().getCreatureStats(character); bool isStillOnGround = (numSteps > 0 && wasOnGround && physicActor->getOnGround()); if (isStillOnGround || flying || swimming || slowFall < 1) - stats.land(movementItem.first == player && (flying || swimming)); + stats.land(character == player && (flying || swimming)); else if (heightDiff < 0) stats.addToFallHeight(-heightDiff); - mMovementResults.emplace_back(movementItem.first, interpolated); + mMovementResults.emplace(character, interpolated); } - mMovementQueue.clear(); - return mMovementResults; } - void PhysicsSystem::stepSimulation(float dt) + void PhysicsSystem::stepSimulation() { - for (Object* animatedObject : mAnimatedObjects) - animatedObject->animateCollisionShapes(mCollisionWorld); + for (Object* animatedObject : mAnimatedObjects) + animatedObject->animateCollisionShapes(mCollisionWorld.get()); #ifndef BT_NO_PROFILE CProfileManager::Reset(); @@ -795,12 +780,12 @@ namespace MWPhysics { ObjectMap::iterator found = mObjects.find(object); if (found != mObjects.end()) - found->second->animateCollisionShapes(mCollisionWorld); + found->second->animateCollisionShapes(mCollisionWorld.get()); } void PhysicsSystem::debugDraw() { - if (mDebugDrawer.get()) + if (mDebugDrawer) mDebugDrawer->step(); } @@ -865,7 +850,7 @@ namespace MWPhysics void PhysicsSystem::updateWater() { - if (mWaterCollisionObject.get()) + if (mWaterCollisionObject) { mCollisionWorld->removeCollisionObject(mWaterCollisionObject.get()); } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 26005b396..fd9b52cb6 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -47,7 +47,8 @@ class btCollisionShape; namespace MWPhysics { - typedef std::vector > PtrVelocityList; + using PtrPositionList = std::map; + using CollisionMap = std::map; class HeightField; class Object; @@ -93,7 +94,7 @@ namespace MWPhysics bool toggleCollisionMode(); - void stepSimulation(float dt); + void stepSimulation(); void debugDraw(); std::vector getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; ///< get handles this object collides with @@ -102,7 +103,7 @@ namespace MWPhysics std::pair getHitContact(const MWWorld::ConstPtr& actor, const osg::Vec3f &origin, const osg::Quat &orientation, - float queryDistance, std::vector targets = std::vector()); + float queryDistance, std::vector& targets); /// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the @@ -146,7 +147,7 @@ namespace MWPhysics void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity); /// Apply all queued movements, then clear the list. - const PtrVelocityList& applyQueuedMovement(float dt); + const PtrPositionList& applyQueuedMovement(float dt); /// Clear the queued movements list without applying. void clearQueuedMovement(); @@ -192,37 +193,37 @@ namespace MWPhysics osg::ref_ptr mUnrefQueue; - btBroadphaseInterface* mBroadphase; - btDefaultCollisionConfiguration* mCollisionConfiguration; - btCollisionDispatcher* mDispatcher; - btCollisionWorld* mCollisionWorld; + std::unique_ptr mBroadphase; + std::unique_ptr mCollisionConfiguration; + std::unique_ptr mDispatcher; + std::shared_ptr mCollisionWorld; std::unique_ptr mShapeManager; Resource::ResourceSystem* mResourceSystem; - typedef std::map ObjectMap; + using ObjectMap = std::map>; ObjectMap mObjects; std::set mAnimatedObjects; // stores pointers to elements in mObjects - typedef std::map ActorMap; + using ActorMap = std::map>; ActorMap mActors; - typedef std::map, HeightField*> HeightFieldMap; + using HeightFieldMap = std::map, HeightField *>; HeightFieldMap mHeightFields; bool mDebugDrawEnabled; // Tracks standing collisions happening during a single frame. // This will detect standing on an object, but won't detect running e.g. against a wall. - typedef std::map CollisionMap; CollisionMap mStandingCollisions; // replaces all occurrences of 'old' in the map by 'updated', no matter if it's a key or value void updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated); + using PtrVelocityList = std::vector>; PtrVelocityList mMovementQueue; - PtrVelocityList mMovementResults; + PtrPositionList mMovementResults; float mTimeAccum; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 127fbb45a..e363fdd3b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1494,24 +1494,22 @@ namespace MWWorld void World::doPhysics(float duration) { - mPhysics->stepSimulation(duration); + mPhysics->stepSimulation(); processDoors(duration); mProjectileManager->update(duration); - const MWPhysics::PtrVelocityList &results = mPhysics->applyQueuedMovement(duration); - MWPhysics::PtrVelocityList::const_iterator player(results.end()); - for(MWPhysics::PtrVelocityList::const_iterator iter(results.begin());iter != results.end();++iter) + const auto results = mPhysics->applyQueuedMovement(duration); + + for(const auto& result : results) { - if(iter->first == getPlayerPtr()) - { - // Handle player last, in case a cell transition occurs - player = iter; - continue; - } - moveObjectImp(iter->first, iter->second.x(), iter->second.y(), iter->second.z(), false); + // Handle player last, in case a cell transition occurs + if(result.first != getPlayerPtr()) + moveObjectImp(result.first, result.second.x(), result.second.y(), result.second.z(), false); } - if(player != results.end()) + + const auto player = results.find(getPlayerPtr()); + if (player != results.end()) moveObjectImp(player->first, player->second.x(), player->second.y(), player->second.z(), false); } From 4ef36973fb1e32201079d46ba68ba031d356c497 Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 14 Oct 2020 15:47:50 +0200 Subject: [PATCH 184/224] Make the Actor class manage its collision object and position. --- apps/openmw/mwphysics/actor.cpp | 51 ++++++++++++++++++++++++--------- apps/openmw/mwphysics/actor.hpp | 5 ++++ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 0688b9869..e8338cc17 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -76,6 +76,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btColl updatePosition(); addCollisionMask(getCollisionMask()); + commitPositionChange(); } Actor::~Actor() @@ -105,8 +106,7 @@ void Actor::addCollisionMask(int collisionMask) void Actor::updateCollisionMask() { - mCollisionWorld->removeCollisionObject(mCollisionObject.get()); - addCollisionMask(getCollisionMask()); + mCollisionObject->getBroadphaseHandle()->m_collisionFilterMask = getCollisionMask(); } int Actor::getCollisionMask() const @@ -126,29 +126,53 @@ void Actor::updatePosition() mPosition = position; mPreviousPosition = position; + mTransformUpdatePending = true; updateCollisionObjectPosition(); } void Actor::updateCollisionObjectPosition() { - btTransform tr = mCollisionObject->getWorldTransform(); osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale); osg::Vec3f newPosition = scaledTranslation + mPosition; - tr.setOrigin(Misc::Convert::toBullet(newPosition)); - mCollisionObject->setWorldTransform(tr); + mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition)); + mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation)); + +} + +void Actor::commitPositionChange() +{ + if (mScaleUpdatePending) + { + mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); + mScaleUpdatePending = false; + } + if (mTransformUpdatePending) + { + mCollisionObject->setWorldTransform(mLocalTransform); + mTransformUpdatePending = false; + } } osg::Vec3f Actor::getCollisionObjectPosition() const { - return Misc::Convert::toOsg(mCollisionObject->getWorldTransform().getOrigin()); + return Misc::Convert::toOsg(mLocalTransform.getOrigin()); } void Actor::setPosition(const osg::Vec3f &position) { - mPreviousPosition = mPosition; + if (mTransformUpdatePending) + { + mCollisionObject->setWorldTransform(mLocalTransform); + mTransformUpdatePending = false; + } + else + { + mPreviousPosition = mPosition; - mPosition = position; - updateCollisionObjectPosition(); + mPosition = position; + updateCollisionObjectPosition(); + mCollisionObject->setWorldTransform(mLocalTransform); + } } osg::Vec3f Actor::getPosition() const @@ -163,11 +187,11 @@ osg::Vec3f Actor::getPreviousPosition() const void Actor::updateRotation () { - btTransform tr = mCollisionObject->getWorldTransform(); + if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude()) + return; mRotation = mPtr.getRefData().getBaseNode()->getAttitude(); - tr.setRotation(Misc::Convert::toBullet(mRotation)); - mCollisionObject->setWorldTransform(tr); + mTransformUpdatePending = true; updateCollisionObjectPosition(); } @@ -183,12 +207,13 @@ void Actor::updateScale() mPtr.getClass().adjustScale(mPtr, scaleVec, false); mScale = scaleVec; - mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); + mScaleUpdatePending = true; scaleVec = osg::Vec3f(scale,scale,scale); mPtr.getClass().adjustScale(mPtr, scaleVec, true); mRenderingScale = scaleVec; + mTransformUpdatePending = true; updateCollisionObjectPosition(); } diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index a6ff838ad..5393f9bfb 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -5,6 +5,7 @@ #include "ptrholder.hpp" +#include #include #include #include @@ -61,6 +62,7 @@ namespace MWPhysics void updatePosition(); void updateCollisionObjectPosition(); + void commitPositionChange(); /** * Returns the half extents of the collision body (scaled according to collision scale) @@ -157,6 +159,9 @@ namespace MWPhysics osg::Vec3f mRenderingScale; osg::Vec3f mPosition; osg::Vec3f mPreviousPosition; + btTransform mLocalTransform; + bool mScaleUpdatePending; + bool mTransformUpdatePending; osg::Vec3f mForce; bool mOnGround; From d76cc5d0a96a4348918f07ec1dcaf5858cace4dd Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 14 Oct 2020 15:55:15 +0200 Subject: [PATCH 185/224] Make the Object class manage its collision object and position. --- apps/openmw/mwphysics/object.cpp | 38 +++++++++++++++++++------ apps/openmw/mwphysics/object.hpp | 11 ++++++- apps/openmw/mwphysics/physicssystem.cpp | 10 +++++-- apps/openmw/mwworld/scene.cpp | 4 +-- apps/openmw/mwworld/worldimp.cpp | 4 +-- 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index b21a3e3ca..c1eadc05d 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -30,6 +30,7 @@ namespace MWPhysics setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude())); const float* pos = ptr.getRefData().getPosition().pos; setOrigin(btVector3(pos[0], pos[1], pos[2])); + commitPositionChange(); } Object::~Object() @@ -45,17 +46,34 @@ namespace MWPhysics void Object::setScale(float scale) { - mShapeInstance->setLocalScaling(btVector3(scale, scale, scale)); + mScale = { scale,scale,scale }; + mScaleUpdatePending = true; } void Object::setRotation(const btQuaternion& quat) { - mCollisionObject->getWorldTransform().setRotation(quat); + mLocalTransform.setRotation(quat); + mTransformUpdatePending = true; } void Object::setOrigin(const btVector3& vec) { - mCollisionObject->getWorldTransform().setOrigin(vec); + mLocalTransform.setOrigin(vec); + mTransformUpdatePending = true; + } + + void Object::commitPositionChange() + { + if (mScaleUpdatePending) + { + mShapeInstance->setLocalScaling(mScale); + mScaleUpdatePending = false; + } + if (mTransformUpdatePending) + { + mCollisionObject->setWorldTransform(mLocalTransform); + mTransformUpdatePending = false; + } } btCollisionObject* Object::getCollisionObject() @@ -68,6 +86,11 @@ namespace MWPhysics return mCollisionObject.get(); } + btTransform Object::getTransform() const + { + return mLocalTransform; + } + bool Object::isSolid() const { return mSolid; @@ -83,10 +106,10 @@ namespace MWPhysics return !mShapeInstance->mAnimatedShapes.empty(); } - void Object::animateCollisionShapes(btCollisionWorld* collisionWorld) + bool Object::animateCollisionShapes() { if (mShapeInstance->mAnimatedShapes.empty()) - return; + return false; assert (mShapeInstance->getCollisionShape()->isCompound()); @@ -107,7 +130,7 @@ namespace MWPhysics // Remove nonexistent nodes from animated shapes map and early out mShapeInstance->mAnimatedShapes.erase(recIndex); - return; + return false; } osg::NodePath nodePath = visitor.mFoundPath; nodePath.erase(nodePath.begin()); @@ -129,7 +152,6 @@ namespace MWPhysics if (!(transform == compound->getChildTransform(shapeIndex))) compound->updateChildTransform(shapeIndex, transform); } - - collisionWorld->updateSingleAabb(mCollisionObject.get()); + return true; } } diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp index 87d1b0433..d1f3dff74 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -3,6 +3,7 @@ #include "ptrholder.hpp" +#include #include #include @@ -30,13 +31,17 @@ namespace MWPhysics void setScale(float scale); void setRotation(const btQuaternion& quat); void setOrigin(const btVector3& vec); + void commitPositionChange(); btCollisionObject* getCollisionObject(); const btCollisionObject* getCollisionObject() const; + btTransform getTransform() const; /// Return solid flag. Not used by the object itself, true by default. bool isSolid() const; void setSolid(bool solid); bool isAnimated() const; - void animateCollisionShapes(btCollisionWorld* collisionWorld); + /// @brief update object shape + /// @return true if shape changed + bool animateCollisionShapes(); private: std::unique_ptr mCollisionObject; @@ -44,6 +49,10 @@ namespace MWPhysics std::map mRecIndexToNodePath; bool mSolid; btCollisionWorld* mCollisionWorld; + btVector3 mScale; + btTransform mLocalTransform; + bool mScaleUpdatePending; + bool mTransformUpdatePending; }; } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 58d96de28..97be7c39e 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -768,7 +768,12 @@ namespace MWPhysics void PhysicsSystem::stepSimulation() { for (Object* animatedObject : mAnimatedObjects) - animatedObject->animateCollisionShapes(mCollisionWorld.get()); + if (animatedObject->animateCollisionShapes()) + { + auto obj = mObjects.find(animatedObject->getPtr()); + assert(obj != mObjects.end()); + mCollisionWorld->updateSingleAabb(obj->second->getCollisionObject()); + } #ifndef BT_NO_PROFILE CProfileManager::Reset(); @@ -780,7 +785,8 @@ namespace MWPhysics { ObjectMap::iterator found = mObjects.find(object); if (found != mObjects.end()) - found->second->animateCollisionShapes(mCollisionWorld.get()); + if (found->second->animateCollisionShapes()) + mCollisionWorld->updateSingleAabb(found->second->getCollisionObject()); } void PhysicsSystem::debugDraw() diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 64316789f..684376226 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -152,7 +152,7 @@ namespace ? btVector3(distanceFromDoor, 0, 0) : btVector3(0, distanceFromDoor, 0); - const auto& transform = object->getCollisionObject()->getWorldTransform(); + const auto transform = object->getTransform(); const btTransform closedDoorTransform( Misc::Convert::toBullet(makeObjectOsgQuat(ptr.getCellRef().getPosition())), transform.getOrigin() @@ -187,7 +187,7 @@ namespace *object->getShapeInstance()->getCollisionShape(), object->getShapeInstance()->getAvoidCollisionShape() }, - object->getCollisionObject()->getWorldTransform() + object->getTransform() ); } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e363fdd3b..273a5f302 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1537,7 +1537,7 @@ namespace MWWorld *object->getShapeInstance()->getCollisionShape(), object->getShapeInstance()->getAvoidCollisionShape() }; - return mNavigator->updateObject(DetourNavigator::ObjectId(object), shapes, object->getCollisionObject()->getWorldTransform()); + return mNavigator->updateObject(DetourNavigator::ObjectId(object), shapes, object->getTransform()); } const MWPhysics::RayCastingInterface* World::getRayCasting() const @@ -3880,7 +3880,7 @@ namespace MWWorld btVector3 aabbMax; object->getShapeInstance()->getCollisionShape()->getAabb(btTransform::getIdentity(), aabbMin, aabbMax); - const auto toLocal = object->getCollisionObject()->getWorldTransform().inverse(); + const auto toLocal = object->getTransform().inverse(); const auto localFrom = toLocal(Misc::Convert::toBullet(position)); const auto localTo = toLocal(Misc::Convert::toBullet(destination)); From 91b3926a49fbc3285c4b354764060f9243a1e419 Mon Sep 17 00:00:00 2001 From: fredzio Date: Thu, 15 Oct 2020 06:11:00 +0200 Subject: [PATCH 186/224] We need to update the collision world after each step. Change order of traversal simulation step to make it rare enough to be parallelizable Before: for actor in actors: repeat numstep: solve(actor) After: repeat numstep: for actor in actors: solve(actor) Introduce struct ActorFrameData to pack all data that is necessary for the solver --- apps/openmw/mwphysics/movementsolver.cpp | 90 ++++------ apps/openmw/mwphysics/movementsolver.hpp | 13 +- apps/openmw/mwphysics/physicssystem.cpp | 203 ++++++++++++++++++----- apps/openmw/mwphysics/physicssystem.hpp | 50 ++++++ 4 files changed, 255 insertions(+), 101 deletions(-) diff --git a/apps/openmw/mwphysics/movementsolver.cpp b/apps/openmw/mwphysics/movementsolver.cpp index 6345a76d9..3c78104dc 100644 --- a/apps/openmw/mwphysics/movementsolver.cpp +++ b/apps/openmw/mwphysics/movementsolver.cpp @@ -10,18 +10,14 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" -#include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/movement.hpp" - #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/refdata.hpp" #include "actor.hpp" #include "collisiontype.hpp" #include "constants.hpp" +#include "physicssystem.hpp" #include "stepper.hpp" #include "trace.h" @@ -78,24 +74,26 @@ namespace MWPhysics return tracer.mEndPos-offset + osg::Vec3f(0.f, 0.f, sGroundOffset); } - osg::Vec3f MovementSolver::move(osg::Vec3f position, const MWWorld::Ptr &ptr, Actor* physicActor, const osg::Vec3f &movement, float time, - bool isFlying, float waterlevel, float slowFall, const btCollisionWorld* collisionWorld, - std::map& standingCollisionTracker) + void MovementSolver::move(ActorFrameData& actor, float time, const btCollisionWorld* collisionWorld, + WorldFrameData& worldData) { - const ESM::Position& refpos = ptr.getRefData().getPosition(); + auto* physicActor = actor.mActorRaw; + auto ptr = actor.mPtr; + const ESM::Position& refpos = actor.mRefpos; // Early-out for totally static creatures // (Not sure if gravity should still apply?) if (!ptr.getClass().isMobile(ptr)) - return position; + return; // Reset per-frame data physicActor->setWalkingOnWater(false); // Anything to collide with? if(!physicActor->getCollisionMode()) { - return position + (osg::Quat(refpos.rot[0], osg::Vec3f(-1, 0, 0)) * + actor.mPosition += (osg::Quat(refpos.rot[0], osg::Vec3f(-1, 0, 0)) * osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1)) - ) * movement * time; + ) * actor.mMovement * time; + return; } const btCollisionObject *colobj = physicActor->getCollisionObject(); @@ -105,23 +103,23 @@ namespace MWPhysics // That means the collision shape used for moving this actor is in a different spot than the collision shape // other actors are using to collide against this actor. // While this is strictly speaking wrong, it's needed for MW compatibility. - position.z() += halfExtents.z(); + actor.mPosition.z() += halfExtents.z(); static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get().find("fSwimHeightScale")->mValue.getFloat(); - float swimlevel = waterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale); + float swimlevel = actor.mWaterlevel + halfExtents.z() - (physicActor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale); ActorTracer tracer; osg::Vec3f inertia = physicActor->getInertialForce(); osg::Vec3f velocity; - if (position.z() < swimlevel || isFlying) + if (actor.mPosition.z() < swimlevel || actor.mFlying) { - velocity = (osg::Quat(refpos.rot[0], osg::Vec3f(-1, 0, 0)) * osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1))) * movement; + velocity = (osg::Quat(refpos.rot[0], osg::Vec3f(-1, 0, 0)) * osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1))) * actor.mMovement; } else { - velocity = (osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1))) * movement; + velocity = (osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1))) * actor.mMovement; if ((velocity.z() > 0.f && physicActor->getOnGround() && !physicActor->getOnSlope()) || (velocity.z() > 0.f && velocity.z() + inertia.z() <= -velocity.z() && physicActor->getOnSlope())) @@ -131,38 +129,16 @@ namespace MWPhysics } // dead actors underwater will float to the surface, if the CharacterController tells us to do so - if (movement.z() > 0 && ptr.getClass().getCreatureStats(ptr).isDead() && position.z() < swimlevel) + if (actor.mMovement.z() > 0 && actor.mIsDead && actor.mPosition.z() < swimlevel) velocity = osg::Vec3f(0,0,1) * 25; - if (ptr.getClass().getMovementSettings(ptr).mPosition[2]) - { - const bool isPlayer = (ptr == MWMechanics::getPlayer()); - // Advance acrobatics and set flag for GetPCJumping - if (isPlayer) - { - ptr.getClass().skillUsageSucceeded(ptr, ESM::Skill::Acrobatics, 0); - MWBase::Environment::get().getWorld()->getPlayer().setJumping(true); - } - - // Decrease fatigue - if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState()) - { - const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); - const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); - const float normalizedEncumbrance = std::min(1.f, ptr.getClass().getNormalizedEncumbrance(ptr)); - const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult; - MWMechanics::DynamicStat fatigue = ptr.getClass().getCreatureStats(ptr).getFatigue(); - fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); - ptr.getClass().getCreatureStats(ptr).setFatigue(fatigue); - } - ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0; - } + if (actor.mWantJump) + actor.mDidJump = true; // Now that we have the effective movement vector, apply wind forces to it - if (MWBase::Environment::get().getWorld()->isInStorm()) + if (worldData.mIsInStorm) { - osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection(); + osg::Vec3f stormDirection = worldData.mStormDirection; float angleDegrees = osg::RadiansToDegrees(std::acos(stormDirection * velocity / (stormDirection.length() * velocity.length()))); static const float fStromWalkMult = MWBase::Environment::get().getWorld()->getStore().get().find("fStromWalkMult")->mValue.getFloat(); velocity *= 1.f-(fStromWalkMult * (angleDegrees/180.f)); @@ -170,7 +146,7 @@ namespace MWPhysics Stepper stepper(collisionWorld, colobj); osg::Vec3f origVelocity = velocity; - osg::Vec3f newPosition = position; + osg::Vec3f newPosition = actor.mPosition; /* * A loop to find newPosition using tracer, if successful different from the starting position. * nextpos is the local variable used to find potential newPosition, using velocity and remainingTime @@ -182,7 +158,7 @@ namespace MWPhysics osg::Vec3f nextpos = newPosition + velocity * remainingTime; // If not able to fly, don't allow to swim up into the air - if(!isFlying && nextpos.z() > swimlevel && newPosition.z() < swimlevel) + if(!actor.mFlying && nextpos.z() > swimlevel && newPosition.z() < swimlevel) { const osg::Vec3f down(0,0,-1); velocity = slide(velocity, down); @@ -235,7 +211,7 @@ namespace MWPhysics if (result) { // don't let pure water creatures move out of water after stepMove - if (ptr.getClass().isPureWaterCreature(ptr) && newPosition.z() + halfExtents.z() > waterlevel) + if (ptr.getClass().isPureWaterCreature(ptr) && newPosition.z() + halfExtents.z() > actor.mWaterlevel) newPosition = oldPosition; } else @@ -245,7 +221,7 @@ namespace MWPhysics // Do not allow sliding upward if there is gravity. // Stepping will have taken care of that. - if(!(newPosition.z() < swimlevel || isFlying)) + if(!(newPosition.z() < swimlevel || actor.mFlying)) newVelocity.z() = std::min(newVelocity.z(), 0.0f); if ((newVelocity-velocity).length2() < 0.01) @@ -269,11 +245,11 @@ namespace MWPhysics const btCollisionObject* standingOn = tracer.mHitObject; PtrHolder* ptrHolder = static_cast(standingOn->getUserPointer()); if (ptrHolder) - standingCollisionTracker[ptr] = ptrHolder->getPtr(); + actor.mStandingOn = ptrHolder->getPtr(); if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water) physicActor->setWalkingOnWater(true); - if (!isFlying) + if (!actor.mFlying) newPosition.z() = tracer.mEndPos.z() + sGroundOffset; isOnGround = true; @@ -292,7 +268,7 @@ namespace MWPhysics btVector3 aabbMin, aabbMax; tracer.mHitObject->getCollisionShape()->getAabb(tracer.mHitObject->getWorldTransform(), aabbMin, aabbMax); btVector3 center = (aabbMin + aabbMax) / 2.f; - inertia = osg::Vec3f(position.x() - center.x(), position.y() - center.y(), 0); + inertia = osg::Vec3f(actor.mPosition.x() - center.x(), actor.mPosition.y() - center.y(), 0); inertia.normalize(); inertia *= 100; } @@ -302,16 +278,16 @@ namespace MWPhysics } } - if((isOnGround && !isOnSlope) || newPosition.z() < swimlevel || isFlying) + if((isOnGround && !isOnSlope) || newPosition.z() < swimlevel || actor.mFlying) physicActor->setInertialForce(osg::Vec3f(0.f, 0.f, 0.f)); else { inertia.z() -= time * Constants::GravityConst * Constants::UnitsPerMeter; if (inertia.z() < 0) - inertia.z() *= slowFall; - if (slowFall < 1.f) { - inertia.x() *= slowFall; - inertia.y() *= slowFall; + inertia.z() *= actor.mSlowFall; + if (actor.mSlowFall < 1.f) { + inertia.x() *= actor.mSlowFall; + inertia.y() *= actor.mSlowFall; } physicActor->setInertialForce(inertia); } @@ -319,6 +295,6 @@ namespace MWPhysics physicActor->setOnSlope(isOnSlope); newPosition.z() -= halfExtents.z(); // remove what was added at the beginning - return newPosition; + actor.mPosition = newPosition; } } diff --git a/apps/openmw/mwphysics/movementsolver.hpp b/apps/openmw/mwphysics/movementsolver.hpp index 54a417fa7..75fba1cf0 100644 --- a/apps/openmw/mwphysics/movementsolver.hpp +++ b/apps/openmw/mwphysics/movementsolver.hpp @@ -5,13 +5,18 @@ #include -#include "../mwworld/ptr.hpp" - class btCollisionWorld; +namespace MWWorld +{ + class Ptr; +} + namespace MWPhysics { class Actor; + struct ActorFrameData; + struct WorldFrameData; class MovementSolver { @@ -31,9 +36,7 @@ namespace MWPhysics public: static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight); - static osg::Vec3f move(osg::Vec3f position, const MWWorld::Ptr &ptr, Actor* physicActor, const osg::Vec3f &movement, float time, - bool isFlying, float waterlevel, float slowFall, const btCollisionWorld* collisionWorld, - std::map& standingCollisionTracker); + static void move(ActorFrameData& actor, float time, const btCollisionWorld* collisionWorld, WorldFrameData& worldData); }; } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 97be7c39e..2fb556522 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -31,9 +31,11 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/player.hpp" #include "../mwrender/bulletdebugdraw.hpp" @@ -687,14 +689,106 @@ namespace MWPhysics numSteps = std::min(numSteps, maxAllowedSteps); mTimeAccum -= numSteps * mPhysicsDt; + mActorsFrameData = prepareFrameData(); + bool advanceSimulation = (numSteps != 0); + if (advanceSimulation) + mWorldFrameData = std::make_unique(); - if (numSteps) + // update each actor position based on latest data + for (auto& data : mActorsFrameData) + data.updatePosition(); + + mMovementResults.clear(); + while (numSteps--) { - // Collision events should be available on every frame - mStandingCollisions.clear(); + for (auto& actorData : mActorsFrameData) + MovementSolver::move(actorData, mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData); + + // update actors position + for (auto& actorData : mActorsFrameData) + { + if(const auto actor = actorData.mActor.lock()) + { + if (actorData.mPosition != actorData.mActorRaw->getPosition()) + actorData.mPositionChanged = true; + actorData.mActorRaw->setPosition(actorData.mPosition); + } + } } - const MWWorld::Ptr player = MWMechanics::getPlayer(); + for (auto& actorData : mActorsFrameData) + { + // handle fall of actor + const float heightDiff = actorData.mPosition.z() - actorData.mOldHeight; + + const bool isStillOnGround = (advanceSimulation && actorData.mWasOnGround && actorData.mActorRaw->getOnGround()); + + if (isStillOnGround || actorData.mFlying || actorData.mSwimming || actorData.mSlowFall < 1) + actorData.mNeedLand = true; + else if (heightDiff < 0) + actorData.mFallHeight += heightDiff; + + // interpolate position + const float interpolationFactor = mTimeAccum / mPhysicsDt; + mMovementResults[actorData.mPtr] = actorData.mPosition * interpolationFactor + actorData.mActorRaw->getPreviousPosition() * (1.f - interpolationFactor); + + // update mechanics if actor jumped + if (actorData.mDidJump) + { + const bool isPlayer = (actorData.mPtr == MWMechanics::getPlayer()); + // Advance acrobatics and set flag for GetPCJumping + if (isPlayer) + { + actorData.mPtr.getClass().skillUsageSucceeded(actorData.mPtr, ESM::Skill::Acrobatics, 0); + MWBase::Environment::get().getWorld()->getPlayer().setJumping(true); + } + + // Decrease fatigue + if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState()) + { + const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); + const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); + const float normalizedEncumbrance = std::min(1.f, actorData.mPtr.getClass().getNormalizedEncumbrance(actorData.mPtr)); + const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult; + MWMechanics::DynamicStat fatigue = actorData.mPtr.getClass().getCreatureStats(actorData.mPtr).getFatigue(); + fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); + actorData.mPtr.getClass().getCreatureStats(actorData.mPtr).setFatigue(fatigue); + } + actorData.mPtr.getClass().getMovementSettings(actorData.mPtr).mPosition[2] = 0; + } + + MWMechanics::CreatureStats& stats = actorData.mPtr.getClass().getCreatureStats(actorData.mPtr); + if (actorData.mNeedLand) + stats.land(actorData.mPtr == MWMechanics::getPlayer() && (actorData.mFlying || actorData.mSwimming)); + else if (actorData.mFallHeight < 0) + stats.addToFallHeight(-actorData.mFallHeight); + } + + // update actors aabb + for (const auto& actorData : mActorsFrameData) + if (actorData.mPositionChanged) + mCollisionWorld->updateSingleAabb(actorData.mActorRaw->getCollisionObject()); + + // update standing collisions map + if (advanceSimulation) + { + mStandingCollisions.clear(); + for (auto& actorData : mActorsFrameData) + { + if (!actorData.mStandingOn.isEmpty()) + mStandingCollisions[actorData.mPtr] = actorData.mStandingOn; + else + mStandingCollisions.erase(actorData.mPtr); + } + } + return mMovementResults; + } + + std::vector PhysicsSystem::prepareFrameData() + { + std::vector actorsFrameData; + actorsFrameData.reserve(mMovementQueue.size()); const MWBase::World *world = MWBase::Environment::get().getWorld(); for (const auto& m : mMovementQueue) { @@ -702,7 +796,10 @@ namespace MWPhysics const auto& movement = m.second; const auto foundActor = mActors.find(character); if (foundActor == mActors.end()) // actor was already removed from the scene + { + mStandingCollisions.erase(character); continue; + } auto physicActor = foundActor->second; float waterlevel = -std::numeric_limits::max(); @@ -713,56 +810,27 @@ namespace MWPhysics const MWMechanics::MagicEffects& effects = character.getClass().getCreatureStats(character).getMagicEffects(); bool waterCollision = false; + bool moveToWaterSurface = false; if (cell->getCell()->hasWater() && effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()) { if (!world->isUnderwater(character.getCell(), osg::Vec3f(character.getRefData().getPosition().asVec3()))) waterCollision = true; else if (physicActor->getCollisionMode() && canMoveToWaterSurface(character, waterlevel)) { - const osg::Vec3f actorPosition = physicActor->getPosition(); - physicActor->setPosition(osg::Vec3f(actorPosition.x(), actorPosition.y(), waterlevel)); + moveToWaterSurface = true; waterCollision = true; } } + physicActor->setCanWaterWalk(waterCollision); // Slow fall reduces fall speed by a factor of (effect magnitude / 200) - float slowFall = 1.f - std::max(0.f, std::min(1.f, effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f)); + const float slowFall = 1.f - std::max(0.f, std::min(1.f, effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f)); - bool flying = world->isFlying(character); - bool swimming = world->isSwimming(character); - - bool wasOnGround = physicActor->getOnGround(); - osg::Vec3f position = physicActor->getPosition(); - float oldHeight = position.z(); - bool positionChanged = false; - for (int i=0; igetPtr(), physicActor.get(), movement, mPhysicsDt, - flying, waterlevel, slowFall, mCollisionWorld.get(), mStandingCollisions); - if (position != physicActor->getPosition()) - positionChanged = true; - physicActor->setPosition(position); // always set even if unchanged to make sure interpolation is correct - } - if (positionChanged) - mCollisionWorld->updateSingleAabb(physicActor->getCollisionObject()); - - float interpolationFactor = mTimeAccum / mPhysicsDt; - osg::Vec3f interpolated = position * interpolationFactor + physicActor->getPreviousPosition() * (1.f - interpolationFactor); - - float heightDiff = position.z() - oldHeight; - - MWMechanics::CreatureStats& stats = character.getClass().getCreatureStats(character); - bool isStillOnGround = (numSteps > 0 && wasOnGround && physicActor->getOnGround()); - if (isStillOnGround || flying || swimming || slowFall < 1) - stats.land(character == player && (flying || swimming)); - else if (heightDiff < 0) - stats.addToFallHeight(-heightDiff); - - mMovementResults.emplace(character, interpolated); + actorsFrameData.emplace_back(std::move(physicActor), character, mStandingCollisions[character], moveToWaterSurface, movement, slowFall, waterlevel); } mMovementQueue.clear(); - return mMovementResults; + return actorsFrameData; } void PhysicsSystem::stepSimulation() @@ -896,4 +964,61 @@ namespace MWPhysics stats.setAttribute(frameNumber, "Physics Objects", mObjects.size()); stats.setAttribute(frameNumber, "Physics HeightFields", mHeightFields.size()); } + + ActorFrameData::ActorFrameData(const std::shared_ptr& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, + bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel) + : mActor(actor), mActorRaw(actor.get()), mStandingOn(standingOn), + mPositionChanged(false), mDidJump(false), mNeedLand(false), mMoveToWaterSurface(moveToWaterSurface), + mWaterlevel(waterlevel), mSlowFall(slowFall), mOldHeight(0), mFallHeight(0), mMovement(movement), mPosition(), mRefpos() + { + const MWBase::World *world = MWBase::Environment::get().getWorld(); + mPtr = actor->getPtr(); + mFlying = world->isFlying(character); + mSwimming = world->isSwimming(character); + mWantJump = mPtr.getClass().getMovementSettings(mPtr).mPosition[2] != 0; + mIsDead = mPtr.getClass().getCreatureStats(mPtr).isDead(); + mWasOnGround = actor->getOnGround(); + } + + void ActorFrameData::updatePosition() + { + mPosition = mActorRaw->getPosition(); + if (mMoveToWaterSurface) + { + mPosition.z() = mWaterlevel; + mActorRaw->setPosition(mPosition); + } + mOldHeight = mPosition.z(); + mRefpos = mPtr.getRefData().getPosition(); + } + + WorldFrameData::WorldFrameData() + : mIsInStorm(MWBase::Environment::get().getWorld()->isInStorm()) + , mStormDirection(MWBase::Environment::get().getWorld()->getStormDirection()) + {} + + LOSRequest::LOSRequest(const std::weak_ptr& a1, const std::weak_ptr& a2) + : mResult(false), mStale(false), mAge(0) + { + // we use raw actor pointer pair to uniquely identify request + // sort the pointer value in ascending order to not duplicate equivalent requests, eg. getLOS(A, B) and getLOS(B, A) + auto* raw1 = a1.lock().get(); + auto* raw2 = a2.lock().get(); + assert(raw1 != raw2); + if (raw1 < raw2) + { + mActors = {a1, a2}; + mRawActors = {raw1, raw2}; + } + else + { + mActors = {a2, a1}; + mRawActors = {raw2, raw1}; + } + } + + bool operator==(const LOSRequest& lhs, const LOSRequest& rhs) noexcept + { + return lhs.mRawActors == rhs.mRawActors; + } } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index fd9b52cb6..b9390e9de 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_MWPHYSICS_PHYSICSSYSTEM_H #define OPENMW_MWPHYSICS_PHYSICSSYSTEM_H +#include #include #include #include @@ -53,6 +54,51 @@ namespace MWPhysics class HeightField; class Object; class Actor; + class PhysicsTaskScheduler; + + struct LOSRequest + { + LOSRequest(const std::weak_ptr& a1, const std::weak_ptr& a2); + std::array, 2> mActors; + std::array mRawActors; + bool mResult; + bool mStale; + int mAge; + }; + bool operator==(const LOSRequest& lhs, const LOSRequest& rhs) noexcept; + + struct ActorFrameData + { + ActorFrameData(const std::shared_ptr& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel); + void updatePosition(); + std::weak_ptr mActor; + Actor* mActorRaw; + MWWorld::Ptr mPtr; + MWWorld::Ptr mStandingOn; + bool mFlying; + bool mSwimming; + bool mPositionChanged; + bool mWasOnGround; + bool mWantJump; + bool mDidJump; + bool mIsDead; + bool mNeedLand; + bool mMoveToWaterSurface; + float mWaterlevel; + float mSlowFall; + float mOldHeight; + float mFallHeight; + osg::Vec3f mMovement; + osg::Vec3f mPosition; + ESM::Position mRefpos; + }; + + struct WorldFrameData + { + WorldFrameData(); + bool mIsInStorm; + osg::Vec3f mStormDirection; + }; class PhysicsSystem : public RayCastingInterface { @@ -191,6 +237,8 @@ namespace MWPhysics void updateWater(); + std::vector prepareFrameData(); + osg::ref_ptr mUnrefQueue; std::unique_ptr mBroadphase; @@ -224,6 +272,8 @@ namespace MWPhysics using PtrVelocityList = std::vector>; PtrVelocityList mMovementQueue; PtrPositionList mMovementResults; + std::unique_ptr mWorldFrameData; + std::vector mActorsFrameData; float mTimeAccum; From 3c2504b4420ede190de69efa465c67d50b98759c Mon Sep 17 00:00:00 2001 From: fredzio Date: Thu, 15 Oct 2020 06:11:44 +0200 Subject: [PATCH 187/224] Process movement queue in one or several background threads Before movement calculation, the main thread prepare a vector of ActorFrameData, which contains all data necessary to perform the simulation, and feed it to the solver. At the same time it fetches the result from the previous background simulation, which in turn is used by the game mechanics. Other functions of the physics system (weapon hit for instance) interrupt the background simulation, with some exceptions described below. The number of threads is controlled by the numeric setting [Physics] async num threads In case 'async num threads' > 1 and Bullet doesn't support multiple threads, 1 async thread will be used. 0 means synchronous solver. Additional settings (will be silently switched off if async num threads = 0) [Physics] defer aabb update Update AABBs of actors and objects in the background thread(s). It is not an especially costly operation, but it needs exclusive access to the collision world, which blocks other operations. Since AABB needs to be updated for collision detection, one can queue them to defer update before start of the movement solver. Extensive tests on as much as one installation (mine) show no drawback having that switched on. [Physics] lineofsight keep inactive cache Control for how long (how many frames) the line of sight (LOS) request will be kept updated. When a request for LOS is made for the first time, the background threads are stopped to service it. From now on, the LOS will be refreshed preemptively as part of the background routine until it is not required for lineofsight keep inactive cache frames. This mean that subsequent request will not interrupt the background computation. --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwphysics/actor.cpp | 42 +- apps/openmw/mwphysics/actor.hpp | 25 +- apps/openmw/mwphysics/mtphysics.cpp | 607 ++++++++++++++++++++++++ apps/openmw/mwphysics/mtphysics.hpp | 94 ++++ apps/openmw/mwphysics/object.cpp | 13 +- apps/openmw/mwphysics/object.hpp | 9 +- apps/openmw/mwphysics/physicssystem.cpp | 186 ++------ apps/openmw/mwphysics/physicssystem.hpp | 6 +- apps/openmw/mwworld/worldimp.cpp | 7 +- apps/openmw/mwworld/worldimp.hpp | 1 + components/misc/barrier.hpp | 51 ++ files/settings-default.cfg | 12 + 13 files changed, 872 insertions(+), 183 deletions(-) create mode 100644 apps/openmw/mwphysics/mtphysics.cpp create mode 100644 apps/openmw/mwphysics/mtphysics.hpp create mode 100644 components/misc/barrier.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b718322ac..d943c7836 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -73,7 +73,7 @@ add_openmw_dir (mwworld add_openmw_dir (mwphysics physicssystem trace collisiontype actor convert object heightfield closestnotmerayresultcallback contacttestresultcallback deepestnotmecontacttestresultcallback stepper movementsolver - closestnotmeconvexresultcallback raycasting + closestnotmeconvexresultcallback raycasting mtphysics ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index e8338cc17..5caaba5c9 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -12,18 +12,19 @@ #include "../mwworld/class.hpp" #include "collisiontype.hpp" +#include "mtphysics.hpp" namespace MWPhysics { -Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btCollisionWorld* world) +Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler) : mCanWaterWalk(false), mWalkingOnWater(false) , mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents) , mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) , mInternalCollisionMode(true) , mExternalCollisionMode(true) - , mCollisionWorld(world) + , mTaskScheduler(scheduler) { mPtr = ptr; @@ -82,12 +83,12 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btColl Actor::~Actor() { if (mCollisionObject) - mCollisionWorld->removeCollisionObject(mCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } void Actor::enableCollisionMode(bool collision) { - mInternalCollisionMode = collision; + mInternalCollisionMode.store(collision, std::memory_order_release); } void Actor::enableCollisionBody(bool collision) @@ -101,12 +102,12 @@ void Actor::enableCollisionBody(bool collision) void Actor::addCollisionMask(int collisionMask) { - mCollisionWorld->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); + mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); } void Actor::updateCollisionMask() { - mCollisionObject->getBroadphaseHandle()->m_collisionFilterMask = getCollisionMask(); + mTaskScheduler->setCollisionFilterMask(mCollisionObject.get(), getCollisionMask()); } int Actor::getCollisionMask() const @@ -121,6 +122,7 @@ int Actor::getCollisionMask() const void Actor::updatePosition() { + std::unique_lock lock(mPositionMutex); osg::Vec3f position = mPtr.getRefData().getPosition().asVec3(); mPosition = position; @@ -141,6 +143,7 @@ void Actor::updateCollisionObjectPosition() void Actor::commitPositionChange() { + std::unique_lock lock(mPositionMutex); if (mScaleUpdatePending) { mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); @@ -155,11 +158,13 @@ void Actor::commitPositionChange() osg::Vec3f Actor::getCollisionObjectPosition() const { + std::unique_lock lock(mPositionMutex); return Misc::Convert::toOsg(mLocalTransform.getOrigin()); } -void Actor::setPosition(const osg::Vec3f &position) +void Actor::setPosition(const osg::Vec3f &position, bool updateCollisionObject) { + std::unique_lock lock(mPositionMutex); if (mTransformUpdatePending) { mCollisionObject->setWorldTransform(mLocalTransform); @@ -170,23 +175,29 @@ void Actor::setPosition(const osg::Vec3f &position) mPreviousPosition = mPosition; mPosition = position; - updateCollisionObjectPosition(); - mCollisionObject->setWorldTransform(mLocalTransform); + if (updateCollisionObject) + { + updateCollisionObjectPosition(); + mCollisionObject->setWorldTransform(mLocalTransform); + } } } osg::Vec3f Actor::getPosition() const { + std::unique_lock lock(mPositionMutex); return mPosition; } osg::Vec3f Actor::getPreviousPosition() const { + std::unique_lock lock(mPositionMutex); return mPreviousPosition; } void Actor::updateRotation () { + std::unique_lock lock(mPositionMutex); if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude()) return; mRotation = mPtr.getRefData().getBaseNode()->getAttitude(); @@ -202,6 +213,7 @@ bool Actor::isRotationallyInvariant() const void Actor::updateScale() { + std::unique_lock lock(mPositionMutex); float scale = mPtr.getCellRef().getScale(); osg::Vec3f scaleVec(scale,scale,scale); @@ -219,16 +231,19 @@ void Actor::updateScale() osg::Vec3f Actor::getHalfExtents() const { + std::unique_lock lock(mPositionMutex); return osg::componentMultiply(mHalfExtents, mScale); } osg::Vec3f Actor::getOriginalHalfExtents() const { + std::unique_lock lock(mPositionMutex); return mHalfExtents; } osg::Vec3f Actor::getRenderingHalfExtents() const { + std::unique_lock lock(mPositionMutex); return osg::componentMultiply(mHalfExtents, mRenderingScale); } @@ -239,26 +254,27 @@ void Actor::setInertialForce(const osg::Vec3f &force) void Actor::setOnGround(bool grounded) { - mOnGround = grounded; + mOnGround.store(grounded, std::memory_order_release); } void Actor::setOnSlope(bool slope) { - mOnSlope = slope; + mOnSlope.store(slope, std::memory_order_release); } bool Actor::isWalkingOnWater() const { - return mWalkingOnWater; + return mWalkingOnWater.load(std::memory_order_acquire); } void Actor::setWalkingOnWater(bool walkingOnWater) { - mWalkingOnWater = walkingOnWater; + mWalkingOnWater.store(walkingOnWater, std::memory_order_release); } void Actor::setCanWaterWalk(bool waterWalk) { + std::unique_lock lock(mPositionMutex); if (waterWalk != mCanWaterWalk) { mCanWaterWalk = waterWalk; diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 5393f9bfb..ef7b368b9 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -1,7 +1,9 @@ #ifndef OPENMW_MWPHYSICS_ACTOR_H #define OPENMW_MWPHYSICS_ACTOR_H +#include #include +#include #include "ptrholder.hpp" @@ -10,7 +12,6 @@ #include #include -class btCollisionWorld; class btCollisionShape; class btCollisionObject; class btConvexShape; @@ -27,7 +28,7 @@ namespace MWPhysics class Actor final : public PtrHolder { public: - Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btCollisionWorld* world); + Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler); ~Actor() override; /** @@ -37,7 +38,7 @@ namespace MWPhysics bool getCollisionMode() const { - return mInternalCollisionMode; + return mInternalCollisionMode.load(std::memory_order_acquire); } btConvexShape* getConvexShape() const { return mConvexShape; } @@ -82,8 +83,9 @@ namespace MWPhysics /** * Store the current position into mPreviousPosition, then move to this position. + * Optionally, inform the physics engine about the change of position. */ - void setPosition(const osg::Vec3f& position); + void setPosition(const osg::Vec3f& position, bool updateCollisionObject=true); osg::Vec3f getPosition() const; @@ -113,14 +115,14 @@ namespace MWPhysics bool getOnGround() const { - return mInternalCollisionMode && mOnGround; + return mInternalCollisionMode.load(std::memory_order_acquire) && mOnGround.load(std::memory_order_acquire); } void setOnSlope(bool slope); bool getOnSlope() const { - return mInternalCollisionMode && mOnSlope; + return mInternalCollisionMode.load(std::memory_order_acquire) && mOnSlope.load(std::memory_order_acquire); } btCollisionObject* getCollisionObject() const @@ -142,7 +144,7 @@ namespace MWPhysics int getCollisionMask() const; bool mCanWaterWalk; - bool mWalkingOnWater; + std::atomic mWalkingOnWater; bool mRotationallyInvariant; @@ -162,14 +164,15 @@ namespace MWPhysics btTransform mLocalTransform; bool mScaleUpdatePending; bool mTransformUpdatePending; + mutable std::mutex mPositionMutex; osg::Vec3f mForce; - bool mOnGround; - bool mOnSlope; - bool mInternalCollisionMode; + std::atomic mOnGround; + std::atomic mOnSlope; + std::atomic mInternalCollisionMode; bool mExternalCollisionMode; - btCollisionWorld* mCollisionWorld; + PhysicsTaskScheduler* mTaskScheduler; Actor(const Actor&); Actor& operator=(const Actor&); diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp new file mode 100644 index 000000000..9aff85359 --- /dev/null +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -0,0 +1,607 @@ +#include +#include + +#include "components/debug/debuglog.hpp" +#include +#include "components/misc/convert.hpp" +#include "components/settings/settings.hpp" +#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/movement.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" + +#include "actor.hpp" +#include "movementsolver.hpp" +#include "mtphysics.hpp" +#include "object.hpp" +#include "physicssystem.hpp" + +class btIParallelSumBody; // needed to compile with bullet < 2.88 + +namespace +{ + /// @brief A scoped lock that is either shared or exclusive depending on configuration + template + class MaybeSharedLock + { + public: + /// @param mutex a shared mutex + /// @param canBeSharedLock decide wether the lock will be shared or exclusive + MaybeSharedLock(Mutex& mutex, bool canBeSharedLock) : mMutex(mutex), mCanBeSharedLock(canBeSharedLock) + { + if (mCanBeSharedLock) + mMutex.lock_shared(); + else + mMutex.lock(); + } + + ~MaybeSharedLock() + { + if (mCanBeSharedLock) + mMutex.unlock_shared(); + else + mMutex.unlock(); + } + private: + Mutex& mMutex; + bool mCanBeSharedLock; + }; + + void handleFall(MWPhysics::ActorFrameData& actorData, bool simulationPerformed) + { + const float heightDiff = actorData.mPosition.z() - actorData.mOldHeight; + + const bool isStillOnGround = (simulationPerformed && actorData.mWasOnGround && actorData.mActorRaw->getOnGround()); + + if (isStillOnGround || actorData.mFlying || actorData.mSwimming || actorData.mSlowFall < 1) + actorData.mNeedLand = true; + else if (heightDiff < 0) + actorData.mFallHeight += heightDiff; + } + + void handleJump(const MWWorld::Ptr &ptr) + { + const bool isPlayer = (ptr == MWMechanics::getPlayer()); + // Advance acrobatics and set flag for GetPCJumping + if (isPlayer) + { + ptr.getClass().skillUsageSucceeded(ptr, ESM::Skill::Acrobatics, 0); + MWBase::Environment::get().getWorld()->getPlayer().setJumping(true); + } + + // Decrease fatigue + if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState()) + { + const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); + const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); + const float normalizedEncumbrance = std::min(1.f, ptr.getClass().getNormalizedEncumbrance(ptr)); + const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult; + MWMechanics::DynamicStat fatigue = ptr.getClass().getCreatureStats(ptr).getFatigue(); + fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); + ptr.getClass().getCreatureStats(ptr).setFatigue(fatigue); + } + ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0; + } + + void updateStandingCollision(MWPhysics::ActorFrameData& actorData, MWPhysics::CollisionMap& standingCollisions) + { + if (!actorData.mStandingOn.isEmpty()) + standingCollisions[actorData.mPtr] = actorData.mStandingOn; + else + standingCollisions.erase(actorData.mPtr); + } + + void updateMechanics(MWPhysics::ActorFrameData& actorData) + { + if (actorData.mDidJump) + handleJump(actorData.mPtr); + + MWMechanics::CreatureStats& stats = actorData.mPtr.getClass().getCreatureStats(actorData.mPtr); + if (actorData.mNeedLand) + stats.land(actorData.mPtr == MWMechanics::getPlayer() && (actorData.mFlying || actorData.mSwimming)); + else if (actorData.mFallHeight < 0) + stats.addToFallHeight(-actorData.mFallHeight); + } + + osg::Vec3f interpolateMovements(const MWPhysics::ActorFrameData& actorData, float timeAccum, float physicsDt) + { + const float interpolationFactor = timeAccum / physicsDt; + return actorData.mPosition * interpolationFactor + actorData.mActorRaw->getPreviousPosition() * (1.f - interpolationFactor); + } + + struct WorldFrameData + { + WorldFrameData() : mIsInStorm(MWBase::Environment::get().getWorld()->isInStorm()) + , mStormDirection(MWBase::Environment::get().getWorld()->getStormDirection()) + {} + + bool mIsInStorm; + osg::Vec3f mStormDirection; + }; + + namespace Config + { + /* The purpose of these 2 classes is to make OpenMW works with Bullet compiled with either single or multithread support. + At runtime, Bullet resolve the call to btParallelFor() to: + - btITaskScheduler::parallelFor() if bullet is multithreaded + - btIParallelForBody::forLoop() if bullet is singlethreaded. + + NOTE: From Bullet 2.88, there is a btDefaultTaskScheduler(), that returns NULL if multithreading is not supported. + It might be worth considering to simplify the API once OpenMW stops supporting 2.87. + */ + + template + using void_t = void; + + /// @brief for Bullet <= 2.87 + template + class MultiThreadedBulletImpl : public T + { + public: + MultiThreadedBulletImpl(): T("") {}; + ~MultiThreadedBulletImpl() override = default; + int getMaxNumThreads() const override { return 1; }; + int getNumThreads() const override { return 1; }; + void setNumThreads(int numThreads) override {}; + + /// @brief will be called by Bullet if threading is supported + void parallelFor(int iBegin, int iEnd, int batchsize, const btIParallelForBody& body) override {}; + }; + + /// @brief for Bullet >= 2.88 + template + class MultiThreadedBulletImpl> : public T + { + public: + MultiThreadedBulletImpl(): T("") {}; + ~MultiThreadedBulletImpl() override = default; + int getMaxNumThreads() const override { return 1; }; + int getNumThreads() const override { return 1; }; + void setNumThreads(int numThreads) override {}; + + /// @brief will be called by Bullet if threading is supported + void parallelFor(int iBegin, int iEnd, int batchsize, const btIParallelForBody& body) override {}; + + btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) override { return {}; }; + }; + + using MultiThreadedBullet = MultiThreadedBulletImpl; + + class SingleThreadedBullet : public btIParallelForBody + { + public: + explicit SingleThreadedBullet(bool &threadingSupported): mThreadingSupported(threadingSupported) {}; + /// @brief will be called by Bullet if threading is NOT supported + void forLoop(int iBegin, int iEnd) const override + { + mThreadingSupported = false; + } + private: + bool &mThreadingSupported; + }; + + /// @return either the number of thread as configured by the user, or 1 if Bullet doesn't support multithreading + int computeNumThreads(bool& threadSafeBullet) + { + int wantedThread = Settings::Manager::getInt("async num threads", "Physics"); + + auto bulletScheduler = std::make_unique(); + btSetTaskScheduler(bulletScheduler.get()); + bool threadingSupported = true; + btParallelFor(0, 0, 0, SingleThreadedBullet(threadingSupported)); + + threadSafeBullet = threadingSupported; + if (!threadingSupported && wantedThread > 1) + { + Log(Debug::Warning) << "Bullet was not compiled with multithreading support, 1 async thread will be used"; + return 1; + } + return std::max(0, wantedThread); + } + } +} + +namespace MWPhysics +{ + PhysicsTaskScheduler::PhysicsTaskScheduler(float physicsDt, std::shared_ptr collisionWorld) + : mPhysicsDt(physicsDt) + , mCollisionWorld(std::move(collisionWorld)) + , mNumJobs(0) + , mRemainingSteps(0) + , mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics")) + , mDeferAabbUpdate(Settings::Manager::getBool("defer aabb update", "Physics")) + , mNewFrame(false) + , mAdvanceSimulation(false) + , mQuit(false) + , mNextJob(0) + , mNextLOS(0) + { + mNumThreads = Config::computeNumThreads(mThreadSafeBullet); + + if (mNumThreads >= 1) + { + for (int i = 0; i < mNumThreads; ++i) + mThreads.emplace_back([&] { worker(); } ); + } + else + { + mLOSCacheExpiry = -1; + mDeferAabbUpdate = false; + } + + mPreStepBarrier = std::make_unique(mNumThreads, [&]() + { + updateAabbs(); + }); + + mPostStepBarrier = std::make_unique(mNumThreads, [&]() + { + if (mRemainingSteps) + --mRemainingSteps; + mNextJob.store(0, std::memory_order_release); + updateActorsPositions(); + }); + + mPostSimBarrier = std::make_unique(mNumThreads, [&]() + { + udpateActorsAabbs(); + mNewFrame = false; + if (mLOSCacheExpiry >= 0) + { + std::unique_lock lock(mLOSCacheMutex); + mLOSCache.erase( + std::remove_if(mLOSCache.begin(), mLOSCache.end(), + [](const LOSRequest& req) { return req.mStale; }), + mLOSCache.end()); + } + }); + } + + PhysicsTaskScheduler::~PhysicsTaskScheduler() + { + std::unique_lock lock(mSimulationMutex); + mQuit = true; + mNumJobs = 0; + mRemainingSteps = 0; + lock.unlock(); + mHasJob.notify_all(); + for (auto& thread : mThreads) + thread.join(); + } + + const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector&& actorsData, CollisionMap& standingCollisions, bool skipSimulation) + { + // This function run in the main thread. + // While the mSimulationMutex is held, background physics threads can't run. + + std::unique_lock lock(mSimulationMutex); + + // start by finishing previous background computation + if (mNumThreads != 0) + { + if (mAdvanceSimulation) + standingCollisions.clear(); + + for (auto& data : mActorsFrameData) + { + // Ignore actors that were deleted while the background thread was running + if (!data.mActor.lock()) + continue; + + updateMechanics(data); + if (mAdvanceSimulation) + updateStandingCollision(data, standingCollisions); + } + } + + // init + mRemainingSteps = numSteps; + mTimeAccum = timeAccum; + mActorsFrameData = std::move(actorsData); + mAdvanceSimulation = (mRemainingSteps != 0); + mNewFrame = true; + mNumJobs = mActorsFrameData.size(); + mNextLOS.store(0, std::memory_order_relaxed); + mNextJob.store(0, std::memory_order_release); + + if (mAdvanceSimulation) + mWorldFrameData = std::make_unique(); + + // update each actor position based on latest data + for (auto& data : mActorsFrameData) + data.updatePosition(); + + // we are asked to skip the simulation (load a savegame for instance) + // just return the actors' reference position without applying the movements + if (skipSimulation) + { + standingCollisions.clear(); + mMovementResults.clear(); + for (const auto& m : mActorsFrameData) + mMovementResults[m.mPtr] = m.mPosition; + return mMovementResults; + } + + if (mNumThreads == 0) + { + mMovementResults.clear(); + syncComputation(); + + if (mAdvanceSimulation) + { + standingCollisions.clear(); + for (auto& data : mActorsFrameData) + updateStandingCollision(data, standingCollisions); + } + return mMovementResults; + } + + // Remove actors that were deleted while the background thread was running + for (auto& data : mActorsFrameData) + { + if (!data.mActor.lock()) + mMovementResults.erase(data.mPtr); + } + std::swap(mMovementResults, mPreviousMovementResults); + + // mMovementResults is shared between all workers instance + // pre-allocate all nodes so that we don't need synchronization + mMovementResults.clear(); + for (const auto& m : mActorsFrameData) + mMovementResults[m.mPtr] = m.mPosition; + + lock.unlock(); + mHasJob.notify_all(); + return mPreviousMovementResults; + } + + void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const + { + MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet); + mCollisionWorld->rayTest(rayFromWorld, rayToWorld, resultCallback); + } + + void PhysicsTaskScheduler::convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const + { + MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet); + mCollisionWorld->convexSweepTest(castShape, from, to, resultCallback); + } + + void PhysicsTaskScheduler::contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback) + { + std::shared_lock lock(mCollisionWorldMutex); + mCollisionWorld->contactTest(colObj, resultCallback); + } + + boost::optional PhysicsTaskScheduler::getHitPoint(const btTransform& from, btCollisionObject* target) + { + MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet); + // target the collision object's world origin, this should be the center of the collision object + btTransform rayTo; + rayTo.setIdentity(); + rayTo.setOrigin(target->getWorldTransform().getOrigin()); + + btCollisionWorld::ClosestRayResultCallback cb(from.getOrigin(), rayTo.getOrigin()); + + mCollisionWorld->rayTestSingle(from, rayTo, target, target->getCollisionShape(), target->getWorldTransform(), cb); + if (!cb.hasHit()) + // didn't hit the target. this could happen if point is already inside the collision box + return boost::none; + return {cb.m_hitPointWorld}; + } + + void PhysicsTaskScheduler::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) + { + std::shared_lock lock(mCollisionWorldMutex); + mCollisionWorld->getBroadphase()->aabbTest(aabbMin, aabbMax, callback); + } + + void PhysicsTaskScheduler::getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max) + { + std::shared_lock lock(mCollisionWorldMutex); + obj->getCollisionShape()->getAabb(obj->getWorldTransform(), min, max); + } + + void PhysicsTaskScheduler::setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask) + { + std::unique_lock lock(mCollisionWorldMutex); + collisionObject->getBroadphaseHandle()->m_collisionFilterMask = collisionFilterMask; + } + + void PhysicsTaskScheduler::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) + { + std::unique_lock lock(mCollisionWorldMutex); + mCollisionWorld->addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask); + } + + void PhysicsTaskScheduler::removeCollisionObject(btCollisionObject* collisionObject) + { + std::unique_lock lock(mCollisionWorldMutex); + mCollisionWorld->removeCollisionObject(collisionObject); + } + + void PhysicsTaskScheduler::updateSingleAabb(std::weak_ptr ptr) + { + if (mDeferAabbUpdate) + { + std::unique_lock lock(mUpdateAabbMutex); + mUpdateAabb.insert(std::move(ptr)); + } + else + { + std::unique_lock lock(mCollisionWorldMutex); + updatePtrAabb(ptr); + } + } + + bool PhysicsTaskScheduler::getLineOfSight(const std::weak_ptr& actor1, const std::weak_ptr& actor2) + { + std::unique_lock lock(mLOSCacheMutex); + + auto actorPtr1 = actor1.lock(); + auto actorPtr2 = actor2.lock(); + if (!actorPtr1 || !actorPtr2) + return false; + + auto req = LOSRequest(actor1, actor2); + auto result = std::find(mLOSCache.begin(), mLOSCache.end(), req); + if (result == mLOSCache.end()) + { + req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get()); + if (mLOSCacheExpiry >= 0) + mLOSCache.push_back(req); + return req.mResult; + } + result->mAge = 0; + return result->mResult; + } + + void PhysicsTaskScheduler::refreshLOSCache() + { + std::shared_lock lock(mLOSCacheMutex); + int job = 0; + int numLOS = mLOSCache.size(); + while ((job = mNextLOS.fetch_add(1, std::memory_order_relaxed)) < numLOS) + { + auto& req = mLOSCache[job]; + auto actorPtr1 = req.mActors[0].lock(); + auto actorPtr2 = req.mActors[1].lock(); + + if (req.mAge++ > mLOSCacheExpiry || !actorPtr1 || !actorPtr2) + req.mStale = true; + else + req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get()); + } + + } + + void PhysicsTaskScheduler::updateAabbs() + { + std::unique_lock lock1(mCollisionWorldMutex, std::defer_lock); + std::unique_lock lock2(mUpdateAabbMutex, std::defer_lock); + std::lock(lock1, lock2); + std::for_each(mUpdateAabb.begin(), mUpdateAabb.end(), + [this](const std::weak_ptr& ptr) { updatePtrAabb(ptr); }); + mUpdateAabb.clear(); + } + + void PhysicsTaskScheduler::updatePtrAabb(const std::weak_ptr& ptr) + { + if (const auto p = ptr.lock()) + { + if (const auto actor = std::dynamic_pointer_cast(p)) + { + actor->commitPositionChange(); + mCollisionWorld->updateSingleAabb(actor->getCollisionObject()); + } + else if (const auto object = std::dynamic_pointer_cast(p)) + { + object->commitPositionChange(); + mCollisionWorld->updateSingleAabb(object->getCollisionObject()); + } + }; + } + + void PhysicsTaskScheduler::worker() + { + std::shared_lock lock(mSimulationMutex); + while (!mQuit) + { + if (!mNewFrame) + mHasJob.wait(lock, [&]() { return mQuit || mNewFrame; }); + + if (mDeferAabbUpdate) + mPreStepBarrier->wait(); + + int job = 0; + while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs) + { + MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet); + if(const auto actor = mActorsFrameData[job].mActor.lock()) + { + if (mRemainingSteps) + MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData); + else + { + auto& actorData = mActorsFrameData[job]; + handleFall(actorData, mAdvanceSimulation); + mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt); + } + } + } + + mPostStepBarrier->wait(); + + if (!mRemainingSteps) + { + if (mLOSCacheExpiry >= 0) + refreshLOSCache(); + mPostSimBarrier->wait(); + } + } + } + + void PhysicsTaskScheduler::updateActorsPositions() + { + std::unique_lock lock(mCollisionWorldMutex); + for (auto& actorData : mActorsFrameData) + { + if(const auto actor = actorData.mActor.lock()) + { + if (actorData.mPosition == actor->getPosition()) + actor->setPosition(actorData.mPosition, false); // update previous position to make sure interpolation is correct + else + { + actorData.mPositionChanged = true; + actor->setPosition(actorData.mPosition); + } + } + } + } + + void PhysicsTaskScheduler::udpateActorsAabbs() + { + std::unique_lock lock(mCollisionWorldMutex); + for (const auto& actorData : mActorsFrameData) + if (actorData.mPositionChanged) + { + if(const auto actor = actorData.mActor.lock()) + mCollisionWorld->updateSingleAabb(actor->getCollisionObject()); + } + } + + bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2) + { + btVector3 pos1 = Misc::Convert::toBullet(actor1->getCollisionObjectPosition() + osg::Vec3f(0,0,actor1->getHalfExtents().z() * 0.9)); // eye level + btVector3 pos2 = Misc::Convert::toBullet(actor2->getCollisionObjectPosition() + osg::Vec3f(0,0,actor2->getHalfExtents().z() * 0.9)); + + btCollisionWorld::ClosestRayResultCallback resultCallback(pos1, pos2); + resultCallback.m_collisionFilterGroup = 0xFF; + resultCallback.m_collisionFilterMask = CollisionType_World|CollisionType_HeightMap|CollisionType_Door; + + MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet); + mCollisionWorld->rayTest(pos1, pos2, resultCallback); + + return !resultCallback.hasHit(); + } + + void PhysicsTaskScheduler::syncComputation() + { + while (mRemainingSteps--) + { + for (auto& actorData : mActorsFrameData) + MovementSolver::move(actorData, mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData); + + updateActorsPositions(); + } + + for (auto& actorData : mActorsFrameData) + { + handleFall(actorData, mAdvanceSimulation); + mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt); + updateMechanics(actorData); + } + udpateActorsAabbs(); + } +} diff --git a/apps/openmw/mwphysics/mtphysics.hpp b/apps/openmw/mwphysics/mtphysics.hpp new file mode 100644 index 000000000..4862393f3 --- /dev/null +++ b/apps/openmw/mwphysics/mtphysics.hpp @@ -0,0 +1,94 @@ +#ifndef OPENMW_MWPHYSICS_MTPHYSICS_H +#define OPENMW_MWPHYSICS_MTPHYSICS_H + +#include +#include +#include +#include + +#include +#include + +#include "physicssystem.hpp" +#include "ptrholder.hpp" + +namespace Misc +{ + class Barrier; +} + +namespace MWPhysics +{ + class PhysicsTaskScheduler + { + public: + PhysicsTaskScheduler(float physicsDt, std::shared_ptr collisionWorld); + ~PhysicsTaskScheduler(); + + /// @brief move actors taking into account desired movements and collisions + /// @param numSteps how much simulation step to run + /// @param timeAccum accumulated time from previous run to interpolate movements + /// @param actorsData per actor data needed to compute new positions + /// @return new position of each actor + const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector&& actorsData, CollisionMap& standingCollisions, bool skip); + + // Thread safe wrappers + void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; + void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const; + void contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback); + boost::optional getHitPoint(const btTransform& from, btCollisionObject* target); + void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + void getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max); + void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask); + void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask); + void removeCollisionObject(btCollisionObject* collisionObject); + void updateSingleAabb(std::weak_ptr ptr); + bool getLineOfSight(const std::weak_ptr& actor1, const std::weak_ptr& actor2); + + private: + void syncComputation(); + void worker(); + void updateActorsPositions(); + void udpateActorsAabbs(); + bool hasLineOfSight(const Actor* actor1, const Actor* actor2); + void refreshLOSCache(); + void updateAabbs(); + void updatePtrAabb(const std::weak_ptr& ptr); + + std::unique_ptr mWorldFrameData; + std::vector mActorsFrameData; + PtrPositionList mMovementResults; + PtrPositionList mPreviousMovementResults; + const float mPhysicsDt; + float mTimeAccum; + std::shared_ptr mCollisionWorld; + std::vector mLOSCache; + std::set, std::owner_less>> mUpdateAabb; + + // TODO: use std::experimental::flex_barrier or std::barrier once it becomes a thing + std::unique_ptr mPreStepBarrier; + std::unique_ptr mPostStepBarrier; + std::unique_ptr mPostSimBarrier; + + int mNumThreads; + int mNumJobs; + int mRemainingSteps; + int mLOSCacheExpiry; + bool mDeferAabbUpdate; + bool mNewFrame; + bool mAdvanceSimulation; + bool mThreadSafeBullet; + bool mQuit; + std::atomic mNextJob; + std::atomic mNextLOS; + std::vector mThreads; + + mutable std::shared_timed_mutex mSimulationMutex; + mutable std::shared_timed_mutex mCollisionWorldMutex; + mutable std::shared_timed_mutex mLOSCacheMutex; + mutable std::mutex mUpdateAabbMutex; + std::condition_variable_any mHasJob; + }; + +} +#endif diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index c1eadc05d..c822bbcbe 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -1,4 +1,5 @@ #include "object.hpp" +#include "mtphysics.hpp" #include #include @@ -8,16 +9,15 @@ #include #include -#include #include namespace MWPhysics { - Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, btCollisionWorld* world) + Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, PhysicsTaskScheduler* scheduler) : mShapeInstance(shapeInstance) , mSolid(true) - , mCollisionWorld(world) + , mTaskScheduler(scheduler) { mPtr = ptr; @@ -36,7 +36,7 @@ namespace MWPhysics Object::~Object() { if (mCollisionObject) - mCollisionWorld->removeCollisionObject(mCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } const Resource::BulletShapeInstance* Object::getShapeInstance() const @@ -46,24 +46,28 @@ namespace MWPhysics void Object::setScale(float scale) { + std::unique_lock lock(mPositionMutex); mScale = { scale,scale,scale }; mScaleUpdatePending = true; } void Object::setRotation(const btQuaternion& quat) { + std::unique_lock lock(mPositionMutex); mLocalTransform.setRotation(quat); mTransformUpdatePending = true; } void Object::setOrigin(const btVector3& vec) { + std::unique_lock lock(mPositionMutex); mLocalTransform.setOrigin(vec); mTransformUpdatePending = true; } void Object::commitPositionChange() { + std::unique_lock lock(mPositionMutex); if (mScaleUpdatePending) { mShapeInstance->setLocalScaling(mScale); @@ -88,6 +92,7 @@ namespace MWPhysics btTransform Object::getTransform() const { + std::unique_lock lock(mPositionMutex); return mLocalTransform; } diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp index d1f3dff74..876e35651 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace Resource { @@ -15,16 +16,17 @@ namespace Resource } class btCollisionObject; -class btCollisionWorld; class btQuaternion; class btVector3; namespace MWPhysics { + class PhysicsTaskScheduler; + class Object final : public PtrHolder { public: - Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, btCollisionWorld* world); + Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, PhysicsTaskScheduler* scheduler); ~Object() override; const Resource::BulletShapeInstance* getShapeInstance() const; @@ -48,11 +50,12 @@ namespace MWPhysics osg::ref_ptr mShapeInstance; std::map mRecIndexToNodePath; bool mSolid; - btCollisionWorld* mCollisionWorld; btVector3 mScale; btTransform mLocalTransform; bool mScaleUpdatePending; bool mTransformUpdatePending; + mutable std::mutex mPositionMutex; + PhysicsTaskScheduler* mTaskScheduler; }; } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 2fb556522..00068c1e6 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -35,7 +35,6 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/cellstore.hpp" -#include "../mwworld/player.hpp" #include "../mwrender/bulletdebugdraw.hpp" @@ -52,6 +51,7 @@ #include "contacttestresultcallback.hpp" #include "constants.hpp" #include "movementsolver.hpp" +#include "mtphysics.hpp" namespace MWPhysics { @@ -88,6 +88,8 @@ namespace MWPhysics Log(Debug::Warning) << "Warning: using custom physics framerate (" << physFramerate << " FPS)."; } } + + mTaskScheduler = std::make_unique(mPhysicsDt, mCollisionWorld); } PhysicsSystem::~PhysicsSystem() @@ -95,11 +97,11 @@ namespace MWPhysics mResourceSystem->removeResourceManager(mShapeManager.get()); if (mWaterCollisionObject) - mCollisionWorld->removeCollisionObject(mWaterCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get()); for (auto& heightField : mHeightFields) { - mCollisionWorld->removeCollisionObject(heightField.second->getCollisionObject()); + mTaskScheduler->removeCollisionObject(heightField.second->getCollisionObject()); delete heightField.second; } @@ -211,7 +213,7 @@ namespace MWPhysics DeepestNotMeContactTestResultCallback resultCallback(me, targetCollisionObjects, Misc::Convert::toBullet(origin)); resultCallback.m_collisionFilterGroup = CollisionType_Actor; resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor; - mCollisionWorld->contactTest(&object, resultCallback); + mTaskScheduler->contactTest(&object, resultCallback); if (resultCallback.mObject) { @@ -235,21 +237,12 @@ namespace MWPhysics rayFrom.setIdentity(); rayFrom.setOrigin(Misc::Convert::toBullet(point)); - // target the collision object's world origin, this should be the center of the collision object - btTransform rayTo; - rayTo.setIdentity(); - rayTo.setOrigin(targetCollisionObj->getWorldTransform().getOrigin()); + auto hitpoint = mTaskScheduler->getHitPoint(rayFrom, targetCollisionObj); + if (hitpoint) + return (point - Misc::Convert::toOsg(hitpoint.get())).length(); - btCollisionWorld::ClosestRayResultCallback cb(rayFrom.getOrigin(), rayTo.getOrigin()); - - btCollisionWorld::rayTestSingle(rayFrom, rayTo, targetCollisionObj, targetCollisionObj->getCollisionShape(), targetCollisionObj->getWorldTransform(), cb); - if (!cb.hasHit()) - { - // didn't hit the target. this could happen if point is already inside the collision box - return 0.f; - } - else - return (point - Misc::Convert::toOsg(cb.m_hitPointWorld)).length(); + // didn't hit the target. this could happen if point is already inside the collision box + return 0.f; } RayCastingResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, std::vector targets, int mask, int group) const @@ -293,7 +286,7 @@ namespace MWPhysics resultCallback.m_collisionFilterGroup = group; resultCallback.m_collisionFilterMask = mask; - mCollisionWorld->rayTest(btFrom, btTo, resultCallback); + mTaskScheduler->rayTest(btFrom, btTo, resultCallback); RayCastingResult result; result.mHit = resultCallback.hasHit(); @@ -319,7 +312,7 @@ namespace MWPhysics btTransform from_ (btrot, Misc::Convert::toBullet(from)); btTransform to_ (btrot, Misc::Convert::toBullet(to)); - mCollisionWorld->convexSweepTest(&shape, from_, to_, callback); + mTaskScheduler->convexSweepTest(&shape, from_, to_, callback); RayCastingResult result; result.mHit = callback.hasHit(); @@ -333,18 +326,15 @@ namespace MWPhysics bool PhysicsSystem::getLineOfSight(const MWWorld::ConstPtr &actor1, const MWWorld::ConstPtr &actor2) const { - const Actor* physactor1 = getActor(actor1); - const Actor* physactor2 = getActor(actor2); + const auto getWeakPtr = [&](const MWWorld::ConstPtr &ptr) -> std::weak_ptr + { + const auto found = mActors.find(ptr); + if (found != mActors.end()) + return { found->second }; + return {}; + }; - if (!physactor1 || !physactor2) - return false; - - osg::Vec3f pos1 (physactor1->getCollisionObjectPosition() + osg::Vec3f(0,0,physactor1->getHalfExtents().z() * 0.9)); // eye level - osg::Vec3f pos2 (physactor2->getCollisionObjectPosition() + osg::Vec3f(0,0,physactor2->getHalfExtents().z() * 0.9)); - - RayCastingResult result = castRay(pos1, pos2, MWWorld::ConstPtr(), std::vector(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door); - - return !result.mHit; + return mTaskScheduler->getLineOfSight(getWeakPtr(actor1), getWeakPtr(actor2)); } bool PhysicsSystem::isOnGround(const MWWorld::Ptr &actor) @@ -398,7 +388,7 @@ namespace MWPhysics const Object * physobject = getObject(object); if (!physobject) return osg::BoundingBox(); btVector3 min, max; - physobject->getCollisionObject()->getCollisionShape()->getAabb(physobject->getCollisionObject()->getWorldTransform(), min, max); + mTaskScheduler->getAabb(physobject->getCollisionObject(), min, max); return osg::BoundingBox(Misc::Convert::toOsg(min), Misc::Convert::toOsg(max)); } @@ -424,7 +414,7 @@ namespace MWPhysics ContactTestResultCallback resultCallback (me); resultCallback.m_collisionFilterGroup = collisionGroup; resultCallback.m_collisionFilterMask = collisionMask; - mCollisionWorld->contactTest(me, resultCallback); + mTaskScheduler->contactTest(me, resultCallback); return resultCallback.mResult; } @@ -442,7 +432,7 @@ namespace MWPhysics HeightField *heightfield = new HeightField(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject); mHeightFields[std::make_pair(x,y)] = heightfield; - mCollisionWorld->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap, + mTaskScheduler->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap, CollisionType_Actor|CollisionType_Projectile); } @@ -451,7 +441,7 @@ namespace MWPhysics HeightFieldMap::iterator heightfield = mHeightFields.find(std::make_pair(x,y)); if(heightfield != mHeightFields.end()) { - mCollisionWorld->removeCollisionObject(heightfield->second->getCollisionObject()); + mTaskScheduler->removeCollisionObject(heightfield->second->getCollisionObject()); delete heightfield->second; mHeightFields.erase(heightfield); } @@ -471,13 +461,13 @@ namespace MWPhysics if (!shapeInstance || !shapeInstance->getCollisionShape()) return; - auto obj = std::make_shared(ptr, shapeInstance, mCollisionWorld.get()); + auto obj = std::make_shared(ptr, shapeInstance, mTaskScheduler.get()); mObjects.emplace(ptr, obj); if (obj->isAnimated()) mAnimatedObjects.insert(obj.get()); - mCollisionWorld->addCollisionObject(obj->getCollisionObject(), collisionType, + mTaskScheduler->addCollisionObject(obj->getCollisionObject(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); } @@ -571,14 +561,14 @@ namespace MWPhysics { float scale = ptr.getCellRef().getScale(); found->second->setScale(scale); - mCollisionWorld->updateSingleAabb(found->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(found->second); return; } ActorMap::iterator foundActor = mActors.find(ptr); if (foundActor != mActors.end()) { foundActor->second->updateScale(); - mCollisionWorld->updateSingleAabb(foundActor->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(foundActor->second); return; } } @@ -589,7 +579,7 @@ namespace MWPhysics if (found != mObjects.end()) { found->second->setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude())); - mCollisionWorld->updateSingleAabb(found->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(found->second); return; } ActorMap::iterator foundActor = mActors.find(ptr); @@ -598,7 +588,7 @@ namespace MWPhysics if (!foundActor->second->isRotationallyInvariant()) { foundActor->second->updateRotation(); - mCollisionWorld->updateSingleAabb(foundActor->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(foundActor->second); } return; } @@ -610,14 +600,14 @@ namespace MWPhysics if (found != mObjects.end()) { found->second->setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3())); - mCollisionWorld->updateSingleAabb(found->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(found->second); return; } ActorMap::iterator foundActor = mActors.find(ptr); if (foundActor != mActors.end()) { foundActor->second->updatePosition(); - mCollisionWorld->updateSingleAabb(foundActor->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(foundActor->second); return; } } @@ -639,7 +629,7 @@ namespace MWPhysics if (!shape) return; - auto actor = std::make_shared(ptr, shape, mCollisionWorld.get()); + auto actor = std::make_shared(ptr, shape, mTaskScheduler.get()); mActors.emplace(ptr, std::move(actor)); } @@ -678,10 +668,8 @@ namespace MWPhysics mStandingCollisions.clear(); } - const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt) + const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation) { - mMovementResults.clear(); - mTimeAccum += dt; const int maxAllowedSteps = 20; @@ -689,100 +677,8 @@ namespace MWPhysics numSteps = std::min(numSteps, maxAllowedSteps); mTimeAccum -= numSteps * mPhysicsDt; - mActorsFrameData = prepareFrameData(); - bool advanceSimulation = (numSteps != 0); - if (advanceSimulation) - mWorldFrameData = std::make_unique(); - // update each actor position based on latest data - for (auto& data : mActorsFrameData) - data.updatePosition(); - - mMovementResults.clear(); - while (numSteps--) - { - for (auto& actorData : mActorsFrameData) - MovementSolver::move(actorData, mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData); - - // update actors position - for (auto& actorData : mActorsFrameData) - { - if(const auto actor = actorData.mActor.lock()) - { - if (actorData.mPosition != actorData.mActorRaw->getPosition()) - actorData.mPositionChanged = true; - actorData.mActorRaw->setPosition(actorData.mPosition); - } - } - } - - for (auto& actorData : mActorsFrameData) - { - // handle fall of actor - const float heightDiff = actorData.mPosition.z() - actorData.mOldHeight; - - const bool isStillOnGround = (advanceSimulation && actorData.mWasOnGround && actorData.mActorRaw->getOnGround()); - - if (isStillOnGround || actorData.mFlying || actorData.mSwimming || actorData.mSlowFall < 1) - actorData.mNeedLand = true; - else if (heightDiff < 0) - actorData.mFallHeight += heightDiff; - - // interpolate position - const float interpolationFactor = mTimeAccum / mPhysicsDt; - mMovementResults[actorData.mPtr] = actorData.mPosition * interpolationFactor + actorData.mActorRaw->getPreviousPosition() * (1.f - interpolationFactor); - - // update mechanics if actor jumped - if (actorData.mDidJump) - { - const bool isPlayer = (actorData.mPtr == MWMechanics::getPlayer()); - // Advance acrobatics and set flag for GetPCJumping - if (isPlayer) - { - actorData.mPtr.getClass().skillUsageSucceeded(actorData.mPtr, ESM::Skill::Acrobatics, 0); - MWBase::Environment::get().getWorld()->getPlayer().setJumping(true); - } - - // Decrease fatigue - if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState()) - { - const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); - const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); - const float normalizedEncumbrance = std::min(1.f, actorData.mPtr.getClass().getNormalizedEncumbrance(actorData.mPtr)); - const float fatigueDecrease = fFatigueJumpBase + normalizedEncumbrance * fFatigueJumpMult; - MWMechanics::DynamicStat fatigue = actorData.mPtr.getClass().getCreatureStats(actorData.mPtr).getFatigue(); - fatigue.setCurrent(fatigue.getCurrent() - fatigueDecrease); - actorData.mPtr.getClass().getCreatureStats(actorData.mPtr).setFatigue(fatigue); - } - actorData.mPtr.getClass().getMovementSettings(actorData.mPtr).mPosition[2] = 0; - } - - MWMechanics::CreatureStats& stats = actorData.mPtr.getClass().getCreatureStats(actorData.mPtr); - if (actorData.mNeedLand) - stats.land(actorData.mPtr == MWMechanics::getPlayer() && (actorData.mFlying || actorData.mSwimming)); - else if (actorData.mFallHeight < 0) - stats.addToFallHeight(-actorData.mFallHeight); - } - - // update actors aabb - for (const auto& actorData : mActorsFrameData) - if (actorData.mPositionChanged) - mCollisionWorld->updateSingleAabb(actorData.mActorRaw->getCollisionObject()); - - // update standing collisions map - if (advanceSimulation) - { - mStandingCollisions.clear(); - for (auto& actorData : mActorsFrameData) - { - if (!actorData.mStandingOn.isEmpty()) - mStandingCollisions[actorData.mPtr] = actorData.mStandingOn; - else - mStandingCollisions.erase(actorData.mPtr); - } - } - return mMovementResults; + return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(), mStandingCollisions, skipSimulation); } std::vector PhysicsSystem::prepareFrameData() @@ -840,7 +736,7 @@ namespace MWPhysics { auto obj = mObjects.find(animatedObject->getPtr()); assert(obj != mObjects.end()); - mCollisionWorld->updateSingleAabb(obj->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(obj->second); } #ifndef BT_NO_PROFILE @@ -854,7 +750,7 @@ namespace MWPhysics ObjectMap::iterator found = mObjects.find(object); if (found != mObjects.end()) if (found->second->animateCollisionShapes()) - mCollisionWorld->updateSingleAabb(found->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(found->second); } void PhysicsSystem::debugDraw() @@ -926,7 +822,7 @@ namespace MWPhysics { if (mWaterCollisionObject) { - mCollisionWorld->removeCollisionObject(mWaterCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get()); } if (!mWaterEnabled) @@ -938,7 +834,7 @@ namespace MWPhysics mWaterCollisionObject.reset(new btCollisionObject()); mWaterCollisionShape.reset(new btStaticPlaneShape(btVector3(0,0,1), mWaterHeight)); mWaterCollisionObject->setCollisionShape(mWaterCollisionShape.get()); - mCollisionWorld->addCollisionObject(mWaterCollisionObject.get(), CollisionType_Water, + mTaskScheduler->addCollisionObject(mWaterCollisionObject.get(), CollisionType_Water, CollisionType_Actor); } @@ -954,7 +850,7 @@ namespace MWPhysics const int mask = MWPhysics::CollisionType_Actor; const int group = 0xff; HasSphereCollisionCallback callback(bulletPosition, radius, object, mask, group); - mCollisionWorld->getBroadphase()->aabbTest(aabbMin, aabbMax, callback); + mTaskScheduler->aabbTest(aabbMin, aabbMax, callback); return callback.getResult(); } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index b9390e9de..e5ee925c4 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -193,7 +193,7 @@ namespace MWPhysics void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity); /// Apply all queued movements, then clear the list. - const PtrPositionList& applyQueuedMovement(float dt); + const PtrPositionList& applyQueuedMovement(float dt, bool skipSimulation); /// Clear the queued movements list without applying. void clearQueuedMovement(); @@ -245,6 +245,7 @@ namespace MWPhysics std::unique_ptr mCollisionConfiguration; std::unique_ptr mDispatcher; std::shared_ptr mCollisionWorld; + std::unique_ptr mTaskScheduler; std::unique_ptr mShapeManager; Resource::ResourceSystem* mResourceSystem; @@ -271,9 +272,6 @@ namespace MWPhysics using PtrVelocityList = std::vector>; PtrVelocityList mMovementQueue; - PtrPositionList mMovementResults; - std::unique_ptr mWorldFrameData; - std::vector mActorsFrameData; float mTimeAccum; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 273a5f302..38bafa61b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -144,7 +144,7 @@ namespace MWWorld const std::string& resourcePath, const std::string& userDataPath) : mResourceSystem(resourceSystem), mLocalScripts (mStore), mCells (mStore, mEsm), mSky (true), - mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), + mGodMode(false), mScriptsEnabled(true), mDiscardMovements(true), mContentFiles (contentFiles), mUserDataPath(userDataPath), mShouldUpdateNavigator(false), mActivationDistanceOverride (activationDistanceOverride), mStartCell(startCell), mDistanceToFacedObject(-1.f), mTeleportEnabled(true), @@ -932,6 +932,7 @@ namespace MWWorld void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { mPhysics->clearQueuedMovement(); + mDiscardMovements = true; if (changeEvent && mCurrentWorldSpace != cellName) { @@ -951,6 +952,7 @@ namespace MWWorld void World::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { mPhysics->clearQueuedMovement(); + mDiscardMovements = true; if (changeEvent && mCurrentWorldSpace != ESM::CellId::sDefaultWorldspace) { @@ -1499,7 +1501,8 @@ namespace MWWorld mProjectileManager->update(duration); - const auto results = mPhysics->applyQueuedMovement(duration); + const auto results = mPhysics->applyQueuedMovement(duration, mDiscardMovements); + mDiscardMovements = false; for(const auto& result : results) { diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 9ba24541d..c10c7ea5a 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -102,6 +102,7 @@ namespace MWWorld bool mSky; bool mGodMode; bool mScriptsEnabled; + bool mDiscardMovements; std::vector mContentFiles; std::string mUserDataPath; diff --git a/components/misc/barrier.hpp b/components/misc/barrier.hpp new file mode 100644 index 000000000..7259b8452 --- /dev/null +++ b/components/misc/barrier.hpp @@ -0,0 +1,51 @@ +#ifndef OPENMW_BARRIER_H +#define OPENMW_BARRIER_H + +#include +#include +#include + +namespace Misc +{ + /// @brief Synchronize several threads + class Barrier + { + public: + using BarrierCallback = std::function; + /// @param count number of threads to wait on + /// @param func callable to be executed once after all threads have met + Barrier(int count, BarrierCallback&& func) : mThreadCount(count), mRendezvousCount(0), mGeneration(0) + , mFunc(std::forward(func)) + {} + + /// @brief stop execution of threads until count distinct threads reach this point + void wait() + { + std::unique_lock lock(mMutex); + + ++mRendezvousCount; + const int currentGeneration = mGeneration; + if (mRendezvousCount == mThreadCount) + { + ++mGeneration; + mRendezvousCount = 0; + mFunc(); + mRendezvous.notify_all(); + } + else + { + mRendezvous.wait(lock, [&]() { return mGeneration != currentGeneration; }); + } + } + + private: + int mThreadCount; + int mRendezvousCount; + int mGeneration; + mutable std::mutex mMutex; + std::condition_variable mRendezvous; + BarrierCallback mFunc; + }; +} + +#endif diff --git a/files/settings-default.cfg b/files/settings-default.cfg index fab5fe569..3c6e736d8 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -916,3 +916,15 @@ object shadows = false # Allow shadows indoors. Due to limitations with Morrowind's data, only actors can cast shadows indoors, which some might feel is distracting. enable indoor shadows = true + +[Physics] +# how much background thread to use in the physics solver. 0 to disable (i.e solver run in the main thread) +async num threads = 0 + +# maintain a cache of lineofsight request in the bacground physics thread +# determines for how much frames an inactive lineofsight request should be kept updated in the cache +# -1 to disable (i.e the LOS will be calculated only on request) +lineofsight keep inactive cache = 0 + +# wether to defer aabb update till before collision detection +defer aabb update = true From ae3306c01920377c906fb66ad18eb47f1f92687f Mon Sep 17 00:00:00 2001 From: fredzio Date: Wed, 14 Oct 2020 22:26:21 +0200 Subject: [PATCH 188/224] Document async physics settings Add an option to the launcher Update changelog --- CHANGELOG.md | 1 + apps/launcher/advancedpage.cpp | 6 +++ .../reference/modding/settings/index.rst | 1 + .../reference/modding/settings/physics.rst | 37 +++++++++++++++++++ files/ui/advancedpage.ui | 30 +++++++++++++++ 5 files changed, 75 insertions(+) create mode 100644 docs/source/reference/modding/settings/physics.rst diff --git a/CHANGELOG.md b/CHANGELOG.md index 80253e99c..3d2f315aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ Feature #5524: Resume failed script execution after reload Feature #5525: Search fields tweaks (utf-8) Feature #5545: Option to allow stealing from an unconscious NPC during combat + Feature #5563: Run physics update in background thread Feature #5579: MCP SetAngle enhancement Feature #5610: Actors movement should be smoother Task #5480: Drop Qt4 support diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 2e929faf5..bd3f6979e 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -94,6 +94,9 @@ bool Launcher::AdvancedPage::loadSettings() unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); loadSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); loadSettingBool(enableNavigatorCheckBox, "enable", "Navigator"); + int numPhysicsThreads = mEngineSettings.getInt("async num threads", "Physics"); + if (numPhysicsThreads >= 0) + physicsThreadsSpinBox->setValue(numPhysicsThreads); } // Visuals @@ -208,6 +211,9 @@ void Launcher::AdvancedPage::saveSettings() mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); saveSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); saveSettingBool(enableNavigatorCheckBox, "enable", "Navigator"); + int numPhysicsThreads = physicsThreadsSpinBox->value(); + if (numPhysicsThreads != mEngineSettings.getInt("async num threads", "Physics")) + mEngineSettings.setInt("async num threads", "Physics", numPhysicsThreads); } // Visuals diff --git a/docs/source/reference/modding/settings/index.rst b/docs/source/reference/modding/settings/index.rst index a31ce0d53..2261fe8e1 100644 --- a/docs/source/reference/modding/settings/index.rst +++ b/docs/source/reference/modding/settings/index.rst @@ -57,3 +57,4 @@ The ranges included with each setting are the physically possible ranges, not re water windows navigator + physics diff --git a/docs/source/reference/modding/settings/physics.rst b/docs/source/reference/modding/settings/physics.rst new file mode 100644 index 000000000..59aba91aa --- /dev/null +++ b/docs/source/reference/modding/settings/physics.rst @@ -0,0 +1,37 @@ +Physics Settings +################ + +async num threads +----------------- + +:Type: integer +:Range: >= 0 +:Default: 0 + +Determines how many threads will be spawned to compute physics update in the background (that is, process actors movement). A value of 0 means that the update will be performed in the main thread. +A value greater than 1 requires the Bullet library be compiled with multithreading support. If that's not the case, a warning will be written in ``openmw.log`` and a value of 1 will be used. + +lineofsight keep inactive cache +------------------------------- + +:Type: integer +:Range: >= -1 +:Default: 0 + +The line of sight determines if 2 actors can see each other (without taking into account game mechanics such as invisibility or sneaking). It is used by some scripts (the getLOS function), by the AI (to determine if an actor should start combat or chase an opponent) and for functionnalities such as greetings or turning NPC head toward an object. +This parameters determine for how long a cache of request should be kept warm. It depends on :ref:`async num threads` being > 0, otherwise a value of -1 will be used. If a request is not found in the cache, it is always fulfilled immediately. In case Bullet is compiled without multithreading support, non-cached requests involve blocking the async thread(s), which might hurt performance. +A value of -1 means no caching. +A value of 0 means that for as long as a request is made (after the first one), it will be preemptively "refreshed" in the async thread, without blocking neither the main thread nor the async thread. +Any value > 0 is the number of frames for which the values are kept in cache even if the results was not requested again. +If Bullet is compiled with multithreading support, requests are non blocking, it is better to set this parameter to -1. + +defer aabb update +----------------- + +:Type: boolean +:Range: True/False +:Default: True + +Axis-aligned bounding box (aabb for short) are used by Bullet for collision detection. They should be updated anytime a physical object is modified (for instance moved) for collision detection to be correct. +This parameter control wether the update should be done as soon as the object is modified (the default), which involves blocking the async thread(s), or queue the modifications to update them as a batch before the collision detections. It depends on :ref:`async num threads` being > 0, otherwise it will be disabled. +Disabling this parameter is intended as an aid for debugging collisions detection issues. diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 3a91db791..6cb73e7ef 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -211,6 +211,36 @@ + + + + + + <html><head/><body><p>How many threads will be spawned to compute physics update in the background. A value of 0 means that the update will be performed in the main thread.</p><p>A value greater than 1 requires the Bullet library be compiled with multithreading support.</p></body></html> + + + Background physics threads + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + From b024518c180644d89ffff3db76f12bbe334dfef2 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Thu, 15 Oct 2020 11:12:23 +0200 Subject: [PATCH 189/224] Resolve 'shared_timed_mutex' is unavailable: introduced in macOS 10.12 --- CI/before_script.osx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 993de79fe..0eeef60a4 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -16,7 +16,7 @@ cmake \ -D CMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" \ -D CMAKE_C_FLAGS_RELEASE="-g -O0" \ -D CMAKE_CXX_FLAGS_RELEASE="-g -O0" \ --D CMAKE_OSX_DEPLOYMENT_TARGET="10.9" \ +-D CMAKE_OSX_DEPLOYMENT_TARGET="10.12" \ -D CMAKE_BUILD_TYPE=RELEASE \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_OPENMW=TRUE \ From 590635906b029f9bad4294d86d6d6c824cc89813 Mon Sep 17 00:00:00 2001 From: Chris Djali Date: Thu, 15 Oct 2020 21:02:57 +0100 Subject: [PATCH 190/224] Fix MSVC 2017 Resolves the regression introduced with Async Physics --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fecb589eb..cd1c7df6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -586,6 +586,10 @@ if (WIN32) set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") set_target_properties(osg-ffmpeg-videoplayer PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") + + if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920) + target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE) + endif() if (BUILD_BSATOOL) set_target_properties(bsatool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") From 978af12c2d45989e930805ea847d30407d12446e Mon Sep 17 00:00:00 2001 From: fredzio Date: Fri, 16 Oct 2020 19:28:49 +0200 Subject: [PATCH 191/224] Restore fall damage --- apps/openmw/mwphysics/mtphysics.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 9aff85359..a53a011f6 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -515,26 +515,27 @@ namespace MWPhysics mPreStepBarrier->wait(); int job = 0; - while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs) + while (mRemainingSteps && (job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs) { MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet); if(const auto actor = mActorsFrameData[job].mActor.lock()) - { - if (mRemainingSteps) - MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData); - else - { - auto& actorData = mActorsFrameData[job]; - handleFall(actorData, mAdvanceSimulation); - mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt); - } - } + MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData); } mPostStepBarrier->wait(); if (!mRemainingSteps) { + while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs) + { + if(const auto actor = mActorsFrameData[job].mActor.lock()) + { + auto& actorData = mActorsFrameData[job]; + handleFall(actorData, mAdvanceSimulation); + mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt); + } + } + if (mLOSCacheExpiry >= 0) refreshLOSCache(); mPostSimBarrier->wait(); From 8ca3c3b123daeb026552de39fdf5182fa0263b49 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 16 Oct 2020 22:18:54 +0400 Subject: [PATCH 192/224] Mark overrided methods by override keyword --- CMakeLists.txt | 4 + apps/launcher/maindialog.hpp | 2 +- apps/launcher/utils/lineedit.hpp | 2 +- apps/launcher/utils/textinputdialog.hpp | 2 +- apps/opencs/main.cpp | 2 +- apps/opencs/model/doc/savingstages.hpp | 48 +- apps/opencs/model/filter/andnode.hpp | 4 +- apps/opencs/model/filter/booleannode.hpp | 6 +- apps/opencs/model/filter/leafnode.hpp | 2 +- apps/opencs/model/filter/narynode.hpp | 4 +- apps/opencs/model/filter/notnode.hpp | 4 +- apps/opencs/model/filter/ornode.hpp | 4 +- apps/opencs/model/filter/textnode.hpp | 8 +- apps/opencs/model/filter/unarynode.hpp | 4 +- apps/opencs/model/filter/valuenode.hpp | 8 +- apps/opencs/model/prefs/boolsetting.hpp | 4 +- apps/opencs/model/prefs/coloursetting.hpp | 4 +- apps/opencs/model/prefs/doublesetting.hpp | 4 +- apps/opencs/model/prefs/enumsetting.hpp | 4 +- apps/opencs/model/prefs/intsetting.hpp | 4 +- apps/opencs/model/prefs/modifiersetting.hpp | 6 +- .../model/prefs/shortcuteventhandler.hpp | 2 +- apps/opencs/model/prefs/shortcutsetting.hpp | 6 +- apps/opencs/model/tools/birthsigncheck.hpp | 4 +- apps/opencs/model/tools/bodypartcheck.hpp | 4 +- apps/opencs/model/tools/classcheck.hpp | 4 +- apps/opencs/model/tools/enchantmentcheck.hpp | 4 +- apps/opencs/model/tools/factioncheck.hpp | 4 +- apps/opencs/model/tools/gmstcheck.hpp | 4 +- apps/opencs/model/tools/journalcheck.hpp | 4 +- apps/opencs/model/tools/magiceffectcheck.hpp | 4 +- apps/opencs/model/tools/mandatoryid.hpp | 4 +- apps/opencs/model/tools/mergeoperation.hpp | 2 +- apps/opencs/model/tools/mergestages.hpp | 36 +- apps/opencs/model/tools/pathgridcheck.hpp | 4 +- apps/opencs/model/tools/racecheck.hpp | 4 +- .../opencs/model/tools/referenceablecheck.hpp | 4 +- apps/opencs/model/tools/referencecheck.hpp | 4 +- apps/opencs/model/tools/regioncheck.hpp | 4 +- apps/opencs/model/tools/reportmodel.hpp | 10 +- apps/opencs/model/tools/scriptcheck.hpp | 8 +- apps/opencs/model/tools/searchstage.hpp | 4 +- apps/opencs/model/tools/skillcheck.hpp | 4 +- apps/opencs/model/tools/soundcheck.hpp | 4 +- apps/opencs/model/tools/soundgencheck.hpp | 4 +- apps/opencs/model/tools/spellcheck.hpp | 4 +- apps/opencs/model/tools/startscriptcheck.hpp | 4 +- apps/opencs/model/tools/topicinfocheck.hpp | 4 +- apps/opencs/model/world/collection.hpp | 46 +- apps/opencs/model/world/columnbase.hpp | 8 +- apps/opencs/model/world/columnimp.hpp | 508 +++++++-------- apps/opencs/model/world/commands.hpp | 38 +- apps/opencs/model/world/idtable.hpp | 31 +- apps/opencs/model/world/idtableproxymodel.hpp | 6 +- apps/opencs/model/world/idtree.hpp | 19 +- apps/opencs/model/world/infocollection.hpp | 6 +- .../model/world/infotableproxymodel.hpp | 10 +- .../model/world/nestedcoladapterimp.hpp | 278 ++++----- .../opencs/model/world/nestedidcollection.hpp | 18 +- .../model/world/nestedinfocollection.hpp | 18 +- .../model/world/nestedtableproxymodel.hpp | 20 +- .../opencs/model/world/nestedtablewrapper.hpp | 2 +- apps/opencs/model/world/record.hpp | 6 +- apps/opencs/model/world/refidadapterimp.hpp | 589 +++++++++--------- apps/opencs/model/world/refidcollection.hpp | 62 +- apps/opencs/model/world/refiddata.hpp | 18 +- apps/opencs/model/world/regionmap.hpp | 8 +- apps/opencs/model/world/resourcetable.hpp | 29 +- apps/opencs/model/world/scriptcontext.hpp | 12 +- apps/opencs/model/world/subcellcollection.hpp | 2 +- apps/opencs/model/world/tablemimedata.hpp | 2 +- apps/opencs/view/doc/loader.hpp | 2 +- apps/opencs/view/doc/newgame.hpp | 2 +- apps/opencs/view/doc/runlogsubview.hpp | 2 +- apps/opencs/view/doc/sizehint.hpp | 2 +- apps/opencs/view/doc/subview.hpp | 4 +- apps/opencs/view/doc/subviewfactoryimp.hpp | 4 +- apps/opencs/view/doc/view.hpp | 2 +- apps/opencs/view/filter/filterbox.hpp | 6 +- apps/opencs/view/prefs/contextmenulist.hpp | 4 +- apps/opencs/view/prefs/dialogue.hpp | 2 +- apps/opencs/view/prefs/pagebase.hpp | 2 +- apps/opencs/view/render/cameracontroller.hpp | 12 +- apps/opencs/view/render/cell.cpp | 2 +- apps/opencs/view/render/cellarrow.hpp | 2 +- apps/opencs/view/render/editmode.hpp | 10 +- apps/opencs/view/render/instancemode.hpp | 34 +- .../view/render/instanceselectionmode.hpp | 2 +- apps/opencs/view/render/lighting.cpp | 2 +- apps/opencs/view/render/lightingbright.hpp | 6 +- apps/opencs/view/render/lightingday.hpp | 6 +- apps/opencs/view/render/lightingnight.hpp | 6 +- apps/opencs/view/render/object.hpp | 2 +- apps/opencs/view/render/orbitcameramode.hpp | 6 +- .../view/render/pagedworldspacewidget.hpp | 64 +- apps/opencs/view/render/pathgrid.cpp | 2 +- apps/opencs/view/render/pathgrid.hpp | 2 +- apps/opencs/view/render/pathgridmode.hpp | 24 +- .../view/render/pathgridselectionmode.hpp | 2 +- apps/opencs/view/render/scenewidget.hpp | 4 +- apps/opencs/view/render/selectionmode.hpp | 2 +- apps/opencs/view/render/terrainstorage.hpp | 2 +- .../view/render/unpagedworldspacewidget.hpp | 57 +- apps/opencs/view/render/worldspacewidget.hpp | 12 +- apps/opencs/view/tools/merge.hpp | 2 +- apps/opencs/view/tools/reportsubview.hpp | 2 +- apps/opencs/view/tools/reporttable.cpp | 4 +- apps/opencs/view/tools/reporttable.hpp | 8 +- apps/opencs/view/tools/searchsubview.hpp | 6 +- apps/opencs/view/widget/coloreditor.hpp | 4 +- apps/opencs/view/widget/colorpickerpopup.hpp | 4 +- apps/opencs/view/widget/completerpopup.hpp | 2 +- apps/opencs/view/widget/droplineedit.hpp | 6 +- apps/opencs/view/widget/pushbutton.hpp | 6 +- apps/opencs/view/widget/scenetool.hpp | 2 +- apps/opencs/view/widget/scenetoolbar.hpp | 2 +- apps/opencs/view/widget/scenetoolmode.hpp | 6 +- apps/opencs/view/widget/scenetoolrun.hpp | 4 +- .../view/widget/scenetoolshapebrush.hpp | 8 +- .../view/widget/scenetooltexturebrush.hpp | 8 +- apps/opencs/view/widget/scenetooltoggle.hpp | 2 +- apps/opencs/view/widget/scenetooltoggle2.hpp | 2 +- apps/opencs/view/world/bodypartcreator.hpp | 6 +- apps/opencs/view/world/cellcreator.hpp | 12 +- apps/opencs/view/world/colordelegate.hpp | 8 +- apps/opencs/view/world/creator.hpp | 4 +- .../opencs/view/world/datadisplaydelegate.hpp | 8 +- apps/opencs/view/world/dialoguecreator.hpp | 6 +- apps/opencs/view/world/dialoguespinbox.hpp | 12 +- apps/opencs/view/world/dialoguesubview.hpp | 34 +- apps/opencs/view/world/dragrecordtable.hpp | 6 +- apps/opencs/view/world/enumdelegate.hpp | 22 +- .../world/extendedcommandconfigurator.hpp | 2 +- apps/opencs/view/world/genericcreator.hpp | 16 +- apps/opencs/view/world/globalcreator.hpp | 2 +- .../view/world/idcompletiondelegate.hpp | 12 +- apps/opencs/view/world/idtypedelegate.hpp | 2 +- apps/opencs/view/world/idvalidator.hpp | 2 +- apps/opencs/view/world/infocreator.hpp | 16 +- apps/opencs/view/world/nestedtable.hpp | 4 +- apps/opencs/view/world/pathgridcreator.hpp | 16 +- apps/opencs/view/world/previewsubview.hpp | 4 +- .../view/world/recordstatusdelegate.hpp | 2 +- .../view/world/referenceablecreator.hpp | 10 +- apps/opencs/view/world/referencecreator.hpp | 16 +- apps/opencs/view/world/regionmap.hpp | 10 +- apps/opencs/view/world/regionmapsubview.hpp | 2 +- apps/opencs/view/world/scenesubview.hpp | 8 +- apps/opencs/view/world/scriptedit.hpp | 16 +- apps/opencs/view/world/scripterrortable.hpp | 4 +- apps/opencs/view/world/scripthighlighter.hpp | 28 +- apps/opencs/view/world/scriptsubview.hpp | 6 +- apps/opencs/view/world/startscriptcreator.hpp | 16 +- apps/opencs/view/world/table.hpp | 8 +- apps/opencs/view/world/tablebottombox.hpp | 2 +- apps/opencs/view/world/tablesubview.hpp | 8 +- apps/opencs/view/world/util.hpp | 18 +- apps/opencs/view/world/vartypedelegate.hpp | 8 +- apps/openmw/engine.cpp | 2 +- apps/openmw/mwbase/windowmanager.hpp | 6 +- apps/openmw/mwclass/activator.hpp | 26 +- apps/openmw/mwclass/actor.hpp | 18 +- apps/openmw/mwclass/apparatus.hpp | 32 +- apps/openmw/mwclass/armor.hpp | 50 +- apps/openmw/mwclass/bodypart.hpp | 12 +- apps/openmw/mwclass/book.hpp | 38 +- apps/openmw/mwclass/clothing.hpp | 44 +- apps/openmw/mwclass/container.hpp | 46 +- apps/openmw/mwclass/creature.cpp | 6 +- apps/openmw/mwclass/creature.hpp | 78 +-- apps/openmw/mwclass/creaturelevlist.cpp | 6 +- apps/openmw/mwclass/creaturelevlist.hpp | 14 +- apps/openmw/mwclass/door.cpp | 6 +- apps/openmw/mwclass/door.hpp | 36 +- apps/openmw/mwclass/ingredient.hpp | 32 +- apps/openmw/mwclass/itemlevlist.hpp | 4 +- apps/openmw/mwclass/light.hpp | 48 +- apps/openmw/mwclass/lockpick.hpp | 40 +- apps/openmw/mwclass/misc.hpp | 36 +- apps/openmw/mwclass/npc.cpp | 6 +- apps/openmw/mwclass/npc.hpp | 97 ++- apps/openmw/mwclass/potion.hpp | 32 +- apps/openmw/mwclass/probe.hpp | 40 +- apps/openmw/mwclass/repair.hpp | 37 +- apps/openmw/mwclass/static.hpp | 12 +- apps/openmw/mwclass/weapon.hpp | 50 +- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 48 +- apps/openmw/mwdialogue/journalimp.hpp | 30 +- apps/openmw/mwdialogue/quest.hpp | 4 +- apps/openmw/mwgui/alchemywindow.hpp | 4 +- apps/openmw/mwgui/birth.hpp | 4 +- apps/openmw/mwgui/bookpage.cpp | 30 +- apps/openmw/mwgui/bookwindow.hpp | 4 +- apps/openmw/mwgui/class.hpp | 18 +- apps/openmw/mwgui/companionitemmodel.hpp | 4 +- apps/openmw/mwgui/companionwindow.hpp | 12 +- apps/openmw/mwgui/confirmationdialog.hpp | 2 +- apps/openmw/mwgui/console.cpp | 2 +- apps/openmw/mwgui/console.hpp | 14 +- apps/openmw/mwgui/container.hpp | 12 +- apps/openmw/mwgui/containeritemmodel.hpp | 18 +- apps/openmw/mwgui/debugwindow.hpp | 2 +- apps/openmw/mwgui/dialogue.cpp | 2 +- apps/openmw/mwgui/dialogue.hpp | 26 +- apps/openmw/mwgui/enchantingdialog.hpp | 14 +- apps/openmw/mwgui/formatting.hpp | 8 +- apps/openmw/mwgui/hud.cpp | 14 +- apps/openmw/mwgui/hud.hpp | 4 +- apps/openmw/mwgui/inventoryitemmodel.hpp | 16 +- apps/openmw/mwgui/inventorywindow.hpp | 10 +- apps/openmw/mwgui/itemmodel.hpp | 14 +- apps/openmw/mwgui/itemselection.hpp | 2 +- apps/openmw/mwgui/jailscreen.hpp | 4 +- apps/openmw/mwgui/journalviewmodel.cpp | 28 +- apps/openmw/mwgui/journalwindow.cpp | 6 +- apps/openmw/mwgui/journalwindow.hpp | 4 +- apps/openmw/mwgui/keyboardnavigation.hpp | 2 +- apps/openmw/mwgui/levelupdialog.hpp | 2 +- apps/openmw/mwgui/loadingscreen.cpp | 4 +- apps/openmw/mwgui/loadingscreen.hpp | 14 +- apps/openmw/mwgui/mainmenu.hpp | 8 +- apps/openmw/mwgui/mapwindow.hpp | 24 +- apps/openmw/mwgui/merchantrepair.hpp | 4 +- apps/openmw/mwgui/messagebox.hpp | 2 +- apps/openmw/mwgui/pickpocketitemmodel.hpp | 16 +- apps/openmw/mwgui/quickkeysmenu.hpp | 10 +- apps/openmw/mwgui/race.hpp | 6 +- apps/openmw/mwgui/recharge.hpp | 4 +- apps/openmw/mwgui/repair.hpp | 4 +- apps/openmw/mwgui/review.hpp | 6 +- apps/openmw/mwgui/savegamedialog.hpp | 4 +- apps/openmw/mwgui/screenfader.hpp | 2 +- apps/openmw/mwgui/scrollwindow.hpp | 4 +- apps/openmw/mwgui/settingswindow.hpp | 4 +- apps/openmw/mwgui/sortfilteritemmodel.hpp | 14 +- apps/openmw/mwgui/spellbuyingwindow.hpp | 10 +- apps/openmw/mwgui/spellcreationdialog.hpp | 16 +- apps/openmw/mwgui/spellicons.hpp | 4 +- apps/openmw/mwgui/spellwindow.hpp | 8 +- apps/openmw/mwgui/statswindow.hpp | 6 +- apps/openmw/mwgui/textinput.hpp | 4 +- apps/openmw/mwgui/tradeitemmodel.hpp | 8 +- apps/openmw/mwgui/tradewindow.hpp | 14 +- apps/openmw/mwgui/trainingwindow.hpp | 12 +- apps/openmw/mwgui/travelwindow.hpp | 4 +- apps/openmw/mwgui/waitdialog.hpp | 12 +- apps/openmw/mwgui/windowbase.hpp | 8 +- apps/openmw/mwgui/windowmanagerimp.hpp | 254 ++++---- apps/openmw/mwinput/bindingsmanager.cpp | 26 +- apps/openmw/mwinput/controllermanager.hpp | 10 +- apps/openmw/mwinput/inputmanagerimp.hpp | 52 +- apps/openmw/mwinput/keyboardmanager.hpp | 6 +- apps/openmw/mwinput/mousemanager.hpp | 8 +- apps/openmw/mwinput/sensormanager.hpp | 4 +- apps/openmw/mwmechanics/actors.cpp | 24 +- apps/openmw/mwmechanics/aicombataction.hpp | 36 +- apps/openmw/mwmechanics/character.hpp | 2 +- .../mwmechanics/mechanicsmanagerimp.hpp | 154 ++--- apps/openmw/mwmechanics/spellabsorption.cpp | 4 +- apps/openmw/mwmechanics/summoning.hpp | 4 +- apps/openmw/mwmechanics/typedaipackage.hpp | 2 +- .../closestnotmeconvexresultcallback.hpp | 2 +- .../closestnotmerayresultcallback.hpp | 2 +- .../mwphysics/contacttestresultcallback.hpp | 4 +- .../deepestnotmecontacttestresultcallback.hpp | 4 +- apps/openmw/mwphysics/physicssystem.hpp | 8 +- apps/openmw/mwrender/actoranimation.hpp | 8 +- apps/openmw/mwrender/animation.cpp | 56 +- apps/openmw/mwrender/animation.hpp | 10 +- apps/openmw/mwrender/bulletdebugdraw.hpp | 12 +- apps/openmw/mwrender/camera.cpp | 2 +- apps/openmw/mwrender/characterpreview.cpp | 6 +- apps/openmw/mwrender/characterpreview.hpp | 6 +- apps/openmw/mwrender/creatureanimation.hpp | 32 +- apps/openmw/mwrender/globalmap.cpp | 4 +- apps/openmw/mwrender/landmanager.hpp | 2 +- apps/openmw/mwrender/localmap.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 8 +- apps/openmw/mwrender/npcanimation.hpp | 44 +- apps/openmw/mwrender/objectpaging.cpp | 18 +- apps/openmw/mwrender/objectpaging.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 10 +- apps/openmw/mwrender/renderingmanager.hpp | 2 +- apps/openmw/mwrender/rotatecontroller.hpp | 2 +- apps/openmw/mwrender/sky.cpp | 66 +- apps/openmw/mwrender/terrainstorage.hpp | 8 +- apps/openmw/mwrender/util.cpp | 2 +- apps/openmw/mwrender/util.hpp | 2 +- apps/openmw/mwrender/water.cpp | 10 +- apps/openmw/mwrender/weaponanimation.hpp | 2 +- apps/openmw/mwscript/aiextensions.cpp | 38 +- apps/openmw/mwscript/animationextensions.cpp | 6 +- apps/openmw/mwscript/cellextensions.cpp | 20 +- apps/openmw/mwscript/compilercontext.hpp | 12 +- apps/openmw/mwscript/containerextensions.cpp | 16 +- apps/openmw/mwscript/controlextensions.cpp | 22 +- apps/openmw/mwscript/dialogueextensions.cpp | 30 +- apps/openmw/mwscript/guiextensions.cpp | 22 +- apps/openmw/mwscript/interpretercontext.hpp | 72 +-- apps/openmw/mwscript/miscextensions.cpp | 160 ++--- apps/openmw/mwscript/scriptmanagerimp.hpp | 12 +- apps/openmw/mwscript/skyextensions.cpp | 16 +- apps/openmw/mwscript/soundextensions.cpp | 18 +- apps/openmw/mwscript/statsextensions.cpp | 104 ++-- .../mwscript/transformationextensions.cpp | 44 +- apps/openmw/mwscript/userextensions.cpp | 8 +- apps/openmw/mwsound/movieaudiofactory.cpp | 4 +- apps/openmw/mwsound/movieaudiofactory.hpp | 2 +- apps/openmw/mwsound/openal_output.hpp | 54 +- apps/openmw/mwsound/soundmanagerimp.hpp | 68 +- apps/openmw/mwstate/statemanagerimp.hpp | 34 +- apps/openmw/mwworld/actionalchemy.hpp | 2 +- apps/openmw/mwworld/actionapply.hpp | 4 +- apps/openmw/mwworld/actiondoor.hpp | 2 +- apps/openmw/mwworld/actioneat.hpp | 2 +- apps/openmw/mwworld/actionequip.hpp | 2 +- apps/openmw/mwworld/actionharvest.hpp | 2 +- apps/openmw/mwworld/actionopen.hpp | 2 +- apps/openmw/mwworld/actionread.hpp | 2 +- apps/openmw/mwworld/actionrepair.hpp | 2 +- apps/openmw/mwworld/actionsoulgem.hpp | 2 +- apps/openmw/mwworld/actiontake.hpp | 2 +- apps/openmw/mwworld/actiontalk.hpp | 2 +- apps/openmw/mwworld/actionteleport.hpp | 2 +- apps/openmw/mwworld/actiontrap.hpp | 2 +- apps/openmw/mwworld/cellpreloader.cpp | 10 +- apps/openmw/mwworld/cells.cpp | 2 +- apps/openmw/mwworld/esmloader.hpp | 2 +- apps/openmw/mwworld/failedaction.hpp | 2 +- apps/openmw/mwworld/inventorystore.hpp | 18 +- apps/openmw/mwworld/livecellref.hpp | 4 +- apps/openmw/mwworld/nullaction.hpp | 4 +- apps/openmw/mwworld/projectilemanager.cpp | 2 +- apps/openmw/mwworld/scene.cpp | 2 +- apps/openmw/mwworld/store.hpp | 50 +- apps/openmw/mwworld/worldimp.cpp | 6 +- apps/wizard/componentselectionpage.hpp | 6 +- apps/wizard/conclusionpage.hpp | 4 +- apps/wizard/existinginstallationpage.hpp | 8 +- apps/wizard/importpage.hpp | 2 +- apps/wizard/installationpage.hpp | 6 +- apps/wizard/installationtargetpage.hpp | 6 +- apps/wizard/intropage.hpp | 2 +- apps/wizard/languageselectionpage.hpp | 4 +- apps/wizard/mainwizard.hpp | 4 +- apps/wizard/methodselectionpage.hpp | 2 +- components/bsa/compressedbsafile.hpp | 6 +- .../bullethelpers/processtrianglecallback.hpp | 2 +- components/compiler/controlparser.hpp | 10 +- components/compiler/declarationparser.hpp | 10 +- components/compiler/discardparser.hpp | 12 +- components/compiler/exprparser.hpp | 14 +- components/compiler/fileparser.hpp | 12 +- components/compiler/junkparser.hpp | 12 +- components/compiler/lineparser.hpp | 20 +- components/compiler/nullerrorhandler.hpp | 4 +- components/compiler/quickfileparser.hpp | 10 +- components/compiler/scriptparser.hpp | 12 +- components/compiler/skipparser.hpp | 12 +- components/compiler/streamerrorhandler.hpp | 4 +- components/compiler/stringparser.hpp | 10 +- .../contentselector/model/contentmodel.hpp | 22 +- .../contentselector/model/modelitem.hpp | 2 +- components/contentselector/view/combobox.hpp | 2 +- components/debug/debugging.hpp | 2 +- components/debug/gldebug.hpp | 2 +- components/esm/variantimp.hpp | 44 +- components/esmterrain/storage.hpp | 20 +- components/files/constrainedfilestream.cpp | 6 +- components/interpreter/controlopcodes.hpp | 10 +- components/interpreter/genericopcodes.hpp | 14 +- components/interpreter/localopcodes.hpp | 40 +- components/interpreter/mathopcodes.hpp | 12 +- components/interpreter/miscopcodes.hpp | 10 +- components/myguiplatform/myguidatamanager.hpp | 10 +- components/myguiplatform/myguiloglistener.hpp | 8 +- .../myguiplatform/myguirendermanager.cpp | 14 +- .../myguiplatform/myguirendermanager.hpp | 24 +- components/myguiplatform/myguitexture.hpp | 28 +- components/myguiplatform/scalinglayer.cpp | 8 +- components/nif/base.hpp | 12 +- components/nif/controlled.hpp | 24 +- components/nif/controller.hpp | 40 +- components/nif/data.hpp | 38 +- components/nif/effect.hpp | 12 +- components/nif/extra.hpp | 20 +- components/nif/node.hpp | 34 +- components/nif/property.hpp | 22 +- components/nifosg/controller.hpp | 30 +- components/nifosg/nifloader.cpp | 2 +- components/nifosg/particle.hpp | 34 +- components/resource/bulletshapemanager.cpp | 2 +- components/resource/bulletshapemanager.hpp | 6 +- components/resource/imagemanager.hpp | 2 +- components/resource/keyframemanager.hpp | 2 +- components/resource/niffilemanager.hpp | 2 +- components/resource/resourcemanager.hpp | 10 +- components/resource/scenemanager.cpp | 14 +- components/resource/stats.cpp | 2 +- components/resource/stats.hpp | 4 +- components/sceneutil/attach.cpp | 8 +- components/sceneutil/clone.hpp | 4 +- components/sceneutil/controller.hpp | 12 +- components/sceneutil/lightcontroller.hpp | 2 +- components/sceneutil/lightmanager.cpp | 32 +- components/sceneutil/lightmanager.hpp | 2 +- components/sceneutil/morphgeometry.hpp | 10 +- components/sceneutil/mwshadowtechnique.cpp | 4 +- components/sceneutil/mwshadowtechnique.hpp | 24 +- components/sceneutil/optimizer.cpp | 66 +- components/sceneutil/optimizer.hpp | 30 +- .../sceneutil/positionattitudetransform.hpp | 9 +- components/sceneutil/riggeometry.hpp | 12 +- components/sceneutil/skeleton.cpp | 2 +- components/sceneutil/skeleton.hpp | 6 +- components/sceneutil/statesetupdater.hpp | 6 +- components/sceneutil/unrefqueue.hpp | 2 +- components/sceneutil/util.cpp | 2 +- components/sceneutil/util.hpp | 4 +- components/sceneutil/visitor.hpp | 28 +- components/sceneutil/waterutil.cpp | 2 +- components/sdlutil/sdlgraphicswindow.hpp | 36 +- components/shader/shadervisitor.hpp | 6 +- components/terrain/chunkmanager.hpp | 2 +- components/terrain/compositemaprenderer.hpp | 2 +- components/terrain/quadtreenode.hpp | 2 +- components/terrain/quadtreeworld.cpp | 4 +- components/terrain/terraindrawable.hpp | 14 +- components/terrain/terraingrid.cpp | 2 +- components/terrain/terraingrid.hpp | 8 +- components/terrain/texturemanager.hpp | 2 +- components/terrain/viewdata.hpp | 2 +- components/terrain/world.hpp | 2 +- components/vfs/bsaarchive.hpp | 4 +- components/vfs/filesystemarchive.hpp | 4 +- components/widgets/fontwrapper.hpp | 4 +- extern/oics/tinyxml.h | 106 ++-- extern/osgQt/GraphicsWindowQt | 48 +- extern/osgQt/GraphicsWindowQt.cpp | 10 +- .../DebugUtils/Include/DebugDraw.h | 10 +- .../Detour/Source/DetourNavMeshQuery.cpp | 4 +- 441 files changed, 3661 insertions(+), 3673 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fecb589eb..29600550f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,6 +431,10 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.6 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.6) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-but-set-parameter") endif() + + if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 5.0) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override") + endif() elseif (MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:MULTIPLE") endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index d87a43100..214d31dd4 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -84,7 +84,7 @@ namespace Launcher inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); } bool startProgram(const QString &name, const QStringList &arguments, bool detached = false); - void closeEvent(QCloseEvent *event); + void closeEvent(QCloseEvent *event) override; PlayPage *mPlayPage; GraphicsPage *mGraphicsPage; diff --git a/apps/launcher/utils/lineedit.hpp b/apps/launcher/utils/lineedit.hpp index 2dd7da32b..50da73045 100644 --- a/apps/launcher/utils/lineedit.hpp +++ b/apps/launcher/utils/lineedit.hpp @@ -27,7 +27,7 @@ public: LineEdit(QWidget *parent = 0); protected: - void resizeEvent(QResizeEvent *); + void resizeEvent(QResizeEvent *) override; private slots: void updateClearButton(const QString &text); diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index 9eb9c717d..a9353956a 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -21,7 +21,7 @@ namespace Launcher inline LineEdit *lineEdit() { return mLineEdit; } void setOkButtonEnabled(bool enabled); - int exec(); + int exec() override; private: diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index 0473291ce..d1d4944cf 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -22,7 +22,7 @@ class Application : public QApplication { private: - bool notify (QObject *receiver, QEvent *event) + bool notify (QObject *receiver, QEvent *event) override { try { diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 64afd0dd8..d3a0cc9b3 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -37,10 +37,10 @@ namespace CSMDoc OpenSaveStage (Document& document, SavingState& state, bool projectFile); ///< \param projectFile Saving the project file instead of the content file. - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -55,10 +55,10 @@ namespace CSMDoc WriteHeaderStage (Document& document, SavingState& state, bool simple); ///< \param simple Simplified header (used for project files). - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -75,10 +75,10 @@ namespace CSMDoc WriteCollectionStage (const CollectionT& collection, SavingState& state, CSMWorld::Scope scope = CSMWorld::Scope_Content); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -125,10 +125,10 @@ namespace CSMDoc WriteDialogueCollectionStage (Document& document, SavingState& state, bool journal); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -142,10 +142,10 @@ namespace CSMDoc WriteRefIdCollectionStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -159,10 +159,10 @@ namespace CSMDoc CollectionReferencesStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -175,10 +175,10 @@ namespace CSMDoc WriteCellCollectionStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -192,10 +192,10 @@ namespace CSMDoc WritePathgridCollectionStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -209,10 +209,10 @@ namespace CSMDoc WriteLandCollectionStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -226,10 +226,10 @@ namespace CSMDoc WriteLandTextureCollectionStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -241,10 +241,10 @@ namespace CSMDoc CloseSaveStage (SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -257,10 +257,10 @@ namespace CSMDoc FinalSavingStage (Document& document, SavingState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, Messages& messages); + void perform (int stage, Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/filter/andnode.hpp b/apps/opencs/model/filter/andnode.hpp index 56d1d7948..ab2c3ea99 100644 --- a/apps/opencs/model/filter/andnode.hpp +++ b/apps/opencs/model/filter/andnode.hpp @@ -11,8 +11,8 @@ namespace CSMFilter AndNode (const std::vector >& nodes); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const; + bool test (const CSMWorld::IdTableBase& table, int row, + const std::map& columns) const override; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping }; diff --git a/apps/opencs/model/filter/booleannode.hpp b/apps/opencs/model/filter/booleannode.hpp index 32206b575..bed6cbeb0 100644 --- a/apps/opencs/model/filter/booleannode.hpp +++ b/apps/opencs/model/filter/booleannode.hpp @@ -13,12 +13,12 @@ namespace CSMFilter BooleanNode (bool true_); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const; + bool test (const CSMWorld::IdTableBase& table, int row, + const std::map& columns) const override; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping - virtual std::string toString (bool numericColumns) const; + std::string toString (bool numericColumns) const override; ///< Return a string that represents this node. /// /// \param numericColumns Use numeric IDs instead of string to represent columns. diff --git a/apps/opencs/model/filter/leafnode.hpp b/apps/opencs/model/filter/leafnode.hpp index 2f3d91070..d27bdcfe8 100644 --- a/apps/opencs/model/filter/leafnode.hpp +++ b/apps/opencs/model/filter/leafnode.hpp @@ -11,7 +11,7 @@ namespace CSMFilter { public: - virtual std::vector getReferencedColumns() const; + std::vector getReferencedColumns() const override; ///< Return a list of the IDs of the columns referenced by this node. The column mapping /// passed into test as columns must contain all columns listed here. }; diff --git a/apps/opencs/model/filter/narynode.hpp b/apps/opencs/model/filter/narynode.hpp index 1cd93e62e..231e38e13 100644 --- a/apps/opencs/model/filter/narynode.hpp +++ b/apps/opencs/model/filter/narynode.hpp @@ -21,11 +21,11 @@ namespace CSMFilter const Node& operator[] (int index) const; - virtual std::vector getReferencedColumns() const; + std::vector getReferencedColumns() const override; ///< Return a list of the IDs of the columns referenced by this node. The column mapping /// passed into test as columns must contain all columns listed here. - virtual std::string toString (bool numericColumns) const; + std::string toString (bool numericColumns) const override; ///< Return a string that represents this node. /// /// \param numericColumns Use numeric IDs instead of string to represent columns. diff --git a/apps/opencs/model/filter/notnode.hpp b/apps/opencs/model/filter/notnode.hpp index e3c57cede..5b15163d9 100644 --- a/apps/opencs/model/filter/notnode.hpp +++ b/apps/opencs/model/filter/notnode.hpp @@ -11,8 +11,8 @@ namespace CSMFilter NotNode (std::shared_ptr child); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const; + bool test (const CSMWorld::IdTableBase& table, int row, + const std::map& columns) const override; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping }; diff --git a/apps/opencs/model/filter/ornode.hpp b/apps/opencs/model/filter/ornode.hpp index b89da4e75..61115b3d9 100644 --- a/apps/opencs/model/filter/ornode.hpp +++ b/apps/opencs/model/filter/ornode.hpp @@ -11,8 +11,8 @@ namespace CSMFilter OrNode (const std::vector >& nodes); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const; + bool test (const CSMWorld::IdTableBase& table, int row, + const std::map& columns) const override; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping }; diff --git a/apps/opencs/model/filter/textnode.hpp b/apps/opencs/model/filter/textnode.hpp index 60ead85de..0e7a0e4f5 100644 --- a/apps/opencs/model/filter/textnode.hpp +++ b/apps/opencs/model/filter/textnode.hpp @@ -14,16 +14,16 @@ namespace CSMFilter TextNode (int columnId, const std::string& text); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const; + bool test (const CSMWorld::IdTableBase& table, int row, + const std::map& columns) const override; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping - virtual std::vector getReferencedColumns() const; + std::vector getReferencedColumns() const override; ///< Return a list of the IDs of the columns referenced by this node. The column mapping /// passed into test as columns must contain all columns listed here. - virtual std::string toString (bool numericColumns) const; + std::string toString (bool numericColumns) const override; ///< Return a string that represents this node. /// /// \param numericColumns Use numeric IDs instead of string to represent columns. diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index cbee4e0ba..39326d167 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -18,11 +18,11 @@ namespace CSMFilter Node& getChild(); - virtual std::vector getReferencedColumns() const; + std::vector getReferencedColumns() const override; ///< Return a list of the IDs of the columns referenced by this node. The column mapping /// passed into test as columns must contain all columns listed here. - virtual std::string toString (bool numericColumns) const; + std::string toString (bool numericColumns) const override; ///< Return a string that represents this node. /// /// \param numericColumns Use numeric IDs instead of string to represent columns. diff --git a/apps/opencs/model/filter/valuenode.hpp b/apps/opencs/model/filter/valuenode.hpp index 5b7ffec4e..339e4948a 100644 --- a/apps/opencs/model/filter/valuenode.hpp +++ b/apps/opencs/model/filter/valuenode.hpp @@ -27,16 +27,16 @@ namespace CSMFilter ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const; + bool test (const CSMWorld::IdTableBase& table, int row, + const std::map& columns) const override; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping - virtual std::vector getReferencedColumns() const; + std::vector getReferencedColumns() const override; ///< Return a list of the IDs of the columns referenced by this node. The column mapping /// passed into test as columns must contain all columns listed here. - virtual std::string toString (bool numericColumns) const; + std::string toString (bool numericColumns) const override; ///< Return a string that represents this node. /// /// \param numericColumns Use numeric IDs instead of string to represent columns. diff --git a/apps/opencs/model/prefs/boolsetting.hpp b/apps/opencs/model/prefs/boolsetting.hpp index 37c018d14..941cb5037 100644 --- a/apps/opencs/model/prefs/boolsetting.hpp +++ b/apps/opencs/model/prefs/boolsetting.hpp @@ -23,9 +23,9 @@ namespace CSMPrefs BoolSetting& setTooltip (const std::string& tooltip); /// Return label, input widget. - virtual std::pair makeWidgets (QWidget *parent); + std::pair makeWidgets (QWidget *parent) override; - virtual void updateWidget(); + void updateWidget() override; private slots: diff --git a/apps/opencs/model/prefs/coloursetting.hpp b/apps/opencs/model/prefs/coloursetting.hpp index e892b21d6..4a814c0e2 100644 --- a/apps/opencs/model/prefs/coloursetting.hpp +++ b/apps/opencs/model/prefs/coloursetting.hpp @@ -29,9 +29,9 @@ namespace CSMPrefs ColourSetting& setTooltip (const std::string& tooltip); /// Return label, input widget. - virtual std::pair makeWidgets (QWidget *parent); + std::pair makeWidgets (QWidget *parent) override; - virtual void updateWidget(); + void updateWidget() override; private slots: diff --git a/apps/opencs/model/prefs/doublesetting.hpp b/apps/opencs/model/prefs/doublesetting.hpp index 4d297409b..47886e446 100644 --- a/apps/opencs/model/prefs/doublesetting.hpp +++ b/apps/opencs/model/prefs/doublesetting.hpp @@ -36,9 +36,9 @@ namespace CSMPrefs DoubleSetting& setTooltip (const std::string& tooltip); /// Return label, input widget. - virtual std::pair makeWidgets (QWidget *parent); + std::pair makeWidgets (QWidget *parent) override; - virtual void updateWidget(); + void updateWidget() override; private slots: diff --git a/apps/opencs/model/prefs/enumsetting.hpp b/apps/opencs/model/prefs/enumsetting.hpp index b01635cdf..235f6adc3 100644 --- a/apps/opencs/model/prefs/enumsetting.hpp +++ b/apps/opencs/model/prefs/enumsetting.hpp @@ -54,9 +54,9 @@ namespace CSMPrefs EnumSetting& addValue (const std::string& value, const std::string& tooltip); /// Return label, input widget. - virtual std::pair makeWidgets (QWidget *parent); + std::pair makeWidgets (QWidget *parent) override; - virtual void updateWidget(); + void updateWidget() override; private slots: diff --git a/apps/opencs/model/prefs/intsetting.hpp b/apps/opencs/model/prefs/intsetting.hpp index ee0989d83..f18213b77 100644 --- a/apps/opencs/model/prefs/intsetting.hpp +++ b/apps/opencs/model/prefs/intsetting.hpp @@ -32,9 +32,9 @@ namespace CSMPrefs IntSetting& setTooltip (const std::string& tooltip); /// Return label, input widget. - virtual std::pair makeWidgets (QWidget *parent); + std::pair makeWidgets (QWidget *parent) override; - virtual void updateWidget(); + void updateWidget() override; private slots: diff --git a/apps/opencs/model/prefs/modifiersetting.hpp b/apps/opencs/model/prefs/modifiersetting.hpp index 2c6a45b5a..977badb8d 100644 --- a/apps/opencs/model/prefs/modifiersetting.hpp +++ b/apps/opencs/model/prefs/modifiersetting.hpp @@ -19,13 +19,13 @@ namespace CSMPrefs ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, const std::string& label); - virtual std::pair makeWidgets(QWidget* parent); + std::pair makeWidgets(QWidget* parent) override; - virtual void updateWidget(); + void updateWidget() override; protected: - bool eventFilter(QObject* target, QEvent* event); + bool eventFilter(QObject* target, QEvent* event) override; private: diff --git a/apps/opencs/model/prefs/shortcuteventhandler.hpp b/apps/opencs/model/prefs/shortcuteventhandler.hpp index 6a7ba2522..700b977fd 100644 --- a/apps/opencs/model/prefs/shortcuteventhandler.hpp +++ b/apps/opencs/model/prefs/shortcuteventhandler.hpp @@ -27,7 +27,7 @@ namespace CSMPrefs protected: - bool eventFilter(QObject* watched, QEvent* event); + bool eventFilter(QObject* watched, QEvent* event) override; private: diff --git a/apps/opencs/model/prefs/shortcutsetting.hpp b/apps/opencs/model/prefs/shortcutsetting.hpp index c388305a6..a0c588b42 100644 --- a/apps/opencs/model/prefs/shortcutsetting.hpp +++ b/apps/opencs/model/prefs/shortcutsetting.hpp @@ -19,13 +19,13 @@ namespace CSMPrefs ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, const std::string& label); - virtual std::pair makeWidgets(QWidget* parent); + std::pair makeWidgets(QWidget* parent) override; - virtual void updateWidget(); + void updateWidget() override; protected: - bool eventFilter(QObject* target, QEvent* event); + bool eventFilter(QObject* target, QEvent* event) override; private: diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index 9001c524c..498894f88 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -22,10 +22,10 @@ namespace CSMTools BirthsignCheckStage (const CSMWorld::IdCollection &birthsigns, const CSMWorld::Resources &textures); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/bodypartcheck.hpp b/apps/opencs/model/tools/bodypartcheck.hpp index 5c8ae2929..2c379bd07 100644 --- a/apps/opencs/model/tools/bodypartcheck.hpp +++ b/apps/opencs/model/tools/bodypartcheck.hpp @@ -25,10 +25,10 @@ namespace CSMTools const CSMWorld::Resources &meshes, const CSMWorld::IdCollection &races ); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform( int stage, CSMDoc::Messages &messages ); + void perform(int stage, CSMDoc::Messages &messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/classcheck.hpp b/apps/opencs/model/tools/classcheck.hpp index ba0a07047..a78c2eb97 100644 --- a/apps/opencs/model/tools/classcheck.hpp +++ b/apps/opencs/model/tools/classcheck.hpp @@ -19,10 +19,10 @@ namespace CSMTools ClassCheckStage (const CSMWorld::IdCollection& classes); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/enchantmentcheck.hpp b/apps/opencs/model/tools/enchantmentcheck.hpp index 3bd85326f..e9c8b9eec 100644 --- a/apps/opencs/model/tools/enchantmentcheck.hpp +++ b/apps/opencs/model/tools/enchantmentcheck.hpp @@ -19,10 +19,10 @@ namespace CSMTools EnchantmentCheckStage (const CSMWorld::IdCollection& enchantments); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; diff --git a/apps/opencs/model/tools/factioncheck.hpp b/apps/opencs/model/tools/factioncheck.hpp index b26d19717..d281c1b41 100644 --- a/apps/opencs/model/tools/factioncheck.hpp +++ b/apps/opencs/model/tools/factioncheck.hpp @@ -19,10 +19,10 @@ namespace CSMTools FactionCheckStage (const CSMWorld::IdCollection& factions); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/gmstcheck.hpp b/apps/opencs/model/tools/gmstcheck.hpp index 27bd61317..2c12a8607 100644 --- a/apps/opencs/model/tools/gmstcheck.hpp +++ b/apps/opencs/model/tools/gmstcheck.hpp @@ -16,10 +16,10 @@ namespace CSMTools GmstCheckStage(const CSMWorld::IdCollection& gameSettings); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform(int stage, CSMDoc::Messages& messages); + void perform(int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages private: diff --git a/apps/opencs/model/tools/journalcheck.hpp b/apps/opencs/model/tools/journalcheck.hpp index 661edcaef..b63127b52 100644 --- a/apps/opencs/model/tools/journalcheck.hpp +++ b/apps/opencs/model/tools/journalcheck.hpp @@ -18,10 +18,10 @@ namespace CSMTools JournalCheckStage(const CSMWorld::IdCollection& journals, const CSMWorld::InfoCollection& journalInfos); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform(int stage, CSMDoc::Messages& messages); + void perform(int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages private: diff --git a/apps/opencs/model/tools/magiceffectcheck.hpp b/apps/opencs/model/tools/magiceffectcheck.hpp index a52723b0f..4b2c24cc7 100644 --- a/apps/opencs/model/tools/magiceffectcheck.hpp +++ b/apps/opencs/model/tools/magiceffectcheck.hpp @@ -32,9 +32,9 @@ namespace CSMTools const CSMWorld::Resources &icons, const CSMWorld::Resources &textures); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages &messages); + void perform (int stage, CSMDoc::Messages &messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/mandatoryid.hpp b/apps/opencs/model/tools/mandatoryid.hpp index 86015c982..9d069a2da 100644 --- a/apps/opencs/model/tools/mandatoryid.hpp +++ b/apps/opencs/model/tools/mandatoryid.hpp @@ -27,10 +27,10 @@ namespace CSMTools MandatoryIdStage (const CSMWorld::CollectionBase& idCollection, const CSMWorld::UniversalId& collectionId, const std::vector& ids); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/mergeoperation.hpp b/apps/opencs/model/tools/mergeoperation.hpp index 733fc8eba..427967190 100644 --- a/apps/opencs/model/tools/mergeoperation.hpp +++ b/apps/opencs/model/tools/mergeoperation.hpp @@ -31,7 +31,7 @@ namespace CSMTools protected slots: - virtual void operationDone(); + void operationDone() override; signals: diff --git a/apps/opencs/model/tools/mergestages.hpp b/apps/opencs/model/tools/mergestages.hpp index 4b41c5a04..bcb3fe2ad 100644 --- a/apps/opencs/model/tools/mergestages.hpp +++ b/apps/opencs/model/tools/mergestages.hpp @@ -22,10 +22,10 @@ namespace CSMTools StartMergeStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -38,10 +38,10 @@ namespace CSMTools FinishMergedDocumentStage (MergeState& state, ToUTF8::FromType encoding); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -55,10 +55,10 @@ namespace CSMTools MergeIdCollectionStage (MergeState& state, Collection& (CSMWorld::Data::*accessor)()); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -93,10 +93,10 @@ namespace CSMTools MergeRefIdsStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -109,10 +109,10 @@ namespace CSMTools MergeReferencesStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -125,10 +125,10 @@ namespace CSMTools PopulateLandTexturesMergeStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -140,10 +140,10 @@ namespace CSMTools MergeLandStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -157,10 +157,10 @@ namespace CSMTools FixLandsAndLandTexturesMergeStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; @@ -174,10 +174,10 @@ namespace CSMTools CleanupLandTexturesMergeStage (MergeState& state); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/pathgridcheck.hpp b/apps/opencs/model/tools/pathgridcheck.hpp index 3e2fdd0ab..212637fd4 100644 --- a/apps/opencs/model/tools/pathgridcheck.hpp +++ b/apps/opencs/model/tools/pathgridcheck.hpp @@ -32,9 +32,9 @@ namespace CSMTools PathgridCheckStage (const CSMWorld::SubCellCollection >& pathgrids); - virtual int setup(); + int setup() override; - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; }; } diff --git a/apps/opencs/model/tools/racecheck.hpp b/apps/opencs/model/tools/racecheck.hpp index 55c283611..7c70f13b0 100644 --- a/apps/opencs/model/tools/racecheck.hpp +++ b/apps/opencs/model/tools/racecheck.hpp @@ -24,10 +24,10 @@ namespace CSMTools RaceCheckStage (const CSMWorld::IdCollection& races); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index e55e5fad9..83c8f1232 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -22,8 +22,8 @@ namespace CSMTools const CSMWorld::Resources& icons, const CSMWorld::IdCollection& bodyparts); - virtual void perform(int stage, CSMDoc::Messages& messages); - virtual int setup(); + void perform(int stage, CSMDoc::Messages& messages) override; + int setup() override; private: //CONCRETE CHECKS diff --git a/apps/opencs/model/tools/referencecheck.hpp b/apps/opencs/model/tools/referencecheck.hpp index 7373903e6..2da139869 100644 --- a/apps/opencs/model/tools/referencecheck.hpp +++ b/apps/opencs/model/tools/referencecheck.hpp @@ -14,8 +14,8 @@ namespace CSMTools const CSMWorld::IdCollection& cells, const CSMWorld::IdCollection& factions); - virtual void perform(int stage, CSMDoc::Messages& messages); - virtual int setup(); + void perform(int stage, CSMDoc::Messages& messages) override; + int setup() override; private: const CSMWorld::RefCollection& mReferences; diff --git a/apps/opencs/model/tools/regioncheck.hpp b/apps/opencs/model/tools/regioncheck.hpp index 4c12727f0..e7ddb0bca 100644 --- a/apps/opencs/model/tools/regioncheck.hpp +++ b/apps/opencs/model/tools/regioncheck.hpp @@ -19,10 +19,10 @@ namespace CSMTools RegionCheckStage (const CSMWorld::IdCollection& regions); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/reportmodel.hpp b/apps/opencs/model/tools/reportmodel.hpp index 61b4e6307..809dfcc3e 100644 --- a/apps/opencs/model/tools/reportmodel.hpp +++ b/apps/opencs/model/tools/reportmodel.hpp @@ -33,15 +33,15 @@ namespace CSMTools ReportModel (bool fieldColumn = false, bool severityColumn = true); - virtual int rowCount (const QModelIndex & parent = QModelIndex()) const; + int rowCount (const QModelIndex & parent = QModelIndex()) const override; - virtual int columnCount (const QModelIndex & parent = QModelIndex()) const; + int columnCount (const QModelIndex & parent = QModelIndex()) const override; - virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); + bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; void add (const CSMDoc::Message& message); diff --git a/apps/opencs/model/tools/scriptcheck.hpp b/apps/opencs/model/tools/scriptcheck.hpp index 8f4ac9763..d975e02da 100644 --- a/apps/opencs/model/tools/scriptcheck.hpp +++ b/apps/opencs/model/tools/scriptcheck.hpp @@ -36,20 +36,20 @@ namespace CSMTools CSMDoc::Message::Severity getSeverity (Type type); - virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); + void report (const std::string& message, const Compiler::TokenLoc& loc, Type type) override; ///< Report error to the user. - virtual void report (const std::string& message, Type type); + void report (const std::string& message, Type type) override; ///< Report a file related error public: ScriptCheckStage (const CSMDoc::Document& document); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/searchstage.hpp b/apps/opencs/model/tools/searchstage.hpp index 073487c0d..86abf31a3 100644 --- a/apps/opencs/model/tools/searchstage.hpp +++ b/apps/opencs/model/tools/searchstage.hpp @@ -24,10 +24,10 @@ namespace CSMTools SearchStage (const CSMWorld::IdTableBase *model); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages. void setOperation (const SearchOperation *operation); diff --git a/apps/opencs/model/tools/skillcheck.hpp b/apps/opencs/model/tools/skillcheck.hpp index edd6b79a0..b1af887f6 100644 --- a/apps/opencs/model/tools/skillcheck.hpp +++ b/apps/opencs/model/tools/skillcheck.hpp @@ -19,10 +19,10 @@ namespace CSMTools SkillCheckStage (const CSMWorld::IdCollection& skills); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/soundcheck.hpp b/apps/opencs/model/tools/soundcheck.hpp index fc5925717..80eb9e7f2 100644 --- a/apps/opencs/model/tools/soundcheck.hpp +++ b/apps/opencs/model/tools/soundcheck.hpp @@ -22,10 +22,10 @@ namespace CSMTools SoundCheckStage (const CSMWorld::IdCollection& sounds, const CSMWorld::Resources &soundfiles); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/soundgencheck.hpp b/apps/opencs/model/tools/soundgencheck.hpp index 3c2a7f071..306d35ded 100644 --- a/apps/opencs/model/tools/soundgencheck.hpp +++ b/apps/opencs/model/tools/soundgencheck.hpp @@ -20,10 +20,10 @@ namespace CSMTools const CSMWorld::IdCollection &sounds, const CSMWorld::RefIdCollection &objects); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform(int stage, CSMDoc::Messages &messages); + void perform(int stage, CSMDoc::Messages &messages) override; ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/spellcheck.hpp b/apps/opencs/model/tools/spellcheck.hpp index 03513adc3..bfc962810 100644 --- a/apps/opencs/model/tools/spellcheck.hpp +++ b/apps/opencs/model/tools/spellcheck.hpp @@ -19,10 +19,10 @@ namespace CSMTools SpellCheckStage (const CSMWorld::IdCollection& spells); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform (int stage, CSMDoc::Messages& messages); + void perform (int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/startscriptcheck.hpp b/apps/opencs/model/tools/startscriptcheck.hpp index a7d70ee5a..a45d3c943 100644 --- a/apps/opencs/model/tools/startscriptcheck.hpp +++ b/apps/opencs/model/tools/startscriptcheck.hpp @@ -21,8 +21,8 @@ namespace CSMTools StartScriptCheckStage (const CSMWorld::IdCollection& startScripts, const CSMWorld::IdCollection& scripts); - virtual void perform(int stage, CSMDoc::Messages& messages); - virtual int setup(); + void perform(int stage, CSMDoc::Messages& messages) override; + int setup() override; }; } diff --git a/apps/opencs/model/tools/topicinfocheck.hpp b/apps/opencs/model/tools/topicinfocheck.hpp index 9575181b0..b9dbdc153 100644 --- a/apps/opencs/model/tools/topicinfocheck.hpp +++ b/apps/opencs/model/tools/topicinfocheck.hpp @@ -40,10 +40,10 @@ namespace CSMTools const CSMWorld::RefIdData& referencables, const CSMWorld::Resources& soundFiles); - virtual int setup(); + int setup() override; ///< \return number of steps - virtual void perform(int step, CSMDoc::Messages& messages); + void perform(int step, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages private: diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 3d6802b86..451ef9d0e 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -120,19 +120,19 @@ namespace CSMWorld void add (const ESXRecordT& record); ///< Add a new record (modified) - virtual int getSize() const; + int getSize() const override; - virtual std::string getId (int index) const; + std::string getId (int index) const override; - virtual int getIndex (const std::string& id) const; + int getIndex (const std::string& id) const override; - virtual int getColumns() const; + int getColumns() const override; - virtual QVariant getData (int index, int column) const; + QVariant getData (int index, int column) const override; - virtual void setData (int index, int column, const QVariant& data); + void setData (int index, int column, const QVariant& data) override; - virtual const ColumnBase& getColumn (int column) const; + const ColumnBase& getColumn (int column) const override; virtual void merge(); ///< Merge modified into base. @@ -140,43 +140,43 @@ namespace CSMWorld virtual void purge(); ///< Remove records that are flagged as erased. - virtual void removeRows (int index, int count) ; + void removeRows (int index, int count) override; - virtual void appendBlankRecord (const std::string& id, - UniversalId::Type type = UniversalId::Type_None); + void appendBlankRecord (const std::string& id, + UniversalId::Type type = UniversalId::Type_None) override; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual void cloneRecord(const std::string& origin, + void cloneRecord(const std::string& origin, const std::string& destination, - const UniversalId::Type type); + const UniversalId::Type type) override; - virtual bool touchRecord(const std::string& id); + bool touchRecord(const std::string& id) override; ///< Change the state of a record from base to modified, if it is not already. /// \return True if the record was changed. - virtual int searchId (const std::string& id) const; + int searchId (const std::string& id) const override; ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, const RecordBase& record); + void replace (int index, const RecordBase& record) override; ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record, - UniversalId::Type type = UniversalId::Type_None); + void appendRecord (const RecordBase& record, + UniversalId::Type type = UniversalId::Type_None) override; ///< If the record type does not match, an exception is thrown. ///< \param type Will be ignored, unless the collection supports multiple record types - virtual const Record& getRecord (const std::string& id) const; + const Record& getRecord (const std::string& id) const override; - virtual const Record& getRecord (int index) const; + const Record& getRecord (int index) const override; - virtual int getAppendIndex (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) const; + int getAppendIndex (const std::string& id, + UniversalId::Type type = UniversalId::Type_None) const override; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds (bool listDeleted = true) const; + std::vector getIds (bool listDeleted = true) const override; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list @@ -190,7 +190,7 @@ namespace CSMWorld /// If the index is invalid either generally (by being out of range) or for the particular /// record, an exception is thrown. - virtual bool reorderRows (int baseIndex, const std::vector& newOrder); + bool reorderRows (int baseIndex, const std::vector& newOrder) override; ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). /// diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index d4f78854d..6dc58bd63 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -211,13 +211,13 @@ namespace CSMWorld : Column (id, ColumnBase::Display_NestedHeader, flags), mFixedRows(fixedRows) {} - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { // There is nothing to do here. // This prevents exceptions from parent's implementation } - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { // by default editable; also see IdTree::hasChildren() if (mFixedRows) @@ -226,7 +226,7 @@ namespace CSMWorld return QVariant::fromValue(ColumnBase::TableEdit_Full); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -240,7 +240,7 @@ namespace CSMWorld NestedChildColumn (int id, Display display, int flags = ColumnBase::Flag_Dialogue, bool isEditable = true); - virtual bool isEditable() const; + bool isEditable() const override; private: bool mIsEditable; diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index ccc18263b..c69ca1d84 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -28,19 +28,19 @@ namespace CSMWorld { FloatValueColumn() : Column (Columns::ColumnId_Value, ColumnBase::Display_Float) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mValue.getFloat(); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mValue.setFloat (data.toFloat()); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -54,12 +54,12 @@ namespace CSMWorld hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mId.c_str()); } - virtual bool isEditable() const + bool isEditable() const override { return false; } @@ -86,7 +86,7 @@ namespace CSMWorld : Column (Columns::ColumnId_Modification, ColumnBase::Display_RecordState) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { if (record.mState==Record::State_Erased) return static_cast (Record::State_Deleted); @@ -94,17 +94,17 @@ namespace CSMWorld return static_cast (record.mState); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { record.mState = static_cast (data.toInt()); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return false; } @@ -120,12 +120,12 @@ namespace CSMWorld mType (type) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return mType; } - virtual bool isEditable() const + bool isEditable() const override { return false; } @@ -139,19 +139,19 @@ namespace CSMWorld : Column (Columns::ColumnId_ValueType, display, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mValue.getType()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mValue.setType (static_cast (data.toInt())); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -163,7 +163,7 @@ namespace CSMWorld { VarValueColumn() : Column (Columns::ColumnId_Value, ColumnBase::Display_Var, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { switch (record.get().mValue.getType()) { @@ -185,7 +185,7 @@ namespace CSMWorld } } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -214,7 +214,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -227,12 +227,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Description, ColumnBase::Display_LongString) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mDescription.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -241,7 +241,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -254,12 +254,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Specialisation, ColumnBase::Display_Specialisation) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mSpecialization; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -268,7 +268,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -284,12 +284,12 @@ namespace CSMWorld mIndex (index) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mUseValue[mIndex]; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -298,7 +298,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -311,12 +311,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mAttribute; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -325,7 +325,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -336,12 +336,12 @@ namespace CSMWorld { NameColumn() : Column (Columns::ColumnId_Name, ColumnBase::Display_String) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mName.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -350,7 +350,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -366,12 +366,12 @@ namespace CSMWorld mIndex (index) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mAttribute[mIndex]; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -380,7 +380,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -399,14 +399,14 @@ namespace CSMWorld mIndex (index), mMajor (major) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { int skill = record.get().mData.getSkill (mIndex, mMajor); return QString::fromUtf8 (ESM::Skill::indexToId (skill).c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { std::istringstream stream (data.toString().toUtf8().constData()); @@ -425,7 +425,7 @@ namespace CSMWorld } } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -437,12 +437,12 @@ namespace CSMWorld PlayableColumn() : Column (Columns::ColumnId_Playable, ColumnBase::Display_Boolean) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mIsPlayable!=0; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -451,7 +451,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -462,12 +462,12 @@ namespace CSMWorld { HiddenColumn() : Column (Columns::ColumnId_Hidden, ColumnBase::Display_Boolean) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mIsHidden!=0; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -476,7 +476,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -494,7 +494,7 @@ namespace CSMWorld mInverted (inverted) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { bool flag = (record.get().mData.mFlags & mMask)!=0; @@ -504,7 +504,7 @@ namespace CSMWorld return flag; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -518,7 +518,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -535,7 +535,7 @@ namespace CSMWorld mInverted (inverted) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { bool flag = (record.get().mFlags & mMask)!=0; @@ -545,7 +545,7 @@ namespace CSMWorld return flag; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -559,7 +559,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -579,7 +579,7 @@ namespace CSMWorld mMale (male), mWeight (weight) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { const ESM::Race::MaleFemaleF& value = mWeight ? record.get().mData.mWeight : record.get().mData.mHeight; @@ -587,7 +587,7 @@ namespace CSMWorld return mMale ? value.mMale : value.mFemale; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -599,7 +599,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -624,7 +624,7 @@ namespace CSMWorld mType (type) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { int value = 0; @@ -638,7 +638,7 @@ namespace CSMWorld return value; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { int value = data.toInt(); @@ -659,7 +659,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -672,12 +672,12 @@ namespace CSMWorld : Column (Columns::ColumnId_SoundFile, ColumnBase::Display_SoundRes) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mSound.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -686,7 +686,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -699,19 +699,19 @@ namespace CSMWorld : Column (Columns::ColumnId_MapColour, ColumnBase::Display_Colour) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mMapColor; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT copy = record.get(); copy.mMapColor = data.toInt(); record.setModified (copy); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -724,12 +724,12 @@ namespace CSMWorld : Column (Columns::ColumnId_SleepEncounter, ColumnBase::Display_CreatureLevelledList) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mSleepList.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -738,7 +738,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -749,12 +749,12 @@ namespace CSMWorld { TextureColumn() : Column (Columns::ColumnId_Texture, ColumnBase::Display_Texture) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mTexture.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -763,7 +763,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -776,12 +776,12 @@ namespace CSMWorld : Column (Columns::ColumnId_SpellType, ColumnBase::Display_SpellType) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mType; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -790,7 +790,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -801,19 +801,19 @@ namespace CSMWorld { CostColumn() : Column (Columns::ColumnId_Cost, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mCost; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mCost = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -835,12 +835,12 @@ namespace CSMWorld type==Type_File ? 0 : ColumnBase::Flag_Dialogue) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mScriptText.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -849,7 +849,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -860,12 +860,12 @@ namespace CSMWorld { RegionColumn() : Column (Columns::ColumnId_Region, ColumnBase::Display_Region) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mRegion.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -874,7 +874,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -891,12 +891,12 @@ namespace CSMWorld mBlocked (blocked) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mCell.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -905,12 +905,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return !mBlocked; } @@ -923,12 +923,12 @@ namespace CSMWorld : Column (Columns::ColumnId_OriginalCell, ColumnBase::Display_Cell) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mOriginalCell.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -937,12 +937,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return false; } @@ -954,12 +954,12 @@ namespace CSMWorld IdColumn() : Column (Columns::ColumnId_ReferenceableId, ColumnBase::Display_Referenceable) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mRefID.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -968,7 +968,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -979,19 +979,19 @@ namespace CSMWorld { ScaleColumn() : Column (Columns::ColumnId_Scale, ColumnBase::Display_Float) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mScale; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mScale = data.toFloat(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1002,12 +1002,12 @@ namespace CSMWorld { OwnerColumn() : Column (Columns::ColumnId_Owner, ColumnBase::Display_Npc) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mOwner.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1016,7 +1016,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1027,12 +1027,12 @@ namespace CSMWorld { SoulColumn() : Column (Columns::ColumnId_Soul, ColumnBase::Display_Creature) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mSoul.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1041,7 +1041,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1052,12 +1052,12 @@ namespace CSMWorld { FactionColumn() : Column (Columns::ColumnId_Faction, ColumnBase::Display_Faction) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mFaction.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1066,7 +1066,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1079,19 +1079,19 @@ namespace CSMWorld : Column (Columns::ColumnId_FactionIndex, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mFactionRank; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFactionRank = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1102,19 +1102,19 @@ namespace CSMWorld { ChargesColumn() : Column (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mChargeInt; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mChargeInt = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1127,19 +1127,19 @@ namespace CSMWorld : Column (Columns::ColumnId_Enchantment, ColumnBase::Display_Float) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mEnchantmentCharge; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mEnchantmentCharge = data.toFloat(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1151,19 +1151,19 @@ namespace CSMWorld GoldValueColumn() : Column (Columns::ColumnId_CoinValue, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mGoldValue; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mGoldValue = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1176,12 +1176,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Teleport, ColumnBase::Display_Boolean) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mTeleport; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1190,7 +1190,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1203,12 +1203,12 @@ namespace CSMWorld : Column (Columns::ColumnId_TeleportCell, ColumnBase::Display_Cell) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mDestCell.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1217,12 +1217,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return true; } @@ -1235,19 +1235,19 @@ namespace CSMWorld : Column (Columns::ColumnId_LockLevel, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mLockLevel; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mLockLevel = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1258,12 +1258,12 @@ namespace CSMWorld { KeyColumn() : Column (Columns::ColumnId_Key, ColumnBase::Display_Miscellaneous) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mKey.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1272,7 +1272,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1283,12 +1283,12 @@ namespace CSMWorld { TrapColumn() : Column (Columns::ColumnId_Trap, ColumnBase::Display_Spell) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mTrap.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1297,7 +1297,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1308,12 +1308,12 @@ namespace CSMWorld { FilterColumn() : Column (Columns::ColumnId_Filter, ColumnBase::Display_Filter) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mFilter.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1322,7 +1322,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1339,13 +1339,13 @@ namespace CSMWorld (door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos)+index, ColumnBase::Display_Float), mPosition (position), mIndex (index) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { const ESM::Position& position = record.get().*mPosition; return position.pos[mIndex]; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1356,7 +1356,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1373,13 +1373,13 @@ namespace CSMWorld (door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot)+index, ColumnBase::Display_Double), mPosition (position), mIndex (index) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { const ESM::Position& position = record.get().*mPosition; return osg::RadiansToDegrees(position.rot[mIndex]); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1390,7 +1390,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1404,12 +1404,12 @@ namespace CSMWorld hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mType); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1418,12 +1418,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return false; } @@ -1436,12 +1436,12 @@ namespace CSMWorld : Column (Columns::ColumnId_QuestStatusType, ColumnBase::Display_QuestStatusType) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mQuestStatus); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1450,7 +1450,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1461,12 +1461,12 @@ namespace CSMWorld { QuestDescriptionColumn() : Column (Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mResponse.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1475,7 +1475,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1488,19 +1488,19 @@ namespace CSMWorld : Column (Columns::ColumnId_QuestIndex, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mDisposition; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mDisposition = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1514,12 +1514,12 @@ namespace CSMWorld journal ? ColumnBase::Display_Journal : ColumnBase::Display_Topic) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mTopicId.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1528,12 +1528,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return false; } @@ -1544,12 +1544,12 @@ namespace CSMWorld { ActorColumn() : Column (Columns::ColumnId_Actor, ColumnBase::Display_Npc) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mActor.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1558,7 +1558,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1569,12 +1569,12 @@ namespace CSMWorld { RaceColumn() : Column (Columns::ColumnId_Race, ColumnBase::Display_Race) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mRace.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1583,7 +1583,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1594,12 +1594,12 @@ namespace CSMWorld { ClassColumn() : Column (Columns::ColumnId_Class, ColumnBase::Display_Class) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mClass.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1608,7 +1608,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1619,12 +1619,12 @@ namespace CSMWorld { PcFactionColumn() : Column (Columns::ColumnId_PcFaction, ColumnBase::Display_Faction) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mPcFaction.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1633,7 +1633,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1644,12 +1644,12 @@ namespace CSMWorld { ResponseColumn() : Column (Columns::ColumnId_Response, ColumnBase::Display_LongString) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mResponse.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1658,7 +1658,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1671,19 +1671,19 @@ namespace CSMWorld : Column (Columns::ColumnId_Disposition, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mDisposition; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mDisposition = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1696,19 +1696,19 @@ namespace CSMWorld : Column (Columns::ColumnId_Rank, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mData.mRank); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mRank = static_cast (data.toInt()); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1721,19 +1721,19 @@ namespace CSMWorld : Column (Columns::ColumnId_PcRank, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mData.mPCrank); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mPCrank = static_cast (data.toInt()); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1746,12 +1746,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Gender, ColumnBase::Display_Gender) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mData.mGender); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1760,7 +1760,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1773,7 +1773,7 @@ namespace CSMWorld : Column(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc) {} - virtual QVariant get(const Record& record) const + QVariant get(const Record& record) const override { // Implemented this way to allow additional gender types in the future. if ((record.get().mData.mFlags & ESM::BodyPart::BPF_Female) == ESM::BodyPart::BPF_Female) @@ -1782,7 +1782,7 @@ namespace CSMWorld return 0; } - virtual void set(Record& record, const QVariant& data) + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1795,7 +1795,7 @@ namespace CSMWorld record.setModified(record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1808,12 +1808,12 @@ namespace CSMWorld : Column (Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mData.mType); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1822,7 +1822,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1833,19 +1833,19 @@ namespace CSMWorld { ChargesColumn2() : Column (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mCharge; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mCharge = data.toInt(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1857,12 +1857,12 @@ namespace CSMWorld AutoCalcColumn() : Column (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mAutocalc!=0; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1871,7 +1871,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1882,12 +1882,12 @@ namespace CSMWorld { ModelColumn() : Column (Columns::ColumnId_Model, ColumnBase::Display_Mesh) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mModel.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1896,7 +1896,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1908,12 +1908,12 @@ namespace CSMWorld VampireColumn() : Column (Columns::ColumnId_Vampire, ColumnBase::Display_Boolean) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mVampire!=0; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1922,7 +1922,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1935,12 +1935,12 @@ namespace CSMWorld : Column (Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mData.mPart); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1949,7 +1949,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1962,12 +1962,12 @@ namespace CSMWorld : Column (Columns::ColumnId_MeshType, ColumnBase::Display_MeshType, flags) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mData.mType); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1976,7 +1976,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -1989,12 +1989,12 @@ namespace CSMWorld : Column (Columns::ColumnId_OwnerGlobal, ColumnBase::Display_GlobalVariable) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mGlobalVariable.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2003,7 +2003,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2016,12 +2016,12 @@ namespace CSMWorld : Column (Columns::ColumnId_RefNumCounter, ColumnBase::Display_Integer, 0) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mRefNumCounter); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2030,12 +2030,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return false; } @@ -2048,12 +2048,12 @@ namespace CSMWorld : Column (Columns::ColumnId_RefNum, ColumnBase::Display_Integer, 0) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mRefNum.mIndex); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2062,12 +2062,12 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } - virtual bool isUserEditable() const + bool isUserEditable() const override { return false; } @@ -2080,12 +2080,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Sound, ColumnBase::Display_Sound) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mSound.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2094,7 +2094,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2107,12 +2107,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Creature, ColumnBase::Display_Creature) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mCreature.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2121,7 +2121,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2134,12 +2134,12 @@ namespace CSMWorld : Column (Columns::ColumnId_SoundGeneratorType, ColumnBase::Display_SoundGeneratorType) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return static_cast (record.get().mType); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2148,7 +2148,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2159,19 +2159,19 @@ namespace CSMWorld { BaseCostColumn() : Column (Columns::ColumnId_BaseCost, ColumnBase::Display_Float) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mBaseCost; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mBaseCost = data.toFloat(); record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2184,12 +2184,12 @@ namespace CSMWorld : Column (Columns::ColumnId_School, ColumnBase::Display_School) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mData.mSchool; } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2198,7 +2198,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2216,14 +2216,14 @@ namespace CSMWorld this->mColumnId==Columns::ColumnId_Particle); } - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 ( (this->mColumnId==Columns::ColumnId_Icon ? record.get().mIcon : record.get().mParticle).c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2234,7 +2234,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2252,7 +2252,7 @@ namespace CSMWorld this->mColumnId==Columns::ColumnId_BoltObject); } - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { const std::string *string = 0; @@ -2270,7 +2270,7 @@ namespace CSMWorld return QString::fromUtf8 (string->c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { std::string *string = 0; @@ -2292,7 +2292,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2310,7 +2310,7 @@ namespace CSMWorld this->mColumnId==Columns::ColumnId_BoltSound); } - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { const std::string *string = 0; @@ -2328,7 +2328,7 @@ namespace CSMWorld return QString::fromUtf8 (string->c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { std::string *string = 0; @@ -2350,7 +2350,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2363,12 +2363,12 @@ namespace CSMWorld : Column (Columns::ColumnId_FileFormat, ColumnBase::Display_Integer) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return record.get().mFormat; } - virtual bool isEditable() const + bool isEditable() const override { return false; } @@ -2381,12 +2381,12 @@ namespace CSMWorld : Column (Columns::ColumnId_Author, ColumnBase::Display_String32) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mAuthor.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2395,7 +2395,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2408,12 +2408,12 @@ namespace CSMWorld : Column (Columns::ColumnId_FileDescription, ColumnBase::Display_LongString256) {} - virtual QVariant get (const Record& record) const + QVariant get (const Record& record) const override { return QString::fromUtf8 (record.get().mDescription.c_str()); } - virtual void set (Record& record, const QVariant& data) + void set (Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -2422,7 +2422,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2511,9 +2511,9 @@ namespace CSMWorld BodyPartRaceColumn(const MeshTypeColumn *meshType); - virtual QVariant get(const Record &record) const; - virtual void set(Record &record, const QVariant &data); - virtual bool isEditable() const; + QVariant get(const Record &record) const override; + void set(Record &record, const QVariant &data) override; + bool isEditable() const override; }; } diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 58a1b1d1c..88af32636 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -142,9 +142,9 @@ namespace CSMWorld ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand *parent = 0); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class CreateCommand : public QUndoCommand @@ -175,9 +175,9 @@ namespace CSMWorld void addNestedValue(int parentColumn, int nestedColumn, const QVariant &value); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class CloneCommand : public CreateCommand @@ -191,9 +191,9 @@ namespace CSMWorld const UniversalId::Type type, QUndoCommand* parent = 0); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class RevertCommand : public QUndoCommand @@ -212,9 +212,9 @@ namespace CSMWorld virtual ~RevertCommand(); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class DeleteCommand : public QUndoCommand @@ -235,9 +235,9 @@ namespace CSMWorld virtual ~DeleteCommand(); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class ReorderRowsCommand : public QUndoCommand @@ -250,9 +250,9 @@ namespace CSMWorld ReorderRowsCommand (IdTable& model, int baseIndex, const std::vector& newOrder); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class CreatePathgridCommand : public CreateCommand @@ -261,7 +261,7 @@ namespace CSMWorld CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand *parent = 0); - virtual void redo(); + void redo() override; }; /// \brief Update cell ID according to x/y-coordinates @@ -281,9 +281,9 @@ namespace CSMWorld UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent = 0); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; @@ -318,9 +318,9 @@ namespace CSMWorld DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class AddNestedCommand : public QUndoCommand, private NestedTableStoring @@ -340,9 +340,9 @@ namespace CSMWorld AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; } diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 4136061e4..6b7b8d318 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -31,24 +31,23 @@ namespace CSMWorld virtual ~IdTable(); - virtual int rowCount (const QModelIndex & parent = QModelIndex()) const; + int rowCount (const QModelIndex & parent = QModelIndex()) const override; - virtual int columnCount (const QModelIndex & parent = QModelIndex()) const; + int columnCount (const QModelIndex & parent = QModelIndex()) const override; - virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - virtual Qt::ItemFlags flags (const QModelIndex & index) const; + Qt::ItemFlags flags (const QModelIndex & index) const override; - virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); + bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; - virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) - const; + QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override; - virtual QModelIndex parent (const QModelIndex& index) const; + QModelIndex parent (const QModelIndex& index) const override; void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); ///< \param type Will be ignored, unless the collection supports multiple record types @@ -66,7 +65,7 @@ namespace CSMWorld std::string getId(int row) const; - virtual QModelIndex getModelIndex (const std::string& id, int column) const; + QModelIndex getModelIndex (const std::string& id, int column) const override; void setRecord (const std::string& id, const RecordBase& record, UniversalId::Type type = UniversalId::Type_None); @@ -74,10 +73,10 @@ namespace CSMWorld const RecordBase& getRecord (const std::string& id) const; - virtual int searchColumnIndex (Columns::ColumnId id) const; + int searchColumnIndex (Columns::ColumnId id) const override; ///< Return index of column with the given \a id. If no such column exists, -1 is returned. - virtual int findColumnIndex (Columns::ColumnId id) const; + int findColumnIndex (Columns::ColumnId id) const override; ///< Return index of column with the given \a id. If no such column exists, an exception is /// thrown. @@ -85,14 +84,14 @@ namespace CSMWorld ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - virtual std::pair view (int row) const; + std::pair view (int row) const override; ///< Return the UniversalId and the hint for viewing \a row. If viewing is not /// supported by this table, return (UniversalId::Type_None, ""). /// Is \a id flagged as deleted? - virtual bool isDeleted (const std::string& id) const; + bool isDeleted (const std::string& id) const override; - virtual int getColumnId(int column) const; + int getColumnId(int column) const override; protected: diff --git a/apps/opencs/model/world/idtableproxymodel.hpp b/apps/opencs/model/world/idtableproxymodel.hpp index ad5f267db..14d705792 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -39,7 +39,7 @@ namespace CSMWorld virtual QModelIndex getModelIndex (const std::string& id, int column) const; - virtual void setSourceModel(QAbstractItemModel *model); + void setSourceModel(QAbstractItemModel *model) override; void setFilter (const std::shared_ptr& filter); @@ -47,9 +47,9 @@ namespace CSMWorld protected: - virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; - virtual bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const; + bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const override; QString getRecordId(int sourceRow) const; diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 1539bd4a2..c525a60b8 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -44,22 +44,21 @@ namespace CSMWorld virtual ~IdTree(); - virtual int rowCount (const QModelIndex & parent = QModelIndex()) const; + int rowCount (const QModelIndex & parent = QModelIndex()) const override; - virtual int columnCount (const QModelIndex & parent = QModelIndex()) const; + int columnCount (const QModelIndex & parent = QModelIndex()) const override; - virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; - virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - virtual Qt::ItemFlags flags (const QModelIndex & index) const; + Qt::ItemFlags flags (const QModelIndex & index) const override; - virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); + bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; - virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) - const; + QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override; - virtual QModelIndex parent (const QModelIndex& index) const; + QModelIndex parent (const QModelIndex& index) const override; QModelIndex getNestedModelIndex (const std::string& id, int column) const; @@ -71,7 +70,7 @@ namespace CSMWorld void addNestedRow (const QModelIndex& parent, int position); - virtual bool hasChildren (const QModelIndex& index) const; + bool hasChildren (const QModelIndex& index) const override; virtual int searchNestedColumnIndex(int parentColumn, Columns::ColumnId id); ///< \return the column index or -1 if the requested column wasn't found. diff --git a/apps/opencs/model/world/infocollection.hpp b/apps/opencs/model/world/infocollection.hpp index e5a5575c7..8f5aea601 100644 --- a/apps/opencs/model/world/infocollection.hpp +++ b/apps/opencs/model/world/infocollection.hpp @@ -29,11 +29,11 @@ namespace CSMWorld public: - virtual int getAppendIndex (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) const; + int getAppendIndex (const std::string& id, + UniversalId::Type type = UniversalId::Type_None) const override; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual bool reorderRows (int baseIndex, const std::vector& newOrder); + bool reorderRows (int baseIndex, const std::vector& newOrder) override; ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). /// diff --git a/apps/opencs/model/world/infotableproxymodel.hpp b/apps/opencs/model/world/infotableproxymodel.hpp index 51d93f9a1..6a8e66b4f 100644 --- a/apps/opencs/model/world/infotableproxymodel.hpp +++ b/apps/opencs/model/world/infotableproxymodel.hpp @@ -30,15 +30,15 @@ namespace CSMWorld public: InfoTableProxyModel(UniversalId::Type type, QObject *parent = 0); - virtual void setSourceModel(QAbstractItemModel *sourceModel); + void setSourceModel(QAbstractItemModel *sourceModel) override; protected: - virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; protected slots: - virtual void sourceRowsInserted(const QModelIndex &parent, int start, int end); - virtual void sourceRowsRemoved(const QModelIndex &parent, int start, int end); - virtual void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void sourceRowsInserted(const QModelIndex &parent, int start, int end) override; + void sourceRowsRemoved(const QModelIndex &parent, int start, int end) override; + void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) override; }; } diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 60d983098..54780d290 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -30,24 +30,24 @@ namespace CSMWorld public: PathgridPointListAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class PathgridEdgeListAdapter : public NestedColumnAdapter @@ -55,24 +55,24 @@ namespace CSMWorld public: PathgridEdgeListAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class FactionReactionsAdapter : public NestedColumnAdapter @@ -80,24 +80,24 @@ namespace CSMWorld public: FactionReactionsAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class FactionRanksAdapter : public NestedColumnAdapter @@ -105,24 +105,24 @@ namespace CSMWorld public: FactionRanksAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class RegionSoundListAdapter : public NestedColumnAdapter @@ -130,24 +130,24 @@ namespace CSMWorld public: RegionSoundListAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; template @@ -156,7 +156,7 @@ namespace CSMWorld public: SpellListAdapter () {} - virtual void addRow(Record& record, int position) const + void addRow(Record& record, int position) const override { ESXRecordT raceOrBthSgn = record.get(); @@ -170,7 +170,7 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual void removeRow(Record& record, int rowToRemove) const + void removeRow(Record& record, int rowToRemove) const override { ESXRecordT raceOrBthSgn = record.get(); @@ -184,7 +184,7 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override { ESXRecordT raceOrBthSgn = record.get(); @@ -194,13 +194,13 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual NestedTableWrapperBase* table(const Record& record) const + NestedTableWrapperBase* table(const Record& record) const override { // deleted by dtor of NestedTableStoring return new NestedTableWrapper >(record.get().mPowers.mList); } - virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override { ESXRecordT raceOrBthSgn = record.get(); @@ -217,8 +217,8 @@ namespace CSMWorld } } - virtual void setData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const + void setData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const override { ESXRecordT raceOrBthSgn = record.get(); @@ -239,12 +239,12 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual int getColumnsCount(const Record& record) const + int getColumnsCount(const Record& record) const override { return 1; } - virtual int getRowsCount(const Record& record) const + int getRowsCount(const Record& record) const override { return static_cast(record.get().mPowers.mList.size()); } @@ -256,7 +256,7 @@ namespace CSMWorld public: EffectsListAdapter () {} - virtual void addRow(Record& record, int position) const + void addRow(Record& record, int position) const override { ESXRecordT magic = record.get(); @@ -278,7 +278,7 @@ namespace CSMWorld record.setModified (magic); } - virtual void removeRow(Record& record, int rowToRemove) const + void removeRow(Record& record, int rowToRemove) const override { ESXRecordT magic = record.get(); @@ -292,7 +292,7 @@ namespace CSMWorld record.setModified (magic); } - virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override { ESXRecordT magic = record.get(); @@ -302,13 +302,13 @@ namespace CSMWorld record.setModified (magic); } - virtual NestedTableWrapperBase* table(const Record& record) const + NestedTableWrapperBase* table(const Record& record) const override { // deleted by dtor of NestedTableStoring return new NestedTableWrapper >(record.get().mEffects.mList); } - virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override { ESXRecordT magic = record.get(); @@ -370,8 +370,8 @@ namespace CSMWorld } } - virtual void setData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const + void setData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const override { ESXRecordT magic = record.get(); @@ -415,12 +415,12 @@ namespace CSMWorld record.setModified (magic); } - virtual int getColumnsCount(const Record& record) const + int getColumnsCount(const Record& record) const override { return 8; } - virtual int getRowsCount(const Record& record) const + int getRowsCount(const Record& record) const override { return static_cast(record.get().mEffects.mList.size()); } @@ -431,24 +431,24 @@ namespace CSMWorld public: InfoListAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class InfoConditionAdapter : public NestedColumnAdapter @@ -456,24 +456,24 @@ namespace CSMWorld public: InfoConditionAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class RaceAttributeAdapter : public NestedColumnAdapter @@ -481,24 +481,24 @@ namespace CSMWorld public: RaceAttributeAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class RaceSkillsBonusAdapter : public NestedColumnAdapter @@ -506,24 +506,24 @@ namespace CSMWorld public: RaceSkillsBonusAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class CellListAdapter : public NestedColumnAdapter @@ -531,24 +531,24 @@ namespace CSMWorld public: CellListAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; class RegionWeatherAdapter : public NestedColumnAdapter @@ -556,24 +556,24 @@ namespace CSMWorld public: RegionWeatherAdapter (); - virtual void addRow(Record& record, int position) const; + void addRow(Record& record, int position) const override; - virtual void removeRow(Record& record, int rowToRemove) const; + void removeRow(Record& record, int rowToRemove) const override; - virtual void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const; + void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* table(const Record& record) const; + NestedTableWrapperBase* table(const Record& record) const override; - virtual QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const; + QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const override; - virtual void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const; + void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getColumnsCount(const Record& record) const; + int getColumnsCount(const Record& record) const override; - virtual int getRowsCount(const Record& record) const; + int getRowsCount(const Record& record) const override; }; } diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp index 56b112365..a699d4bd6 100644 --- a/apps/opencs/model/world/nestedidcollection.hpp +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -32,24 +32,24 @@ namespace CSMWorld NestedIdCollection (); ~NestedIdCollection(); - virtual void addNestedRow(int row, int column, int position); + void addNestedRow(int row, int column, int position) override; - virtual void removeNestedRows(int row, int column, int subRow); + void removeNestedRows(int row, int column, int subRow) override; - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; - virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + NestedTableWrapperBase* nestedTable(int row, int column) const override; - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; - virtual int getNestedRowsCount(int row, int column) const; + int getNestedRowsCount(int row, int column) const override; - virtual int getNestedColumnsCount(int row, int column) const; + int getNestedColumnsCount(int row, int column) const override; // this method is inherited from NestedCollection, not from Collection - virtual NestableColumn *getNestableColumn(int column); + NestableColumn *getNestableColumn(int column) override; void addAdapter(std::pair* > adapter); }; diff --git a/apps/opencs/model/world/nestedinfocollection.hpp b/apps/opencs/model/world/nestedinfocollection.hpp index 03c0c2349..fe2cd43fa 100644 --- a/apps/opencs/model/world/nestedinfocollection.hpp +++ b/apps/opencs/model/world/nestedinfocollection.hpp @@ -24,24 +24,24 @@ namespace CSMWorld NestedInfoCollection (); ~NestedInfoCollection(); - virtual void addNestedRow(int row, int column, int position); + void addNestedRow(int row, int column, int position) override; - virtual void removeNestedRows(int row, int column, int subRow); + void removeNestedRows(int row, int column, int subRow) override; - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; - virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + NestedTableWrapperBase* nestedTable(int row, int column) const override; - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; - virtual int getNestedRowsCount(int row, int column) const; + int getNestedRowsCount(int row, int column) const override; - virtual int getNestedColumnsCount(int row, int column) const; + int getNestedColumnsCount(int row, int column) const override; // this method is inherited from NestedCollection, not from Collection > - virtual NestableColumn *getNestableColumn(int column); + NestableColumn *getNestableColumn(int column) override; void addAdapter(std::pair* > adapter); }; diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index 2d5a46c48..b10f8a3a3 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -39,25 +39,25 @@ namespace CSMWorld CSMWorld::IdTree* model() const; - virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; + QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override; - virtual QModelIndex mapToSource(const QModelIndex& proxyIndex) const; + QModelIndex mapToSource(const QModelIndex& proxyIndex) const override; - virtual int rowCount(const QModelIndex& parent) const; + int rowCount(const QModelIndex& parent) const override; - virtual int columnCount(const QModelIndex& parent) const; + int columnCount(const QModelIndex& parent) const override; - virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; - virtual QModelIndex parent(const QModelIndex& index) const; + QModelIndex parent(const QModelIndex& index) const override; - virtual QVariant headerData (int section, Qt::Orientation orientation, int role) const; + QVariant headerData (int section, Qt::Orientation orientation, int role) const override; - virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - virtual bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); + bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; + Qt::ItemFlags flags(const QModelIndex& index) const override; private: void setupHeaderVectors(ColumnBase::Display columnId); diff --git a/apps/opencs/model/world/nestedtablewrapper.hpp b/apps/opencs/model/world/nestedtablewrapper.hpp index f0ca00dbe..7d46dff8b 100644 --- a/apps/opencs/model/world/nestedtablewrapper.hpp +++ b/apps/opencs/model/world/nestedtablewrapper.hpp @@ -22,7 +22,7 @@ namespace CSMWorld virtual ~NestedTableWrapper() {} - virtual int size() const + int size() const override { return mNestedTable.size(); //i hope that this will be enough } diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 3362f9f96..82f2abe77 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -45,11 +45,11 @@ namespace CSMWorld Record(State state, const ESXRecordT *base = 0, const ESXRecordT *modified = 0); - virtual RecordBase *clone() const; + RecordBase *clone() const override; - virtual RecordBase *modifiedCopy() const; + RecordBase *modifiedCopy() const override; - virtual void assign (const RecordBase& record); + void assign (const RecordBase& record) override; const ESXRecordT& get() const; ///< Throws an exception, if the record is deleted. diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 6cb6fcd9c..7695e9ace 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -39,15 +39,14 @@ namespace CSMWorld BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); - virtual std::string getId (const RecordBase& record) const; + std::string getId (const RecordBase& record) const override; - virtual void setId (RecordBase& record, const std::string& id); + void setId (RecordBase& record, const std::string& id) override; - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. UniversalId::Type getType() const; @@ -129,11 +128,11 @@ namespace CSMWorld ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -192,11 +191,11 @@ namespace CSMWorld NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -261,11 +260,11 @@ namespace CSMWorld InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -333,11 +332,11 @@ namespace CSMWorld PotionRefIdAdapter (const PotionColumns& columns, const RefIdColumn *autoCalc); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -356,11 +355,11 @@ namespace CSMWorld IngredientRefIdAdapter (const IngredientColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -378,27 +377,27 @@ namespace CSMWorld virtual ~IngredEffectRefIdAdapter(); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; struct EnchantableColumns : public InventoryColumns @@ -419,11 +418,11 @@ namespace CSMWorld EnchantableRefIdAdapter (UniversalId::Type type, const EnchantableColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -488,11 +487,11 @@ namespace CSMWorld ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -563,11 +562,11 @@ namespace CSMWorld ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -664,11 +663,11 @@ namespace CSMWorld ApparatusRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *type, const RefIdColumn *quality); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -684,11 +683,11 @@ namespace CSMWorld ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor, const RefIdColumn *partRef); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -703,11 +702,11 @@ namespace CSMWorld BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *bookType, const RefIdColumn *skill, const RefIdColumn *text); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -721,11 +720,11 @@ namespace CSMWorld ClothingRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, const RefIdColumn *partRef); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -741,10 +740,10 @@ namespace CSMWorld ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -770,11 +769,11 @@ namespace CSMWorld CreatureRefIdAdapter (const CreatureColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -788,11 +787,11 @@ namespace CSMWorld DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound, const RefIdColumn *closeSound); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -816,11 +815,11 @@ namespace CSMWorld LightRefIdAdapter (const LightColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -832,11 +831,11 @@ namespace CSMWorld MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -865,11 +864,11 @@ namespace CSMWorld NpcRefIdAdapter (const NpcColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -895,11 +894,11 @@ namespace CSMWorld WeaponRefIdAdapter (const WeaponColumns& columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -912,27 +911,27 @@ namespace CSMWorld NpcAttributesRefIdAdapter (); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; class NpcSkillsRefIdAdapter : public NestedRefIdAdapterBase @@ -941,27 +940,27 @@ namespace CSMWorld NpcSkillsRefIdAdapter (); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; class NpcMiscRefIdAdapter : public NestedRefIdAdapterBase @@ -974,27 +973,27 @@ namespace CSMWorld NpcMiscRefIdAdapter (); virtual ~NpcMiscRefIdAdapter(); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; class CreatureAttributesRefIdAdapter : public NestedRefIdAdapterBase @@ -1003,27 +1002,27 @@ namespace CSMWorld CreatureAttributesRefIdAdapter (); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; class CreatureAttackRefIdAdapter : public NestedRefIdAdapterBase @@ -1032,27 +1031,27 @@ namespace CSMWorld CreatureAttackRefIdAdapter (); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; class CreatureMiscRefIdAdapter : public NestedRefIdAdapterBase @@ -1065,27 +1064,27 @@ namespace CSMWorld CreatureMiscRefIdAdapter (); virtual ~CreatureMiscRefIdAdapter(); - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const; + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const; + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const; + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const; + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; }; template @@ -1106,61 +1105,61 @@ namespace CSMWorld virtual ~EffectsRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); EffectsListAdapter::addRow(record, position); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); EffectsListAdapter::removeRow(record, rowToRemove); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); EffectsListAdapter::setTable(record, nestedTable); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); return EffectsListAdapter::table(record); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); return EffectsListAdapter::getData(record, subRowIndex, subColIndex); } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); EffectsListAdapter::setData(record, value, subRowIndex, subColIndex); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { const Record record; // not used, just a dummy return EffectsListAdapter::getColumnsCount(record); } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1183,8 +1182,8 @@ namespace CSMWorld virtual ~NestedInventoryRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1202,8 +1201,8 @@ namespace CSMWorld record.setModified (container); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1219,8 +1218,8 @@ namespace CSMWorld record.setModified (container); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1232,8 +1231,8 @@ namespace CSMWorld record.setModified (container); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1242,8 +1241,8 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mInventory.mList); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1264,8 +1263,8 @@ namespace CSMWorld } } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -1292,12 +1291,12 @@ namespace CSMWorld record.setModified (container); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 2; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1321,8 +1320,8 @@ namespace CSMWorld virtual ~NestedSpellRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1340,8 +1339,8 @@ namespace CSMWorld record.setModified (caster); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1357,8 +1356,8 @@ namespace CSMWorld record.setModified (caster); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1370,8 +1369,8 @@ namespace CSMWorld record.setModified (caster); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1380,8 +1379,8 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mSpells.mList); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1399,8 +1398,8 @@ namespace CSMWorld throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -1418,12 +1417,12 @@ namespace CSMWorld record.setModified (caster); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 1; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1447,8 +1446,8 @@ namespace CSMWorld virtual ~NestedTravelRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1475,8 +1474,8 @@ namespace CSMWorld record.setModified (traveller); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1492,8 +1491,8 @@ namespace CSMWorld record.setModified (traveller); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1505,8 +1504,8 @@ namespace CSMWorld record.setModified (traveller); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1515,8 +1514,8 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mTransport.mList); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1542,8 +1541,8 @@ namespace CSMWorld } } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -1569,12 +1568,12 @@ namespace CSMWorld record.setModified (traveller); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 7; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1600,8 +1599,8 @@ namespace CSMWorld // FIXME: should check if the AI package type is already in the list and use a default // that wasn't used already (in extreme case do not add anything at all? - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1627,8 +1626,8 @@ namespace CSMWorld record.setModified (actor); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1644,8 +1643,8 @@ namespace CSMWorld record.setModified (actor); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1657,8 +1656,8 @@ namespace CSMWorld record.setModified (actor); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1667,8 +1666,8 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mAiPackage.mList); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1768,8 +1767,8 @@ namespace CSMWorld } } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -1891,12 +1890,12 @@ namespace CSMWorld record.setModified (actor); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 19; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1921,8 +1920,8 @@ namespace CSMWorld virtual ~BodyPartRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1943,8 +1942,8 @@ namespace CSMWorld record.setModified (apparel); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1960,8 +1959,8 @@ namespace CSMWorld record.setModified (apparel); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1973,8 +1972,8 @@ namespace CSMWorld record.setModified (apparel); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -1983,8 +1982,8 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mParts.mParts); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2012,8 +2011,8 @@ namespace CSMWorld } } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -2035,12 +2034,12 @@ namespace CSMWorld record.setModified (apparel); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 3; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2067,11 +2066,11 @@ namespace CSMWorld LevelledListRefIdAdapter (UniversalId::Type type, const LevListColumns &columns); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const override; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const override; ///< If the data type does not match an exception is thrown. }; @@ -2117,32 +2116,32 @@ namespace CSMWorld virtual ~NestedListLevListRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { throw std::logic_error ("cannot add a row to a fixed table"); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { throw std::logic_error ("cannot remove a row to a fixed table"); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { throw std::logic_error ("table operation not supported"); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { throw std::logic_error ("table operation not supported"); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2171,8 +2170,8 @@ namespace CSMWorld } } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -2240,12 +2239,12 @@ namespace CSMWorld record.setModified (leveled); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 3; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { return 1; // fixed at size 1 } @@ -2267,8 +2266,8 @@ namespace CSMWorld virtual ~NestedLevListRefIdAdapter() {} - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const + void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2288,8 +2287,8 @@ namespace CSMWorld record.setModified (leveled); } - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const + void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2305,8 +2304,8 @@ namespace CSMWorld record.setModified (leveled); } - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2318,8 +2317,8 @@ namespace CSMWorld record.setModified (leveled); } - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const + NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2328,8 +2327,8 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mList); } - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const + QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); @@ -2350,8 +2349,8 @@ namespace CSMWorld } } - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); @@ -2372,12 +2371,12 @@ namespace CSMWorld record.setModified (leveled); } - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override { return 2; } - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 48558d1c2..e85263ac1 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -32,9 +32,9 @@ namespace CSMWorld int flag = Flag_Table | Flag_Dialogue, bool editable = true, bool userEditable = true); - virtual bool isEditable() const; + bool isEditable() const override; - virtual bool isUserEditable() const; + bool isUserEditable() const override; }; class RefIdCollection : public CollectionBase, public NestedCollection @@ -60,82 +60,82 @@ namespace CSMWorld virtual ~RefIdCollection(); - virtual int getSize() const; + int getSize() const override; - virtual std::string getId (int index) const; + std::string getId (int index) const override; - virtual int getIndex (const std::string& id) const; + int getIndex (const std::string& id) const override; - virtual int getColumns() const; + int getColumns() const override; - virtual const ColumnBase& getColumn (int column) const; + const ColumnBase& getColumn (int column) const override; - virtual QVariant getData (int index, int column) const; + QVariant getData (int index, int column) const override; - virtual void setData (int index, int column, const QVariant& data); + void setData (int index, int column, const QVariant& data) override; - virtual void removeRows (int index, int count); + void removeRows (int index, int count) override; - virtual void cloneRecord(const std::string& origin, + void cloneRecord(const std::string& origin, const std::string& destination, - const UniversalId::Type type); + const UniversalId::Type type) override; - virtual bool touchRecord(const std::string& id); + bool touchRecord(const std::string& id) override; - virtual void appendBlankRecord (const std::string& id, UniversalId::Type type); + void appendBlankRecord (const std::string& id, UniversalId::Type type) override; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual int searchId (const std::string& id) const; + int searchId (const std::string& id) const override; ////< Search record with \a id. /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, const RecordBase& record); + void replace (int index, const RecordBase& record) override; ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record, UniversalId::Type type); + void appendRecord (const RecordBase& record, UniversalId::Type type) override; ///< If the record type does not match, an exception is thrown. /// ///< \param type Will be ignored, unless the collection supports multiple record types - virtual const RecordBase& getRecord (const std::string& id) const; + const RecordBase& getRecord (const std::string& id) const override; - virtual const RecordBase& getRecord (int index) const; + const RecordBase& getRecord (int index) const override; void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); - virtual int getAppendIndex (const std::string& id, UniversalId::Type type) const; + int getAppendIndex (const std::string& id, UniversalId::Type type) const override; ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds (bool listDeleted) const; + std::vector getIds (bool listDeleted) const override; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list - virtual bool reorderRows (int baseIndex, const std::vector& newOrder); + bool reorderRows (int baseIndex, const std::vector& newOrder) override; ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). /// /// \return Success? - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; - virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + NestedTableWrapperBase* nestedTable(int row, int column) const override; - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; - virtual int getNestedRowsCount(int row, int column) const; + int getNestedRowsCount(int row, int column) const override; - virtual int getNestedColumnsCount(int row, int column) const; + int getNestedColumnsCount(int row, int column) const override; - NestableColumn *getNestableColumn(int column); + NestableColumn *getNestableColumn(int column) override; - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; - virtual void removeNestedRows(int row, int column, int subRow); + void removeNestedRows(int row, int column, int subRow) override; - virtual void addNestedRow(int row, int col, int position); + void addNestedRow(int row, int col, int position) override; void save (int index, ESM::ESMWriter& writer) const; diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 94f641edc..1480bb71d 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -66,24 +66,24 @@ namespace CSMWorld { std::vector > mContainer; - virtual int getSize() const; + int getSize() const override; - virtual const RecordBase& getRecord (int index) const; + const RecordBase& getRecord (int index) const override; - virtual RecordBase& getRecord (int index); + RecordBase& getRecord (int index) override; - virtual void appendRecord (const std::string& id, bool base); + void appendRecord (const std::string& id, bool base) override; - virtual void insertRecord (RecordBase& record); + void insertRecord (RecordBase& record) override; - virtual int load (ESM::ESMReader& reader, bool base); + int load (ESM::ESMReader& reader, bool base) override; ///< \return index of a loaded record or -1 if no record was loaded - virtual void erase (int index, int count); + void erase (int index, int count) override; - virtual std::string getId (int index) const; + std::string getId (int index) const override; - virtual void save (int index, ESM::ESMWriter& writer) const; + void save (int index, ESM::ESMWriter& writer) const override; }; template diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 7d7685e89..1de7f1cdb 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -91,15 +91,15 @@ namespace CSMWorld RegionMap (Data& data); - virtual int rowCount (const QModelIndex& parent = QModelIndex()) const; + int rowCount (const QModelIndex& parent = QModelIndex()) const override; - virtual int columnCount (const QModelIndex& parent = QModelIndex()) const; + int columnCount (const QModelIndex& parent = QModelIndex()) const override; - virtual QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const; + QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override; ///< \note Calling this function with role==Role_CellId may return the ID of a cell /// that does not exist. - virtual Qt::ItemFlags flags (const QModelIndex& index) const; + Qt::ItemFlags flags (const QModelIndex& index) const override; private slots: diff --git a/apps/opencs/model/world/resourcetable.hpp b/apps/opencs/model/world/resourcetable.hpp index 7d538df53..8a3fab8a2 100644 --- a/apps/opencs/model/world/resourcetable.hpp +++ b/apps/opencs/model/world/resourcetable.hpp @@ -18,41 +18,40 @@ namespace CSMWorld virtual ~ResourceTable(); - virtual int rowCount (const QModelIndex & parent = QModelIndex()) const; + int rowCount (const QModelIndex & parent = QModelIndex()) const override; - virtual int columnCount (const QModelIndex & parent = QModelIndex()) const; + int columnCount (const QModelIndex & parent = QModelIndex()) const override; - virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - virtual Qt::ItemFlags flags (const QModelIndex & index) const; + Qt::ItemFlags flags (const QModelIndex & index) const override; - virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) - const; + QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override; - virtual QModelIndex parent (const QModelIndex& index) const; + QModelIndex parent (const QModelIndex& index) const override; - virtual QModelIndex getModelIndex (const std::string& id, int column) const; + QModelIndex getModelIndex (const std::string& id, int column) const override; /// Return index of column with the given \a id. If no such column exists, -1 is /// returned. - virtual int searchColumnIndex (Columns::ColumnId id) const; + int searchColumnIndex (Columns::ColumnId id) const override; /// Return index of column with the given \a id. If no such column exists, an /// exception is thrown. - virtual int findColumnIndex (Columns::ColumnId id) const; + int findColumnIndex (Columns::ColumnId id) const override; /// Return the UniversalId and the hint for viewing \a row. If viewing is not /// supported by this table, return (UniversalId::Type_None, ""). - virtual std::pair view (int row) const; + std::pair view (int row) const override; /// Is \a id flagged as deleted? - virtual bool isDeleted (const std::string& id) const; + bool isDeleted (const std::string& id) const override; - virtual int getColumnId (int column) const; + int getColumnId (int column) const override; /// Signal Qt that the data is about to change. void beginReset(); diff --git a/apps/opencs/model/world/scriptcontext.hpp b/apps/opencs/model/world/scriptcontext.hpp index 2cd59f070..8e1a5e57b 100644 --- a/apps/opencs/model/world/scriptcontext.hpp +++ b/apps/opencs/model/world/scriptcontext.hpp @@ -23,23 +23,23 @@ namespace CSMWorld ScriptContext (const Data& data); - virtual bool canDeclareLocals() const; + bool canDeclareLocals() const override; ///< Is the compiler allowed to declare local variables? - virtual char getGlobalType (const std::string& name) const; + char getGlobalType (const std::string& name) const override; ///< 'l: long, 's': short, 'f': float, ' ': does not exist. - virtual std::pair getMemberType (const std::string& name, - const std::string& id) const; + std::pair getMemberType (const std::string& name, + const std::string& id) const override; ///< Return type of member variable \a name in script \a id or in script of reference of /// \a id /// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist. /// second: true: script of reference - virtual bool isId (const std::string& name) const; + bool isId (const std::string& name) const override; ///< Does \a name match an ID, that can be referenced? - virtual bool isJournalId (const std::string& name) const; + bool isJournalId (const std::string& name) const override; ///< Does \a name match a journal ID? void invalidateIds(); diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index 496cb0643..a60929680 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -20,7 +20,7 @@ namespace CSMWorld { const IdCollection& mCells; - virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted); + void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted) override; public: diff --git a/apps/opencs/model/world/tablemimedata.hpp b/apps/opencs/model/world/tablemimedata.hpp index 3be8054bd..234524912 100644 --- a/apps/opencs/model/world/tablemimedata.hpp +++ b/apps/opencs/model/world/tablemimedata.hpp @@ -36,7 +36,7 @@ namespace CSMWorld ~TableMimeData(); - virtual QStringList formats() const; + QStringList formats() const override; std::string getIcon() const; diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index e004007c9..24cbee788 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -38,7 +38,7 @@ namespace CSVDoc private: - void closeEvent (QCloseEvent *event); + void closeEvent (QCloseEvent *event) override; public: diff --git a/apps/opencs/view/doc/newgame.hpp b/apps/opencs/view/doc/newgame.hpp index 70e9d684b..e3c6f53ca 100644 --- a/apps/opencs/view/doc/newgame.hpp +++ b/apps/opencs/view/doc/newgame.hpp @@ -44,7 +44,7 @@ namespace CSVDoc void create(); - void reject(); + void reject() override; }; } diff --git a/apps/opencs/view/doc/runlogsubview.hpp b/apps/opencs/view/doc/runlogsubview.hpp index cfb676a37..e7b490fff 100644 --- a/apps/opencs/view/doc/runlogsubview.hpp +++ b/apps/opencs/view/doc/runlogsubview.hpp @@ -13,7 +13,7 @@ namespace CSVDoc RunLogSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; }; } diff --git a/apps/opencs/view/doc/sizehint.hpp b/apps/opencs/view/doc/sizehint.hpp index cf5a02580..1b3c52eb8 100644 --- a/apps/opencs/view/doc/sizehint.hpp +++ b/apps/opencs/view/doc/sizehint.hpp @@ -14,7 +14,7 @@ namespace CSVDoc SizeHintWidget(QWidget *parent = 0); ~SizeHintWidget(); - virtual QSize sizeHint() const; + QSize sizeHint() const override; void setSizeHint(const QSize &size); }; } diff --git a/apps/opencs/view/doc/subview.hpp b/apps/opencs/view/doc/subview.hpp index 44b81743f..ca9ca8225 100644 --- a/apps/opencs/view/doc/subview.hpp +++ b/apps/opencs/view/doc/subview.hpp @@ -34,7 +34,7 @@ namespace CSVDoc void setUniversalId(const CSMWorld::UniversalId& id); - bool event (QEvent *event); + bool event (QEvent *event) override; public: @@ -54,7 +54,7 @@ namespace CSVDoc private: - void closeEvent (QCloseEvent *event); + void closeEvent (QCloseEvent *event) override; signals: diff --git a/apps/opencs/view/doc/subviewfactoryimp.hpp b/apps/opencs/view/doc/subviewfactoryimp.hpp index 670137985..152b443a3 100644 --- a/apps/opencs/view/doc/subviewfactoryimp.hpp +++ b/apps/opencs/view/doc/subviewfactoryimp.hpp @@ -12,7 +12,7 @@ namespace CSVDoc { public: - virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) override; }; template @@ -32,7 +32,7 @@ namespace CSVDoc SubViewFactoryWithCreator (bool sorting = true); - virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) override; }; template diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 87c312412..322bcdfb7 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -64,7 +64,7 @@ namespace CSVDoc private: - void closeEvent (QCloseEvent *event); + void closeEvent (QCloseEvent *event) override; QAction* createMenuEntry(CSMWorld::UniversalId::Type type, QMenu* menu, const char* shortcutName); QAction* createMenuEntry(const std::string& title, const std::string& iconName, QMenu* menu, const char* shortcutName); diff --git a/apps/opencs/view/filter/filterbox.hpp b/apps/opencs/view/filter/filterbox.hpp index e794a9880..94aa80b84 100644 --- a/apps/opencs/view/filter/filterbox.hpp +++ b/apps/opencs/view/filter/filterbox.hpp @@ -34,11 +34,11 @@ namespace CSVFilter private: - void dragEnterEvent (QDragEnterEvent* event); + void dragEnterEvent (QDragEnterEvent* event) override; - void dropEvent (QDropEvent* event); + void dropEvent (QDropEvent* event) override; - void dragMoveEvent(QDragMoveEvent *event); + void dragMoveEvent(QDragMoveEvent *event) override; signals: void recordFilterChanged (std::shared_ptr filter); diff --git a/apps/opencs/view/prefs/contextmenulist.hpp b/apps/opencs/view/prefs/contextmenulist.hpp index a3b6c9735..f527057d2 100644 --- a/apps/opencs/view/prefs/contextmenulist.hpp +++ b/apps/opencs/view/prefs/contextmenulist.hpp @@ -18,9 +18,9 @@ namespace CSVPrefs protected: - void contextMenuEvent(QContextMenuEvent* e); + void contextMenuEvent(QContextMenuEvent* e) override; - void mousePressEvent(QMouseEvent* e); + void mousePressEvent(QMouseEvent* e) override; private slots: diff --git a/apps/opencs/view/prefs/dialogue.hpp b/apps/opencs/view/prefs/dialogue.hpp index ce017209a..2e0975649 100644 --- a/apps/opencs/view/prefs/dialogue.hpp +++ b/apps/opencs/view/prefs/dialogue.hpp @@ -34,7 +34,7 @@ namespace CSVPrefs protected: - void closeEvent (QCloseEvent *event); + void closeEvent (QCloseEvent *event) override; public slots: diff --git a/apps/opencs/view/prefs/pagebase.hpp b/apps/opencs/view/prefs/pagebase.hpp index 91a4dee5b..ce5b378b3 100644 --- a/apps/opencs/view/prefs/pagebase.hpp +++ b/apps/opencs/view/prefs/pagebase.hpp @@ -26,7 +26,7 @@ namespace CSVPrefs protected: - void contextMenuEvent(QContextMenuEvent*); + void contextMenuEvent(QContextMenuEvent*) override; private slots: diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 658e572c5..dff0f212e 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -96,10 +96,10 @@ namespace CSVRender void fixUpAxis(const osg::Vec3d& up); void unfixUpAxis(); - void handleMouseMoveEvent(int x, int y); - void handleMouseScrollEvent(int x); + void handleMouseMoveEvent(int x, int y) override; + void handleMouseScrollEvent(int x) override; - void update(double dt); + void update(double dt) override; private: @@ -152,10 +152,10 @@ namespace CSVRender void setOrbitSpeedMultiplier(double value); void setPickingMask(unsigned int value); - void handleMouseMoveEvent(int x, int y); - void handleMouseScrollEvent(int x); + void handleMouseMoveEvent(int x, int y) override; + void handleMouseScrollEvent(int x) override; - void update(double dt); + void update(double dt) override; /// \brief Flag controller to be re-initialized. void reset(); diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 056c50e45..c18c29efe 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -45,7 +45,7 @@ namespace CSVRender { public: - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { traverse(node, nv); CellNodeContainer* container = static_cast(node->getUserData()); diff --git a/apps/opencs/view/render/cellarrow.hpp b/apps/opencs/view/render/cellarrow.hpp index 452356194..9a49b80db 100644 --- a/apps/opencs/view/render/cellarrow.hpp +++ b/apps/opencs/view/render/cellarrow.hpp @@ -27,7 +27,7 @@ namespace CSVRender CellArrow *getCellArrow() const; - virtual QString getToolTip (bool hideBasics) const; + QString getToolTip (bool hideBasics) const override; }; diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 911594327..c0482c81a 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -34,7 +34,7 @@ namespace CSVRender unsigned int getInteractionMask() const; - virtual void activate (CSVWidget::SceneToolbar *toolbar); + void activate (CSVWidget::SceneToolbar *toolbar) override; /// Default-implementation: Ignored. virtual void setEditLock (bool locked); @@ -90,15 +90,15 @@ namespace CSVRender virtual void dragWheel (int diff, double speedFactor); /// Default-implementation: ignored - virtual void dragEnterEvent (QDragEnterEvent *event); + void dragEnterEvent (QDragEnterEvent *event) override; /// Default-implementation: ignored - virtual void dropEvent (QDropEvent *event); + void dropEvent (QDropEvent *event) override; /// Default-implementation: ignored - virtual void dragMoveEvent (QDragMoveEvent *event); + void dragMoveEvent (QDragMoveEvent *event) override; - virtual void mouseMoveEvent (QMouseEvent *event); + void mouseMoveEvent (QMouseEvent *event) override; /// Default: return -1 virtual int getSubMode() const; diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index beb60aff3..29955feef 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -64,41 +64,41 @@ namespace CSVRender InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr parentNode, QWidget *parent = 0); - virtual void activate (CSVWidget::SceneToolbar *toolbar); + void activate (CSVWidget::SceneToolbar *toolbar) override; - virtual void deactivate (CSVWidget::SceneToolbar *toolbar); + void deactivate (CSVWidget::SceneToolbar *toolbar) override; - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual void primaryOpenPressed (const WorldspaceHitResult& hit); + void primaryOpenPressed (const WorldspaceHitResult& hit) override; - virtual void primaryEditPressed (const WorldspaceHitResult& hit); + void primaryEditPressed (const WorldspaceHitResult& hit) override; - virtual void secondaryEditPressed (const WorldspaceHitResult& hit); + void secondaryEditPressed (const WorldspaceHitResult& hit) override; - virtual void primarySelectPressed (const WorldspaceHitResult& hit); + void primarySelectPressed (const WorldspaceHitResult& hit) override; - virtual void secondarySelectPressed (const WorldspaceHitResult& hit); + void secondarySelectPressed (const WorldspaceHitResult& hit) override; - virtual bool primaryEditStartDrag (const QPoint& pos); + bool primaryEditStartDrag (const QPoint& pos) override; - virtual bool secondaryEditStartDrag (const QPoint& pos); + bool secondaryEditStartDrag (const QPoint& pos) override; - virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor); + void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; - virtual void dragCompleted(const QPoint& pos); + void dragCompleted(const QPoint& pos) override; /// \note dragAborted will not be called, if the drag is aborted via changing /// editing mode - virtual void dragAborted(); + void dragAborted() override; - virtual void dragWheel (int diff, double speedFactor); + void dragWheel (int diff, double speedFactor) override; - virtual void dragEnterEvent (QDragEnterEvent *event); + void dragEnterEvent (QDragEnterEvent *event) override; - virtual void dropEvent (QDropEvent *event); + void dropEvent (QDropEvent *event) override; - virtual int getSubMode() const; + int getSubMode() const override; signals: diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp index a590240d9..a23811671 100644 --- a/apps/opencs/view/render/instanceselectionmode.hpp +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -21,7 +21,7 @@ namespace CSVRender /// /// \return Have there been any menu items to be added (if menu is 0 and there /// items to be added, the function must return true anyway. - bool createContextMenu(QMenu* menu); + bool createContextMenu(QMenu* menu) override; private: diff --git a/apps/opencs/view/render/lighting.cpp b/apps/opencs/view/render/lighting.cpp index f62e86148..82ad43e6a 100644 --- a/apps/opencs/view/render/lighting.cpp +++ b/apps/opencs/view/render/lighting.cpp @@ -14,7 +14,7 @@ public: , mIndex(index) { } - virtual void apply(osg::Switch &switchNode) + void apply(osg::Switch &switchNode) override { if (switchNode.getName() == Constants::NightDayLabel) switchNode.setSingleChildOn(mIndex); diff --git a/apps/opencs/view/render/lightingbright.hpp b/apps/opencs/view/render/lightingbright.hpp index 7bdebfd3d..aa1492752 100644 --- a/apps/opencs/view/render/lightingbright.hpp +++ b/apps/opencs/view/render/lightingbright.hpp @@ -17,11 +17,11 @@ namespace CSVRender LightingBright(); - virtual void activate (osg::Group* rootNode, bool /*isExterior*/); + void activate (osg::Group* rootNode, bool /*isExterior*/) override; - virtual void deactivate(); + void deactivate() override; - virtual osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient); + osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) override; }; } diff --git a/apps/opencs/view/render/lightingday.hpp b/apps/opencs/view/render/lightingday.hpp index 516dd2bbf..eafc6b8e8 100644 --- a/apps/opencs/view/render/lightingday.hpp +++ b/apps/opencs/view/render/lightingday.hpp @@ -11,11 +11,11 @@ namespace CSVRender LightingDay(); - virtual void activate (osg::Group* rootNode, bool /*isExterior*/); + void activate (osg::Group* rootNode, bool /*isExterior*/) override; - virtual void deactivate(); + void deactivate() override; - virtual osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient); + osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient) override; }; } diff --git a/apps/opencs/view/render/lightingnight.hpp b/apps/opencs/view/render/lightingnight.hpp index 3f03150cd..bfa94ce97 100644 --- a/apps/opencs/view/render/lightingnight.hpp +++ b/apps/opencs/view/render/lightingnight.hpp @@ -11,10 +11,10 @@ namespace CSVRender LightingNight(); - virtual void activate (osg::Group* rootNode, bool isExterior); - virtual void deactivate(); + void activate (osg::Group* rootNode, bool isExterior) override; + void deactivate() override; - virtual osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient); + osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient) override; }; } diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 4d1763f80..a19d64223 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -54,7 +54,7 @@ namespace CSVRender Object* mObject; - virtual QString getToolTip (bool hideBasics) const; + QString getToolTip (bool hideBasics) const override; }; class ObjectMarkerTag : public ObjectTag diff --git a/apps/opencs/view/render/orbitcameramode.hpp b/apps/opencs/view/render/orbitcameramode.hpp index 90c9e97f4..10bc97b0f 100644 --- a/apps/opencs/view/render/orbitcameramode.hpp +++ b/apps/opencs/view/render/orbitcameramode.hpp @@ -24,9 +24,9 @@ namespace CSVRender QWidget* parent = nullptr); ~OrbitCameraMode(); - virtual void activate(CSVWidget::SceneToolbar* toolbar); - virtual void deactivate(CSVWidget::SceneToolbar* toolbar); - virtual bool createContextMenu(QMenu* menu); + void activate(CSVWidget::SceneToolbar* toolbar) override; + void deactivate(CSVWidget::SceneToolbar* toolbar) override; + bool createContextMenu(QMenu* menu) override; private: diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index fcc55fe7d..d17670cfa 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -39,26 +39,26 @@ namespace CSVRender /// \return Any cells added or removed? bool adjustCells(); - virtual void referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight); + void referenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) override; - virtual void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; - virtual void referenceableAdded (const QModelIndex& index, int start, int end); + void referenceableAdded (const QModelIndex& index, int start, int end) override; - virtual void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - virtual void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; - virtual void referenceAdded (const QModelIndex& index, int start, int end); + void referenceAdded (const QModelIndex& index, int start, int end) override; - virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; - virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + void pathgridAdded (const QModelIndex& parent, int start, int end) override; - virtual std::string getStartupInstruction(); + std::string getStartupInstruction() override; /// \note Does not update the view or any cell marker void addCellToScene (const CSMWorld::CellCoordinates& coordinates); @@ -86,45 +86,45 @@ namespace CSVRender virtual ~PagedWorldspaceWidget(); /// Decodes the the hint string to set of cell that are rendered. - void useViewHint (const std::string& hint); + void useViewHint (const std::string& hint) override; void setCellSelection(const CSMWorld::CellSelection& selection); const CSMWorld::CellSelection& getCellSelection() const; /// \return Drop handled? - virtual bool handleDrop (const std::vector& data, - DropType type); + bool handleDrop (const std::vector& data, + DropType type) override; - virtual dropRequirments getDropRequirements(DropType type) const; + dropRequirments getDropRequirements(DropType type) const override; /// \attention The created tool is not added to the toolbar (via addTool). Doing /// that is the responsibility of the calling function. virtual CSVWidget::SceneToolToggle2 *makeControlVisibilitySelector ( CSVWidget::SceneToolbar *parent); - virtual unsigned int getVisibilityMask() const; + unsigned int getVisibilityMask() const override; /// \param elementMask Elements to be affected by the clear operation - virtual void clearSelection (int elementMask); + void clearSelection (int elementMask) override; /// \param elementMask Elements to be affected by the select operation - virtual void invertSelection (int elementMask); + void invertSelection (int elementMask) override; /// \param elementMask Elements to be affected by the select operation - virtual void selectAll (int elementMask); + void selectAll (int elementMask) override; // Select everything that references the same ID as at least one of the elements // already selected // /// \param elementMask Elements to be affected by the select operation - virtual void selectAllWithSameParentId (int elementMask); + void selectAllWithSameParentId (int elementMask) override; - virtual std::string getCellId (const osg::Vec3f& point) const; + std::string getCellId (const osg::Vec3f& point) const override; - virtual Cell* getCell(const osg::Vec3d& point) const; + Cell* getCell(const osg::Vec3d& point) const override; - virtual Cell* getCell(const CSMWorld::CellCoordinates& coords) const; + Cell* getCell(const CSMWorld::CellCoordinates& coords) const override; void setCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height); @@ -132,24 +132,24 @@ namespace CSVRender void resetAllAlteredHeights(); - virtual std::vector > getSelection (unsigned int elementMask) - const; + std::vector > getSelection (unsigned int elementMask) + const override; - virtual std::vector > getEdited (unsigned int elementMask) - const; + std::vector > getEdited (unsigned int elementMask) + const override; - virtual void setSubMode (int subMode, unsigned int elementMask); + void setSubMode (int subMode, unsigned int elementMask) override; /// Erase all overrides and restore the visual representation to its true state. - virtual void reset (unsigned int elementMask); + void reset (unsigned int elementMask) override; protected: - virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); + void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool) override; - virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); + void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool) override; - virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type); + void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type) override; signals: diff --git a/apps/opencs/view/render/pathgrid.cpp b/apps/opencs/view/render/pathgrid.cpp index d8acfe2e1..7f0454d8f 100644 --- a/apps/opencs/view/render/pathgrid.cpp +++ b/apps/opencs/view/render/pathgrid.cpp @@ -23,7 +23,7 @@ namespace CSVRender { public: - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { PathgridTag* tag = static_cast(node->getUserData()); tag->getPathgrid()->update(); diff --git a/apps/opencs/view/render/pathgrid.hpp b/apps/opencs/view/render/pathgrid.hpp index 181a62b44..8f5d45a48 100644 --- a/apps/opencs/view/render/pathgrid.hpp +++ b/apps/opencs/view/render/pathgrid.hpp @@ -40,7 +40,7 @@ namespace CSVRender Pathgrid* getPathgrid () const; - virtual QString getToolTip (bool hideBasics) const; + QString getToolTip (bool hideBasics) const override; private: diff --git a/apps/opencs/view/render/pathgridmode.hpp b/apps/opencs/view/render/pathgridmode.hpp index a012a67e4..6d8f96e8c 100644 --- a/apps/opencs/view/render/pathgridmode.hpp +++ b/apps/opencs/view/render/pathgridmode.hpp @@ -17,31 +17,31 @@ namespace CSVRender PathgridMode(WorldspaceWidget* worldspace, QWidget* parent=0); - virtual void activate(CSVWidget::SceneToolbar* toolbar); + void activate(CSVWidget::SceneToolbar* toolbar) override; - virtual void deactivate(CSVWidget::SceneToolbar* toolbar); + void deactivate(CSVWidget::SceneToolbar* toolbar) override; - virtual void primaryOpenPressed(const WorldspaceHitResult& hit); + void primaryOpenPressed(const WorldspaceHitResult& hit) override; - virtual void primaryEditPressed(const WorldspaceHitResult& hit); + void primaryEditPressed(const WorldspaceHitResult& hit) override; - virtual void secondaryEditPressed(const WorldspaceHitResult& hit); + void secondaryEditPressed(const WorldspaceHitResult& hit) override; - virtual void primarySelectPressed(const WorldspaceHitResult& hit); + void primarySelectPressed(const WorldspaceHitResult& hit) override; - virtual void secondarySelectPressed(const WorldspaceHitResult& hit); + void secondarySelectPressed(const WorldspaceHitResult& hit) override; - virtual bool primaryEditStartDrag (const QPoint& pos); + bool primaryEditStartDrag (const QPoint& pos) override; - virtual bool secondaryEditStartDrag (const QPoint& pos); + bool secondaryEditStartDrag (const QPoint& pos) override; - virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor); + void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; - virtual void dragCompleted(const QPoint& pos); + void dragCompleted(const QPoint& pos) override; /// \note dragAborted will not be called, if the drag is aborted via changing /// editing mode - virtual void dragAborted(); + void dragAborted() override; private: diff --git a/apps/opencs/view/render/pathgridselectionmode.hpp b/apps/opencs/view/render/pathgridselectionmode.hpp index e4cb1e044..19bfca803 100644 --- a/apps/opencs/view/render/pathgridselectionmode.hpp +++ b/apps/opencs/view/render/pathgridselectionmode.hpp @@ -21,7 +21,7 @@ namespace CSVRender /// /// \return Have there been any menu items to be added (if menu is 0 and there /// items to be added, the function must return true anyway. - bool createContextMenu(QMenu* menu); + bool createContextMenu(QMenu* menu) override; private: diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 85b898d04..6a94254b9 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -97,8 +97,8 @@ namespace CSVRender void setAmbient(const osg::Vec4f& ambient); - virtual void mouseMoveEvent (QMouseEvent *event); - virtual void wheelEvent (QWheelEvent *event); + void mouseMoveEvent (QMouseEvent *event) override; + void wheelEvent (QWheelEvent *event) override; std::shared_ptr mResourceSystem; diff --git a/apps/opencs/view/render/selectionmode.hpp b/apps/opencs/view/render/selectionmode.hpp index f28888bfd..95f6de41b 100644 --- a/apps/opencs/view/render/selectionmode.hpp +++ b/apps/opencs/view/render/selectionmode.hpp @@ -30,7 +30,7 @@ namespace CSVRender /// /// \return Have there been any menu items to be added (if menu is 0 and there /// items to be added, the function must return true anyway. - virtual bool createContextMenu (QMenu* menu); + bool createContextMenu (QMenu* menu) override; private: diff --git a/apps/opencs/view/render/terrainstorage.hpp b/apps/opencs/view/render/terrainstorage.hpp index 74c30ce5c..21faf9b64 100644 --- a/apps/opencs/view/render/terrainstorage.hpp +++ b/apps/opencs/view/render/terrainstorage.hpp @@ -19,7 +19,7 @@ namespace CSVRender void setAlteredHeight(int inCellX, int inCellY, float heightMap); void resetHeights(); - virtual bool useAlteration() const { return true; } + bool useAlteration() const override { return true; } float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY); float* getAlteredHeight(int inCellX, int inCellY); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index d169220f9..eec1b01f3 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -39,71 +39,70 @@ namespace CSVRender UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget *parent); - virtual dropRequirments getDropRequirements(DropType type) const; + dropRequirments getDropRequirements(DropType type) const override; /// \return Drop handled? - virtual bool handleDrop (const std::vector& data, - DropType type); + bool handleDrop (const std::vector& data, + DropType type) override; /// \param elementMask Elements to be affected by the clear operation - virtual void clearSelection (int elementMask); + void clearSelection (int elementMask) override; /// \param elementMask Elements to be affected by the select operation - virtual void invertSelection (int elementMask); + void invertSelection (int elementMask) override; /// \param elementMask Elements to be affected by the select operation - virtual void selectAll (int elementMask); + void selectAll (int elementMask) override; // Select everything that references the same ID as at least one of the elements // already selected // /// \param elementMask Elements to be affected by the select operation - virtual void selectAllWithSameParentId (int elementMask); + void selectAllWithSameParentId (int elementMask) override; - virtual std::string getCellId (const osg::Vec3f& point) const; + std::string getCellId (const osg::Vec3f& point) const override; - virtual Cell* getCell(const osg::Vec3d& point) const; + Cell* getCell(const osg::Vec3d& point) const override; - virtual Cell* getCell(const CSMWorld::CellCoordinates& coords) const; + Cell* getCell(const CSMWorld::CellCoordinates& coords) const override; - virtual std::vector > getSelection (unsigned int elementMask) - const; + std::vector > getSelection (unsigned int elementMask) + const override; - virtual std::vector > getEdited (unsigned int elementMask) - const; + std::vector > getEdited (unsigned int elementMask) + const override; - virtual void setSubMode (int subMode, unsigned int elementMask); + void setSubMode (int subMode, unsigned int elementMask) override; /// Erase all overrides and restore the visual representation to its true state. - virtual void reset (unsigned int elementMask); + void reset (unsigned int elementMask) override; private: - virtual void referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight); + void referenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) override; - virtual void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; - virtual void referenceableAdded (const QModelIndex& index, int start, int end); + void referenceableAdded (const QModelIndex& index, int start, int end) override; - virtual void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - virtual void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; - virtual void referenceAdded (const QModelIndex& index, int start, int end); + void referenceAdded (const QModelIndex& index, int start, int end) override; - virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; - virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + void pathgridAdded (const QModelIndex& parent, int start, int end) override; - - virtual std::string getStartupInstruction(); + std::string getStartupInstruction() override; protected: - virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); + void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool) override; private slots: diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index a80032b82..5ed3d01b3 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -203,12 +203,12 @@ namespace CSVRender virtual void updateOverlay(); - virtual void mouseMoveEvent (QMouseEvent *event); - virtual void wheelEvent (QWheelEvent *event); + void mouseMoveEvent (QMouseEvent *event) override; + void wheelEvent (QWheelEvent *event) override; virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type); - virtual void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged (const CSMPrefs::Setting *setting) override; EditMode *getEditMode(); @@ -216,11 +216,11 @@ namespace CSVRender private: - void dragEnterEvent(QDragEnterEvent *event); + void dragEnterEvent(QDragEnterEvent *event) override; - void dropEvent(QDropEvent* event); + void dropEvent(QDropEvent* event) override; - void dragMoveEvent(QDragMoveEvent *event); + void dragMoveEvent(QDragMoveEvent *event) override; virtual std::string getStartupInstruction() = 0; diff --git a/apps/opencs/view/tools/merge.hpp b/apps/opencs/view/tools/merge.hpp index e332b799f..c82feba14 100644 --- a/apps/opencs/view/tools/merge.hpp +++ b/apps/opencs/view/tools/merge.hpp @@ -35,7 +35,7 @@ namespace CSVTools CSVDoc::AdjusterWidget *mAdjuster; CSMDoc::DocumentManager& mDocumentManager; - void keyPressEvent (QKeyEvent *event); + void keyPressEvent (QKeyEvent *event) override; public: diff --git a/apps/opencs/view/tools/reportsubview.hpp b/apps/opencs/view/tools/reportsubview.hpp index 9f43efdac..6d48690b4 100644 --- a/apps/opencs/view/tools/reportsubview.hpp +++ b/apps/opencs/view/tools/reportsubview.hpp @@ -27,7 +27,7 @@ namespace CSVTools ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; private slots: diff --git a/apps/opencs/view/tools/reporttable.cpp b/apps/opencs/view/tools/reporttable.cpp index 426c12f68..7b28f2b0f 100644 --- a/apps/opencs/view/tools/reporttable.cpp +++ b/apps/opencs/view/tools/reporttable.cpp @@ -27,8 +27,8 @@ namespace CSVTools RichTextDelegate (QObject *parent = 0); - virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + void paint(QPainter *painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; }; } diff --git a/apps/opencs/view/tools/reporttable.hpp b/apps/opencs/view/tools/reporttable.hpp index 88936d3c3..4c169a986 100644 --- a/apps/opencs/view/tools/reporttable.hpp +++ b/apps/opencs/view/tools/reporttable.hpp @@ -49,11 +49,11 @@ namespace CSVTools private: - void contextMenuEvent (QContextMenuEvent *event); + void contextMenuEvent (QContextMenuEvent *event) override; - void mouseMoveEvent (QMouseEvent *event); + void mouseMoveEvent (QMouseEvent *event) override; - virtual void mouseDoubleClickEvent (QMouseEvent *event); + void mouseDoubleClickEvent (QMouseEvent *event) override; public: @@ -64,7 +64,7 @@ namespace CSVTools ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id, bool richTextDescription, int refreshState = 0, QWidget *parent = 0); - virtual std::vector getDraggedRecords() const; + std::vector getDraggedRecords() const override; void clear(); diff --git a/apps/opencs/view/tools/searchsubview.hpp b/apps/opencs/view/tools/searchsubview.hpp index c0f3eac84..cbcb01577 100644 --- a/apps/opencs/view/tools/searchsubview.hpp +++ b/apps/opencs/view/tools/searchsubview.hpp @@ -41,15 +41,15 @@ namespace CSVTools protected: - void showEvent (QShowEvent *event); + void showEvent (QShowEvent *event) override; public: SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual void setStatusBar (bool show); + void setStatusBar (bool show) override; private slots: diff --git a/apps/opencs/view/widget/coloreditor.hpp b/apps/opencs/view/widget/coloreditor.hpp index 368896e42..d4a802ca2 100644 --- a/apps/opencs/view/widget/coloreditor.hpp +++ b/apps/opencs/view/widget/coloreditor.hpp @@ -37,8 +37,8 @@ namespace CSVWidget void setColor(const int colorInt); protected: - virtual void paintEvent(QPaintEvent *event); - virtual void showEvent(QShowEvent *event); + void paintEvent(QPaintEvent *event) override; + void showEvent(QShowEvent *event) override; private: ColorEditor(QWidget *parent = 0, const bool popupOnStart = false); diff --git a/apps/opencs/view/widget/colorpickerpopup.hpp b/apps/opencs/view/widget/colorpickerpopup.hpp index eb5653f46..d653d68fb 100644 --- a/apps/opencs/view/widget/colorpickerpopup.hpp +++ b/apps/opencs/view/widget/colorpickerpopup.hpp @@ -19,8 +19,8 @@ namespace CSVWidget void showPicker(const QPoint &position, const QColor &initialColor); protected: - virtual void mousePressEvent(QMouseEvent *event); - virtual bool eventFilter(QObject *object, QEvent *event); + void mousePressEvent(QMouseEvent *event) override; + bool eventFilter(QObject *object, QEvent *event) override; signals: void colorChanged(const QColor &color); diff --git a/apps/opencs/view/widget/completerpopup.hpp b/apps/opencs/view/widget/completerpopup.hpp index 6857064b8..62fdf5388 100644 --- a/apps/opencs/view/widget/completerpopup.hpp +++ b/apps/opencs/view/widget/completerpopup.hpp @@ -10,7 +10,7 @@ namespace CSVWidget public: CompleterPopup(QWidget *parent = 0); - virtual int sizeHintForRow(int row) const; + int sizeHintForRow(int row) const override; }; } diff --git a/apps/opencs/view/widget/droplineedit.hpp b/apps/opencs/view/widget/droplineedit.hpp index 60832e71b..ed991af0d 100644 --- a/apps/opencs/view/widget/droplineedit.hpp +++ b/apps/opencs/view/widget/droplineedit.hpp @@ -29,9 +29,9 @@ namespace CSVWidget DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent = 0); protected: - void dragEnterEvent(QDragEnterEvent *event); - void dragMoveEvent(QDragMoveEvent *event); - void dropEvent(QDropEvent *event); + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; signals: void tableMimeDataDropped(const CSMWorld::UniversalId &id, const CSMDoc::Document *document); diff --git a/apps/opencs/view/widget/pushbutton.hpp b/apps/opencs/view/widget/pushbutton.hpp index bdbdc9c4d..5522cd74f 100644 --- a/apps/opencs/view/widget/pushbutton.hpp +++ b/apps/opencs/view/widget/pushbutton.hpp @@ -38,11 +38,11 @@ namespace CSVWidget protected: - virtual void keyPressEvent (QKeyEvent *event); + void keyPressEvent (QKeyEvent *event) override; - virtual void keyReleaseEvent (QKeyEvent *event); + void keyReleaseEvent (QKeyEvent *event) override; - virtual void mouseReleaseEvent (QMouseEvent *event); + void mouseReleaseEvent (QMouseEvent *event) override; public: diff --git a/apps/opencs/view/widget/scenetool.hpp b/apps/opencs/view/widget/scenetool.hpp index cdea88096..295375f26 100644 --- a/apps/opencs/view/widget/scenetool.hpp +++ b/apps/opencs/view/widget/scenetool.hpp @@ -24,7 +24,7 @@ namespace CSVWidget protected: - void mouseReleaseEvent (QMouseEvent *event); + void mouseReleaseEvent (QMouseEvent *event) override; private slots: diff --git a/apps/opencs/view/widget/scenetoolbar.hpp b/apps/opencs/view/widget/scenetoolbar.hpp index 8e2c8ab00..d9998eefc 100644 --- a/apps/opencs/view/widget/scenetoolbar.hpp +++ b/apps/opencs/view/widget/scenetoolbar.hpp @@ -19,7 +19,7 @@ namespace CSVWidget protected: - virtual void focusInEvent (QFocusEvent *event); + void focusInEvent (QFocusEvent *event) override; public: diff --git a/apps/opencs/view/widget/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp index 90f1dc419..896a6d9c6 100644 --- a/apps/opencs/view/widget/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -31,7 +31,7 @@ namespace CSVWidget void adjustToolTip (const ModeButton *activeMode); - virtual void contextMenuEvent (QContextMenuEvent *event); + void contextMenuEvent (QContextMenuEvent *event) override; /// Add context menu items to \a menu. Default-implementation: Pass on request to /// current mode button or return false, if there is no current mode button. @@ -46,13 +46,13 @@ namespace CSVWidget protected: - bool event(QEvent* event); + bool event(QEvent* event) override; public: SceneToolMode (SceneToolbar *parent, const QString& toolTip); - virtual void showPanel (const QPoint& position); + void showPanel (const QPoint& position) override; void addButton (const std::string& icon, const std::string& id, const QString& tooltip = ""); diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp index dd035462f..4a90aa7c0 100644 --- a/apps/opencs/view/widget/scenetoolrun.hpp +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -35,9 +35,9 @@ namespace CSVWidget SceneToolRun (SceneToolbar *parent, const QString& toolTip, const QString& icon, const std::vector& profiles); - virtual void showPanel (const QPoint& position); + void showPanel (const QPoint& position) override; - virtual void activate(); + void activate() override; /// \attention This function does not remove the profile from the profile selection /// panel. diff --git a/apps/opencs/view/widget/scenetoolshapebrush.hpp b/apps/opencs/view/widget/scenetoolshapebrush.hpp index 2c027baf0..76c0dfa04 100644 --- a/apps/opencs/view/widget/scenetoolshapebrush.hpp +++ b/apps/opencs/view/widget/scenetoolshapebrush.hpp @@ -105,18 +105,18 @@ namespace CSVWidget SceneToolShapeBrush (SceneToolbar *parent, const QString& toolTip, CSMDoc::Document& document); - virtual void showPanel (const QPoint& position); + void showPanel (const QPoint& position) override; void updatePanel (); - void dropEvent (QDropEvent *event); - void dragEnterEvent (QDragEnterEvent *event); + void dropEvent (QDropEvent *event) override; + void dragEnterEvent (QDragEnterEvent *event) override; friend class CSVRender::TerrainShapeMode; public slots: void setButtonIcon(CSVWidget::BrushShape brushShape); void clicked (const QModelIndex& index); - virtual void activate(); + void activate() override; signals: void passEvent(QDropEvent *event); diff --git a/apps/opencs/view/widget/scenetooltexturebrush.hpp b/apps/opencs/view/widget/scenetooltexturebrush.hpp index 5f5ccc6b1..c6f0b5e52 100644 --- a/apps/opencs/view/widget/scenetooltexturebrush.hpp +++ b/apps/opencs/view/widget/scenetooltexturebrush.hpp @@ -112,11 +112,11 @@ namespace CSVWidget SceneToolTextureBrush (SceneToolbar *parent, const QString& toolTip, CSMDoc::Document& document); - virtual void showPanel (const QPoint& position); + void showPanel (const QPoint& position) override; void updatePanel (); - void dropEvent (QDropEvent *event); - void dragEnterEvent (QDragEnterEvent *event); + void dropEvent (QDropEvent *event) override; + void dragEnterEvent (QDragEnterEvent *event) override; friend class CSVRender::TerrainTextureMode; @@ -124,7 +124,7 @@ namespace CSVWidget void setButtonIcon(CSVWidget::BrushShape brushShape); void updateBrushHistory (const std::string& mBrushTexture); void clicked (const QModelIndex& index); - virtual void activate(); + void activate() override; signals: void passEvent(QDropEvent *event); diff --git a/apps/opencs/view/widget/scenetooltoggle.hpp b/apps/opencs/view/widget/scenetooltoggle.hpp index 68cd2362e..f08d117fb 100644 --- a/apps/opencs/view/widget/scenetooltoggle.hpp +++ b/apps/opencs/view/widget/scenetooltoggle.hpp @@ -46,7 +46,7 @@ namespace CSVWidget SceneToolToggle (SceneToolbar *parent, const QString& toolTip, const std::string& emptyIcon); - virtual void showPanel (const QPoint& position); + void showPanel (const QPoint& position) override; /// \attention After the last button has been added, setSelection must be called at /// least once to finalise the layout. diff --git a/apps/opencs/view/widget/scenetooltoggle2.hpp b/apps/opencs/view/widget/scenetooltoggle2.hpp index 50337ac11..e25019298 100644 --- a/apps/opencs/view/widget/scenetooltoggle2.hpp +++ b/apps/opencs/view/widget/scenetooltoggle2.hpp @@ -52,7 +52,7 @@ namespace CSVWidget SceneToolToggle2 (SceneToolbar *parent, const QString& toolTip, const std::string& compositeIcon, const std::string& singleIcon); - virtual void showPanel (const QPoint& position); + void showPanel (const QPoint& position) override; /// \param buttonId used to compose the icon filename /// \param mask used for the reported getSelectionMask() / setSelectionMask() diff --git a/apps/opencs/view/world/bodypartcreator.hpp b/apps/opencs/view/world/bodypartcreator.hpp index 3c27136dd..f526b7fae 100644 --- a/apps/opencs/view/world/bodypartcreator.hpp +++ b/apps/opencs/view/world/bodypartcreator.hpp @@ -23,7 +23,7 @@ namespace CSVWorld private: /// \return ID entered by user. - virtual std::string getId() const; + std::string getId() const override; public: @@ -33,10 +33,10 @@ namespace CSVWorld const CSMWorld::UniversalId& id); /// \return Error description for current user input. - virtual std::string getErrors() const; + std::string getErrors() const override; /// \brief Clear ID and checkbox input widgets. - virtual void reset(); + void reset() override; private slots: diff --git a/apps/opencs/view/world/cellcreator.hpp b/apps/opencs/view/world/cellcreator.hpp index 6c682c6cd..032096aa2 100644 --- a/apps/opencs/view/world/cellcreator.hpp +++ b/apps/opencs/view/world/cellcreator.hpp @@ -21,21 +21,21 @@ namespace CSVWorld protected: - virtual std::string getId() const; + std::string getId() const override; /// Allow subclasses to add additional data to \a command. - virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const; + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; public: CellCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - virtual void reset(); + void reset() override; - virtual void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type); + void cloneMode(const std::string& originId, + const CSMWorld::UniversalId::Type type) override; - virtual std::string getErrors() const; + std::string getErrors() const override; ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. diff --git a/apps/opencs/view/world/colordelegate.hpp b/apps/opencs/view/world/colordelegate.hpp index 87051e86d..041051d13 100644 --- a/apps/opencs/view/world/colordelegate.hpp +++ b/apps/opencs/view/world/colordelegate.hpp @@ -19,17 +19,17 @@ namespace CSVWorld CSMDoc::Document& document, QObject *parent); - virtual void paint(QPainter *painter, + void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const override; }; class ColorDelegateFactory : public CommandDelegateFactory { public: - virtual CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher, + CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document &document, - QObject *parent) const; + QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/creator.hpp b/apps/opencs/view/world/creator.hpp index f50333e4e..516f71f15 100644 --- a/apps/opencs/view/world/creator.hpp +++ b/apps/opencs/view/world/creator.hpp @@ -74,7 +74,7 @@ namespace CSVWorld { public: - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const; + Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; ///< The ownership of the returned Creator is transferred to the caller. /// /// \note The function always returns 0. @@ -85,7 +85,7 @@ namespace CSVWorld { public: - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const; + Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; ///< The ownership of the returned Creator is transferred to the caller. /// /// \note The function can return a 0-pointer, which means no UI for creating/deleting diff --git a/apps/opencs/view/world/datadisplaydelegate.hpp b/apps/opencs/view/world/datadisplaydelegate.hpp index f8e775369..df06359a0 100755 --- a/apps/opencs/view/world/datadisplaydelegate.hpp +++ b/apps/opencs/view/world/datadisplaydelegate.hpp @@ -53,9 +53,9 @@ namespace CSVWorld ~DataDisplayDelegate(); - virtual void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; /// pass a QSize defining height / width of icon. Default is QSize (16,16). void setIconSize (const QSize& icon); @@ -74,7 +74,7 @@ namespace CSVWorld /// rebuild the list of pixmaps from the provided icons (called when icon size is changed) void buildPixmaps(); - virtual void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged (const CSMPrefs::Setting *setting) override; }; class DataDisplayDelegateFactory : public EnumDelegateFactory @@ -85,7 +85,7 @@ namespace CSVWorld public: - virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; + CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. protected: diff --git a/apps/opencs/view/world/dialoguecreator.hpp b/apps/opencs/view/world/dialoguecreator.hpp index 20430fdb6..0aef2f84d 100644 --- a/apps/opencs/view/world/dialoguecreator.hpp +++ b/apps/opencs/view/world/dialoguecreator.hpp @@ -11,7 +11,7 @@ namespace CSVWorld protected: - virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + void configureCreateCommand (CSMWorld::CreateCommand& command) const override; public: @@ -23,7 +23,7 @@ namespace CSVWorld { public: - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const; + Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; ///< The ownership of the returned Creator is transferred to the caller. }; @@ -31,7 +31,7 @@ namespace CSVWorld { public: - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const; + Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; ///< The ownership of the returned Creator is transferred to the caller. }; } diff --git a/apps/opencs/view/world/dialoguespinbox.hpp b/apps/opencs/view/world/dialoguespinbox.hpp index a68e0c314..b7c4889a5 100644 --- a/apps/opencs/view/world/dialoguespinbox.hpp +++ b/apps/opencs/view/world/dialoguespinbox.hpp @@ -16,9 +16,9 @@ namespace CSVWorld protected: - virtual void focusInEvent(QFocusEvent *event); - virtual void focusOutEvent(QFocusEvent *event); - virtual void wheelEvent(QWheelEvent *event); + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void wheelEvent(QWheelEvent *event) override; }; class DialogueDoubleSpinBox : public QDoubleSpinBox @@ -31,9 +31,9 @@ namespace CSVWorld protected: - virtual void focusInEvent(QFocusEvent *event); - virtual void focusOutEvent(QFocusEvent *event); - virtual void wheelEvent(QWheelEvent *event); + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void wheelEvent(QWheelEvent *event) override; }; } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 52d3d8da5..eb14efa8e 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -52,22 +52,22 @@ namespace CSVWorld NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent = 0); - virtual void setEditorData (QWidget* editor, const QModelIndex& index) const; + void setEditorData (QWidget* editor, const QModelIndex& index) const override; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; - virtual void paint (QPainter* painter, + void paint (QPainter* painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + const QModelIndex& index) const override; ///< does nothing - virtual QSize sizeHint (const QStyleOptionViewItem& option, - const QModelIndex& index) const; + QSize sizeHint (const QStyleOptionViewItem& option, + const QModelIndex& index) const override; ///< does nothing - virtual QWidget *createEditor (QWidget *parent, + QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + const QModelIndex& index) const override; }; //this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals @@ -136,22 +136,22 @@ namespace CSVWorld ///< will return null if delegate is not present, parent of the widget is //same as for dispatcher itself - virtual void setEditorData (QWidget* editor, const QModelIndex& index) const; + void setEditorData (QWidget* editor, const QModelIndex& index) const override; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, - const QModelIndex& index) const; + void setModelData (QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index) const override; virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; - virtual void paint (QPainter* painter, + void paint (QPainter* painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + const QModelIndex& index) const override; ///< does nothing - virtual QSize sizeHint (const QStyleOptionViewItem& option, - const QModelIndex& index) const; + QSize sizeHint (const QStyleOptionViewItem& option, + const QModelIndex& index) const override; ///< does nothing private slots: @@ -248,7 +248,7 @@ namespace CSVWorld SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; private slots: @@ -276,7 +276,7 @@ namespace CSVWorld DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting = false); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; private slots: diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index 9e29b6145..a6b6756aa 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -37,11 +37,11 @@ namespace CSVWorld protected: void startDragFromTable(const DragRecordTable& table); - void dragEnterEvent(QDragEnterEvent *event); + void dragEnterEvent(QDragEnterEvent *event) override; - void dragMoveEvent(QDragMoveEvent *event); + void dragMoveEvent(QDragMoveEvent *event) override; - void dropEvent(QDropEvent *event); + void dropEvent(QDropEvent *event) override; private: CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex &index) const; diff --git a/apps/opencs/view/world/enumdelegate.hpp b/apps/opencs/view/world/enumdelegate.hpp index bd20943d9..91326e2c0 100644 --- a/apps/opencs/view/world/enumdelegate.hpp +++ b/apps/opencs/view/world/enumdelegate.hpp @@ -23,8 +23,8 @@ namespace CSVWorld private: - virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const; + void setModelDataImp (QWidget *editor, QAbstractItemModel *model, + const QModelIndex& index) const override; virtual void addCommands (QAbstractItemModel *model, const QModelIndex& index, int type) const; @@ -34,21 +34,21 @@ namespace CSVWorld EnumDelegate (const std::vector >& values, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); - virtual QWidget *createEditor(QWidget *parent, + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + const QModelIndex& index) const override; - virtual QWidget *createEditor(QWidget *parent, + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index, - CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; + CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const override; - virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; + void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const override; - virtual void paint (QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + void paint (QPainter *painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; - virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; @@ -68,7 +68,7 @@ namespace CSVWorld EnumDelegateFactory (const std::vector>& names, bool allowNone = false); /// \param allowNone Use value of -1 for "none selected" (empty string) - virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; + CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. void add (int value, const QString& name); diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 641b4a524..42573924a 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -63,7 +63,7 @@ namespace CSVWorld void setEditLock(bool locked); protected: - virtual void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event) override; private slots: void performExtendedCommand(); diff --git a/apps/opencs/view/world/genericcreator.hpp b/apps/opencs/view/world/genericcreator.hpp index 3baacfc06..3e2a43c91 100644 --- a/apps/opencs/view/world/genericcreator.hpp +++ b/apps/opencs/view/world/genericcreator.hpp @@ -96,25 +96,25 @@ namespace CSVWorld GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, bool relaxedIdRules = false); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual void reset(); + void reset() override; - virtual void toggleWidgets (bool active = true); + void toggleWidgets (bool active = true) override; - virtual void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type); + void cloneMode(const std::string& originId, + const CSMWorld::UniversalId::Type type) override; - virtual void touch(const std::vector& ids); + void touch(const std::vector& ids) override; virtual std::string getErrors() const; ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. - virtual void setScope (unsigned int scope); + void setScope (unsigned int scope) override; /// Focus main input widget - virtual void focus(); + void focus() override; private slots: diff --git a/apps/opencs/view/world/globalcreator.hpp b/apps/opencs/view/world/globalcreator.hpp index 8c6cc628c..057798a4c 100644 --- a/apps/opencs/view/world/globalcreator.hpp +++ b/apps/opencs/view/world/globalcreator.hpp @@ -15,7 +15,7 @@ namespace CSVWorld protected: - virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const; + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; }; } diff --git a/apps/opencs/view/world/idcompletiondelegate.hpp b/apps/opencs/view/world/idcompletiondelegate.hpp index d2ac6874f..57c2c11c4 100644 --- a/apps/opencs/view/world/idcompletiondelegate.hpp +++ b/apps/opencs/view/world/idcompletiondelegate.hpp @@ -13,22 +13,22 @@ namespace CSVWorld CSMDoc::Document& document, QObject *parent); - virtual QWidget *createEditor (QWidget *parent, + QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const override; - virtual QWidget *createEditor (QWidget *parent, + QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index, - CSMWorld::ColumnBase::Display display) const; + CSMWorld::ColumnBase::Display display) const override; }; class IdCompletionDelegateFactory : public CommandDelegateFactory { public: - virtual CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher, + CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, - QObject *parent) const; + QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/idtypedelegate.hpp b/apps/opencs/view/world/idtypedelegate.hpp index d0ed6997b..f1c3b539c 100755 --- a/apps/opencs/view/world/idtypedelegate.hpp +++ b/apps/opencs/view/world/idtypedelegate.hpp @@ -20,7 +20,7 @@ namespace CSVWorld IdTypeDelegateFactory(); - virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; + CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/idvalidator.hpp b/apps/opencs/view/world/idvalidator.hpp index a9df9580a..17624a243 100644 --- a/apps/opencs/view/world/idvalidator.hpp +++ b/apps/opencs/view/world/idvalidator.hpp @@ -22,7 +22,7 @@ namespace CSVWorld IdValidator (bool relaxed = false, QObject *parent = 0); ///< \param relaxed Relaxed rules for IDs that also functino as user visible text - virtual State validate (QString& input, int& pos) const; + State validate (QString& input, int& pos) const override; void setNamespace (const std::string& namespace_); diff --git a/apps/opencs/view/world/infocreator.hpp b/apps/opencs/view/world/infocreator.hpp index d131e3fac..404dcf372 100644 --- a/apps/opencs/view/world/infocreator.hpp +++ b/apps/opencs/view/world/infocreator.hpp @@ -22,26 +22,26 @@ namespace CSVWorld CSVWidget::DropLineEdit *mTopic; - virtual std::string getId() const; + std::string getId() const override; - virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + void configureCreateCommand (CSMWorld::CreateCommand& command) const override; public: InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager); - virtual void cloneMode (const std::string& originId, - const CSMWorld::UniversalId::Type type); + void cloneMode (const std::string& originId, + const CSMWorld::UniversalId::Type type) override; - virtual void reset(); + void reset() override; - virtual std::string getErrors() const; + std::string getErrors() const override; ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. /// Focus main input widget - virtual void focus(); + void focus() override; private slots: @@ -52,7 +52,7 @@ namespace CSVWorld { public: - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const; + Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; ///< The ownership of the returned Creator is transferred to the caller. }; } diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index b39c7e560..f864f5d80 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -42,10 +42,10 @@ namespace CSVWorld bool editable = true, bool fixedRows = false); - virtual std::vector getDraggedRecords() const; + std::vector getDraggedRecords() const override; private: - void contextMenuEvent (QContextMenuEvent *event); + void contextMenuEvent (QContextMenuEvent *event) override; private slots: void removeRowActionTriggered(); diff --git a/apps/opencs/view/world/pathgridcreator.hpp b/apps/opencs/view/world/pathgridcreator.hpp index 7e82155f6..773735e25 100644 --- a/apps/opencs/view/world/pathgridcreator.hpp +++ b/apps/opencs/view/world/pathgridcreator.hpp @@ -33,7 +33,7 @@ namespace CSVWorld private: /// \return Cell ID entered by user. - virtual std::string getId() const; + std::string getId() const override; /// \return reference to table containing pathgrids. CSMWorld::IdTable& getPathgridsTable() const; @@ -49,18 +49,18 @@ namespace CSVWorld /// \brief Set cell ID input widget to ID of record to be cloned. /// \param originId Cell ID to be cloned. /// \param type Type of record to be cloned. - virtual void cloneMode( + void cloneMode( const std::string& originId, - const CSMWorld::UniversalId::Type type); + const CSMWorld::UniversalId::Type type) override; /// \return Error description for current user input. - virtual std::string getErrors() const; + std::string getErrors() const override; /// \brief Set focus to cell ID input widget. - virtual void focus(); + void focus() override; /// \brief Clear cell ID input widget. - virtual void reset(); + void reset() override; private slots: @@ -73,9 +73,9 @@ namespace CSVWorld { public: - virtual Creator *makeCreator( + Creator *makeCreator( CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const; + const CSMWorld::UniversalId& id) const override; }; } diff --git a/apps/opencs/view/world/previewsubview.hpp b/apps/opencs/view/world/previewsubview.hpp index a28be5c36..ed88d0488 100644 --- a/apps/opencs/view/world/previewsubview.hpp +++ b/apps/opencs/view/world/previewsubview.hpp @@ -26,9 +26,9 @@ namespace CSVWorld PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual std::string getTitle() const; + std::string getTitle() const override; private slots: diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index acaf872a6..6ec8c37bd 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -28,7 +28,7 @@ namespace CSVWorld RecordStatusDelegateFactory(); - virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; + CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; diff --git a/apps/opencs/view/world/referenceablecreator.hpp b/apps/opencs/view/world/referenceablecreator.hpp index 14ad24b29..d4657bcf7 100644 --- a/apps/opencs/view/world/referenceablecreator.hpp +++ b/apps/opencs/view/world/referenceablecreator.hpp @@ -15,19 +15,19 @@ namespace CSVWorld private: - virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + void configureCreateCommand (CSMWorld::CreateCommand& command) const override; public: ReferenceableCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - virtual void reset(); + void reset() override; - virtual void cloneMode (const std::string& originId, - const CSMWorld::UniversalId::Type type); + void cloneMode (const std::string& originId, + const CSMWorld::UniversalId::Type type) override; - virtual void toggleWidgets(bool active = true); + void toggleWidgets(bool active = true) override; }; } diff --git a/apps/opencs/view/world/referencecreator.hpp b/apps/opencs/view/world/referencecreator.hpp index 31010fa24..3903900ad 100644 --- a/apps/opencs/view/world/referencecreator.hpp +++ b/apps/opencs/view/world/referencecreator.hpp @@ -25,26 +25,26 @@ namespace CSVWorld private: - virtual std::string getId() const; + std::string getId() const override; - virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + void configureCreateCommand (CSMWorld::CreateCommand& command) const override; public: ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager); - virtual void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type); + void cloneMode(const std::string& originId, + const CSMWorld::UniversalId::Type type) override; - virtual void reset(); + void reset() override; - virtual std::string getErrors() const; + std::string getErrors() const override; ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. /// Focus main input widget - virtual void focus(); + void focus() override; private slots: @@ -55,7 +55,7 @@ namespace CSVWorld { public: - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const; + Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; ///< The ownership of the returned Creator is transferred to the caller. }; } diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index ba773224f..b1f7cdc67 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -39,7 +39,7 @@ namespace CSVWorld private: - void contextMenuEvent (QContextMenuEvent *event); + void contextMenuEvent (QContextMenuEvent *event) override; QModelIndexList getUnselectedCells() const; ///< \note Non-existent cells are not listed. @@ -54,16 +54,16 @@ namespace CSVWorld void setRegion (const std::string& regionId); ///< Set region Id of selected cells. - void mouseMoveEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event) override; - void dropEvent(QDropEvent* event); + void dropEvent(QDropEvent* event) override; public: RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget *parent = 0); - virtual std::vector getDraggedRecords() const; + std::vector getDraggedRecords() const override; signals: @@ -71,7 +71,7 @@ namespace CSVWorld private slots: - void selectAll(); + void selectAll() override; void clearSelection(); diff --git a/apps/opencs/view/world/regionmapsubview.hpp b/apps/opencs/view/world/regionmapsubview.hpp index 524727901..232d88fc6 100644 --- a/apps/opencs/view/world/regionmapsubview.hpp +++ b/apps/opencs/view/world/regionmapsubview.hpp @@ -24,7 +24,7 @@ namespace CSVWorld RegionMapSubView (CSMWorld::UniversalId universalId, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; private slots: diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 85f7d0925..aabb7ca2a 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -51,13 +51,13 @@ namespace CSVWorld SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual void setStatusBar (bool show); + void setStatusBar (bool show) override; - virtual void useHint (const std::string& hint); + void useHint (const std::string& hint) override; - virtual std::string getTitle() const; + std::string getTitle() const override; private: diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index b0a4b0577..21fabee58 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -61,7 +61,7 @@ namespace CSVWorld protected: - bool event (QEvent *event); + bool event (QEvent *event) override; public: @@ -79,9 +79,9 @@ namespace CSVWorld protected: - virtual void resizeEvent(QResizeEvent *e); + void resizeEvent(QResizeEvent *e) override; - virtual void contextMenuEvent(QContextMenuEvent *event); + void contextMenuEvent(QContextMenuEvent *event) override; private: @@ -89,11 +89,11 @@ namespace CSVWorld const CSMDoc::Document& mDocument; const QRegExp mWhiteListQoutes; - void dragEnterEvent (QDragEnterEvent* event); + void dragEnterEvent (QDragEnterEvent* event) override; - void dropEvent (QDropEvent* event); + void dropEvent (QDropEvent* event) override; - void dragMoveEvent (QDragMoveEvent* event); + void dragMoveEvent (QDragMoveEvent* event) override; bool stringNeedsQuote(const std::string& id) const; @@ -133,11 +133,11 @@ namespace CSVWorld public: LineNumberArea(ScriptEdit *editor); - QSize sizeHint() const; + QSize sizeHint() const override; protected: - void paintEvent(QPaintEvent *event); + void paintEvent(QPaintEvent *event) override; }; } #endif // SCRIPTEDIT_H diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index 4841aac5b..ad287707d 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -28,10 +28,10 @@ namespace CSVWorld Compiler::Extensions mExtensions; CSMWorld::ScriptContext mContext; - virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); + void report (const std::string& message, const Compiler::TokenLoc& loc, Type type) override; ///< Report error to the user. - virtual void report (const std::string& message, Type type); + void report (const std::string& message, Type type) override; ///< Report a file related error void addMessage (const std::string& message, CSMDoc::Message::Severity severity, diff --git a/apps/opencs/view/world/scripthighlighter.hpp b/apps/opencs/view/world/scripthighlighter.hpp index a7d0fc2a1..9b4a5b7be 100644 --- a/apps/opencs/view/world/scripthighlighter.hpp +++ b/apps/opencs/view/world/scripthighlighter.hpp @@ -54,37 +54,37 @@ namespace CSVWorld private: - virtual bool parseInt (int value, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner); + bool parseInt (int value, const Compiler::TokenLoc& loc, + Compiler::Scanner& scanner) override; ///< Handle an int token. /// \return fetch another token? - virtual bool parseFloat (float value, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner); + bool parseFloat (float value, const Compiler::TokenLoc& loc, + Compiler::Scanner& scanner) override; ///< Handle a float token. /// \return fetch another token? - virtual bool parseName (const std::string& name, - const Compiler::TokenLoc& loc, Compiler::Scanner& scanner); + bool parseName (const std::string& name, + const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner); + bool parseKeyword (int keyword, const Compiler::TokenLoc& loc, + Compiler::Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner); + bool parseSpecial (int code, const Compiler::TokenLoc& loc, + Compiler::Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - virtual bool parseComment (const std::string& comment, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner); + bool parseComment (const std::string& comment, const Compiler::TokenLoc& loc, + Compiler::Scanner& scanner) override; ///< Handle comment token. /// \return fetch another token? - virtual void parseEOF (Compiler::Scanner& scanner); + void parseEOF (Compiler::Scanner& scanner) override; ///< Handle EOF token. void highlight (const Compiler::TokenLoc& loc, Type type); @@ -93,7 +93,7 @@ namespace CSVWorld ScriptHighlighter (const CSMWorld::Data& data, Mode mode, QTextDocument *parent); - virtual void highlightBlock (const QString& text); + void highlightBlock (const QString& text) override; void setMarkOccurrences(bool); diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index c1016babf..dc352cc5b 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -70,11 +70,11 @@ namespace CSVWorld ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual void useHint (const std::string& hint); + void useHint (const std::string& hint) override; - virtual void setStatusBar (bool show); + void setStatusBar (bool show) override; public slots: diff --git a/apps/opencs/view/world/startscriptcreator.hpp b/apps/opencs/view/world/startscriptcreator.hpp index 72eb67bcc..cb7f3f619 100644 --- a/apps/opencs/view/world/startscriptcreator.hpp +++ b/apps/opencs/view/world/startscriptcreator.hpp @@ -26,7 +26,7 @@ namespace CSVWorld private: /// \return script ID entered by user. - virtual std::string getId() const; + std::string getId() const override; /// \return reference to table containing start scripts. CSMWorld::IdTable& getStartScriptsTable() const; @@ -42,18 +42,18 @@ namespace CSVWorld /// \brief Set script ID input widget to ID of record to be cloned. /// \param originId Script ID to be cloned. /// \param type Type of record to be cloned. - virtual void cloneMode( + void cloneMode( const std::string& originId, - const CSMWorld::UniversalId::Type type); + const CSMWorld::UniversalId::Type type) override; /// \return Error description for current user input. - virtual std::string getErrors() const; + std::string getErrors() const override; /// \brief Set focus to script ID input widget. - virtual void focus(); + void focus() override; /// \brief Clear script ID input widget. - virtual void reset(); + void reset() override; private slots: @@ -66,9 +66,9 @@ namespace CSVWorld { public: - virtual Creator *makeCreator( + Creator *makeCreator( CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const; + const CSMWorld::UniversalId& id) const override; }; } diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 36c423b33..61dd57c06 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -77,13 +77,13 @@ namespace CSVWorld private: - void contextMenuEvent (QContextMenuEvent *event); + void contextMenuEvent (QContextMenuEvent *event) override; - void mouseMoveEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event) override; protected: - virtual void mouseDoubleClickEvent (QMouseEvent *event); + void mouseDoubleClickEvent (QMouseEvent *event) override; public: @@ -100,7 +100,7 @@ namespace CSVWorld std::vector getSelectedIds() const; - virtual std::vector getDraggedRecords() const; + std::vector getDraggedRecords() const override; signals: diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index baa68087b..50d61150f 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -63,7 +63,7 @@ namespace CSVWorld virtual ~TableBottomBox(); - virtual bool eventFilter(QObject *object, QEvent *event); + bool eventFilter(QObject *object, QEvent *event) override; void setEditLock (bool locked); diff --git a/apps/opencs/view/world/tablesubview.hpp b/apps/opencs/view/world/tablesubview.hpp index 1adf862d5..337d2c762 100644 --- a/apps/opencs/view/world/tablesubview.hpp +++ b/apps/opencs/view/world/tablesubview.hpp @@ -41,14 +41,14 @@ namespace CSVWorld TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting); - virtual void setEditLock (bool locked); + void setEditLock (bool locked) override; - virtual void setStatusBar (bool show); + void setStatusBar (bool show) override; - virtual void useHint (const std::string& hint); + void useHint (const std::string& hint) override; protected: - bool eventFilter(QObject* object, QEvent *event); + bool eventFilter(QObject* object, QEvent *event) override; signals: void cloneRequest(const std::string&, diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index ebd5c0ad7..2c4537dac 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -40,13 +40,13 @@ namespace CSVWorld NastyTableModelHack (QAbstractItemModel& model); - int rowCount (const QModelIndex & parent = QModelIndex()) const; + int rowCount (const QModelIndex & parent = QModelIndex()) const override; - int columnCount (const QModelIndex & parent = QModelIndex()) const; + int columnCount (const QModelIndex & parent = QModelIndex()) const override; - QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; - bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; QVariant getData() const; }; @@ -124,12 +124,12 @@ namespace CSVWorld /// cells, a 0-pointer can be passed here. CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, CSMDoc::Document& document, QObject *parent); - virtual void setModelData (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const; + void setModelData (QWidget *editor, QAbstractItemModel *model, + const QModelIndex& index) const override; - virtual QWidget *createEditor (QWidget *parent, + QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + const QModelIndex& index) const override; virtual QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option, @@ -142,7 +142,7 @@ namespace CSVWorld ///< \return Does column require update? - virtual void setEditorData (QWidget *editor, const QModelIndex& index) const; + void setEditorData (QWidget *editor, const QModelIndex& index) const override; virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const; diff --git a/apps/opencs/view/world/vartypedelegate.hpp b/apps/opencs/view/world/vartypedelegate.hpp index a8f39c318..44705e80e 100644 --- a/apps/opencs/view/world/vartypedelegate.hpp +++ b/apps/opencs/view/world/vartypedelegate.hpp @@ -11,8 +11,8 @@ namespace CSVWorld { private: - virtual void addCommands (QAbstractItemModel *model, - const QModelIndex& index, int type) const; + void addCommands (QAbstractItemModel *model, + const QModelIndex& index, int type) const override; public: @@ -30,8 +30,8 @@ namespace CSVWorld ESM::VarType type1 = ESM::VT_Unknown, ESM::VarType type2 = ESM::VT_Unknown, ESM::VarType type3 = ESM::VT_Unknown); - virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, QObject *parent) const; + CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, + CSMDoc::Document& document, QObject *parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. void add (ESM::VarType type); diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 012ab8f59..49a4b4059 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -774,7 +774,7 @@ public: { } - virtual void operator()(const osg::Image& image, const unsigned int context_id) + void operator()(const osg::Image& image, const unsigned int context_id) override { // Count screenshots. int shotCount = 0; diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 1d59015d3..29d404777 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -341,9 +341,9 @@ namespace MWBase virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) = 0; virtual bool injectKeyRelease(MyGUI::KeyCode key) = 0; - virtual void windowVisibilityChange(bool visible) = 0; - virtual void windowResized(int x, int y) = 0; - virtual void windowClosed() = 0; + void windowVisibilityChange(bool visible) override = 0; + void windowResized(int x, int y) override = 0; + void windowClosed() override = 0; virtual bool isWindowVisible() = 0; virtual void watchActor(const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp index d5175b739..10ace6f74 100644 --- a/apps/openmw/mwclass/activator.hpp +++ b/apps/openmw/mwclass/activator.hpp @@ -8,45 +8,45 @@ namespace MWClass class Activator : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; static int getSndGenTypeFromName(const std::string &name); public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) - virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const; + bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const override; ///< Return whether this class of object can be activated with telekinesis - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; ///< Generate action for activation static void registerSelf(); - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual bool useAnim() const; + bool useAnim() const override; ///< Whether or not to use animated variant of model (default false) - virtual bool isActivator() const; + bool isActivator() const override; - virtual std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const; + std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const override; }; } diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index 6ccd552f9..3d509b276 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -20,30 +20,30 @@ namespace MWClass public: virtual ~Actor(); - virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const; + void adjustPosition(const MWWorld::Ptr& ptr, bool force) const override; ///< Adjust position to stand on ground. Must be called post model load /// @param force do this even if the ptr is flying - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual bool useAnim() const; + bool useAnim() const override; - virtual void block(const MWWorld::Ptr &ptr) const; + void block(const MWWorld::Ptr &ptr) const override; - virtual osg::Vec3f getRotationVector(const MWWorld::Ptr& ptr) const; + osg::Vec3f getRotationVector(const MWWorld::Ptr& ptr) const override; ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. - virtual float getEncumbrance(const MWWorld::Ptr& ptr) const; + float getEncumbrance(const MWWorld::Ptr& ptr) const override; ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. - virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const; + bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const override; ///< Return whether this class of object can be activated with telekinesis - virtual bool isActor() const; + bool isActor() const override; /// Return current movement speed. - virtual float getCurrentSpeed(const MWWorld::Ptr& ptr) const; + float getCurrentSpeed(const MWWorld::Ptr& ptr) const override; // not implemented Actor(const Actor&); diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index ea06f74bd..8087c57ba 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -8,50 +8,50 @@ namespace MWClass class Apparatus : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index e25a4ae8a..4f04e0824 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -7,79 +7,79 @@ namespace MWClass { class Armor : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual bool hasItemHealth (const MWWorld::ConstPtr& ptr) const; + bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override; ///< \return Item health data available? - virtual int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const; + int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; ///< Return item max health or throw an exception, if class does not have item health - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const; + std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const; + int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const override; /// Return the index of the skill this item corresponds to when equipped or -1, if there is /// no such skill. - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getEnchantment (const MWWorld::ConstPtr& ptr) const; + std::string getEnchantment (const MWWorld::ConstPtr& ptr) const override; ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - virtual std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; + std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - virtual std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const; + std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const override; ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. \n /// Second item in the pair specifies the error message - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const; + int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; /// Get the effective armor rating, factoring in the actor's skills, for the given armor. - virtual float getEffectiveArmorRating(const MWWorld::ConstPtr& armor, const MWWorld::Ptr& actor) const; + float getEffectiveArmorRating(const MWWorld::ConstPtr& armor, const MWWorld::Ptr& actor) const override; }; } diff --git a/apps/openmw/mwclass/bodypart.hpp b/apps/openmw/mwclass/bodypart.hpp index b75dee754..13d914138 100644 --- a/apps/openmw/mwclass/bodypart.hpp +++ b/apps/openmw/mwclass/bodypart.hpp @@ -8,24 +8,24 @@ namespace MWClass class BodyPart : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) static void registerSelf(); - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; }; } diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index 6bdb4e79b..c58e68ad8 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -7,58 +7,58 @@ namespace MWClass { class Book : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getEnchantment (const MWWorld::ConstPtr& ptr) const; + std::string getEnchantment (const MWWorld::ConstPtr& ptr) const override; ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - virtual std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; + std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const; + int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index e71e9b307..a87e0cbe0 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -7,70 +7,70 @@ namespace MWClass { class Clothing : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const; + std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const; + int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const override; /// Return the index of the skill this item corresponds to when equipped or -1, if there is /// no such skill. - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getEnchantment (const MWWorld::ConstPtr& ptr) const; + std::string getEnchantment (const MWWorld::ConstPtr& ptr) const override; ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - virtual std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; + std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - virtual std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const; + std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const override; ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. /// Second item in the pair specifies the error message - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const; + int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 0ee549f81..54775e2b0 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -20,10 +20,10 @@ namespace MWClass ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell); ContainerCustomData(const ESM::InventoryState& inventory); - virtual MWWorld::CustomData *clone() const; + MWWorld::CustomData *clone() const override; - virtual ContainerCustomData& asContainerCustomData(); - virtual const ContainerCustomData& asContainerCustomData() const; + ContainerCustomData& asContainerCustomData() override; + const ContainerCustomData& asContainerCustomData() const override; friend class Container; }; @@ -32,60 +32,58 @@ namespace MWClass { void ensureCustomData (const MWWorld::Ptr& ptr) const; - - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; + MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const override; ///< Return container store - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual float getCapacity (const MWWorld::Ptr& ptr) const; + float getCapacity (const MWWorld::Ptr& ptr) const override; ///< Return total weight that fits into the object. Throws an exception, if the object can't /// hold other objects. - virtual float getEncumbrance (const MWWorld::Ptr& ptr) const; + float getEncumbrance (const MWWorld::Ptr& ptr) const override; ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. - virtual bool canLock(const MWWorld::ConstPtr &ptr) const; + bool canLock(const MWWorld::ConstPtr &ptr) const override; - virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const; + void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) + const override; ///< Read additional state from \a state into \a ptr. - virtual void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const; + void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; ///< Write additional state from \a ptr into \a state. static void registerSelf(); - virtual void respawn (const MWWorld::Ptr& ptr) const; + void respawn (const MWWorld::Ptr& ptr) const override; - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual bool useAnim() const; + bool useAnim() const override; }; } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 8e67498a1..c51eab513 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -58,13 +58,13 @@ namespace MWClass MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures MWMechanics::Movement mMovement; - virtual MWWorld::CustomData *clone() const; + MWWorld::CustomData *clone() const override; - virtual CreatureCustomData& asCreatureCustomData() + CreatureCustomData& asCreatureCustomData() override { return *this; } - virtual const CreatureCustomData& asCreatureCustomData() const + const CreatureCustomData& asCreatureCustomData() const override { return *this; } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 21d25633a..0df782eaf 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -14,7 +14,7 @@ namespace MWClass { void ensureCustomData (const MWWorld::Ptr& ptr) const; - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; static int getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name); @@ -40,97 +40,97 @@ namespace MWClass public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip(const MWWorld::ConstPtr& ptr) const; + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const; + MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const override; ///< Return creature stats - virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const; + void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const override; - virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const; + void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const override; - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWWorld::ContainerStore& getContainerStore ( - const MWWorld::Ptr& ptr) const; + MWWorld::ContainerStore& getContainerStore ( + const MWWorld::Ptr& ptr) const override; ///< Return container store - virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const; + MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const override; ///< Return inventory store - virtual bool hasInventoryStore (const MWWorld::Ptr &ptr) const; + bool hasInventoryStore (const MWWorld::Ptr &ptr) const override; - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual float getCapacity (const MWWorld::Ptr& ptr) const; + float getCapacity (const MWWorld::Ptr& ptr) const override; ///< Return total weight that fits into the object. Throws an exception, if the object can't /// hold other objects. - virtual float getArmorRating (const MWWorld::Ptr& ptr) const; + float getArmorRating (const MWWorld::Ptr& ptr) const override; ///< @return combined armor rating of this actor - virtual bool isEssential (const MWWorld::ConstPtr& ptr) const; + bool isEssential (const MWWorld::ConstPtr& ptr) const override; ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) - virtual int getServices (const MWWorld::ConstPtr& actor) const; + int getServices (const MWWorld::ConstPtr& actor) const override; - virtual bool isPersistent (const MWWorld::ConstPtr& ptr) const; + bool isPersistent (const MWWorld::ConstPtr& ptr) const override; - virtual std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const; + std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const override; - virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; + MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const override; ///< Return desired movement. - float getMaxSpeed (const MWWorld::Ptr& ptr) const; + float getMaxSpeed (const MWWorld::Ptr& ptr) const override; static void registerSelf(); - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const; + void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). - virtual bool isBipedal (const MWWorld::ConstPtr &ptr) const; - virtual bool canFly (const MWWorld::ConstPtr &ptr) const; - virtual bool canSwim (const MWWorld::ConstPtr &ptr) const; - virtual bool canWalk (const MWWorld::ConstPtr &ptr) const; + bool isBipedal (const MWWorld::ConstPtr &ptr) const override; + bool canFly (const MWWorld::ConstPtr &ptr) const override; + bool canSwim (const MWWorld::ConstPtr &ptr) const override; + bool canWalk (const MWWorld::ConstPtr &ptr) const override; - virtual float getSkill(const MWWorld::Ptr &ptr, int skill) const; + float getSkill(const MWWorld::Ptr &ptr, int skill) const override; /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) - virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const; + int getBloodTexture (const MWWorld::ConstPtr& ptr) const override; - virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const; + void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; ///< Read additional state from \a state into \a ptr. - virtual void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const; + void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; ///< Write additional state from \a ptr into \a state. - virtual int getBaseGold(const MWWorld::ConstPtr& ptr) const; + int getBaseGold(const MWWorld::ConstPtr& ptr) const override; - virtual void respawn (const MWWorld::Ptr& ptr) const; + void respawn (const MWWorld::Ptr& ptr) const override; - virtual int getBaseFightRating(const MWWorld::ConstPtr &ptr) const; + int getBaseFightRating(const MWWorld::ConstPtr &ptr) const override; - virtual void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const; + void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const override; /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh - virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const override; - virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; + void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const override; float getWalkSpeed(const MWWorld::Ptr& ptr) const final; diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index 2f3ac0d1e..e3e52901e 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -17,13 +17,13 @@ namespace MWClass int mSpawnActorId; bool mSpawn; // Should a new creature be spawned? - virtual MWWorld::CustomData *clone() const; + MWWorld::CustomData *clone() const override; - virtual CreatureLevListCustomData& asCreatureLevListCustomData() + CreatureLevListCustomData& asCreatureLevListCustomData() override { return *this; } - virtual const CreatureLevListCustomData& asCreatureLevListCustomData() const + const CreatureLevListCustomData& asCreatureLevListCustomData() const override { return *this; } diff --git a/apps/openmw/mwclass/creaturelevlist.hpp b/apps/openmw/mwclass/creaturelevlist.hpp index 3a05f5272..35152a942 100644 --- a/apps/openmw/mwclass/creaturelevlist.hpp +++ b/apps/openmw/mwclass/creaturelevlist.hpp @@ -11,27 +11,27 @@ namespace MWClass public: - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) static void registerSelf(); - virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const; + void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const; + void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; ///< Read additional state from \a state into \a ptr. - virtual void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const; + void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; ///< Write additional state from \a ptr into \a state. - virtual void respawn (const MWWorld::Ptr& ptr) const; + void respawn (const MWWorld::Ptr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 4f82aa977..ba51d9c2b 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -36,13 +36,13 @@ namespace MWClass public: MWWorld::DoorState mDoorState = MWWorld::DoorState::Idle; - virtual MWWorld::CustomData *clone() const; + MWWorld::CustomData *clone() const override; - virtual DoorCustomData& asDoorCustomData() + DoorCustomData& asDoorCustomData() override { return *this; } - virtual const DoorCustomData& asDoorCustomData() const + const DoorCustomData& asDoorCustomData() const override { return *this; } diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index 84761900c..6c2fa26b8 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -11,55 +11,53 @@ namespace MWClass { void ensureCustomData (const MWWorld::Ptr& ptr) const; - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual bool isDoor() const; + bool isDoor() const override; - virtual bool useAnim() const; + bool useAnim() const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. static std::string getDestination (const MWWorld::LiveCellRef& door); ///< @return destination cell name or token - virtual bool canLock(const MWWorld::ConstPtr &ptr) const; + bool canLock(const MWWorld::ConstPtr &ptr) const override; - virtual bool allowTelekinesis(const MWWorld::ConstPtr &ptr) const; + bool allowTelekinesis(const MWWorld::ConstPtr &ptr) const override; ///< Return whether this class of object can be activated with telekinesis - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr static void registerSelf(); - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual MWWorld::DoorState getDoorState (const MWWorld::ConstPtr &ptr) const; + MWWorld::DoorState getDoorState (const MWWorld::ConstPtr &ptr) const override; /// This does not actually cause the door to move. Use World::activateDoor instead. - virtual void setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const; + void setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const override; - virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const; + void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; ///< Read additional state from \a state into \a ptr. - virtual void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const; + void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; ///< Write additional state from \a ptr into \a state. }; } diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 8b2ea4f86..5219cf39c 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -7,50 +7,50 @@ namespace MWClass { class Ingredient : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/itemlevlist.hpp b/apps/openmw/mwclass/itemlevlist.hpp index 36019f491..771f8b7a7 100644 --- a/apps/openmw/mwclass/itemlevlist.hpp +++ b/apps/openmw/mwclass/itemlevlist.hpp @@ -9,10 +9,10 @@ namespace MWClass { public: - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) static void registerSelf(); diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index ba3179971..e37dddc25 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -7,71 +7,71 @@ namespace MWClass { class Light : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual bool useAnim() const; + bool useAnim() const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual bool showsInInventory (const MWWorld::ConstPtr& ptr) const; + bool showsInInventory (const MWWorld::ConstPtr& ptr) const override; - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const; + std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const; + void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const override; ///< Sets the remaining duration of the object. - virtual float getRemainingUsageTime (const MWWorld::ConstPtr& ptr) const; + float getRemainingUsageTime (const MWWorld::ConstPtr& ptr) const override; ///< Returns the remaining duration of the object. - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; - std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const; + std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const override; - virtual std::string getSound(const MWWorld::ConstPtr& ptr) const; + std::string getSound(const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index 20ca2d166..fabae3343 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -7,61 +7,61 @@ namespace MWClass { class Lockpick : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const; + std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const; + std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const override; - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const; + int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; ///< Return item max health or throw an exception, if class does not have item health - virtual bool hasItemHealth (const MWWorld::ConstPtr& ptr) const { return true; } + bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override { return true; } ///< \return Item health data available? (default implementation: false) }; } diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index 4812deb5f..9bff85ca5 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -9,52 +9,52 @@ namespace MWClass { public: - virtual MWWorld::Ptr copyToCell(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell, int count) const; + MWWorld::Ptr copyToCell(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell, int count) const override; - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; - virtual bool isKey (const MWWorld::ConstPtr &ptr) const; + bool isKey (const MWWorld::ConstPtr &ptr) const override; - virtual bool isGold (const MWWorld::ConstPtr& ptr) const; + bool isGold (const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 0187f2727..6e8f56925 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -253,13 +253,13 @@ namespace MWClass MWMechanics::Movement mMovement; MWWorld::InventoryStore mInventoryStore; - virtual MWWorld::CustomData *clone() const; + MWWorld::CustomData *clone() const override; - virtual NpcCustomData& asNpcCustomData() + NpcCustomData& asNpcCustomData() override { return *this; } - virtual const NpcCustomData& asNpcCustomData() const + const NpcCustomData& asNpcCustomData() const override { return *this; } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 43340b8d7..dc5fee73a 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -14,7 +14,7 @@ namespace MWClass { void ensureCustomData (const MWWorld::Ptr& ptr) const; - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; struct GMST { @@ -44,128 +44,127 @@ namespace MWClass public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const; + MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const override; ///< Return creature stats - virtual MWMechanics::NpcStats& getNpcStats (const MWWorld::Ptr& ptr) const; + MWMechanics::NpcStats& getNpcStats (const MWWorld::Ptr& ptr) const override; ///< Return NPC stats - virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; + MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const override; ///< Return container store - virtual bool hasToolTip(const MWWorld::ConstPtr& ptr) const; + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const; + MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const override; ///< Return inventory store - virtual bool hasInventoryStore(const MWWorld::Ptr &ptr) const { return true; } + bool hasInventoryStore(const MWWorld::Ptr &ptr) const override { return true; } - virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const; + void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const override; - virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const; + void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const override; - virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const; + void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual float getMaxSpeed (const MWWorld::Ptr& ptr) const; + float getMaxSpeed (const MWWorld::Ptr& ptr) const override; ///< Return maximal movement speed. - virtual float getJump(const MWWorld::Ptr &ptr) const; + float getJump(const MWWorld::Ptr &ptr) const override; ///< Return jump velocity (not accounting for movement) - virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; + MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const override; ///< Return desired movement. - virtual float getCapacity (const MWWorld::Ptr& ptr) const; + float getCapacity (const MWWorld::Ptr& ptr) const override; ///< Return total weight that fits into the object. Throws an exception, if the object can't /// hold other objects. - virtual float getEncumbrance (const MWWorld::Ptr& ptr) const; + float getEncumbrance (const MWWorld::Ptr& ptr) const override; ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. - virtual float getArmorRating (const MWWorld::Ptr& ptr) const; + float getArmorRating (const MWWorld::Ptr& ptr) const override; ///< @return combined armor rating of this actor - virtual bool apply (const MWWorld::Ptr& ptr, const std::string& id, - const MWWorld::Ptr& actor) const; + bool apply (const MWWorld::Ptr& ptr, const std::string& id, + const MWWorld::Ptr& actor) const override; ///< Apply \a id on \a ptr. /// \param actor Actor that is resposible for the ID being applied to \a ptr. /// \return Any effect? - virtual void adjustScale (const MWWorld::ConstPtr &ptr, osg::Vec3f &scale, bool rendering) const; + void adjustScale (const MWWorld::ConstPtr &ptr, osg::Vec3f &scale, bool rendering) const override; /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh - virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const; + void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const override; ///< Inform actor \a ptr that a skill use has succeeded. - virtual bool isEssential (const MWWorld::ConstPtr& ptr) const; + bool isEssential (const MWWorld::ConstPtr& ptr) const override; ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) - virtual int getServices (const MWWorld::ConstPtr& actor) const; + int getServices (const MWWorld::ConstPtr& actor) const override; - virtual bool isPersistent (const MWWorld::ConstPtr& ptr) const; + bool isPersistent (const MWWorld::ConstPtr& ptr) const override; - virtual std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const; + std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const override; static void registerSelf(); - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const; + float getSkill(const MWWorld::Ptr& ptr, int skill) const override; /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) - virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const; + int getBloodTexture (const MWWorld::ConstPtr& ptr) const override; - virtual bool isNpc() const { + bool isNpc() const override + { return true; } - virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const; + void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; ///< Read additional state from \a state into \a ptr. - virtual void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const; + void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; ///< Write additional state from \a ptr into \a state. - virtual int getBaseGold(const MWWorld::ConstPtr& ptr) const; + int getBaseGold(const MWWorld::ConstPtr& ptr) const override; - virtual bool isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const; + bool isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const override; - virtual bool canSwim (const MWWorld::ConstPtr &ptr) const; + bool canSwim (const MWWorld::ConstPtr &ptr) const override; - virtual bool canWalk (const MWWorld::ConstPtr &ptr) const; + bool canWalk (const MWWorld::ConstPtr &ptr) const override; - virtual bool isBipedal (const MWWorld::ConstPtr &ptr) const; + bool isBipedal (const MWWorld::ConstPtr &ptr) const override; - virtual void respawn (const MWWorld::Ptr& ptr) const; + void respawn (const MWWorld::Ptr& ptr) const override; - virtual int getBaseFightRating (const MWWorld::ConstPtr& ptr) const; + int getBaseFightRating (const MWWorld::ConstPtr& ptr) const override; - virtual std::string getPrimaryFaction(const MWWorld::ConstPtr &ptr) const; - virtual int getPrimaryFactionRank(const MWWorld::ConstPtr &ptr) const; + std::string getPrimaryFaction(const MWWorld::ConstPtr &ptr) const override; + int getPrimaryFactionRank(const MWWorld::ConstPtr &ptr) const override; - virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const override; - virtual void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const; + void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const override; float getWalkSpeed(const MWWorld::Ptr& ptr) const final; diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index 8ec4aef44..75d923f0b 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -7,50 +7,50 @@ namespace MWClass { class Potion : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 51a5f8231..a0a41dcfb 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -7,61 +7,61 @@ namespace MWClass { class Probe : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const; + std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const; + std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const override; - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const; + int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; ///< Return item max health or throw an exception, if class does not have item health - virtual bool hasItemHealth (const MWWorld::ConstPtr& ptr) const { return true; } + bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override { return true; } ///< \return Item health data available? (default implementation: false) }; } diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 5d2cfb682..b9791e9cf 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -7,59 +7,58 @@ namespace MWClass { class Repair : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) - const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu (default implementation: return a /// null action). - virtual bool hasItemHealth (const MWWorld::ConstPtr& ptr) const; + bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override; ///< \return Item health data available? (default implementation: false) - virtual int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const; + int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; ///< Return item max health or throw an exception, if class does not have item health /// (default implementation: throw an exception) - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp index 6b3b8088c..6bc783dad 100644 --- a/apps/openmw/mwclass/static.hpp +++ b/apps/openmw/mwclass/static.hpp @@ -7,24 +7,24 @@ namespace MWClass { class Static : public MWWorld::Class { - virtual MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; + bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) static void registerSelf(); - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; }; } diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 2c1197b69..f1824b7d1 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -7,77 +7,77 @@ namespace MWClass { class Weapon : public MWWorld::Class { - virtual MWWorld::Ptr - copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const; + MWWorld::Ptr + copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; public: - virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; + void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const override; - virtual std::string getName (const MWWorld::ConstPtr& ptr) const; + std::string getName (const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - virtual std::shared_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const; + std::shared_ptr activate (const MWWorld::Ptr& ptr, + const MWWorld::Ptr& actor) const override; ///< Generate action for activation - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; + MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual bool hasItemHealth (const MWWorld::ConstPtr& ptr) const; + bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override; ///< \return Item health data available? - virtual int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const; + int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; ///< Return item max health or throw an exception, if class does not have item health - virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; + std::string getScript (const MWWorld::ConstPtr& ptr) const override; ///< Return name of the script attached to ptr - virtual std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const; + std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? - virtual int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const; + int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const override; /// Return the index of the skill this item corresponds to when equipped or -1, if there is /// no such skill. - virtual int getValue (const MWWorld::ConstPtr& ptr) const; + int getValue (const MWWorld::ConstPtr& ptr) const override; ///< Return trade value of the object. Throws an exception, if the object can't be traded. static void registerSelf(); - virtual std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getUpSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the pick up sound Id - virtual std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const; + std::string getDownSoundId (const MWWorld::ConstPtr& ptr) const override; ///< Return the put down sound Id - virtual std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const; + std::string getInventoryIcon (const MWWorld::ConstPtr& ptr) const override; ///< Return name of inventory icon. - virtual std::string getEnchantment (const MWWorld::ConstPtr& ptr) const; + std::string getEnchantment (const MWWorld::ConstPtr& ptr) const override; ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - virtual std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; + std::string applyEnchantment(const MWWorld::ConstPtr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - virtual std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const; + std::pair canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const override; ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. /// Second item in the pair specifies the error message - virtual std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const; + std::shared_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; ///< Generate action for using via inventory menu - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; + bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + float getWeight (const MWWorld::ConstPtr& ptr) const override; - virtual int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const; + int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 23dd68e91..77e59b633 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -66,57 +66,57 @@ namespace MWDialogue DialogueManager (const Compiler::Extensions& extensions, Translation::Storage& translationDataStorage); - virtual void clear(); + void clear() override; - virtual bool isInChoice() const; + bool isInChoice() const override; - virtual bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback); + bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) override; - std::list getAvailableTopics(); + std::list getAvailableTopics() override; int getTopicFlag(const std::string& topicId) final; bool inJournal (const std::string& topicId, const std::string& infoId) final; - virtual void addTopic (const std::string& topic); + void addTopic (const std::string& topic) override; - virtual void addChoice (const std::string& text,int choice); - const std::vector >& getChoices(); + void addChoice (const std::string& text,int choice) override; + const std::vector >& getChoices() override; - virtual bool isGoodbye(); + bool isGoodbye() override; - virtual void goodbye(); + void goodbye() override; - virtual bool checkServiceRefused (ResponseCallback* callback); + bool checkServiceRefused (ResponseCallback* callback) override; - virtual void say(const MWWorld::Ptr &actor, const std::string &topic); + void say(const MWWorld::Ptr &actor, const std::string &topic) override; //calbacks for the GUI - virtual void keywordSelected (const std::string& keyword, ResponseCallback* callback); - virtual void goodbyeSelected(); - virtual void questionAnswered (int answer, ResponseCallback* callback); + void keywordSelected (const std::string& keyword, ResponseCallback* callback) override; + void goodbyeSelected() override; + void questionAnswered (int answer, ResponseCallback* callback) override; - virtual void persuade (int type, ResponseCallback* callback); - virtual int getTemporaryDispositionChange () const; + void persuade (int type, ResponseCallback* callback) override; + int getTemporaryDispositionChange () const override; /// @note Controlled by an option, gets discarded when dialogue ends by default - virtual void applyBarterDispositionChange (int delta); + void applyBarterDispositionChange (int delta) override; - virtual int countSavedGameRecords() const; + int countSavedGameRecords() const override; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + void write (ESM::ESMWriter& writer, Loading::Listener& progress) const override; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type); + void readRecord (ESM::ESMReader& reader, uint32_t type) override; /// Changes faction1's opinion of faction2 by \a diff. - virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff); + void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff) override; - virtual void setFactionReaction (const std::string& faction1, const std::string& faction2, int absolute); + void setFactionReaction (const std::string& faction1, const std::string& faction2, int absolute) override; /// @return faction1's opinion of faction2 - virtual int getFactionReaction (const std::string& faction1, const std::string& faction2) const; + int getFactionReaction (const std::string& faction1, const std::string& faction2) const override; /// Removes the last added topic response for the given actor from the journal - virtual void clearInfoActor (const MWWorld::Ptr& actor) const; + void clearInfoActor (const MWWorld::Ptr& actor) const override; }; } diff --git a/apps/openmw/mwdialogue/journalimp.hpp b/apps/openmw/mwdialogue/journalimp.hpp index c3e940629..a6501e54e 100644 --- a/apps/openmw/mwdialogue/journalimp.hpp +++ b/apps/openmw/mwdialogue/journalimp.hpp @@ -27,52 +27,52 @@ namespace MWDialogue Journal(); - virtual void clear(); + void clear() override; - virtual void addEntry (const std::string& id, int index, const MWWorld::Ptr& actor); + void addEntry (const std::string& id, int index, const MWWorld::Ptr& actor) override; ///< Add a journal entry. /// @param actor Used as context for replacing of escape sequences (%name, etc). - virtual void setJournalIndex (const std::string& id, int index); + void setJournalIndex (const std::string& id, int index) override; ///< Set the journal index without adding an entry. - virtual int getJournalIndex (const std::string& id) const; + int getJournalIndex (const std::string& id) const override; ///< Get the journal index. - virtual void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor); + void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) override; /// \note topicId must be lowercase - virtual void removeLastAddedTopicResponse (const std::string& topicId, const std::string& actorName); + void removeLastAddedTopicResponse (const std::string& topicId, const std::string& actorName) override; ///< Removes the last topic response added for the given topicId and actor name. /// \note topicId must be lowercase - virtual TEntryIter begin() const; + TEntryIter begin() const override; ///< Iterator pointing to the begin of the main journal. /// /// \note Iterators to main journal entries will never become invalid. - virtual TEntryIter end() const; + TEntryIter end() const override; ///< Iterator pointing past the end of the main journal. - virtual TQuestIter questBegin() const; + TQuestIter questBegin() const override; ///< Iterator pointing to the first quest (sorted by topic ID) - virtual TQuestIter questEnd() const; + TQuestIter questEnd() const override; ///< Iterator pointing past the last quest. - virtual TTopicIter topicBegin() const; + TTopicIter topicBegin() const override; ///< Iterator pointing to the first topic (sorted by topic ID) /// /// \note The topic ID is identical with the user-visible topic string. - virtual TTopicIter topicEnd() const; + TTopicIter topicEnd() const override; ///< Iterator pointing past the last topic. - virtual int countSavedGameRecords() const; + int countSavedGameRecords() const override; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + void write (ESM::ESMWriter& writer, Loading::Listener& progress) const override; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type); + void readRecord (ESM::ESMReader& reader, uint32_t type) override; }; } diff --git a/apps/openmw/mwdialogue/quest.hpp b/apps/openmw/mwdialogue/quest.hpp index 40824f398..712f94fae 100644 --- a/apps/openmw/mwdialogue/quest.hpp +++ b/apps/openmw/mwdialogue/quest.hpp @@ -24,7 +24,7 @@ namespace MWDialogue Quest (const ESM::QuestState& state); - virtual std::string getName() const; + std::string getName() const override; ///< May be an empty string int getIndex() const; @@ -34,7 +34,7 @@ namespace MWDialogue bool isFinished() const; - virtual void addEntry (const JournalEntry& entry); + void addEntry (const JournalEntry& entry) override; ///< Add entry and adjust index accordingly. /// /// \note Redundant entries are ignored, but the index is still adjusted. diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index 82dd0a243..33bd1f974 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -29,9 +29,9 @@ namespace MWGui public: AlchemyWindow(); - virtual void onOpen(); + void onOpen() override; - void onResChange(int, int) { center(); } + void onResChange(int, int) override { center(); } private: diff --git a/apps/openmw/mwgui/birth.hpp b/apps/openmw/mwgui/birth.hpp index 86af14286..9f9d4332f 100644 --- a/apps/openmw/mwgui/birth.hpp +++ b/apps/openmw/mwgui/birth.hpp @@ -20,9 +20,9 @@ namespace MWGui void setBirthId(const std::string &raceId); void setNextButtonShow(bool shown); - virtual void onOpen(); + void onOpen() override; - bool exit() { return false; } + bool exit() override { return false; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index 47027c2b7..a346526eb 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -115,9 +115,9 @@ struct TypesetBookImpl : TypesetBook return Range (i->data(), i->data() + i->size()); } - size_t pageCount () const { return mPages.size (); } + size_t pageCount () const override { return mPages.size (); } - std::pair getSize () const + std::pair getSize () const override { return std::make_pair (mRect.width (), mRect.height ()); } @@ -261,7 +261,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter { } - Style * createStyle (const std::string& fontName, const Colour& fontColour, bool useBookFont) + Style * createStyle (const std::string& fontName, const Colour& fontColour, bool useBookFont) override { std::string fullFontName; if (fontName.empty()) @@ -291,7 +291,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter } Style* createHotStyle (Style* baseStyle, const Colour& normalColour, const Colour& hoverColour, - const Colour& activeColour, InteractiveId id, bool unique) + const Colour& activeColour, InteractiveId id, bool unique) override { StyleImpl* BaseStyle = static_cast (baseStyle); @@ -311,14 +311,14 @@ struct TypesetBookImpl::Typesetter : BookTypesetter return &style; } - void write (Style * style, Utf8Span text) + void write (Style * style, Utf8Span text) override { Range range = mBook->addContent (text); writeImpl (static_cast (style), range.first, range.second); } - intptr_t addContent (Utf8Span text, bool select) + intptr_t addContent (Utf8Span text, bool select) override { add_partial_text(); @@ -330,14 +330,14 @@ struct TypesetBookImpl::Typesetter : BookTypesetter return reinterpret_cast (&(*i)); } - void selectContent (intptr_t contentHandle) + void selectContent (intptr_t contentHandle) override { add_partial_text(); mCurrentContent = reinterpret_cast (contentHandle); } - void write (Style * style, size_t begin, size_t end) + void write (Style * style, size_t begin, size_t end) override { assert (mCurrentContent != nullptr); assert (end <= mCurrentContent->size ()); @@ -349,7 +349,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter writeImpl (static_cast (style), begin_, end_); } - void lineBreak (float margin) + void lineBreak (float margin) override { assert (margin == 0); //TODO: figure out proper behavior here... @@ -359,7 +359,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter mLine = nullptr; } - void sectionBreak (int margin) + void sectionBreak (int margin) override { add_partial_text(); @@ -374,7 +374,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter } } - void setSectionAlignment (Alignment sectionAlignment) + void setSectionAlignment (Alignment sectionAlignment) override { add_partial_text(); @@ -383,7 +383,7 @@ struct TypesetBookImpl::Typesetter : BookTypesetter mCurrentAlignment = sectionAlignment; } - TypesetBook::Ptr complete () + TypesetBook::Ptr complete () override { int curPageStart = 0; int curPageStop = 0; @@ -869,12 +869,12 @@ protected: } } - void doRender() { mDisplay->doRender (*this); } + void doRender() override { mDisplay->doRender (*this); } // this isn't really a sub-widget, its just a "drawitem" which // should have its own interface - void createDrawItem(MyGUI::ITexture* _texture, MyGUI::ILayerNode* _node) {} - void destroyDrawItem() {}; + void createDrawItem(MyGUI::ITexture* _texture, MyGUI::ILayerNode* _node) override {} + void destroyDrawItem() override {} }; void resetPage() diff --git a/apps/openmw/mwgui/bookwindow.hpp b/apps/openmw/mwgui/bookwindow.hpp index b0dfe09ce..116437f22 100644 --- a/apps/openmw/mwgui/bookwindow.hpp +++ b/apps/openmw/mwgui/bookwindow.hpp @@ -14,10 +14,10 @@ namespace MWGui public: BookWindow(); - void setPtr(const MWWorld::Ptr& book); + void setPtr(const MWWorld::Ptr& book) override; void setInventoryAllowed(bool allowed); - void onResChange(int, int) { center(); } + void onResChange(int, int) override { center(); } protected: void onNextPageButtonClicked (MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index 3a2573fd4..bb34a0553 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -21,9 +21,9 @@ namespace MWGui std::string getText() const; void setButtons(ButtonList &buttons); - virtual void onOpen(); + void onOpen() override; - bool exit() { return false; } + bool exit() override { return false; } // Events typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Int; @@ -69,7 +69,7 @@ namespace MWGui std::string getClassId() const; void setClassId(const std::string &classId); - bool exit() { return false; } + bool exit() override { return false; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; @@ -104,9 +104,9 @@ namespace MWGui void setClassId(const std::string &classId); void setNextButtonShow(bool shown); - virtual void onOpen(); + void onOpen() override; - bool exit() { return false; } + bool exit() override { return false; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; @@ -148,7 +148,7 @@ namespace MWGui SelectSpecializationDialog(); ~SelectSpecializationDialog(); - virtual bool exit(); + bool exit() override; ESM::Class::Specialization getSpecializationId() const { return mSpecializationId; } @@ -181,7 +181,7 @@ namespace MWGui SelectAttributeDialog(); ~SelectAttributeDialog(); - virtual bool exit(); + bool exit() override; ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; } @@ -212,7 +212,7 @@ namespace MWGui SelectSkillDialog(); ~SelectSkillDialog(); - virtual bool exit(); + bool exit() override; ESM::Skill::SkillEnum getSkillId() const { return mSkillId; } @@ -268,7 +268,7 @@ namespace MWGui CreateClassDialog(); virtual ~CreateClassDialog(); - bool exit() { return false; } + bool exit() override { return false; } std::string getName() const; std::string getDescription() const; diff --git a/apps/openmw/mwgui/companionitemmodel.hpp b/apps/openmw/mwgui/companionitemmodel.hpp index b30a98142..1872dd156 100644 --- a/apps/openmw/mwgui/companionitemmodel.hpp +++ b/apps/openmw/mwgui/companionitemmodel.hpp @@ -13,8 +13,8 @@ namespace MWGui public: CompanionItemModel (const MWWorld::Ptr& actor); - virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true); - virtual void removeItem (const ItemStack& item, size_t count); + MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem (const ItemStack& item, size_t count) override; bool hasProfit(const MWWorld::Ptr& actor); }; diff --git a/apps/openmw/mwgui/companionwindow.hpp b/apps/openmw/mwgui/companionwindow.hpp index 442ce57da..7a7c92e3d 100644 --- a/apps/openmw/mwgui/companionwindow.hpp +++ b/apps/openmw/mwgui/companionwindow.hpp @@ -22,13 +22,13 @@ namespace MWGui public: CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager); - virtual bool exit(); + bool exit() override; - virtual void resetReference(); + void resetReference() override; - void setPtr(const MWWorld::Ptr& npc); - void onFrame (float dt); - void clear() { resetReference(); } + void setPtr(const MWWorld::Ptr& npc) override; + void onFrame (float dt) override; + void clear() override { resetReference(); } private: ItemView* mItemView; @@ -55,7 +55,7 @@ namespace MWGui void onCloseButtonClicked(MyGUI::Widget* _sender); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; }; } diff --git a/apps/openmw/mwgui/confirmationdialog.hpp b/apps/openmw/mwgui/confirmationdialog.hpp index ab52549ec..2acefd54c 100644 --- a/apps/openmw/mwgui/confirmationdialog.hpp +++ b/apps/openmw/mwgui/confirmationdialog.hpp @@ -10,7 +10,7 @@ namespace MWGui public: ConfirmationDialog(); void askForConfirmation(const std::string& message); - virtual bool exit(); + bool exit() override; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 120573d59..e56cd170c 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -30,7 +30,7 @@ namespace MWGui ConsoleInterpreterContext (Console& console, MWWorld::Ptr reference); - virtual void report (const std::string& message); + void report (const std::string& message) override; }; ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console, diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index e431d18d1..52aa42f2a 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -39,9 +39,9 @@ namespace MWGui Console(int w, int h, bool consoleOnlyScripts); - virtual void onOpen(); + void onOpen() override; - void onResChange(int width, int height); + void onResChange(int width, int height) override; // Print a message to the console, in specified color. void print(const std::string &msg, const std::string& color = "#FFFFFF"); @@ -60,13 +60,13 @@ namespace MWGui void updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr); - void clear(); + void clear() override; - virtual void resetReference (); + void resetReference () override; protected: - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; private: @@ -86,10 +86,10 @@ namespace MWGui bool compile (const std::string& cmd, Compiler::Output& output); /// Report error to the user. - virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); + void report (const std::string& message, const Compiler::TokenLoc& loc, Type type) override; /// Report a file related error - virtual void report (const std::string& message, Type type); + void report (const std::string& message, Type type) override; /// Write all valid identifiers and keywords into mNames and sort them. /// \note If mNames is not empty, this function is a no-op. diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index cf02d165d..feda123fb 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -33,13 +33,13 @@ namespace MWGui public: ContainerWindow(DragAndDrop* dragAndDrop); - void setPtr(const MWWorld::Ptr& container); - virtual void onClose(); - void clear() { resetReference(); } + void setPtr(const MWWorld::Ptr& container) override; + void onClose() override; + void clear() override { resetReference(); } - void onFrame(float dt) { checkReferenceAvailable(); } + void onFrame(float dt) override { checkReferenceAvailable(); } - virtual void resetReference(); + void resetReference() override; private: DragAndDrop* mDragAndDrop; @@ -64,7 +64,7 @@ namespace MWGui /// @return is taking the item allowed? bool onTakeItem(const ItemStack& item, int count); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; }; } #endif // CONTAINER_H diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index d09bd7def..c54f11314 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -22,19 +22,19 @@ namespace MWGui ContainerItemModel (const MWWorld::Ptr& source); - virtual bool allowedToUseItems() const; + bool allowedToUseItems() const override; - virtual bool onDropItem(const MWWorld::Ptr &item, int count); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); + bool onDropItem(const MWWorld::Ptr &item, int count) override; + bool onTakeItem(const MWWorld::Ptr &item, int count) override; - virtual ItemStack getItem (ModelIndex index); - virtual ModelIndex getIndex (ItemStack item); - virtual size_t getItemCount(); + ItemStack getItem (ModelIndex index) override; + ModelIndex getIndex (ItemStack item) override; + size_t getItemCount() override; - virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true); - virtual void removeItem (const ItemStack& item, size_t count); + MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem (const ItemStack& item, size_t count) override; - virtual void update(); + void update() override; private: std::vector> mItemSources; diff --git a/apps/openmw/mwgui/debugwindow.hpp b/apps/openmw/mwgui/debugwindow.hpp index af5b914ea..33647c078 100644 --- a/apps/openmw/mwgui/debugwindow.hpp +++ b/apps/openmw/mwgui/debugwindow.hpp @@ -11,7 +11,7 @@ namespace MWGui public: DebugWindow(); - void onFrame(float dt); + void onFrame(float dt) override; private: MyGUI::TabControl* mTabControl; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 2527da374..8517dfd96 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -41,7 +41,7 @@ namespace MWGui } - void addResponse(const std::string& title, const std::string& text) + void addResponse(const std::string& title, const std::string& text) override { mWindow->addResponse(title, text, mNeedMargin); } diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index d9c26ef20..ed4c39afe 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -29,9 +29,9 @@ namespace MWGui public: PersuasionDialog(ResponseCallback* callback); - virtual void onOpen(); + void onOpen() override; - virtual MyGUI::Widget* getDefaultKeyFocus(); + MyGUI::Widget* getDefaultKeyFocus() override; private: std::unique_ptr mCallback; @@ -62,7 +62,7 @@ namespace MWGui EventHandle_TopicId eventTopicActivated; Topic(const std::string& id) : mTopicId(id) {} std::string mTopicId; - virtual void activated (); + void activated () override; }; struct Choice : Link @@ -71,14 +71,14 @@ namespace MWGui EventHandle_ChoiceId eventChoiceActivated; Choice(int id) : mChoiceId(id) {} int mChoiceId; - virtual void activated (); + void activated () override; }; struct Goodbye : Link { typedef MyGUI::delegates::CMultiDelegate0 Event_Activated; Event_Activated eventActivated; - virtual void activated (); + void activated () override; }; typedef MWDialogue::KeywordSearch KeywordSearchT; @@ -93,7 +93,7 @@ namespace MWGui struct Response : DialogueText { Response(const std::string& text, const std::string& title = "", bool needMargin = true); - virtual void write (BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map& topicLinks) const; + void write (BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map& topicLinks) const override; void addTopicLink (BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const; std::string mTitle; bool mNeedMargin; @@ -102,7 +102,7 @@ namespace MWGui struct Message : DialogueText { Message(const std::string& text); - virtual void write (BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map& topicLinks) const; + void write (BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map& topicLinks) const override; }; class DialogueWindow: public WindowBase, public ReferenceInterface @@ -113,14 +113,14 @@ namespace MWGui void onTradeComplete(); - virtual bool exit(); + bool exit() override; // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; void notifyLinkClicked (TypesetBook::InteractiveId link); - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) override; void setKeywords(std::list keyWord); @@ -128,12 +128,12 @@ namespace MWGui void addMessageBox(const std::string& text); - void onFrame(float dt); - void clear() { resetReference(); } + void onFrame(float dt) override; + void clear() override { resetReference(); } void updateTopics(); - void onClose(); + void onClose() override; protected: void updateTopicsPane(); @@ -152,7 +152,7 @@ namespace MWGui void updateHistory(bool scrollbar=false); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; private: void updateDisposition(); diff --git a/apps/openmw/mwgui/enchantingdialog.hpp b/apps/openmw/mwgui/enchantingdialog.hpp index 4906de919..3989ae076 100644 --- a/apps/openmw/mwgui/enchantingdialog.hpp +++ b/apps/openmw/mwgui/enchantingdialog.hpp @@ -19,23 +19,23 @@ namespace MWGui EnchantingDialog(); virtual ~EnchantingDialog(); - virtual void onOpen(); + void onOpen() override; - void onFrame(float dt) { checkReferenceAvailable(); } - void clear() { resetReference(); } + void onFrame(float dt) override { checkReferenceAvailable(); } + void clear() override { resetReference(); } void setSoulGem (const MWWorld::Ptr& gem); void setItem (const MWWorld::Ptr& item); /// Actor Ptr: buy enchantment from this actor /// Soulgem Ptr: player self-enchant - void setPtr(const MWWorld::Ptr& ptr); + void setPtr(const MWWorld::Ptr& ptr) override; - virtual void resetReference(); + void resetReference() override; protected: - virtual void onReferenceUnavailable(); - virtual void notifyEffectsChanged (); + void onReferenceUnavailable() override; + void notifyEffectsChanged() override; void onCancelButtonClicked(MyGUI::Widget* sender); void onSelectItem (MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index b16a4e57d..d56351414 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -149,8 +149,8 @@ namespace MWGui public: TextElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle, const TextStyle & textStyle, const std::string & text); - virtual int getHeight(); - virtual int pageSplit(); + int getHeight() override; + int pageSplit() override; private: int currentFontHeight() const; TextStyle mTextStyle; @@ -162,8 +162,8 @@ namespace MWGui public: ImageElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle, const std::string & src, int width, int height); - virtual int getHeight(); - virtual int pageSplit(); + int getHeight() override; + int pageSplit() override; private: int mImageHeight; diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index fd0fcb798..a4ab20fd6 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -37,8 +37,8 @@ namespace MWGui { public: WorldItemModel(float left, float top) : mLeft(left), mTop(top) {} - virtual ~WorldItemModel() {} - virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool /*allowAutoEquip*/) + virtual ~WorldItemModel() override {} + MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override { MWBase::World* world = MWBase::Environment::get().getWorld(); @@ -52,11 +52,11 @@ namespace MWGui return dropped; } - virtual void removeItem (const ItemStack& item, size_t count) { throw std::runtime_error("removeItem not implemented"); } - virtual ModelIndex getIndex (ItemStack item) { throw std::runtime_error("getIndex not implemented"); } - virtual void update() {} - virtual size_t getItemCount() { return 0; } - virtual ItemStack getItem (ModelIndex index) { throw std::runtime_error("getItem not implemented"); } + void removeItem (const ItemStack& item, size_t count) override { throw std::runtime_error("removeItem not implemented"); } + ModelIndex getIndex (ItemStack item) override { throw std::runtime_error("getIndex not implemented"); } + void update() override {} + size_t getItemCount() override { return 0; } + ItemStack getItem (ModelIndex index) override { throw std::runtime_error("getItem not implemented"); } private: // Where to drop the item diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index 15235fe91..8a89320d8 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -112,8 +112,8 @@ namespace MWGui void onMapClicked(MyGUI::Widget* _sender); // LocalMapBase - virtual void customMarkerCreated(MyGUI::Widget* marker) override; - virtual void doorMarkerCreated(MyGUI::Widget* marker) override; + void customMarkerCreated(MyGUI::Widget* marker) override; + void doorMarkerCreated(MyGUI::Widget* marker) override; void updateEnemyHealthBar(); diff --git a/apps/openmw/mwgui/inventoryitemmodel.hpp b/apps/openmw/mwgui/inventoryitemmodel.hpp index d1fb88b6e..30d17f3e6 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.hpp +++ b/apps/openmw/mwgui/inventoryitemmodel.hpp @@ -11,19 +11,19 @@ namespace MWGui public: InventoryItemModel (const MWWorld::Ptr& actor); - virtual ItemStack getItem (ModelIndex index); - virtual ModelIndex getIndex (ItemStack item); - virtual size_t getItemCount(); + ItemStack getItem (ModelIndex index) override; + ModelIndex getIndex (ItemStack item) override; + size_t getItemCount() override; - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); + bool onTakeItem(const MWWorld::Ptr &item, int count) override; - virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true); - virtual void removeItem (const ItemStack& item, size_t count); + MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem (const ItemStack& item, size_t count) override; /// Move items from this model to \a otherModel. - virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel); + MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel) override; - virtual void update(); + void update() override; protected: MWWorld::Ptr mActor; diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index f2ab7f1ee..dc3ee9e0c 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -35,12 +35,12 @@ namespace MWGui public: InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem); - virtual void onOpen(); + void onOpen() override; /// start trading, disables item drag&drop void setTrading(bool trading); - void onFrame(float dt); + void onFrame(float dt) override; void pickUpObject (MWWorld::Ptr object); @@ -56,7 +56,7 @@ namespace MWGui void updatePlayer(); - void clear(); + void clear() override; void useItem(const MWWorld::Ptr& ptr, bool force=false); @@ -66,7 +66,7 @@ namespace MWGui void cycle(bool next); protected: - virtual void onTitleDoubleClicked(); + void onTitleDoubleClicked() override; private: DragAndDrop* mDragAndDrop; @@ -123,7 +123,7 @@ namespace MWGui void onFilterChanged(MyGUI::Widget* _sender); void onNameFilterChanged(MyGUI::EditBox* _sender); void onAvatarClicked(MyGUI::Widget* _sender); - void onPinToggled(); + void onPinToggled() override; void updateEncumbranceBar(); void notifyContentChanged(); diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp index 4d923bae3..e120dde0f 100644 --- a/apps/openmw/mwgui/itemmodel.hpp +++ b/apps/openmw/mwgui/itemmodel.hpp @@ -88,15 +88,15 @@ namespace MWGui ProxyItemModel(); virtual ~ProxyItemModel(); - bool allowedToUseItems() const; + bool allowedToUseItems() const override; - virtual void onClose(); - virtual bool onDropItem(const MWWorld::Ptr &item, int count); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); + void onClose() override; + bool onDropItem(const MWWorld::Ptr &item, int count) override; + bool onTakeItem(const MWWorld::Ptr &item, int count) override; - virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true); - virtual void removeItem (const ItemStack& item, size_t count); - virtual ModelIndex getIndex (ItemStack item); + MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem (const ItemStack& item, size_t count) override; + ModelIndex getIndex (ItemStack item) override; /// @note Takes ownership of the passed pointer. void setSourceModel(ItemModel* sourceModel); diff --git a/apps/openmw/mwgui/itemselection.hpp b/apps/openmw/mwgui/itemselection.hpp index 07b6452a5..6132bac7a 100644 --- a/apps/openmw/mwgui/itemselection.hpp +++ b/apps/openmw/mwgui/itemselection.hpp @@ -21,7 +21,7 @@ namespace MWGui public: ItemSelectionDialog(const std::string& label); - virtual bool exit(); + bool exit() override; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Item; diff --git a/apps/openmw/mwgui/jailscreen.hpp b/apps/openmw/mwgui/jailscreen.hpp index 36d19b5a9..871a861d7 100644 --- a/apps/openmw/mwgui/jailscreen.hpp +++ b/apps/openmw/mwgui/jailscreen.hpp @@ -12,9 +12,9 @@ namespace MWGui JailScreen(); void goToJail(int days); - void onFrame(float dt); + void onFrame(float dt) override; - bool exit() { return false; } + bool exit() override { return false; } private: int mDays; diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index 3621656bc..426c3b437 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -46,11 +46,11 @@ struct JournalViewModelImpl : JournalViewModel return Utf8Span (point, point + str.size ()); } - void load () + void load () override { } - void unload () + void unload () override { mKeywordSearch.clear (); mKeywordSearchLoaded = false; @@ -69,7 +69,7 @@ struct JournalViewModelImpl : JournalViewModel } } - bool isEmpty () const + bool isEmpty () const override { MWBase::Journal * journal = MWBase::Environment::get().getJournal(); @@ -141,14 +141,14 @@ struct JournalViewModelImpl : JournalViewModel } } - Utf8Span body () const + Utf8Span body () const override { ensureLoaded (); return toUtf8Span (utf8text); } - void visitSpans (std::function < void (TopicId, size_t, size_t)> visitor) const + void visitSpans (std::function < void (TopicId, size_t, size_t)> visitor) const override { ensureLoaded (); mModel->ensureKeyWordSearchLoaded (); @@ -192,7 +192,7 @@ struct JournalViewModelImpl : JournalViewModel }; - void visitQuestNames (bool active_only, std::function visitor) const + void visitQuestNames (bool active_only, std::function visitor) const override { MWBase::Journal * journal = MWBase::Environment::get ().getJournal (); @@ -242,12 +242,12 @@ struct JournalViewModelImpl : JournalViewModel BaseEntry (model, itr) {} - std::string getText () const + std::string getText () const override { return itr->getText(); } - Utf8Span timestamp () const + Utf8Span timestamp () const override { if (timestamp_buffer.empty ()) { @@ -267,7 +267,7 @@ struct JournalViewModelImpl : JournalViewModel } }; - void visitJournalEntries (const std::string& questName, std::function visitor) const + void visitJournalEntries (const std::string& questName, std::function visitor) const override { MWBase::Journal * journal = MWBase::Environment::get().getJournal(); @@ -300,13 +300,13 @@ struct JournalViewModelImpl : JournalViewModel } } - void visitTopicName (TopicId topicId, std::function visitor) const + void visitTopicName (TopicId topicId, std::function visitor) const override { MWDialogue::Topic const & topic = * reinterpret_cast (topicId); visitor (toUtf8Span (topic.getName())); } - void visitTopicNamesStartingWith (Utf8Stream::UnicodeChar character, std::function < void (const std::string&) > visitor) const + void visitTopicNamesStartingWith (Utf8Stream::UnicodeChar character, std::function < void (const std::string&) > visitor) const override { MWBase::Journal * journal = MWBase::Environment::get().getJournal(); @@ -330,19 +330,19 @@ struct JournalViewModelImpl : JournalViewModel BaseEntry (model, itr), mTopic (topic) {} - std::string getText () const + std::string getText () const override { return itr->getText(); } - Utf8Span source () const + Utf8Span source () const override { return toUtf8Span (itr->mActorName); } }; - void visitTopicEntries (TopicId topicId, std::function visitor) const + void visitTopicEntries (TopicId topicId, std::function visitor) const override { typedef MWDialogue::Topic::TEntryIter iterator_t; diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 43e7edf1e..1474becf0 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -226,7 +226,7 @@ namespace mTopicsMode = false; } - void onOpen() + void onOpen() override { if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ()) { @@ -257,7 +257,7 @@ namespace MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(getWidget(CloseBTN)); } - void onClose() + void onClose() override { mModel->unload (); @@ -270,7 +270,7 @@ namespace mTopicIndexBook.reset (); } - void setVisible (bool newValue) + void setVisible (bool newValue) override { WindowBase::setVisible (newValue); } diff --git a/apps/openmw/mwgui/journalwindow.hpp b/apps/openmw/mwgui/journalwindow.hpp index 8cc0a5ef3..c18e6e4c0 100644 --- a/apps/openmw/mwgui/journalwindow.hpp +++ b/apps/openmw/mwgui/journalwindow.hpp @@ -21,10 +21,10 @@ namespace MWGui static JournalWindow * create (std::shared_ptr Model, bool questList, ToUTF8::FromType encoding); /// destroy this instance of the JournalWindow implementation - virtual ~JournalWindow () {}; + virtual ~JournalWindow () {} /// show/hide the journal window - virtual void setVisible (bool newValue) = 0; + void setVisible (bool newValue) override = 0; }; } diff --git a/apps/openmw/mwgui/keyboardnavigation.hpp b/apps/openmw/mwgui/keyboardnavigation.hpp index 2a094a2df..d5159c24a 100644 --- a/apps/openmw/mwgui/keyboardnavigation.hpp +++ b/apps/openmw/mwgui/keyboardnavigation.hpp @@ -19,7 +19,7 @@ namespace MWGui void saveFocus(int mode); void restoreFocus(int mode); - void _unlinkWidget(MyGUI::Widget* widget); + void _unlinkWidget(MyGUI::Widget* widget) override; void onFrame(); diff --git a/apps/openmw/mwgui/levelupdialog.hpp b/apps/openmw/mwgui/levelupdialog.hpp index 36810665e..6c9182609 100644 --- a/apps/openmw/mwgui/levelupdialog.hpp +++ b/apps/openmw/mwgui/levelupdialog.hpp @@ -11,7 +11,7 @@ namespace MWGui public: LevelupDialog(); - virtual void onOpen(); + void onOpen() override; private: MyGUI::Button* mOkButton; diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 521b88f29..cd0384bb0 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -141,7 +141,7 @@ namespace MWGui { } - virtual void operator () (osg::RenderInfo& renderInfo) const + void operator () (osg::RenderInfo& renderInfo) const override { if (!oneshot) return; @@ -159,7 +159,7 @@ namespace MWGui class DontComputeBoundCallback : public osg::Node::ComputeBoundingSphereCallback { public: - virtual osg::BoundingSphere computeBound(const osg::Node&) const { return osg::BoundingSphere(); } + osg::BoundingSphere computeBound(const osg::Node&) const override { return osg::BoundingSphere(); } }; void LoadingScreen::loadingOn(bool visible) diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index b3e2534ce..2577827aa 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -36,14 +36,14 @@ namespace MWGui virtual ~LoadingScreen(); /// Overridden from Loading::Listener, see the Loading::Listener documentation for usage details - virtual void setLabel (const std::string& label, bool important, bool center); - virtual void loadingOn(bool visible=true); - virtual void loadingOff(); - virtual void setProgressRange (size_t range); - virtual void setProgress (size_t value); - virtual void increaseProgress (size_t increase=1); + void setLabel (const std::string& label, bool important, bool center) override; + void loadingOn(bool visible=true) override; + void loadingOff() override; + void setProgressRange (size_t range) override; + void setProgress (size_t value) override; + void increaseProgress (size_t increase=1) override; - virtual void setVisible(bool visible); + void setVisible(bool visible) override; double getTargetFrameRate() const; diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 82553d22e..560eb93dc 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -32,13 +32,13 @@ namespace MWGui MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription); ~MainMenu(); - void onResChange(int w, int h); + void onResChange(int w, int h) override; - virtual void setVisible (bool visible); + void setVisible (bool visible) override; - void onFrame(float dt); + void onFrame(float dt) override; - bool exit(); + bool exit() override; private: const VFS::Manager* mVFS; diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 7b86f7617..7e8092f28 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -179,7 +179,7 @@ namespace MWGui public: EditNoteDialog(); - virtual void onOpen(); + void onOpen() override; void showDeleteButton(bool show); bool getDeleteButtonShown(); @@ -210,8 +210,8 @@ namespace MWGui void setCellName(const std::string& cellName); - virtual void setAlpha(float alpha); - void setVisible(bool visible); + void setAlpha(float alpha) override; + void setVisible(bool visible) override; void renderGlobalMap(); @@ -227,14 +227,14 @@ namespace MWGui void ensureGlobalMapLoaded(); - virtual void onOpen(); + void onOpen() override; - void onFrame(float dt); + void onFrame(float dt) override; - virtual void updateCustomMarkers(); + void updateCustomMarkers() override; /// Clear all savegame-specific data - void clear(); + void clear() override; void write (ESM::ESMWriter& writer, Loading::Listener& progress); void readRecord (ESM::ESMReader& reader, uint32_t type); @@ -280,13 +280,13 @@ namespace MWGui EditNoteDialog mEditNoteDialog; ESM::CustomMarker mEditingMarker; - virtual void onPinToggled(); - virtual void onTitleDoubleClicked(); + void onPinToggled() override; + void onTitleDoubleClicked() override; - virtual void doorMarkerCreated(MyGUI::Widget* marker); - virtual void customMarkerCreated(MyGUI::Widget *marker); + void doorMarkerCreated(MyGUI::Widget* marker) override; + void customMarkerCreated(MyGUI::Widget *marker) override; - virtual void notifyPlayerUpdate(); + void notifyPlayerUpdate() override; }; } diff --git a/apps/openmw/mwgui/merchantrepair.hpp b/apps/openmw/mwgui/merchantrepair.hpp index 26887ae2c..f5276d7f6 100644 --- a/apps/openmw/mwgui/merchantrepair.hpp +++ b/apps/openmw/mwgui/merchantrepair.hpp @@ -12,9 +12,9 @@ class MerchantRepair : public WindowBase public: MerchantRepair(); - virtual void onOpen(); + void onOpen() override; - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) override; private: MyGUI::ScrollView* mList; diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index e4e4b743c..aeb1b8300 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -83,7 +83,7 @@ namespace MWGui MyGUI::Widget* getDefaultKeyFocus() override; - virtual bool exit() override { return false; } + bool exit() override { return false; } bool mMarkedToDelete; diff --git a/apps/openmw/mwgui/pickpocketitemmodel.hpp b/apps/openmw/mwgui/pickpocketitemmodel.hpp index 83caf2ffd..e28af73d7 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.hpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.hpp @@ -12,14 +12,14 @@ namespace MWGui public: PickpocketItemModel (const MWWorld::Ptr& thief, ItemModel* sourceModel, bool hideItems=true); - virtual bool allowedToUseItems() const; - virtual ItemStack getItem (ModelIndex index); - virtual size_t getItemCount(); - virtual void update(); - virtual void removeItem (const ItemStack& item, size_t count); - virtual void onClose(); - virtual bool onDropItem(const MWWorld::Ptr &item, int count); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); + bool allowedToUseItems() const override; + ItemStack getItem (ModelIndex index) override; + size_t getItemCount() override; + void update() override; + void removeItem (const ItemStack& item, size_t count) override; + void onClose() override; + bool onDropItem(const MWWorld::Ptr &item, int count) override; + bool onTakeItem(const MWWorld::Ptr &item, int count) override; protected: MWWorld::Ptr mActor; diff --git a/apps/openmw/mwgui/quickkeysmenu.hpp b/apps/openmw/mwgui/quickkeysmenu.hpp index 431e847cb..d0e950979 100644 --- a/apps/openmw/mwgui/quickkeysmenu.hpp +++ b/apps/openmw/mwgui/quickkeysmenu.hpp @@ -22,7 +22,7 @@ namespace MWGui QuickKeysMenu(); ~QuickKeysMenu(); - void onResChange(int, int) { center(); } + void onResChange(int, int) override { center(); } void onItemButtonClicked(MyGUI::Widget* sender); void onMagicButtonClicked(MyGUI::Widget* sender); @@ -34,7 +34,7 @@ namespace MWGui void onAssignMagicItem (MWWorld::Ptr item); void onAssignMagic (const std::string& spellId); void onAssignMagicCancel (); - void onOpen(); + void onOpen() override; void activateQuickKey(int index); void updateActivatedQuickKey(); @@ -51,7 +51,7 @@ namespace MWGui void write (ESM::ESMWriter& writer); void readRecord (ESM::ESMReader& reader, uint32_t type); - void clear(); + void clear() override; private: @@ -102,8 +102,8 @@ namespace MWGui public: MagicSelectionDialog(QuickKeysMenu* parent); - virtual void onOpen(); - virtual bool exit(); + void onOpen() override; + bool exit() override; private: MyGUI::Button* mCancelButton; diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index 0fa4fdec5..0299c2a1a 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -53,10 +53,10 @@ namespace MWGui void setGender(Gender gender) { mGenderIndex = gender == GM_Male ? 0 : 1; } void setNextButtonShow(bool shown); - virtual void onOpen(); - virtual void onClose(); + void onOpen() override; + void onClose() override; - bool exit() { return false; } + bool exit() override { return false; } // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; diff --git a/apps/openmw/mwgui/recharge.hpp b/apps/openmw/mwgui/recharge.hpp index f4602ce30..3d469bac5 100644 --- a/apps/openmw/mwgui/recharge.hpp +++ b/apps/openmw/mwgui/recharge.hpp @@ -22,9 +22,9 @@ class Recharge : public WindowBase public: Recharge(); - virtual void onOpen(); + void onOpen() override; - void setPtr (const MWWorld::Ptr& gem); + void setPtr (const MWWorld::Ptr& gem) override; protected: ItemChargeView* mBox; diff --git a/apps/openmw/mwgui/repair.hpp b/apps/openmw/mwgui/repair.hpp index f31625095..594ad2823 100644 --- a/apps/openmw/mwgui/repair.hpp +++ b/apps/openmw/mwgui/repair.hpp @@ -19,9 +19,9 @@ class Repair : public WindowBase public: Repair(); - virtual void onOpen(); + void onOpen() override; - void setPtr (const MWWorld::Ptr& item); + void setPtr (const MWWorld::Ptr& item) override; protected: ItemChargeView* mRepairBox; diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index f46ad280d..bd17c7afb 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -31,7 +31,7 @@ namespace MWGui ReviewDialog(); - bool exit() { return false; } + bool exit() override { return false; } void setPlayerName(const std::string &name); void setRace(const std::string &raceId); @@ -47,9 +47,9 @@ namespace MWGui void configureSkills(const SkillList& major, const SkillList& minor); void setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::SkillValue& value); - virtual void onOpen(); + void onOpen() override; - void onFrame(float duration); + void onFrame(float duration) override; // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; diff --git a/apps/openmw/mwgui/savegamedialog.hpp b/apps/openmw/mwgui/savegamedialog.hpp index e2c41af70..c22d86fd1 100644 --- a/apps/openmw/mwgui/savegamedialog.hpp +++ b/apps/openmw/mwgui/savegamedialog.hpp @@ -19,8 +19,8 @@ namespace MWGui public: SaveGameDialog(); - virtual void onOpen(); - virtual void onClose(); + void onOpen() override; + void onClose() override; void setLoadOrSave(bool load); diff --git a/apps/openmw/mwgui/screenfader.hpp b/apps/openmw/mwgui/screenfader.hpp index aa17ed4e8..8eb8a6859 100644 --- a/apps/openmw/mwgui/screenfader.hpp +++ b/apps/openmw/mwgui/screenfader.hpp @@ -45,7 +45,7 @@ namespace MWGui void fadeOut(const float time, float delay=0); void fadeTo(const int percent, const float time, float delay=0); - void clear(); + void clear() override; void setFactor (float factor); void setRepeat(bool repeat); diff --git a/apps/openmw/mwgui/scrollwindow.hpp b/apps/openmw/mwgui/scrollwindow.hpp index 7f2a7a281..8a1e323ab 100644 --- a/apps/openmw/mwgui/scrollwindow.hpp +++ b/apps/openmw/mwgui/scrollwindow.hpp @@ -17,10 +17,10 @@ namespace MWGui public: ScrollWindow (); - void setPtr (const MWWorld::Ptr& scroll); + void setPtr (const MWWorld::Ptr& scroll) override; void setInventoryAllowed(bool allowed); - void onResChange(int, int) { center(); } + void onResChange(int, int) override { center(); } protected: void onCloseButtonClicked (MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 37d671a5a..6f25dd114 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -15,11 +15,11 @@ namespace MWGui public: SettingsWindow(); - virtual void onOpen(); + void onOpen() override; void updateControlsBox(); - void onResChange(int, int) { center(); } + void onResChange(int, int) override { center(); } protected: MyGUI::TabControl* mSettingsTab; diff --git a/apps/openmw/mwgui/sortfilteritemmodel.hpp b/apps/openmw/mwgui/sortfilteritemmodel.hpp index 3e616875e..fa70a0edd 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.hpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.hpp @@ -11,13 +11,13 @@ namespace MWGui public: SortFilterItemModel (ItemModel* sourceModel); - virtual void update(); + void update() override; bool filterAccepts (const ItemStack& item); - bool allowedToUseItems() const; - virtual ItemStack getItem (ModelIndex index); - virtual size_t getItemCount(); + bool allowedToUseItems() const override; + ItemStack getItem (ModelIndex index) override; + size_t getItemCount() override; /// Dragged items are not displayed. void addDragItem (const MWWorld::Ptr& dragItem, size_t count); @@ -31,9 +31,9 @@ namespace MWGui /// Use ItemStack::Type for sorting? void setSortByType(bool sort) { mSortByType = sort; } - void onClose(); - bool onDropItem(const MWWorld::Ptr &item, int count); - bool onTakeItem(const MWWorld::Ptr &item, int count); + void onClose() override; + bool onDropItem(const MWWorld::Ptr &item, int count) override; + bool onTakeItem(const MWWorld::Ptr &item, int count) override; static const int Category_Weapon = (1<<1); static const int Category_Apparel = (1<<2); diff --git a/apps/openmw/mwgui/spellbuyingwindow.hpp b/apps/openmw/mwgui/spellbuyingwindow.hpp index c68ec2483..622548c95 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.hpp +++ b/apps/openmw/mwgui/spellbuyingwindow.hpp @@ -27,13 +27,13 @@ namespace MWGui public: SpellBuyingWindow(); - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) override; void setPtr(const MWWorld::Ptr& actor, int startOffset); - void onFrame(float dt) { checkReferenceAvailable(); } - void clear() { resetReference(); } + void onFrame(float dt) override { checkReferenceAvailable(); } + void clear() override { resetReference(); } - void onResChange(int, int) { center(); } + void onResChange(int, int) override { center(); } protected: MyGUI::Button* mCancelButton; @@ -52,7 +52,7 @@ namespace MWGui void updateLabels(); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; bool playerHasSpell (const std::string& id); diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index ec90fa3ce..73352ac23 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -23,8 +23,8 @@ namespace MWGui public: EditEffectDialog(); - virtual void onOpen(); - virtual bool exit(); + void onOpen() override; + bool exit() override; void setConstantEffect(bool constant); @@ -150,21 +150,21 @@ namespace MWGui public: SpellCreationDialog(); - virtual void onOpen(); - void clear() { resetReference(); } + void onOpen() override; + void clear() override { resetReference(); } - void onFrame(float dt) { checkReferenceAvailable(); } + void onFrame(float dt) override { checkReferenceAvailable(); } - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) override; protected: - virtual void onReferenceUnavailable (); + void onReferenceUnavailable() override; void onCancelButtonClicked (MyGUI::Widget* sender); void onBuyButtonClicked (MyGUI::Widget* sender); void onAccept(MyGUI::EditBox* sender); - virtual void notifyEffectsChanged (); + void notifyEffectsChanged() override; MyGUI::EditBox* mNameEdit; MyGUI::TextBox* mMagickaCost; diff --git a/apps/openmw/mwgui/spellicons.hpp b/apps/openmw/mwgui/spellicons.hpp index 67351688f..b6aa49e69 100644 --- a/apps/openmw/mwgui/spellicons.hpp +++ b/apps/openmw/mwgui/spellicons.hpp @@ -46,9 +46,9 @@ namespace MWGui virtual ~EffectSourceVisitor() {} - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1); + float magnitude, float remainingTime = -1, float totalTime = -1) override; }; class SpellIcons diff --git a/apps/openmw/mwgui/spellwindow.hpp b/apps/openmw/mwgui/spellwindow.hpp index 01a9c7392..cf5e88f8e 100644 --- a/apps/openmw/mwgui/spellwindow.hpp +++ b/apps/openmw/mwgui/spellwindow.hpp @@ -19,7 +19,7 @@ namespace MWGui void updateSpells(); - void onFrame(float dt); + void onFrame(float dt) override; /// Cycle to next/previous spell void cycle(bool next); @@ -37,9 +37,9 @@ namespace MWGui void onDeleteSpellAccept(); void askDeleteSpell(const std::string& spellId); - virtual void onPinToggled(); - virtual void onTitleDoubleClicked(); - virtual void onOpen(); + void onPinToggled() override; + void onTitleDoubleClicked() override; + void onOpen() override; SpellView* mSpellView; SpellIcons* mSpellIcons; diff --git a/apps/openmw/mwgui/statswindow.hpp b/apps/openmw/mwgui/statswindow.hpp index 1b6c60793..24f302580 100644 --- a/apps/openmw/mwgui/statswindow.hpp +++ b/apps/openmw/mwgui/statswindow.hpp @@ -35,7 +35,7 @@ namespace MWGui void setBounty (int bounty) { if (bounty != mBounty) mChanged = true; this->mBounty = bounty; } void updateSkillArea(); - virtual void onOpen() override { onWindowResize(mMainWidget->castType()); } + void onOpen() override { onWindowResize(mMainWidget->castType()); } private: void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); @@ -70,8 +70,8 @@ namespace MWGui const int mMinFullWidth; protected: - virtual void onPinToggled() override; - virtual void onTitleDoubleClicked() override; + void onPinToggled() override; + void onTitleDoubleClicked() override; }; } #endif diff --git a/apps/openmw/mwgui/textinput.hpp b/apps/openmw/mwgui/textinput.hpp index 56c6632e1..84d9d032d 100644 --- a/apps/openmw/mwgui/textinput.hpp +++ b/apps/openmw/mwgui/textinput.hpp @@ -20,9 +20,9 @@ namespace MWGui void setNextButtonShow(bool shown); void setTextLabel(const std::string &label); - virtual void onOpen(); + void onOpen() override; - bool exit() { return false; } + bool exit() override { return false; } /** Event : Dialog finished, OK button clicked.\n signature : void method()\n diff --git a/apps/openmw/mwgui/tradeitemmodel.hpp b/apps/openmw/mwgui/tradeitemmodel.hpp index e349c225a..53b616aed 100644 --- a/apps/openmw/mwgui/tradeitemmodel.hpp +++ b/apps/openmw/mwgui/tradeitemmodel.hpp @@ -15,12 +15,12 @@ namespace MWGui public: TradeItemModel (ItemModel* sourceModel, const MWWorld::Ptr& merchant); - bool allowedToUseItems() const; + bool allowedToUseItems() const override; - virtual ItemStack getItem (ModelIndex index); - virtual size_t getItemCount(); + ItemStack getItem (ModelIndex index) override; + size_t getItemCount() override; - virtual void update(); + void update() override; void borrowItemFromUs (ModelIndex itemIndex, size_t count); diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index b211c6d09..f82d7b0f7 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -27,20 +27,20 @@ namespace MWGui public: TradeWindow(); - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) override; - virtual void onClose() override; - void onFrame(float dt); - void clear() { resetReference(); } + void onClose() override; + void onFrame(float dt) override; + void clear() override { resetReference(); } void borrowItem (int index, size_t count); void returnItem (int index, size_t count); int getMerchantServices(); - virtual bool exit(); + bool exit() override; - virtual void resetReference(); + void resetReference() override; typedef MyGUI::delegates::CMultiDelegate0 EventHandle_TradeDone; EventHandle_TradeDone eventTradeDone; @@ -109,7 +109,7 @@ namespace MWGui void updateLabels(); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; int getMerchantGold(); }; diff --git a/apps/openmw/mwgui/trainingwindow.hpp b/apps/openmw/mwgui/trainingwindow.hpp index 955615516..57fdd323a 100644 --- a/apps/openmw/mwgui/trainingwindow.hpp +++ b/apps/openmw/mwgui/trainingwindow.hpp @@ -19,20 +19,20 @@ namespace MWGui public: TrainingWindow(); - virtual void onOpen(); + void onOpen() override; - bool exit(); + bool exit() override; - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) override; - void onFrame(float dt); + void onFrame(float dt) override; WindowBase* getProgressBar() { return &mProgressBar; } - void clear() { resetReference(); } + void clear() override { resetReference(); } protected: - virtual void onReferenceUnavailable (); + void onReferenceUnavailable() override; void onCancelButtonClicked (MyGUI::Widget* sender); void onTrainingSelected(MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index dcf0b7727..962d17161 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -24,7 +24,7 @@ namespace MWGui public: TravelWindow(); - void setPtr (const MWWorld::Ptr& actor); + void setPtr (const MWWorld::Ptr& actor) override; protected: MyGUI::Button* mCancelButton; @@ -43,7 +43,7 @@ namespace MWGui void updateLabels(); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; }; } diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 2aecb002f..bf84e7e81 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -13,7 +13,7 @@ namespace MWGui public: WaitDialogProgressBar(); - virtual void onOpen(); + void onOpen() override; void setProgress(int cur, int total); @@ -27,15 +27,15 @@ namespace MWGui public: WaitDialog(); - void setPtr(const MWWorld::Ptr &ptr); + void setPtr(const MWWorld::Ptr &ptr) override; - virtual void onOpen(); + void onOpen() override; - virtual bool exit(); + bool exit() override; - virtual void clear(); + void clear() override; - void onFrame(float dt); + void onFrame(float dt) override; bool getSleeping() { return mTimeAdvancer.isRunning() && mSleeping; } void wakeUp(); diff --git a/apps/openmw/mwgui/windowbase.hpp b/apps/openmw/mwgui/windowbase.hpp index a729a7920..8afb2321e 100644 --- a/apps/openmw/mwgui/windowbase.hpp +++ b/apps/openmw/mwgui/windowbase.hpp @@ -41,7 +41,7 @@ namespace MWGui /// Gracefully exits the window virtual bool exit() {return true;} /// Sets the visibility of the window - virtual void setVisible(bool visible); + void setVisible(bool visible) override; /// Returns the visibility state of the window bool isVisible(); @@ -67,9 +67,9 @@ namespace MWGui { public: WindowModal(const std::string& parLayout); - virtual void onOpen() override; - virtual void onClose() override; - virtual bool exit() override {return true;} + void onOpen() override; + void onClose() override; + bool exit() override {return true;} }; /// A window that cannot be the target of a drag&drop action. diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 67a16f516..cc1a1b694 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -141,136 +141,136 @@ namespace MWGui void setStore (const MWWorld::ESMStore& store); void initUI(); - virtual void loadUserFonts(); + void loadUserFonts() override; - virtual Loading::Listener* getLoadingScreen(); + Loading::Listener* getLoadingScreen() override; /// @note This method will block until the video finishes playing /// (and will continually update the window while doing so) - virtual void playVideo(const std::string& name, bool allowSkipping); + void playVideo(const std::string& name, bool allowSkipping) override; /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. - virtual void setKeyFocusWidget (MyGUI::Widget* widget); + void setKeyFocusWidget (MyGUI::Widget* widget) override; - virtual void setNewGame(bool newgame); + void setNewGame(bool newgame) override; - virtual void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg); - virtual void pushGuiMode (GuiMode mode); - virtual void popGuiMode(bool noSound=false); - virtual void removeGuiMode(GuiMode mode, bool noSound=false); ///< can be anywhere in the stack + void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg) override; + void pushGuiMode (GuiMode mode) override; + void popGuiMode(bool noSound=false) override; + void removeGuiMode(GuiMode mode, bool noSound=false) override; ///< can be anywhere in the stack - virtual void goToJail(int days); + void goToJail(int days) override; - virtual GuiMode getMode() const; - virtual bool containsMode(GuiMode mode) const; + GuiMode getMode() const override; + bool containsMode(GuiMode mode) const override; - virtual bool isGuiMode() const; + bool isGuiMode() const override; - virtual bool isConsoleMode() const; + bool isConsoleMode() const override; - virtual void toggleVisible(GuiWindow wnd); + void toggleVisible(GuiWindow wnd) override; - virtual void forceHide(MWGui::GuiWindow wnd); - virtual void unsetForceHide(MWGui::GuiWindow wnd); + void forceHide(MWGui::GuiWindow wnd) override; + void unsetForceHide(MWGui::GuiWindow wnd) override; /// Disallow all inventory mode windows - virtual void disallowAll(); + void disallowAll() override; /// Allow one or more windows - virtual void allow(GuiWindow wnd); + void allow(GuiWindow wnd) override; - virtual bool isAllowed(GuiWindow wnd) const; + bool isAllowed(GuiWindow wnd) const override; /// \todo investigate, if we really need to expose every single lousy UI element to the outside world - virtual MWGui::InventoryWindow* getInventoryWindow(); - virtual MWGui::CountDialog* getCountDialog(); - virtual MWGui::ConfirmationDialog* getConfirmationDialog(); - virtual MWGui::TradeWindow* getTradeWindow(); + MWGui::InventoryWindow* getInventoryWindow() override; + MWGui::CountDialog* getCountDialog() override; + MWGui::ConfirmationDialog* getConfirmationDialog() override; + MWGui::TradeWindow* getTradeWindow() override; /// Make the player use an item, while updating GUI state accordingly - virtual void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions=false); + void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions=false) override; - virtual void updateSpellWindow(); + void updateSpellWindow() override; - virtual void setConsoleSelectedObject(const MWWorld::Ptr& object); + void setConsoleSelectedObject(const MWWorld::Ptr& object) override; /// Set time left for the player to start drowning (update the drowning bar) /// @param time time left to start drowning /// @param maxTime how long we can be underwater (in total) until drowning starts - virtual void setDrowningTimeLeft (float time, float maxTime); + void setDrowningTimeLeft (float time, float maxTime) override; - virtual void changeCell(const MWWorld::CellStore* cell); ///< change the active cell + void changeCell(const MWWorld::CellStore* cell) override; ///< change the active cell - virtual void setFocusObject(const MWWorld::Ptr& focus); - virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); + void setFocusObject(const MWWorld::Ptr& focus) override; + void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) override; - virtual void getMousePosition(int &x, int &y); - virtual void getMousePosition(float &x, float &y); - virtual void setDragDrop(bool dragDrop); - virtual bool getWorldMouseOver(); + void getMousePosition(int &x, int &y) override; + void getMousePosition(float &x, float &y) override; + void setDragDrop(bool dragDrop) override; + bool getWorldMouseOver() override; - virtual bool toggleFogOfWar(); - virtual bool toggleFullHelp(); ///< show extra info in item tooltips (owner, script) - virtual bool getFullHelp() const; + bool toggleFogOfWar() override; + bool toggleFullHelp() override; ///< show extra info in item tooltips (owner, script) + bool getFullHelp() const override; - virtual void setActiveMap(int x, int y, bool interior); + void setActiveMap(int x, int y, bool interior) override; ///< set the indices of the map texture that should be used /// sets the visibility of the drowning bar - virtual void setDrowningBarVisibility(bool visible); + void setDrowningBarVisibility(bool visible) override; // sets the visibility of the hud health/magicka/stamina bars - virtual void setHMSVisibility(bool visible); + void setHMSVisibility(bool visible) override; // sets the visibility of the hud minimap - virtual void setMinimapVisibility(bool visible); - virtual void setWeaponVisibility(bool visible); - virtual void setSpellVisibility(bool visible); - virtual void setSneakVisibility(bool visible); + void setMinimapVisibility(bool visible) override; + void setWeaponVisibility(bool visible) override; + void setSpellVisibility(bool visible) override; + void setSneakVisibility(bool visible) override; /// activate selected quick key - virtual void activateQuickKey (int index); + void activateQuickKey (int index) override; /// update activated quick key state (if action executing was delayed for some reason) - virtual void updateActivatedQuickKey (); + void updateActivatedQuickKey () override; - virtual std::string getSelectedSpell() { return mSelectedSpell; } - virtual void setSelectedSpell(const std::string& spellId, int successChancePercent); - virtual void setSelectedEnchantItem(const MWWorld::Ptr& item); - virtual const MWWorld::Ptr& getSelectedEnchantItem() const; - virtual void setSelectedWeapon(const MWWorld::Ptr& item); - virtual const MWWorld::Ptr& getSelectedWeapon() const; - virtual int getFontHeight() const; - virtual void unsetSelectedSpell(); - virtual void unsetSelectedWeapon(); + std::string getSelectedSpell() override { return mSelectedSpell; } + void setSelectedSpell(const std::string& spellId, int successChancePercent) override; + void setSelectedEnchantItem(const MWWorld::Ptr& item) override; + const MWWorld::Ptr& getSelectedEnchantItem() const override; + void setSelectedWeapon(const MWWorld::Ptr& item) override; + const MWWorld::Ptr& getSelectedWeapon() const override; + int getFontHeight() const override; + void unsetSelectedSpell() override; + void unsetSelectedWeapon() override; - virtual void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr); + void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) override; - virtual void showCrosshair(bool show); - virtual bool getSubtitlesEnabled(); + void showCrosshair(bool show) override; + bool getSubtitlesEnabled() override; /// Turn visibility of HUD on or off - virtual bool toggleHud(); + bool toggleHud() override; - virtual void disallowMouse(); - virtual void allowMouse(); - virtual void notifyInputActionBound(); + void disallowMouse() override; + void allowMouse() override; + void notifyInputActionBound() override; - virtual void addVisitedLocation(const std::string& name, int x, int y); + void addVisitedLocation(const std::string& name, int x, int y) override; ///Hides dialog and schedules dialog to be deleted. - virtual void removeDialog(Layout* dialog); + void removeDialog(Layout* dialog) override; ///Gracefully attempts to exit the topmost GUI mode - virtual void exitCurrentGuiMode(); + void exitCurrentGuiMode() override; - virtual void messageBox (const std::string& message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible); - virtual void staticMessageBox(const std::string& message); - virtual void removeStaticMessageBox(); - virtual void interactiveMessageBox (const std::string& message, - const std::vector& buttons = std::vector(), bool block=false); + void messageBox (const std::string& message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) override; + void staticMessageBox(const std::string& message) override; + void removeStaticMessageBox() override; + void interactiveMessageBox (const std::string& message, + const std::vector& buttons = std::vector(), bool block=false) override; - virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) + int readPressedButton () override; ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) - virtual void update (float duration); + void update (float duration) override; /** * Fetches a GMST string from the store, if there is no setting with the given @@ -279,108 +279,108 @@ namespace MWGui * @param id Identifier for the GMST setting, e.g. "aName" * @param default Default value if the GMST setting cannot be used. */ - virtual std::string getGameSettingString(const std::string &id, const std::string &default_); + std::string getGameSettingString(const std::string &id, const std::string &default_) override; - virtual void processChangedSettings(const Settings::CategorySettingVector& changed); + void processChangedSettings(const Settings::CategorySettingVector& changed) override; - virtual void windowVisibilityChange(bool visible); - virtual void windowResized(int x, int y); - virtual void windowClosed(); - virtual bool isWindowVisible(); + void windowVisibilityChange(bool visible) override; + void windowResized(int x, int y) override; + void windowClosed() override; + bool isWindowVisible() override; - virtual void watchActor(const MWWorld::Ptr& ptr); - virtual MWWorld::Ptr getWatchedActor() const; + void watchActor(const MWWorld::Ptr& ptr) override; + MWWorld::Ptr getWatchedActor() const override; - virtual void executeInConsole (const std::string& path); + void executeInConsole (const std::string& path) override; - virtual void enableRest() { mRestAllowed = true; } - virtual bool getRestEnabled(); + void enableRest() override { mRestAllowed = true; } + bool getRestEnabled() override; - virtual bool getJournalAllowed() { return (mAllowed & GW_Magic) != 0; } + bool getJournalAllowed() override { return (mAllowed & GW_Magic) != 0; } - virtual bool getPlayerSleeping(); - virtual void wakeUpPlayer(); + bool getPlayerSleeping() override; + void wakeUpPlayer() override; - virtual void updatePlayer(); + void updatePlayer() override; - virtual void showSoulgemDialog (MWWorld::Ptr item); + void showSoulgemDialog (MWWorld::Ptr item) override; - virtual void changePointer (const std::string& name); + void changePointer (const std::string& name) override; - virtual void setEnemy (const MWWorld::Ptr& enemy); + void setEnemy (const MWWorld::Ptr& enemy) override; - virtual int getMessagesCount() const; + int getMessagesCount() const override; - virtual const Translation::Storage& getTranslationDataStorage() const; + const Translation::Storage& getTranslationDataStorage() const override; void onSoulgemDialogButtonPressed (int button); - virtual bool getCursorVisible(); + bool getCursorVisible() override; /// Call when mouse cursor or buttons are used. - virtual void setCursorActive(bool active); + void setCursorActive(bool active) override; /// Clear all savegame-specific data - virtual void clear(); + void clear() override; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress); - virtual void readRecord (ESM::ESMReader& reader, uint32_t type); - virtual int countSavedGameRecords() const; + void write (ESM::ESMWriter& writer, Loading::Listener& progress) override; + void readRecord (ESM::ESMReader& reader, uint32_t type) override; + int countSavedGameRecords() const override; /// Does the current stack of GUI-windows permit saving? - virtual bool isSavingAllowed() const; + bool isSavingAllowed() const override; /// Send exit command to active Modal window **/ - virtual void exitCurrentModal(); + void exitCurrentModal() override; /// Sets the current Modal /** Used to send exit command to active Modal when Esc is pressed **/ - virtual void addCurrentModal(WindowModal* input); + void addCurrentModal(WindowModal* input) override; /// Removes the top Modal /** Used when one Modal adds another Modal \param input Pointer to the current modal, to ensure proper modal is removed **/ - virtual void removeCurrentModal(WindowModal* input); + void removeCurrentModal(WindowModal* input) override; - virtual void pinWindow (MWGui::GuiWindow window); - virtual void toggleMaximized(Layout *layout); + void pinWindow (MWGui::GuiWindow window) override; + void toggleMaximized(Layout *layout) override; /// Fade the screen in, over \a time seconds - virtual void fadeScreenIn(const float time, bool clearQueue, float delay); + void fadeScreenIn(const float time, bool clearQueue, float delay) override; /// Fade the screen out to black, over \a time seconds - virtual void fadeScreenOut(const float time, bool clearQueue, float delay); + void fadeScreenOut(const float time, bool clearQueue, float delay) override; /// Fade the screen to a specified percentage of black, over \a time seconds - virtual void fadeScreenTo(const int percent, const float time, bool clearQueue, float delay); + void fadeScreenTo(const int percent, const float time, bool clearQueue, float delay) override; /// Darken the screen to a specified percentage - virtual void setBlindness(const int percent); + void setBlindness(const int percent) override; - virtual void activateHitOverlay(bool interrupt); - virtual void setWerewolfOverlay(bool set); + void activateHitOverlay(bool interrupt) override; + void setWerewolfOverlay(bool set) override; - virtual void toggleConsole(); - virtual void toggleDebugWindow(); + void toggleConsole() override; + void toggleDebugWindow() override; /// Cycle to next or previous spell - virtual void cycleSpell(bool next); + void cycleSpell(bool next) override; /// Cycle to next or previous weapon - virtual void cycleWeapon(bool next); + void cycleWeapon(bool next) override; - virtual void playSound(const std::string& soundId, float volume = 1.f, float pitch = 1.f); + void playSound(const std::string& soundId, float volume = 1.f, float pitch = 1.f) override; // In WindowManager for now since there isn't a VFS singleton - virtual std::string correctIconPath(const std::string& path); - virtual std::string correctBookartPath(const std::string& path, int width, int height, bool* exists = nullptr); - virtual std::string correctTexturePath(const std::string& path); - virtual bool textureExists(const std::string& path); + std::string correctIconPath(const std::string& path) override; + std::string correctBookartPath(const std::string& path, int width, int height, bool* exists = nullptr) override; + std::string correctTexturePath(const std::string& path) override; + bool textureExists(const std::string& path) override; - void addCell(MWWorld::CellStore* cell); - void removeCell(MWWorld::CellStore* cell); - void writeFog(MWWorld::CellStore* cell); + void addCell(MWWorld::CellStore* cell) override; + void removeCell(MWWorld::CellStore* cell) override; + void writeFog(MWWorld::CellStore* cell) override; - virtual const MWGui::TextColours& getTextColours(); + const MWGui::TextColours& getTextColours() override; - virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat=false); - virtual bool injectKeyRelease(MyGUI::KeyCode key); + bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat=false) override; + bool injectKeyRelease(MyGUI::KeyCode key) override; private: unsigned int mOldUpdateMask; unsigned int mOldCullMask; @@ -458,7 +458,7 @@ namespace MWGui int mPlayerBounty; - void setCursorVisible(bool visible); + void setCursorVisible(bool visible) override; MyGUI::Gui *mGui; // Gui diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp index 9d77ec99c..18fac6ae2 100644 --- a/apps/openmw/mwinput/bindingsmanager.cpp +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -62,14 +62,14 @@ namespace MWInput virtual ~BindingsListener() = default; - virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue) + void channelChanged(ICS::Channel* channel, float currentValue, float previousValue) override { int action = channel->getNumber(); mBindingsManager->actionValueChanged(action, currentValue, previousValue); } - virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) + void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) override { //Disallow binding escape key if (key==SDL_SCANCODE_ESCAPE) @@ -99,15 +99,15 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) + void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) override { // we don't want mouse movement bindings return; } - virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) + void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , unsigned int button, ICS::Control::ControlChangingDirection direction) override { if (!mDetectingKeyboard) return; @@ -117,8 +117,8 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) + void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) override { if (!mDetectingKeyboard) return; @@ -128,8 +128,8 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , int axis, ICS::Control::ControlChangingDirection direction) + void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control + , int axis, ICS::Control::ControlChangingDirection direction) override { //only allow binding to the trigers if (axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) @@ -144,8 +144,8 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) + void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control + , unsigned int button, ICS::Control::ControlChangingDirection direction) override { if (mDetectingKeyboard) return; diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 3c1a2ee6e..871f11102 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -25,11 +25,11 @@ namespace MWInput bool update(float dt); - virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); - virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); - virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); - virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); - virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg); + void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) override; + void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) override; + void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) override; + void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) override; + void controllerRemoved(const SDL_ControllerDeviceEvent &arg) override; void processChangedSettings(const Settings::CategorySettingVector& changed); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index debbf27e0..f930836d1 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -58,43 +58,43 @@ namespace MWInput virtual ~InputManager(); /// Clear all savegame-specific data - virtual void clear(); + void clear() override; - virtual void update(float dt, bool disableControls=false, bool disableEvents=false); + void update(float dt, bool disableControls=false, bool disableEvents=false) override; - virtual void changeInputMode(bool guiMode); + void changeInputMode(bool guiMode) override; - virtual void processChangedSettings(const Settings::CategorySettingVector& changed); + void processChangedSettings(const Settings::CategorySettingVector& changed) override; - virtual void setDragDrop(bool dragDrop); - virtual void setGamepadGuiCursorEnabled(bool enabled); - virtual void setAttemptJump(bool jumping); + void setDragDrop(bool dragDrop) override; + void setGamepadGuiCursorEnabled(bool enabled) override; + void setAttemptJump(bool jumping) override; - virtual void toggleControlSwitch (const std::string& sw, bool value); - virtual bool getControlSwitch (const std::string& sw); + void toggleControlSwitch (const std::string& sw, bool value) override; + bool getControlSwitch (const std::string& sw) override; - virtual std::string getActionDescription (int action); - virtual std::string getActionKeyBindingName (int action); - virtual std::string getActionControllerBindingName (int action); - virtual int getNumActions() { return A_Last; } - virtual std::vector getActionKeySorting(); - virtual std::vector getActionControllerSorting(); - virtual void enableDetectingBindingMode (int action, bool keyboard); - virtual void resetToDefaultKeyBindings(); - virtual void resetToDefaultControllerBindings(); + std::string getActionDescription (int action) override; + std::string getActionKeyBindingName (int action) override; + std::string getActionControllerBindingName (int action) override; + int getNumActions() override { return A_Last; } + std::vector getActionKeySorting() override; + std::vector getActionControllerSorting() override; + void enableDetectingBindingMode (int action, bool keyboard) override; + void resetToDefaultKeyBindings() override; + void resetToDefaultControllerBindings() override; - virtual void setJoystickLastUsed(bool enabled); - virtual bool joystickLastUsed(); + void setJoystickLastUsed(bool enabled) override; + bool joystickLastUsed() override; - virtual int countSavedGameRecords() const; - virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress); - virtual void readRecord(ESM::ESMReader& reader, uint32_t type); + int countSavedGameRecords() const override; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) override; + void readRecord(ESM::ESMReader& reader, uint32_t type) override; - virtual void resetIdleTime(); + void resetIdleTime() override; - virtual void executeAction(int action); + void executeAction(int action) override; - virtual bool controlsDisabled() { return mControlsDisabled; } + bool controlsDisabled() override { return mControlsDisabled; } private: void convertMousePosForMyGUI(int& x, int& y); diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index b7027220f..f97f6b9e6 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -15,9 +15,9 @@ namespace MWInput virtual ~KeyboardManager() = default; - virtual void textInput(const SDL_TextInputEvent &arg); - virtual void keyPressed(const SDL_KeyboardEvent &arg); - virtual void keyReleased(const SDL_KeyboardEvent &arg); + void textInput(const SDL_TextInputEvent &arg) override; + void keyPressed(const SDL_KeyboardEvent &arg) override; + void keyReleased(const SDL_KeyboardEvent &arg) override; private: BindingsManager* mBindingsManager; diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index f3d16cd80..3bf692bcf 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -23,10 +23,10 @@ namespace MWInput void updateCursorMode(); void update(float dt); - virtual void mouseMoved(const SDLUtil::MouseMotionEvent &arg); - virtual void mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id); - virtual void mouseReleased(const SDL_MouseButtonEvent &arg, Uint8 id); - virtual void mouseWheelMoved(const SDL_MouseWheelEvent &arg); + void mouseMoved(const SDLUtil::MouseMotionEvent &arg) override; + void mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id) override; + void mouseReleased(const SDL_MouseButtonEvent &arg, Uint8 id) override; + void mouseWheelMoved(const SDL_MouseWheelEvent &arg) override; void processChangedSettings(const Settings::CategorySettingVector& changed); diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index 8f333ad31..75472d43b 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -29,8 +29,8 @@ namespace MWInput void update(float dt); - virtual void sensorUpdated(const SDL_SensorEvent &arg); - virtual void displayOrientationChanged(); + void sensorUpdated(const SDL_SensorEvent &arg) override; + void displayOrientationChanged() override; void processChangedSettings(const Settings::CategorySettingVector& changed); void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ec6599093..d936a0b00 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -95,9 +95,9 @@ public: : mActor(actor) , mCommanded(false){} - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1) + float magnitude, float remainingTime = -1, float totalTime = -1) override { if (((key.mId == ESM::MagicEffect::CommandHumanoid && mActor.getClass().isNpc()) || (key.mId == ESM::MagicEffect::CommandCreature && mActor.getTypeName() == typeid(ESM::Creature).name())) @@ -159,9 +159,9 @@ namespace MWMechanics GetStuntedMagickaDuration(const MWWorld::Ptr& actor) : mRemainingTime(0.f){} - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1) + float magnitude, float remainingTime = -1, float totalTime = -1) override { if (mRemainingTime == -1) return; @@ -189,9 +189,9 @@ namespace MWMechanics { } - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1) + float magnitude, float remainingTime = -1, float totalTime = -1) override { if (magnitude <= 0) return; @@ -209,9 +209,9 @@ namespace MWMechanics { public: - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1) + float magnitude, float remainingTime = -1, float totalTime = -1) override { if (key.mId != ESM::MagicEffect::Corprus) return; @@ -234,9 +234,9 @@ namespace MWMechanics { } - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1) + float magnitude, float remainingTime = -1, float totalTime = -1) override { if (mTrapped) return; @@ -901,9 +901,9 @@ namespace MWMechanics { } - virtual void visit (MWMechanics::EffectKey key, int /*effectIndex*/, + void visit (MWMechanics::EffectKey key, int /*effectIndex*/, const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, - float magnitude, float remainingTime = -1, float /*totalTime*/ = -1) + float magnitude, float remainingTime = -1, float /*totalTime*/ = -1) override { if (magnitude > 0 && remainingTime > 0 && remainingTime < mDuration) { diff --git a/apps/openmw/mwmechanics/aicombataction.hpp b/apps/openmw/mwmechanics/aicombataction.hpp index cf7dc78fd..77a19f804 100644 --- a/apps/openmw/mwmechanics/aicombataction.hpp +++ b/apps/openmw/mwmechanics/aicombataction.hpp @@ -17,7 +17,7 @@ namespace MWMechanics virtual void prepare(const MWWorld::Ptr& actor) = 0; virtual float getCombatRange (bool& isRanged) const = 0; virtual float getActionCooldown() { return 0.f; } - virtual const ESM::Weapon* getWeapon() const { return nullptr; }; + virtual const ESM::Weapon* getWeapon() const { return nullptr; } virtual bool isAttackingOrSpell() const { return true; } virtual bool isFleeing() const { return false; } }; @@ -26,11 +26,11 @@ namespace MWMechanics { public: ActionFlee() {} - virtual void prepare(const MWWorld::Ptr& actor) {} - virtual float getCombatRange (bool& isRanged) const { return 0.0f; } - virtual float getActionCooldown() { return 3.0f; } - virtual bool isAttackingOrSpell() const { return false; } - virtual bool isFleeing() const { return true; } + void prepare(const MWWorld::Ptr& actor) override {} + float getCombatRange (bool& isRanged) const override { return 0.0f; } + float getActionCooldown() override { return 3.0f; } + bool isAttackingOrSpell() const override { return false; } + bool isFleeing() const override { return true; } }; class ActionSpell : public Action @@ -39,9 +39,9 @@ namespace MWMechanics ActionSpell(const std::string& spellId) : mSpellId(spellId) {} std::string mSpellId; /// Sets the given spell as selected on the actor's spell list. - virtual void prepare(const MWWorld::Ptr& actor); + void prepare(const MWWorld::Ptr& actor) override; - virtual float getCombatRange (bool& isRanged) const; + float getCombatRange (bool& isRanged) const override; }; class ActionEnchantedItem : public Action @@ -50,11 +50,11 @@ namespace MWMechanics ActionEnchantedItem(const MWWorld::ContainerStoreIterator& item) : mItem(item) {} MWWorld::ContainerStoreIterator mItem; /// Sets the given item as selected enchanted item in the actor's InventoryStore. - virtual void prepare(const MWWorld::Ptr& actor); - virtual float getCombatRange (bool& isRanged) const; + void prepare(const MWWorld::Ptr& actor) override; + float getCombatRange (bool& isRanged) const override; /// Since this action has no animation, apply a small cool down for using it - virtual float getActionCooldown() { return 0.75f; } + float getActionCooldown() override { return 0.75f; } }; class ActionPotion : public Action @@ -63,12 +63,12 @@ namespace MWMechanics ActionPotion(const MWWorld::Ptr& potion) : mPotion(potion) {} MWWorld::Ptr mPotion; /// Drinks the given potion. - virtual void prepare(const MWWorld::Ptr& actor); - virtual float getCombatRange (bool& isRanged) const; - virtual bool isAttackingOrSpell() const { return false; } + void prepare(const MWWorld::Ptr& actor) override; + float getCombatRange (bool& isRanged) const override; + bool isAttackingOrSpell() const override { return false; } /// Since this action has no animation, apply a small cool down for using it - virtual float getActionCooldown() { return 0.75f; } + float getActionCooldown() override { return 0.75f; } }; class ActionWeapon : public Action @@ -82,9 +82,9 @@ namespace MWMechanics ActionWeapon(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo = MWWorld::Ptr()) : mAmmunition(ammo), mWeapon(weapon) {} /// Equips the given weapon. - virtual void prepare(const MWWorld::Ptr& actor); - virtual float getCombatRange (bool& isRanged) const; - virtual const ESM::Weapon* getWeapon() const; + void prepare(const MWWorld::Ptr& actor) override; + float getCombatRange (bool& isRanged) const override; + const ESM::Weapon* getWeapon() const override; }; std::shared_ptr prepareNextAction (const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 0336c4e69..949affcfd 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -241,7 +241,7 @@ public: CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim); virtual ~CharacterController(); - virtual void handleTextKey(const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key, const NifOsg::TextKeyMap& map); + void handleTextKey(const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key, const NifOsg::TextKeyMap& map) override; // Be careful when to call this, see comment in Actors void updateContinuousVfx(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index c546497bb..28f62b777 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -42,65 +42,65 @@ namespace MWMechanics MechanicsManager(); - virtual void add (const MWWorld::Ptr& ptr) override; + void add (const MWWorld::Ptr& ptr) override; ///< Register an object for management - virtual void remove (const MWWorld::Ptr& ptr) override; + void remove (const MWWorld::Ptr& ptr) override; ///< Deregister an object for management - virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) override; + void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) override; ///< Moves an object to a new cell - virtual void drop(const MWWorld::CellStore *cellStore) override; + void drop(const MWWorld::CellStore *cellStore) override; ///< Deregister all objects in the given cell. - virtual void update (float duration, bool paused) override; + void update (float duration, bool paused) override; ///< Update objects /// /// \param paused In game type does not currently advance (this usually means some GUI /// component is up). - virtual void setPlayerName (const std::string& name) override; + void setPlayerName (const std::string& name) override; ///< Set player name. - virtual void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) override; + void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) override; ///< Set player race. - virtual void setPlayerBirthsign (const std::string& id) override; + void setPlayerBirthsign (const std::string& id) override; ///< Set player birthsign. - virtual void setPlayerClass (const std::string& id) override; + void setPlayerClass (const std::string& id) override; ///< Set player class to stock class. - virtual void setPlayerClass (const ESM::Class& class_) override; + void setPlayerClass (const ESM::Class& class_) override; ///< Set player class to custom class. - virtual void restoreDynamicStats(MWWorld::Ptr actor, double hours, bool sleep) override; + void restoreDynamicStats(MWWorld::Ptr actor, double hours, bool sleep) override; - virtual void rest(double hours, bool sleep) override; + void rest(double hours, bool sleep) override; ///< If the player is sleeping or waiting, this should be called every hour. /// @param sleep is the player sleeping or waiting? - virtual int getHoursToRest() const override; + int getHoursToRest() const override; ///< Calculate how many hours the player needs to rest in order to be fully healed - virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) override; + int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) override; ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. - virtual int getDerivedDisposition(const MWWorld::Ptr& ptr, bool addTemporaryDispositionChange = true) override; + int getDerivedDisposition(const MWWorld::Ptr& ptr, bool addTemporaryDispositionChange = true) override; ///< Calculate the diposition of an NPC toward the player. - virtual int countDeaths (const std::string& id) const override; + int countDeaths (const std::string& id) const override; ///< Return the number of deaths for actors with the given ID. - virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, float& tempChange, float& permChange) override; + void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, float& tempChange, float& permChange) override; ///< Perform a persuasion action on NPC /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! - virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) override; + bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) override; /// Makes \a ptr fight \a target. Also shouts a combat taunt. - virtual void startCombat (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; + void startCombat (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; /** * @note victim may be empty @@ -109,127 +109,127 @@ namespace MWMechanics * If this parameter is false, it will be determined by a line-of-sight and awareness check. * @return was the crime seen? */ - virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, const std::string& factionId="", int arg=0, bool victimAware=false) override; /// @return false if the attack was considered a "friendly hit" and forgiven - virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; + bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; /// Notify that actor was killed, add a murder bounty if applicable /// @note No-op for non-player attackers - virtual void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; + void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; /// Utility to check if taking this item is illegal and calling commitCrime if so /// @param container The container the item is in; may be empty for an item in the world - virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, + void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, int count, bool alarm = true) override; /// Utility to check if unlocking this object is illegal and calling commitCrime if so - virtual void unlockAttempted (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) override; + void unlockAttempted (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) override; /// Attempt sleeping in a bed. If this is illegal, call commitCrime. /// @return was it illegal, and someone saw you doing it? Also returns fail when enemies are nearby - virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) override; + bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) override; - virtual void forceStateUpdate(const MWWorld::Ptr &ptr) override; + void forceStateUpdate(const MWWorld::Ptr &ptr) override; /// Attempt to play an animation group /// @return Success or error - virtual bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false) override; - virtual void skipAnimation(const MWWorld::Ptr& ptr) override; - virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName) override; - virtual void persistAnimationStates() override; + bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false) override; + void skipAnimation(const MWWorld::Ptr& ptr) override; + bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName) override; + void persistAnimationStates() override; /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently /// paused we may want to do it manually (after equipping permanent enchantment) - virtual void updateMagicEffects (const MWWorld::Ptr& ptr) override; + void updateMagicEffects (const MWWorld::Ptr& ptr) override; - virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& objects) override; - virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) override; + void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& objects) override; + void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) override; /// Check if there are actors in selected range - virtual bool isAnyActorInRange(const osg::Vec3f &position, float radius) override; + bool isAnyActorInRange(const osg::Vec3f &position, float radius) override; - virtual std::list getActorsSidingWith(const MWWorld::Ptr& actor) override; - virtual std::list getActorsFollowing(const MWWorld::Ptr& actor) override; - virtual std::list getActorsFollowingIndices(const MWWorld::Ptr& actor) override; + std::list getActorsSidingWith(const MWWorld::Ptr& actor) override; + std::list getActorsFollowing(const MWWorld::Ptr& actor) override; + std::list getActorsFollowingIndices(const MWWorld::Ptr& actor) override; - virtual std::list getActorsFighting(const MWWorld::Ptr& actor) override; - virtual std::list getEnemiesNearby(const MWWorld::Ptr& actor) override; + std::list getActorsFighting(const MWWorld::Ptr& actor) override; + std::list getEnemiesNearby(const MWWorld::Ptr& actor) override; /// Recursive version of getActorsFollowing - virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) override; + void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) override; /// Recursive version of getActorsSidingWith - virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) override; + void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) override; - virtual bool toggleAI() override; - virtual bool isAIActive() override; + bool toggleAI() override; + bool isAIActive() override; - virtual void playerLoaded() override; + void playerLoaded() override; - virtual bool onOpen(const MWWorld::Ptr& ptr) override; - virtual void onClose(const MWWorld::Ptr& ptr) override; + bool onOpen(const MWWorld::Ptr& ptr) override; + void onClose(const MWWorld::Ptr& ptr) override; - virtual int countSavedGameRecords() const override; + int countSavedGameRecords() const override; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const override; + void write (ESM::ESMWriter& writer, Loading::Listener& listener) const override; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type) override; + void readRecord (ESM::ESMReader& reader, uint32_t type) override; - virtual void clear() override; + void clear() override; - virtual bool isAggressive (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; + bool isAggressive (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; - virtual void resurrect(const MWWorld::Ptr& ptr) override; + void resurrect(const MWWorld::Ptr& ptr) override; - virtual bool isCastingSpell (const MWWorld::Ptr& ptr) const override; + bool isCastingSpell (const MWWorld::Ptr& ptr) const override; - virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const override; + bool isReadyToBlock (const MWWorld::Ptr& ptr) const override; /// Is \a ptr casting spell or using weapon now? - virtual bool isAttackingOrSpell(const MWWorld::Ptr &ptr) const override; + bool isAttackingOrSpell(const MWWorld::Ptr &ptr) const override; - virtual void castSpell(const MWWorld::Ptr& ptr, const std::string spellId, bool manualSpell=false) override; + void castSpell(const MWWorld::Ptr& ptr, const std::string spellId, bool manualSpell=false) override; void processChangedSettings(const Settings::CategorySettingVector& settings) override; - virtual float getActorsProcessingRange() const override; + float getActorsProcessingRange() const override; - virtual void notifyDied(const MWWorld::Ptr& actor) override; + void notifyDied(const MWWorld::Ptr& actor) override; /// Check if the target actor was detected by an observer /// If the observer is a non-NPC, check all actors in AI processing distance as observers - virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) override; + bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) override; - virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) override; + void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) override; /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction). /// - virtual std::vector > getStolenItemOwners(const std::string& itemid) override; + std::vector > getStolenItemOwners(const std::string& itemid) override; /// Has the player stolen this item from the given owner? - virtual bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) override; + bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) override; - virtual bool isBoundItem(const MWWorld::Ptr& item) override; + bool isBoundItem(const MWWorld::Ptr& item) override; /// @return is \a ptr allowed to take/use \a target or is it a crime? - virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) override; + bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) override; - virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) override; - virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) override; + void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) override; + void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) override; - virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) override; + void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) override; - virtual void confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) override; + void confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) override; - virtual bool isAttackPreparing(const MWWorld::Ptr& ptr) override; - virtual bool isRunning(const MWWorld::Ptr& ptr) override; - virtual bool isSneaking(const MWWorld::Ptr& ptr) override; + bool isAttackPreparing(const MWWorld::Ptr& ptr) override; + bool isRunning(const MWWorld::Ptr& ptr) override; + bool isSneaking(const MWWorld::Ptr& ptr) override; - virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; + void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; - virtual int getGreetingTimer(const MWWorld::Ptr& ptr) const override; - virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const override; - virtual GreetingState getGreetingState(const MWWorld::Ptr& ptr) const override; - virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const override; + int getGreetingTimer(const MWWorld::Ptr& ptr) const override; + float getAngleToPlayer(const MWWorld::Ptr& ptr) const override; + GreetingState getGreetingState(const MWWorld::Ptr& ptr) const override; + bool isTurningToPlayer(const MWWorld::Ptr& ptr) const override; - virtual void restoreStatsAfterCorprus(const MWWorld::Ptr& actor, const std::string& sourceId) override; + void restoreStatsAfterCorprus(const MWWorld::Ptr& actor, const std::string& sourceId) override; private: bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); diff --git a/apps/openmw/mwmechanics/spellabsorption.cpp b/apps/openmw/mwmechanics/spellabsorption.cpp index 74df66780..bab290fda 100644 --- a/apps/openmw/mwmechanics/spellabsorption.cpp +++ b/apps/openmw/mwmechanics/spellabsorption.cpp @@ -24,9 +24,9 @@ namespace MWMechanics GetAbsorptionProbability() = default; - virtual void visit (MWMechanics::EffectKey key, int /*effectIndex*/, + void visit (MWMechanics::EffectKey key, int /*effectIndex*/, const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, - float magnitude, float /*remainingTime*/, float /*totalTime*/) + float magnitude, float /*remainingTime*/, float /*totalTime*/) override { if (key.mId == ESM::MagicEffect::SpellAbsorption) { diff --git a/apps/openmw/mwmechanics/summoning.hpp b/apps/openmw/mwmechanics/summoning.hpp index ac820e32f..7e787499e 100644 --- a/apps/openmw/mwmechanics/summoning.hpp +++ b/apps/openmw/mwmechanics/summoning.hpp @@ -22,9 +22,9 @@ namespace MWMechanics UpdateSummonedCreatures(const MWWorld::Ptr& actor); virtual ~UpdateSummonedCreatures() = default; - virtual void visit (MWMechanics::EffectKey key, int effectIndex, + void visit (MWMechanics::EffectKey key, int effectIndex, const std::string& sourceName, const std::string& sourceId, int casterActorId, - float magnitude, float remainingTime = -1, float totalTime = -1); + float magnitude, float remainingTime = -1, float totalTime = -1) override; /// To call after all effect sources have been visited void process(bool cleanup); diff --git a/apps/openmw/mwmechanics/typedaipackage.hpp b/apps/openmw/mwmechanics/typedaipackage.hpp index c959f4d68..d2d424326 100644 --- a/apps/openmw/mwmechanics/typedaipackage.hpp +++ b/apps/openmw/mwmechanics/typedaipackage.hpp @@ -18,7 +18,7 @@ namespace MWMechanics TypedAiPackage(Derived*) : AiPackage(Derived::getTypeId(), Derived::makeDefaultOptions()) {} - virtual std::unique_ptr clone() const override + std::unique_ptr clone() const override { return std::make_unique(*static_cast(this)); } diff --git a/apps/openmw/mwphysics/closestnotmeconvexresultcallback.hpp b/apps/openmw/mwphysics/closestnotmeconvexresultcallback.hpp index e4e960ab8..97aaa64a1 100644 --- a/apps/openmw/mwphysics/closestnotmeconvexresultcallback.hpp +++ b/apps/openmw/mwphysics/closestnotmeconvexresultcallback.hpp @@ -12,7 +12,7 @@ namespace MWPhysics public: ClosestNotMeConvexResultCallback(const btCollisionObject *me, const btVector3 &motion, btScalar minCollisionDot); - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace); + btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) override; protected: const btCollisionObject *mMe; diff --git a/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp b/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp index 3d2c5704b..23d52998c 100644 --- a/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp +++ b/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp @@ -14,7 +14,7 @@ namespace MWPhysics public: ClosestNotMeRayResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3& from, const btVector3& to); - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace); + btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) override; private: const btCollisionObject* mMe; const std::vector mTargets; diff --git a/apps/openmw/mwphysics/contacttestresultcallback.hpp b/apps/openmw/mwphysics/contacttestresultcallback.hpp index 0f469127d..03fc36299 100644 --- a/apps/openmw/mwphysics/contacttestresultcallback.hpp +++ b/apps/openmw/mwphysics/contacttestresultcallback.hpp @@ -19,9 +19,9 @@ namespace MWPhysics public: ContactTestResultCallback(const btCollisionObject* testedAgainst); - virtual btScalar addSingleResult(btManifoldPoint& cp, + btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1); + const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) override; std::vector mResult; }; diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp index f1107046b..9b2e97e65 100644 --- a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp @@ -24,9 +24,9 @@ namespace MWPhysics DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3 &origin); - virtual btScalar addSingleResult(btManifoldPoint& cp, + btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1); + const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) override; }; } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index e5ee925c4..f89a29cae 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -156,17 +156,17 @@ namespace MWPhysics /// target vector hits the collision shape and then calculates distance from the intersection point. /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful. /// \note Only Actor targets are supported at the moment. - float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const override final; + float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const final; /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors. RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), std::vector targets = std::vector(), - int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const override final; + int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const final; - RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const override final; + RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const final; /// Return true if actor1 can see actor2. - bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const override final; + bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const final; bool isOnGround (const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwrender/actoranimation.hpp b/apps/openmw/mwrender/actoranimation.hpp index 14c687a5d..86929a18a 100644 --- a/apps/openmw/mwrender/actoranimation.hpp +++ b/apps/openmw/mwrender/actoranimation.hpp @@ -35,11 +35,11 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); virtual ~ActorAnimation(); - virtual void itemAdded(const MWWorld::ConstPtr& item, int count); - virtual void itemRemoved(const MWWorld::ConstPtr& item, int count); + void itemAdded(const MWWorld::ConstPtr& item, int count) override; + void itemRemoved(const MWWorld::ConstPtr& item, int count) override; virtual bool isArrowAttached() const { return false; } - virtual bool useShieldAnimations() const; - bool updateCarriedLeftVisible(const int weaptype) const; + bool useShieldAnimations() const override; + bool updateCarriedLeftVisible(const int weaptype) const override; protected: osg::Group* getBoneByName(const std::string& boneName); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 3835e26de..29645a7c1 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -62,7 +62,7 @@ namespace : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { } - virtual void apply(osg::Node &node) + void apply(osg::Node &node) override { if (dynamic_cast(&node)) mToRemove.push_back(&node); @@ -70,7 +70,7 @@ namespace traverse(node); } - virtual void apply(osg::Drawable& drw) + void apply(osg::Drawable& drw) override { if (osgParticle::ParticleSystem* partsys = dynamic_cast(&drw)) mToRemove.push_back(partsys); @@ -98,7 +98,7 @@ namespace { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { unsigned int state = MWBase::Environment::get().getWorld()->getNightDayMode(); const unsigned int newState = node->asGroup()->getNumChildren() > state ? state : 0; @@ -123,7 +123,7 @@ namespace : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { } - virtual void apply(osg::Switch &switchNode) + void apply(osg::Switch &switchNode) override { if (switchNode.getName() == Constants::NightDayLabel) switchNode.addUpdateCallback(new DayNightCallback()); @@ -140,7 +140,7 @@ namespace { } - virtual void apply(osg::Switch& node) + void apply(osg::Switch& node) override { if (node.getName() == Constants::HerbalismLabel) { @@ -235,7 +235,7 @@ namespace { } - void apply(osg::Node& node) + void apply(osg::Node& node) override { if (SceneUtil::hasUserDescription(&node, "CustomBone")) { @@ -260,12 +260,12 @@ namespace { } - virtual void apply(osg::Node &node) + void apply(osg::Node &node) override { traverse(node); } - virtual void apply(osg::Group &group) + void apply(osg::Group &group) override { traverse(group); @@ -284,12 +284,12 @@ namespace } } - virtual void apply(osg::MatrixTransform &node) + void apply(osg::MatrixTransform &node) override { traverse(node); } - virtual void apply(osg::Geometry&) + void apply(osg::Geometry&) override { } }; @@ -313,12 +313,12 @@ namespace { } - virtual void apply(osg::Node &node) + void apply(osg::Node &node) override { traverse(node); } - virtual void apply(osg::Group &group) + void apply(osg::Group &group) override { traverse(group); @@ -337,12 +337,12 @@ namespace } } - virtual void apply(osg::MatrixTransform &node) + void apply(osg::MatrixTransform &node) override { traverse(node); } - virtual void apply(osg::Geometry&) + void apply(osg::Geometry&) override { } @@ -368,12 +368,12 @@ namespace { } - virtual void apply(osg::Node &node) + void apply(osg::Node &node) override { traverse(node); } - virtual void apply(osg::Group &group) + void apply(osg::Group &group) override { osg::Callback* callback = group.getUpdateCallback(); if (callback) @@ -390,12 +390,12 @@ namespace traverse(group); } - virtual void apply(osg::MatrixTransform &node) + void apply(osg::MatrixTransform &node) override { traverse(node); } - virtual void apply(osg::Geometry&) + void apply(osg::Geometry&) override { } @@ -407,20 +407,20 @@ namespace class CleanObjectRootVisitor : public RemoveVisitor { public: - virtual void apply(osg::Drawable& drw) + void apply(osg::Drawable& drw) override { applyDrawable(drw); } - virtual void apply(osg::Group& node) + void apply(osg::Group& node) override { applyNode(node); } - virtual void apply(osg::MatrixTransform& node) + void apply(osg::MatrixTransform& node) override { applyNode(node); } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { applyNode(node); } @@ -461,16 +461,16 @@ namespace class RemoveTriBipVisitor : public RemoveVisitor { public: - virtual void apply(osg::Drawable& drw) + void apply(osg::Drawable& drw) override { applyImpl(drw); } - virtual void apply(osg::Group& node) + void apply(osg::Group& node) override { traverse(node); } - virtual void apply(osg::MatrixTransform& node) + void apply(osg::MatrixTransform& node) override { traverse(node); } @@ -505,7 +505,7 @@ namespace MWRender } protected: - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { osg::BlendFunc* blendfunc (new osg::BlendFunc); stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); @@ -525,7 +525,7 @@ namespace MWRender stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) + void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override { osg::Material* material = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); material->setAlpha(osg::Material::FRONT_AND_BACK, mAlpha); @@ -586,7 +586,7 @@ namespace MWRender class ResetAccumRootCallback : public osg::NodeCallback { public: - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osg::MatrixTransform* transform = static_cast(node); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 8a1719db4..9d03831be 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -45,7 +45,7 @@ class EffectAnimationTime : public SceneUtil::ControllerSource private: float mTime; public: - virtual float getValue(osg::NodeVisitor* nv); + float getValue(osg::NodeVisitor* nv) override; void addTime(float duration); void resetTime(float time); @@ -173,13 +173,13 @@ protected: std::shared_ptr getTimePtr() const { return mTimePtr; } - virtual float getValue(osg::NodeVisitor* nv); + float getValue(osg::NodeVisitor* nv) override; }; class NullAnimationTime : public SceneUtil::ControllerSource { public: - virtual float getValue(osg::NodeVisitor *nv) + float getValue(osg::NodeVisitor *nv) override { return 0.f; } @@ -506,7 +506,7 @@ class ObjectAnimation : public Animation { public: ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model, Resource::ResourceSystem* resourceSystem, bool animated, bool allowLight); - bool canBeHarvested() const; + bool canBeHarvested() const override; }; class UpdateVfxCallback : public osg::NodeCallback @@ -522,7 +522,7 @@ public: bool mFinished; EffectParams mParams; - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); + void operator()(osg::Node* node, osg::NodeVisitor* nv) override; private: double mStartingTime; diff --git a/apps/openmw/mwrender/bulletdebugdraw.hpp b/apps/openmw/mwrender/bulletdebugdraw.hpp index 30da3aa72..30cabc4f9 100644 --- a/apps/openmw/mwrender/bulletdebugdraw.hpp +++ b/apps/openmw/mwrender/bulletdebugdraw.hpp @@ -39,19 +39,19 @@ public: void step(); - void drawLine(const btVector3& from,const btVector3& to,const btVector3& color); + void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) override; - void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color); + void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) override; - void reportErrorWarning(const char* warningString); + void reportErrorWarning(const char* warningString) override; - void draw3dText(const btVector3& location,const char* textString) {} + void draw3dText(const btVector3& location,const char* textString) override {} //0 for off, anything else for on. - void setDebugMode(int isOn); + void setDebugMode(int isOn) override; //0 for off, anything else for on. - int getDebugMode() const; + int getDebugMode() const override; }; diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 0d6ed262b..527dddb9d 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -33,7 +33,7 @@ public: { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osg::Camera* cam = static_cast(node); diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index b2552e598..89db3e5f4 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -41,7 +41,7 @@ namespace MWRender { } - virtual void operator () (osg::Node* node, osg::NodeVisitor* nv) + void operator () (osg::Node* node, osg::NodeVisitor* nv) override { if (!mRendered) { @@ -89,7 +89,7 @@ namespace MWRender { } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { if (osg::StateSet* stateset = node.getStateSet()) { @@ -432,7 +432,7 @@ namespace MWRender { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osg::Camera* cam = static_cast(node); diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index b71bffb62..3eb968846 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -86,7 +86,7 @@ namespace MWRender protected: osg::ref_ptr mViewport; - virtual void onSetup(); + void onSetup() override; }; class UpdateCameraCallback; @@ -98,8 +98,8 @@ namespace MWRender protected: - virtual bool renderHeadOnly() { return true; } - virtual void onSetup(); + bool renderHeadOnly() override { return true; } + void onSetup() override; public: RaceSelectionPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem); diff --git a/apps/openmw/mwrender/creatureanimation.hpp b/apps/openmw/mwrender/creatureanimation.hpp index 071500d74..9169e4102 100644 --- a/apps/openmw/mwrender/creatureanimation.hpp +++ b/apps/openmw/mwrender/creatureanimation.hpp @@ -28,37 +28,37 @@ namespace MWRender CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem); virtual ~CreatureWeaponAnimation() {} - virtual void equipmentChanged() { updateParts(); } + void equipmentChanged() override { updateParts(); } - virtual void showWeapons(bool showWeapon); + void showWeapons(bool showWeapon) override; - virtual bool getCarriedLeftShown() const { return mShowCarriedLeft; } - virtual void showCarriedLeft(bool show); + bool getCarriedLeftShown() const override { return mShowCarriedLeft; } + void showCarriedLeft(bool show) override; void updateParts(); void updatePart(PartHolderPtr& scene, int slot); - virtual void attachArrow(); - virtual void detachArrow(); - virtual void releaseArrow(float attackStrength); + void attachArrow() override; + void detachArrow() override; + void releaseArrow(float attackStrength) override; // WeaponAnimation - virtual osg::Group* getArrowBone(); - virtual osg::Node* getWeaponNode(); - virtual Resource::ResourceSystem* getResourceSystem(); - virtual void showWeapon(bool show) { showWeapons(show); } - virtual void setWeaponGroup(const std::string& group, bool relativeDuration) { mWeaponAnimationTime->setGroup(group, relativeDuration); } + osg::Group* getArrowBone() override; + osg::Node* getWeaponNode() override; + Resource::ResourceSystem* getResourceSystem() override; + void showWeapon(bool show) override { showWeapons(show); } + void setWeaponGroup(const std::string& group, bool relativeDuration) override { mWeaponAnimationTime->setGroup(group, relativeDuration); } - virtual void addControllers(); + void addControllers() override; - virtual osg::Vec3f runAnimation(float duration); + osg::Vec3f runAnimation(float duration) override; /// A relative factor (0-1) that decides if and how much the skeleton should be pitched /// to indicate the facing orientation of the character. - virtual void setPitchFactor(float factor) { mPitchFactor = factor; } + void setPitchFactor(float factor) override { mPitchFactor = factor; } protected: - virtual bool isArrowAttached() const; + bool isArrowAttached() const override; private: PartHolderPtr mWeapon; diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index afa83a1d7..ba300accb 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -70,7 +70,7 @@ namespace { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { if (mRendered) { @@ -105,7 +105,7 @@ namespace MWRender { } - virtual void doWork() + void doWork() override { osg::ref_ptr image = new osg::Image; image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE); diff --git a/apps/openmw/mwrender/landmanager.hpp b/apps/openmw/mwrender/landmanager.hpp index 0d37097d8..ea73f11c2 100644 --- a/apps/openmw/mwrender/landmanager.hpp +++ b/apps/openmw/mwrender/landmanager.hpp @@ -23,7 +23,7 @@ namespace MWRender /// @note Will return nullptr if not found. osg::ref_ptr getLand(int x, int y); - virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const; + void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; private: int mLoadFlags; diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index aaa797ef1..feefb29f5 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -39,7 +39,7 @@ namespace { } - virtual void operator()(osg::Node* node, osg::NodeVisitor*) + void operator()(osg::Node* node, osg::NodeVisitor*) override { if (mRendered) node->setNodeMask(0); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 30942d75f..36213fc96 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -145,7 +145,7 @@ public: void setBlinkStart(float value); void setBlinkStop(float value); - virtual float getValue(osg::NodeVisitor* nv); + float getValue(osg::NodeVisitor* nv) override; }; // -------------------------------------------------------------------------------- @@ -166,7 +166,7 @@ public: mOffset = offset; } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osg::MatrixTransform* transform = static_cast(node); osg::Matrix matrix = transform->getMatrix(); @@ -378,7 +378,7 @@ public: mDepth->setWriteMask(true); } - virtual void drawImplementation(osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) + void drawImplementation(osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) override { renderInfo.getState()->applyAttribute(mDepth); @@ -400,7 +400,7 @@ public: { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); float fov, aspect, zNear, zFar; diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index cf695c878..7e55001da 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -30,8 +30,8 @@ class HeadAnimationTime; class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener { public: - virtual void equipmentChanged(); - virtual void permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew); + void equipmentChanged() override; + void permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew) override; public: typedef std::map PartBoneMap; @@ -104,9 +104,9 @@ private: static NpcType getNpcType(const MWWorld::Ptr& ptr); protected: - virtual void addControllers(); - virtual bool isArrowAttached() const; - virtual std::string getShieldMesh(MWWorld::ConstPtr shield) const; + void addControllers() override; + bool isArrowAttached() const override; + std::string getShieldMesh(MWWorld::ConstPtr shield) const override; public: /** @@ -122,35 +122,35 @@ public: bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f); virtual ~NpcAnimation(); - virtual void enableHeadAnimation(bool enable); + void enableHeadAnimation(bool enable) override; /// 1: the first person meshes follow the camera's rotation completely /// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands - virtual void setAccurateAiming(bool enabled); + void setAccurateAiming(bool enabled) override; - virtual void setWeaponGroup(const std::string& group, bool relativeDuration); + void setWeaponGroup(const std::string& group, bool relativeDuration) override; - virtual osg::Vec3f runAnimation(float timepassed); + osg::Vec3f runAnimation(float timepassed) override; /// A relative factor (0-1) that decides if and how much the skeleton should be pitched /// to indicate the facing orientation of the character. - virtual void setPitchFactor(float factor) { mPitchFactor = factor; } + void setPitchFactor(float factor) override { mPitchFactor = factor; } - virtual void showWeapons(bool showWeapon); + void showWeapons(bool showWeapon) override; - virtual bool getCarriedLeftShown() const { return mShowCarriedLeft; } - virtual void showCarriedLeft(bool show); + bool getCarriedLeftShown() const override { return mShowCarriedLeft; } + void showCarriedLeft(bool show) override; - virtual void attachArrow(); - virtual void detachArrow(); - virtual void releaseArrow(float attackStrength); + void attachArrow() override; + void detachArrow() override; + void releaseArrow(float attackStrength) override; - virtual osg::Group* getArrowBone(); - virtual osg::Node* getWeaponNode(); - virtual Resource::ResourceSystem* getResourceSystem(); + osg::Group* getArrowBone() override; + osg::Node* getWeaponNode() override; + Resource::ResourceSystem* getResourceSystem() override; // WeaponAnimation - virtual void showWeapon(bool show) { showWeapons(show); } + void showWeapon(bool show) override { showWeapons(show); } void setViewMode(ViewMode viewMode); @@ -162,12 +162,12 @@ public: /// Get the inventory slot that the given node path leads into, or -1 if not found. int getSlot(const osg::NodePath& path) const; - virtual void setVampire(bool vampire); + void setVampire(bool vampire) override; /// Set a translation offset (in object root space) to apply to meshes when in first person mode. void setFirstPersonOffset(const osg::Vec3f& offset); - virtual void updatePtr(const MWWorld::Ptr& updated); + void updatePtr(const MWWorld::Ptr& updated) override; /// Get a list of body parts that may be used by an NPC of given race and gender. /// @note This is a fixed size list, one list item for each ESM::PartReferenceType, may contain nullptr body parts. diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index c756a3fc7..f74455d59 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -89,11 +89,11 @@ namespace MWRender class CanOptimizeCallback : public SceneUtil::Optimizer::IsOperationPermissibleForObjectCallback { public: - virtual bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Drawable* node,unsigned int option) const + bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Drawable* node,unsigned int option) const override { return true; } - virtual bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const + bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const override { return (node->getDataVariance() != osg::Object::DYNAMIC); } @@ -119,7 +119,7 @@ namespace MWRender } } - virtual osg::Node* operator() (const osg::Node* node) const + osg::Node* operator() (const osg::Node* node) const override { if (const osg::Drawable* d = node->asDrawable()) return operator()(d); @@ -222,7 +222,7 @@ namespace MWRender matrixTransform->setMatrix(newMatrix); } - virtual osg::Drawable* operator() (const osg::Drawable* drawable) const + osg::Drawable* operator() (const osg::Drawable* drawable) const override { if (dynamic_cast(drawable)) return nullptr; @@ -243,7 +243,7 @@ namespace MWRender else return const_cast(drawable); } - virtual osg::Callback* operator() (const osg::Callback* callback) const + osg::Callback* operator() (const osg::Callback* callback) const override { return nullptr; } @@ -281,13 +281,13 @@ namespace MWRender unsigned int mNumVerts = 0; }; - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { if (node.getStateSet()) mCurrentStateSet = node.getStateSet(); traverse(node); } - virtual void apply(osg::Geometry& geom) + void apply(osg::Geometry& geom) override { if (osg::Array* array = geom.getVertexArray()) mResult.mNumVerts += array->getNumElements(); @@ -328,7 +328,7 @@ namespace MWRender { public: DebugVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} - virtual void apply(osg::Drawable& node) + void apply(osg::Drawable& node) override { osg::ref_ptr m (new osg::Material); osg::Vec4f color(Misc::Rng::rollProbability(), Misc::Rng::rollProbability(), Misc::Rng::rollProbability(), 0.f); @@ -349,7 +349,7 @@ namespace MWRender public: AddRefnumMarkerVisitor(const ESM::RefNum &refnum) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mRefnum(refnum) {} ESM::RefNum mRefnum; - virtual void apply(osg::Geometry &node) + void apply(osg::Geometry &node) override { osg::ref_ptr marker (new RefnumMarker); marker->mRefnum = mRefnum; diff --git a/apps/openmw/mwrender/objectpaging.hpp b/apps/openmw/mwrender/objectpaging.hpp index 18fa30289..ff32dadd4 100644 --- a/apps/openmw/mwrender/objectpaging.hpp +++ b/apps/openmw/mwrender/objectpaging.hpp @@ -31,7 +31,7 @@ namespace MWRender osg::ref_ptr createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile); - virtual unsigned int getNodeMask() override; + unsigned int getNodeMask() override; /// @return true if view needs rebuild bool enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5c79a4d26..fd80e0bfa 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -89,7 +89,7 @@ namespace MWRender { } - virtual void setDefaults(osg::StateSet *stateset) + void setDefaults(osg::StateSet *stateset) override { osg::LightModel* lightModel = new osg::LightModel; stateset->setAttribute(lightModel, osg::StateAttribute::ON); @@ -106,7 +106,7 @@ namespace MWRender stateset->removeAttribute(osg::StateAttribute::POLYGONMODE); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor*) + void apply(osg::StateSet* stateset, osg::NodeVisitor*) override { osg::LightModel* lightModel = static_cast(stateset->getAttribute(osg::StateAttribute::LIGHTMODEL)); lightModel->setAmbientIntensity(mAmbientColor); @@ -166,7 +166,7 @@ namespace MWRender { } - virtual void doWork() + void doWork() override { try { @@ -701,7 +701,7 @@ namespace MWRender { } - virtual void operator () (osg::RenderInfo& renderInfo) const + void operator () (osg::RenderInfo& renderInfo) const override { std::lock_guard lock(mMutex); if (renderInfo.getState()->getFrameStamp()->getFrameNumber() >= mFrame) @@ -928,7 +928,7 @@ namespace MWRender : mWidth(width), mHeight(height), mImage(image) { } - virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* /*drawable*/) const + void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* /*drawable*/) const override { int screenW = renderInfo.getCurrentCamera()->getViewport()->width(); int screenH = renderInfo.getCurrentCamera()->getViewport()->height(); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 1f6f25ace..ef28cf544 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -98,7 +98,7 @@ namespace MWRender osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation(); - MWRender::Objects& getObjects(); + MWRender::Objects& getObjects() override; Resource::ResourceSystem* getResourceSystem(); diff --git a/apps/openmw/mwrender/rotatecontroller.hpp b/apps/openmw/mwrender/rotatecontroller.hpp index 456a6dd20..9d4080ac6 100644 --- a/apps/openmw/mwrender/rotatecontroller.hpp +++ b/apps/openmw/mwrender/rotatecontroller.hpp @@ -20,7 +20,7 @@ public: void setRotate(const osg::Quat& rotate); - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); + void operator()(osg::Node* node, osg::NodeVisitor* nv) override; protected: osg::Quat getWorldOrientation(osg::Node* node); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 10fc630bd..7ba490b92 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -119,12 +119,12 @@ public: } protected: - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { stateset->setAttributeAndModes(createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) + void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override { osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); mat->setEmission(osg::Material::FRONT_AND_BACK, mEmissionColor); @@ -149,7 +149,7 @@ public: } protected: - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { osg::ref_ptr texEnv (new osg::TexEnvCombine); texEnv->setCombine_Alpha(osg::TexEnvCombine::MODULATE); @@ -162,7 +162,7 @@ protected: stateset->setTextureAttributeAndModes(1, texEnv, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) + void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override { osg::TexEnvCombine* texEnv = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); texEnv->setConstantColor(mColor); @@ -201,7 +201,7 @@ public: } protected: - virtual void setDefaults(osg::StateSet *stateset) + void setDefaults(osg::StateSet *stateset) override { osg::ref_ptr texmat (new osg::TexMat); stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON); @@ -223,7 +223,7 @@ protected: stateset->setTextureMode(1, GL_TEXTURE_2D, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); } - virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) + void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override { osg::TexMat* texMat = static_cast(stateset->getTextureAttribute(0, osg::StateAttribute::TEXMAT)); texMat->setMatrix(osg::Matrix::translate(osg::Vec3f(0, -mAnimationTimer, 0.f))); @@ -272,7 +272,7 @@ public: return mViewPoint; } - virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const + bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const override { if (nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR) { @@ -291,7 +291,7 @@ public: } } - osg::BoundingSphere computeBound() const + osg::BoundingSphere computeBound() const override { return osg::BoundingSphere(osg::Vec3f(0,0,0), 0); } @@ -299,7 +299,7 @@ public: class CullCallback : public osg::NodeCallback { public: - virtual void operator() (osg::Node* node, osg::NodeVisitor* nv) + void operator() (osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); @@ -351,7 +351,7 @@ public: { } - void apply(osg::Drawable& drw) + void apply(osg::Drawable& drw) override { osg::Geometry* geom = drw.asGeometry(); if (!geom) @@ -409,7 +409,7 @@ public: return mEnabled && viewPoint.z() < mWaterLevel; } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { if (isUnderwater()) return; @@ -521,7 +521,7 @@ public: mUpdater->mColor.b() = color.b(); } - virtual void adjustTransparency(const float ratio) + void adjustTransparency(const float ratio) override { mUpdater->mColor.a() = ratio; if (mSunGlareCallback) @@ -550,7 +550,7 @@ private: class DummyComputeBoundCallback : public osg::Node::ComputeBoundingSphereCallback { public: - virtual osg::BoundingSphere computeBound(const osg::Node& node) const { return osg::BoundingSphere(); } + osg::BoundingSphere computeBound(const osg::Node& node) const override { return osg::BoundingSphere(); } }; /// @param queryVisible If true, queries the amount of visible pixels. If false, queries the total amount of pixels. @@ -701,12 +701,12 @@ private: { } - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { stateset->setAttributeAndModes(createUnlitMaterial(), osg::StateAttribute::ON); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor*) + void apply(osg::StateSet* stateset, osg::NodeVisitor*) override { osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,mColor.a())); @@ -766,7 +766,7 @@ private: { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); @@ -851,7 +851,7 @@ private: mColor[i] = std::min(1.f, mColor[i]); } - virtual void operator ()(osg::Node* node, osg::NodeVisitor* nv) + void operator ()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); @@ -955,7 +955,7 @@ public: mGeom->removeUpdateCallback(mUpdater); } - virtual void adjustTransparency(const float ratio) + void adjustTransparency(const float ratio) override { mUpdater->mTransparency *= ratio; } @@ -1026,7 +1026,7 @@ private: { } - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { stateset->setTextureAttributeAndModes(0, mPhaseTex, osg::StateAttribute::ON); osg::ref_ptr texEnv = new osg::TexEnvCombine; @@ -1050,7 +1050,7 @@ private: stateset->setAttributeAndModes(createUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor*) + void apply(osg::StateSet* stateset, osg::NodeVisitor*) override { osg::TexEnvCombine* texEnv = static_cast(stateset->getTextureAttribute(0, osg::StateAttribute::TEXENV)); texEnv->setConstantColor(mMoonColor * mShadowBlend); @@ -1226,7 +1226,7 @@ void SkyManager::create() class RainCounter : public osgParticle::ConstantRateCounter { public: - virtual int numParticlesToCreate(double dt) const + int numParticlesToCreate(double dt) const override { // limit dt to avoid large particle emissions if there are jumps in the simulation time // 0.2 seconds is the same cap as used in Engine's frame loop @@ -1243,7 +1243,7 @@ public: { } - virtual void shoot(osgParticle::Particle* particle) const + void shoot(osgParticle::Particle* particle) const override { particle->setVelocity(mVelocity); particle->setAngle(osg::Vec3f(-mAngle, 0, (Misc::Rng::rollProbability() * 2 - 1) * osg::PI)); @@ -1259,11 +1259,11 @@ public: mAngle = angle; } - virtual osg::Object* cloneType() const + osg::Object* cloneType() const override { return new RainShooter; } - virtual osg::Object* clone(const osg::CopyOp &) const + osg::Object* clone(const osg::CopyOp &) const override { return new RainShooter(*this); } @@ -1289,14 +1289,14 @@ public: mAlpha = alpha; } - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { // need to create a deep copy of StateAttributes we will modify osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); stateset->setAttribute(osg::clone(mat, osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON); } - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) + void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override { osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,mAlpha)); @@ -1315,7 +1315,7 @@ public: mAlphaUpdate = alphaUpdate; } - virtual void apply(osg::Node &node) + void apply(osg::Node &node) override { if (osg::StateSet* stateset = node.getStateSet()) { @@ -1368,7 +1368,7 @@ public: { } - virtual void setDefaults(osg::StateSet* stateset) + void setDefaults(osg::StateSet* stateset) override { osg::ref_ptr mat (new osg::Material); mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); @@ -1377,7 +1377,7 @@ public: stateset->setAttributeAndModes(mat, osg::StateAttribute::ON); } - virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) + void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override { AlphaFader::apply(stateset,nv); *mAlphaUpdate = mAlpha * 2.0; // mAlpha is limited to 0.6 so multiply by 2 to reach full intensity @@ -1400,21 +1400,21 @@ public: mPreviousCameraPosition = getCameraPosition(); } - virtual osg::Object *cloneType() const override + osg::Object *cloneType() const override { return nullptr; } - virtual osg::Object *clone(const osg::CopyOp &op) const override + osg::Object *clone(const osg::CopyOp &op) const override { return nullptr; } - virtual void operate(osgParticle::Particle *P, double dt) override + void operate(osgParticle::Particle *P, double dt) override { } - virtual void operateParticles(osgParticle::ParticleSystem *ps, double dt) override + void operateParticles(osgParticle::ParticleSystem *ps, double dt) override { osg::Vec3 position = getCameraPosition(); osg::Vec3 positionDifference = position - mPreviousCameraPosition; diff --git a/apps/openmw/mwrender/terrainstorage.hpp b/apps/openmw/mwrender/terrainstorage.hpp index c9ad94398..90bf42b84 100644 --- a/apps/openmw/mwrender/terrainstorage.hpp +++ b/apps/openmw/mwrender/terrainstorage.hpp @@ -20,13 +20,13 @@ namespace MWRender TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern = "", const std::string& normalHeightMapPattern = "", bool autoUseNormalMaps = false, const std::string& specularMapPattern = "", bool autoUseSpecularMaps = false); ~TerrainStorage(); - virtual osg::ref_ptr getLand (int cellX, int cellY) override; - virtual const ESM::LandTexture* getLandTexture(int index, short plugin) override; + osg::ref_ptr getLand (int cellX, int cellY) override; + const ESM::LandTexture* getLandTexture(int index, short plugin) override; - virtual bool hasData(int cellX, int cellY) override; + bool hasData(int cellX, int cellY) override; /// Get bounds of the whole terrain in cell units - virtual void getBounds(float& minX, float& maxX, float& minY, float& maxY) override; + void getBounds(float& minX, float& maxX, float& minY, float& maxY) override; LandManager* getLandManager() const; diff --git a/apps/openmw/mwrender/util.cpp b/apps/openmw/mwrender/util.cpp index 59a12794b..e3fc48040 100644 --- a/apps/openmw/mwrender/util.cpp +++ b/apps/openmw/mwrender/util.cpp @@ -21,7 +21,7 @@ class TextureOverrideVisitor : public osg::NodeVisitor { } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { int index = 0; osg::ref_ptr nodePtr(&node); diff --git a/apps/openmw/mwrender/util.hpp b/apps/openmw/mwrender/util.hpp index eebcfd9b0..a89baa22b 100644 --- a/apps/openmw/mwrender/util.hpp +++ b/apps/openmw/mwrender/util.hpp @@ -27,7 +27,7 @@ namespace MWRender class NoTraverseCallback : public osg::NodeCallback { public: - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { // no traverse() } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index a1691d5d1..b569f1bfa 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -65,7 +65,7 @@ class ClipCullNode : public osg::Group { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); @@ -98,7 +98,7 @@ class ClipCullNode : public osg::Group { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); osg::Vec3d eyePoint = cv->getEyePoint(); @@ -168,7 +168,7 @@ class InheritViewPointCallback : public osg::NodeCallback public: InheritViewPointCallback() {} - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); osg::ref_ptr modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); @@ -184,7 +184,7 @@ public: class FudgeCallback : public osg::NodeCallback { public: - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); @@ -408,7 +408,7 @@ private: class DepthClampCallback : public osg::Drawable::DrawCallback { public: - virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const + void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const override { static bool supported = osg::isGLExtensionOrVersionSupported(renderInfo.getState()->getContextID(), "GL_ARB_depth_clamp", 3.3); if (!supported) diff --git a/apps/openmw/mwrender/weaponanimation.hpp b/apps/openmw/mwrender/weaponanimation.hpp index dac1b663d..d02107333 100644 --- a/apps/openmw/mwrender/weaponanimation.hpp +++ b/apps/openmw/mwrender/weaponanimation.hpp @@ -23,7 +23,7 @@ namespace MWRender void setGroup(const std::string& group, bool relativeTime); void updateStartTime(); - virtual float getValue(osg::NodeVisitor* nv); + float getValue(osg::NodeVisitor* nv) override; }; /// Handles attach & release of projectiles for ranged weapons diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 2e426701c..499c2f672 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -40,7 +40,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -61,7 +61,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -89,7 +89,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -123,7 +123,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -165,7 +165,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -180,7 +180,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -237,7 +237,7 @@ namespace MWScript public: OpGetAiSetting(MWMechanics::CreatureStats::AiSetting index) : mIndex(index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -251,7 +251,7 @@ namespace MWScript public: OpModAiSetting(MWMechanics::CreatureStats::AiSetting index) : mIndex(index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; @@ -270,7 +270,7 @@ namespace MWScript public: OpSetAiSetting(MWMechanics::CreatureStats::AiSetting index) : mIndex(index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; @@ -288,7 +288,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -322,7 +322,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -358,7 +358,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -373,7 +373,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr observer = R()(runtime, false); // required=false @@ -395,7 +395,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr source = R()(runtime); @@ -418,7 +418,7 @@ namespace MWScript class OpGetTarget : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime &runtime) + void execute (Interpreter::Runtime &runtime) override { MWWorld::Ptr actor = R()(runtime); std::string testedTargetId = runtime.getStringLiteral (runtime[0].mInteger); @@ -448,7 +448,7 @@ namespace MWScript class OpStartCombat : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime &runtime) + void execute (Interpreter::Runtime &runtime) override { MWWorld::Ptr actor = R()(runtime); std::string targetID = runtime.getStringLiteral (runtime[0].mInteger); @@ -464,7 +464,7 @@ namespace MWScript class OpStopCombat : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr actor = R()(runtime); MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); @@ -476,7 +476,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getMechanicsManager()->toggleAI(); @@ -488,7 +488,7 @@ namespace MWScript class OpFace : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime& runtime) + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr actor = R()(runtime); diff --git a/apps/openmw/mwscript/animationextensions.cpp b/apps/openmw/mwscript/animationextensions.cpp index 6e959c0c0..8bb6cc6ad 100644 --- a/apps/openmw/mwscript/animationextensions.cpp +++ b/apps/openmw/mwscript/animationextensions.cpp @@ -24,7 +24,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -37,7 +37,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -67,7 +67,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 13ef98c63..356428156 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -30,7 +30,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWorld()->hasCellChanged() ? 1 : 0); } @@ -40,7 +40,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) { @@ -63,7 +63,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) { @@ -86,7 +86,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string cell = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -114,7 +114,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Integer x = runtime[0].mInteger; runtime.pop(); @@ -140,7 +140,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { if (!MWMechanics::getPlayer().isInCell()) { @@ -159,7 +159,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -185,7 +185,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { if (!MWMechanics::getPlayer().isInCell()) { @@ -206,7 +206,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Float level = runtime[0].mFloat; @@ -229,7 +229,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Float level = runtime[0].mFloat; diff --git a/apps/openmw/mwscript/compilercontext.hpp b/apps/openmw/mwscript/compilercontext.hpp index ca7efd77a..00b10ea06 100644 --- a/apps/openmw/mwscript/compilercontext.hpp +++ b/apps/openmw/mwscript/compilercontext.hpp @@ -25,22 +25,22 @@ namespace MWScript CompilerContext (Type type); /// Is the compiler allowed to declare local variables? - virtual bool canDeclareLocals() const; + bool canDeclareLocals() const override; /// 'l: long, 's': short, 'f': float, ' ': does not exist. - virtual char getGlobalType (const std::string& name) const; + char getGlobalType (const std::string& name) const override; - virtual std::pair getMemberType (const std::string& name, - const std::string& id) const; + std::pair getMemberType (const std::string& name, + const std::string& id) const override; ///< Return type of member variable \a name in script \a id or in script of reference of /// \a id /// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist. /// second: true: script of reference - virtual bool isId (const std::string& name) const; + bool isId (const std::string& name) const override; ///< Does \a name match an ID, that can be referenced? - virtual bool isJournalId (const std::string& name) const; + bool isJournalId (const std::string& name) const override; ///< Does \a name match a journal ID? }; } diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 9ed9204ad..7b5bf4730 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -37,7 +37,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -107,7 +107,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -131,7 +131,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -202,7 +202,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -239,7 +239,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -312,7 +312,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -338,7 +338,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -362,7 +362,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index 956792863..5362759e1 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -35,7 +35,7 @@ namespace MWScript : mControl (control), mEnable (enable) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get() .getInputManager() @@ -53,7 +53,7 @@ namespace MWScript : mControl (control) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push(!MWBase::Environment::get().getInputManager()->getControlSwitch (mControl)); } @@ -63,7 +63,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleCollisionMode(); @@ -80,7 +80,7 @@ namespace MWScript OpClearMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -97,7 +97,7 @@ namespace MWScript OpSetMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -110,7 +110,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -124,7 +124,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -138,7 +138,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -152,7 +152,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -165,7 +165,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); @@ -183,7 +183,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); runtime.push(MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr)); diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index 25c7f518e..b99a043bf 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -28,7 +28,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime, false); // required=false if (ptr.isEmpty()) @@ -57,7 +57,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string quest = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -73,7 +73,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string quest = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -89,7 +89,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string topic = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -102,7 +102,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWBase::DialogueManager* dialogue = MWBase::Environment::get().getDialogueManager(); while(arg0>0) @@ -127,7 +127,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -150,7 +150,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime& runtime) + void execute(Interpreter::Runtime& runtime) override { MWBase::Environment::get().getDialogueManager()->goodbye(); } @@ -161,7 +161,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; @@ -176,7 +176,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Integer value = runtime[0].mInteger; @@ -191,7 +191,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -204,7 +204,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -218,7 +218,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string faction1 = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -237,7 +237,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string faction1 = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -254,7 +254,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string faction1 = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -273,7 +273,7 @@ namespace MWScript class OpClearInfoActor : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 64f45b4c0..cb1e5cd91 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -30,7 +30,7 @@ namespace MWScript OpEnableWindow (MWGui::GuiWindow window) : mWindow (window) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWindowManager()->allow (mWindow); } @@ -40,7 +40,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWindowManager()->enableRest(); } @@ -50,7 +50,7 @@ namespace MWScript class OpShowRestMenu : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr bed = R()(runtime, false); @@ -70,7 +70,7 @@ namespace MWScript : mDialogue (dialogue) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWindowManager()->pushGuiMode(mDialogue); } @@ -80,7 +80,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWindowManager()->readPressedButton()); } @@ -90,7 +90,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.getContext().report(MWBase::Environment::get().getWindowManager()->toggleFogOfWar() ? "Fog of war -> On" : "Fog of war -> Off"); @@ -101,7 +101,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.getContext().report(MWBase::Environment::get().getWindowManager()->toggleFullHelp() ? "Full help -> On" : "Full help -> Off"); @@ -112,7 +112,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string cell = (runtime.getStringLiteral (runtime[0].mInteger)); ::Misc::StringUtils::lowerCaseInPlace(cell); @@ -143,7 +143,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { const MWWorld::Store &cells = MWBase::Environment::get().getWorld ()->getStore().get(); @@ -166,7 +166,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { int arg=0; if(arg0>0) @@ -206,7 +206,7 @@ namespace MWScript class OpToggleMenus : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { bool state = MWBase::Environment::get().getWindowManager()->toggleHud(); runtime.getContext().report(state ? "GUI -> On" : "GUI -> Off"); diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index e7c2790ce..c1481d6d0 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -57,82 +57,82 @@ namespace MWScript InterpreterContext (MWScript::Locals *locals, const MWWorld::Ptr& reference); ///< The ownership of \a locals is not transferred. 0-pointer allowed. - virtual int getLocalShort (int index) const; + int getLocalShort (int index) const override; - virtual int getLocalLong (int index) const; + int getLocalLong (int index) const override; - virtual float getLocalFloat (int index) const; + float getLocalFloat (int index) const override; - virtual void setLocalShort (int index, int value); + void setLocalShort (int index, int value) override; - virtual void setLocalLong (int index, int value); + void setLocalLong (int index, int value) override; - virtual void setLocalFloat (int index, float value); + void setLocalFloat (int index, float value) override; using Interpreter::Context::messageBox; - virtual void messageBox (const std::string& message, - const std::vector& buttons); + void messageBox (const std::string& message, + const std::vector& buttons) override; - virtual void report (const std::string& message); + void report (const std::string& message) override; ///< By default, do nothing. - virtual int getGlobalShort (const std::string& name) const; + int getGlobalShort (const std::string& name) const override; - virtual int getGlobalLong (const std::string& name) const; + int getGlobalLong (const std::string& name) const override; - virtual float getGlobalFloat (const std::string& name) const; + float getGlobalFloat (const std::string& name) const override; - virtual void setGlobalShort (const std::string& name, int value); + void setGlobalShort (const std::string& name, int value) override; - virtual void setGlobalLong (const std::string& name, int value); + void setGlobalLong (const std::string& name, int value) override; - virtual void setGlobalFloat (const std::string& name, float value); + void setGlobalFloat (const std::string& name, float value) override; - virtual std::vector getGlobals () const; + std::vector getGlobals () const override; - virtual char getGlobalType (const std::string& name) const; + char getGlobalType (const std::string& name) const override; - virtual std::string getActionBinding(const std::string& action) const; + std::string getActionBinding(const std::string& action) const override; - virtual std::string getActorName() const; + std::string getActorName() const override; - virtual std::string getNPCRace() const; + std::string getNPCRace() const override; - virtual std::string getNPCClass() const; + std::string getNPCClass() const override; - virtual std::string getNPCFaction() const; + std::string getNPCFaction() const override; - virtual std::string getNPCRank() const; + std::string getNPCRank() const override; - virtual std::string getPCName() const; + std::string getPCName() const override; - virtual std::string getPCRace() const; + std::string getPCRace() const override; - virtual std::string getPCClass() const; + std::string getPCClass() const override; - virtual std::string getPCRank() const; + std::string getPCRank() const override; - virtual std::string getPCNextRank() const; + std::string getPCNextRank() const override; - virtual int getPCBounty() const; + int getPCBounty() const override; - virtual std::string getCurrentCellName() const; + std::string getCurrentCellName() const override; void executeActivation(MWWorld::Ptr ptr, MWWorld::Ptr actor); ///< Execute the activation action for this ptr. If ptr is mActivated, mark activation as handled. - virtual int getMemberShort (const std::string& id, const std::string& name, bool global) const; + int getMemberShort (const std::string& id, const std::string& name, bool global) const override; - virtual int getMemberLong (const std::string& id, const std::string& name, bool global) const; + int getMemberLong (const std::string& id, const std::string& name, bool global) const override; - virtual float getMemberFloat (const std::string& id, const std::string& name, bool global) const; + float getMemberFloat (const std::string& id, const std::string& name, bool global) const override; - virtual void setMemberShort (const std::string& id, const std::string& name, int value, bool global); + void setMemberShort (const std::string& id, const std::string& name, int value, bool global) override; - virtual void setMemberLong (const std::string& id, const std::string& name, int value, bool global); + void setMemberLong (const std::string& id, const std::string& name, int value, bool global) override; - virtual void setMemberFloat (const std::string& id, const std::string& name, float value, bool global); + void setMemberFloat (const std::string& id, const std::string& name, float value, bool global) override; MWWorld::Ptr getReference(bool required=true); ///< Reference, that the script is running from (can be empty) diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 8ce891741..a288d6673 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -84,7 +84,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWindowManager()->isGuiMode()); } @@ -94,7 +94,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Integer limit = runtime[0].mInteger; runtime.pop(); @@ -112,7 +112,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr target = R()(runtime, false); std::string name = runtime.getStringLiteral (runtime[0].mInteger); @@ -125,7 +125,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -137,7 +137,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -149,7 +149,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getFrameDuration()); } @@ -160,7 +160,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); MWBase::Environment::get().getWorld()->enable (ptr); @@ -172,7 +172,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); MWBase::Environment::get().getWorld()->disable (ptr); @@ -184,7 +184,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push (!ptr.getRefData().isEnabled()); @@ -195,7 +195,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -211,7 +211,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWindowManager ()->getPlayerSleeping()); } @@ -221,7 +221,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World* world = MWBase::Environment::get().getWorld(); runtime.push (world->getPlayer().getJumping()); @@ -232,7 +232,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWindowManager ()->wakeUpPlayer(); } @@ -242,7 +242,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (0); } @@ -253,7 +253,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -266,7 +266,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { InterpreterContext& context = static_cast (runtime.getContext()); @@ -283,7 +283,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -314,7 +314,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -326,7 +326,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_CollisionDebug); @@ -341,7 +341,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_CollisionDebug); @@ -355,7 +355,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_Wireframe); @@ -369,7 +369,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleBorders(); @@ -382,7 +382,7 @@ namespace MWScript class OpTogglePathgrid : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_Pathgrid); @@ -396,7 +396,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); @@ -409,7 +409,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Float time = runtime[0].mFloat; runtime.pop(); @@ -422,7 +422,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { Interpreter::Type_Float alpha = runtime[0].mFloat; runtime.pop(); @@ -438,7 +438,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.getContext().report(MWBase::Environment::get().getWorld()->toggleWater() ? "Water -> On" : "Water -> Off"); @@ -449,7 +449,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.getContext().report(MWBase::Environment::get().getWorld()->toggleWorld() ? "World -> On" : "World -> Off"); @@ -460,7 +460,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { // We are ignoring the DontSaveObject statement for now. Probably not worth // bothering with. The incompatibility we are creating should be marginal at most. @@ -471,7 +471,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { if (!MWBase::Environment::get().getWorld()->isFirstPerson()) MWBase::Environment::get().getWorld()->togglePOV(true); @@ -480,7 +480,7 @@ namespace MWScript class OpPcForce3rdPerson : public Interpreter::Opcode0 { - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { if (MWBase::Environment::get().getWorld()->isFirstPerson()) MWBase::Environment::get().getWorld()->togglePOV(true); @@ -490,7 +490,7 @@ namespace MWScript class OpPcGet3rdPerson : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime& runtime) + void execute(Interpreter::Runtime& runtime) override { runtime.push(!MWBase::Environment::get().getWorld()->isFirstPerson()); } @@ -502,7 +502,7 @@ namespace MWScript public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -522,7 +522,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -535,7 +535,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -580,7 +580,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -612,7 +612,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -643,7 +643,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -730,7 +730,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -760,7 +760,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -773,7 +773,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -787,7 +787,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -800,7 +800,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); std::string id = runtime.getStringLiteral(runtime[0].mInteger); @@ -821,7 +821,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push(MWBase::Environment::get().getWorld()->getTimeStamp().getHour()); } @@ -832,7 +832,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); int parameter = runtime[0].mInteger; @@ -851,7 +851,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { float param = runtime[0].mFloat; runtime.pop(); @@ -865,7 +865,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { } }; @@ -875,7 +875,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push (MWBase::Environment::get().getWorld()->getPlayerStandingOn(ptr)); @@ -887,7 +887,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push (MWBase::Environment::get().getWorld()->getActorStandingOn(ptr)); @@ -899,7 +899,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push (MWBase::Environment::get().getWorld()->getPlayerCollidingWith(ptr)); @@ -911,7 +911,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push (MWBase::Environment::get().getWorld()->getActorCollidingWith(ptr)); @@ -923,7 +923,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); float healthDiffPerSecond = runtime[0].mFloat; @@ -938,7 +938,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); float healthDiffPerSecond = runtime[0].mFloat; @@ -952,7 +952,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push(MWBase::Environment::get().getWorld()->getWindSpeed()); } @@ -963,7 +963,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -982,7 +982,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1001,7 +1001,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World *world = MWBase::Environment::get().getWorld(); world->enableTeleporting(Enable); @@ -1013,7 +1013,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World *world = MWBase::Environment::get().getWorld(); world->enableLevitation(Enable); @@ -1025,7 +1025,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime, false); std::string var = runtime.getStringLiteral(runtime[0].mInteger); @@ -1162,7 +1162,7 @@ namespace MWScript } public: - virtual void execute(Interpreter::Runtime& runtime) + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime, false); if (!ptr.isEmpty()) @@ -1178,7 +1178,7 @@ namespace MWScript class OpToggleScripts : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleScripts(); @@ -1189,7 +1189,7 @@ namespace MWScript class OpToggleGodMode : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode(); @@ -1201,7 +1201,7 @@ namespace MWScript class OpCast : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1247,7 +1247,7 @@ namespace MWScript class OpExplodeSpell : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1284,7 +1284,7 @@ namespace MWScript class OpGoToJail : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World* world = MWBase::Environment::get().getWorld(); world->goToJail(); @@ -1294,7 +1294,7 @@ namespace MWScript class OpPayFine : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr player = MWMechanics::getPlayer(); player.getClass().getNpcStats(player).setBounty(0); @@ -1306,7 +1306,7 @@ namespace MWScript class OpPayFineThief : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr player = MWMechanics::getPlayer(); player.getClass().getNpcStats(player).setBounty(0); @@ -1318,7 +1318,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime &runtime) + void execute (Interpreter::Runtime &runtime) override { runtime.push (MWBase::Environment::get().getWorld()->isPlayerInJail()); } @@ -1328,7 +1328,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime &runtime) + void execute (Interpreter::Runtime &runtime) override { runtime.push (MWBase::Environment::get().getWorld()->isPlayerTraveling()); } @@ -1338,7 +1338,7 @@ namespace MWScript class OpBetaComment : public Interpreter::Opcode1 { public: - virtual void execute(Interpreter::Runtime &runtime, unsigned int arg0) + void execute(Interpreter::Runtime &runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -1400,7 +1400,7 @@ namespace MWScript class OpAddToLevCreature : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { const std::string& levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1418,7 +1418,7 @@ namespace MWScript class OpRemoveFromLevCreature : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { const std::string& levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1436,7 +1436,7 @@ namespace MWScript class OpAddToLevItem : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { const std::string& levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1454,7 +1454,7 @@ namespace MWScript class OpRemoveFromLevItem : public Interpreter::Opcode0 { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { const std::string& levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1473,7 +1473,7 @@ namespace MWScript class OpShowSceneGraph : public Interpreter::Opcode1 { public: - virtual void execute(Interpreter::Runtime &runtime, unsigned int arg0) + void execute(Interpreter::Runtime &runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime, false); @@ -1498,7 +1498,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_NavMesh); @@ -1512,7 +1512,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_ActorsPaths); @@ -1526,7 +1526,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { const auto navMeshNumber = runtime[0].mInteger; runtime.pop(); @@ -1546,7 +1546,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { // Broken in vanilla and deliberately no-op. runtime.push(0); @@ -1557,7 +1557,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_RecastMesh); diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index 50cc7afa8..7ddcd2489 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -68,23 +68,23 @@ namespace MWScript Compiler::Context& compilerContext, int warningsMode, const std::vector& scriptBlacklist); - virtual void clear(); + void clear() override; - virtual bool run (const std::string& name, Interpreter::Context& interpreterContext); + bool run (const std::string& name, Interpreter::Context& interpreterContext) override; ///< Run the script with the given name (compile first, if not compiled yet) - virtual bool compile (const std::string& name); + bool compile (const std::string& name) override; ///< Compile script with the given namen /// \return Success? - virtual std::pair compileAll(); + std::pair compileAll() override; ///< Compile all scripts /// \return count, success - virtual const Compiler::Locals& getLocals (const std::string& name); + const Compiler::Locals& getLocals (const std::string& name) override; ///< Return locals for script \a name. - virtual GlobalScripts& getGlobalScripts(); + GlobalScripts& getGlobalScripts() override; }; } diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index efcef6827..2b6bf826f 100644 --- a/apps/openmw/mwscript/skyextensions.cpp +++ b/apps/openmw/mwscript/skyextensions.cpp @@ -21,7 +21,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleSky(); @@ -33,7 +33,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWorld()->setMoonColour (false); } @@ -43,7 +43,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWorld()->setMoonColour (true); } @@ -53,7 +53,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWorld()->getMasserPhase()); } @@ -63,7 +63,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWorld()->getSecundaPhase()); } @@ -73,7 +73,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.push (MWBase::Environment::get().getWorld()->getCurrentWeather()); } @@ -83,7 +83,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string region = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -99,7 +99,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { std::string region = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index fe6f7bac3..6eab758f1 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -26,7 +26,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -51,7 +51,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -63,7 +63,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -76,7 +76,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -89,7 +89,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -113,7 +113,7 @@ namespace MWScript OpPlaySound3D (bool loop) : mLoop (loop) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -136,7 +136,7 @@ namespace MWScript OpPlaySoundVP3D (bool loop) : mLoop (loop) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -162,7 +162,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -178,7 +178,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 37751c6d4..58a943e1a 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -51,7 +51,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -69,7 +69,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -91,7 +91,7 @@ namespace MWScript OpGetAttribute (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -114,7 +114,7 @@ namespace MWScript OpSetAttribute (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -136,7 +136,7 @@ namespace MWScript OpModAttribute (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -172,7 +172,7 @@ namespace MWScript OpGetDynamic (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Float value; @@ -201,7 +201,7 @@ namespace MWScript OpSetDynamic (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -227,7 +227,7 @@ namespace MWScript OpModDynamic (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { int peek = R::implicit ? 0 : runtime[0].mInteger; @@ -277,7 +277,7 @@ namespace MWScript OpModCurrentDynamic (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -315,7 +315,7 @@ namespace MWScript OpGetDynamicGetRatio (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -341,7 +341,7 @@ namespace MWScript OpGetSkill (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -360,7 +360,7 @@ namespace MWScript OpSetSkill (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -382,7 +382,7 @@ namespace MWScript OpModSkill (int index) : mIndex (index) {} - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -411,7 +411,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World *world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); @@ -423,7 +423,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World *world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); @@ -441,7 +441,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::World *world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); @@ -456,7 +456,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -481,7 +481,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -517,7 +517,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -534,7 +534,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -550,7 +550,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -572,7 +572,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr actor = R()(runtime, false); @@ -604,7 +604,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr actor = R()(runtime, false); @@ -643,7 +643,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr actor = R()(runtime, false); @@ -675,7 +675,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -717,7 +717,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -737,7 +737,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -754,7 +754,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -769,7 +769,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime[0].mInteger = MWBase::Environment::get().getMechanicsManager()->countDeaths (id); @@ -781,7 +781,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -813,7 +813,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -847,7 +847,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -883,7 +883,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -896,7 +896,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -909,7 +909,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::ConstPtr ptr = R()(runtime); @@ -928,7 +928,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); @@ -941,7 +941,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -973,7 +973,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -1000,7 +1000,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + void execute (Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::ConstPtr ptr = R()(runtime, false); @@ -1025,7 +1025,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1060,7 +1060,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1097,7 +1097,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1116,7 +1116,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1135,7 +1135,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1151,7 +1151,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push(ptr.getClass().getNpcStats(ptr).isWerewolf()); @@ -1163,7 +1163,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set); @@ -1175,7 +1175,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr); @@ -1187,7 +1187,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1217,7 +1217,7 @@ namespace MWScript class OpGetStat : public Interpreter::Opcode0 { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { // dummy runtime.push(0); @@ -1237,7 +1237,7 @@ namespace MWScript { } - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1272,7 +1272,7 @@ namespace MWScript { } - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); @@ -1307,7 +1307,7 @@ namespace MWScript { } - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 3bc8cb1f0..ce45729b3 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -44,7 +44,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr from = R()(runtime); std::string name = runtime.getStringLiteral (runtime[0].mInteger); @@ -101,7 +101,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -117,7 +117,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); runtime.push(ptr.getCellRef().getScale()); @@ -129,7 +129,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -146,7 +146,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -181,7 +181,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -208,7 +208,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -235,7 +235,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -262,7 +262,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -318,7 +318,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -345,7 +345,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -412,7 +412,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -465,7 +465,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string itemID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -518,7 +518,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { std::string itemID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); @@ -565,7 +565,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr actor = pc ? MWMechanics::getPlayer() @@ -606,7 +606,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { const MWWorld::Ptr& ptr = R()(runtime); @@ -633,7 +633,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -669,7 +669,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -694,7 +694,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { const MWWorld::Ptr& ptr = R()(runtime); @@ -743,7 +743,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -779,7 +779,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWorld()->resetActors(); } @@ -789,7 +789,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWorld()->fixPosition(); } diff --git a/apps/openmw/mwscript/userextensions.cpp b/apps/openmw/mwscript/userextensions.cpp index 165a93062..3f443304d 100644 --- a/apps/openmw/mwscript/userextensions.cpp +++ b/apps/openmw/mwscript/userextensions.cpp @@ -21,7 +21,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.getContext().report ("user1: not in use"); } @@ -31,7 +31,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { runtime.getContext().report ("user2: not in use"); } @@ -42,7 +42,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { // MWWorld::Ptr ptr = R()(runtime); @@ -55,7 +55,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { // MWWorld::Ptr ptr = R()(runtime); diff --git a/apps/openmw/mwsound/movieaudiofactory.cpp b/apps/openmw/mwsound/movieaudiofactory.cpp index b0bfd52e1..d8c1c928e 100644 --- a/apps/openmw/mwsound/movieaudiofactory.cpp +++ b/apps/openmw/mwsound/movieaudiofactory.cpp @@ -57,13 +57,13 @@ namespace MWSound private: // MovieAudioDecoder overrides - virtual double getAudioClock() + double getAudioClock() override { return (double)getSampleOffset()/(double)mAudioContext->sample_rate - MWBase::Environment::get().getSoundManager()->getTrackTimeDelay(mAudioTrack); } - virtual void adjustAudioSettings(AVSampleFormat& sampleFormat, uint64_t& channelLayout, int& sampleRate) + void adjustAudioSettings(AVSampleFormat& sampleFormat, uint64_t& channelLayout, int& sampleRate) override { if (sampleFormat == AV_SAMPLE_FMT_U8P || sampleFormat == AV_SAMPLE_FMT_U8) sampleFormat = AV_SAMPLE_FMT_U8; diff --git a/apps/openmw/mwsound/movieaudiofactory.hpp b/apps/openmw/mwsound/movieaudiofactory.hpp index 6ec49a4d3..63b8fd7e9 100644 --- a/apps/openmw/mwsound/movieaudiofactory.hpp +++ b/apps/openmw/mwsound/movieaudiofactory.hpp @@ -8,7 +8,7 @@ namespace MWSound class MovieAudioFactory : public Video::MovieAudioFactory { - virtual std::shared_ptr createDecoder(Video::VideoState* videoState); + std::shared_ptr createDecoder(Video::VideoState* videoState) override; }; } diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index 6039d97d6..d9ca924a7 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -59,41 +59,41 @@ namespace MWSound OpenAL_Output(const OpenAL_Output &rhs); public: - virtual std::vector enumerate(); - virtual bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode); - virtual void deinit(); + std::vector enumerate() override; + bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode) override; + void deinit() override; - virtual std::vector enumerateHrtf(); - virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode); + std::vector enumerateHrtf() override; + void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) override; - virtual std::pair loadSound(const std::string &fname); - virtual size_t unloadSound(Sound_Handle data); + std::pair loadSound(const std::string &fname) override; + size_t unloadSound(Sound_Handle data) override; - virtual bool playSound(Sound *sound, Sound_Handle data, float offset); - virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset); - virtual void finishSound(Sound *sound); - virtual bool isSoundPlaying(Sound *sound); - virtual void updateSound(Sound *sound); + bool playSound(Sound *sound, Sound_Handle data, float offset) override; + bool playSound3D(Sound *sound, Sound_Handle data, float offset) override; + void finishSound(Sound *sound) override; + bool isSoundPlaying(Sound *sound) override; + void updateSound(Sound *sound) override; - virtual bool streamSound(DecoderPtr decoder, Stream *sound, bool getLoudnessData=false); - virtual bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData); - virtual void finishStream(Stream *sound); - virtual double getStreamDelay(Stream *sound); - virtual double getStreamOffset(Stream *sound); - virtual float getStreamLoudness(Stream *sound); - virtual bool isStreamPlaying(Stream *sound); - virtual void updateStream(Stream *sound); + bool streamSound(DecoderPtr decoder, Stream *sound, bool getLoudnessData=false) override; + bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) override; + void finishStream(Stream *sound) override; + double getStreamDelay(Stream *sound) override; + double getStreamOffset(Stream *sound) override; + float getStreamLoudness(Stream *sound) override; + bool isStreamPlaying(Stream *sound) override; + void updateStream(Stream *sound) override; - virtual void startUpdate(); - virtual void finishUpdate(); + void startUpdate() override; + void finishUpdate() override; - virtual void updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env); + void updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env) override; - virtual void pauseSounds(int types); - virtual void resumeSounds(int types); + void pauseSounds(int types) override; + void resumeSounds(int types) override; - virtual void pauseActiveDevice(); - virtual void resumeActiveDevice(); + void pauseActiveDevice() override; + void resumeActiveDevice() override; OpenAL_Output(SoundManager &mgr); virtual ~OpenAL_Output(); diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index b3f612d7d..37b099c02 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -169,111 +169,111 @@ namespace MWSound SoundManager(const VFS::Manager* vfs, bool useSound); virtual ~SoundManager(); - virtual void processChangedSettings(const Settings::CategorySettingVector& settings); + void processChangedSettings(const Settings::CategorySettingVector& settings) override; - virtual void stopMusic(); + void stopMusic() override; ///< Stops music if it's playing - virtual void streamMusic(const std::string& filename); + void streamMusic(const std::string& filename) override; ///< Play a soundifle /// \param filename name of a sound file in "Music/" in the data directory. - virtual bool isMusicPlaying(); + bool isMusicPlaying() override; ///< Returns true if music is playing - virtual void playPlaylist(const std::string &playlist); + void playPlaylist(const std::string &playlist) override; ///< Start playing music from the selected folder /// \param name of the folder that contains the playlist - virtual void playTitleMusic(); + void playTitleMusic() override; ///< Start playing title music - virtual void say(const MWWorld::ConstPtr &reference, const std::string& filename); + void say(const MWWorld::ConstPtr &reference, const std::string& filename) override; ///< Make an actor say some text. /// \param filename name of a sound file in "Sound/" in the data directory. - virtual void say(const std::string& filename); + void say(const std::string& filename) override; ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - virtual bool sayActive(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const; + bool sayActive(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const override; ///< Is actor not speaking? - virtual bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const; + bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const override; ///< For scripting backward compatibility - virtual void stopSay(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()); + void stopSay(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) override; ///< Stop an actor speaking - virtual float getSaySoundLoudness(const MWWorld::ConstPtr& reference) const; + float getSaySoundLoudness(const MWWorld::ConstPtr& reference) const override; ///< Check the currently playing say sound for this actor /// and get an average loudness value (scale [0,1]) at the current time position. /// If the actor is not saying anything, returns 0. - virtual Stream *playTrack(const DecoderPtr& decoder, Type type); + Stream *playTrack(const DecoderPtr& decoder, Type type) override; ///< Play a 2D audio track, using a custom decoder - virtual void stopTrack(Stream *stream); + void stopTrack(Stream *stream) override; ///< Stop the given audio track from playing - virtual double getTrackTimeDelay(Stream *stream); + double getTrackTimeDelay(Stream *stream) override; ///< Retives the time delay, in seconds, of the audio track (must be a sound /// returned by \ref playTrack). Only intended to be called by the track /// decoder's read method. - virtual Sound *playSound(const std::string& soundId, float volume, float pitch, Type type=Type::Sfx, PlayMode mode=PlayMode::Normal, float offset=0); + Sound *playSound(const std::string& soundId, float volume, float pitch, Type type=Type::Sfx, PlayMode mode=PlayMode::Normal, float offset=0) override; ///< Play a sound, independently of 3D-position ///< @param offset Number of seconds into the sound to start playback. - virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId, + Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId, float volume, float pitch, Type type=Type::Sfx, - PlayMode mode=PlayMode::Normal, float offset=0); + PlayMode mode=PlayMode::Normal, float offset=0) override; ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified. ///< @param offset Number of seconds into the sound to start playback. - virtual Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId, - float volume, float pitch, Type type, PlayMode mode, float offset=0); + Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId, + float volume, float pitch, Type type, PlayMode mode, float offset=0) override; ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition. ///< @param offset Number of seconds into the sound to start playback. - virtual void stopSound(Sound *sound); + void stopSound(Sound *sound) override; ///< Stop the given sound from playing /// @note no-op if \a sound is null - virtual void stopSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId); + void stopSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId) override; ///< Stop the given object from playing the given sound, - virtual void stopSound3D(const MWWorld::ConstPtr &reference); + void stopSound3D(const MWWorld::ConstPtr &reference) override; ///< Stop the given object from playing all sounds. - virtual void stopSound(const MWWorld::CellStore *cell); + void stopSound(const MWWorld::CellStore *cell) override; ///< Stop all sounds for the given cell. - virtual void fadeOutSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId, float duration); + void fadeOutSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId, float duration) override; ///< Fade out given sound (that is already playing) of given object ///< @param reference Reference to object, whose sound is faded out ///< @param soundId ID of the sound to fade out. ///< @param duration Time until volume reaches 0. - virtual bool getSoundPlaying(const MWWorld::ConstPtr &reference, const std::string& soundId) const; + bool getSoundPlaying(const MWWorld::ConstPtr &reference, const std::string& soundId) const override; ///< Is the given sound currently playing on the given object? - virtual void pauseSounds(MWSound::BlockerType blocker, int types=int(Type::Mask)); + void pauseSounds(MWSound::BlockerType blocker, int types=int(Type::Mask)) override; ///< Pauses all currently playing sounds, including music. - virtual void resumeSounds(MWSound::BlockerType blocker); + void resumeSounds(MWSound::BlockerType blocker) override; ///< Resumes all previously paused sounds. - virtual void pausePlayback(); - virtual void resumePlayback(); + void pausePlayback() override; + void resumePlayback() override; - virtual void update(float duration); + void update(float duration) override; - virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater); + void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) override; - virtual void updatePtr (const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated); + void updatePtr (const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override; - virtual void clear(); + void clear() override; }; } diff --git a/apps/openmw/mwstate/statemanagerimp.hpp b/apps/openmw/mwstate/statemanagerimp.hpp index d71fae850..11984b7f5 100644 --- a/apps/openmw/mwstate/statemanagerimp.hpp +++ b/apps/openmw/mwstate/statemanagerimp.hpp @@ -33,27 +33,27 @@ namespace MWState StateManager (const boost::filesystem::path& saves, const std::string& game); - virtual void requestQuit(); + void requestQuit() override; - virtual bool hasQuitRequest() const; + bool hasQuitRequest() const override; - virtual void askLoadRecent(); + void askLoadRecent() override; - virtual State getState() const; + State getState() const override; - virtual void newGame (bool bypass = false); + void newGame (bool bypass = false) override; ///< Start a new game. /// /// \param bypass Skip new game mechanics. - virtual void endGame(); + void endGame() override; - virtual void resumeGame(); + void resumeGame() override; - virtual void deleteGame (const MWState::Character *character, const MWState::Slot *slot); + void deleteGame (const MWState::Character *character, const MWState::Slot *slot) override; ///< Delete a saved game slot from this character. If all save slots are deleted, the character will be deleted too. - virtual void saveGame (const std::string& description, const Slot *slot = 0); + void saveGame (const std::string& description, const Slot *slot = 0) override; ///< Write a saved game to \a slot or create a new slot if \a slot == 0. /// /// \note Slot must belong to the current character. @@ -61,30 +61,30 @@ namespace MWState ///Saves a file, using supplied filename, overwritting if needed /** This is mostly used for quicksaving and autosaving, for they use the same name over and over again \param name Name of save, defaults to "Quicksave"**/ - virtual void quickSave(std::string name = "Quicksave"); + void quickSave(std::string name = "Quicksave") override; ///Loads the last saved file /** Used for quickload **/ - virtual void quickLoad(); + void quickLoad() override; - virtual void loadGame (const std::string& filepath); + void loadGame (const std::string& filepath) override; ///< Load a saved game directly from the given file path. This will search the CharacterManager /// for a Character containing this save file, and set this Character current if one was found. /// Otherwise, a new Character will be created. - virtual void loadGame (const Character *character, const std::string &filepath); + void loadGame (const Character *character, const std::string &filepath) override; ///< Load a saved game file belonging to the given character. - virtual Character *getCurrentCharacter (); + Character *getCurrentCharacter () override; ///< @note May return null. - virtual CharacterIterator characterBegin(); + CharacterIterator characterBegin() override; ///< Any call to SaveGame and getCurrentCharacter can invalidate the returned /// iterator. - virtual CharacterIterator characterEnd(); + CharacterIterator characterEnd() override; - virtual void update (float duration); + void update (float duration) override; }; } diff --git a/apps/openmw/mwworld/actionalchemy.hpp b/apps/openmw/mwworld/actionalchemy.hpp index 0f79d5c2d..194ef308b 100644 --- a/apps/openmw/mwworld/actionalchemy.hpp +++ b/apps/openmw/mwworld/actionalchemy.hpp @@ -8,7 +8,7 @@ namespace MWWorld class ActionAlchemy : public Action { bool mForce; - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: ActionAlchemy(bool force=false); diff --git a/apps/openmw/mwworld/actionapply.hpp b/apps/openmw/mwworld/actionapply.hpp index 4a1d2aefa..4350b7af4 100644 --- a/apps/openmw/mwworld/actionapply.hpp +++ b/apps/openmw/mwworld/actionapply.hpp @@ -11,7 +11,7 @@ namespace MWWorld { std::string mId; - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: @@ -24,7 +24,7 @@ namespace MWWorld int mSkillIndex; int mUsageType; - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: diff --git a/apps/openmw/mwworld/actiondoor.hpp b/apps/openmw/mwworld/actiondoor.hpp index 2dc5ad8c1..4be61f576 100644 --- a/apps/openmw/mwworld/actiondoor.hpp +++ b/apps/openmw/mwworld/actiondoor.hpp @@ -8,7 +8,7 @@ namespace MWWorld { class ActionDoor : public Action { - virtual void executeImp (const MWWorld::Ptr& actor); + void executeImp (const MWWorld::Ptr& actor) override; public: ActionDoor (const Ptr& object); diff --git a/apps/openmw/mwworld/actioneat.hpp b/apps/openmw/mwworld/actioneat.hpp index db21ffa17..ddc231d99 100644 --- a/apps/openmw/mwworld/actioneat.hpp +++ b/apps/openmw/mwworld/actioneat.hpp @@ -7,7 +7,7 @@ namespace MWWorld { class ActionEat : public Action { - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: diff --git a/apps/openmw/mwworld/actionequip.hpp b/apps/openmw/mwworld/actionequip.hpp index 1b5e52dd8..1ac3cb236 100644 --- a/apps/openmw/mwworld/actionequip.hpp +++ b/apps/openmw/mwworld/actionequip.hpp @@ -9,7 +9,7 @@ namespace MWWorld { bool mForce; - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: /// @param item to equip diff --git a/apps/openmw/mwworld/actionharvest.hpp b/apps/openmw/mwworld/actionharvest.hpp index b93ff7f10..2edc2f34e 100644 --- a/apps/openmw/mwworld/actionharvest.hpp +++ b/apps/openmw/mwworld/actionharvest.hpp @@ -8,7 +8,7 @@ namespace MWWorld { class ActionHarvest : public Action { - virtual void executeImp (const MWWorld::Ptr& actor); + void executeImp (const MWWorld::Ptr& actor) override; public: ActionHarvest (const Ptr& container); diff --git a/apps/openmw/mwworld/actionopen.hpp b/apps/openmw/mwworld/actionopen.hpp index e36b971a2..e9f76c4d7 100644 --- a/apps/openmw/mwworld/actionopen.hpp +++ b/apps/openmw/mwworld/actionopen.hpp @@ -7,7 +7,7 @@ namespace MWWorld { class ActionOpen : public Action { - virtual void executeImp (const MWWorld::Ptr& actor); + void executeImp (const MWWorld::Ptr& actor) override; public: ActionOpen (const Ptr& container); diff --git a/apps/openmw/mwworld/actionread.hpp b/apps/openmw/mwworld/actionread.hpp index 7c4d7d2f4..6387933eb 100644 --- a/apps/openmw/mwworld/actionread.hpp +++ b/apps/openmw/mwworld/actionread.hpp @@ -7,7 +7,7 @@ namespace MWWorld { class ActionRead : public Action { - virtual void executeImp (const MWWorld::Ptr& actor); + void executeImp (const MWWorld::Ptr& actor) override; public: /// @param book or scroll to read diff --git a/apps/openmw/mwworld/actionrepair.hpp b/apps/openmw/mwworld/actionrepair.hpp index fc64522d8..218077f5d 100644 --- a/apps/openmw/mwworld/actionrepair.hpp +++ b/apps/openmw/mwworld/actionrepair.hpp @@ -9,7 +9,7 @@ namespace MWWorld { bool mForce; - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: /// @param item repair hammer diff --git a/apps/openmw/mwworld/actionsoulgem.hpp b/apps/openmw/mwworld/actionsoulgem.hpp index 6a8f220bc..d2b14c912 100644 --- a/apps/openmw/mwworld/actionsoulgem.hpp +++ b/apps/openmw/mwworld/actionsoulgem.hpp @@ -7,7 +7,7 @@ namespace MWWorld { class ActionSoulgem : public Action { - virtual void executeImp (const MWWorld::Ptr& actor); + void executeImp (const MWWorld::Ptr& actor) override; public: /// @param soulgem to use diff --git a/apps/openmw/mwworld/actiontake.hpp b/apps/openmw/mwworld/actiontake.hpp index fb8d2f4ce..bb9c0d380 100644 --- a/apps/openmw/mwworld/actiontake.hpp +++ b/apps/openmw/mwworld/actiontake.hpp @@ -7,7 +7,7 @@ namespace MWWorld { class ActionTake : public Action { - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: diff --git a/apps/openmw/mwworld/actiontalk.hpp b/apps/openmw/mwworld/actiontalk.hpp index 01738a0bb..6dd70380f 100644 --- a/apps/openmw/mwworld/actiontalk.hpp +++ b/apps/openmw/mwworld/actiontalk.hpp @@ -7,7 +7,7 @@ namespace MWWorld { class ActionTalk : public Action { - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: diff --git a/apps/openmw/mwworld/actionteleport.hpp b/apps/openmw/mwworld/actionteleport.hpp index bd7b236a4..0a981a418 100644 --- a/apps/openmw/mwworld/actionteleport.hpp +++ b/apps/openmw/mwworld/actionteleport.hpp @@ -17,7 +17,7 @@ namespace MWWorld bool mTeleportFollowers; /// Teleports this actor and also teleports anyone following that actor. - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; /// Teleports only the given actor (internal use). void teleport(const Ptr &actor); diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 5b0d429c4..fe51959d1 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -12,7 +12,7 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - virtual void executeImp (const Ptr& actor); + void executeImp (const Ptr& actor) override; public: diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index bee6a957d..c6f71df6c 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -69,13 +69,13 @@ namespace MWWorld cell->forEach(visitor); } - virtual void abort() + void abort() override { mAbort = true; } /// Preload work to be called from the worker thread. - virtual void doWork() + void doWork() override { if (mIsExterior) { @@ -177,7 +177,7 @@ namespace MWWorld return true; } - virtual void doWork() + void doWork() override { for (unsigned int i=0; iupdateCache(mReferenceTime); } diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index bf107b422..0603b9de5 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -376,7 +376,7 @@ public: MWWorld::Cells& mCells; - virtual MWWorld::CellStore* getCellStore(const ESM::CellId& cellId) + MWWorld::CellStore* getCellStore(const ESM::CellId& cellId) override { try { diff --git a/apps/openmw/mwworld/esmloader.hpp b/apps/openmw/mwworld/esmloader.hpp index b96af707c..506105beb 100644 --- a/apps/openmw/mwworld/esmloader.hpp +++ b/apps/openmw/mwworld/esmloader.hpp @@ -25,7 +25,7 @@ struct EsmLoader : public ContentLoader EsmLoader(MWWorld::ESMStore& store, std::vector& readers, ToUTF8::Utf8Encoder* encoder, Loading::Listener& listener); - void load(const boost::filesystem::path& filepath, int& index); + void load(const boost::filesystem::path& filepath, int& index) override; private: std::vector& mEsm; diff --git a/apps/openmw/mwworld/failedaction.hpp b/apps/openmw/mwworld/failedaction.hpp index bafbb6f2d..2a201cdb3 100644 --- a/apps/openmw/mwworld/failedaction.hpp +++ b/apps/openmw/mwworld/failedaction.hpp @@ -10,7 +10,7 @@ namespace MWWorld { std::string mMessage; - virtual void executeImp(const Ptr &actor); + void executeImp(const Ptr &actor) override; public: FailedAction(const std::string &message = std::string(), const Ptr& target = Ptr()); diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 97ca931e7..6d669dd45 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -110,8 +110,8 @@ namespace MWWorld void fireEquipmentChangedEvent(const Ptr& actor); - virtual void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const; - virtual void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory); + void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const override; + void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) override; ContainerStoreIterator findSlot (int slot) const; @@ -123,9 +123,9 @@ namespace MWWorld InventoryStore& operator= (const InventoryStore& store); - virtual InventoryStore* clone() { return new InventoryStore(*this); } + InventoryStore* clone() override { return new InventoryStore(*this); } - virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true); + ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true) override; ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) /// Auto-equip items if specific conditions are fulfilled and allowAutoEquip is true (see the implementation). /// @@ -162,13 +162,13 @@ namespace MWWorld const MWMechanics::MagicEffects& getMagicEffects() const; ///< Return magic effects from worn items. - virtual bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const; + bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const override; ///< @return true if the two specified objects can stack with each other virtual int remove(const std::string& itemId, int count, const Ptr& actor); virtual int remove(const std::string& itemId, int count, const Ptr& actor, bool equipReplacement); - virtual int remove(const Ptr& item, int count, const Ptr& actor); + int remove(const Ptr& item, int count, const Ptr& actor) override; virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement); ///< Remove \a count item(s) designated by \a item from this inventory. /// @@ -209,12 +209,12 @@ namespace MWWorld void purgeEffect (short effectId, const std::string& sourceId, bool wholeSpell = false, int effectIndex=-1); ///< Remove a magic effect - virtual void clear(); + void clear() override; ///< Empty container. - virtual void writeState (ESM::InventoryState& state) const; + void writeState (ESM::InventoryState& state) const override; - virtual void readState (const ESM::InventoryState& state); + void readState (const ESM::InventoryState& state) override; }; } diff --git a/apps/openmw/mwworld/livecellref.hpp b/apps/openmw/mwworld/livecellref.hpp index 4b61c0a08..414fde42b 100644 --- a/apps/openmw/mwworld/livecellref.hpp +++ b/apps/openmw/mwworld/livecellref.hpp @@ -87,12 +87,12 @@ namespace MWWorld // The object that this instance is based on. const X* mBase; - virtual void load (const ESM::ObjectState& state); + void load (const ESM::ObjectState& state) override; ///< Load state into a LiveCellRef, that has already been initialised with base and class. /// /// \attention Must not be called with an invalid \a state. - virtual void save (ESM::ObjectState& state) const; + void save (ESM::ObjectState& state) const override; ///< Save LiveCellRef state into \a state. static bool checkState (const ESM::ObjectState& state); diff --git a/apps/openmw/mwworld/nullaction.hpp b/apps/openmw/mwworld/nullaction.hpp index 5461d8711..4ee1115e5 100644 --- a/apps/openmw/mwworld/nullaction.hpp +++ b/apps/openmw/mwworld/nullaction.hpp @@ -8,9 +8,9 @@ namespace MWWorld /// \brief Action: do nothing class NullAction : public Action { - virtual void executeImp (const Ptr& actor) {} + void executeImp (const Ptr& actor) override {} - virtual bool isNullAction() { return true; } + bool isNullAction() override { return true; } }; } diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index cc906e932..2c6feef46 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -166,7 +166,7 @@ namespace MWWorld { } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osg::PositionAttitudeTransform* transform = static_cast(node); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 684376226..bbf41ad2e 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -961,7 +961,7 @@ namespace MWWorld { } - virtual void doWork() + void doWork() override { try { diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index f119fa928..d2406b602 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -163,8 +163,8 @@ namespace MWWorld typedef SharedIterator iterator; // setUp needs to be called again after - virtual void clearDynamic(); - void setUp(); + void clearDynamic() override; + void setUp() override; const T *search(const std::string &id) const; const T *searchStatic(const std::string &id) const; @@ -186,22 +186,22 @@ namespace MWWorld iterator begin() const; iterator end() const; - size_t getSize() const; - int getDynamicSize() const; + size_t getSize() const override; + int getDynamicSize() const override; /// @note The record identifiers are listed in the order that the records were defined by the content files. - void listIdentifier(std::vector &list) const; + void listIdentifier(std::vector &list) const override; T *insert(const T &item); T *insertStatic(const T &item); - bool eraseStatic(const std::string &id); + bool eraseStatic(const std::string &id) override; bool erase(const std::string &id); bool erase(const T &item); - RecordId load(ESM::ESMReader &esm); - void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; - RecordId read(ESM::ESMReader& reader); + RecordId load(ESM::ESMReader &esm) override; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override; + RecordId read(ESM::ESMReader& reader) override; }; template <> @@ -224,11 +224,11 @@ namespace MWWorld /// Resize the internal store to hold at least \a num plugins. void resize(size_t num); - size_t getSize() const; + size_t getSize() const override; size_t getSize(size_t plugin) const; RecordId load(ESM::ESMReader &esm, size_t plugin); - RecordId load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm) override; iterator begin(size_t plugin) const; iterator end(size_t plugin) const; @@ -244,7 +244,7 @@ namespace MWWorld virtual ~Store(); - size_t getSize() const; + size_t getSize() const override; iterator begin() const; iterator end() const; @@ -253,8 +253,8 @@ namespace MWWorld const ESM::Land *search(int x, int y) const; const ESM::Land *find(int x, int y) const; - RecordId load(ESM::ESMReader &esm); - void setUp(); + RecordId load(ESM::ESMReader &esm) override; + void setUp() override; private: bool mBuilt = false; }; @@ -304,10 +304,10 @@ namespace MWWorld const ESM::Cell *find(const std::string &id) const; const ESM::Cell *find(int x, int y) const; - virtual void clearDynamic(); - void setUp(); + void clearDynamic() override; + void setUp() override; - RecordId load(ESM::ESMReader &esm); + RecordId load(ESM::ESMReader &esm) override; iterator intBegin() const; iterator intEnd() const; @@ -320,11 +320,11 @@ namespace MWWorld // Return the northernmost cell in the easternmost column. const ESM::Cell *searchExtByRegion(const std::string &id) const; - size_t getSize() const; + size_t getSize() const override; size_t getExtSize() const; size_t getIntSize() const; - void listIdentifier(std::vector &list) const; + void listIdentifier(std::vector &list) const override; ESM::Cell *insert(const ESM::Cell &cell); @@ -351,10 +351,10 @@ namespace MWWorld Store(); void setCells(Store& cells); - RecordId load(ESM::ESMReader &esm); - size_t getSize() const; + RecordId load(ESM::ESMReader &esm) override; + size_t getSize() const override; - void setUp(); + void setUp() override; const ESM::Pathgrid *search(int x, int y) const; const ESM::Pathgrid *search(const std::string& name) const; @@ -412,13 +412,13 @@ namespace MWWorld const ESM::WeaponType *search(const int id) const; const ESM::WeaponType *find(const int id) const; - RecordId load(ESM::ESMReader &esm) { return RecordId(0, false); } + RecordId load(ESM::ESMReader &esm) override { return RecordId(0, false); } ESM::WeaponType* insert(const ESM::WeaponType &weaponType); - void setUp(); + void setUp() override; - size_t getSize() const; + size_t getSize() const override; iterator begin() const; iterator end() const; }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 38bafa61b..daef81b5c 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -102,7 +102,7 @@ namespace MWWorld return mLoaders.insert(std::make_pair(extension, loader)).second; } - void load(const boost::filesystem::path& filepath, int& index) + void load(const boost::filesystem::path& filepath, int& index) override { LoadersContainer::iterator it(mLoaders.find(Misc::StringUtils::lowerCase(filepath.extension().string()))); if (it != mLoaders.end()) @@ -3123,9 +3123,9 @@ namespace MWWorld { } - virtual void visit (MWMechanics::EffectKey key, int /*effectIndex*/, + void visit (MWMechanics::EffectKey key, int /*effectIndex*/, const std::string& /*sourceName*/, const std::string& /*sourceId*/, int /*casterActorId*/, - float /*magnitude*/, float /*remainingTime*/ = -1, float /*totalTime*/ = -1) + float /*magnitude*/, float /*remainingTime*/ = -1, float /*totalTime*/ = -1) override { const ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const auto magicEffect = store.get().find(key.mId); diff --git a/apps/wizard/componentselectionpage.hpp b/apps/wizard/componentselectionpage.hpp index ca4347108..2509b9f5e 100644 --- a/apps/wizard/componentselectionpage.hpp +++ b/apps/wizard/componentselectionpage.hpp @@ -15,8 +15,8 @@ namespace Wizard public: ComponentSelectionPage(QWidget *parent); - int nextId() const; - virtual bool validatePage(); + int nextId() const override; + bool validatePage() override; private slots: void updateButton(QListWidgetItem *item); @@ -25,7 +25,7 @@ namespace Wizard MainWizard *mWizard; protected: - void initializePage(); + void initializePage() override; }; diff --git a/apps/wizard/conclusionpage.hpp b/apps/wizard/conclusionpage.hpp index 0e9abed72..f5f27dfca 100644 --- a/apps/wizard/conclusionpage.hpp +++ b/apps/wizard/conclusionpage.hpp @@ -15,13 +15,13 @@ namespace Wizard public: ConclusionPage(QWidget *parent); - int nextId() const; + int nextId() const override; private: MainWizard *mWizard; protected: - void initializePage(); + void initializePage() override; }; diff --git a/apps/wizard/existinginstallationpage.hpp b/apps/wizard/existinginstallationpage.hpp index 601295464..bb229e249 100644 --- a/apps/wizard/existinginstallationpage.hpp +++ b/apps/wizard/existinginstallationpage.hpp @@ -15,9 +15,9 @@ namespace Wizard public: ExistingInstallationPage(QWidget *parent); - int nextId() const; - virtual bool isComplete() const; - virtual bool validatePage(); + int nextId() const override; + bool isComplete() const override; + bool validatePage() override; private slots: void on_browseButton_clicked(); @@ -28,7 +28,7 @@ namespace Wizard MainWizard *mWizard; protected: - void initializePage(); + void initializePage() override; }; diff --git a/apps/wizard/importpage.hpp b/apps/wizard/importpage.hpp index 386cd59af..412d39ac1 100644 --- a/apps/wizard/importpage.hpp +++ b/apps/wizard/importpage.hpp @@ -15,7 +15,7 @@ namespace Wizard public: ImportPage(QWidget *parent); - int nextId() const; + int nextId() const override; private: MainWizard *mWizard; diff --git a/apps/wizard/installationpage.hpp b/apps/wizard/installationpage.hpp index 822cd21cd..cc1ccf559 100644 --- a/apps/wizard/installationpage.hpp +++ b/apps/wizard/installationpage.hpp @@ -22,8 +22,8 @@ namespace Wizard InstallationPage(QWidget *parent); ~InstallationPage(); - int nextId() const; - virtual bool isComplete() const; + int nextId() const override; + bool isComplete() const override; private: MainWizard *mWizard; @@ -41,7 +41,7 @@ namespace Wizard void installationError(const QString &text, const QString &details); protected: - void initializePage(); + void initializePage() override; }; diff --git a/apps/wizard/installationtargetpage.hpp b/apps/wizard/installationtargetpage.hpp index ca3b505b7..7cba29573 100644 --- a/apps/wizard/installationtargetpage.hpp +++ b/apps/wizard/installationtargetpage.hpp @@ -20,8 +20,8 @@ namespace Wizard public: InstallationTargetPage(QWidget *parent, const Files::ConfigurationManager &cfg); - int nextId() const; - virtual bool validatePage(); + int nextId() const override; + bool validatePage() override; private slots: void on_browseButton_clicked(); @@ -31,7 +31,7 @@ namespace Wizard const Files::ConfigurationManager &mCfgMgr; protected: - void initializePage(); + void initializePage() override; }; diff --git a/apps/wizard/intropage.hpp b/apps/wizard/intropage.hpp index 4ad9b4111..c8cd69016 100644 --- a/apps/wizard/intropage.hpp +++ b/apps/wizard/intropage.hpp @@ -15,7 +15,7 @@ namespace Wizard public: IntroPage(QWidget *parent); - int nextId() const; + int nextId() const override; private: MainWizard *mWizard; diff --git a/apps/wizard/languageselectionpage.hpp b/apps/wizard/languageselectionpage.hpp index abc3edb98..cc86ba9b3 100644 --- a/apps/wizard/languageselectionpage.hpp +++ b/apps/wizard/languageselectionpage.hpp @@ -15,13 +15,13 @@ namespace Wizard public: LanguageSelectionPage(QWidget *parent); - int nextId() const; + int nextId() const override; private: MainWizard *mWizard; protected: - void initializePage(); + void initializePage() override; }; } diff --git a/apps/wizard/mainwizard.hpp b/apps/wizard/mainwizard.hpp index a05013d98..8d9623baa 100644 --- a/apps/wizard/mainwizard.hpp +++ b/apps/wizard/mainwizard.hpp @@ -81,8 +81,8 @@ namespace Wizard void importerStarted(); void importerFinished(int exitCode, QProcess::ExitStatus exitStatus); - void accept(); - void reject(); + void accept() override; + void reject() override; }; diff --git a/apps/wizard/methodselectionpage.hpp b/apps/wizard/methodselectionpage.hpp index 60941c651..c189ea171 100644 --- a/apps/wizard/methodselectionpage.hpp +++ b/apps/wizard/methodselectionpage.hpp @@ -15,7 +15,7 @@ namespace Wizard public: MethodSelectionPage(QWidget *parent); - int nextId() const; + int nextId() const override; private: MainWizard *mWizard; diff --git a/components/bsa/compressedbsafile.hpp b/components/bsa/compressedbsafile.hpp index a22d6e149..3c28b5a5f 100644 --- a/components/bsa/compressedbsafile.hpp +++ b/components/bsa/compressedbsafile.hpp @@ -88,10 +88,10 @@ namespace Bsa static BsaVersion detectVersion(std::string filePath); /// Read header information from the input source - virtual void readHeader(); + void readHeader() override; - Files::IStreamPtr getFile(const char* filePath); - Files::IStreamPtr getFile(const FileStruct* fileStruct); + Files::IStreamPtr getFile(const char* filePath) override; + Files::IStreamPtr getFile(const FileStruct* fileStruct) override; }; } diff --git a/components/bullethelpers/processtrianglecallback.hpp b/components/bullethelpers/processtrianglecallback.hpp index ee005b459..b0d156754 100644 --- a/components/bullethelpers/processtrianglecallback.hpp +++ b/components/bullethelpers/processtrianglecallback.hpp @@ -15,7 +15,7 @@ namespace BulletHelpers : mImpl(std::move(impl)) {} - void processTriangle(btVector3* triangle, int partId, int triangleIndex) override final + void processTriangle(btVector3* triangle, int partId, int triangleIndex) final { return mImpl(triangle, partId, triangleIndex); } diff --git a/components/compiler/controlparser.hpp b/components/compiler/controlparser.hpp index 59958fd90..fad8025b4 100644 --- a/components/compiler/controlparser.hpp +++ b/components/compiler/controlparser.hpp @@ -54,20 +54,20 @@ namespace Compiler void appendCode (std::vector& code) const; ///< store generated code in \a code. - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - void reset(); + void reset() override; ///< Reset parser to clean state. }; } diff --git a/components/compiler/declarationparser.hpp b/components/compiler/declarationparser.hpp index 43dd83570..c04f1dc26 100644 --- a/components/compiler/declarationparser.hpp +++ b/components/compiler/declarationparser.hpp @@ -22,20 +22,20 @@ namespace Compiler DeclarationParser (ErrorHandler& errorHandler, const Context& context, Locals& locals); - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - void reset(); + void reset() override; }; } diff --git a/components/compiler/discardparser.hpp b/components/compiler/discardparser.hpp index 2a7ed5544..15e06756e 100644 --- a/components/compiler/discardparser.hpp +++ b/components/compiler/discardparser.hpp @@ -21,24 +21,24 @@ namespace Compiler DiscardParser (ErrorHandler& errorHandler, const Context& context); - virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); + bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle an int token. /// \return fetch another token? - virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner); + bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a float token. /// \return fetch another token? - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - virtual void reset(); + void reset() override; ///< Reset parser to clean state. /// Returns TokenLoc object for value. If no value has been parsed, the TokenLoc diff --git a/components/compiler/exprparser.hpp b/components/compiler/exprparser.hpp index dd8259ee1..0e8ad88c6 100644 --- a/components/compiler/exprparser.hpp +++ b/components/compiler/exprparser.hpp @@ -67,28 +67,28 @@ namespace Compiler char getType() const; ///< Return type of parsed expression ('l' integer, 'f' float) - virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); + bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle an int token. /// \return fetch another token? - virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner); + bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a float token. /// \return fetch another token? - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - void reset(); + void reset() override; ///< Reset parser to clean state. char append (std::vector& code); diff --git a/components/compiler/fileparser.hpp b/components/compiler/fileparser.hpp index 00f96cff0..b08ec9cdd 100644 --- a/components/compiler/fileparser.hpp +++ b/components/compiler/fileparser.hpp @@ -36,23 +36,23 @@ namespace Compiler const Locals& getLocals() const; ///< get local variable declarations. - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - virtual void parseEOF (Scanner& scanner); + void parseEOF (Scanner& scanner) override; ///< Handle EOF token. - void reset(); + void reset() override; ///< Reset parser to clean state. }; } diff --git a/components/compiler/junkparser.hpp b/components/compiler/junkparser.hpp index 6dfbd97af..0b42d4693 100644 --- a/components/compiler/junkparser.hpp +++ b/components/compiler/junkparser.hpp @@ -15,24 +15,24 @@ namespace Compiler JunkParser (ErrorHandler& errorHandler, const Context& context, int ignoreKeyword = -1); - virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); + bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle an int token. /// \return fetch another token? - virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner); + bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a float token. /// \return fetch another token? - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? }; diff --git a/components/compiler/lineparser.hpp b/components/compiler/lineparser.hpp index cc32b9592..c434792d1 100644 --- a/components/compiler/lineparser.hpp +++ b/components/compiler/lineparser.hpp @@ -51,28 +51,28 @@ namespace Compiler ///< \param allowExpression Allow lines consisting of a naked expression /// (result is send to the messagebox interface) - virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); + bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle an int token. /// \return fetch another token? - virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner); + bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a float token. /// \return fetch another token? - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - void reset(); + void reset() override; ///< Reset parser to clean state. }; @@ -82,11 +82,11 @@ namespace Compiler std::string mArguments; protected: - virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision, Notation notation); - virtual void visitedCharacter(char c) {} + void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision, Notation notation) override; + void visitedCharacter(char c) override {} public: - virtual void process(const std::string& message) + void process(const std::string& message) override { mArguments.clear(); ::Misc::MessageFormatParser::process(message); diff --git a/components/compiler/nullerrorhandler.hpp b/components/compiler/nullerrorhandler.hpp index 3dcff9250..d689fba63 100644 --- a/components/compiler/nullerrorhandler.hpp +++ b/components/compiler/nullerrorhandler.hpp @@ -9,10 +9,10 @@ namespace Compiler class NullErrorHandler : public ErrorHandler { - virtual void report (const std::string& message, const TokenLoc& loc, Type type); + void report (const std::string& message, const TokenLoc& loc, Type type) override; ///< Report error to the user. - virtual void report (const std::string& message, Type type); + void report (const std::string& message, Type type) override; ///< Report a file related error }; } diff --git a/components/compiler/quickfileparser.hpp b/components/compiler/quickfileparser.hpp index 440d91038..95e6b401c 100644 --- a/components/compiler/quickfileparser.hpp +++ b/components/compiler/quickfileparser.hpp @@ -17,20 +17,20 @@ namespace Compiler QuickFileParser (ErrorHandler& errorHandler, const Context& context, Locals& locals); - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - virtual void parseEOF (Scanner& scanner); + void parseEOF (Scanner& scanner) override; ///< Handle EOF token. }; } diff --git a/components/compiler/scriptparser.hpp b/components/compiler/scriptparser.hpp index edabb9c5c..d6dfe768c 100644 --- a/components/compiler/scriptparser.hpp +++ b/components/compiler/scriptparser.hpp @@ -29,23 +29,23 @@ namespace Compiler void getCode (std::vector& code) const; ///< store generated code in \a code. - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? - virtual void parseEOF (Scanner& scanner); + void parseEOF (Scanner& scanner) override; ///< Handle EOF token. - void reset(); + void reset() override; ///< Reset parser to clean state. }; } diff --git a/components/compiler/skipparser.hpp b/components/compiler/skipparser.hpp index 239c8bb02..4be90f3a1 100644 --- a/components/compiler/skipparser.hpp +++ b/components/compiler/skipparser.hpp @@ -15,24 +15,24 @@ namespace Compiler SkipParser (ErrorHandler& errorHandler, const Context& context); - virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); + bool parseInt (int value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle an int token. /// \return fetch another token? - virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner); + bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a float token. /// \return fetch another token? - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? }; diff --git a/components/compiler/streamerrorhandler.hpp b/components/compiler/streamerrorhandler.hpp index 1f3b6e1ec..ad3416695 100644 --- a/components/compiler/streamerrorhandler.hpp +++ b/components/compiler/streamerrorhandler.hpp @@ -20,10 +20,10 @@ namespace Compiler StreamErrorHandler (const StreamErrorHandler&); StreamErrorHandler& operator= (const StreamErrorHandler&); - virtual void report (const std::string& message, const TokenLoc& loc, Type type); + void report (const std::string& message, const TokenLoc& loc, Type type) override; ///< Report error to the user. - virtual void report (const std::string& message, Type type); + void report (const std::string& message, Type type) override; ///< Report a file related error public: diff --git a/components/compiler/stringparser.hpp b/components/compiler/stringparser.hpp index 72dab0580..197662836 100644 --- a/components/compiler/stringparser.hpp +++ b/components/compiler/stringparser.hpp @@ -30,16 +30,16 @@ namespace Compiler StringParser (ErrorHandler& errorHandler, const Context& context, Literals& literals); - virtual bool parseName (const std::string& name, const TokenLoc& loc, - Scanner& scanner); + bool parseName (const std::string& name, const TokenLoc& loc, + Scanner& scanner) override; ///< Handle a name token. /// \return fetch another token? - virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner); + bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a keyword token. /// \return fetch another token? - virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); + bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) override; ///< Handle a special character token. /// \return fetch another token? @@ -49,7 +49,7 @@ namespace Compiler void smashCase(); ///< Transform all scanned strings to lower case - void reset(); + void reset() override; ///< Reset parser to clean state (this includes the smashCase function). /// Returns TokenLoc object for string. If no string has been parsed, the TokenLoc diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index 80cd6e4c3..030865b35 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -28,20 +28,20 @@ namespace ContentSelectorModel void setEncoding(const QString &encoding); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QVariant data(const QModelIndex &index, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); - bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; - Qt::DropActions supportedDropActions() const; - QStringList mimeTypes() const; - QMimeData *mimeData(const QModelIndexList &indexes) const; - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + Qt::DropActions supportedDropActions() const override; + QStringList mimeTypes() const override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; void addFiles(const QString &path); void clearFiles(); diff --git a/components/contentselector/model/modelitem.hpp b/components/contentselector/model/modelitem.hpp index 57214b09c..e4ea7acc6 100644 --- a/components/contentselector/model/modelitem.hpp +++ b/components/contentselector/model/modelitem.hpp @@ -26,7 +26,7 @@ namespace ContentSelectorModel void appendChild(ModelItem *child); void removeChild(int row); - bool hasFormat(const QString &mimetype) const; + bool hasFormat(const QString &mimetype) const override; //virtual bool acceptChild(ModelItem *child); diff --git a/components/contentselector/view/combobox.hpp b/components/contentselector/view/combobox.hpp index e3888af2c..c57a5f116 100644 --- a/components/contentselector/view/combobox.hpp +++ b/components/contentselector/view/combobox.hpp @@ -22,7 +22,7 @@ namespace ContentSelectorView QString mPlaceholderText; protected: - void paintEvent(QPaintEvent *); + void paintEvent(QPaintEvent *) override; QRegExpValidator *mValidator; }; } diff --git a/components/debug/debugging.hpp b/components/debug/debugging.hpp index 1cae4b006..39390446f 100644 --- a/components/debug/debugging.hpp +++ b/components/debug/debugging.hpp @@ -89,7 +89,7 @@ namespace Debug mColors[NoLevel] = Reset; } - virtual std::streamsize writeImpl(const char *str, std::streamsize size, Level debugLevel) + std::streamsize writeImpl(const char *str, std::streamsize size, Level debugLevel) override { out.write (str, size); out.flush(); diff --git a/components/debug/gldebug.hpp b/components/debug/gldebug.hpp index 823d4f36f..8be747afe 100644 --- a/components/debug/gldebug.hpp +++ b/components/debug/gldebug.hpp @@ -10,7 +10,7 @@ namespace Debug public: EnableGLDebugOperation(); - virtual void operator()(osg::GraphicsContext* graphicsContext); + void operator()(osg::GraphicsContext* graphicsContext) override; private: OpenThreads::Mutex mMutex; diff --git a/components/esm/variantimp.hpp b/components/esm/variantimp.hpp index 1dc20c21f..e7ac722b1 100644 --- a/components/esm/variantimp.hpp +++ b/components/esm/variantimp.hpp @@ -75,25 +75,25 @@ namespace ESM ///< Calling the constructor with an incompatible data type will result in a silent /// default initialisation. - virtual VariantDataBase *clone() const; + VariantDataBase *clone() const override; - virtual std::string getString (bool default_ = false) const; + std::string getString (bool default_ = false) const override; ///< Will throw an exception, if value can not be represented as a string. /// /// \note Numeric values are not converted to strings. /// /// \param default_ Return a default value instead of throwing an exception. - virtual void setString (const std::string& value); + void setString (const std::string& value) override; ///< Will throw an exception, if type is not compatible with string. - virtual void read (ESMReader& esm, Variant::Format format, VarType type); + void read (ESMReader& esm, Variant::Format format, VarType type) override; ///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail - virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const; + void write (ESMWriter& esm, Variant::Format format, VarType type) const override; ///< If \a type is not supported by \a format, an exception is thrown. - virtual bool isEqual (const VariantDataBase& value) const; + bool isEqual (const VariantDataBase& value) const override; ///< If the (C++) type of \a value does not match the type of *this, an exception is thrown. }; @@ -107,32 +107,32 @@ namespace ESM ///< Calling the constructor with an incompatible data type will result in a silent /// default initialisation. - virtual VariantDataBase *clone() const; + VariantDataBase *clone() const override; - virtual int getInteger (bool default_ = false) const; + int getInteger (bool default_ = false) const override; ///< Will throw an exception, if value can not be represented as an integer (implicit /// casting of float values is permitted). /// /// \param default_ Return a default value instead of throwing an exception. - virtual float getFloat (bool default_ = false) const; + float getFloat (bool default_ = false) const override; ///< Will throw an exception, if value can not be represented as a float value. /// /// \param default_ Return a default value instead of throwing an exception. - virtual void setInteger (int value); + void setInteger (int value) override; ///< Will throw an exception, if type is not compatible with integer. - virtual void setFloat (float value); + void setFloat (float value) override; ///< Will throw an exception, if type is not compatible with float. - virtual void read (ESMReader& esm, Variant::Format format, VarType type); + void read (ESMReader& esm, Variant::Format format, VarType type) override; ///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail - virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const; + void write (ESMWriter& esm, Variant::Format format, VarType type) const override; ///< If \a type is not supported by \a format, an exception is thrown. - virtual bool isEqual (const VariantDataBase& value) const; + bool isEqual (const VariantDataBase& value) const override; ///< If the (C++) type of \a value does not match the type of *this, an exception is thrown. }; @@ -146,32 +146,32 @@ namespace ESM ///< Calling the constructor with an incompatible data type will result in a silent /// default initialisation. - virtual VariantDataBase *clone() const; + VariantDataBase *clone() const override; - virtual int getInteger (bool default_ = false) const; + int getInteger (bool default_ = false) const override; ///< Will throw an exception, if value can not be represented as an integer (implicit /// casting of float values is permitted). /// /// \param default_ Return a default value instead of throwing an exception. - virtual float getFloat (bool default_ = false) const; + float getFloat (bool default_ = false) const override; ///< Will throw an exception, if value can not be represented as a float value. /// /// \param default_ Return a default value instead of throwing an exception. - virtual void setInteger (int value); + void setInteger (int value) override; ///< Will throw an exception, if type is not compatible with integer. - virtual void setFloat (float value); + void setFloat (float value) override; ///< Will throw an exception, if type is not compatible with float. - virtual void read (ESMReader& esm, Variant::Format format, VarType type); + void read (ESMReader& esm, Variant::Format format, VarType type) override; ///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail - virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const; + void write (ESMWriter& esm, Variant::Format format, VarType type) const override; ///< If \a type is not supported by \a format, an exception is thrown. - virtual bool isEqual (const VariantDataBase& value) const; + bool isEqual (const VariantDataBase& value) const override; ///< If the (C++) type of \a value does not match the type of *this, an exception is thrown. }; } diff --git a/components/esmterrain/storage.hpp b/components/esmterrain/storage.hpp index c64531140..68e71574e 100644 --- a/components/esmterrain/storage.hpp +++ b/components/esmterrain/storage.hpp @@ -60,7 +60,7 @@ namespace ESMTerrain virtual osg::ref_ptr getLand (int cellX, int cellY)= 0; virtual const ESM::LandTexture* getLandTexture(int index, short plugin) = 0; /// Get bounds of the whole terrain in cell units - virtual void getBounds(float& minX, float& maxX, float& minY, float& maxY) = 0; + void getBounds(float& minX, float& maxX, float& minY, float& maxY) override = 0; /// Get the minimum and maximum heights of a terrain region. /// @note Will only be called for chunks with size = minBatchSize, i.e. leafs of the quad tree. @@ -70,7 +70,7 @@ namespace ESMTerrain /// @param min min height will be stored here /// @param max max height will be stored here /// @return true if there was data available for this terrain chunk - virtual bool getMinMaxHeights (float size, const osg::Vec2f& center, float& min, float& max); + bool getMinMaxHeights (float size, const osg::Vec2f& center, float& min, float& max) override; /// Fill vertex buffers for a terrain chunk. /// @note May be called from background threads. Make sure to only call thread-safe functions from here! @@ -82,10 +82,10 @@ namespace ESMTerrain /// @param positions buffer to write vertices /// @param normals buffer to write vertex normals /// @param colours buffer to write vertex colours - virtual void fillVertexBuffers (int lodLevel, float size, const osg::Vec2f& center, + void fillVertexBuffers (int lodLevel, float size, const osg::Vec2f& center, osg::ref_ptr positions, osg::ref_ptr normals, - osg::ref_ptr colours); + osg::ref_ptr colours) override; /// Create textures holding layer blend values for a terrain chunk. /// @note The terrain chunk shouldn't be larger than one cell since otherwise we might @@ -95,18 +95,18 @@ namespace ESMTerrain /// @param chunkCenter center of the chunk in cell units /// @param blendmaps created blendmaps will be written here /// @param layerList names of the layer textures used will be written here - virtual void getBlendmaps (float chunkSize, const osg::Vec2f& chunkCenter, ImageVector& blendmaps, - std::vector& layerList); + void getBlendmaps (float chunkSize, const osg::Vec2f& chunkCenter, ImageVector& blendmaps, + std::vector& layerList) override; - virtual float getHeightAt (const osg::Vec3f& worldPos); + float getHeightAt (const osg::Vec3f& worldPos) override; /// Get the transformation factor for mapping cell units to world units. - virtual float getCellWorldSize(); + float getCellWorldSize() override; /// Get the number of vertices on one side for each cell. Should be (power of two)+1 - virtual int getCellVertices(); + int getCellVertices() override; - virtual int getBlendmapScale(float chunkSize); + int getBlendmapScale(float chunkSize) override; float getVertexHeight (const ESM::Land::LandData* data, int x, int y) { diff --git a/components/files/constrainedfilestream.cpp b/components/files/constrainedfilestream.cpp index 419af0d6c..d2802218f 100644 --- a/components/files/constrainedfilestream.cpp +++ b/components/files/constrainedfilestream.cpp @@ -37,7 +37,7 @@ namespace Files mOrigin = start; } - virtual int_type underflow() + int_type underflow() override { if(gptr() == egptr()) { @@ -53,7 +53,7 @@ namespace Files return traits_type::to_int_type(*gptr()); } - virtual pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) + pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) override { if((mode&std::ios_base::out) || !(mode&std::ios_base::in)) return traits_type::eof(); @@ -86,7 +86,7 @@ namespace Files return newPos; } - virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode) + pos_type seekpos(pos_type pos, std::ios_base::openmode mode) override { if((mode&std::ios_base::out) || !(mode&std::ios_base::in)) return traits_type::eof(); diff --git a/components/interpreter/controlopcodes.hpp b/components/interpreter/controlopcodes.hpp index caa755989..fdf929161 100644 --- a/components/interpreter/controlopcodes.hpp +++ b/components/interpreter/controlopcodes.hpp @@ -12,7 +12,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { runtime.setPC (-1); } @@ -22,7 +22,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; runtime.pop(); @@ -36,7 +36,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; runtime.pop(); @@ -50,7 +50,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime, unsigned int arg0) + void execute (Runtime& runtime, unsigned int arg0) override { if (arg0==0) throw std::logic_error ("infinite loop"); @@ -63,7 +63,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime, unsigned int arg0) + void execute (Runtime& runtime, unsigned int arg0) override { if (arg0==0) throw std::logic_error ("infinite loop"); diff --git a/components/interpreter/genericopcodes.hpp b/components/interpreter/genericopcodes.hpp index 44ef3fc6b..ca08027ae 100644 --- a/components/interpreter/genericopcodes.hpp +++ b/components/interpreter/genericopcodes.hpp @@ -10,7 +10,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime, unsigned int arg0) + void execute (Runtime& runtime, unsigned int arg0) override { runtime.push (static_cast (arg0)); } @@ -20,7 +20,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; Type_Float floatValue = static_cast (data); @@ -32,7 +32,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float data = runtime[0].mFloat; Type_Integer integerValue = static_cast (data); @@ -44,7 +44,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; data = -data; @@ -56,7 +56,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float data = runtime[0].mFloat; data = -data; @@ -68,7 +68,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[1].mInteger; Type_Float floatValue = static_cast (data); @@ -80,7 +80,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float data = runtime[1].mFloat; Type_Integer integerValue = static_cast (data); diff --git a/components/interpreter/localopcodes.hpp b/components/interpreter/localopcodes.hpp index 7844a9ea7..0227327b3 100644 --- a/components/interpreter/localopcodes.hpp +++ b/components/interpreter/localopcodes.hpp @@ -11,7 +11,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; int index = runtime[1].mInteger; @@ -27,7 +27,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; int index = runtime[1].mInteger; @@ -43,7 +43,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float data = runtime[0].mFloat; int index = runtime[1].mInteger; @@ -59,7 +59,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer intValue = runtime.getIntegerLiteral (runtime[0].mInteger); runtime[0].mInteger = intValue; @@ -70,7 +70,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float floatValue = runtime.getFloatLiteral (runtime[0].mInteger); runtime[0].mFloat = floatValue; @@ -81,7 +81,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int index = runtime[0].mInteger; int value = runtime.getContext().getLocalShort (index); @@ -93,7 +93,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int index = runtime[0].mInteger; int value = runtime.getContext().getLocalLong (index); @@ -105,7 +105,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int index = runtime[0].mInteger; float value = runtime.getContext().getLocalFloat (index); @@ -117,7 +117,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; int index = runtime[1].mInteger; @@ -135,7 +135,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; int index = runtime[1].mInteger; @@ -153,7 +153,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float data = runtime[0].mFloat; int index = runtime[1].mInteger; @@ -171,7 +171,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int index = runtime[0].mInteger; std::string name = runtime.getStringLiteral (index); @@ -184,7 +184,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int index = runtime[0].mInteger; std::string name = runtime.getStringLiteral (index); @@ -197,7 +197,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int index = runtime[0].mInteger; std::string name = runtime.getStringLiteral (index); @@ -214,7 +214,7 @@ namespace Interpreter OpStoreMemberShort (bool global) : mGlobal (global) {} - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; Type_Integer index = runtime[1].mInteger; @@ -238,7 +238,7 @@ namespace Interpreter OpStoreMemberLong (bool global) : mGlobal (global) {} - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer data = runtime[0].mInteger; Type_Integer index = runtime[1].mInteger; @@ -262,7 +262,7 @@ namespace Interpreter OpStoreMemberFloat (bool global) : mGlobal (global) {} - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float data = runtime[0].mFloat; Type_Integer index = runtime[1].mInteger; @@ -286,7 +286,7 @@ namespace Interpreter OpFetchMemberShort (bool global) : mGlobal (global) {} - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer index = runtime[0].mInteger; std::string id = runtime.getStringLiteral (index); @@ -307,7 +307,7 @@ namespace Interpreter OpFetchMemberLong (bool global) : mGlobal (global) {} - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer index = runtime[0].mInteger; std::string id = runtime.getStringLiteral (index); @@ -328,7 +328,7 @@ namespace Interpreter OpFetchMemberFloat (bool global) : mGlobal (global) {} - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Integer index = runtime[0].mInteger; std::string id = runtime.getStringLiteral (index); diff --git a/components/interpreter/mathopcodes.hpp b/components/interpreter/mathopcodes.hpp index 14d5d98df..42cb486b9 100644 --- a/components/interpreter/mathopcodes.hpp +++ b/components/interpreter/mathopcodes.hpp @@ -14,7 +14,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { T result = getData (runtime[1]) + getData (runtime[0]); @@ -29,7 +29,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { T result = getData (runtime[1]) - getData (runtime[0]); @@ -44,7 +44,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { T result = getData (runtime[1]) * getData (runtime[0]); @@ -59,7 +59,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { T left = getData (runtime[0]); @@ -78,7 +78,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { Type_Float value = runtime[0].mFloat; @@ -97,7 +97,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { int result = C() (getData (runtime[1]), getData (runtime[0])); diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index 07bd84ec9..5a9311346 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -22,7 +22,7 @@ namespace Interpreter Runtime& mRuntime; protected: - virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision, Notation notation) + void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision, Notation notation) override { std::ostringstream out; out.fill(padding); @@ -86,7 +86,7 @@ namespace Interpreter } } - virtual void visitedCharacter(char c) + void visitedCharacter(char c) override { mFormattedMessage += c; } @@ -97,7 +97,7 @@ namespace Interpreter { } - virtual void process(const std::string& message) + void process(const std::string& message) override { mFormattedMessage.clear(); MessageFormatParser::process(message); @@ -123,7 +123,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime, unsigned int arg0) + void execute (Runtime& runtime, unsigned int arg0) override { // message int index = runtime[0].mInteger; @@ -153,7 +153,7 @@ namespace Interpreter { public: - virtual void execute (Runtime& runtime) + void execute (Runtime& runtime) override { // message int index = runtime[0].mInteger; diff --git a/components/myguiplatform/myguidatamanager.hpp b/components/myguiplatform/myguidatamanager.hpp index 5002f0fb7..a97c6ad2e 100644 --- a/components/myguiplatform/myguidatamanager.hpp +++ b/components/myguiplatform/myguidatamanager.hpp @@ -18,28 +18,28 @@ public: /** Get data stream from specified resource name. @param _name Resource name (usually file name). */ - virtual MyGUI::IDataStream* getData(const std::string& _name); + MyGUI::IDataStream* getData(const std::string& _name) override; /** Free data stream. @param _data Data stream. */ - virtual void freeData(MyGUI::IDataStream* _data); + void freeData(MyGUI::IDataStream* _data) override; /** Is data with specified name exist. @param _name Resource name. */ - virtual bool isDataExist(const std::string& _name); + bool isDataExist(const std::string& _name) override; /** Get all data names with names that matches pattern. @param _pattern Pattern to match (for example "*.layout"). */ - virtual const MyGUI::VectorString& getDataListNames(const std::string& _pattern); + const MyGUI::VectorString& getDataListNames(const std::string& _pattern) override; /** Get full path to data. @param _name Resource name. @return Return full path to specified data. */ - virtual const std::string& getDataPath(const std::string& _name); + const std::string& getDataPath(const std::string& _name) override; private: std::string mResourcePath; diff --git a/components/myguiplatform/myguiloglistener.hpp b/components/myguiplatform/myguiloglistener.hpp index 70dfc4ecf..4bab20ac9 100644 --- a/components/myguiplatform/myguiloglistener.hpp +++ b/components/myguiplatform/myguiloglistener.hpp @@ -24,11 +24,11 @@ namespace osgMyGUI ~CustomLogListener() {} - virtual void open(); - virtual void close(); - virtual void flush(); + void open() override; + void close() override; + void flush() override; - virtual void log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line); + void log(const std::string& _section, MyGUI::LogLevel _level, const struct tm* _time, const std::string& _message, const char* _file, int _line) override; const std::string& getFileName() const { return mFileName; } diff --git a/components/myguiplatform/myguirendermanager.cpp b/components/myguiplatform/myguirendermanager.cpp index 33cc31e2e..bba7df702 100644 --- a/components/myguiplatform/myguirendermanager.cpp +++ b/components/myguiplatform/myguirendermanager.cpp @@ -59,7 +59,7 @@ public: mRenderManager = renderManager; } - virtual void update(osg::NodeVisitor*, osg::Drawable*) + void update(osg::NodeVisitor*, osg::Drawable*) override { if (mRenderManager) mRenderManager->update(); @@ -83,7 +83,7 @@ public: mRenderManager = renderManager; } - virtual bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const + bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const override { if (!mRenderManager) return false; @@ -97,7 +97,7 @@ public: }; // Stage 2: execute the draw calls. Run during the Draw traversal. May run in parallel with the update traversal of the next frame. - virtual void drawImplementation(osg::RenderInfo &renderInfo) const + void drawImplementation(osg::RenderInfo &renderInfo) const override { osg::State *state = renderInfo.getState(); @@ -262,11 +262,11 @@ public: osg::Array* getVertexArray(); osg::VertexBufferObject* getVertexBuffer(); - virtual void setVertexCount(size_t count); - virtual size_t getVertexCount(); + void setVertexCount(size_t count) override; + size_t getVertexCount() override; - virtual MyGUI::Vertex *lock(); - virtual void unlock(); + MyGUI::Vertex *lock() override; + void unlock() override; }; diff --git a/components/myguiplatform/myguirendermanager.hpp b/components/myguiplatform/myguirendermanager.hpp index 8c9e3e30f..1e82bc0df 100644 --- a/components/myguiplatform/myguirendermanager.hpp +++ b/components/myguiplatform/myguirendermanager.hpp @@ -67,42 +67,42 @@ public: { return static_cast(MyGUI::RenderManager::getInstancePtr()); } /** @see RenderManager::getViewSize */ - virtual const MyGUI::IntSize& getViewSize() const { return mViewSize; } + const MyGUI::IntSize& getViewSize() const override { return mViewSize; } /** @see RenderManager::getVertexFormat */ - virtual MyGUI::VertexColourType getVertexFormat() { return mVertexFormat; } + MyGUI::VertexColourType getVertexFormat() override { return mVertexFormat; } /** @see RenderManager::isFormatSupported */ - virtual bool isFormatSupported(MyGUI::PixelFormat format, MyGUI::TextureUsage usage); + bool isFormatSupported(MyGUI::PixelFormat format, MyGUI::TextureUsage usage) override; /** @see RenderManager::createVertexBuffer */ - virtual MyGUI::IVertexBuffer* createVertexBuffer(); + MyGUI::IVertexBuffer* createVertexBuffer() override; /** @see RenderManager::destroyVertexBuffer */ - virtual void destroyVertexBuffer(MyGUI::IVertexBuffer *buffer); + void destroyVertexBuffer(MyGUI::IVertexBuffer *buffer) override; /** @see RenderManager::createTexture */ - virtual MyGUI::ITexture* createTexture(const std::string &name); + MyGUI::ITexture* createTexture(const std::string &name) override; /** @see RenderManager::destroyTexture */ - virtual void destroyTexture(MyGUI::ITexture* _texture); + void destroyTexture(MyGUI::ITexture* _texture) override; /** @see RenderManager::getTexture */ - virtual MyGUI::ITexture* getTexture(const std::string &name); + MyGUI::ITexture* getTexture(const std::string &name) override; // Called by the update traversal void update(); // Called by the cull traversal /** @see IRenderTarget::begin */ - virtual void begin(); + void begin() override; /** @see IRenderTarget::end */ - virtual void end(); + void end() override; /** @see IRenderTarget::doRender */ - virtual void doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *texture, size_t count); + void doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *texture, size_t count) override; /** specify a StateSet to inject for rendering. The StateSet will be used by future doRender calls until you reset it to nullptr again. */ void setInjectState(osg::StateSet* stateSet); /** @see IRenderTarget::getInfo */ - virtual const MyGUI::RenderTargetInfo& getInfo() { return mInfo; } + const MyGUI::RenderTargetInfo& getInfo() override { return mInfo; } bool checkTexture(MyGUI::ITexture* _texture); diff --git a/components/myguiplatform/myguitexture.hpp b/components/myguiplatform/myguitexture.hpp index 48f2ed265..6baeb7459 100644 --- a/components/myguiplatform/myguitexture.hpp +++ b/components/myguiplatform/myguitexture.hpp @@ -37,26 +37,26 @@ namespace osgMyGUI OSGTexture(osg::Texture2D* texture); virtual ~OSGTexture(); - virtual const std::string& getName() const { return mName; } + const std::string& getName() const override { return mName; } - virtual void createManual(int width, int height, MyGUI::TextureUsage usage, MyGUI::PixelFormat format); - virtual void loadFromFile(const std::string &fname); - virtual void saveToFile(const std::string &fname); + void createManual(int width, int height, MyGUI::TextureUsage usage, MyGUI::PixelFormat format) override; + void loadFromFile(const std::string &fname) override; + void saveToFile(const std::string &fname) override; - virtual void destroy(); + void destroy() override; - virtual void* lock(MyGUI::TextureUsage access); - virtual void unlock(); - virtual bool isLocked(); + void* lock(MyGUI::TextureUsage access) override; + void unlock() override; + bool isLocked() override; - virtual int getWidth(); - virtual int getHeight(); + int getWidth() override; + int getHeight() override; - virtual MyGUI::PixelFormat getFormat() { return mFormat; } - virtual MyGUI::TextureUsage getUsage() { return mUsage; } - virtual size_t getNumElemBytes() { return mNumElemBytes; } + MyGUI::PixelFormat getFormat() override { return mFormat; } + MyGUI::TextureUsage getUsage() override { return mUsage; } + size_t getNumElemBytes() override { return mNumElemBytes; } - virtual MyGUI::IRenderTarget *getRenderTarget(); + MyGUI::IRenderTarget *getRenderTarget() override; /*internal:*/ osg::Texture2D *getTexture() const { return mTexture.get(); } diff --git a/components/myguiplatform/scalinglayer.cpp b/components/myguiplatform/scalinglayer.cpp index ee9de349e..07a5161b2 100644 --- a/components/myguiplatform/scalinglayer.cpp +++ b/components/myguiplatform/scalinglayer.cpp @@ -22,22 +22,22 @@ namespace osgMyGUI { } - virtual void begin() + void begin() override { mTarget->begin(); } - virtual void end() + void end() override { mTarget->end(); } - virtual void doRender(MyGUI::IVertexBuffer* _buffer, MyGUI::ITexture* _texture, size_t _count) + void doRender(MyGUI::IVertexBuffer* _buffer, MyGUI::ITexture* _texture, size_t _count) override { mTarget->doRender(_buffer, _texture, _count); } - virtual const MyGUI::RenderTargetInfo& getInfo() + const MyGUI::RenderTargetInfo& getInfo() override { mInfo = mTarget->getInfo(); mInfo.hOffset = mHOffset; diff --git a/components/nif/base.hpp b/components/nif/base.hpp index 0d42131e5..711272abb 100644 --- a/components/nif/base.hpp +++ b/components/nif/base.hpp @@ -17,7 +17,7 @@ public: std::string name; ExtraPtr next; // Next extra data record in the list - void read(NIFStream *nif) + void read(NIFStream *nif) override { if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) name = nif->getString(); @@ -28,7 +28,7 @@ public: } } - void post(NIFFile *nif) { next.post(nif); } + void post(NIFFile *nif) override { next.post(nif); } }; class Controller : public Record @@ -40,8 +40,8 @@ public: float timeStart, timeStop; NamedPtr target; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; /// Has name, extra-data and controller @@ -53,7 +53,7 @@ public: ExtraList extralist; ControllerPtr controller; - void read(NIFStream *nif) + void read(NIFStream *nif) override { name = nif->getString(); if (nif->getVersion() < NIFStream::generateVersion(10,0,1,0)) @@ -63,7 +63,7 @@ public: controller.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { extra.post(nif); extralist.post(nif); diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp index 8396eae04..57d538f83 100644 --- a/components/nif/controlled.hpp +++ b/components/nif/controlled.hpp @@ -62,8 +62,8 @@ public: */ unsigned int alpha; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; struct NiParticleModifier : public Record @@ -71,8 +71,8 @@ struct NiParticleModifier : public Record NiParticleModifierPtr next; ControllerPtr controller; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiParticleGrowFade : public NiParticleModifier @@ -81,7 +81,7 @@ public: float growTime; float fadeTime; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiParticleColorModifier : public NiParticleModifier @@ -89,8 +89,8 @@ class NiParticleColorModifier : public NiParticleModifier public: NiColorDataPtr data; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiGravity : public NiParticleModifier @@ -105,20 +105,20 @@ public: osg::Vec3f mPosition; osg::Vec3f mDirection; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiParticleCollider : public NiParticleModifier { float mBounceFactor; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; // NiPinaColada class NiPlanarCollider : public NiParticleCollider { public: - void read(NIFStream *nif); + void read(NIFStream *nif) override; osg::Vec3f mPlaneNormal; float mPlaneDistance; @@ -130,13 +130,13 @@ public: float mRadius; osg::Vec3f mCenter; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiParticleRotation : public NiParticleModifier { public: - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index a527a4400..54cf9bf8f 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -75,8 +75,8 @@ public: NiParticleModifierPtr affectors; NiParticleModifierPtr colliders; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; using NiBSPArrayController = NiParticleSystemController; @@ -86,8 +86,8 @@ public: NiPosDataPtr data; unsigned int targetColor; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiPathController : public Controller @@ -110,8 +110,8 @@ public: float maxBankAngle, smoothing; short followAxis; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiLookAtController : public Controller @@ -120,8 +120,8 @@ public: NodePtr target; unsigned short lookAtFlags{0}; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiUVController : public Controller @@ -130,8 +130,8 @@ public: NiUVDataPtr data; unsigned int uvSet; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiKeyframeController : public Controller @@ -139,16 +139,16 @@ class NiKeyframeController : public Controller public: NiKeyframeDataPtr data; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; struct NiFloatInterpController : public Controller { NiFloatDataPtr data; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiAlphaController : public NiFloatInterpController { }; @@ -159,8 +159,8 @@ class NiGeomMorpherController : public Controller public: NiMorphDataPtr data; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiVisController : public Controller @@ -168,8 +168,8 @@ class NiVisController : public Controller public: NiVisDataPtr data; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiFlipController : public Controller @@ -179,8 +179,8 @@ public: float mDelta; // Time between two flips. delta = (start_time - stop_time) / num_sources NiSourceTextureList mSources; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; } // Namespace diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 58d6cf755..0ba544645 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -41,7 +41,7 @@ public: osg::Vec3f center; float radius; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiTriShapeData : public NiGeometryData @@ -50,7 +50,7 @@ public: // Triangles, three vertex indices per triangle std::vector triangles; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiTriStripsData : public NiGeometryData @@ -59,7 +59,7 @@ public: // Triangle strips, series of vertex indices. std::vector> strips; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiLinesData : public NiGeometryData @@ -67,7 +67,7 @@ struct NiLinesData : public NiGeometryData // Lines, series of indices that correspond to connected vertices. std::vector lines; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiAutoNormalParticlesData : public NiGeometryData @@ -81,13 +81,13 @@ public: std::vector rotations; std::vector rotationAxes; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiRotatingParticlesData : public NiAutoNormalParticlesData { public: - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiPosData : public Record @@ -95,7 +95,7 @@ class NiPosData : public Record public: Vector3KeyMapPtr mKeyList; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiUVData : public Record @@ -103,7 +103,7 @@ class NiUVData : public Record public: FloatKeyMapPtr mKeyList[4]; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiFloatData : public Record @@ -111,7 +111,7 @@ class NiFloatData : public Record public: FloatKeyMapPtr mKeyList; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiPixelData : public Record @@ -146,8 +146,8 @@ public: std::vector data; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiColorData : public Record @@ -155,7 +155,7 @@ class NiColorData : public Record public: Vector4KeyMapPtr mKeyMap; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiVisData : public Record @@ -167,7 +167,7 @@ public: }; std::vector mVis; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiSkinInstance : public Record @@ -177,8 +177,8 @@ public: NodePtr root; NodeList bones; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiSkinData : public Record @@ -201,7 +201,7 @@ public: Transformation trafo; std::vector bones; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiMorphData : public Record @@ -212,7 +212,7 @@ struct NiMorphData : public Record }; std::vector mMorphs; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; @@ -228,7 +228,7 @@ struct NiKeyframeData : public Record Vector3KeyMapPtr mTranslations; FloatKeyMapPtr mScales; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiPalette : public Record @@ -237,7 +237,7 @@ public: // 32-bit RGBA colors that correspond to 8-bit indices std::vector colors; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; } // Namespace diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 818df90a2..32eb3d80d 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -31,7 +31,7 @@ namespace Nif struct NiDynamicEffect : public Node { - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); if (nif->getVersion() >= nif->generateVersion(10,1,0,106) @@ -51,7 +51,7 @@ struct NiLight : NiDynamicEffect osg::Vec3f diffuse; osg::Vec3f specular; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiPointLight : public NiLight @@ -60,14 +60,14 @@ struct NiPointLight : public NiLight float linearAttenuation; float quadraticAttenuation; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiSpotLight : public NiPointLight { float cutoff; float exponent; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiTextureEffect : NiDynamicEffect @@ -94,8 +94,8 @@ struct NiTextureEffect : NiDynamicEffect }; CoordGenType coordGenType; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; } // Namespace diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 0e8cc16bf..3be627004 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -32,7 +32,7 @@ namespace Nif class NiVertWeightsExtraData : public Extra { public: - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiTextKeyExtraData : public Extra @@ -45,7 +45,7 @@ public: }; std::vector list; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiStringExtraData : public Extra @@ -57,56 +57,56 @@ public: */ std::string string; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiIntegerExtraData : public Extra { unsigned int data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiIntegersExtraData : public Extra { std::vector data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiBinaryExtraData : public Extra { std::vector data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiBooleanExtraData : public Extra { bool data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiVectorExtraData : public Extra { osg::Vec4f data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiFloatExtraData : public Extra { float data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; struct NiFloatsExtraData : public Extra { std::vector data; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; } // Namespace diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 4c57b2e81..72adfe06c 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -35,7 +35,7 @@ public: Matrix3 boundRot; osg::Vec3f boundXYZ; // Box size - void read(NIFStream *nif) + void read(NIFStream *nif) override { Named::read(nif); @@ -64,7 +64,7 @@ public: isBone = false; } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Named::post(nif); props.post(nif); @@ -104,7 +104,7 @@ struct NiNode : Node ControllerFlag_Active = 0x8 }; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); children.read(nif); @@ -120,7 +120,7 @@ struct NiNode : Node } } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); children.post(nif); @@ -183,7 +183,7 @@ struct NiTriShape : NiGeometry NiTriShapeDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); @@ -191,7 +191,7 @@ struct NiTriShape : NiGeometry materialData.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -205,7 +205,7 @@ struct NiTriStrips : NiGeometry { NiTriStripsDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); @@ -213,7 +213,7 @@ struct NiTriStrips : NiGeometry materialData.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -227,14 +227,14 @@ struct NiLines : NiGeometry { NiLinesDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); skin.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -284,7 +284,7 @@ struct NiCamera : Node }; Camera cam; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); @@ -301,14 +301,14 @@ struct NiAutoNormalParticles : Node { NiAutoNormalParticlesDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); nif->getInt(); // -1 } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -319,14 +319,14 @@ struct NiRotatingParticles : Node { NiRotatingParticlesDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); nif->getInt(); // -1 } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -339,7 +339,7 @@ struct NiSwitchNode : public NiNode unsigned int switchFlags{0}; unsigned int initialIndex; - void read(NIFStream *nif) + void read(NIFStream *nif) override { NiNode::read(nif); if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) @@ -359,7 +359,7 @@ struct NiLODNode : public NiSwitchNode }; std::vector lodLevels; - void read(NIFStream *nif) + void read(NIFStream *nif) override { NiSwitchNode::read(nif); if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFStream::generateVersion(10,0,1,0)) diff --git a/components/nif/property.hpp b/components/nif/property.hpp index aeef0c027..c821b7c37 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -92,8 +92,8 @@ public: osg::Vec2f envMapLumaBias; osg::Vec4f bumpMapMatrix; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiFogProperty : public Property @@ -103,14 +103,14 @@ public: float mFogDepth; osg::Vec3f mColour; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; // These contain no other data than the 'flags' field struct NiShadeProperty : public Property { unsigned short flags{0u}; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Property::read(nif); if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3) @@ -121,7 +121,7 @@ struct NiShadeProperty : public Property struct NiDitherProperty : public Property { unsigned short flags; - void read(NIFStream* nif) + void read(NIFStream* nif) override { Property::read(nif); flags = nif->getUShort(); @@ -132,7 +132,7 @@ struct NiZBufferProperty : public Property { unsigned short flags; unsigned int testFunction; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Property::read(nif); flags = nif->getUShort(); @@ -145,7 +145,7 @@ struct NiZBufferProperty : public Property struct NiSpecularProperty : public Property { unsigned short flags; - void read(NIFStream* nif) + void read(NIFStream* nif) override { Property::read(nif); flags = nif->getUShort(); @@ -155,7 +155,7 @@ struct NiSpecularProperty : public Property struct NiWireframeProperty : public Property { unsigned short flags; - void read(NIFStream* nif) + void read(NIFStream* nif) override { Property::read(nif); flags = nif->getUShort(); @@ -169,7 +169,7 @@ struct StructPropT : Property T data; unsigned short flags; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Property::read(nif); flags = nif->getUShort(); @@ -301,7 +301,7 @@ struct NiStencilProperty : public Property S_StencilProperty data; unsigned short flags{0u}; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Property::read(nif); if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD) @@ -315,7 +315,7 @@ struct NiMaterialProperty : public Property S_MaterialProperty data; unsigned short flags{0u}; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Property::read(nif); if (nif->getVersion() >= NIFStream::generateVersion(3,0,0,0) diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index a93dd28eb..c087e635f 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -179,9 +179,9 @@ namespace NifOsg public: ControllerFunction(const Nif::Controller *ctrl); - float calculate(float value) const; + float calculate(float value) const override; - virtual float getMaximum() const; + float getMaximum() const override; }; /// Must be set on a SceneUtil::MorphGeometry. @@ -194,7 +194,7 @@ namespace NifOsg META_Object(NifOsg, GeomMorpherController) - virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable); + void update(osg::NodeVisitor* nv, osg::Drawable* drawable) override; private: std::vector mKeyFrames; @@ -211,7 +211,7 @@ namespace NifOsg virtual osg::Vec3f getTranslation(float time) const; - virtual void operator() (osg::Node*, osg::NodeVisitor*); + void operator() (osg::Node*, osg::NodeVisitor*) override; private: QuaternionInterpolator mRotations; @@ -235,8 +235,8 @@ namespace NifOsg META_Object(NifOsg,UVController) - virtual void setDefaults(osg::StateSet* stateset); - virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv); + void setDefaults(osg::StateSet* stateset) override; + void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override; private: FloatInterpolator mUTrans; @@ -261,7 +261,7 @@ namespace NifOsg META_Object(NifOsg, VisController) - virtual void operator() (osg::Node* node, osg::NodeVisitor* nv); + void operator() (osg::Node* node, osg::NodeVisitor* nv) override; }; class RollController : public osg::NodeCallback, public SceneUtil::Controller @@ -275,7 +275,7 @@ namespace NifOsg RollController() = default; RollController(const RollController& copy, const osg::CopyOp& copyop); - virtual void operator() (osg::Node* node, osg::NodeVisitor* nv); + void operator() (osg::Node* node, osg::NodeVisitor* nv) override; META_Object(NifOsg, RollController) }; @@ -290,9 +290,9 @@ namespace NifOsg AlphaController(); AlphaController(const AlphaController& copy, const osg::CopyOp& copyop); - virtual void setDefaults(osg::StateSet* stateset); + void setDefaults(osg::StateSet* stateset) override; - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv); + void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override; META_Object(NifOsg, AlphaController) }; @@ -313,9 +313,9 @@ namespace NifOsg META_Object(NifOsg, MaterialColorController) - virtual void setDefaults(osg::StateSet* stateset); + void setDefaults(osg::StateSet* stateset) override; - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv); + void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override; private: Vec3Interpolator mData; @@ -340,7 +340,7 @@ namespace NifOsg std::vector >& getTextures() { return mTextures; } - virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv); + void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override; }; class ParticleSystemController : public osg::NodeCallback, public SceneUtil::Controller @@ -352,7 +352,7 @@ namespace NifOsg META_Object(NifOsg, ParticleSystemController) - virtual void operator() (osg::Node* node, osg::NodeVisitor* nv); + void operator() (osg::Node* node, osg::NodeVisitor* nv) override; private: float mEmitStart; @@ -368,7 +368,7 @@ namespace NifOsg META_Object(NifOsg, PathController) - virtual void operator() (osg::Node*, osg::NodeVisitor*); + void operator() (osg::Node*, osg::NodeVisitor*) override; private: Vec3Interpolator mPath; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 61a276dc1..65f62346d 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -102,7 +102,7 @@ namespace META_Object(NifOsg, BillboardCallback) - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgUtil::CullVisitor* cv = static_cast(nv); diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index d71cbb9f5..724a8a721 100644 --- a/components/nifosg/particle.hpp +++ b/components/nifosg/particle.hpp @@ -32,11 +32,11 @@ namespace NifOsg META_Object(NifOsg, ParticleSystem) - virtual osgParticle::Particle* createParticle(const osgParticle::Particle *ptemplate); + osgParticle::Particle* createParticle(const osgParticle::Particle *ptemplate) override; void setQuota(int quota); - virtual void drawImplementation(osg::RenderInfo& renderInfo) const; + void drawImplementation(osg::RenderInfo& renderInfo) const override; private: int mQuota; @@ -70,7 +70,7 @@ namespace NifOsg META_Object(NifOsg, InverseWorldMatrix) - void operator()(osg::Node* node, osg::NodeVisitor* nv); + void operator()(osg::Node* node, osg::NodeVisitor* nv) override; }; class ParticleShooter : public osgParticle::Shooter @@ -85,7 +85,7 @@ namespace NifOsg META_Object(NifOsg, ParticleShooter) - virtual void shoot(osgParticle::Particle* particle) const; + void shoot(osgParticle::Particle* particle) const override; private: float mMinSpeed; @@ -107,8 +107,8 @@ namespace NifOsg META_Object(NifOsg, PlanarCollider) - virtual void beginOperate(osgParticle::Program* program); - virtual void operate(osgParticle::Particle* particle, double dt); + void beginOperate(osgParticle::Program* program) override; + void operate(osgParticle::Particle* particle, double dt) override; private: float mBounceFactor; @@ -125,8 +125,8 @@ namespace NifOsg META_Object(NifOsg, SphericalCollider) - virtual void beginOperate(osgParticle::Program* program); - virtual void operate(osgParticle::Particle* particle, double dt); + void beginOperate(osgParticle::Program* program) override; + void operate(osgParticle::Particle* particle, double dt) override; private: float mBounceFactor; osg::BoundingSphere mSphere; @@ -144,8 +144,8 @@ namespace NifOsg META_Object(NifOsg, GrowFadeAffector) - virtual void beginOperate(osgParticle::Program* program); - virtual void operate(osgParticle::Particle* particle, double dt); + void beginOperate(osgParticle::Program* program) override; + void operate(osgParticle::Particle* particle, double dt) override; private: float mGrowTime; @@ -165,7 +165,7 @@ namespace NifOsg META_Object(NifOsg, ParticleColorAffector) - virtual void operate(osgParticle::Particle* particle, double dt); + void operate(osgParticle::Particle* particle, double dt) override; private: Vec4Interpolator mData; @@ -182,8 +182,8 @@ namespace NifOsg META_Object(NifOsg, GravityAffector) - virtual void operate(osgParticle::Particle* particle, double dt); - virtual void beginOperate(osgParticle::Program *); + void operate(osgParticle::Particle* particle, double dt) override; + void beginOperate(osgParticle::Program *) override ; private: float mForce; @@ -206,12 +206,12 @@ namespace NifOsg public: FindGroupByRecIndex(int recIndex); - virtual void apply(osg::Node &node); + void apply(osg::Node &node) override; // Technically not required as the default implementation would trickle down to apply(Node&) anyway, // but we'll shortcut instead to avoid the chain of virtual function calls - virtual void apply(osg::MatrixTransform& node); - virtual void apply(osg::Geometry& node); + void apply(osg::MatrixTransform& node) override; + void apply(osg::Geometry& node) override; void applyNode(osg::Node& searchNode); @@ -231,7 +231,7 @@ namespace NifOsg META_Object(NifOsg, Emitter) - virtual void emitParticles(double dt); + void emitParticles(double dt) override; void setShooter(osgParticle::Shooter* shooter); void setPlacer(osgParticle::Placer* placer); diff --git a/components/resource/bulletshapemanager.cpp b/components/resource/bulletshapemanager.cpp index 4193cd5b4..bcadf51c4 100644 --- a/components/resource/bulletshapemanager.cpp +++ b/components/resource/bulletshapemanager.cpp @@ -68,7 +68,7 @@ public: } - virtual void apply(osg::Drawable &drawable) + void apply(osg::Drawable &drawable) override { if (!mTriangleMesh) mTriangleMesh.reset(new btTriangleMesh); diff --git a/components/resource/bulletshapemanager.hpp b/components/resource/bulletshapemanager.hpp index 8ae2b531f..7b1289e45 100644 --- a/components/resource/bulletshapemanager.hpp +++ b/components/resource/bulletshapemanager.hpp @@ -40,11 +40,11 @@ namespace Resource osg::ref_ptr getInstance(const std::string& name); /// @see ResourceManager::updateCache - virtual void updateCache(double referenceTime); + void updateCache(double referenceTime) override; - virtual void clearCache(); + void clearCache() override; - void reportStats(unsigned int frameNumber, osg::Stats *stats) const; + void reportStats(unsigned int frameNumber, osg::Stats *stats) const override; private: osg::ref_ptr createInstance(const std::string& name); diff --git a/components/resource/imagemanager.hpp b/components/resource/imagemanager.hpp index 8eea4a70b..64954af54 100644 --- a/components/resource/imagemanager.hpp +++ b/components/resource/imagemanager.hpp @@ -32,7 +32,7 @@ namespace Resource osg::Image* getWarningImage(); - void reportStats(unsigned int frameNumber, osg::Stats* stats) const; + void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; private: osg::ref_ptr mWarningImage; diff --git a/components/resource/keyframemanager.hpp b/components/resource/keyframemanager.hpp index 3496342fa..fe1c4014e 100644 --- a/components/resource/keyframemanager.hpp +++ b/components/resource/keyframemanager.hpp @@ -23,7 +23,7 @@ namespace Resource /// @note Throws an exception if the resource is not found. osg::ref_ptr get(const std::string& name); - void reportStats(unsigned int frameNumber, osg::Stats* stats) const; + void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; }; } diff --git a/components/resource/niffilemanager.hpp b/components/resource/niffilemanager.hpp index c783bb7e0..d88aefd63 100644 --- a/components/resource/niffilemanager.hpp +++ b/components/resource/niffilemanager.hpp @@ -23,7 +23,7 @@ namespace Resource /// to be done in advance by other managers accessing the NifFileManager. Nif::NIFFilePtr get(const std::string& name); - void reportStats(unsigned int frameNumber, osg::Stats *stats) const; + void reportStats(unsigned int frameNumber, osg::Stats *stats) const override; }; } diff --git a/components/resource/resourcemanager.hpp b/components/resource/resourcemanager.hpp index a5ae27c6a..ccb065e3b 100644 --- a/components/resource/resourcemanager.hpp +++ b/components/resource/resourcemanager.hpp @@ -48,23 +48,23 @@ namespace Resource virtual ~GenericResourceManager() {} /// Clear cache entries that have not been referenced for longer than expiryDelay. - virtual void updateCache(double referenceTime) + void updateCache(double referenceTime) override { mCache->updateTimeStampOfObjectsInCacheWithExternalReferences(referenceTime); mCache->removeExpiredObjectsInCache(referenceTime - mExpiryDelay); } /// Clear all cache entries. - virtual void clearCache() { mCache->clear(); } + void clearCache() override { mCache->clear(); } /// How long to keep objects in cache after no longer being referenced. - void setExpiryDelay (double expiryDelay) { mExpiryDelay = expiryDelay; } + void setExpiryDelay (double expiryDelay) override { mExpiryDelay = expiryDelay; } const VFS::Manager* getVFS() const { return mVFS; } - virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const {} + void reportStats(unsigned int frameNumber, osg::Stats* stats) const override {} - virtual void releaseGLObjects(osg::State* state) { mCache->releaseGLObjects(state); } + void releaseGLObjects(osg::State* state) override { mCache->releaseGLObjects(state); } protected: const VFS::Manager* mVFS; diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index ca6c7c895..b87446351 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -40,7 +40,7 @@ namespace class InitWorldSpaceParticlesCallback : public osg::NodeCallback { public: - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { osgParticle::ParticleSystem* partsys = static_cast(node); @@ -91,7 +91,7 @@ namespace && partsys->getUserDataContainer()->getDescriptions()[0] == "worldspace"); } - void apply(osg::Drawable& drw) + void apply(osg::Drawable& drw) override { if (osgParticle::ParticleSystem* partsys = dynamic_cast(&drw)) { @@ -143,7 +143,7 @@ namespace Resource { } - virtual void visit(osg::Node& node, SceneUtil::Controller& ctrl) + void visit(osg::Node& node, SceneUtil::Controller& ctrl) override { if (NifOsg::FlipController* flipctrl = dynamic_cast(&ctrl)) { @@ -175,7 +175,7 @@ namespace Resource { } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { osg::StateSet* stateset = node.getStateSet(); if (stateset) @@ -316,7 +316,7 @@ namespace Resource { } - virtual osgDB::ReaderWriter::ReadResult readImage(const std::string& filename, const osgDB::Options* options) + osgDB::ReaderWriter::ReadResult readImage(const std::string& filename, const osgDB::Options* options) override { try { @@ -400,7 +400,7 @@ namespace Resource return it != reservedNames.end(); } - virtual bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Drawable* node,unsigned int option) const + bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Drawable* node,unsigned int option) const override { if (option & SceneUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS) { @@ -412,7 +412,7 @@ namespace Resource return (option & optimizer->getPermissibleOptimizationsForObject(node))!=0; } - virtual bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const + bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const override { if (node->getNumDescriptions()>0) return false; if (node->getDataVariance() == osg::Object::DYNAMIC) return false; diff --git a/components/resource/stats.cpp b/components/resource/stats.cpp index 147970add..942bd92d8 100644 --- a/components/resource/stats.cpp +++ b/components/resource/stats.cpp @@ -211,7 +211,7 @@ public: { } - virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const + void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const override { if (!mStats) return; diff --git a/components/resource/stats.hpp b/components/resource/stats.hpp index 8f04ee10d..9fa583cca 100644 --- a/components/resource/stats.hpp +++ b/components/resource/stats.hpp @@ -29,7 +29,7 @@ namespace Resource void setKey(int key) { _key = key; } int getKey() const { return _key; } - bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa); + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override; void setWindowSize(int w, int h); @@ -39,7 +39,7 @@ namespace Resource void setUpScene(osgViewer::ViewerBase* viewer); /** Get the keyboard and mouse usage of this manipulator.*/ - virtual void getUsage(osg::ApplicationUsage& usage) const; + void getUsage(osg::ApplicationUsage& usage) const override; private: osg::ref_ptr _switch; diff --git a/components/sceneutil/attach.cpp b/components/sceneutil/attach.cpp index 2a6ec84e5..597c7adf4 100644 --- a/components/sceneutil/attach.cpp +++ b/components/sceneutil/attach.cpp @@ -30,20 +30,20 @@ namespace SceneUtil mFilter2 = "tri " + mFilter; } - virtual void apply(osg::MatrixTransform& node) + void apply(osg::MatrixTransform& node) override { traverse(node); } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { traverse(node); } - virtual void apply(osg::Group& node) + void apply(osg::Group& node) override { traverse(node); } - virtual void apply(osg::Drawable& drawable) + void apply(osg::Drawable& drawable) override { if (!filterMatches(drawable.getName())) return; diff --git a/components/sceneutil/clone.hpp b/components/sceneutil/clone.hpp index 8c5fbd351..1cf00c9e5 100644 --- a/components/sceneutil/clone.hpp +++ b/components/sceneutil/clone.hpp @@ -27,8 +27,8 @@ namespace SceneUtil virtual osgParticle::ParticleSystem* operator() (const osgParticle::ParticleSystem* partsys) const; virtual osgParticle::ParticleProcessor* operator() (const osgParticle::ParticleProcessor* processor) const; - virtual osg::Node* operator() (const osg::Node* node) const; - virtual osg::Drawable* operator() (const osg::Drawable* drawable) const; + osg::Node* operator() (const osg::Node* node) const override; + osg::Drawable* operator() (const osg::Drawable* drawable) const override; private: // maps new pointers to their old pointers diff --git a/components/sceneutil/controller.hpp b/components/sceneutil/controller.hpp index d02b65cf1..2656d654e 100644 --- a/components/sceneutil/controller.hpp +++ b/components/sceneutil/controller.hpp @@ -18,7 +18,7 @@ namespace SceneUtil { public: FrameTimeSource(); - virtual float getValue(osg::NodeVisitor* nv); + float getValue(osg::NodeVisitor* nv) override; }; /// @note ControllerFunctions may be shared - you should not hold any state in it. That is why all its methods are declared const. @@ -63,12 +63,12 @@ namespace SceneUtil public: ControllerVisitor(); - virtual void apply(osg::Node& node); + void apply(osg::Node& node) override; // Technically not required as the default implementation would trickle down to apply(Node&) anyway, // but we'll shortcut instead to avoid the chain of virtual function calls - virtual void apply(osg::MatrixTransform& node); - virtual void apply(osg::Geometry& node); + void apply(osg::MatrixTransform& node) override; + void apply(osg::Geometry& node) override; void applyNode(osg::Node& node); @@ -83,7 +83,7 @@ namespace SceneUtil /// Assign the wanted ControllerSource. May be overridden in derived classes. /// By default assigns the ControllerSource passed to the constructor of this class if no ControllerSource is assigned to that controller yet. - virtual void visit(osg::Node& node, Controller& ctrl); + void visit(osg::Node& node, Controller& ctrl) override; private: std::shared_ptr mToAssign; @@ -95,7 +95,7 @@ namespace SceneUtil public: FindMaxControllerLengthVisitor(); - virtual void visit(osg::Node& , Controller& ctrl); + void visit(osg::Node& , Controller& ctrl) override; float getMaxLength() const; diff --git a/components/sceneutil/lightcontroller.hpp b/components/sceneutil/lightcontroller.hpp index 3292ae541..36b2e868e 100644 --- a/components/sceneutil/lightcontroller.hpp +++ b/components/sceneutil/lightcontroller.hpp @@ -26,7 +26,7 @@ namespace SceneUtil void setDiffuse(const osg::Vec4f& color); - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); + void operator()(osg::Node* node, osg::NodeVisitor* nv) override; private: LightType mType; diff --git a/components/sceneutil/lightmanager.cpp b/components/sceneutil/lightmanager.cpp index 415bdae3a..7f1be2eea 100644 --- a/components/sceneutil/lightmanager.cpp +++ b/components/sceneutil/lightmanager.cpp @@ -31,26 +31,26 @@ namespace SceneUtil LightStateAttribute(const LightStateAttribute& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osg::StateAttribute(copy,copyop), mIndex(copy.mIndex), mLights(copy.mLights) {} - unsigned int getMember() const + unsigned int getMember() const override { return mIndex; } - virtual bool getModeUsage(ModeUsage & usage) const + bool getModeUsage(ModeUsage & usage) const override { for (unsigned int i=0; i(node); lightManager->update(); @@ -295,30 +295,30 @@ namespace SceneUtil DisableLight(const DisableLight& copy,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osg::StateAttribute(copy,copyop), mIndex(copy.mIndex) {} - virtual osg::Object* cloneType() const { return new DisableLight(mIndex); } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new DisableLight(*this,copyop); } - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=nullptr; } - virtual const char* libraryName() const { return "SceneUtil"; } - virtual const char* className() const { return "DisableLight"; } - virtual Type getType() const { return LIGHT; } + osg::Object* cloneType() const override { return new DisableLight(mIndex); } + osg::Object* clone(const osg::CopyOp& copyop) const override { return new DisableLight(*this,copyop); } + bool isSameKindAs(const osg::Object* obj) const override { return dynamic_cast(obj)!=nullptr; } + const char* libraryName() const override { return "SceneUtil"; } + const char* className() const override { return "DisableLight"; } + Type getType() const override { return LIGHT; } - unsigned int getMember() const + unsigned int getMember() const override { return mIndex; } - virtual bool getModeUsage(ModeUsage & usage) const + bool getModeUsage(ModeUsage & usage) const override { usage.usesMode(GL_LIGHT0 + mIndex); return true; } - virtual int compare(const StateAttribute &sa) const + int compare(const StateAttribute &sa) const override { throw std::runtime_error("DisableLight::compare: unimplemented"); } - virtual void apply(osg::State& state) const + void apply(osg::State& state) const override { int lightNum = GL_LIGHT0 + mIndex; glLightfv( lightNum, GL_AMBIENT, mnullptr.ptr() ); diff --git a/components/sceneutil/lightmanager.hpp b/components/sceneutil/lightmanager.hpp index ea6c640c4..c370f1b7f 100644 --- a/components/sceneutil/lightmanager.hpp +++ b/components/sceneutil/lightmanager.hpp @@ -172,7 +172,7 @@ namespace SceneUtil META_Object(SceneUtil, LightListCallback) - void operator()(osg::Node* node, osg::NodeVisitor* nv); + void operator()(osg::Node* node, osg::NodeVisitor* nv) override; bool pushLightState(osg::Node* node, osgUtil::CullVisitor* nv); diff --git a/components/sceneutil/morphgeometry.hpp b/components/sceneutil/morphgeometry.hpp index ba3b40961..6c492ad15 100644 --- a/components/sceneutil/morphgeometry.hpp +++ b/components/sceneutil/morphgeometry.hpp @@ -22,7 +22,7 @@ namespace SceneUtil void setSourceGeometry(osg::ref_ptr sourceGeom); // Currently empty as this is difficult to implement. Technically we would need to compile both internal geometries in separate frames but this method is only called once. Alternatively we could compile just the static parts of the model. - virtual void compileGLObjects(osg::RenderInfo& renderInfo) const {} + void compileGLObjects(osg::RenderInfo& renderInfo) const override {} class MorphTarget { @@ -59,11 +59,11 @@ namespace SceneUtil osg::ref_ptr getSourceGeometry() const; - virtual void accept(osg::NodeVisitor &nv); - virtual bool supports(const osg::PrimitiveFunctor&) const { return true; } - virtual void accept(osg::PrimitiveFunctor&) const; + void accept(osg::NodeVisitor &nv) override; + bool supports(const osg::PrimitiveFunctor&) const override { return true; } + void accept(osg::PrimitiveFunctor&) const override; - virtual osg::BoundingBox computeBoundingBox() const; + osg::BoundingBox computeBoundingBox() const override; private: void cull(osg::NodeVisitor* nv); diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index dc22d4d80..8e5b2aa85 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -236,7 +236,7 @@ class VDSMCameraCullCallback : public osg::NodeCallback VDSMCameraCullCallback(MWShadowTechnique* vdsm, osg::Polytope& polytope); - virtual void operator()(osg::Node*, osg::NodeVisitor* nv); + void operator()(osg::Node*, osg::NodeVisitor* nv) override; osg::RefMatrix* getProjectionMatrix() { return _projectionMatrix.get(); } osgUtil::RenderStage* getRenderStage() { return _renderStage.get(); } @@ -3077,7 +3077,7 @@ class DoubleBufferCallback : public osg::Callback public: DoubleBufferCallback(osg::NodeList &children) : mChildren(children) {} - virtual bool run(osg::Object* node, osg::Object* visitor) override + bool run(osg::Object* node, osg::Object* visitor) override { // We can't use a static cast as NodeVisitor virtually inherits from Object osg::ref_ptr nodeVisitor = visitor->asNodeVisitor(); diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index bdfb44e46..23a8e009a 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -46,24 +46,24 @@ namespace SceneUtil { META_Object(SceneUtil, MWShadowTechnique); /** initialize the ShadowedScene and local cached data structures.*/ - virtual void init(); + void init() override; /** run the update traversal of the ShadowedScene and update any loca chached data structures.*/ - virtual void update(osg::NodeVisitor& nv); + void update(osg::NodeVisitor& nv) override; /** run the cull traversal of the ShadowedScene and set up the rendering for this ShadowTechnique.*/ - virtual void cull(osgUtil::CullVisitor& cv); + void cull(osgUtil::CullVisitor& cv) override; /** Resize any per context GLObject buffers to specified size. */ - virtual void resizeGLObjectBuffers(unsigned int maxSize); + void resizeGLObjectBuffers(unsigned int maxSize) override; /** If State is non-zero, this function releases any associated OpenGL objects for * the specified graphics context. Otherwise, releases OpenGL objects * for all graphics contexts. */ - virtual void releaseGLObjects(osg::State* = 0) const; + void releaseGLObjects(osg::State* = 0) const override; /** Clean scene graph from any shadow technique specific nodes, state and drawables.*/ - virtual void cleanSceneGraph(); + void cleanSceneGraph() override; virtual void enableShadows(); @@ -92,19 +92,19 @@ namespace SceneUtil { public: ComputeLightSpaceBounds(osg::Viewport* viewport, const osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix); - void apply(osg::Node& node); + void apply(osg::Node& node) override; - void apply(osg::Drawable& drawable); + void apply(osg::Drawable& drawable) override; void apply(Terrain::QuadTreeWorld& quadTreeWorld); - void apply(osg::Billboard&); + void apply(osg::Billboard&) override; - void apply(osg::Projection&); + void apply(osg::Projection&) override; - void apply(osg::Transform& transform); + void apply(osg::Transform& transform) override; - void apply(osg::Camera&); + void apply(osg::Camera&) override; using osg::NodeVisitor::apply; diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp index b9da2d1c8..b48ceda40 100644 --- a/components/sceneutil/optimizer.cpp +++ b/components/sceneutil/optimizer.cpp @@ -160,7 +160,7 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor setTraversalMode(osg::NodeVisitor::TRAVERSE_PARENTS); } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { if (node.getNumParents()) { @@ -173,7 +173,7 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor } } - virtual void apply(osg::LOD& lod) + void apply(osg::LOD& lod) override { _currentObjectList.push_back(&lod); @@ -182,23 +182,22 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor _currentObjectList.pop_back(); } - virtual void apply(osg::Transform& transform) + void apply(osg::Transform& transform) override { // for all current objects associated this transform with them. registerWithCurrentObjects(&transform); } - virtual void apply(osg::Geode& geode) + void apply(osg::Geode& geode) override { traverse(geode); } - virtual void apply(osg::Billboard& geode) + void apply(osg::Billboard& geode) override { traverse(geode); } - void collectDataFor(osg::Node* node) { _currentObjectList.push_back(node); @@ -1605,41 +1604,40 @@ class MergeArrayVisitor : public osg::ArrayVisitor lhs->insert(lhs->end(),rhs.begin(),rhs.end()); } - virtual void apply(osg::Array&) { OSG_WARN << "Warning: Optimizer's MergeArrayVisitor cannot merge Array type." << std::endl; } + void apply(osg::Array&) override { OSG_WARN << "Warning: Optimizer's MergeArrayVisitor cannot merge Array type." << std::endl; } + void apply(osg::ByteArray& rhs) override { _merge(rhs); } + void apply(osg::ShortArray& rhs) override { _merge(rhs); } + void apply(osg::IntArray& rhs) override { _merge(rhs); } + void apply(osg::UByteArray& rhs) override { _merge(rhs); } + void apply(osg::UShortArray& rhs) override { _merge(rhs); } + void apply(osg::UIntArray& rhs) override { _merge(rhs); } - virtual void apply(osg::ByteArray& rhs) { _merge(rhs); } - virtual void apply(osg::ShortArray& rhs) { _merge(rhs); } - virtual void apply(osg::IntArray& rhs) { _merge(rhs); } - virtual void apply(osg::UByteArray& rhs) { _merge(rhs); } - virtual void apply(osg::UShortArray& rhs) { _merge(rhs); } - virtual void apply(osg::UIntArray& rhs) { _merge(rhs); } + void apply(osg::Vec4ubArray& rhs) override { _merge(rhs); } + void apply(osg::Vec3ubArray& rhs) override{ _merge(rhs); } + void apply(osg::Vec2ubArray& rhs) override { _merge(rhs); } - virtual void apply(osg::Vec4ubArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3ubArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec2ubArray& rhs) { _merge(rhs); } + void apply(osg::Vec4usArray& rhs) override { _merge(rhs); } + void apply(osg::Vec3usArray& rhs) override { _merge(rhs); } + void apply(osg::Vec2usArray& rhs) override { _merge(rhs); } - virtual void apply(osg::Vec4usArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3usArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec2usArray& rhs) { _merge(rhs); } + void apply(osg::FloatArray& rhs) override { _merge(rhs); } + void apply(osg::Vec2Array& rhs) override { _merge(rhs); } + void apply(osg::Vec3Array& rhs) override { _merge(rhs); } + void apply(osg::Vec4Array& rhs) override { _merge(rhs); } - virtual void apply(osg::FloatArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec2Array& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3Array& rhs) { _merge(rhs); } - virtual void apply(osg::Vec4Array& rhs) { _merge(rhs); } + void apply(osg::DoubleArray& rhs) override { _merge(rhs); } + void apply(osg::Vec2dArray& rhs) override { _merge(rhs); } + void apply(osg::Vec3dArray& rhs) override { _merge(rhs); } + void apply(osg::Vec4dArray& rhs) override { _merge(rhs); } - virtual void apply(osg::DoubleArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec2dArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3dArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec4dArray& rhs) { _merge(rhs); } + void apply(osg::Vec2bArray& rhs) override { _merge(rhs); } + void apply(osg::Vec3bArray& rhs) override { _merge(rhs); } + void apply(osg::Vec4bArray& rhs) override { _merge(rhs); } - virtual void apply(osg::Vec2bArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3bArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec4bArray& rhs) { _merge(rhs); } - - virtual void apply(osg::Vec2sArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3sArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec4sArray& rhs) { _merge(rhs); } + void apply(osg::Vec2sArray& rhs) override { _merge(rhs); } + void apply(osg::Vec3sArray& rhs) override { _merge(rhs); } + void apply(osg::Vec4sArray& rhs) override { _merge(rhs); } }; bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geometry& rhs) diff --git a/components/sceneutil/optimizer.hpp b/components/sceneutil/optimizer.hpp index d7c83e898..2d6293e23 100644 --- a/components/sceneutil/optimizer.hpp +++ b/components/sceneutil/optimizer.hpp @@ -273,10 +273,10 @@ class Optimizer FlattenStaticTransformsVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, FLATTEN_STATIC_TRANSFORMS) {} - virtual void apply(osg::Node& geode); - virtual void apply(osg::Drawable& drawable); - virtual void apply(osg::Billboard& geode); - virtual void apply(osg::Transform& transform); + void apply(osg::Node& geode) override; + void apply(osg::Drawable& drawable) override; + void apply(osg::Billboard& geode) override; + void apply(osg::Transform& transform) override; bool removeTransforms(osg::Node* nodeWeCannotRemove); @@ -304,7 +304,7 @@ class Optimizer CombineStaticTransformsVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, FLATTEN_STATIC_TRANSFORMS) {} - virtual void apply(osg::MatrixTransform& transform); + void apply(osg::MatrixTransform& transform) override; bool removeTransforms(osg::Node* nodeWeCannotRemove); @@ -326,7 +326,7 @@ class Optimizer RemoveEmptyNodesVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {} - virtual void apply(osg::Group& group); + void apply(osg::Group& group) override; void removeEmptyNodes(); @@ -343,10 +343,10 @@ class Optimizer RemoveRedundantNodesVisitor(Optimizer* optimizer=0): BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {} - virtual void apply(osg::Group& group); - virtual void apply(osg::Transform& transform); - virtual void apply(osg::LOD& lod); - virtual void apply(osg::Switch& switchNode); + void apply(osg::Group& group) override; + void apply(osg::Transform& transform) override; + void apply(osg::LOD& lod) override; + void apply(osg::Switch& switchNode) override; bool isOperationPermissible(osg::Node& node); @@ -365,9 +365,9 @@ class Optimizer bool isOperationPermissible(osg::Group& node); - virtual void apply(osg::Group& group); - virtual void apply(osg::LOD& lod); - virtual void apply(osg::Switch& switchNode); + void apply(osg::Group& group) override; + void apply(osg::LOD& lod) override; + void apply(osg::Switch& switchNode) override; }; class MergeGeometryVisitor : public BaseOptimizerVisitor @@ -402,8 +402,8 @@ class Optimizer void popStateSet(); void checkAlphaBlendingActive(); - virtual void apply(osg::Group& group); - virtual void apply(osg::Billboard&) { /* don't do anything*/ } + void apply(osg::Group& group) override; + void apply(osg::Billboard&) override { /* don't do anything*/ } bool mergeGroup(osg::Group& group); diff --git a/components/sceneutil/positionattitudetransform.hpp b/components/sceneutil/positionattitudetransform.hpp index b6f92ee84..9513c0e36 100644 --- a/components/sceneutil/positionattitudetransform.hpp +++ b/components/sceneutil/positionattitudetransform.hpp @@ -25,22 +25,17 @@ class PositionAttitudeTransform : public osg::Transform inline void setPosition(const osg::Vec3f& pos) { _position = pos; dirtyBound(); } inline const osg::Vec3f& getPosition() const { return _position; } - inline void setAttitude(const osg::Quat& quat) { _attitude = quat; dirtyBound(); } inline const osg::Quat& getAttitude() const { return _attitude; } - inline void setScale(const osg::Vec3f& scale) { _scale = scale; dirtyBound(); } inline const osg::Vec3f& getScale() const { return _scale; } - - - virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const; - virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const; + bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const override; + bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const override; protected : - virtual ~PositionAttitudeTransform() {} osg::Vec3f _position; diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 801c172b3..e01583399 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -23,7 +23,7 @@ namespace SceneUtil META_Object(SceneUtil, RigGeometry) // Currently empty as this is difficult to implement. Technically we would need to compile both internal geometries in separate frames but this method is only called once. Alternatively we could compile just the static parts of the model. - virtual void compileGLObjects(osg::RenderInfo& renderInfo) const {} + void compileGLObjects(osg::RenderInfo& renderInfo) const override {} struct BoneInfluence { @@ -46,22 +46,22 @@ namespace SceneUtil osg::ref_ptr getSourceGeometry() const; - virtual void accept(osg::NodeVisitor &nv); - virtual bool supports(const osg::PrimitiveFunctor&) const { return true; } - virtual void accept(osg::PrimitiveFunctor&) const; + void accept(osg::NodeVisitor &nv) override; + bool supports(const osg::PrimitiveFunctor&) const override{ return true; } + void accept(osg::PrimitiveFunctor&) const override; struct CopyBoundingBoxCallback : osg::Drawable::ComputeBoundingBoxCallback { osg::BoundingBox boundingBox; - virtual osg::BoundingBox computeBound(const osg::Drawable&) const override { return boundingBox; } + osg::BoundingBox computeBound(const osg::Drawable&) const override { return boundingBox; } }; struct CopyBoundingSphereCallback : osg::Node::ComputeBoundingSphereCallback { osg::BoundingSphere boundingSphere; - virtual osg::BoundingSphere computeBound(const osg::Node&) const override { return boundingSphere; } + osg::BoundingSphere computeBound(const osg::Node&) const override { return boundingSphere; } }; private: diff --git a/components/sceneutil/skeleton.cpp b/components/sceneutil/skeleton.cpp index 9be440d93..40f524e0a 100644 --- a/components/sceneutil/skeleton.cpp +++ b/components/sceneutil/skeleton.cpp @@ -18,7 +18,7 @@ public: { } - void apply(osg::Transform &node) + void apply(osg::Transform &node) override { osg::MatrixTransform* bone = node.asMatrixTransform(); if (!bone) diff --git a/components/sceneutil/skeleton.hpp b/components/sceneutil/skeleton.hpp index 1d8069f8e..22988dfd5 100644 --- a/components/sceneutil/skeleton.hpp +++ b/components/sceneutil/skeleton.hpp @@ -60,12 +60,12 @@ namespace SceneUtil bool getActive() const; - void traverse(osg::NodeVisitor& nv); + void traverse(osg::NodeVisitor& nv) override; void markDirty(); - virtual void childInserted(unsigned int); - virtual void childRemoved(unsigned int, unsigned int); + void childInserted(unsigned int) override; + void childRemoved(unsigned int, unsigned int) override; private: // The root bone is not a "real" bone, it has no corresponding node in the scene graph. diff --git a/components/sceneutil/statesetupdater.hpp b/components/sceneutil/statesetupdater.hpp index d12316fb2..25e50acfd 100644 --- a/components/sceneutil/statesetupdater.hpp +++ b/components/sceneutil/statesetupdater.hpp @@ -24,7 +24,7 @@ namespace SceneUtil META_Object(SceneUtil, StateSetUpdater) - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); + void operator()(osg::Node* node, osg::NodeVisitor* nv) override; /// Apply state - to override in derived classes /// @note Due to the double buffering approach you *have* to apply all state @@ -57,11 +57,11 @@ namespace SceneUtil void addController(StateSetUpdater* ctrl); - virtual void apply(osg::StateSet* stateset, osg::NodeVisitor* nv); + void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override; protected: - virtual void setDefaults(osg::StateSet *stateset); + void setDefaults(osg::StateSet *stateset) override; std::vector > mCtrls; }; diff --git a/components/sceneutil/unrefqueue.hpp b/components/sceneutil/unrefqueue.hpp index 7155e669c..84372d28c 100644 --- a/components/sceneutil/unrefqueue.hpp +++ b/components/sceneutil/unrefqueue.hpp @@ -16,7 +16,7 @@ namespace SceneUtil { public: std::deque > mObjects; - virtual void doWork(); + void doWork() override; }; /// @brief Handles unreferencing of objects through the WorkQueue. Typical use scenario diff --git a/components/sceneutil/util.cpp b/components/sceneutil/util.cpp index ff46329e5..a23f3f109 100644 --- a/components/sceneutil/util.cpp +++ b/components/sceneutil/util.cpp @@ -24,7 +24,7 @@ public: { } - virtual void apply(osg::Node& node) + void apply(osg::Node& node) override { if (osg::StateSet* stateset = node.getStateSet()) mLowestUnusedTexUnit = std::max(mLowestUnusedTexUnit, int(stateset->getTextureAttributeList().size())); diff --git a/components/sceneutil/util.hpp b/components/sceneutil/util.hpp index 5cc8e3a9d..303d609f5 100644 --- a/components/sceneutil/util.hpp +++ b/components/sceneutil/util.hpp @@ -19,10 +19,10 @@ namespace SceneUtil GlowUpdater(int texUnit, const osg::Vec4f& color, const std::vector >& textures, osg::Node* node, float duration, Resource::ResourceSystem* resourcesystem); - virtual void setDefaults(osg::StateSet *stateset); + void setDefaults(osg::StateSet *stateset) override; void removeTexture(osg::StateSet* stateset); - virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv); + void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override; bool isPermanentGlowUpdater(); diff --git a/components/sceneutil/visitor.hpp b/components/sceneutil/visitor.hpp index 02a351da7..5e041dc45 100644 --- a/components/sceneutil/visitor.hpp +++ b/components/sceneutil/visitor.hpp @@ -20,9 +20,9 @@ namespace SceneUtil { } - virtual void apply(osg::Group& group); - virtual void apply(osg::MatrixTransform& node); - virtual void apply(osg::Geometry& node); + void apply(osg::Group& group) override; + void apply(osg::MatrixTransform& node) override; + void apply(osg::Geometry& node) override; bool checkGroup(osg::Group& group); @@ -39,7 +39,7 @@ namespace SceneUtil { } - virtual void apply(osg::Node &node); + void apply(osg::Node &node) override; std::string mNameToFind; std::vector mFoundNodes; @@ -54,9 +54,9 @@ namespace SceneUtil { } - virtual void apply(osg::MatrixTransform& node); + void apply(osg::MatrixTransform& node) override; - virtual void apply(osg::Drawable& drw); + void apply(osg::Drawable& drw) override; }; /// Maps names to nodes @@ -71,7 +71,7 @@ namespace SceneUtil { } - void apply(osg::MatrixTransform& trans); + void apply(osg::MatrixTransform& trans) override; private: NodeMap& mMap; @@ -100,10 +100,10 @@ namespace SceneUtil class CleanObjectRootVisitor : public RemoveVisitor { public: - virtual void apply(osg::Drawable& drw); - virtual void apply(osg::Group& node); - virtual void apply(osg::MatrixTransform& node); - virtual void apply(osg::Node& node); + void apply(osg::Drawable& drw) override; + void apply(osg::Group& node) override; + void apply(osg::MatrixTransform& node) override; + void apply(osg::Node& node) override; void applyNode(osg::Node& node); void applyDrawable(osg::Node& node); @@ -112,9 +112,9 @@ namespace SceneUtil class RemoveTriBipVisitor : public RemoveVisitor { public: - virtual void apply(osg::Drawable& drw); - virtual void apply(osg::Group& node); - virtual void apply(osg::MatrixTransform& node); + void apply(osg::Drawable& drw) override; + void apply(osg::Group& node) override; + void apply(osg::MatrixTransform& node) override; void applyImpl(osg::Node& node); }; diff --git a/components/sceneutil/waterutil.cpp b/components/sceneutil/waterutil.cpp index 3a17963af..8a434105c 100644 --- a/components/sceneutil/waterutil.cpp +++ b/components/sceneutil/waterutil.cpp @@ -10,7 +10,7 @@ namespace SceneUtil // disable nonsense test against a worldsize bb what will always pass class WaterBoundCallback : public osg::Drawable::ComputeBoundingBoxCallback { - virtual osg::BoundingBox computeBound(const osg::Drawable&) const { return osg::BoundingBox(); } + osg::BoundingBox computeBound(const osg::Drawable&) const override { return osg::BoundingBox(); } }; osg::ref_ptr createWaterGeometry(float size, int segments, float textureRepeats) diff --git a/components/sdlutil/sdlgraphicswindow.hpp b/components/sdlutil/sdlgraphicswindow.hpp index dd8076776..01a97e754 100644 --- a/components/sdlutil/sdlgraphicswindow.hpp +++ b/components/sdlutil/sdlgraphicswindow.hpp @@ -24,53 +24,53 @@ class GraphicsWindowSDL2 : public osgViewer::GraphicsWindow public: GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits); - virtual bool isSameKindAs(const Object* object) const { return dynamic_cast(object)!=0; } - virtual const char* libraryName() const { return "osgViewer"; } - virtual const char* className() const { return "GraphicsWindowSDL2"; } + bool isSameKindAs(const Object* object) const override { return dynamic_cast(object)!=0; } + const char* libraryName() const override { return "osgViewer"; } + const char* className() const override { return "GraphicsWindowSDL2"; } - virtual bool valid() const { return mValid; } + bool valid() const override { return mValid; } /** Realise the GraphicsContext.*/ - virtual bool realizeImplementation(); + bool realizeImplementation()override ; /** Return true if the graphics context has been realised and is ready to use.*/ - virtual bool isRealizedImplementation() const { return mRealized; } + bool isRealizedImplementation() const override { return mRealized; } /** Close the graphics context.*/ - virtual void closeImplementation(); + void closeImplementation() override; /** Make this graphics context current.*/ - virtual bool makeCurrentImplementation(); + bool makeCurrentImplementation() override; /** Release the graphics context.*/ - virtual bool releaseContextImplementation(); + bool releaseContextImplementation() override; /** Swap the front and back buffers.*/ - virtual void swapBuffersImplementation(); + void swapBuffersImplementation() override; /** Set sync-to-vblank. */ - virtual void setSyncToVBlank(bool on); + void setSyncToVBlank(bool on) override; /** Set Window decoration.*/ - virtual bool setWindowDecorationImplementation(bool flag); + bool setWindowDecorationImplementation(bool flag) override; /** Raise specified window */ - virtual void raiseWindow(); + void raiseWindow() override; /** Set the window's position and size.*/ - virtual bool setWindowRectangleImplementation(int x, int y, int width, int height); + bool setWindowRectangleImplementation(int x, int y, int width, int height) override; /** Set the name of the window */ - virtual void setWindowName(const std::string &name); + void setWindowName(const std::string &name) override; /** Set mouse cursor to a specific shape.*/ - virtual void setCursor(MouseCursor cursor); + void setCursor(MouseCursor cursor) override; /** Get focus.*/ - virtual void grabFocus() {} + void grabFocus() override {} /** Get focus on if the pointer is in this window.*/ - virtual void grabFocusIfPointerInWindow() {} + void grabFocusIfPointerInWindow() override {} /** WindowData is used to pass in the SDL2 window handle attached to the GraphicsContext::Traits structure. */ struct WindowData : public osg::Referenced diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index 8e35f1d9c..bf1022180 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -38,10 +38,10 @@ namespace Shader void setSpecularMapPattern(const std::string& pattern); - virtual void apply(osg::Node& node); + void apply(osg::Node& node) override; - virtual void apply(osg::Drawable& drawable); - virtual void apply(osg::Geometry& geometry); + void apply(osg::Drawable& drawable) override; + void apply(osg::Geometry& geometry) override; void applyStateSet(osg::ref_ptr stateset, osg::Node& node); diff --git a/components/terrain/chunkmanager.hpp b/components/terrain/chunkmanager.hpp index 02a782c62..118df698f 100644 --- a/components/terrain/chunkmanager.hpp +++ b/components/terrain/chunkmanager.hpp @@ -42,7 +42,7 @@ namespace Terrain void setMaxCompositeGeometrySize(float maxCompGeometrySize) { mMaxCompGeometrySize = maxCompGeometrySize; } void setNodeMask(unsigned int mask) { mNodeMask = mask; } - virtual unsigned int getNodeMask() override { return mNodeMask; } + unsigned int getNodeMask() override { return mNodeMask; } void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; diff --git a/components/terrain/compositemaprenderer.hpp b/components/terrain/compositemaprenderer.hpp index 9d5719c23..257173af4 100644 --- a/components/terrain/compositemaprenderer.hpp +++ b/components/terrain/compositemaprenderer.hpp @@ -41,7 +41,7 @@ namespace Terrain CompositeMapRenderer(); ~CompositeMapRenderer(); - virtual void drawImplementation(osg::RenderInfo& renderInfo) const; + void drawImplementation(osg::RenderInfo& renderInfo) const override; void compile(CompositeMap& compositeMap, osg::RenderInfo& renderInfo, double* timeLeft) const; diff --git a/components/terrain/quadtreenode.hpp b/components/terrain/quadtreenode.hpp index a309d91fc..7ae59b92f 100644 --- a/components/terrain/quadtreenode.hpp +++ b/components/terrain/quadtreenode.hpp @@ -42,7 +42,7 @@ namespace Terrain inline QuadTreeNode* getParent() { return mParent; } inline QuadTreeNode* getChild(unsigned int i) { return static_cast(Group::getChild(i)); } - inline unsigned int getNumChildren() const { return _children.size(); } + inline unsigned int getNumChildren() const override { return _children.size(); } // osg::Group::addChild() does a lot of unrelated stuff, but we just really want to add a child node. void addChildNode(QuadTreeNode* child) diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index ca1dcb08c..57c09000c 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -61,7 +61,7 @@ public: { } - virtual ReturnValue isSufficientDetail(QuadTreeNode* node, float dist) + ReturnValue isSufficientDetail(QuadTreeNode* node, float dist) override { const osg::Vec2f& center = node->getCenter(); bool activeGrid = (center.x() > mActiveGrid.x() && center.y() > mActiveGrid.y() && center.x() < mActiveGrid.z() && center.y() < mActiveGrid.w()); @@ -106,7 +106,7 @@ public: mWorld = world; } - virtual void accept(osg::NodeVisitor &nv) + void accept(osg::NodeVisitor &nv) override { if (!nv.validNodeMask(*this)) return; diff --git a/components/terrain/terraindrawable.hpp b/components/terrain/terraindrawable.hpp index a84200f66..dbfdd3c80 100644 --- a/components/terrain/terraindrawable.hpp +++ b/components/terrain/terraindrawable.hpp @@ -30,17 +30,17 @@ namespace Terrain class TerrainDrawable : public osg::Geometry { public: - virtual osg::Object* cloneType() const { return new TerrainDrawable (); } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new TerrainDrawable (*this,copyop); } - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=nullptr; } - virtual const char* className() const { return "TerrainDrawable"; } - virtual const char* libraryName() const { return "Terrain"; } + osg::Object* cloneType() const override { return new TerrainDrawable (); } + osg::Object* clone(const osg::CopyOp& copyop) const override { return new TerrainDrawable (*this,copyop); } + bool isSameKindAs(const osg::Object* obj) const override { return dynamic_cast(obj)!=nullptr; } + const char* className() const override { return "TerrainDrawable"; } + const char* libraryName() const override { return "Terrain"; } TerrainDrawable(); ~TerrainDrawable(); // has to be defined in the cpp file because we only forward declared some members. TerrainDrawable(const TerrainDrawable& copy, const osg::CopyOp& copyop); - virtual void accept(osg::NodeVisitor &nv); + void accept(osg::NodeVisitor &nv) override; void cull(osgUtil::CullVisitor* cv); typedef std::vector > PassVector; @@ -50,7 +50,7 @@ namespace Terrain void createClusterCullingCallback(); - virtual void compileGLObjects(osg::RenderInfo& renderInfo) const; + void compileGLObjects(osg::RenderInfo& renderInfo) const override; void setupWaterBoundingBox(float waterheight, float margin); const osg::BoundingBox& getWaterBoundingBox() const { return mWaterBoundingBox; } diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index 5f99cd97e..679597971 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -17,7 +17,7 @@ class MyView : public View public: osg::ref_ptr mLoaded; - virtual void reset() {} + void reset() override {} }; TerrainGrid::TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask, int borderMask) diff --git a/components/terrain/terraingrid.hpp b/components/terrain/terraingrid.hpp index 8b36448c1..f8b0fb259 100644 --- a/components/terrain/terraingrid.hpp +++ b/components/terrain/terraingrid.hpp @@ -17,15 +17,15 @@ namespace Terrain TerrainGrid(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSystem* resourceSystem, Storage* storage, int nodeMask, int preCompileMask=~0, int borderMask=0); ~TerrainGrid(); - virtual void cacheCell(View* view, int x, int y); + void cacheCell(View* view, int x, int y) override; /// @note Not thread safe. - virtual void loadCell(int x, int y); + void loadCell(int x, int y) override; /// @note Not thread safe. - virtual void unloadCell(int x, int y); + void unloadCell(int x, int y) override; - View* createView(); + View* createView() override; protected: bool isGridEmpty() const { return mGrid.empty(); } diff --git a/components/terrain/texturemanager.hpp b/components/terrain/texturemanager.hpp index e1205606e..46c363055 100644 --- a/components/terrain/texturemanager.hpp +++ b/components/terrain/texturemanager.hpp @@ -27,7 +27,7 @@ namespace Terrain osg::ref_ptr getTexture(const std::string& name); - virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const; + void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; private: Resource::SceneManager* mSceneManager; diff --git a/components/terrain/viewdata.hpp b/components/terrain/viewdata.hpp index 400d9fbbe..028935258 100644 --- a/components/terrain/viewdata.hpp +++ b/components/terrain/viewdata.hpp @@ -21,7 +21,7 @@ namespace Terrain void add(QuadTreeNode* node); - void reset(); + void reset() override; bool suitableToUse(const osg::Vec4i& activeGrid) const; diff --git a/components/terrain/world.hpp b/components/terrain/world.hpp index 9f08454c8..d94125100 100644 --- a/components/terrain/world.hpp +++ b/components/terrain/world.hpp @@ -70,7 +70,7 @@ namespace Terrain return mMask; } - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { if (mLowZ <= mHighZ) traverse(node, nv); diff --git a/components/vfs/bsaarchive.hpp b/components/vfs/bsaarchive.hpp index a87f278c7..65a9db16c 100644 --- a/components/vfs/bsaarchive.hpp +++ b/components/vfs/bsaarchive.hpp @@ -12,7 +12,7 @@ namespace VFS public: BsaArchiveFile(const Bsa::BSAFile::FileStruct* info, Bsa::BSAFile* bsa); - virtual Files::IStreamPtr open(); + Files::IStreamPtr open() override; const Bsa::BSAFile::FileStruct* mInfo; Bsa::BSAFile* mFile; @@ -23,7 +23,7 @@ namespace VFS public: BsaArchive(const std::string& filename); virtual ~BsaArchive(); - virtual void listResources(std::map& out, char (*normalize_function) (char)); + void listResources(std::map& out, char (*normalize_function) (char)) override; private: std::unique_ptr mFile; diff --git a/components/vfs/filesystemarchive.hpp b/components/vfs/filesystemarchive.hpp index 6c8e1b82b..d228ba87c 100644 --- a/components/vfs/filesystemarchive.hpp +++ b/components/vfs/filesystemarchive.hpp @@ -11,7 +11,7 @@ namespace VFS public: FileSystemArchiveFile(const std::string& path); - virtual Files::IStreamPtr open(); + Files::IStreamPtr open() override; private: std::string mPath; @@ -23,7 +23,7 @@ namespace VFS public: FileSystemArchive(const std::string& path); - virtual void listResources(std::map& out, char (*normalize_function) (char)); + void listResources(std::map& out, char (*normalize_function) (char)) override; private: diff --git a/components/widgets/fontwrapper.hpp b/components/widgets/fontwrapper.hpp index 8b0011dda..daa69f920 100644 --- a/components/widgets/fontwrapper.hpp +++ b/components/widgets/fontwrapper.hpp @@ -11,14 +11,14 @@ namespace Gui class FontWrapper : public T { public: - virtual void setFontName(const std::string& name) + void setFontName(const std::string& name) override { T::setFontName(name); T::setPropertyOverride ("FontHeight", getFontSize()); } protected: - virtual void setPropertyOverride(const std::string& _key, const std::string& _value) + void setPropertyOverride(const std::string& _key, const std::string& _value) override { T::setPropertyOverride (_key, _value); diff --git a/extern/oics/tinyxml.h b/extern/oics/tinyxml.h index 7237825c5..7b5daedf9 100644 --- a/extern/oics/tinyxml.h +++ b/extern/oics/tinyxml.h @@ -865,10 +865,11 @@ public: /* Attribute parsing starts: first letter of the name returns: the next char after the value end quote */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override; // Prints this Attribute to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const { + void Print( FILE* cfile, int depth ) const override + { Print( cfile, depth, 0 ); } void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; @@ -1112,21 +1113,21 @@ public: const char* GetText() const; /// Creates a new Element and returns it - the returned element is a copy. - virtual TiXmlNode* Clone() const; + TiXmlNode* Clone() const override; // Print the Element to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; + void Print( FILE* cfile, int depth ) const override; /* Attribtue parsing starts: next char past '<' returns: next char past '>' */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override; - virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + const TiXmlElement* ToElement() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlElement* ToElement() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ - virtual bool Accept( TiXmlVisitor* visitor ) const; + bool Accept( TiXmlVisitor* visitor ) const override; protected: @@ -1135,7 +1136,7 @@ protected: // Used to be public [internal use] #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override; #endif /* [internal use] Reads the "value" of the element -- another element, or text. @@ -1166,28 +1167,28 @@ public: virtual ~TiXmlComment() {} /// Returns a copy of this Comment. - virtual TiXmlNode* Clone() const; + TiXmlNode* Clone() const override; // Write this Comment to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; + void Print( FILE* cfile, int depth ) const override; /* Attribtue parsing starts: at the ! of the !-- returns: next char past '>' */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override; - virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + const TiXmlComment* ToComment() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlComment* ToComment() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ - virtual bool Accept( TiXmlVisitor* visitor ) const; + bool Accept( TiXmlVisitor* visitor ) const override; protected: void CopyTo( TiXmlComment* target ) const; // used to be public #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override; #endif // virtual void StreamOut( TIXML_OSTREAM * out ) const; @@ -1229,31 +1230,31 @@ public: void operator=( const TiXmlText& base ) { base.CopyTo( this ); } // Write this text object to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; + void Print( FILE* cfile, int depth ) const override; /// Queries whether this represents text using a CDATA section. bool CDATA() const { return cdata; } /// Turns on or off a CDATA representation of text. void SetCDATA( bool _cdata ) { cdata = _cdata; } - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override; - virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + const TiXmlText* ToText() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlText* ToText() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ - virtual bool Accept( TiXmlVisitor* content ) const; + bool Accept( TiXmlVisitor* content ) const override; protected : /// [internal use] Creates a new Element and returns it. - virtual TiXmlNode* Clone() const; + TiXmlNode* Clone() const override; void CopyTo( TiXmlText* target ) const; bool Blank() const; // returns true if all white space and new lines // [internal use] #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override; #endif private: @@ -1305,27 +1306,28 @@ public: const char *Standalone() const { return standalone.c_str (); } /// Creates a copy of this Declaration and returns it. - virtual TiXmlNode* Clone() const; + TiXmlNode* Clone() const override; // Print this declaration to a FILE stream. virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - virtual void Print( FILE* cfile, int depth ) const { + void Print( FILE* cfile, int depth ) const override + { Print( cfile, depth, 0 ); } - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override; - virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + const TiXmlDeclaration* ToDeclaration() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlDeclaration* ToDeclaration()override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ - virtual bool Accept( TiXmlVisitor* visitor ) const; + bool Accept( TiXmlVisitor* visitor ) const override; protected: void CopyTo( TiXmlDeclaration* target ) const; // used to be public #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override; #endif private: @@ -1353,24 +1355,24 @@ public: void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } /// Creates a copy of this Unknown and returns it. - virtual TiXmlNode* Clone() const; + TiXmlNode* Clone() const override; // Print this Unknown to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; + void Print( FILE* cfile, int depth ) const override; - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override; - virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + const TiXmlUnknown* ToUnknown() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlUnknown* ToUnknown()override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ - virtual bool Accept( TiXmlVisitor* content ) const; + bool Accept( TiXmlVisitor* content ) const override; protected: void CopyTo( TiXmlUnknown* target ) const; #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override; #endif private: @@ -1439,7 +1441,7 @@ public: method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml to use that encoding, regardless of what TinyXml might otherwise try to detect. */ - virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) override; /** Get the root element -- the only top level element -- of the document. In well formed XML, there should only be one. TinyXml is tolerant of @@ -1521,22 +1523,22 @@ public: //char* PrintToMemory() const; /// Print this Document to a FILE stream. - virtual void Print( FILE* cfile, int depth = 0 ) const; + void Print( FILE* cfile, int depth = 0 ) const override; // [internal use] void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + const TiXmlDocument* ToDocument() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + TiXmlDocument* ToDocument() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ - virtual bool Accept( TiXmlVisitor* content ) const; + bool Accept( TiXmlVisitor* content ) const override; protected : // [internal use] - virtual TiXmlNode* Clone() const; + TiXmlNode* Clone() const override; #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override; #endif private: @@ -1736,16 +1738,16 @@ public: TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), buffer(), indent( " " ), lineBreak( "\n" ) {} - virtual bool VisitEnter( const TiXmlDocument& doc ); - virtual bool VisitExit( const TiXmlDocument& doc ); + bool VisitEnter( const TiXmlDocument& doc ) override; + bool VisitExit( const TiXmlDocument& doc ) override; - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); - virtual bool VisitExit( const TiXmlElement& element ); + bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) override; + bool VisitExit( const TiXmlElement& element ) override; - virtual bool Visit( const TiXmlDeclaration& declaration ); - virtual bool Visit( const TiXmlText& text ); - virtual bool Visit( const TiXmlComment& comment ); - virtual bool Visit( const TiXmlUnknown& unknown ); + bool Visit( const TiXmlDeclaration& declaration ) override; + bool Visit( const TiXmlText& text ) override; + bool Visit( const TiXmlComment& comment ) override; + bool Visit( const TiXmlUnknown& unknown ) override; /** Set the indent characters for printing. By default 4 spaces but tab (\t) is also useful, or null/empty string for no indentation. diff --git a/extern/osgQt/GraphicsWindowQt b/extern/osgQt/GraphicsWindowQt index 5b1e53734..18fcb754f 100644 --- a/extern/osgQt/GraphicsWindowQt +++ b/extern/osgQt/GraphicsWindowQt @@ -84,10 +84,10 @@ protected: qreal _devicePixelRatio; - virtual void resizeEvent( QResizeEvent* event ); - virtual void moveEvent( QMoveEvent* event ); - virtual void glDraw(); - virtual bool event( QEvent* event ); + void resizeEvent( QResizeEvent* event ) override; + void moveEvent( QMoveEvent* event ) override; + void glDraw() override; + bool event( QEvent* event ) override; }; class GraphicsWindowQt : public osgViewer::GraphicsWindow @@ -118,28 +118,28 @@ public: static void qglFormat2traits( const QGLFormat& format, osg::GraphicsContext::Traits* traits ); static osg::GraphicsContext::Traits* createTraits( const QGLWidget* widget ); - virtual bool setWindowRectangleImplementation( int x, int y, int width, int height ); - virtual void getWindowRectangle( int& x, int& y, int& width, int& height ); - virtual bool setWindowDecorationImplementation( bool windowDecoration ); - virtual bool getWindowDecoration() const; - virtual void grabFocus(); - virtual void grabFocusIfPointerInWindow(); - virtual void raiseWindow(); - virtual void setWindowName( const std::string& name ); - virtual std::string getWindowName(); - virtual void useCursor( bool cursorOn ); - virtual void setCursor( MouseCursor cursor ); + bool setWindowRectangleImplementation( int x, int y, int width, int height ) override; + void getWindowRectangle( int& x, int& y, int& width, int& height ) override; + bool setWindowDecorationImplementation( bool windowDecoration ) override; + bool getWindowDecoration() const override; + void grabFocus() override; + void grabFocusIfPointerInWindow( )override; + void raiseWindow() override; + void setWindowName( const std::string& name ) override; + std::string getWindowName() override; + void useCursor( bool cursorOn ) override; + void setCursor( MouseCursor cursor ) override; - virtual bool valid() const; - virtual bool realizeImplementation(); - virtual bool isRealizedImplementation() const; - virtual void closeImplementation(); - virtual bool makeCurrentImplementation(); - virtual bool releaseContextImplementation(); - virtual void swapBuffersImplementation(); - virtual void runOperations(); + bool valid() const override; + bool realizeImplementation() override; + bool isRealizedImplementation() const override; + void closeImplementation() override; + bool makeCurrentImplementation() override; + bool releaseContextImplementation() override; + void swapBuffersImplementation() override; + void runOperations() override; - virtual void requestWarpPointer( float x, float y ); + void requestWarpPointer( float x, float y ) override; protected: diff --git a/extern/osgQt/GraphicsWindowQt.cpp b/extern/osgQt/GraphicsWindowQt.cpp index 784cf9179..4755ad4a8 100644 --- a/extern/osgQt/GraphicsWindowQt.cpp +++ b/extern/osgQt/GraphicsWindowQt.cpp @@ -564,7 +564,7 @@ public: } // Return the number of screens present in the system - virtual unsigned int getNumScreens( const osg::GraphicsContext::ScreenIdentifier& /*si*/ ) + unsigned int getNumScreens( const osg::GraphicsContext::ScreenIdentifier& /*si*/ ) override { OSG_WARN << "osgQt: getNumScreens() not implemented yet." << std::endl; return 0; @@ -572,26 +572,26 @@ public: // Return the resolution of specified screen // (0,0) is returned if screen is unknown - virtual void getScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*si*/, osg::GraphicsContext::ScreenSettings & /*resolution*/ ) + void getScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*si*/, osg::GraphicsContext::ScreenSettings & /*resolution*/ ) override { OSG_WARN << "osgQt: getScreenSettings() not implemented yet." << std::endl; } // Set the resolution for given screen - virtual bool setScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*si*/, const osg::GraphicsContext::ScreenSettings & /*resolution*/ ) + bool setScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*si*/, const osg::GraphicsContext::ScreenSettings & /*resolution*/ ) override { OSG_WARN << "osgQt: setScreenSettings() not implemented yet." << std::endl; return false; } // Enumerates available resolutions - virtual void enumerateScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*screenIdentifier*/, osg::GraphicsContext::ScreenSettingsList & /*resolution*/ ) + void enumerateScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*screenIdentifier*/, osg::GraphicsContext::ScreenSettingsList & /*resolution*/ ) override { OSG_WARN << "osgQt: enumerateScreenSettings() not implemented yet." << std::endl; } // Create a graphics context with given traits - virtual osg::GraphicsContext* createGraphicsContext( osg::GraphicsContext::Traits* traits ) + osg::GraphicsContext* createGraphicsContext( osg::GraphicsContext::Traits* traits ) override { if (traits->pbuffer) { diff --git a/extern/recastnavigation/DebugUtils/Include/DebugDraw.h b/extern/recastnavigation/DebugUtils/Include/DebugDraw.h index 00b544d1c..f47df0b7b 100644 --- a/extern/recastnavigation/DebugUtils/Include/DebugDraw.h +++ b/extern/recastnavigation/DebugUtils/Include/DebugDraw.h @@ -206,11 +206,11 @@ class duDisplayList : public duDebugDraw public: duDisplayList(int cap = 512); ~duDisplayList(); - virtual void depthMask(bool state); - virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f); - virtual void vertex(const float x, const float y, const float z, unsigned int color); - virtual void vertex(const float* pos, unsigned int color); - virtual void end(); + void depthMask(bool state) override; + void begin(duDebugDrawPrimitives prim, float size = 1.0f) override; + void vertex(const float x, const float y, const float z, unsigned int color) override; + void vertex(const float* pos, unsigned int color) override; + void end() override; void clear(); void draw(struct duDebugDraw* dd); private: diff --git a/extern/recastnavigation/Detour/Source/DetourNavMeshQuery.cpp b/extern/recastnavigation/Detour/Source/DetourNavMeshQuery.cpp index 839ee1e81..265b10b34 100644 --- a/extern/recastnavigation/Detour/Source/DetourNavMeshQuery.cpp +++ b/extern/recastnavigation/Detour/Source/DetourNavMeshQuery.cpp @@ -640,7 +640,7 @@ public: dtPolyRef nearestRef() const { return m_nearestRef; } const float* nearestPoint() const { return m_nearestPoint; } - void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) + void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) override { dtIgnoreUnused(polys); @@ -842,7 +842,7 @@ public: int numCollected() const { return m_numCollected; } bool overflowed() const { return m_overflow; } - void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) + void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) override { dtIgnoreUnused(tile); dtIgnoreUnused(polys); From df178ed97c457bdc906fa23dc4c7f0ee000181ac Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 16 Oct 2020 19:54:26 +0000 Subject: [PATCH 193/224] Merge branch 'container-regressions' into 'master' Fix container regressions See merge request OpenMW/openmw!346 (cherry picked from commit b0aee6f83d4cddb0116284b197913f9687dd9cee) 95e7a22d fix container regressions --- apps/openmw/mwgui/container.cpp | 16 +++++++++------- components/misc/rng.cpp | 6 +++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 810a369d8..fdb27addc 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -230,36 +230,38 @@ namespace MWGui { MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); + // Copy mPtr because onTakeAllButtonClicked closes the window which resets the reference + MWWorld::Ptr ptr = mPtr; onTakeAllButtonClicked(mTakeButton); - if (mPtr.getClass().isPersistent(mPtr)) + if (ptr.getClass().isPersistent(ptr)) MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}"); else { - MWMechanics::CreatureStats& creatureStats = mPtr.getClass().getCreatureStats(mPtr); + MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); // If we dispose corpse before end of death animation, we should update death counter counter manually. // Also we should run actor's script - it may react on actor's death. if (creatureStats.isDead() && !creatureStats.isDeathAnimationFinished()) { creatureStats.setDeathAnimationFinished(true); - MWBase::Environment::get().getMechanicsManager()->notifyDied(mPtr); + MWBase::Environment::get().getMechanicsManager()->notifyDied(ptr); - const std::string script = mPtr.getClass().getScript(mPtr); + const std::string script = ptr.getClass().getScript(ptr); if (!script.empty() && MWBase::Environment::get().getWorld()->getScriptsEnabled()) { - MWScript::InterpreterContext interpreterContext (&mPtr.getRefData().getLocals(), mPtr); + MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); MWBase::Environment::get().getScriptManager()->run (script, interpreterContext); } // Clean up summoned creatures as well std::map& creatureMap = creatureStats.getSummonedCreatureMap(); for (const auto& creature : creatureMap) - MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mPtr, creature.second); + MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(ptr, creature.second); creatureMap.clear(); } - MWBase::Environment::get().getWorld()->deleteObject(mPtr); + MWBase::Environment::get().getWorld()->deleteObject(ptr); } mPtr = MWWorld::Ptr(); diff --git a/components/misc/rng.cpp b/components/misc/rng.cpp index 4189404b1..23d820448 100644 --- a/components/misc/rng.cpp +++ b/components/misc/rng.cpp @@ -30,17 +30,17 @@ namespace Misc float Rng::rollProbability(Seed& seed) { - return std::uniform_real_distribution(0, 1 - std::numeric_limits::epsilon())(sSeed.mGenerator); + return std::uniform_real_distribution(0, 1 - std::numeric_limits::epsilon())(seed.mGenerator); } float Rng::rollClosedProbability(Seed& seed) { - return std::uniform_real_distribution(0, 1)(sSeed.mGenerator); + return std::uniform_real_distribution(0, 1)(seed.mGenerator); } int Rng::rollDice(int max, Seed& seed) { - return max > 0 ? std::uniform_int_distribution(0, max - 1)(sSeed.mGenerator) : 0; + return max > 0 ? std::uniform_int_distribution(0, max - 1)(seed.mGenerator) : 0; } unsigned int Rng::generateDefaultSeed() From 5e7e14c87044d3c209eac44b999365ccbc56cda5 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sat, 17 Oct 2020 00:16:39 +0000 Subject: [PATCH 194/224] Only use MacOS runners for this project, not forks --- .gitlab-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6f8e4dbd3..65cfc7e09 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,8 +71,11 @@ MacOS: tags: - macos stage: build + only: + variables: + - $CI_PROJECT_ID == "7107382" script: - - rm -fr build/* # remove anything in the build directory + - rm -fr build/* # remove anything in the build directory - CI/before_install.osx.sh - CI/before_script.osx.sh - cd build; make -j2 package From c72199155cffe6781ed5a4252122d9b07d8b1fad Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 17 Oct 2020 15:33:23 +0200 Subject: [PATCH 195/224] Use full speed in the "NPCs give way" maneuver. --- apps/openmw/mwmechanics/actors.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index d936a0b00..3e4a7498e 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1804,11 +1804,9 @@ namespace MWMechanics osg::Vec2f newMovement = origMovement + movementCorrection; // Step to the side rather than backward. Otherwise player will be able to push the NPC far away from it's original location. newMovement.y() = std::max(newMovement.y(), 0.f); + newMovement.normalize(); if (isMoving) - { // Keep the original speed. - newMovement.normalize(); - newMovement *= origMovement.length(); - } + newMovement *= origMovement.length(); // Keep the original speed. movement.mPosition[0] = newMovement.x(); movement.mPosition[1] = newMovement.y(); if (shouldTurnToApproachingActor) From 9ec6fce446da90ba1d05deacff60ccfd6e063552 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 17 Oct 2020 16:11:22 +0200 Subject: [PATCH 196/224] Makes the delay of turning while run configurable (part of "smooth movement"). --- apps/openmw/mwmechanics/character.cpp | 3 ++- docs/source/reference/modding/settings/game.rst | 11 +++++++++++ files/settings-default.cfg | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index ad64f79d7..b0792a9e5 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1966,6 +1966,7 @@ void CharacterController::update(float duration, bool animationOnly) static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); if (smoothMovement && !isFirstPersonPlayer) { + static const float playerTurningCoef = 1.0 / std::max(0.01f, Settings::Manager::getFloat("smooth movement player turning delay", "Game")); float angle = mPtr.getRefData().getPosition().rot[2]; osg::Vec2f targetSpeed = Misc::rotateVec2f(osg::Vec2f(vec.x(), vec.y()), -angle) * movementSettings.mSpeedFactor; osg::Vec2f delta = targetSpeed - mSmoothedSpeed; @@ -1975,7 +1976,7 @@ void CharacterController::update(float duration, bool animationOnly) float maxDelta; if (std::abs(speedDelta) < deltaLen / 2) // Turning is smooth for player and less smooth for NPCs (otherwise NPC can miss a path point). - maxDelta = duration * (isPlayer ? 3.f : 6.f); + maxDelta = duration * (isPlayer ? playerTurningCoef : 6.f); else if (isPlayer && speedDelta < -deltaLen / 2) // As soon as controls are released, mwinput switches player from running to walking. // So stopping should be instant for player, otherwise it causes a small twitch. diff --git a/docs/source/reference/modding/settings/game.rst b/docs/source/reference/modding/settings/game.rst index f942f6e7c..fd93eba61 100644 --- a/docs/source/reference/modding/settings/game.rst +++ b/docs/source/reference/modding/settings/game.rst @@ -344,6 +344,17 @@ Recommended to use with "turn to movement direction" enabled. This setting can be controlled in Advanced tab of the launcher. +smooth movement player turning delay +------------------------------------ + +:Type: floating point +:Range: >= 0.01 +:Default: 0.333 + +Max delay of turning (in seconds) if player drastically changes direction on the run. Makes sense only if "smooth movement" is enabled. + +This setting can only be configured by editing the settings configuration file. + NPCs avoid collisions --------------------- diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 3c6e736d8..c5c0ece96 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -328,6 +328,9 @@ turn to movement direction = false # Makes all movements of NPCs and player more smooth. smooth movement = false +# Max delay of turning (in seconds) if player drastically changes direction on the run. +smooth movement player turning delay = 0.333 + # All actors avoid collisions with other actors. NPCs avoid collisions = false From f90e403bc168d603e1539156a879ba2ced4a957d Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 18 Oct 2020 01:40:58 +0300 Subject: [PATCH 197/224] Avoid summon spawn if actor isn't in a cell (bug #5644) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/actors.cpp | 5 +++++ apps/openmw/mwworld/worldimp.cpp | 2 ++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95919af31..ad3bcfad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ Bug #5603: Setting constant effect cast style doesn't correct effects view Bug #5611: Usable items with "0 Uses" should be used only once Bug #5622: Can't properly interact with the console when in pause menu + Bug #5644: Summon effects running on the player during game initialization cause crashes Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging Feature #4894: Consider actors as obstacles for pathfinding diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3e4a7498e..4d7841010 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1198,6 +1198,11 @@ namespace MWMechanics } } + // Summoned creature update visitor assumes the actor belongs to a cell. + // This assumption isn't always valid for the player character. + if (!ptr.isInCell()) + return; + bool hasSummonEffect = false; for (MagicEffects::Collection::const_iterator it = effects.begin(); it != effects.end(); ++it) { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index daef81b5c..dcd282f8d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2182,6 +2182,8 @@ namespace MWWorld Ptr World::copyObjectToCell(const ConstPtr &object, CellStore* cell, ESM::Position pos, int count, bool adjustPos) { + if (!cell) + throw std::runtime_error("copyObjectToCell(): cannot copy object to null cell"); if (cell->isExterior()) { int cellX, cellY; From d7fadc933f48ffef31919194a0fefa091432eae5 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 18 Oct 2020 09:55:55 +0400 Subject: [PATCH 198/224] Fix override warning with MyGUI 3.4 --- components/myguiplatform/myguirendermanager.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/myguiplatform/myguirendermanager.hpp b/components/myguiplatform/myguirendermanager.hpp index 1e82bc0df..72abebd18 100644 --- a/components/myguiplatform/myguirendermanager.hpp +++ b/components/myguiplatform/myguirendermanager.hpp @@ -106,10 +106,16 @@ public: bool checkTexture(MyGUI::ITexture* _texture); + // setViewSize() is a part of MyGUI::RenderManager interface since 3.4.0 release +#if MYGUI_VERSION < MYGUI_DEFINE_VERSION(3,4,0) + void setViewSize(int width, int height); +#else + void setViewSize(int width, int height) override; +#endif + /*internal:*/ void collectDrawCalls(); - void setViewSize(int width, int height); }; } From b222872446f3fb4c135816625d73e5a071dec470 Mon Sep 17 00:00:00 2001 From: psi29a Date: Mon, 19 Oct 2020 08:27:38 +0000 Subject: [PATCH 199/224] Android build on gitlab --- .gitlab-ci.yml | 32 ++++++++++++++++++++++++++++++++ CI/before_install.android.sh | 4 ++++ CI/before_script.android.sh | 25 +++++++++++++++++++++++++ CMakeLists.txt | 6 +++++- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100755 CI/before_install.android.sh create mode 100755 CI/before_script.android.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 65cfc7e09..5831a73b8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -268,3 +268,35 @@ Windows_MSBuild_CS_RelWithDebInfo: variables: <<: *cs-targets config: "RelWithDebInfo" + +Debian_AndroidNDK_arm64-v8a: + tags: + - linux + image: debian:bullseye + variables: + CCACHE_SIZE: 3G + cache: + key: Debian_AndroidNDK_arm64-v8a.v2 + paths: + - apt-cache/ + - ccache/ + before_script: + - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR + - echo "deb http://deb.debian.org/debian unstable main contrib" > /etc/apt/sources.list + - echo "google-android-ndk-installer google-android-installers/mirror select https://dl.google.com" | debconf-set-selections + - apt-get update -yq + - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake ccache curl unzip git build-essential google-android-ndk-installer + stage: build + script: + - export CCACHE_BASEDIR="`pwd`" + - export CCACHE_DIR="`pwd`/ccache" && mkdir -pv "$CCACHE_DIR" + - ccache -z -M "${CCACHE_SIZE}" + - CI/before_install.android.sh + - CI/before_script.android.sh + - cd build + - cmake --build . -- -j $(nproc) + - cmake --install . + - ccache -s + artifacts: + paths: + - build/install/ \ No newline at end of file diff --git a/CI/before_install.android.sh b/CI/before_install.android.sh new file mode 100755 index 000000000..791377dd9 --- /dev/null +++ b/CI/before_install.android.sh @@ -0,0 +1,4 @@ +#!/bin/sh -ex + +curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/android/openmw-android-deps-20201018.zip -o ~/openmw-android-deps.zip +unzip -o ~/openmw-android-deps -d /usr/lib/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr > /dev/null diff --git a/CI/before_script.android.sh b/CI/before_script.android.sh new file mode 100755 index 000000000..8f0ec77da --- /dev/null +++ b/CI/before_script.android.sh @@ -0,0 +1,25 @@ +#!/bin/sh -ex + +# hack to work around: FFmpeg version is too old, 3.2 is required +sed -i s/"NOT FFVER_OK"/"FALSE"/ CMakeLists.txt + +mkdir build +cd build + +cmake \ +-DCMAKE_TOOLCHAIN_FILE=/usr/lib/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake \ +-DANDROID_ABI=arm64-v8a \ +-DANDROID_PLATFORM=android-21 \ +-DCMAKE_C_COMPILER_LAUNCHER=ccache \ +-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ +-DCMAKE_INSTALL_PREFIX=install \ +-DBUILD_BSATOOL=0 \ +-DBUILD_NIFTEST=0 \ +-DBUILD_ESMTOOL=0 \ +-DBUILD_LAUNCHER=0 \ +-DBUILD_MWINIIMPORTER=0 \ +-DBUILD_ESSIMPORTER=0 \ +-DBUILD_OPENCS=0 \ +-DBUILD_WIZARD=0 \ +-DMyGUI_LIBRARY="/usr/lib/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/libMyGUIEngineStatic.a" \ +.. diff --git a/CMakeLists.txt b/CMakeLists.txt index 15049548c..829927de6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -837,7 +837,11 @@ elseif(NOT APPLE) # Install binaries IF(BUILD_OPENMW) - INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw" DESTINATION "${BINDIR}" ) + IF(ANDROID) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/libopenmw.so" DESTINATION "${BINDIR}" ) + ELSE(ANDROID) + INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw" DESTINATION "${BINDIR}" ) + ENDIF(ANDROID) ENDIF(BUILD_OPENMW) IF(BUILD_LAUNCHER) INSTALL(PROGRAMS "${INSTALL_SOURCE}/openmw-launcher" DESTINATION "${BINDIR}" ) From 7954dccb44f57e6b75efbd4d41f41d9c51951484 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Thu, 15 Oct 2020 23:47:19 +0200 Subject: [PATCH 200/224] lz4 prep work; get linux and windows ready --- .gitlab-ci.yml | 2 +- .travis.yml | 4 +- CI/before_script.msvc.sh | 24 ++++++++ CMakeLists.txt | 2 + cmake/FindLZ4.cmake | 130 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 cmake/FindLZ4.cmake diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5831a73b8..3201dd6b7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,7 @@ stages: before_script: - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR - apt-get update -yq - - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev ccache git clang + - apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev liblz4-dev ccache git clang stage: build script: - export CCACHE_BASEDIR="`pwd`" diff --git a/.travis.yml b/.travis.yml index 8d98d0dd4..5bbe90c8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,8 +23,8 @@ addons: # FFmpeg libavcodec-dev, libavformat-dev, libavutil-dev, libswresample-dev, libswscale-dev, # Audio, Video and Misc. deps - libsdl2-dev, libqt5opengl5-dev, libopenal-dev, libunshield-dev, libtinyxml-dev, - # The other ones from OpenMW ppa + libsdl2-dev, libqt5opengl5-dev, libopenal-dev, libunshield-dev, libtinyxml-dev, liblz4-dev + # The other ones from OpenMW ppa libbullet-dev, libopenscenegraph-dev, libmygui-dev ] coverity_scan: # TODO: currently takes too long, disabled openmw/openmw-cs for now. diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 8b3ece2bd..4dbf433cb 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -571,6 +571,11 @@ if [ -z $SKIP_DOWNLOAD ]; then "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/SDL2-2.0.12.zip" \ "SDL2-2.0.12.zip" + # LZ4 + download "LZ4 1.9.2" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/lz4_win${BITS}_v1_9_2.zip" \ + "lz4_win${BITS}_v1_9_2.zip" + # Google test and mock if [ ! -z $TEST_FRAMEWORK ]; then echo "Google test 1.10.0..." @@ -901,6 +906,25 @@ printf "SDL 2.0.12... " } cd $DEPS echo +# LZ4 +printf "LZ4 1.9.2... " +{ + if [ -d LZ4-1.9.2 ]; then + printf "Exists. " + elif [ -z $SKIP_EXTRACT ]; then + rm -rf LZ4-1.9.2 + eval 7z x -y lz4_win${BITS}_v1.9.2.zip $STRIP + fi + export LZ4DIR="$(real_pwd)/LZ4-1.9.2" + add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \ + -DLZ4_LIBRARY="${LZ4DIR}/static/liblz4_static.lib" + for config in ${CONFIGURATIONS[@]}; do + add_runtime_dlls $config "$(pwd)/LZ4-1.9.2/dll/liblz4.dll.a" + done + echo Done. +} +cd $DEPS +echo # Google Test and Google Mock if [ ! -z $TEST_FRAMEWORK ]; then printf "Google test 1.10.0 ..." diff --git a/CMakeLists.txt b/CMakeLists.txt index 829927de6..c4002ea50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,8 @@ endif() # Dependencies find_package(OpenGL REQUIRED) +find_package(LZ4 REQUIRED) + if (USE_QT) find_package(Qt5Core 5.12 REQUIRED) find_package(Qt5Widgets REQUIRED) diff --git a/cmake/FindLZ4.cmake b/cmake/FindLZ4.cmake new file mode 100644 index 000000000..ec854c6b1 --- /dev/null +++ b/cmake/FindLZ4.cmake @@ -0,0 +1,130 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindLZ4 +------- + +Find the LZ4 include directory and library. + +Use this module by invoking find_package with the form:: + +.. code-block:: cmake + + find_package(LZ4 + [version] # Minimum version e.g. 1.8.0 + [REQUIRED] # Fail with error if LZ4 is not found + ) + +Imported targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` targets: + +.. variable:: LZ4::LZ4 + + Imported target for using the LZ4 library, if found. + +Result variables +^^^^^^^^^^^^^^^^ + +.. variable:: LZ4_FOUND + + Set to true if LZ4 library found, otherwise false or undefined. + +.. variable:: LZ4_INCLUDE_DIRS + + Paths to include directories listed in one variable for use by LZ4 client. + +.. variable:: LZ4_LIBRARIES + + Paths to libraries to linked against to use LZ4. + +.. variable:: LZ4_VERSION + + The version string of LZ4 found. + +Cache variables +^^^^^^^^^^^^^^^ + +For users who wish to edit and control the module behavior, this module +reads hints about search locations from the following variables:: + +.. variable:: LZ4_INCLUDE_DIR + + Path to LZ4 include directory with ``lz4.h`` header. + +.. variable:: LZ4_LIBRARY + + Path to LZ4 library to be linked. + +NOTE: The variables above should not usually be used in CMakeLists.txt files! + +#]=======================================================================] + +### Find library ############################################################## + +if(NOT LZ4_LIBRARY) + find_library(LZ4_LIBRARY_RELEASE NAMES lz4) + find_library(LZ4_LIBRARY_DEBUG NAMES lz4d) + + include(SelectLibraryConfigurations) + select_library_configurations(LZ4) +else() + file(TO_CMAKE_PATH "${LZ4_LIBRARY}" LZ4_LIBRARY) +endif() + +### Find include directory #################################################### +find_path(LZ4_INCLUDE_DIR NAMES lz4.h) + +if(LZ4_INCLUDE_DIR AND EXISTS "${LZ4_INCLUDE_DIR}/lz4.h") + file(STRINGS "${LZ4_INCLUDE_DIR}/lz4.h" _lz4_h_contents + REGEX "#define LZ4_VERSION_[A-Z]+[ ]+[0-9]+") + string(REGEX REPLACE "#define LZ4_VERSION_MAJOR[ ]+([0-9]+).+" "\\1" + LZ4_VERSION_MAJOR "${_lz4_h_contents}") + string(REGEX REPLACE ".+#define LZ4_VERSION_MINOR[ ]+([0-9]+).+" "\\1" + LZ4_VERSION_MINOR "${_lz4_h_contents}") + string(REGEX REPLACE ".+#define LZ4_VERSION_RELEASE[ ]+([0-9]+).*" "\\1" + LZ4_VERSION_RELEASE "${_lz4_h_contents}") + set(LZ4_VERSION "${LZ4_VERSION_MAJOR}.${LZ4_VERSION_MINOR}.${LZ4_VERSION_RELEASE}") + unset(_lz4_h_contents) +endif() + +### Set result variables ###################################################### +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LZ4 DEFAULT_MSG + LZ4_LIBRARY LZ4_INCLUDE_DIR LZ4_VERSION) + +mark_as_advanced(LZ4_INCLUDE_DIR LZ4_LIBRARY) + +set(LZ4_LIBRARIES ${LZ4_LIBRARY}) +set(LZ4_INCLUDE_DIRS ${LZ4_INCLUDE_DIR}) + +### Import targets ############################################################ +if(LZ4_FOUND) + if(NOT TARGET LZ4::LZ4) + add_library(LZ4::LZ4 UNKNOWN IMPORTED) + set_target_properties(LZ4::LZ4 PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_INCLUDE_DIRECTORIES "${LZ4_INCLUDE_DIR}") + + if(LZ4_LIBRARY_RELEASE) + set_property(TARGET LZ4::LZ4 APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(LZ4::LZ4 PROPERTIES + IMPORTED_LOCATION_RELEASE "${LZ4_LIBRARY_RELEASE}") + endif() + + if(LZ4_LIBRARY_DEBUG) + set_property(TARGET LZ4::LZ4 APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(LZ4::LZ4 PROPERTIES + IMPORTED_LOCATION_DEBUG "${LZ4_LIBRARY_DEBUG}") + endif() + + if(NOT LZ4_LIBRARY_RELEASE AND NOT LZ4_LIBRARY_DEBUG) + set_property(TARGET LZ4::LZ4 APPEND PROPERTY + IMPORTED_LOCATION "${LZ4_LIBRARY}") + endif() + endif() +endif() From e280a3670109f9fdde0b62ecf7d9d42b815eb05f Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 16 Oct 2020 00:05:55 +0200 Subject: [PATCH 201/224] correct filename of lz4 archive; fix indentation --- .travis.yml | 2 +- CI/before_script.msvc.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5bbe90c8d..2f457798a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ addons: libavcodec-dev, libavformat-dev, libavutil-dev, libswresample-dev, libswscale-dev, # Audio, Video and Misc. deps libsdl2-dev, libqt5opengl5-dev, libopenal-dev, libunshield-dev, libtinyxml-dev, liblz4-dev - # The other ones from OpenMW ppa + # The other ones from OpenMW ppa libbullet-dev, libopenscenegraph-dev, libmygui-dev ] coverity_scan: # TODO: currently takes too long, disabled openmw/openmw-cs for now. diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 4dbf433cb..9ca2d3ebf 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -913,7 +913,7 @@ printf "LZ4 1.9.2... " printf "Exists. " elif [ -z $SKIP_EXTRACT ]; then rm -rf LZ4-1.9.2 - eval 7z x -y lz4_win${BITS}_v1.9.2.zip $STRIP + eval 7z x -y lz4_win${BITS}_v1_9_2.zip $STRIP fi export LZ4DIR="$(real_pwd)/LZ4-1.9.2" add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \ From edd6a329ee104a7d005f9cf056fbb24a6bf87b90 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 16 Oct 2020 00:29:12 +0200 Subject: [PATCH 202/224] tell 7z to extract to specific directory --- CI/before_script.msvc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 9ca2d3ebf..d9f11ff30 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -913,7 +913,7 @@ printf "LZ4 1.9.2... " printf "Exists. " elif [ -z $SKIP_EXTRACT ]; then rm -rf LZ4-1.9.2 - eval 7z x -y lz4_win${BITS}_v1_9_2.zip $STRIP + eval 7z x -y lz4_win${BITS}_v1_9_2.zip -o./LZ4-1.9.2 $STRIP fi export LZ4DIR="$(real_pwd)/LZ4-1.9.2" add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \ From 503bf7f78b166456289c336ae028c06a0441b1d8 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 16 Oct 2020 16:37:20 +0200 Subject: [PATCH 203/224] added lz4 to our macos deps; let us see if that works --- CI/before_install.osx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index c3514e25b..9edfdf0d2 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -5,5 +5,5 @@ command -v ccache >/dev/null 2>&1 || brew install ccache command -v cmake >/dev/null 2>&1 || brew install cmake command -v qmake >/dev/null 2>&1 || brew install qt -curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip +curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-20201016.zip -o ~/openmw-deps.zip unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null From 66d2b9c1958cddb4210fe30f4fb3af3e932a6943 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sat, 10 Oct 2020 14:00:03 +0300 Subject: [PATCH 204/224] Add Skyrim SE BSA version support Fix embedded file name loading --- CHANGELOG.md | 1 + components/CMakeLists.txt | 2 +- components/bsa/compressedbsafile.cpp | 87 ++++++++++++++++++++-------- components/bsa/compressedbsafile.hpp | 4 +- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad3bcfad0..7ae5f506d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ Feature #5579: MCP SetAngle enhancement Feature #5610: Actors movement should be smoother Feature #5642: Ability to attach arrows to actor skeleton instead of bow mesh + Feature #5649: Skyrim SE compressed BSA format support Task #5480: Drop Qt4 support Task #5520: Improve cell name autocompleter implementation diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7f44cf6fb..686bd8caa 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -233,7 +233,7 @@ target_link_libraries(components ${SDL2_LIBRARIES} ${OPENGL_gl_LIBRARY} ${MyGUI_LIBRARIES} - ${BSAOPTHASH_LIBRARIES} + ${LZ4_LIBRARIES} RecastNavigation::DebugUtils RecastNavigation::Detour RecastNavigation::Recast diff --git a/components/bsa/compressedbsafile.cpp b/components/bsa/compressedbsafile.cpp index d0bebe3c1..bf805e5f7 100644 --- a/components/bsa/compressedbsafile.cpp +++ b/components/bsa/compressedbsafile.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include @@ -132,8 +134,11 @@ void CompressedBSAFile::readHeader() input.read(reinterpret_cast(header), 36); - if(header[0] != 0x00415342 /*"BSA\x00"*/ || (header[1] != 0x67 /*TES4*/ && header[1] != 0x68 /*TES5*/)) - fail("Unrecognized TES4 BSA header"); + if (header[0] != 0x00415342) /*"BSA\x00"*/ + fail("Unrecognized compressed BSA format"); + mVersion = header[1]; + if (mVersion != 0x67 /*TES4*/ && mVersion != 0x68 /*FO3, FNV, TES5*/ && mVersion != 0x69 /*SSE*/) + fail("Unrecognized compressed BSA version"); // header[2] is offset, should be 36 = 0x24 which is the size of the header @@ -158,7 +163,8 @@ void CompressedBSAFile::readHeader() // header[8]; // fileFlags : an opportunity to optimize here mCompressedByDefault = (archiveFlags & 0x4) != 0; - mEmbeddedFileNames = header[1] == 0x68 /*TES5*/ && (archiveFlags & 0x100) != 0; + if (mVersion == 0x68 || mVersion == 0x69) /*FO3, FNV, TES5, SSE*/ + mEmbeddedFileNames = (archiveFlags & 0x100) != 0; } // folder records @@ -168,7 +174,14 @@ void CompressedBSAFile::readHeader() { input.read(reinterpret_cast(&hash), 8); input.read(reinterpret_cast(&fr.count), 4); // not sure purpose of count - input.read(reinterpret_cast(&fr.offset), 4); // not sure purpose of offset + if (mVersion == 0x69) // SSE + { + std::uint32_t unknown; + input.read(reinterpret_cast(&unknown), 4); + input.read(reinterpret_cast(&fr.offset), 8); + } + else + input.read(reinterpret_cast(&fr.offset), 4); // not sure purpose of offset std::map::const_iterator lb = mFolders.lower_bound(hash); if (lb != mFolders.end() && !(mFolders.key_comp()(hash, lb->first))) @@ -327,32 +340,56 @@ Files::IStreamPtr CompressedBSAFile::getFile(const char* file) Files::IStreamPtr CompressedBSAFile::getFile(const FileRecord& fileRecord) { - if (fileRecord.isCompressed(mCompressedByDefault)) { - Files::IStreamPtr streamPtr = Files::openConstrainedFileStream(mFilename.c_str(), fileRecord.offset, fileRecord.getSizeWithoutCompressionFlag()); + size_t size = fileRecord.getSizeWithoutCompressionFlag(); + size_t uncompressedSize = size; + bool compressed = fileRecord.isCompressed(mCompressedByDefault); + Files::IStreamPtr streamPtr = Files::openConstrainedFileStream(mFilename.c_str(), fileRecord.offset, size); + std::istream* fileStream = streamPtr.get(); + if (mEmbeddedFileNames) + { + // Skip over the embedded file name + char length = 0; + fileStream->read(&length, 1); + fileStream->ignore(length); + size -= length + sizeof(char); + } + if (compressed) + { + fileStream->read(reinterpret_cast(&uncompressedSize), sizeof(uint32_t)); + size -= sizeof(uint32_t); + } + std::shared_ptr memoryStreamPtr = std::make_shared(uncompressedSize); - std::istream* fileStream = streamPtr.get(); + if (compressed) + { + if (mVersion != 0x69) // Non-SSE: zlib + { + boost::iostreams::filtering_streambuf inputStreamBuf; + inputStreamBuf.push(boost::iostreams::zlib_decompressor()); + inputStreamBuf.push(*fileStream); - if (mEmbeddedFileNames) { - std::string embeddedFileName; - getBZString(embeddedFileName, *fileStream); + boost::iostreams::basic_array_sink sr(memoryStreamPtr->getRawData(), uncompressedSize); + boost::iostreams::copy(inputStreamBuf, sr); } - - uint32_t uncompressedSize = 0u; - fileStream->read(reinterpret_cast(&uncompressedSize), sizeof(uncompressedSize)); - - boost::iostreams::filtering_streambuf inputStreamBuf; - inputStreamBuf.push(boost::iostreams::zlib_decompressor()); - inputStreamBuf.push(*fileStream); - - std::shared_ptr memoryStreamPtr = std::make_shared(uncompressedSize); - - boost::iostreams::basic_array_sink sr(memoryStreamPtr->getRawData(), uncompressedSize); - boost::iostreams::copy(inputStreamBuf, sr); - - return std::shared_ptr(memoryStreamPtr, (std::istream*)memoryStreamPtr.get()); + else // SSE: lz4 + { + boost::scoped_array buffer(new char[size]); + fileStream->read(buffer.get(), size); + LZ4F_dctx* context = nullptr; + LZ4F_createDecompressionContext(&context, LZ4F_VERSION); + LZ4F_decompressOptions_t options = {}; + LZ4F_decompress(context, memoryStreamPtr->getRawData(), &uncompressedSize, buffer.get(), &size, &options); + LZ4F_errorCode_t errorCode = LZ4F_freeDecompressionContext(context); + if (LZ4F_isError(errorCode)) + fail("LZ4 decompression error (file " + mFilename + "): " + LZ4F_getErrorName(errorCode)); + } + } + else + { + fileStream->read(memoryStreamPtr->getRawData(), size); } - return Files::openConstrainedFileStream(mFilename.c_str(), fileRecord.offset, fileRecord.size); + return std::shared_ptr(memoryStreamPtr, (std::istream*)memoryStreamPtr.get()); } BsaVersion CompressedBSAFile::detectVersion(std::string filePath) diff --git a/components/bsa/compressedbsafile.hpp b/components/bsa/compressedbsafile.hpp index 3c28b5a5f..f3ad584d8 100644 --- a/components/bsa/compressedbsafile.hpp +++ b/components/bsa/compressedbsafile.hpp @@ -64,10 +64,12 @@ namespace Bsa //if each file record begins with BZ string with file name bool mEmbeddedFileNames; + std::uint32_t mVersion{0u}; + struct FolderRecord { std::uint32_t count; - std::uint32_t offset; + std::uint64_t offset; std::map files; }; std::map mFolders; From d6612eef2013e3f2a8bb9fd03a3737d23963232e Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sat, 17 Oct 2020 21:37:46 +0300 Subject: [PATCH 205/224] Fix indentation --- CI/before_script.msvc.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index d9f11ff30..b1c72ab0e 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -571,10 +571,10 @@ if [ -z $SKIP_DOWNLOAD ]; then "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/SDL2-2.0.12.zip" \ "SDL2-2.0.12.zip" - # LZ4 - download "LZ4 1.9.2" \ - "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/lz4_win${BITS}_v1_9_2.zip" \ - "lz4_win${BITS}_v1_9_2.zip" + # LZ4 + download "LZ4 1.9.2" \ + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/lz4_win${BITS}_v1_9_2.zip" \ + "lz4_win${BITS}_v1_9_2.zip" # Google test and mock if [ ! -z $TEST_FRAMEWORK ]; then From a03618324883ca9d172e01ce4775fdd70ae66189 Mon Sep 17 00:00:00 2001 From: fredzio Date: Mon, 19 Oct 2020 21:26:21 +0200 Subject: [PATCH 206/224] Use a much simpler and assert-free check for Bullet multithreading support --- apps/openmw/mwphysics/mtphysics.cpp | 74 ++--------------------------- 1 file changed, 5 insertions(+), 69 deletions(-) diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index a53a011f6..1ad0ae9c0 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -1,5 +1,5 @@ +#include #include -#include #include "components/debug/debuglog.hpp" #include @@ -16,8 +16,6 @@ #include "object.hpp" #include "physicssystem.hpp" -class btIParallelSumBody; // needed to compile with bullet < 2.88 - namespace { /// @brief A scoped lock that is either shared or exclusive depending on configuration @@ -122,77 +120,15 @@ namespace namespace Config { - /* The purpose of these 2 classes is to make OpenMW works with Bullet compiled with either single or multithread support. - At runtime, Bullet resolve the call to btParallelFor() to: - - btITaskScheduler::parallelFor() if bullet is multithreaded - - btIParallelForBody::forLoop() if bullet is singlethreaded. - - NOTE: From Bullet 2.88, there is a btDefaultTaskScheduler(), that returns NULL if multithreading is not supported. - It might be worth considering to simplify the API once OpenMW stops supporting 2.87. - */ - - template - using void_t = void; - - /// @brief for Bullet <= 2.87 - template - class MultiThreadedBulletImpl : public T - { - public: - MultiThreadedBulletImpl(): T("") {}; - ~MultiThreadedBulletImpl() override = default; - int getMaxNumThreads() const override { return 1; }; - int getNumThreads() const override { return 1; }; - void setNumThreads(int numThreads) override {}; - - /// @brief will be called by Bullet if threading is supported - void parallelFor(int iBegin, int iEnd, int batchsize, const btIParallelForBody& body) override {}; - }; - - /// @brief for Bullet >= 2.88 - template - class MultiThreadedBulletImpl> : public T - { - public: - MultiThreadedBulletImpl(): T("") {}; - ~MultiThreadedBulletImpl() override = default; - int getMaxNumThreads() const override { return 1; }; - int getNumThreads() const override { return 1; }; - void setNumThreads(int numThreads) override {}; - - /// @brief will be called by Bullet if threading is supported - void parallelFor(int iBegin, int iEnd, int batchsize, const btIParallelForBody& body) override {}; - - btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) override { return {}; }; - }; - - using MultiThreadedBullet = MultiThreadedBulletImpl; - - class SingleThreadedBullet : public btIParallelForBody - { - public: - explicit SingleThreadedBullet(bool &threadingSupported): mThreadingSupported(threadingSupported) {}; - /// @brief will be called by Bullet if threading is NOT supported - void forLoop(int iBegin, int iEnd) const override - { - mThreadingSupported = false; - } - private: - bool &mThreadingSupported; - }; - /// @return either the number of thread as configured by the user, or 1 if Bullet doesn't support multithreading int computeNumThreads(bool& threadSafeBullet) { int wantedThread = Settings::Manager::getInt("async num threads", "Physics"); - auto bulletScheduler = std::make_unique(); - btSetTaskScheduler(bulletScheduler.get()); - bool threadingSupported = true; - btParallelFor(0, 0, 0, SingleThreadedBullet(threadingSupported)); - - threadSafeBullet = threadingSupported; - if (!threadingSupported && wantedThread > 1) + auto broad = std::make_unique(); + auto maxSupportedThreads = broad->m_rayTestStacks.size(); + threadSafeBullet = (maxSupportedThreads > 1); + if (!threadSafeBullet && wantedThread > 1) { Log(Debug::Warning) << "Bullet was not compiled with multithreading support, 1 async thread will be used"; return 1; From 1492ba4a533db5f558274f81a5dad84071206583 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Mon, 19 Oct 2020 22:36:02 +0300 Subject: [PATCH 207/224] Link against LZ4::LZ4 --- components/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 686bd8caa..c399a7010 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -233,7 +233,7 @@ target_link_libraries(components ${SDL2_LIBRARIES} ${OPENGL_gl_LIBRARY} ${MyGUI_LIBRARIES} - ${LZ4_LIBRARIES} + LZ4::LZ4 RecastNavigation::DebugUtils RecastNavigation::Detour RecastNavigation::Recast From de6d4ab44d136381d7b3fc08db23b2b62070ffe6 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Tue, 13 Oct 2020 00:22:33 +0300 Subject: [PATCH 208/224] Make messageboxes overlap tooltips (bug #5639) --- CHANGELOG.md | 1 + files/mygui/openmw_layers.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad3bcfad0..e198f62a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ Bug #5603: Setting constant effect cast style doesn't correct effects view Bug #5611: Usable items with "0 Uses" should be used only once Bug #5622: Can't properly interact with the console when in pause menu + Bug #5639: Tooltips cover Messageboxes Bug #5644: Summon effects running on the player during game initialization cause crashes Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index a090fb369..c28865502 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -12,8 +12,8 @@ - + From b3e27fae4cec319bb57a6af0a0279b7a3fc1f5e4 Mon Sep 17 00:00:00 2001 From: psi29a Date: Mon, 19 Oct 2020 20:29:22 +0000 Subject: [PATCH 209/224] use updated msvc lz4 provided by anyoldname3 --- CI/before_script.msvc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index b1c72ab0e..1fcac5d12 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -917,9 +917,9 @@ printf "LZ4 1.9.2... " fi export LZ4DIR="$(real_pwd)/LZ4-1.9.2" add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \ - -DLZ4_LIBRARY="${LZ4DIR}/static/liblz4_static.lib" + -DLZ4_LIBRARY="${LZ4DIR}/static/liblz4.lib" for config in ${CONFIGURATIONS[@]}; do - add_runtime_dlls $config "$(pwd)/LZ4-1.9.2/dll/liblz4.dll.a" + add_runtime_dlls $config "$(pwd)/LZ4-1.9.2/dll/liblz4.dll" done echo Done. } From c0e3f1c7ce66cbddde067e1d477f8a4d6d5ef641 Mon Sep 17 00:00:00 2001 From: psi29a Date: Mon, 19 Oct 2020 21:59:44 +0000 Subject: [PATCH 210/224] Update CI/before_script.msvc.sh --- CI/before_script.msvc.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 1fcac5d12..b5fb655aa 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -573,8 +573,8 @@ if [ -z $SKIP_DOWNLOAD ]; then # LZ4 download "LZ4 1.9.2" \ - "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/lz4_win${BITS}_v1_9_2.zip" \ - "lz4_win${BITS}_v1_9_2.zip" + "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/lz4_win${BITS}_v1_9_2.7z" \ + "lz4_win${BITS}_v1_9_2.7z" # Google test and mock if [ ! -z $TEST_FRAMEWORK ]; then @@ -913,13 +913,19 @@ printf "LZ4 1.9.2... " printf "Exists. " elif [ -z $SKIP_EXTRACT ]; then rm -rf LZ4-1.9.2 - eval 7z x -y lz4_win${BITS}_v1_9_2.zip -o./LZ4-1.9.2 $STRIP + eval 7z x -y lz4_win${BITS}_v1_9_2.7z -o./LZ4-1.9.2 $STRIP fi export LZ4DIR="$(real_pwd)/LZ4-1.9.2" add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \ - -DLZ4_LIBRARY="${LZ4DIR}/static/liblz4.lib" - for config in ${CONFIGURATIONS[@]}; do - add_runtime_dlls $config "$(pwd)/LZ4-1.9.2/dll/liblz4.dll" + -DLZ4_LIBRARY="${LZ4DIR}/lib/liblz4.lib" + for CONFIGURATION in ${CONFIGURATIONS[@]}; do + if [ $CONFIGURATION == "Debug" ]; then + LZ4_CONFIGURATION="Debug" + else + SUFFIX="" + LZ4_CONFIGURATION="Release" + fi + add_runtime_dlls $CONFIGURATION "$(pwd)/LZ4-1.9.2/bin/${LZ4_CONFIGURATION}/liblz4.dll" done echo Done. } From 1278d3b784c0f320a41051a7fd6a6071ee2753ad Mon Sep 17 00:00:00 2001 From: psi29a Date: Mon, 19 Oct 2020 22:36:34 +0000 Subject: [PATCH 211/224] make sure to use new path and trick caching --- CI/before_script.msvc.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index b5fb655aa..81994ec9c 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -909,13 +909,13 @@ echo # LZ4 printf "LZ4 1.9.2... " { - if [ -d LZ4-1.9.2 ]; then + if [ -d LZ4_1.9.2 ]; then printf "Exists. " elif [ -z $SKIP_EXTRACT ]; then rm -rf LZ4-1.9.2 - eval 7z x -y lz4_win${BITS}_v1_9_2.7z -o./LZ4-1.9.2 $STRIP + eval 7z x -y lz4_win${BITS}_v1_9_2.7z -o./LZ4_1.9.2 $STRIP fi - export LZ4DIR="$(real_pwd)/LZ4-1.9.2" + export LZ4DIR="$(real_pwd)/LZ4_1.9.2" add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \ -DLZ4_LIBRARY="${LZ4DIR}/lib/liblz4.lib" for CONFIGURATION in ${CONFIGURATIONS[@]}; do From 7b1cd8a72fd523cf4f0bbaffcc9208061c836df0 Mon Sep 17 00:00:00 2001 From: psi29a Date: Tue, 20 Oct 2020 07:35:02 +0000 Subject: [PATCH 212/224] use LZ4_1.9.2 instead of LZ4_1.9.2 --- CI/before_script.msvc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 81994ec9c..2a0db9c91 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -912,7 +912,7 @@ printf "LZ4 1.9.2... " if [ -d LZ4_1.9.2 ]; then printf "Exists. " elif [ -z $SKIP_EXTRACT ]; then - rm -rf LZ4-1.9.2 + rm -rf LZ4_1.9.2 eval 7z x -y lz4_win${BITS}_v1_9_2.7z -o./LZ4_1.9.2 $STRIP fi export LZ4DIR="$(real_pwd)/LZ4_1.9.2" @@ -925,7 +925,7 @@ printf "LZ4 1.9.2... " SUFFIX="" LZ4_CONFIGURATION="Release" fi - add_runtime_dlls $CONFIGURATION "$(pwd)/LZ4-1.9.2/bin/${LZ4_CONFIGURATION}/liblz4.dll" + add_runtime_dlls $CONFIGURATION "$(pwd)/LZ4_1.9.2/bin/${LZ4_CONFIGURATION}/liblz4.dll" done echo Done. } From 6c591c190bc692b4ed86d9fed8dc5c40a9b2438d Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 21 Aug 2020 17:18:39 +0400 Subject: [PATCH 213/224] Add support for service-specific refusals (feature #5580) --- CHANGELOG.md | 1 + apps/openmw/mwbase/dialoguemanager.hpp | 14 ++++++++++++- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 4 ++-- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 2 +- apps/openmw/mwgui/dialogue.cpp | 20 ++++++++++--------- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 882c8199e..b1888ec7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ Feature #5545: Option to allow stealing from an unconscious NPC during combat Feature #5563: Run physics update in background thread Feature #5579: MCP SetAngle enhancement + Feature #5580: Service refusal filtering Feature #5610: Actors movement should be smoother Feature #5642: Ability to attach arrows to actor skeleton instead of bow mesh Feature #5649: Skyrim SE compressed BSA format support diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index e25762f32..6103921e0 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -76,10 +76,22 @@ namespace MWBase Exhausted = 2 }; + enum ServiceType + { + Any = -1, + Barter = 1, + Repair = 2, + Spells = 3, + Training = 4, + Travel = 5, + Spellmaking = 6, + Enchanting = 7 + }; + virtual std::list getAvailableTopics() = 0; virtual int getTopicFlag(const std::string&) = 0; - virtual bool checkServiceRefused (ResponseCallback* callback) = 0; + virtual bool checkServiceRefused (ResponseCallback* callback, ServiceType service = ServiceType::Any) = 0; virtual void persuade (int type, ResponseCallback* callback) = 0; virtual int getTemporaryDispositionChange () const = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index e3f1796a4..047a910b6 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -551,9 +551,9 @@ namespace MWDialogue mPermanentDispositionChange += delta; } - bool DialogueManager::checkServiceRefused(ResponseCallback* callback) + bool DialogueManager::checkServiceRefused(ResponseCallback* callback, ServiceType service) { - Filter filter (mActor, mChoice, mTalkedTo); + Filter filter (mActor, service, mTalkedTo); const MWWorld::Store &dialogues = MWBase::Environment::get().getWorld()->getStore().get(); diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 77e59b633..6c6eb9a9d 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -86,7 +86,7 @@ namespace MWDialogue void goodbye() override; - bool checkServiceRefused (ResponseCallback* callback) override; + bool checkServiceRefused (ResponseCallback* callback, ServiceType service = ServiceType::Any) override; void say(const MWWorld::Ptr &actor, const std::string &topic) override; diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 8517dfd96..fde029d77 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -362,7 +362,9 @@ namespace MWGui void DialogueWindow::onSelectListItem(const std::string& topic, int id) { - if (mGoodbye || MWBase::Environment::get().getDialogueManager()->isInChoice()) + MWBase::DialogueManager* dialogueManager = MWBase::Environment::get().getDialogueManager(); + + if (mGoodbye || dialogueManager->isInChoice()) return; const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); @@ -389,21 +391,21 @@ namespace MWGui mPersuasionDialog.setVisible(true); else if (topic == sCompanionShare) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion, mPtr); - else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused(mCallback.get())) + else if (!dialogueManager->checkServiceRefused(mCallback.get())) { - if (topic == sBarter) + if (topic == sBarter && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Barter)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter, mPtr); - else if (topic == sSpells) + else if (topic == sSpells && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Spells)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellBuying, mPtr); - else if (topic == sTravel) + else if (topic == sTravel && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Travel)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Travel, mPtr); - else if (topic == sSpellMakingMenuTitle) + else if (topic == sSpellMakingMenuTitle && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Spellmaking)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellCreation, mPtr); - else if (topic == sEnchanting) + else if (topic == sEnchanting && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Enchanting)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting, mPtr); - else if (topic == sServiceTrainingTitle) + else if (topic == sServiceTrainingTitle && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Training)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Training, mPtr); - else if (topic == sRepair) + else if (topic == sRepair && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Repair)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair, mPtr); } else From d39aef3f5a253ed67709ef727f369bc065ef7cd0 Mon Sep 17 00:00:00 2001 From: WW Date: Tue, 20 Oct 2020 15:15:29 +0000 Subject: [PATCH 214/224] Changed `LZ4F_dctx*` to `LZ4F_decompressionContext_t` for better compatibility. --- components/bsa/compressedbsafile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bsa/compressedbsafile.cpp b/components/bsa/compressedbsafile.cpp index bf805e5f7..adc98c454 100644 --- a/components/bsa/compressedbsafile.cpp +++ b/components/bsa/compressedbsafile.cpp @@ -375,7 +375,7 @@ Files::IStreamPtr CompressedBSAFile::getFile(const FileRecord& fileRecord) { boost::scoped_array buffer(new char[size]); fileStream->read(buffer.get(), size); - LZ4F_dctx* context = nullptr; + LZ4F_decompressionContext_t context = nullptr; LZ4F_createDecompressionContext(&context, LZ4F_VERSION); LZ4F_decompressOptions_t options = {}; LZ4F_decompress(context, memoryStreamPtr->getRawData(), &uncompressedSize, buffer.get(), &size, &options); From 09373a757d6b128c3bc86b1f9b1334e180d7bec4 Mon Sep 17 00:00:00 2001 From: psi29a Date: Tue, 20 Oct 2020 09:22:43 +0000 Subject: [PATCH 215/224] Merge branch 'radioactive' into 'master' Container base record mutations See merge request OpenMW/openmw!353 (cherry picked from commit 8b33765dd414680f0074b3e115b52b291b4cb7cb) 275908a0 mutate container base records 16fca11d add changelog entry --- CHANGELOG.md | 1 + apps/openmw/mwbase/world.hpp | 7 ++ apps/openmw/mwclass/container.cpp | 6 ++ apps/openmw/mwclass/container.hpp | 2 + apps/openmw/mwmechanics/actorutil.hpp | 2 + apps/openmw/mwscript/containerextensions.cpp | 87 +++++++++++++++++--- apps/openmw/mwworld/cells.cpp | 52 ++++++++++++ apps/openmw/mwworld/cells.hpp | 2 + apps/openmw/mwworld/containerstore.cpp | 16 ++-- apps/openmw/mwworld/containerstore.hpp | 6 +- apps/openmw/mwworld/inventorystore.cpp | 4 +- apps/openmw/mwworld/inventorystore.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 10 +++ apps/openmw/mwworld/worldimp.hpp | 6 ++ 14 files changed, 181 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 882c8199e..39f6684a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Bug #2069: Fireflies in Fireflies invade Morrowind look wrong Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs Bug #2473: Unable to overstock merchants + Bug #2798: Mutable ESM records Bug #3676: NiParticleColorModifier isn't applied properly Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects Bug #3862: Random container contents behave differently than vanilla diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 70e65e0ea..f9cbc8972 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -36,6 +36,7 @@ namespace ESM struct Position; struct Cell; struct Class; + struct Container; struct Creature; struct Potion; struct Spell; @@ -385,6 +386,10 @@ namespace MWBase ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. /// \return pointer to created record + virtual const ESM::Container *createOverrideRecord (const ESM::Container& record) = 0; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + virtual void update (float duration, bool paused) = 0; virtual void updatePhysics (float duration, bool paused) = 0; @@ -641,6 +646,8 @@ namespace MWBase virtual bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const = 0; virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; + + virtual std::vector getAll(const std::string& id) = 0; }; } diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 9befa0636..a27e3debd 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -27,6 +27,7 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/npcstats.hpp" namespace MWClass @@ -290,6 +291,11 @@ namespace MWClass return !(ref->mBase->mFlags & ESM::Container::Organic); } + void Container::modifyBaseInventory(const std::string& containerId, const std::string& itemId, int amount) const + { + MWMechanics::modifyBaseInventory(containerId, itemId, amount); + } + MWWorld::Ptr Container::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const { const MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 54775e2b0..57dbf0c76 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -84,6 +84,8 @@ namespace MWClass std::string getModel(const MWWorld::ConstPtr &ptr) const override; bool useAnim() const override; + + void modifyBaseInventory(const std::string& containerId, const std::string& itemId, int amount) const override; }; } diff --git a/apps/openmw/mwmechanics/actorutil.hpp b/apps/openmw/mwmechanics/actorutil.hpp index 490dc119a..1e993f560 100644 --- a/apps/openmw/mwmechanics/actorutil.hpp +++ b/apps/openmw/mwmechanics/actorutil.hpp @@ -3,6 +3,7 @@ #include +#include #include #include @@ -83,6 +84,7 @@ namespace MWMechanics template void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value); template void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount); template void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount); + template void modifyBaseInventory(const std::string& containerId, const std::string& itemId, int amount); } #endif diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 7b5bf4730..0af5cee2b 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -19,15 +19,35 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" +#include "../mwclass/container.hpp" + #include "../mwworld/action.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/manualref.hpp" #include "../mwmechanics/actorutil.hpp" #include "ref.hpp" +namespace +{ + void addToStore(MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& ptr, MWWorld::ContainerStore& store, bool resolve = true) + { + if (itemPtr.getClass().getScript(itemPtr).empty()) + { + store.add (itemPtr, count, ptr, true, resolve); + } + else + { + // Adding just one item per time to make sure there isn't a stack of scripted items + for (int i = 0; i < count; i++) + store.add (itemPtr, 1, ptr, true, resolve); + } + } +} + namespace MWScript { namespace Container @@ -60,6 +80,13 @@ namespace MWScript || ::Misc::StringUtils::ciEqual(item, "gold_100")) item = "gold_001"; + // Check if "item" can be placed in a container + MWWorld::ManualRef manualRef(MWBase::Environment::get().getWorld()->getStore(), item, 1); + MWWorld::Ptr itemPtr = manualRef.getPtr(); + bool isLevelledList = itemPtr.getClass().getTypeName() == typeid(ESM::ItemLevList).name(); + if(!isLevelledList) + MWWorld::ContainerStore::getType(itemPtr); + // Explicit calls to non-unique actors affect the base record if(!R::implicit && ptr.getClass().isActor() && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) { @@ -67,19 +94,36 @@ namespace MWScript return; } - MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); - // Create a Ptr for the first added item to recover the item name later - MWWorld::Ptr itemPtr = *store.add (item, 1, ptr); - if (itemPtr.getClass().getScript(itemPtr).empty()) + // Calls to unresolved containers affect the base record + if(ptr.getClass().getTypeName() == typeid(ESM::Container).name() && (!ptr.getRefData().getCustomData() || + !ptr.getClass().getContainerStore(ptr).isResolved())) { - store.add (item, count-1, ptr); - } - else - { - // Adding just one item per time to make sure there isn't a stack of scripted items - for (int i = 1; i < count; i++) - store.add (item, 1, ptr); + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, count); + const ESM::Container* baseRecord = MWBase::Environment::get().getWorld()->getStore().get().find(ptr.getCellRef().getRefId()); + const auto& ptrs = MWBase::Environment::get().getWorld()->getAll(ptr.getCellRef().getRefId()); + for(const auto& container : ptrs) + { + // use the new base record + container.get()->mBase = baseRecord; + if(container.getRefData().getCustomData()) + { + auto& store = container.getClass().getContainerStore(container); + if(isLevelledList) + { + if(store.isResolved()) + { + // TODO #2404 + } + } + else + addToStore(itemPtr, count, ptr, store, store.isResolved()); + } + } + return; } + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); + // TODO #2404 + addToStore(itemPtr, count, ptr, store); // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr() ) @@ -160,7 +204,26 @@ namespace MWScript ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); return; } - + // Calls to unresolved containers affect the base record instead + else if(ptr.getClass().getTypeName() == typeid(ESM::Container).name() && + (!ptr.getRefData().getCustomData() || !ptr.getClass().getContainerStore(ptr).isResolved())) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); + const ESM::Container* baseRecord = MWBase::Environment::get().getWorld()->getStore().get().find(ptr.getCellRef().getRefId()); + const auto& ptrs = MWBase::Environment::get().getWorld()->getAll(ptr.getCellRef().getRefId()); + for(const auto& container : ptrs) + { + container.get()->mBase = baseRecord; + if(container.getRefData().getCustomData()) + { + auto& store = container.getClass().getContainerStore(container); + // Note that unlike AddItem, RemoveItem only removes from unresolved containers + if(!store.isResolved()) + store.remove(item, count, ptr, false); + } + } + return; + } MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); std::string itemName; diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 0603b9de5..94c78b433 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -16,6 +16,50 @@ #include "containerstore.hpp" #include "cellstore.hpp" +namespace +{ + template + bool forEachInStore(const std::string& id, Visitor&& visitor, std::map& cellStore) + { + for(auto& cell : cellStore) + { + if(cell.second.getState() == MWWorld::CellStore::State_Unloaded) + cell.second.preload(); + if(cell.second.getState() == MWWorld::CellStore::State_Preloaded) + { + if(cell.second.hasId(id)) + { + cell.second.load(); + } + else + continue; + } + bool cont = cell.second.forEach([&] (MWWorld::Ptr ptr) + { + if(*ptr.getCellRef().getRefIdPtr() == id) + { + return visitor(ptr); + } + return true; + }); + if(!cont) + return false; + } + return true; + } + + struct PtrCollector + { + std::vector mPtrs; + + bool operator()(MWWorld::Ptr ptr) + { + mPtrs.emplace_back(ptr); + return true; + } + }; +} + MWWorld::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) { if (cell->mData.mFlags & ESM::Cell::Interior) @@ -330,6 +374,14 @@ void MWWorld::Cells::getInteriorPtrs(const std::string &name, std::vector MWWorld::Cells::getAll(const std::string& id) +{ + PtrCollector visitor; + if(forEachInStore(id, visitor, mInteriors)) + forEachInStore(id, visitor, mExteriors); + return visitor.mPtrs; +} + int MWWorld::Cells::countSavedGameRecords() const { int count = 0; diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 3e64ad975..90ede409b 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -80,6 +80,8 @@ namespace MWWorld /// @note name must be lower case void getInteriorPtrs (const std::string& name, std::vector& out); + std::vector getAll(const std::string& id); + int countSavedGameRecords() const; void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 5ecb3dd3a..17eb6a372 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -290,11 +290,11 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string & return add(ref.getPtr(), count, actorPtr); } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool /*allowAutoEquip*/) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool /*allowAutoEquip*/, bool resolve) { Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - MWWorld::ContainerStoreIterator it = addImp(itemPtr, count); + MWWorld::ContainerStoreIterator it = addImp(itemPtr, count, resolve); // The copy of the original item we just made MWWorld::Ptr item = *it; @@ -463,14 +463,15 @@ void MWWorld::ContainerStore::updateRechargingItems() } } -int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const Ptr& actor) +int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const Ptr& actor, bool resolveFirst) { - resolve(); + if(resolveFirst) + resolve(); int toRemove = count; for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter) if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), itemId)) - toRemove -= remove(*iter, toRemove, actor); + toRemove -= removeImp(*iter, toRemove, actor); flagAsModified(); @@ -494,6 +495,11 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor assert(this == item.getContainerStore()); resolve(); + return removeImp(item, count, actor); +} + +int MWWorld::ContainerStore::removeImp(const Ptr& item, int count, const Ptr& actor) +{ int toRemove = count; RefData& itemRef = item.getRefData(); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index c89e855f9..be73603b2 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -129,6 +129,8 @@ namespace MWWorld void addInitialItem (const std::string& id, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true, const std::string& levItem = ""); void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true, const std::string& levItem = ""); + int removeImp(const Ptr& item, int count, const Ptr& actor); + template ContainerStoreIterator getState (CellRefList& collection, const ESM::ObjectState& state); @@ -165,7 +167,7 @@ namespace MWWorld bool hasVisibleItems() const; - virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true); + virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, bool resolve = true); ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) /// /// \note The item pointed to is not required to exist beyond this function call. @@ -178,7 +180,7 @@ namespace MWWorld ContainerStoreIterator add(const std::string& id, int count, const Ptr& actorPtr); ///< Utility to construct a ManualRef and call add(ptr, count, actorPtr, true) - int remove(const std::string& itemId, int count, const Ptr& actor); + int remove(const std::string& itemId, int count, const Ptr& actor, bool resolve = true); ///< Remove \a count item(s) designated by \a itemId from this container. /// /// @return the number of items actually removed diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index cf2b97ce7..c2785579b 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -132,9 +132,9 @@ MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStor return *this; } -MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip) +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip, bool resolve) { - const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, allowAutoEquip); + const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, allowAutoEquip, resolve); // Auto-equip items if an armor/clothing item is added, but not for the player nor werewolves if (allowAutoEquip && actorPtr != MWMechanics::getPlayer() diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 6d669dd45..12306f809 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -125,7 +125,7 @@ namespace MWWorld InventoryStore* clone() override { return new InventoryStore(*this); } - ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true) override; + ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, bool resolve = true) override; ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) /// Auto-equip items if specific conditions are fulfilled and allowAutoEquip is true (see the implementation). /// diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index dcd282f8d..dbe6af326 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1735,6 +1735,11 @@ namespace MWWorld return mStore.overrideRecord(record); } + const ESM::Container *World::createOverrideRecord(const ESM::Container &record) + { + return mStore.overrideRecord(record); + } + const ESM::NPC *World::createRecord(const ESM::NPC &record) { bool update = false; @@ -3910,4 +3915,9 @@ namespace MWWorld ESM::EpochTimeStamp currentDate = mCurrentDate->getEpochTimeStamp(); mRendering->skySetDate(currentDate.mDay, currentDate.mMonth); } + + std::vector World::getAll(const std::string& id) + { + return mCells.getAll(id); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index c10c7ea5a..909ac1d41 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -488,6 +488,10 @@ namespace MWWorld ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. /// \return pointer to created record + const ESM::Container *createOverrideRecord (const ESM::Container& record) override; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + void update (float duration, bool paused) override; void updatePhysics (float duration, bool paused) override; @@ -733,6 +737,8 @@ namespace MWWorld bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const override; void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; + + std::vector getAll(const std::string& id) override; }; } From f62905eb0a068944dbff8cbde133e99ba9b42bba Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Tue, 20 Oct 2020 21:04:35 +0200 Subject: [PATCH 216/224] remove redundant argument --- apps/openmw/mwworld/containerstore.cpp | 12 ++++++------ apps/openmw/mwworld/containerstore.hpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 17eb6a372..3852b1abe 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -550,7 +550,7 @@ void MWWorld::ContainerStore::fillNonRandom (const ESM::InventoryList& items, co } void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count, - Misc::Rng::Seed* seed, bool topLevel, const std::string& levItem) + Misc::Rng::Seed* seed, bool topLevel) { if (count == 0) return; //Don't restock with nothing. try @@ -558,13 +558,13 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count); if (ref.getPtr().getClass().getScript(ref.getPtr()).empty()) { - addInitialItemImp(ref.getPtr(), owner, count, seed, topLevel, levItem); + addInitialItemImp(ref.getPtr(), owner, count, seed, topLevel); } else { // Adding just one item per time to make sure there isn't a stack of scripted items for (int i = 0; i < std::abs(count); i++) - addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, seed, topLevel, levItem); + addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, seed, topLevel); } } catch (const std::exception& e) @@ -574,7 +574,7 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std:: } void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, int count, - Misc::Rng::Seed* seed, bool topLevel, const std::string& levItem) + Misc::Rng::Seed* seed, bool topLevel) { if (ptr.getTypeName()==typeid (ESM::ItemLevList).name()) { @@ -585,7 +585,7 @@ void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const s if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each) { for (int i=0; i 0 ? 1 : -1, seed, true, levItemList->mId); + addInitialItem(ptr.getCellRef().getRefId(), owner, count > 0 ? 1 : -1, seed, true); return; } else @@ -593,7 +593,7 @@ void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const s std::string itemId = MWMechanics::getLevelledItem(ptr.get()->mBase, false, *seed); if (itemId.empty()) return; - addInitialItem(itemId, owner, count, seed, false, levItemList->mId); + addInitialItem(itemId, owner, count, seed, false); } } else diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index be73603b2..9092d41fc 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -126,8 +126,8 @@ namespace MWWorld std::weak_ptr mResolutionListener; ContainerStoreIterator addImp (const Ptr& ptr, int count, bool markModified = true); - void addInitialItem (const std::string& id, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true, const std::string& levItem = ""); - void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true, const std::string& levItem = ""); + void addInitialItem (const std::string& id, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true); + void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true); int removeImp(const Ptr& item, int count, const Ptr& actor); From 0719b75307404f02e4ed6bf702ca74a79bd22c2f Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 20 Oct 2020 22:28:09 +0200 Subject: [PATCH 217/224] try to use brew version of lz4 --- CI/before_install.osx.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 9edfdf0d2..28acae13c 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -4,6 +4,7 @@ command -v ccache >/dev/null 2>&1 || brew install ccache command -v cmake >/dev/null 2>&1 || brew install cmake command -v qmake >/dev/null 2>&1 || brew install qt +command -v lz4 >/dev/null 2>&1 || brew install lz4 -curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-20201016.zip -o ~/openmw-deps.zip +curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null From c3b464a0c82d9a8ce0761054109d6374013af7c5 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 20 Oct 2020 23:00:37 +0200 Subject: [PATCH 218/224] brew reinstall lz4; purge /tmp/openmw-deps just in case --- CI/before_install.osx.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 28acae13c..c6cf797e0 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -4,7 +4,8 @@ command -v ccache >/dev/null 2>&1 || brew install ccache command -v cmake >/dev/null 2>&1 || brew install cmake command -v qmake >/dev/null 2>&1 || brew install qt -command -v lz4 >/dev/null 2>&1 || brew install lz4 +brew reinstall lz4 curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip +rm -fr /tmp/openmw-deps unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null From 8b5aa4c00151ad8908f95b1517ddb3bb7e3553ca Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 20 Oct 2020 23:06:08 +0200 Subject: [PATCH 219/224] try for link overwriting --- CI/before_install.osx.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index c6cf797e0..5285e4e9a 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -4,6 +4,8 @@ command -v ccache >/dev/null 2>&1 || brew install ccache command -v cmake >/dev/null 2>&1 || brew install cmake command -v qmake >/dev/null 2>&1 || brew install qt +brew link --overwrite --dry-run lz4 +brew link --overwrite lz4 brew reinstall lz4 curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip From 06689cfe2a0f627058cc95fd5c3dacbc144ddbfb Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 20 Oct 2020 23:22:37 +0200 Subject: [PATCH 220/224] bingo; cleanup --- CI/before_install.osx.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CI/before_install.osx.sh b/CI/before_install.osx.sh index 5285e4e9a..fd77e0693 100755 --- a/CI/before_install.osx.sh +++ b/CI/before_install.osx.sh @@ -4,10 +4,9 @@ command -v ccache >/dev/null 2>&1 || brew install ccache command -v cmake >/dev/null 2>&1 || brew install cmake command -v qmake >/dev/null 2>&1 || brew install qt -brew link --overwrite --dry-run lz4 -brew link --overwrite lz4 + +brew link --overwrite lz4 # overwrite system lz4; use brew brew reinstall lz4 curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip -rm -fr /tmp/openmw-deps unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null From c86094e4dbaf758831e6b04081b597c042ac64b1 Mon Sep 17 00:00:00 2001 From: psi29a Date: Thu, 8 Oct 2020 18:25:01 +0000 Subject: [PATCH 221/224] Bump to C++17 --- CI/before_script.osx.sh | 2 +- CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 0eeef60a4..e11ef1b58 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -13,7 +13,7 @@ cmake \ -D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH" \ -D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ -D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE" \ --D CMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" \ +-D CMAKE_CXX_FLAGS="-stdlib=libc++" \ -D CMAKE_C_FLAGS_RELEASE="-g -O0" \ -D CMAKE_CXX_FLAGS_RELEASE="-g -O0" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.12" \ diff --git a/CMakeLists.txt b/CMakeLists.txt index c4002ea50..7c4322d64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,7 +416,7 @@ endif() if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef -Wno-unused-parameter -std=c++14 -pedantic -Wno-long-long") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef -Wno-unused-parameter -std=c++17 -pedantic -Wno-long-long") add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS=ON ) if (APPLE) From c62546fb12e10d85d591eb13cadc2fa29c98c9d5 Mon Sep 17 00:00:00 2001 From: psi29a Date: Thu, 8 Oct 2020 18:43:55 +0000 Subject: [PATCH 222/224] make it count --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c4322d64..ac74f5f2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -394,7 +394,7 @@ if (NOT WIN32 AND NOT APPLE) endif() # CXX Compiler settings -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) if(OPENMW_LTO_BUILD) if(NOT CMAKE_VERSION VERSION_LESS 3.9) From 82431b752d1b58ee39372f0cd48c6b94c800d104 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Fri, 9 Oct 2020 06:50:17 +0200 Subject: [PATCH 223/224] removed unnessary bits that cmake should be doing for us; replace Misc::gcd with std::gcd --- CMakeLists.txt | 2 +- apps/launcher/graphicspage.cpp | 5 +++-- apps/openmw/mwgui/settingswindow.cpp | 4 ++-- components/CMakeLists.txt | 2 +- components/misc/gcd.hpp | 13 ------------- 5 files changed, 7 insertions(+), 19 deletions(-) delete mode 100644 components/misc/gcd.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ac74f5f2c..87551fe01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,7 +416,7 @@ endif() if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef -Wno-unused-parameter -std=c++17 -pedantic -Wno-long-long") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef -Wno-unused-parameter -pedantic -Wno-long-long") add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS=ON ) if (APPLE) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index c745332dc..d7e7eabc5 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -13,12 +13,13 @@ #include +#include + #include -#include QString getAspect(int x, int y) { - int gcd = Misc::gcd (x, y); + int gcd = std::gcd (x, y); int xaspect = x / gcd; int yaspect = y / gcd; // special case: 8 : 5 is usually referred to as 16:10 diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index aec3396a1..c5fa17ca4 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -10,10 +10,10 @@ #include #include +#include #include #include -#include #include #include #include @@ -60,7 +60,7 @@ namespace std::string getAspect (int x, int y) { - int gcd = Misc::gcd (x, y); + int gcd = std::gcd (x, y); int xaspect = x / gcd; int yaspect = y / gcd; // special case: 8 : 5 is usually referred to as 16:10 diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index c399a7010..69d8145f0 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -86,7 +86,7 @@ add_component_dir (esmterrain ) add_component_dir (misc - gcd constants utf8stream stringops resourcehelpers rng messageformatparser weakcache + constants utf8stream stringops resourcehelpers rng messageformatparser weakcache ) add_component_dir (debug diff --git a/components/misc/gcd.hpp b/components/misc/gcd.hpp deleted file mode 100644 index fd9e972e7..000000000 --- a/components/misc/gcd.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MISC_GCD_H -#define MISC_GCD_H - -namespace Misc -{ - // TODO: replace to the std::gcd() when the C++17 will be available. - int gcd(int a, int b) - { - return b == 0 ? a : gcd(b, a % b); - } -} - -#endif From bdcd2bc802ca423b6b476c73c4c74fb3d871c4bf Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 21 Oct 2020 17:21:28 +0200 Subject: [PATCH 224/224] Allow adding levelled lists with AddItem --- CHANGELOG.md | 1 + apps/openmw/mwscript/containerextensions.cpp | 35 +++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39f6684a9..b0128af4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ Bug #5644: Summon effects running on the player during game initialization cause crashes Feature #390: 3rd person look "over the shoulder" Feature #2386: Distant Statics in the form of Object Paging + Feature #2404: Levelled List can not be placed into a container Feature #4894: Consider actors as obstacles for pathfinding Feature #5043: Head Bobbing Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 0af5cee2b..2e78fe374 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -28,12 +28,13 @@ #include "../mwworld/manualref.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/levelledlist.hpp" #include "ref.hpp" namespace { - void addToStore(MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& ptr, MWWorld::ContainerStore& store, bool resolve = true) + void addToStore(const MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& ptr, MWWorld::ContainerStore& store, bool resolve = true) { if (itemPtr.getClass().getScript(itemPtr).empty()) { @@ -46,6 +47,30 @@ namespace store.add (itemPtr, 1, ptr, true, resolve); } } + + void addRandomToStore(const MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& owner, MWWorld::ContainerStore& store, bool topLevel = true) + { + if(itemPtr.getTypeName() == typeid(ESM::ItemLevList).name()) + { + const ESM::ItemLevList* levItemList = itemPtr.get()->mBase; + + if(topLevel && count > 1 && levItemList->mFlags & ESM::ItemLevList::Each) + { + for(int i = 0; i < count; i++) + addRandomToStore(itemPtr, 1, owner, store, true); + } + else + { + std::string itemId = MWMechanics::getLevelledItem(itemPtr.get()->mBase, false); + if (itemId.empty()) + return; + MWWorld::ManualRef manualRef(MWBase::Environment::get().getWorld()->getStore(), itemId, 1); + addRandomToStore(manualRef.getPtr(), count, owner, store, false); + } + } + else + addToStore(itemPtr, count, owner, store); + } } namespace MWScript @@ -112,7 +137,7 @@ namespace MWScript { if(store.isResolved()) { - // TODO #2404 + addRandomToStore(itemPtr, count, ptr, store); } } else @@ -122,8 +147,10 @@ namespace MWScript return; } MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); - // TODO #2404 - addToStore(itemPtr, count, ptr, store); + if(isLevelledList) + addRandomToStore(itemPtr, count, ptr, store); + else + addToStore(itemPtr, count, ptr, store); // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr() )