diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0855633af..810e23d38 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,12 +13,12 @@ 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`" - 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) @@ -32,53 +32,60 @@ stages: Debian_GCC: extends: .Debian cache: - key: Debian_GCC.v1 + key: Debian_GCC.v2 variables: CC: gcc CXX: g++ + CCACHE_SIZE: 3G + # When CCache doesn't exist (e.g. first build on a fork), build takes more than 1h, which is the default for forks. + timeout: 2h Debian_GCC_tests: extends: .Debian cache: - key: Debian_GCC_tests.v1 + key: Debian_GCC_tests.v2 variables: CC: gcc CXX: g++ + CCACHE_SIZE: 1G BUILD_TESTS_ONLY: 1 Debian_Clang: extends: .Debian cache: - key: Debian_Clang.v1 + key: Debian_Clang.v2 variables: CC: clang CXX: clang++ + CCACHE_SIZE: 2G Debian_Clang_tests: extends: .Debian cache: - key: Debian_Clang_tests.v1 + key: Debian_Clang_tests.v2 variables: CC: clang CXX: clang++ + CCACHE_SIZE: 1G BUILD_TESTS_ONLY: 1 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 + 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 + - for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.dmg"; done artifacts: paths: - build/OpenMW-*.dmg + - "build/**/*.log" variables: &engine-targets targets: "openmw,openmw-essimporter,openmw-iniimporter,openmw-launcher,openmw-wizard" @@ -91,7 +98,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/Chocolately/" --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 @@ -115,6 +122,8 @@ variables: &cs-targets Get-ChildItem -Recurse *.pdb | Remove-Item } - 7z a -tzip ..\..\OpenMW_MSVC2019_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.zip '*' + after_script: + - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log cache: key: ninja-v2 paths: @@ -181,7 +190,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/Chocolately/" --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 @@ -203,6 +212,8 @@ Windows_Ninja_CS_RelWithDebInfo: Get-ChildItem -Recurse *.pdb | Remove-Item } - 7z a -tzip ..\..\OpenMW_MSVC2019_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.zip '*' + after_script: + - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log cache: key: msbuild-v2 paths: @@ -263,3 +274,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/ diff --git a/.travis.yml b/.travis.yml index 8d98d0dd4..e84a9ad71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,19 +2,12 @@ language: cpp branches: only: - master - - coverity_scan - /openmw-.*$/ -env: - global: - # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created - # via the "travis encrypt" command using the project repo's public key - - secure: "jybGzAdUbqt9vWR/GEnRd96BgAi/7Zd1+2HK68j/i/8+/1YH2XxLOy4Jv/DUBhBlJIkxs/Xv8dRcUlFOclZDHX1d/9Qnsqd3oUVkD7k1y7cTOWy9TBQaE/v/kZo3LpzA3xPwwthrb0BvqIbOfIELi5fS5s8ba85WFRg3AX70wWE=" cache: ccache addons: apt: sources: - sourceline: 'ppa:openmw/openmw' - # - ubuntu-toolchain-r-test # for GCC-10 packages: [ # Dev build-essential, cmake, clang-tools, ccache, @@ -23,32 +16,21 @@ 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, + 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. - project: - name: "OpenMW/openmw" - description: "" - branch_pattern: coverity_scan - notification_email: 1122069+psi29a@users.noreply.github.com - build_command_prepend: "cov-configure --comptype gcc --compiler gcc-5 --template; cmake . -DBUILD_OPENMW=FALSE -DBUILD_OPENCS=FALSE" - build_command: "make VERBOSE=1 -j3" matrix: include: - name: OpenMW (all) on MacOS 10.15 with Xcode 11.6 os: osx osx_image: xcode11.6 - if: branch != coverity_scan - name: OpenMW (all) on Ubuntu Focal with GCC 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 @@ -57,30 +39,21 @@ matrix: env: - MATRIX_EVAL="CC=clang && CXX=clang++" - ANALYZE="scan-build --force-analyze-debug-code --use-cc clang --use-c++ clang++" - if: branch != coverity_scan compiler: clang - - name: OpenMW Components Coverity Scan - os: linux - dist: focal - if: branch = coverity_scan -# allow_failures: -# - name: OpenMW (openmw) on Ubuntu Focal with GCC-10 -# env: -# - MATRIX_EVAL="CC=gcc-10 && CXX=g++-10" before_install: - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then eval "${MATRIX_EVAL}"; fi - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./CI/before_install.${TRAVIS_OS_NAME}.sh; fi + - ./CI/before_install.${TRAVIS_OS_NAME}.sh before_script: - ccache -z - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./CI/before_script.${TRAVIS_OS_NAME}.sh; fi + - ./CI/before_script.${TRAVIS_OS_NAME}.sh 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}" = "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 + - ${ANALYZE} make -j3; + - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi + - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi + - if [ "${TRAVIS_OS_NAME}" = "linux" ] && [ "${BUILD_TESTS_ONLY}" ]; then ./openmw_test_suite; fi + - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi - cd "${TRAVIS_BUILD_DIR}" - ccache -s deploy: diff --git a/AUTHORS.md b/AUTHORS.md index 25004078e..09ab78412 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -96,6 +96,7 @@ Programmers Jan Borsodi (am0s) Jason Hooks (jhooks) jeaye + jefetienne Jeffrey Haines (Jyby) Jengerer Jiří Kuneš (kunesj) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc0b2848c..f0c6dd5ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,17 @@ 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 #2798: Mutable ESM records + Bug #2976 [reopened]: Issues combining settings from the command line and both config files Bug #3676: NiParticleColorModifier isn't applied properly Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects + Bug #3789: Crash in visitEffectSources while in battle + 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 #4083: Door animation freezes when colliding with actors 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 @@ -29,6 +36,7 @@ Bug #5403: Enchantment effect doesn't show on an enemy during death animation Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work Bug #5416: Junk non-node records before the root node are not handled gracefully + Bug #5422: The player loses all spells when resurrected Bug #5424: Creatures do not headtrack player Bug #5425: Poison effect only appears for one frame Bug #5427: GetDistance unknown ID error is misleading @@ -50,21 +58,39 @@ 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 #5604: Only one valid NIF root node is loaded from a single file 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 #5633: Damage Spells in effect before god mode is enabled continue to hurt the player character and can kill them + Bug #5639: Tooltips cover Messageboxes + Bug #5644: Summon effects running on the player during game initialization cause crashes + Bug #5656: Sneaking characters block hits while standing + Bug #5661: Region sounds don't play at the right interval + Bug #5688: Water shader broken indoors with enable indoor shadows = false + Bug #5703: OpenMW-CS menu system crashing on XFCE 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 Feature #5362: Show the soul gems' trapped soul in count dialog Feature #5445: Handle NiLines + Feature #5456: Basic collada animation support 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) 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 + Feature #5672: Make stretch menu background configuration more accessible + Feature #5692: Improve spell/magic item search to factor in magic effect names Task #5480: Drop Qt4 support Task #5520: Improve cell name autocompleter implementation diff --git a/CHANGELOG_PR.md b/CHANGELOG_PR.md index 0a039ec3f..6a16b7658 100644 --- a/CHANGELOG_PR.md +++ b/CHANGELOG_PR.md @@ -18,6 +18,7 @@ Known Issues: New Features: - Dialogue to split item stacks now displays the name of the trapped soul for stacks of soul gems (#5362) +- Basics of Collada animations are now supported via osgAnimation plugin (#5456) New Editor Features: - ? @@ -34,6 +35,7 @@ Bug Fixes: Editor Bug Fixes: - Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400) +- Flicker and crashing on XFCE4 fixed (#5703) Miscellaneous: - Prevent save-game bloating by using an appropriate fog texture format (#5108) 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_install.osx.sh b/CI/before_install.osx.sh index 5dae1f102..85434fa06 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 +curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-f8918dd.zip -o ~/openmw-deps.zip unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /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/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 8b3ece2bd..0ef67f47e 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.7z" \ + "lz4_win${BITS}_v1_9_2.7z" + # Google test and mock if [ ! -z $TEST_FRAMEWORK ]; then echo "Google test 1.10.0..." @@ -901,6 +906,31 @@ 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.7z -o$(real_pwd)/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}/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. +} +cd $DEPS +echo # Google Test and Google Mock if [ ! -z $TEST_FRAMEWORK ]; then printf "Google test 1.10.0 ..." diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 993de79fe..8f9be16e1 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -13,10 +13,10 @@ 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.9" \ +-D CMAKE_OSX_DEPLOYMENT_TARGET="10.12" \ -D CMAKE_BUILD_TYPE=RELEASE \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D BUILD_OPENMW=TRUE \ @@ -25,5 +25,6 @@ cmake \ -D BUILD_BSATOOL=TRUE \ -D BUILD_ESSIMPORTER=TRUE \ -D BUILD_NIFTEST=TRUE \ +-D BULLET_USE_DOUBLES=TRUE \ -G"Unix Makefiles" \ .. diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b6836237..76764fbd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ project(OpenMW) cmake_minimum_required(VERSION 3.1.0) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # for link time optimization, remove if cmake version is >= 3.9 if(POLICY CMP0069) @@ -152,6 +154,8 @@ endif() # Dependencies find_package(OpenGL REQUIRED) +find_package(LZ4 REQUIRED) + if (USE_QT) find_package(Qt5Core 5.12 REQUIRED) find_package(Qt5Widgets REQUIRED) @@ -255,7 +259,7 @@ if(NOT HAVE_STDINT_H) endif() -find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgParticle osgUtil osgFX osgShadow) +find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgParticle osgUtil osgFX osgShadow osgAnimation) include_directories(SYSTEM ${OPENSCENEGRAPH_INCLUDE_DIRS}) set(USED_OSG_PLUGINS @@ -304,7 +308,7 @@ endif() set(Boost_NO_BOOST_CMAKE ON) -find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) +find_package(Boost 1.6.2 REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(MyGUI 3.2.2 REQUIRED) find_package(SDL2 2.0.9 REQUIRED) find_package(OpenAL REQUIRED) @@ -391,9 +395,6 @@ if (NOT WIN32 AND NOT APPLE) "${OpenMW_BINARY_DIR}/org.openmw.cs.desktop") endif() -# CXX Compiler settings -set(CMAKE_CXX_STANDARD 14) - if(OPENMW_LTO_BUILD) if(NOT CMAKE_VERSION VERSION_LESS 3.9) include(CheckIPOSupported) @@ -414,7 +415,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 -pedantic -Wno-long-long") add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS=ON ) if (APPLE) @@ -431,6 +432,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) @@ -586,6 +591,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}") @@ -829,7 +838,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}" ) @@ -882,7 +895,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(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" diff --git a/apps/bsatool/bsatool.cpp b/apps/bsatool/bsatool.cpp index ed86a3a42..3afbd777f 100644 --- a/apps/bsatool/bsatool.cpp +++ b/apps/bsatool/bsatool.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #define BSATOOL_VERSION 1.1 @@ -25,16 +26,6 @@ struct Arguments bool fullpath; }; -void replaceAll(std::string& str, const std::string& needle, const std::string& substitute) -{ - size_t pos = str.find(needle); - while(pos != std::string::npos) - { - str.replace(pos, needle.size(), substitute); - pos = str.find(needle); - } -} - bool parseOptions (int argc, char** argv, Arguments &info) { bpo::options_description desc("Inspect and extract files from Bethesda BSA archives\n\n" @@ -144,9 +135,9 @@ bool parseOptions (int argc, char** argv, Arguments &info) return true; } -int list(Bsa::BSAFile& bsa, Arguments& info); -int extract(Bsa::BSAFile& bsa, Arguments& info); -int extractAll(Bsa::BSAFile& bsa, Arguments& info); +int list(std::unique_ptr& bsa, Arguments& info); +int extract(std::unique_ptr& bsa, Arguments& info); +int extractAll(std::unique_ptr& bsa, Arguments& info); int main(int argc, char** argv) { @@ -157,8 +148,16 @@ int main(int argc, char** argv) return 1; // Open file - Bsa::BSAFile bsa; - bsa.open(info.filename); + std::unique_ptr bsa; + + Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(info.filename); + + if (bsaVersion == Bsa::BSAVER_COMPRESSED) + bsa = std::make_unique(Bsa::CompressedBSAFile()); + else + bsa = std::make_unique(Bsa::BSAFile()); + + bsa->open(info.filename); if (info.mode == "list") return list(bsa, info); @@ -179,10 +178,10 @@ int main(int argc, char** argv) } } -int list(Bsa::BSAFile& bsa, Arguments& info) +int list(std::unique_ptr& bsa, Arguments& info) { // List all files - const Bsa::BSAFile::FileList &files = bsa.getList(); + const Bsa::BSAFile::FileList &files = bsa->getList(); for (const auto& file : files) { if(info.longformat) @@ -201,15 +200,15 @@ int list(Bsa::BSAFile& bsa, Arguments& info) return 0; } -int extract(Bsa::BSAFile& bsa, Arguments& info) +int extract(std::unique_ptr& bsa, Arguments& info) { std::string archivePath = info.extractfile; - replaceAll(archivePath, "/", "\\"); + Misc::StringUtils::replaceAll(archivePath, "/", "\\"); std::string extractPath = info.extractfile; - replaceAll(extractPath, "\\", "/"); + Misc::StringUtils::replaceAll(extractPath, "\\", "/"); - if (!bsa.exists(archivePath.c_str())) + if (!bsa->exists(archivePath.c_str())) { std::cout << "ERROR: file '" << archivePath << "' not found\n"; std::cout << "In archive: " << info.filename << std::endl; @@ -237,7 +236,7 @@ int extract(Bsa::BSAFile& bsa, Arguments& info) } // Get a stream for the file to extract - Files::IStreamPtr stream = bsa.getFile(archivePath.c_str()); + Files::IStreamPtr stream = bsa->getFile(archivePath.c_str()); bfs::ofstream out(target, std::ios::binary); @@ -250,12 +249,12 @@ int extract(Bsa::BSAFile& bsa, Arguments& info) return 0; } -int extractAll(Bsa::BSAFile& bsa, Arguments& info) +int extractAll(std::unique_ptr& bsa, Arguments& info) { - for (const auto &file : bsa.getList()) + for (const auto &file : bsa->getList()) { std::string extractPath(file.name); - replaceAll(extractPath, "\\", "/"); + Misc::StringUtils::replaceAll(extractPath, "\\", "/"); // Get the target path (the path the file will be extracted to) bfs::path target (info.outdir); @@ -273,7 +272,7 @@ int extractAll(Bsa::BSAFile& bsa, Arguments& info) // Get a stream for the file to extract // (inefficient because getFile iter on the list again) - Files::IStreamPtr data = bsa.getFile(file.name); + Files::IStreamPtr data = bsa->getFile(file.name); bfs::ofstream out(target, std::ios::binary); // Write the file to disk diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 2e929faf5..b35e78639 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 @@ -133,6 +136,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); } @@ -148,6 +152,7 @@ bool Launcher::AdvancedPage::loadSettings() // 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(stretchBackgroundCheckBox, "stretch menu background", "GUI"); } // Bug fixes @@ -208,6 +213,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 @@ -247,6 +255,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)) @@ -269,6 +278,7 @@ void Launcher::AdvancedPage::saveSettings() int showOwnedCurrentIndex = showOwnedComboBox->currentIndex(); if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game")) mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex); + saveSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI"); } // Bug fixes diff --git a/apps/launcher/advancedpage.hpp b/apps/launcher/advancedpage.hpp index bdf5af0c8..ef2f4740f 100644 --- a/apps/launcher/advancedpage.hpp +++ b/apps/launcher/advancedpage.hpp @@ -20,7 +20,7 @@ namespace Launcher public: AdvancedPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, - Settings::Manager &engineSettings, QWidget *parent = 0); + Settings::Manager &engineSettings, QWidget *parent = nullptr); bool loadSettings(); void saveSettings(); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index af54fe75e..92984847e 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -32,7 +32,7 @@ namespace Launcher public: explicit DataFilesPage (Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, - Config::LauncherSettings &launcherSettings, QWidget *parent = 0); + Config::LauncherSettings &launcherSettings, QWidget *parent = nullptr); QAbstractItemModel* profilesModel() const; 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/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 3b03a72bd..55178e0d7 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -20,7 +20,7 @@ namespace Launcher Q_OBJECT public: - GraphicsPage(Files::ConfigurationManager &cfg, Settings::Manager &engineSettings, QWidget *parent = 0); + GraphicsPage(Files::ConfigurationManager &cfg, Settings::Manager &engineSettings, QWidget *parent = nullptr); void saveSettings(); bool loadSettings(); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d88a41117..df2ba6891 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -211,10 +211,10 @@ void Launcher::MainDialog::setVersionLabel() versionLabel->setText(tr("OpenMW development (%1)").arg(revision.left(10))); // Add the compile date and time - versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), - QLatin1String("MMM d yyyy")).toString(Qt::SystemLocaleLongDate), - QLocale(QLocale::C).toTime(QString(__TIME__).simplified(), - QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate))); + auto compileDate = QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), QLatin1String("MMM d yyyy")); + auto compileTime = QLocale(QLocale::C).toTime(QString(__TIME__).simplified(), QLatin1String("hh:mm:ss")); + versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale::system().toString(compileDate, QLocale::LongFormat), + QLocale::system().toString(compileTime, QLocale::ShortFormat))); } bool Launcher::MainDialog::setup() diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index d87a43100..de7423330 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -48,7 +48,7 @@ namespace Launcher Q_OBJECT public: - explicit MainDialog(QWidget *parent = 0); + explicit MainDialog(QWidget *parent = nullptr); ~MainDialog(); FirstRunDialogResult showFirstRunDialog(); @@ -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/playpage.hpp b/apps/launcher/playpage.hpp index 1dc5bb0fe..b0bd3ee27 100644 --- a/apps/launcher/playpage.hpp +++ b/apps/launcher/playpage.hpp @@ -16,7 +16,7 @@ namespace Launcher Q_OBJECT public: - PlayPage(QWidget *parent = 0); + PlayPage(QWidget *parent = nullptr); void setProfilesModel(QAbstractItemModel *model); signals: diff --git a/apps/launcher/settingspage.hpp b/apps/launcher/settingspage.hpp index ccc2061dd..97b099dd6 100644 --- a/apps/launcher/settingspage.hpp +++ b/apps/launcher/settingspage.hpp @@ -24,7 +24,7 @@ namespace Launcher public: SettingsPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, - Config::LauncherSettings &launcherSettings, MainDialog *parent = 0); + Config::LauncherSettings &launcherSettings, MainDialog *parent = nullptr); ~SettingsPage(); void saveSettings(); diff --git a/apps/launcher/utils/lineedit.hpp b/apps/launcher/utils/lineedit.hpp index 2dd7da32b..da28e858c 100644 --- a/apps/launcher/utils/lineedit.hpp +++ b/apps/launcher/utils/lineedit.hpp @@ -24,10 +24,10 @@ class LineEdit : public QLineEdit QString mPlaceholderText; public: - LineEdit(QWidget *parent = 0); + LineEdit(QWidget *parent = nullptr); protected: - void resizeEvent(QResizeEvent *); + void resizeEvent(QResizeEvent *) override; private slots: void updateClearButton(const QString &text); diff --git a/apps/launcher/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp index 7df89098e..462c2ebc2 100644 --- a/apps/launcher/utils/profilescombobox.cpp +++ b/apps/launcher/utils/profilescombobox.cpp @@ -33,7 +33,7 @@ void ProfilesComboBox::setEditEnabled(bool editable) ComboBoxLineEdit *edit = new ComboBoxLineEdit(this); setLineEdit(edit); - setCompleter(0); + setCompleter(nullptr); connect(lineEdit(), SIGNAL(editingFinished()), this, SLOT(slotEditingFinished())); diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp index 7b83c41b2..065682f3d 100644 --- a/apps/launcher/utils/profilescombobox.hpp +++ b/apps/launcher/utils/profilescombobox.hpp @@ -16,12 +16,12 @@ public: class ComboBoxLineEdit : public LineEdit { public: - explicit ComboBoxLineEdit (QWidget *parent = 0); + explicit ComboBoxLineEdit (QWidget *parent = nullptr); }; public: - explicit ProfilesComboBox(QWidget *parent = 0); + explicit ProfilesComboBox(QWidget *parent = nullptr); void setEditEnabled(bool editable); void setCurrentProfile(int index) { diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index 385d086fd..70b827596 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -23,7 +23,7 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString & QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore mLineEdit = new LineEdit(this); mLineEdit->setValidator(validator); - mLineEdit->setCompleter(0); + mLineEdit->setCompleter(nullptr); QVBoxLayout *dialogLayout = new QVBoxLayout(this); dialogLayout->addWidget(label); diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index 9eb9c717d..de0659963 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -15,13 +15,13 @@ namespace Launcher public: - explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); + explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = nullptr); ~TextInputDialog (); inline LineEdit *lineEdit() { return mLineEdit; } void setOkButtonEnabled(bool enabled); - int exec(); + int exec() override; private: diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 600b4917a..23aea2deb 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -645,7 +645,7 @@ MwIniImporter::MwIniImporter() } for(int i=0; fallback[i]; i++) { - mMergeFallback.push_back(fallback[i]); + mMergeFallback.emplace_back(fallback[i]); } } @@ -910,7 +910,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co std::time_t time = lastWriteTime(path, defaultTime); if (time != defaultTime) { - contentFiles.push_back({time, path}); + contentFiles.emplace_back(time, std::move(path)); found = true; break; } @@ -985,14 +985,7 @@ std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename std::time_t writeTime(defaultTime); if (boost::filesystem::exists(filename)) { - // FixMe: remove #if when Boost dependency for Linux builds updated - // This allows Linux to build until then -#if (BOOST_VERSION >= 104800) - // need to resolve any symlinks so that we get time of file, not symlink boost::filesystem::path resolved = boost::filesystem::canonical(filename); -#else - boost::filesystem::path resolved = filename; -#endif writeTime = boost::filesystem::last_write_time(resolved); // print timestamp diff --git a/apps/niftest/niftest.cpp b/apps/niftest/niftest.cpp index f848ae330..e9484d5f5 100644 --- a/apps/niftest/niftest.cpp +++ b/apps/niftest/niftest.cpp @@ -132,6 +132,7 @@ int main(int argc, char **argv) if(!parseOptions (argc, argv, files)) return 1; + Nif::NIFFile::setLoadUnsupportedFiles(true); // std::cout << "Reading Files" << std::endl; for(std::vector::const_iterator it=files.begin(); it!=files.end(); ++it) { diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 0c3d006c4..3f53a523f 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -89,10 +89,10 @@ std::pair > CS::Editor::readConfi desc.add_options() ("data", boost::program_options::value()->default_value(Files::EscapePathContainer(), "data")->multitoken()->composing()) - ("data-local", boost::program_options::value()->default_value("")) + ("data-local", boost::program_options::value()->default_value(Files::EscapePath(), "")) ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")) - ("resources", boost::program_options::value()->default_value("resources")) + ("resources", boost::program_options::value()->default_value(Files::EscapePath(), "resources")) ("fallback-archive", boost::program_options::value()-> default_value(Files::EscapeStringVector(), "fallback-archive")->multitoken()) ("fallback", boost::program_options::value()->default_value(FallbackMap(), "") @@ -112,7 +112,7 @@ std::pair > CS::Editor::readConfi mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName)); mFileDialog.setEncoding (QString::fromUtf8(mEncodingName.c_str())); - mDocumentManager.setResourceDir (mResources = variables["resources"].as().toStdString()); + mDocumentManager.setResourceDir (mResources = variables["resources"].as().mPath); if (variables["script-blacklist-use"].as()) mDocumentManager.setBlacklistedScripts ( @@ -125,14 +125,9 @@ std::pair > CS::Editor::readConfi dataDirs = Files::PathContainer(Files::EscapePath::toPathContainer(variables["data"].as())); } - std::string local = variables["data-local"].as().toStdString(); + Files::PathContainer::value_type local(variables["data-local"].as().mPath); if (!local.empty()) - { - if (local.front() == '\"') - local = local.substr(1, local.length() - 2); - - dataLocal.push_back(Files::PathContainer::value_type(local)); - } + dataLocal.push_back(local); mCfgMgr.processPaths (dataDirs); mCfgMgr.processPaths (dataLocal, true); @@ -229,7 +224,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath, const std:: if(discoveredFiles.empty()) { for (const QString &path : mFileDialog.selectedFilePaths()) - files.push_back(path.toUtf8().constData()); + files.emplace_back(path.toUtf8().constData()); } else { @@ -246,7 +241,7 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath) std::vector files; for (const QString &path : mFileDialog.selectedFilePaths()) { - files.push_back(path.toUtf8().constData()); + files.emplace_back(path.toUtf8().constData()); } files.push_back (savePath); diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index 0473291ce..5287c8b19 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 { @@ -47,9 +47,6 @@ int runApplication(int argc, char *argv[]) setenv("OSG_GL_TEXTURE_STORAGE", "OFF", 0); #endif - // To allow background thread drawing in OSG - QApplication::setAttribute(Qt::AA_X11InitThreads, true); - Q_INIT_RESOURCE (resources); qRegisterMetaType ("std::string"); diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index 44d6883ef..69c78bd5e 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -127,7 +127,7 @@ void CSMDoc::Loader::load() void CSMDoc::Loader::loadDocument (CSMDoc::Document *document) { - mDocuments.push_back (std::make_pair (document, Stage())); + mDocuments.emplace_back (document, Stage()); } void CSMDoc::Loader::abortLoading (CSMDoc::Document *document) diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index a27ee9f51..218e13e38 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -57,7 +57,7 @@ void CSMDoc::Operation::run() void CSMDoc::Operation::appendStage (Stage *stage) { - mStages.push_back (std::make_pair (stage, 0)); + mStages.emplace_back (stage, 0); } void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity) diff --git a/apps/opencs/model/doc/operationholder.hpp b/apps/opencs/model/doc/operationholder.hpp index b73d61dab..69af6ed66 100644 --- a/apps/opencs/model/doc/operationholder.hpp +++ b/apps/opencs/model/doc/operationholder.hpp @@ -25,7 +25,7 @@ namespace CSMDoc public: - OperationHolder (Operation *operation = 0); + OperationHolder (Operation *operation = nullptr); void setOperation (Operation *operation); diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 84bc61a9a..ccdff1444 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -8,7 +8,7 @@ #include "operationholder.hpp" CSMDoc::Runner::Runner (const boost::filesystem::path& projectPath) -: mRunning (false), mStartup (0), mProjectPath (projectPath) +: mRunning (false), mStartup (nullptr), mProjectPath (projectPath) { connect (&mProcess, SIGNAL (finished (int, QProcess::ExitStatus)), this, SLOT (finished (int, QProcess::ExitStatus))); @@ -25,7 +25,7 @@ CSMDoc::Runner::~Runner() { if (mRunning) { - disconnect (&mProcess, 0, this, 0); + disconnect (&mProcess, nullptr, this, nullptr); mProcess.kill(); mProcess.waitForFinished(); } @@ -36,7 +36,7 @@ void CSMDoc::Runner::start (bool delayed) if (mStartup) { delete mStartup; - mStartup = 0; + mStartup = nullptr; } if (!delayed) @@ -102,7 +102,7 @@ void CSMDoc::Runner::start (bool delayed) void CSMDoc::Runner::stop() { delete mStartup; - mStartup = 0; + mStartup = nullptr; if (mProcess.state()==QProcess::NotRunning) { 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.cpp b/apps/opencs/model/prefs/boolsetting.cpp index 6431dc6af..005875349 100644 --- a/apps/opencs/model/prefs/boolsetting.cpp +++ b/apps/opencs/model/prefs/boolsetting.cpp @@ -11,7 +11,7 @@ CSMPrefs::BoolSetting::BoolSetting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label, bool default_) -: Setting (parent, values, mutex, key, label), mDefault (default_), mWidget(0) +: Setting (parent, values, mutex, key, label), mDefault (default_), mWidget(nullptr) {} CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip) @@ -33,7 +33,7 @@ std::pair CSMPrefs::BoolSetting::makeWidgets (QWidget *par connect (mWidget, SIGNAL (stateChanged (int)), this, SLOT (valueChanged (int))); - return std::make_pair (static_cast (0), mWidget); + return std::make_pair (static_cast (nullptr), mWidget); } void CSMPrefs::BoolSetting::updateWidget() 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.cpp b/apps/opencs/model/prefs/coloursetting.cpp index 1a41621da..e676ad91c 100644 --- a/apps/opencs/model/prefs/coloursetting.cpp +++ b/apps/opencs/model/prefs/coloursetting.cpp @@ -14,7 +14,7 @@ CSMPrefs::ColourSetting::ColourSetting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label, QColor default_) -: Setting (parent, values, mutex, key, label), mDefault (default_), mWidget(0) +: Setting (parent, values, mutex, key, label), mDefault (default_), mWidget(nullptr) {} CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip) 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.cpp b/apps/opencs/model/prefs/doublesetting.cpp index 8ae6f4818..757b67389 100644 --- a/apps/opencs/model/prefs/doublesetting.cpp +++ b/apps/opencs/model/prefs/doublesetting.cpp @@ -16,7 +16,7 @@ CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *val QMutex *mutex, const std::string& key, const std::string& label, double default_) : Setting (parent, values, mutex, key, label), mPrecision(2), mMin (0), mMax (std::numeric_limits::max()), - mDefault (default_), mWidget(0) + mDefault (default_), mWidget(nullptr) {} CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setPrecision(int precision) 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.cpp b/apps/opencs/model/prefs/enumsetting.cpp index 226b17173..ec3fca328 100644 --- a/apps/opencs/model/prefs/enumsetting.cpp +++ b/apps/opencs/model/prefs/enumsetting.cpp @@ -35,14 +35,14 @@ CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValue& value) CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const std::string& tooltip) { - mValues.push_back (EnumValue (value, tooltip)); + mValues.emplace_back(value, tooltip); return *this; } CSMPrefs::EnumSetting::EnumSetting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label, const EnumValue& default_) -: Setting (parent, values, mutex, key, label), mDefault (default_), mWidget(0) +: Setting (parent, values, mutex, key, label), mDefault (default_), mWidget(nullptr) {} CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip) 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.cpp b/apps/opencs/model/prefs/intsetting.cpp index 25dbf78c2..407ed11f0 100644 --- a/apps/opencs/model/prefs/intsetting.cpp +++ b/apps/opencs/model/prefs/intsetting.cpp @@ -15,7 +15,7 @@ CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label, int default_) : Setting (parent, values, mutex, key, label), mMin (0), mMax (std::numeric_limits::max()), - mDefault (default_), mWidget(0) + mDefault (default_), mWidget(nullptr) {} CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange (int min, int max) 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.cpp b/apps/opencs/model/prefs/modifiersetting.cpp index da6b2ccdd..288926d00 100644 --- a/apps/opencs/model/prefs/modifiersetting.cpp +++ b/apps/opencs/model/prefs/modifiersetting.cpp @@ -15,7 +15,7 @@ namespace CSMPrefs ModifierSetting::ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, const std::string& label) : Setting(parent, values, mutex, key, label) - , mButton(0) + , mButton(nullptr) , mEditorActive(false) { } 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/shortcut.cpp b/apps/opencs/model/prefs/shortcut.cpp index 924b9535e..ff7b949a4 100644 --- a/apps/opencs/model/prefs/shortcut.cpp +++ b/apps/opencs/model/prefs/shortcut.cpp @@ -23,7 +23,7 @@ namespace CSMPrefs , mLastPos(0) , mActivationStatus(AS_Inactive) , mModifierStatus(false) - , mAction(0) + , mAction(nullptr) { assert (parent); @@ -42,7 +42,7 @@ namespace CSMPrefs , mLastPos(0) , mActivationStatus(AS_Inactive) , mModifierStatus(false) - , mAction(0) + , mAction(nullptr) { assert (parent); @@ -62,7 +62,7 @@ namespace CSMPrefs , mLastPos(0) , mActivationStatus(AS_Inactive) , mModifierStatus(false) - , mAction(0) + , mAction(nullptr) { assert (parent); @@ -218,6 +218,6 @@ namespace CSMPrefs void Shortcut::actionDeleted() { - mAction = 0; + mAction = nullptr; } } diff --git a/apps/opencs/model/prefs/shortcuteventhandler.cpp b/apps/opencs/model/prefs/shortcuteventhandler.cpp index 07c48fcaa..a4102e1db 100644 --- a/apps/opencs/model/prefs/shortcuteventhandler.cpp +++ b/apps/opencs/model/prefs/shortcuteventhandler.cpp @@ -182,7 +182,7 @@ namespace CSMPrefs } else if (pos == lastPos) { - potentials.push_back(std::make_pair(result, shortcut)); + potentials.emplace_back(result, shortcut); } } } 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/shortcutmanager.cpp b/apps/opencs/model/prefs/shortcutmanager.cpp index f39492c6c..781ad4de3 100644 --- a/apps/opencs/model/prefs/shortcutmanager.cpp +++ b/apps/opencs/model/prefs/shortcutmanager.cpp @@ -781,7 +781,7 @@ namespace CSMPrefs std::make_pair((int)Qt::Key_LastNumberRedial , "LastNumberRedial"), std::make_pair((int)Qt::Key_Camera , "Camera"), std::make_pair((int)Qt::Key_CameraFocus , "CameraFocus"), - std::make_pair(0 , (const char*) 0) + std::make_pair(0 , (const char*) nullptr) }; } diff --git a/apps/opencs/model/prefs/shortcutsetting.cpp b/apps/opencs/model/prefs/shortcutsetting.cpp index de495b9fc..1c065f7da 100644 --- a/apps/opencs/model/prefs/shortcutsetting.cpp +++ b/apps/opencs/model/prefs/shortcutsetting.cpp @@ -18,7 +18,7 @@ namespace CSMPrefs ShortcutSetting::ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, const std::string& label) : Setting(parent, values, mutex, key, label) - , mButton(0) + , mButton(nullptr) , mEditorActive(false) , mEditorPos(0) { 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/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index abd1ddfc8..39aae48bd 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -12,7 +12,7 @@ #include "shortcutsetting.hpp" #include "modifiersetting.hpp" -CSMPrefs::State *CSMPrefs::State::sThis = 0; +CSMPrefs::State *CSMPrefs::State::sThis = nullptr; void CSMPrefs::State::load() { @@ -599,7 +599,7 @@ CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager) CSMPrefs::State::~State() { - sThis = 0; + sThis = nullptr; } void CSMPrefs::State::save() 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.cpp b/apps/opencs/model/tools/mergestages.cpp index 897c3329c..016e2da39 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -104,7 +104,7 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa ref.mNew = false; CSMWorld::Record newRecord ( - CSMWorld::RecordBase::State_ModifiedOnly, 0, &ref); + CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &ref); mState.mTarget->getData().getReferences().appendRecord (newRecord); } diff --git a/apps/opencs/model/tools/mergestages.hpp b/apps/opencs/model/tools/mergestages.hpp index 4b41c5a04..a6b6de58f 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. }; @@ -82,7 +82,7 @@ namespace CSMTools const CSMWorld::Record& record = source.getRecord (stage); if (!record.isDeleted()) - target.appendRecord (CSMWorld::Record (CSMWorld::RecordBase::State_ModifiedOnly, 0, &record.get())); + target.appendRecord (CSMWorld::Record (CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get())); } class MergeRefIdsStage : public CSMDoc::Stage @@ -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.cpp b/apps/opencs/model/tools/scriptcheck.cpp index 952127edf..46a74362b 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -50,7 +50,7 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, Type type) } CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document) -: mDocument (document), mContext (document.getData()), mMessages (0), mWarningMode (Mode_Ignore) +: mDocument (document), mContext (document.getData()), mMessages (nullptr), mWarningMode (Mode_Ignore) { /// \todo add an option to configure warning mode setWarningsMode (0); @@ -73,7 +73,7 @@ int CSMTools::ScriptCheckStage::setup() mWarningMode = Mode_Strict; mContext.clear(); - mMessages = 0; + mMessages = nullptr; mId.clear(); Compiler::ErrorHandler::reset(); @@ -130,5 +130,5 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages) messages.add (id, stream.str(), "", CSMDoc::Message::Severity_SeriousError); } - mMessages = 0; + mMessages = nullptr; } 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.cpp b/apps/opencs/model/tools/searchstage.cpp index 3db10b0c3..7cd3f4924 100644 --- a/apps/opencs/model/tools/searchstage.cpp +++ b/apps/opencs/model/tools/searchstage.cpp @@ -5,7 +5,7 @@ #include "searchoperation.hpp" CSMTools::SearchStage::SearchStage (const CSMWorld::IdTableBase *model) -: mModel (model), mOperation (0) +: mModel (model), mOperation (nullptr) {} int CSMTools::SearchStage::setup() 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/tools.cpp b/apps/opencs/model/tools/tools.cpp index 07a721e8e..a3d7db497 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -43,7 +43,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::get (int type) case CSMDoc::State_Merging: return &mMerge; } - return 0; + return nullptr; } const CSMDoc::OperationHolder *CSMTools::Tools::get (int type) const @@ -138,8 +138,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() } CSMTools::Tools::Tools (CSMDoc::Document& document, ToUTF8::FromType encoding) -: mDocument (document), mData (document.getData()), mVerifierOperation (0), - mSearchOperation (0), mMergeOperation (0), mNextReportNumber (0), mEncoding (encoding) +: mDocument (document), mData (document.getData()), mVerifierOperation (nullptr), + mSearchOperation (nullptr), mMergeOperation (nullptr), mNextReportNumber (0), mEncoding (encoding) { // index 0: load error log mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); 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..17518937c 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,9 +2252,9 @@ 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; + const std::string *string = nullptr; switch (this->mColumnId) { @@ -2270,9 +2270,9 @@ 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; + std::string *string = nullptr; ESXRecordT record2 = record.get(); @@ -2292,7 +2292,7 @@ namespace CSMWorld record.setModified (record2); } - virtual bool isEditable() const + bool isEditable() const override { return true; } @@ -2310,9 +2310,9 @@ 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; + const std::string *string = nullptr; switch (this->mColumnId) { @@ -2328,9 +2328,9 @@ 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; + std::string *string = nullptr; ESXRecordT record2 = record.get(); @@ -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/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index 2493813a6..36b3ba2e0 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -127,7 +127,7 @@ std::vector CSMWorld::CommandDispatcher::getExtendedTypes if (mId==UniversalId::Type_Cells) { tables.push_back (mId); - tables.push_back (UniversalId::Type_References); + tables.emplace_back(UniversalId::Type_References); /// \todo add other cell-specific types } diff --git a/apps/opencs/model/world/commanddispatcher.hpp b/apps/opencs/model/world/commanddispatcher.hpp index 1d29e48c1..538fd7f18 100644 --- a/apps/opencs/model/world/commanddispatcher.hpp +++ b/apps/opencs/model/world/commanddispatcher.hpp @@ -34,7 +34,7 @@ namespace CSMWorld public: CommandDispatcher (CSMDoc::Document& document, const CSMWorld::UniversalId& id, - QObject *parent = 0); + QObject *parent = nullptr); ///< \param id ID of the table the commands should operate on primarily. void setEditLock (bool locked); diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index e9682d7c9..e33be1139 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -290,7 +290,7 @@ void CSMWorld::CreateCommand::undo() } CSMWorld::RevertCommand::RevertCommand (IdTable& model, const std::string& id, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld (0) +: QUndoCommand (parent), mModel (model), mId (id), mOld (nullptr) { setText (("Revert record " + id).c_str()); @@ -326,7 +326,7 @@ void CSMWorld::RevertCommand::undo() CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, CSMWorld::UniversalId::Type type, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld (0), mType(type) +: QUndoCommand (parent), mModel (model), mId (id), mOld (nullptr), mType(type) { setText (("Delete record " + id).c_str()); diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 58a1b1d1c..5776cae36 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -140,11 +140,11 @@ namespace CSMWorld public: ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class CreateCommand : public QUndoCommand @@ -167,7 +167,7 @@ namespace CSMWorld public: - CreateCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0); + CreateCommand (IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); void setType (UniversalId::Type type); @@ -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 @@ -189,11 +189,11 @@ namespace CSMWorld CloneCommand (IdTable& model, const std::string& idOrigin, const std::string& IdDestination, const UniversalId::Type type, - QUndoCommand* parent = 0); + QUndoCommand* parent = nullptr); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class RevertCommand : public QUndoCommand @@ -208,13 +208,13 @@ namespace CSMWorld public: - RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0); + RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); virtual ~RevertCommand(); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class DeleteCommand : public QUndoCommand @@ -231,13 +231,13 @@ namespace CSMWorld public: DeleteCommand (IdTable& model, const std::string& id, - UniversalId::Type type = UniversalId::Type_None, QUndoCommand *parent = 0); + UniversalId::Type type = UniversalId::Type_None, QUndoCommand *parent = nullptr); virtual ~DeleteCommand(); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class ReorderRowsCommand : public QUndoCommand @@ -250,18 +250,18 @@ 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 { public: - CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand *parent = 0); + CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); - virtual void redo(); + void redo() override; }; /// \brief Update cell ID according to x/y-coordinates @@ -279,11 +279,11 @@ namespace CSMWorld public: - UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent = 0); + UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent = nullptr); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; @@ -316,11 +316,11 @@ namespace CSMWorld public: - DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); + DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; class AddNestedCommand : public QUndoCommand, private NestedTableStoring @@ -338,11 +338,11 @@ namespace CSMWorld public: - AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); + AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); - virtual void redo(); + void redo() override; - virtual void undo(); + void undo() override; }; } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 23720a99a..70c496e3f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -68,7 +68,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, const std::vector& archives, const boost::filesystem::path& resDir) : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), - mReader (0), mDialogue (0), mReaderIndex(1), + mReader (nullptr), mDialogue (nullptr), mReaderIndex(1), mFsStrict(fsStrict), mDataPaths(dataPaths), mArchives(archives) { mVFS.reset(new VFS::Manager(mFsStrict)); @@ -916,7 +916,7 @@ const CSMWorld::MetaData& CSMWorld::Data::getMetaData() const void CSMWorld::Data::setMetaData (const MetaData& metaData) { - Record record (RecordBase::State_ModifiedOnly, 0, &metaData); + Record record (RecordBase::State_ModifiedOnly, nullptr, &metaData); mMetaData.setRecord (0, record); } @@ -932,7 +932,7 @@ QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& // construction of the ESX data where no update signals are available. if (id.getType()==UniversalId::Type_RegionMap) { - RegionMap *table = 0; + RegionMap *table = nullptr; addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, false); return table; } @@ -962,9 +962,9 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base // Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading std::shared_ptr ptr(mReader); mReaders.push_back(ptr); - mReader = 0; + mReader = nullptr; - mDialogue = 0; + mDialogue = nullptr; mReader = new ESM::ESMReader; mReader->setEncoder (&mEncoder); @@ -982,7 +982,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base metaData.mId = "sys::meta"; metaData.load (*mReader); - mMetaData.setRecord (0, Record (RecordBase::State_ModifiedOnly, 0, &metaData)); + mMetaData.setRecord (0, Record (RecordBase::State_ModifiedOnly, nullptr, &metaData)); } // Fix uninitialized master data index @@ -1064,9 +1064,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) else delete mReader; - mReader = 0; + mReader = nullptr; - mDialogue = 0; + mDialogue = nullptr; loadFallbackEntries(); @@ -1151,7 +1151,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) if (isDeleted) { // record vector can be shuffled around which would make pointer to record invalid - mDialogue = 0; + mDialogue = nullptr; if (mJournals.tryDelete (record.mId)) { diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index bc5a8e69d..27d60ae98 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -355,7 +355,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import // If it does not exist or it is in the current plugin, it can be skipped. if (oldRow < 0 || plugin == 0) { - results.recordMapping.push_back(std::make_pair(id, id)); + results.recordMapping.emplace_back(id, id); continue; } @@ -366,7 +366,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import auto searchIt = reverseLookupMap.find(texture); if (searchIt != reverseLookupMap.end()) { - results.recordMapping.push_back(std::make_pair(id, searchIt->second)); + results.recordMapping.emplace_back(id, searchIt->second); continue; } @@ -381,7 +381,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import // Id not taken, clone it cloneRecord(id, newId, UniversalId::Type_LandTexture); results.createdRecords.push_back(newId); - results.recordMapping.push_back(std::make_pair(id, newId)); + results.recordMapping.emplace_back(id, newId); reverseLookupMap.emplace(texture, newId); break; } 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..7e0563834 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -35,11 +35,11 @@ namespace CSMWorld public: - IdTableProxyModel (QObject *parent = 0); + IdTableProxyModel (QObject *parent = nullptr); 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..92afdabdc 100644 --- a/apps/opencs/model/world/infotableproxymodel.hpp +++ b/apps/opencs/model/world/infotableproxymodel.hpp @@ -28,17 +28,17 @@ namespace CSMWorld ///< \a currentRow is a row of the source model. public: - InfoTableProxyModel(UniversalId::Type type, QObject *parent = 0); + InfoTableProxyModel(UniversalId::Type type, QObject *parent = nullptr); - 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..5f67a93b1 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. @@ -87,7 +87,7 @@ namespace CSMWorld template RecordBase *Record::modifiedCopy() const { - return new Record (State_ModifiedOnly, 0, &(this->get())); + return new Record (State_ModifiedOnly, nullptr, &(this->get())); } template diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 1d91bbd59..d8f6b391b 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -64,6 +64,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool // ignore content file number std::map::iterator iter = cache.begin(); + ref.mRefNum.mIndex = ref.mRefNum.mIndex & 0x00ffffff; for (; iter != cache.end(); ++iter) { if (ref.mRefNum.mIndex == iter->first.mIndex) 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.cpp b/apps/opencs/model/world/refidcollection.cpp index 3502d6319..cd2dd89df 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -40,45 +40,45 @@ CSMWorld::RefIdCollection::RefIdCollection() { BaseColumns baseColumns; - mColumns.push_back (RefIdColumn (Columns::ColumnId_Id, ColumnBase::Display_Id, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + mColumns.emplace_back(Columns::ColumnId_Id, ColumnBase::Display_Id, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); baseColumns.mId = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Modification, ColumnBase::Display_RecordState, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false)); + mColumns.emplace_back(Columns::ColumnId_Modification, ColumnBase::Display_RecordState, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false); baseColumns.mModified = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + mColumns.emplace_back(Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); baseColumns.mType = &mColumns.back(); ModelColumns modelColumns (baseColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Model, ColumnBase::Display_Mesh)); + mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh); modelColumns.mModel = &mColumns.back(); NameColumns nameColumns (modelColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Name, ColumnBase::Display_String)); + mColumns.emplace_back(Columns::ColumnId_Name, ColumnBase::Display_String); nameColumns.mName = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Script, ColumnBase::Display_Script)); + mColumns.emplace_back(Columns::ColumnId_Script, ColumnBase::Display_Script); nameColumns.mScript = &mColumns.back(); InventoryColumns inventoryColumns (nameColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Icon, ColumnBase::Display_Icon)); + mColumns.emplace_back(Columns::ColumnId_Icon, ColumnBase::Display_Icon); inventoryColumns.mIcon = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Weight, ColumnBase::Display_Float)); + mColumns.emplace_back(Columns::ColumnId_Weight, ColumnBase::Display_Float); inventoryColumns.mWeight = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_CoinValue, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_CoinValue, ColumnBase::Display_Integer); inventoryColumns.mValue = &mColumns.back(); IngredientColumns ingredientColumns (inventoryColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_EffectList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); ingredientColumns.mEffects = &mColumns.back(); std::map ingredientEffectsMap; ingredientEffectsMap.insert(std::make_pair(UniversalId::Type_Ingredient, new IngredEffectRefIdAdapter ())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), ingredientEffectsMap)); + mNestedAdapters.emplace_back(&mColumns.back(), ingredientEffectsMap); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_IngredEffectId)); mColumns.back().addColumn( @@ -88,13 +88,13 @@ CSMWorld::RefIdCollection::RefIdCollection() // nested table PotionColumns potionColumns (inventoryColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_EffectList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp std::map effectsMap; effectsMap.insert(std::make_pair(UniversalId::Type_Potion, new EffectsRefIdAdapter (UniversalId::Type_Potion))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), effectsMap)); + mNestedAdapters.emplace_back(&mColumns.back(), effectsMap); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mColumns.back().addColumn( @@ -114,67 +114,67 @@ CSMWorld::RefIdCollection::RefIdCollection() EnchantableColumns enchantableColumns (inventoryColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment)); + mColumns.emplace_back(Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment); enchantableColumns.mEnchantment = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer); enchantableColumns.mEnchantmentPoints = &mColumns.back(); ToolColumns toolsColumns (inventoryColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Quality, ColumnBase::Display_Float)); + mColumns.emplace_back(Columns::ColumnId_Quality, ColumnBase::Display_Float); toolsColumns.mQuality = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Charges, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_Charges, ColumnBase::Display_Integer); toolsColumns.mUses = &mColumns.back(); ActorColumns actorsColumns (nameColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger16)); + mColumns.emplace_back(Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger16); actorsColumns.mHello = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFlee, ColumnBase::Display_UnsignedInteger8)); + mColumns.emplace_back(Columns::ColumnId_AiFlee, ColumnBase::Display_UnsignedInteger8); actorsColumns.mFlee = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFight, ColumnBase::Display_UnsignedInteger8)); + mColumns.emplace_back(Columns::ColumnId_AiFight, ColumnBase::Display_UnsignedInteger8); actorsColumns.mFight = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_UnsignedInteger8)); + mColumns.emplace_back(Columns::ColumnId_AiAlarm, ColumnBase::Display_UnsignedInteger8); actorsColumns.mAlarm = &mColumns.back(); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_ActorInventory, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mInventory = &mColumns.back(); std::map inventoryMap; inventoryMap.insert(std::make_pair(UniversalId::Type_Npc, new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); inventoryMap.insert(std::make_pair(UniversalId::Type_Creature, new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap)); + mNestedAdapters.emplace_back(&mColumns.back(), inventoryMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_SpellList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mSpells = &mColumns.back(); std::map spellsMap; spellsMap.insert(std::make_pair(UniversalId::Type_Npc, new NestedSpellRefIdAdapter (UniversalId::Type_Npc))); spellsMap.insert(std::make_pair(UniversalId::Type_Creature, new NestedSpellRefIdAdapter (UniversalId::Type_Creature))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap)); + mNestedAdapters.emplace_back(&mColumns.back(), spellsMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_NpcDestinations, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mDestinations = &mColumns.back(); std::map destMap; destMap.insert(std::make_pair(UniversalId::Type_Npc, new NestedTravelRefIdAdapter (UniversalId::Type_Npc))); destMap.insert(std::make_pair(UniversalId::Type_Creature, new NestedTravelRefIdAdapter (UniversalId::Type_Creature))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap)); + mNestedAdapters.emplace_back(&mColumns.back(), destMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell)); mColumns.back().addColumn( @@ -191,15 +191,15 @@ CSMWorld::RefIdCollection::RefIdCollection() new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Double)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_AiPackageList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_AiPackageList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mAiPackages = &mColumns.back(); std::map aiMap; aiMap.insert(std::make_pair(UniversalId::Type_Npc, new ActorAiRefIdAdapter (UniversalId::Type_Npc))); aiMap.insert(std::make_pair(UniversalId::Type_Creature, new ActorAiRefIdAdapter (UniversalId::Type_Creature))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), aiMap)); + mNestedAdapters.emplace_back(&mColumns.back(), aiMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiPackageType, CSMWorld::ColumnBase::Display_AiPackageType)); mColumns.back().addColumn( @@ -270,56 +270,56 @@ CSMWorld::RefIdCollection::RefIdCollection() for (int i=0; sServiceTable[i].mName!=-1; ++i) { - mColumns.push_back (RefIdColumn (sServiceTable[i].mName, ColumnBase::Display_Boolean)); + mColumns.emplace_back(sServiceTable[i].mName, ColumnBase::Display_Boolean); actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag)); } - mColumns.push_back (RefIdColumn (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); + mColumns.emplace_back(Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); const RefIdColumn *autoCalc = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_ApparatusType, - ColumnBase::Display_ApparatusType)); + mColumns.emplace_back(Columns::ColumnId_ApparatusType, + ColumnBase::Display_ApparatusType); const RefIdColumn *apparatusType = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_ArmorType, ColumnBase::Display_ArmorType)); + mColumns.emplace_back(Columns::ColumnId_ArmorType, ColumnBase::Display_ArmorType); const RefIdColumn *armorType = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Health, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_Health, ColumnBase::Display_Integer); const RefIdColumn *health = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer); const RefIdColumn *armor = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_BookType, ColumnBase::Display_BookType)); + mColumns.emplace_back(Columns::ColumnId_BookType, ColumnBase::Display_BookType); const RefIdColumn *bookType = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Skill, ColumnBase::Display_SkillId)); + mColumns.emplace_back(Columns::ColumnId_Skill, ColumnBase::Display_SkillId); const RefIdColumn *skill = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Text, ColumnBase::Display_LongString)); + mColumns.emplace_back(Columns::ColumnId_Text, ColumnBase::Display_LongString); const RefIdColumn *text = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType)); + mColumns.emplace_back(Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType); const RefIdColumn *clothingType = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_WeightCapacity, ColumnBase::Display_Float)); + mColumns.emplace_back(Columns::ColumnId_WeightCapacity, ColumnBase::Display_Float); const RefIdColumn *weightCapacity = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_OrganicContainer, ColumnBase::Display_Boolean)); + mColumns.emplace_back(Columns::ColumnId_OrganicContainer, ColumnBase::Display_Boolean); const RefIdColumn *organic = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean)); + mColumns.emplace_back(Columns::ColumnId_Respawn, ColumnBase::Display_Boolean); const RefIdColumn *respawn = &mColumns.back(); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_ContainerContent, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); const RefIdColumn *content = &mColumns.back(); std::map contMap; contMap.insert(std::make_pair(UniversalId::Type_Container, new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap)); + mNestedAdapters.emplace_back(&mColumns.back(), contMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( @@ -327,11 +327,11 @@ CSMWorld::RefIdCollection::RefIdCollection() CreatureColumns creatureColumns (actorsColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType)); + mColumns.emplace_back(Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType); creatureColumns.mType = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Scale, ColumnBase::Display_Float)); + mColumns.emplace_back(Columns::ColumnId_Scale, ColumnBase::Display_Float); creatureColumns.mScale = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_ParentCreature, ColumnBase::Display_Creature)); + mColumns.emplace_back(Columns::ColumnId_ParentCreature, ColumnBase::Display_Creature); creatureColumns.mOriginal = &mColumns.back(); static const struct @@ -350,11 +350,11 @@ CSMWorld::RefIdCollection::RefIdCollection() }; // for re-use in NPC records - const RefIdColumn *essential = 0; + const RefIdColumn *essential = nullptr; for (int i=0; sCreatureFlagTable[i].mName!=-1; ++i) { - mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean)); + mColumns.emplace_back(sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean); creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag)); switch (sCreatureFlagTable[i].mFlag) @@ -363,7 +363,7 @@ CSMWorld::RefIdCollection::RefIdCollection() } } - mColumns.push_back(RefIdColumn(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType)); + mColumns.emplace_back(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType); // For re-use in NPC records. const RefIdColumn *bloodType = &mColumns.back(); creatureColumns.mBloodType = bloodType; @@ -371,24 +371,24 @@ CSMWorld::RefIdCollection::RefIdCollection() creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_CreatureAttributes, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_CreatureAttributes, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureColumns.mAttributes = &mColumns.back(); std::map creaAttrMap; creaAttrMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttributesRefIdAdapter())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), creaAttrMap)); + mNestedAdapters.emplace_back(&mColumns.back(), creaAttrMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AttributeValue, CSMWorld::ColumnBase::Display_Integer)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_CreatureAttack, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_CreatureAttack, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureColumns.mAttacks = &mColumns.back(); std::map attackMap; attackMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttackRefIdAdapter())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), attackMap)); + mNestedAdapters.emplace_back(&mColumns.back(), attackMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_CreatureAttack, CSMWorld::ColumnBase::Display_Integer, false, false)); mColumns.back().addColumn( @@ -397,12 +397,12 @@ CSMWorld::RefIdCollection::RefIdCollection() new RefIdColumn (Columns::ColumnId_MaxAttack, CSMWorld::ColumnBase::Display_Integer)); // Nested list - mColumns.push_back(RefIdColumn (Columns::ColumnId_CreatureMisc, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + mColumns.emplace_back(Columns::ColumnId_CreatureMisc, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); creatureColumns.mMisc = &mColumns.back(); std::map creaMiscMap; creaMiscMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureMiscRefIdAdapter())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), creaMiscMap)); + mNestedAdapters.emplace_back(&mColumns.back(), creaMiscMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); @@ -423,27 +423,27 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer)); - mColumns.push_back (RefIdColumn (Columns::ColumnId_OpenSound, ColumnBase::Display_Sound)); + mColumns.emplace_back(Columns::ColumnId_OpenSound, ColumnBase::Display_Sound); const RefIdColumn *openSound = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_CloseSound, ColumnBase::Display_Sound)); + mColumns.emplace_back(Columns::ColumnId_CloseSound, ColumnBase::Display_Sound); const RefIdColumn *closeSound = &mColumns.back(); LightColumns lightColumns (inventoryColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_Duration, ColumnBase::Display_Integer); lightColumns.mTime = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Radius, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_Radius, ColumnBase::Display_Integer); lightColumns.mRadius = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Colour, ColumnBase::Display_Colour)); + mColumns.emplace_back(Columns::ColumnId_Colour, ColumnBase::Display_Colour); lightColumns.mColor = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Sound, ColumnBase::Display_Sound)); + mColumns.emplace_back(Columns::ColumnId_Sound, ColumnBase::Display_Sound); lightColumns.mSound = &mColumns.back(); - mColumns.push_back(RefIdColumn(Columns::ColumnId_EmitterType, ColumnBase::Display_EmitterType)); + mColumns.emplace_back(Columns::ColumnId_EmitterType, ColumnBase::Display_EmitterType); lightColumns.mEmitterType = &mColumns.back(); static const struct @@ -462,31 +462,31 @@ CSMWorld::RefIdCollection::RefIdCollection() for (int i=0; sLightFlagTable[i].mName!=-1; ++i) { - mColumns.push_back (RefIdColumn (sLightFlagTable[i].mName, ColumnBase::Display_Boolean)); + mColumns.emplace_back(sLightFlagTable[i].mName, ColumnBase::Display_Boolean); lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag)); } - mColumns.push_back (RefIdColumn (Columns::ColumnId_IsKey, ColumnBase::Display_Boolean)); + mColumns.emplace_back(Columns::ColumnId_IsKey, ColumnBase::Display_Boolean); const RefIdColumn *key = &mColumns.back(); NpcColumns npcColumns (actorsColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Race, ColumnBase::Display_Race)); + mColumns.emplace_back(Columns::ColumnId_Race, ColumnBase::Display_Race); npcColumns.mRace = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Class, ColumnBase::Display_Class)); + mColumns.emplace_back(Columns::ColumnId_Class, ColumnBase::Display_Class); npcColumns.mClass = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction)); + mColumns.emplace_back(Columns::ColumnId_Faction, ColumnBase::Display_Faction); npcColumns.mFaction = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::Columnid_Hair, ColumnBase::Display_BodyPart)); + mColumns.emplace_back(Columns::Columnid_Hair, ColumnBase::Display_BodyPart); npcColumns.mHair = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Head, ColumnBase::Display_BodyPart)); + mColumns.emplace_back(Columns::ColumnId_Head, ColumnBase::Display_BodyPart); npcColumns.mHead = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc)); + mColumns.emplace_back(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc); npcColumns.mGender = &mColumns.back(); npcColumns.mFlags.insert (std::make_pair (essential, ESM::NPC::Essential)); @@ -503,36 +503,36 @@ CSMWorld::RefIdCollection::RefIdCollection() // These needs to be driven from the autocalculated setting. // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcAttributes, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_NpcAttributes, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); npcColumns.mAttributes = &mColumns.back(); std::map attrMap; attrMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcAttributesRefIdAdapter())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), attrMap)); + mNestedAdapters.emplace_back(&mColumns.back(), attrMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcSkills, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_NpcSkills, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); npcColumns.mSkills = &mColumns.back(); std::map skillsMap; skillsMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcSkillsRefIdAdapter())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), skillsMap)); + mNestedAdapters.emplace_back(&mColumns.back(), skillsMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Skill, CSMWorld::ColumnBase::Display_SkillId, false, false)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8)); // Nested list - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcMisc, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + mColumns.emplace_back(Columns::ColumnId_NpcMisc, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); npcColumns.mMisc = &mColumns.back(); std::map miscMap; miscMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcMiscRefIdAdapter())); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), miscMap)); + mNestedAdapters.emplace_back(&mColumns.back(), miscMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16)); mColumns.back().addColumn( @@ -554,15 +554,15 @@ CSMWorld::RefIdCollection::RefIdCollection() WeaponColumns weaponColumns (enchantableColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); + mColumns.emplace_back(Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType); weaponColumns.mType = &mColumns.back(); weaponColumns.mHealth = health; - mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponSpeed, ColumnBase::Display_Float)); + mColumns.emplace_back(Columns::ColumnId_WeaponSpeed, ColumnBase::Display_Float); weaponColumns.mSpeed = &mColumns.back(); - mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponReach, ColumnBase::Display_Float)); + mColumns.emplace_back(Columns::ColumnId_WeaponReach, ColumnBase::Display_Float); weaponColumns.mReach = &mColumns.back(); for (int i=0; i<3; ++i) @@ -572,8 +572,7 @@ CSMWorld::RefIdCollection::RefIdCollection() for (int j=0; j<2; ++j) { - mColumns.push_back ( - RefIdColumn (Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer)); + mColumns.emplace_back(Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer); column[j] = &mColumns.back(); } } @@ -591,19 +590,19 @@ CSMWorld::RefIdCollection::RefIdCollection() for (int i=0; sWeaponFlagTable[i].mName!=-1; ++i) { - mColumns.push_back (RefIdColumn (sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean)); + mColumns.emplace_back(sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean); weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag)); } // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); const RefIdColumn *partRef = &mColumns.back(); std::map partMap; partMap.insert(std::make_pair(UniversalId::Type_Armor, new BodyPartRefIdAdapter (UniversalId::Type_Armor))); partMap.insert(std::make_pair(UniversalId::Type_Clothing, new BodyPartRefIdAdapter (UniversalId::Type_Clothing))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), partMap)); + mNestedAdapters.emplace_back(&mColumns.back(), partMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); mColumns.back().addColumn( @@ -614,30 +613,30 @@ CSMWorld::RefIdCollection::RefIdCollection() LevListColumns levListColumns (baseColumns); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.emplace_back(Columns::ColumnId_LevelledList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); levListColumns.mLevList = &mColumns.back(); std::map levListMap; levListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, new NestedLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); levListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, new NestedLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), levListMap)); + mNestedAdapters.emplace_back(&mColumns.back(), levListMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); // Nested list - mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + mColumns.emplace_back(Columns::ColumnId_LevelledList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); levListColumns.mNestedListLevList = &mColumns.back(); std::map nestedListLevListMap; nestedListLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, new NestedListLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); nestedListLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, new NestedListLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); - mNestedAdapters.push_back (std::make_pair(&mColumns.back(), nestedListLevListMap)); + mNestedAdapters.emplace_back(&mColumns.back(), nestedListLevListMap); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemTypeEach, CSMWorld::ColumnBase::Display_Boolean)); mColumns.back().addColumn( 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/resources.hpp b/apps/opencs/model/world/resources.hpp index 5e9872ea8..c217b793d 100644 --- a/apps/opencs/model/world/resources.hpp +++ b/apps/opencs/model/world/resources.hpp @@ -25,9 +25,9 @@ namespace CSMWorld /// \param type Type of resources in this table. Resources (const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, - const char * const *extensions = 0); + const char * const *extensions = nullptr); - void recreate(const VFS::Manager* vfs, const char * const *extensions = 0); + void recreate(const VFS::Manager* vfs, const char * const *extensions = nullptr); int getSize() const; 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/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp index 91e308236..cec9ca229 100644 --- a/apps/opencs/view/doc/adjusterwidget.hpp +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -32,7 +32,7 @@ namespace CSVDoc public: - AdjusterWidget (QWidget *parent = 0); + AdjusterWidget (QWidget *parent = nullptr); void setLocalData (const boost::filesystem::path& localData); void setAction (ContentAction action); diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 7a3fe398f..69490edca 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -18,7 +18,7 @@ #include "adjusterwidget.hpp" CSVDoc::FileDialog::FileDialog(QWidget *parent) : - QDialog(parent), mSelector (0), mAction(ContentAction_Undefined), mFileWidget (0), mAdjusterWidget (0), mDialogBuilt(false) + QDialog(parent), mSelector (nullptr), mAction(ContentAction_Undefined), mFileWidget (nullptr), mAdjusterWidget (nullptr), mDialogBuilt(false) { ui.setupUi (this); resize(400, 400); diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index bec2c6869..6c48fa78b 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -42,7 +42,7 @@ namespace CSVDoc public: - explicit FileDialog(QWidget *parent = 0); + explicit FileDialog(QWidget *parent = nullptr); void showDialog (ContentAction action); void addFiles (const QString &path); diff --git a/apps/opencs/view/doc/filewidget.hpp b/apps/opencs/view/doc/filewidget.hpp index ab06f37f1..626b8d77d 100644 --- a/apps/opencs/view/doc/filewidget.hpp +++ b/apps/opencs/view/doc/filewidget.hpp @@ -23,7 +23,7 @@ namespace CSVDoc public: - FileWidget (QWidget *parent = 0); + FileWidget (QWidget *parent = nullptr); void setType (bool addon); diff --git a/apps/opencs/view/doc/globaldebugprofilemenu.cpp b/apps/opencs/view/doc/globaldebugprofilemenu.cpp index f0d9655dd..c898b819c 100644 --- a/apps/opencs/view/doc/globaldebugprofilemenu.cpp +++ b/apps/opencs/view/doc/globaldebugprofilemenu.cpp @@ -13,7 +13,7 @@ void CSVDoc::GlobalDebugProfileMenu::rebuild() clear(); delete mActions; - mActions = 0; + mActions = nullptr; int idColumn = mDebugProfiles->findColumnIndex (CSMWorld::Columns::ColumnId_Id); int stateColumn = mDebugProfiles->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); @@ -48,7 +48,7 @@ void CSVDoc::GlobalDebugProfileMenu::rebuild() CSVDoc::GlobalDebugProfileMenu::GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, QWidget *parent) -: QMenu (parent), mDebugProfiles (debugProfiles), mActions (0) +: QMenu (parent), mDebugProfiles (debugProfiles), mActions (nullptr) { rebuild(); diff --git a/apps/opencs/view/doc/globaldebugprofilemenu.hpp b/apps/opencs/view/doc/globaldebugprofilemenu.hpp index 0d7906cce..e12ee306a 100644 --- a/apps/opencs/view/doc/globaldebugprofilemenu.hpp +++ b/apps/opencs/view/doc/globaldebugprofilemenu.hpp @@ -26,7 +26,7 @@ namespace CSVDoc public: - GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, QWidget *parent = 0); + GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, QWidget *parent = nullptr); void updateActions (bool running); diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index 49a53e179..1cdfc0173 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -17,7 +17,7 @@ void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) } CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) -: mDocument (document), mAborted (false), mMessages (0), mTotalRecords (0) +: mDocument (document), mAborted (false), mMessages (nullptr), mTotalRecords (0) { setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str())); 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..14ec7b186 100644 --- a/apps/opencs/view/doc/sizehint.hpp +++ b/apps/opencs/view/doc/sizehint.hpp @@ -11,10 +11,10 @@ namespace CSVDoc QSize mSize; public: - SizeHintWidget(QWidget *parent = 0); + SizeHintWidget(QWidget *parent = nullptr); ~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.cpp b/apps/opencs/view/doc/view.cpp index ac7c8ebf9..be3fe5142 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -733,7 +733,7 @@ void CSVDoc::View::infoAbout() #endif // Get current year - time_t now = time(NULL); + time_t now = time(nullptr); struct tm tstruct; char copyrightInfo[40]; tstruct = *localtime(&now); 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/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 70431107f..8424be6f8 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -43,7 +43,7 @@ namespace CSVDoc ViewManager& operator= (const ViewManager&); void updateIndices(); - bool notifySaveOnClose (View *view = 0); + bool notifySaveOnClose (View *view = nullptr); bool showModifiedDocumentMessageBox (View *view); bool showSaveInProgressMessageBox (View *view); bool removeDocument(View *view); diff --git a/apps/opencs/view/filter/editwidget.hpp b/apps/opencs/view/filter/editwidget.hpp index b47a884a3..f933ec92e 100644 --- a/apps/opencs/view/filter/editwidget.hpp +++ b/apps/opencs/view/filter/editwidget.hpp @@ -30,7 +30,7 @@ namespace CSVFilter public: - EditWidget (CSMWorld::Data& data, QWidget *parent = 0); + EditWidget (CSMWorld::Data& data, QWidget *parent = nullptr); void createFilterRequest(std::vector > >& filterSource, Qt::DropAction action); diff --git a/apps/opencs/view/filter/filterbox.hpp b/apps/opencs/view/filter/filterbox.hpp index e794a9880..94b5fced3 100644 --- a/apps/opencs/view/filter/filterbox.hpp +++ b/apps/opencs/view/filter/filterbox.hpp @@ -25,7 +25,7 @@ namespace CSVFilter RecordFilterBox *mRecordFilterBox; public: - FilterBox (CSMWorld::Data& data, QWidget *parent = 0); + FilterBox (CSMWorld::Data& data, QWidget *parent = nullptr); void setRecordFilter (const std::string& filter); @@ -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/filter/recordfilterbox.hpp b/apps/opencs/view/filter/recordfilterbox.hpp index 77a07c92b..3bcd7c57b 100644 --- a/apps/opencs/view/filter/recordfilterbox.hpp +++ b/apps/opencs/view/filter/recordfilterbox.hpp @@ -25,7 +25,7 @@ namespace CSVFilter public: - RecordFilterBox (CSMWorld::Data& data, QWidget *parent = 0); + RecordFilterBox (CSMWorld::Data& data, QWidget *parent = nullptr); void setFilter (const std::string& 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/keybindingpage.cpp b/apps/opencs/view/prefs/keybindingpage.cpp index eed5c0eb8..39c9f78ec 100644 --- a/apps/opencs/view/prefs/keybindingpage.cpp +++ b/apps/opencs/view/prefs/keybindingpage.cpp @@ -16,9 +16,9 @@ namespace CSVPrefs { KeyBindingPage::KeyBindingPage(CSMPrefs::Category& category, QWidget* parent) : PageBase(category, parent) - , mStackedLayout(0) - , mPageLayout(0) - , mPageSelector(0) + , mStackedLayout(nullptr) + , mPageLayout(nullptr) + , mPageSelector(nullptr) { // Need one widget for scroll area QWidget* topWidget = new QWidget(); 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..75d83cf63 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()); @@ -504,12 +504,12 @@ void CSVRender::Cell::setCellArrows (int mask) bool enable = mask & direction; - if (enable!=(mCellArrows[i].get()!=0)) + if (enable!=(mCellArrows[i].get()!=nullptr)) { if (enable) mCellArrows[i].reset (new CellArrow (mCellNode, direction, mCoordinates)); else - mCellArrows[i].reset (0); + mCellArrows[i].reset (nullptr); } } } @@ -553,7 +553,7 @@ std::vector > CSVRender::Cell::getSelection (un result.push_back (iter->second->getTag()); if (mPathgrid && elementMask & Mask_Pathgrid) if (mPathgrid->isSelected()) - result.push_back(mPathgrid->getTag()); + result.emplace_back(mPathgrid->getTag()); return result; } 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/cellwater.cpp b/apps/opencs/view/render/cellwater.cpp index 435178860..f8857c3af 100644 --- a/apps/opencs/view/render/cellwater.cpp +++ b/apps/opencs/view/render/cellwater.cpp @@ -27,9 +27,9 @@ namespace CSVRender : mData(data) , mId(id) , mParentNode(cellNode) - , mWaterTransform(0) - , mWaterNode(0) - , mWaterGeometry(0) + , mWaterTransform(nullptr) + , mWaterNode(nullptr) + , mWaterGeometry(nullptr) , mDeleted(false) , mExterior(false) , mHasWater(false) @@ -137,7 +137,7 @@ namespace CSVRender if (mWaterGeometry) { mWaterNode->removeDrawable(mWaterGeometry); - mWaterGeometry = 0; + mWaterGeometry = nullptr; } if (mDeleted || !mHasWater) diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 911594327..52c35811d 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -30,11 +30,11 @@ namespace CSVRender public: EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, unsigned int mask, - const QString& tooltip = "", QWidget *parent = 0); + const QString& tooltip = "", QWidget *parent = nullptr); 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.cpp b/apps/opencs/view/render/instancemode.cpp index 987dea437..19018fae6 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -98,7 +98,7 @@ osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos) CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr parentNode, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), Mask_Reference | Mask_Terrain, "Instance editing", - parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None), + parent), mSubMode (nullptr), mSubModeId ("move"), mSelectionMode (nullptr), mDragMode (DragMode_None), mDragAxis (-1), mLocked (false), mUnitScaleDist(1), mParentNode (parentNode) { connect(this, SIGNAL(requestFocus(const std::string&)), @@ -169,14 +169,14 @@ void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar) { toolbar->removeTool (mSelectionMode); delete mSelectionMode; - mSelectionMode = 0; + mSelectionMode = nullptr; } if (mSubMode) { toolbar->removeTool (mSubMode); delete mSubMode; - mSubMode = 0; + mSubMode = nullptr; } EditMode::deactivate (toolbar); diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index beb60aff3..32dd4ac67 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -62,43 +62,43 @@ namespace CSVRender public: - InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr parentNode, QWidget *parent = 0); + InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr parentNode, QWidget *parent = nullptr); - 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/instancemovemode.hpp b/apps/opencs/view/render/instancemovemode.hpp index bd0e28dac..62e6b6a1f 100644 --- a/apps/opencs/view/render/instancemovemode.hpp +++ b/apps/opencs/view/render/instancemovemode.hpp @@ -11,7 +11,7 @@ namespace CSVRender public: - InstanceMoveMode (QWidget *parent = 0); + InstanceMoveMode (QWidget *parent = nullptr); }; } 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/lighting.hpp b/apps/opencs/view/render/lighting.hpp index 66b0eec00..d9d90767f 100644 --- a/apps/opencs/view/render/lighting.hpp +++ b/apps/opencs/view/render/lighting.hpp @@ -16,7 +16,7 @@ namespace CSVRender { public: - Lighting() : mRootNode(0) {} + Lighting() : mRootNode(nullptr) {} virtual ~Lighting(); virtual void activate (osg::Group* rootNode, bool isExterior) = 0; 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.cpp b/apps/opencs/view/render/object.cpp index f9d2c8872..2bb537d74 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -413,7 +413,7 @@ osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode, const std::string& id, bool referenceable, bool forceBaseToZero) -: mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero), +: mData (data), mBaseNode(nullptr), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero), mScaleOverride (1), mOverrideFlags (0), mSubMode (-1), mMarkerTransparency(0.5f) { mRootNode = new osg::PositionAttitudeTransform; 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.cpp b/apps/opencs/view/render/orbitcameramode.cpp index ba25beaba..79ac0167a 100644 --- a/apps/opencs/view/render/orbitcameramode.cpp +++ b/apps/opencs/view/render/orbitcameramode.cpp @@ -13,7 +13,7 @@ namespace CSVRender QWidget* parent) : ModeButton(icon, tooltip, parent) , mWorldspaceWidget(worldspaceWidget) - , mCenterOnSelection(0) + , mCenterOnSelection(nullptr) { mCenterShortcut = new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget); mCenterShortcut->enable(false); @@ -35,7 +35,7 @@ namespace CSVRender void OrbitCameraMode::deactivate(CSVWidget::SceneToolbar* toolbar) { - mCenterShortcut->associateAction(0); + mCenterShortcut->associateAction(nullptr); mCenterShortcut->enable(false); } 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.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b5d9234e4..dca5549af 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -787,7 +787,7 @@ CSVRender::Cell* CSVRender::PagedWorldspaceWidget::getCell(const osg::Vec3d& poi if (searchResult != mCells.end()) return searchResult->second; else - return 0; + return nullptr; } CSVRender::Cell* CSVRender::PagedWorldspaceWidget::getCell(const CSMWorld::CellCoordinates& coords) const 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..470a3d092 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(); @@ -60,8 +60,8 @@ namespace CSVRender , mRemoveGeometry(false) , mUseOffset(true) , mParent(parent) - , mPathgridGeometry(0) - , mDragGeometry(0) + , mPathgridGeometry(nullptr) + , mDragGeometry(nullptr) , mTag(new PathgridTag(this)) { const float CoordScalar = ESM::Land::REAL_SIZE; @@ -219,7 +219,7 @@ namespace CSVRender mMoveOffset.set(0, 0, 0); mPathgridGeode->removeDrawable(mDragGeometry); - mDragGeometry = 0; + mDragGeometry = nullptr; } void Pathgrid::applyPoint(CSMWorld::CommandMacro& commands, const osg::Vec3d& worldPos) @@ -557,7 +557,7 @@ namespace CSVRender if (mPathgridGeometry) { mPathgridGeode->removeDrawable(mPathgridGeometry); - mPathgridGeometry = 0; + mPathgridGeometry = nullptr; } } @@ -566,7 +566,7 @@ namespace CSVRender if (mSelectedGeometry) { mPathgridGeode->removeDrawable(mSelectedGeometry); - mSelectedGeometry = 0; + mSelectedGeometry = nullptr; } } @@ -612,7 +612,7 @@ namespace CSVRender return &mPathgridCollection.getRecord(index).get(); } - return 0; + return nullptr; } int Pathgrid::edgeExists(const CSMWorld::Pathgrid& source, unsigned short node1, unsigned short node2) 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.cpp b/apps/opencs/view/render/pathgridmode.cpp index 8863ad235..7a3fc8ecf 100644 --- a/apps/opencs/view/render/pathgridmode.cpp +++ b/apps/opencs/view/render/pathgridmode.cpp @@ -27,7 +27,7 @@ namespace CSVRender getTooltip(), parent) , mDragMode(DragMode_None) , mFromNode(0) - , mSelectionMode(0) + , mSelectionMode(nullptr) { } @@ -59,7 +59,7 @@ namespace CSVRender { toolbar->removeTool (mSelectionMode); delete mSelectionMode; - mSelectionMode = 0; + mSelectionMode = nullptr; } } @@ -214,7 +214,7 @@ namespace CSVRender Cell* cell = getWorldspaceWidget().getCell(hit.worldPos); if (cell && cell->getPathgrid()) { - PathgridTag* tag = 0; + PathgridTag* tag = nullptr; if (hit.tag && (tag = dynamic_cast(hit.tag.get())) && tag->getPathgrid()->getId() == mEdgeId) { unsigned short node = SceneUtil::getPathgridNode(static_cast(hit.index0)); diff --git a/apps/opencs/view/render/pathgridmode.hpp b/apps/opencs/view/render/pathgridmode.hpp index a012a67e4..cc61dfe9b 100644 --- a/apps/opencs/view/render/pathgridmode.hpp +++ b/apps/opencs/view/render/pathgridmode.hpp @@ -15,33 +15,33 @@ namespace CSVRender public: - PathgridMode(WorldspaceWidget* worldspace, QWidget* parent=0); + PathgridMode(WorldspaceWidget* worldspace, QWidget* parent=nullptr); - 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/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 630ccf293..a8d73729a 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -29,7 +29,7 @@ namespace CSVRender public: PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, - QWidget *parent = 0); + QWidget *parent = nullptr); signals: diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 9ef068a28..d45b9daaa 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -37,7 +37,7 @@ namespace CSVRender RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) - , mRootNode(0) + , mRootNode(nullptr) { osgViewer::CompositeViewer& viewer = CompositeViewer::get(); @@ -258,7 +258,7 @@ void SceneWidget::setLighting(Lighting *lighting) mLighting = lighting; mLighting->activate (mRootNode, mIsExterior); - osg::Vec4f ambient = mLighting->getAmbientColour(mHasDefaultAmbient ? &mDefaultAmbient : 0); + osg::Vec4f ambient = mLighting->getAmbientColour(mHasDefaultAmbient ? &mDefaultAmbient : nullptr); setAmbient(ambient); flagAsModified(); 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/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index 5664378ca..e495d2355 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -99,7 +99,7 @@ void CSVRender::TerrainShapeMode::primaryOpenPressed (const WorldspaceHitResult& void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult& hit) { - if (hit.hit && hit.tag == 0) + if (hit.hit && hit.tag == nullptr) { if (mShapeEditTool == ShapeEditTool_Flatten) setFlattenToolTargetHeight(hit); @@ -124,7 +124,7 @@ void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult& void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == 0) + if(hit.hit && hit.tag == nullptr) { selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, false); } @@ -132,7 +132,7 @@ void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult void CSVRender::TerrainShapeMode::secondarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == 0) + if(hit.hit && hit.tag == nullptr) { selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, false); } @@ -144,7 +144,7 @@ bool CSVRender::TerrainShapeMode::primaryEditStartDrag (const QPoint& pos) mDragMode = InteractionType_PrimaryEdit; - if (hit.hit && hit.tag == 0) + if (hit.hit && hit.tag == nullptr) { mEditingPos = hit.worldPos; mIsEditing = true; @@ -164,7 +164,7 @@ bool CSVRender::TerrainShapeMode::primarySelectStartDrag (const QPoint& pos) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_PrimarySelect; - if (!hit.hit || hit.tag != 0) + if (!hit.hit || hit.tag != nullptr) { mDragMode = InteractionType_None; return false; @@ -177,7 +177,7 @@ bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_SecondarySelect; - if (!hit.hit || hit.tag != 0) + if (!hit.hit || hit.tag != nullptr) { mDragMode = InteractionType_None; return false; @@ -202,13 +202,13 @@ void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, if (mDragMode == InteractionType_PrimarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == 0) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true); + if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0, true); } if (mDragMode == InteractionType_SecondarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == 0) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true); + if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1, true); } } diff --git a/apps/opencs/view/render/terrainshapemode.hpp b/apps/opencs/view/render/terrainshapemode.hpp index d0fec764f..a88e60c9c 100644 --- a/apps/opencs/view/render/terrainshapemode.hpp +++ b/apps/opencs/view/render/terrainshapemode.hpp @@ -59,38 +59,38 @@ namespace CSVRender /// Editmode for terrain shape grid TerrainShapeMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); - void primaryOpenPressed (const WorldspaceHitResult& hit) final; + void primaryOpenPressed (const WorldspaceHitResult& hit) override; /// Create single command for one-click shape editing - void primaryEditPressed (const WorldspaceHitResult& hit) final; + void primaryEditPressed (const WorldspaceHitResult& hit) override; /// Open brush settings window - void primarySelectPressed(const WorldspaceHitResult&) final; + void primarySelectPressed(const WorldspaceHitResult&) override; - void secondarySelectPressed(const WorldspaceHitResult&) final; + void secondarySelectPressed(const WorldspaceHitResult&) override; - void activate(CSVWidget::SceneToolbar*) final; - void deactivate(CSVWidget::SceneToolbar*) final; + void activate(CSVWidget::SceneToolbar*) override; + void deactivate(CSVWidget::SceneToolbar*) override; /// Start shape editing command macro - bool primaryEditStartDrag (const QPoint& pos) final; + bool primaryEditStartDrag (const QPoint& pos) override; - bool secondaryEditStartDrag (const QPoint& pos) final; - bool primarySelectStartDrag (const QPoint& pos) final; - bool secondarySelectStartDrag (const QPoint& pos) final; + bool secondaryEditStartDrag (const QPoint& pos) override; + bool primarySelectStartDrag (const QPoint& pos) override; + bool secondarySelectStartDrag (const QPoint& pos) override; /// Handle shape edit behavior during dragging - void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) final; + void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; /// End shape editing command macro - void dragCompleted(const QPoint& pos) final; + void dragCompleted(const QPoint& pos) override; /// Cancel shape editing, and reset all pending changes - void dragAborted() final; + void dragAborted() override; - void dragWheel (int diff, double speedFactor) final; - void dragMoveEvent (QDragMoveEvent *event) final; - void mouseMoveEvent (QMouseEvent *event) final; + void dragWheel (int diff, double speedFactor) override; + void dragMoveEvent (QDragMoveEvent *event) override; + void mouseMoveEvent (QMouseEvent *event) override; private: diff --git a/apps/opencs/view/render/terrainstorage.hpp b/apps/opencs/view/render/terrainstorage.hpp index 74c30ce5c..762eb8003 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); @@ -27,10 +27,10 @@ namespace CSVRender const CSMWorld::Data& mData; std::array mAlteredHeight; - osg::ref_ptr getLand (int cellX, int cellY) final; - const ESM::LandTexture* getLandTexture(int index, short plugin) final; + osg::ref_ptr getLand (int cellX, int cellY) override; + const ESM::LandTexture* getLandTexture(int index, short plugin) override; - void getBounds(float& minX, float& maxX, float& minY, float& maxY) final; + void getBounds(float& minX, float& maxX, float& minY, float& maxY) override; int getThisHeight(int col, int row, const ESM::Land::LandData *heightData) const; int getLeftHeight(int col, int row, const ESM::Land::LandData *heightData) const; @@ -44,8 +44,8 @@ namespace CSVRender bool leftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; bool rightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; - void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const final; - float getAlteredHeight(int col, int row) const final; + void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const override; + float getAlteredHeight(int col, int row) const override; }; } diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index ae5711881..c8d63f32e 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -119,7 +119,7 @@ void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult CSMWorld::IdCollection& landtexturesCollection = document.getData().getLandTextures(); int index = landtexturesCollection.searchId(mBrushTexture); - if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == 0) + if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == nullptr) { undoStack.beginMacro ("Edit texture records"); if(allowLandTextureEditing(mCellId)) @@ -133,7 +133,7 @@ void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == 0) + if(hit.hit && hit.tag == nullptr) { selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, false); } @@ -141,7 +141,7 @@ void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResu void CSVRender::TerrainTextureMode::secondarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == 0) + if(hit.hit && hit.tag == nullptr) { selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, false); } @@ -166,7 +166,7 @@ bool CSVRender::TerrainTextureMode::primaryEditStartDrag (const QPoint& pos) CSMWorld::IdCollection& landtexturesCollection = document.getData().getLandTextures(); int index = landtexturesCollection.searchId(mBrushTexture); - if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == 0) + if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == nullptr) { undoStack.beginMacro ("Edit texture records"); mIsEditing = true; @@ -189,7 +189,7 @@ bool CSVRender::TerrainTextureMode::primarySelectStartDrag (const QPoint& pos) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_PrimarySelect; - if (!hit.hit || hit.tag != 0) + if (!hit.hit || hit.tag != nullptr) { mDragMode = InteractionType_None; return false; @@ -202,7 +202,7 @@ bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_SecondarySelect; - if (!hit.hit || hit.tag != 0) + if (!hit.hit || hit.tag != nullptr) { mDragMode = InteractionType_None; return false; @@ -222,7 +222,7 @@ void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diff CSMWorld::IdCollection& landtexturesCollection = document.getData().getLandTextures(); int index = landtexturesCollection.searchId(mBrushTexture); - if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == 0) + if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == nullptr) { editTerrainTextureGrid(hit); } @@ -231,13 +231,13 @@ void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diff if (mDragMode == InteractionType_PrimarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == 0) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, true); + if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0, true); } if (mDragMode == InteractionType_SecondarySelect) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == 0) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, true); + if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1, true); } } diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index 0d8c4a94a..31932df21 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -53,37 +53,37 @@ namespace CSVRender /// \brief Editmode for terrain texture grid TerrainTextureMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); - void primaryOpenPressed (const WorldspaceHitResult& hit) final; + void primaryOpenPressed (const WorldspaceHitResult& hit) override; /// \brief Create single command for one-click texture editing - void primaryEditPressed (const WorldspaceHitResult& hit) final; + void primaryEditPressed (const WorldspaceHitResult& hit) override; /// \brief Open brush settings window - void primarySelectPressed(const WorldspaceHitResult&) final; + void primarySelectPressed(const WorldspaceHitResult&) override; - void secondarySelectPressed(const WorldspaceHitResult&) final; + void secondarySelectPressed(const WorldspaceHitResult&) override; - void activate(CSVWidget::SceneToolbar*) final; - void deactivate(CSVWidget::SceneToolbar*) final; + void activate(CSVWidget::SceneToolbar*) override; + void deactivate(CSVWidget::SceneToolbar*) override; /// \brief Start texture editing command macro - bool primaryEditStartDrag (const QPoint& pos) final; + bool primaryEditStartDrag (const QPoint& pos) override; - bool secondaryEditStartDrag (const QPoint& pos) final; - bool primarySelectStartDrag (const QPoint& pos) final; - bool secondarySelectStartDrag (const QPoint& pos) final; + bool secondaryEditStartDrag (const QPoint& pos) override; + bool primarySelectStartDrag (const QPoint& pos) override; + bool secondarySelectStartDrag (const QPoint& pos) override; /// \brief Handle texture edit behavior during dragging - void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) final; + void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; /// \brief End texture editing command macro - void dragCompleted(const QPoint& pos) final; + void dragCompleted(const QPoint& pos) override; - void dragAborted() final; - void dragWheel (int diff, double speedFactor) final; - void dragMoveEvent (QDragMoveEvent *event) final; + void dragAborted() override; + void dragWheel (int diff, double speedFactor) override; + void dragMoveEvent (QDragMoveEvent *event) override; - void mouseMoveEvent (QMouseEvent *event) final; + void mouseMoveEvent (QMouseEvent *event) override; private: /// \brief Handle brush mechanics, maths regarding worldspace hit etc. 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.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 916c349d2..82a1459f2 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -34,11 +34,11 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) : SceneWidget (document.getData().getResourceSystem(), parent, Qt::WindowFlags(), false) - , mSceneElements(0) - , mRun(0) + , mSceneElements(nullptr) + , mRun(nullptr) , mDocument(document) , mInteractionMask (0) - , mEditMode (0) + , mEditMode (nullptr) , mLocked (false) , mDragMode(InteractionType_None) , mDragging (false) @@ -255,8 +255,7 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool ( bool default_ = debugProfiles.data (debugProfiles.index (i, defaultColumn)).toInt(); if (state!=CSMWorld::RecordBase::State_Deleted && default_) - profiles.push_back ( - debugProfiles.data (debugProfiles.index (i, idColumn)). + profiles.emplace_back(debugProfiles.data (debugProfiles.index (i, idColumn)). toString().toUtf8().constData()); } @@ -436,7 +435,7 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo } // Something untagged, probably terrain - WorldspaceHitResult hit = { true, 0, 0, 0, 0, intersection.getWorldIntersectPoint() }; + WorldspaceHitResult hit = { true, nullptr, 0, 0, 0, intersection.getWorldIntersectPoint() }; if (intersection.indexList.size() >= 3) { hit.index0 = intersection.indexList[0]; @@ -450,7 +449,7 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo direction.normalize(); direction *= CSMPrefs::get()["3D Scene Editing"]["distance"].toInt(); - WorldspaceHitResult hit = { false, 0, 0, 0, 0, start + direction }; + WorldspaceHitResult hit = { false, nullptr, 0, 0, 0, start + direction }; return hit; } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index a80032b82..3b8cf70c2 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -96,7 +96,7 @@ namespace CSVRender InteractionType_None }; - WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0); + WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = nullptr); ~WorldspaceWidget (); CSVWidget::SceneToolMode *makeNavigationSelector (CSVWidget::SceneToolbar *parent); @@ -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.cpp b/apps/opencs/view/tools/merge.cpp index c49044ccd..f50a85f2f 100644 --- a/apps/opencs/view/tools/merge.cpp +++ b/apps/opencs/view/tools/merge.cpp @@ -27,7 +27,7 @@ void CSVTools::Merge::keyPressEvent (QKeyEvent *event) } CSVTools::Merge::Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent) -: QWidget (parent), mDocument (0), mDocumentManager (documentManager) +: QWidget (parent), mDocument (nullptr), mDocumentManager (documentManager) { setWindowTitle ("Merge Content Files into a new Game File"); @@ -117,7 +117,7 @@ CSMDoc::Document *CSVTools::Merge::getDocument() const void CSVTools::Merge::cancel() { - mDocument = 0; + mDocument = nullptr; hide(); } diff --git a/apps/opencs/view/tools/merge.hpp b/apps/opencs/view/tools/merge.hpp index e332b799f..d394a431e 100644 --- a/apps/opencs/view/tools/merge.hpp +++ b/apps/opencs/view/tools/merge.hpp @@ -35,11 +35,11 @@ namespace CSVTools CSVDoc::AdjusterWidget *mAdjuster; CSMDoc::DocumentManager& mDocumentManager; - void keyPressEvent (QKeyEvent *event); + void keyPressEvent (QKeyEvent *event) override; public: - Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent = 0); + Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent = nullptr); /// Configure dialogue for a new merge void configure (CSMDoc::Document *document); 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..c1297d475 100644 --- a/apps/opencs/view/tools/reporttable.cpp +++ b/apps/opencs/view/tools/reporttable.cpp @@ -25,10 +25,10 @@ namespace CSVTools { public: - RichTextDelegate (QObject *parent = 0); + RichTextDelegate (QObject *parent = nullptr); - virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + void paint(QPainter *painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; }; } @@ -142,7 +142,7 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id, bool richTextDescription, int refreshState, QWidget *parent) : CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id)), - mRefreshAction (0), mRefreshState (refreshState) + mRefreshAction (nullptr), mRefreshState (refreshState) { horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); horizontalHeader()->setStretchLastSection (true); @@ -159,7 +159,7 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document, setModel (mProxyModel); setColumnHidden (2, true); - mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (0, + mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (nullptr, mDocument, this); setItemDelegateForColumn (0, mIdTypeDelegate); diff --git a/apps/opencs/view/tools/reporttable.hpp b/apps/opencs/view/tools/reporttable.hpp index 88936d3c3..f39dd6f85 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: @@ -62,9 +62,9 @@ namespace CSVTools /// 0 no refresh function exists. If the document current has the specified state /// the refresh function is disabled. ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id, - bool richTextDescription, int refreshState = 0, QWidget *parent = 0); + bool richTextDescription, int refreshState = 0, QWidget *parent = nullptr); - virtual std::vector getDraggedRecords() const; + std::vector getDraggedRecords() const override; void clear(); diff --git a/apps/opencs/view/tools/searchbox.hpp b/apps/opencs/view/tools/searchbox.hpp index eff5296b4..cbeb150d8 100644 --- a/apps/opencs/view/tools/searchbox.hpp +++ b/apps/opencs/view/tools/searchbox.hpp @@ -41,7 +41,7 @@ namespace CSVTools public: - SearchBox (QWidget *parent = 0); + SearchBox (QWidget *parent = nullptr); void setSearchMode (bool enabled); diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index 9bada22af..07ba7907e 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -30,7 +30,7 @@ void CSVTools::SearchSubView::replace (bool selection) bool autoDelete = CSMPrefs::get()["Search & Replace"]["auto-delete"].isTrue(); CSMTools::Search search (mSearch); - CSMWorld::IdTableBase *currentTable = 0; + CSMWorld::IdTableBase *currentTable = nullptr; // We are running through the indices in reverse order to avoid messing up multiple results // in a single string. 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..aa746da68 100644 --- a/apps/opencs/view/widget/coloreditor.hpp +++ b/apps/opencs/view/widget/coloreditor.hpp @@ -22,8 +22,8 @@ namespace CSVWidget QPoint calculatePopupPosition(); public: - ColorEditor(const QColor &color, QWidget *parent = 0, const bool popupOnStart = false); - ColorEditor(const int colorInt, QWidget *parent = 0, const bool popupOnStart = false); + ColorEditor(const QColor &color, QWidget *parent = nullptr, const bool popupOnStart = false); + ColorEditor(const int colorInt, QWidget *parent = nullptr, const bool popupOnStart = false); QColor color() const; @@ -37,11 +37,11 @@ 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); + ColorEditor(QWidget *parent = nullptr, const bool popupOnStart = false); private slots: void showPicker(); 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..96675f56f 100644 --- a/apps/opencs/view/widget/completerpopup.hpp +++ b/apps/opencs/view/widget/completerpopup.hpp @@ -8,9 +8,9 @@ namespace CSVWidget class CompleterPopup : public QListView { public: - CompleterPopup(QWidget *parent = 0); + CompleterPopup(QWidget *parent = nullptr); - 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..911051873 100644 --- a/apps/opencs/view/widget/droplineedit.hpp +++ b/apps/opencs/view/widget/droplineedit.hpp @@ -26,12 +26,12 @@ namespace CSVWidget ///< The accepted Display type for this LineEdit. public: - DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent = 0); + DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent = nullptr); 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/modebutton.hpp b/apps/opencs/view/widget/modebutton.hpp index 1615ff298..f59596923 100644 --- a/apps/opencs/view/widget/modebutton.hpp +++ b/apps/opencs/view/widget/modebutton.hpp @@ -17,7 +17,7 @@ namespace CSVWidget public: ModeButton (const QIcon& icon, const QString& tooltip = "", - QWidget *parent = 0); + QWidget *parent = nullptr); /// Default-Implementation: do nothing virtual void activate (SceneToolbar *toolbar); diff --git a/apps/opencs/view/widget/pushbutton.hpp b/apps/opencs/view/widget/pushbutton.hpp index bdbdc9c4d..b3aaaebef 100644 --- a/apps/opencs/view/widget/pushbutton.hpp +++ b/apps/opencs/view/widget/pushbutton.hpp @@ -38,21 +38,21 @@ 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: /// \param push Do not maintain a toggle state PushButton (const QIcon& icon, Type type, const QString& tooltip = "", - QWidget *parent = 0); + QWidget *parent = nullptr); /// \param push Do not maintain a toggle state PushButton (Type type, const QString& tooltip = "", - QWidget *parent = 0); + QWidget *parent = nullptr); bool hasKeepOpen() const; 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..70f580765 100644 --- a/apps/opencs/view/widget/scenetoolbar.hpp +++ b/apps/opencs/view/widget/scenetoolbar.hpp @@ -19,15 +19,15 @@ namespace CSVWidget protected: - virtual void focusInEvent (QFocusEvent *event); + void focusInEvent (QFocusEvent *event) override; public: - SceneToolbar (int buttonSize, QWidget *parent = 0); + SceneToolbar (int buttonSize, QWidget *parent = nullptr); /// If insertPoint==0, insert \a tool at the end of the scrollbar. Otherwise /// insert tool after \a insertPoint. - void addTool (SceneTool *tool, SceneTool *insertPoint = 0); + void addTool (SceneTool *tool, SceneTool *insertPoint = nullptr); void removeTool (SceneTool *tool); diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp index 7b2ff64db..3aec44f1b 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -33,7 +33,7 @@ void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) toolTip += "

(left click to change mode)"; - if (createContextMenu (0)) + if (createContextMenu (nullptr)) toolTip += "
(right click to access context menu)"; setToolTip (toolTip); @@ -62,7 +62,7 @@ void CSVWidget::SceneToolMode::setButton (std::map::i CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip) : SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()), - mToolTip (toolTip), mFirst (0), mCurrent (0), mToolbar (parent) + mToolTip (toolTip), mFirst (nullptr), mCurrent (nullptr), mToolbar (parent) { mPanel = new QFrame (this, Qt::Popup); 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..3afd7f8b3 100644 --- a/apps/opencs/view/widget/scenetoolshapebrush.hpp +++ b/apps/opencs/view/widget/scenetoolshapebrush.hpp @@ -54,7 +54,7 @@ namespace CSVWidget public: - ShapeBrushWindow(CSMDoc::Document& document, QWidget *parent = 0); + ShapeBrushWindow(CSMDoc::Document& document, QWidget *parent = nullptr); void configureButtonInitialSettings(QPushButton *button); const QString toolTipPoint = "Paint single point"; @@ -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..5f42800cb 100644 --- a/apps/opencs/view/widget/scenetooltexturebrush.hpp +++ b/apps/opencs/view/widget/scenetooltexturebrush.hpp @@ -57,7 +57,7 @@ namespace CSVWidget Q_OBJECT public: - TextureBrushWindow(CSMDoc::Document& document, QWidget *parent = 0); + TextureBrushWindow(CSMDoc::Document& document, QWidget *parent = nullptr); void configureButtonInitialSettings(QPushButton *button); const QString toolTipPoint = "Paint single point"; @@ -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.cpp b/apps/opencs/view/widget/scenetooltoggle.cpp index 5919a280a..fa0be3155 100644 --- a/apps/opencs/view/widget/scenetooltoggle.cpp +++ b/apps/opencs/view/widget/scenetooltoggle.cpp @@ -115,7 +115,7 @@ QRect CSVWidget::SceneToolToggle::getIconBox (int index) const CSVWidget::SceneToolToggle::SceneToolToggle (SceneToolbar *parent, const QString& toolTip, const std::string& emptyIcon) : SceneTool (parent), mEmptyIcon (emptyIcon), mButtonSize (parent->getButtonSize()), - mIconSize (parent->getIconSize()), mToolTip (toolTip), mFirst (0) + mIconSize (parent->getIconSize()), mToolTip (toolTip), mFirst (nullptr) { mPanel = new QFrame (this, Qt::Popup); 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.cpp b/apps/opencs/view/widget/scenetooltoggle2.cpp index 720da6a96..cf9bfe349 100644 --- a/apps/opencs/view/widget/scenetooltoggle2.cpp +++ b/apps/opencs/view/widget/scenetooltoggle2.cpp @@ -57,7 +57,7 @@ CSVWidget::SceneToolToggle2::SceneToolToggle2 (SceneToolbar *parent, const QStri const std::string& compositeIcon, const std::string& singleIcon) : SceneTool (parent), mCompositeIcon (compositeIcon), mSingleIcon (singleIcon), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()), mToolTip (toolTip), - mFirst (0) + mFirst (nullptr) { mPanel = new QFrame (this, Qt::Popup); 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.cpp b/apps/opencs/view/world/creator.cpp index 7a93339c5..53664c186 100644 --- a/apps/opencs/view/world/creator.cpp +++ b/apps/opencs/view/world/creator.cpp @@ -17,5 +17,5 @@ CSVWorld::CreatorFactoryBase::~CreatorFactoryBase() {} CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return 0; + return nullptr; } 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.cpp b/apps/opencs/view/world/datadisplaydelegate.cpp index f0c364bc2..6da62d408 100644 --- a/apps/opencs/view/world/datadisplaydelegate.cpp +++ b/apps/opencs/view/world/datadisplaydelegate.cpp @@ -32,7 +32,7 @@ void CSVWorld::DataDisplayDelegate::buildPixmaps () while (it != mIcons.end()) { - mPixmaps.push_back (std::make_pair (it->mValue, it->mIcon.pixmap (mIconSize) ) ); + mPixmaps.emplace_back (it->mValue, it->mIcon.pixmap (mIconSize) ); ++it; } } 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..90fe8d20c 100644 --- a/apps/opencs/view/world/dialoguespinbox.hpp +++ b/apps/opencs/view/world/dialoguespinbox.hpp @@ -12,13 +12,13 @@ namespace CSVWorld public: - DialogueSpinBox (QWidget *parent = 0); + DialogueSpinBox (QWidget *parent = nullptr); 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 @@ -27,13 +27,13 @@ namespace CSVWorld public: - DialogueDoubleSpinBox (QWidget *parent = 0); + DialogueDoubleSpinBox (QWidget *parent = nullptr); 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.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e29fcb779..3d3b3cdbe 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -498,7 +498,7 @@ void CSVWorld::EditWidget::remake(int row) if (mDispatcher) delete mDispatcher; - mDispatcher = new DialogueDelegateDispatcher(0/*this*/, mTable, mCommandDispatcher, mDocument); + mDispatcher = new DialogueDelegateDispatcher(nullptr/*this*/, mTable, mCommandDispatcher, mDocument); if (mNestedTableDispatcher) delete mNestedTableDispatcher; @@ -648,7 +648,7 @@ void CSVWorld::EditWidget::remake(int row) mNestedTableMapper->setModel(tree); // FIXME: lack MIME support? mNestedTableDispatcher = - new DialogueDelegateDispatcher (0/*this*/, mTable, mCommandDispatcher, mDocument, tree); + new DialogueDelegateDispatcher (nullptr/*this*/, mTable, mCommandDispatcher, mDocument, tree); mNestedTableMapper->setRootIndex (tree->index(row, i)); mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); @@ -732,7 +732,7 @@ bool CSVWorld::SimpleDialogueSubView::isLocked() const CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), - mEditWidget(0), + mEditWidget(nullptr), mMainLayout(nullptr), mTable(dynamic_cast(document.getData().getTableModel(id))), mLocked(false), @@ -834,7 +834,7 @@ void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &pa if(mEditWidget) { delete mEditWidget; - mEditWidget = 0; + mEditWidget = nullptr; } emit closeRequest(this); } @@ -869,7 +869,7 @@ void CSVWorld::DialogueSubView::addButtonBar() CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting) -: SimpleDialogueSubView (id, document), mButtons (0) +: SimpleDialogueSubView (id, document), mButtons (nullptr) { // bottom box mBottom = new TableBottomBox (creatorFactory, document, id, this); @@ -905,7 +905,7 @@ void CSVWorld::DialogueSubView::settingChanged (const CSMPrefs::Setting *setting { getMainLayout().removeWidget (mButtons); delete mButtons; - mButtons = 0; + mButtons = nullptr; } } } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 52d3d8da5..2cf05f711 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -50,24 +50,24 @@ namespace CSVWorld const CSMWorld::IdTable* mTable; public: NotEditableSubDelegate(const CSMWorld::IdTable* table, - QObject * parent = 0); + QObject * parent = nullptr); - 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 @@ -126,7 +126,7 @@ namespace CSVWorld CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, - QAbstractItemModel* model = 0); + QAbstractItemModel* model = nullptr); ~DialogueDelegateDispatcher(); @@ -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.cpp b/apps/opencs/view/world/enumdelegate.cpp index 8027cec62..65ded46c7 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -71,7 +71,7 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptio const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid()) - return 0; + return nullptr; QComboBox *comboBox = new QComboBox (parent); @@ -181,5 +181,5 @@ void CSVWorld::EnumDelegateFactory::add (int value, const QString& name) } } - mValues.push_back(std::make_pair (value, name)); + mValues.emplace_back (value, name); } 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..85862ac49 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -57,13 +57,13 @@ namespace CSVWorld public: ExtendedCommandConfigurator(CSMDoc::Document &document, const CSMWorld::UniversalId &id, - QWidget *parent = 0); + QWidget *parent = nullptr); void configure(Mode mode, const std::vector &selectedIds); 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.cpp b/apps/opencs/view/world/genericcreator.cpp index 5e2118e9b..23813f806 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -148,8 +148,8 @@ void CSVWorld::GenericCreator::addScope (const QString& name, CSMWorld::Scope sc CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, bool relaxedIdRules) : mData (data), mUndoStack (undoStack), mListId (id), mLocked (false), - mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (0), - mScopeLabel (0), mCloneMode (false) + mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (nullptr), + mScopeLabel (nullptr), mCloneMode (false) { // If the collection ID has a parent type, use it instead. // It will change IDs with Record/SubRecord class (used for creators in Dialogue subviews) @@ -322,10 +322,10 @@ void CSVWorld::GenericCreator::setScope (unsigned int scope) else { delete mScope; - mScope = 0; + mScope = nullptr; delete mScopeLabel; - mScopeLabel = 0; + mScopeLabel = nullptr; } updateNamespace(); 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.cpp b/apps/opencs/view/world/idcompletiondelegate.cpp index 4ff850b9f..447bcc25d 100644 --- a/apps/opencs/view/world/idcompletiondelegate.cpp +++ b/apps/opencs/view/world/idcompletiondelegate.cpp @@ -74,7 +74,7 @@ QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent, { return new CSVWidget::DropLineEdit(display, parent); } - default: return 0; // The rest of them can't be edited anyway + default: return nullptr; // The rest of them can't be edited anyway } } 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..278335a65 100644 --- a/apps/opencs/view/world/idvalidator.hpp +++ b/apps/opencs/view/world/idvalidator.hpp @@ -19,10 +19,10 @@ namespace CSVWorld public: - IdValidator (bool relaxed = false, QObject *parent = 0); + IdValidator (bool relaxed = false, QObject *parent = nullptr); ///< \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/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp index fbee066ce..aca3211f8 100644 --- a/apps/opencs/view/world/recordbuttonbar.hpp +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -58,8 +58,8 @@ namespace CSVWorld public: RecordButtonBar (const CSMWorld::UniversalId& id, - CSMWorld::IdTable& table, TableBottomBox *bottomBox = 0, - CSMWorld::CommandDispatcher *commandDispatcher = 0, QWidget *parent = 0); + CSMWorld::IdTable& table, TableBottomBox *bottomBox = nullptr, + CSMWorld::CommandDispatcher *commandDispatcher = nullptr, QWidget *parent = nullptr); void setEditLock (bool locked); diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index acaf872a6..38f066862 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -19,7 +19,7 @@ namespace CSVWorld RecordStatusDelegate (const ValueList& values, const IconList& icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, - QObject *parent = 0); + QObject *parent = nullptr); }; class RecordStatusDelegateFactory : public DataDisplayDelegateFactory @@ -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.cpp b/apps/opencs/view/world/regionmap.cpp index af91464b6..d2d4fbd23 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -345,18 +345,16 @@ std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDraggedRecords() co std::vector ids; for (const QModelIndex& it : selected) { - ids.push_back( - CSMWorld::UniversalId( + ids.emplace_back( CSMWorld::UniversalId::Type_Cell, - model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData())); + model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); } selected = getSelectedCells(false, true); for (const QModelIndex& it : selected) { - ids.push_back( - CSMWorld::UniversalId( + ids.emplace_back( CSMWorld::UniversalId::Type_Cell_Missing, - model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData())); + model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); } return ids; } diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index ba773224f..443de9ce3 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); + QWidget *parent = nullptr); - 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.cpp b/apps/opencs/view/world/scriptedit.cpp index 9083359d2..743df9c76 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -47,7 +47,7 @@ CSVWorld::ScriptEdit::ScriptEdit( ) : QPlainTextEdit(parent), mChangeLocked(0), mShowLineNum(false), - mLineNumberArea(0), + mLineNumberArea(nullptr), mDefaultFont(font()), mMonoFont(QFont("Monospace")), mTabCharCount(4), @@ -314,7 +314,7 @@ void CSVWorld::ScriptEdit::markOccurrences() // prevent infinite recursion with cursor.select(), // which ends up calling this function again // could be fixed with blockSignals, but mDocument is const - disconnect(this, SIGNAL(cursorPositionChanged()), this, 0); + disconnect(this, SIGNAL(cursorPositionChanged()), this, nullptr); cursor.select(QTextCursor::WordUnderCursor); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(markOccurrences())); 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..7165d0fc6 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, @@ -41,7 +41,7 @@ namespace CSVWorld public: - ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = 0); + ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = nullptr); void update (const std::string& source); 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.cpp b/apps/opencs/view/world/scriptsubview.cpp index 58ad09451..096fc8a9e 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -88,7 +88,7 @@ void CSVWorld::ScriptSubView::adjustSplitter() } CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mButtons (0), +: SubView (id), mDocument (document), mColumn (-1), mBottom(nullptr), mButtons (nullptr), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())), mErrorHeight (CSMPrefs::get()["Scripts"]["error-height"].toInt()) { @@ -177,7 +177,7 @@ void CSVWorld::ScriptSubView::settingChanged (const CSMPrefs::Setting *setting) { mLayout.removeWidget (mButtons); delete mButtons; - mButtons = 0; + mButtons = nullptr; } } else if (*setting=="Scripts/compile-delay") 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.cpp b/apps/opencs/view/world/table.cpp index 9d47e2fe5..e5f4e36c5 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -452,7 +452,7 @@ std::vector CSVWorld::Table::getSelectedIds() const ++iter) { int row = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)).row(); - ids.push_back (mModel->data (mModel->index (row, columnIndex)).toString().toUtf8().constData()); + ids.emplace_back(mModel->data (mModel->index (row, columnIndex)).toString().toUtf8().constData()); } return ids; } @@ -784,7 +784,7 @@ std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column if (display == columndisplay) { - titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData()); + titles.emplace_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData()); } } return titles; 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.cpp b/apps/opencs/view/world/tablebottombox.cpp index f6b060a8f..1b065da49 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -95,7 +95,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto mStatus = new QLabel; - mStatusBar = new QStatusBar; + mStatusBar = new QStatusBar(this); mStatusBar->addWidget (mStatus); diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index baa68087b..6ad2dbd82 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -59,11 +59,11 @@ namespace CSVWorld TableBottomBox (const CreatorFactoryBase& creatorFactory, CSMDoc::Document& document, const CSMWorld::UniversalId& id, - QWidget *parent = 0); + QWidget *parent = nullptr); 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/tableeditidaction.hpp b/apps/opencs/view/world/tableeditidaction.hpp index f2cf0b7bd..9fe41b0de 100644 --- a/apps/opencs/view/world/tableeditidaction.hpp +++ b/apps/opencs/view/world/tableeditidaction.hpp @@ -19,7 +19,7 @@ namespace CSVWorld CellData getCellData(int row, int column) const; public: - TableEditIdAction(const QTableView &table, QWidget *parent = 0); + TableEditIdAction(const QTableView &table, QWidget *parent = nullptr); void setCell(int row, int column); diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index b0bae7fdf..5413f87a6 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -133,12 +133,12 @@ void CSVWorld::TableSubView::createFilterRequest (std::vector< CSMWorld::Univers std::vector col = mTable->getColumnsWithDisplay(CSMWorld::TableMimeData::convertEnums(type)); if(!col.empty()) { - filterSource.push_back(std::make_pair(it->getId(), col)); + filterSource.emplace_back(it->getId(), col); } if(hasRefIdDisplay && CSMWorld::TableMimeData::isReferencable(type)) { - filterSource.push_back(std::make_pair(it->getId(), refIdColumns)); + filterSource.emplace_back(it->getId(), refIdColumns); } } 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.cpp b/apps/opencs/view/world/util.cpp index 5a4503362..ba9f40847 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -57,7 +57,7 @@ QVariant CSVWorld::NastyTableModelHack::getData() const CSVWorld::CommandDelegateFactory::~CommandDelegateFactory() {} -CSVWorld::CommandDelegateFactoryCollection *CSVWorld::CommandDelegateFactoryCollection::sThis = 0; +CSVWorld::CommandDelegateFactoryCollection *CSVWorld::CommandDelegateFactoryCollection::sThis = nullptr; CSVWorld::CommandDelegateFactoryCollection::CommandDelegateFactoryCollection() { @@ -69,7 +69,7 @@ CSVWorld::CommandDelegateFactoryCollection::CommandDelegateFactoryCollection() CSVWorld::CommandDelegateFactoryCollection::~CommandDelegateFactoryCollection() { - sThis = 0; + sThis = nullptr; for (std::map::iterator iter ( mFactories.begin()); @@ -193,7 +193,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO variant = index.data(Qt::DisplayRole); if (!variant.isValid()) { - return 0; + return nullptr; } } @@ -362,7 +362,7 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde if (!n.isEmpty()) { if (!variant.isValid()) - variant = QVariant(editor->property(n).userType(), (const void *)0); + variant = QVariant(editor->property(n).userType(), (const void *)nullptr); editor->setProperty(n, variant); } 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/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/engine.cpp b/apps/openmw/engine.cpp index ea1cd6dd8..2068580ed 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -98,6 +98,7 @@ namespace Script, Mechanics, Physics, + PhysicsWorker, World, Gui, @@ -128,6 +129,9 @@ namespace template <> const UserStats UserStatsValue::sValue {"Phys", "physics"}; + template <> + const UserStats UserStatsValue::sValue {" -Async", "physicsworker"}; + template <> const UserStats UserStatsValue::sValue {"World", "world"}; @@ -207,6 +211,10 @@ namespace profiler.addUserStatsLine(v.mLabel, textColor, barColor, v.mTaken, multiplier, average, averageInInverseSpace, v.mBegin, v.mEnd, maxValue); }); + // the forEachUserStatsValue loop is "run" at compile time, hence the settings manager is not available. + // Unconditionnally add the async physics stats, and then remove it at runtime if necessary + if (Settings::Manager::getInt("async num threads", "Physics") == 0) + profiler.removeUserStatsLine(" -Async"); } } @@ -322,7 +330,7 @@ bool OMW::Engine::frame(float frametime) if (mEnvironment.getStateManager()->getState() != MWBase::StateManager::State_NoGame) { - mEnvironment.getWorld()->updatePhysics(frametime, guiActive); + mEnvironment.getWorld()->updatePhysics(frametime, guiActive, frameStart, frameNumber, *stats); } } @@ -379,7 +387,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mGrab(true) , mExportFonts(false) , mRandomSeed(0) - , mScriptContext (0) + , mScriptContext (nullptr) , mFSStrict (false) , mScriptBlacklistUse (true) , mNewGame (false) @@ -803,7 +811,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/main.cpp b/apps/openmw/main.cpp index a39dd2e39..3a6dc526a 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -21,22 +21,6 @@ #include #endif -/** - * Workaround for problems with whitespaces in paths in older versions of Boost library - */ -#if (BOOST_VERSION <= 104600) -namespace boost -{ - -template<> -inline boost::filesystem::path lexical_cast(const std::string& arg) -{ - return boost::filesystem::path(arg); -} - -} /* namespace boost */ -#endif /* (BOOST_VERSION <= 104600) */ - using namespace Fallback; @@ -63,20 +47,20 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("data", bpo::value()->default_value(Files::EscapePathContainer(), "data") ->multitoken()->composing(), "set data directories (later directories have higher priority)") - ("data-local", bpo::value()->default_value(""), + ("data-local", bpo::value()->default_value(Files::EscapePath(), ""), "set local data directory (highest priority)") ("fallback-archive", bpo::value()->default_value(Files::EscapeStringVector(), "fallback-archive") - ->multitoken(), "set fallback BSA archives (later archives have higher priority)") + ->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)") - ("resources", bpo::value()->default_value("resources"), + ("resources", bpo::value()->default_value(Files::EscapePath(), "resources"), "set resources directory") - ("start", bpo::value()->default_value(""), + ("start", bpo::value()->default_value(""), "set initial cell") ("content", bpo::value()->default_value(Files::EscapeStringVector(), "") - ->multitoken(), "content file(s): esm/esp, or omwgame/omwaddon") + ->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon") ("no-sound", bpo::value()->implicit_value(true) ->default_value(false), "disable all sounds") @@ -90,7 +74,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("script-console", bpo::value()->implicit_value(true) ->default_value(false), "enable console-only script functionality") - ("script-run", bpo::value()->default_value(""), + ("script-run", bpo::value()->default_value(""), "select a file containing a list of console commands that is executed on startup") ("script-warn", bpo::value()->implicit_value (1) @@ -101,12 +85,12 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat "\t2 - treat warnings as errors") ("script-blacklist", bpo::value()->default_value(Files::EscapeStringVector(), "") - ->multitoken(), "ignore the specified script (if the use of the blacklist is enabled)") + ->multitoken()->composing(), "ignore the specified script (if the use of the blacklist is enabled)") ("script-blacklist-use", bpo::value()->implicit_value(true) ->default_value(true), "enable script blacklisting") - ("load-savegame", bpo::value()->default_value(""), + ("load-savegame", bpo::value()->default_value(Files::EscapePath(), ""), "load a save game file on game startup (specify an absolute filename or a filename relative to the current working directory)") ("skip-menu", bpo::value()->implicit_value(true) @@ -118,14 +102,14 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("fs-strict", bpo::value()->implicit_value(true) ->default_value(false), "strict file system handling (no case folding)") - ("encoding", bpo::value()-> + ("encoding", bpo::value()-> default_value("win1252"), "Character encoding used in OpenMW game messages:\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1252 - Western European (Latin) alphabet, used by default") - ("fallback", bpo::value()->default_value(FallbackMap(), "") + ("fallback", bpo::value()->default_value(FallbackMap(), "") ->multitoken()->composing(), "fallback values") ("no-grab", bpo::value()->implicit_value(true)->default_value(false), "Don't grab mouse cursor") @@ -159,14 +143,16 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat { cfgMgr.readConfiguration(variables, desc, true); - Version::Version v = Version::getOpenmwVersion(variables["resources"].as().toStdString()); + Version::Version v = Version::getOpenmwVersion(variables["resources"].as().mPath.string()); std::cout << v.describe() << std::endl; return false; } + bpo::variables_map composingVariables = cfgMgr.separateComposingVariables(variables, desc); cfgMgr.readConfiguration(variables, desc); + cfgMgr.mergeComposingVariables(variables, composingVariables, desc); - Version::Version v = Version::getOpenmwVersion(variables["resources"].as().toStdString()); + Version::Version v = Version::getOpenmwVersion(variables["resources"].as().mPath.string()); std::cout << v.describe() << std::endl; engine.setGrabMouse(!variables["no-grab"].as()); @@ -181,18 +167,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat Files::PathContainer dataDirs(Files::EscapePath::toPathContainer(variables["data"].as())); - std::string local(variables["data-local"].as().toStdString()); + Files::PathContainer::value_type local(variables["data-local"].as().mPath); if (!local.empty()) - { - if (local.front() == '\"') - local = local.substr(1, local.length() - 2); - - dataDirs.push_back(Files::PathContainer::value_type(local)); - } + dataDirs.push_back(local); cfgMgr.processPaths(dataDirs); - engine.setResourceDir(variables["resources"].as().toStdString()); + engine.setResourceDir(variables["resources"].as().mPath); engine.setDataDirs(dataDirs); // fallback archives @@ -230,7 +211,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setWarningsMode (variables["script-warn"].as()); engine.setScriptBlacklist (variables["script-blacklist"].as().toStdStringVector()); engine.setScriptBlacklistUse (variables["script-blacklist-use"].as()); - engine.setSaveGameFile (variables["load-savegame"].as().toStdString()); + engine.setSaveGameFile (variables["load-savegame"].as().mPath.string()); // other settings Fallback::Map::init(variables["fallback"].as().mMap); @@ -242,6 +223,42 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat return true; } +namespace +{ + class OSGLogHandler : public osg::NotifyHandler + { + void notify(osg::NotifySeverity severity, const char* msg) override + { + // Copy, because osg logging is not thread safe. + std::string msgCopy(msg); + if (msgCopy.empty()) + return; + + Debug::Level level; + switch (severity) + { + case osg::ALWAYS: + case osg::FATAL: + level = Debug::Error; + break; + case osg::WARN: + case osg::NOTICE: + level = Debug::Warning; + break; + case osg::INFO: + level = Debug::Info; + break; + case osg::DEBUG_INFO: + case osg::DEBUG_FP: + default: + level = Debug::Debug; + } + std::string_view s(msgCopy); + Log(level) << (s.back() == '\n' ? s.substr(0, s.size() - 1) : s); + } + }; +} + int runApplication(int argc, char *argv[]) { #ifdef __APPLE__ @@ -250,6 +267,7 @@ int runApplication(int argc, char *argv[]) setenv("OSG_GL_TEXTURE_STORAGE", "OFF", 0); #endif + osg::setNotifyHandler(new OSGLogHandler()); Files::ConfigurationManager cfgMgr; std::unique_ptr engine; engine.reset(new OMW::Engine(cfgMgr)); 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/mwbase/environment.cpp b/apps/openmw/mwbase/environment.cpp index 764a07ec9..aca2685e0 100644 --- a/apps/openmw/mwbase/environment.cpp +++ b/apps/openmw/mwbase/environment.cpp @@ -14,11 +14,11 @@ #include "windowmanager.hpp" #include "statemanager.hpp" -MWBase::Environment *MWBase::Environment::sThis = 0; +MWBase::Environment *MWBase::Environment::sThis = nullptr; MWBase::Environment::Environment() -: mWorld (0), mSoundManager (0), mScriptManager (0), mWindowManager (0), - mMechanicsManager (0), mDialogueManager (0), mJournal (0), mInputManager (0), mStateManager (0), +: mWorld (nullptr), mSoundManager (nullptr), mScriptManager (nullptr), mWindowManager (nullptr), + mMechanicsManager (nullptr), mDialogueManager (nullptr), mJournal (nullptr), mInputManager (nullptr), mStateManager (nullptr), mFrameDuration (0), mFrameRateLimit(0.f) { assert (!sThis); @@ -28,7 +28,7 @@ MWBase::Environment::Environment() MWBase::Environment::~Environment() { cleanup(); - sThis = 0; + sThis = nullptr; } void MWBase::Environment::setWorld (World *world) @@ -166,31 +166,31 @@ float MWBase::Environment::getFrameDuration() const void MWBase::Environment::cleanup() { delete mMechanicsManager; - mMechanicsManager = 0; + mMechanicsManager = nullptr; delete mDialogueManager; - mDialogueManager = 0; + mDialogueManager = nullptr; delete mJournal; - mJournal = 0; + mJournal = nullptr; delete mScriptManager; - mScriptManager = 0; + mScriptManager = nullptr; delete mWindowManager; - mWindowManager = 0; + mWindowManager = nullptr; delete mWorld; - mWorld = 0; + mWorld = nullptr; delete mSoundManager; - mSoundManager = 0; + mSoundManager = nullptr; delete mInputManager; - mInputManager = 0; + mInputManager = nullptr; delete mStateManager; - mStateManager = 0; + mStateManager = nullptr; } const MWBase::Environment& MWBase::Environment::get() diff --git a/apps/openmw/mwbase/statemanager.hpp b/apps/openmw/mwbase/statemanager.hpp index 643695c37..157833a0e 100644 --- a/apps/openmw/mwbase/statemanager.hpp +++ b/apps/openmw/mwbase/statemanager.hpp @@ -59,7 +59,7 @@ namespace MWBase virtual void deleteGame (const MWState::Character *character, const MWState::Slot *slot) = 0; - virtual void saveGame (const std::string& description, const MWState::Slot *slot = 0) = 0; + virtual void saveGame (const std::string& description, const MWState::Slot *slot = nullptr) = 0; ///< Write a saved game to \a slot or create a new slot if \a slot == 0. /// /// \note Slot must belong to the current character. 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/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 70e65e0ea..d4f1d2f8a 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -10,6 +10,8 @@ #include +#include + #include "../mwworld/ptr.hpp" #include "../mwworld/doorstate.hpp" @@ -36,6 +38,7 @@ namespace ESM struct Position; struct Cell; struct Class; + struct Container; struct Creature; struct Potion; struct Spell; @@ -177,7 +180,7 @@ namespace MWBase virtual char getGlobalVariableType (const std::string& name) const = 0; ///< Return ' ', if there is no global variable with this name. - virtual std::string getCellName (const MWWorld::CellStore *cell = 0) const = 0; + virtual std::string getCellName (const MWWorld::CellStore *cell = nullptr) const = 0; ///< Return name of the cell. /// /// \note If cell==0, the cell the player is currently in will be used instead to @@ -385,8 +388,12 @@ 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; + virtual void updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) = 0; virtual void updateWindowManager () = 0; @@ -641,6 +648,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/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.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; } 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.cpp b/apps/openmw/mwclass/container.cpp index b4b068c91..a27e3debd 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -27,48 +27,46 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/npcstats.hpp" namespace MWClass { - class ContainerCustomData : public MWWorld::CustomData + ContainerCustomData::ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell) { - public: - MWWorld::ContainerStore mContainerStore; - - virtual MWWorld::CustomData *clone() const; + 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 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 +96,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 +215,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 +240,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; } @@ -305,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(); @@ -317,16 +308,8 @@ 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 @@ -338,7 +321,13 @@ namespace MWClass } const ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); + if (!customData.mStore.isResolved()) + { + state.mHasCustomState = false; + return; + } + 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..57dbf0c76 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -2,69 +2,90 @@ #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); + + MWWorld::CustomData *clone() const override; + + ContainerCustomData& asContainerCustomData() override; + const ContainerCustomData& asContainerCustomData() const override; + + friend class Container; + }; + class Container : public MWWorld::Class { 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 void restock (const MWWorld::Ptr &ptr) const; + std::string getModel(const MWWorld::ConstPtr &ptr) const override; - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + bool useAnim() const override; - virtual bool useAnim() const; + void modifyBaseInventory(const std::string& containerId, const std::string& itemId, int amount) const override; }; } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 5c5524a12..31341db73 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -58,18 +58,18 @@ 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; } - CreatureCustomData() : mContainerStore(0) {} + CreatureCustomData() : mContainerStore(nullptr) {} virtual ~CreatureCustomData() { delete mContainerStore; } }; @@ -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..5bb503034 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,105 +40,103 @@ 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 void restock (const MWWorld::Ptr &ptr) const; + int getBaseFightRating(const MWWorld::ConstPtr &ptr) const override; - virtual int getBaseFightRating(const MWWorld::ConstPtr &ptr) const; - - 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; + float getWalkSpeed(const MWWorld::Ptr& ptr) const override; - float getRunSpeed(const MWWorld::Ptr& ptr) const final; + float getRunSpeed(const MWWorld::Ptr& ptr) const override; - float getSwimSpeed(const MWWorld::Ptr& ptr) const final; + float getSwimSpeed(const MWWorld::Ptr& ptr) const override; }; } 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 4aab95f9d..27c98bbce 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; } @@ -431,12 +431,12 @@ namespace MWClass const MWWorld::LiveCellRef *npc = ptr.get(); const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mRace); if(race && race->mData.mFlags & ESM::Race::Beast) - models.push_back("meshes\\base_animkna.nif"); + models.emplace_back("meshes\\base_animkna.nif"); // keep these always loaded just in case - models.push_back("meshes/xargonian_swimkna.nif"); - models.push_back("meshes/xbase_anim_female.nif"); - models.push_back("meshes/xbase_anim.nif"); + models.emplace_back("meshes/xargonian_swimkna.nif"); + models.emplace_back("meshes/xbase_anim_female.nif"); + models.emplace_back("meshes/xbase_anim.nif"); if (!npc->mBase->mModel.empty()) models.push_back("meshes/"+npc->mBase->mModel); @@ -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()); @@ -1399,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..612763d12 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,136 +44,133 @@ 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; - - virtual bool isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const; + int getBaseGold(const MWWorld::ConstPtr& ptr) const override; - virtual bool canSwim (const MWWorld::ConstPtr &ptr) const; + bool isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const override; - virtual bool canWalk (const MWWorld::ConstPtr &ptr) const; + bool canSwim (const MWWorld::ConstPtr &ptr) const override; - virtual bool isBipedal (const MWWorld::ConstPtr &ptr) const; + bool canWalk (const MWWorld::ConstPtr &ptr) const override; - virtual void respawn (const MWWorld::Ptr& ptr) const; + bool isBipedal (const MWWorld::ConstPtr &ptr) const override; - virtual void restock (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; + float getWalkSpeed(const MWWorld::Ptr& ptr) const override; - float getRunSpeed(const MWWorld::Ptr& ptr) const final; + float getRunSpeed(const MWWorld::Ptr& ptr) const override; - float getSwimSpeed(const MWWorld::Ptr& ptr) const final; + float getSwimSpeed(const MWWorld::Ptr& ptr) const override; }; } 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.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index e3f1796a4..34fd5828f 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -468,7 +468,7 @@ namespace MWDialogue void DialogueManager::addChoice (const std::string& text, int choice) { mIsInChoice = true; - mChoices.push_back(std::make_pair(text, choice)); + mChoices.emplace_back(text, choice); } const std::vector >& DialogueManager::getChoices() @@ -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 23dd68e91..b35bee6d4 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(); - int getTopicFlag(const std::string& topicId) final; + std::list getAvailableTopics() override; + int getTopicFlag(const std::string& topicId) override; - bool inJournal (const std::string& topicId, const std::string& infoId) final; + bool inJournal (const std::string& topicId, const std::string& infoId) override; - 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, ServiceType service = ServiceType::Any) 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/hypertextparser.cpp b/apps/openmw/mwdialogue/hypertextparser.cpp index aa748e772..28e450e2b 100644 --- a/apps/openmw/mwdialogue/hypertextparser.cpp +++ b/apps/openmw/mwdialogue/hypertextparser.cpp @@ -30,7 +30,7 @@ namespace MWDialogue tokenizeKeywords(text.substr(iteration_pos, pos_begin - iteration_pos), result); std::string link = text.substr(pos_begin + 1, pos_end - pos_begin - 1); - result.push_back(Token(link, Token::ExplicitLink)); + result.emplace_back(link, Token::ExplicitLink); iteration_pos = pos_end + 1; } @@ -65,7 +65,7 @@ namespace MWDialogue for (std::vector::Match>::const_iterator it = matches.begin(); it != matches.end(); ++it) { - tokens.push_back(Token(std::string(it->mBeg, it->mEnd), Token::ImplicitKeyword)); + tokens.emplace_back(std::string(it->mBeg, it->mEnd), Token::ImplicitKeyword); } } 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/backgroundimage.hpp b/apps/openmw/mwgui/backgroundimage.hpp index 3ea8b3bba..32cdf1a65 100644 --- a/apps/openmw/mwgui/backgroundimage.hpp +++ b/apps/openmw/mwgui/backgroundimage.hpp @@ -22,8 +22,8 @@ namespace MWGui */ void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool stretch=true); - void setSize (const MyGUI::IntSize &_value) final; - void setCoord (const MyGUI::IntCoord &_value) final; + void setSize (const MyGUI::IntSize &_value) override; + void setCoord (const MyGUI::IntCoord &_value) override; private: MyGUI::ImageBox* mChild; diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 6f6a621ad..41711f5e4 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -147,7 +147,7 @@ namespace MWGui for (const ESM::BirthSign& sign : signs) { - birthSigns.push_back(std::make_pair(sign.mId, &sign)); + birthSigns.emplace_back(sign.mId, &sign); } std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns); 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..c70783f39 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; @@ -524,9 +524,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter break; if ( lead != origin ) - mPartialWhitespace.push_back (PartialText (style, lead, origin, space_width)); + mPartialWhitespace.emplace_back(style, lead, origin, space_width); if ( origin != extent ) - mPartialWord.push_back (PartialText (style, origin, extent, word_width)); + mPartialWord.emplace_back(style, origin, extent, word_width); } } @@ -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() @@ -925,7 +925,7 @@ public: void dirtyFocusItem () { - if (mFocusItem != 0) + if (mFocusItem != nullptr) { MyGUI::IFont* Font = mBook->affectedFont (mFocusItem); @@ -946,7 +946,7 @@ public: dirtyFocusItem (); - mFocusItem = 0; + mFocusItem = nullptr; mItemActive = false; } @@ -976,7 +976,7 @@ public: } } else - if (mFocusItem != 0) + if (mFocusItem != nullptr) { bool newItemActive = hit == mFocusItem; @@ -1152,7 +1152,7 @@ public: i->second->createDrawItem (mNode); } - void setVisible (bool newVisible) final + void setVisible (bool newVisible) override { if (mVisible == newVisible) return; @@ -1174,7 +1174,7 @@ public: } } - void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) final + void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) override { mNode = node; @@ -1242,9 +1242,9 @@ public: // ISubWidget should not necessarily be a drawitem // in this case, it is not... - void doRender() final { } + void doRender() override { } - void _updateView () final + void _updateView () override { _checkMargin(); @@ -1253,7 +1253,7 @@ public: mNode->outOfDate (i->second->mRenderItem); } - void _correctView() final + void _correctView() override { _checkMargin (); @@ -1263,7 +1263,7 @@ public: } - void destroyDrawItem() final + void destroyDrawItem() override { for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) i->second->destroyDrawItem (mNode); @@ -1283,24 +1283,24 @@ public: { } - void showPage (TypesetBook::Ptr book, size_t page) final + void showPage (TypesetBook::Ptr book, size_t page) override { mPageDisplay->showPage (book, page); } - void adviseLinkClicked (std::function linkClicked) final + void adviseLinkClicked (std::function linkClicked) override { mPageDisplay->mLinkClicked = linkClicked; } - void unadviseLinkClicked () final + void unadviseLinkClicked () override { mPageDisplay->mLinkClicked = std::function (); } protected: - void initialiseOverride() final + void initialiseOverride() override { Base::initialiseOverride(); @@ -1314,24 +1314,24 @@ protected: } } - void onMouseLostFocus(Widget* _new) final + void onMouseLostFocus(Widget* _new) override { // NOTE: MyGUI also fires eventMouseLostFocus for widgets that are about to be destroyed (if they had focus). // Child widgets may already be destroyed! So be careful. mPageDisplay->onMouseLostFocus (); } - void onMouseMove(int left, int top) final + void onMouseMove(int left, int top) override { mPageDisplay->onMouseMove (left, top); } - void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) final + void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) override { mPageDisplay->onMouseButtonPressed (left, top, id); } - void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) final + void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) override { mPageDisplay->onMouseButtonReleased (left, top, id); } 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/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 31fe3afb0..827f87c7d 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -87,15 +87,15 @@ namespace MWGui CharacterCreation::CharacterCreation(osg::Group* parent, Resource::ResourceSystem* resourceSystem) : mParent(parent) , mResourceSystem(resourceSystem) - , mNameDialog(0) - , mRaceDialog(0) - , mClassChoiceDialog(0) - , mGenerateClassQuestionDialog(0) - , mGenerateClassResultDialog(0) - , mPickClassDialog(0) - , mCreateClassDialog(0) - , mBirthSignDialog(0) - , mReviewDialog(0) + , mNameDialog(nullptr) + , mRaceDialog(nullptr) + , mClassChoiceDialog(nullptr) + , mGenerateClassQuestionDialog(nullptr) + , mGenerateClassResultDialog(nullptr) + , mPickClassDialog(nullptr) + , mCreateClassDialog(nullptr) + , mBirthSignDialog(nullptr) + , mReviewDialog(nullptr) , mGenerateClassStep(0) { mCreationStage = CSE_NotStarted; @@ -184,7 +184,7 @@ namespace MWGui { case GM_Name: MWBase::Environment::get().getWindowManager()->removeDialog(mNameDialog); - mNameDialog = 0; + mNameDialog = nullptr; mNameDialog = new TextInputDialog(); mNameDialog->setTextLabel(MWBase::Environment::get().getWindowManager()->getGameSettingString("sName", "Name")); mNameDialog->setTextInput(mPlayerName); @@ -195,7 +195,7 @@ namespace MWGui case GM_Race: MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog); - mRaceDialog = 0; + mRaceDialog = nullptr; mRaceDialog = new RaceDialog(mParent, mResourceSystem); mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen); mRaceDialog->setRaceId(mPlayerRaceId); @@ -208,7 +208,7 @@ namespace MWGui case GM_Class: MWBase::Environment::get().getWindowManager()->removeDialog(mClassChoiceDialog); - mClassChoiceDialog = 0; + mClassChoiceDialog = nullptr; mClassChoiceDialog = new ClassChoiceDialog(); mClassChoiceDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassChoice); mClassChoiceDialog->setVisible(true); @@ -218,7 +218,7 @@ namespace MWGui case GM_ClassPick: MWBase::Environment::get().getWindowManager()->removeDialog(mPickClassDialog); - mPickClassDialog = 0; + mPickClassDialog = nullptr; mPickClassDialog = new PickClassDialog(); mPickClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen); mPickClassDialog->setClassId(mPlayerClass.mId); @@ -231,7 +231,7 @@ namespace MWGui case GM_Birth: MWBase::Environment::get().getWindowManager()->removeDialog(mBirthSignDialog); - mBirthSignDialog = 0; + mBirthSignDialog = nullptr; mBirthSignDialog = new BirthDialog(); mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen); mBirthSignDialog->setBirthId(mPlayerBirthSignId); @@ -266,7 +266,7 @@ namespace MWGui break; case GM_Review: MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog); - mReviewDialog = 0; + mReviewDialog = nullptr; mReviewDialog = new ReviewDialog(); MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -316,7 +316,7 @@ namespace MWGui void CharacterCreation::onReviewDialogDone(WindowBase* parWindow) { MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog); - mReviewDialog = 0; + mReviewDialog = nullptr; MWBase::Environment::get().getWindowManager()->popGuiMode(); } @@ -324,7 +324,7 @@ namespace MWGui void CharacterCreation::onReviewDialogBack() { MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog); - mReviewDialog = 0; + mReviewDialog = nullptr; mCreationStage = CSE_ReviewBack; MWBase::Environment::get().getWindowManager()->popGuiMode(); @@ -334,7 +334,7 @@ namespace MWGui void CharacterCreation::onReviewActivateDialog(int parDialog) { MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog); - mReviewDialog = 0; + mReviewDialog = nullptr; mCreationStage = CSE_ReviewNext; MWBase::Environment::get().getWindowManager()->popGuiMode(); @@ -370,7 +370,7 @@ namespace MWGui mPlayerClass = *klass; } MWBase::Environment::get().getWindowManager()->removeDialog(mPickClassDialog); - mPickClassDialog = 0; + mPickClassDialog = nullptr; } updatePlayerHealth(); @@ -394,7 +394,7 @@ namespace MWGui void CharacterCreation::onClassChoice(int _index) { MWBase::Environment::get().getWindowManager()->removeDialog(mClassChoiceDialog); - mClassChoiceDialog = 0; + mClassChoiceDialog = nullptr; MWBase::Environment::get().getWindowManager()->popGuiMode(); @@ -423,7 +423,7 @@ namespace MWGui mPlayerName = mNameDialog->getTextInput(); MWBase::Environment::get().getMechanicsManager()->setPlayerName(mPlayerName); MWBase::Environment::get().getWindowManager()->removeDialog(mNameDialog); - mNameDialog = 0; + mNameDialog = nullptr; } handleDialogDone(CSE_NameChosen, GM_Race); @@ -446,7 +446,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getInventoryWindow()->rebuildAvatar(); MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog); - mRaceDialog = 0; + mRaceDialog = nullptr; } updatePlayerHealth(); @@ -475,7 +475,7 @@ namespace MWGui if (!mPlayerBirthSignId.empty()) MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mPlayerBirthSignId); MWBase::Environment::get().getWindowManager()->removeDialog(mBirthSignDialog); - mBirthSignDialog = 0; + mBirthSignDialog = nullptr; } updatePlayerHealth(); @@ -551,7 +551,7 @@ namespace MWGui MWBase::Environment::get().getSoundManager()->stopSay(); MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassQuestionDialog); - mGenerateClassQuestionDialog = 0; + mGenerateClassQuestionDialog = nullptr; if (_index < 0 || _index >= 3) { @@ -669,7 +669,7 @@ namespace MWGui } MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog); - mGenerateClassResultDialog = 0; + mGenerateClassResultDialog = nullptr; mGenerateClassResultDialog = new GenerateClassResultDialog(); mGenerateClassResultDialog->setClassId(mGenerateClass); @@ -687,7 +687,7 @@ namespace MWGui } MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassQuestionDialog); - mGenerateClassQuestionDialog = 0; + mGenerateClassQuestionDialog = nullptr; mGenerateClassQuestionDialog = new InfoBoxDialog(); @@ -711,7 +711,7 @@ namespace MWGui void CharacterCreation::selectGeneratedClass() { MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog); - mGenerateClassResultDialog = 0; + mGenerateClassResultDialog = nullptr; MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index a92ad934c..ee5fe5939 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -217,7 +217,7 @@ namespace MWGui if (store.get().isDynamic(classInfo.mId)) continue; // custom-made class not relevant for this dialog - items.push_back(std::make_pair(classInfo.mId, classInfo.mName)); + items.emplace_back(classInfo.mId, classInfo.mName); } std::sort(items.begin(), items.end(), sortClasses); @@ -550,16 +550,16 @@ namespace MWGui void CreateClassDialog::onDialogCancel() { MWBase::Environment::get().getWindowManager()->removeDialog(mSpecDialog); - mSpecDialog = 0; + mSpecDialog = nullptr; MWBase::Environment::get().getWindowManager()->removeDialog(mAttribDialog); - mAttribDialog = 0; + mAttribDialog = nullptr; MWBase::Environment::get().getWindowManager()->removeDialog(mSkillDialog); - mSkillDialog = 0; + mSkillDialog = nullptr; MWBase::Environment::get().getWindowManager()->removeDialog(mDescDialog); - mDescDialog = 0; + mDescDialog = nullptr; } void CreateClassDialog::onSpecializationClicked(MyGUI::Widget* _sender) @@ -577,7 +577,7 @@ namespace MWGui setSpecialization(mSpecializationId); MWBase::Environment::get().getWindowManager()->removeDialog(mSpecDialog); - mSpecDialog = 0; + mSpecDialog = nullptr; } void CreateClassDialog::setSpecialization(int id) @@ -618,7 +618,7 @@ namespace MWGui } mAffectedAttribute->setAttributeId(id); MWBase::Environment::get().getWindowManager()->removeDialog(mAttribDialog); - mAttribDialog = 0; + mAttribDialog = nullptr; update(); } @@ -651,7 +651,7 @@ namespace MWGui mAffectedSkill->setSkillId(mSkillDialog->getSkillId()); MWBase::Environment::get().getWindowManager()->removeDialog(mSkillDialog); - mSkillDialog = 0; + mSkillDialog = nullptr; update(); } @@ -667,7 +667,7 @@ namespace MWGui { mDescription = mDescDialog->getTextInput(); MWBase::Environment::get().getWindowManager()->removeDialog(mDescDialog); - mDescDialog = 0; + mDescDialog = nullptr; } void CreateClassDialog::onOkClicked(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.cpp b/apps/openmw/mwgui/companionwindow.cpp index b3f6e3339..926456219 100644 --- a/apps/openmw/mwgui/companionwindow.cpp +++ b/apps/openmw/mwgui/companionwindow.cpp @@ -163,8 +163,8 @@ bool CompanionWindow::exit() if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0) { std::vector buttons; - buttons.push_back("#{sCompanionWarningButtonOne}"); - buttons.push_back("#{sCompanionWarningButtonTwo}"); + buttons.emplace_back("#{sCompanionWarningButtonOne}"); + buttons.emplace_back("#{sCompanionWarningButtonTwo}"); mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons); mMessageBoxManager->eventButtonPressed += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked); return false; 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..89ba5d388 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -30,13 +30,13 @@ 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, MWWorld::Ptr reference) : MWScript::InterpreterContext ( - reference.isEmpty() ? 0 : &reference.getRefData().getLocals(), reference), + reference.isEmpty() ? nullptr : &reference.getRefData().getLocals(), reference), mConsole (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.cpp b/apps/openmw/mwgui/container.cpp index a68fddca1..16b38eaf9 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -163,11 +163,16 @@ namespace MWGui { WindowBase::onClose(); + // Make sure the window was actually closed and not temporarily hidden. + if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container)) + return; + if (mModel) mModel->onClose(); if (!mPtr.isEmpty()) MWBase::Environment::get().getMechanicsManager()->onClose(mPtr); + resetReference(); } void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) @@ -184,6 +189,7 @@ namespace MWGui // transfer everything into the player's inventory ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel(); + assert(mModel); mModel->update(); // unequip all items to avoid unequipping/reequipping @@ -229,36 +235,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/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.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index 0cfa6ebf5..56f084bb9 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.emplace_back(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.emplace_back(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..c54f11314 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 { @@ -17,24 +22,24 @@ 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; + std::vector> mItemSources; std::vector mWorldItems; - + const bool mTrading; std::vector mItems; }; diff --git a/apps/openmw/mwgui/controllers.hpp b/apps/openmw/mwgui/controllers.hpp index bd9646ec2..416f104d9 100644 --- a/apps/openmw/mwgui/controllers.hpp +++ b/apps/openmw/mwgui/controllers.hpp @@ -9,21 +9,17 @@ namespace MyGUI class Widget; } -namespace MWGui -{ - namespace Controllers +namespace MWGui::Controllers { /// Automatically positions a widget below the mouse cursor. - class ControllerFollowMouse final : - public MyGUI::ControllerItem + class ControllerFollowMouse final : public MyGUI::ControllerItem { MYGUI_RTTI_DERIVED( ControllerFollowMouse ) private: - bool addTime(MyGUI::Widget* _widget, float _time) final; - void prepareItem(MyGUI::Widget* _widget) final; + bool addTime(MyGUI::Widget* _widget, float _time) override; + void prepareItem(MyGUI::Widget* _widget) override; }; } -} #endif diff --git a/apps/openmw/mwgui/cursor.hpp b/apps/openmw/mwgui/cursor.hpp index ef5099ef8..7e1f9adba 100644 --- a/apps/openmw/mwgui/cursor.hpp +++ b/apps/openmw/mwgui/cursor.hpp @@ -20,10 +20,10 @@ namespace MWGui ResourceImageSetPointerFix(); virtual ~ResourceImageSetPointerFix(); - void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final; + void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) override; - void setImage(MyGUI::ImageBox* _image) final; - void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point) final; + void setImage(MyGUI::ImageBox* _image) override; + void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point) override; //and now for the whole point of this class, allow us to get //the hot spot, the image and the size of the cursor. 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..fde029d77 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); } @@ -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 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/draganddrop.cpp b/apps/openmw/mwgui/draganddrop.cpp index daf9f6636..cfe60db5d 100644 --- a/apps/openmw/mwgui/draganddrop.cpp +++ b/apps/openmw/mwgui/draganddrop.cpp @@ -135,7 +135,7 @@ void DragAndDrop::finish() MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget); - mDraggedWidget = 0; + mDraggedWidget = nullptr; MWBase::Environment::get().getWindowManager()->setDragDrop(false); } 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.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/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/itemchargeview.hpp b/apps/openmw/mwgui/itemchargeview.hpp index 2522f55d1..039dcaf4e 100644 --- a/apps/openmw/mwgui/itemchargeview.hpp +++ b/apps/openmw/mwgui/itemchargeview.hpp @@ -36,7 +36,7 @@ namespace MWGui /// Register needed components with MyGUI's factory manager static void registerComponents(); - void initialiseOverride() final; + void initialiseOverride() override; /// Takes ownership of \a model void setModel(ItemModel* model); @@ -47,8 +47,8 @@ namespace MWGui void layoutWidgets(); void resetScrollbars(); - void setSize(const MyGUI::IntSize& value) final; - void setCoord(const MyGUI::IntCoord& value) final; + void setSize(const MyGUI::IntSize& value) override; + void setCoord(const MyGUI::IntCoord& value) override; MyGUI::delegates::CMultiDelegate2 eventItemClicked; 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/itemview.hpp b/apps/openmw/mwgui/itemview.hpp index a5e537aa0..4074e55e4 100644 --- a/apps/openmw/mwgui/itemview.hpp +++ b/apps/openmw/mwgui/itemview.hpp @@ -13,7 +13,7 @@ namespace MWGui MYGUI_RTTI_DERIVED(ItemView) public: ItemView(); - virtual ~ItemView(); + ~ItemView() override; /// Register needed components with MyGUI's factory manager static void registerComponents (); @@ -33,12 +33,12 @@ namespace MWGui void resetScrollBars(); private: - void initialiseOverride() final; + void initialiseOverride() override; void layoutWidgets(); - void setSize(const MyGUI::IntSize& _value) final; - void setCoord(const MyGUI::IntCoord& _value) final; + void setSize(const MyGUI::IntSize& _value) override; + void setCoord(const MyGUI::IntCoord& _value) override; void onSelectedItem (MyGUI::Widget* sender); void onSelectedBackground (MyGUI::Widget* sender); diff --git a/apps/openmw/mwgui/itemwidget.hpp b/apps/openmw/mwgui/itemwidget.hpp index 748a44445..550d73643 100644 --- a/apps/openmw/mwgui/itemwidget.hpp +++ b/apps/openmw/mwgui/itemwidget.hpp @@ -41,7 +41,7 @@ namespace MWGui void setFrame (const std::string& frame, const MyGUI::IntCoord& coord); protected: - void initialiseOverride() final; + void initialiseOverride() override; MyGUI::ImageBox* mItem; MyGUI::ImageBox* mItemShadow; diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index 67124884f..cc793073e 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -123,7 +123,7 @@ namespace MWGui } std::vector buttons; - buttons.push_back("#{sOk}"); + buttons.emplace_back("#{sOk}"); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons); } } 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); - - virtual void setVisible(bool visible); + 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; + + void setVisible(bool visible) override; double getTargetFrameRate() const; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 4778ee7b0..4e695710f 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -24,7 +24,7 @@ namespace MWGui MainMenu::MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription) : WindowBase("openmw_mainmenu.layout") , mWidth (w), mHeight (h) - , mVFS(vfs), mButtonBox(0) + , mVFS(vfs), mButtonBox(nullptr) , mBackground(nullptr) , mVideoBackground(nullptr) , mVideo(nullptr) @@ -231,25 +231,25 @@ namespace MWGui std::vector buttons; if (state==MWBase::StateManager::State_Running) - buttons.push_back("return"); + buttons.emplace_back("return"); - buttons.push_back("newgame"); + buttons.emplace_back("newgame"); if (state==MWBase::StateManager::State_Running && MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 && MWBase::Environment::get().getWindowManager()->isSavingAllowed()) - buttons.push_back("savegame"); + buttons.emplace_back("savegame"); if (MWBase::Environment::get().getStateManager()->characterBegin()!= MWBase::Environment::get().getStateManager()->characterEnd()) - buttons.push_back("loadgame"); + buttons.emplace_back("loadgame"); - buttons.push_back("options"); + buttons.emplace_back("options"); if (state==MWBase::StateManager::State_NoGame) - buttons.push_back("credits"); + buttons.emplace_back("credits"); - buttons.push_back("exitgame"); + buttons.emplace_back("exitgame"); // Create new buttons if needed std::vector allButtons { "return", "newgame", "savegame", "loadgame", "options", "credits", "exitgame"}; 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.cpp b/apps/openmw/mwgui/mapwindow.cpp index f0ece76d5..6e8804a43 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -74,12 +74,12 @@ namespace MyGUI::Colour mNormalColour; MyGUI::Colour mHoverColour; - void onMouseLostFocus(MyGUI::Widget* _new) final + void onMouseLostFocus(MyGUI::Widget* _new) override { setColour(mNormalColour); } - void onMouseSetFocus(MyGUI::Widget* _old) final + void onMouseSetFocus(MyGUI::Widget* _old) override { setColour(mHoverColour); } @@ -644,7 +644,7 @@ namespace MWGui : WindowPinnableBase("openmw_map_window.layout") , LocalMapBase(customMarkers, localMapRender) , NoDrop(drag, mMainWidget) - , mGlobalMap(0) + , mGlobalMap(nullptr) , mGlobalMapImage(nullptr) , mGlobalMapOverlay(nullptr) , mGlobal(Settings::Manager::getBool("global", "Map")) 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.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 8449e6a5b..a6bfac2a4 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -37,9 +37,9 @@ namespace MWGui , mKey(std::vector(10)) , mSelected(nullptr) , mActivated(nullptr) - , mAssignDialog(0) - , mItemSelectionDialog(0) - , mMagicSelectionDialog(0) + , mAssignDialog(nullptr) + , mItemSelectionDialog(nullptr) + , mMagicSelectionDialog(nullptr) { getWidget(mOkButton, "OKButton"); @@ -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/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.cpp b/apps/openmw/mwgui/race.cpp index cf69ecca3..457594697 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -358,7 +358,7 @@ namespace MWGui if (!playable) // Only display playable races continue; - items.push_back(std::make_pair(race.mId, race.mName)); + items.emplace_back(race.mId, race.mName); } std::sort(items.begin(), items.end(), sortRaces); 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/resourceskin.hpp b/apps/openmw/mwgui/resourceskin.hpp index bdf0d2f0b..fd1977e66 100644 --- a/apps/openmw/mwgui/resourceskin.hpp +++ b/apps/openmw/mwgui/resourceskin.hpp @@ -10,7 +10,7 @@ namespace MWGui MYGUI_RTTI_DERIVED( AutoSizedResourceSkin ) public: - void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final; + void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) override; }; } diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index e76cbe770..101b6956d 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -86,7 +86,7 @@ namespace MWGui for (int i = 0; i < ESM::Skill::Length; ++i) { mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue())); - mSkillWidgetMap.insert(std::make_pair(i, static_cast (0))); + mSkillWidgetMap.insert(std::make_pair(i, static_cast (nullptr))); } MyGUI::Button* backButton; 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.cpp b/apps/openmw/mwgui/settingswindow.cpp index aec3396a1..68dac4a95 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 @@ -244,7 +244,7 @@ namespace MWGui { SDL_DisplayMode mode; SDL_GetDisplayMode(screen, i, &mode); - resolutions.push_back(std::make_pair(mode.w, mode.h)); + resolutions.emplace_back(mode.w, mode.h); } std::sort(resolutions.begin(), resolutions.end(), sortResolutions); for (std::pair& resolution : resolutions) 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.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index f18cac681..28b13cdf0 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -31,18 +31,18 @@ namespace { // this defines the sorting order of types. types that are first in the vector appear before other types. std::vector mapping; - mapping.push_back( typeid(ESM::Weapon).name() ); - mapping.push_back( typeid(ESM::Armor).name() ); - mapping.push_back( typeid(ESM::Clothing).name() ); - mapping.push_back( typeid(ESM::Potion).name() ); - mapping.push_back( typeid(ESM::Ingredient).name() ); - mapping.push_back( typeid(ESM::Apparatus).name() ); - mapping.push_back( typeid(ESM::Book).name() ); - mapping.push_back( typeid(ESM::Light).name() ); - mapping.push_back( typeid(ESM::Miscellaneous).name() ); - mapping.push_back( typeid(ESM::Lockpick).name() ); - mapping.push_back( typeid(ESM::Repair).name() ); - mapping.push_back( typeid(ESM::Probe).name() ); + mapping.emplace_back(typeid(ESM::Weapon).name() ); + mapping.emplace_back(typeid(ESM::Armor).name() ); + mapping.emplace_back(typeid(ESM::Clothing).name() ); + mapping.emplace_back(typeid(ESM::Potion).name() ); + mapping.emplace_back(typeid(ESM::Ingredient).name() ); + mapping.emplace_back(typeid(ESM::Apparatus).name() ); + mapping.emplace_back(typeid(ESM::Book).name() ); + mapping.emplace_back(typeid(ESM::Light).name() ); + mapping.emplace_back(typeid(ESM::Miscellaneous).name() ); + mapping.emplace_back(typeid(ESM::Lockpick).name() ); + mapping.emplace_back(typeid(ESM::Repair).name() ); + mapping.emplace_back(typeid(ESM::Probe).name() ); assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() ); assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() ); @@ -166,7 +166,7 @@ namespace MWGui void SortFilterItemModel::addDragItem (const MWWorld::Ptr& dragItem, size_t count) { - mDragItems.push_back(std::make_pair(dragItem, count)); + mDragItems.emplace_back(dragItem, count); } void SortFilterItemModel::clearDragItems() 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/soulgemdialog.cpp b/apps/openmw/mwgui/soulgemdialog.cpp index 104c81eab..345c8b722 100644 --- a/apps/openmw/mwgui/soulgemdialog.cpp +++ b/apps/openmw/mwgui/soulgemdialog.cpp @@ -12,8 +12,8 @@ namespace MWGui { mSoulgem = soulgem; std::vector buttons; - buttons.push_back("#{sRechargeEnchantment}"); - buttons.push_back("#{sMake Enchantment}"); + buttons.emplace_back("#{sRechargeEnchantment}"); + buttons.emplace_back("#{sMake Enchantment}"); mManager->createInteractiveMessageBox("#{sDoYouWantTo}", buttons); mManager->eventButtonPressed += MyGUI::newDelegate(this, &SoulgemDialog::onButtonPressed); } 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.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 1f086507f..f9de469e2 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -587,7 +587,7 @@ namespace MWGui mAddEffectDialog.newEffect(effect); mAddEffectDialog.setAttribute (mSelectAttributeDialog->getAttributeId()); MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog); - mSelectAttributeDialog = 0; + mSelectAttributeDialog = nullptr; } void EffectEditorBase::onSelectSkill () @@ -598,7 +598,7 @@ namespace MWGui mAddEffectDialog.newEffect(effect); mAddEffectDialog.setSkill (mSelectSkillDialog->getSkillId()); MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog); - mSelectSkillDialog = 0; + mSelectSkillDialog = nullptr; } void EffectEditorBase::onAttributeOrSkillCancel () @@ -608,8 +608,8 @@ namespace MWGui if (mSelectAttributeDialog) MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog); - mSelectSkillDialog = 0; - mSelectAttributeDialog = 0; + mSelectSkillDialog = nullptr; + mSelectAttributeDialog = nullptr; } void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender) 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/spellmodel.cpp b/apps/openmw/mwgui/spellmodel.cpp index 1dedfa10b..136547c4c 100644 --- a/apps/openmw/mwgui/spellmodel.cpp +++ b/apps/openmw/mwgui/spellmodel.cpp @@ -42,6 +42,44 @@ namespace MWGui { } + bool SpellModel::matchingEffectExists(std::string filter, const ESM::EffectList &effects) + { + auto wm = MWBase::Environment::get().getWindowManager(); + const MWWorld::ESMStore &store = + MWBase::Environment::get().getWorld()->getStore(); + + for (unsigned int i = 0; i < effects.mList.size(); ++i) + { + short effectId = effects.mList[i].mEffectID; + + if (effectId != -1) + { + const ESM::MagicEffect *magicEffect = + store.get().search(effectId); + std::string effectIDStr = ESM::MagicEffect::effectIdToString(effectId); + std::string fullEffectName = wm->getGameSettingString(effectIDStr, ""); + + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill && effects.mList[i].mSkill != -1) + { + fullEffectName += " " + wm->getGameSettingString(ESM::Skill::sSkillNameIds[effects.mList[i].mSkill], ""); + } + + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute && effects.mList[i].mAttribute != -1) + { + fullEffectName += " " + wm->getGameSettingString(ESM::Attribute::sGmstAttributeIds[effects.mList[i].mAttribute], ""); + } + + std::string convert = Misc::StringUtils::lowerCaseUtf8(fullEffectName); + if (convert.find(filter) != std::string::npos) + { + return true; + } + } + } + + return false; + } + void SpellModel::update() { mSpells.clear(); @@ -61,8 +99,9 @@ namespace MWGui continue; std::string name = Misc::StringUtils::lowerCaseUtf8(spell->mName); - - if (name.find(filter) == std::string::npos) + + if (name.find(filter) == std::string::npos + && !matchingEffectExists(filter, spell->mEffects)) continue; Spell newSpell; @@ -103,7 +142,8 @@ namespace MWGui std::string name = Misc::StringUtils::lowerCaseUtf8(item.getClass().getName(item)); - if (name.find(filter) == std::string::npos) + if (name.find(filter) == std::string::npos + && !matchingEffectExists(filter, enchant->mEffects)) continue; Spell newSpell; diff --git a/apps/openmw/mwgui/spellmodel.hpp b/apps/openmw/mwgui/spellmodel.hpp index d191cba0e..2404610bf 100644 --- a/apps/openmw/mwgui/spellmodel.hpp +++ b/apps/openmw/mwgui/spellmodel.hpp @@ -2,6 +2,7 @@ #define OPENMW_GUI_SPELLMODEL_H #include "../mwworld/ptr.hpp" +#include namespace MWGui { @@ -57,6 +58,8 @@ namespace MWGui std::vector mSpells; std::string mFilter; + + bool matchingEffectExists(std::string filter, const ESM::EffectList &effects); }; } diff --git a/apps/openmw/mwgui/spellview.cpp b/apps/openmw/mwgui/spellview.cpp index f03c1cedb..a8b7cb639 100644 --- a/apps/openmw/mwgui/spellview.cpp +++ b/apps/openmw/mwgui/spellview.cpp @@ -128,10 +128,10 @@ namespace MWGui group.push_back(costChance); Gui::SharedStateButton::createButtonGroup(group); - mLines.push_back(LineInfo(t, costChance, i)); + mLines.emplace_back(t, costChance, i); } else - mLines.push_back(LineInfo(t, (MyGUI::Widget*)nullptr, i)); + mLines.emplace_back(t, (MyGUI::Widget*)nullptr, i); t->setStateSelected(spell.mSelected); } @@ -236,7 +236,7 @@ namespace MWGui MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 18), MyGUI::Align::Left | MyGUI::Align::Top); separator->setNeedMouseFocus(false); - mLines.push_back(LineInfo(separator, (MyGUI::Widget*)nullptr, NoSpellIndex)); + mLines.emplace_back(separator, (MyGUI::Widget*)nullptr, NoSpellIndex); } MyGUI::TextBox* groupWidget = mScrollView->createWidget("SandBrightText", @@ -255,10 +255,10 @@ namespace MWGui groupWidget2->setTextAlign(MyGUI::Align::Right); groupWidget2->setNeedMouseFocus(false); - mLines.push_back(LineInfo(groupWidget, groupWidget2, NoSpellIndex)); + mLines.emplace_back(groupWidget, groupWidget2, NoSpellIndex); } else - mLines.push_back(LineInfo(groupWidget, (MyGUI::Widget*)nullptr, NoSpellIndex)); + mLines.emplace_back(groupWidget, (MyGUI::Widget*)nullptr, NoSpellIndex); } diff --git a/apps/openmw/mwgui/spellview.hpp b/apps/openmw/mwgui/spellview.hpp index a387cac39..6b3effc45 100644 --- a/apps/openmw/mwgui/spellview.hpp +++ b/apps/openmw/mwgui/spellview.hpp @@ -47,10 +47,10 @@ namespace MWGui /// Fired when a spell was clicked EventHandle_ModelIndex eventSpellClicked; - void initialiseOverride() final; + void initialiseOverride() override; - void setSize(const MyGUI::IntSize& _value) final; - void setCoord(const MyGUI::IntCoord& _value) final; + void setSize(const MyGUI::IntSize& _value) override; + void setCoord(const MyGUI::IntCoord& _value) override; void resetScrollbars(); 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/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/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index c0db57b1b..e0a8e4d3e 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -153,7 +153,7 @@ namespace MWGui return; MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getMouseFocusWidget(); - if (focus == 0) + if (focus == nullptr) return; MyGUI::IntSize tooltipSize; @@ -410,7 +410,7 @@ namespace MWGui if (text.size() > 0 && text[0] == '\n') text.erase(0, 1); - const ESM::Enchantment* enchant = 0; + const ESM::Enchantment* enchant = nullptr; const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (info.enchant != "") { 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..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); @@ -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..81d6a8ab3 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,12 @@ namespace MWGui mTradeModel = nullptr; mSortModel = nullptr; } + + void TradeWindow::onClose() + { + // Make sure the window was actually closed and not temporarily hidden. + if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Barter)) + return; + resetReference(); + } } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 0730df04f..f82d7b0f7 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -27,19 +27,20 @@ namespace MWGui public: TradeWindow(); - void setPtr(const MWWorld::Ptr& actor); + void setPtr(const MWWorld::Ptr& actor) 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; @@ -108,11 +109,9 @@ namespace MWGui void updateLabels(); - virtual void onReferenceUnavailable(); + void onReferenceUnavailable() override; int getMerchantGold(); - - void restock(); }; } diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index da3c7d186..7fae33bae 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -84,7 +84,7 @@ namespace MWGui { float value = getSkillForTraining(actorStats, i); - skills.push_back(std::make_pair(i, value)); + skills.emplace_back(i, value); } std::sort(skills.begin(), skills.end(), sortSkills); 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/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 74076641a..fb8521f06 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -101,7 +101,7 @@ namespace MWGui button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); } - button = 0; + button = nullptr; assignWidget(button, "StatValueButton"); if (button) { @@ -192,7 +192,7 @@ namespace MWGui button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); } - button = 0; + button = nullptr; assignWidget(button, "StatValueButton"); if (button) { diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index ff3b2311a..731a41a35 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -116,7 +116,7 @@ namespace MWGui protected: virtual ~MWSkill(); - void initialiseOverride() final; + void initialiseOverride() override; void onClicked(MyGUI::Widget* _sender); @@ -156,7 +156,7 @@ namespace MWGui protected: virtual ~MWAttribute(); - void initialiseOverride() final; + void initialiseOverride() override; void onClicked(MyGUI::Widget* _sender); @@ -199,7 +199,7 @@ namespace MWGui protected: virtual ~MWSpell(); - void initialiseOverride() final; + void initialiseOverride() override; private: void updateWidgets(); @@ -241,7 +241,7 @@ namespace MWGui protected: virtual ~MWEffectList(); - void initialiseOverride() final; + void initialiseOverride() override; private: void updateWidgets(); @@ -265,7 +265,7 @@ namespace MWGui protected: virtual ~MWSpellEffect(); - void initialiseOverride() final; + void initialiseOverride() override; private: static const int sIconOffset = 24; @@ -294,7 +294,7 @@ namespace MWGui protected: virtual ~MWDynamicStat(); - void initialiseOverride() final; + void initialiseOverride() override; private: 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.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 840f0f9cf..bfce90810 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1957,7 +1957,7 @@ namespace MWGui { if (_type != "Text") return; - char* text=0; + char* text=nullptr; text = SDL_GetClipboardText(); if (text) _data = MyGUI::TextIterator::toTagsString(text); 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.cpp b/apps/openmw/mwinput/mousemanager.cpp index ac30d4487..4816470ff 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -154,7 +154,7 @@ namespace MWInput { guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - if (MyGUI::InputManager::getInstance().getMouseFocusWidget () != 0) + if (MyGUI::InputManager::getInstance().getMouseFocusWidget () != nullptr) { MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); if (b && b->getEnabled() && id == SDL_BUTTON_LEFT) 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 3de1a3acc..047741bac 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; @@ -199,7 +199,7 @@ namespace MWMechanics if (sourceId != mSpellId) return; - mMagnitudes.push_back(std::make_pair(key, magnitude)); + mMagnitudes.emplace_back(key, magnitude); } std::vector> mMagnitudes; @@ -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; @@ -590,7 +590,9 @@ namespace MWMechanics if (!actorState.isTurningToPlayer()) { - float angle = std::atan2(dir.x(), dir.y()); + float from = dir.x(); + float to = dir.y(); + float angle = std::atan2(from, to); actorState.setAngleToPlayer(angle); float deltaAngle = Misc::normalizeAngle(angle - actor.getRefData().getPosition().rot[2]); if (!mSmoothMovement || std::abs(deltaAngle) > osg::DegreesToRadians(60.f)) @@ -901,9 +903,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) { @@ -914,10 +916,53 @@ namespace MWMechanics } }; + void Actors::applyCureEffects(const MWWorld::Ptr& actor) + { + CreatureStats &creatureStats = actor.getClass().getCreatureStats(actor); + const MagicEffects &effects = creatureStats.getMagicEffects(); + + if (effects.get(ESM::MagicEffect::CurePoison).getModifier() > 0) + { + creatureStats.getActiveSpells().purgeEffect(ESM::MagicEffect::Poison); + creatureStats.getSpells().purgeEffect(ESM::MagicEffect::Poison); + if (actor.getClass().hasInventoryStore(actor)) + actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Poison); + } + else if (effects.get(ESM::MagicEffect::CureParalyzation).getModifier() > 0) + { + creatureStats.getActiveSpells().purgeEffect(ESM::MagicEffect::Paralyze); + creatureStats.getSpells().purgeEffect(ESM::MagicEffect::Paralyze); + if (actor.getClass().hasInventoryStore(actor)) + actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Paralyze); + } + else if (effects.get(ESM::MagicEffect::CureCommonDisease).getModifier() > 0) + { + creatureStats.getSpells().purgeCommonDisease(); + } + else if (effects.get(ESM::MagicEffect::CureBlightDisease).getModifier() > 0) + { + creatureStats.getSpells().purgeBlightDisease(); + } + else if (effects.get(ESM::MagicEffect::CureCorprusDisease).getModifier() > 0) + { + creatureStats.getActiveSpells().purgeCorprusDisease(); + creatureStats.getSpells().purgeCorprusDisease(); + if (actor.getClass().hasInventoryStore(actor)) + actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Corprus, true); + } + else if (effects.get(ESM::MagicEffect::RemoveCurse).getModifier() > 0) + { + creatureStats.getSpells().purgeCurses(); + } + } + void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration) { CreatureStats &creatureStats = ptr.getClass().getCreatureStats(ptr); const MagicEffects &effects = creatureStats.getMagicEffects(); + bool godmode = ptr == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); + + applyCureEffects(ptr); bool wasDead = creatureStats.isDead(); @@ -969,8 +1014,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 +1030,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); } @@ -1189,6 +1242,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) { @@ -1214,14 +1272,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)); } } @@ -1667,9 +1731,13 @@ namespace MWMechanics void Actors::predictAndAvoidCollisions() { + if (!MWBase::Environment::get().getMechanicsManager()->isAIActive()) + return; + 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 +1748,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 @@ -1696,7 +1770,7 @@ namespace MWMechanics shouldAvoidCollision = true; else if (package->getTypeId() == AiPackageTypeId::Wander && giveWayWhenIdle) { - if (!dynamic_cast(package.get())->isStationary()) + if (!static_cast(package.get())->isStationary()) shouldAvoidCollision = true; } else if (package->getTypeId() == AiPackageTypeId::Combat || package->getTypeId() == AiPackageTypeId::Pursue) @@ -1710,11 +1784,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 +1804,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,21 +1842,23 @@ 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); + 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) @@ -1827,6 +1904,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 +2085,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/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 9299d468c..453540001 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -206,6 +206,7 @@ namespace MWMechanics private: void updateVisibility (const MWWorld::Ptr& ptr, CharacterController* ctrl); + void applyCureEffects (const MWWorld::Ptr& actor); PtrActorMap mActors; float mTimerDisposeSummonsCorpses; 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/mwmechanics/aiactivate.hpp b/apps/openmw/mwmechanics/aiactivate.hpp index c53744e88..dc7e0bb26 100644 --- a/apps/openmw/mwmechanics/aiactivate.hpp +++ b/apps/openmw/mwmechanics/aiactivate.hpp @@ -24,15 +24,15 @@ namespace MWMechanics public: /// Constructor /** \param objectId Reference to object to activate **/ - AiActivate(const std::string &objectId); + explicit AiActivate(const std::string &objectId); - AiActivate(const ESM::AiSequence::AiActivate* activate); + explicit AiActivate(const ESM::AiSequence::AiActivate* activate); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; } - void writeState(ESM::AiSequence::AiSequence& sequence) const final; + void writeState(ESM::AiSequence::AiSequence& sequence) const override; private: const std::string mObjectId; diff --git a/apps/openmw/mwmechanics/aiavoiddoor.hpp b/apps/openmw/mwmechanics/aiavoiddoor.hpp index cd0718e2e..1781c5e4a 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.hpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.hpp @@ -20,9 +20,9 @@ namespace MWMechanics { public: /// Avoid door until the door is fully open - AiAvoidDoor(const MWWorld::ConstPtr& doorPtr); + explicit AiAvoidDoor(const MWWorld::ConstPtr& doorPtr); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::AvoidDoor; } diff --git a/apps/openmw/mwmechanics/aibreathe.hpp b/apps/openmw/mwmechanics/aibreathe.hpp index 7e9ac69da..b84c0eb76 100644 --- a/apps/openmw/mwmechanics/aibreathe.hpp +++ b/apps/openmw/mwmechanics/aibreathe.hpp @@ -10,7 +10,7 @@ namespace MWMechanics class AiBreathe final : public TypedAiPackage { public: - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Breathe; } diff --git a/apps/openmw/mwmechanics/aicast.hpp b/apps/openmw/mwmechanics/aicast.hpp index 1175dccd2..9758c2b94 100644 --- a/apps/openmw/mwmechanics/aicast.hpp +++ b/apps/openmw/mwmechanics/aicast.hpp @@ -15,11 +15,11 @@ namespace MWMechanics public: AiCast(const std::string& targetId, const std::string& spellId, bool manualSpell=false); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Cast; } - MWWorld::Ptr getTarget() const final; + MWWorld::Ptr getTarget() const override; static constexpr Options makeDefaultOptions() { 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 (storage.mReadyToAttack) + if (isRangedCombat) { - 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; + // 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.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) + { storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target); // start new attack storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat); diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp index ff8a0e081..64645ca94 100644 --- a/apps/openmw/mwmechanics/aicombat.hpp +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -96,13 +96,13 @@ namespace MWMechanics public: ///Constructor /** \param actor Actor to fight **/ - AiCombat(const MWWorld::Ptr& actor); + explicit AiCombat(const MWWorld::Ptr& actor); - AiCombat (const ESM::AiSequence::AiCombat* combat); + explicit AiCombat (const ESM::AiSequence::AiCombat* combat); void init(); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Combat; } @@ -116,9 +116,9 @@ namespace MWMechanics } ///Returns target ID - MWWorld::Ptr getTarget() const final; + MWWorld::Ptr getTarget() const override; - void writeState(ESM::AiSequence::AiSequence &sequence) const final; + void writeState(ESM::AiSequence::AiSequence &sequence) const override; private: /// Returns true if combat should end 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/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index edfd0ca3f..27a177893 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -30,7 +30,7 @@ namespace MWMechanics AiEscort(const ESM::AiSequence::AiEscort* escort); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Escort; } @@ -42,11 +42,11 @@ namespace MWMechanics return options; } - void writeState(ESM::AiSequence::AiSequence &sequence) const final; + void writeState(ESM::AiSequence::AiSequence &sequence) const override; - void fastForward(const MWWorld::Ptr& actor, AiState& state) final; + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - osg::Vec3f getDestination() const final { return osg::Vec3f(mX, mY, mZ); } + osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } private: const std::string mCellId; diff --git a/apps/openmw/mwmechanics/aiface.hpp b/apps/openmw/mwmechanics/aiface.hpp index a5ee67a14..e176eb52e 100644 --- a/apps/openmw/mwmechanics/aiface.hpp +++ b/apps/openmw/mwmechanics/aiface.hpp @@ -10,7 +10,7 @@ namespace MWMechanics public: AiFace(float targetX, float targetY); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Face; } diff --git a/apps/openmw/mwmechanics/aifollow.hpp b/apps/openmw/mwmechanics/aifollow.hpp index d0c2cec97..e6aeebb24 100644 --- a/apps/openmw/mwmechanics/aifollow.hpp +++ b/apps/openmw/mwmechanics/aifollow.hpp @@ -53,7 +53,7 @@ namespace MWMechanics AiFollow(const ESM::AiSequence::AiFollow* follow); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Follow; } @@ -69,15 +69,15 @@ namespace MWMechanics /// Returns the actor being followed std::string getFollowedActor(); - void writeState (ESM::AiSequence::AiSequence& sequence) const final; + void writeState (ESM::AiSequence::AiSequence& sequence) const override; bool isCommanded() const; int getFollowIndex() const; - void fastForward(const MWWorld::Ptr& actor, AiState& state) final; + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - osg::Vec3f getDestination() const final + osg::Vec3f getDestination() const override { MWWorld::Ptr target = getTarget(); if (target.isEmpty()) diff --git a/apps/openmw/mwmechanics/aipursue.hpp b/apps/openmw/mwmechanics/aipursue.hpp index 64465f530..2fbc13b87 100644 --- a/apps/openmw/mwmechanics/aipursue.hpp +++ b/apps/openmw/mwmechanics/aipursue.hpp @@ -26,7 +26,7 @@ namespace MWMechanics AiPursue(const ESM::AiSequence::AiPursue* pursue); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Pursue; } @@ -38,9 +38,9 @@ namespace MWMechanics return options; } - MWWorld::Ptr getTarget() const final; + MWWorld::Ptr getTarget() const override; - void writeState (ESM::AiSequence::AiSequence& sequence) const final; + void writeState (ESM::AiSequence::AiSequence& sequence) const override; }; } #endif diff --git a/apps/openmw/mwmechanics/aitravel.hpp b/apps/openmw/mwmechanics/aitravel.hpp index 0c19572d2..2ea2a8f71 100644 --- a/apps/openmw/mwmechanics/aitravel.hpp +++ b/apps/openmw/mwmechanics/aitravel.hpp @@ -25,14 +25,14 @@ namespace MWMechanics AiTravel(float x, float y, float z); - AiTravel(const ESM::AiSequence::AiTravel* travel); + explicit AiTravel(const ESM::AiSequence::AiTravel* travel); /// Simulates the passing of time - void fastForward(const MWWorld::Ptr& actor, AiState& state) final; + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - void writeState(ESM::AiSequence::AiSequence &sequence) const final; + void writeState(ESM::AiSequence::AiSequence &sequence) const override; - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; } @@ -44,7 +44,7 @@ namespace MWMechanics return options; } - osg::Vec3f getDestination() const final { return osg::Vec3f(mX, mY, mZ); } + osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } private: const float mX; @@ -62,7 +62,7 @@ namespace MWMechanics static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::InternalTravel; } - std::unique_ptr clone() const final; + std::unique_ptr clone() const override; }; } diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 4165cebbd..68bcddf22 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -89,9 +89,9 @@ namespace MWMechanics \param repeat Repeat wander or not **/ AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat); - AiWander (const ESM::AiSequence::AiWander* wander); + explicit AiWander (const ESM::AiSequence::AiWander* wander); - bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Wander; } @@ -103,13 +103,13 @@ namespace MWMechanics return options; } - void writeState(ESM::AiSequence::AiSequence &sequence) const final; + void writeState(ESM::AiSequence::AiSequence &sequence) const override; - void fastForward(const MWWorld::Ptr& actor, AiState& state) final; + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - osg::Vec3f getDestination(const MWWorld::Ptr& actor) const final; + osg::Vec3f getDestination(const MWWorld::Ptr& actor) const override; - osg::Vec3f getDestination() const final + osg::Vec3f getDestination() const override { if (!mHasDestination) return osg::Vec3f(0, 0, 0); diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index 116937fcd..6d06724f0 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -255,7 +255,7 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) co return &(*iter); } - return 0; + return nullptr; } void MWMechanics::Alchemy::removeIngredients() diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 1dcccb888..9b3c8576e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -270,6 +270,7 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle) mCurrentHit = "shield"; MWRender::Animation::AnimPriority priorityBlock (Priority_Hit); priorityBlock[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block; + priorityBlock[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; mAnimation->play(mCurrentHit, priorityBlock, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0); } @@ -289,6 +290,8 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle) mUpperBodyState = UpperCharState_Nothing; } } + if (mHitState != CharState_None) + idle = CharState_None; } else if(!mAnimation->isPlaying(mCurrentHit)) { @@ -308,8 +311,6 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle) mAnimation->disable(mCurrentHit); mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "loop stop", "stop", 0.0f, 0); } - if (mHitState != CharState_None) - idle = CharState_None; } void CharacterController::refreshJumpAnims(const std::string& weapShortGroup, JumpingState jump, CharacterState& idle, bool force) @@ -935,7 +936,7 @@ void split(const std::string &s, char delim, std::vector &elems) { } } -void CharacterController::handleTextKey(const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key, const NifOsg::TextKeyMap& map) +void CharacterController::handleTextKey(const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) { const std::string &evt = key->second; @@ -1929,7 +1930,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); @@ -1966,6 +1967,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 +1977,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/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 0336c4e69..2308ba971 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, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) override; // Be careful when to call this, see comment in Actors void updateContinuousVfx(); 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..b1db2562b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -971,7 +971,7 @@ namespace MWMechanics { const OwnerMap& owners = it->second; for (OwnerMap::const_iterator ownerIt = owners.begin(); ownerIt != owners.end(); ++ownerIt) - result.push_back(std::make_pair(ownerIt->first.first, ownerIt->second)); + result.emplace_back(ownerIt->first.first, ownerIt->second); return result; } } @@ -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/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/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); } diff --git a/apps/openmw/mwmechanics/spellabsorption.cpp b/apps/openmw/mwmechanics/spellabsorption.cpp index 71e1d0aee..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) { @@ -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); 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/tickableeffects.cpp b/apps/openmw/mwmechanics/tickableeffects.cpp index 31e8c150c..5056179f8 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) @@ -188,24 +205,6 @@ namespace MWMechanics break; } - case ESM::MagicEffect::CurePoison: - actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Poison); - break; - case ESM::MagicEffect::CureParalyzation: - actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Paralyze); - break; - case ESM::MagicEffect::CureCommonDisease: - actor.getClass().getCreatureStats(actor).getSpells().purgeCommonDisease(); - break; - case ESM::MagicEffect::CureBlightDisease: - actor.getClass().getCreatureStats(actor).getSpells().purgeBlightDisease(); - break; - case ESM::MagicEffect::CureCorprusDisease: - actor.getClass().getCreatureStats(actor).getSpells().purgeCorprusDisease(); - break; - case ESM::MagicEffect::RemoveCurse: - actor.getClass().getCreatureStats(actor).getSpells().purgeCurses(); - break; default: return false; } diff --git a/apps/openmw/mwmechanics/tickableeffects.hpp b/apps/openmw/mwmechanics/tickableeffects.hpp index c4abed6a3..ccd42ca19 100644 --- a/apps/openmw/mwmechanics/tickableeffects.hpp +++ b/apps/openmw/mwmechanics/tickableeffects.hpp @@ -12,6 +12,7 @@ namespace MWMechanics struct EffectKey; /// Apply a magic effect that is applied in tick intervals until its remaining time ends or it is removed + /// Note: this function works in loop, so magic effects should not be removed here to avoid iterator invalidation. /// @return Was the effect a tickable effect with a magnitude? bool effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const EffectKey& effectKey, float magnitude); } 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/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/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 0f8814aca..0e557378d 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -12,37 +12,35 @@ #include "../mwworld/class.hpp" #include "collisiontype.hpp" +#include "mtphysics.hpp" namespace MWPhysics { -Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr shape, btCollisionWorld* world) - : mCanWaterWalk(false), mWalkingOnWater(false) - , mCollisionObject(nullptr), mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) +Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler) + : mStandingOnPtr(nullptr), 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; - 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; @@ -76,20 +74,19 @@ Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr updateRotation(); updateScale(); - updatePosition(); - + resetPosition(); addCollisionMask(getCollisionMask()); } Actor::~Actor() { - if (mCollisionObject.get()) - mCollisionWorld->removeCollisionObject(mCollisionObject.get()); + if (mCollisionObject) + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } void Actor::enableCollisionMode(bool collision) { - mInternalCollisionMode = collision; + mInternalCollisionMode.store(collision, std::memory_order_release); } void Actor::enableCollisionBody(bool collision) @@ -103,16 +100,15 @@ 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() { - mCollisionWorld->removeCollisionObject(mCollisionObject.get()); - addCollisionMask(getCollisionMask()); + mTaskScheduler->setCollisionFilterMask(mCollisionObject.get(), getCollisionMask()); } -int Actor::getCollisionMask() +int Actor::getCollisionMask() const { int collisionMask = CollisionType_World | CollisionType_HeightMap; if (mExternalCollisionMode) @@ -120,39 +116,79 @@ int Actor::getCollisionMask() if (mCanWaterWalk) collisionMask |= CollisionType_Water; return collisionMask; - +} + +void Actor::updatePositionUnsafe() +{ + mWorldPosition = mPtr.getRefData().getPosition().asVec3(); } void Actor::updatePosition() { - osg::Vec3f position = mPtr.getRefData().getPosition().asVec3(); + std::scoped_lock lock(mPositionMutex); + updatePositionUnsafe(); +} - mPosition = position; - mPreviousPosition = position; +osg::Vec3f Actor::getWorldPosition() const +{ + std::scoped_lock lock(mPositionMutex); + return mWorldPosition; +} - updateCollisionObjectPosition(); +void Actor::setSimulationPosition(const osg::Vec3f& position) +{ + mSimulationPosition = position; } -void Actor::updateCollisionObjectPosition() +osg::Vec3f Actor::getSimulationPosition() const { - btTransform tr = mCollisionObject->getWorldTransform(); + return mSimulationPosition; +} + +void Actor::updateCollisionObjectPositionUnsafe() +{ + mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); 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)); + mCollisionObject->setWorldTransform(mLocalTransform); +} + +void Actor::updateCollisionObjectPosition() +{ + std::scoped_lock lock(mPositionMutex); + updateCollisionObjectPositionUnsafe(); } osg::Vec3f Actor::getCollisionObjectPosition() const { - return Misc::Convert::toOsg(mCollisionObject->getWorldTransform().getOrigin()); + std::scoped_lock lock(mPositionMutex); + return Misc::Convert::toOsg(mLocalTransform.getOrigin()); } -void Actor::setPosition(const osg::Vec3f &position) +void Actor::setPosition(const osg::Vec3f& position) { + std::scoped_lock lock(mPositionMutex); mPreviousPosition = mPosition; - mPosition = position; - updateCollisionObjectPosition(); +} + +void Actor::adjustPosition(const osg::Vec3f& offset) +{ + std::scoped_lock lock(mPositionMutex); + mPosition += offset; + mPreviousPosition += offset; +} + +void Actor::resetPosition() +{ + std::scoped_lock lock(mPositionMutex); + updatePositionUnsafe(); + mPreviousPosition = mWorldPosition; + mPosition = mWorldPosition; + mSimulationPosition = mWorldPosition; + updateCollisionObjectPositionUnsafe(); } osg::Vec3f Actor::getPosition() const @@ -167,12 +203,10 @@ osg::Vec3f Actor::getPreviousPosition() const void Actor::updateRotation () { - btTransform tr = mCollisionObject->getWorldTransform(); + std::scoped_lock lock(mPositionMutex); + if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude()) + return; mRotation = mPtr.getRefData().getBaseNode()->getAttitude(); - tr.setRotation(Misc::Convert::toBullet(mRotation)); - mCollisionObject->setWorldTransform(tr); - - updateCollisionObjectPosition(); } bool Actor::isRotationallyInvariant() const @@ -182,32 +216,33 @@ bool Actor::isRotationallyInvariant() const void Actor::updateScale() { + std::scoped_lock lock(mPositionMutex); float scale = mPtr.getCellRef().getScale(); osg::Vec3f scaleVec(scale,scale,scale); mPtr.getClass().adjustScale(mPtr, scaleVec, false); mScale = scaleVec; - mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); scaleVec = osg::Vec3f(scale,scale,scale); mPtr.getClass().adjustScale(mPtr, scaleVec, true); mRenderingScale = scaleVec; - - updateCollisionObjectPosition(); } osg::Vec3f Actor::getHalfExtents() const { + std::scoped_lock lock(mPositionMutex); return osg::componentMultiply(mHalfExtents, mScale); } osg::Vec3f Actor::getOriginalHalfExtents() const { + std::scoped_lock lock(mPositionMutex); return mHalfExtents; } osg::Vec3f Actor::getRenderingHalfExtents() const { + std::scoped_lock lock(mPositionMutex); return osg::componentMultiply(mHalfExtents, mRenderingScale); } @@ -218,26 +253,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::scoped_lock lock(mPositionMutex); if (waterWalk != mCanWaterWalk) { mCanWaterWalk = waterWalk; @@ -245,4 +281,16 @@ void Actor::setCanWaterWalk(bool waterWalk) } } +MWWorld::Ptr Actor::getStandingOnPtr() const +{ + std::scoped_lock lock(mPositionMutex); + return mStandingOnPtr; +} + +void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr) +{ + std::scoped_lock lock(mPositionMutex); + mStandingOnPtr = ptr; +} + } diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 8752f7fee..07a9bebd2 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -1,15 +1,17 @@ #ifndef OPENMW_MWPHYSICS_ACTOR_H #define OPENMW_MWPHYSICS_ACTOR_H +#include #include +#include #include "ptrholder.hpp" +#include #include #include #include -class btCollisionWorld; class btCollisionShape; class btCollisionObject; class btConvexShape; @@ -21,12 +23,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, PhysicsTaskScheduler* scheduler); + ~Actor() override; /** * Sets the collisionMode for this actor. If disabled, the actor can fly and clip geometry. @@ -35,7 +38,7 @@ namespace MWPhysics bool getCollisionMode() const { - return mInternalCollisionMode; + return mInternalCollisionMode.load(std::memory_order_acquire); } btConvexShape* getConvexShape() const { return mConvexShape; } @@ -54,10 +57,18 @@ namespace MWPhysics bool isRotationallyInvariant() const; /** - * Set mPosition and mPreviousPosition to the position in the Ptr's RefData. This should be used + * Set mWorldPosition to the position in the Ptr's RefData. This is used by the physics simulation to account for * when an object is "instantly" moved/teleported as opposed to being moved by the physics simulation. */ void updatePosition(); + osg::Vec3f getWorldPosition() const; + + /** + * Used by the physics simulation to store the simulation result. Used in conjunction with mWorldPosition + * to account for e.g. scripted movements + */ + void setSimulationPosition(const osg::Vec3f& position); + osg::Vec3f getSimulationPosition() const; void updateCollisionObjectPosition(); @@ -81,6 +92,8 @@ namespace MWPhysics * Store the current position into mPreviousPosition, then move to this position. */ void setPosition(const osg::Vec3f& position); + void resetPosition(); + void adjustPosition(const osg::Vec3f& offset); osg::Vec3f getPosition() const; @@ -110,14 +123,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 @@ -132,14 +145,20 @@ namespace MWPhysics void setWalkingOnWater(bool walkingOnWater); bool isWalkingOnWater() const; + MWWorld::Ptr getStandingOnPtr() const; + void setStandingOnPtr(const MWWorld::Ptr& ptr); + private: + MWWorld::Ptr mStandingOnPtr; /// Removes then re-adds the collision object to the dynamics world void updateCollisionMask(); void addCollisionMask(int collisionMask); - int getCollisionMask(); + int getCollisionMask() const; + void updateCollisionObjectPositionUnsafe(); + void updatePositionUnsafe(); bool mCanWaterWalk; - bool mWalkingOnWater; + std::atomic mWalkingOnWater; bool mRotationallyInvariant; @@ -154,16 +173,20 @@ namespace MWPhysics osg::Vec3f mScale; osg::Vec3f mRenderingScale; + osg::Vec3f mWorldPosition; + osg::Vec3f mSimulationPosition; osg::Vec3f mPosition; osg::Vec3f mPreviousPosition; + btTransform mLocalTransform; + 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/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.cpp b/apps/openmw/mwphysics/contacttestresultcallback.cpp index f8209e363..5829ee02f 100644 --- a/apps/openmw/mwphysics/contacttestresultcallback.cpp +++ b/apps/openmw/mwphysics/contacttestresultcallback.cpp @@ -2,6 +2,8 @@ #include +#include "components/misc/convert.hpp" + #include "ptrholder.hpp" namespace MWPhysics @@ -20,7 +22,7 @@ namespace MWPhysics collisionObject = col1Wrap->m_collisionObject; PtrHolder* holder = static_cast(collisionObject->getUserPointer()); if (holder) - mResult.push_back(holder->getPtr()); + mResult.emplace_back(ContactPoint{holder->getPtr(), Misc::Convert::toOsg(cp.m_positionWorldOnB), Misc::Convert::toOsg(cp.m_normalWorldOnB)}); return 0.f; } diff --git a/apps/openmw/mwphysics/contacttestresultcallback.hpp b/apps/openmw/mwphysics/contacttestresultcallback.hpp index 0f469127d..fbe12d5dc 100644 --- a/apps/openmw/mwphysics/contacttestresultcallback.hpp +++ b/apps/openmw/mwphysics/contacttestresultcallback.hpp @@ -7,6 +7,8 @@ #include "../mwworld/ptr.hpp" +#include "physicssystem.hpp" + class btCollisionObject; struct btCollisionObjectWrapper; @@ -19,11 +21,11 @@ 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; + std::vector mResult; }; } diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp index 0baaa6241..7744af14b 100644 --- a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp @@ -39,6 +39,7 @@ namespace MWPhysics mObject = collisionObject; mLeastDistSqr = distsqr; mContactPoint = cp.getPositionWorldOnA(); + mContactNormal = cp.m_normalWorldOnB; } } diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp index f1107046b..00cb5c01f 100644 --- a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp @@ -20,13 +20,14 @@ namespace MWPhysics public: const btCollisionObject *mObject{nullptr}; btVector3 mContactPoint{0,0,0}; + btVector3 mContactNormal{0,0,0}; btScalar mLeastDistSqr; 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/hasspherecollisioncallback.hpp b/apps/openmw/mwphysics/hasspherecollisioncallback.hpp index 58e7373e5..275325cf6 100644 --- a/apps/openmw/mwphysics/hasspherecollisioncallback.hpp +++ b/apps/openmw/mwphysics/hasspherecollisioncallback.hpp @@ -35,7 +35,7 @@ namespace MWPhysics { } - bool process(const btBroadphaseProxy* proxy) final + bool process(const btBroadphaseProxy* proxy) override { if (mResult) return false; 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/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp new file mode 100644 index 000000000..bdffcef44 --- /dev/null +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -0,0 +1,544 @@ +#include +#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" + +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 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(MWPhysics::ActorFrameData& actorData, float timeAccum, float physicsDt) + { + const float interpolationFactor = timeAccum / physicsDt; + + // account for force change of actor's position in the main thread + const auto correction = actorData.mActorRaw->getWorldPosition() - actorData.mOrigin; + if (correction.length() != 0) + { + actorData.mActorRaw->adjustPosition(correction); + actorData.mPosition = actorData.mActorRaw->getPosition(); + } + + 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 + { + /// @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 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; + } + return std::max(0, wantedThread); + } + } +} + +namespace MWPhysics +{ + PhysicsTaskScheduler::PhysicsTaskScheduler(float physicsDt, std::shared_ptr collisionWorld) + : mPhysicsDt(physicsDt) + , mTimeAccum(0.f) + , 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) + , mFrameNumber(0) + , mTimer(osg::Timer::instance()) + { + 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, [&]() + { + 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()); + } + mTimeEnd = mTimer->tick(); + }); + } + + 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, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) + { + // This function run in the main thread. + // While the mSimulationMutex is held, background physics threads can't run. + + std::unique_lock lock(mSimulationMutex); + + for (auto& data : actorsData) + data.updatePosition(); + + // start by finishing previous background computation + if (mNumThreads != 0) + { + for (auto& data : mActorsFrameData) + { + // Ignore actors that were deleted while the background thread was running + if (!data.mActor.lock()) + continue; + + updateMechanics(data); + if (mAdvanceSimulation) + data.mActorRaw->setStandingOnPtr(data.mStandingOn); + + if (mMovementResults.find(data.mPtr) != mMovementResults.end()) + data.mActorRaw->setSimulationPosition(mMovementResults[data.mPtr]); + } + + if (mFrameNumber == frameNumber - 1) + { + stats.setAttribute(mFrameNumber, "physicsworker_time_begin", mTimer->delta_s(mFrameStart, mTimeBegin)); + stats.setAttribute(mFrameNumber, "physicsworker_time_taken", mTimer->delta_s(mTimeBegin, mTimeEnd)); + stats.setAttribute(mFrameNumber, "physicsworker_time_end", mTimer->delta_s(mFrameStart, mTimeEnd)); + } + mFrameStart = frameStart; + mTimeBegin = mTimer->tick(); + mFrameNumber = frameNumber; + } + + // 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(); + + if (mNumThreads == 0) + { + mMovementResults.clear(); + syncComputation(); + + for (auto& data : mActorsFrameData) + { + if (mAdvanceSimulation) + data.mActorRaw->setStandingOnPtr(data.mStandingOn); + if (mMovementResults.find(data.mPtr) != mMovementResults.end()) + data.mActorRaw->setSimulationPosition(mMovementResults[data.mPtr]); + } + 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; + } + + const PtrPositionList& PhysicsTaskScheduler::resetSimulation() + { + std::unique_lock lock(mSimulationMutex); + mMovementResults.clear(); + mPreviousMovementResults.clear(); + mActorsFrameData.clear(); + return mMovementResults; + } + + 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); + } + + std::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 std::nullopt; + 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::scoped_lock lock(mCollisionWorldMutex, mUpdateAabbMutex); + 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->updateCollisionObjectPosition(); + 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 (mRemainingSteps && (job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs) + { + MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet); + if(const auto actor = mActorsFrameData[job].mActor.lock()) + 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(); + } + } + } + + void PhysicsTaskScheduler::updateActorsPositions() + { + std::unique_lock lock(mCollisionWorldMutex); + for (auto& actorData : mActorsFrameData) + { + if(const auto actor = actorData.mActor.lock()) + { + bool positionChanged = actorData.mPosition != actorData.mActorRaw->getPosition(); + actorData.mActorRaw->setPosition(actorData.mPosition); + if (positionChanged) + { + actor->updateCollisionObjectPosition(); + 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); + } + } +} diff --git a/apps/openmw/mwphysics/mtphysics.hpp b/apps/openmw/mwphysics/mtphysics.hpp new file mode 100644 index 000000000..f7a131ca2 --- /dev/null +++ b/apps/openmw/mwphysics/mtphysics.hpp @@ -0,0 +1,103 @@ +#ifndef OPENMW_MWPHYSICS_MTPHYSICS_H +#define OPENMW_MWPHYSICS_MTPHYSICS_H + +#include +#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, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); + + const PtrPositionList& resetSimulation(); + + // 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); + std::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(); + 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_mutex mSimulationMutex; + mutable std::shared_mutex mCollisionWorldMutex; + mutable std::shared_mutex mLOSCacheMutex; + mutable std::mutex mUpdateAabbMutex; + std::condition_variable_any mHasJob; + + unsigned int mFrameNumber; + const osg::Timer* mTimer; + osg::Timer_t mTimeBegin; + osg::Timer_t mTimeEnd; + osg::Timer_t mFrameStart; + }; + +} +#endif diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index f95a67823..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,15 +9,15 @@ #include #include -#include #include namespace MWPhysics { - Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance) + Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, PhysicsTaskScheduler* scheduler) : mShapeInstance(shapeInstance) , mSolid(true) + , mTaskScheduler(scheduler) { mPtr = ptr; @@ -29,6 +30,13 @@ 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() + { + if (mCollisionObject) + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } const Resource::BulletShapeInstance* Object::getShapeInstance() const @@ -38,17 +46,38 @@ namespace MWPhysics void Object::setScale(float scale) { - mShapeInstance->setLocalScaling(btVector3(scale, scale, scale)); + std::unique_lock lock(mPositionMutex); + mScale = { scale,scale,scale }; + mScaleUpdatePending = true; } void Object::setRotation(const btQuaternion& quat) { - mCollisionObject->getWorldTransform().setRotation(quat); + std::unique_lock lock(mPositionMutex); + mLocalTransform.setRotation(quat); + mTransformUpdatePending = true; } void Object::setOrigin(const btVector3& vec) { - mCollisionObject->getWorldTransform().setOrigin(vec); + std::unique_lock lock(mPositionMutex); + mLocalTransform.setOrigin(vec); + mTransformUpdatePending = true; + } + + void Object::commitPositionChange() + { + std::unique_lock lock(mPositionMutex); + if (mScaleUpdatePending) + { + mShapeInstance->setLocalScaling(mScale); + mScaleUpdatePending = false; + } + if (mTransformUpdatePending) + { + mCollisionObject->setWorldTransform(mLocalTransform); + mTransformUpdatePending = false; + } } btCollisionObject* Object::getCollisionObject() @@ -61,6 +90,12 @@ namespace MWPhysics return mCollisionObject.get(); } + btTransform Object::getTransform() const + { + std::unique_lock lock(mPositionMutex); + return mLocalTransform; + } + bool Object::isSolid() const { return mSolid; @@ -76,10 +111,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()); @@ -100,7 +135,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()); @@ -122,7 +157,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 b948433e3..876e35651 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -3,10 +3,12 @@ #include "ptrholder.hpp" +#include #include #include #include +#include namespace Resource { @@ -14,34 +16,46 @@ namespace Resource } class btCollisionObject; -class btCollisionWorld; class btQuaternion; class btVector3; namespace MWPhysics { - class Object : public PtrHolder + class PhysicsTaskScheduler; + + class Object final : public PtrHolder { public: - Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance); + Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, PhysicsTaskScheduler* scheduler); + ~Object() override; const Resource::BulletShapeInstance* getShapeInstance() const; 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; osg::ref_ptr mShapeInstance; std::map mRecIndexToNodePath; bool mSolid; + 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 8b07fea4b..cdbad2cdd 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1,7 +1,11 @@ #include "physicssystem.hpp" +#include +#include +#include #include #include +#include #include #include @@ -31,6 +35,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/cellstore.hpp" @@ -50,6 +55,7 @@ #include "contacttestresultcallback.hpp" #include "constants.hpp" #include "movementsolver.hpp" +#include "mtphysics.hpp" namespace MWPhysics { @@ -65,11 +71,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. @@ -86,36 +92,27 @@ namespace MWPhysics Log(Debug::Warning) << "Warning: using custom physics framerate (" << physFramerate << " FPS)."; } } + + mTaskScheduler = std::make_unique(mPhysicsDt, mCollisionWorld); + mDebugDrawer = std::make_unique(mParentNode, mCollisionWorld.get(), mDebugDrawEnabled); } PhysicsSystem::~PhysicsSystem() { mResourceSystem->removeResourceManager(mShapeManager.get()); - if (mWaterCollisionObject.get()) - mCollisionWorld->removeCollisionObject(mWaterCollisionObject.get()); + if (mWaterCollisionObject) + mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get()); for (auto& heightField : mHeightFields) { - mCollisionWorld->removeCollisionObject(heightField.second->getCollisionObject()); + mTaskScheduler->removeCollisionObject(heightField.second->getCollisionObject()); delete heightField.second; } - for (auto& object : mObjects) - { - mCollisionWorld->removeCollisionObject(object.second->getCollisionObject()); - delete object.second; - } - - for (auto& actor : mActors) - { - delete actor.second; - } + mObjects.clear(); + mActors.clear(); - delete mCollisionWorld; - delete mCollisionConfiguration; - delete mDispatcher; - delete mBroadphase; } void PhysicsSystem::setUnrefQueue(SceneUtil::UnrefQueue *unrefQueue) @@ -132,14 +129,8 @@ namespace MWPhysics { mDebugDrawEnabled = !mDebugDrawEnabled; - if (mDebugDrawEnabled && !mDebugDrawer.get()) - { - mDebugDrawer.reset(new MWRender::DebugDrawer(mParentNode, mCollisionWorld)); - mCollisionWorld->setDebugDrawer(mDebugDrawer.get()); - mDebugDrawer->setDebugMode(mDebugDrawEnabled); - } - else if (mDebugDrawer.get()) - mDebugDrawer->setDebugMode(mDebugDrawEnabled); + mCollisionWorld->setDebugDrawer(mDebugDrawEnabled ? mDebugDrawer.get() : nullptr); + mDebugDrawer->setDebugMode(mDebugDrawEnabled); return mDebugDrawEnabled; } @@ -158,11 +149,11 @@ namespace MWPhysics if (!physactor || !physactor->getOnGround()) return false; - CollisionMap::const_iterator found = mStandingCollisions.find(actor); - if (found == mStandingCollisions.end()) + const auto obj = physactor->getStandingOnPtr(); + if (obj.isEmpty()) return true; // assume standing on terrain (which is a non-object, so not collision tracked) - ObjectMap::const_iterator foundObj = mObjects.find(found->second); + ObjectMap::const_iterator foundObj = mObjects.find(obj); if (foundObj == mObjects.end()) return false; @@ -175,7 +166,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; @@ -183,6 +174,7 @@ namespace MWPhysics if (result.mHit) { + reportCollision(Misc::Convert::toBullet(result.mHitPos), Misc::Convert::toBullet(result.mHitNormal)); return std::make_pair(result.mHitObject, result.mHitPos); } @@ -221,13 +213,16 @@ 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) { PtrHolder* holder = static_cast(resultCallback.mObject->getUserPointer()); if (holder) + { + reportCollision(resultCallback.mContactPoint, resultCallback.mContactNormal); return std::make_pair(holder->getPtr(), Misc::Convert::toOsg(resultCallback.mContactPoint)); + } } return std::make_pair(MWWorld::Ptr(), osg::Vec3f()); } @@ -245,27 +240,22 @@ 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()); - - btCollisionWorld::ClosestRayResultCallback cb(rayFrom.getOrigin(), rayTo.getOrigin()); + auto hitpoint = mTaskScheduler->getHitPoint(rayFrom, targetCollisionObj); + if (hitpoint) + return (point - Misc::Convert::toOsg(*hitpoint)).length(); - 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 { 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); @@ -299,7 +289,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(); @@ -325,7 +315,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(); @@ -339,18 +329,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); - - 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); + const auto getWeakPtr = [&](const MWWorld::ConstPtr &ptr) -> std::weak_ptr + { + const auto found = mActors.find(ptr); + if (found != mActors.end()) + return { found->second }; + return {}; + }; - return !result.mHit; + return mTaskScheduler->getLineOfSight(getWeakPtr(actor1), getWeakPtr(actor2)); } bool PhysicsSystem::isOnGround(const MWWorld::Ptr &actor) @@ -369,7 +356,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); } @@ -404,7 +391,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)); } @@ -417,30 +404,38 @@ namespace MWPhysics return osg::Vec3f(); } - std::vector PhysicsSystem::getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const + std::vector PhysicsSystem::getCollisionsPoints(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const { btCollisionObject* me = nullptr; - ObjectMap::const_iterator found = mObjects.find(ptr); + auto found = mObjects.find(ptr); if (found != mObjects.end()) me = found->second->getCollisionObject(); else - return std::vector(); + return {}; ContactTestResultCallback resultCallback (me); resultCallback.m_collisionFilterGroup = collisionGroup; resultCallback.m_collisionFilterMask = collisionMask; - mCollisionWorld->contactTest(me, resultCallback); + mTaskScheduler->contactTest(me, resultCallback); return resultCallback.mResult; } + std::vector PhysicsSystem::getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const + { + std::vector actors; + for (auto& [actor, point, normal] : getCollisionsPoints(ptr, collisionGroup, collisionMask)) + actors.emplace_back(actor); + return actors; + } + osg::Vec3f PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight) { ActorMap::iterator found = mActors.find(ptr); if (found == mActors.end()) return ptr.getRefData().getPosition().asVec3(); - else - return MovementSolver::traceDown(ptr, position, found->second, mCollisionWorld, maxHeight); + found->second->resetPosition(); + 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) @@ -448,7 +443,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); } @@ -457,7 +452,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); } @@ -477,13 +472,13 @@ namespace MWPhysics if (!shapeInstance || !shapeInstance->getCollisionShape()) return; - Object *obj = new Object(ptr, shapeInstance); + auto obj = std::make_shared(ptr, shapeInstance, mTaskScheduler.get()); mObjects.emplace(ptr, obj); if (obj->isAnimated()) - mAnimatedObjects.insert(obj); + mAnimatedObjects.insert(obj.get()); - mCollisionWorld->addCollisionObject(obj->getCollisionObject(), collisionType, + mTaskScheduler->addCollisionObject(obj->getCollisionObject(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); } @@ -492,69 +487,53 @@ 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); } } - void PhysicsSystem::updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated) - { - CollisionMap::iterator found = map.find(old); - if (found != map.end()) - { - map[updated] = found->second; - map.erase(found); - } - - for (auto& collision : map) - { - if (collision.second == old) - collision.second = updated; - } - } - void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) { 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); + for (auto& [_, actor] : mActors) + { + if (actor->getStandingOnPtr() == old) + actor->setStandingOnPtr(updated); + } } Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr) { ActorMap::iterator found = mActors.find(ptr); if (found != mActors.end()) - return found->second; + return found->second.get(); return nullptr; } @@ -562,7 +541,7 @@ namespace MWPhysics { ActorMap::const_iterator found = mActors.find(ptr); if (found != mActors.end()) - return found->second; + return found->second.get(); return nullptr; } @@ -570,7 +549,7 @@ namespace MWPhysics { ObjectMap::const_iterator found = mObjects.find(ptr); if (found != mObjects.end()) - return found->second; + return found->second.get(); return nullptr; } @@ -581,14 +560,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; } } @@ -599,7 +578,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); @@ -608,7 +587,7 @@ namespace MWPhysics if (!foundActor->second->isRotationallyInvariant()) { foundActor->second->updateRotation(); - mCollisionWorld->updateSingleAabb(foundActor->second->getCollisionObject()); + mTaskScheduler->updateSingleAabb(foundActor->second); } return; } @@ -620,14 +599,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; } } @@ -635,11 +614,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) @@ -648,8 +625,11 @@ namespace MWPhysics } } - Actor* actor = new Actor(ptr, shape, mCollisionWorld); - mActors.emplace(ptr, actor); + if (!shape) + return; + + auto actor = std::make_shared(ptr, shape, mTaskScheduler.get()); + mActors.emplace(ptr, std::move(actor)); } bool PhysicsSystem::toggleCollisionMode() @@ -667,119 +647,106 @@ namespace MWPhysics return false; } - void PhysicsSystem::queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &movement) + void PhysicsSystem::queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity) { for(auto& movementItem : mMovementQueue) { if (movementItem.first == ptr) { - movementItem.second = movement; + movementItem.second = velocity; return; } } - mMovementQueue.emplace_back(ptr, movement); + mMovementQueue.emplace_back(ptr, velocity); } void PhysicsSystem::clearQueuedMovement() { mMovementQueue.clear(); - mStandingCollisions.clear(); } - const PtrVelocityList& PhysicsSystem::applyQueuedMovement(float dt) + const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { - mMovementResults.clear(); - mTimeAccum += dt; const int maxAllowedSteps = 20; - int numSteps = mTimeAccum / (mPhysicsDt); + int numSteps = mTimeAccum / mPhysicsDt; numSteps = std::min(numSteps, maxAllowedSteps); mTimeAccum -= numSteps * mPhysicsDt; - if (numSteps) + if (skipSimulation) { - // Collision events should be available on every frame - mStandingCollisions.clear(); + for (auto& [_, actor] : mActors) + { + actor->resetPosition(); + actor->setStandingOnPtr(nullptr); + } + return mTaskScheduler->resetSimulation(); } - const MWWorld::Ptr player = MWMechanics::getPlayer(); + return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), frameStart, frameNumber, stats); + } + + std::vector PhysicsSystem::prepareFrameData(int numSteps) + { + std::vector actorsFrameData; + actorsFrameData.reserve(mMovementQueue.size()); const MWBase::World *world = MWBase::Environment::get().getWorld(); - for(auto& movementItem : mMovementQueue) + for (const auto& [character, movement] : mMovementQueue) { - ActorMap::iterator foundActor = mActors.find(movementItem.first); + 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; + bool moveToWaterSurface = 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)); + 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(movementItem.first); - bool swimming = world->isSwimming(movementItem.first); - - bool wasOnGround = physicActor->getOnGround(); - osg::Vec3f position = physicActor->getPosition(); - float oldHeight = position.z(); - bool positionChanged = false; - for (int i=0; igetPtr(), physicActor, movementItem.second, mPhysicsDt, - flying, waterlevel, slowFall, mCollisionWorld, 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()); + // Ue current value only if we don't advance the simulation. Otherwise we might get a stale value. + MWWorld::Ptr standingOn; + if (numSteps == 0) + standingOn = physicActor->getStandingOnPtr(); - float interpolationFactor = mTimeAccum / mPhysicsDt; - osg::Vec3f interpolated = position * interpolationFactor + physicActor->getPreviousPosition() * (1.f - interpolationFactor); - - float heightDiff = position.z() - oldHeight; - - MWMechanics::CreatureStats& stats = movementItem.first.getClass().getCreatureStats(movementItem.first); - bool isStillOnGround = (numSteps > 0 && wasOnGround && physicActor->getOnGround()); - if (isStillOnGround || flying || swimming || slowFall < 1) - stats.land(movementItem.first == player && (flying || swimming)); - else if (heightDiff < 0) - stats.addToFallHeight(-heightDiff); - - mMovementResults.emplace_back(movementItem.first, interpolated); + actorsFrameData.emplace_back(std::move(physicActor), character, standingOn, moveToWaterSurface, movement, slowFall, waterlevel); } - mMovementQueue.clear(); - - return mMovementResults; + return actorsFrameData; } - void PhysicsSystem::stepSimulation(float dt) + void PhysicsSystem::stepSimulation() { - for (Object* animatedObject : mAnimatedObjects) - animatedObject->animateCollisionShapes(mCollisionWorld); + for (Object* animatedObject : mAnimatedObjects) + if (animatedObject->animateCollisionShapes()) + { + auto obj = mObjects.find(animatedObject->getPtr()); + assert(obj != mObjects.end()); + mTaskScheduler->updateSingleAabb(obj->second); + } #ifndef BT_NO_PROFILE CProfileManager::Reset(); @@ -791,31 +758,30 @@ namespace MWPhysics { ObjectMap::iterator found = mObjects.find(object); if (found != mObjects.end()) - found->second->animateCollisionShapes(mCollisionWorld); + if (found->second->animateCollisionShapes()) + mTaskScheduler->updateSingleAabb(found->second); } void PhysicsSystem::debugDraw() { - if (mDebugDrawer.get()) + if (mDebugDrawEnabled) mDebugDrawer->step(); } bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const { - for (const auto& standingActor : mStandingCollisions) - { - if (standingActor.first == actor && standingActor.second == object) - return true; - } + const auto physActor = mActors.find(actor); + if (physActor != mActors.end()) + return physActor->second->getStandingOnPtr() == object; return false; } void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr &object, std::vector &out) const { - for (const auto& standingActor : mStandingCollisions) + for (const auto& [_, actor] : mActors) { - if (standingActor.second == object) - out.push_back(standingActor.first); + if (actor->getStandingOnPtr() == object) + out.emplace_back(actor->getPtr()); } } @@ -861,9 +827,9 @@ namespace MWPhysics void PhysicsSystem::updateWater() { - if (mWaterCollisionObject.get()) + if (mWaterCollisionObject) { - mCollisionWorld->removeCollisionObject(mWaterCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get()); } if (!mWaterEnabled) @@ -875,7 +841,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); } @@ -891,7 +857,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(); } @@ -901,4 +867,69 @@ namespace MWPhysics stats.setAttribute(frameNumber, "Physics Objects", mObjects.size()); stats.setAttribute(frameNumber, "Physics HeightFields", mHeightFields.size()); } + + void PhysicsSystem::reportCollision(const btVector3& position, const btVector3& normal) + { + if (mDebugDrawEnabled) + mDebugDrawer->addCollision(position, normal); + } + + 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), + 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() + { + mActorRaw->updatePosition(); + mOrigin = mActorRaw->getSimulationPosition(); + 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 26005b396..03ae78993 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 @@ -9,6 +10,7 @@ #include #include #include +#include #include "../mwworld/ptr.hpp" @@ -44,14 +46,67 @@ class btDefaultCollisionConfiguration; class btCollisionDispatcher; class btCollisionObject; class btCollisionShape; +class btVector3; namespace MWPhysics { - typedef std::vector > PtrVelocityList; + using PtrPositionList = std::map; class HeightField; class Object; class Actor; + class PhysicsTaskScheduler; + + struct ContactPoint + { + MWWorld::Ptr mObject; + osg::Vec3f mPoint; + osg::Vec3f mNormal; + }; + + 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 mWasOnGround; + bool mWantJump; + bool mDidJump; + bool mIsDead; + bool mNeedLand; + bool mMoveToWaterSurface; + float mWaterlevel; + float mSlowFall; + float mOldHeight; + float mFallHeight; + osg::Vec3f mMovement; + osg::Vec3f mOrigin; + osg::Vec3f mPosition; + ESM::Position mRefpos; + }; + + struct WorldFrameData + { + WorldFrameData(); + bool mIsInStorm; + osg::Vec3f mStormDirection; + }; class PhysicsSystem : public RayCastingInterface { @@ -93,33 +148,34 @@ 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 + std::vector getCollisionsPoints(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight); 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 /// 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 override; /// @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 override; - 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 override; /// 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 override; bool isOnGround (const MWWorld::Ptr& actor); @@ -146,7 +202,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, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); /// Clear the queued movements list without applying. void clearQueuedMovement(); @@ -185,44 +241,40 @@ namespace MWPhysics bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const; void reportStats(unsigned int frameNumber, osg::Stats& stats) const; + void reportCollision(const btVector3& position, const btVector3& normal); private: void updateWater(); + std::vector prepareFrameData(int numSteps); + 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 mTaskScheduler; 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; float mTimeAccum; 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..8c9f5f493 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -16,13 +16,11 @@ #include #include -#include #include #include -#include // KeyframeHolder -#include +#include #include @@ -37,8 +35,6 @@ #include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" @@ -62,18 +58,18 @@ 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); + mToRemove.emplace_back(&node); 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); + mToRemove.emplace_back(partsys); } void remove() @@ -98,7 +94,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 +119,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 +136,7 @@ namespace { } - virtual void apply(osg::Switch& node) + void apply(osg::Switch& node) override { if (node.getName() == Constants::HerbalismLabel) { @@ -151,7 +147,7 @@ namespace } }; - float calcAnimVelocity(const NifOsg::TextKeyMap& keys, NifOsg::KeyframeController *nonaccumctrl, + float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl, const osg::Vec3f& accum, const std::string &groupname) { const std::string start = groupname+": start"; @@ -235,7 +231,7 @@ namespace { } - void apply(osg::Node& node) + void apply(osg::Node& node) override { if (SceneUtil::hasUserDescription(&node, "CustomBone")) { @@ -260,12 +256,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); @@ -277,19 +273,19 @@ namespace if (vfxCallback) { if (vfxCallback->mFinished) - mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + mToRemove.emplace_back(group.asNode(), group.getParent(0)); else mHasMagicEffects = true; } } } - 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 +309,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); @@ -330,19 +326,19 @@ namespace { bool toRemove = mEffectId < 0 || vfxCallback->mParams.mEffectId == mEffectId; if (toRemove) - mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + mToRemove.emplace_back(group.asNode(), group.getParent(0)); else mHasMagicEffects = true; } } } - 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 +364,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 +386,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 +403,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); } @@ -431,7 +427,7 @@ namespace node.setStateSet(nullptr); if (node.getNodeMask() == 0x1 && node.getNumParents() == 1) - mToRemove.push_back(std::make_pair(&node, node.getParent(0))); + mToRemove.emplace_back(&node, node.getParent(0)); else traverse(node); } @@ -449,28 +445,28 @@ namespace osg::Group* parentParent = static_cast(*(parent - 1)); if (parentGroup->getNumChildren() == 1 && parentGroup->getDataVariance() == osg::Object::STATIC) { - mToRemove.push_back(std::make_pair(parentGroup, parentParent)); + mToRemove.emplace_back(parentGroup, parentParent); return; } } - mToRemove.push_back(std::make_pair(&node, parentGroup)); + mToRemove.emplace_back(&node, parentGroup); } }; 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); } @@ -482,7 +478,7 @@ namespace { osg::Group* parent = static_cast(*(getNodePath().end()-2)); // Not safe to remove in apply(), since the visitor is still iterating the child list - mToRemove.push_back(std::make_pair(&node, parent)); + mToRemove.emplace_back(&node, parent); } } }; @@ -493,9 +489,8 @@ namespace MWRender class TransparencyUpdater : public SceneUtil::StateSetUpdater { public: - TransparencyUpdater(const float alpha, osg::ref_ptr shadowUniform) + TransparencyUpdater(const float alpha) : mAlpha(alpha) - , mShadowUniform(shadowUniform) { } @@ -505,13 +500,10 @@ 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); - // TODO: don't do this anymore once custom shadow renderbin is handling it - if (mShadowUniform) - stateset->addUniform(mShadowUniform); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); @@ -525,7 +517,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); @@ -533,18 +525,17 @@ namespace MWRender private: float mAlpha; - osg::ref_ptr mShadowUniform; }; struct Animation::AnimSource { - osg::ref_ptr mKeyframes; + osg::ref_ptr mKeyframes; - typedef std::map > ControllerMap; + typedef std::map > ControllerMap; ControllerMap mControllerMap[Animation::sNumBlendMasks]; - const NifOsg::TextKeyMap& getTextKeys() const; + const SceneUtil::TextKeyMap& getTextKeys() const; }; void UpdateVfxCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) @@ -586,7 +577,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); @@ -696,7 +687,7 @@ namespace MWRender return 0; } - const NifOsg::TextKeyMap &Animation::AnimSource::getTextKeys() const + const SceneUtil::TextKeyMap &Animation::AnimSource::getTextKeys() const { return mKeyframes->mTextKeys; } @@ -737,8 +728,6 @@ namespace MWRender if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0) kfname.replace(kfname.size()-4, 4, ".kf"); - else - return; addSingleAnimSource(kfname, baseModel); @@ -761,7 +750,7 @@ namespace MWRender const NodeMap& nodeMap = getNodeMap(); - for (NifOsg::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin(); + for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin(); it != animsrc->mKeyframes->mKeyframeControllers.end(); ++it) { std::string bonename = Misc::StringUtils::lowerCase(it->first); @@ -777,7 +766,7 @@ namespace MWRender size_t blendMask = detectBlendMask(node); // clone the controller, because each Animation needs its own ControllerSource - osg::ref_ptr cloned = new NifOsg::KeyframeController(*it->second, osg::CopyOp::SHALLOW_COPY); + osg::ref_ptr cloned = osg::clone(it->second.get(), osg::CopyOp::SHALLOW_COPY); cloned->setSource(mAnimationTimePtr[blendMask]); animsrc->mControllerMap[blendMask].insert(std::make_pair(bonename, cloned)); @@ -793,6 +782,8 @@ namespace MWRender NodeMap::const_iterator found = nodeMap.find("bip01"); if (found == nodeMap.end()) found = nodeMap.find("root bone"); + if (found == nodeMap.end()) + found = nodeMap.find("root"); if (found != nodeMap.end()) mAccumRoot = found->second; @@ -818,7 +809,7 @@ namespace MWRender AnimSourceList::const_iterator iter(mAnimSources.begin()); for(;iter != mAnimSources.end();++iter) { - const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys(); if (keys.hasGroupStart(anim)) return true; } @@ -830,7 +821,7 @@ namespace MWRender { for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) { - const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys(); const auto found = keys.findGroupStart(groupname); if(found != keys.end()) @@ -843,7 +834,7 @@ namespace MWRender { for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) { - const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys(); for(auto iterKey = keys.begin(); iterKey != keys.end(); ++iterKey) { @@ -855,8 +846,8 @@ namespace MWRender return -1.f; } - void Animation::handleTextKey(AnimState &state, const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key, - const NifOsg::TextKeyMap& map) + void Animation::handleTextKey(AnimState &state, const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, + const SceneUtil::TextKeyMap& map) { const std::string &evt = key->second; @@ -919,7 +910,7 @@ namespace MWRender AnimSourceList::reverse_iterator iter(mAnimSources.rbegin()); for(;iter != mAnimSources.rend();++iter) { - const NifOsg::TextKeyMap &textkeys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap &textkeys = (*iter)->getTextKeys(); if(reset(state, textkeys, groupname, start, stop, startpoint, loopfallback)) { state.mSource = *iter; @@ -964,7 +955,7 @@ namespace MWRender resetActiveGroups(); } - bool Animation::reset(AnimState &state, const NifOsg::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, bool loopfallback) + bool Animation::reset(AnimState &state, const SceneUtil::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, bool loopfallback) { // Look for text keys in reverse. This normally wouldn't matter, but for some reason undeadwolf_2.nif has two // separate walkforward keys, and the last one is supposed to be used. @@ -1194,7 +1185,7 @@ namespace MWRender AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin()); for(;animsrc != mAnimSources.rend();++animsrc) { - const NifOsg::TextKeyMap &keys = (*animsrc)->getTextKeys(); + const SceneUtil::TextKeyMap &keys = (*animsrc)->getTextKeys(); if (keys.hasGroupStart(groupname)) break; } @@ -1202,7 +1193,7 @@ namespace MWRender return 0.0f; float velocity = 0.0f; - const NifOsg::TextKeyMap &keys = (*animsrc)->getTextKeys(); + const SceneUtil::TextKeyMap &keys = (*animsrc)->getTextKeys(); const AnimSource::ControllerMap& ctrls = (*animsrc)->mControllerMap[0]; for (AnimSource::ControllerMap::const_iterator it = ctrls.begin(); it != ctrls.end(); ++it) @@ -1223,7 +1214,7 @@ namespace MWRender while(!(velocity > 1.0f) && ++animiter != mAnimSources.rend()) { - const NifOsg::TextKeyMap &keys2 = (*animiter)->getTextKeys(); + const SceneUtil::TextKeyMap &keys2 = (*animiter)->getTextKeys(); const AnimSource::ControllerMap& ctrls2 = (*animiter)->mControllerMap[0]; for (AnimSource::ControllerMap::const_iterator it = ctrls2.begin(); it != ctrls2.end(); ++it) @@ -1273,7 +1264,7 @@ namespace MWRender continue; } - const NifOsg::TextKeyMap &textkeys = state.mSource->getTextKeys(); + const SceneUtil::TextKeyMap &textkeys = state.mSource->getTextKeys(); auto textkey = textkeys.upperBound(state.getTime()); float timepassed = duration * state.mSpeedMult; @@ -1773,7 +1764,7 @@ namespace MWRender { if (mTransparencyUpdater == nullptr) { - mTransparencyUpdater = new TransparencyUpdater(alpha, mResourceSystem->getSceneManager()->getShaderManager().getShadowMapAlphaTestEnableUniform()); + mTransparencyUpdater = new TransparencyUpdater(alpha); mObjectRoot->addCullCallback(mTransparencyUpdater); } else @@ -1847,7 +1838,7 @@ namespace MWRender osg::Callback* cb = node->getUpdateCallback(); while (cb) { - if (dynamic_cast(cb)) + if (dynamic_cast(cb)) { foundKeyframeCtrl = true; break; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 8a1719db4..ebfe8a2e5 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -4,8 +4,8 @@ #include "../mwworld/ptr.hpp" #include +#include #include -#include #include @@ -20,14 +20,10 @@ namespace Resource class ResourceSystem; } -namespace NifOsg +namespace SceneUtil { class KeyframeHolder; class KeyframeController; -} - -namespace SceneUtil -{ class LightSource; class LightListCallback; class Skeleton; @@ -45,7 +41,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); @@ -150,8 +146,8 @@ public: class TextKeyListener { public: - virtual void handleTextKey(const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key, - const NifOsg::TextKeyMap& map) = 0; + virtual void handleTextKey(const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, + const SceneUtil::TextKeyMap& map) = 0; virtual ~TextKeyListener() = default; }; @@ -173,13 +169,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; } @@ -242,7 +238,7 @@ protected: osg::ref_ptr mAccumRoot; // The controller animating that node. - osg::ref_ptr mAccumCtrl; + osg::ref_ptr mAccumCtrl; // Used to reset the position of the accumulation root every frame - the movement should be applied to the physics system osg::ref_ptr mResetAccumRootCallback; @@ -306,12 +302,12 @@ protected: * the marker is not found, or if the markers are the same, it returns * false. */ - bool reset(AnimState &state, const NifOsg::TextKeyMap &keys, + bool reset(AnimState &state, const SceneUtil::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, bool loopfallback); - void handleTextKey(AnimState &state, const std::string &groupname, NifOsg::TextKeyMap::ConstIterator key, - const NifOsg::TextKeyMap& map); + void handleTextKey(AnimState &state, const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, + const SceneUtil::TextKeyMap& map); /** Sets the root model of the object. * @@ -506,7 +502,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 +518,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.cpp b/apps/openmw/mwrender/bulletdebugdraw.cpp index 4cf76e473..00529ef80 100644 --- a/apps/openmw/mwrender/bulletdebugdraw.cpp +++ b/apps/openmw/mwrender/bulletdebugdraw.cpp @@ -1,4 +1,4 @@ -#include "bulletdebugdraw.hpp" +#include #include @@ -6,27 +6,19 @@ #include #include +#include +#include "bulletdebugdraw.hpp" #include "vismask.hpp" -namespace -{ - osg::Vec3f toOsg(const btVector3& vec) - { - return osg::Vec3f(vec.x(), vec.y(), vec.z()); - } -} - namespace MWRender { -DebugDrawer::DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld *world) +DebugDrawer::DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld *world, int debugMode) : mParentNode(parentNode), - mWorld(world), - mDebugOn(true) + mWorld(world) { - - createGeometry(); + setDebugMode(debugMode); } void DebugDrawer::createGeometry() @@ -37,11 +29,14 @@ void DebugDrawer::createGeometry() mGeometry->setNodeMask(Mask_Debug); mVertices = new osg::Vec3Array; + mColors = new osg::Vec4Array; mDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES); mGeometry->setUseDisplayList(false); mGeometry->setVertexArray(mVertices); + mGeometry->setColorArray(mColors); + mGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); mGeometry->setDataVariance(osg::Object::DYNAMIC); mGeometry->addPrimitiveSet(mDrawArrays); @@ -70,23 +65,53 @@ void DebugDrawer::step() if (mDebugOn) { mVertices->clear(); + mColors->clear(); mWorld->debugDrawWorld(); + showCollisions(); mDrawArrays->setCount(mVertices->size()); mVertices->dirty(); + mColors->dirty(); mGeometry->dirtyBound(); } } void DebugDrawer::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color) { - mVertices->push_back(toOsg(from)); - mVertices->push_back(toOsg(to)); + mVertices->push_back(Misc::Convert::toOsg(from)); + mVertices->push_back(Misc::Convert::toOsg(to)); + mColors->push_back({1,1,1,1}); + mColors->push_back({1,1,1,1}); +} + +void DebugDrawer::addCollision(const btVector3& orig, const btVector3& normal) +{ + mCollisionViews.emplace_back(orig, normal); +} + +void DebugDrawer::showCollisions() +{ + const auto now = std::chrono::steady_clock::now(); + for (auto& [from, to , created] : mCollisionViews) + { + if (now - created < std::chrono::seconds(2)) + { + mVertices->push_back(Misc::Convert::toOsg(from)); + mVertices->push_back(Misc::Convert::toOsg(to)); + mColors->push_back({1,0,0,1}); + mColors->push_back({1,0,0,1}); + } + } + mCollisionViews.erase(std::remove_if(mCollisionViews.begin(), mCollisionViews.end(), + [&now](const CollisionView& view) { return now - view.mCreated >= std::chrono::seconds(2); }), + mCollisionViews.end()); } void DebugDrawer::drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color) { - mVertices->push_back(toOsg(PointOnB)); - mVertices->push_back(toOsg(PointOnB) + (toOsg(normalOnB) * distance * 20)); + mVertices->push_back(Misc::Convert::toOsg(PointOnB)); + mVertices->push_back(Misc::Convert::toOsg(PointOnB) + (Misc::Convert::toOsg(normalOnB) * distance * 20)); + mColors->push_back({1,1,1,1}); + mColors->push_back({1,1,1,1}); } void DebugDrawer::reportErrorWarning(const char *warningString) @@ -96,7 +121,7 @@ void DebugDrawer::reportErrorWarning(const char *warningString) void DebugDrawer::setDebugMode(int isOn) { - mDebugOn = (isOn == 0) ? false : true; + mDebugOn = (isOn != 0); if (!mDebugOn) destroyGeometry(); @@ -109,6 +134,4 @@ int DebugDrawer::getDebugMode() const return mDebugOn; } - - } diff --git a/apps/openmw/mwrender/bulletdebugdraw.hpp b/apps/openmw/mwrender/bulletdebugdraw.hpp index 30da3aa72..ec421bd74 100644 --- a/apps/openmw/mwrender/bulletdebugdraw.hpp +++ b/apps/openmw/mwrender/bulletdebugdraw.hpp @@ -1,6 +1,9 @@ #ifndef OPENMW_MWRENDER_BULLETDEBUGDRAW_H #define OPENMW_MWRENDER_BULLETDEBUGDRAW_H +#include +#include + #include #include #include @@ -20,11 +23,22 @@ namespace MWRender class DebugDrawer : public btIDebugDraw { +private: + struct CollisionView + { + btVector3 mOrig; + btVector3 mEnd; + std::chrono::time_point mCreated; + CollisionView(btVector3 orig, btVector3 normal) : mOrig(orig), mEnd(orig + normal * 20), mCreated(std::chrono::steady_clock::now()) {}; + }; + std::vector mCollisionViews; + protected: osg::ref_ptr mParentNode; btCollisionWorld *mWorld; osg::ref_ptr mGeometry; osg::ref_ptr mVertices; + osg::ref_ptr mColors; osg::ref_ptr mDrawArrays; bool mDebugOn; @@ -34,24 +48,28 @@ protected: public: - DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld *world); + DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld *world, int debugMode = 1); ~DebugDrawer(); 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 addCollision(const btVector3& orig, const btVector3& normal); + + void showCollisions(); - 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..b964eacff 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); @@ -66,6 +66,9 @@ namespace MWRender mIsNearest(false), mHeight(124.f), mBaseCameraDistance(Settings::Manager::getFloat("third person camera distance", "Camera")), + mPitch(0.f), + mYaw(0.f), + mRoll(0.f), mVanityToggleQueued(false), mVanityToggleQueuedValue(false), mViewModeToggleQueued(false), @@ -80,6 +83,10 @@ namespace MWRender mZoomOutWhenMoveCoef(Settings::Manager::getFloat("zoom out when move coef", "Camera")), mDynamicCameraDistanceEnabled(false), mShowCrosshairInThirdPersonMode(false), + mHeadBobbingEnabled(Settings::Manager::getBool("head bobbing", "Camera")), + mHeadBobbingOffset(0.f), + mHeadBobbingWeight(0.f), + mTotalMovement(0.f), mDeferredRotation(osg::Vec3f()), mDeferredRotationDisabled(false) { @@ -104,7 +111,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 +152,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 +225,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..9e2b608df 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; // Value from 0 to 1 for smooth enabling/disabling. + float mTotalMovement; // Needed for head bobbing. + void updateHeadBobbing(float duration); + void updateFocalPointOffset(float duration); void updatePosition(); float getCameraDistanceCorrection() const; 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.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/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..401e21ae4 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); @@ -118,7 +118,7 @@ void LocalMap::saveFogOfWar(MWWorld::CellStore* cell) if (segment.mFogOfWarImage && segment.mHasFogState) { std::unique_ptr fog (new ESM::FogState()); - fog->mFogTextures.push_back(ESM::FogTexture()); + fog->mFogTextures.emplace_back(); segment.saveFogOfWar(fog->mFogTextures.back()); @@ -150,7 +150,7 @@ void LocalMap::saveFogOfWar(MWWorld::CellStore* cell) { const MapSegment& segment = mSegments[std::make_pair(x,y)]; - fog->mFogTextures.push_back(ESM::FogTexture()); + fog->mFogTextures.emplace_back(); // saving even if !segment.mHasFogState so we don't mess up the segmenting // plus, older openmw versions can't deal with empty images diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 31cf3f015..d97e57115 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -19,11 +19,10 @@ #include #include #include +#include #include -#include // TextKeyMapHolder - #include #include "../mwworld/esmstore.hpp" @@ -145,7 +144,7 @@ public: void setBlinkStart(float value); void setBlinkStop(float value); - virtual float getValue(osg::NodeVisitor* nv); + float getValue(osg::NodeVisitor* nv) override; }; // -------------------------------------------------------------------------------- @@ -166,7 +165,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 +377,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 +399,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; @@ -864,7 +863,7 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g for (unsigned int i=0; igetUserDataContainer()->getNumUserObjects(); ++i) { osg::Object* obj = node->getUserDataContainer()->getUserObject(i); - if (NifOsg::TextKeyMapHolder* keys = dynamic_cast(obj)) + if (SceneUtil::TextKeyMapHolder* keys = dynamic_cast(obj)) { for (const auto &key : keys->mTextKeys) { @@ -1078,10 +1077,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/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..a5015f377 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; @@ -596,7 +596,7 @@ namespace MWRender if (numinstances > 0) { // add a ref to the original template, to hint to the cache that it's still being used and should be kept in cache - templateRefs->mObjects.push_back(cnode); + templateRefs->mObjects.emplace_back(cnode); if (pair.second.mNeedCompile) { 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 c117de924..362a32959 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -90,7 +90,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); @@ -107,7 +107,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); @@ -167,7 +167,7 @@ namespace MWRender { } - virtual void doWork() + void doWork() override { try { @@ -218,6 +218,7 @@ namespace MWRender resourceSystem->getSceneManager()->setNormalHeightMapPattern(Settings::Manager::getString("normal height map pattern", "Shaders")); resourceSystem->getSceneManager()->setAutoUseSpecularMaps(Settings::Manager::getBool("auto use object specular maps", "Shaders")); resourceSystem->getSceneManager()->setSpecularMapPattern(Settings::Manager::getString("specular map pattern", "Shaders")); + resourceSystem->getSceneManager()->setApplyLightingToEnvMaps(Settings::Manager::getBool("apply lighting to environment maps", "Shaders")); osg::ref_ptr sceneRoot = new SceneUtil::LightManager; sceneRoot->setLightingMask(Mask_Lighting); @@ -306,7 +307,7 @@ namespace MWRender mTerrain->setWorkQueue(mWorkQueue.get()); // water goes after terrain for correct waterculling order - mWater.reset(new Water(mRootNode, sceneRoot, mResourceSystem, mViewer->getIncrementalCompileOperation(), resourcePath)); + mWater.reset(new Water(sceneRoot->getParent(0), sceneRoot, mResourceSystem, mViewer->getIncrementalCompileOperation(), resourcePath)); mCamera.reset(new Camera(mViewer->getCamera())); if (Settings::Manager::getBool("view over shoulder", "Camera")) @@ -363,6 +364,7 @@ namespace MWRender mViewer->getCamera()->setCullMask(~(Mask_UpdateVisitor|Mask_SimpleWater)); NifOsg::Loader::setHiddenNodeMask(Mask_UpdateVisitor); NifOsg::Loader::setIntersectionDisabledNodeMask(Mask_Effect); + Nif::NIFFile::setLoadUnsupportedFiles(Settings::Manager::getBool("load unsupported nif files", "Models")); mNearClip = Settings::Manager::getFloat("near clip", "Camera"); mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); @@ -432,7 +434,7 @@ namespace MWRender workItem->mKeyframes.push_back(std::string("meshes/") + basemodels[i] + ".kf"); } - workItem->mTextures.push_back("textures/_land_default.dds"); + workItem->mTextures.emplace_back("textures/_land_default.dds"); mWorkQueue->addWorkItem(workItem); } @@ -705,7 +707,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) @@ -932,7 +934,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 fd3870665..a5143be9e 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..2920e07dd 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); @@ -941,10 +941,10 @@ public: Moon(osg::Group* parentNode, Resource::ImageManager& imageManager, float scaleFactor, Type type) : CelestialBody(parentNode, scaleFactor, 2) , mType(type) - , mPhase(MoonState::Phase_Unspecified) + , mPhase(MoonState::Phase::Unspecified) , mUpdater(new Updater(imageManager)) { - setPhase(MoonState::Phase_Full); + setPhase(MoonState::Phase::Full); setVisible(true); mGeom->addUpdateCallback(mUpdater); @@ -955,7 +955,7 @@ public: mGeom->removeUpdateCallback(mUpdater); } - virtual void adjustTransparency(const float ratio) + void adjustTransparency(const float ratio) override { mUpdater->mTransparency *= ratio; } @@ -993,14 +993,14 @@ public: unsigned int getPhaseInt() const { - if (mPhase == MoonState::Phase_New) return 0; - else if (mPhase == MoonState::Phase_WaxingCrescent) return 1; - else if (mPhase == MoonState::Phase_WaningCrescent) return 1; - else if (mPhase == MoonState::Phase_FirstQuarter) return 2; - else if (mPhase == MoonState::Phase_ThirdQuarter) return 2; - else if (mPhase == MoonState::Phase_WaxingGibbous) return 3; - else if (mPhase == MoonState::Phase_WaningGibbous) return 3; - else if (mPhase == MoonState::Phase_Full) return 4; + if (mPhase == MoonState::Phase::New) return 0; + else if (mPhase == MoonState::Phase::WaxingCrescent) return 1; + else if (mPhase == MoonState::Phase::WaningCrescent) return 1; + else if (mPhase == MoonState::Phase::FirstQuarter) return 2; + else if (mPhase == MoonState::Phase::ThirdQuarter) return 2; + else if (mPhase == MoonState::Phase::WaxingGibbous) return 3; + else if (mPhase == MoonState::Phase::WaningGibbous) return 3; + else if (mPhase == MoonState::Phase::Full) return 4; return 0; } @@ -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); @@ -1090,14 +1090,14 @@ private: else textureName += "masser_"; - if (phase == MoonState::Phase_New) textureName += "new"; - else if(phase == MoonState::Phase_WaxingCrescent) textureName += "one_wax"; - else if(phase == MoonState::Phase_FirstQuarter) textureName += "half_wax"; - else if(phase == MoonState::Phase_WaxingGibbous) textureName += "three_wax"; - else if(phase == MoonState::Phase_WaningCrescent) textureName += "one_wan"; - else if(phase == MoonState::Phase_ThirdQuarter) textureName += "half_wan"; - else if(phase == MoonState::Phase_WaningGibbous) textureName += "three_wan"; - else if(phase == MoonState::Phase_Full) textureName += "full"; + if (phase == MoonState::Phase::New) textureName += "new"; + else if(phase == MoonState::Phase::WaxingCrescent) textureName += "one_wax"; + else if(phase == MoonState::Phase::FirstQuarter) textureName += "half_wax"; + else if(phase == MoonState::Phase::WaxingGibbous) textureName += "three_wax"; + else if(phase == MoonState::Phase::WaningCrescent) textureName += "one_wan"; + else if(phase == MoonState::Phase::ThirdQuarter) textureName += "half_wan"; + else if(phase == MoonState::Phase::WaningGibbous) textureName += "three_wan"; + else if(phase == MoonState::Phase::Full) textureName += "full"; textureName += ".dds"; @@ -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; @@ -1911,42 +1911,42 @@ void SkyManager::setWaterHeight(float height) void SkyManager::listAssetsToPreload(std::vector& models, std::vector& textures) { - models.push_back("meshes/sky_atmosphere.nif"); + models.emplace_back("meshes/sky_atmosphere.nif"); if (mSceneManager->getVFS()->exists("meshes/sky_night_02.nif")) - models.push_back("meshes/sky_night_02.nif"); - models.push_back("meshes/sky_night_01.nif"); - models.push_back("meshes/sky_clouds_01.nif"); - - models.push_back("meshes\\ashcloud.nif"); - models.push_back("meshes\\blightcloud.nif"); - models.push_back("meshes\\snow.nif"); - models.push_back("meshes\\blizzard.nif"); - - textures.push_back("textures/tx_mooncircle_full_s.dds"); - textures.push_back("textures/tx_mooncircle_full_m.dds"); - - textures.push_back("textures/tx_masser_new.dds"); - textures.push_back("textures/tx_masser_one_wax.dds"); - textures.push_back("textures/tx_masser_half_wax.dds"); - textures.push_back("textures/tx_masser_three_wax.dds"); - textures.push_back("textures/tx_masser_one_wan.dds"); - textures.push_back("textures/tx_masser_half_wan.dds"); - textures.push_back("textures/tx_masser_three_wan.dds"); - textures.push_back("textures/tx_masser_full.dds"); - - textures.push_back("textures/tx_secunda_new.dds"); - textures.push_back("textures/tx_secunda_one_wax.dds"); - textures.push_back("textures/tx_secunda_half_wax.dds"); - textures.push_back("textures/tx_secunda_three_wax.dds"); - textures.push_back("textures/tx_secunda_one_wan.dds"); - textures.push_back("textures/tx_secunda_half_wan.dds"); - textures.push_back("textures/tx_secunda_three_wan.dds"); - textures.push_back("textures/tx_secunda_full.dds"); - - textures.push_back("textures/tx_sun_05.dds"); - textures.push_back("textures/tx_sun_flash_grey_05.dds"); - - textures.push_back("textures/tx_raindrop_01.dds"); + models.emplace_back("meshes/sky_night_02.nif"); + models.emplace_back("meshes/sky_night_01.nif"); + models.emplace_back("meshes/sky_clouds_01.nif"); + + models.emplace_back("meshes\\ashcloud.nif"); + models.emplace_back("meshes\\blightcloud.nif"); + models.emplace_back("meshes\\snow.nif"); + models.emplace_back("meshes\\blizzard.nif"); + + textures.emplace_back("textures/tx_mooncircle_full_s.dds"); + textures.emplace_back("textures/tx_mooncircle_full_m.dds"); + + textures.emplace_back("textures/tx_masser_new.dds"); + textures.emplace_back("textures/tx_masser_one_wax.dds"); + textures.emplace_back("textures/tx_masser_half_wax.dds"); + textures.emplace_back("textures/tx_masser_three_wax.dds"); + textures.emplace_back("textures/tx_masser_one_wan.dds"); + textures.emplace_back("textures/tx_masser_half_wan.dds"); + textures.emplace_back("textures/tx_masser_three_wan.dds"); + textures.emplace_back("textures/tx_masser_full.dds"); + + textures.emplace_back("textures/tx_secunda_new.dds"); + textures.emplace_back("textures/tx_secunda_one_wax.dds"); + textures.emplace_back("textures/tx_secunda_half_wax.dds"); + textures.emplace_back("textures/tx_secunda_three_wax.dds"); + textures.emplace_back("textures/tx_secunda_one_wan.dds"); + textures.emplace_back("textures/tx_secunda_half_wan.dds"); + textures.emplace_back("textures/tx_secunda_three_wan.dds"); + textures.emplace_back("textures/tx_secunda_full.dds"); + + textures.emplace_back("textures/tx_sun_05.dds"); + textures.emplace_back("textures/tx_sun_flash_grey_05.dds"); + + textures.emplace_back("textures/tx_raindrop_01.dds"); } void SkyManager::setWaterEnabled(bool enabled) diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 9727529d9..cf697bd44 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -99,17 +99,17 @@ namespace MWRender struct MoonState { - enum Phase + enum class Phase { - Phase_Full = 0, - Phase_WaningGibbous, - Phase_ThirdQuarter, - Phase_WaningCrescent, - Phase_New, - Phase_WaxingCrescent, - Phase_FirstQuarter, - Phase_WaxingGibbous, - Phase_Unspecified + Full = 0, + WaningGibbous, + ThirdQuarter, + WaningCrescent, + New, + WaxingCrescent, + FirstQuarter, + WaxingGibbous, + Unspecified }; float mRotationFromHorizon; 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 c1c3e84a9..60a5b0bac 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -67,7 +67,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); @@ -100,7 +100,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(); @@ -170,7 +170,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()); @@ -186,7 +186,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); @@ -237,13 +237,14 @@ public: Refraction() { unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water"); - setRenderOrder(osg::Camera::PRE_RENDER); + setRenderOrder(osg::Camera::PRE_RENDER, 1); setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); setReferenceFrame(osg::Camera::RELATIVE_RF); setSmallFeatureCullingPixelSize(Settings::Manager::getInt("small feature culling pixel size", "Water")); setName("RefractionCamera"); setCullCallback(new InheritViewPointCallback); + setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); setCullMask(Mask_Effect|Mask_Scene|Mask_Object|Mask_Static|Mask_Terrain|Mask_Actor|Mask_ParticleSystem|Mask_Sky|Mask_Sun|Mask_Player|Mask_Lighting); setNodeMask(Mask_RenderToTexture); @@ -286,7 +287,8 @@ public: attach(osg::Camera::DEPTH_BUFFER, mRefractionDepthTexture); - SceneUtil::ShadowManager::disableShadowsForStateSet(getOrCreateStateSet()); + if (Settings::Manager::getFloat("refraction scale", "Water") != 1) // TODO: to be removed with issue #5709 + SceneUtil::ShadowManager::disableShadowsForStateSet(getOrCreateStateSet()); } void setScene(osg::Node* scene) @@ -411,7 +413,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..186940dd9 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -19,15 +19,60 @@ #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 "../mwmechanics/levelledlist.hpp" #include "ref.hpp" +namespace +{ + void addToStore(const 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); + } + } + + 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 { namespace Container @@ -37,7 +82,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -60,6 +105,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 +119,38 @@ 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); + 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()) + { + addRandomToStore(itemPtr, count, ptr, store); + } + } + else + addToStore(itemPtr, count, ptr, store, store.isResolved()); + } + } + return; } + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); + if(isLevelledList) + addRandomToStore(itemPtr, count, ptr, store); 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); - } + 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() ) @@ -107,7 +178,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -131,7 +202,7 @@ namespace MWScript { public: - virtual void execute (Interpreter::Runtime& runtime) + void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -160,7 +231,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, false); + } + } + return; + } MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); std::string itemName; @@ -202,7 +292,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -239,7 +329,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -312,7 +402,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -338,7 +428,7 @@ namespace MWScript { public: - virtual void execute(Interpreter::Runtime &runtime) + void execute(Interpreter::Runtime &runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -362,7 +452,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/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 41f153b28..1a7e3ebbc 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -186,7 +186,7 @@ namespace MWScript // make list of global scripts to be added std::vector scripts; - scripts.push_back ("main"); + scripts.emplace_back("main"); for (MWWorld::Store::iterator iter = mStore.get().begin(); 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/locals.cpp b/apps/openmw/mwscript/locals.cpp index 381d73ec8..352dc67b3 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -191,7 +191,7 @@ namespace MWScript case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break; } - locals.mVariables.push_back (std::make_pair (names[i2], value)); + locals.mVariables.emplace_back (names[i2], value); } } } 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..a908940ed 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); @@ -368,7 +368,7 @@ namespace MWScript std::string cellID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - MWWorld::CellStore* store = 0; + MWWorld::CellStore* store = nullptr; try { store = MWBase::Environment::get().getWorld()->getInterior(cellID); @@ -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(); @@ -481,7 +481,7 @@ namespace MWScript Interpreter::Type_Float zRotDegrees = runtime[0].mFloat; runtime.pop(); - MWWorld::CellStore* store = 0; + MWWorld::CellStore* store = nullptr; try { store = MWBase::Environment::get().getWorld()->getInterior(cellID); @@ -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/ffmpeg_decoder.cpp b/apps/openmw/mwsound/ffmpeg_decoder.cpp index 6c334978c..95ed9eeed 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.cpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.cpp @@ -437,7 +437,7 @@ FFmpeg_Decoder::FFmpeg_Decoder(const VFS::Manager* vfs) , mFrameSize(0) , mFramePos(0) , mNextPts(0.0) - , mSwr(0) + , mSwr(nullptr) , mOutputSampleFormat(AV_SAMPLE_FMT_NONE) , mOutputChannelLayout(0) , mDataBuf(nullptr) 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.cpp b/apps/openmw/mwsound/openal_output.cpp index 1606b2979..67b52309d 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -579,7 +579,7 @@ std::vector OpenAL_Output::enumerate() devnames = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); while(devnames && *devnames) { - devlist.push_back(devnames); + devlist.emplace_back(devnames); devnames += strlen(devnames)+1; } return devlist; @@ -624,7 +624,7 @@ bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname attrs.reserve(15); if(ALC.SOFT_HRTF) { - LPALCGETSTRINGISOFT alcGetStringiSOFT = 0; + LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); attrs.push_back(ALC_HRTF_SOFT); @@ -850,13 +850,13 @@ void OpenAL_Output::deinit() alDeleteFilters(1, &mWaterFilter); mWaterFilter = 0; - alcMakeContextCurrent(0); + alcMakeContextCurrent(nullptr); if(mContext) alcDestroyContext(mContext); - mContext = 0; + mContext = nullptr; if(mDevice) alcCloseDevice(mDevice); - mDevice = 0; + mDevice = nullptr; mInitialized = false; } @@ -869,7 +869,7 @@ std::vector OpenAL_Output::enumerateHrtf() if(!mDevice || !ALC.SOFT_HRTF) return ret; - LPALCGETSTRINGISOFT alcGetStringiSOFT = 0; + LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); ALCint num_hrtf; @@ -878,7 +878,7 @@ std::vector OpenAL_Output::enumerateHrtf() for(ALCint i = 0;i < num_hrtf;++i) { const ALCchar *entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); - ret.push_back(entry); + ret.emplace_back(entry); } return ret; @@ -892,10 +892,10 @@ void OpenAL_Output::setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) return; } - LPALCGETSTRINGISOFT alcGetStringiSOFT = 0; + LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); - LPALCRESETDEVICESOFT alcResetDeviceSOFT = 0; + LPALCRESETDEVICESOFT alcResetDeviceSOFT = nullptr; getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT"); std::vector attrs; @@ -1213,7 +1213,7 @@ void OpenAL_Output::finishSound(Sound *sound) { if(!sound->mHandle) return; ALuint source = GET_PTRID(sound->mHandle); - sound->mHandle = 0; + sound->mHandle = nullptr; // Rewind the stream to put the source back into an AL_INITIAL state, for // the next time it's used. @@ -1316,7 +1316,7 @@ void OpenAL_Output::finishStream(Stream *sound) OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); ALuint source = stream->mSource; - sound->mHandle = 0; + sound->mHandle = nullptr; mStreamThread->remove(stream); // Rewind the stream to put the source back into an AL_INITIAL state, for @@ -1462,7 +1462,7 @@ void OpenAL_Output::pauseActiveDevice() if(alcIsExtensionPresent(mDevice, "ALC_SOFT_PAUSE_DEVICE")) { - LPALCDEVICEPAUSESOFT alcDevicePauseSOFT = 0; + LPALCDEVICEPAUSESOFT alcDevicePauseSOFT = nullptr; getALCFunc(alcDevicePauseSOFT, mDevice, "alcDevicePauseSOFT"); alcDevicePauseSOFT(mDevice); getALCError(mDevice); @@ -1478,7 +1478,7 @@ void OpenAL_Output::resumeActiveDevice() if(alcIsExtensionPresent(mDevice, "ALC_SOFT_PAUSE_DEVICE")) { - LPALCDEVICERESUMESOFT alcDeviceResumeSOFT = 0; + LPALCDEVICERESUMESOFT alcDeviceResumeSOFT = nullptr; getALCFunc(alcDeviceResumeSOFT, mDevice, "alcDeviceResumeSOFT"); alcDeviceResumeSOFT(mDevice); getALCError(mDevice); @@ -1513,7 +1513,7 @@ void OpenAL_Output::resumeSounds(int types) OpenAL_Output::OpenAL_Output(SoundManager &mgr) : Sound_Output(mgr) - , mDevice(0), mContext(0) + , mDevice(nullptr), mContext(nullptr) , mListenerPos(0.0f, 0.0f, 0.0f), mListenerEnv(Env_Normal) , mWaterFilter(0), mWaterEffect(0), mDefaultEffect(0), mEffectSlot(0) , mStreamThread(new StreamThread) 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/regionsoundselector.cpp b/apps/openmw/mwsound/regionsoundselector.cpp index ac5f66721..752c4a26b 100644 --- a/apps/openmw/mwsound/regionsoundselector.cpp +++ b/apps/openmw/mwsound/regionsoundselector.cpp @@ -1,5 +1,6 @@ #include "regionsoundselector.hpp" +#include #include #include @@ -18,7 +19,12 @@ namespace MWSound } } - boost::optional RegionSoundSelector::getNextRandom(float duration, const std::string& regionName, + RegionSoundSelector::RegionSoundSelector() + : mMinTimeBetweenSounds(Fallback::Map::getFloat("Weather_Minimum_Time_Between_Environmental_Sounds")) + , mMaxTimeBetweenSounds(Fallback::Map::getFloat("Weather_Maximum_Time_Between_Environmental_Sounds")) + {} + + std::optional RegionSoundSelector::getNextRandom(float duration, const std::string& regionName, const MWBase::World& world) { mTimePassed += duration; @@ -27,9 +33,7 @@ namespace MWSound return {}; const float a = Misc::Rng::rollClosedProbability(); - // NOTE: We should use the "Minimum Time Between Environmental Sounds" and - // "Maximum Time Between Environmental Sounds" fallback settings here. - mTimeToNextEnvSound = 5.0f * a + 15.0f * (1.0f - a); + mTimeToNextEnvSound = mMinTimeBetweenSounds + (mMaxTimeBetweenSounds - mMinTimeBetweenSounds) * a; mTimePassed = 0; if (mLastRegionName != regionName) @@ -50,7 +54,7 @@ namespace MWSound return {}; } - const int r = Misc::Rng::rollDice(mSumChance); + const int r = Misc::Rng::rollDice(std::max(mSumChance, 100)); int pos = 0; const auto isSelected = [&] (const ESM::Region::SoundRef& sound) diff --git a/apps/openmw/mwsound/regionsoundselector.hpp b/apps/openmw/mwsound/regionsoundselector.hpp index 00a2d5ca8..35df8a531 100644 --- a/apps/openmw/mwsound/regionsoundselector.hpp +++ b/apps/openmw/mwsound/regionsoundselector.hpp @@ -1,8 +1,7 @@ #ifndef GAME_SOUND_REGIONSOUNDSELECTOR_H #define GAME_SOUND_REGIONSOUNDSELECTOR_H -#include - +#include #include namespace MWBase @@ -15,14 +14,18 @@ namespace MWSound class RegionSoundSelector { public: - boost::optional getNextRandom(float duration, const std::string& regionName, + std::optional getNextRandom(float duration, const std::string& regionName, const MWBase::World& world); + RegionSoundSelector(); + private: float mTimeToNextEnvSound = 0.0f; int mSumChance = 0; std::string mLastRegionName; float mTimePassed = 0.0; + float mMinTimeBetweenSounds; + float mMaxTimeBetweenSounds; }; } diff --git a/apps/openmw/mwsound/sound_buffer.hpp b/apps/openmw/mwsound/sound_buffer.hpp index 5ca3a45da..83b08d6be 100644 --- a/apps/openmw/mwsound/sound_buffer.hpp +++ b/apps/openmw/mwsound/sound_buffer.hpp @@ -20,7 +20,7 @@ namespace MWSound size_t mUses; Sound_Buffer(std::string resname, float volume, float mindist, float maxdist) - : mResourceName(resname), mVolume(volume), mMinDist(mindist), mMaxDist(maxdist), mHandle(0), mUses(0) + : mResourceName(resname), mVolume(volume), mMinDist(mindist), mMaxDist(maxdist), mHandle(nullptr), mUses(0) { } }; } diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 17aa184a7..37ba80820 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -65,6 +65,9 @@ namespace MWSound , mUnderwaterSound(nullptr) , mNearWaterSound(nullptr) , mPlaybackPaused(false) + , mTimePassed(0.f) + , mLastCell(nullptr) + , mCurrentRegionSound(nullptr) { mBufferCacheMin = std::max(Settings::Manager::getInt("buffer cache min", "Sound"), 1); mBufferCacheMax = std::max(Settings::Manager::getInt("buffer cache max", "Sound"), 1); @@ -117,7 +120,7 @@ namespace MWSound { if(sfx.mHandle) mOutput->unloadSound(sfx.mHandle); - sfx.mHandle = 0; + sfx.mHandle = nullptr; } mUnusedBuffers.clear(); mOutput.reset(); @@ -226,7 +229,7 @@ namespace MWSound size = mOutput->unloadSound(unused->mHandle); mBufferCacheSize -= size; - unused->mHandle = 0; + unused->mHandle = nullptr; mUnusedBuffers.pop_back(); } while(mBufferCacheSize > mBufferCacheMin); @@ -895,9 +898,11 @@ namespace MWSound if (!cell->isExterior()) return; + if (mCurrentRegionSound && mOutput->isSoundPlaying(mCurrentRegionSound)) + return; if (const auto next = mRegionSoundSelector.getNextRandom(duration, cell->mRegion, *world)) - playSound(*next, 1.0f, 1.0f); + mCurrentRegionSound = playSound(*next, 1.0f, 1.0f); } void SoundManager::updateWaterSound() diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index b3f612d7d..f69171a09 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -116,9 +116,11 @@ namespace MWSound RegionSoundSelector mRegionSoundSelector; - float mTimePassed = 0; + float mTimePassed; - const ESM::Cell *mLastCell = nullptr; + const ESM::Cell *mLastCell; + + Sound* mCurrentRegionSound; Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound); @@ -169,111 +171,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/character.cpp b/apps/openmw/mwstate/character.cpp index 3c5c4f8b2..df1ab1bdf 100644 --- a/apps/openmw/mwstate/character.cpp +++ b/apps/openmw/mwstate/character.cpp @@ -64,7 +64,7 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile) } slot.mProfile = profile; - slot.mTimeStamp = std::time (0); + slot.mTimeStamp = std::time (nullptr); mSlots.push_back (slot); } @@ -143,7 +143,7 @@ const MWState::Slot *MWState::Character::updateSlot (const Slot *slot, const ESM Slot newSlot = *slot; newSlot.mProfile = profile; - newSlot.mTimeStamp = std::time (0); + newSlot.mTimeStamp = std::time (nullptr); mSlots.erase (mSlots.begin()+index); diff --git a/apps/openmw/mwstate/charactermanager.cpp b/apps/openmw/mwstate/charactermanager.cpp index 856264d03..a324dfe0f 100644 --- a/apps/openmw/mwstate/charactermanager.cpp +++ b/apps/openmw/mwstate/charactermanager.cpp @@ -7,7 +7,7 @@ MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves, const std::string& game) -: mPath (saves), mCurrent (0), mGame (game) +: mPath (saves), mCurrent (nullptr), mGame (game) { if (!boost::filesystem::is_directory (mPath)) { @@ -77,7 +77,7 @@ MWState::Character* MWState::CharacterManager::createCharacter(const std::string path = mPath / test.str(); } - mCharacters.push_back (Character (path, mGame)); + mCharacters.emplace_back(path, mGame); return &mCharacters.back(); } diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index d59704bf1..72e4b1ae0 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -48,8 +48,8 @@ void MWState::StateManager::cleanup (bool force) MWBase::Environment::get().getDialogueManager()->clear(); MWBase::Environment::get().getJournal()->clear(); MWBase::Environment::get().getScriptManager()->clear(); - MWBase::Environment::get().getWorld()->clear(); MWBase::Environment::get().getWindowManager()->clear(); + MWBase::Environment::get().getWorld()->clear(); MWBase::Environment::get().getInputManager()->clear(); MWBase::Environment::get().getMechanicsManager()->clear(); @@ -118,8 +118,8 @@ void MWState::StateManager::askLoadRecent() { MWState::Slot lastSave = *character->begin(); std::vector buttons; - buttons.push_back("#{sYes}"); - buttons.push_back("#{sNo}"); + buttons.emplace_back("#{sYes}"); + buttons.emplace_back("#{sNo}"); std::string tag("%s"); std::string message = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLoadLastSaveMsg", tag); size_t pos = message.find(tag); @@ -165,7 +165,7 @@ void MWState::StateManager::newGame (bool bypass) MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); std::vector buttons; - buttons.push_back("#{sOk}"); + buttons.emplace_back("#{sOk}"); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(error.str(), buttons); } } @@ -306,7 +306,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot Log(Debug::Error) << error.str(); std::vector buttons; - buttons.push_back("#{sOk}"); + buttons.emplace_back("#{sOk}"); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(error.str(), buttons); // If no file was written, clean up the slot @@ -451,6 +451,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str case ESM::REC_LEVC: case ESM::REC_LEVI: case ESM::REC_CREA: + case ESM::REC_CONT: MWBase::Environment::get().getWorld()->readRecord(reader, n.intval, contentFileMap); break; @@ -557,7 +558,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); std::vector buttons; - buttons.push_back("#{sOk}"); + buttons.emplace_back("#{sOk}"); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(error.str(), buttons); } } @@ -633,8 +634,8 @@ bool MWState::StateManager::verifyProfile(const ESM::SavedGame& profile) const if (notFound) { std::vector buttons; - buttons.push_back("#{sYes}"); - buttons.push_back("#{sNo}"); + buttons.emplace_back("#{sYes}"); + buttons.emplace_back("#{sNo}"); MWBase::Environment::get().getWindowManager()->interactiveMessageBox("#{sMissingMastersMsg}", buttons, true); int selectedButton = MWBase::Environment::get().getWindowManager()->readPressedButton(); if (selectedButton == 1 || selectedButton == -1) diff --git a/apps/openmw/mwstate/statemanagerimp.hpp b/apps/openmw/mwstate/statemanagerimp.hpp index d71fae850..3534dabf2 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 = nullptr) 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.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/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..31af5b24b 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); } @@ -496,7 +496,7 @@ namespace MWWorld else if (mTerrainViews.size() < positions.size()) { for (unsigned int i=mTerrainViews.size(); icreateView()); + mTerrainViews.emplace_back(mTerrain->createView()); } mTerrainPreloadPositions = positions; diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index bf107b422..15c1b46ba 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) @@ -50,7 +94,7 @@ void MWWorld::Cells::clear() { mInteriors.clear(); mExteriors.clear(); - std::fill(mIdCache.begin(), mIdCache.end(), std::make_pair("", (MWWorld::CellStore*)0)); + std::fill(mIdCache.begin(), mIdCache.end(), std::make_pair("", (MWWorld::CellStore*)nullptr)); mIdCacheIndex = 0; } @@ -88,7 +132,7 @@ void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, CellStore& cell) const MWWorld::Cells::Cells (const MWWorld::ESMStore& store, std::vector& reader) : mStore (store), mReader (reader), - mIdCache (Settings::Manager::getInt("pointers cache size", "Cells"), std::pair ("", (CellStore*)0)), + mIdCache (Settings::Manager::getInt("pointers cache size", "Cells"), std::pair ("", (CellStore*)nullptr)), mIdCacheIndex (0) {} @@ -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; @@ -376,7 +428,7 @@ public: MWWorld::Cells& mCells; - virtual MWWorld::CellStore* getCellStore(const ESM::CellId& cellId) + MWWorld::CellStore* getCellStore(const ESM::CellId& cellId) override { try { @@ -397,7 +449,7 @@ bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, uint32_t type, ESM::CellState state; state.mId.load (reader); - CellStore *cellStore = 0; + CellStore *cellStore = nullptr; try { 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/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 2cda83e17..b48fe74a6 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -37,7 +37,7 @@ namespace for (typename MWWorld::CellRefList::List::iterator iter (containerList.mList.begin()); iter!=containerList.mList.end(); ++iter) { - MWWorld::Ptr container (&*iter, 0); + MWWorld::Ptr container (&*iter, nullptr); if (container.getRefData().getCustomData() == nullptr) continue; @@ -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..17c35489f 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()); @@ -51,7 +67,7 @@ namespace { if (Misc::StringUtils::ciEqual(iter->mBase->mId, id2) && iter->mData.getCount()) { - MWWorld::Ptr ptr (&*iter, 0); + MWWorld::Ptr ptr (&*iter, nullptr); ptr.setContainerStore (store); return ptr; } @@ -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 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 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)) - 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; @@ -266,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; @@ -302,7 +326,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr if (actorPtr == player) { // Items in player's inventory have cell set to 0, so their scripts will never be removed - item.mCell = 0; + item.mCell = nullptr; } else { @@ -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; @@ -437,13 +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 equipReplacement, bool resolveFirst) { + 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 -= remove(*iter, toRemove, actor, equipReplacement, resolveFirst); flagAsModified(); @@ -462,9 +490,11 @@ bool MWWorld::ContainerStore::hasVisibleItems() const return false; } -int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor) +int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement, bool resolveFirst) { assert(this == item.getContainerStore()); + if(resolveFirst) + resolve(); int toRemove = count; RefData& itemRef = item.getRefData(); @@ -476,7 +506,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 +520,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 (const ESM::ContItem& iter : items.mList) + { + std::string id = Misc::StringUtils::lowerCase(iter.mItem); + addInitialItem(id, owner, iter.mCount, &seed); + } + + flagAsModified(); + mResolved = true; +} + +void MWWorld::ContainerStore::fillNonRandom (const ESM::InventoryList& items, const std::string& owner, unsigned int seed) { - for (std::vector::const_iterator iter (items.mList.begin()); iter!=items.mList.end(); - ++iter) + mSeed = seed; + 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, nullptr); } flagAsModified(); + mResolved = false; } -void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, - int count, bool topLevel, const std::string& levItem) +void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, int count, + Misc::Rng::Seed* seed, bool topLevel) { if (count == 0) return; //Don't restock with nothing. try @@ -511,13 +554,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); } 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); } } catch (const std::exception& e) @@ -526,137 +569,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) { 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); 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); } } 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 +614,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 +749,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 +825,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 +858,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 +898,6 @@ void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) break; } } - - - mLevelledItemMap = inventory.mLevelledItemMap; } template @@ -1136,18 +1138,18 @@ PtrType MWWorld::ContainerStoreIteratorBase::operator*() const switch (mType) { - case ContainerStore::Type_Potion: ptr = PtrType (&*mPotion, 0); break; - case ContainerStore::Type_Apparatus: ptr = PtrType (&*mApparatus, 0); break; - case ContainerStore::Type_Armor: ptr = PtrType (&*mArmor, 0); break; - case ContainerStore::Type_Book: ptr = PtrType (&*mBook, 0); break; - case ContainerStore::Type_Clothing: ptr = PtrType (&*mClothing, 0); break; - case ContainerStore::Type_Ingredient: ptr = PtrType (&*mIngredient, 0); break; - case ContainerStore::Type_Light: ptr = PtrType (&*mLight, 0); break; - case ContainerStore::Type_Lockpick: ptr = PtrType (&*mLockpick, 0); break; - case ContainerStore::Type_Miscellaneous: ptr = PtrType (&*mMiscellaneous, 0); break; - case ContainerStore::Type_Probe: ptr = PtrType (&*mProbe, 0); break; - case ContainerStore::Type_Repair: ptr = PtrType (&*mRepair, 0); break; - case ContainerStore::Type_Weapon: ptr = PtrType (&*mWeapon, 0); break; + case ContainerStore::Type_Potion: ptr = PtrType (&*mPotion, nullptr); break; + case ContainerStore::Type_Apparatus: ptr = PtrType (&*mApparatus, nullptr); break; + case ContainerStore::Type_Armor: ptr = PtrType (&*mArmor, nullptr); break; + case ContainerStore::Type_Book: ptr = PtrType (&*mBook, nullptr); break; + case ContainerStore::Type_Clothing: ptr = PtrType (&*mClothing, nullptr); break; + case ContainerStore::Type_Ingredient: ptr = PtrType (&*mIngredient, nullptr); break; + case ContainerStore::Type_Light: ptr = PtrType (&*mLight, nullptr); break; + case ContainerStore::Type_Lockpick: ptr = PtrType (&*mLockpick, nullptr); break; + case ContainerStore::Type_Miscellaneous: ptr = PtrType (&*mMiscellaneous, nullptr); break; + case ContainerStore::Type_Probe: ptr = PtrType (&*mProbe, nullptr); break; + case ContainerStore::Type_Repair: ptr = PtrType (&*mRepair, nullptr); break; + case ContainerStore::Type_Weapon: ptr = PtrType (&*mWeapon, nullptr); break; } if (ptr.isEmpty()) diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index f2858c5aa..e0843efba 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); + void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Seed* seed, bool topLevel=true); template ContainerStoreIterator getState (CellRefList& collection, @@ -139,7 +165,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. @@ -152,12 +178,12 @@ 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 equipReplacement = 0, bool resolve = true); ///< Remove \a count item(s) designated by \a itemId from this container. /// /// @return the number of items actually removed - virtual int remove(const Ptr& item, int count, const Ptr& actor); + virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true); ///< Remove \a count item(s) designated by \a item from this inventory. /// /// @return the number of items actually removed @@ -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/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/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index aea9a5e4f..90bc80b48 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -71,7 +71,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) { listener->setProgressRange(1000); - ESM::Dialogue *dialogue = 0; + ESM::Dialogue *dialogue = nullptr; // Land texture loading needs to use a separate internal store for each plugin. // We set the number of plugins here to avoid continual resizes during loading, @@ -153,7 +153,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener) if (n.intval==ESM::REC_DIAL) { dialogue = const_cast(mDialogs.find(id.mId)); } else { - dialogue = 0; + dialogue = nullptr; } } listener->setProgress(static_cast(esm.getFileOffset() / (float)esm.getFileSize() * 1000)); @@ -345,7 +345,8 @@ void ESMStore::validate() +mWeapons.getDynamicSize() +mCreatureLists.getDynamicSize() +mItemLists.getDynamicSize() - +mCreatures.getDynamicSize(); + +mCreatures.getDynamicSize() + +mContainers.getDynamicSize(); } void ESMStore::write (ESM::ESMWriter& writer, Loading::Listener& progress) const @@ -368,6 +369,7 @@ void ESMStore::validate() mItemLists.write (writer, progress); mCreatureLists.write (writer, progress); mCreatures.write (writer, progress); + mContainers.write (writer, progress); } bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type) @@ -386,6 +388,7 @@ void ESMStore::validate() case ESM::REC_LEVI: case ESM::REC_LEVC: case ESM::REC_CREA: + case ESM::REC_CONT: mStores[type]->read (reader); return true; diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 99db96ac1..d69c56d8c 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -196,7 +196,7 @@ namespace MWWorld const std::string id = "$dynamic" + std::to_string(mDynamicCount++); Store &store = const_cast &>(get()); - if (store.search(id) != 0) + if (store.search(id) != nullptr) { const std::string msg = "Try to override existing record '" + id + "'"; throw std::runtime_error(msg); @@ -234,7 +234,7 @@ namespace MWWorld const std::string id = "$dynamic" + std::to_string(mDynamicCount++); Store &store = const_cast &>(get()); - if (store.search(id) != 0) + if (store.search(id) != nullptr) { const std::string msg = "Try to override existing record '" + id + "'"; throw std::runtime_error(msg); @@ -286,7 +286,7 @@ namespace MWWorld { return mNpcs.insert(npc); } - else if (mNpcs.search(id) != 0) + else if (mNpcs.search(id) != nullptr) { const std::string msg = "Try to override existing record '" + id + "'"; throw std::runtime_error(msg); 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.cpp b/apps/openmw/mwworld/inventorystore.cpp index d67a22884..386bbb30a 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 @@ -131,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() @@ -709,33 +710,9 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSelectedEnchantItem( return mSelectedEnchantItem; } -int MWWorld::InventoryStore::remove(const std::string& itemId, int count, const Ptr& actor) +int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement, bool resolve) { - return remove(itemId, count, actor, false); -} - -int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor) -{ - return remove(item, count, actor, false); -} - -int MWWorld::InventoryStore::remove(const std::string& itemId, int count, const Ptr& actor, bool equipReplacement) -{ - 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, equipReplacement); - - flagAsModified(); - - // number of removed items - return count - toRemove; -} - -int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement) -{ - int retCount = ContainerStore::remove(item, count, actor); + int retCount = ContainerStore::remove(item, count, actor, equipReplacement, resolve); bool wasEquipped = false; if (!item.getRefData().getCount()) @@ -850,8 +827,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; } } @@ -1011,7 +988,7 @@ void MWWorld::InventoryStore::writeState(ESM::InventoryState &state) const std::vector > params; for (std::vector::const_iterator pIt = it->second.begin(); pIt != it->second.end(); ++pIt) { - params.push_back(std::make_pair(pIt->mRandom, pIt->mMultiplier)); + params.emplace_back(pIt->mRandom, pIt->mMultiplier); } state.mPermanentMagicEffectMagnitudes[it->first] = params; diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 97ca931e7..e70c21480 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, 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). /// @@ -162,14 +162,11 @@ 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); - virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement); + using ContainerStore::remove; + int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true) override; ///< Remove \a count item(s) designated by \a item from this inventory. /// /// @return the number of items actually removed @@ -209,12 +206,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/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp index a727b4b3a..42914d4ac 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) @@ -101,7 +101,7 @@ void MWWorld::LocalScripts::add (const std::string& scriptName, const Ptr& ptr) break; } - mScripts.push_back (std::make_pair (scriptName, ptr)); + mScripts.emplace_back (scriptName, ptr); } catch (const std::exception& exception) { diff --git a/apps/openmw/mwworld/manualref.cpp b/apps/openmw/mwworld/manualref.cpp index 48270d224..7f7fd6033 100644 --- a/apps/openmw/mwworld/manualref.cpp +++ b/apps/openmw/mwworld/manualref.cpp @@ -26,7 +26,7 @@ namespace MWWorld::LiveCellRef ref(cellRef, base); refValue = ref; - ptrValue = MWWorld::Ptr(&boost::any_cast&>(refValue), 0); + ptrValue = MWWorld::Ptr(&boost::any_cast&>(refValue), nullptr); } } 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/player.cpp b/apps/openmw/mwworld/player.cpp index 2b157f18a..d8e2fb2f0 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -29,7 +29,7 @@ namespace MWWorld { Player::Player (const ESM::NPC *player) - : mCellStore(0), + : mCellStore(nullptr), mLastKnownExteriorPosition(0,0,0), mMarkedPosition(ESM::Position()), mMarkedCell(nullptr), @@ -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(); @@ -298,9 +299,9 @@ namespace MWWorld void Player::clear() { - mCellStore = 0; + mCellStore = nullptr; mSign.clear(); - mMarkedCell = 0; + mMarkedCell = nullptr; mAutoMove = false; mForwardBackward = 0; mTeleported = false; @@ -447,7 +448,7 @@ namespace MWWorld } else { - mMarkedCell = 0; + mMarkedCell = nullptr; } mForwardBackward = 0; diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index cc906e932..39cdc3e72 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -81,7 +82,7 @@ namespace continue; if (magicEffect->mBolt.empty()) - projectileIDs.push_back("VFX_DefaultBolt"); + projectileIDs.emplace_back("VFX_DefaultBolt"); else projectileIDs.push_back(magicEffect->mBolt); @@ -166,7 +167,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); @@ -442,6 +443,7 @@ namespace MWWorld cast.mSourceName = it->mSourceName; cast.mStack = false; cast.inflict(result.mHitObject, caster, it->mEffects, ESM::RT_Target, false, true); + mPhysics->reportCollision(Misc::Convert::toBullet(result.mHitPos), Misc::Convert::toBullet(result.mHitNormal)); } } @@ -522,6 +524,7 @@ namespace MWWorld caster = result.mHitObject; MWMechanics::projectileHit(caster, result.mHitObject, bow, projectileRef.getPtr(), result.mHit ? result.mHitPos : newPos, it->mAttackStrength); + mPhysics->reportCollision(Misc::Convert::toBullet(result.mHitPos), Misc::Convert::toBullet(result.mHitNormal)); if (underwater) mRendering->emitWaterRipple(newPos); diff --git a/apps/openmw/mwworld/ptr.cpp b/apps/openmw/mwworld/ptr.cpp index 12c44b0b3..e16a19629 100644 --- a/apps/openmw/mwworld/ptr.cpp +++ b/apps/openmw/mwworld/ptr.cpp @@ -8,7 +8,7 @@ const std::string& MWWorld::Ptr::getTypeName() const { - if(mRef != 0) + if(mRef != nullptr) return mRef->mClass->getTypeName(); throw std::runtime_error("Can't get type name from an empty object."); } @@ -57,7 +57,7 @@ MWWorld::Ptr::operator const void *() const std::string &MWWorld::ConstPtr::getTypeName() const { - if(mRef != 0) + if(mRef != nullptr) return mRef->mClass->getTypeName(); throw std::runtime_error("Can't get type name from an empty object."); } diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index d7c170e45..9ab18d7f4 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -25,21 +25,21 @@ namespace MWWorld ContainerStore *mContainerStore; public: - Ptr(MWWorld::LiveCellRefBase *liveCellRef=0, CellStore *cell=0) - : mRef(liveCellRef), mCell(cell), mContainerStore(0) + Ptr(MWWorld::LiveCellRefBase *liveCellRef=nullptr, CellStore *cell=nullptr) + : mRef(liveCellRef), mCell(cell), mContainerStore(nullptr) { } bool isEmpty() const { - return mRef == 0; + return mRef == nullptr; } const std::string& getTypeName() const; const Class& getClass() const { - if(mRef != 0) + if(mRef != nullptr) return *(mRef->mClass); throw std::runtime_error("Cannot get class of an empty object"); } @@ -52,7 +52,7 @@ namespace MWWorld std::stringstream str; str<< "Bad LiveCellRef cast to "<mClass); throw std::runtime_error("Cannot get class of an empty object"); } @@ -128,7 +128,7 @@ namespace MWWorld std::stringstream str; str<< "Bad LiveCellRef cast to "<clone() : 0; + mCustomData = refData.mCustomData ? refData.mCustomData->clone() : nullptr; } void RefData::cleanup() { - mBaseNode = 0; + mBaseNode = nullptr; delete mCustomData; - mCustomData = 0; + mCustomData = nullptr; } RefData::RefData() - : mBaseNode(0), mDeletedByContentFile(false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false), mFlags(0) + : mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mCount (1), mCustomData (nullptr), mChanged(false), mFlags(0) { for (int i=0; i<3; ++i) { @@ -56,20 +56,20 @@ namespace MWWorld } RefData::RefData (const ESM::CellRef& cellRef) - : mBaseNode(0), mDeletedByContentFile(false), mEnabled (true), + : mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mCount (1), mPosition (cellRef.mPos), - mCustomData (0), + mCustomData (nullptr), mChanged(false), mFlags(0) // Loading from ESM/ESP files -> assume unchanged { } RefData::RefData (const ESM::ObjectState& objectState, bool deletedByContentFile) - : mBaseNode(0), mDeletedByContentFile(deletedByContentFile), + : mBaseNode(nullptr), mDeletedByContentFile(deletedByContentFile), mEnabled (objectState.mEnabled != 0), mCount (objectState.mCount), mPosition (objectState.mPosition), mAnimationState(objectState.mAnimationState), - mCustomData (0), + mCustomData (nullptr), mChanged(true), mFlags(objectState.mFlags) // Loading from a savegame -> assume changed { // "Note that the ActivationFlag_UseEnabled is saved to the reference, @@ -79,7 +79,7 @@ namespace MWWorld } RefData::RefData (const RefData& refData) - : mBaseNode(0), mCustomData (0) + : mBaseNode(nullptr), mCustomData (nullptr) { try { @@ -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/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 64316789f..47b62862f 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() ); } } @@ -397,7 +397,7 @@ namespace MWWorld if (!test && cell->getCell()->isExterior()) { osg::ref_ptr land = mRendering.getLandManager()->getLand(cellX, cellY); - const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : 0; + const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr; if (data) { mPhysics->addHeightField (data->mHeights, cellX, cellY, worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get()); @@ -563,7 +563,7 @@ namespace MWWorld if (iter==mActiveCells.end()) { refsToLoad += MWBase::Environment::get().getWorld()->getExterior(x, y)->count(); - cellsPositionsToLoad.push_back(std::make_pair(x, y)); + cellsPositionsToLoad.emplace_back(x, y); } } } @@ -755,7 +755,7 @@ namespace MWWorld Scene::Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics, DetourNavigator::Navigator& navigator) - : mCurrentCell (0), mCellChanged (false), mPhysics(physics), mRendering(rendering), mNavigator(navigator) + : mCurrentCell (nullptr), mCellChanged (false), mPhysics(physics), mRendering(rendering), mNavigator(navigator) , mCellLoadingThreshold(1024.f) , mPreloadDistance(Settings::Manager::getInt("preload distance", "Cells")) , mPreloadEnabled(Settings::Manager::getBool("preload enabled", "Cells")) @@ -961,7 +961,7 @@ namespace MWWorld { } - virtual void doWork() + void doWork() override { try { @@ -1027,7 +1027,7 @@ namespace MWWorld { continue; } - teleportDoors.push_back(MWWorld::ConstPtr(&door, cellStore)); + teleportDoors.emplace_back(&door, cellStore); } } diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 4c4417587..69ca1f8c2 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -101,7 +101,7 @@ namespace MWWorld const T *IndexedStore::find(int index) const { const T *ptr = search(index); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = T::getRecordType() + " with index " + std::to_string(index) + " not found"; throw std::runtime_error(msg); @@ -146,7 +146,7 @@ namespace MWWorld if (it != mStatic.end()) return &(it->second); - return 0; + return nullptr; } template const T *Store::searchStatic(const std::string &id) const @@ -156,7 +156,7 @@ namespace MWWorld if (it != mStatic.end()) return &(it->second); - return 0; + return nullptr; } template @@ -178,7 +178,7 @@ namespace MWWorld const T *Store::find(const std::string &id) const { const T *ptr = search(id); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = T::getRecordType() + " '" + id + "' not found"; throw std::runtime_error(msg); @@ -189,7 +189,7 @@ namespace MWWorld const T *Store::findRandom(const std::string &id) const { const T *ptr = searchRandom(id); - if(ptr == 0) + if(ptr == nullptr) { const std::string msg = T::getRecordType() + " starting with '" + id + "' not found"; throw std::runtime_error(msg); @@ -352,7 +352,7 @@ namespace MWWorld //========================================================================= Store::Store() { - mStatic.push_back(LandTextureList()); + mStatic.emplace_back(); LandTextureList <exl = mStatic[0]; // More than enough to hold Morrowind.esm. Extra lists for plugins will we // added on-the-fly in a different method. @@ -370,7 +370,7 @@ namespace MWWorld const ESM::LandTexture *Store::find(size_t index, size_t plugin) const { const ESM::LandTexture *ptr = search(index, plugin); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = "Land texture with index " + std::to_string(index) + " not found"; throw std::runtime_error(msg); @@ -471,12 +471,12 @@ namespace MWWorld if (it != mStatic.end() && (*it)->mX == x && (*it)->mY == y) { return *it; } - return 0; + return nullptr; } const ESM::Land *Store::find(int x, int y) const { const ESM::Land *ptr = search(x, y); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = "Land at (" + std::to_string(x) + ", " + std::to_string(y) + ") not found"; throw std::runtime_error(msg); @@ -570,7 +570,7 @@ namespace MWWorld return &dit->second; } - return 0; + return nullptr; } const ESM::Cell *Store::search(int x, int y) const { @@ -588,7 +588,7 @@ namespace MWWorld return &dit->second; } - return 0; + return nullptr; } const ESM::Cell *Store::searchStatic(int x, int y) const { @@ -600,7 +600,7 @@ namespace MWWorld if (it != mExt.end()) { return &(it->second); } - return 0; + return nullptr; } const ESM::Cell *Store::searchOrCreate(int x, int y) { @@ -628,7 +628,7 @@ namespace MWWorld const ESM::Cell *Store::find(const std::string &id) const { const ESM::Cell *ptr = search(id); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = "Cell '" + id + "' not found"; throw std::runtime_error(msg); @@ -638,7 +638,7 @@ namespace MWWorld const ESM::Cell *Store::find(int x, int y) const { const ESM::Cell *ptr = search(x, y); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = "Exterior at (" + std::to_string(x) + ", " + std::to_string(y) + ") not found"; throw std::runtime_error(msg); @@ -781,7 +781,7 @@ namespace MWWorld { if (Misc::StringUtils::ciEqual(sharedCell->mName, id)) { - if (cell == 0 || + if (cell == nullptr || (sharedCell->mData.mX > cell->mData.mX) || (sharedCell->mData.mX == cell->mData.mX && sharedCell->mData.mY > cell->mData.mY)) { @@ -831,7 +831,7 @@ namespace MWWorld } ESM::Cell *Store::insert(const ESM::Cell &cell) { - if (search(cell) != 0) + if (search(cell) != nullptr) { const std::string cellType = (cell.isExterior()) ? "exterior" : "interior"; throw std::runtime_error("Failed to create " + cellType + " cell"); @@ -1032,7 +1032,7 @@ namespace MWWorld const ESM::Attribute *Store::search(size_t index) const { if (index >= mStatic.size()) { - return 0; + return nullptr; } return &mStatic.at(index); } @@ -1040,7 +1040,7 @@ namespace MWWorld const ESM::Attribute *Store::find(size_t index) const { const ESM::Attribute *ptr = search(index); - if (ptr == 0) + if (ptr == nullptr) { const std::string msg = "Attribute with index " + std::to_string(index) + " not found"; throw std::runtime_error(msg); diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index f119fa928..cb9f4f1e0 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(nullptr, 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/weather.cpp b/apps/openmw/mwworld/weather.cpp index 2f054488b..6a4a227a4 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -370,7 +370,7 @@ MWRender::MoonState MoonModel::calculateState(const TimeStamp& gameTime) const { rotationFromHorizon, mAxisOffset, // Reverse engineered from Morrowind's scene graph rotation matrices. - static_cast(phase(gameTime)), + phase(gameTime), shadowBlend(rotationFromHorizon), earlyMoonShadowAlpha(rotationFromHorizon) * hourlyAlpha(gameTime.getHour()) }; @@ -439,17 +439,15 @@ inline float MoonModel::rotation(float hours) const return 15.0f * mSpeed * hours; } -inline unsigned int MoonModel::phase(const TimeStamp& gameTime) const +MWRender::MoonState::Phase MoonModel::phase(const TimeStamp& gameTime) const { // Morrowind starts with a full moon on 16 Last Seed and then begins to wane 17 Last Seed, working on 3 day phase cycle. - // Note: this is an internal helper, and as such we don't want to return MWRender::MoonState::Phase since we can't - // forward declare it (C++11 strongly typed enums solve this). // If the moon didn't rise yet today, use yesterday's moon phase. if(gameTime.getHour() < moonRiseHour(gameTime.getDay())) - return (gameTime.getDay() / 3) % 8; + return static_cast((gameTime.getDay() / 3) % 8); else - return ((gameTime.getDay() + 1) / 3) % 8; + return static_cast(((gameTime.getDay() + 1) / 3) % 8); } inline float MoonModel::shadowBlend(float angle) const diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 696f7c688..a3928465c 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -261,7 +261,7 @@ namespace MWWorld float angle(const TimeStamp& gameTime) const; float moonRiseHour(unsigned int daysPassed) const; float rotation(float hours) const; - unsigned int phase(const TimeStamp& gameTime) const; + MWRender::MoonState::Phase phase(const TimeStamp& gameTime) const; float shadowBlend(float angle) const; float hourlyAlpha(float gameHour) const; float earlyMoonShadowAlpha(float angle) const; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 265a7663c..224925dd5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -102,7 +103,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()) @@ -144,7 +145,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), @@ -301,7 +302,7 @@ namespace MWWorld if (mPlayer) { mPlayer->clear(); - mPlayer->setCell(0); + mPlayer->setCell(nullptr); mPlayer->getPlayer().getRefData() = RefData(); mPlayer->set(mStore.get().find ("player")); } @@ -889,6 +890,7 @@ namespace MWWorld { mRendering->notifyWorldSpaceChanged(); mProjectileManager->clear(); + mDiscardMovements = true; } } @@ -932,6 +934,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 +954,7 @@ namespace MWWorld void World::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { mPhysics->clearQueuedMovement(); + mDiscardMovements = true; if (changeEvent && mCurrentWorldSpace != ESM::CellId::sDefaultWorldspace) { @@ -1006,7 +1010,7 @@ namespace MWWorld if (!facedObject.isEmpty() && !facedObject.getClass().allowTelekinesis(facedObject) && mDistanceToFacedObject > getMaxActivationDistance() && !MWBase::Environment::get().getWindowManager()->isGuiMode()) - return 0; + return nullptr; } return facedObject; } @@ -1176,7 +1180,7 @@ namespace MWWorld haveToMove = false; newPtr = currCell->moveTo(ptr, newCell); - newPtr.getRefData().setBaseNode(0); + newPtr.getRefData().setBaseNode(nullptr); } else if (!currCellActive && !newCellActive) newPtr = currCell->moveTo(ptr, newCell); @@ -1259,7 +1263,7 @@ namespace MWWorld mWorldScene->removeFromPagedRefs(ptr); } - if(ptr.getRefData().getBaseNode() != 0) + if(ptr.getRefData().getBaseNode() != nullptr) mWorldScene->updateObjectScale(ptr); if (mPhysics->getActor(ptr)) @@ -1307,7 +1311,7 @@ namespace MWWorld mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr); mWorldScene->removeFromPagedRefs(ptr); - if(ptr.getRefData().getBaseNode() != 0) + if(ptr.getRefData().getBaseNode() != nullptr) { const auto order = flags & MWBase::RotationFlag_inverseOrder ? RotationOrder::inverse : RotationOrder::direct; @@ -1392,7 +1396,7 @@ namespace MWWorld void World::rotateWorldObject (const Ptr& ptr, osg::Quat rotate) { - if(ptr.getRefData().getBaseNode() != 0) + if(ptr.getRefData().getBaseNode() != nullptr) { mRendering->pagingBlacklistObject(mStore.find(ptr.getCellRef().getRefId()), ptr); mWorldScene->removeFromPagedRefs(ptr); @@ -1492,26 +1496,25 @@ namespace MWWorld mPhysics->updateAnimatedCollisionShape(ptr); } - void World::doPhysics(float duration) + void World::doPhysics(float duration, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { - 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, mDiscardMovements, frameStart, frameNumber, stats); + mDiscardMovements = false; + + for(const auto& [actor, position]: 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(actor != getPlayerPtr()) + moveObjectImp(actor, position.x(), position.y(), position.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); } @@ -1539,7 +1542,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 @@ -1576,21 +1579,28 @@ namespace MWWorld float minRot = door.getCellRef().getPosition().rot[2]; float maxRot = minRot + osg::DegreesToRadians(90.f); - float diff = duration * osg::DegreesToRadians(90.f); - float targetRot = std::min(std::max(minRot, oldRot + diff * (state == MWWorld::DoorState::Opening ? 1 : -1)), maxRot); + float diff = duration * osg::DegreesToRadians(90.f) * (state == MWWorld::DoorState::Opening ? 1 : -1); + float targetRot = std::min(std::max(minRot, oldRot + diff), maxRot); rotateObject(door, objPos.rot[0], objPos.rot[1], targetRot, MWBase::RotationFlag_none); bool reached = (targetRot == maxRot && state != MWWorld::DoorState::Idle) || targetRot == minRot; /// \todo should use convexSweepTest here bool collisionWithActor = false; - std::vector collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor); - for (MWWorld::Ptr& ptr : collisions) + for (auto& [ptr, point, normal] : mPhysics->getCollisionsPoints(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor)) { + if (ptr.getClass().isActor()) { + auto localPoint = objPos.asVec3() - point; + osg::Vec3f direction = osg::Quat(diff, osg::Vec3f(0, 0, 1)) * localPoint - localPoint; + direction.normalize(); + mPhysics->reportCollision(Misc::Convert::toBullet(point), Misc::Convert::toBullet(normal)); + if (direction * normal < 0) // door is turning away from actor + continue; + collisionWithActor = true; - + // Collided with actor, ask actor to try to avoid door if(ptr != getPlayerPtr() ) { @@ -1734,6 +1744,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; @@ -1817,11 +1832,11 @@ namespace MWWorld } } - void World::updatePhysics (float duration, bool paused) + void World::updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { if (!paused) { - doPhysics (duration); + doPhysics (duration, frameStart, frameNumber, stats); } } @@ -1863,10 +1878,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))); } @@ -2178,6 +2196,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; @@ -3119,9 +3139,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); @@ -3879,7 +3899,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)); @@ -3904,4 +3924,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 9ba24541d..1fc5ebc20 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; @@ -156,7 +157,7 @@ namespace MWWorld void processDoors(float duration); ///< Run physics simulation and modify \a world accordingly. - void doPhysics(float duration); + void doPhysics(float duration, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); ///< Run physics simulation and modify \a world accordingly. void updateNavigator(); @@ -274,7 +275,7 @@ namespace MWWorld char getGlobalVariableType (const std::string& name) const override; ///< Return ' ', if there is no global variable with this name. - std::string getCellName (const MWWorld::CellStore *cell = 0) const override; + std::string getCellName (const MWWorld::CellStore *cell = nullptr) const override; ///< Return name of the cell. /// /// \note If cell==0, the cell the player is currently in will be used instead to @@ -487,8 +488,12 @@ 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; + void updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) override; void updateWindowManager () override; @@ -732,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; }; } diff --git a/apps/openmw_test_suite/detournavigator/navigator.cpp b/apps/openmw_test_suite/detournavigator/navigator.cpp index 5a92d5d28..ae345d187 100644 --- a/apps/openmw_test_suite/detournavigator/navigator.cpp +++ b/apps/openmw_test_suite/detournavigator/navigator.cpp @@ -8,12 +8,9 @@ #include #include -#include - #include #include -#include #include MATCHER_P3(Vec3fEq, x, y, z, "") 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/apps/openmw_test_suite/misc/test_stringops.cpp b/apps/openmw_test_suite/misc/test_stringops.cpp index 081ca8da6..086908692 100644 --- a/apps/openmw_test_suite/misc/test_stringops.cpp +++ b/apps/openmw_test_suite/misc/test_stringops.cpp @@ -5,14 +5,14 @@ struct PartialBinarySearchTest : public ::testing::Test { protected: std::vector mDataVec; - virtual void SetUp() + void SetUp() override { const char* data[] = { "Head", "Chest", "Tri Head", "Tri Chest", "Bip01", "Tri Bip01" }; mDataVec = std::vector(data, data+sizeof(data)/sizeof(data[0])); std::sort(mDataVec.begin(), mDataVec.end(), Misc::StringUtils::ciLess); } - virtual void TearDown() + void TearDown() override { } diff --git a/apps/openmw_test_suite/mwdialogue/test_keywordsearch.cpp b/apps/openmw_test_suite/mwdialogue/test_keywordsearch.cpp index e0e1871d2..431725be2 100644 --- a/apps/openmw_test_suite/mwdialogue/test_keywordsearch.cpp +++ b/apps/openmw_test_suite/mwdialogue/test_keywordsearch.cpp @@ -4,11 +4,11 @@ struct KeywordSearchTest : public ::testing::Test { protected: - virtual void SetUp() + void SetUp() override { } - virtual void TearDown() + void TearDown() override { } }; diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index 60f60adb3..77aaccfdd 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -22,7 +22,7 @@ struct ContentFileTest : public ::testing::Test { protected: - virtual void SetUp() + void SetUp() override { readContentFiles(); @@ -31,13 +31,13 @@ struct ContentFileTest : public ::testing::Test readerList.resize(mContentFiles.size()); int index=0; - for (std::vector::const_iterator it = mContentFiles.begin(); it != mContentFiles.end(); ++it) + for (const auto & mContentFile : mContentFiles) { ESM::ESMReader lEsm; lEsm.setEncoder(nullptr); lEsm.setIndex(index); lEsm.setGlobalReaderList(&readerList); - lEsm.open(it->string()); + lEsm.open(mContentFile.string()); readerList[index] = lEsm; mEsmStore.load(readerList[index], &dummyListener); @@ -47,7 +47,7 @@ struct ContentFileTest : public ::testing::Test mEsmStore.setUp(); } - virtual void TearDown() + void TearDown() override { } @@ -86,8 +86,8 @@ struct ContentFileTest : public ::testing::Test Files::Collections collections (dataDirs, true); std::vector contentFiles = variables["content"].as >(); - for (std::vector::iterator it = contentFiles.begin(); it != contentFiles.end(); ++it) - mContentFiles.push_back(collections.getPath(*it)); + for (auto & contentFile : contentFiles) + mContentFiles.push_back(collections.getPath(contentFile)); } protected: @@ -111,14 +111,12 @@ TEST_F(ContentFileTest, dialogue_merging_test) stream.open(file); const MWWorld::Store& dialStore = mEsmStore.get(); - for (MWWorld::Store::iterator it = dialStore.begin(); it != dialStore.end(); ++it) + for (const auto & dial : dialStore) { - const ESM::Dialogue& dial = *it; stream << "Dialogue: " << dial.mId << std::endl; - for (ESM::Dialogue::InfoContainer::const_iterator infoIt = dial.mInfo.begin(); infoIt != dial.mInfo.end(); ++infoIt) + for (const auto & info : dial.mInfo) { - const ESM::DialInfo& info = *infoIt; stream << info.mId << std::endl; } stream << std::endl; @@ -229,7 +227,7 @@ template Files::IStreamPtr getEsmFile(T record, bool deleted) { ESM::ESMWriter writer; - std::stringstream* stream = new std::stringstream; + auto* stream = new std::stringstream; writer.setFormat(0); writer.save(*stream); writer.startRecord(T::sRecordId); diff --git a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp index 72dcd3066..7da8f0fd5 100644 --- a/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp +++ b/apps/openmw_test_suite/nifloader/testbulletnifloader.cpp @@ -373,6 +373,7 @@ namespace TEST_F(TestBulletNifLoader, for_zero_num_roots_should_return_default) { EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(0)); + EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); const auto result = mLoader.load(mNifFile); Resource::BulletShape expected; @@ -422,11 +423,13 @@ namespace { mNode.hasBounds = true; mNode.flags |= Nif::NiNode::Flag_BBoxCollision; - mNode.boundXYZ = osg::Vec3f(1, 2, 3); - mNode.boundPos = osg::Vec3f(-1, -2, -3); + mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); + EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); const auto result = mLoader.load(mNifFile); Resource::BulletShape expected; @@ -444,12 +447,14 @@ namespace { mNode.hasBounds = true; mNode.flags |= Nif::NiNode::Flag_BBoxCollision; - mNode.boundXYZ = osg::Vec3f(1, 2, 3); - mNode.boundPos = osg::Vec3f(-1, -2, -3); + mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); mNiNode.children = Nif::NodeList(std::vector({Nif::NodePtr(&mNode)})); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); + EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); const auto result = mLoader.load(mNifFile); Resource::BulletShape expected; @@ -467,16 +472,19 @@ namespace { mNode.hasBounds = true; mNode.flags |= Nif::NiNode::Flag_BBoxCollision; - mNode.boundXYZ = osg::Vec3f(1, 2, 3); - mNode.boundPos = osg::Vec3f(-1, -2, -3); + mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); mNiNode.hasBounds = true; - mNiNode.boundXYZ = osg::Vec3f(4, 5, 6); - mNiNode.boundPos = osg::Vec3f(-4, -5, -6); + mNiNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiNode.bounds.box.extents = osg::Vec3f(4, 5, 6); + mNiNode.bounds.box.center = osg::Vec3f(-4, -5, -6); mNiNode.children = Nif::NodeList(std::vector({Nif::NodePtr(&mNode)})); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); + EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); const auto result = mLoader.load(mNifFile); Resource::BulletShape expected; @@ -494,20 +502,24 @@ namespace { mNode.hasBounds = true; mNode.flags |= Nif::NiNode::Flag_BBoxCollision; - mNode.boundXYZ = osg::Vec3f(1, 2, 3); - mNode.boundPos = osg::Vec3f(-1, -2, -3); + mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); mNode2.hasBounds = true; - mNode2.boundXYZ = osg::Vec3f(4, 5, 6); - mNode2.boundPos = osg::Vec3f(-4, -5, -6); + mNode2.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode2.bounds.box.extents = osg::Vec3f(4, 5, 6); + mNode2.bounds.box.center = osg::Vec3f(-4, -5, -6); mNiNode.hasBounds = true; - mNiNode.boundXYZ = osg::Vec3f(7, 8, 9); - mNiNode.boundPos = osg::Vec3f(-7, -8, -9); + mNiNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiNode.bounds.box.extents = osg::Vec3f(7, 8, 9); + mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9); mNiNode.children = Nif::NodeList(std::vector({Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2)})); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); + EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); const auto result = mLoader.load(mNifFile); Resource::BulletShape expected; @@ -524,21 +536,25 @@ namespace TEST_F(TestBulletNifLoader, for_root_and_two_children_where_both_with_bounds_but_only_second_with_flag_should_use_second_bounds) { mNode.hasBounds = true; - mNode.boundXYZ = osg::Vec3f(1, 2, 3); - mNode.boundPos = osg::Vec3f(-1, -2, -3); + mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); mNode2.hasBounds = true; mNode2.flags |= Nif::NiNode::Flag_BBoxCollision; - mNode2.boundXYZ = osg::Vec3f(4, 5, 6); - mNode2.boundPos = osg::Vec3f(-4, -5, -6); + mNode2.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode2.bounds.box.extents = osg::Vec3f(4, 5, 6); + mNode2.bounds.box.center = osg::Vec3f(-4, -5, -6); mNiNode.hasBounds = true; - mNiNode.boundXYZ = osg::Vec3f(7, 8, 9); - mNiNode.boundPos = osg::Vec3f(-7, -8, -9); + mNiNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiNode.bounds.box.extents = osg::Vec3f(7, 8, 9); + mNiNode.bounds.box.center = osg::Vec3f(-7, -8, -9); mNiNode.children = Nif::NodeList(std::vector({Nif::NodePtr(&mNode), Nif::NodePtr(&mNode2)})); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiNode)); + EXPECT_CALL(mNifFile, getFilename()).WillOnce(Return("test.nif")); const auto result = mLoader.load(mNifFile); Resource::BulletShape expected; @@ -555,8 +571,9 @@ namespace TEST_F(TestBulletNifLoader, for_root_nif_node_with_bounds_but_without_flag_should_return_shape_with_bounds_but_with_null_collision_shape) { mNode.hasBounds = true; - mNode.boundXYZ = osg::Vec3f(1, 2, 3); - mNode.boundPos = osg::Vec3f(-1, -2, -3); + mNode.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNode.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNode.bounds.box.center = osg::Vec3f(-1, -2, -3); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNode)); @@ -588,8 +605,9 @@ namespace TEST_F(TestBulletNifLoader, for_tri_shape_root_node_with_bounds_should_return_shape_with_bounds_but_with_null_collision_shape) { mNiTriShape.hasBounds = true; - mNiTriShape.boundXYZ = osg::Vec3f(1, 2, 3); - mNiTriShape.boundPos = osg::Vec3f(-1, -2, -3); + mNiTriShape.bounds.type = Nif::NiBoundingVolume::Type::BOX_BV; + mNiTriShape.bounds.box.extents = osg::Vec3f(1, 2, 3); + mNiTriShape.bounds.box.center = osg::Vec3f(-1, -2, -3); EXPECT_CALL(mNifFile, numRoots()).WillOnce(Return(1)); EXPECT_CALL(mNifFile, getRoot(0)).WillOnce(Return(&mNiTriShape)); 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..4c221635e 100644 --- a/apps/wizard/mainwizard.hpp +++ b/apps/wizard/mainwizard.hpp @@ -41,7 +41,7 @@ namespace Wizard Page_Conclusion }; - MainWizard(QWidget *parent = 0); + MainWizard(QWidget *parent = nullptr); ~MainWizard(); bool findFiles(const QString &name, const QString &path); @@ -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/apps/wizard/unshield/unshieldworker.hpp b/apps/wizard/unshield/unshieldworker.hpp index 3f922ad78..2553d1bef 100644 --- a/apps/wizard/unshield/unshieldworker.hpp +++ b/apps/wizard/unshield/unshieldworker.hpp @@ -26,7 +26,7 @@ namespace Wizard Q_OBJECT public: - UnshieldWorker(QObject *parent = 0); + UnshieldWorker(QObject *parent = nullptr); ~UnshieldWorker(); void stopWorker(); diff --git a/apps/wizard/utils/componentlistwidget.hpp b/apps/wizard/utils/componentlistwidget.hpp index 23965f8a6..be15ea49f 100644 --- a/apps/wizard/utils/componentlistwidget.hpp +++ b/apps/wizard/utils/componentlistwidget.hpp @@ -10,7 +10,7 @@ class ComponentListWidget : public QListWidget Q_PROPERTY(QStringList mCheckedItems READ checkedItems) public: - ComponentListWidget(QWidget *parent = 0); + ComponentListWidget(QWidget *parent = nullptr); QStringList mCheckedItems; QStringList checkedItems(); 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() diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 05e860239..1833210e4 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -41,7 +41,8 @@ add_component_dir (vfs ) add_component_dir (resource - scenemanager keyframemanager imagemanager bulletshapemanager bulletshape niffilemanager objectcache multiobjectcache resourcesystem resourcemanager stats + scenemanager keyframemanager imagemanager bulletshapemanager bulletshape niffilemanager objectcache multiobjectcache resourcesystem + resourcemanager stats animation ) add_component_dir (shader @@ -51,7 +52,7 @@ add_component_dir (shader add_component_dir (sceneutil clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize optimizer - actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh + actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller ) add_component_dir (nif @@ -86,7 +87,8 @@ add_component_dir (esmterrain ) add_component_dir (misc - gcd constants utf8stream stringops resourcehelpers rng messageformatparser weakcache stereo + gcd constants utf8stream stringops resourcehelpers rng messageformatparser weakcache + constants utf8stream stringops resourcehelpers rng messageformatparser weakcache stereo ) add_component_dir (debug @@ -233,7 +235,7 @@ target_link_libraries(components ${SDL2_LIBRARIES} ${OPENGL_gl_LIBRARY} ${MyGUI_LIBRARIES} - ${BSAOPTHASH_LIBRARIES} + LZ4::LZ4 RecastNavigation::DebugUtils RecastNavigation::Detour RecastNavigation::Recast diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index abeca5326..3fd74dd83 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -150,7 +150,7 @@ void BSAFile::readHeader() /// Get the index of a given file name, or -1 if not found int BSAFile::getIndex(const char *str) const { - Lookup::const_iterator it = mLookup.find(str); + auto it = mLookup.find(str); if(it == mLookup.end()) return -1; diff --git a/components/bsa/bsa_file.hpp b/components/bsa/bsa_file.hpp index d12d01b0c..037802739 100644 --- a/components/bsa/bsa_file.hpp +++ b/components/bsa/bsa_file.hpp @@ -24,7 +24,7 @@ #ifndef BSA_BSA_FILE_H #define BSA_BSA_FILE_H -#include +#include #include #include #include @@ -106,8 +106,7 @@ public: : mIsLoaded(false) { } - virtual ~BSAFile() - { } + virtual ~BSAFile() = default; /// Open an archive file. void open(const std::string &file); diff --git a/components/bsa/compressedbsafile.cpp b/components/bsa/compressedbsafile.cpp index d0bebe3c1..77e477ac5 100644 --- a/components/bsa/compressedbsafile.cpp +++ b/components/bsa/compressedbsafile.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include @@ -34,7 +36,6 @@ #include #include #include -#include #include #include @@ -101,8 +102,7 @@ CompressedBSAFile::CompressedBSAFile() : mCompressedByDefault(false), mEmbeddedFileNames(false) { } -CompressedBSAFile::~CompressedBSAFile() -{ } +CompressedBSAFile::~CompressedBSAFile() = default; /// Read header information from the input source void CompressedBSAFile::readHeader() @@ -132,8 +132,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 +161,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,9 +172,16 @@ 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); + auto lb = mFolders.lower_bound(hash); if (lb != mFolders.end() && !(mFolders.key_comp()(hash, lb->first))) fail("Archive found duplicate folder name hash"); else @@ -181,7 +192,7 @@ void CompressedBSAFile::readHeader() std::uint64_t fileHash; FileRecord file; - std::string folder(""); + std::string folder; std::uint64_t folderHash; if ((archiveFlags & 0x1) == 0) folderCount = 1; // TODO: not tested - unit test necessary @@ -196,7 +207,7 @@ void CompressedBSAFile::readHeader() folderHash = generateHash(folder, std::string()); - std::map::iterator iter = mFolders.find(folderHash); + auto iter = mFolders.find(folderHash); if (iter == mFolders.end()) fail("Archive folder name hash not found"); @@ -206,13 +217,13 @@ void CompressedBSAFile::readHeader() input.read(reinterpret_cast(&file.size), 4); input.read(reinterpret_cast(&file.offset), 4); - std::map::const_iterator lb = iter->second.files.lower_bound(fileHash); + auto lb = iter->second.files.lower_bound(fileHash); if (lb != iter->second.files.end() && !(iter->second.files.key_comp()(fileHash, lb->first))) fail("Archive found duplicate file name hash"); iter->second.files.insert(lb, std::pair(fileHash, file)); - FileStruct fileStruct; + FileStruct fileStruct{}; fileStruct.fileSize = file.getSizeWithoutCompressionFlag(); fileStruct.offset = file.offset; fileStruct.name = nullptr; @@ -295,12 +306,12 @@ CompressedBSAFile::FileRecord CompressedBSAFile::getFileRecord(const std::string std::string folder = p.string(); std::uint64_t folderHash = generateHash(folder, std::string()); - std::map::const_iterator it = mFolders.find(folderHash); + auto it = mFolders.find(folderHash); if (it == mFolders.end()) return FileRecord(); // folder not found, return default which has offset of sInvalidOffset std::uint64_t fileHash = generateHash(stem, ext); - std::map::const_iterator iter = it->second.files.find(fileHash); + auto iter = it->second.files.find(fileHash); if (iter == it->second.files.end()) return FileRecord(); // file not found, return default which has offset of sInvalidOffset @@ -327,32 +338,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_decompressionContext_t 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) @@ -393,12 +428,12 @@ BsaVersion CompressedBSAFile::detectVersion(std::string filePath) //mFiles used by OpenMW expects uncompressed sizes void CompressedBSAFile::convertCompressedSizesToUncompressed() { - for (auto iter = mFiles.begin(); iter != mFiles.end(); ++iter) + for (auto & mFile : mFiles) { - const FileRecord& fileRecord = getFileRecord(iter->name); + const FileRecord& fileRecord = getFileRecord(mFile.name); if (!fileRecord.isValid()) { - fail("Could not find file " + std::string(iter->name) + " in BSA"); + fail("Could not find file " + std::string(mFile.name) + " in BSA"); } if (!fileRecord.isCompressed(mCompressedByDefault)) @@ -415,47 +450,37 @@ void CompressedBSAFile::convertCompressedSizesToUncompressed() getBZString(embeddedFileName, *(dataBegin.get())); } - dataBegin->read(reinterpret_cast(&(iter->fileSize)), sizeof(iter->fileSize)); + dataBegin->read(reinterpret_cast(&(mFile.fileSize)), sizeof(mFile.fileSize)); } } -std::uint64_t CompressedBSAFile::generateHash(std::string stem, std::string extension) const +std::uint64_t CompressedBSAFile::generateHash(std::string stem, std::string extension) { size_t len = stem.length(); if (len == 0) return 0; - std::uint64_t hash = 0; - unsigned int hash2 = 0; + std::replace(stem.begin(), stem.end(), '/', '\\'); Misc::StringUtils::lowerCaseInPlace(stem); - if (extension.empty()) // It's a folder. - std::replace(stem.begin(), stem.end(), '/', '\\'); - else - { - Misc::StringUtils::lowerCaseInPlace(extension); - for (const char &c : extension) - hash = hash * 0x1003f + c; - } + uint64_t result = stem[len-1] | (len >= 3 ? (stem[len-2] << 8) : 0) | (len << 16) | (stem[0] << 24); if (len >= 4) { - for (size_t i = 1; i < len-2; i++) - hash2 = hash2 * 0x1003f + stem[i]; - } - hash = (hash + hash2) << 32; - hash2 = (stem[0] << 24) | (len << 16); - if (len >= 2) - { - if (len >= 3) - hash2 |= stem[len-2] << 8; - hash2 |= stem[len-1]; - } - if (!extension.empty()) - { - if (extension == ".kf") hash2 |= 0x80; - else if (extension == ".nif") hash2 |= 0x8000; - else if (extension == ".dds") hash2 |= 0x8080; - else if (extension == ".wav") hash2 |= 0x80000000; + uint32_t hash = 0; + for (size_t i = 1; i <= len-3; ++i) + hash = hash * 0x1003f + stem[i]; + result += static_cast(hash) << 32; } - return hash + hash2; + if (extension.empty()) + return result; + Misc::StringUtils::lowerCaseInPlace(extension); + if (extension == ".kf") result |= 0x80; + else if (extension == ".nif") result |= 0x8000; + else if (extension == ".dds") result |= 0x8080; + else if (extension == ".wav") result |= 0x80000000; + uint32_t hash = 0; + for (const char &c : extension) + hash = hash * 0x1003f + c; + result += static_cast(hash) << 32; + return result; } } //namespace Bsa diff --git a/components/bsa/compressedbsafile.hpp b/components/bsa/compressedbsafile.hpp index a22d6e149..deddfae38 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; @@ -78,7 +80,7 @@ namespace Bsa //mFiles used by OpenMW will contain uncompressed file sizes void convertCompressedSizesToUncompressed(); /// \brief Normalizes given filename or folder and generates format-compatible hash. See https://en.uesp.net/wiki/Tes4Mod:Hash_Calculation. - std::uint64_t generateHash(std::string stem, std::string extension) const; + static std::uint64_t generateHash(std::string stem, std::string extension) ; Files::IStreamPtr getFile(const FileRecord& fileRecord); public: CompressedBSAFile(); @@ -88,10 +90,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/bsa/memorystream.hpp b/components/bsa/memorystream.hpp index 5dbe16ebe..d168e93d6 100644 --- a/components/bsa/memorystream.hpp +++ b/components/bsa/memorystream.hpp @@ -37,8 +37,8 @@ Class used internally by MemoryInputStream. class MemoryInputStreamBuf : public std::streambuf { public: - MemoryInputStreamBuf(size_t bufferSize); - char* getRawData(); + explicit MemoryInputStreamBuf(size_t bufferSize); + virtual char* getRawData(); private: //correct call to delete [] on C++ 11 std::vector mBufferPtr; @@ -54,8 +54,8 @@ private: */ class MemoryInputStream : virtual MemoryInputStreamBuf, std::istream { public: - MemoryInputStream(size_t bufferSize); - char* getRawData(); + explicit MemoryInputStream(size_t bufferSize); + char* getRawData() override; }; } diff --git a/components/bullethelpers/processtrianglecallback.hpp b/components/bullethelpers/processtrianglecallback.hpp index ee005b459..22ab30b2a 100644 --- a/components/bullethelpers/processtrianglecallback.hpp +++ b/components/bullethelpers/processtrianglecallback.hpp @@ -11,11 +11,11 @@ namespace BulletHelpers class ProcessTriangleCallback : public btTriangleCallback { public: - ProcessTriangleCallback(Impl impl) + explicit ProcessTriangleCallback(Impl impl) : mImpl(std::move(impl)) {} - void processTriangle(btVector3* triangle, int partId, int triangleIndex) override final + void processTriangle(btVector3* triangle, int partId, int triangleIndex) override { return mImpl(triangle, partId, triangleIndex); } diff --git a/components/compiler/context.hpp b/components/compiler/context.hpp index 84bb89bdc..399e8125b 100644 --- a/components/compiler/context.hpp +++ b/components/compiler/context.hpp @@ -13,14 +13,14 @@ namespace Compiler public: - Context() : mExtensions (0) {} + Context() : mExtensions (nullptr) {} - virtual ~Context() {} + virtual ~Context() = default; virtual bool canDeclareLocals() const = 0; ///< Is the compiler allowed to declare local variables? - void setExtensions (const Extensions *extensions = 0) + void setExtensions (const Extensions *extensions = nullptr) { mExtensions = extensions; } diff --git a/components/compiler/controlparser.cpp b/components/compiler/controlparser.cpp index ebadcbbc6..ec69fffa2 100644 --- a/components/compiler/controlparser.cpp +++ b/components/compiler/controlparser.cpp @@ -33,7 +33,7 @@ namespace Compiler // store code for if-cascade Codes codes; - for (IfCodes::reverse_iterator iter (mIfCode.rbegin()); + for (auto iter (mIfCode.rbegin()); iter!=mIfCode.rend(); ++iter) { Codes block; 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/errorhandler.cpp b/components/compiler/errorhandler.cpp index 7f02255db..f02097736 100644 --- a/components/compiler/errorhandler.cpp +++ b/components/compiler/errorhandler.cpp @@ -5,7 +5,7 @@ namespace Compiler ErrorHandler::ErrorHandler() : mWarnings (0), mErrors (0), mWarningsMode (1), mDowngradeErrors (false) {} - ErrorHandler::~ErrorHandler() {} + ErrorHandler::~ErrorHandler() = default; // Was compiling successful? diff --git a/components/compiler/errorhandler.hpp b/components/compiler/errorhandler.hpp index ea904e385..dfd29f273 100644 --- a/components/compiler/errorhandler.hpp +++ b/components/compiler/errorhandler.hpp @@ -83,7 +83,7 @@ namespace Compiler public: - ErrorDowngrade (ErrorHandler& handler); + explicit ErrorDowngrade (ErrorHandler& handler); ~ErrorDowngrade(); }; diff --git a/components/compiler/exception.hpp b/components/compiler/exception.hpp index 33bad7590..3aa8997c7 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 override { 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 override { return "End of file"; } ///< Return error message }; } diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index 8c8fe640e..0afe3de6d 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -21,7 +21,7 @@ namespace Compiler { - int ExprParser::getPriority (char op) const + int ExprParser::getPriority (char op) { switch (op) { @@ -654,28 +654,27 @@ namespace Compiler std::stack > stack; - for (std::string::const_iterator iter (arguments.begin()); iter!=arguments.end(); - ++iter) + for (char argument : arguments) { - if (*iter=='/') + if (argument=='/') { optional = true; } - else if (*iter=='S' || *iter=='c' || *iter=='x') + else if (argument=='S' || argument=='c' || argument=='x') { stringParser.reset(); - if (optional || *iter=='x') + if (optional || argument=='x') stringParser.setOptional (true); - if (*iter=='c') stringParser.smashCase(); - if (*iter=='x') stringParser.discard(); + if (argument=='c') stringParser.smashCase(); + if (argument=='x') stringParser.discard(); scanner.scan (stringParser); - if ((optional || *iter=='x') && stringParser.isEmpty()) + if ((optional || argument=='x') && stringParser.isEmpty()) break; - if (*iter!='x') + if (argument!='x') { std::vector tmp; stringParser.append (tmp); @@ -689,7 +688,7 @@ namespace Compiler getErrorHandler().warning ("Extra argument", stringParser.getTokenLoc()); } - else if (*iter=='X') + else if (argument=='X') { parser.reset(); @@ -702,7 +701,7 @@ namespace Compiler else getErrorHandler().warning("Extra argument", parser.getTokenLoc()); } - else if (*iter=='z') + else if (argument=='z') { discardParser.reset(); discardParser.setOptional (true); @@ -714,7 +713,7 @@ namespace Compiler else getErrorHandler().warning("Extra argument", discardParser.getTokenLoc()); } - else if (*iter=='j') + else if (argument=='j') { /// \todo disable this when operating in strict mode junkParser.reset(); @@ -737,8 +736,8 @@ namespace Compiler char type = parser.append (tmp); - if (type!=*iter) - Generator::convert (tmp, type, *iter); + if (type!=argument) + Generator::convert (tmp, type, argument); stack.push (tmp); diff --git a/components/compiler/exprparser.hpp b/components/compiler/exprparser.hpp index dd8259ee1..2f3eaa8a9 100644 --- a/components/compiler/exprparser.hpp +++ b/components/compiler/exprparser.hpp @@ -28,7 +28,7 @@ namespace Compiler bool mRefOp; bool mMemberOp; - int getPriority (char op) const; + static int getPriority (char op) ; char getOperandType (int Index = 0) const; @@ -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/extensions.cpp b/components/compiler/extensions.cpp index dbb953e20..9646d54a7 100644 --- a/components/compiler/extensions.cpp +++ b/components/compiler/extensions.cpp @@ -12,8 +12,7 @@ namespace Compiler int Extensions::searchKeyword (const std::string& keyword) const { - std::map::const_iterator iter = mKeywords.find (keyword); - + auto iter = mKeywords.find (keyword); if (iter==mKeywords.end()) return 0; @@ -23,8 +22,7 @@ namespace Compiler bool Extensions::isFunction (int keyword, ScriptReturn& returnType, ScriptArgs& argumentType, bool& explicitReference) const { - std::map::const_iterator iter = mFunctions.find (keyword); - + auto iter = mFunctions.find (keyword); if (iter==mFunctions.end()) return false; @@ -39,8 +37,7 @@ namespace Compiler bool Extensions::isInstruction (int keyword, ScriptArgs& argumentType, bool& explicitReference) const { - std::map::const_iterator iter = mInstructions.find (keyword); - + auto iter = mInstructions.find (keyword); if (iter==mInstructions.end()) return false; @@ -115,8 +112,7 @@ namespace Compiler { assert (optionalArguments>=0); - std::map::const_iterator iter = mFunctions.find (keyword); - + auto iter = mFunctions.find (keyword); if (iter==mFunctions.end()) throw std::logic_error ("unknown custom function keyword"); @@ -164,8 +160,7 @@ namespace Compiler { assert (optionalArguments>=0); - std::map::const_iterator iter = mInstructions.find (keyword); - + auto iter = mInstructions.find (keyword); if (iter==mInstructions.end()) throw std::logic_error ("unknown custom instruction keyword"); @@ -209,8 +204,7 @@ namespace Compiler void Extensions::listKeywords (std::vector& keywords) const { - for (std::map::const_iterator iter (mKeywords.begin()); - iter!=mKeywords.end(); ++iter) - keywords.push_back (iter->first); + for (const auto & mKeyword : mKeywords) + keywords.push_back (mKeyword.first); } } 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/generator.cpp b/components/compiler/generator.cpp index 2787488c2..34da1c412 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -283,9 +283,7 @@ namespace } } -namespace Compiler -{ - namespace Generator +namespace Compiler::Generator { void pushInt (CodeContainer& code, Literals& literals, int value) { @@ -732,4 +730,3 @@ namespace Compiler } } } -} 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.cpp b/components/compiler/lineparser.cpp index 829ad6f08..77afaee8b 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -260,7 +260,7 @@ namespace Compiler /// \todo add option to disable this std::unique_ptr errorDowngrade (nullptr); if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell") - errorDowngrade.reset (new ErrorDowngrade (getErrorHandler())); + errorDowngrade = std::make_unique (getErrorHandler()); std::vector code; int optionals = mExprParser.parseArguments (argumentType, scanner, code, keyword); 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/literals.cpp b/components/compiler/literals.cpp index ee2c4d345..774ca4ca7 100644 --- a/components/compiler/literals.cpp +++ b/components/compiler/literals.cpp @@ -30,13 +30,11 @@ namespace Compiler void Literals::append (std::vector& code) const { - for (std::vector::const_iterator iter (mIntegers.begin()); - iter!=mIntegers.end(); ++iter) - code.push_back (*reinterpret_cast (&*iter)); + for (const int & mInteger : mIntegers) + code.push_back (*reinterpret_cast (&mInteger)); - for (std::vector::const_iterator iter (mFloats.begin()); - iter!=mFloats.end(); ++iter) - code.push_back (*reinterpret_cast (&*iter)); + for (const float & mFloat : mFloats) + code.push_back (*reinterpret_cast (&mFloat)); int stringBlockSize = getStringSize(); int size = static_cast (code.size()); @@ -45,12 +43,11 @@ namespace Compiler int offset = 0; - for (std::vector::const_iterator iter (mStrings.begin()); - iter!=mStrings.end(); ++iter) + for (const auto & mString : mStrings) { - int stringSize = iter->size()+1; + int stringSize = mString.size()+1; - std::copy (iter->c_str(), iter->c_str()+stringSize, + std::copy (mString.c_str(), mString.c_str()+stringSize, reinterpret_cast (&code[size]) + offset); offset += stringSize; } diff --git a/components/compiler/locals.cpp b/components/compiler/locals.cpp index a7102c38d..9b233b8f5 100644 --- a/components/compiler/locals.cpp +++ b/components/compiler/locals.cpp @@ -25,8 +25,7 @@ namespace Compiler { const std::vector& collection = get (type); - std::vector::const_iterator iter = - std::find (collection.begin(), collection.end(), name); + auto iter = std::find (collection.begin(), collection.end(), name); if (iter==collection.end()) return -1; 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/opcodes.cpp b/components/compiler/opcodes.cpp index 03081dff9..9e2356d0e 100644 --- a/components/compiler/opcodes.cpp +++ b/components/compiler/opcodes.cpp @@ -1,8 +1,6 @@ #include "opcodes.hpp" -namespace Compiler -{ - namespace Control +namespace Compiler::Control { const char *controls[numberOfControls] = { @@ -10,4 +8,3 @@ namespace Compiler "playerviewswitch", "vanitymode" }; } -} diff --git a/components/compiler/parser.cpp b/components/compiler/parser.cpp index 62265d8a1..ffa393a29 100644 --- a/components/compiler/parser.cpp +++ b/components/compiler/parser.cpp @@ -58,7 +58,7 @@ namespace Compiler // destructor - Parser::~Parser() {} + Parser::~Parser() = default; // Handle an int token. // \return fetch another token? 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/scanner.cpp b/components/compiler/scanner.cpp index 9f2865868..573c8cc93 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -1,7 +1,6 @@ #include "scanner.hpp" #include -#include #include "exception.hpp" #include "errorhandler.hpp" @@ -266,7 +265,7 @@ namespace Compiler "messagebox", "set", "to", "getsquareroot", - 0 + nullptr }; bool Scanner::scanName (MultiChar& c, Parser& parser, bool& cont) @@ -638,7 +637,7 @@ namespace Compiler void Scanner::listKeywords (std::vector& keywords) { for (int i=0; Compiler::sKeywords[i]; ++i) - keywords.push_back (Compiler::sKeywords[i]); + keywords.emplace_back(Compiler::sKeywords[i]); if (mExtensions) mExtensions->listKeywords (keywords); diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index b6321a92d..2139f04b2 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -28,7 +28,7 @@ namespace Compiler blank(); } - MultiChar(const char ch) + explicit MultiChar(const char ch) { blank(); mData[0] = ch; @@ -36,7 +36,7 @@ namespace Compiler mLength = getCharLength(ch); } - int getCharLength(const char ch) + static int getCharLength(const char ch) { unsigned char c = ch; if (c<=127) return 0; @@ -170,8 +170,8 @@ namespace Compiler } private: - char mData[4]; - int mLength; + char mData[4]{}; + int mLength{}; }; class Scanner @@ -251,7 +251,7 @@ namespace Compiler public: Scanner (ErrorHandler& errorHandler, std::istream& inputStream, - const Extensions *extensions = 0); + const Extensions *extensions = nullptr); ///< constructor void scan (Parser& parser); diff --git a/components/compiler/scriptparser.hpp b/components/compiler/scriptparser.hpp index edabb9c5c..0433a23a3 100644 --- a/components/compiler/scriptparser.hpp +++ b/components/compiler/scriptparser.hpp @@ -1,7 +1,6 @@ #ifndef COMPILER_SCRIPTPARSER_H_INCLUDED #define COMPILER_SCRIPTPARSER_H_INCLUDED - #include "parser.hpp" #include "lineparser.hpp" #include "controlparser.hpp" @@ -29,23 +28,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.cpp b/components/compiler/streamerrorhandler.cpp index 1c41d3f7f..030d02d1d 100644 --- a/components/compiler/streamerrorhandler.cpp +++ b/components/compiler/streamerrorhandler.cpp @@ -61,7 +61,7 @@ namespace Compiler mContext = context; } - StreamErrorHandler::StreamErrorHandler() {} + StreamErrorHandler::StreamErrorHandler() = default; ContextOverride::ContextOverride(StreamErrorHandler& handler, const std::string& context) : mHandler(handler), mContext(handler.mContext) { 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/compiler/tokenloc.hpp b/components/compiler/tokenloc.hpp index 62b5cdee5..ff715c5e9 100644 --- a/components/compiler/tokenloc.hpp +++ b/components/compiler/tokenloc.hpp @@ -13,7 +13,7 @@ namespace Compiler int mLine; std::string mLiteral; - TokenLoc() : mColumn (0), mLine (0), mLiteral ("") {} + TokenLoc() : mColumn (0), mLine (0), mLiteral () {} }; } diff --git a/components/config/gamesettings.cpp b/components/config/gamesettings.cpp index b771b7fc8..85c090a3f 100644 --- a/components/config/gamesettings.cpp +++ b/components/config/gamesettings.cpp @@ -7,24 +7,6 @@ #include -#include - -/** - * Workaround for problems with whitespaces in paths in older versions of Boost library - */ -#if (BOOST_VERSION <= 104600) -namespace boost -{ - - template<> - inline boost::filesystem::path lexical_cast(const std::string& arg) - { - return boost::filesystem::path(arg); - } - -} /* namespace boost */ -#endif /* (BOOST_VERSION <= 104600) */ - const char Config::GameSettings::sContentKey[] = "content"; Config::GameSettings::GameSettings(Files::ConfigurationManager &cfg) @@ -32,9 +14,7 @@ Config::GameSettings::GameSettings(Files::ConfigurationManager &cfg) { } -Config::GameSettings::~GameSettings() -{ -} +Config::GameSettings::~GameSettings() = default; void Config::GameSettings::validatePaths() { @@ -51,8 +31,8 @@ void Config::GameSettings::validatePaths() mCfgMgr.processPaths(dataDirs); mDataDirs.clear(); - for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) { - QString path = QString::fromUtf8(it->string().c_str()); + for (auto & dataDir : dataDirs) { + QString path = QString::fromUtf8(dataDir.string().c_str()); QDir dir(path); if (dir.exists()) @@ -118,12 +98,19 @@ bool Config::GameSettings::readFile(QTextStream &stream, QMultiMap comments; - std::vector::iterator commentStart = fileCopy.end(); + auto commentStart = fileCopy.end(); std::map > commentsMap; - for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) + for (auto iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) { if (isOrderedLine(*iter)) { @@ -339,9 +315,9 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) if (commentStart == fileCopy.end()) throw std::runtime_error("Config::GameSettings: failed to parse settings - iterator is past of end of settings file"); - for (std::vector::const_iterator it = comments.begin(); it != comments.end(); ++it) + for (const auto & comment : comments) { - *commentStart = *it; + *commentStart = comment; ++commentStart; } comments.clear(); @@ -383,16 +359,16 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) } // comments at top of file - for (std::vector::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter) + for (auto & iter : fileCopy) { - if ((*iter).isNull()) + if (iter.isNull()) continue; // Below is based on readFile() code, if that changes corresponding change may be // required (for example duplicates may be inserted if the rules don't match) - if (/*(*iter).isEmpty() ||*/ (*iter).contains(QRegExp("^\\s*#"))) + if (/*(*iter).isEmpty() ||*/ iter.contains(QRegExp("^\\s*#"))) { - stream << *iter << "\n"; + stream << iter << "\n"; continue; } } @@ -406,7 +382,10 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) { it.previous(); - if (it.key() == QLatin1String("data")) + if (it.key() == QLatin1String("data") + || it.key() == QLatin1String("data-local") + || it.key() == QLatin1String("resources") + || it.key() == QLatin1String("load-savegame")) { settingLine = it.key() + "="; @@ -416,30 +395,20 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) QString string = it.value(); settingLine += delim; - for (QString::const_iterator iter = string.begin(); iter != string.end(); ++iter) + for (auto iter : string) { - if (*iter == delim || *iter == escape) + if (iter == delim || iter == escape) settingLine += escape; - settingLine += *iter; + settingLine += iter; } settingLine += delim; } - // Quote paths with spaces - else if ((it.key() == QLatin1String("data-local") - || it.key() == QLatin1String("resources")) && it.value().contains(QChar(' '))) - { - QString stripped = it.value(); - stripped.remove(QChar('\"')); // Remove quotes - - settingLine = it.key() + "=\"" + stripped + "\""; - } else settingLine = it.key() + "=" + it.value(); if (settingRegex.indexIn(settingLine) != -1) { - std::map >::iterator i = - commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2)); + auto i = commentsMap.find(settingRegex.cap(1)+"="+settingRegex.cap(2)); // check if previous removed content item with comments if (i == commentsMap.end()) @@ -448,8 +417,8 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) if (i != commentsMap.end()) { std::vector cLines = i->second; - for (std::vector::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci) - stream << *ci << "\n"; + for (const auto & cLine : cLines) + stream << cLine << "\n"; commentsMap.erase(i); } @@ -461,14 +430,14 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) // flush any removed settings if (!commentsMap.empty()) { - std::map >::const_iterator i = commentsMap.begin(); + auto i = commentsMap.begin(); for (; i != commentsMap.end(); ++i) { if (i->first.contains(QRegExp("^\\s*content\\s*="))) { std::vector cLines = i->second; - for (std::vector::const_iterator ci = cLines.begin(); ci != cLines.end(); ++ci) - stream << *ci << "\n"; + for (const auto & cLine : cLines) + stream << cLine << "\n"; // mark the content line entry for future preocessing stream << "##" << i->first << "\n"; @@ -481,8 +450,8 @@ bool Config::GameSettings::writeFileWithComments(QFile &file) // flush any end comments if (!comments.empty()) { - for (std::vector::const_iterator ci = comments.begin(); ci != comments.end(); ++ci) - stream << *ci << "\n"; + for (const auto & comment : comments) + stream << comment << "\n"; } file.resize(file.pos()); diff --git a/components/config/gamesettings.hpp b/components/config/gamesettings.hpp index a6876b83d..ccb1d5fd2 100644 --- a/components/config/gamesettings.hpp +++ b/components/config/gamesettings.hpp @@ -88,7 +88,7 @@ namespace Config static const char sContentKey[]; - bool isOrderedLine(const QString& line) const; + static bool isOrderedLine(const QString& line) ; }; } #endif // GAMESETTINGS_HPP diff --git a/components/config/launchersettings.cpp b/components/config/launchersettings.cpp index ae591ef58..ff2c38438 100644 --- a/components/config/launchersettings.cpp +++ b/components/config/launchersettings.cpp @@ -12,13 +12,9 @@ const char Config::LauncherSettings::sLauncherConfigFileName[] = "launcher.cfg"; const char Config::LauncherSettings::sContentListsSectionPrefix[] = "Profiles/"; const char Config::LauncherSettings::sContentListSuffix[] = "/content"; -Config::LauncherSettings::LauncherSettings() -{ -} +Config::LauncherSettings::LauncherSettings() = default; -Config::LauncherSettings::~LauncherSettings() -{ -} +Config::LauncherSettings::~LauncherSettings() = default; QStringList Config::LauncherSettings::subKeys(const QString &key) { diff --git a/components/config/settingsbase.hpp b/components/config/settingsbase.hpp index 119971716..86fa962ae 100644 --- a/components/config/settingsbase.hpp +++ b/components/config/settingsbase.hpp @@ -15,7 +15,7 @@ namespace Config public: SettingsBase() { mMultiValue = false; } - ~SettingsBase() {} + ~SettingsBase() = default; inline QString value(const QString &key, const QString &defaultValue = QString()) const { diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 86208d7af..e51c1809a 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -53,7 +53,7 @@ const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(in if (row >= 0 && row < mFiles.size()) return mFiles.at(row); - return 0; + return nullptr; } ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) @@ -61,7 +61,7 @@ ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(int row) if (row >= 0 && row < mFiles.count()) return mFiles.at(row); - return 0; + return nullptr; } const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(const QString &name) const { @@ -75,7 +75,7 @@ const ContentSelectorModel::EsmFile *ContentSelectorModel::ContentModel::item(co if (name.compare(file->fileProperty (fp).toString(), Qt::CaseInsensitive) == 0) return file; } - return 0; + return nullptr; } QModelIndex ContentSelectorModel::ContentModel::indexFromItem(const EsmFile *item) const 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/esmfile.hpp b/components/contentselector/model/esmfile.hpp index 614eee298..66863d7c6 100644 --- a/components/contentselector/model/esmfile.hpp +++ b/components/contentselector/model/esmfile.hpp @@ -28,7 +28,7 @@ namespace ContentSelectorModel FileProperty_GameFile = 6 }; - EsmFile(QString fileName = QString(), ModelItem *parent = 0); + EsmFile(QString fileName = QString(), ModelItem *parent = nullptr); // EsmFile(const EsmFile &); ~EsmFile() diff --git a/components/contentselector/model/modelitem.hpp b/components/contentselector/model/modelitem.hpp index 57214b09c..a860b1891 100644 --- a/components/contentselector/model/modelitem.hpp +++ b/components/contentselector/model/modelitem.hpp @@ -11,7 +11,7 @@ namespace ContentSelectorModel Q_OBJECT public: - ModelItem(ModelItem *parent = 0); + ModelItem(ModelItem *parent = nullptr); //ModelItem(const ModelItem *parent = 0); ~ModelItem(); @@ -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.cpp b/components/contentselector/view/combobox.cpp index 1ef9f9bd7..742e236b3 100644 --- a/components/contentselector/view/combobox.cpp +++ b/components/contentselector/view/combobox.cpp @@ -9,7 +9,7 @@ ContentSelectorView::ComboBox::ComboBox(QWidget *parent) : mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore setValidator(mValidator); setEditable(true); - setCompleter(0); + setCompleter(nullptr); setEnabled (true); setInsertPolicy(QComboBox::NoInsert); diff --git a/components/contentselector/view/combobox.hpp b/components/contentselector/view/combobox.hpp index e3888af2c..9af3c83af 100644 --- a/components/contentselector/view/combobox.hpp +++ b/components/contentselector/view/combobox.hpp @@ -14,7 +14,7 @@ namespace ContentSelectorView Q_OBJECT public: - explicit ComboBox (QWidget *parent = 0); + explicit ComboBox (QWidget *parent = nullptr); void setPlaceholderText(const QString &text); @@ -22,7 +22,7 @@ namespace ContentSelectorView QString mPlaceholderText; protected: - void paintEvent(QPaintEvent *); + void paintEvent(QPaintEvent *) override; QRegExpValidator *mValidator; }; } diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index f1058d510..1b50f1e5e 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -23,7 +23,7 @@ namespace ContentSelectorView public: - explicit ContentSelector(QWidget *parent = 0); + explicit ContentSelector(QWidget *parent = nullptr); QString currentFile() const; diff --git a/components/crashcatcher/crashcatcher.cpp b/components/crashcatcher/crashcatcher.cpp index 99df2cfd8..4ad856548 100644 --- a/components/crashcatcher/crashcatcher.cpp +++ b/components/crashcatcher/crashcatcher.cpp @@ -143,8 +143,14 @@ static void gdb_info(pid_t pid) FILE *f; int fd; - /* Create a temp file to put gdb commands into */ + /* + * Create a temp file to put gdb commands into. + * Note: POSIX.1-2008 declares that the file should be already created with mode 0600 by default. + * Modern systems implement it and and suggest to do not touch masks in multithreaded applications. + * So CoverityScan warning is valid only for ancient versions of stdlib. + */ strcpy(respfile, "/tmp/gdb-respfile-XXXXXX"); + // coverity[secure_temp] if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != nullptr) { fprintf(f, "attach %d\n" @@ -445,7 +451,7 @@ static void getExecPath(char **argv) if(argv[0][0] == '/') snprintf(argv0, sizeof(argv0), "%s", argv[0]); - else if (getcwd(argv0, sizeof(argv0)) != NULL) + else if (getcwd(argv0, sizeof(argv0)) != nullptr) { cwdlen = strlen(argv0); snprintf(argv0+cwdlen, sizeof(argv0)-cwdlen, "/%s", argv[0]); diff --git a/components/debug/debugging.cpp b/components/debug/debugging.cpp index dfed077e3..88219dcbe 100644 --- a/components/debug/debugging.cpp +++ b/components/debug/debugging.cpp @@ -1,5 +1,7 @@ #include "debugging.hpp" +#include + #include #ifdef _WIN32 @@ -11,11 +13,22 @@ namespace Debug { #ifdef _WIN32 + bool isRedirected(DWORD nStdHandle) + { + DWORD fileType = GetFileType(GetStdHandle(nStdHandle)); + + return (fileType == FILE_TYPE_DISK) || (fileType == FILE_TYPE_PIPE); + } + bool attachParentConsole() { if (GetConsoleWindow() != nullptr) return true; + bool inRedirected = isRedirected(STD_INPUT_HANDLE); + bool outRedirected = isRedirected(STD_OUTPUT_HANDLE); + bool errRedirected = isRedirected(STD_ERROR_HANDLE); + if (AttachConsole(ATTACH_PARENT_PROCESS)) { fflush(stdout); @@ -24,12 +37,21 @@ namespace Debug std::cerr.flush(); // this looks dubious but is really the right way - _wfreopen(L"CON", L"w", stdout); - _wfreopen(L"CON", L"w", stderr); - _wfreopen(L"CON", L"r", stdin); - freopen("CON", "w", stdout); - freopen("CON", "w", stderr); - freopen("CON", "r", stdin); + if (!inRedirected) + { + _wfreopen(L"CON", L"r", stdin); + freopen("CON", "r", stdin); + } + if (!outRedirected) + { + _wfreopen(L"CON", L"w", stdout); + freopen("CON", "w", stdout); + } + if (!errRedirected) + { + _wfreopen(L"CON", L"w", stderr); + freopen("CON", "w", stderr); + } return true; } @@ -40,15 +62,40 @@ namespace Debug std::streamsize DebugOutputBase::write(const char *str, std::streamsize size) { + if (size <= 0) + return size; + std::string_view msg{str, size_t(size)}; + // Skip debug level marker Level level = getLevelMarker(str); if (level != NoLevel) + msg = msg.substr(1); + + char prefix[32]; + int prefixSize; { - writeImpl(str+1, size-1, level); - return size; + prefix[0] = '['; + uint64_t ms = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + std::time_t t = ms / 1000; + prefixSize = std::strftime(prefix + 1, sizeof(prefix) - 1, "%T", std::localtime(&t)) + 1; + char levelLetter = " EWIVD*"[int(level)]; + prefixSize += snprintf(prefix + prefixSize, sizeof(prefix) - prefixSize, + ".%03u %c] ", static_cast(ms % 1000), levelLetter); + } + + while (!msg.empty()) + { + if (msg[0] == 0) + break; + size_t lineSize = 1; + while (lineSize < msg.size() && msg[lineSize - 1] != '\n') + lineSize++; + writeImpl(prefix, prefixSize, level); + writeImpl(msg.data(), lineSize, level); + msg = msg.substr(lineSize); } - writeImpl(str, size, NoLevel); return size; } @@ -152,6 +199,7 @@ int wrapApplication(int (*innerApplication)(int argc, char *argv[]), int argc, c // Restore cout and cerr std::cout.rdbuf(cout_rdbuf); std::cerr.rdbuf(cerr_rdbuf); + Debug::CurrentDebugLevel = Debug::NoLevel; return ret; } 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/detournavigator/asyncnavmeshupdater.cpp b/components/detournavigator/asyncnavmeshupdater.cpp index 0683a43bc..1ac928f07 100644 --- a/components/detournavigator/asyncnavmeshupdater.cpp +++ b/components/detournavigator/asyncnavmeshupdater.cpp @@ -38,8 +38,14 @@ 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"; + return stream << "unknown(" << static_cast(value) << ")"; } AsyncNavMeshUpdater::AsyncNavMeshUpdater(const Settings& settings, TileCachedRecastMeshManager& recastMeshManager, @@ -126,7 +132,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) @@ -192,7 +198,7 @@ namespace DetourNavigator return isSuccess(status); } - boost::optional AsyncNavMeshUpdater::getNextJob() + std::optional AsyncNavMeshUpdater::getNextJob() { std::unique_lock lock(mMutex); @@ -211,7 +217,7 @@ namespace DetourNavigator mFirstStart.lock()->reset(); if (mJobs.empty() && getTotalThreadJobsUnsafe() == 0) mDone.notify_all(); - return boost::none; + return std::nullopt; } Log(Debug::Debug) << "Got " << mJobs.size() << " navigator jobs and " @@ -233,7 +239,7 @@ namespace DetourNavigator } } - boost::optional AsyncNavMeshUpdater::getJob(Jobs& jobs, Pushed& pushed, bool changeLastUpdate) + std::optional AsyncNavMeshUpdater::getJob(Jobs& jobs, Pushed& pushed, bool changeLastUpdate) { const auto now = std::chrono::steady_clock::now(); diff --git a/components/detournavigator/asyncnavmeshupdater.hpp b/components/detournavigator/asyncnavmeshupdater.hpp index 4debcd6cd..53e7fd7c1 100644 --- a/components/detournavigator/asyncnavmeshupdater.hpp +++ b/components/detournavigator/asyncnavmeshupdater.hpp @@ -9,8 +9,6 @@ #include -#include - #include #include #include @@ -106,20 +104,20 @@ namespace DetourNavigator Jobs mJobs; std::map> mPushed; Misc::ScopeGuarded mPlayerTile; - Misc::ScopeGuarded> mFirstStart; + Misc::ScopeGuarded> mFirstStart; NavMeshTilesCache mNavMeshTilesCache; Misc::ScopeGuarded>> mProcessingTiles; std::map> mLastUpdates; std::map mThreadsQueues; std::vector mThreads; - void process() throw(); + void process() noexcept; bool processJob(const Job& job); - boost::optional getNextJob(); + std::optional getNextJob(); - boost::optional getJob(Jobs& jobs, Pushed& pushed, bool changeLastUpdate); + std::optional getJob(Jobs& jobs, Pushed& pushed, bool changeLastUpdate); void postThreadJob(Job&& job, Queue& queue); diff --git a/components/detournavigator/cachedrecastmeshmanager.cpp b/components/detournavigator/cachedrecastmeshmanager.cpp index da0f6c874..90b426610 100644 --- a/components/detournavigator/cachedrecastmeshmanager.cpp +++ b/components/detournavigator/cachedrecastmeshmanager.cpp @@ -25,7 +25,7 @@ namespace DetourNavigator return true; } - boost::optional CachedRecastMeshManager::removeObject(const ObjectId id) + std::optional CachedRecastMeshManager::removeObject(const ObjectId id) { const auto object = mImpl.removeObject(id); if (object) @@ -42,7 +42,7 @@ namespace DetourNavigator return true; } - boost::optional CachedRecastMeshManager::removeWater(const osg::Vec2i& cellPosition) + std::optional CachedRecastMeshManager::removeWater(const osg::Vec2i& cellPosition) { const auto water = mImpl.removeWater(cellPosition); if (water) diff --git a/components/detournavigator/cachedrecastmeshmanager.hpp b/components/detournavigator/cachedrecastmeshmanager.hpp index 5efb315e8..54574aa99 100644 --- a/components/detournavigator/cachedrecastmeshmanager.hpp +++ b/components/detournavigator/cachedrecastmeshmanager.hpp @@ -3,8 +3,6 @@ #include "recastmeshmanager.hpp" -#include - namespace DetourNavigator { class CachedRecastMeshManager @@ -19,9 +17,9 @@ namespace DetourNavigator bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const btTransform& transform); - boost::optional removeWater(const osg::Vec2i& cellPosition); + std::optional removeWater(const osg::Vec2i& cellPosition); - boost::optional removeObject(const ObjectId id); + std::optional removeObject(const ObjectId id); std::shared_ptr getMesh(); diff --git a/components/detournavigator/chunkytrimesh.cpp b/components/detournavigator/chunkytrimesh.cpp index 3a8fc3480..ffd39d0a9 100644 --- a/components/detournavigator/chunkytrimesh.cpp +++ b/components/detournavigator/chunkytrimesh.cpp @@ -51,7 +51,7 @@ namespace DetourNavigator const auto inum = imax - imin; const auto icur = curNode; - if (curNode > nodes.size()) + if (curNode >= nodes.size()) return; ChunkyTriMeshNode& node = nodes[curNode++]; diff --git a/components/detournavigator/findrandompointaroundcircle.cpp b/components/detournavigator/findrandompointaroundcircle.cpp index 3888c59fe..f2e815c91 100644 --- a/components/detournavigator/findrandompointaroundcircle.cpp +++ b/components/detournavigator/findrandompointaroundcircle.cpp @@ -10,12 +10,12 @@ namespace DetourNavigator { - boost::optional findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, + std::optional findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const Settings& settings) { dtNavMeshQuery navMeshQuery; if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes)) - return boost::optional(); + return std::optional(); dtQueryFilter queryFilter; queryFilter.setIncludeFlags(includeFlags); @@ -31,16 +31,16 @@ namespace DetourNavigator } if (startRef == 0) - return boost::optional(); + return std::optional(); 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(); + return std::optional(); - return boost::optional(resultPosition); + return std::optional(resultPosition); } } diff --git a/components/detournavigator/findrandompointaroundcircle.hpp b/components/detournavigator/findrandompointaroundcircle.hpp index 841508f67..d0dc2bbbc 100644 --- a/components/detournavigator/findrandompointaroundcircle.hpp +++ b/components/detournavigator/findrandompointaroundcircle.hpp @@ -3,8 +3,7 @@ #include "flags.hpp" -#include - +#include #include class dtNavMesh; @@ -13,7 +12,7 @@ namespace DetourNavigator { struct Settings; - boost::optional findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, + std::optional findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents, const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const Settings& settings); } diff --git a/components/detournavigator/findsmoothpath.cpp b/components/detournavigator/findsmoothpath.cpp index ef0341d72..a13b83abd 100644 --- a/components/detournavigator/findsmoothpath.cpp +++ b/components/detournavigator/findsmoothpath.cpp @@ -58,8 +58,8 @@ namespace DetourNavigator return path; // Get connected polygons - const dtMeshTile* tile = 0; - const dtPoly* poly = 0; + const dtMeshTile* tile = nullptr; + const dtPoly* poly = nullptr; if (dtStatusFailed(navQuery.getAttachedNavMesh()->getTileAndPolyByRef(path[0], &tile, &poly))) return path; @@ -103,7 +103,7 @@ namespace DetourNavigator return result; } - boost::optional getSteerTarget(const dtNavMeshQuery& navQuery, const osg::Vec3f& startPos, + std::optional getSteerTarget(const dtNavMeshQuery& navQuery, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const float minTargetDist, const std::vector& path) { // Find steer target. @@ -117,7 +117,7 @@ namespace DetourNavigator steerPathFlags.data(), steerPathPolys.data(), &nsteerPath, MAX_STEER_POINTS); assert(nsteerPath >= 0); if (!nsteerPath) - return boost::none; + return std::nullopt; // Find vertex far enough to steer to. std::size_t ns = 0; @@ -131,7 +131,7 @@ namespace DetourNavigator } // Failed to find good point to steer to. if (ns >= static_cast(nsteerPath)) - return boost::none; + return std::nullopt; dtVcopy(result.steerPos.ptr(), &steerPath[ns * 3]); result.steerPos.y() = startPos[1]; diff --git a/components/detournavigator/findsmoothpath.hpp b/components/detournavigator/findsmoothpath.hpp index f1de71207..a351f8279 100644 --- a/components/detournavigator/findsmoothpath.hpp +++ b/components/detournavigator/findsmoothpath.hpp @@ -18,10 +18,8 @@ #include -#include - #include - +#include #include class dtNavMesh; @@ -58,7 +56,7 @@ namespace DetourNavigator dtPolyRef steerPosRef; }; - boost::optional getSteerTarget(const dtNavMeshQuery& navQuery, const osg::Vec3f& startPos, + std::optional getSteerTarget(const dtNavMeshQuery& navQuery, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const float minTargetDist, const std::vector& path); template @@ -111,7 +109,7 @@ namespace DetourNavigator std::vector mVisited; }; - inline boost::optional moveAlongSurface(const dtNavMeshQuery& navMeshQuery, + inline std::optional moveAlongSurface(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& filter, const std::size_t maxVisitedSize) { @@ -128,7 +126,7 @@ namespace DetourNavigator return {std::move(result)}; } - inline boost::optional> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef, + inline std::optional> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef, const dtPolyRef endRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& queryFilter, const std::size_t maxSize) { @@ -144,7 +142,7 @@ namespace DetourNavigator return {std::move(result)}; } - inline boost::optional getPolyHeight(const dtNavMeshQuery& navMeshQuery, const dtPolyRef ref, const osg::Vec3f& pos) + inline std::optional getPolyHeight(const dtNavMeshQuery& navMeshQuery, const dtPolyRef ref, const osg::Vec3f& pos) { float result = 0.0f; const auto status = navMeshQuery.getPolyHeight(ref, pos.ptr(), &result); @@ -160,10 +158,10 @@ namespace DetourNavigator { // Iterate over the path to find smooth path on the detail mesh surface. osg::Vec3f iterPos; - navMeshQuery.closestPointOnPoly(polygonPath.front(), start.ptr(), iterPos.ptr(), 0); + navMeshQuery.closestPointOnPoly(polygonPath.front(), start.ptr(), iterPos.ptr(), nullptr); osg::Vec3f targetPos; - navMeshQuery.closestPointOnPoly(polygonPath.back(), end.ptr(), targetPos.ptr(), 0); + navMeshQuery.closestPointOnPoly(polygonPath.back(), end.ptr(), targetPos.ptr(), nullptr); const float SLOP = 0.01f; 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/navigator.cpp b/components/detournavigator/navigator.cpp index a58a4f876..658e539ad 100644 --- a/components/detournavigator/navigator.cpp +++ b/components/detournavigator/navigator.cpp @@ -3,18 +3,18 @@ namespace DetourNavigator { - boost::optional Navigator::findRandomPointAroundCircle(const osg::Vec3f& agentHalfExtents, + std::optional Navigator::findRandomPointAroundCircle(const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start, const float maxRadius, const Flags includeFlags) const { const auto navMesh = getNavMesh(agentHalfExtents); if (!navMesh) - return boost::optional(); + return std::optional(); const auto settings = getSettings(); const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(), toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start), toNavMeshCoordinates(settings, maxRadius), includeFlags, settings); if (!result) - return boost::optional(); - return boost::optional(fromNavMeshCoordinates(settings, *result)); + return std::optional(); + return std::optional(fromNavMeshCoordinates(settings, *result)); } } diff --git a/components/detournavigator/navigator.hpp b/components/detournavigator/navigator.hpp index 3e7f54178..a79aa59d4 100644 --- a/components/detournavigator/navigator.hpp +++ b/components/detournavigator/navigator.hpp @@ -220,7 +220,7 @@ namespace DetourNavigator * @param includeFlags setup allowed surfaces for actor to walk. * @return not empty optional with position if point is found and empty optional if point is not found. */ - boost::optional findRandomPointAroundCircle(const osg::Vec3f& agentHalfExtents, + std::optional findRandomPointAroundCircle(const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start, const float maxRadius, const Flags includeFlags) const; virtual RecastMeshTiles getRecastMeshTiles() = 0; diff --git a/components/detournavigator/navigatorimpl.hpp b/components/detournavigator/navigatorimpl.hpp index a1d66463c..e197c71b7 100644 --- a/components/detournavigator/navigatorimpl.hpp +++ b/components/detournavigator/navigatorimpl.hpp @@ -15,7 +15,7 @@ namespace DetourNavigator * @brief Navigator constructor initializes all internal data. Constructed object is ready to build a scene. * @param settings allows to customize navigator work. Constructor is only place to set navigator settings. */ - NavigatorImpl(const Settings& settings); + explicit NavigatorImpl(const Settings& settings); void addAgent(const osg::Vec3f& agentHalfExtents) override; @@ -40,9 +40,9 @@ namespace DetourNavigator bool removeWater(const osg::Vec2i& cellPosition) override; - void addPathgrid(const ESM::Cell& cell, const ESM::Pathgrid& pathgrid) final; + void addPathgrid(const ESM::Cell& cell, const ESM::Pathgrid& pathgrid) override; - void removePathgrid(const ESM::Pathgrid& pathgrid) final; + void removePathgrid(const ESM::Pathgrid& pathgrid) override; void update(const osg::Vec3f& playerPosition) override; diff --git a/components/detournavigator/navigatorstub.hpp b/components/detournavigator/navigatorstub.hpp index 9279e77e3..8b81bde19 100644 --- a/components/detournavigator/navigatorstub.hpp +++ b/components/detournavigator/navigatorstub.hpp @@ -60,9 +60,9 @@ namespace DetourNavigator return false; } - void addPathgrid(const ESM::Cell& /*cell*/, const ESM::Pathgrid& /*pathgrid*/) final {} + void addPathgrid(const ESM::Cell& /*cell*/, const ESM::Pathgrid& /*pathgrid*/) override {} - void removePathgrid(const ESM::Pathgrid& /*pathgrid*/) final {} + void removePathgrid(const ESM::Pathgrid& /*pathgrid*/) override {} void update(const osg::Vec3f& /*playerPosition*/) override {} diff --git a/components/detournavigator/navmeshcacheitem.hpp b/components/detournavigator/navmeshcacheitem.hpp index f13341397..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; @@ -143,7 +158,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 +196,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)); } }; 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 { 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(); } diff --git a/components/detournavigator/recastmeshbuilder.cpp b/components/detournavigator/recastmeshbuilder.cpp index 59f60394d..ee014b932 100644 --- a/components/detournavigator/recastmeshbuilder.cpp +++ b/components/detournavigator/recastmeshbuilder.cpp @@ -17,6 +17,7 @@ #include #include +#include #include namespace DetourNavigator diff --git a/components/detournavigator/recastmeshmanager.cpp b/components/detournavigator/recastmeshmanager.cpp index 05f250596..3796c9816 100644 --- a/components/detournavigator/recastmeshmanager.cpp +++ b/components/detournavigator/recastmeshmanager.cpp @@ -34,11 +34,11 @@ namespace DetourNavigator return true; } - boost::optional RecastMeshManager::removeObject(const ObjectId id) + std::optional RecastMeshManager::removeObject(const ObjectId id) { const auto object = mObjects.find(id); if (object == mObjects.end()) - return boost::none; + return std::nullopt; const RemovedRecastMeshObject result {object->second->getShape(), object->second->getTransform()}; mObjectsOrder.erase(object->second); mObjects.erase(object); @@ -59,11 +59,11 @@ namespace DetourNavigator return true; } - boost::optional RecastMeshManager::removeWater(const osg::Vec2i& cellPosition) + std::optional RecastMeshManager::removeWater(const osg::Vec2i& cellPosition) { const auto water = mWater.find(cellPosition); if (water == mWater.end()) - return boost::none; + return std::nullopt; ++mRevision; const auto result = *water->second; mWaterOrder.erase(water->second); diff --git a/components/detournavigator/recastmeshmanager.hpp b/components/detournavigator/recastmeshmanager.hpp index f1870ec6b..5b568e004 100644 --- a/components/detournavigator/recastmeshmanager.hpp +++ b/components/detournavigator/recastmeshmanager.hpp @@ -9,11 +9,10 @@ #include -#include - +#include #include +#include #include -#include class btCollisionShape; @@ -43,9 +42,9 @@ namespace DetourNavigator bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const btTransform& transform); - boost::optional removeWater(const osg::Vec2i& cellPosition); + std::optional removeWater(const osg::Vec2i& cellPosition); - boost::optional removeObject(const ObjectId id); + std::optional removeObject(const ObjectId id); std::shared_ptr getMesh(); diff --git a/components/detournavigator/settings.cpp b/components/detournavigator/settings.cpp index 49aec41ff..977b80cf5 100644 --- a/components/detournavigator/settings.cpp +++ b/components/detournavigator/settings.cpp @@ -4,10 +4,10 @@ namespace DetourNavigator { - boost::optional makeSettingsFromSettingsManager() + std::optional makeSettingsFromSettingsManager() { if (!::Settings::Manager::getBool("enable", "Navigator")) - return boost::optional(); + return std::optional(); Settings navigatorSettings; diff --git a/components/detournavigator/settings.hpp b/components/detournavigator/settings.hpp index 939d825a5..d73087b21 100644 --- a/components/detournavigator/settings.hpp +++ b/components/detournavigator/settings.hpp @@ -1,10 +1,9 @@ #ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGS_H #define OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGS_H -#include - -#include #include +#include +#include namespace DetourNavigator { @@ -42,7 +41,7 @@ namespace DetourNavigator std::chrono::milliseconds mMinUpdateInterval; }; - boost::optional makeSettingsFromSettingsManager(); + std::optional makeSettingsFromSettingsManager(); } #endif diff --git a/components/detournavigator/tilecachedrecastmeshmanager.cpp b/components/detournavigator/tilecachedrecastmeshmanager.cpp index 9debe5dea..fddaa88f1 100644 --- a/components/detournavigator/tilecachedrecastmeshmanager.cpp +++ b/components/detournavigator/tilecachedrecastmeshmanager.cpp @@ -31,12 +31,12 @@ namespace DetourNavigator return result; } - boost::optional TileCachedRecastMeshManager::removeObject(const ObjectId id) + std::optional TileCachedRecastMeshManager::removeObject(const ObjectId id) { const auto object = mObjectsTilesPositions.find(id); if (object == mObjectsTilesPositions.end()) - return boost::none; - boost::optional result; + return std::nullopt; + std::optional result; { auto tiles = mTiles.lock(); for (const auto& tilePosition : object->second) @@ -100,12 +100,12 @@ namespace DetourNavigator return result; } - boost::optional TileCachedRecastMeshManager::removeWater(const osg::Vec2i& cellPosition) + std::optional TileCachedRecastMeshManager::removeWater(const osg::Vec2i& cellPosition) { const auto object = mWaterTilesPositions.find(cellPosition); if (object == mWaterTilesPositions.end()) - return boost::none; - boost::optional result; + return std::nullopt; + std::optional result; for (const auto& tilePosition : object->second) { const auto tiles = mTiles.lock(); @@ -168,12 +168,12 @@ namespace DetourNavigator return tile != tiles.end() && tile->second.updateObject(id, transform, areaType); } - boost::optional TileCachedRecastMeshManager::removeTile(const ObjectId id, + std::optional TileCachedRecastMeshManager::removeTile(const ObjectId id, const TilePosition& tilePosition, std::map& tiles) { const auto tile = tiles.find(tilePosition); if (tile == tiles.end()) - return boost::optional(); + return std::optional(); const auto tileResult = tile->second.removeObject(id); if (tile->second.isEmpty()) { diff --git a/components/detournavigator/tilecachedrecastmeshmanager.hpp b/components/detournavigator/tilecachedrecastmeshmanager.hpp index 557cde1be..fa192bd73 100644 --- a/components/detournavigator/tilecachedrecastmeshmanager.hpp +++ b/components/detournavigator/tilecachedrecastmeshmanager.hpp @@ -69,11 +69,11 @@ namespace DetourNavigator return changed; } - boost::optional removeObject(const ObjectId id); + std::optional removeObject(const ObjectId id); bool addWater(const osg::Vec2i& cellPosition, const int cellSize, const btTransform& transform); - boost::optional removeWater(const osg::Vec2i& cellPosition); + std::optional removeWater(const osg::Vec2i& cellPosition); std::shared_ptr getMesh(const TilePosition& tilePosition); @@ -103,7 +103,7 @@ namespace DetourNavigator bool updateTile(const ObjectId id, const btTransform& transform, const AreaType areaType, const TilePosition& tilePosition, std::map& tiles); - boost::optional removeTile(const ObjectId id, const TilePosition& tilePosition, + std::optional removeTile(const ObjectId id, const TilePosition& tilePosition, std::map& tiles); }; } diff --git a/components/esm/aisequence.cpp b/components/esm/aisequence.cpp index 7891299e3..df3c1ca9d 100644 --- a/components/esm/aisequence.cpp +++ b/components/esm/aisequence.cpp @@ -171,7 +171,7 @@ namespace AiSequence int type; esm.getHT(type); - mPackages.push_back(AiPackageContainer()); + mPackages.emplace_back(); mPackages.back().mType = type; switch (type) diff --git a/components/esm/containerstate.hpp b/components/esm/containerstate.hpp index b0c4da2d1..7f1afd077 100644 --- a/components/esm/containerstate.hpp +++ b/components/esm/containerstate.hpp @@ -12,14 +12,14 @@ namespace ESM { InventoryState mInventory; - void load (ESMReader &esm) final; - void save (ESMWriter &esm, bool inInventory = false) const final; + void load (ESMReader &esm) override; + void save (ESMWriter &esm, bool inInventory = false) const override; - ContainerState& asContainerState() final + ContainerState& asContainerState() override { return *this; } - const ContainerState& asContainerState() const final + const ContainerState& asContainerState() const override { return *this; } diff --git a/components/esm/creaturelevliststate.hpp b/components/esm/creaturelevliststate.hpp index ec0bc8667..2ee9e511f 100644 --- a/components/esm/creaturelevliststate.hpp +++ b/components/esm/creaturelevliststate.hpp @@ -12,14 +12,14 @@ namespace ESM int mSpawnActorId; bool mSpawn; - void load (ESMReader &esm) final; - void save (ESMWriter &esm, bool inInventory = false) const final; + void load (ESMReader &esm) override; + void save (ESMWriter &esm, bool inInventory = false) const override; - CreatureLevListState& asCreatureLevListState() final + CreatureLevListState& asCreatureLevListState() override { return *this; } - const CreatureLevListState& asCreatureLevListState() const final + const CreatureLevListState& asCreatureLevListState() const override { return *this; } diff --git a/components/esm/creaturestate.hpp b/components/esm/creaturestate.hpp index 3e9a44d56..4b4c59d71 100644 --- a/components/esm/creaturestate.hpp +++ b/components/esm/creaturestate.hpp @@ -15,16 +15,16 @@ namespace ESM CreatureStats mCreatureStats; /// Initialize to default state - void blank(); + void blank() override; - void load (ESMReader &esm) final; - void save (ESMWriter &esm, bool inInventory = false) const final; + void load (ESMReader &esm) override; + void save (ESMWriter &esm, bool inInventory = false) const override; - CreatureState& asCreatureState() final + CreatureState& asCreatureState() override { return *this; } - const CreatureState& asCreatureState() const final + const CreatureState& asCreatureState() const override { return *this; } diff --git a/components/esm/doorstate.hpp b/components/esm/doorstate.hpp index 04ad110d6..c3aeb42e3 100644 --- a/components/esm/doorstate.hpp +++ b/components/esm/doorstate.hpp @@ -11,14 +11,14 @@ namespace ESM { int mDoorState = 0; - void load (ESMReader &esm) final; - void save (ESMWriter &esm, bool inInventory = false) const final; + void load (ESMReader &esm) override; + void save (ESMWriter &esm, bool inInventory = false) const override; - DoorState& asDoorState() final + DoorState& asDoorState() override { return *this; } - const DoorState& asDoorState() const final + const DoorState& asDoorState() const override { return *this; } 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 diff --git a/components/esm/inventorystate.cpp b/components/esm/inventorystate.cpp index fe54762c5..980d67f7e 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 @@ -74,7 +76,7 @@ void ESM::InventoryState::load (ESMReader &esm) float rand, multiplier; esm.getHT (rand); esm.getHNT (multiplier, "MULT"); - params.push_back(std::make_pair(rand, multiplier)); + params.emplace_back(rand, multiplier); } mPermanentMagicEffectMagnitudes[id] = params; } @@ -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/loadcell.hpp b/components/esm/loadcell.hpp index 132c869ad..d06b509c5 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -185,7 +185,7 @@ struct Cell CellRef &ref, bool &isDeleted, bool ignoreMoves = false, - MovedCellRef *mref = 0); + MovedCellRef *mref = nullptr); /* This fetches an MVRF record, which is used to track moved references. * Since they are comparably rare, we use a separate method for this. diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 3064d0c31..2aa8f21db 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -331,9 +331,10 @@ namespace ESM std::copy(land.mWnam, land.mWnam + LAND_GLOBAL_MAP_LOD_SIZE, mWnam); } - Land& Land::operator= (Land land) + Land& Land::operator= (const Land& land) { - swap (land); + Land tmp(land); + swap(tmp); return *this; } diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp index e5faf4b31..2a1140ad2 100644 --- a/components/esm/loadland.hpp +++ b/components/esm/loadland.hpp @@ -148,7 +148,7 @@ struct Land Land (const Land& land); - Land& operator= (Land land); + Land& operator= (const Land& land); void swap (Land& land); diff --git a/components/esm/locals.cpp b/components/esm/locals.cpp index bd51be08f..4149695fe 100644 --- a/components/esm/locals.cpp +++ b/components/esm/locals.cpp @@ -12,7 +12,7 @@ void ESM::Locals::load (ESMReader &esm) Variant value; value.read (esm, Variant::Format_Local); - mVariables.push_back (std::make_pair (id, value)); + mVariables.emplace_back (id, value); } } diff --git a/components/esm/npcstate.hpp b/components/esm/npcstate.hpp index 6c0469050..fc6b91764 100644 --- a/components/esm/npcstate.hpp +++ b/components/esm/npcstate.hpp @@ -17,16 +17,16 @@ namespace ESM CreatureStats mCreatureStats; /// Initialize to default state - void blank(); + void blank() override; - void load (ESMReader &esm) final; - void save (ESMWriter &esm, bool inInventory = false) const final; + void load (ESMReader &esm) override; + void save (ESMWriter &esm, bool inInventory = false) const override; - NpcState& asNpcState() final + NpcState& asNpcState() override { return *this; } - const NpcState& asNpcState() const final + const NpcState& asNpcState() const override { return *this; } diff --git a/components/esm/objectstate.hpp b/components/esm/objectstate.hpp index 1079d6c72..6b0fca5ea 100644 --- a/components/esm/objectstate.hpp +++ b/components/esm/objectstate.hpp @@ -49,7 +49,7 @@ namespace ESM virtual void save (ESMWriter &esm, bool inInventory = false) const; - /// Initialize to default state + virtual /// Initialize to default state void blank(); virtual ~ObjectState(); 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/esm/variant.cpp b/components/esm/variant.cpp index c65eed5e0..6ff31dc44 100644 --- a/components/esm/variant.cpp +++ b/components/esm/variant.cpp @@ -16,11 +16,11 @@ namespace const uint32_t STTV = ESM::FourCC<'S','T','T','V'>::value; } -ESM::Variant::Variant() : mType (VT_None), mData (0) {} +ESM::Variant::Variant() : mType (VT_None), mData (nullptr) {} ESM::Variant::Variant(const std::string &value) { - mData = 0; + mData = nullptr; mType = VT_None; setType(VT_String); setString(value); @@ -28,7 +28,7 @@ ESM::Variant::Variant(const std::string &value) ESM::Variant::Variant(int value) { - mData = 0; + mData = nullptr; mType = VT_None; setType(VT_Long); setInteger(value); @@ -36,7 +36,7 @@ ESM::Variant::Variant(int value) ESM::Variant::Variant(float value) { - mData = 0; + mData = nullptr; mType = VT_None; setType(VT_Float); setFloat(value); @@ -51,7 +51,7 @@ ESM::Variant& ESM::Variant::operator= (const Variant& variant) { if (&variant!=this) { - VariantDataBase *newData = variant.mData ? variant.mData->clone() : 0; + VariantDataBase *newData = variant.mData ? variant.mData->clone() : nullptr; delete mData; @@ -63,7 +63,7 @@ ESM::Variant& ESM::Variant::operator= (const Variant& variant) } ESM::Variant::Variant (const Variant& variant) -: mType (variant.mType), mData (variant.mData ? variant.mData->clone() : 0) +: mType (variant.mType), mData (variant.mData ? variant.mData->clone() : nullptr) {} ESM::VarType ESM::Variant::getType() const @@ -254,7 +254,7 @@ void ESM::Variant::setType (VarType type) { if (type!=mType) { - VariantDataBase *newData = 0; + VariantDataBase *newData = nullptr; switch (type) { diff --git a/components/esm/variantimp.hpp b/components/esm/variantimp.hpp index 1dc20c21f..c1203ddf8 100644 --- a/components/esm/variantimp.hpp +++ b/components/esm/variantimp.hpp @@ -71,29 +71,29 @@ namespace ESM public: - VariantStringData (const VariantDataBase *data = 0); + VariantStringData (const VariantDataBase *data = nullptr); ///< 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. }; @@ -103,36 +103,36 @@ namespace ESM public: - VariantIntegerData (const VariantDataBase *data = 0); + VariantIntegerData (const VariantDataBase *data = nullptr); ///< 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. }; @@ -142,36 +142,36 @@ namespace ESM public: - VariantFloatData (const VariantDataBase *data = 0); + VariantFloatData (const VariantDataBase *data = nullptr); ///< 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.cpp b/components/esmterrain/storage.cpp index cf27b7128..4d3f3c305 100644 --- a/components/esmterrain/storage.cpp +++ b/components/esmterrain/storage.cpp @@ -71,7 +71,7 @@ namespace ESMTerrain int endColumn = startColumn + size * (ESM::Land::LAND_SIZE-1) + 1; osg::ref_ptr land = getLand (cellX, cellY); - const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : 0; + const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr; if (data) { min = std::numeric_limits::max(); @@ -119,7 +119,7 @@ namespace ESMTerrain } const LandObject* land = getLand(cellX, cellY, cache); - const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VNML) : 0; + const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VNML) : nullptr; if (data) { normal.x() = data->mNormals[col*ESM::Land::LAND_SIZE*3+row*3]; @@ -156,7 +156,7 @@ namespace ESMTerrain } const LandObject* land = getLand(cellX, cellY, cache); - const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VCLR) : 0; + const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VCLR) : nullptr; if (data) { color.r() = data->mColours[col*ESM::Land::LAND_SIZE*3+row*3]; @@ -207,9 +207,9 @@ namespace ESMTerrain for (int cellX = startCellX; cellX < startCellX + std::ceil(size); ++cellX) { const LandObject* land = getLand(cellX, cellY, cache); - const ESM::Land::LandData *heightData = 0; - const ESM::Land::LandData *normalData = 0; - const ESM::Land::LandData *colourData = 0; + const ESM::Land::LandData *heightData = nullptr; + const ESM::Land::LandData *normalData = nullptr; + const ESM::Land::LandData *colourData = nullptr; if (land) { heightData = land->getData(ESM::Land::DATA_VHGT); @@ -341,7 +341,7 @@ namespace ESMTerrain const LandObject* land = getLand(cellX, cellY, cache); - const ESM::Land::LandData *data = land ? land->getData(ESM::Land::DATA_VTEX) : 0; + const ESM::Land::LandData *data = land ? land->getData(ESM::Land::DATA_VTEX) : nullptr; if (data) { int tex = data->mTextures[y * ESM::Land::LAND_TEXTURE_SIZE + x]; 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/fallback/validate.cpp b/components/fallback/validate.cpp new file mode 100644 index 000000000..982c709af --- /dev/null +++ b/components/fallback/validate.cpp @@ -0,0 +1,24 @@ +#include "validate.hpp" + +void Fallback::validate(boost::any& v, std::vector const& tokens, FallbackMap*, int) +{ + if (v.empty()) + { + v = boost::any(FallbackMap()); + } + + FallbackMap *map = boost::any_cast(&v); + + for (const auto& token : tokens) + { + std::string temp = Files::EscapeHashString::processString(token); + size_t sep = temp.find(","); + if (sep < 1 || sep == temp.length() - 1 || sep == std::string::npos) + throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value); + + std::string key(temp.substr(0, sep)); + std::string value(temp.substr(sep + 1)); + + map->mMap[key] = value; + } +} diff --git a/components/fallback/validate.hpp b/components/fallback/validate.hpp index cef52e462..96690f50a 100644 --- a/components/fallback/validate.hpp +++ b/components/fallback/validate.hpp @@ -16,32 +16,7 @@ namespace Fallback std::map mMap; }; - void validate(boost::any &v, std::vector const &tokens, FallbackMap*, int) - { - if (v.empty()) - { - v = boost::any(FallbackMap()); - } - - FallbackMap *map = boost::any_cast(&v); - - for (std::vector::const_iterator it = tokens.begin(); it != tokens.end(); ++it) - { - std::string temp = Files::EscapeHashString::processString(*it); - int sep = temp.find(","); - if (sep < 1 || sep == (int)temp.length() - 1) -#if (BOOST_VERSION < 104200) - throw boost::program_options::validation_error("invalid value"); -#else - throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value); -#endif - - std::string key(temp.substr(0, sep)); - std::string value(temp.substr(sep + 1)); - - map->mMap[key] = value; - } - } + void validate(boost::any &v, std::vector const &tokens, FallbackMap*, int); } #endif diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 0ba2d1519..92d35a6b6 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -2,6 +2,7 @@ #include #include +#include #include /** @@ -58,23 +59,96 @@ void ConfigurationManager::readConfiguration(boost::program_options::variables_m { bool silent = mSilent; mSilent = quiet; + + // User config has the highest priority. + auto composingVariables = separateComposingVariables(variables, description); + loadConfig(mFixedPath.getUserConfigPath(), variables, description); + mergeComposingVariables(variables, composingVariables, description); + boost::program_options::notify(variables); // read either local or global config depending on type of installation + composingVariables = separateComposingVariables(variables, description); bool loaded = loadConfig(mFixedPath.getLocalPath(), variables, description); + mergeComposingVariables(variables, composingVariables, description); boost::program_options::notify(variables); if (!loaded) { + composingVariables = separateComposingVariables(variables, description); loadConfig(mFixedPath.getGlobalConfigPath(), variables, description); + mergeComposingVariables(variables, composingVariables, description); boost::program_options::notify(variables); } - // User config has the highest priority. - loadConfig(mFixedPath.getUserConfigPath(), variables, description); - boost::program_options::notify(variables); - mSilent = silent; } +boost::program_options::variables_map ConfigurationManager::separateComposingVariables(boost::program_options::variables_map & variables, boost::program_options::options_description& description) +{ + boost::program_options::variables_map composingVariables; + for (auto itr = variables.begin(); itr != variables.end();) + { + if (description.find(itr->first, false).semantic()->is_composing()) + { + composingVariables.emplace(*itr); + itr = variables.erase(itr); + } + else + ++itr; + } + return composingVariables; +} + +void ConfigurationManager::mergeComposingVariables(boost::program_options::variables_map & first, boost::program_options::variables_map & second, boost::program_options::options_description& description) +{ + for (const auto& option : description.options()) + { + if (option->semantic()->is_composing()) + { + std::string name = option->canonical_display_name(); + + auto firstPosition = first.find(name); + if (firstPosition == first.end()) + { + first.emplace(name, second[name]); + continue; + } + + if (second[name].defaulted() || second[name].empty()) + continue; + + boost::any& firstValue = firstPosition->second.value(); + const boost::any& secondValue = second[name].value(); + + if (firstValue.type() == typeid(Files::EscapePathContainer)) + { + auto& firstPathContainer = boost::any_cast(firstValue); + const auto& secondPathContainer = boost::any_cast(secondValue); + + firstPathContainer.insert(firstPathContainer.end(), secondPathContainer.begin(), secondPathContainer.end()); + } + else if (firstValue.type() == typeid(Files::EscapeStringVector)) + { + auto& firstVector = boost::any_cast(firstValue); + const auto& secondVector = boost::any_cast(secondValue); + + firstVector.mVector.insert(firstVector.mVector.end(), secondVector.mVector.begin(), secondVector.mVector.end()); + } + else if (firstValue.type() == typeid(Fallback::FallbackMap)) + { + auto& firstMap = boost::any_cast(firstValue); + const auto& secondMap = boost::any_cast(secondValue); + + std::map tempMap(secondMap.mMap); + tempMap.merge(firstMap.mMap); + firstMap.mMap.swap(tempMap); + } + else + Log(Debug::Error) << "Unexpected composing variable type. Curse boost and their blasted arcane templates."; + } + } + +} + void ConfigurationManager::processPaths(Files::PathContainer& dataDirs, bool create) { std::string path; diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 446abd4dc..0ec0a1f67 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -25,6 +25,10 @@ struct ConfigurationManager void readConfiguration(boost::program_options::variables_map& variables, boost::program_options::options_description& description, bool quiet=false); + boost::program_options::variables_map separateComposingVariables(boost::program_options::variables_map& variables, boost::program_options::options_description& description); + + void mergeComposingVariables(boost::program_options::variables_map& first, boost::program_options::variables_map& second, boost::program_options::options_description& description); + void processPaths(Files::PathContainer& dataDirs, bool create = false); ///< \param create Try creating the directory, if it does not exist. diff --git a/components/files/constrainedfilestream.cpp b/components/files/constrainedfilestream.cpp index 419af0d6c..baab1b081 100644 --- a/components/files/constrainedfilestream.cpp +++ b/components/files/constrainedfilestream.cpp @@ -32,12 +32,12 @@ namespace Files if (start != 0) mFile.seek(start); - setg(0,0,0); + setg(nullptr,nullptr,nullptr); 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(); @@ -81,12 +81,12 @@ namespace Files mFile.seek(mOrigin+newPos); // Clear read pointers so underflow() gets called on the next read attempt. - setg(0, 0, 0); + setg(nullptr, nullptr, nullptr); 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(); @@ -97,7 +97,7 @@ namespace Files mFile.seek(mOrigin + pos); // Clear read pointers so underflow() gets called on the next read attempt. - setg(0, 0, 0); + setg(nullptr, nullptr, nullptr); return pos; } diff --git a/components/files/escape.cpp b/components/files/escape.cpp index 93ae9b885..8b11504d3 100644 --- a/components/files/escape.cpp +++ b/components/files/escape.cpp @@ -121,7 +121,7 @@ namespace Files EscapeStringVector * eSV = boost::any_cast(&v); for (std::vector::const_iterator it = tokens.begin(); it != tokens.end(); ++it) - eSV->mVector.push_back(EscapeHashString(*it)); + eSV->mVector.emplace_back(*it); } PathContainer EscapePath::toPathContainer(const EscapePathContainer & escapePathContainer) diff --git a/components/files/lowlevelfile.cpp b/components/files/lowlevelfile.cpp index 424527b9d..07915abba 100644 --- a/components/files/lowlevelfile.cpp +++ b/components/files/lowlevelfile.cpp @@ -4,6 +4,11 @@ #include #include +#if FILE_API == FILE_API_STDIO +#include +#include +#endif + #if FILE_API == FILE_API_POSIX #include #include @@ -39,7 +44,7 @@ void LowLevelFile::open (char const * filename) if (mHandle == nullptr) { std::ostringstream os; - os << "Failed to open '" << filename << "' for reading."; + os << "Failed to open '" << filename << "' for reading: " << strerror(errno); throw std::runtime_error (os.str ()); } } @@ -58,42 +63,63 @@ size_t LowLevelFile::size () assert (mHandle != nullptr); long oldPosition = ftell (mHandle); - if (oldPosition == -1) - throw std::runtime_error ("A query operation on a file failed."); + { + std::ostringstream os; + os << "An ftell() call failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } if (fseek (mHandle, 0, SEEK_END) != 0) - throw std::runtime_error ("A query operation on a file failed."); - - long Size = ftell (mHandle); + { + std::ostringstream os; + os << "An fseek() call failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } - if (Size == -1) - throw std::runtime_error ("A query operation on a file failed."); + long size = ftell (mHandle); + if (size == -1) + { + std::ostringstream os; + os << "An ftell() call failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } if (fseek (mHandle, oldPosition, SEEK_SET) != 0) - throw std::runtime_error ("A query operation on a file failed."); + { + std::ostringstream os; + os << "An fseek() call failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } - return size_t (Size); + return size_t (size); } -void LowLevelFile::seek (size_t Position) +void LowLevelFile::seek (size_t position) { assert (mHandle != nullptr); - if (fseek (mHandle, Position, SEEK_SET) != 0) - throw std::runtime_error ("A seek operation on a file failed."); + if (fseek (mHandle, position, SEEK_SET) != 0) + { + std::ostringstream os; + os << "An fseek() call failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } } size_t LowLevelFile::tell () { assert (mHandle != nullptr); - long Position = ftell (mHandle); - - if (Position == -1) - throw std::runtime_error ("A query operation on a file failed."); + long position = ftell (mHandle); + if (position == -1) + { + std::ostringstream os; + os << "An ftell() call failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } - return size_t (Position); + return size_t (position); } size_t LowLevelFile::read (void * data, size_t size) @@ -103,7 +129,11 @@ size_t LowLevelFile::read (void * data, size_t size) int amount = fread (data, 1, size, mHandle); if (amount == 0 && ferror (mHandle)) - throw std::runtime_error ("A read operation on a file failed."); + { + std::ostringstream os; + os << "An attempt to read " << size << " bytes failed: " << strerror(errno); + throw std::runtime_error (os.str ()); + } return amount; } @@ -164,37 +194,37 @@ size_t LowLevelFile::size () if (oldPosition == size_t (-1)) { std::ostringstream os; - os << "An lseek() call failed:" << strerror(errno); + os << "An lseek() call failed: " << strerror(errno); throw std::runtime_error (os.str ()); } - size_t Size = ::lseek (mHandle, 0, SEEK_END); + size_t size = ::lseek (mHandle, 0, SEEK_END); - if (Size == size_t (-1)) + if (size == size_t (-1)) { std::ostringstream os; - os << "An lseek() call failed:" << strerror(errno); + os << "An lseek() call failed: " << strerror(errno); throw std::runtime_error (os.str ()); } if (lseek (mHandle, oldPosition, SEEK_SET) == -1) { std::ostringstream os; - os << "An lseek() call failed:" << strerror(errno); + os << "An lseek() call failed: " << strerror(errno); throw std::runtime_error (os.str ()); } - return Size; + return size; } -void LowLevelFile::seek (size_t Position) +void LowLevelFile::seek (size_t position) { assert (mHandle != -1); - if (::lseek (mHandle, Position, SEEK_SET) == -1) + if (::lseek (mHandle, position, SEEK_SET) == -1) { std::ostringstream os; - os << "An lseek() call failed:" << strerror(errno); + os << "An lseek() call failed: " << strerror(errno); throw std::runtime_error (os.str ()); } } @@ -203,16 +233,16 @@ size_t LowLevelFile::tell () { assert (mHandle != -1); - size_t Position = ::lseek (mHandle, 0, SEEK_CUR); + size_t position = ::lseek (mHandle, 0, SEEK_CUR); - if (Position == size_t (-1)) + if (position == size_t (-1)) { std::ostringstream os; - os << "An lseek() call failed:" << strerror(errno); + os << "An lseek() call failed: " << strerror(errno); throw std::runtime_error (os.str ()); } - return Position; + return position; } size_t LowLevelFile::read (void * data, size_t size) @@ -224,7 +254,7 @@ size_t LowLevelFile::read (void * data, size_t size) if (amount == -1) { std::ostringstream os; - os << "An attempt to read " << size << "bytes failed:" << strerror(errno); + os << "An attempt to read " << size << " bytes failed: " << strerror(errno); throw std::runtime_error (os.str ()); } @@ -292,11 +322,11 @@ size_t LowLevelFile::size () return info.nFileSizeLow; } -void LowLevelFile::seek (size_t Position) +void LowLevelFile::seek (size_t position) { assert (mHandle != INVALID_HANDLE_VALUE); - if (SetFilePointer (mHandle, Position, nullptr, SEEK_SET) == INVALID_SET_FILE_POINTER) + if (SetFilePointer (mHandle, position, nullptr, SEEK_SET) == INVALID_SET_FILE_POINTER) if (GetLastError () != NO_ERROR) throw std::runtime_error ("A seek operation on a file failed."); } 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/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index a90bda94b..35ad93a8a 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -6,7 +6,7 @@ namespace Interpreter { - Runtime::Runtime() : mContext (0), mCode (0), mCodeSize(0), mPC (0) {} + Runtime::Runtime() : mContext (nullptr), mCode (nullptr), mCodeSize(0), mPC (0) {} int Runtime::getPC() const { @@ -65,8 +65,8 @@ namespace Interpreter void Runtime::clear() { - mContext = 0; - mCode = 0; + mContext = nullptr; + mCode = nullptr; mCodeSize = 0; mStack.clear(); } diff --git a/components/misc/barrier.hpp b/components/misc/barrier.hpp new file mode 100644 index 000000000..a5af9f565 --- /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/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 diff --git a/components/misc/rng.cpp b/components/misc/rng.cpp index 09279e85e..23d820448 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())(seed.mGenerator); } - float Rng::rollClosedProbability() + float Rng::rollClosedProbability(Seed& seed) { - return std::uniform_real_distribution(0, 1)(generator); + return std::uniform_real_distribution(0, 1)(seed.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)(seed.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: - - /// create a RNG - static std::mt19937 generator; + class Seed + { + std::mt19937 mGenerator; + public: + Seed(); + Seed(const Seed&) = delete; + Seed(unsigned int seed); + friend class Rng; + }; + + 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(); diff --git a/components/myguiplatform/additivelayer.hpp b/components/myguiplatform/additivelayer.hpp index f0cfc1b41..f89e1d007 100644 --- a/components/myguiplatform/additivelayer.hpp +++ b/components/myguiplatform/additivelayer.hpp @@ -20,9 +20,9 @@ namespace osgMyGUI MYGUI_RTTI_DERIVED( AdditiveLayer ) AdditiveLayer(); - ~AdditiveLayer(); + ~AdditiveLayer() override; - void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) final; + void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) override; private: osg::ref_ptr mStateSet; 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..dc771f11f 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(); @@ -127,7 +127,7 @@ public: if(texture) state->applyTextureAttribute(0, texture); - osg::GLBufferObject* bufferobject = state->isVertexBufferObjectSupported() ? vbo->getOrCreateGLBufferObject(state->getContextID()) : 0; + osg::GLBufferObject* bufferobject = state->isVertexBufferObjectSupported() ? vbo->getOrCreateGLBufferObject(state->getContextID()) : nullptr; if (bufferobject) { state->bindVertexBufferObject(bufferobject); @@ -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..72abebd18 100644 --- a/components/myguiplatform/myguirendermanager.hpp +++ b/components/myguiplatform/myguirendermanager.hpp @@ -67,49 +67,55 @@ 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); + // 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); }; } 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/myguiplatform/scalinglayer.hpp b/components/myguiplatform/scalinglayer.hpp index 7ce5f84f7..f9fd92a78 100644 --- a/components/myguiplatform/scalinglayer.hpp +++ b/components/myguiplatform/scalinglayer.hpp @@ -13,13 +13,13 @@ namespace osgMyGUI public: MYGUI_RTTI_DERIVED(ScalingLayer) - void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final; + void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) override; - MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const final; - MyGUI::IntPoint getPosition(int _left, int _top) const final; - void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) final; + MyGUI::ILayerItem* getLayerItemByPoint(int _left, int _top) const override; + MyGUI::IntPoint getPosition(int _left, int _top) const override; + void renderToTarget(MyGUI::IRenderTarget* _target, bool _update) override; - void resizeView(const MyGUI::IntSize& _viewSize) final; + void resizeView(const MyGUI::IntSize& _viewSize) override; private: void screenToLayerCoords(int& _left, int& _top) const; 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.cpp b/components/nif/controller.cpp index 07699239e..1e909120e 100644 --- a/components/nif/controller.cpp +++ b/components/nif/controller.cpp @@ -92,6 +92,8 @@ namespace Nif void NiMaterialColorController::read(NIFStream *nif) { Controller::read(nif); + if (nif->getVersion() > NIFStream::generateVersion(10,1,0,103)) + interpolator.read(nif); // Two bits that correspond to the controlled material color. // 00: Ambient // 01: Diffuse @@ -101,12 +103,14 @@ namespace Nif targetColor = nif->getUShort() & 3; else targetColor = (flags >> 4) & 3; - data.read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) + data.read(nif); } void NiMaterialColorController::post(NIFFile *nif) { Controller::post(nif); + interpolator.post(nif); data.post(nif); } @@ -161,25 +165,33 @@ namespace Nif void NiKeyframeController::read(NIFStream *nif) { Controller::read(nif); - data.read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) + data.read(nif); + else + interpolator.read(nif); } void NiKeyframeController::post(NIFFile *nif) { Controller::post(nif); data.post(nif); + interpolator.post(nif); } void NiFloatInterpController::read(NIFStream *nif) { Controller::read(nif); - data.read(nif); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) + data.read(nif); + else + interpolator.read(nif); } void NiFloatInterpController::post(NIFFile *nif) { Controller::post(nif); data.post(nif); + interpolator.post(nif); } void NiGeomMorpherController::read(NIFStream *nif) @@ -189,13 +201,34 @@ namespace Nif /*bool updateNormals = !!*/nif->getUShort(); data.read(nif); if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW) + { /*bool alwaysActive = */nif->getChar(); // Always 0 + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,106)) + { + if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB) + { + interpolators.read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0) && nif->getBethVersion() > 9) + { + unsigned int numUnknown = nif->getUInt(); + nif->skip(4 * numUnknown); + } + } + else + { + // TODO: handle weighted interpolators + unsigned int numInterps = nif->getUInt(); + nif->skip(8 * numInterps); + } + } + } } void NiGeomMorpherController::post(NIFFile *nif) { Controller::post(nif); data.post(nif); + interpolators.post(nif); } void NiVisController::read(NIFStream *nif) @@ -213,6 +246,8 @@ namespace Nif void NiFlipController::read(NIFStream *nif) { Controller::read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,2,0,0)) + mInterpolator.read(nif); mTexSlot = nif->getUInt(); if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,103)) { @@ -225,7 +260,69 @@ namespace Nif void NiFlipController::post(NIFFile *nif) { Controller::post(nif); + mInterpolator.post(nif); mSources.post(nif); } + void bhkBlendController::read(NIFStream *nif) + { + Controller::read(nif); + nif->getUInt(); // Zero + } + + void NiPoint3Interpolator::read(NIFStream *nif) + { + defaultVal = nif->getVector3(); + data.read(nif); + } + + void NiPoint3Interpolator::post(NIFFile *nif) + { + data.post(nif); + } + + void NiBoolInterpolator::read(NIFStream *nif) + { + defaultVal = nif->getBoolean(); + data.read(nif); + } + + void NiBoolInterpolator::post(NIFFile *nif) + { + data.post(nif); + } + + void NiFloatInterpolator::read(NIFStream *nif) + { + defaultVal = nif->getFloat(); + data.read(nif); + } + + void NiFloatInterpolator::post(NIFFile *nif) + { + data.post(nif); + } + + void NiTransformInterpolator::read(NIFStream *nif) + { + defaultPos = nif->getVector3(); + defaultRot = nif->getQuaternion(); + defaultScale = nif->getFloat(); + if (nif->getVersion() <= NIFStream::generateVersion(10,1,0,109)) + { + if (!nif->getBoolean()) + defaultPos = osg::Vec3f(); + if (!nif->getBoolean()) + defaultRot = osg::Quat(); + if (!nif->getBoolean()) + defaultScale = 1.f; + } + data.read(nif); + } + + void NiTransformInterpolator::post(NIFFile *nif) + { + data.post(nif); + } + } diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index a527a4400..6b84d3749 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -75,19 +75,20 @@ 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; class NiMaterialColorController : public Controller { public: + NiPoint3InterpolatorPtr interpolator; 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 +111,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 +121,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,25 +131,27 @@ 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 { public: NiKeyframeDataPtr data; + NiTransformInterpolatorPtr interpolator; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; struct NiFloatInterpController : public Controller { NiFloatDataPtr data; + NiFloatInterpolatorPtr interpolator; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiAlphaController : public NiFloatInterpController { }; @@ -158,9 +161,10 @@ class NiGeomMorpherController : public Controller { public: NiMorphDataPtr data; + NiFloatInterpolatorList interpolators; - void read(NIFStream *nif); - void post(NIFFile *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; class NiVisController : public Controller @@ -168,19 +172,62 @@ 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 { public: + NiFloatInterpolatorPtr mInterpolator; int mTexSlot; // NiTexturingProperty::TextureType 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; +}; + +struct bhkBlendController : public Controller +{ + void read(NIFStream *nif) override; +}; + +struct Interpolator : public Record { }; + +struct NiPoint3Interpolator : public Interpolator +{ + osg::Vec3f defaultVal; + NiPosDataPtr data; + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; +}; + +struct NiBoolInterpolator : public Interpolator +{ + bool defaultVal; + NiBoolDataPtr data; + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; +}; + +struct NiFloatInterpolator : public Interpolator +{ + float defaultVal; + NiFloatDataPtr data; + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; +}; + +struct NiTransformInterpolator : public Interpolator +{ + osg::Vec3f defaultPos; + osg::Quat defaultRot; + float defaultScale; + NiKeyframeDataPtr data; + + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; }; } // Namespace diff --git a/components/nif/data.cpp b/components/nif/data.cpp index e76541d5c..415a013b3 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -6,6 +6,8 @@ namespace Nif void NiSkinInstance::read(NIFStream *nif) { data.read(nif); + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,101)) + partitions.read(nif); root.read(nif); bones.read(nif); } @@ -13,6 +15,7 @@ void NiSkinInstance::read(NIFStream *nif) void NiSkinInstance::post(NIFFile *nif) { data.post(nif); + partitions.post(nif); root.post(nif); bones.post(nif); @@ -67,19 +70,18 @@ void NiGeometryData::read(NIFStream *nif) if (nif->getBoolean()) nif->getVector4s(colors, verts); - // 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)) - { 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; + + // In Morrowind this field only corresponds to the number of UV sets. + // In later games only the first 6 bits are used as a count and the rest are flags. + if (nif->getVersion() > NIFFile::NIFVersion::VER_MW) + { + numUVs &= 0x3f; + if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0) + numUVs &= 0x1; } - if (nif->getVersion() == NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 0) - numUVs &= 0x1; bool hasUVs = true; if (nif->getVersion() <= NIFFile::NIFVersion::VER_MW) @@ -145,7 +147,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) @@ -182,7 +184,7 @@ void NiLinesData::read(NIFStream *nif) } } -void NiAutoNormalParticlesData::read(NIFStream *nif) +void NiParticlesData::read(NIFStream *nif) { NiGeometryData::read(nif); @@ -214,7 +216,7 @@ void NiAutoNormalParticlesData::read(NIFStream *nif) void NiRotatingParticlesData::read(NIFStream *nif) { - NiAutoNormalParticlesData::read(nif); + NiParticlesData::read(nif); if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0) && nif->getBoolean()) nif->getQuaternions(rotations, vertices.size()); @@ -321,7 +323,7 @@ void NiSkinData::read(NIFStream *nif) int boneNum = nif->getInt(); if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW && nif->getVersion() <= NIFStream::generateVersion(10,1,0,0)) - nif->skip(4); // NiSkinPartition link + partitions.read(nif); // Has vertex weights flag if (nif->getVersion() > NIFStream::generateVersion(4,2,1,0) && !nif->getBoolean()) @@ -346,6 +348,69 @@ void NiSkinData::read(NIFStream *nif) } } +void NiSkinData::post(NIFFile *nif) +{ + partitions.post(nif); +} + +void NiSkinPartition::read(NIFStream *nif) +{ + unsigned int num = nif->getUInt(); + data.resize(num); + for (auto& partition : data) + partition.read(nif); +} + +void NiSkinPartition::Partition::read(NIFStream *nif) +{ + unsigned short numVertices = nif->getUShort(); + unsigned short numTriangles = nif->getUShort(); + unsigned short numBones = nif->getUShort(); + unsigned short numStrips = nif->getUShort(); + unsigned short bonesPerVertex = nif->getUShort(); + if (numBones) + nif->getUShorts(bones, numBones); + + bool hasVertexMap = true; + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + hasVertexMap = nif->getBoolean(); + if (hasVertexMap && numVertices) + nif->getUShorts(vertexMap, numVertices); + + bool hasVertexWeights = true; + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + hasVertexWeights = nif->getBoolean(); + if (hasVertexWeights && numVertices && bonesPerVertex) + nif->getFloats(weights, numVertices * bonesPerVertex); + + std::vector stripLengths; + if (numStrips) + nif->getUShorts(stripLengths, numStrips); + + bool hasFaces = true; + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,0)) + hasFaces = nif->getBoolean(); + if (hasFaces) + { + if (numStrips) + { + strips.resize(numStrips); + for (unsigned short i = 0; i < numStrips; i++) + nif->getUShorts(strips[i], stripLengths[i]); + } + else if (numTriangles) + nif->getUShorts(triangles, numTriangles * 3); + } + bool hasBoneIndices = nif->getChar() != 0; + if (hasBoneIndices && numVertices && bonesPerVertex) + nif->getChars(boneIndices, numVertices * bonesPerVertex); + if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3) + { + nif->getChar(); // LOD level + nif->getBoolean(); // Global VB + } +} + void NiMorphData::read(NIFStream *nif) { int morphCount = nif->getInt(); @@ -356,7 +421,7 @@ void NiMorphData::read(NIFStream *nif) for(int i = 0;i < morphCount;i++) { mMorphs[i].mKeyFrames = std::make_shared(); - mMorphs[i].mKeyFrames->read(nif, true); + mMorphs[i].mKeyFrames->read(nif, true, /*morph*/true); nif->getVector3s(mMorphs[i].mVertices, vertCount); } } @@ -393,4 +458,17 @@ void NiPalette::read(NIFStream *nif) colors[i] = nif->getUInt() | alphaMask; } +void NiStringPalette::read(NIFStream *nif) +{ + palette = nif->getString(); + if (nif->getUInt() != palette.size()) + nif->file->warn("Failed size check in NiStringPalette"); +} + +void NiBoolData::read(NIFStream *nif) +{ + mKeyList = std::make_shared(); + mKeyList->read(nif); +} + } // Namespace diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 58d6cf755..908313f50 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,10 +67,10 @@ 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 +class NiParticlesData : public NiGeometryData { public: int numParticles{0}; @@ -81,13 +81,13 @@ public: std::vector rotations; std::vector rotationAxes; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; -class NiRotatingParticlesData : public NiAutoNormalParticlesData +class NiRotatingParticlesData : public NiParticlesData { 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,18 +167,19 @@ public: }; std::vector mVis; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiSkinInstance : public Record { public: NiSkinDataPtr data; + NiSkinPartitionPtr partitions; 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 @@ -200,8 +201,27 @@ public: Transformation trafo; std::vector bones; + NiSkinPartitionPtr partitions; - void read(NIFStream *nif); + void read(NIFStream *nif) override; + void post(NIFFile *nif) override; +}; + +struct NiSkinPartition : public Record +{ + struct Partition + { + std::vector bones; + std::vector vertexMap; + std::vector weights; + std::vector> strips; + std::vector triangles; + std::vector boneIndices; + void read(NIFStream *nif); + }; + std::vector data; + + void read(NIFStream *nif) override; }; struct NiMorphData : public Record @@ -212,7 +232,7 @@ struct NiMorphData : public Record }; std::vector mMorphs; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; @@ -228,7 +248,7 @@ struct NiKeyframeData : public Record Vector3KeyMapPtr mTranslations; FloatKeyMapPtr mScales; - void read(NIFStream *nif); + void read(NIFStream *nif) override; }; class NiPalette : public Record @@ -237,7 +257,19 @@ public: // 32-bit RGBA colors that correspond to 8-bit indices std::vector colors; - void read(NIFStream *nif); + void read(NIFStream *nif) override; +}; + +struct NiStringPalette : public Record +{ + std::string palette; + void read(NIFStream *nif) override; +}; + +struct NiBoolData : public Record +{ + ByteKeyMapPtr mKeyList; + 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.cpp b/components/nif/extra.cpp index d08e5d738..eeaf9d3ac 100644 --- a/components/nif/extra.cpp +++ b/components/nif/extra.cpp @@ -80,5 +80,11 @@ void NiFloatsExtraData::read(NIFStream *nif) nif->getFloats(data, num); } +void BSBound::read(NIFStream *nif) +{ + Extra::read(nif); + center = nif->getVector3(); + halfExtents = nif->getVector3(); +} } diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 0e8cc16bf..5d7aa0c3b 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,63 @@ 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; +}; + +struct BSBound : public Extra +{ + osg::Vec3f center, halfExtents; + + void read(NIFStream *nif) override; }; } // Namespace diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 8d65753d2..67c864f47 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -1,6 +1,7 @@ #include "niffile.hpp" #include "effect.hpp" +#include #include #include @@ -46,8 +47,9 @@ static std::map makeFactory() 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["NiParticles"] = {&construct , RC_NiParticles }; + factory["NiRotatingParticles"] = {&construct , RC_NiParticles }; + factory["NiAutoNormalParticles"] = {&construct , RC_NiParticles }; factory["NiCamera"] = {&construct , RC_NiCamera }; factory["RootCollisionNode"] = {&construct , RC_RootCollisionNode }; factory["NiTexturingProperty"] = {&construct , RC_NiTexturingProperty }; @@ -98,8 +100,9 @@ static std::map makeFactory() 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["NiParticlesData"] = {&construct , RC_NiParticlesData }; + factory["NiRotatingParticlesData"] = {&construct , RC_NiParticlesData }; + factory["NiAutoNormalParticlesData"] = {&construct , RC_NiParticlesData }; factory["NiSequenceStreamHelper"] = {&construct , RC_NiSequenceStreamHelper }; factory["NiSourceTexture"] = {&construct , RC_NiSourceTexture }; factory["NiSkinInstance"] = {&construct , RC_NiSkinInstance }; @@ -113,6 +116,19 @@ static std::map makeFactory() factory["NiColorExtraData"] = {&construct , RC_NiColorExtraData }; factory["NiFloatExtraData"] = {&construct , RC_NiFloatExtraData }; factory["NiFloatsExtraData"] = {&construct , RC_NiFloatsExtraData }; + factory["NiStringPalette"] = {&construct , RC_NiStringPalette }; + factory["NiBoolData"] = {&construct , RC_NiBoolData }; + factory["NiSkinPartition"] = {&construct , RC_NiSkinPartition }; + factory["BSXFlags"] = {&construct , RC_BSXFlags }; + factory["BSBound"] = {&construct , RC_BSBound }; + factory["NiTransformData"] = {&construct , RC_NiKeyframeData }; + factory["BSFadeNode"] = {&construct , RC_NiNode }; + factory["bhkBlendController"] = {&construct , RC_bhkBlendController }; + factory["NiFloatInterpolator"] = {&construct , RC_NiFloatInterpolator }; + factory["NiBoolInterpolator"] = {&construct , RC_NiBoolInterpolator }; + factory["NiPoint3Interpolator"] = {&construct , RC_NiPoint3Interpolator }; + factory["NiTransformController"] = {&construct , RC_NiKeyframeController }; + factory["NiTransformInterpolator"] = {&construct , RC_NiTransformInterpolator }; return factory; } @@ -137,15 +153,45 @@ void NIFFile::parse(Files::IStreamPtr stream) // Check the header string std::string head = nif.getVersionString(); - if(head.compare(0, 22, "NetImmerse File Format") != 0) + static const std::array verStrings = + { + "NetImmerse File Format", + "Gamebryo File Format" + }; + bool supported = false; + for (const std::string& verString : verStrings) + { + supported = (head.compare(0, verString.size(), verString) == 0); + if (supported) + break; + } + if (!supported) fail("Invalid NIF header: " + head); + supported = false; + // Get BCD version ver = nif.getUInt(); // 4.0.0.0 is an older, practically identical version of the format. // 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)); + static const std::array supportedVers = + { + NIFStream::generateVersion(4,0,0,0), + VER_MW + }; + for (uint32_t supportedVer : supportedVers) + { + supported = (ver == supportedVer); + if (supported) + break; + } + if (!supported) + { + if (sLoadUnsupportedFiles) + warn("Unsupported NIF version: " + printVersion(ver) + ". Proceed with caution!"); + else + fail("Unsupported NIF version: " + printVersion(ver)); + } // NIF data endianness if (ver >= NIFStream::generateVersion(20,0,0,4)) @@ -160,7 +206,7 @@ void NIFFile::parse(Files::IStreamPtr stream) userVer = nif.getUInt(); // Number of records - size_t recNum = nif.getUInt(); + unsigned int recNum = nif.getUInt(); records.resize(recNum); // Bethesda stream header @@ -212,7 +258,7 @@ void NIFFile::parse(Files::IStreamPtr stream) } 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++) + for (unsigned int i = 0; i < recNum; i++) { Record *r = nullptr; @@ -245,6 +291,9 @@ void NIFFile::parse(Files::IStreamPtr stream) else fail("Unknown record type " + rec); + if (!supported) + Log(Debug::Verbose) << "NIF Debug: Reading record of type " << rec << ", index " << i << " (" << filename << ")"; + assert(r != nullptr); assert(r->recType != RC_MISSING); r->recName = rec; @@ -253,11 +302,11 @@ void NIFFile::parse(Files::IStreamPtr stream) r->read(&nif); } - size_t rootNum = nif.getUInt(); + unsigned int rootNum = nif.getUInt(); roots.resize(rootNum); //Determine which records are roots - for(size_t i = 0;i < rootNum;i++) + for (unsigned int i = 0; i < rootNum; i++) { int idx = nif.getInt(); if (idx >= 0 && idx < int(records.size())) @@ -286,4 +335,11 @@ bool NIFFile::getUseSkinning() const return mUseSkinning; } +bool NIFFile::sLoadUnsupportedFiles = false; + +void NIFFile::setLoadUnsupportedFiles(bool load) +{ + sLoadUnsupportedFiles = load; +} + } diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index 9d8edac26..c6dd8af75 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -62,6 +62,8 @@ class NIFFile final : public File bool mUseSkinning = false; + static bool sLoadUnsupportedFiles; + /// Parse the file void parse(Files::IStreamPtr stream); @@ -149,6 +151,8 @@ public: /// Get the Bethesda version of the NIF format used unsigned int getBethVersion() const override { return bethVer; } + + static void setLoadUnsupportedFiles(bool load); }; using NIFFilePtr = std::shared_ptr; diff --git a/components/nif/nifkey.hpp b/components/nif/nifkey.hpp index 4c10327e1..de2fa31c8 100644 --- a/components/nif/nifkey.hpp +++ b/components/nif/nifkey.hpp @@ -52,16 +52,27 @@ struct KeyMapT { MapType mKeys; //Read in a KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html) - void read(NIFStream *nif, bool force=false) + void read(NIFStream *nif, bool force = false, bool morph = false) { assert(nif); mInterpolationType = InterpolationType_Unknown; + if (morph && nif->getVersion() >= NIFStream::generateVersion(10,1,0,106)) + nif->getString(); // Frame name + size_t count = nif->getUInt(); - if(count == 0 && !force) + if (count == 0 && !force && !morph) return; + if (morph && nif->getVersion() > NIFStream::generateVersion(10,1,0,0)) + { + if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,104) && + nif->getVersion() <= NIFStream::generateVersion(20,1,0,2) && nif->getBethVersion() < 10) + nif->getFloat(); // Legacy weight + return; + } + mKeys.clear(); mInterpolationType = nif->getUInt(); diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 4c57b2e81..58397bdca 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -16,6 +16,117 @@ namespace Nif struct NiNode; +struct NiBoundingVolume +{ + enum Type + { + SPHERE_BV = 0, + BOX_BV = 1, + CAPSULE_BV = 2, + LOZENGE_BV = 3, + UNION_BV = 4, + HALFSPACE_BV = 5 + }; + + struct NiSphereBV + { + osg::Vec3f center; + float radius{0.f}; + }; + + struct NiBoxBV + { + osg::Vec3f center; + Matrix3 axis; + osg::Vec3f extents; + }; + + struct NiCapsuleBV + { + osg::Vec3f center, axis; + float extent{0.f}, radius{0.f}; + }; + + struct NiLozengeBV + { + float radius{0.f}, extent0{0.f}, extent1{0.f}; + osg::Vec3f center, axis0, axis1; + }; + + struct NiHalfSpaceBV + { + osg::Vec3f center, normal; + }; + + unsigned int type; + NiSphereBV sphere; + NiBoxBV box; + NiCapsuleBV capsule; + NiLozengeBV lozenge; + std::vector children; + NiHalfSpaceBV plane; + void read(NIFStream* nif) + { + type = nif->getUInt(); + switch (type) + { + case SPHERE_BV: + { + sphere.center = nif->getVector3(); + sphere.radius = nif->getFloat(); + break; + } + case BOX_BV: + { + box.center = nif->getVector3(); + box.axis = nif->getMatrix3(); + box.extents = nif->getVector3(); + break; + } + case CAPSULE_BV: + { + capsule.center = nif->getVector3(); + capsule.axis = nif->getVector3(); + capsule.extent = nif->getFloat(); + capsule.radius = nif->getFloat(); + break; + } + case LOZENGE_BV: + { + lozenge.radius = nif->getFloat(); + lozenge.extent0 = nif->getFloat(); + lozenge.extent1 = nif->getFloat(); + lozenge.center = nif->getVector3(); + lozenge.axis0 = nif->getVector3(); + lozenge.axis1 = nif->getVector3(); + break; + } + case UNION_BV: + { + unsigned int numChildren = nif->getUInt(); + if (numChildren == 0) + break; + children.resize(numChildren); + for (NiBoundingVolume& child : children) + child.read(nif); + break; + } + case HALFSPACE_BV: + { + plane.center = nif->getVector3(); + plane.normal = nif->getVector3(); + break; + } + default: + { + std::stringstream error; + error << "Unhandled NiBoundingVolume type: " << type; + nif->file->fail(error.str()); + } + } + } +}; + /** A Node is an object that's part of the main NIF tree. It has parent node (unless it's the root), and transformation (location and rotation) relative to it's parent. @@ -31,11 +142,9 @@ public: // Bounding box info bool hasBounds{false}; - osg::Vec3f boundPos; - Matrix3 boundRot; - osg::Vec3f boundXYZ; // Box size + NiBoundingVolume bounds; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Named::read(nif); @@ -48,13 +157,8 @@ public: if (nif->getVersion() <= NIFStream::generateVersion(4,2,2,0)) hasBounds = nif->getBoolean(); - if(hasBounds) - { - nif->getInt(); // always 1 - boundPos = nif->getVector3(); - boundRot = nif->getMatrix3(); - boundXYZ = nif->getVector3(); - } + if (hasBounds) + bounds.read(nif); // Reference to the collision object in Gamebryo files. if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) nif->skip(4); @@ -64,7 +168,7 @@ public: isBone = false; } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Named::post(nif); props.post(nif); @@ -104,7 +208,7 @@ struct NiNode : Node ControllerFlag_Active = 0x8 }; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); children.read(nif); @@ -120,7 +224,7 @@ struct NiNode : Node } } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); children.post(nif); @@ -183,7 +287,7 @@ struct NiTriShape : NiGeometry NiTriShapeDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); @@ -191,7 +295,7 @@ struct NiTriShape : NiGeometry materialData.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -205,7 +309,7 @@ struct NiTriStrips : NiGeometry { NiTriStripsDataPtr data; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); @@ -213,7 +317,7 @@ struct NiTriStrips : NiGeometry materialData.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); @@ -227,14 +331,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 +388,7 @@ struct NiCamera : Node }; Camera cam; - void read(NIFStream *nif) + void read(NIFStream *nif) override { Node::read(nif); @@ -297,39 +401,22 @@ struct NiCamera : Node } }; -struct NiAutoNormalParticles : Node -{ - NiAutoNormalParticlesDataPtr data; - - void read(NIFStream *nif) - { - Node::read(nif); - data.read(nif); - nif->getInt(); // -1 - } - - void post(NIFFile *nif) - { - Node::post(nif); - data.post(nif); - } -}; - -struct NiRotatingParticles : Node +struct NiParticles : NiGeometry { - NiRotatingParticlesDataPtr data; - - void read(NIFStream *nif) + NiParticlesDataPtr data; + void read(NIFStream *nif) override { Node::read(nif); data.read(nif); - nif->getInt(); // -1 + skin.read(nif); + materialData.read(nif); } - void post(NIFFile *nif) + void post(NIFFile *nif) override { Node::post(nif); data.post(nif); + skin.post(nif); } }; @@ -339,7 +426,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 +446,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/nif/record.hpp b/components/nif/record.hpp index f9bb613a0..2217c588e 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -44,8 +44,7 @@ enum RecordType RC_NiTriShape, RC_NiTriStrips, RC_NiLines, - RC_NiRotatingParticles, - RC_NiAutoNormalParticles, + RC_NiParticles, RC_NiBSParticleNode, RC_NiCamera, RC_NiTexturingProperty, @@ -94,7 +93,7 @@ enum RecordType RC_NiUVData, RC_NiPosData, RC_NiRotatingParticlesData, - RC_NiAutoNormalParticlesData, + RC_NiParticlesData, RC_NiSequenceStreamHelper, RC_NiSourceTexture, RC_NiSkinInstance, @@ -109,18 +108,28 @@ enum RecordType RC_NiVectorExtraData, RC_NiColorExtraData, RC_NiFloatExtraData, - RC_NiFloatsExtraData + RC_NiFloatsExtraData, + RC_NiStringPalette, + RC_NiBoolData, + RC_NiSkinPartition, + RC_BSXFlags, + RC_BSBound, + RC_bhkBlendController, + RC_NiFloatInterpolator, + RC_NiPoint3Interpolator, + RC_NiBoolInterpolator, + RC_NiTransformInterpolator }; /// Base class for all records struct Record { // Record type and type name - int recType; + int recType{RC_MISSING}; std::string recName; - size_t recIndex; + unsigned int recIndex{~0u}; - Record() : recType(RC_MISSING), recIndex(~(size_t)0) {} + Record() = default; /// Parses the record from file virtual void read(NIFStream *nif) = 0; diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index 57607cb6a..ed8f7ef6b 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -138,11 +138,15 @@ class NiTriShapeData; class NiTriStripsData; class NiSkinInstance; class NiSourceTexture; -class NiRotatingParticlesData; -class NiAutoNormalParticlesData; +class NiParticlesData; class NiPalette; struct NiParticleModifier; struct NiLinesData; +struct NiBoolData; +struct NiSkinPartition; +struct NiFloatInterpolator; +struct NiPoint3Interpolator; +struct NiTransformInterpolator; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -162,15 +166,20 @@ using NiTriStripsDataPtr = RecordPtrT; using NiLinesDataPtr = RecordPtrT; using NiSkinInstancePtr = RecordPtrT; using NiSourceTexturePtr = RecordPtrT; -using NiRotatingParticlesDataPtr = RecordPtrT; -using NiAutoNormalParticlesDataPtr = RecordPtrT; +using NiParticlesDataPtr = RecordPtrT; using NiPalettePtr = RecordPtrT; using NiParticleModifierPtr = RecordPtrT; +using NiBoolDataPtr = RecordPtrT; +using NiSkinPartitionPtr = RecordPtrT; +using NiFloatInterpolatorPtr = RecordPtrT; +using NiPoint3InterpolatorPtr = RecordPtrT; +using NiTransformInterpolatorPtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT; using ExtraList = RecordListT; using NiSourceTextureList = RecordListT; +using NiFloatInterpolatorList = RecordListT; } // Namespace #endif diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 15834ffad..db9d5ae43 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -8,6 +8,7 @@ #include +#include #include #include @@ -24,11 +25,6 @@ osg::Matrixf getWorldTransform(const Nif::Node *node) return node->trafo.toMatrix(); } -btVector3 getbtVector(const osg::Vec3f &v) -{ - return btVector3(v.x(), v.y(), v.z()); -} - bool pathFileNameStartsWithX(const std::string& path) { const std::size_t slashpos = path.find_last_of("/\\"); @@ -36,7 +32,7 @@ bool pathFileNameStartsWithX(const std::string& path) return letterPos < path.size() && (path[letterPos] == 'x' || path[letterPos] == 'X'); } -void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriShapeData& data, const osg::Matrixf &transform) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriShapeData& data, const osg::Matrixf &transform) { mesh.preallocateVertices(static_cast(data.vertices.size())); mesh.preallocateIndices(static_cast(data.triangles.size())); @@ -47,20 +43,20 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriShapeDa for (std::size_t i = 0; i < triangles.size(); i += 3) { mesh.addTriangle( - getbtVector(vertices[triangles[i + 0]] * transform), - getbtVector(vertices[triangles[i + 1]] * transform), - getbtVector(vertices[triangles[i + 2]] * transform) + Misc::Convert::toBullet(vertices[triangles[i + 0]] * transform), + Misc::Convert::toBullet(vertices[triangles[i + 1]] * transform), + Misc::Convert::toBullet(vertices[triangles[i + 2]] * transform) ); } } -void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, const osg::Matrixf &transform) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, const osg::Matrixf &transform) { const std::vector &vertices = data.vertices; const std::vector> &strips = data.strips; if (vertices.empty() || strips.empty()) return; - mesh.preallocateVertices(static_cast(data.vertices.size())); + mesh.preallocateVertices(static_cast(vertices.size())); int numTriangles = 0; for (const std::vector& strip : strips) { @@ -88,17 +84,17 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD if (i%2==0) { mesh.addTriangle( - getbtVector(vertices[a] * transform), - getbtVector(vertices[b] * transform), - getbtVector(vertices[c] * transform) + Misc::Convert::toBullet(vertices[a] * transform), + Misc::Convert::toBullet(vertices[b] * transform), + Misc::Convert::toBullet(vertices[c] * transform) ); } else { mesh.addTriangle( - getbtVector(vertices[a] * transform), - getbtVector(vertices[c] * transform), - getbtVector(vertices[b] * transform) + Misc::Convert::toBullet(vertices[a] * transform), + Misc::Convert::toBullet(vertices[c] * transform), + Misc::Convert::toBullet(vertices[b] * transform) ); } } @@ -106,17 +102,12 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD } } -void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::Node* nifNode, const osg::Matrixf &transform) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* nifNode, const osg::Matrixf &transform = osg::Matrixf()) { if (nifNode->recType == Nif::RC_NiTriShape) - fillTriangleMeshWithTransform(mesh, static_cast(nifNode)->data.get(), transform); - else // if (nifNode->recType == Nif::RC_NiTriStrips) - fillTriangleMeshWithTransform(mesh, static_cast(nifNode)->data.get(), transform); -} - -void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* node) -{ - fillTriangleMeshWithTransform(mesh, node, osg::Matrixf()); + fillTriangleMesh(mesh, static_cast(nifNode)->data.get(), transform); + else if (nifNode->recType == Nif::RC_NiTriStrips) + fillTriangleMesh(mesh, static_cast(nifNode)->data.get(), transform); } } @@ -132,81 +123,102 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) mStaticMesh.reset(); mAvoidStaticMesh.reset(); - Nif::Node* node = nullptr; const size_t numRoots = nif.numRoots(); + std::vector roots; for (size_t i = 0; i < numRoots; ++i) { Nif::Record* r = nif.getRoot(i); assert(r != nullptr); + Nif::Node* node = nullptr; if ((node = dynamic_cast(r))) - break; + roots.emplace_back(node); } - if (!node) + const std::string filename = nif.getFilename(); + if (roots.empty()) { - warn("Found no root nodes in NIF."); + warn("Found no root nodes in NIF file " + filename); return mShape; } - if (findBoundingBox(node)) + // Try to find a valid bounding box first. If one's found for any root node, use that. + for (const Nif::Node* node : roots) { - std::unique_ptr compound (new btCompoundShape); - std::unique_ptr boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents))); - btTransform transform = btTransform::getIdentity(); - transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate)); - compound->addChildShape(transform, boxShape.get()); - boxShape.release(); - - mShape->mCollisionShape = compound.release(); - return mShape; + if (findBoundingBox(node, filename)) + { + const btVector3 halfExtents = Misc::Convert::toBullet(mShape->mCollisionBoxHalfExtents); + const btVector3 origin = Misc::Convert::toBullet(mShape->mCollisionBoxTranslate); + std::unique_ptr compound (new btCompoundShape); + std::unique_ptr boxShape(new btBoxShape(halfExtents)); + btTransform transform = btTransform::getIdentity(); + transform.setOrigin(origin); + compound->addChildShape(transform, boxShape.get()); + boxShape.release(); + + mShape->mCollisionShape = compound.release(); + return mShape; + } } - else + // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource). + // assume all nodes in the file will be animated + const bool isAnimated = pathFileNameStartsWithX(filename); + + // If there's no bounding box, we'll have to generate a Bullet collision shape + // from the collision data present in every root node. + for (const Nif::Node* node : roots) { bool autogenerated = hasAutoGeneratedCollision(node); - - // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource). - // assume all nodes in the file will be animated - const auto filename = nif.getFilename(); - const bool isAnimated = pathFileNameStartsWithX(filename); - handleNode(filename, node, 0, autogenerated, isAnimated, autogenerated); + } - if (mCompoundShape) - { - if (mStaticMesh) - { - btTransform trans; - trans.setIdentity(); - std::unique_ptr child(new Resource::TriangleMeshShape(mStaticMesh.get(), true)); - mCompoundShape->addChildShape(trans, child.get()); - child.release(); - mStaticMesh.release(); - } - mShape->mCollisionShape = mCompoundShape.release(); - } - else if (mStaticMesh) + if (mCompoundShape) + { + if (mStaticMesh) { - mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh.get(), true); + btTransform trans; + trans.setIdentity(); + std::unique_ptr child(new Resource::TriangleMeshShape(mStaticMesh.get(), true)); + mCompoundShape->addChildShape(trans, child.get()); + child.release(); mStaticMesh.release(); } + mShape->mCollisionShape = mCompoundShape.release(); + } + else if (mStaticMesh) + { + mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh.get(), true); + mStaticMesh.release(); + } - if (mAvoidStaticMesh) - { - mShape->mAvoidCollisionShape = new Resource::TriangleMeshShape(mAvoidStaticMesh.get(), false); - mAvoidStaticMesh.release(); - } - - return mShape; + if (mAvoidStaticMesh) + { + mShape->mAvoidCollisionShape = new Resource::TriangleMeshShape(mAvoidStaticMesh.get(), false); + mAvoidStaticMesh.release(); } + + return mShape; } // Find a boundingBox in the node hierarchy. // Return: use bounding box for collision? -bool BulletNifLoader::findBoundingBox(const Nif::Node* node) +bool BulletNifLoader::findBoundingBox(const Nif::Node* node, const std::string& filename) { if (node->hasBounds) { - mShape->mCollisionBoxHalfExtents = node->boundXYZ; - mShape->mCollisionBoxTranslate = node->boundPos; + unsigned int type = node->bounds.type; + switch (type) + { + case Nif::NiBoundingVolume::Type::BOX_BV: + mShape->mCollisionBoxHalfExtents = node->bounds.box.extents; + mShape->mCollisionBoxTranslate = node->bounds.box.center; + break; + default: + { + std::stringstream warning; + warning << "Unsupported NiBoundingVolume type " << type << " in node " << node->recIndex; + warning << " in file " << filename; + warn(warning.str()); + } + } if (node->flags & Nif::NiNode::Flag_BBoxCollision) { @@ -222,8 +234,7 @@ bool BulletNifLoader::findBoundingBox(const Nif::Node* node) { if(!list[i].empty()) { - bool found = findBoundingBox (list[i].getPtr()); - if (found) + if (findBoundingBox(list[i].getPtr(), filename)) return true; } } @@ -383,7 +394,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons if (!mAvoidStaticMesh) mAvoidStaticMesh.reset(new btTriangleMesh(false)); - fillTriangleMeshWithTransform(*mAvoidStaticMesh, nifNode, transform); + fillTriangleMesh(*mAvoidStaticMesh, nifNode, transform); } else { @@ -391,7 +402,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons mStaticMesh.reset(new btTriangleMesh(false)); // Static shape, just transform all vertices into position - fillTriangleMeshWithTransform(*mStaticMesh, nifNode, transform); + fillTriangleMesh(*mStaticMesh, nifNode, transform); } } diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index e423e5149..054b33fed 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -40,7 +40,7 @@ class BulletNifLoader public: void warn(const std::string &msg) { - Log(Debug::Warning) << "NIFLoader: Warn:" << msg; + Log(Debug::Warning) << "NIFLoader: Warn: " << msg; } void fail(const std::string &msg) @@ -52,7 +52,7 @@ public: osg::ref_ptr load(const Nif::File& file); private: - bool findBoundingBox(const Nif::Node* node); + bool findBoundingBox(const Nif::Node* node, const std::string& filename); void handleNode(const std::string& fileName, Nif::Node const *node, int flags, bool isCollisionNode, bool isAnimated=false, bool autogenerated=false, bool avoid=false); diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 0f4c4a5bd..31fd92b43 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -71,8 +71,7 @@ KeyframeController::KeyframeController() } KeyframeController::KeyframeController(const KeyframeController ©, const osg::CopyOp ©op) - : osg::NodeCallback(copy, copyop) - , Controller(copy) + : SceneUtil::KeyframeController(copy, copyop) , mRotations(copy.mRotations) , mXRotations(copy.mXRotations) , mYRotations(copy.mYRotations) @@ -92,6 +91,26 @@ KeyframeController::KeyframeController(const Nif::NiKeyframeData *data) { } +KeyframeController::KeyframeController(const Nif::NiTransformInterpolator* interpolator) + : mRotations(interpolator->data->mRotations, interpolator->defaultRot) + , mXRotations(interpolator->data->mXRotations, 0.f) + , mYRotations(interpolator->data->mYRotations, 0.f) + , mZRotations(interpolator->data->mZRotations, 0.f) + , mTranslations(interpolator->data->mTranslations, interpolator->defaultPos) + , mScales(interpolator->data->mScales, interpolator->defaultScale) +{ +} + +KeyframeController::KeyframeController(const float scale, const osg::Vec3f& pos, const osg::Quat& rot) + : mRotations(Nif::QuaternionKeyMapPtr(), rot) + , mXRotations(Nif::FloatKeyMapPtr(), 0.f) + , mYRotations(Nif::FloatKeyMapPtr(), 0.f) + , mZRotations(Nif::FloatKeyMapPtr(), 0.f) + , mTranslations(Nif::Vector3KeyMapPtr(), pos) + , mScales(Nif::FloatKeyMapPtr(), scale) +{ +} + osg::Quat KeyframeController::getXYZRotation(float time) const { float xrot = 0, yrot = 0, zrot = 0; @@ -177,10 +196,25 @@ GeomMorpherController::GeomMorpherController(const GeomMorpherController ©, { } -GeomMorpherController::GeomMorpherController(const Nif::NiMorphData *data) +GeomMorpherController::GeomMorpherController(const Nif::NiGeomMorpherController* ctrl) { - for (unsigned int i=0; imMorphs.size(); ++i) - mKeyFrames.push_back(FloatInterpolator(data->mMorphs[i].mKeyFrames)); + if (ctrl->interpolators.length() == 0) + { + if (ctrl->data.empty()) + return; + for (const auto& morph : ctrl->data->mMorphs) + mKeyFrames.emplace_back(morph.mKeyFrames); + } + else + { + for (size_t i = 0; i < ctrl->interpolators.length(); ++i) + { + if (!ctrl->interpolators[i].empty()) + mKeyFrames.emplace_back(ctrl->interpolators[i].getPtr()); + else + mKeyFrames.emplace_back(); + } + } } void GeomMorpherController::update(osg::NodeVisitor *nv, osg::Drawable *drawable) @@ -313,6 +347,11 @@ RollController::RollController(const Nif::NiFloatData *data) { } +RollController::RollController(const Nif::NiFloatInterpolator* interpolator) + : mData(interpolator) +{ +} + RollController::RollController(const RollController ©, const osg::CopyOp ©op) : osg::NodeCallback(copy, copyop) , Controller(copy) @@ -344,6 +383,10 @@ void RollController::operator() (osg::Node* node, osg::NodeVisitor* nv) } } +AlphaController::AlphaController() +{ +} + AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial) : mData(data->mKeyList, 1.f) , mBaseMaterial(baseMaterial) @@ -351,7 +394,9 @@ AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Materi } -AlphaController::AlphaController() +AlphaController::AlphaController(const Nif::NiFloatInterpolator* interpolator, const osg::Material* baseMaterial) + : mData(interpolator) + , mBaseMaterial(baseMaterial) { } @@ -379,6 +424,10 @@ void AlphaController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) } } +MaterialColorController::MaterialColorController() +{ +} + MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial) : mData(data->mKeyList, osg::Vec3f(1,1,1)) , mTargetColor(color) @@ -386,7 +435,10 @@ MaterialColorController::MaterialColorController(const Nif::NiPosData *data, Tar { } -MaterialColorController::MaterialColorController() +MaterialColorController::MaterialColorController(const Nif::NiPoint3Interpolator* interpolator, TargetColor color, const osg::Material* baseMaterial) + : mData(interpolator) + , mTargetColor(color) + , mBaseMaterial(baseMaterial) { } @@ -448,6 +500,8 @@ FlipController::FlipController(const Nif::NiFlipController *ctrl, const std::vec , mDelta(ctrl->mDelta) , mTextures(textures) { + if (!ctrl->mInterpolator.empty()) + mData = ctrl->mInterpolator.getPtr(); } FlipController::FlipController(int texSlot, float delta, const std::vector >& textures) @@ -463,14 +517,19 @@ FlipController::FlipController(const FlipController ©, const osg::CopyOp &co , mTexSlot(copy.mTexSlot) , mDelta(copy.mDelta) , mTextures(copy.mTextures) + , mData(copy.mData) { } void FlipController::apply(osg::StateSet* stateset, osg::NodeVisitor* nv) { - if (hasInput() && mDelta != 0 && !mTextures.empty()) + if (hasInput() && !mTextures.empty()) { - int curTexture = int(getInputValue(nv) / mDelta) % mTextures.size(); + int curTexture = 0; + if (mDelta != 0) + curTexture = int(getInputValue(nv) / mDelta) % mTextures.size(); + else + curTexture = int(mData.interpKey(getInputValue(nv))) % mTextures.size(); stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]); } } diff --git a/components/nifosg/controller.hpp b/components/nifosg/controller.hpp index a93dd28eb..0063b2ec0 100644 --- a/components/nifosg/controller.hpp +++ b/components/nifosg/controller.hpp @@ -6,10 +6,11 @@ #include #include -#include +#include #include #include +#include #include @@ -59,6 +60,31 @@ namespace NifOsg ValueInterpolator() = default; + template< + class T, + typename = std::enable_if_t< + std::conjunction_v< + std::disjunction< + std::is_same, + std::is_same + >, + std::is_same + >, + T + > + > + ValueInterpolator(const T* interpolator) : mDefaultVal(interpolator->defaultVal) + { + if (interpolator->data.empty()) + return; + mKeys = interpolator->data->mKeyList; + if (mKeys) + { + mLastLowKey = mKeys->mKeys.end(); + mLastHighKey = mKeys->mKeys.end(); + } + } + ValueInterpolator(std::shared_ptr keys, ValueT defaultVal = ValueT()) : mKeys(keys) , mDefaultVal(defaultVal) @@ -179,39 +205,46 @@ 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. class GeomMorpherController : public osg::Drawable::UpdateCallback, public SceneUtil::Controller { public: - GeomMorpherController(const Nif::NiMorphData* data); + GeomMorpherController(const Nif::NiGeomMorpherController* ctrl); GeomMorpherController(); GeomMorpherController(const GeomMorpherController& copy, const osg::CopyOp& copyop); 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; }; - class KeyframeController : public osg::NodeCallback, public SceneUtil::Controller + class KeyframeController : public SceneUtil::KeyframeController { public: + // This is used if there's no interpolator but there is data (Morrowind meshes). KeyframeController(const Nif::NiKeyframeData *data); + // This is used if the interpolator has data. + KeyframeController(const Nif::NiTransformInterpolator* interpolator); + // This is used if there are default values available (e.g. from a data-less interpolator). + // If there's neither keyframe data nor an interpolator a KeyframeController must not be created. + KeyframeController(const float scale, const osg::Vec3f& pos, const osg::Quat& rot); + KeyframeController(); KeyframeController(const KeyframeController& copy, const osg::CopyOp& copyop); META_Object(NifOsg, KeyframeController) - virtual osg::Vec3f getTranslation(float time) const; + osg::Vec3f getTranslation(float time) const override; - virtual void operator() (osg::Node*, osg::NodeVisitor*); + void operator() (osg::Node*, osg::NodeVisitor*) override; private: QuaternionInterpolator mRotations; @@ -235,8 +268,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 +294,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 @@ -272,10 +305,11 @@ namespace NifOsg public: RollController(const Nif::NiFloatData *data); + RollController(const Nif::NiFloatInterpolator* interpolator); 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) }; @@ -287,12 +321,13 @@ namespace NifOsg osg::ref_ptr mBaseMaterial; public: AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial); + AlphaController(const Nif::NiFloatInterpolator* interpolator, const osg::Material* baseMaterial); 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) }; @@ -308,14 +343,15 @@ namespace NifOsg Emissive = 3 }; MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial); + MaterialColorController(const Nif::NiPoint3Interpolator* interpolator, TargetColor color, const osg::Material* baseMaterial); MaterialColorController(); MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop); 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; @@ -329,6 +365,7 @@ namespace NifOsg int mTexSlot{0}; float mDelta{0.f}; std::vector > mTextures; + FloatInterpolator mData; public: FlipController(const Nif::NiFlipController* ctrl, const std::vector >& textures); @@ -340,7 +377,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 +389,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 +405,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 4a2dac36c..0db15237e 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -43,7 +43,6 @@ #include #include "matrixtransform.hpp" -#include "nodeindexholder.hpp" #include "particle.hpp" namespace @@ -61,6 +60,18 @@ namespace } } + bool isTypeGeometry(int type) + { + switch (type) + { + case Nif::RC_NiTriShape: + case Nif::RC_NiTriStrips: + case Nif::RC_NiLines: + return true; + } + return false; + } + // Collect all properties affecting the given drawable that should be handled on drawable basis rather than on the node hierarchy above it. void collectDrawableProperties(const Nif::Node* nifNode, std::vector& out) { @@ -102,7 +113,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); @@ -128,7 +139,7 @@ namespace } }; - void extractTextKeys(const Nif::NiTextKeyExtraData *tk, NifOsg::TextKeyMap &textkeys) + void extractTextKeys(const Nif::NiTextKeyExtraData *tk, SceneUtil::TextKeyMap &textkeys) { for(size_t i = 0;i < tk->list.size();i++) { @@ -220,10 +231,13 @@ namespace NifOsg size_t mFirstRootTextureIndex = -1; bool mFoundFirstRootTexturingProperty = false; + bool mHasNightDayLabel = false; + bool mHasHerbalismLabel = false; + // This is used to queue emitters that weren't attached to their node yet. std::vector>> mEmitterQueue; - static void loadKf(Nif::NIFFilePtr nif, KeyframeHolder& target) + static void loadKf(Nif::NIFFilePtr nif, SceneUtil::KeyframeHolder& target) { const Nif::NiSequenceStreamHelper *seq = nullptr; const size_t numRoots = nif->numRoots(); @@ -270,10 +284,10 @@ namespace NifOsg const Nif::NiStringExtraData *strdata = static_cast(extra.getPtr()); const Nif::NiKeyframeController *key = static_cast(ctrl.getPtr()); - if(key->data.empty()) + if (key->data.empty() && key->interpolator.empty()) continue; - osg::ref_ptr callback(new NifOsg::KeyframeController(key->data.getPtr())); + osg::ref_ptr callback(handleKeyframeController(key)); callback->setFunction(std::shared_ptr(new NifOsg::ControllerFunction(key))); if (!target.mKeyframeControllers.emplace(strdata->string, callback).second) @@ -283,20 +297,31 @@ namespace NifOsg osg::ref_ptr load(Nif::NIFFilePtr nif, Resource::ImageManager* imageManager) { - const Nif::Node* nifNode = nullptr; const size_t numRoots = nif->numRoots(); + std::vector roots; for (size_t i = 0; i < numRoots; ++i) { const Nif::Record* r = nif->getRoot(i); + const Nif::Node* nifNode = nullptr; if ((nifNode = dynamic_cast(r))) - break; + roots.emplace_back(nifNode); } - if (!nifNode) + if (roots.empty()) nif->fail("Found no root nodes"); - osg::ref_ptr textkeys (new TextKeyMapHolder); + osg::ref_ptr textkeys (new SceneUtil::TextKeyMapHolder); - osg::ref_ptr created = handleNode(nifNode, nullptr, imageManager, std::vector(), 0, false, false, false, &textkeys->mTextKeys); + osg::ref_ptr created(new osg::Group); + created->setDataVariance(osg::Object::STATIC); + for (const Nif::Node* root : roots) + { + auto node = handleNode(root, nullptr, imageManager, std::vector(), 0, false, false, false, &textkeys->mTextKeys); + created->addChild(node); + } + if (mHasNightDayLabel) + created->getOrCreateUserDataContainer()->addDescription(Constants::NightDayLabel); + if (mHasHerbalismLabel) + created->getOrCreateUserDataContainer()->addDescription(Constants::HerbalismLabel); // Attach particle emitters to their nodes which should all be loaded by now. handleQueuedParticleEmitters(created, nif); @@ -304,18 +329,11 @@ namespace NifOsg if (nif->getUseSkinning()) { osg::ref_ptr skel = new SceneUtil::Skeleton; - - osg::Group* root = created->asGroup(); - if (root && root->getDataVariance() == osg::Object::STATIC && !root->asTransform()) - { - skel->setStateSet(root->getStateSet()); - skel->setName(root->getName()); - for (unsigned int i=0; igetNumChildren(); ++i) - skel->addChild(root->getChild(i)); - root->removeChildren(0, root->getNumChildren()); - } - else - skel->addChild(created); + skel->setStateSet(created->getStateSet()); + skel->setName(created->getName()); + for (unsigned int i=0; i < created->getNumChildren(); ++i) + skel->addChild(created->getChild(i)); + created->removeChildren(0, created->getNumChildren()); created = skel; } @@ -342,10 +360,10 @@ namespace NifOsg else if (props[i].getPtr()->recType == Nif::RC_NiTexturingProperty) { if (props[i].getPtr()->recIndex == mFirstRootTextureIndex) - applyTo->setUserValue("overrideFx", 1); + applyTo->setUserValue("overrideFx", 1); } handleProperty(props[i].getPtr(), applyTo, composite, imageManager, boundTextures, animflags); - } + } } } @@ -503,7 +521,7 @@ namespace NifOsg } osg::ref_ptr handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::ImageManager* imageManager, - std::vector boundTextures, int animflags, bool skipMeshes, bool hasMarkers, bool hasAnimatedParents, TextKeyMap* textKeys, osg::Node* rootNode=nullptr) + std::vector boundTextures, int animflags, bool skipMeshes, bool hasMarkers, bool hasAnimatedParents, SceneUtil::TextKeyMap* textKeys, osg::Node* rootNode=nullptr) { if (rootNode != nullptr && Misc::StringUtils::ciEqual(nifNode->name, "Bounding Box")) return nullptr; @@ -527,9 +545,21 @@ namespace NifOsg // - 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)); + node->setUserValue("recIndex", nifNode->recIndex); + + std::vector extraCollection; for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) + extraCollection.emplace_back(e); + + for (size_t i = 0; i < nifNode->extralist.length(); ++i) + { + Nif::ExtraPtr e = nifNode->extralist[i]; + if (!e.empty()) + extraCollection.emplace_back(e); + } + + for (const auto& e : extraCollection) { if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) { @@ -585,7 +615,7 @@ namespace NifOsg applyNodeProperties(nifNode, node, composite, imageManager, boundTextures, animflags); - const bool isGeometry = nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines; + const bool isGeometry = isTypeGeometry(nifNode->recType); if (isGeometry && !skipMeshes) { @@ -608,8 +638,8 @@ namespace NifOsg } } - if(nifNode->recType == Nif::RC_NiAutoNormalParticles || nifNode->recType == Nif::RC_NiRotatingParticles) - handleParticleSystem(nifNode, node, composite, animflags, rootNode); + if (nifNode->recType == Nif::RC_NiParticles) + handleParticleSystem(nifNode, node, composite, animflags); if (composite->getNumControllers() > 0) { @@ -639,10 +669,10 @@ namespace NifOsg const Nif::NiSwitchNode* niSwitchNode = static_cast(nifNode); osg::ref_ptr switchNode = handleSwitchNode(niSwitchNode); node->addChild(switchNode); - if (niSwitchNode->name == Constants::NightDayLabel && !SceneUtil::hasUserDescription(rootNode, Constants::NightDayLabel)) - rootNode->getOrCreateUserDataContainer()->addDescription(Constants::NightDayLabel); - else if (niSwitchNode->name == Constants::HerbalismLabel && !SceneUtil::hasUserDescription(rootNode, Constants::HerbalismLabel)) - rootNode->getOrCreateUserDataContainer()->addDescription(Constants::HerbalismLabel); + if (niSwitchNode->name == Constants::NightDayLabel) + mHasNightDayLabel = true; + else if (niSwitchNode->name == Constants::HerbalismLabel) + mHasHerbalismLabel = true; currentNode = switchNode; } @@ -702,6 +732,24 @@ namespace NifOsg } } + static osg::ref_ptr handleKeyframeController(const Nif::NiKeyframeController* keyctrl) + { + osg::ref_ptr ctrl; + if (!keyctrl->interpolator.empty()) + { + const Nif::NiTransformInterpolator* interp = keyctrl->interpolator.getPtr(); + if (!interp->data.empty()) + ctrl = new NifOsg::KeyframeController(interp); + else + ctrl = new NifOsg::KeyframeController(interp->defaultScale, interp->defaultPos, interp->defaultRot); + } + else if (!keyctrl->data.empty()) + { + ctrl = new NifOsg::KeyframeController(keyctrl->data.getPtr()); + } + return ctrl; + } + void handleNodeControllers(const Nif::Node* nifNode, osg::Node* node, int animflags, bool& isAnimated) { for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) @@ -711,9 +759,9 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiKeyframeController) { const Nif::NiKeyframeController *key = static_cast(ctrl.getPtr()); - if (key->data.empty()) + if (key->data.empty() && key->interpolator.empty()) continue; - osg::ref_ptr callback(new KeyframeController(key->data.getPtr())); + osg::ref_ptr callback(handleKeyframeController(key)); setupController(key, callback, animflags); node->addUpdateCallback(callback); isAnimated = true; @@ -740,9 +788,13 @@ namespace NifOsg else if (ctrl->recType == Nif::RC_NiRollController) { const Nif::NiRollController *rollctrl = static_cast(ctrl.getPtr()); - if (rollctrl->data.empty()) + if (rollctrl->data.empty() && rollctrl->interpolator.empty()) continue; - osg::ref_ptr callback(new RollController(rollctrl->data.getPtr())); + osg::ref_ptr callback; + if (!rollctrl->interpolator.empty()) + callback = new RollController(rollctrl->interpolator.getPtr()); + else // if (!rollctrl->data.empty()) + callback = new RollController(rollctrl->data.getPtr()); setupController(rollctrl, callback, animflags); node->addUpdateCallback(callback); isAnimated = true; @@ -768,19 +820,27 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiAlphaController) { const Nif::NiAlphaController* alphactrl = static_cast(ctrl.getPtr()); - if (alphactrl->data.empty()) + if (alphactrl->data.empty() && alphactrl->interpolator.empty()) continue; - osg::ref_ptr osgctrl(new AlphaController(alphactrl->data.getPtr(), baseMaterial)); + osg::ref_ptr osgctrl; + if (!alphactrl->interpolator.empty()) + osgctrl = new AlphaController(alphactrl->interpolator.getPtr(), baseMaterial); + else // if (!alphactrl->data.empty()) + osgctrl = new AlphaController(alphactrl->data.getPtr(), baseMaterial); setupController(alphactrl, osgctrl, animflags); composite->addController(osgctrl); } else if (ctrl->recType == Nif::RC_NiMaterialColorController) { const Nif::NiMaterialColorController* matctrl = static_cast(ctrl.getPtr()); - if (matctrl->data.empty()) + if (matctrl->data.empty() && matctrl->interpolator.empty()) continue; + osg::ref_ptr osgctrl; auto targetColor = static_cast(matctrl->targetColor); - osg::ref_ptr osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor, baseMaterial)); + if (!matctrl->interpolator.empty()) + osgctrl = new MaterialColorController(matctrl->interpolator.getPtr(), targetColor, baseMaterial); + else // if (!matctrl->data.empty()) + osgctrl = new MaterialColorController(matctrl->data.getPtr(), targetColor, baseMaterial); setupController(matctrl, osgctrl, animflags); composite->addController(osgctrl); } @@ -886,14 +946,12 @@ namespace NifOsg // Load the initial state of the particle system, i.e. the initial particles and their positions, velocity and colors. void handleParticleInitialState(const Nif::Node* nifNode, osgParticle::ParticleSystem* partsys, const Nif::NiParticleSystemController* partctrl) { - const Nif::NiAutoNormalParticlesData *particledata = nullptr; - if(nifNode->recType == Nif::RC_NiAutoNormalParticles) - particledata = static_cast(nifNode)->data.getPtr(); - else if(nifNode->recType == Nif::RC_NiRotatingParticles) - particledata = static_cast(nifNode)->data.getPtr(); - else + const auto particleNode = static_cast(nifNode); + if (particleNode->data.empty()) return; + const Nif::NiParticlesData* particledata = particleNode->data.getPtr(); + osg::BoundingBox box; int i=0; @@ -970,7 +1028,7 @@ namespace NifOsg return emitter; } - void handleQueuedParticleEmitters(osg::Node* rootNode, Nif::NIFFilePtr nif) + void handleQueuedParticleEmitters(osg::Group* rootNode, Nif::NIFFilePtr nif) { for (const auto& emitterPair : mEmitterQueue) { @@ -991,7 +1049,7 @@ namespace NifOsg mEmitterQueue.clear(); } - void handleParticleSystem(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite, int animflags, osg::Node* rootNode) + void handleParticleSystem(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite, int animflags) { osg::ref_ptr partsys (new ParticleSystem); partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT); @@ -1144,7 +1202,7 @@ namespace NifOsg for (const auto& strip : data->strips) { if (strip.size() >= 3) - geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(), + geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(), (unsigned short*)strip.data())); } } @@ -1176,7 +1234,7 @@ namespace NifOsg void handleGeometry(const Nif::Node* nifNode, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { - assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines); + assert(isTypeGeometry(nifNode->recType)); osg::ref_ptr drawable; osg::ref_ptr geom (new osg::Geometry); handleNiGeometry(nifNode, geom, parentNode, composite, boundTextures, animflags); @@ -1191,7 +1249,7 @@ namespace NifOsg continue; drawable = handleMorphGeometry(nimorphctrl, geom, parentNode, composite, boundTextures, animflags); - osg::ref_ptr morphctrl = new GeomMorpherController(nimorphctrl->data.getPtr()); + osg::ref_ptr morphctrl = new GeomMorpherController(nimorphctrl); setupController(ctrl.getPtr(), morphctrl, animflags); drawable->setUpdateCallback(morphctrl); break; @@ -1221,7 +1279,7 @@ namespace NifOsg void handleSkinnedGeometry(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { - assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines); + assert(isTypeGeometry(nifNode->recType)); osg::ref_ptr geometry (new osg::Geometry); handleNiGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags); osg::ref_ptr rig(new SceneUtil::RigGeometry); @@ -1239,13 +1297,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); @@ -1399,32 +1459,16 @@ namespace NifOsg } // We're going to convert the indices that pixel data contains // into real colors using the palette. - const std::vector& palette = pixelData->palette->colors; - if (pixelData->fmt == Nif::NiPixelData::NIPXFMT_PAL8) + const auto& palette = pixelData->palette->colors; + const int numChannels = pixelformat == GL_RGBA ? 4 : 3; + unsigned char* data = new unsigned char[pixels.size() * numChannels]; + unsigned char* pixel = data; + for (unsigned char index : pixels) { - unsigned char* data = new unsigned char[pixels.size() * 3]; - for (size_t i = 0; i < pixels.size(); i++) - { - unsigned int color = palette[pixels[i]]; - data[i * 3 + 0] = (color >> 0) & 0xFF; - data[i * 3 + 1] = (color >> 8) & 0xFF; - data[i * 3 + 2] = (color >> 16) & 0xFF; - } - image->setImage(width, height, 1, pixelformat, pixelformat, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE); - } - else // if (fmt = NIPXFMT_PALA8) - { - unsigned char* data = new unsigned char[pixels.size() * 4]; - for (size_t i = 0; i < pixels.size(); i++) - { - unsigned int color = palette[pixels[i]]; - data[i * 4 + 0] = (color >> 0) & 0xFF; - data[i * 4 + 1] = (color >> 8) & 0xFF; - data[i * 4 + 2] = (color >> 16) & 0xFF; - data[i * 4 + 3] = (color >> 24) & 0xFF; - } - image->setImage(width, height, 1, pixelformat, pixelformat, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE); + memcpy(pixel, &palette[index], sizeof(unsigned char) * numChannels); + pixel += numChannels; } + image->setImage(width, height, 1, pixelformat, pixelformat, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE); break; } default: @@ -1890,7 +1934,7 @@ namespace NifOsg return impl.load(file, imageManager); } - void Loader::loadKf(Nif::NIFFilePtr kf, KeyframeHolder& target) + void Loader::loadKf(Nif::NIFFilePtr kf, SceneUtil::KeyframeHolder& target) { LoaderImpl impl(kf->getFilename(), kf->getVersion(), kf->getUserVersion(), kf->getBethVersion()); impl.loadKf(kf, target); diff --git a/components/nifosg/nifloader.hpp b/components/nifosg/nifloader.hpp index 49a78ad5f..8ee6b4167 100644 --- a/components/nifosg/nifloader.hpp +++ b/components/nifosg/nifloader.hpp @@ -2,12 +2,13 @@ #define OPENMW_COMPONENTS_NIFOSG_LOADER #include +#include +#include #include #include #include "controller.hpp" -#include "textkeymap.hpp" namespace osg { @@ -21,39 +22,6 @@ namespace Resource namespace NifOsg { - struct TextKeyMapHolder : public osg::Object - { - public: - TextKeyMapHolder() {} - TextKeyMapHolder(const TextKeyMapHolder& copy, const osg::CopyOp& copyop) - : osg::Object(copy, copyop) - , mTextKeys(copy.mTextKeys) - {} - - TextKeyMap mTextKeys; - - META_Object(NifOsg, TextKeyMapHolder) - - }; - - class KeyframeHolder : public osg::Object - { - public: - KeyframeHolder() {} - KeyframeHolder(const KeyframeHolder& copy, const osg::CopyOp& copyop) - : mTextKeys(copy.mTextKeys) - , mKeyframeControllers(copy.mKeyframeControllers) - { - } - - TextKeyMap mTextKeys; - - META_Object(OpenMW, KeyframeHolder) - - typedef std::map > KeyframeControllerMap; - KeyframeControllerMap mKeyframeControllers; - }; - /// The main class responsible for loading NIF files into an OSG-Scenegraph. /// @par This scene graph is self-contained and can be cloned using osg::clone if desired. Particle emitters /// and programs hold a pointer to their ParticleSystem, which would need to be manually updated when cloning. @@ -64,7 +32,7 @@ namespace NifOsg static osg::ref_ptr load(Nif::NIFFilePtr file, Resource::ImageManager* imageManager); /// Load keyframe controllers from the given kf file. - static void loadKf(Nif::NIFFilePtr kf, KeyframeHolder& target); + static void loadKf(Nif::NIFFilePtr kf, SceneUtil::KeyframeHolder& target); /// Set whether or not nodes marked as "MRK" should be shown. /// These should be hidden ingame, but visible in the editor. diff --git a/components/nifosg/nodeindexholder.hpp b/components/nifosg/nodeindexholder.hpp deleted file mode 100644 index e7d4f0db3..000000000 --- a/components/nifosg/nodeindexholder.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#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 0cbc3f22b..e2e1f92cf 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -5,14 +5,13 @@ #include #include #include +#include #include #include #include #include -#include "nodeindexholder.hpp" - namespace NifOsg { @@ -345,7 +344,7 @@ void Emitter::emitParticles(double dt) for (int i=0; icreateParticle(0); + osgParticle::Particle* P = getParticleSystem()->createParticle(nullptr); if (P) { mPlacer->place(P); @@ -357,7 +356,7 @@ void Emitter::emitParticles(double dt) } } -FindGroupByRecIndex::FindGroupByRecIndex(int recIndex) +FindGroupByRecIndex::FindGroupByRecIndex(unsigned int recIndex) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mFound(nullptr) , mRecIndex(recIndex) @@ -381,19 +380,16 @@ void FindGroupByRecIndex::apply(osg::Geometry &node) void FindGroupByRecIndex::applyNode(osg::Node &searchNode) { - if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) + unsigned int recIndex; + if (searchNode.getUserValue("recIndex", recIndex) && mRecIndex == recIndex) { - NodeIndexHolder* holder = dynamic_cast(searchNode.getUserDataContainer()->getUserObject(0)); - if (holder && holder->getIndex() == mRecIndex) - { - osg::Group* group = searchNode.asGroup(); - if (!group) - group = searchNode.getParent(0); + osg::Group* group = searchNode.asGroup(); + if (!group) + group = searchNode.getParent(0); - mFound = group; - mFoundPath = getNodePath(); - return; - } + mFound = group; + mFoundPath = getNodePath(); + return; } traverse(searchNode); } diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index d71cbb9f5..dd89f4501 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; @@ -204,21 +204,21 @@ namespace NifOsg class FindGroupByRecIndex : public osg::NodeVisitor { public: - FindGroupByRecIndex(int recIndex); + FindGroupByRecIndex(unsigned 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); osg::Group* mFound; osg::NodePath mFoundPath; private: - int mRecIndex; + unsigned int mRecIndex; }; // Subclass emitter to support randomly choosing one of the child node's transforms for the emit position of new particles. @@ -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/animation.cpp b/components/resource/animation.cpp new file mode 100644 index 000000000..34ae162ee --- /dev/null +++ b/components/resource/animation.cpp @@ -0,0 +1,40 @@ +#include + +#include +#include + +namespace Resource +{ + Animation::Animation(const Animation& anim, const osg::CopyOp& copyop): osg::Object(anim, copyop), + mDuration(0.0f), + mStartTime(0.0f) + { + const osgAnimation::ChannelList& channels = anim.getChannels(); + for (const osg::ref_ptr channel: channels) + addChannel(channel.get()->clone()); + } + + void Animation::addChannel(osg::ref_ptr pChannel) + { + mChannels.push_back(pChannel); + } + + std::vector>& Animation::getChannels() + { + return mChannels; + } + + const std::vector>& Animation::getChannels() const + { + return mChannels; + } + + bool Animation::update (double time) + { + for (const osg::ref_ptr channel: mChannels) + { + channel->update(time, 1.0f, 0); + } + return true; + } +} diff --git a/components/resource/animation.hpp b/components/resource/animation.hpp new file mode 100644 index 000000000..885394747 --- /dev/null +++ b/components/resource/animation.hpp @@ -0,0 +1,39 @@ +#ifndef OPENMW_COMPONENTS_RESOURCE_ANIMATION_HPP +#define OPENMW_COMPONENTS_RESOURCE_ANIMATION_HPP + +#include + +#include +#include +#include + +namespace Resource +{ + /// Stripped down class of osgAnimation::Animation, only needed for OSG's plugin formats like dae + class Animation : public osg::Object + { + public: + META_Object(Resource, Animation) + + Animation() : + mDuration(0.0), mStartTime(0) {} + + Animation(const Animation&, const osg::CopyOp&); + ~Animation() {} + + void addChannel (osg::ref_ptr pChannel); + + std::vector>& getChannels(); + + const std::vector>& getChannels() const; + + bool update (double time); + + protected: + double mDuration; + double mStartTime; + std::vector> mChannels; + }; +} + +#endif 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.cpp b/components/resource/imagemanager.cpp index ff6fb04a6..dd34ed1a1 100644 --- a/components/resource/imagemanager.cpp +++ b/components/resource/imagemanager.cpp @@ -151,7 +151,7 @@ namespace Resource image->setFileName(normalized); if (!checkSupported(image, filename)) { - static bool uncompress = (getenv("OPENMW_DECOMPRESS_TEXTURES") != 0); + static bool uncompress = (getenv("OPENMW_DECOMPRESS_TEXTURES") != nullptr); if (!uncompress) { Log(Debug::Error) << "Error loading " << filename << ": no S3TC texture compression support installed"; 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.cpp b/components/resource/keyframemanager.cpp index 8c5c50adc..af0f365ee 100644 --- a/components/resource/keyframemanager.cpp +++ b/components/resource/keyframemanager.cpp @@ -2,13 +2,88 @@ #include +#include +#include +#include + +#include +#include +#include + +#include "animation.hpp" #include "objectcache.hpp" +#include "scenemanager.hpp" namespace Resource { - KeyframeManager::KeyframeManager(const VFS::Manager* vfs) + RetrieveAnimationsVisitor::RetrieveAnimationsVisitor(SceneUtil::KeyframeHolder& target, osg::ref_ptr animationManager) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mTarget(target), mAnimationManager(animationManager) {} + + void RetrieveAnimationsVisitor::apply(osg::Node& node) + { + if (node.libraryName() == std::string("osgAnimation") && node.className() == std::string("Bone") && node.getName() == std::string("root")) + { + osg::ref_ptr callback = new SceneUtil::OsgAnimationController(); + + std::vector emulatedAnimations; + + for (auto animation : mAnimationManager->getAnimationList()) + { + if (animation) + { + if (animation->getName() == "Default") //"Default" is osg dae plugin's default naming scheme for unnamed animations + { + animation->setName(std::string("idle")); // animation naming scheme "idle: start" and "idle: stop" is the default idle animation that OpenMW seems to want to play + } + + osg::ref_ptr mergedAnimationTrack = new Resource::Animation; + std::string animationName = animation->getName(); + std::string start = animationName + std::string(": start"); + std::string stop = animationName + std::string(": stop"); + std::string loopstart = animationName + std::string(": loop start"); + std::string loopstop = animationName + std::string(": loop stop"); + + const osgAnimation::ChannelList& channels = animation->getChannels(); + for (const osg::ref_ptr channel: channels) + { + mergedAnimationTrack->addChannel(channel.get()->clone()); // is ->clone needed? + } + mergedAnimationTrack->setName(animation->getName()); + callback->addMergedAnimationTrack(mergedAnimationTrack); + + float startTime = animation->getStartTime(); + float stopTime = startTime + animation->getDuration(); + + // mTextKeys is a nif-thing, used by OpenMW's animation system + // Format is likely "AnimationName: [Keyword_optional] [Start OR Stop]" + // AnimationNames are keywords like idle2, idle3... AiPackages and various mechanics control which animations are played + // Keywords can be stuff like Loop, Equip, Unequip, Block, InventoryHandtoHand, InventoryWeaponOneHand, PickProbe, Slash, Thrust, Chop... even "Slash Small Follow" + mTarget.mTextKeys.emplace(startTime, std::move(start)); + mTarget.mTextKeys.emplace(stopTime, std::move(stop)); + mTarget.mTextKeys.emplace(startTime, std::move(loopstart)); + mTarget.mTextKeys.emplace(stopTime, std::move(loopstop)); + + SceneUtil::EmulatedAnimation emulatedAnimation; + emulatedAnimation.mStartTime = startTime; + emulatedAnimation.mStopTime = stopTime; + emulatedAnimation.mName = animationName; + emulatedAnimations.emplace_back(emulatedAnimation); + } + } + callback->setEmulatedAnimations(emulatedAnimations); + mTarget.mKeyframeControllers.emplace(node.getName(), callback); + } + + traverse(node); + } +} + +namespace Resource +{ + + KeyframeManager::KeyframeManager(const VFS::Manager* vfs, SceneManager* sceneManager) : ResourceManager(vfs) + , mSceneManager(sceneManager) { } @@ -16,19 +91,32 @@ namespace Resource { } - osg::ref_ptr KeyframeManager::get(const std::string &name) + osg::ref_ptr KeyframeManager::get(const std::string &name) { std::string normalized = name; mVFS->normalizeFilename(normalized); osg::ref_ptr obj = mCache->getRefFromObjectCache(normalized); if (obj) - return osg::ref_ptr(static_cast(obj.get())); + return osg::ref_ptr(static_cast(obj.get())); else { - osg::ref_ptr loaded (new NifOsg::KeyframeHolder); - NifOsg::Loader::loadKf(Nif::NIFFilePtr(new Nif::NIFFile(mVFS->getNormalized(normalized), normalized)), *loaded.get()); - + osg::ref_ptr loaded (new SceneUtil::KeyframeHolder); + std::string ext = Resource::getFileExtension(normalized); + if (ext == "kf") + { + NifOsg::Loader::loadKf(Nif::NIFFilePtr(new Nif::NIFFile(mVFS->getNormalized(normalized), normalized)), *loaded.get()); + } + else + { + osg::ref_ptr scene = const_cast ( mSceneManager->getTemplate(normalized).get() ); + osg::ref_ptr bam = dynamic_cast (scene->getUpdateCallback()); + if (bam) + { + Resource::RetrieveAnimationsVisitor rav(*loaded.get(), bam); + scene->accept(rav); + } + } mCache->addEntryToObjectCache(normalized, loaded); return loaded; } diff --git a/components/resource/keyframemanager.hpp b/components/resource/keyframemanager.hpp index 3496342fa..3e992ac5e 100644 --- a/components/resource/keyframemanager.hpp +++ b/components/resource/keyframemanager.hpp @@ -2,28 +2,50 @@ #define OPENMW_COMPONENTS_KEYFRAMEMANAGER_H #include +#include #include -#include +#include #include "resourcemanager.hpp" namespace Resource { + /// @brief extract animations to OpenMW's animation system + class RetrieveAnimationsVisitor : public osg::NodeVisitor + { + public: + RetrieveAnimationsVisitor(SceneUtil::KeyframeHolder& target, osg::ref_ptr animationManager); + + virtual void apply(osg::Node& node) override; + + private: + SceneUtil::KeyframeHolder& mTarget; + osg::ref_ptr mAnimationManager; + + }; +} + +namespace Resource +{ + + class SceneManager; /// @brief Managing of keyframe resources /// @note May be used from any thread. class KeyframeManager : public ResourceManager { public: - KeyframeManager(const VFS::Manager* vfs); + KeyframeManager(const VFS::Manager* vfs, SceneManager* sceneManager); ~KeyframeManager(); /// Retrieve a read-only keyframe resource by name (case-insensitive). /// @note Throws an exception if the resource is not found. - osg::ref_ptr get(const std::string& name); + 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; + private: + SceneManager* mSceneManager; }; } 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/objectcache.hpp b/components/resource/objectcache.hpp index 6e309a7f7..5c4b511f0 100644 --- a/components/resource/objectcache.hpp +++ b/components/resource/objectcache.hpp @@ -119,7 +119,7 @@ class GenericObjectCache : public osg::Referenced typename ObjectCacheMap::iterator itr = _objectCache.find(key); if (itr!=_objectCache.end()) return itr->second.first; - else return 0; + else return nullptr; } /** Check if an object is in the cache, and if it is, update its usage time stamp. */ 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/resourcesystem.cpp b/components/resource/resourcesystem.cpp index 2015ba874..ab9d0aba2 100644 --- a/components/resource/resourcesystem.cpp +++ b/components/resource/resourcesystem.cpp @@ -14,9 +14,9 @@ namespace Resource : mVFS(vfs) { mNifFileManager.reset(new NifFileManager(vfs)); - mKeyframeManager.reset(new KeyframeManager(vfs)); mImageManager.reset(new ImageManager(vfs)); mSceneManager.reset(new SceneManager(vfs, mImageManager.get(), mNifFileManager.get())); + mKeyframeManager.reset(new KeyframeManager(vfs, mSceneManager.get())); addResourceManager(mNifFileManager.get()); addResourceManager(mKeyframeManager.get()); diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index b01b5d158..c55024261 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) @@ -220,6 +220,7 @@ namespace Resource , mClampLighting(true) , mAutoUseNormalMaps(false) , mAutoUseSpecularMaps(false) + , mApplyLightingToEnvMaps(false) , mInstanceCache(new MultiObjectCache) , mSharedStateManager(new SharedStateManager) , mImageManager(imageManager) @@ -242,9 +243,9 @@ namespace Resource return mForceShaders; } - void SceneManager::recreateShaders(osg::ref_ptr node) + void SceneManager::recreateShaders(osg::ref_ptr node, const std::string& shaderPrefix) { - osg::ref_ptr shaderVisitor(createShaderVisitor()); + osg::ref_ptr shaderVisitor(createShaderVisitor(shaderPrefix)); shaderVisitor->setAllowedToModifyStateSets(false); node->accept(*shaderVisitor); } @@ -284,6 +285,11 @@ namespace Resource mSpecularMapPattern = pattern; } + void SceneManager::setApplyLightingToEnvMaps(bool apply) + { + mApplyLightingToEnvMaps = apply; + } + SceneManager::~SceneManager() { // this has to be defined in the .cpp file as we can't delete incomplete types @@ -316,7 +322,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 { @@ -332,17 +338,9 @@ namespace Resource Resource::ImageManager* mImageManager; }; - std::string getFileExtension(const std::string& file) - { - size_t extPos = file.find_last_of('.'); - if (extPos != std::string::npos && extPos+1 < file.size()) - return file.substr(extPos+1); - return std::string(); - } - osg::ref_ptr load (Files::IStreamPtr file, const std::string& normalizedFilename, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager) { - std::string ext = getFileExtension(normalizedFilename); + std::string ext = Resource::getFileExtension(normalizedFilename); if (ext == "nif") return NifOsg::Loader::load(nifFileManager->get(normalizedFilename), imageManager); else @@ -412,7 +410,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) { @@ -424,7 +422,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; @@ -498,7 +496,7 @@ namespace Resource } catch (std::exception& e) { - static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2" }; + static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", "dae" }; for (unsigned int i=0; isetAttribute(frameNumber, "Node Instance", mInstanceCache->getCacheSize()); } - Shader::ShaderVisitor *SceneManager::createShaderVisitor() + Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix) { - Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, "objects_vertex.glsl", "objects_fragment.glsl"); + Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix+"_vertex.glsl", shaderPrefix+"_fragment.glsl"); shaderVisitor->setForceShaders(mForceShaders); shaderVisitor->setAutoUseNormalMaps(mAutoUseNormalMaps); shaderVisitor->setNormalMapPattern(mNormalMapPattern); shaderVisitor->setNormalHeightMapPattern(mNormalHeightMapPattern); shaderVisitor->setAutoUseSpecularMaps(mAutoUseSpecularMaps); shaderVisitor->setSpecularMapPattern(mSpecularMapPattern); + shaderVisitor->setApplyLightingToEnvMaps(mApplyLightingToEnvMaps); return shaderVisitor; } + std::string getFileExtension(const std::string& file) + { + size_t extPos = file.find_last_of('.'); + if (extPos != std::string::npos && extPos+1 < file.size()) + return file.substr(extPos+1); + return std::string(); + } } diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index 3a72caf6a..fd75070a1 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -51,7 +51,7 @@ namespace Resource Shader::ShaderManager& getShaderManager(); /// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed. - void recreateShaders(osg::ref_ptr node); + void recreateShaders(osg::ref_ptr node, const std::string& shaderPrefix = "objects"); /// @see ShaderVisitor::setForceShaders void setForceShaders(bool force); @@ -73,6 +73,8 @@ namespace Resource void setSpecularMapPattern(const std::string& pattern); + void setApplyLightingToEnvMaps(bool apply); + void setShaderPath(const std::string& path); /// Check if a given scene is loaded and if so, update its usage timestamp to prevent it from being unloaded @@ -146,7 +148,7 @@ namespace Resource private: - Shader::ShaderVisitor* createShaderVisitor(); + Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects"); std::unique_ptr mShaderManager; bool mForceShaders; @@ -156,6 +158,7 @@ namespace Resource std::string mNormalHeightMapPattern; bool mAutoUseSpecularMaps; std::string mSpecularMapPattern; + bool mApplyLightingToEnvMaps; osg::ref_ptr mInstanceCache; @@ -178,6 +181,7 @@ namespace Resource void operator = (const SceneManager&); }; + std::string getFileExtension(const std::string& file); } #endif 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.cpp b/components/sceneutil/clone.cpp index 1de7bfd91..07a6e691a 100644 --- a/components/sceneutil/clone.cpp +++ b/components/sceneutil/clone.cpp @@ -2,6 +2,11 @@ #include +#include +#include +#include +#include + #include #include #include @@ -30,6 +35,11 @@ namespace SceneUtil mUpdaterToOldPs[cloned] = updater->getParticleSystem(0); return cloned; } + + if (dynamic_cast(node) || dynamic_cast(node)) + { + return osg::clone(node, *this); + } return osg::CopyOp::operator()(node); } @@ -38,7 +48,7 @@ namespace SceneUtil if (const osgParticle::ParticleSystem* partsys = dynamic_cast(drawable)) return operator()(partsys); - if (dynamic_cast(drawable) || dynamic_cast(drawable)) + if (dynamic_cast(drawable) || dynamic_cast(drawable) || dynamic_cast(drawable) || dynamic_cast(drawable)) { return static_cast(drawable->clone(*this)); } 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/keyframe.hpp b/components/sceneutil/keyframe.hpp new file mode 100644 index 000000000..e09541cb9 --- /dev/null +++ b/components/sceneutil/keyframe.hpp @@ -0,0 +1,68 @@ +#ifndef OPENMW_COMPONENTS_SCENEUTIL_KEYFRAME_HPP +#define OPENMW_COMPONENTS_SCENEUTIL_KEYFRAME_HPP + +#include + +#include + +#include +#include +#include + +namespace SceneUtil +{ + class KeyframeController : public osg::NodeCallback, public SceneUtil::Controller + { + public: + KeyframeController() {} + + KeyframeController(const KeyframeController& copy, const osg::CopyOp& copyop) + : osg::NodeCallback(copy, copyop) + , SceneUtil::Controller(copy) + {} + META_Object(SceneUtil, KeyframeController) + + virtual osg::Vec3f getTranslation(float time) const { return osg::Vec3f(); } + + virtual void operator() (osg::Node* node, osg::NodeVisitor* nodeVisitor) override { traverse(node, nodeVisitor); } + }; + + /// Wrapper object containing an animation track as a ref-countable osg::Object. + struct TextKeyMapHolder : public osg::Object + { + public: + TextKeyMapHolder() {} + TextKeyMapHolder(const TextKeyMapHolder& copy, const osg::CopyOp& copyop) + : osg::Object(copy, copyop) + , mTextKeys(copy.mTextKeys) + {} + + TextKeyMap mTextKeys; + + META_Object(SceneUtil, TextKeyMapHolder) + + }; + + /// Wrapper object containing the animation track and its KeyframeControllers. + class KeyframeHolder : public osg::Object + { + public: + KeyframeHolder() {} + KeyframeHolder(const KeyframeHolder& copy, const osg::CopyOp& copyop) + : mTextKeys(copy.mTextKeys) + , mKeyframeControllers(copy.mKeyframeControllers) + { + } + + TextKeyMap mTextKeys; + + META_Object(SceneUtil, KeyframeHolder) + + /// Controllers mapped to node name. + typedef std::map > KeyframeControllerMap; + KeyframeControllerMap mKeyframeControllers; + }; + +} + +#endif 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..2ebce241d 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(); @@ -237,7 +237,7 @@ namespace SceneUtil std::vector > lights; lights.reserve(lightList.size()); for (unsigned int i=0; imLightSource->getLight(frameNum)); + lights.emplace_back(lightList[i]->mLightSource->getLight(frameNum)); // the first light state attribute handles the actual state setting for all lights // it's best to batch these up so that we don't need to touch the modelView matrix more than necessary @@ -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 38fc6ab32..fab1334e7 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -27,6 +27,7 @@ #include #include +#include "shadowsbin.hpp" namespace { @@ -238,7 +239,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(); } @@ -275,10 +276,20 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) cv->pushCullingSet(); } #endif + // bin has to go inside camera cull or the rendertexture stage will override it + static osg::ref_ptr ss; + if (!ss) + { + ShadowsBinAdder adder("ShadowsBin"); + ss = new osg::StateSet; + ss->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "ShadowsBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); + } + cv->pushStateSet(ss); if (_vdsm->getShadowedScene()) { _vdsm->getShadowedScene()->osg::Group::traverse(*nv); } + cv->popStateSet(); #if 1 if (!_polytope.empty()) { @@ -557,6 +568,7 @@ MWShadowTechnique::ShadowData::ShadowData(MWShadowTechnique::ViewDependentData* _camera = new osg::Camera; _camera->setName("ShadowCamera"); _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT); + _camera->setImplicitBufferAttachmentMask(0, 0); //_camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); _camera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f)); @@ -813,9 +825,10 @@ void MWShadowTechnique::enableShadows() _enableShadows = true; } -void MWShadowTechnique::disableShadows() +void MWShadowTechnique::disableShadows(bool setDummyState) { _enableShadows = false; + mSetDummyStateWhenDisabled = setDummyState; } void SceneUtil::MWShadowTechnique::enableDebugHUD() @@ -879,15 +892,6 @@ void SceneUtil::MWShadowTechnique::setupCastingShader(Shader::ShaderManager & sh _castingProgram->addShader(shaderManager.getShader("shadowcasting_vertex.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::VERTEX)); _castingProgram->addShader(shaderManager.getShader("shadowcasting_fragment.glsl", Shader::ShaderManager::DefineMap(), osg::Shader::FRAGMENT)); - - _shadowMapAlphaTestDisableUniform = shaderManager.getShadowMapAlphaTestDisableUniform(); - _shadowMapAlphaTestDisableUniform->setName("alphaTestShadows"); - _shadowMapAlphaTestDisableUniform->setType(osg::Uniform::BOOL); - _shadowMapAlphaTestDisableUniform->set(false); - - shaderManager.getShadowMapAlphaTestEnableUniform()->setName("alphaTestShadows"); - shaderManager.getShadowMapAlphaTestEnableUniform()->setType(osg::Uniform::BOOL); - shaderManager.getShadowMapAlphaTestEnableUniform()->set(true); } MWShadowTechnique::ViewDependentData* MWShadowTechnique::createViewDependentData(osgUtil::CullVisitor* /*cv*/) @@ -916,7 +920,28 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv) { if (!_enableShadows) { + if (mSetDummyStateWhenDisabled) + { + osg::ref_ptr dummyState = new osg::StateSet(); + + ShadowSettings* settings = getShadowedScene()->getShadowSettings(); + int baseUnit = settings->getBaseShadowTextureUnit(); + int endUnit = baseUnit + settings->getNumShadowMapsPerLight(); + for (int i = baseUnit; i < endUnit; ++i) + { + dummyState->setTextureAttributeAndModes(i, _fallbackShadowMapTexture, osg::StateAttribute::ON); + dummyState->addUniform(new osg::Uniform(("shadowTexture" + std::to_string(i - baseUnit)).c_str(), i)); + dummyState->addUniform(new osg::Uniform(("shadowTextureUnit" + std::to_string(i - baseUnit)).c_str(), i)); + } + + cv.pushStateSet(dummyState); + } + _shadowedScene->osg::Group::traverse(cv); + + if (mSetDummyStateWhenDisabled) + cv.popStateSet(); + return; } @@ -1513,7 +1538,7 @@ void MWShadowTechnique::createShaders() { perFrameUniformList.clear(); perFrameUniformList.push_back(baseTextureSampler); - perFrameUniformList.push_back(baseTextureUnit.get()); + perFrameUniformList.emplace_back(baseTextureUnit.get()); perFrameUniformList.push_back(maxDistance); perFrameUniformList.push_back(fadeStart); } @@ -1525,7 +1550,7 @@ void MWShadowTechnique::createShaders() sstr<<"shadowTexture"< shadowTextureSampler = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i)); for (auto& perFrameUniformList : _uniforms) - perFrameUniformList.push_back(shadowTextureSampler.get()); + perFrameUniformList.emplace_back(shadowTextureSampler.get()); } { @@ -1533,7 +1558,7 @@ void MWShadowTechnique::createShaders() sstr<<"shadowTextureUnit"< shadowTextureUnit = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i)); for (auto& perFrameUniformList : _uniforms) - perFrameUniformList.push_back(shadowTextureUnit.get()); + perFrameUniformList.emplace_back(shadowTextureUnit.get()); } } @@ -1579,6 +1604,8 @@ void MWShadowTechnique::createShaders() _fallbackShadowMapTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT); _fallbackShadowMapTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST); _fallbackShadowMapTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); + _fallbackShadowMapTexture->setShadowComparison(true); + _fallbackShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS); } @@ -1588,17 +1615,14 @@ void MWShadowTechnique::createShaders() _shadowCastingStateSet->setAttributeAndModes(_castingProgram, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); // The casting program uses a sampler, so to avoid undefined behaviour, we must bind a dummy texture in case no other is supplied _shadowCastingStateSet->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); - _shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); - _shadowCastingStateSet->addUniform(_shadowMapAlphaTestDisableUniform); + _shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true)); + _shadowCastingStateSet->addUniform(new osg::Uniform("alphaTestShadows", false)); osg::ref_ptr depth = new osg::Depth; depth->setWriteMask(true); _shadowCastingStateSet->setAttribute(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); _shadowCastingStateSet->setMode(GL_DEPTH_CLAMP, osg::StateAttribute::ON); - _shadowCastingStateSet->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "RenderBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); - // TODO: compare performance when alpha testing is handled here versus using a discard in the fragment shader - // TODO: compare performance when we set a bunch of GL state to the default here with OVERRIDE set so that there are fewer pointless state switches } osg::Polytope MWShadowTechnique::computeLightViewFrustumPolytope(Frustum& frustum, LightData& positionedLight) @@ -2563,12 +2587,12 @@ bool MWShadowTechnique::cropShadowCameraToMainFrustum(Frustum& frustum, osg::Cam yMax = convexHull.max(1); zMin = convexHull.min(2); - planeList.push_back(osg::Plane(0.0, -1.0, 0.0, yMax)); - planeList.push_back(osg::Plane(0.0, 1.0, 0.0, -yMin)); - planeList.push_back(osg::Plane(-1.0, 0.0, 0.0, xMax)); - planeList.push_back(osg::Plane(1.0, 0.0, 0.0, -xMin)); + planeList.emplace_back(0.0, -1.0, 0.0, yMax); + planeList.emplace_back(0.0, 1.0, 0.0, -yMin); + planeList.emplace_back(-1.0, 0.0, 0.0, xMax); + planeList.emplace_back(1.0, 0.0, 0.0, -xMin); // In view space, the light is at the most positive value, and we want to cull stuff beyond the minimum value. - planeList.push_back(osg::Plane(0.0, 0.0, 1.0, -zMin)); + planeList.emplace_back(0.0, 0.0, 1.0, -zMin); // Don't add a zMax culling plane - we still want those objects, but don't care about their depth buffer value. } @@ -3082,7 +3106,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(); @@ -3197,7 +3221,7 @@ void SceneUtil::MWShadowTechnique::DebugHUD::addAnotherShadowMap() mDebugCameras[shadowMapNumber]->setClearColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); mDebugCameras[shadowMapNumber]->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); - mDebugGeometry.push_back(osg::createTexturedQuadGeometry(osg::Vec3(-1, -1, 0), osg::Vec3(2, 0, 0), osg::Vec3(0, 2, 0))); + mDebugGeometry.emplace_back(osg::createTexturedQuadGeometry(osg::Vec3(-1, -1, 0), osg::Vec3(2, 0, 0), osg::Vec3(0, 2, 0))); mDebugGeometry[shadowMapNumber]->setCullingActive(false); mDebugCameras[shadowMapNumber]->addChild(mDebugGeometry[shadowMapNumber]); osg::ref_ptr stateSet = mDebugGeometry[shadowMapNumber]->getOrCreateStateSet(); diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index bdfb44e46..5125247dd 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -46,28 +46,28 @@ 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(); - virtual void disableShadows(); + virtual void disableShadows(bool setDummyState = false); virtual void enableDebugHUD(); @@ -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; @@ -252,6 +252,7 @@ namespace SceneUtil { osg::ref_ptr _program; bool _enableShadows; + bool mSetDummyStateWhenDisabled; double _splitPointUniformLogRatio = 0.5; double _splitPointDeltaBias = 0.0; @@ -288,7 +289,6 @@ namespace SceneUtil { osg::ref_ptr _debugHud; osg::ref_ptr _castingProgram; - osg::ref_ptr _shadowMapAlphaTestDisableUniform; }; } 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; } - 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::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::Vec4ubArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3ubArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec2ubArray& 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::Vec4usArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3usArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec2usArray& 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::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::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::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::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::Vec2bArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec3bArray& rhs) { _merge(rhs); } - virtual void apply(osg::Vec4bArray& 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::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/osgacontroller.cpp b/components/sceneutil/osgacontroller.cpp new file mode 100644 index 000000000..87e6f02fe --- /dev/null +++ b/components/sceneutil/osgacontroller.cpp @@ -0,0 +1,197 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace SceneUtil +{ + LinkVisitor::LinkVisitor() : osg::NodeVisitor( TRAVERSE_ALL_CHILDREN ) + { + mAnimation = nullptr; + } + + void LinkVisitor::link(osgAnimation::UpdateMatrixTransform* umt) + { + const osgAnimation::ChannelList& channels = mAnimation->getChannels(); + for (const osg::ref_ptr channel: channels) + { + const std::string& channelName = channel->getName(); + const std::string& channelTargetName = channel->getTargetName(); + + if (channelTargetName != umt->getName()) continue; + + // check if we can link a StackedTransformElement to the current Channel + for (auto stackedTransform : umt->getStackedTransforms()) + { + osgAnimation::StackedTransformElement* element = stackedTransform.get(); + if (element && !element->getName().empty() && channelName == element->getName()) + { + osgAnimation::Target* target = element->getOrCreateTarget(); + if (target) + { + channel->setTarget(target); + } + } + } + } + } + + void LinkVisitor::handle_stateset(osg::StateSet* stateset) + { + if (!stateset) + return; + const osg::StateSet::AttributeList& attributeList = stateset->getAttributeList(); + for (auto attribute : attributeList) + { + osg::StateAttribute* sattr = attribute.second.first.get(); + osgAnimation::UpdateMatrixTransform* umt = dynamic_cast(sattr->getUpdateCallback()); //Can this even be in sa? + if (umt) link(umt); + } + } + + void LinkVisitor::setAnimation(Resource::Animation* animation) + { + mAnimation = animation; + } + + void LinkVisitor::apply(osg::Node& node) + { + osg::StateSet* st = node.getStateSet(); + if (st) + handle_stateset(st); + + osg::Callback* cb = node.getUpdateCallback(); + while (cb) + { + osgAnimation::UpdateMatrixTransform* umt = dynamic_cast(cb); + if (umt) + if (node.getName() != "root") link(umt); + cb = cb->getNestedCallback(); + } + + traverse( node ); + } + + void LinkVisitor::apply(osg::Geode& node) + { + for (unsigned int i = 0; i < node.getNumDrawables(); i++) + { + osg::Drawable* drawable = node.getDrawable(i); + if (drawable && drawable->getStateSet()) + handle_stateset(drawable->getStateSet()); + } + apply(static_cast(node)); + } + + OsgAnimationController::OsgAnimationController(const OsgAnimationController ©, const osg::CopyOp ©op) : SceneUtil::KeyframeController(copy, copyop) + , mMergedAnimationTracks(copy.mMergedAnimationTracks) + , mEmulatedAnimations(copy.mEmulatedAnimations) + { + mLinker = nullptr; + } + + osg::Vec3f OsgAnimationController::getTranslation(float time) const + { + osg::Vec3f translationValue; + std::string animationName; + float newTime = time; + + //Find the correct animation based on time + for (const EmulatedAnimation& emulatedAnimation : mEmulatedAnimations) + { + if (time > emulatedAnimation.mStartTime && time < emulatedAnimation.mStopTime) + { + newTime = time - emulatedAnimation.mStartTime; + animationName = emulatedAnimation.mName; + } + } + + //Find the root transform track in animation + for (const osg::ref_ptr mergedAnimationTrack : mMergedAnimationTracks) + { + if (mergedAnimationTrack->getName() != animationName) continue; + + const osgAnimation::ChannelList& channels = mergedAnimationTrack->getChannels(); + + for (const osg::ref_ptr channel: channels) + { + if (channel->getTargetName() != "root" || channel->getName() != "transform") continue; + + if ( osgAnimation::MatrixLinearSampler* templateSampler = dynamic_cast (channel->getSampler()) ) + { + osg::Matrixf matrix; + templateSampler->getValueAt(newTime, matrix); + translationValue = matrix.getTrans(); + return osg::Vec3f(translationValue[0], translationValue[1], translationValue[2]); + } + } + } + + return osg::Vec3f(); + } + + void OsgAnimationController::update(float time, std::string animationName) + { + for (const osg::ref_ptr mergedAnimationTrack : mMergedAnimationTracks) + { + if (mergedAnimationTrack->getName() == animationName) mergedAnimationTrack->update(time); + } + } + + void OsgAnimationController::operator() (osg::Node* node, osg::NodeVisitor* nv) + { + if (hasInput()) + { + if (mNeedToLink) + { + for (const osg::ref_ptr mergedAnimationTrack : mMergedAnimationTracks) + { + if (!mLinker.valid()) mLinker = new LinkVisitor(); + mLinker->setAnimation(mergedAnimationTrack); + node->accept(*mLinker); + } + mNeedToLink = false; + } + + float time = getInputValue(nv); + + for (const EmulatedAnimation& emulatedAnimation : mEmulatedAnimations) + { + if (time > emulatedAnimation.mStartTime && time < emulatedAnimation.mStopTime) + { + update(time - emulatedAnimation.mStartTime, emulatedAnimation.mName); + } + } + } + + traverse(node, nv); + } + + void OsgAnimationController::setEmulatedAnimations(std::vector emulatedAnimations) + { + mEmulatedAnimations = emulatedAnimations; + } + + void OsgAnimationController::addMergedAnimationTrack(osg::ref_ptr animationTrack) + { + mMergedAnimationTracks.emplace_back(animationTrack); + } +} diff --git a/components/sceneutil/osgacontroller.hpp b/components/sceneutil/osgacontroller.hpp new file mode 100644 index 000000000..f1c1584c2 --- /dev/null +++ b/components/sceneutil/osgacontroller.hpp @@ -0,0 +1,80 @@ +#ifndef OPENMW_COMPONENTS_SCENEUTIL_OSGACONTROLLER_HPP +#define OPENMW_COMPONENTS_SCENEUTIL_OSGACONTROLLER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace SceneUtil +{ + struct EmulatedAnimation + { + float mStartTime; + float mStopTime; + std::string mName; + }; + + class LinkVisitor : public osg::NodeVisitor + { + public: + LinkVisitor(); + + virtual void link(osgAnimation::UpdateMatrixTransform* umt); + + virtual void handle_stateset(osg::StateSet* stateset); + + virtual void setAnimation(Resource::Animation* animation); + + virtual void apply(osg::Node& node) override; + + virtual void apply(osg::Geode& node) override; + + protected: + Resource::Animation* mAnimation; + }; + + class OsgAnimationController : public SceneUtil::KeyframeController + { + public: + /// @brief Handles the animation for osgAnimation formats + OsgAnimationController() {}; + + OsgAnimationController(const OsgAnimationController& copy, const osg::CopyOp& copyop); + + META_Object(SceneUtil, OsgAnimationController) + + /// @brief Handles the location of the instance + osg::Vec3f getTranslation(float time) const override; + + /// @brief Calls animation track update() + void update(float time, std::string animationName); + + /// @brief Called every frame for osgAnimation + void operator() (osg::Node*, osg::NodeVisitor*) override; + + /// @brief Sets details of the animations + void setEmulatedAnimations(std::vector emulatedAnimations); + + /// @brief Adds an animation track to a model + void addMergedAnimationTrack(osg::ref_ptr animationTrack); + + private: + bool mNeedToLink = true; + osg::ref_ptr mLinker; + std::vector> mMergedAnimationTracks; // Used only by osgAnimation-based formats (e.g. dae) + std::vector mEmulatedAnimations; + }; +} + +#endif 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.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..e01583399 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -23,34 +23,19 @@ 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 {} - - struct VertexWeight - { - unsigned short vertex; - float value; - }; + void compileGLObjects(osg::RenderInfo& renderInfo) const override {} 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); @@ -61,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: @@ -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; + + typedef std::pair BoneWeight; + + typedef std::vector VertexList; - using VertexList = std::vector; - using BoneWeightList = std::vector; - using Bone2VertexMap = std::map; + 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; diff --git a/components/sceneutil/serialize.cpp b/components/sceneutil/serialize.cpp index 9e7aa83f6..d03612fc1 100644 --- a/components/sceneutil/serialize.cpp +++ b/components/sceneutil/serialize.cpp @@ -144,7 +144,6 @@ void registerSerializers() "NifOsg::UpdateMorphGeometry", "NifOsg::UVController", "NifOsg::VisController", - "NifOsg::NodeIndexHolder", "osgMyGUI::Drawable", "osg::DrawCallback", "osgOQ::ClearQueriesCallback", diff --git a/components/sceneutil/shadow.cpp b/components/sceneutil/shadow.cpp index 1e14fbbb1..3244dc672 100644 --- a/components/sceneutil/shadow.cpp +++ b/components/sceneutil/shadow.cpp @@ -72,6 +72,9 @@ namespace SceneUtil void ShadowManager::disableShadowsForStateSet(osg::ref_ptr stateset) { + if (!Settings::Manager::getBool("enable shadows", "Shadows")) + return; + int numberOfShadowMapsPerLight = Settings::Manager::getInt("number of shadow maps", "Shadows"); numberOfShadowMapsPerLight = std::max(1, std::min(numberOfShadowMapsPerLight, 8)); @@ -168,7 +171,7 @@ namespace SceneUtil if (Settings::Manager::getBool("enable indoor shadows", "Shadows")) mShadowSettings->setCastsShadowTraversalMask(mIndoorShadowCastingMask); else - mShadowTechnique->disableShadows(); + mShadowTechnique->disableShadows(true); } void ShadowManager::enableOutdoorMode() diff --git a/components/sceneutil/shadowsbin.cpp b/components/sceneutil/shadowsbin.cpp new file mode 100644 index 000000000..520ad0362 --- /dev/null +++ b/components/sceneutil/shadowsbin.cpp @@ -0,0 +1,166 @@ +#include "shadowsbin.hpp" +#include +#include +#include +#include + +using namespace osgUtil; + +namespace +{ + template + inline void accumulateState(T& currentValue, T newValue, bool& isOverride, unsigned int overrideFlags) + { + if (isOverride && !(overrideFlags & osg::StateAttribute::PROTECTED)) return; + + if (overrideFlags & osg::StateAttribute::OVERRIDE) + isOverride = true; + + currentValue = newValue; + } + + inline void accumulateModeState(const osg::StateSet* ss, bool& currentValue, bool& isOverride, int mode) + { + const osg::StateSet::ModeList& l = ss->getModeList(); + osg::StateSet::ModeList::const_iterator mf = l.find(mode); + if (mf == l.end()) + return; + int flags = mf->second; + bool newValue = flags & osg::StateAttribute::ON; + accumulateState(currentValue, newValue, isOverride, ss->getMode(mode)); + } + + inline bool materialNeedShadows(osg::Material* m) + { + // I'm pretty sure this needs to check the colour mode - vertex colours might override this value. + return m->getDiffuse(osg::Material::FRONT).a() > 0.5; + } +} + +namespace SceneUtil +{ + +ShadowsBin::ShadowsBin() +{ + mNoTestStateSet = new osg::StateSet; + mNoTestStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); + mNoTestStateSet->addUniform(new osg::Uniform("alphaTestShadows", false)); + + mShaderAlphaTestStateSet = new osg::StateSet; + mShaderAlphaTestStateSet->addUniform(new osg::Uniform("alphaTestShadows", true)); + mShaderAlphaTestStateSet->setMode(GL_BLEND, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); +} + +StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::unordered_set& uninterestingCache) +{ + std::vector return_path; + State state; + StateGraph* sg_new = sg; + do + { + if (uninterestingCache.find(sg_new) != uninterestingCache.end()) + break; + return_path.push_back(sg_new); + sg_new = sg_new->_parent; + } while (sg_new && sg_new != root); + + for(auto itr=return_path.rbegin(); itr!=return_path.rend(); ++itr) + { + const osg::StateSet* ss = (*itr)->getStateSet(); + if (!ss) + continue; + + accumulateModeState(ss, state.mAlphaBlend, state.mAlphaBlendOverride, GL_BLEND); + accumulateModeState(ss, state.mAlphaTest, state.mAlphaTestOverride, GL_ALPHA_TEST); + + const osg::StateSet::AttributeList& attributes = ss->getAttributeList(); + osg::StateSet::AttributeList::const_iterator found = attributes.find(std::make_pair(osg::StateAttribute::MATERIAL, 0)); + if (found != attributes.end()) + { + const osg::StateSet::RefAttributePair& rap = found->second; + accumulateState(state.mMaterial, static_cast(rap.first.get()), state.mMaterialOverride, rap.second); + if (state.mMaterial && !materialNeedShadows(state.mMaterial)) + state.mMaterial = nullptr; + } + + // osg::FrontFace specifies triangle winding, not front-face culling. We can't safely reparent anything under it. + found = attributes.find(std::make_pair(osg::StateAttribute::FRONTFACE, 0)); + if (found != attributes.end()) + state.mImportantState = true; + + if ((*itr) != sg && !state.interesting()) + uninterestingCache.insert(*itr); + } + + if (!state.needShadows()) + return nullptr; + + if (!state.needTexture() && !state.mImportantState) + { + for (RenderLeaf* leaf : sg->_leaves) + { + leaf->_parent = root; + root->_leaves.push_back(leaf); + } + return nullptr; + } + + if (state.mAlphaBlend) + { + sg_new = sg->find_or_insert(mShaderAlphaTestStateSet); + for (RenderLeaf* leaf : sg->_leaves) + { + leaf->_parent = sg_new; + sg_new->_leaves.push_back(leaf); + } + return sg_new; + } + return sg; +} + +bool ShadowsBin::State::needShadows() const +{ + if (!mMaterial) + return true; + return materialNeedShadows(mMaterial); +} + +void ShadowsBin::sortImplementation() +{ + // The cull visitor contains a stategraph. + // When a stateset is pushed, it's added/found as a child of the current stategraph node, then that node becomes the new current stategraph node. + // When a drawable is added, the current stategraph node is added to the current renderbin (if it's not there already) and the drawable is added as a renderleaf to the stategraph + // This means our list only contains stategraph nodes with directly-attached renderleaves, but they might have parents with more state set that needs to be considered. + if (!_stateGraphList.size()) + return; + StateGraph* root = _stateGraphList[0]; + while (root->_parent) + { + root = root->_parent; + const osg::StateSet* ss = root->getStateSet(); + if (ss->getMode(GL_NORMALIZE) & osg::StateAttribute::ON // that is root stategraph of renderingmanager cpp + || ss->getAttribute(osg::StateAttribute::VIEWPORT)) // fallback to rendertargets sg just in case + break; + if (!root->_parent) + return; + } + StateGraph* noTestRoot = root->find_or_insert(mNoTestStateSet.get()); + // root is now a stategraph with useDiffuseMapForShadowAlpha disabled but minimal other state + noTestRoot->_leaves.reserve(_stateGraphList.size()); + StateGraphList newList; + std::unordered_set uninterestingCache; + for (StateGraph* graph : _stateGraphList) + { + // Render leaves which shouldn't use the diffuse map for shadow alpha but do cast shadows become children of root, so graph is now empty. Don't add to newList. + // Graphs containing just render leaves which don't cast shadows are discarded. Don't add to newList. + // Graphs containing other leaves need to be in newList. + StateGraph* graphToAdd = cullStateGraph(graph, noTestRoot, uninterestingCache); + if (graphToAdd) + newList.push_back(graphToAdd); + } + if (!noTestRoot->_leaves.empty()) + newList.push_back(noTestRoot); + _stateGraphList = newList; +} + +} diff --git a/components/sceneutil/shadowsbin.hpp b/components/sceneutil/shadowsbin.hpp new file mode 100644 index 000000000..cc6fd3525 --- /dev/null +++ b/components/sceneutil/shadowsbin.hpp @@ -0,0 +1,76 @@ +#ifndef OPENMW_COMPONENTS_SCENEUTIL_SHADOWBIN_H +#define OPENMW_COMPONENTS_SCENEUTIL_SHADOWBIN_H +#include +#include + +namespace osg +{ + class Material; +} + +namespace SceneUtil +{ + + /// renderbin which culls redundant state for shadow map rendering + class ShadowsBin : public osgUtil::RenderBin + { + private: + osg::ref_ptr mNoTestStateSet; + osg::ref_ptr mShaderAlphaTestStateSet; + public: + META_Object(SceneUtil, ShadowsBin) + ShadowsBin(); + ShadowsBin(const ShadowsBin& rhs, const osg::CopyOp& copyop) + : osgUtil::RenderBin(rhs, copyop) + , mNoTestStateSet(rhs.mNoTestStateSet) + , mShaderAlphaTestStateSet(rhs.mShaderAlphaTestStateSet) + {} + + void sortImplementation() override; + + struct State + { + State() + : mAlphaBlend(false) + , mAlphaBlendOverride(false) + , mAlphaTest(false) + , mAlphaTestOverride(false) + , mMaterial(nullptr) + , mMaterialOverride(false) + , mImportantState(false) + {} + + bool mAlphaBlend; + bool mAlphaBlendOverride; + bool mAlphaTest; + bool mAlphaTestOverride; + osg::Material* mMaterial; + bool mMaterialOverride; + bool mImportantState; + bool needTexture() const { return mAlphaBlend || mAlphaTest; } + bool needShadows() const; + // A state is interesting if there's anything about it that might affect whether we can optimise child state + bool interesting() const + { + return !needShadows() || needTexture() || mAlphaBlendOverride || mAlphaTestOverride || mMaterialOverride || mImportantState; + } + }; + + osgUtil::StateGraph* cullStateGraph(osgUtil::StateGraph* sg, osgUtil::StateGraph* root, std::unordered_set& uninteresting); + + static void addPrototype(const std::string& name) + { + osg::ref_ptr bin (new ShadowsBin); + osgUtil::RenderBin::addRenderBinPrototype(name, bin); + } + }; + + class ShadowsBinAdder + { + public: + ShadowsBinAdder(const std::string& name){ ShadowsBin::addPrototype(name); } + }; + +} + +#endif 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.cpp b/components/sceneutil/statesetupdater.cpp index 9fb9ba496..5d7dbd755 100644 --- a/components/sceneutil/statesetupdater.cpp +++ b/components/sceneutil/statesetupdater.cpp @@ -73,7 +73,7 @@ namespace SceneUtil : StateSetUpdater(copy, copyop) { for (unsigned int i=0; i > mCtrls; }; diff --git a/components/nifosg/textkeymap.hpp b/components/sceneutil/textkeymap.hpp similarity index 94% rename from components/nifosg/textkeymap.hpp rename to components/sceneutil/textkeymap.hpp index 49e1e461e..ee58bc72a 100644 --- a/components/nifosg/textkeymap.hpp +++ b/components/sceneutil/textkeymap.hpp @@ -1,12 +1,12 @@ -#ifndef OPENMW_COMPONENTS_NIFOSG_TEXTKEYMAP -#define OPENMW_COMPONENTS_NIFOSG_TEXTKEYMAP +#ifndef OPENMW_COMPONENTS_SCENEUTIL_TEXTKEYMAP +#define OPENMW_COMPONENTS_SCENEUTIL_TEXTKEYMAP #include #include #include #include -namespace NifOsg +namespace SceneUtil { class TextKeyMap { diff --git a/components/sceneutil/unrefqueue.cpp b/components/sceneutil/unrefqueue.cpp index 21ba836c0..50b23cae9 100644 --- a/components/sceneutil/unrefqueue.cpp +++ b/components/sceneutil/unrefqueue.cpp @@ -18,7 +18,7 @@ namespace SceneUtil void UnrefQueue::push(const osg::Referenced *obj) { - mWorkItem->mObjects.push_back(obj); + mWorkItem->mObjects.emplace_back(obj); } void UnrefQueue::flush(SceneUtil::WorkQueue *workQueue) 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..2c0d8efa0 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())); @@ -112,6 +112,8 @@ void GlowUpdater::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) removeTexture(stateset); this->reset(); mDone = true; + // normally done in StateSetUpdater::operator(), but needs doing here so the shader visitor sees the right StateSet + mNode->setStateSet(stateset); mResourceSystem->getSceneManager()->recreateShaders(mNode); } if (mOriginalDuration < 0) // if this glowupdater was originally a permanent glow 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.cpp b/components/sceneutil/visitor.cpp index 876ea920f..00d18ffcb 100644 --- a/components/sceneutil/visitor.cpp +++ b/components/sceneutil/visitor.cpp @@ -101,7 +101,7 @@ namespace SceneUtil node.setStateSet(nullptr); if (node.getNodeMask() == 0x1 && node.getNumParents() == 1) - mToRemove.push_back(std::make_pair(&node, node.getParent(0))); + mToRemove.emplace_back(&node, node.getParent(0)); else traverse(node); } @@ -120,12 +120,12 @@ namespace SceneUtil osg::Group* parentParent = static_cast(*(parent - 1)); if (parentGroup->getNumChildren() == 1 && parentGroup->getDataVariance() == osg::Object::STATIC) { - mToRemove.push_back(std::make_pair(parentGroup, parentParent)); + mToRemove.emplace_back(parentGroup, parentParent); return; } } - mToRemove.push_back(std::make_pair(&node, parentGroup)); + mToRemove.emplace_back(&node, parentGroup); } void RemoveTriBipVisitor::apply(osg::Drawable& drw) @@ -150,7 +150,7 @@ namespace SceneUtil { osg::Group* parent = static_cast(*(getNodePath().end()-2)); // Not safe to remove in apply(), since the visitor is still iterating the child list - mToRemove.push_back(std::make_pair(&node, parent)); + mToRemove.emplace_back(&node, parent); } } } 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/sdlcursormanager.cpp b/components/sdlutil/sdlcursormanager.cpp index 82854cb2f..56225868e 100644 --- a/components/sdlutil/sdlcursormanager.cpp +++ b/components/sdlutil/sdlcursormanager.cpp @@ -50,7 +50,7 @@ namespace CursorDecompression traits->alpha = 8; traits->windowDecoration = false; traits->doubleBuffer = false; - traits->sharedContext = 0; + traits->sharedContext = nullptr; traits->pbuffer = true; osg::GraphicsContext::ScreenIdentifier si; @@ -267,7 +267,7 @@ namespace SDLUtil if (mCursorMap.find(name) != mCursorMap.end()) return; - static bool forceSoftwareDecompression = (getenv("OPENMW_DECOMPRESS_TEXTURES") != 0); + static bool forceSoftwareDecompression = (getenv("OPENMW_DECOMPRESS_TEXTURES") != nullptr); SurfaceUniquePtr (*decompressionFunction)(osg::ref_ptr, float); if (forceSoftwareDecompression || CursorDecompression::DXTCSupported) { diff --git a/components/sdlutil/sdlgraphicswindow.cpp b/components/sdlutil/sdlgraphicswindow.cpp index 257894ecb..39b479f29 100644 --- a/components/sdlutil/sdlgraphicswindow.cpp +++ b/components/sdlutil/sdlgraphicswindow.cpp @@ -13,8 +13,8 @@ GraphicsWindowSDL2::~GraphicsWindowSDL2() } GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits) - : mWindow(0) - , mContext(0) + : mWindow(nullptr) + , mContext(nullptr) , mValid(false) , mRealized(false) , mOwnsWindow(false) @@ -81,7 +81,7 @@ void GraphicsWindowSDL2::init() WindowData *inheritedWindowData = dynamic_cast(_traits->inheritedWindowData.get()); mWindow = inheritedWindowData ? inheritedWindowData->mWindow : nullptr; - mOwnsWindow = (mWindow == 0); + mOwnsWindow = (mWindow == nullptr); if(mOwnsWindow) { OSG_FATAL<<"Error: No SDL window provided."<(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)!=nullptr; } + 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/shadermanager.cpp b/components/shader/shadermanager.cpp index 56db194b5..c76e3efed 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -503,16 +503,6 @@ namespace Shader program.second->releaseGLObjects(state); } - const osg::ref_ptr ShaderManager::getShadowMapAlphaTestEnableUniform() - { - return mShadowMapAlphaTestEnableUniform; - } - - const osg::ref_ptr ShaderManager::getShadowMapAlphaTestDisableUniform() - { - return mShadowMapAlphaTestDisableUniform; - } - std::string ShaderManager::getTemplateSource(const std::string& templateName) { // read the template if we haven't already diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index 47df0b4e9..05434a09b 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -51,9 +51,6 @@ namespace Shader void releaseGLObjects(osg::State* state); - const osg::ref_ptr getShadowMapAlphaTestEnableUniform(); - const osg::ref_ptr getShadowMapAlphaTestDisableUniform(); - private: std::string getTemplateSource(const std::string& templateName); @@ -77,9 +74,6 @@ namespace Shader ProgramMap mPrograms; std::mutex mMutex; - - const osg::ref_ptr mShadowMapAlphaTestEnableUniform = new osg::Uniform(); - const osg::ref_ptr mShadowMapAlphaTestDisableUniform = new osg::Uniform(); }; bool parseFors(std::string& source, const std::string& templateName); diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index c690ace25..19636050c 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -1,7 +1,5 @@ #include "shadervisitor.hpp" -#include -#include #include #include #include @@ -14,7 +12,6 @@ #include #include #include -#include #include "shadermanager.hpp" @@ -25,7 +22,6 @@ namespace Shader : mShaderRequired(false) , mColorMode(0) , mMaterialOverridden(false) - , mBlendFuncOverridden(false) , mNormalHeight(false) , mTexStageRequiringTangents(-1) , mNode(nullptr) @@ -43,12 +39,13 @@ namespace Shader , mAllowedToModifyStateSets(true) , mAutoUseNormalMaps(false) , mAutoUseSpecularMaps(false) + , mApplyLightingToEnvMaps(false) , mShaderManager(shaderManager) , mImageManager(imageManager) , mDefaultVsTemplate(defaultVsTemplate) , mDefaultFsTemplate(defaultFsTemplate) { - mRequirements.push_back(ShaderRequirements()); + mRequirements.emplace_back(); } void ShaderVisitor::setForceShaders(bool force) @@ -144,11 +141,9 @@ namespace Shader // Bump maps are off by default as well writableStateSet->setTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON); } - else if (texName == "envMap") + else if (texName == "envMap" && mApplyLightingToEnvMaps) { - static const bool preLightEnv = Settings::Manager::getBool("apply lighting to environment maps", "Shaders"); - if (preLightEnv) - mRequirements.back().mShaderRequired = true; + mRequirements.back().mShaderRequired = true; } } else @@ -233,14 +228,11 @@ namespace Shader if (!writableStateSet) writableStateSet = getWritableStateSet(node); // We probably shouldn't construct a new version of this each time as Uniforms use pointer comparison for early-out. - // Also it should probably belong to the shader manager + // Also it should probably belong to the shader manager or be applied by the shadows bin writableStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true)); } } - bool alphaSettingsChanged = false; - bool alphaTestShadows = false; - const osg::StateSet::AttributeList& attributes = stateset->getAttributeList(); for (osg::StateSet::AttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it) { @@ -284,28 +276,8 @@ namespace Shader mRequirements.back().mColorMode = colorMode; } } - else if (it->first.first == osg::StateAttribute::BLENDFUNC) - { - if (!mRequirements.back().mBlendFuncOverridden || it->second.second & osg::StateAttribute::PROTECTED) - { - if (it->second.second & osg::StateAttribute::OVERRIDE) - mRequirements.back().mBlendFuncOverridden = true; - - const osg::BlendFunc* blend = static_cast(it->second.first.get()); - if (blend->getSource() == osg::BlendFunc::SRC_ALPHA || blend->getSource() == osg::BlendFunc::SRC_COLOR) - alphaTestShadows = true; - alphaSettingsChanged = true; - } - } // Eventually, move alpha testing to discard in shader adn remove deprecated state here } - // we don't need to check for glEnable/glDisable of blending as we always set it at the same time - if (alphaSettingsChanged) - { - if (!writableStateSet) - writableStateSet = getWritableStateSet(node); - writableStateSet->addUniform(alphaTestShadows ? mShaderManager.getShadowMapAlphaTestEnableUniform() : mShaderManager.getShadowMapAlphaTestDisableUniform()); - } } void ShaderVisitor::pushRequirements(osg::Node& node) @@ -322,7 +294,10 @@ namespace Shader void ShaderVisitor::createProgram(const ShaderRequirements &reqs) { if (!reqs.mShaderRequired && !mForceShaders) + { + ensureFFP(*reqs.mNode); return; + } osg::Node& node = *reqs.mNode; osg::StateSet* writableStateSet = nullptr; @@ -362,6 +337,19 @@ namespace Shader } } + void ShaderVisitor::ensureFFP(osg::Node& node) + { + if (!node.getStateSet() || !node.getStateSet()->getAttribute(osg::StateAttribute::PROGRAM)) + return; + osg::StateSet* writableStateSet = nullptr; + if (mAllowedToModifyStateSets) + writableStateSet = node.getStateSet(); + else + writableStateSet = getWritableStateSet(node); + + writableStateSet->removeAttribute(osg::StateAttribute::PROGRAM); + } + bool ShaderVisitor::adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs) { bool useShader = reqs.mShaderRequired || mForceShaders; @@ -409,6 +397,8 @@ namespace Shader createProgram(reqs); } + else + ensureFFP(geometry); if (needPop) popRequirements(); @@ -443,6 +433,8 @@ namespace Shader morph->setSourceGeometry(sourceGeometry); } } + else + ensureFFP(drawable); if (needPop) popRequirements(); @@ -478,4 +470,9 @@ namespace Shader mSpecularMapPattern = pattern; } + void ShaderVisitor::setApplyLightingToEnvMaps(bool apply) + { + mApplyLightingToEnvMaps = apply; + } + } diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index 8e35f1d9c..6031dbfe6 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -38,10 +38,12 @@ namespace Shader void setSpecularMapPattern(const std::string& pattern); - virtual void apply(osg::Node& node); + void setApplyLightingToEnvMaps(bool apply); - virtual void apply(osg::Drawable& drawable); - virtual void apply(osg::Geometry& geometry); + void apply(osg::Node& node) override; + + void apply(osg::Drawable& drawable) override; + void apply(osg::Geometry& geometry) override; void applyStateSet(osg::ref_ptr stateset, osg::Node& node); @@ -59,6 +61,8 @@ namespace Shader bool mAutoUseSpecularMaps; std::string mSpecularMapPattern; + bool mApplyLightingToEnvMaps; + ShaderManager& mShaderManager; Resource::ImageManager& mImageManager; @@ -75,7 +79,6 @@ namespace Shader int mColorMode; bool mMaterialOverridden; - bool mBlendFuncOverridden; bool mNormalHeight; // true if normal map has height info in alpha channel @@ -91,6 +94,7 @@ namespace Shader std::string mDefaultFsTemplate; void createProgram(const ShaderRequirements& reqs); + void ensureFFP(osg::Node& node); bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs); }; diff --git a/components/terrain/chunkmanager.cpp b/components/terrain/chunkmanager.cpp index 87966b47c..041414a87 100644 --- a/components/terrain/chunkmanager.cpp +++ b/components/terrain/chunkmanager.cpp @@ -112,7 +112,7 @@ void ChunkManager::createCompositeMapGeometry(float chunkSize, const osg::Vec2f& geom->setStateSet(*it); - compositeMap.mDrawables.push_back(geom); + compositeMap.mDrawables.emplace_back(geom); } } } 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.cpp b/components/terrain/quadtreenode.cpp index 7baea45c8..c113a629c 100644 --- a/components/terrain/quadtreenode.cpp +++ b/components/terrain/quadtreenode.cpp @@ -63,7 +63,7 @@ QuadTreeNode::QuadTreeNode(QuadTreeNode* parent, ChildDirection direction, float , mCenter(center) { for (unsigned int i=0; i<4; ++i) - mNeighbours[i] = 0; + mNeighbours[i] = nullptr; } QuadTreeNode::~QuadTreeNode() 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.cpp b/components/terrain/viewdata.cpp index c24252b7d..e4d043ffc 100644 --- a/components/terrain/viewdata.cpp +++ b/components/terrain/viewdata.cpp @@ -192,7 +192,7 @@ ViewData *ViewDataMap::createOrReuseView() } else { - mViewVector.push_back(ViewData()); + mViewVector.emplace_back(); vd = &mViewVector.back(); } mUsedViews.push_back(vd); 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.cpp b/components/vfs/bsaarchive.cpp index 9646b62af..ac65c58a1 100644 --- a/components/vfs/bsaarchive.cpp +++ b/components/vfs/bsaarchive.cpp @@ -21,7 +21,7 @@ BsaArchive::BsaArchive(const std::string &filename) const Bsa::BSAFile::FileList &filelist = mFile->getList(); for(Bsa::BSAFile::FileList::const_iterator it = filelist.begin();it != filelist.end();++it) { - mResources.push_back(BsaArchiveFile(&*it, mFile.get())); + mResources.emplace_back(&*it, mFile.get()); } } 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/box.cpp b/components/widgets/box.cpp index 1db193320..23a108ee9 100644 --- a/components/widgets/box.cpp +++ b/components/widgets/box.cpp @@ -8,7 +8,7 @@ namespace Gui void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w) { MyGUI::Widget * parent = w->getParent(); - if (parent != 0) + if (parent != nullptr) { if (mExpandDirection.isLeft()) { @@ -17,7 +17,7 @@ namespace Gui } w->setSize(getRequestedSize ()); - while (parent != 0) + while (parent != nullptr) { Box * b = dynamic_cast(parent); if (b) @@ -280,7 +280,7 @@ namespace Gui void HBox::initialiseOverride() { Base::initialiseOverride(); - MyGUI::Widget* client = 0; + MyGUI::Widget* client = nullptr; assignWidget(client, "Client"); setWidgetClient(client); } @@ -435,7 +435,7 @@ namespace Gui void VBox::initialiseOverride() { Base::initialiseOverride(); - MyGUI::Widget* client = 0; + MyGUI::Widget* client = nullptr; assignWidget(client, "Client"); setWidgetClient(client); } diff --git a/components/widgets/box.hpp b/components/widgets/box.hpp index e84c3bb1f..60d0ea67a 100644 --- a/components/widgets/box.hpp +++ b/components/widgets/box.hpp @@ -46,11 +46,11 @@ namespace Gui MYGUI_RTTI_DERIVED( AutoSizedTextBox ) public: - MyGUI::IntSize getRequestedSize() final; - void setCaption(const MyGUI::UString& _value) final; + MyGUI::IntSize getRequestedSize() override; + void setCaption(const MyGUI::UString& _value) override; protected: - void setPropertyOverride(const std::string& _key, const std::string& _value) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; std::string mFontSize; }; @@ -60,13 +60,13 @@ namespace Gui public: - MyGUI::IntSize getRequestedSize() final; - void setCaption(const MyGUI::UString& _value) final; + MyGUI::IntSize getRequestedSize() override; + void setCaption(const MyGUI::UString& _value) override; - void initialiseOverride() final; + void initialiseOverride() override; protected: - void setPropertyOverride(const std::string& _key, const std::string& _value) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; int getWidth(); std::string mFontSize; bool mShrink = false; @@ -79,11 +79,11 @@ namespace Gui MYGUI_RTTI_DERIVED( AutoSizedButton ) public: - MyGUI::IntSize getRequestedSize() final; - void setCaption(const MyGUI::UString& _value) final; + MyGUI::IntSize getRequestedSize() override; + void setCaption(const MyGUI::UString& _value) override; protected: - void setPropertyOverride(const std::string& _key, const std::string& _value) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; std::string mFontSize; }; @@ -118,7 +118,7 @@ namespace Gui public: Spacer(); - MyGUI::IntSize getRequestedSize() final { return MyGUI::IntSize(0,0); } + MyGUI::IntSize getRequestedSize() override { return MyGUI::IntSize(0,0); } }; class HBox : public Box, public MyGUI::Widget @@ -126,18 +126,18 @@ namespace Gui MYGUI_RTTI_DERIVED( HBox ) public: - void setSize (const MyGUI::IntSize &_value) final; - void setCoord (const MyGUI::IntCoord &_value) final; + void setSize (const MyGUI::IntSize &_value) override; + void setCoord (const MyGUI::IntCoord &_value) override; protected: - void initialiseOverride() final; + void initialiseOverride() override; - void align() final; - MyGUI::IntSize getRequestedSize() final; + void align() override; + MyGUI::IntSize getRequestedSize() override; - void setPropertyOverride(const std::string& _key, const std::string& _value) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; - void onWidgetCreated(MyGUI::Widget* _widget) final; + void onWidgetCreated(MyGUI::Widget* _widget) override; }; class VBox : public Box, public MyGUI::Widget @@ -145,18 +145,18 @@ namespace Gui MYGUI_RTTI_DERIVED( VBox) public: - void setSize (const MyGUI::IntSize &_value) final; - void setCoord (const MyGUI::IntCoord &_value) final; + void setSize (const MyGUI::IntSize &_value) override; + void setCoord (const MyGUI::IntCoord &_value) override; protected: - void initialiseOverride() final; + void initialiseOverride() override; - void align() final; - MyGUI::IntSize getRequestedSize() final; + void align() override; + MyGUI::IntSize getRequestedSize() override; - void setPropertyOverride(const std::string& _key, const std::string& _value) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; - void onWidgetCreated(MyGUI::Widget* _widget) final; + void onWidgetCreated(MyGUI::Widget* _widget) override; }; } 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/components/widgets/imagebutton.hpp b/components/widgets/imagebutton.hpp index 160f24e99..6e3fc1733 100644 --- a/components/widgets/imagebutton.hpp +++ b/components/widgets/imagebutton.hpp @@ -31,13 +31,13 @@ namespace Gui static bool sDefaultNeedKeyFocus; protected: - void setPropertyOverride(const std::string& _key, const std::string& _value) final; - void onMouseLostFocus(MyGUI::Widget* _new) final; - void onMouseSetFocus(MyGUI::Widget* _old) final; - void onMouseButtonPressed(int _left, int _top, MyGUI::MouseButton _id) final; - void onMouseButtonReleased(int _left, int _top, MyGUI::MouseButton _id) final; - void onKeySetFocus(MyGUI::Widget* _old) final; - void onKeyLostFocus(MyGUI::Widget* _new) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; + void onMouseLostFocus(MyGUI::Widget* _new) override; + void onMouseSetFocus(MyGUI::Widget* _old) override; + void onMouseButtonPressed(int _left, int _top, MyGUI::MouseButton _id) override; + void onMouseButtonReleased(int _left, int _top, MyGUI::MouseButton _id) override; + void onKeySetFocus(MyGUI::Widget* _old) override; + void onKeyLostFocus(MyGUI::Widget* _new) override; std::string mImageHighlighted; std::string mImageNormal; diff --git a/components/widgets/list.cpp b/components/widgets/list.cpp index 73e01675a..73ca94929 100644 --- a/components/widgets/list.cpp +++ b/components/widgets/list.cpp @@ -7,9 +7,9 @@ namespace Gui { - MWList::MWList() : - mScrollView(0) - ,mClient(0) + MWList::MWList() + : mScrollView(nullptr) + , mClient(nullptr) , mItemHeight(0) { } @@ -19,7 +19,7 @@ namespace Gui Base::initialiseOverride(); assignWidget(mClient, "Client"); - if (mClient == 0) + if (mClient == nullptr) mClient = this; mScrollView = mClient->createWidgetReal( @@ -34,7 +34,7 @@ namespace Gui void MWList::addSeparator() { - mItems.push_back(""); + mItems.emplace_back(""); } void MWList::adjustSize() diff --git a/components/widgets/list.hpp b/components/widgets/list.hpp index 604d5dada..be0339f33 100644 --- a/components/widgets/list.hpp +++ b/components/widgets/list.hpp @@ -48,10 +48,10 @@ namespace Gui void scrollToTop(); - void setPropertyOverride(const std::string& _key, const std::string& _value) final; + void setPropertyOverride(const std::string& _key, const std::string& _value) override; protected: - void initialiseOverride() final; + void initialiseOverride() override; void redraw(bool scrollbarShown = false); diff --git a/components/widgets/numericeditbox.hpp b/components/widgets/numericeditbox.hpp index ff16424d0..e1f33e887 100644 --- a/components/widgets/numericeditbox.hpp +++ b/components/widgets/numericeditbox.hpp @@ -22,8 +22,8 @@ namespace Gui { } - void initialiseOverride() final; - void shutdownOverride() final; + void initialiseOverride() override; + void shutdownOverride() override; typedef MyGUI::delegates::CMultiDelegate1 EventHandle_ValueChanged; EventHandle_ValueChanged eventValueChanged; @@ -36,8 +36,8 @@ namespace Gui void setMaxValue(int maxValue); private: void onEditTextChange(MyGUI::EditBox* sender); - void onKeyLostFocus(MyGUI::Widget* _new) final; - void onKeyButtonPressed(MyGUI::KeyCode key, MyGUI::Char character) final; + void onKeyLostFocus(MyGUI::Widget* _new) override; + void onKeyButtonPressed(MyGUI::KeyCode key, MyGUI::Char character) override; int mValue; diff --git a/components/widgets/sharedstatebutton.hpp b/components/widgets/sharedstatebutton.hpp index 859543d20..42c6424b2 100644 --- a/components/widgets/sharedstatebutton.hpp +++ b/components/widgets/sharedstatebutton.hpp @@ -23,13 +23,13 @@ namespace Gui protected: void updateButtonState(); - void onMouseButtonPressed(int _left, int _top, MyGUI::MouseButton _id) final; - void onMouseButtonReleased(int _left, int _top, MyGUI::MouseButton _id) final; - void onMouseSetFocus(MyGUI::Widget* _old) final; - void onMouseLostFocus(MyGUI::Widget* _new) final; - void baseUpdateEnable() final; + void onMouseButtonPressed(int _left, int _top, MyGUI::MouseButton _id) override; + void onMouseButtonReleased(int _left, int _top, MyGUI::MouseButton _id) override; + void onMouseSetFocus(MyGUI::Widget* _old) override; + void onMouseLostFocus(MyGUI::Widget* _new) override; + void baseUpdateEnable() override; - void shutdownOverride() final; + void shutdownOverride() override; bool _setState(const std::string &_value); diff --git a/components/widgets/windowcaption.hpp b/components/widgets/windowcaption.hpp index f8c1a310c..256c82831 100644 --- a/components/widgets/windowcaption.hpp +++ b/components/widgets/windowcaption.hpp @@ -14,11 +14,11 @@ namespace Gui public: WindowCaption(); - void setCaption(const MyGUI::UString &_value) final; - void initialiseOverride() final; + void setCaption(const MyGUI::UString &_value) override; + void initialiseOverride() override; - void setSize(const MyGUI::IntSize& _value) final; - void setCoord(const MyGUI::IntCoord& _value) final; + void setSize(const MyGUI::IntSize& _value) override; + void setCoord(const MyGUI::IntCoord& _value) override; private: MyGUI::Widget* mLeft; 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 diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index 349a98697..cad04ab5c 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -72,7 +72,7 @@ The Bethesda provided assets have a 4:3 aspect ratio, but other assets are permi If this setting is false, the assets will be centered in their correct aspect ratio, with black bars filling the remainder of the screen. -This setting can only be configured by editing the settings configuration file. +This setting can be configured in the Interface section of Advanced tab of the launcher. subtitles --------- 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/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/docs/source/reference/modding/settings/index.rst b/docs/source/reference/modding/settings/index.rst index a31ce0d53..586a99dbb 100644 --- a/docs/source/reference/modding/settings/index.rst +++ b/docs/source/reference/modding/settings/index.rst @@ -57,3 +57,5 @@ The ranges included with each setting are the physically possible ranges, not re water windows navigator + physics + models diff --git a/docs/source/reference/modding/settings/models.rst b/docs/source/reference/modding/settings/models.rst new file mode 100644 index 000000000..b0da374d6 --- /dev/null +++ b/docs/source/reference/modding/settings/models.rst @@ -0,0 +1,31 @@ +Models Settings +############### + +load unsupported nif files +-------------------------- + +:Type: boolean +:Range: True/False +:Default: False + +Allow the engine to load arbitrary NIF files as long as they appear to be valid. + +OpenMW has limited and **experimental** support for NIF files +that Morrowind itself cannot load, which normally goes unused. + +If enabled, this setting allows the NIF loader to make use of that functionality. + +.. warning:: + You must keep in mind that since the mentioned support is experimental, + loading unsupported NIF files may fail, and the degree of this failure may vary. + + In milder cases, OpenMW will reject the file anyway because + it lacks a definition for a certain record type that the file may use. + + In more severe cases OpenMW's incomplete understanding of a record type + can lead to memory corruption, freezes or even crashes. + + **Do not enable** this if you're not so sure that you know what you're doing. + +To help debug possible issues OpenMW will log its progress in loading +every file that uses an unsupported NIF version. 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/docs/source/reference/modding/settings/terrain.rst b/docs/source/reference/modding/settings/terrain.rst index 824c27913..149ef979e 100644 --- a/docs/source/reference/modding/settings/terrain.rst +++ b/docs/source/reference/modding/settings/terrain.rst @@ -8,21 +8,19 @@ distant terrain :Range: True/False :Default: False -Controls whether the engine will use paging and LOD algorithms to load the terrain of the entire world at all times. +Controls whether the engine will use paging (chunking) and LOD algorithms to load the terrain of the entire world at all times. Otherwise, only the terrain of the surrounding cells is loaded. .. note:: When enabling distant terrain, make sure the 'viewing distance' in the camera section is set to a larger value so - that you can actually see the additional terrain. + that you can actually see the additional terrain and objects. To avoid frame drops as the player moves around, nearby terrain pages are always preloaded in the background, regardless of the preloading settings in the 'Cells' section, but the preloading of terrain behind a door or a travel destination, for example, will still be controlled by cell preloading settings. -The distant terrain engine is currently considered experimental -and may receive updates and/or further configuration options in the future. -The glaring omission of non-terrain objects in the distance somewhat limits this setting's usefulness. +The distant terrain engine is currently considered experimental and may receive updates in the future. vertex lod mod -------------- @@ -101,3 +99,107 @@ max composite geometry size Controls the maximum size of simple composite geometry chunk in cell units. With small values there will more draw calls and small textures, but higher values create more overdraw (not every texture layer is used everywhere). + +object paging +------------- + +:Type: boolean +:Range: True/False +:Default: True + +Controls whether the engine will use paging (chunking) algorithms to load non-terrain objects +outside of the active cell grid. + +Depending on the settings below every object in the game world has a chance +to be batched and be visible in the game world, effectively allowing +the engine to render distant objects with a relatively low performance impact automatically. + +In general, an object is more likely to be batched if the number of the object's vertices +and the corresponding memory cost of merging the object is low compared to +the expected number of the draw calls that are going to be optimized out. +This memory cost and the saved number of draw calls shall be called +the "merging cost" and the "merging benefit" in the following documentation. + +Objects that are scripted to disappear from the game world +will be handled properly as long as their scripts have a chance to actually disable them. + +This setting has no effect if distant terrain is disabled. + +object paging active grid +------------------------- +:Type: boolean +:Range: True/False +:Default: False + +Controls whether the objects in the active cells use the mentioned paging algorithms. +Active grid paging significantly improves the framerate when your setup is CPU-limited. + +.. note:: + Given that only 8 light sources may affect an object at a time at the moment, + lighting issues arising due to merged objects being considered a single object + may disrupt your gameplay experience. + +object paging merge factor +-------------------------- +:Type: float +:Range: >0 +:Default: 250.0 + +Affects the likelyhood of objects being merged. +Higher values improve the framerate at the cost of memory. + +Technically this is implemented as a multiplier to the merging benefit, and since +an object has a lot of vertices, sometimes in terms of hundreds and thousands, +and doesn't often need as much draw calls to be rendered (typically that number is in 1 or 2 digits) +this value needs to be large enough, as this is what makes +the merging cost and the merging benefit actually comparable for the sake of paging. + +object paging min size +---------------------- +:Type: float +:Range: >0 +:Default: 0.01 + +Controls how large an object must be to be visible in the scene. +The object's size is divided by its distance to the camera +and the result of the division is compared with this value. +The smaller this value is, the more objects you will see in the scene. + +object paging min size merge factor +----------------------------------- +:Type: float +:Range: >0 +:Default: 0.3 + +This setting gives inexpensive objects a chance to be rendered from a greater distance +even if the engine would rather discard them according to the previous setting. + +It controls the factor that the minimum size is multiplied by +roughly according to the following formula: + + factor = merge cost * min size cost multiplier / merge benefit + + factor = factor + (1 - factor) * min size merge factor + +Since the larger this factor is, the smaller chance a large object has to be rendered, +decreasing this value makes more objects visible in the scene +without impacting the performance as dramatically as the minimum size setting. + +object paging min size cost multiplier +-------------------------------------- +:Type: float +:Range: >0 +:Default: 25.0 + +This setting adjusts the calculated cost of merging an object used in the mentioned functionality. +The larger this value is, the less expensive objects can be before they are discarded. +See the formula above to figure out the math. + +object paging debug batches +--------------------------- +:Type: boolean +:Range: True/False +:Default: False + +This debug setting allows you to see what objects have been merged in the scene +by making them colored randomly. diff --git a/docs/source/reference/modding/settings/water.rst b/docs/source/reference/modding/settings/water.rst index 3581efb99..b79daacb7 100644 --- a/docs/source/reference/modding/settings/water.rst +++ b/docs/source/reference/modding/settings/water.rst @@ -59,7 +59,7 @@ This setting has no effect if the shader setting is false. This setting can be toggled with the 'Refraction' button in the Water tab of the Video panel of the Options menu. reflection detail --------------- +----------------- :Type: integer :Range: 0, 1, 2, 3, 4 @@ -111,3 +111,6 @@ This setting only applies if water shader is on and refractions are enabled. Not setting if off, there will still be small refractions caused by the water waves, which however do not cause such significant distortion. +.. warning:: + The `refraction scale` is currently mutually exclusive to underwater shadows. Setting this to any value except 1.0 + will cause underwater shadows to be disabled. This will be addressed in issue https://gitlab.com/OpenMW/openmw/-/issues/5709 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/osg-ffmpeg-videoplayer/audiodecoder.cpp b/extern/osg-ffmpeg-videoplayer/audiodecoder.cpp index 0c314ec7d..337382679 100644 --- a/extern/osg-ffmpeg-videoplayer/audiodecoder.cpp +++ b/extern/osg-ffmpeg-videoplayer/audiodecoder.cpp @@ -30,7 +30,7 @@ namespace Video struct AudioResampler { AudioResampler() - : mSwr(NULL) + : mSwr(nullptr) { } @@ -51,8 +51,8 @@ MovieAudioDecoder::MovieAudioDecoder(VideoState* videoState) , mFramePos(0) , mFrameSize(0) , mAudioClock(0.0) - , mDataBuf(NULL) - , mFrameData(NULL) + , mDataBuf(nullptr) + , mFrameData(nullptr) , mDataBufLen(0) , mFrame(av_frame_alloc()) , mGetNextPacket(true) @@ -125,7 +125,7 @@ void MovieAudioDecoder::setupFormat() inputSampleFormat, inputSampleRate, 0, // logging level offset - NULL); // log context + nullptr); // log context if(!mAudioResampler->mSwr) fail(std::string("Couldn't allocate SwrContext")); if(swr_init(mAudioResampler->mSwr) < 0) diff --git a/extern/osg-ffmpeg-videoplayer/videoplayer.cpp b/extern/osg-ffmpeg-videoplayer/videoplayer.cpp index c6544de9c..28ac3b36c 100644 --- a/extern/osg-ffmpeg-videoplayer/videoplayer.cpp +++ b/extern/osg-ffmpeg-videoplayer/videoplayer.cpp @@ -11,7 +11,7 @@ namespace Video { VideoPlayer::VideoPlayer() - : mState(NULL) + : mState(nullptr) { } @@ -87,13 +87,13 @@ void VideoPlayer::close() mState->deinit(); delete mState; - mState = NULL; + mState = nullptr; } } bool VideoPlayer::hasAudioStream() { - return mState && mState->audio_st != NULL; + return mState && mState->audio_st != nullptr; } void VideoPlayer::play() diff --git a/extern/osg-ffmpeg-videoplayer/videostate.cpp b/extern/osg-ffmpeg-videoplayer/videostate.cpp index c176fe0f2..5858d985a 100644 --- a/extern/osg-ffmpeg-videoplayer/videostate.cpp +++ b/extern/osg-ffmpeg-videoplayer/videostate.cpp @@ -42,14 +42,14 @@ namespace Video { VideoState::VideoState() - : mAudioFactory(NULL) - , format_ctx(NULL) - , video_ctx(NULL) - , audio_ctx(NULL) + : mAudioFactory(nullptr) + , format_ctx(nullptr) + , video_ctx(nullptr) + , audio_ctx(nullptr) , av_sync_type(AV_SYNC_DEFAULT) - , audio_st(NULL) - , video_st(NULL), frame_last_pts(0.0) - , video_clock(0.0), sws_context(NULL), rgbaFrame(NULL), pictq_size(0) + , audio_st(nullptr) + , video_st(nullptr), frame_last_pts(0.0) + , video_clock(0.0), sws_context(nullptr), rgbaFrame(nullptr), pictq_size(0) , pictq_rindex(0), pictq_windex(0) , mSeekRequested(false) , mSeekPos(0) @@ -86,7 +86,7 @@ void PacketQueue::put(AVPacket *pkt) throw std::runtime_error("Failed to duplicate packet"); pkt1->pkt = *pkt; - pkt1->next = NULL; + pkt1->next = nullptr; this->mutex.lock (); @@ -112,7 +112,7 @@ int PacketQueue::get(AVPacket *pkt, VideoState *is) { this->first_pkt = pkt1->next; if(!this->first_pkt) - this->last_pkt = NULL; + this->last_pkt = nullptr; this->nb_packets--; this->size -= pkt1->pkt.size; @@ -141,15 +141,15 @@ void PacketQueue::clear() AVPacketList *pkt, *pkt1; this->mutex.lock(); - for(pkt = this->first_pkt; pkt != NULL; pkt = pkt1) + for(pkt = this->first_pkt; pkt != nullptr; pkt = pkt1) { pkt1 = pkt->next; if (pkt->pkt.data != flush_pkt.data) av_packet_unref(&pkt->pkt); av_freep(&pkt); } - this->last_pkt = NULL; - this->first_pkt = NULL; + this->last_pkt = nullptr; + this->first_pkt = nullptr; this->nb_packets = 0; this->size = 0; this->mutex.unlock (); @@ -296,14 +296,14 @@ int VideoState::queue_picture(AVFrame *pFrame, double pts) // Convert the image into RGBA format // TODO: we could do this in a pixel shader instead, if the source format // matches a commonly used format (ie YUV420P) - if(this->sws_context == NULL) + if(this->sws_context == nullptr) { int w = this->video_ctx->width; int h = this->video_ctx->height; this->sws_context = sws_getContext(w, h, this->video_ctx->pix_fmt, w, h, AV_PIX_FMT_RGBA, SWS_BICUBIC, - NULL, NULL, NULL); - if(this->sws_context == NULL) + nullptr, nullptr, nullptr); + if(this->sws_context == nullptr) throw std::runtime_error("Cannot initialize the conversion context!\n"); } @@ -587,7 +587,7 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx) av_codec_set_pkt_timebase(this->audio_ctx, pFormatCtx->streams[stream_index]->time_base); #endif - if (avcodec_open2(this->audio_ctx, codec, NULL) < 0) + if (avcodec_open2(this->audio_ctx, codec, nullptr) < 0) { fprintf(stderr, "Unsupported codec!\n"); return -1; @@ -597,7 +597,7 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx) { std::cerr << "No audio factory registered, can not play audio stream" << std::endl; avcodec_free_context(&this->audio_ctx); - this->audio_st = NULL; + this->audio_st = nullptr; return -1; } @@ -606,7 +606,7 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx) { std::cerr << "Failed to create audio decoder, can not play audio stream" << std::endl; avcodec_free_context(&this->audio_ctx); - this->audio_st = NULL; + this->audio_st = nullptr; return -1; } mAudioDecoder->setupFormat(); @@ -624,7 +624,7 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx) av_codec_set_pkt_timebase(this->video_ctx, pFormatCtx->streams[stream_index]->time_base); #endif - if (avcodec_open2(this->video_ctx, codec, NULL) < 0) + if (avcodec_open2(this->video_ctx, codec, nullptr) < 0) { fprintf(stderr, "Unsupported codec!\n"); return -1; @@ -653,7 +653,7 @@ void VideoState::init(std::shared_ptr inputstream, const std::stri if(!this->stream.get()) throw std::runtime_error("Failed to open video resource"); - AVIOContext *ioCtx = avio_alloc_context(NULL, 0, 0, this, istream_read, istream_write, istream_seek); + AVIOContext *ioCtx = avio_alloc_context(nullptr, 0, 0, this, istream_read, istream_write, istream_seek); if(!ioCtx) throw std::runtime_error("Failed to allocate AVIOContext"); this->format_ctx = avformat_alloc_context(); @@ -667,27 +667,27 @@ void VideoState::init(std::shared_ptr inputstream, const std::stri /// /// https://trac.ffmpeg.org/ticket/1357 /// - if(!this->format_ctx || avformat_open_input(&this->format_ctx, name.c_str(), NULL, NULL)) + if(!this->format_ctx || avformat_open_input(&this->format_ctx, name.c_str(), nullptr, nullptr)) { - if (this->format_ctx != NULL) + if (this->format_ctx != nullptr) { - if (this->format_ctx->pb != NULL) + if (this->format_ctx->pb != nullptr) { av_free(this->format_ctx->pb->buffer); - this->format_ctx->pb->buffer = NULL; + this->format_ctx->pb->buffer = nullptr; av_free(this->format_ctx->pb); - this->format_ctx->pb = NULL; + this->format_ctx->pb = nullptr; } } // "Note that a user-supplied AVFormatContext will be freed on failure." - this->format_ctx = NULL; + this->format_ctx = nullptr; av_free(ioCtx); throw std::runtime_error("Failed to open video input"); } // Retrieve stream information - if(avformat_find_stream_info(this->format_ctx, NULL) < 0) + if(avformat_find_stream_info(this->format_ctx, nullptr) < 0) throw std::runtime_error("Failed to retrieve stream information"); // Dump information about file onto standard error @@ -735,16 +735,16 @@ void VideoState::deinit() if(this->audio_ctx) avcodec_free_context(&this->audio_ctx); - this->audio_st = NULL; - this->audio_ctx = NULL; + this->audio_st = nullptr; + this->audio_ctx = nullptr; if(this->video_ctx) avcodec_free_context(&this->video_ctx); - this->video_st = NULL; - this->video_ctx = NULL; + this->video_st = nullptr; + this->video_ctx = nullptr; if(this->sws_context) sws_freeContext(this->sws_context); - this->sws_context = NULL; + this->sws_context = nullptr; if(this->format_ctx) { @@ -754,13 +754,13 @@ void VideoState::deinit() /// /// https://trac.ffmpeg.org/ticket/1357 /// - if (this->format_ctx->pb != NULL) + if (this->format_ctx->pb != nullptr) { av_free(this->format_ctx->pb->buffer); - this->format_ctx->pb->buffer = NULL; + this->format_ctx->pb->buffer = nullptr; av_free(this->format_ctx->pb); - this->format_ctx->pb = NULL; + this->format_ctx->pb = nullptr; } avformat_close_input(&this->format_ctx); } @@ -768,8 +768,8 @@ void VideoState::deinit() if (mTexture) { // reset Image separately, it's pointing to *this and there might still be outside references to mTexture - mTexture->setImage(NULL); - mTexture = NULL; + mTexture->setImage(nullptr); + mTexture = nullptr; } } diff --git a/extern/osg-ffmpeg-videoplayer/videostate.hpp b/extern/osg-ffmpeg-videoplayer/videostate.hpp index 984050cd6..641fce04b 100644 --- a/extern/osg-ffmpeg-videoplayer/videostate.hpp +++ b/extern/osg-ffmpeg-videoplayer/videostate.hpp @@ -71,7 +71,7 @@ struct ExternalClock struct PacketQueue { PacketQueue() - : first_pkt(NULL), last_pkt(NULL), flushing(false), nb_packets(0), size(0) + : first_pkt(nullptr), last_pkt(nullptr), flushing(false), nb_packets(0), size(0) { } ~PacketQueue() { clear(); } 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 ); - - 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(); - - virtual void requestWarpPointer( float x, float y ); + 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; + + 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; + + 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/.id b/extern/recastnavigation/.id index 81e564671..b53727263 100644 --- a/extern/recastnavigation/.id +++ b/extern/recastnavigation/.id @@ -1 +1 @@ -57610fa6ef31b39020231906f8c5d40eaa8294ae +6624e7aef5e15df11cb2f5673574df8e4c96af6a diff --git a/extern/recastnavigation/CMakeLists.txt b/extern/recastnavigation/CMakeLists.txt index 0d31c2e36..cf35af1e8 100644 --- a/extern/recastnavigation/CMakeLists.txt +++ b/extern/recastnavigation/CMakeLists.txt @@ -13,6 +13,12 @@ SET(VERSION 1.0.0) option(RECASTNAVIGATION_STATIC "Build static libraries" ON) +if(MSVC AND BUILD_SHARED_LIBS) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +endif() + +include(GNUInstallDirs) + add_subdirectory(DebugUtils) add_subdirectory(Detour) add_subdirectory(DetourCrowd) diff --git a/extern/recastnavigation/DebugUtils/CMakeLists.txt b/extern/recastnavigation/DebugUtils/CMakeLists.txt index 8b6a3fcf6..21d8f8f9d 100644 --- a/extern/recastnavigation/DebugUtils/CMakeLists.txt +++ b/extern/recastnavigation/DebugUtils/CMakeLists.txt @@ -1,12 +1,8 @@ file(GLOB SOURCES Source/*.cpp) - -if (RECASTNAVIGATION_STATIC) - add_library(DebugUtils STATIC ${SOURCES}) -else() - add_library(DebugUtils SHARED ${SOURCES}) -endif() +add_library(DebugUtils ${SOURCES}) add_library(RecastNavigation::DebugUtils ALIAS DebugUtils) +set_target_properties(DebugUtils PROPERTIES DEBUG_POSTFIX -d) set(DebugUtils_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Include") @@ -23,13 +19,18 @@ target_link_libraries(DebugUtils set_target_properties(DebugUtils PROPERTIES SOVERSION ${SOVERSION} VERSION ${VERSION} + COMPILE_PDB_OUTPUT_DIRECTORY . + COMPILE_PDB_NAME "DebugUtils-d" ) install(TARGETS DebugUtils - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ) file(GLOB INCLUDES Include/*.h) -install(FILES ${INCLUDES} DESTINATION include) +install(FILES ${INCLUDES} DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/recastnavigation) +install(FILES "$/DebugUtils-d.pdb" CONFIGURATIONS "Debug" DESTINATION "lib") 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/CMakeLists.txt b/extern/recastnavigation/Detour/CMakeLists.txt index de88111d5..5cb47ec0e 100644 --- a/extern/recastnavigation/Detour/CMakeLists.txt +++ b/extern/recastnavigation/Detour/CMakeLists.txt @@ -1,12 +1,8 @@ file(GLOB SOURCES Source/*.cpp) - -if(RECASTNAVIGATION_STATIC) - add_library(Detour STATIC ${SOURCES}) -else() - add_library(Detour SHARED ${SOURCES}) -endif() +add_library(Detour ${SOURCES}) add_library(RecastNavigation::Detour ALIAS Detour) +set_target_properties(Detour PROPERTIES DEBUG_POSTFIX -d) set(Detour_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Include") @@ -17,13 +13,18 @@ target_include_directories(Detour PUBLIC set_target_properties(Detour PROPERTIES SOVERSION ${SOVERSION} VERSION ${VERSION} + COMPILE_PDB_OUTPUT_DIRECTORY . + COMPILE_PDB_NAME "Detour-d" ) install(TARGETS Detour - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ) file(GLOB INCLUDES Include/*.h) -install(FILES ${INCLUDES} DESTINATION include) +install(FILES ${INCLUDES} DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/recastnavigation) +install(FILES "$/Detour-d.pdb" CONFIGURATIONS "Debug" DESTINATION "lib") 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); diff --git a/extern/recastnavigation/DetourCrowd/CMakeLists.txt b/extern/recastnavigation/DetourCrowd/CMakeLists.txt index 73cdf7ce8..d0e186be0 100644 --- a/extern/recastnavigation/DetourCrowd/CMakeLists.txt +++ b/extern/recastnavigation/DetourCrowd/CMakeLists.txt @@ -1,12 +1,8 @@ file(GLOB SOURCES Source/*.cpp) - -if (RECASTNAVIGATION_STATIC) - add_library(DetourCrowd STATIC ${SOURCES}) -else () - add_library(DetourCrowd SHARED ${SOURCES}) -endif () +add_library(DetourCrowd ${SOURCES}) add_library(RecastNavigation::DetourCrowd ALIAS DetourCrowd) +set_target_properties(DetourCrowd PROPERTIES DEBUG_POSTFIX -d) set(DetourCrowd_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Include") @@ -21,13 +17,18 @@ target_link_libraries(DetourCrowd set_target_properties(DetourCrowd PROPERTIES SOVERSION ${SOVERSION} VERSION ${VERSION} + COMPILE_PDB_OUTPUT_DIRECTORY . + COMPILE_PDB_NAME "DetourCrowd-d" ) install(TARGETS DetourCrowd - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ) file(GLOB INCLUDES Include/*.h) -install(FILES ${INCLUDES} DESTINATION include) +install(FILES ${INCLUDES} DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/recastnavigation) +install(FILES "$/DetourCrowd-d.pdb" CONFIGURATIONS "Debug" DESTINATION "lib") diff --git a/extern/recastnavigation/DetourCrowd/Source/DetourCrowd.cpp b/extern/recastnavigation/DetourCrowd/Source/DetourCrowd.cpp index 1e76e40ce..3f0311f7f 100644 --- a/extern/recastnavigation/DetourCrowd/Source/DetourCrowd.cpp +++ b/extern/recastnavigation/DetourCrowd/Source/DetourCrowd.cpp @@ -1409,12 +1409,14 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug) } // Update agents using off-mesh connection. - for (int i = 0; i < m_maxAgents; ++i) + for (int i = 0; i < nagents; ++i) { - dtCrowdAgentAnimation* anim = &m_agentAnims[i]; + dtCrowdAgent* ag = agents[i]; + const int idx = (int)(ag - m_agents); + dtCrowdAgentAnimation* anim = &m_agentAnims[idx]; if (!anim->active) continue; - dtCrowdAgent* ag = agents[i]; + anim->t += dt; if (anim->t > anim->tmax) diff --git a/extern/recastnavigation/DetourTileCache/CMakeLists.txt b/extern/recastnavigation/DetourTileCache/CMakeLists.txt index 121b8edcc..3703ebb92 100644 --- a/extern/recastnavigation/DetourTileCache/CMakeLists.txt +++ b/extern/recastnavigation/DetourTileCache/CMakeLists.txt @@ -1,12 +1,8 @@ file(GLOB SOURCES Source/*.cpp) - -if (RECASTNAVIGATION_STATIC) - add_library(DetourTileCache STATIC ${SOURCES}) -else () - add_library(DetourTileCache SHARED ${SOURCES}) -endif () +add_library(DetourTileCache ${SOURCES}) add_library(RecastNavigation::DetourTileCache ALIAS DetourTileCache) +set_target_properties(DetourTileCache PROPERTIES DEBUG_POSTFIX -d) set(DetourTileCache_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Include") @@ -21,14 +17,19 @@ target_link_libraries(DetourTileCache set_target_properties(DetourTileCache PROPERTIES SOVERSION ${SOVERSION} VERSION ${VERSION} + COMPILE_PDB_OUTPUT_DIRECTORY . + COMPILE_PDB_NAME "DetourTileCache-d" ) install(TARGETS DetourTileCache - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ) file(GLOB INCLUDES Include/*.h) -install(FILES ${INCLUDES} DESTINATION include) +install(FILES ${INCLUDES} DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/recastnavigation) +install(FILES "$/DetourTileCache-d.pdb" CONFIGURATIONS "Debug" DESTINATION "lib") diff --git a/extern/recastnavigation/Recast/CMakeLists.txt b/extern/recastnavigation/Recast/CMakeLists.txt index 5e843762e..360654464 100644 --- a/extern/recastnavigation/Recast/CMakeLists.txt +++ b/extern/recastnavigation/Recast/CMakeLists.txt @@ -1,12 +1,8 @@ file(GLOB SOURCES Source/*.cpp) - -if (RECASTNAVIGATION_STATIC) - add_library(Recast STATIC ${SOURCES}) -else () - add_library(Recast SHARED ${SOURCES}) -endif () +add_library(Recast ${SOURCES}) add_library(RecastNavigation::Recast ALIAS Recast) +set_target_properties(Recast PROPERTIES DEBUG_POSTFIX -d) set(Recast_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Include") @@ -17,13 +13,18 @@ target_include_directories(Recast PUBLIC set_target_properties(Recast PROPERTIES SOVERSION ${SOVERSION} VERSION ${VERSION} + COMPILE_PDB_OUTPUT_DIRECTORY . + COMPILE_PDB_NAME "Recast-d" ) install(TARGETS Recast - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library ) file(GLOB INCLUDES Include/*.h) -install(FILES ${INCLUDES} DESTINATION include) +install(FILES ${INCLUDES} DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/recastnavigation) +install(FILES "$/Recast-d.pdb" CONFIGURATIONS "Debug" DESTINATION "lib") diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index a98efe07c..c28865502 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -6,13 +6,14 @@ + - + 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 @@ - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 2c1057bf2..d72728f27 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. @@ -328,6 +340,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 @@ -917,6 +932,25 @@ 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] +# Set the number of background threads used for physics. +# If no background threads are used, physics calculations are processed in the main thread +# and the settings below have no effect. +async num threads = 0 + +# Set the number of frames an inactive line-of-sight request will be kept +# refreshed in the background physics thread cache. +# If this is set to -1, line-of-sight requests are never cached. +lineofsight keep inactive cache = 0 + +# Defer bounding boxes update until collision detection. +defer aabb update = true + +[Models] +# Attempt to load any valid NIF file regardless of its version and track the progress. +# Loading arbitrary meshes is not advised and may cause instability. +load unsupported nif files = false + [Stereo] # Enable/disable stereo view. This setting is ignored in VR. diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index 93ba156be..d9b9463ad 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -246,7 +246,7 @@ void main(void) float sunHeight = lVec.z; vec3 scatterColour = mix(SCATTER_COLOUR*vec3(1.0,0.4,0.0), SCATTER_COLOUR, clamp(1.0-exp(-sunHeight*SUN_EXT), 0.0, 1.0)); vec3 lR = reflect(lVec, lNormal); - float lightScatter = shadow * clamp(dot(lVec,lNormal)*0.7+0.3, 0.0, 1.0) * clamp(dot(lR, vVec)*2.0-1.2, 0.0, 1.0) * SCATTER_AMOUNT * sunFade * clamp(1.0-exp(-sunHeight), 0.0, 1.0); + float lightScatter = clamp(dot(lVec,lNormal)*0.7+0.3, 0.0, 1.0) * clamp(dot(lR, vVec)*2.0-1.2, 0.0, 1.0) * SCATTER_AMOUNT * sunFade * clamp(1.0-exp(-sunHeight), 0.0, 1.0); gl_FragData[0].xyz = mix( mix(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * gl_LightSource[0].specular.xyz + vec3(rainRipple.w) * 0.2; gl_FragData[0].w = 1.0; #else diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 3a91db791..3f53180da 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 + + + + + + @@ -553,6 +583,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 + + + @@ -674,6 +714,16 @@ True: In non-combat mode camera is positioned behind the character's shoulder. C + + + + <html><head/><body><p>Stretch menus, load screens, etc. to the window aspect ratio.</p></body></html> + + + Stretch menu background + + +