Add OpenMW commits up to 21 May 2021

# Conflicts:
#   CMakeLists.txt
#   apps/openmw/mwscript/interpretercontext.cpp
#   components/CMakeLists.txt
pull/593/head
David Cernat 4 years ago
commit 7a6dfc61ec

@ -25,6 +25,7 @@ stages:
- cmake --build . -- -j $(nproc) - cmake --build . -- -j $(nproc)
- cmake --install . - cmake --install .
- if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_test_suite; fi - if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_test_suite; fi
- if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi
- ccache -s - ccache -s
artifacts: artifacts:
paths: paths:
@ -169,6 +170,10 @@ variables: &cs-targets
targets: "openmw-cs,bsatool,esmtool,niftest" targets: "openmw-cs,bsatool,esmtool,niftest"
package: "CS" package: "CS"
variables: &tests-targets
targets: "openmw_test_suite,openmw_detournavigator_navmeshtilescache_benchmark"
package: "Tests"
.Windows_Ninja_Base: .Windows_Ninja_Base:
tags: tags:
- windows - windows
@ -187,7 +192,7 @@ variables: &cs-targets
- $time = (Get-Date -Format "HH:mm:ss") - $time = (Get-Date -Format "HH:mm:ss")
- echo ${time} - echo ${time}
- echo "started by ${GITLAB_USER_NAME}" - echo "started by ${GITLAB_USER_NAME}"
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -N - sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -N -b -t
- cd MSVC2019_64_Ninja - cd MSVC2019_64_Ninja
- .\ActivateMSVC.ps1 - .\ActivateMSVC.ps1
- cmake --build . --config $config --target ($targets.Split(',')) - cmake --build . --config $config --target ($targets.Split(','))
@ -199,6 +204,7 @@ variables: &cs-targets
Get-ChildItem -Recurse *.pdb | Remove-Item Get-ChildItem -Recurse *.pdb | Remove-Item
} }
- 7z a -tzip ..\..\OpenMW_MSVC2019_64_${package}_${config}_${CI_COMMIT_REF_NAME}.zip '*' - 7z a -tzip ..\..\OpenMW_MSVC2019_64_${package}_${config}_${CI_COMMIT_REF_NAME}.zip '*'
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
after_script: after_script:
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
cache: cache:
@ -262,6 +268,15 @@ Windows_Ninja_CS_RelWithDebInfo:
<<: *cs-targets <<: *cs-targets
config: "RelWithDebInfo" config: "RelWithDebInfo"
Windows_Ninja_Tests_RelWithDebInfo:
extends: .Windows_Ninja_Base
stage: build
variables:
<<: *tests-targets
config: "RelWithDebInfo"
# Gitlab can't successfully execute following binaries due to unknown reason
# executables: "openmw_test_suite.exe,openmw_detournavigator_navmeshtilescache_benchmark.exe"
.Windows_MSBuild_Base: .Windows_MSBuild_Base:
tags: tags:
- windows - windows
@ -279,7 +294,7 @@ Windows_Ninja_CS_RelWithDebInfo:
- $time = (Get-Date -Format "HH:mm:ss") - $time = (Get-Date -Format "HH:mm:ss")
- echo ${time} - echo ${time}
- echo "started by ${GITLAB_USER_NAME}" - echo "started by ${GITLAB_USER_NAME}"
- sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V - sh CI/before_script.msvc.sh -c $config -p Win64 -v 2019 -k -V -b -t
- cd MSVC2019_64 - cd MSVC2019_64
- cmake --build . --config $config --target ($targets.Split(',')) - cmake --build . --config $config --target ($targets.Split(','))
- cd $config - cd $config
@ -290,6 +305,7 @@ Windows_Ninja_CS_RelWithDebInfo:
Get-ChildItem -Recurse *.pdb | Remove-Item Get-ChildItem -Recurse *.pdb | Remove-Item
} }
- 7z a -tzip ..\..\OpenMW_MSVC2019_64_${package}_${config}_${CI_COMMIT_REF_NAME}.zip '*' - 7z a -tzip ..\..\OpenMW_MSVC2019_64_${package}_${config}_${CI_COMMIT_REF_NAME}.zip '*'
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
after_script: after_script:
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
cache: cache:
@ -353,6 +369,15 @@ Windows_MSBuild_CS_RelWithDebInfo:
<<: *cs-targets <<: *cs-targets
config: "RelWithDebInfo" config: "RelWithDebInfo"
Windows_MSBuild_Tests_RelWithDebInfo:
extends: .Windows_MSBuild_Base
stage: build
variables:
<<: *tests-targets
config: "RelWithDebInfo"
# Gitlab can't successfully execute following binaries due to unknown reason
# executables: "openmw_test_suite.exe,openmw_detournavigator_navmeshtilescache_benchmark.exe"
Debian_AndroidNDK_arm64-v8a: Debian_AndroidNDK_arm64-v8a:
tags: tags:
- linux - linux

@ -64,6 +64,7 @@
Bug #5452: Autowalk is being included in savegames Bug #5452: Autowalk is being included in savegames
Bug #5469: Local map is reset when re-entering certain cells Bug #5469: Local map is reset when re-entering certain cells
Bug #5472: Mistify mod causes CTD in 0.46 on Mac Bug #5472: Mistify mod causes CTD in 0.46 on Mac
Bug #5473: OpenMW-CS: Cell border lines don't update properly on terrain change
Bug #5479: NPCs who should be walking around town are standing around without walking Bug #5479: NPCs who should be walking around town are standing around without walking
Bug #5484: Zero value items shouldn't be able to be bought or sold for 1 gold Bug #5484: Zero value items shouldn't be able to be bought or sold for 1 gold
Bug #5485: Intimidate doesn't increase disposition on marginal wins Bug #5485: Intimidate doesn't increase disposition on marginal wins
@ -80,6 +81,7 @@
Bug #5603: Setting constant effect cast style doesn't correct effects view 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 #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 #5611: Usable items with "0 Uses" should be used only once
Bug #5619: Input events are queued during save loading
Bug #5622: Can't properly interact with the console when in pause menu Bug #5622: Can't properly interact with the console when in pause menu
Bug #5627: Bookart not shown if it isn't followed by <BR> statement Bug #5627: Bookart not shown if it isn't followed by <BR> statement
Bug #5633: Damage Spells in effect before god mode is enabled continue to hurt the player character and can kill them Bug #5633: Damage Spells in effect before god mode is enabled continue to hurt the player character and can kill them
@ -121,6 +123,15 @@
Bug #5975: NIF controllers from sheath meshes are used Bug #5975: NIF controllers from sheath meshes are used
Bug #5991: Activate should always be allowed for inventory items Bug #5991: Activate should always be allowed for inventory items
Bug #5995: NiUVController doesn't calculate the UV offset properly Bug #5995: NiUVController doesn't calculate the UV offset properly
Bug #6007: Crash when ending cutscene is playing
Bug #6016: Greeting interrupts Fargoth's sneak-walk
Bug #6022: OpenMW-CS: Terrain selection is not updated when undoing/redoing terrain changes
Bug #6023: OpenMW-CS: Clicking on a reference in "Terrain land editing" mode discards corresponding select/edit action
Bug #6028: Particle system controller values are incorrectly used
Bug #6035: OpenMW-CS: Circle brush in "Terrain land editing" mode sometimes includes vertices outside its radius
Bug #6036: OpenMW-CS: Terrain selection at the border of cells omits certain corner vertices
Bug #6043: Actor can have torch missing when torch animation is played
Bug #6047: Mouse bindings can be triggered during save loading
Feature #390: 3rd person look "over the shoulder" Feature #390: 3rd person look "over the shoulder"
Feature #832: OpenMW-CS: Handle deleted references Feature #832: OpenMW-CS: Handle deleted references
Feature #1536: Show more information about level on menu Feature #1536: Show more information about level on menu
@ -141,6 +152,7 @@
Feature #5456: Basic collada animation support Feature #5456: Basic collada animation support
Feature #5457: Realistic diagonal movement Feature #5457: Realistic diagonal movement
Feature #5486: Fixes trainers to choose their training skills based on their base skill points Feature #5486: Fixes trainers to choose their training skills based on their base skill points
Feature #5500: Prepare enough navmesh tiles before scene loading ends
Feature #5511: Add in game option to toggle HRTF support in OpenMW Feature #5511: Add in game option to toggle HRTF support in OpenMW
Feature #5519: Code Patch tab in launcher Feature #5519: Code Patch tab in launcher
Feature #5524: Resume failed script execution after reload Feature #5524: Resume failed script execution after reload
@ -159,6 +171,9 @@
Feature #5814: Bsatool should be able to create BSA archives, not only to extract it Feature #5814: Bsatool should be able to create BSA archives, not only to extract it
Feature #5828: Support more than 8 lights Feature #5828: Support more than 8 lights
Feature #5910: Fall back to delta time when physics can't keep up Feature #5910: Fall back to delta time when physics can't keep up
Feature #6024: OpenMW-CS: Selecting terrain in "Terrain land editing" should support "Add to selection" and "Remove from selection" modes
Feature #6033: Include pathgrid to navigation mesh
Feature #6034: Find path based on area cost depending on NPC stats
Task #5480: Drop Qt4 support Task #5480: Drop Qt4 support
Task #5520: Improve cell name autocompleter implementation Task #5520: Improve cell name autocompleter implementation
Task #5844: Update 'toggle sneak' documentation Task #5844: Update 'toggle sneak' documentation

@ -38,9 +38,15 @@ Editor Bug Fixes:
- Disabled record sorting in Topic and Journal Info tables, implemented drag-move for records (#4357) - Disabled record sorting in Topic and Journal Info tables, implemented drag-move for records (#4357)
- Topic and Journal Info records can now be cloned with a different parent Topic/Journal Id (#4363) - Topic and Journal Info records can now be cloned with a different parent Topic/Journal Id (#4363)
- Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400) - Verifier no longer checks for alleged 'race' entries in clothing body parts (#5400)
- Cell borders are now properly redrawn when undoing/redoing terrain changes (#5473)
- Loading mods now keeps the master index (#5675) - Loading mods now keeps the master index (#5675)
- Flicker and crashing on XFCE4 fixed (#5703) - Flicker and crashing on XFCE4 fixed (#5703)
- Collada models render properly in the Editor (#5713) - Collada models render properly in the Editor (#5713)
- Terrain-selection grid is now properly updated when undoing/redoing terrain changes (#6022)
- Tool outline and select/edit actions in "Terrain land editing" mode now ignore references (#6023)
- Primary-select and secondary-select actions in "Terrain land editing" mode now behave like in "Instance editing" mode (#6024)
- Using the circle brush to select terrain in the "Terrain land editing" mode no longer selects vertices outside the circle (#6035)
- Vertices at the NW and SE corners of a cell can now also be selected in "Terrain land editing" mode if the adjacent cells aren't loaded yet (#6036)
Miscellaneous: Miscellaneous:
- Prevent save-game bloating by using an appropriate fog texture format (#5108) - Prevent save-game bloating by using an appropriate fog texture format (#5108)

@ -4,9 +4,14 @@ set -xeo pipefail
free -m free -m
BUILD_UNITTESTS=OFF
BUILD_BENCHMARKS=OFF
if [[ "${BUILD_TESTS_ONLY}" ]]; then if [[ "${BUILD_TESTS_ONLY}" ]]; then
export GOOGLETEST_DIR="${PWD}/googletest/build/install" export GOOGLETEST_DIR="${PWD}/googletest/build/install"
env GENERATOR='Unix Makefiles' CONFIGURATION=Release CI/build_googletest.sh env GENERATOR='Unix Makefiles' CONFIGURATION=Release CI/build_googletest.sh
BUILD_UNITTESTS=ON
BUILD_BENCHMARKS=ON
fi fi
declare -a CMAKE_CONF_OPTS=( declare -a CMAKE_CONF_OPTS=(
@ -54,7 +59,8 @@ if [[ "${BUILD_TESTS_ONLY}" ]]; then
-DBUILD_ESSIMPORTER=OFF \ -DBUILD_ESSIMPORTER=OFF \
-DBUILD_OPENCS=OFF \ -DBUILD_OPENCS=OFF \
-DBUILD_WIZARD=OFF \ -DBUILD_WIZARD=OFF \
-DBUILD_UNITTESTS=ON \ -DBUILD_UNITTESTS=${BUILD_UNITTESTS} \
-DBUILD_BENCHMARKS=${BUILD_BENCHMARKS} \
-DGTEST_ROOT="${GOOGLETEST_DIR}" \ -DGTEST_ROOT="${GOOGLETEST_DIR}" \
-DGMOCK_ROOT="${GOOGLETEST_DIR}" \ -DGMOCK_ROOT="${GOOGLETEST_DIR}" \
.. ..

@ -73,6 +73,7 @@ CONFIGURATIONS=()
TEST_FRAMEWORK="" TEST_FRAMEWORK=""
GOOGLE_INSTALL_ROOT="" GOOGLE_INSTALL_ROOT=""
INSTALL_PREFIX="." INSTALL_PREFIX="."
BUILD_BENCHMARKS=""
ACTIVATE_MSVC="" ACTIVATE_MSVC=""
SINGLE_CONFIG="" SINGLE_CONFIG=""
@ -133,6 +134,9 @@ while [ $# -gt 0 ]; do
INSTALL_PREFIX=$(echo "$1" | sed 's;\\;/;g' | sed -E 's;/+;/;g') INSTALL_PREFIX=$(echo "$1" | sed 's;\\;/;g' | sed -E 's;/+;/;g')
shift ;; shift ;;
b )
BUILD_BENCHMARKS=true ;;
h ) h )
cat <<EOF cat <<EOF
Usage: $0 [-cdehkpuvVi] Usage: $0 [-cdehkpuvVi]
@ -167,6 +171,8 @@ Options:
Run verbosely Run verbosely
-i -i
CMake install prefix CMake install prefix
-b
Build benchmarks
EOF EOF
wrappedExit 0 wrappedExit 0
;; ;;
@ -1067,6 +1073,10 @@ fi
done done
#fi #fi
if [ "${BUILD_BENCHMARKS}" ]; then
add_cmake_opts -DBUILD_BENCHMARKS=ON
fi
if [ -n "$ACTIVATE_MSVC" ]; then if [ -n "$ACTIVATE_MSVC" ]; then
echo -n "- Activating MSVC in the current shell... " echo -n "- Activating MSVC in the current shell... "
command -v vswhere >/dev/null 2>&1 || { echo "Error: vswhere is not on the path."; wrappedExit 1; } command -v vswhere >/dev/null 2>&1 || { echo "Error: vswhere is not on the path."; wrappedExit 1; }

@ -480,8 +480,8 @@ configure_resource_file(${OpenMW_SOURCE_DIR}/files/tes3mp/tes3mp-client-default.
configure_resource_file(${OpenMW_SOURCE_DIR}/files/tes3mp/tes3mp-server-default.cfg configure_resource_file(${OpenMW_SOURCE_DIR}/files/tes3mp/tes3mp-server-default.cfg
"${OpenMW_BINARY_DIR}" "tes3mp-server-default.cfg") "${OpenMW_BINARY_DIR}" "tes3mp-server-default.cfg")
configure_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg pack_resource_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
"${OpenMW_BINARY_DIR}" "settings-default.cfg") "${OpenMW_BINARY_DIR}" "defaults.bin")
configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.appdata.xml configure_resource_file(${OpenMW_SOURCE_DIR}/files/openmw.appdata.xml
"${OpenMW_BINARY_DIR}" "openmw.appdata.xml") "${OpenMW_BINARY_DIR}" "openmw.appdata.xml")
@ -564,6 +564,7 @@ IF(BUILD_OPENMW OR BUILD_OPENCS)
# End of tes3mp addition # End of tes3mp addition
add_subdirectory (extern/osg-ffmpeg-videoplayer) add_subdirectory (extern/osg-ffmpeg-videoplayer)
add_subdirectory (extern/oics) add_subdirectory (extern/oics)
add_subdirectory (extern/Base64)
if (BUILD_OPENCS) if (BUILD_OPENCS)
add_subdirectory (extern/osgQt) add_subdirectory (extern/osgQt)
endif() endif()
@ -668,11 +669,8 @@ if (WIN32)
set(WARNINGS "/W4") set(WARNINGS "/W4")
set(WARNINGS_DISABLE set(WARNINGS_DISABLE
# OpenMW specific warnings
4100 # Unreferenced formal parameter (-Wunused-parameter) 4100 # Unreferenced formal parameter (-Wunused-parameter)
4127 # Conditional expression is constant 4127 # Conditional expression is constant
4244 # Storing value of one type in variable of another (size_t in int, for example)
4267 # Conversion from 'size_t' to 'int', possible loss of data
4996 # Function was declared deprecated 4996 # Function was declared deprecated
) )
@ -741,6 +739,10 @@ if (WIN32)
if (BUILD_WIZARD) if (BUILD_WIZARD)
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
endif() endif()
if (BUILD_BENCHMARKS)
set_target_properties(openmw_detournavigator_navmeshtilescache_benchmark PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
endif()
endif(MSVC) endif(MSVC)
# TODO: At some point release builds should not use the console but rather write to a log file # TODO: At some point release builds should not use the console but rather write to a log file
@ -880,7 +882,7 @@ elseif(NOT APPLE)
INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/README.md" DESTINATION "." RENAME "README.txt")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt") INSTALL(FILES "${OpenMW_SOURCE_DIR}/LICENSE" DESTINATION "." RENAME "LICENSE.txt")
INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".") INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/mygui/DejaVuFontLicense.txt" DESTINATION ".")
INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/defaults.bin" DESTINATION ".")
# Start of tes3mp addition # Start of tes3mp addition
INSTALL(FILES "${INSTALL_SOURCE}/tes3mp-client-default.cfg" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/tes3mp-client-default.cfg" DESTINATION ".")
INSTALL(FILES "${INSTALL_SOURCE}/tes3mp-server-default.cfg" DESTINATION ".") INSTALL(FILES "${INSTALL_SOURCE}/tes3mp-server-default.cfg" DESTINATION ".")
@ -933,13 +935,13 @@ elseif(NOT APPLE)
SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe") SET(VCREDIST32 "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
if(EXISTS ${VCREDIST32}) if(EXISTS ${VCREDIST32})
INSTALL(FILES ${VCREDIST32} DESTINATION "redist") INSTALL(FILES ${VCREDIST32} DESTINATION "redist")
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q'" ) SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q /norestart'" )
endif(EXISTS ${VCREDIST32}) endif(EXISTS ${VCREDIST32})
SET(VCREDIST64 "${OpenMW_BINARY_DIR}/vcredist_x64.exe") SET(VCREDIST64 "${OpenMW_BINARY_DIR}/vcredist_x64.exe")
if(EXISTS ${VCREDIST64}) if(EXISTS ${VCREDIST64})
INSTALL(FILES ${VCREDIST64} DESTINATION "redist") INSTALL(FILES ${VCREDIST64} DESTINATION "redist")
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q'" ) SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x64.exe\\\" /q /norestart'" )
endif(EXISTS ${VCREDIST64}) endif(EXISTS ${VCREDIST64})
SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe") SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe")
@ -1022,7 +1024,7 @@ elseif(NOT APPLE)
ENDIF(BUILD_OPENCS) ENDIF(BUILD_OPENCS)
# Install global configuration files # Install global configuration files
INSTALL(FILES "${INSTALL_SOURCE}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") INSTALL(FILES "${INSTALL_SOURCE}/defaults.bin" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw") INSTALL(FILES "${INSTALL_SOURCE}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw")
INSTALL(FILES "${INSTALL_SOURCE}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") INSTALL(FILES "${INSTALL_SOURCE}/resources/version" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") INSTALL(FILES "${INSTALL_SOURCE}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")

@ -19,16 +19,9 @@ FetchContent_MakeAvailableExcludeFromAll(benchmark)
set(CMAKE_CXX_FLAGS "${SAVED_CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${SAVED_CMAKE_CXX_FLAGS}")
openmw_add_executable(openmw_detournavigator_navmeshtilescache_benchmark detournavigator/navmeshtilescache.cpp) openmw_add_executable(openmw_detournavigator_navmeshtilescache_benchmark detournavigator/navmeshtilescache.cpp)
target_compile_options(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE -Wall)
target_compile_features(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE cxx_std_17) target_compile_features(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE cxx_std_17)
target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark benchmark::benchmark components) target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark benchmark::benchmark components)
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(openmw_detournavigator_navmeshtilescache_benchmark ${CMAKE_THREAD_LIBS_INIT})
endif() endif()
if (MSVC)
if (CMAKE_CL_64)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
endif (CMAKE_CL_64)
endif (MSVC)

@ -13,9 +13,9 @@ std::string loadSettings (Settings::Manager & settings)
// prefer local // prefer local
if (boost::filesystem::exists(localdefault)) if (boost::filesystem::exists(localdefault))
settings.loadDefault(localdefault); settings.loadDefault(localdefault, false);
else if (boost::filesystem::exists(globaldefault)) else if (boost::filesystem::exists(globaldefault))
settings.loadDefault(globaldefault); settings.loadDefault(globaldefault, false);
else else
throw std::runtime_error ("No default settings file found! Make sure the file \"tes3mp-client-default.cfg\" was properly installed."); throw std::runtime_error ("No default settings file found! Make sure the file \"tes3mp-client-default.cfg\" was properly installed.");

@ -2,6 +2,7 @@
#include <vector> #include <vector>
#include <deque> #include <deque>
#include <list> #include <list>
#include <unordered_set>
#include <map> #include <map>
#include <set> #include <set>
#include <fstream> #include <fstream>
@ -322,7 +323,7 @@ int load(Arguments& info)
std::string filename = info.filename; std::string filename = info.filename;
std::cout << "Loading file: " << filename << std::endl; std::cout << "Loading file: " << filename << std::endl;
std::list<uint32_t> skipped; std::unordered_set<uint32_t> skipped;
try { try {
@ -364,17 +365,17 @@ int load(Arguments& info)
// Loop through all records // Loop through all records
while(esm.hasMoreRecs()) while(esm.hasMoreRecs())
{ {
ESM::NAME n = esm.getRecName(); const ESM::NAME n = esm.getRecName();
uint32_t flags; uint32_t flags;
esm.getRecHeader(flags); esm.getRecHeader(flags);
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n); EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
if (record == nullptr) if (record == nullptr)
{ {
if (std::find(skipped.begin(), skipped.end(), n.intval) == skipped.end()) if (skipped.count(n.intval) == 0)
{ {
std::cout << "Skipping " << n.toString() << " records." << std::endl; std::cout << "Skipping " << n.toString() << " records." << std::endl;
skipped.push_back(n.intval); skipped.emplace(n.intval);
} }
esm.skipRecord(); esm.skipRecord();

@ -172,7 +172,7 @@ void printTransport(const std::vector<ESM::Transport::Dest>& transport)
namespace EsmTool { namespace EsmTool {
RecordBase * RecordBase *
RecordBase::create(ESM::NAME type) RecordBase::create(const ESM::NAME type)
{ {
RecordBase *record = nullptr; RecordBase *record = nullptr;

@ -13,11 +13,9 @@
#include "utils/openalutil.hpp" #include "utils/openalutil.hpp"
Launcher::AdvancedPage::AdvancedPage(Config::GameSettings &gameSettings, Launcher::AdvancedPage::AdvancedPage(Config::GameSettings &gameSettings, QWidget *parent)
Settings::Manager &engineSettings, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, mGameSettings(gameSettings) , mGameSettings(gameSettings)
, mEngineSettings(engineSettings)
{ {
setObjectName ("AdvancedPage"); setObjectName ("AdvancedPage");
setupUi(this); setupUi(this);
@ -100,12 +98,12 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game");
loadSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); loadSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game");
loadSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game"); loadSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game");
int unarmedFactorsStrengthIndex = mEngineSettings.getInt("strength influences hand to hand", "Game"); int unarmedFactorsStrengthIndex = Settings::Manager::getInt("strength influences hand to hand", "Game");
if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2) if (unarmedFactorsStrengthIndex >= 0 && unarmedFactorsStrengthIndex <= 2)
unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex); unarmedFactorsStrengthComboBox->setCurrentIndex(unarmedFactorsStrengthIndex);
loadSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); loadSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game");
loadSettingBool(enableNavigatorCheckBox, "enable", "Navigator"); loadSettingBool(enableNavigatorCheckBox, "enable", "Navigator");
int numPhysicsThreads = mEngineSettings.getInt("async num threads", "Physics"); int numPhysicsThreads = Settings::Manager::getInt("async num threads", "Physics");
if (numPhysicsThreads >= 0) if (numPhysicsThreads >= 0)
physicsThreadsSpinBox->setValue(numPhysicsThreads); physicsThreadsSpinBox->setValue(numPhysicsThreads);
loadSettingBool(allowNPCToFollowOverWaterSurfaceCheckBox, "allow actors to follow over water surface", "Game"); loadSettingBool(allowNPCToFollowOverWaterSurfaceCheckBox, "allow actors to follow over water surface", "Game");
@ -130,26 +128,19 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); loadSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game");
loadSettingBool(smoothMovementCheckBox, "smooth movement", "Game"); loadSettingBool(smoothMovementCheckBox, "smooth movement", "Game");
const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); const bool distantTerrain = Settings::Manager::getBool("distant terrain", "Terrain");
const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain"); const bool objectPaging = Settings::Manager::getBool("object paging", "Terrain");
if (distantTerrain && objectPaging) { if (distantTerrain && objectPaging) {
distantLandCheckBox->setCheckState(Qt::Checked); distantLandCheckBox->setCheckState(Qt::Checked);
} }
loadSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain"); loadSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain");
viewingDistanceComboBox->setValue(convertToCells(mEngineSettings.getInt("viewing distance", "Camera"))); viewingDistanceComboBox->setValue(convertToCells(Settings::Manager::getInt("viewing distance", "Camera")));
int lightingMethod = 1;
if (mEngineSettings.getString("lighting method", "Shaders") == "legacy")
lightingMethod = 0;
else if (mEngineSettings.getString("lighting method", "Shaders") == "shaders")
lightingMethod = 2;
lightingMethodComboBox->setCurrentIndex(lightingMethod);
} }
// Audio // Audio
{ {
std::string selectedAudioDevice = mEngineSettings.getString("device", "Sound"); std::string selectedAudioDevice = Settings::Manager::getString("device", "Sound");
if (selectedAudioDevice.empty() == false) if (selectedAudioDevice.empty() == false)
{ {
int audioDeviceIndex = audioDeviceSelectorComboBox->findData(QString::fromStdString(selectedAudioDevice)); int audioDeviceIndex = audioDeviceSelectorComboBox->findData(QString::fromStdString(selectedAudioDevice));
@ -158,12 +149,12 @@ bool Launcher::AdvancedPage::loadSettings()
audioDeviceSelectorComboBox->setCurrentIndex(audioDeviceIndex); audioDeviceSelectorComboBox->setCurrentIndex(audioDeviceIndex);
} }
} }
int hrtfEnabledIndex = mEngineSettings.getInt("hrtf enable", "Sound"); int hrtfEnabledIndex = Settings::Manager::getInt("hrtf enable", "Sound");
if (hrtfEnabledIndex >= -1 && hrtfEnabledIndex <= 1) if (hrtfEnabledIndex >= -1 && hrtfEnabledIndex <= 1)
{ {
enableHRTFComboBox->setCurrentIndex(hrtfEnabledIndex + 1); enableHRTFComboBox->setCurrentIndex(hrtfEnabledIndex + 1);
} }
std::string selectedHRTFProfile = mEngineSettings.getString("hrtf", "Sound"); std::string selectedHRTFProfile = Settings::Manager::getString("hrtf", "Sound");
if (selectedHRTFProfile.empty() == false) if (selectedHRTFProfile.empty() == false)
{ {
int hrtfProfileIndex = hrtfProfileSelectorComboBox->findData(QString::fromStdString(selectedHRTFProfile)); int hrtfProfileIndex = hrtfProfileSelectorComboBox->findData(QString::fromStdString(selectedHRTFProfile));
@ -185,7 +176,7 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera");
loadSettingBool(headBobbingCheckBox, "head bobbing", "Camera"); loadSettingBool(headBobbingCheckBox, "head bobbing", "Camera");
defaultShoulderComboBox->setCurrentIndex( defaultShoulderComboBox->setCurrentIndex(
mEngineSettings.getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1); Settings::Manager::getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1);
} }
// Interface Changes // Interface Changes
@ -195,13 +186,13 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game"); loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
loadSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); loadSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI");
int showOwnedIndex = mEngineSettings.getInt("show owned", "Game"); int showOwnedIndex = Settings::Manager::getInt("show owned", "Game");
// Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid. // 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) if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
showOwnedComboBox->setCurrentIndex(showOwnedIndex); showOwnedComboBox->setCurrentIndex(showOwnedIndex);
loadSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI"); loadSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI");
loadSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game"); loadSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game");
scalingSpinBox->setValue(mEngineSettings.getFloat("scaling factor", "GUI")); scalingSpinBox->setValue(Settings::Manager::getFloat("scaling factor", "GUI"));
} }
// Bug fixes // Bug fixes
@ -214,10 +205,10 @@ bool Launcher::AdvancedPage::loadSettings()
{ {
// Saves // Saves
loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
maximumQuicksavesComboBox->setValue(mEngineSettings.getInt("max quicksaves", "Saves")); maximumQuicksavesComboBox->setValue(Settings::Manager::getInt("max quicksaves", "Saves"));
// Other Settings // Other Settings
QString screenshotFormatString = QString::fromStdString(mEngineSettings.getString("screenshot format", "General")).toUpper(); QString screenshotFormatString = QString::fromStdString(Settings::Manager::getString("screenshot format", "General")).toUpper();
if (screenshotFormatComboBox->findText(screenshotFormatString) == -1) if (screenshotFormatComboBox->findText(screenshotFormatString) == -1)
screenshotFormatComboBox->addItem(screenshotFormatString); screenshotFormatComboBox->addItem(screenshotFormatString);
screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString)); screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString));
@ -258,13 +249,13 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); saveSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game");
saveSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game"); saveSettingBool(avoidCollisionsCheckBox, "NPCs avoid collisions", "Game");
int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex(); int unarmedFactorsStrengthIndex = unarmedFactorsStrengthComboBox->currentIndex();
if (unarmedFactorsStrengthIndex != mEngineSettings.getInt("strength influences hand to hand", "Game")) if (unarmedFactorsStrengthIndex != Settings::Manager::getInt("strength influences hand to hand", "Game"))
mEngineSettings.setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex); Settings::Manager::setInt("strength influences hand to hand", "Game", unarmedFactorsStrengthIndex);
saveSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game"); saveSettingBool(stealingFromKnockedOutCheckBox, "always allow stealing from knocked out actors", "Game");
saveSettingBool(enableNavigatorCheckBox, "enable", "Navigator"); saveSettingBool(enableNavigatorCheckBox, "enable", "Navigator");
int numPhysicsThreads = physicsThreadsSpinBox->value(); int numPhysicsThreads = physicsThreadsSpinBox->value();
if (numPhysicsThreads != mEngineSettings.getInt("async num threads", "Physics")) if (numPhysicsThreads != Settings::Manager::getInt("async num threads", "Physics"))
mEngineSettings.setInt("async num threads", "Physics", numPhysicsThreads); Settings::Manager::setInt("async num threads", "Physics", numPhysicsThreads);
} }
// Visuals // Visuals
@ -282,23 +273,20 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game"); saveSettingBool(turnToMovementDirectionCheckBox, "turn to movement direction", "Game");
saveSettingBool(smoothMovementCheckBox, "smooth movement", "Game"); saveSettingBool(smoothMovementCheckBox, "smooth movement", "Game");
const bool distantTerrain = mEngineSettings.getBool("distant terrain", "Terrain"); const bool distantTerrain = Settings::Manager::getBool("distant terrain", "Terrain");
const bool objectPaging = mEngineSettings.getBool("object paging", "Terrain"); const bool objectPaging = Settings::Manager::getBool("object paging", "Terrain");
const bool wantDistantLand = distantLandCheckBox->checkState(); const bool wantDistantLand = distantLandCheckBox->checkState();
if (wantDistantLand != (distantTerrain && objectPaging)) { if (wantDistantLand != (distantTerrain && objectPaging)) {
mEngineSettings.setBool("distant terrain", "Terrain", wantDistantLand); Settings::Manager::setBool("distant terrain", "Terrain", wantDistantLand);
mEngineSettings.setBool("object paging", "Terrain", wantDistantLand); Settings::Manager::setBool("object paging", "Terrain", wantDistantLand);
} }
saveSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain"); saveSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain");
double viewingDistance = viewingDistanceComboBox->value(); double viewingDistance = viewingDistanceComboBox->value();
if (viewingDistance != convertToCells(mEngineSettings.getInt("viewing distance", "Camera"))) if (viewingDistance != convertToCells(Settings::Manager::getInt("viewing distance", "Camera")))
{ {
mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance)); Settings::Manager::setInt("viewing distance", "Camera", convertToUnits(viewingDistance));
} }
static std::array<std::string, 3> lightingMethodMap = {"legacy", "shaders compatibility", "shaders"};
mEngineSettings.setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]);
} }
// Audio // Audio
@ -306,25 +294,25 @@ void Launcher::AdvancedPage::saveSettings()
int audioDeviceIndex = audioDeviceSelectorComboBox->currentIndex(); int audioDeviceIndex = audioDeviceSelectorComboBox->currentIndex();
if (audioDeviceIndex != 0) if (audioDeviceIndex != 0)
{ {
mEngineSettings.setString("device", "Sound", audioDeviceSelectorComboBox->currentText().toUtf8().constData()); Settings::Manager::setString("device", "Sound", audioDeviceSelectorComboBox->currentText().toUtf8().constData());
} }
else else
{ {
mEngineSettings.setString("device", "Sound", ""); Settings::Manager::setString("device", "Sound", "");
} }
int hrtfEnabledIndex = enableHRTFComboBox->currentIndex() - 1; int hrtfEnabledIndex = enableHRTFComboBox->currentIndex() - 1;
if (hrtfEnabledIndex != mEngineSettings.getInt("hrtf enable", "Sound")) if (hrtfEnabledIndex != Settings::Manager::getInt("hrtf enable", "Sound"))
{ {
mEngineSettings.setInt("hrtf enable", "Sound", hrtfEnabledIndex); Settings::Manager::setInt("hrtf enable", "Sound", hrtfEnabledIndex);
} }
int selectedHRTFProfileIndex = hrtfProfileSelectorComboBox->currentIndex(); int selectedHRTFProfileIndex = hrtfProfileSelectorComboBox->currentIndex();
if (selectedHRTFProfileIndex != 0) if (selectedHRTFProfileIndex != 0)
{ {
mEngineSettings.setString("hrtf", "Sound", hrtfProfileSelectorComboBox->currentText().toUtf8().constData()); Settings::Manager::setString("hrtf", "Sound", hrtfProfileSelectorComboBox->currentText().toUtf8().constData());
} }
else else
{ {
mEngineSettings.setString("hrtf", "Sound", ""); Settings::Manager::setString("hrtf", "Sound", "");
} }
} }
@ -336,14 +324,14 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); saveSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera");
saveSettingBool(headBobbingCheckBox, "head bobbing", "Camera"); saveSettingBool(headBobbingCheckBox, "head bobbing", "Camera");
osg::Vec2f shoulderOffset = mEngineSettings.getVector2("view over shoulder offset", "Camera"); osg::Vec2f shoulderOffset = Settings::Manager::getVector2("view over shoulder offset", "Camera");
if (defaultShoulderComboBox->currentIndex() != (shoulderOffset.x() >= 0 ? 0 : 1)) if (defaultShoulderComboBox->currentIndex() != (shoulderOffset.x() >= 0 ? 0 : 1))
{ {
if (defaultShoulderComboBox->currentIndex() == 0) if (defaultShoulderComboBox->currentIndex() == 0)
shoulderOffset.x() = std::abs(shoulderOffset.x()); shoulderOffset.x() = std::abs(shoulderOffset.x());
else else
shoulderOffset.x() = -std::abs(shoulderOffset.x()); shoulderOffset.x() = -std::abs(shoulderOffset.x());
mEngineSettings.setVector2("view over shoulder offset", "Camera", shoulderOffset); Settings::Manager::setVector2("view over shoulder offset", "Camera", shoulderOffset);
} }
} }
@ -355,13 +343,13 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI");
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex(); int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game")) if (showOwnedCurrentIndex != Settings::Manager::getInt("show owned", "Game"))
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex); Settings::Manager::setInt("show owned", "Game", showOwnedCurrentIndex);
saveSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI"); saveSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI");
saveSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game"); saveSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game");
float uiScalingFactor = scalingSpinBox->value(); float uiScalingFactor = scalingSpinBox->value();
if (uiScalingFactor != mEngineSettings.getFloat("scaling factor", "GUI")) if (uiScalingFactor != Settings::Manager::getFloat("scaling factor", "GUI"))
mEngineSettings.setFloat("scaling factor", "GUI", uiScalingFactor); Settings::Manager::setFloat("scaling factor", "GUI", uiScalingFactor);
} }
// Bug fixes // Bug fixes
@ -375,15 +363,15 @@ void Launcher::AdvancedPage::saveSettings()
// Saves Settings // Saves Settings
saveSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); saveSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
int maximumQuicksaves = maximumQuicksavesComboBox->value(); int maximumQuicksaves = maximumQuicksavesComboBox->value();
if (maximumQuicksaves != mEngineSettings.getInt("max quicksaves", "Saves")) if (maximumQuicksaves != Settings::Manager::getInt("max quicksaves", "Saves"))
{ {
mEngineSettings.setInt("max quicksaves", "Saves", maximumQuicksaves); Settings::Manager::setInt("max quicksaves", "Saves", maximumQuicksaves);
} }
// Other Settings // Other Settings
std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString(); std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString();
if (screenshotFormatString != mEngineSettings.getString("screenshot format", "General")) if (screenshotFormatString != Settings::Manager::getString("screenshot format", "General"))
mEngineSettings.setString("screenshot format", "General", screenshotFormatString); Settings::Manager::setString("screenshot format", "General", screenshotFormatString);
} }
// Testing // Testing
@ -407,15 +395,15 @@ void Launcher::AdvancedPage::saveSettings()
void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group)
{ {
if (mEngineSettings.getBool(setting, group)) if (Settings::Manager::getBool(setting, group))
checkbox->setCheckState(Qt::Checked); checkbox->setCheckState(Qt::Checked);
} }
void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group)
{ {
bool cValue = checkbox->checkState(); bool cValue = checkbox->checkState();
if (cValue != mEngineSettings.getBool(setting, group)) if (cValue != Settings::Manager::getBool(setting, group))
mEngineSettings.setBool(setting, group, cValue); Settings::Manager::setBool(setting, group, cValue);
} }
void Launcher::AdvancedPage::slotLoadedCellsChanged(QStringList cellNames) void Launcher::AdvancedPage::slotLoadedCellsChanged(QStringList cellNames)

@ -17,8 +17,7 @@ namespace Launcher
Q_OBJECT Q_OBJECT
public: public:
AdvancedPage(Config::GameSettings &gameSettings, explicit AdvancedPage(Config::GameSettings &gameSettings, QWidget *parent = nullptr);
Settings::Manager &engineSettings, QWidget *parent = nullptr);
bool loadSettings(); bool loadSettings();
void saveSettings(); void saveSettings();
@ -34,7 +33,6 @@ namespace Launcher
private: private:
Config::GameSettings &mGameSettings; Config::GameSettings &mGameSettings;
Settings::Manager &mEngineSettings;
QCompleter mCellNameCompleter; QCompleter mCellNameCompleter;
QStringListModel mCellNameCompleterModel; QStringListModel mCellNameCompleterModel;

@ -32,9 +32,8 @@ QString getAspect(int x, int y)
return QString(QString::number(xaspect) + ":" + QString::number(yaspect)); return QString(QString::number(xaspect) + ":" + QString::number(yaspect));
} }
Launcher::GraphicsPage::GraphicsPage(Settings::Manager &engineSettings, QWidget *parent) Launcher::GraphicsPage::GraphicsPage(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, mEngineSettings(engineSettings)
{ {
setObjectName ("GraphicsPage"); setObjectName ("GraphicsPage");
setupUi(this); setupUi(this);
@ -93,26 +92,27 @@ bool Launcher::GraphicsPage::loadSettings()
if (!setupSDL()) if (!setupSDL())
return false; return false;
if (mEngineSettings.getBool("vsync", "Video")) // Visuals
if (Settings::Manager::getBool("vsync", "Video"))
vSyncCheckBox->setCheckState(Qt::Checked); vSyncCheckBox->setCheckState(Qt::Checked);
if (mEngineSettings.getBool("fullscreen", "Video")) if (Settings::Manager::getBool("fullscreen", "Video"))
fullScreenCheckBox->setCheckState(Qt::Checked); fullScreenCheckBox->setCheckState(Qt::Checked);
if (mEngineSettings.getBool("window border", "Video")) if (Settings::Manager::getBool("window border", "Video"))
windowBorderCheckBox->setCheckState(Qt::Checked); windowBorderCheckBox->setCheckState(Qt::Checked);
// aaValue is the actual value (0, 1, 2, 4, 8, 16) // aaValue is the actual value (0, 1, 2, 4, 8, 16)
int aaValue = mEngineSettings.getInt("antialiasing", "Video"); int aaValue = Settings::Manager::getInt("antialiasing", "Video");
// aaIndex is the index into the allowed values in the pull down. // aaIndex is the index into the allowed values in the pull down.
int aaIndex = antiAliasingComboBox->findText(QString::number(aaValue)); int aaIndex = antiAliasingComboBox->findText(QString::number(aaValue));
if (aaIndex != -1) if (aaIndex != -1)
antiAliasingComboBox->setCurrentIndex(aaIndex); antiAliasingComboBox->setCurrentIndex(aaIndex);
int width = mEngineSettings.getInt("resolution x", "Video"); int width = Settings::Manager::getInt("resolution x", "Video");
int height = mEngineSettings.getInt("resolution y", "Video"); int height = Settings::Manager::getInt("resolution y", "Video");
QString resolution = QString::number(width) + QString(" x ") + QString::number(height); QString resolution = QString::number(width) + QString(" x ") + QString::number(height);
screenComboBox->setCurrentIndex(mEngineSettings.getInt("screen", "Video")); screenComboBox->setCurrentIndex(Settings::Manager::getInt("screen", "Video"));
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith); int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
@ -125,40 +125,49 @@ bool Launcher::GraphicsPage::loadSettings()
customHeightSpinBox->setValue(height); customHeightSpinBox->setValue(height);
} }
float fpsLimit = mEngineSettings.getFloat("framerate limit", "Video"); float fpsLimit = Settings::Manager::getFloat("framerate limit", "Video");
if (fpsLimit != 0) if (fpsLimit != 0)
{ {
framerateLimitCheckBox->setCheckState(Qt::Checked); framerateLimitCheckBox->setCheckState(Qt::Checked);
framerateLimitSpinBox->setValue(fpsLimit); framerateLimitSpinBox->setValue(fpsLimit);
} }
if (mEngineSettings.getBool("actor shadows", "Shadows")) // Lighting
int lightingMethod = 1;
if (Settings::Manager::getString("lighting method", "Shaders") == "legacy")
lightingMethod = 0;
else if (Settings::Manager::getString("lighting method", "Shaders") == "shaders")
lightingMethod = 2;
lightingMethodComboBox->setCurrentIndex(lightingMethod);
// Shadows
if (Settings::Manager::getBool("actor shadows", "Shadows"))
actorShadowsCheckBox->setCheckState(Qt::Checked); actorShadowsCheckBox->setCheckState(Qt::Checked);
if (mEngineSettings.getBool("player shadows", "Shadows")) if (Settings::Manager::getBool("player shadows", "Shadows"))
playerShadowsCheckBox->setCheckState(Qt::Checked); playerShadowsCheckBox->setCheckState(Qt::Checked);
if (mEngineSettings.getBool("terrain shadows", "Shadows")) if (Settings::Manager::getBool("terrain shadows", "Shadows"))
terrainShadowsCheckBox->setCheckState(Qt::Checked); terrainShadowsCheckBox->setCheckState(Qt::Checked);
if (mEngineSettings.getBool("object shadows", "Shadows")) if (Settings::Manager::getBool("object shadows", "Shadows"))
objectShadowsCheckBox->setCheckState(Qt::Checked); objectShadowsCheckBox->setCheckState(Qt::Checked);
if (mEngineSettings.getBool("enable indoor shadows", "Shadows")) if (Settings::Manager::getBool("enable indoor shadows", "Shadows"))
indoorShadowsCheckBox->setCheckState(Qt::Checked); indoorShadowsCheckBox->setCheckState(Qt::Checked);
shadowComputeSceneBoundsComboBox->setCurrentIndex( shadowComputeSceneBoundsComboBox->setCurrentIndex(
shadowComputeSceneBoundsComboBox->findText( shadowComputeSceneBoundsComboBox->findText(
QString(tr(mEngineSettings.getString("compute scene bounds", "Shadows").c_str())))); QString(tr(Settings::Manager::getString("compute scene bounds", "Shadows").c_str()))));
int shadowDistLimit = mEngineSettings.getInt("maximum shadow map distance", "Shadows"); int shadowDistLimit = Settings::Manager::getInt("maximum shadow map distance", "Shadows");
if (shadowDistLimit > 0) if (shadowDistLimit > 0)
{ {
shadowDistanceCheckBox->setCheckState(Qt::Checked); shadowDistanceCheckBox->setCheckState(Qt::Checked);
shadowDistanceSpinBox->setValue(shadowDistLimit); shadowDistanceSpinBox->setValue(shadowDistLimit);
} }
float shadowFadeStart = mEngineSettings.getFloat("shadow fade start", "Shadows"); float shadowFadeStart = Settings::Manager::getFloat("shadow fade start", "Shadows");
if (shadowFadeStart != 0) if (shadowFadeStart != 0)
fadeStartSpinBox->setValue(shadowFadeStart); fadeStartSpinBox->setValue(shadowFadeStart);
int shadowRes = mEngineSettings.getInt("shadow map resolution", "Shadows"); int shadowRes = Settings::Manager::getInt("shadow map resolution", "Shadows");
int shadowResIndex = shadowResolutionComboBox->findText(QString::number(shadowRes)); int shadowResIndex = shadowResolutionComboBox->findText(QString::number(shadowRes));
if (shadowResIndex != -1) if (shadowResIndex != -1)
shadowResolutionComboBox->setCurrentIndex(shadowResIndex); shadowResolutionComboBox->setCurrentIndex(shadowResIndex);
@ -168,23 +177,25 @@ bool Launcher::GraphicsPage::loadSettings()
void Launcher::GraphicsPage::saveSettings() void Launcher::GraphicsPage::saveSettings()
{ {
// Visuals
// Ensure we only set the new settings if they changed. This is to avoid cluttering the // Ensure we only set the new settings if they changed. This is to avoid cluttering the
// user settings file (which by definition should only contain settings the user has touched) // user settings file (which by definition should only contain settings the user has touched)
bool cVSync = vSyncCheckBox->checkState(); bool cVSync = vSyncCheckBox->checkState();
if (cVSync != mEngineSettings.getBool("vsync", "Video")) if (cVSync != Settings::Manager::getBool("vsync", "Video"))
mEngineSettings.setBool("vsync", "Video", cVSync); Settings::Manager::setBool("vsync", "Video", cVSync);
bool cFullScreen = fullScreenCheckBox->checkState(); bool cFullScreen = fullScreenCheckBox->checkState();
if (cFullScreen != mEngineSettings.getBool("fullscreen", "Video")) if (cFullScreen != Settings::Manager::getBool("fullscreen", "Video"))
mEngineSettings.setBool("fullscreen", "Video", cFullScreen); Settings::Manager::setBool("fullscreen", "Video", cFullScreen);
bool cWindowBorder = windowBorderCheckBox->checkState(); bool cWindowBorder = windowBorderCheckBox->checkState();
if (cWindowBorder != mEngineSettings.getBool("window border", "Video")) if (cWindowBorder != Settings::Manager::getBool("window border", "Video"))
mEngineSettings.setBool("window border", "Video", cWindowBorder); Settings::Manager::setBool("window border", "Video", cWindowBorder);
int cAAValue = antiAliasingComboBox->currentText().toInt(); int cAAValue = antiAliasingComboBox->currentText().toInt();
if (cAAValue != mEngineSettings.getInt("antialiasing", "Video")) if (cAAValue != Settings::Manager::getInt("antialiasing", "Video"))
mEngineSettings.setInt("antialiasing", "Video", cAAValue); Settings::Manager::setInt("antialiasing", "Video", cAAValue);
int cWidth = 0; int cWidth = 0;
int cHeight = 0; int cHeight = 0;
@ -199,33 +210,38 @@ void Launcher::GraphicsPage::saveSettings()
cHeight = customHeightSpinBox->value(); cHeight = customHeightSpinBox->value();
} }
if (cWidth != mEngineSettings.getInt("resolution x", "Video")) if (cWidth != Settings::Manager::getInt("resolution x", "Video"))
mEngineSettings.setInt("resolution x", "Video", cWidth); Settings::Manager::setInt("resolution x", "Video", cWidth);
if (cHeight != mEngineSettings.getInt("resolution y", "Video")) if (cHeight != Settings::Manager::getInt("resolution y", "Video"))
mEngineSettings.setInt("resolution y", "Video", cHeight); Settings::Manager::setInt("resolution y", "Video", cHeight);
int cScreen = screenComboBox->currentIndex(); int cScreen = screenComboBox->currentIndex();
if (cScreen != mEngineSettings.getInt("screen", "Video")) if (cScreen != Settings::Manager::getInt("screen", "Video"))
mEngineSettings.setInt("screen", "Video", cScreen); Settings::Manager::setInt("screen", "Video", cScreen);
if (framerateLimitCheckBox->checkState() != Qt::Unchecked) if (framerateLimitCheckBox->checkState() != Qt::Unchecked)
{ {
float cFpsLimit = framerateLimitSpinBox->value(); float cFpsLimit = framerateLimitSpinBox->value();
if (cFpsLimit != mEngineSettings.getFloat("framerate limit", "Video")) if (cFpsLimit != Settings::Manager::getFloat("framerate limit", "Video"))
mEngineSettings.setFloat("framerate limit", "Video", cFpsLimit); Settings::Manager::setFloat("framerate limit", "Video", cFpsLimit);
} }
else if (mEngineSettings.getFloat("framerate limit", "Video") != 0) else if (Settings::Manager::getFloat("framerate limit", "Video") != 0)
{ {
mEngineSettings.setFloat("framerate limit", "Video", 0); Settings::Manager::setFloat("framerate limit", "Video", 0);
} }
// Lighting
static std::array<std::string, 3> lightingMethodMap = {"legacy", "shaders compatibility", "shaders"};
Settings::Manager::setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]);
// Shadows
int cShadowDist = shadowDistanceCheckBox->checkState() != Qt::Unchecked ? shadowDistanceSpinBox->value() : 0; int cShadowDist = shadowDistanceCheckBox->checkState() != Qt::Unchecked ? shadowDistanceSpinBox->value() : 0;
if (mEngineSettings.getInt("maximum shadow map distance", "Shadows") != cShadowDist) if (Settings::Manager::getInt("maximum shadow map distance", "Shadows") != cShadowDist)
mEngineSettings.setInt("maximum shadow map distance", "Shadows", cShadowDist); Settings::Manager::setInt("maximum shadow map distance", "Shadows", cShadowDist);
float cFadeStart = fadeStartSpinBox->value(); float cFadeStart = fadeStartSpinBox->value();
if (cShadowDist > 0 && mEngineSettings.getFloat("shadow fade start", "Shadows") != cFadeStart) if (cShadowDist > 0 && Settings::Manager::getFloat("shadow fade start", "Shadows") != cFadeStart)
mEngineSettings.setFloat("shadow fade start", "Shadows", cFadeStart); Settings::Manager::setFloat("shadow fade start", "Shadows", cFadeStart);
bool cActorShadows = actorShadowsCheckBox->checkState(); bool cActorShadows = actorShadowsCheckBox->checkState();
bool cObjectShadows = objectShadowsCheckBox->checkState(); bool cObjectShadows = objectShadowsCheckBox->checkState();
@ -233,42 +249,42 @@ void Launcher::GraphicsPage::saveSettings()
bool cPlayerShadows = playerShadowsCheckBox->checkState(); bool cPlayerShadows = playerShadowsCheckBox->checkState();
if (cActorShadows || cObjectShadows || cTerrainShadows || cPlayerShadows) if (cActorShadows || cObjectShadows || cTerrainShadows || cPlayerShadows)
{ {
if (!mEngineSettings.getBool("enable shadows", "Shadows")) if (!Settings::Manager::getBool("enable shadows", "Shadows"))
mEngineSettings.setBool("enable shadows", "Shadows", true); Settings::Manager::setBool("enable shadows", "Shadows", true);
if (mEngineSettings.getBool("actor shadows", "Shadows") != cActorShadows) if (Settings::Manager::getBool("actor shadows", "Shadows") != cActorShadows)
mEngineSettings.setBool("actor shadows", "Shadows", cActorShadows); Settings::Manager::setBool("actor shadows", "Shadows", cActorShadows);
if (mEngineSettings.getBool("player shadows", "Shadows") != cPlayerShadows) if (Settings::Manager::getBool("player shadows", "Shadows") != cPlayerShadows)
mEngineSettings.setBool("player shadows", "Shadows", cPlayerShadows); Settings::Manager::setBool("player shadows", "Shadows", cPlayerShadows);
if (mEngineSettings.getBool("object shadows", "Shadows") != cObjectShadows) if (Settings::Manager::getBool("object shadows", "Shadows") != cObjectShadows)
mEngineSettings.setBool("object shadows", "Shadows", cObjectShadows); Settings::Manager::setBool("object shadows", "Shadows", cObjectShadows);
if (mEngineSettings.getBool("terrain shadows", "Shadows") != cTerrainShadows) if (Settings::Manager::getBool("terrain shadows", "Shadows") != cTerrainShadows)
mEngineSettings.setBool("terrain shadows", "Shadows", cTerrainShadows); Settings::Manager::setBool("terrain shadows", "Shadows", cTerrainShadows);
} }
else else
{ {
if (mEngineSettings.getBool("enable shadows", "Shadows")) if (Settings::Manager::getBool("enable shadows", "Shadows"))
mEngineSettings.setBool("enable shadows", "Shadows", false); Settings::Manager::setBool("enable shadows", "Shadows", false);
if (mEngineSettings.getBool("actor shadows", "Shadows")) if (Settings::Manager::getBool("actor shadows", "Shadows"))
mEngineSettings.setBool("actor shadows", "Shadows", false); Settings::Manager::setBool("actor shadows", "Shadows", false);
if (mEngineSettings.getBool("player shadows", "Shadows")) if (Settings::Manager::getBool("player shadows", "Shadows"))
mEngineSettings.setBool("player shadows", "Shadows", false); Settings::Manager::setBool("player shadows", "Shadows", false);
if (mEngineSettings.getBool("object shadows", "Shadows")) if (Settings::Manager::getBool("object shadows", "Shadows"))
mEngineSettings.setBool("object shadows", "Shadows", false); Settings::Manager::setBool("object shadows", "Shadows", false);
if (mEngineSettings.getBool("terrain shadows", "Shadows")) if (Settings::Manager::getBool("terrain shadows", "Shadows"))
mEngineSettings.setBool("terrain shadows", "Shadows", false); Settings::Manager::setBool("terrain shadows", "Shadows", false);
} }
bool cIndoorShadows = indoorShadowsCheckBox->checkState(); bool cIndoorShadows = indoorShadowsCheckBox->checkState();
if (mEngineSettings.getBool("enable indoor shadows", "Shadows") != cIndoorShadows) if (Settings::Manager::getBool("enable indoor shadows", "Shadows") != cIndoorShadows)
mEngineSettings.setBool("enable indoor shadows", "Shadows", cIndoorShadows); Settings::Manager::setBool("enable indoor shadows", "Shadows", cIndoorShadows);
int cShadowRes = shadowResolutionComboBox->currentText().toInt(); int cShadowRes = shadowResolutionComboBox->currentText().toInt();
if (cShadowRes != mEngineSettings.getInt("shadow map resolution", "Shadows")) if (cShadowRes != Settings::Manager::getInt("shadow map resolution", "Shadows"))
mEngineSettings.setInt("shadow map resolution", "Shadows", cShadowRes); Settings::Manager::setInt("shadow map resolution", "Shadows", cShadowRes);
auto cComputeSceneBounds = shadowComputeSceneBoundsComboBox->currentText().toStdString(); auto cComputeSceneBounds = shadowComputeSceneBoundsComboBox->currentText().toStdString();
if (cComputeSceneBounds != mEngineSettings.getString("compute scene bounds", "Shadows")) if (cComputeSceneBounds != Settings::Manager::getString("compute scene bounds", "Shadows"))
mEngineSettings.setString("compute scene bounds", "Shadows", cComputeSceneBounds); Settings::Manager::setString("compute scene bounds", "Shadows", cComputeSceneBounds);
} }
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen) QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)

@ -18,7 +18,7 @@ namespace Launcher
Q_OBJECT Q_OBJECT
public: public:
GraphicsPage(Settings::Manager &engineSettings, QWidget *parent = nullptr); explicit GraphicsPage(QWidget *parent = nullptr);
void saveSettings(); void saveSettings();
bool loadSettings(); bool loadSettings();
@ -33,8 +33,6 @@ namespace Launcher
void slotShadowDistLimitToggled(bool checked); void slotShadowDistLimitToggled(bool checked);
private: private:
Settings::Manager &mEngineSettings;
QVector<QStringList> mResolutionsPerScreen; QVector<QStringList> mResolutionsPerScreen;
static QStringList getAvailableResolutions(int screen); static QStringList getAvailableResolutions(int screen);

@ -123,9 +123,9 @@ void Launcher::MainDialog::createPages()
mPlayPage = new PlayPage(this); mPlayPage = new PlayPage(this);
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
mGraphicsPage = new GraphicsPage(mEngineSettings, this); mGraphicsPage = new GraphicsPage(this);
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this); mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
mAdvancedPage = new AdvancedPage(mGameSettings, mEngineSettings, this); mAdvancedPage = new AdvancedPage(mGameSettings, this);
// Set the combobox of the play page to imitate the combobox on the datafilespage // Set the combobox of the play page to imitate the combobox on the datafilespage
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel()); mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
@ -424,11 +424,11 @@ bool Launcher::MainDialog::setupGraphicsSettings()
mEngineSettings.clear(); mEngineSettings.clear();
// Create the settings manager and load default settings file // Create the settings manager and load default settings file
const std::string localDefault = (mCfgMgr.getLocalPath() / "settings-default.cfg").string(); const std::string localDefault = (mCfgMgr.getLocalPath() / "defaults.bin").string();
const std::string globalDefault = (mCfgMgr.getGlobalPath() / "settings-default.cfg").string(); const std::string globalDefault = (mCfgMgr.getGlobalPath() / "defaults.bin").string();
std::string defaultPath; std::string defaultPath;
// Prefer the settings-default.cfg in the current directory. // Prefer the defaults.bin in the current directory.
if (boost::filesystem::exists(localDefault)) if (boost::filesystem::exists(localDefault))
defaultPath = localDefault; defaultPath = localDefault;
else if (boost::filesystem::exists(globalDefault)) else if (boost::filesystem::exists(globalDefault))
@ -436,7 +436,7 @@ bool Launcher::MainDialog::setupGraphicsSettings()
// Something's very wrong if we can't find the file at all. // Something's very wrong if we can't find the file at all.
else { else {
cfgError(tr("Error reading OpenMW configuration file"), cfgError(tr("Error reading OpenMW configuration file"),
tr("<br><b>Could not find settings-default.cfg</b><br><br> \ tr("<br><b>Could not find defaults.bin</b><br><br> \
The problem may be due to an incomplete installation of OpenMW.<br> \ The problem may be due to an incomplete installation of OpenMW.<br> \
Reinstalling OpenMW may resolve the problem.")); Reinstalling OpenMW may resolve the problem."));
return false; return false;
@ -447,7 +447,7 @@ bool Launcher::MainDialog::setupGraphicsSettings()
mEngineSettings.loadDefault(defaultPath); mEngineSettings.loadDefault(defaultPath);
} }
catch (std::exception& e) { catch (std::exception& e) {
std::string msg = std::string("<br><b>Error reading settings-default.cfg</b><br><br>") + e.what(); std::string msg = std::string("<br><b>Error reading defaults.bin</b><br><br>") + e.what();
cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str())); cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str()));
return false; return false;
} }

@ -676,7 +676,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::p
} }
if(line[0] == '[') { if(line[0] == '[') {
int pos = line.find(']'); int pos = static_cast<int>(line.find(']'));
if(pos < 2) { if(pos < 2) {
std::cout << "Warning: ini file wrongly formatted (" << line << "). Line ignored." << std::endl; std::cout << "Warning: ini file wrongly formatted (" << line << "). Line ignored." << std::endl;
continue; continue;
@ -686,12 +686,12 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const boost::filesystem::p
continue; continue;
} }
int comment_pos = line.find(";"); int comment_pos = static_cast<int>(line.find(';'));
if(comment_pos > 0) { if(comment_pos > 0) {
line = line.substr(0,comment_pos); line = line.substr(0,comment_pos);
} }
int pos = line.find("="); int pos = static_cast<int>(line.find('='));
if(pos < 1) { if(pos < 1) {
continue; continue;
} }
@ -722,7 +722,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::p
while (std::getline(file, line)) { while (std::getline(file, line)) {
// we cant say comment by only looking at first char anymore // we cant say comment by only looking at first char anymore
int comment_pos = line.find("#"); int comment_pos = static_cast<int>(line.find('#'));
if(comment_pos > 0) { if(comment_pos > 0) {
line = line.substr(0,comment_pos); line = line.substr(0,comment_pos);
} }
@ -731,7 +731,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const boost::filesystem::p
continue; continue;
} }
int pos = line.find("="); int pos = static_cast<int>(line.find('='));
if(pos < 1) { if(pos < 1) {
continue; continue;
} }

@ -20,7 +20,7 @@ namespace bfs = boost::filesystem;
///See if the file has the named extension ///See if the file has the named extension
bool hasExtension(std::string filename, std::string extensionToFind) bool hasExtension(std::string filename, std::string extensionToFind)
{ {
std::string extension = filename.substr(filename.find_last_of(".")+1); std::string extension = filename.substr(filename.find_last_of('.')+1);
//Convert strings to lower case for comparison //Convert strings to lower case for comparison
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);

@ -89,7 +89,7 @@ opencs_units (view/render
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
previewwidget editmode instancemode instanceselectionmode instancemovemode previewwidget editmode instancemode instanceselectionmode instancemovemode
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw commands
) )
opencs_units_noqt (view/render opencs_units_noqt (view/render

@ -21,7 +21,7 @@ void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
{ {
std::vector<std::string>& list = mIds[type]; std::vector<std::string>& list = mIds[type];
int size = list.size(); size_t size = list.size();
list.resize (size+ids.size()); list.resize (size+ids.size());

@ -5,7 +5,6 @@
#include "../tools/reportmodel.hpp" #include "../tools/reportmodel.hpp"
#include "document.hpp" #include "document.hpp"
#include "state.hpp"
CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLoaded (0), mRecordsLeft (false) {} CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLoaded (0), mRecordsLeft (false) {}

@ -7,7 +7,6 @@
#include "../world/universalid.hpp" #include "../world/universalid.hpp"
#include "state.hpp"
#include "stage.hpp" #include "stage.hpp"
void CSMDoc::Operation::prepareStages() void CSMDoc::Operation::prepareStages()

@ -9,7 +9,7 @@ CSMFilter::NAryNode::NAryNode (const std::vector<std::shared_ptr<Node> >& nodes,
int CSMFilter::NAryNode::getSize() const int CSMFilter::NAryNode::getSize() const
{ {
return mNodes.size(); return static_cast<int>(mNodes.size());
} }
const CSMFilter::Node& CSMFilter::NAryNode::operator[] (int index) const const CSMFilter::Node& CSMFilter::NAryNode::operator[] (int index) const

@ -178,7 +178,7 @@ namespace CSMPrefs
{ {
const int MaxKeys = 4; // A limitation of QKeySequence const int MaxKeys = 4; // A limitation of QKeySequence
size_t end = data.find(";"); size_t end = data.find(';');
size_t size = std::min(end, data.size()); size_t size = std::min(end, data.size());
std::string value = data.substr(0, size); std::string value = data.substr(0, size);
@ -191,7 +191,7 @@ namespace CSMPrefs
while (start < value.size()) while (start < value.size())
{ {
end = data.find("+", start); end = data.find('+', start);
end = std::min(end, value.size()); end = std::min(end, value.size());
std::string name = value.substr(start, end - start); std::string name = value.substr(start, end - start);
@ -243,7 +243,7 @@ namespace CSMPrefs
void ShortcutManager::convertFromString(const std::string& data, int& modifier) const void ShortcutManager::convertFromString(const std::string& data, int& modifier) const
{ {
size_t start = data.find(";") + 1; size_t start = data.find(';') + 1;
start = std::min(start, data.size()); start = std::min(start, data.size());
std::string name = data.substr(start); std::string name = data.substr(start);

@ -11,7 +11,7 @@ CSMTools::MandatoryIdStage::MandatoryIdStage (const CSMWorld::CollectionBase& id
int CSMTools::MandatoryIdStage::setup() int CSMTools::MandatoryIdStage::setup()
{ {
return mIds.size(); return static_cast<int>(mIds.size());
} }
void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages) void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages)

@ -24,7 +24,7 @@ int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
if (parent.isValid()) if (parent.isValid())
return 0; return 0;
return mRows.size(); return static_cast<int>(mRows.size());
} }
int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
@ -140,7 +140,7 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
void CSMTools::ReportModel::add (const CSMDoc::Message& message) void CSMTools::ReportModel::add (const CSMDoc::Message& message)
{ {
beginInsertRows (QModelIndex(), mRows.size(), mRows.size()); beginInsertRows (QModelIndex(), static_cast<int>(mRows.size()), static_cast<int>(mRows.size()));
mRows.push_back (message); mRows.push_back (message);
@ -176,7 +176,7 @@ void CSMTools::ReportModel::clear()
{ {
if (!mRows.empty()) if (!mRows.empty())
{ {
beginRemoveRows (QModelIndex(), 0, mRows.size()-1); beginRemoveRows (QModelIndex(), 0, static_cast<int>(mRows.size())-1);
mRows.clear(); mRows.clear();
endRemoveRows(); endRemoveRows();
} }

@ -270,7 +270,7 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
if (!newOrder.empty()) if (!newOrder.empty())
if (mIdCollection->reorderRows (baseIndex, newOrder)) if (mIdCollection->reorderRows (baseIndex, newOrder))
emit dataChanged (index (baseIndex, 0), emit dataChanged (index (baseIndex, 0),
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1)); index (baseIndex+static_cast<int>(newOrder.size())-1, mIdCollection->getColumns()-1));
} }
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const

@ -1,6 +1,5 @@
#include "refcollection.hpp" #include "refcollection.hpp"
#include <components/misc/stringops.hpp>
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include "ref.hpp" #include "ref.hpp"
@ -109,11 +108,13 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
Record<CellRef> record; Record<CellRef> record;
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record.mBase : record.mModified) = ref; const ESM::RefNum refNum = ref.mRefNum;
std::string refId = ref.mId;
(base ? record.mBase : record.mModified) = std::move(ref);
appendRecord (record); appendRecord (record);
cache.insert (std::make_pair (ref.mRefNum, ref.mId)); cache.emplace(refNum, std::move(refId));
} }
else else
{ {
@ -124,7 +125,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
Record<CellRef> record = getRecord (index); Record<CellRef> record = getRecord (index);
record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified; record.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
(base ? record.mBase : record.mModified) = ref; (base ? record.mBase : record.mModified) = std::move(ref);
setRecord (index, record); setRecord (index, record);
} }

@ -20,13 +20,13 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *
mFiles.clear(); mFiles.clear();
mIndex.clear(); mIndex.clear();
int baseSize = mBaseDirectory.size(); size_t baseSize = mBaseDirectory.size();
const std::map<std::string, VFS::File*>& index = vfs->getIndex(); const std::map<std::string, VFS::File*>& index = vfs->getIndex();
for (std::map<std::string, VFS::File*>::const_iterator it = index.begin(); it != index.end(); ++it) for (std::map<std::string, VFS::File*>::const_iterator it = index.begin(); it != index.end(); ++it)
{ {
std::string filepath = it->first; std::string filepath = it->first;
if (static_cast<int> (filepath.size())<baseSize+1 || if (filepath.size()<baseSize+1 ||
filepath.substr (0, baseSize)!=mBaseDirectory || filepath.substr (0, baseSize)!=mBaseDirectory ||
(filepath[baseSize]!='/' && filepath[baseSize]!='\\')) (filepath[baseSize]!='/' && filepath[baseSize]!='\\'))
continue; continue;
@ -60,7 +60,7 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *
int CSMWorld::Resources::getSize() const int CSMWorld::Resources::getSize() const
{ {
return mFiles.size(); return static_cast<int>(mFiles.size());
} }
std::string CSMWorld::Resources::getId (int index) const std::string CSMWorld::Resources::getId (int index) const

@ -30,7 +30,7 @@ void CSVDoc::Operations::setProgress (int current, int max, int type, int thread
return; return;
} }
int oldCount = mOperations.size(); int oldCount = static_cast<int>(mOperations.size());
int newCount = oldCount + 1; int newCount = oldCount + 1;
Operation *operation = new Operation (type, this); Operation *operation = new Operation (type, this);
@ -51,7 +51,7 @@ void CSVDoc::Operations::quitOperation (int type)
for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter) for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter)
if ((*iter)->getType()==type) if ((*iter)->getType()==type)
{ {
int oldCount = mOperations.size(); int oldCount = static_cast<int>(mOperations.size());
int newCount = oldCount - 1; int newCount = oldCount - 1;
mLayout->removeItem ((*iter)->getLayout()); mLayout->removeItem ((*iter)->getLayout());

@ -11,7 +11,6 @@
#include "../../model/doc/documentmanager.hpp" #include "../../model/doc/documentmanager.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/universalid.hpp"
#include "../../model/world/idcompletionmanager.hpp" #include "../../model/world/idcompletionmanager.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"

@ -2,7 +2,6 @@
#include <osg/Group> #include <osg/Group>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include <osg/Geode>
#include <osg/Geometry> #include <osg/Geometry>
#include <osg/PrimitiveSet> #include <osg/PrimitiveSet>
@ -13,15 +12,23 @@
#include "../../model/world/cellcoordinates.hpp" #include "../../model/world/cellcoordinates.hpp"
const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE; const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE;
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 3;
/*
The number of vertices per cell border is equal to the number of vertices per edge
minus the duplicated corner vertices. An additional vertex to close the loop is NOT needed.
*/
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 4;
CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords) CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords)
: mParentNode(cellNode) : mParentNode(cellNode)
{ {
mBorderGeometry = new osg::Geometry();
mBaseNode = new osg::PositionAttitudeTransform(); mBaseNode = new osg::PositionAttitudeTransform();
mBaseNode->setNodeMask(Mask_CellBorder); mBaseNode->setNodeMask(Mask_CellBorder);
mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10)); mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10));
mBaseNode->addChild(mBorderGeometry);
mParentNode->addChild(mBaseNode); mParentNode->addChild(mBaseNode);
} }
@ -38,56 +45,59 @@ void CSVRender::CellBorder::buildShape(const ESM::Land& esmLand)
if (!landData) if (!landData)
return; return;
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry(); mBaseNode->removeChild(mBorderGeometry);
mBorderGeometry = new osg::Geometry();
// Vertices
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
int x = 0, y = 0; int x = 0;
for (; x < ESM::Land::LAND_SIZE; ++x) int y = 0;
/*
Traverse the cell border counter-clockwise starting at the SW corner vertex (0, 0).
Each loop starts at a corner vertex and ends right before the next corner vertex.
*/
for (; x < ESM::Land::LAND_SIZE - 1; ++x)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)])); vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
x = ESM::Land::LAND_SIZE - 1; x = ESM::Land::LAND_SIZE - 1;
for (; y < ESM::Land::LAND_SIZE; ++y) for (; y < ESM::Land::LAND_SIZE - 1; ++y)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)])); vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
y = ESM::Land::LAND_SIZE - 1; y = ESM::Land::LAND_SIZE - 1;
for (; x >= 0; --x) for (; x > 0; --x)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)])); vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
x = 0; x = 0;
for (; y >= 0; --y) for (; y > 0; --y)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)])); vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
geometry->setVertexArray(vertices); mBorderGeometry->setVertexArray(vertices);
// Color
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(); osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array();
colors->push_back(osg::Vec4f(0.f, 0.5f, 0.f, 1.f)); colors->push_back(osg::Vec4f(0.f, 0.5f, 0.f, 1.f));
geometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET); mBorderGeometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
// Primitive
osg::ref_ptr<osg::DrawElementsUShort> primitives = osg::ref_ptr<osg::DrawElementsUShort> primitives =
new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount+1); new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount + 1);
// Assign one primitive to each vertex.
for (size_t i = 0; i < VertexCount; ++i) for (size_t i = 0; i < VertexCount; ++i)
primitives->setElement(i, i); primitives->setElement(i, i);
// Assign the last primitive to the first vertex to close the loop.
primitives->setElement(VertexCount, 0); primitives->setElement(VertexCount, 0);
geometry->addPrimitiveSet(primitives); mBorderGeometry->addPrimitiveSet(primitives);
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); mBorderGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::ref_ptr<osg::Geode> geode = new osg::Geode(); mBaseNode->addChild(mBorderGeometry);
geode->addDrawable(geometry);
mBaseNode->addChild(geode);
} }
size_t CSVRender::CellBorder::landIndex(int x, int y) size_t CSVRender::CellBorder::landIndex(int x, int y)
{ {
return y * ESM::Land::LAND_SIZE + x; return static_cast<size_t>(y) * ESM::Land::LAND_SIZE + x;
} }
float CSVRender::CellBorder::scaleToWorld(int value) float CSVRender::CellBorder::scaleToWorld(int value)

@ -7,6 +7,7 @@
namespace osg namespace osg
{ {
class Geometry;
class Group; class Group;
class PositionAttitudeTransform; class PositionAttitudeTransform;
} }
@ -47,7 +48,7 @@ namespace CSVRender
osg::Group* mParentNode; osg::Group* mParentNode;
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode; osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
osg::ref_ptr<osg::Geometry> mBorderGeometry;
}; };
} }

@ -0,0 +1,19 @@
#include "commands.hpp"
#include <components/esm/loadland.hpp>
#include "terrainselection.hpp"
CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent)
: mTerrainSelection(terrainSelection)
{ }
void CSVRender::DrawTerrainSelectionCommand::redo()
{
mTerrainSelection.update();
}
void CSVRender::DrawTerrainSelectionCommand::undo()
{
mTerrainSelection.update();
}

@ -0,0 +1,35 @@
#ifndef CSV_RENDER_COMMANDS_HPP
#define CSV_RENDER_COMMANDS_HPP
#include <QUndoCommand>
namespace CSVRender
{
class TerrainSelection;
/*
Current solution to force a redrawing of the terrain-selection grid
when undoing/redoing changes in the editor.
This only triggers a simple redraw of the grid, so only use it in
conjunction with actual data changes which deform the grid.
Please note that this command needs to be put onto the QUndoStack twice:
at the start and at the end of the related terrain manipulation.
This makes sure that the grid is always updated after all changes have
been undone or redone -- but it also means that the selection is redrawn
once at the beginning of either action. Future refinement may solve that.
*/
class DrawTerrainSelectionCommand : public QUndoCommand
{
private:
TerrainSelection& mTerrainSelection;
public:
DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent = nullptr);
void redo() override;
void undo() override;
};
}
#endif

@ -3,7 +3,6 @@
#include <QMenu> #include <QMenu>
#include "../../model/prefs/shortcut.hpp" #include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "worldspacewidget.hpp" #include "worldspacewidget.hpp"

@ -7,18 +7,14 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QApplication> #include <QApplication>
#include <components/esm/loadland.hpp>
#include <components/misc/constants.hpp> #include <components/misc/constants.hpp>
#include "../../model/prefs/shortcut.hpp" #include "../../model/prefs/shortcut.hpp"
#include "../../model/world/tablemimedata.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetooltoggle2.hpp"
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
#include "../widget/scenetooltoggle2.hpp"
#include "editmode.hpp" #include "editmode.hpp"
#include "mask.hpp" #include "mask.hpp"

@ -9,8 +9,6 @@
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/commandmacro.hpp" #include "../../model/world/commandmacro.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/world/idtree.hpp"
#include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolbar.hpp"

@ -25,7 +25,6 @@
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "../../model/prefs/shortcut.hpp" #include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "lighting.hpp" #include "lighting.hpp"
#include "mask.hpp" #include "mask.hpp"

@ -39,64 +39,23 @@ std::vector<std::pair<int, int>> CSVRender::TerrainSelection::getTerrainSelectio
void CSVRender::TerrainSelection::onlySelect(const std::vector<std::pair<int, int>> &localPositions) void CSVRender::TerrainSelection::onlySelect(const std::vector<std::pair<int, int>> &localPositions)
{ {
mSelection = localPositions; mSelection = localPositions;
update(); update();
} }
void CSVRender::TerrainSelection::addSelect(const std::pair<int, int> &localPos) void CSVRender::TerrainSelection::addSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
{ {
if (std::find(mSelection.begin(), mSelection.end(), localPos) == mSelection.end()) handleSelection(localPositions, toggleInProgress, SelectionMethod::AddSelect);
{
mSelection.emplace_back(localPos);
update();
}
} }
void CSVRender::TerrainSelection::toggleSelect(const std::vector<std::pair<int, int>> &localPositions, bool toggleInProgress) void CSVRender::TerrainSelection::removeSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
{ {
if (toggleInProgress) handleSelection(localPositions, toggleInProgress, SelectionMethod::RemoveSelect);
{ }
for(auto const& localPos: localPositions)
{
auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
mDraggedOperationFlag = true;
if (iterTemp == mTemporarySelection.end())
{
auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
if (iter != mSelection.end())
{
mSelection.erase(iter);
}
else
{
mSelection.emplace_back(localPos);
}
}
mTemporarySelection.push_back(localPos); void CSVRender::TerrainSelection::toggleSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress)
} {
} handleSelection(localPositions, toggleInProgress, SelectionMethod::ToggleSelect);
else if (mDraggedOperationFlag == false)
{
for(auto const& localPos: localPositions)
{
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
if (iter != mSelection.end())
{
mSelection.erase(iter);
}
else
{
mSelection.emplace_back(localPos);
}
}
}
else
{
mDraggedOperationFlag = false;
mTemporarySelection.clear();
}
update();
} }
void CSVRender::TerrainSelection::activate() void CSVRender::TerrainSelection::activate()
@ -239,6 +198,100 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr<osg::V
} }
} }
void CSVRender::TerrainSelection::handleSelection(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod)
{
if (toggleInProgress)
{
for (auto const& localPos : localPositions)
{
auto iterTemp = std::find(mTemporarySelection.begin(), mTemporarySelection.end(), localPos);
mDraggedOperationFlag = true;
if (iterTemp == mTemporarySelection.end())
{
auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
switch (selectionMethod)
{
case SelectionMethod::AddSelect:
if (iter == mSelection.end())
{
mSelection.emplace_back(localPos);
}
break;
case SelectionMethod::RemoveSelect:
if (iter != mSelection.end())
{
mSelection.erase(iter);
}
break;
case SelectionMethod::ToggleSelect:
if (iter == mSelection.end())
{
mSelection.emplace_back(localPos);
}
else
{
mSelection.erase(iter);
}
break;
default: break;
}
}
mTemporarySelection.push_back(localPos);
}
}
else if (mDraggedOperationFlag == false)
{
for (auto const& localPos : localPositions)
{
const auto iter = std::find(mSelection.begin(), mSelection.end(), localPos);
switch (selectionMethod)
{
case SelectionMethod::AddSelect:
if (iter == mSelection.end())
{
mSelection.emplace_back(localPos);
}
break;
case SelectionMethod::RemoveSelect:
if (iter != mSelection.end())
{
mSelection.erase(iter);
}
break;
case SelectionMethod::ToggleSelect:
if (iter == mSelection.end())
{
mSelection.emplace_back(localPos);
}
else
{
mSelection.erase(iter);
}
break;
default: break;
}
}
}
else
{
mDraggedOperationFlag = false;
mTemporarySelection.clear();
}
update();
}
bool CSVRender::TerrainSelection::noCell(const std::string& cellId) bool CSVRender::TerrainSelection::noCell(const std::string& cellId)
{ {
CSMDoc::Document& document = mWorldspaceWidget->getDocument(); CSMDoc::Document& document = mWorldspaceWidget->getDocument();

@ -27,6 +27,14 @@ namespace CSVRender
Shape Shape
}; };
enum class SelectionMethod
{
OnlySelect,
AddSelect,
RemoveSelect,
ToggleSelect
};
/// \brief Class handling the terrain selection data and rendering /// \brief Class handling the terrain selection data and rendering
class TerrainSelection class TerrainSelection
{ {
@ -36,7 +44,8 @@ namespace CSVRender
~TerrainSelection(); ~TerrainSelection();
void onlySelect(const std::vector<std::pair<int, int>> &localPositions); void onlySelect(const std::vector<std::pair<int, int>> &localPositions);
void addSelect(const std::pair<int, int> &localPos); void addSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress);
void removeSelect(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress);
void toggleSelect(const std::vector<std::pair<int, int>> &localPositions, bool toggleInProgress); void toggleSelect(const std::vector<std::pair<int, int>> &localPositions, bool toggleInProgress);
void activate(); void activate();
@ -55,6 +64,8 @@ namespace CSVRender
private: private:
void handleSelection(const std::vector<std::pair<int, int>>& localPositions, bool toggleInProgress, SelectionMethod selectionMethod);
bool noCell(const std::string& cellId); bool noCell(const std::string& cellId);
bool noLand(const std::string& cellId); bool noLand(const std::string& cellId);

@ -25,18 +25,16 @@
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "../../model/world/columnbase.hpp"
#include "../../model/world/commandmacro.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/idtree.hpp" #include "../../model/world/idtree.hpp"
#include "../../model/world/land.hpp" #include "../../model/world/land.hpp"
#include "../../model/world/resourcetable.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "brushdraw.hpp" #include "brushdraw.hpp"
#include "commands.hpp"
#include "editmode.hpp" #include "editmode.hpp"
#include "pagedworldspacewidget.hpp" #include "pagedworldspacewidget.hpp"
#include "mask.hpp" #include "mask.hpp"
@ -45,7 +43,7 @@
#include "worldspacewidget.hpp" #include "worldspacewidget.hpp"
CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent)
: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain | Mask_Reference, "Terrain land editing", parent), : EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain, "Terrain land editing", parent),
mParentNode(parentNode) mParentNode(parentNode)
{ {
} }
@ -288,6 +286,9 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
undoStack.beginMacro ("Edit shape and normal records"); undoStack.beginMacro ("Edit shape and normal records");
// One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes.
undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection));
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
{ {
std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY()); std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY());
@ -356,6 +357,9 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
} }
pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId); pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId);
} }
// One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes.
undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection));
undoStack.endMacro(); undoStack.endMacro();
clearTransientEdits(); clearTransientEdits();
} }
@ -433,7 +437,9 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair<int, int>
float smoothedByDistance = 0.0f; float smoothedByDistance = 0.0f;
if (mShapeEditTool == ShapeEditTool_Drag) smoothedByDistance = calculateBumpShape(distance, r, mTotalDiffY); if (mShapeEditTool == ShapeEditTool_Drag) smoothedByDistance = calculateBumpShape(distance, r, mTotalDiffY);
if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) smoothedByDistance = calculateBumpShape(distance, r, r + mShapeEditToolStrength); if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) smoothedByDistance = calculateBumpShape(distance, r, r + mShapeEditToolStrength);
if (distance <= r)
// Using floating-point radius here to prevent selecting too few vertices.
if (distance <= mBrushSize / 2.0f)
{ {
if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, smoothedByDistance); if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, smoothedByDistance);
if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower)
@ -1036,10 +1042,35 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob
return; return;
int selectionX = globalSelectionX; int selectionX = globalSelectionX;
int selectionY = globalSelectionY; int selectionY = globalSelectionY;
if (xIsAtCellBorder)
/*
The northern and eastern edges don't belong to the current cell.
If the corresponding adjacent cell is not loaded, some special handling is necessary to select border vertices.
*/
if (xIsAtCellBorder && yIsAtCellBorder)
{
/*
Handle the NW, NE, and SE corner vertices.
NW corner: (+1, -1) offset to reach current cell.
NE corner: (-1, -1) offset to reach current cell.
SE corner: (-1, +1) offset to reach current cell.
*/
if (isInCellSelection(globalSelectionX - 1, globalSelectionY - 1)
|| isInCellSelection(globalSelectionX + 1, globalSelectionY - 1)
|| isInCellSelection(globalSelectionX - 1, globalSelectionY + 1))
{
selections->emplace_back(globalSelectionX, globalSelectionY);
}
}
else if (xIsAtCellBorder)
{
selectionX--; selectionX--;
if (yIsAtCellBorder) }
else if (yIsAtCellBorder)
{
selectionY--; selectionY--;
}
if (isInCellSelection(selectionX, selectionY)) if (isInCellSelection(selectionX, selectionY))
selections->emplace_back(globalSelectionX, globalSelectionY); selections->emplace_back(globalSelectionX, globalSelectionY);
} }
@ -1074,8 +1105,11 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
{ {
int distanceX = abs(i - vertexCoords.first); int distanceX = abs(i - vertexCoords.first);
int distanceY = abs(j - vertexCoords.second); int distanceY = abs(j - vertexCoords.second);
int distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); float distance = sqrt(pow(distanceX, 2)+pow(distanceY, 2));
if (distance <= r) handleSelection(i, j, &selections);
// Using floating-point radius here to prevent selecting too few vertices.
if (distance <= mBrushSize / 2.0f)
handleSelection(i, j, &selections);
} }
} }
} }
@ -1092,9 +1126,21 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair<int, int>&
} }
} }
if(selectMode == 0) mTerrainShapeSelection->onlySelect(selections); std::string selectAction;
if(selectMode == 1) mTerrainShapeSelection->toggleSelect(selections, dragOperation);
if (selectMode == 0)
selectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString();
else
selectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString();
if (selectAction == "Select only")
mTerrainShapeSelection->onlySelect(selections);
else if (selectAction == "Add to selection")
mTerrainShapeSelection->addSelect(selections, dragOperation);
else if (selectAction == "Remove from selection")
mTerrainShapeSelection->removeSelect(selections, dragOperation);
else if (selectAction == "Invert selection")
mTerrainShapeSelection->toggleSelect(selections, dragOperation);
} }
void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document,

@ -12,23 +12,17 @@
#include <osg/Group> #include <osg/Group>
#include <components/esm/loadland.hpp>
#include "../widget/modebutton.hpp" #include "../widget/modebutton.hpp"
#include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolbar.hpp"
#include "../widget/scenetooltexturebrush.hpp" #include "../widget/scenetooltexturebrush.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "../../model/world/columnbase.hpp"
#include "../../model/world/commandmacro.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/idtree.hpp" #include "../../model/world/idtree.hpp"
#include "../../model/world/land.hpp"
#include "../../model/world/landtexture.hpp" #include "../../model/world/landtexture.hpp"
#include "../../model/world/resourcetable.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../widget/brushshapes.hpp" #include "../widget/brushshapes.hpp"
@ -332,7 +326,7 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe
int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex); int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex);
std::size_t hashlocation = mBrushTexture.find("#"); std::size_t hashlocation = mBrushTexture.find('#');
std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1); std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1);
int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +1 int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +1

@ -12,7 +12,6 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../widget/scenetooltoggle.hpp"
#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetooltoggle2.hpp"
#include "cameracontroller.hpp" #include "cameracontroller.hpp"

@ -17,7 +17,6 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/prefs/shortcut.hpp" #include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "../render/orbitcameramode.hpp" #include "../render/orbitcameramode.hpp"

@ -30,7 +30,7 @@ void CSVWidget::SceneToolRun::updateIcon()
void CSVWidget::SceneToolRun::updatePanel() void CSVWidget::SceneToolRun::updatePanel()
{ {
mTable->setRowCount (mProfiles.size()); mTable->setRowCount (static_cast<int>(mProfiles.size()));
int i = 0; int i = 0;

@ -27,11 +27,6 @@
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/idcollection.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/world/landtexture.hpp"
#include "../../model/world/universalid.hpp"
CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString &title, QWidget *parent) CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString &title, QWidget *parent)

@ -80,7 +80,7 @@ QRect CSVWidget::SceneToolToggle::getIconBox (int index) const
int y = index / xMax; int y = index / xMax;
int x = index % xMax; int x = index % xMax;
int total = mButtons.size(); int total = static_cast<int>(mButtons.size());
int actualYIcons = total/xMax; int actualYIcons = total/xMax;
@ -154,7 +154,7 @@ void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned in
desc.mMask = mask; desc.mMask = mask;
desc.mSmallIcon = smallIcon; desc.mSmallIcon = smallIcon;
desc.mName = name; desc.mName = name;
desc.mIndex = mButtons.size(); desc.mIndex = static_cast<int>(mButtons.size());
mButtons.insert (std::make_pair (button, desc)); mButtons.insert (std::make_pair (button, desc));

@ -99,7 +99,7 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id, unsigned int mask,
desc.mButtonId = id; desc.mButtonId = id;
desc.mMask = mask; desc.mMask = mask;
desc.mName = name; desc.mName = name;
desc.mIndex = mButtons.size(); desc.mIndex = static_cast<int>(mButtons.size());
mButtons.insert (std::make_pair (button, desc)); mButtons.insert (std::make_pair (button, desc));

@ -3,8 +3,6 @@
#include <QPainter> #include <QPainter>
#include <QPushButton> #include <QPushButton>
#include "../widget/coloreditor.hpp"
CSVWorld::ColorDelegate::ColorDelegate(CSMWorld::CommandDispatcher *dispatcher, CSVWorld::ColorDelegate::ColorDelegate(CSMWorld::CommandDispatcher *dispatcher,
CSMDoc::Document& document, CSMDoc::Document& document,
QObject *parent) QObject *parent)

@ -28,7 +28,6 @@
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/record.hpp" #include "../../model/world/record.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"

@ -42,7 +42,7 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con
if (!mNamespace.empty()) if (!mNamespace.empty())
{ {
std::string namespace_ = input.left (mNamespace.size()).toUtf8().constData(); std::string namespace_ = input.left (static_cast<int>(mNamespace.size())).toUtf8().constData();
if (Misc::StringUtils::lowerCase (namespace_)!=mNamespace) if (Misc::StringUtils::lowerCase (namespace_)!=mNamespace)
return QValidator::Invalid; // incorrect namespace return QValidator::Invalid; // incorrect namespace

@ -15,7 +15,6 @@
#include "../render/pagedworldspacewidget.hpp" #include "../render/pagedworldspacewidget.hpp"
#include "../render/unpagedworldspacewidget.hpp" #include "../render/unpagedworldspacewidget.hpp"
#include "../render/editmode.hpp"
#include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"

@ -12,7 +12,6 @@
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/columnbase.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"

@ -85,9 +85,9 @@ std::string loadSettings (Settings::Manager & settings)
// prefer local // prefer local
if (boost::filesystem::exists(localdefault)) if (boost::filesystem::exists(localdefault))
settings.loadDefault(localdefault); settings.loadDefault(localdefault, false);
else if (boost::filesystem::exists(globaldefault)) else if (boost::filesystem::exists(globaldefault))
settings.loadDefault(globaldefault); settings.loadDefault(globaldefault, false);
else else
throw std::runtime_error ("No default settings file found! Make sure the file \"tes3mp-server-default.cfg\" was properly installed."); throw std::runtime_error ("No default settings file found! Make sure the file \"tes3mp-server-default.cfg\" was properly installed.");

@ -247,7 +247,7 @@ if(APPLE)
add_subdirectory(../../files/ ${CMAKE_CURRENT_BINARY_DIR}/files) add_subdirectory(../../files/ ${CMAKE_CURRENT_BINARY_DIR}/files)
configure_file("${OpenMW_BINARY_DIR}/settings-default.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY) configure_file("${OpenMW_BINARY_DIR}/defaults.bin" ${BUNDLE_RESOURCES_DIR} COPYONLY)
configure_file("${OpenMW_BINARY_DIR}/openmw.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY) configure_file("${OpenMW_BINARY_DIR}/openmw.cfg" ${BUNDLE_RESOURCES_DIR} COPYONLY)
configure_file("${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" ${BUNDLE_RESOURCES_DIR} COPYONLY) configure_file("${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" ${BUNDLE_RESOURCES_DIR} COPYONLY)

@ -601,8 +601,8 @@ void OMW::Engine::setSkipMenu (bool skipMenu, bool newGame)
std::string OMW::Engine::loadSettings (Settings::Manager & settings) std::string OMW::Engine::loadSettings (Settings::Manager & settings)
{ {
// Create the settings manager and load default settings file // Create the settings manager and load default settings file
const std::string localdefault = (mCfgMgr.getLocalPath() / "settings-default.cfg").string(); const std::string localdefault = (mCfgMgr.getLocalPath() / "defaults.bin").string();
const std::string globaldefault = (mCfgMgr.getGlobalPath() / "settings-default.cfg").string(); const std::string globaldefault = (mCfgMgr.getGlobalPath() / "defaults.bin").string();
// prefer local // prefer local
if (boost::filesystem::exists(localdefault)) if (boost::filesystem::exists(localdefault))
@ -610,7 +610,7 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
else if (boost::filesystem::exists(globaldefault)) else if (boost::filesystem::exists(globaldefault))
settings.loadDefault(globaldefault); settings.loadDefault(globaldefault);
else else
throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed."); throw std::runtime_error ("No default settings file found! Make sure the file \"defaults.bin\" was properly installed.");
// load user settings if they exist // load user settings if they exist
const std::string settingspath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string(); const std::string settingspath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string();

@ -42,7 +42,6 @@
#include "../mwworld/failedaction.hpp" #include "../mwworld/failedaction.hpp"
#include "../mwworld/customdata.hpp" #include "../mwworld/customdata.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwphysics/physicssystem.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/localscripts.hpp" #include "../mwworld/localscripts.hpp"

@ -52,7 +52,6 @@
#include "../mwworld/failedaction.hpp" #include "../mwworld/failedaction.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/customdata.hpp" #include "../mwworld/customdata.hpp"
#include "../mwphysics/physicssystem.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/localscripts.hpp" #include "../mwworld/localscripts.hpp"

@ -3,7 +3,6 @@
#include "../mwbase/journal.hpp" #include "../mwbase/journal.hpp"
#include "journalentry.hpp"
#include "quest.hpp" #include "quest.hpp"
namespace MWDialogue namespace MWDialogue

@ -10,7 +10,6 @@
#include <stdint.h> #include <stdint.h>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/widgets/widgets.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"

@ -23,6 +23,10 @@
#include <components/compiler/exception.hpp> #include <components/compiler/exception.hpp>
#include <components/compiler/extensions0.hpp> #include <components/compiler/extensions0.hpp>
#include <components/compiler/lineparser.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/interpreter/interpreter.hpp>
#include "../mwscript/extensions.hpp" #include "../mwscript/extensions.hpp"

@ -6,12 +6,8 @@
#include <vector> #include <vector>
#include <components/compiler/errorhandler.hpp> #include <components/compiler/errorhandler.hpp>
#include <components/compiler/lineparser.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp> #include <components/compiler/output.hpp>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include "../mwscript/compilercontext.hpp" #include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp" #include "../mwscript/interpretercontext.hpp"

@ -319,7 +319,7 @@ namespace MWGui
deleteLater(); deleteLater();
for (Link* link : mLinks) for (Link* link : mLinks)
delete link; delete link;
for (auto link : mTopicLinks) for (const auto& link : mTopicLinks)
delete link.second; delete link.second;
for (auto history : mHistoryContents) for (auto history : mHistoryContents)
delete history; delete history;

@ -2,7 +2,6 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"

@ -5,9 +5,7 @@
#include <MyGUI_FactoryManager.h> #include <MyGUI_FactoryManager.h>
#include <MyGUI_Gui.h> #include <MyGUI_Gui.h>
#include <MyGUI_ImageBox.h> #include <MyGUI_ImageBox.h>
#include <MyGUI_TextBox.h>
#include <MyGUI_ScrollView.h> #include <MyGUI_ScrollView.h>
#include <MyGUI_Button.h>
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"

@ -278,7 +278,7 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex ()
mIndexPagesCount = 2; mIndexPagesCount = 2;
} }
unsigned char ch[2] = {0xd0, 0x90}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 unsigned char ch[3] = {0xd0, 0x90, 0x00}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8
for (int i = 0; i < 32; ++i) for (int i = 0; i < 32; ++i)
{ {

@ -12,7 +12,6 @@
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"

@ -25,8 +25,6 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/inputmanager.hpp" #include "../mwbase/inputmanager.hpp"
#include "../mwrender/vismask.hpp"
#include "backgroundimage.hpp" #include "backgroundimage.hpp"
namespace MWGui namespace MWGui

@ -3,7 +3,6 @@
#include <memory> #include <memory>
#include <osg/Camera>
#include <osg/Timer> #include <osg/Timer>
#include <osg/ref_ptr> #include <osg/ref_ptr>

@ -7,7 +7,6 @@
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/pickpocket.hpp" #include "../mwmechanics/pickpocket.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"

@ -1,8 +1,6 @@
#ifndef MWGUI_QUICKKEYS_H #ifndef MWGUI_QUICKKEYS_H
#define MWGUI_QUICKKEYS_H #define MWGUI_QUICKKEYS_H
#include "../mwworld/ptr.hpp"
#include "windowbase.hpp" #include "windowbase.hpp"
#include "spellmodel.hpp" #include "spellmodel.hpp"

@ -1,7 +1,6 @@
#include "recharge.hpp" #include "recharge.hpp"
#include <MyGUI_ScrollView.h> #include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h>
#include <components/widgets/box.hpp> #include <components/widgets/box.hpp>
@ -15,10 +14,10 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/recharge.hpp" #include "../mwmechanics/recharge.hpp"
#include "itemselection.hpp"
#include "itemwidget.hpp" #include "itemwidget.hpp"
#include "itemchargeview.hpp" #include "itemchargeview.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"

@ -3,8 +3,6 @@
#include "windowbase.hpp" #include "windowbase.hpp"
#include "itemselection.hpp"
namespace MWWorld namespace MWWorld
{ {
class Ptr; class Ptr;

@ -3,8 +3,6 @@
#include <iomanip> #include <iomanip>
#include <MyGUI_ScrollView.h> #include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h>
#include <MyGUI_ItemBox.h>
#include <components/widgets/box.hpp> #include <components/widgets/box.hpp>
@ -17,6 +15,7 @@
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "itemselection.hpp"
#include "itemwidget.hpp" #include "itemwidget.hpp"
#include "itemchargeview.hpp" #include "itemchargeview.hpp"
#include "sortfilteritemmodel.hpp" #include "sortfilteritemmodel.hpp"

@ -3,8 +3,6 @@
#include "windowbase.hpp" #include "windowbase.hpp"
#include "itemselection.hpp"
#include "../mwmechanics/repair.hpp" #include "../mwmechanics/repair.hpp"
namespace MWGui namespace MWGui

@ -1,9 +1,7 @@
#include "spellwindow.hpp" #include "spellwindow.hpp"
#include <MyGUI_Button.h>
#include <MyGUI_EditBox.h> #include <MyGUI_EditBox.h>
#include <MyGUI_InputManager.h> #include <MyGUI_InputManager.h>
#include <MyGUI_Window.h>
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>

@ -2,7 +2,6 @@
#define MWGUI_SPELLWINDOW_H #define MWGUI_SPELLWINDOW_H
#include "windowpinnablebase.hpp" #include "windowpinnablebase.hpp"
#include "../mwworld/ptr.hpp"
#include "spellmodel.hpp" #include "spellmodel.hpp"

@ -266,7 +266,7 @@ namespace MWGui
std::map<std::string, std::string> userStrings = focus->getUserStrings(); std::map<std::string, std::string> userStrings = focus->getUserStrings();
for (auto& userStringPair : userStrings) for (auto& userStringPair : userStrings)
{ {
size_t underscorePos = userStringPair.first.find("_"); size_t underscorePos = userStringPair.first.find('_');
if (underscorePos == std::string::npos) if (underscorePos == std::string::npos)
continue; continue;
std::string key = userStringPair.first.substr(0, underscorePos); std::string key = userStringPair.first.substr(0, underscorePos);

@ -38,7 +38,6 @@
#include "containeritemmodel.hpp" #include "containeritemmodel.hpp"
#include "tradeitemmodel.hpp" #include "tradeitemmodel.hpp"
#include "countdialog.hpp" #include "countdialog.hpp"
#include "controllers.hpp"
#include "tooltips.hpp" #include "tooltips.hpp"
namespace namespace

@ -34,8 +34,6 @@
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
#include "../mwstate/charactermanager.hpp"
namespace MWGui namespace MWGui
{ {

@ -9,7 +9,6 @@
#include <MyGUI_UString.h> #include <MyGUI_UString.h>
#include <MyGUI_IPointer.h> #include <MyGUI_IPointer.h>
#include <MyGUI_TextureUtility.h>
#include <MyGUI_FactoryManager.h> #include <MyGUI_FactoryManager.h>
#include <MyGUI_LanguageManager.h> #include <MyGUI_LanguageManager.h>
#include <MyGUI_PointerManager.h> #include <MyGUI_PointerManager.h>
@ -77,7 +76,6 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwmechanics/stat.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"

@ -6,7 +6,6 @@
#include <components/esm/esmwriter.hpp> #include <components/esm/esmwriter.hpp>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
#include <components/esm/controlsstate.hpp>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"

@ -1,7 +1,6 @@
#ifndef MWINPUT_MWKEYBOARDMANAGER_H #ifndef MWINPUT_MWKEYBOARDMANAGER_H
#define MWINPUT_MWKEYBOARDMANAGER_H #define MWINPUT_MWKEYBOARDMANAGER_H
#include <components/settings/settings.hpp>
#include <components/sdlutil/events.hpp> #include <components/sdlutil/events.hpp>
namespace MWInput namespace MWInput

@ -144,7 +144,8 @@ namespace MWInput
void MouseManager::mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id) void MouseManager::mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id)
{ {
MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
input->setJoystickLastUsed(false);
bool guiMode = false; bool guiMode = false;
if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events
@ -165,7 +166,8 @@ namespace MWInput
mBindingsManager->setPlayerControlsEnabled(!guiMode); mBindingsManager->setPlayerControlsEnabled(!guiMode);
// Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible
if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings) // Also do not trigger bindings when input controls are disabled, e.g. during save loading
if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings && !input->controlsDisabled())
mBindingsManager->mousePressed(arg, id); mBindingsManager->mousePressed(arg, id);
} }

@ -5,7 +5,6 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <components/esm/defs.hpp>
#include <components/esm/activespells.hpp> #include <components/esm/activespells.hpp>
#include "../mwworld/timestamp.hpp" #include "../mwworld/timestamp.hpp"

@ -59,7 +59,6 @@
#include "aiwander.hpp" #include "aiwander.hpp"
#include "actor.hpp" #include "actor.hpp"
#include "summoning.hpp" #include "summoning.hpp"
#include "combat.hpp"
#include "actorutil.hpp" #include "actorutil.hpp"
#include "tickableeffects.hpp" #include "tickableeffects.hpp"
@ -623,7 +622,8 @@ namespace MWMechanics
{ {
greetingTimer++; greetingTimer++;
if (greetingTimer <= GREETING_SHOULD_END || MWBase::Environment::get().getSoundManager()->sayActive(actor)) if (!stats.getMovementFlag(CreatureStats::Flag_ForceJump) && !stats.getMovementFlag(CreatureStats::Flag_ForceSneak)
&& (greetingTimer <= GREETING_SHOULD_END || MWBase::Environment::get().getSoundManager()->sayActive(actor)))
turnActorToFacePlayer(actor, actorState, dir); turnActorToFacePlayer(actor, actorState, dir);
if (greetingTimer >= GREETING_COOLDOWN) if (greetingTimer >= GREETING_COOLDOWN)

@ -3,10 +3,6 @@
#include "typedaipackage.hpp" #include "typedaipackage.hpp"
#include <string>
#include <components/esm/defs.hpp>
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "pathfinding.hpp" #include "pathfinding.hpp"

@ -9,7 +9,6 @@
#include "pathfinding.hpp" #include "pathfinding.hpp"
#include "movement.hpp" #include "movement.hpp"
#include "obstacle.hpp"
#include "aitimer.hpp" #include "aitimer.hpp"
namespace ESM namespace ESM

@ -3,8 +3,6 @@
#include <memory> #include <memory>
#include <components/esm/loadspel.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"

@ -9,8 +9,6 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "pathfinding.hpp"
namespace ESM namespace ESM
{ {
namespace AiSequence namespace AiSequence

@ -2,7 +2,6 @@
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/esm/loadland.hpp> #include <components/esm/loadland.hpp>
#include <components/esm/loadmgef.hpp>
#include <components/detournavigator/navigator.hpp> #include <components/detournavigator/navigator.hpp>
#include <components/misc/coordinateconverter.hpp> #include <components/misc/coordinateconverter.hpp>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -15,8 +14,6 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwphysics/collisiontype.hpp"
#include "pathgrid.hpp" #include "pathgrid.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
#include "movement.hpp" #include "movement.hpp"

@ -3,7 +3,6 @@
#include <memory> #include <memory>
#include <components/esm/defs.hpp>
#include <components/detournavigator/areatype.hpp> #include <components/detournavigator/areatype.hpp>
#include "pathfinding.hpp" #include "pathfinding.hpp"

@ -8,7 +8,6 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/action.hpp"
/* /*
Start of tes3mp addition Start of tes3mp addition

@ -5,8 +5,6 @@
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/esm/aisequence.hpp> #include <components/esm/aisequence.hpp>
#include "../mwbase/world.hpp"
#include "aipackage.hpp" #include "aipackage.hpp"
#include "aistate.hpp" #include "aistate.hpp"
#include "aiwander.hpp" #include "aiwander.hpp"

@ -52,14 +52,15 @@ namespace MWMechanics
bool AiTravel::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) bool AiTravel::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
{ {
MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager(); MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager();
auto& stats = actor.getClass().getCreatureStats(actor);
if (mechMgr->isTurningToPlayer(actor) || mechMgr->getGreetingState(actor) == Greet_InProgress) if (!stats.getMovementFlag(CreatureStats::Flag_ForceJump) && !stats.getMovementFlag(CreatureStats::Flag_ForceSneak)
&& (mechMgr->isTurningToPlayer(actor) || mechMgr->getGreetingState(actor) == Greet_InProgress))
return false; return false;
const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
const osg::Vec3f targetPos(mX, mY, mZ); const osg::Vec3f targetPos(mX, mY, mZ);
auto& stats = actor.getClass().getCreatureStats(actor);
stats.setMovementFlag(CreatureStats::Flag_Run, false); stats.setMovementFlag(CreatureStats::Flag_Run, false);
stats.setDrawState(DrawState_Nothing); stats.setDrawState(DrawState_Nothing);

@ -11,7 +11,6 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/dialoguemanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
@ -210,14 +209,17 @@ namespace MWMechanics
storage.setState(AiWanderStorage::Wander_Walking); storage.setState(AiWanderStorage::Wander_Walking);
} }
GreetingState greetingState = MWBase::Environment::get().getMechanicsManager()->getGreetingState(actor); if(!cStats.getMovementFlag(CreatureStats::Flag_ForceJump) && !cStats.getMovementFlag(CreatureStats::Flag_ForceSneak))
if (greetingState == Greet_InProgress)
{ {
if (storage.mState == AiWanderStorage::Wander_Walking) GreetingState greetingState = MWBase::Environment::get().getMechanicsManager()->getGreetingState(actor);
if (greetingState == Greet_InProgress)
{ {
stopMovement(actor); if (storage.mState == AiWanderStorage::Wander_Walking)
mObstacleCheck.clear(); {
storage.setState(AiWanderStorage::Wander_IdleNow); stopMovement(actor);
mObstacleCheck.clear();
storage.setState(AiWanderStorage::Wander_IdleNow);
}
} }
} }

@ -5,8 +5,6 @@
#include <vector> #include <vector>
#include "../mwworld/timestamp.hpp"
#include "pathfinding.hpp" #include "pathfinding.hpp"
#include "obstacle.hpp" #include "obstacle.hpp"
#include "aistate.hpp" #include "aistate.hpp"
@ -128,7 +126,6 @@ namespace MWMechanics
short unsigned getRandomIdle(); short unsigned getRandomIdle();
void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos); void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos);
void evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage); void evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage);
void turnActorToFacePlayer(const osg::Vec3f& actorPosition, const osg::Vec3f& playerPosition, AiWanderStorage& storage);
void doPerFrameActionsForState(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); void doPerFrameActionsForState(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
void onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); void onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);
void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage);

@ -35,7 +35,6 @@
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/manualref.hpp"
#include "magiceffects.hpp" #include "magiceffects.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"

@ -2034,8 +2034,10 @@ bool CharacterController::updateWeaponState(CharacterState& idle)
MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name() if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name()
&& updateCarriedLeftVisible(mWeaponType)) && updateCarriedLeftVisible(mWeaponType))
{ {
if (mAnimation->isPlaying("shield"))
mAnimation->disable("shield");
mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm, mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm,
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true); false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true);
} }
@ -2595,9 +2597,6 @@ void CharacterController::update(float duration)
if (!mMovementAnimationControlled) if (!mMovementAnimationControlled)
world->queueMovement(mPtr, vec); world->queueMovement(mPtr, vec);
} }
else
// We must always queue movement, even if there is none, to apply gravity.
world->queueMovement(mPtr, osg::Vec3f(0.f, 0.f, 0.f));
movement = vec; movement = vec;
movementSettings.mPosition[0] = movementSettings.mPosition[1] = 0; movementSettings.mPosition[0] = movementSettings.mPosition[1] = 0;
@ -2619,8 +2618,6 @@ void CharacterController::update(float duration)
if (cls.isPersistent(mPtr) || cls.getCreatureStats(mPtr).isDeathAnimationFinished()) if (cls.isPersistent(mPtr) || cls.getCreatureStats(mPtr).isDeathAnimationFinished())
playDeath(1.f, mDeathState); playDeath(1.f, mDeathState);
} }
// We must always queue movement, even if there is none, to apply gravity.
world->queueMovement(mPtr, osg::Vec3f(0.f, 0.f, 0.f));
} }
bool isPersist = isPersistentAnimPlaying(); bool isPersist = isPersistentAnimPlaying();

@ -3,8 +3,6 @@
#include <deque> #include <deque>
#include <components/esm/loadmgef.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save