Merge branch 'master' of https://gitlab.com/madsbuvi/openmw.git into openxr_vr

# Conflicts:
#	apps/openmw/mwbase/environment.cpp
#	apps/openmw/mwbase/environment.hpp
#	apps/openmw/mwbase/world.hpp
#	apps/openmw/mwgui/windowmanagerimp.cpp
#	apps/openmw/mwinput/inputmanagerimp.hpp
#	apps/openmw/mwrender/animation.cpp
#	apps/openmw/mwrender/camera.cpp
#	apps/openmw/mwrender/camera.hpp
#	apps/openmw/mwrender/renderingmanager.cpp
#	apps/openmw/mwrender/renderingmanager.hpp
pull/615/head
Mads Buvik Sandvei 5 years ago
commit 58d73e14e6

1
.gitignore vendored

@ -31,6 +31,7 @@ files/windows/*.aps
## qt-creator
CMakeLists.txt.user*
.vs
.vscode
## resources
data

@ -5,7 +5,7 @@ Debian:
tags:
- docker
- linux
image: gcc
image: debian:bullseye
cache:
key: apt-cache
paths:
@ -13,7 +13,7 @@ Debian:
before_script:
- export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR
- apt-get update -yq
- apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt4-dev libopenal-dev libopenscenegraph-3.4-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev
- apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y cmake build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-iostreams-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libsdl2-dev libqt5opengl5-dev libopenal-dev libopenscenegraph-dev libunshield-dev libtinyxml-dev libmygui-dev libbullet-dev
stage: build
script:
- cores_to_use=$((`nproc`-2)); if (( $cores_to_use < 1 )); then cores_to_use=1; fi

@ -14,10 +14,10 @@ addons:
apt:
sources:
- sourceline: 'ppa:openmw/openmw'
- ubuntu-toolchain-r-test
# - ubuntu-toolchain-r-test # for GCC-10
packages: [
# Dev
cmake, clang-tools, gcc-9, g++-9, ccache,
build-essential, cmake, clang-tools, ccache,
# Boost
libboost-filesystem-dev, libboost-iostreams-dev, libboost-program-options-dev, libboost-system-dev,
# FFmpeg
@ -41,45 +41,26 @@ matrix:
os: osx
osx_image: xcode10.2
if: branch != coverity_scan
- name: OpenMW (all) on Ubuntu Bionic GCC-7
- name: OpenMW (all) on Ubuntu Focal with GCC
os: linux
dist: bionic
sudo: required
dist: focal
if: branch != coverity_scan
- name: OpenMW (all) on Ubuntu Bionic GCC-9
- name: OpenMW (openmw) on Ubuntu Focal with Clang's Static Analysis
os: linux
dist: bionic
sudo: required
env:
- MATRIX_EVAL="CC=gcc-9 && CXX=g++-9"
if: branch != coverity_scan
- name: OpenMW (openmw) on Ubuntu Bionic Clang-6 with Static Analysis
os: linux
dist: bionic
sudo: required
env:
- MATRIX_EVAL="CC=clang && CXX=clang++"
- ANALYZE="scan-build --force-analyze-debug-code --use-cc clang --use-c++ clang++"
- BUILD_OPENMW_CS="OFF"
if: branch != coverity_scan
compiler: clang
- name: OpenMW (openmw-cs) on Ubuntu Bionic Clang-6 with Static Analysis
os: linux
dist: bionic
sudo: required
dist: focal
env:
- MATRIX_EVAL="CC=clang && CXX=clang++"
- ANALYZE="scan-build --force-analyze-debug-code --use-cc clang --use-c++ clang++"
- BUILD_OPENMW="OFF"
if: branch != coverity_scan
compiler: clang
- name: OpenMW Components Coverity Scan
os: linux
dist: bionic
sudo: required
dist: focal
if: branch = coverity_scan
# allow_failures:
# - name: OpenMW (openmw) on Ubuntu Bionic Clang-6 with Static Analysis
# - name: OpenMW (openmw) on Ubuntu Focal with GCC-10
# env:
# - MATRIX_EVAL="CC=gcc-10 && CXX=g++-10"
before_install:
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then eval "${MATRIX_EVAL}"; fi

@ -155,6 +155,7 @@ Programmers
Paul McElroy (Greendogo)
pchan3
Perry Hugh
Petr Mikheev (ptmikheev)
Phillip Andrews (PhillipAnd)
Pi03k
Pieter van der Kloet (pvdk)

@ -1,21 +1,46 @@
0.47.0
------
Bug #1662: Qt4 and Windows binaries crash if there's a non-ASCII character in a file path/config path
Bug #1952: Incorrect particle lighting
Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs
Bug #3676: NiParticleColorModifier isn't applied properly
Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects
Bug #4021: Attributes and skills are not stored as floats
Bug #4623: Corprus implementation is incorrect
Bug #4774: Guards are ignorant of an invisible player that tries to attack them
Bug #5108: Savegame bloating due to inefficient fog textures format
Bug #5165: Active spells should use real time intead of timestamps
Bug #5358: ForceGreeting always resets the dialogue window completely
Bug #5363: Enchantment autocalc not always 0/1
Bug #5364: Script fails/stops if trying to startscript an unknown script
Bug #5367: Selecting a spell on an enchanted item per hotkey always plays the equip sound
Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures
Bug #5370: Opening an unlocked but trapped door uses the key
Bug #5397: NPC greeting does not reset if you leave + reenter area
Bug #5400: Editor: Verifier checks race of non-skin bodyparts
Bug #5403: Enchantment effect doesn't show on an enemy during death animation
Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work
Bug #5416: Junk non-node records before the root node are not handled gracefully
Bug #5424: Creatures do not headtrack player
Bug #5425: Poison effect only appears for one frame
Bug #5427: GetDistance unknown ID error is misleading
Bug #5435: Enemies can't hurt the player when collision is off
Bug #5441: Enemies can't push a player character when in critical strike stance
Bug #5451: Magic projectiles don't disappear with the caster
Bug #5452: Autowalk is being included in savegames
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 #5485: Intimidate doesn't increase disposition on marginal wins
Bug #5490: Hits to carried left slot aren't redistributed if there's no shield equipped
Bug #5499: Faction advance is available when requirements not met
Feature #390: 3rd person look "over the shoulder"
Feature #2386: Distant Statics in the form of Object Paging
Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher
Feature #5362: Show the soul gems' trapped soul in count dialog
Feature #5445: Handle NiLines
Feature #5457: Realistic diagonal movement
Task #5480: Drop Qt4 support
0.46.0
------
@ -188,8 +213,8 @@
Bug #5158: Objects without a name don't fallback to their ID
Bug #5159: NiMaterialColorController can only control the diffuse color
Bug #5161: Creature companions can't be activated when they are knocked down
Bug #5164: Faction owned items handling is incorrect
Bug #5163: UserData is not copied during node cloning
Bug #5164: Faction owned items handling is incorrect
Bug #5166: Scripts still should be executed after player's death
Bug #5167: Player can select and cast spells before magic menu is enabled
Bug #5168: Force1stPerson and Force3rdPerson commands are not really force view change
@ -231,6 +256,7 @@
Bug #5350: An attempt to launch magic bolt causes "AL error invalid value" error
Bug #5352: Light source items' duration is decremented while they aren't visible
Feature #1724: Handle AvoidNode
Feature #2159: "Graying out" exhausted dialogue topics
Feature #2229: Improve pathfinding AI
Feature #3025: Analogue gamepad movement controls
Feature #3442: Default values for fallbacks from ini file
@ -287,7 +313,7 @@
Feature #5147: Show spell magicka cost in spell buying window
Feature #5170: Editor: Land shape editing, land selection
Feature #5172: Editor: Delete instances/references with keypress in scene window
Feature #5193: Weapon sheathing
Feature #5193: Shields sheathing
Feature #5201: Editor: Show tool outline in scene view, when using editmodes
Feature #5219: Impelement TestCells console command
Feature #5224: Handle NiKeyframeController for NiTriShape

@ -1,11 +1,13 @@
& "${env:COMSPEC}" /c ActivateMSVC.bat "&&" set | ForEach-Object {
$name, $value = $_ -split '=', 2
Set-Content env:\"$name" $value
if ($_.Contains("=")) {
$name, $value = $_ -split '=', 2
Set-Content env:\"$name" $value
}
}
$MissingTools = $false
$tools = "cl", "link", "rc", "mt", "awooga"
$descriptions = "MSVC Compiler", "MSVC Linker", "MS Windows Resource Compiler", "MS Windows Manifest Tool", "A made up command"
$tools = "cl", "link", "rc", "mt"
$descriptions = "MSVC Compiler", "MSVC Linker", "MS Windows Resource Compiler", "MS Windows Manifest Tool"
for ($i = 0; $i -lt $tools.Length; $i++) {
$present = $true
try {

@ -8,30 +8,16 @@ GOOGLETEST_DIR="$(pwd)/googletest/build"
mkdir build
cd build
if [[ -z "${BUILD_OPENMW}" ]]; then export BUILD_OPENMW=ON; fi
if [[ -z "${BUILD_OPENMW_CS}" ]]; then export BUILD_OPENMW_CS=ON; fi
${ANALYZE} cmake \
-DCMAKE_C_COMPILER="${CC}" \
-DCMAKE_CXX_COMPILER="${CXX}" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DBUILD_OPENMW=${BUILD_OPENMW} \
-DBUILD_OPENCS=${BUILD_OPENMW_CS} \
-DBUILD_LAUNCHER=${BUILD_OPENMW_CS} \
-DBUILD_BSATOOL=${BUILD_OPENMW_CS} \
-DBUILD_ESMTOOL=${BUILD_OPENMW_CS} \
-DBUILD_MWINIIMPORTER=${BUILD_OPENMW_CS} \
-DBUILD_ESSIMPORTER=${BUILD_OPENMW_CS} \
-DBUILD_WIZARD=${BUILD_OPENMW_CS} \
-DBUILD_NIFTEST=${BUILD_OPENMW_CS} \
-DBUILD_UNITTESTS=1 \
-DUSE_SYSTEM_TINYXML=1 \
-DDESIRED_QT_VERSION=5 \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBINDIR=/usr/games \
-DCMAKE_BUILD_TYPE="None" \
-DBUILD_UNITTESTS=TRUE \
-DUSE_SYSTEM_TINYXML=TRUE \
-DCMAKE_INSTALL_PREFIX="/usr" \
-DBINDIR="/usr/games" \
-DCMAKE_BUILD_TYPE="DEBUG" \
-DGTEST_ROOT="${GOOGLETEST_DIR}" \
-DGMOCK_ROOT="${GOOGLETEST_DIR}" \
..

@ -13,7 +13,16 @@ MISSINGTOOLS=0
command -v 7z >/dev/null 2>&1 || { echo "Error: 7z (7zip) is not on the path."; MISSINGTOOLS=1; }
command -v cmake >/dev/null 2>&1 || { echo "Error: cmake (CMake) is not on the path."; MISSINGTOOLS=1; }
command -v python >/dev/null 2>&1 || { echo "Warning: Python is not on the path, automatic Qt installation impossible."; }
MISSINGPYTHON=0
if ! command -v python >/dev/null 2>&1; then
echo "Warning: Python is not on the path, automatic Qt installation impossible."
MISSINGPYTHON=1
elif ! python --version >/dev/null 2>&1; then
echo "Warning: Python is (probably) fake stub Python that comes bundled with newer versions of Windows, automatic Qt installation impossible."
echo "If you think you have Python installed, try changing the order of your PATH environment variable in Advanced System Settings."
MISSINGPYTHON=1
fi
if [ $MISSINGTOOLS -ne 0 ]; then
wrappedExit 1
@ -152,7 +161,7 @@ Options:
Build unit tests / Google test
-u
Configure for unity builds.
-v <2013/2015/2017/2019>
-v <2017/2019>
Choose the Visual Studio version to use.
-n
Produce NMake makefiles instead of a Visual Studio solution. Cannout be used with -N.
@ -204,8 +213,8 @@ run_cmd() {
shift
if [ -z $VERBOSE ]; then
eval $CMD $@ > output.log 2>&1
RET=$?
RET=0
eval $CMD $@ > output.log 2>&1 || RET=$?
if [ $RET -ne 0 ]; then
if [ -z $APPVEYOR ]; then
@ -221,8 +230,9 @@ run_cmd() {
return $RET
else
eval $CMD $@
return $?
RET=0
eval $CMD $@ || RET=$?
return $RET
fi
}
@ -247,15 +257,16 @@ download() {
printf " Downloading $FILE... "
if [ -z $VERBOSE ]; then
curl --silent --retry 10 -kLy 5 -o $FILE $URL
RET=$?
RET=0
curl --silent --retry 10 -kLy 5 -o $FILE $URL || RET=$?
else
curl --retry 10 -kLy 5 -o $FILE $URL
RET=$?
RET=0
curl --retry 10 -kLy 5 -o $FILE $URL || RET=$?
fi
if [ $RET -ne 0 ]; then
echo "Failed!"
wrappedExit $RET
else
echo "Done."
fi
@ -337,21 +348,13 @@ case $VS_VERSION in
;;
14|14.0|2015 )
GENERATOR="Visual Studio 14 2015"
TOOLSET="vc140"
MSVC_REAL_VER="14"
MSVC_VER="14.0"
MSVC_YEAR="2015"
MSVC_REAL_YEAR="2015"
MSVC_DISPLAY_YEAR="2015"
BOOST_VER="1.67.0"
BOOST_VER_URL="1_67_0"
BOOST_VER_SDK="106700"
echo "Visual Studio 2015 is no longer supported"
wrappedExit 1
;;
12|12.0|2013 )
echo "Visual Studio 2013 is no longer supported"
exit 1
wrappedExit 1
;;
esac
@ -494,18 +497,6 @@ if [ -z $SKIP_DOWNLOAD ]; then
"OSG-3.6.5-msvc${MSVC_REAL_YEAR}-win${BITS}-sym.7z"
fi
# Qt
if [ -z $APPVEYOR ]; then
if [ "${MSVC_REAL_YEAR}" = "2015" ] && [ "${BITS}" = "32" ]; then
echo "Qt no longer provides MSVC2015 Win32 packages, switch to 64-bit or a newer Visual Studio. Sorry."
exit 1
fi
download "AQt installer" \
"https://files.pythonhosted.org/packages/f3/bb/aee972f08deecca31bfc46b5aedfad1ce6c7f3aaf1288d685e4a914b53ac/aqtinstall-0.8-py2.py3-none-any.whl" \
"aqtinstall-0.8-py2.py3-none-any.whl"
fi
# SDL2
download "SDL 2.0.12" \
"https://www.libsdl.org/release/SDL2-devel-2.0.12-VC.zip" \
@ -513,11 +504,11 @@ if [ -z $SKIP_DOWNLOAD ]; then
# Google test and mock
if [ ! -z $TEST_FRAMEWORK ]; then
echo "Google test 1.8.1..."
echo "Google test 1.10.0..."
if [ -d googletest ]; then
printf " Google test exists, skipping."
else
git clone -b release-1.8.1 https://github.com/google/googletest.git
git clone -b release-1.10.0 https://github.com/google/googletest.git
fi
fi
fi
@ -595,14 +586,8 @@ fi
# Appveyor has all the boost we need already
BOOST_SDK="c:/Libraries/boost_${BOOST_VER_URL}"
if [ $MSVC_REAL_VER -ge 15 ]; then
LIB_SUFFIX="1"
else
LIB_SUFFIX="0"
fi
add_cmake_opts -DBOOST_ROOT="$BOOST_SDK" \
-DBOOST_LIBRARYDIR="${BOOST_SDK}/lib${BITS}-msvc-${MSVC_VER}.${LIB_SUFFIX}"
-DBOOST_LIBRARYDIR="${BOOST_SDK}/lib${BITS}-msvc-${MSVC_VER}.1"
add_cmake_opts -DBoost_COMPILER="-${TOOLSET}"
echo Done.
@ -740,28 +725,40 @@ fi
fi
if [ -z $APPVEYOR ]; then
cd $DEPS_INSTALL
QT_SDK="$(real_pwd)/Qt/5.15.0/msvc${MSVC_REAL_YEAR}${SUFFIX}"
if [ -d 'Qt/5.15.0' ]; then
qt_version="5.15.0"
if [ "win${BITS}_msvc${MSVC_REAL_YEAR}${SUFFIX}" == "win64_msvc2017_64" ]; then
echo "This combination of options is known not to work. Falling back to Qt 5.14.2."
qt_version="5.14.2"
fi
QT_SDK="$(real_pwd)/Qt/${qt_version}/msvc${MSVC_REAL_YEAR}${SUFFIX}"
if [ -d "Qt/${qt_version}" ]; then
printf "Exists. "
elif [ -z $SKIP_EXTRACT ]; then
if [ $MISSINGPYTHON -ne 0 ]; then
echo "Can't be automatically installed without Python."
wrappedExit 1
fi
pushd "$DEPS" > /dev/null
if ! [ -d 'aqt-venv' ]; then
echo " Creating Virtualenv for aqt..."
eval python -m venv aqt-venv $STRIP
run_cmd python -m venv aqt-venv
fi
if [ -d 'aqt-venv/bin' ]; then
VENV_BIN_DIR='bin'
elif [ -d 'aqt-venv/Scripts' ]; then
VENV_BIN_DIR='Scripts'
else
echo "Error: Failed to create virtualenv."
exit 1
echo "Error: Failed to create virtualenv in expected location."
wrappedExit 1
fi
if ! [ -e "aqt-venv/${VENV_BIN_DIR}/aqt" ]; then
echo " Installing aqt wheel into virtualenv..."
eval "aqt-venv/${VENV_BIN_DIR}/pip" install aqtinstall-0.8-py2.py3-none-any.whl $STRIP
run_cmd "aqt-venv/${VENV_BIN_DIR}/pip" install aqtinstall==0.9.2
fi
popd > /dev/null
@ -770,7 +767,7 @@ fi
mkdir Qt
cd Qt
eval "${DEPS}/aqt-venv/${VENV_BIN_DIR}/aqt" install 5.15.0 windows desktop "win${BITS}_msvc${MSVC_REAL_YEAR}${SUFFIX}" $STRIP
run_cmd "${DEPS}/aqt-venv/${VENV_BIN_DIR}/aqt" install $qt_version windows desktop "win${BITS}_msvc${MSVC_REAL_YEAR}${SUFFIX}"
printf " Cleaning up extraneous data... "
rm -rf Qt/{aqtinstall.log,Tools}
@ -779,8 +776,7 @@ fi
fi
cd $QT_SDK
add_cmake_opts -DDESIRED_QT_VERSION=5 \
-DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \
add_cmake_opts -DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \
-DCMAKE_PREFIX_PATH="$QT_SDK"
if [ $CONFIGURATION == "Debug" ]; then
SUFFIX="d"
@ -792,8 +788,7 @@ fi
echo Done.
else
QT_SDK="C:/Qt/5.13/msvc2017${SUFFIX}"
add_cmake_opts -DDESIRED_QT_VERSION=5 \
-DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \
add_cmake_opts -DQT_QMAKE_EXECUTABLE="${QT_SDK}/bin/qmake.exe" \
-DCMAKE_PREFIX_PATH="$QT_SDK"
if [ $CONFIGURATION == "Debug" ]; then
SUFFIX="d"
@ -825,7 +820,7 @@ cd $DEPS
echo
# Google Test and Google Mock
if [ ! -z $TEST_FRAMEWORK ]; then
printf "Google test 1.8.1 ..."
printf "Google test 1.10.0 ..."
cd googletest
if [ ! -d build ]; then
@ -943,30 +938,18 @@ fi
echo
#fi
if ! [ -z $ACTIVATE_MSVC ]; then
if [ -n "$ACTIVATE_MSVC" ]; then
echo -n "- Activating MSVC in the current shell... "
command -v vswhere >/dev/null 2>&1 || { echo "Error: vswhere is not on the path."; wrappedExit 1; }
MSVC_INSTALLATION_PATH=$(vswhere -legacy -version "[$MSVC_VER,$(awk "BEGIN { print $MSVC_REAL_VER + 1; exit }"))" -property installationPath)
if [ $MSVC_REAL_VER -ge 15 ]; then
echo "@\"${MSVC_INSTALLATION_PATH}\Common7\Tools\VsDevCmd.bat\" -no_logo -arch=$([ $BITS -eq 64 ] && echo "amd64" || echo "x86") -host_arch=$([ $(uname -m) == 'x86_64' ] && echo "amd64" || echo "x86")" > ActivateMSVC.bat
else
if [ $(uname -m) == 'x86_64' ]; then
if [ $BITS -eq 64 ]; then
compiler=amd64
else
compiler=amd64_x86
fi
else
if [ $BITS -eq 64 ]; then
compiler=x86_amd64
else
compiler=x86
fi
fi
echo "@\"${MSVC_INSTALLATION_PATH}\VC\vcvarsall.bat\" $compiler" > ActivateMSVC.bat
MSVC_INSTALLATION_PATH=$(vswhere -legacy -products '*' -version "[$MSVC_VER,$(awk "BEGIN { print $MSVC_REAL_VER + 1; exit }"))" -property installationPath)
if [ -z "$MSVC_INSTALLATION_PATH" ]; then
echo "vswhere was unable to find MSVC $MSVC_DISPLAY_YEAR"
wrappedExit 1
fi
echo "@\"${MSVC_INSTALLATION_PATH}\Common7\Tools\VsDevCmd.bat\" -no_logo -arch=$([ $BITS -eq 64 ] && echo "amd64" || echo "x86") -host_arch=$([ $(uname -m) == 'x86_64' ] && echo "amd64" || echo "x86")" > ActivateMSVC.bat
cp "../CI/activate_msvc.sh" .
sed -i "s/\$MSVC_DISPLAY_YEAR/$MSVC_DISPLAY_YEAR/g" activate_msvc.sh
source ./activate_msvc.sh
@ -983,39 +966,47 @@ if [ -z $VERBOSE ]; then
else
echo "- cmake .. $CMAKE_OPTS"
fi
run_cmd cmake .. $CMAKE_OPTS
RET=$?
RET=0
run_cmd cmake .. $CMAKE_OPTS || RET=$?
if [ -z $VERBOSE ]; then
if [ $RET -eq 0 ]; then
echo Done.
if [ -n $ACTIVATE_MSVC ]; then
echo
echo "Note: you must manually activate MSVC for the shell in which you want to do the build."
echo
echo "Some scripts have been created in the build directory to do so in an existing shell."
echo "Bash: source activate_msvc.sh"
echo "CMD: ActivateMSVC.bat"
echo "PowerShell: ActivateMSVC.ps1"
echo
echo "You may find options to launch a Development/Native Tools/Cross Tools shell in your start menu or Visual Studio."
echo
if [ $(uname -m) == 'x86_64' ]; then
if [ $BITS -eq 64 ]; then
inheritEnvironments=msvc_x64_x64
else
inheritEnvironments=msvc_x64
fi
else
if [ $BITS -eq 64 ]; then
inheritEnvironments=msvc_x86_x64
else
inheritEnvironments=msvc_x86
fi
fi
echo "In Visual Studio 15.3 (2017 Update 3) or later, try setting '\"inheritEnvironments\": [ \"$inheritEnvironments\" ]' in CMakeSettings.json to build in the IDE."
fi
else
echo Failed.
fi
fi
if [ $RET -ne 0 ]; then
wrappedExit $RET
fi
echo "Script completed successfully."
echo "You now have an OpenMW build system at $(unixPathAsWindows "$(pwd)")"
if [ -n "$ACTIVATE_MSVC" ]; then
echo
echo "Note: you must manually activate MSVC for the shell in which you want to do the build."
echo
echo "Some scripts have been created in the build directory to do so in an existing shell."
echo "Bash: source activate_msvc.sh"
echo "CMD: ActivateMSVC.bat"
echo "PowerShell: ActivateMSVC.ps1"
echo
echo "You may find options to launch a Development/Native Tools/Cross Tools shell in your start menu or Visual Studio."
echo
if [ $(uname -m) == 'x86_64' ]; then
if [ $BITS -eq 64 ]; then
inheritEnvironments=msvc_x64_x64
else
inheritEnvironments=msvc_x64
fi
else
if [ $BITS -eq 64 ]; then
inheritEnvironments=msvc_x86_x64
else
inheritEnvironments=msvc_x86
fi
fi
echo "In Visual Studio 15.3 (2017 Update 3) or later, try setting '\"inheritEnvironments\": [ \"$inheritEnvironments\" ]' in CMakeSettings.json to build in the IDE."
fi
wrappedExit $RET

@ -17,7 +17,6 @@ cmake \
-D CMAKE_OSX_SYSROOT="macosx10.14" \
-D CMAKE_BUILD_TYPE=Release \
-D OPENMW_OSX_DEPLOYMENT=TRUE \
-D DESIRED_QT_VERSION=5 \
-D BUILD_ESMTOOL=FALSE \
-G"Unix Makefiles" \
..

@ -20,11 +20,6 @@ else()
set(USE_QT TRUE)
endif()
if (USE_QT)
set(DESIRED_QT_VERSION 4 CACHE STRING "The QT version OpenMW should use (4 or 5)")
set_property(CACHE DESIRED_QT_VERSION PROPERTY STRINGS 4 5)
endif()
# set the minimum required version across the board
cmake_minimum_required(VERSION 3.1.0)
@ -154,18 +149,12 @@ endif()
find_package(OpenGL REQUIRED)
if (USE_QT)
message(STATUS "Using Qt${DESIRED_QT_VERSION}")
if (DESIRED_QT_VERSION MATCHES 4)
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork QtOpenGL)
else()
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(Qt5Core 5.12 REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5OpenGL REQUIRED)
# Instruct CMake to run moc automatically when needed.
#set(CMAKE_AUTOMOC ON)
endif()
endif()
# Sound setup
@ -295,20 +284,12 @@ if(OSG_STATIC)
list(APPEND OPENSCENEGRAPH_LIBRARIES ${OSGPlugins_LIBRARIES})
endif()
if(QT_STATIC)
if(WIN32)
if(DESIRED_QT_VERSION MATCHES 4)
# QtCore needs WSAAsyncSelect from Ws2_32.lib
set(QT_QTCORE_LIBRARY ${QT_QTCORE_LIBRARY} Ws2_32.lib)
message("QT_QTCORE_LIBRARY: ${QT_QTCORE_LIBRARY}")
endif()
endif()
endif()
set(BOOST_COMPONENTS system filesystem program_options iostreams)
if(WIN32)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale zlib)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
if(MSVC)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} zlib)
endif(MSVC)
endif(WIN32)
IF(BOOST_STATIC)
@ -524,10 +505,8 @@ if(WIN32)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Debug/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(FILES "${OpenMW_BINARY_DIR}/Release/gamecontrollerdb.txt" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
IF(DESIRED_QT_VERSION MATCHES 5)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/platforms" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/platforms" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
ENDIF()
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/platforms" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/platforms" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Debug/resources" DESTINATION "." CONFIGURATIONS Debug)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/Release/resources" DESTINATION "." CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel)
@ -817,7 +796,7 @@ if (WIN32)
endif()
# Apple bundling
if (OPENMW_OSX_DEPLOYMENT AND APPLE AND DESIRED_QT_VERSION MATCHES 5)
if (OPENMW_OSX_DEPLOYMENT AND APPLE)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.13 AND CMAKE_VERSION VERSION_LESS 3.13.4)
message(FATAL_ERROR "macOS packaging is broken in early CMake 3.13 releases, see https://gitlab.com/OpenMW/openmw/issues/4767. Please use at least 3.13.4 or an older version like 3.12.4")
endif ()

@ -183,19 +183,19 @@ int list(Bsa::BSAFile& bsa, Arguments& info)
{
// List all files
const Bsa::BSAFile::FileList &files = bsa.getList();
for(unsigned int i=0; i<files.size(); i++)
for (const auto& file : files)
{
if(info.longformat)
{
// Long format
std::ios::fmtflags f(std::cout.flags());
std::cout << std::setw(50) << std::left << files[i].name;
std::cout << std::setw(8) << std::left << std::dec << files[i].fileSize;
std::cout << "@ 0x" << std::hex << files[i].offset << std::endl;
std::cout << std::setw(50) << std::left << file.name;
std::cout << std::setw(8) << std::left << std::dec << file.fileSize;
std::cout << "@ 0x" << std::hex << file.offset << std::endl;
std::cout.flags(f);
}
else
std::cout << files[i].name << std::endl;
std::cout << file.name << std::endl;
}
return 0;
@ -252,14 +252,9 @@ int extract(Bsa::BSAFile& bsa, Arguments& info)
int extractAll(Bsa::BSAFile& bsa, Arguments& info)
{
// Get the list of files present in the archive
Bsa::BSAFile::FileList list = bsa.getList();
// Iter on the list
for(Bsa::BSAFile::FileList::iterator it = list.begin(); it != list.end(); ++it) {
const char* archivePath = it->name;
std::string extractPath (archivePath);
for (const auto &file : bsa.getList())
{
std::string extractPath(file.name);
replaceAll(extractPath, "\\", "/");
// Get the target path (the path the file will be extracted to)
@ -278,7 +273,7 @@ int extractAll(Bsa::BSAFile& bsa, Arguments& info)
// Get a stream for the file to extract
// (inefficient because getFile iter on the list again)
Files::IStreamPtr data = bsa.getFile(archivePath);
Files::IStreamPtr data = bsa.getFile(file.name);
bfs::ofstream out(target, std::ios::binary);
// Write the file to disk

@ -87,7 +87,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
("plain,p", "Print contents of dialogs, books and scripts. "
"(skipped by default)"
"Only affects dump mode.")
("quiet,q", "Supress all record information. Useful for speed tests.")
("quiet,q", "Suppress all record information. Useful for speed tests.")
("loadcells,C", "Browse through contents of all cells.")
( "encoding,e", bpo::value<std::string>(&(info.encoding))->
@ -352,12 +352,12 @@ int load(Arguments& info)
std::cout << "Author: " << esm.getAuthor() << std::endl
<< "Description: " << esm.getDesc() << std::endl
<< "File format version: " << esm.getFVer() << std::endl;
std::vector<ESM::Header::MasterData> m = esm.getGameFiles();
if (!m.empty())
std::vector<ESM::Header::MasterData> masterData = esm.getGameFiles();
if (!masterData.empty())
{
std::cout << "Masters:" << std::endl;
for(unsigned int i=0;i<m.size();i++)
std::cout << " " << m[i].name << ", " << m[i].size << " bytes" << std::endl;
for(const auto& master : masterData)
std::cout << " " << master.name << ", " << master.size << " bytes" << std::endl;
}
}
@ -369,7 +369,7 @@ int load(Arguments& info)
esm.getRecHeader(flags);
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
if (record == 0)
if (record == nullptr)
{
if (std::find(skipped.begin(), skipped.end(), n.intval) == skipped.end())
{
@ -538,8 +538,8 @@ int comp(Arguments& info)
Arguments fileOne;
Arguments fileTwo;
fileOne.raw_given = 0;
fileTwo.raw_given = 0;
fileOne.raw_given = false;
fileTwo.raw_given = false;
fileOne.mode = "clone";
fileTwo.mode = "clone";

@ -779,7 +779,7 @@ std::string creatureListFlags(int flags)
std::string lightFlags(int flags)
{
std::string properties = "";
std::string properties;
if (flags == 0) properties += "[None] ";
if (flags & ESM::Light::Dynamic) properties += "Dynamic ";
if (flags & ESM::Light::Fire) properties += "Fire ";

@ -9,7 +9,7 @@
namespace
{
void printAIPackage(ESM::AIPackage p)
void printAIPackage(const ESM::AIPackage& p)
{
std::cout << " AI Type: " << aiTypeLabel(p.mType)
<< " (" << Misc::StringUtils::format("0x%08X", p.mType) << ")" << std::endl;
@ -53,7 +53,7 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " Cell Name: " << p.mCellName << std::endl;
}
std::string ruleString(ESM::DialInfo::SelectStruct ss)
std::string ruleString(const ESM::DialInfo::SelectStruct& ss)
{
std::string rule = ss.mSelectRule;
@ -126,7 +126,7 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
return result;
}
void printEffectList(ESM::EffectList effects)
void printEffectList(const ESM::EffectList& effects)
{
int i = 0;
for (const ESM::ENAMstruct& effect : effects.mList)
@ -174,7 +174,7 @@ namespace EsmTool {
RecordBase *
RecordBase::create(ESM::NAME type)
{
RecordBase *record = 0;
RecordBase *record = nullptr;
switch (type.intval) {
case ESM::REC_ACTI:
@ -388,7 +388,7 @@ RecordBase::create(ESM::NAME type)
break;
}
default:
record = 0;
record = nullptr;
}
if (record) {
record->mType = type;
@ -728,10 +728,9 @@ void Record<ESM::Faction>::print()
<< " (" << mData.mData.mAttribute[0] << ")" << std::endl;
std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1])
<< " (" << mData.mData.mAttribute[1] << ")" << std::endl;
for (int i = 0; i < 7; i++)
if (mData.mData.mSkills[i] != -1)
std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i])
<< " (" << mData.mData.mSkills[i] << ")" << std::endl;
for (int skill : mData.mData.mSkills)
if (skill != -1)
std::cout << " Skill: " << skillLabel(skill) << " (" << skill << ")" << std::endl;
for (int i = 0; i != 10; i++)
if (!mData.mRanks[i].empty())
{
@ -741,9 +740,9 @@ void Record<ESM::Faction>::print()
std::cout << " Attribute2 Requirement: "
<< mData.mData.mRankData[i].mAttribute2 << std::endl;
std::cout << " One Skill at Level: "
<< mData.mData.mRankData[i].mSkill1 << std::endl;
<< mData.mData.mRankData[i].mPrimarySkill << std::endl;
std::cout << " Two Skills at Level: "
<< mData.mData.mRankData[i].mSkill2 << std::endl;
<< mData.mData.mRankData[i].mFavouredSkill << std::endl;
std::cout << " Faction Reaction: "
<< mData.mData.mRankData[i].mFactReaction << std::endl;
}

@ -74,7 +74,7 @@ namespace EsmTool
: mIsDeleted(false)
{}
std::string getId() const {
std::string getId() const override {
return mData.mId;
}
@ -82,15 +82,15 @@ namespace EsmTool
return mData;
}
void save(ESM::ESMWriter &esm) {
void save(ESM::ESMWriter &esm) override {
mData.save(esm, mIsDeleted);
}
void load(ESM::ESMReader &esm) {
void load(ESM::ESMReader &esm) override {
mData.load(esm, mIsDeleted);
}
void print();
void print() override;
};
template<> std::string Record<ESM::Cell>::getId() const;

@ -52,9 +52,7 @@ namespace
// a dynamically created record e.g. player-enchanted weapon
std::string index = indexedRefId.substr(indexedRefId.size()-8);
if(index.find_first_not_of("0123456789ABCDEF") == std::string::npos )
return true;
return false;
return index.find_first_not_of("0123456789ABCDEF") == std::string::npos;
}
void splitIndexedRefId(const std::string& indexedRefId, int& refIndex, std::string& refId)
@ -139,12 +137,12 @@ namespace ESSImport
image2->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
memcpy(image2->data(), &data[0], data.size());
for (std::set<std::pair<int, int> >::const_iterator it = mContext->mExploredCells.begin(); it != mContext->mExploredCells.end(); ++it)
for (const auto & exploredCell : mContext->mExploredCells)
{
if (it->first > mContext->mGlobalMapState.mBounds.mMaxX
|| it->first < mContext->mGlobalMapState.mBounds.mMinX
|| it->second > mContext->mGlobalMapState.mBounds.mMaxY
|| it->second < mContext->mGlobalMapState.mBounds.mMinY)
if (exploredCell.first > mContext->mGlobalMapState.mBounds.mMaxX
|| exploredCell.first < mContext->mGlobalMapState.mBounds.mMinX
|| exploredCell.second > mContext->mGlobalMapState.mBounds.mMaxY
|| exploredCell.second < mContext->mGlobalMapState.mBounds.mMinY)
{
// out of bounds, I think this could happen, since the original engine had a fixed-size map
continue;
@ -152,12 +150,12 @@ namespace ESSImport
int imageLeftSrc = mGlobalMapImage->s()/2;
int imageTopSrc = mGlobalMapImage->t()/2;
imageLeftSrc += it->first * cellSize;
imageTopSrc -= it->second * cellSize;
imageLeftSrc += exploredCell.first * cellSize;
imageTopSrc -= exploredCell.second * cellSize;
int imageLeftDst = width/2;
int imageTopDst = height/2;
imageLeftDst += it->first * cellSize;
imageTopDst -= it->second * cellSize;
imageLeftDst += exploredCell.first * cellSize;
imageTopDst -= exploredCell.second * cellSize;
for (int x=0; x<cellSize; ++x)
for (int y=0; y<cellSize; ++y)
{
@ -329,9 +327,8 @@ namespace ESSImport
csta.mWaterLevel = esmcell.mWater;
csta.save(esm);
for (std::vector<CellRef>::const_iterator refIt = cell.mRefs.begin(); refIt != cell.mRefs.end(); ++refIt)
for (const auto & cellref : cell.mRefs)
{
const CellRef& cellref = *refIt;
ESM::CellRef out (cellref);
// TODO: use mContext->mCreatures/mNpcs
@ -437,16 +434,16 @@ namespace ESSImport
void ConvertCell::write(ESM::ESMWriter &esm)
{
for (std::map<std::string, Cell>::const_iterator it = mIntCells.begin(); it != mIntCells.end(); ++it)
writeCell(it->second, esm);
for (const auto & cell : mIntCells)
writeCell(cell.second, esm);
for (std::map<std::pair<int, int>, Cell>::const_iterator it = mExtCells.begin(); it != mExtCells.end(); ++it)
writeCell(it->second, esm);
for (const auto & cell : mExtCells)
writeCell(cell.second, esm);
for (std::vector<ESM::CustomMarker>::const_iterator it = mMarkers.begin(); it != mMarkers.end(); ++it)
for (const auto & marker : mMarkers)
{
esm.startRecord(ESM::REC_MARK);
it->save(esm);
marker.save(esm);
esm.endRecord(ESM::REC_MARK);
}
}

@ -79,9 +79,9 @@ template <typename T>
class DefaultConverter : public Converter
{
public:
virtual int getStage() { return 0; }
int getStage() override { return 0; }
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
T record;
bool isDeleted = false;
@ -90,7 +90,7 @@ public:
mRecords[record.mId] = record;
}
virtual void write(ESM::ESMWriter& esm)
void write(ESM::ESMWriter& esm) override
{
for (typename std::map<std::string, T>::const_iterator it = mRecords.begin(); it != mRecords.end(); ++it)
{
@ -107,7 +107,7 @@ protected:
class ConvertNPC : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
ESM::NPC npc;
bool isDeleted = false;
@ -127,8 +127,8 @@ public:
ESM::SpellState::SpellParams empty;
// FIXME: player start spells and birthsign spells aren't listed here,
// need to fix openmw to account for this
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it)
mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells[*it] = empty;
for (const auto & spell : npc.mSpells.mList)
mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells[spell] = empty;
// Clear the list now that we've written it, this prevents issues cropping up with
// ensureCustomData() in OpenMW tripping over no longer existing spells, where an error would be fatal.
@ -144,7 +144,7 @@ public:
class ConvertCREA : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
// See comment in ConvertNPC
ESM::Creature creature;
@ -162,7 +162,7 @@ public:
class ConvertGlobal : public DefaultConverter<ESM::Global>
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
ESM::Global global;
bool isDeleted = false;
@ -183,7 +183,7 @@ public:
class ConvertClass : public DefaultConverter<ESM::Class>
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
ESM::Class class_;
bool isDeleted = false;
@ -199,7 +199,7 @@ public:
class ConvertBook : public DefaultConverter<ESM::Book>
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
ESM::Book book;
bool isDeleted = false;
@ -215,7 +215,7 @@ public:
class ConvertNPCC : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
std::string id = esm.getHNString("NAME");
NPCC npcc;
@ -235,7 +235,7 @@ public:
class ConvertREFR : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
REFR refr;
refr.load(esm);
@ -261,7 +261,7 @@ public:
}
}
}
virtual void write(ESM::ESMWriter& esm)
void write(ESM::ESMWriter& esm) override
{
esm.startRecord(ESM::REC_ASPL);
esm.writeHNString("ID__", mSelectedSpell);
@ -280,14 +280,14 @@ public:
mLevitationEnabled(true)
{}
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
PCDT pcdt;
pcdt.load(esm);
convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, mTeleportingEnabled, mLevitationEnabled, mContext->mControlsState);
}
virtual void write(ESM::ESMWriter &esm)
void write(ESM::ESMWriter &esm) override
{
esm.startRecord(ESM::REC_ENAB);
esm.writeHNT("TELE", mTeleportingEnabled);
@ -306,7 +306,7 @@ private:
class ConvertCNTC : public Converter
{
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
std::string id = esm.getHNString("NAME");
CNTC cntc;
@ -318,7 +318,7 @@ class ConvertCNTC : public Converter
class ConvertCREC : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
std::string id = esm.getHNString("NAME");
CREC crec;
@ -330,8 +330,8 @@ public:
class ConvertFMAP : public Converter
{
public:
virtual void read(ESM::ESMReader &esm);
virtual void write(ESM::ESMWriter &esm);
void read(ESM::ESMReader &esm) override;
void write(ESM::ESMWriter &esm) override;
private:
osg::ref_ptr<osg::Image> mGlobalMapImage;
@ -340,8 +340,8 @@ private:
class ConvertCell : public Converter
{
public:
virtual void read(ESM::ESMReader& esm);
virtual void write(ESM::ESMWriter& esm);
void read(ESM::ESMReader& esm) override;
void write(ESM::ESMWriter& esm) override;
private:
struct Cell
@ -362,7 +362,7 @@ private:
class ConvertKLST : public Converter
{
public:
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
KLST klst;
klst.load(esm);
@ -371,7 +371,7 @@ public:
mContext->mPlayer.mObject.mNpcStats.mWerewolfKills = klst.mWerewolfKills;
}
virtual void write(ESM::ESMWriter &esm)
void write(ESM::ESMWriter &esm) override
{
esm.startRecord(ESM::REC_DCOU);
for (std::map<std::string, int>::const_iterator it = mKillCounter.begin(); it != mKillCounter.end(); ++it)
@ -389,7 +389,7 @@ private:
class ConvertFACT : public Converter
{
public:
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
ESM::Faction faction;
bool isDeleted = false;
@ -409,7 +409,7 @@ public:
class ConvertSTLN : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
std::string itemid = esm.getHNString("NAME");
Misc::StringUtils::lowerCaseInPlace(itemid);
@ -428,15 +428,15 @@ public:
}
}
}
virtual void write(ESM::ESMWriter &esm)
void write(ESM::ESMWriter &esm) override
{
ESM::StolenItems items;
for (std::map<std::string, std::set<Owner> >::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
{
std::map<std::pair<std::string, bool>, int> owners;
for (std::set<Owner>::const_iterator ownerIt = it->second.begin(); ownerIt != it->second.end(); ++ownerIt)
for (const auto & ownerIt : it->second)
{
owners.insert(std::make_pair(std::make_pair(ownerIt->first, ownerIt->second)
owners.insert(std::make_pair(std::make_pair(ownerIt.first, ownerIt.second)
// Since OpenMW doesn't suffer from the owner contamination bug,
// it needs a count argument. But for legacy savegames, we don't know
// this count, so must assume all items of that ID are stolen,
@ -467,7 +467,7 @@ private:
class ConvertINFO : public Converter
{
public:
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
INFO info;
info.load(esm);
@ -477,7 +477,7 @@ public:
class ConvertDIAL : public Converter
{
public:
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
std::string id = esm.getHNString("NAME");
DIAL dial;
@ -485,7 +485,7 @@ public:
if (dial.mIndex > 0)
mDials[id] = dial;
}
virtual void write(ESM::ESMWriter &esm)
void write(ESM::ESMWriter &esm) override
{
for (std::map<std::string, DIAL>::const_iterator it = mDials.begin(); it != mDials.end(); ++it)
{
@ -505,7 +505,7 @@ private:
class ConvertQUES : public Converter
{
public:
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
std::string id = esm.getHNString("NAME");
QUES quest;
@ -516,7 +516,7 @@ public:
class ConvertJOUR : public Converter
{
public:
virtual void read(ESM::ESMReader& esm)
void read(ESM::ESMReader& esm) override
{
JOUR journal;
journal.load(esm);
@ -531,7 +531,7 @@ public:
{
}
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
mGame.load(esm);
mHasGame = true;
@ -551,7 +551,7 @@ public:
}
}
virtual void write(ESM::ESMWriter &esm)
void write(ESM::ESMWriter &esm) override
{
if (!mHasGame)
return;
@ -578,7 +578,7 @@ private:
class ConvertSCPT : public Converter
{
public:
virtual void read(ESM::ESMReader &esm)
void read(ESM::ESMReader &esm) override
{
SCPT script;
script.load(esm);
@ -586,12 +586,12 @@ public:
convertSCPT(script, out);
mScripts.push_back(out);
}
virtual void write(ESM::ESMWriter &esm)
void write(ESM::ESMWriter &esm) override
{
for (std::vector<ESM::GlobalScript>::const_iterator it = mScripts.begin(); it != mScripts.end(); ++it)
for (const auto & script : mScripts)
{
esm.startRecord(ESM::REC_GSCR);
it->save(esm);
script.save(esm);
esm.endRecord(ESM::REC_GSCR);
}
}
@ -603,9 +603,9 @@ private:
class ConvertPROJ : public Converter
{
public:
virtual int getStage() override { return 2; }
virtual void read(ESM::ESMReader& esm) override;
virtual void write(ESM::ESMWriter& esm) override;
int getStage() override { return 2; }
void read(ESM::ESMReader& esm) override;
void write(ESM::ESMWriter& esm) override;
private:
void convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam);
PROJ mProj;
@ -614,8 +614,8 @@ private:
class ConvertSPLM : public Converter
{
public:
virtual void read(ESM::ESMReader& esm) override;
virtual void write(ESM::ESMWriter& esm) override;
void read(ESM::ESMReader& esm) override;
void write(ESM::ESMWriter& esm) override;
private:
SPLM mSPLM;
};

@ -9,21 +9,20 @@ namespace ESSImport
void convertInventory(const Inventory &inventory, ESM::InventoryState &state)
{
int index = 0;
for (std::vector<Inventory::InventoryItem>::const_iterator it = inventory.mItems.begin();
it != inventory.mItems.end(); ++it)
for (const auto & item : inventory.mItems)
{
ESM::ObjectState objstate;
objstate.blank();
objstate.mRef = *it;
objstate.mRef.mRefID = Misc::StringUtils::lowerCase(it->mId);
objstate.mCount = std::abs(it->mCount); // restocking items have negative count in the savefile
objstate.mRef = item;
objstate.mRef.mRefID = Misc::StringUtils::lowerCase(item.mId);
objstate.mCount = std::abs(item.mCount); // restocking items have negative count in the savefile
// openmw handles them differently, so no need to set any flags
state.mItems.push_back(objstate);
if (it->mRelativeEquipmentSlot != -1)
if (item.mRelativeEquipmentSlot != -1)
// Note we should really write the absolute slot here, which we do not know about
// Not a big deal, OpenMW will auto-correct to a valid slot, the only problem is when
// an item could be equipped in two different slots (e.g. equipped two rings)
state.mEquipmentSlots[index] = it->mRelativeEquipmentSlot;
state.mEquipmentSlots[index] = item.mRelativeEquipmentSlot;
++index;
}
}

@ -10,13 +10,13 @@ namespace ESSImport
{
out.mBirthsign = pcdt.mBirthsign;
out.mObject.mNpcStats.mBounty = pcdt.mBounty;
for (std::vector<PCDT::FNAM>::const_iterator it = pcdt.mFactions.begin(); it != pcdt.mFactions.end(); ++it)
for (const auto & essFaction : pcdt.mFactions)
{
ESM::NpcStats::Faction faction;
faction.mExpelled = (it->mFlags & 0x2) != 0;
faction.mRank = it->mRank;
faction.mReputation = it->mReputation;
out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(it->mFactionName.toString())] = faction;
faction.mExpelled = (essFaction.mFlags & 0x2) != 0;
faction.mRank = essFaction.mRank;
faction.mReputation = essFaction.mReputation;
out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(essFaction.mFactionName.toString())] = faction;
}
for (int i=0; i<3; ++i)
out.mObject.mNpcStats.mSpecIncreases[i] = pcdt.mPNAM.mSpecIncreases[i];
@ -35,10 +35,9 @@ namespace ESSImport
teleportingEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_TeleportingDisabled);
levitationEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_LevitationDisabled);
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
it != pcdt.mKnownDialogueTopics.end(); ++it)
for (const auto & knownDialogueTopic : pcdt.mKnownDialogueTopics)
{
outDialogueTopics.push_back(Misc::StringUtils::lowerCase(*it));
outDialogueTopics.push_back(Misc::StringUtils::lowerCase(knownDialogueTopic));
}
controls.mViewSwitchDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ViewSwitchDisabled;

@ -1,18 +1,16 @@
#include "convertscri.hpp"
#include <iostream>
namespace
{
template <typename T, ESM::VarType VariantType>
void storeVariables(const std::vector<T>& variables, ESM::Locals& locals, const std::string& scriptname)
{
for (typename std::vector<T>::const_iterator it = variables.begin(); it != variables.end(); ++it)
for (const auto& variable : variables)
{
ESM::Variant val(*it);
ESM::Variant val(variable);
val.setType(VariantType);
locals.mVariables.push_back(std::make_pair(std::string(), val));
locals.mVariables.emplace_back(std::string(), val);
}
}

@ -86,7 +86,9 @@ namespace ESSImport
bool mHasANIS;
ANIS mANIS; // scripted animation state
void load(ESM::ESMReader& esm);
virtual void load(ESM::ESMReader& esm);
virtual ~ActorData() = default;
};
}

@ -25,7 +25,9 @@ namespace ESSImport
bool mDeleted;
void load(ESM::ESMReader& esm);
void load(ESM::ESMReader& esm) override;
virtual ~CellRef() = default;
};
}

@ -16,15 +16,12 @@
#include <components/esm/player.hpp>
#include <components/esm/loadalch.hpp>
#include <components/esm/loadclas.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/loadarmo.hpp>
#include <components/esm/loadweap.hpp>
#include <components/esm/loadclot.hpp>
#include <components/esm/loadench.hpp>
#include <components/esm/loadweap.hpp>
#include <components/esm/loadlevlist.hpp>
#include <components/esm/loadglob.hpp>
#include <components/misc/constants.hpp>
@ -49,7 +46,7 @@ namespace
image->allocateImage(128, 128, 1, GL_RGB, GL_UNSIGNED_BYTE);
// need to convert pixel format from BGRA to RGB as the jpg readerwriter doesn't support it otherwise
std::vector<unsigned char>::const_iterator it = fileHeader.mSCRS.begin();
auto it = fileHeader.mSCRS.begin();
for (int y=0; y<128; ++y)
{
for (int x=0; x<128; ++x)
@ -317,10 +314,9 @@ namespace ESSImport
std::set<unsigned int> unknownRecords;
for (std::map<unsigned int, std::shared_ptr<Converter> >::const_iterator it = converters.begin();
it != converters.end(); ++it)
for (const auto & converter : converters)
{
it->second->setContext(context);
converter.second->setContext(context);
}
while (esm.hasMoreRecs())
@ -328,7 +324,7 @@ namespace ESSImport
ESM::NAME n = esm.getRecName();
esm.getRecHeader();
std::map<unsigned int, std::shared_ptr<Converter> >::iterator it = converters.find(n.intval);
auto it = converters.find(n.intval);
if (it != converters.end())
{
it->second->read(esm);
@ -358,17 +354,15 @@ namespace ESSImport
writer.setDescription("");
writer.setRecordCount (0);
for (std::vector<ESM::Header::MasterData>::const_iterator it = header.mMaster.begin();
it != header.mMaster.end(); ++it)
writer.addMaster (it->name, 0); // not using the size information anyway -> use value of 0
for (const auto & master : header.mMaster)
writer.addMaster(master.name, 0); // not using the size information anyway -> use value of 0
writer.save (stream);
ESM::SavedGame profile;
for (std::vector<ESM::Header::MasterData>::const_iterator it = header.mMaster.begin();
it != header.mMaster.end(); ++it)
for (const auto & master : header.mMaster)
{
profile.mContentFiles.push_back(it->name);
profile.mContentFiles.push_back(master.name);
}
profile.mDescription = esm.getDesc();
profile.mInGameTime.mDay = context.mDay;

@ -63,7 +63,6 @@ namespace ESSImport
, mHour(0.f)
, mNextActorId(0)
{
mPlayer.mAutoMove = 0;
ESM::CellId playerCellId;
playerCellId.mPaged = true;
playerCellId.mIndex.mX = playerCellId.mIndex.mY = 0;

@ -4,8 +4,6 @@
#include <components/esm/esmreader.hpp>
#include <components/esm/loadcont.hpp>
namespace ESSImport
{

@ -70,16 +70,9 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE)
endif(WIN32)
if (DESIRED_QT_VERSION MATCHES 4)
include(${QT_USE_FILE})
QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI})
else()
QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
QT5_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
QT5_WRAP_UI(UI_HDRS ${LAUNCHER_UI})
endif()
QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
QT5_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
QT5_WRAP_UI(UI_HDRS ${LAUNCHER_UI})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(NOT WIN32)
@ -105,14 +98,7 @@ target_link_libraries(openmw-launcher
components
)
if (DESIRED_QT_VERSION MATCHES 4)
target_link_libraries(openmw-launcher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
if(WIN32)
target_link_libraries(openmw-launcher ${QT_QTMAIN_LIBRARY})
endif(WIN32)
else()
target_link_libraries(openmw-launcher Qt5::Widgets Qt5::Core)
endif()
target_link_libraries(openmw-launcher Qt5::Widgets Qt5::Core)
if (BUILD_WITH_CODE_COVERAGE)
add_definitions (--coverage)

@ -104,6 +104,7 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game");
loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
loadSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI");
int showOwnedIndex = mEngineSettings.getInt("show owned", "Game");
// Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid.
if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
@ -171,6 +172,7 @@ void Launcher::AdvancedPage::saveSettings()
saveSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game");
saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI");
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game"))
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex);

@ -1,13 +1,9 @@
#include "graphicspage.hpp"
#include <csignal>
#include <QDesktopWidget>
#include <QMessageBox>
#include <QDir>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QScreen>
#endif
#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
#undef MAC_OS_X_VERSION_MIN_REQUIRED
@ -55,13 +51,11 @@ Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, Settings:
bool Launcher::GraphicsPage::setupSDL()
{
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
bool sdlConnectSuccessful = initSDL();
if (!sdlConnectSuccessful)
{
return false;
}
#endif
int displays = SDL_GetNumVideoDisplays();
@ -82,10 +76,8 @@ bool Launcher::GraphicsPage::setupSDL()
screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1));
}
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
// Disconnect from SDL processes
quitSDL();
#endif
return true;
}
@ -145,6 +137,10 @@ bool Launcher::GraphicsPage::loadSettings()
if (mEngineSettings.getBool("enable indoor shadows", "Shadows"))
indoorShadowsCheckBox->setCheckState(Qt::Checked);
shadowComputeSceneBoundsComboBox->setCurrentIndex(
shadowComputeSceneBoundsComboBox->findText(
QString(tr(mEngineSettings.getString("compute scene bounds", "Shadows").c_str()))));
int shadowDistLimit = mEngineSettings.getInt("maximum shadow map distance", "Shadows");
if (shadowDistLimit > 0)
{
@ -231,7 +227,7 @@ void Launcher::GraphicsPage::saveSettings()
bool cPlayerShadows = playerShadowsCheckBox->checkState();
if (cActorShadows || cObjectShadows || cTerrainShadows || cPlayerShadows)
{
if (mEngineSettings.getBool("enable shadows", "Shadows") != true)
if (!mEngineSettings.getBool("enable shadows", "Shadows"))
mEngineSettings.setBool("enable shadows", "Shadows", true);
if (mEngineSettings.getBool("actor shadows", "Shadows") != cActorShadows)
mEngineSettings.setBool("actor shadows", "Shadows", cActorShadows);
@ -263,6 +259,10 @@ void Launcher::GraphicsPage::saveSettings()
int cShadowRes = shadowResolutionComboBox->currentText().toInt();
if (cShadowRes != mEngineSettings.getInt("shadow map resolution", "Shadows"))
mEngineSettings.setInt("shadow map resolution", "Shadows", cShadowRes);
auto cComputeSceneBounds = shadowComputeSceneBoundsComboBox->currentText().toStdString();
if (cComputeSceneBounds != mEngineSettings.getString("compute scene bounds", "Shadows"))
mEngineSettings.setString("compute scene bounds", "Shadows", cComputeSceneBounds);
}
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
@ -316,7 +316,6 @@ QRect Launcher::GraphicsPage::getMaximumResolution()
{
QRect max;
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
for (QScreen* screen : QGuiApplication::screens())
{
QRect res = screen->geometry();
@ -325,17 +324,6 @@ QRect Launcher::GraphicsPage::getMaximumResolution()
if (res.height() > max.height())
max.setHeight(res.height());
}
#else
int screens = QApplication::desktop()->screenCount();
for (int i = 0; i < screens; ++i)
{
QRect res = QApplication::desktop()->screenGeometry(i);
if (res.width() > max.width())
max.setWidth(res.width());
if (res.height() > max.height())
max.setHeight(res.height());
}
#endif
return max;
}

@ -38,8 +38,8 @@ namespace Launcher
Files::ConfigurationManager &mCfgMgr;
Settings::Manager &mEngineSettings;
QStringList getAvailableResolutions(int screen);
QRect getMaximumResolution();
static QStringList getAvailableResolutions(int screen);
static QRect getMaximumResolution();
bool setupSDL();
};

@ -13,18 +13,11 @@
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
#include "maindialog.hpp"
#include "sdlinit.hpp"
int main(int argc, char *argv[])
{
try
{
// Note: we should init SDL2 before Qt4 to avoid crashes on Linux,
// but we should init SDL2 after Qt5 to avoid input issues on MacOS X.
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
initSDL();
#endif
QApplication app(argc, argv);
// Internationalization
@ -50,11 +43,6 @@ int main(int argc, char *argv[])
int exitCode = app.exec();
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
// Disconnect from SDL processes
quitSDL();
#endif
return exitCode;
}
catch (std::exception& e)

@ -403,7 +403,7 @@ bool Launcher::MainDialog::setupGameData()
QAbstractButton *skipButton =
msgBox.addButton(tr("Skip"), QMessageBox::RejectRole);
Q_UNUSED(skipButton); // Supress compiler unused warning
Q_UNUSED(skipButton); // Suppress compiler unused warning
msgBox.exec();

@ -149,16 +149,9 @@ if(WIN32)
set(QT_USE_QTMAIN TRUE)
endif(WIN32)
if (DESIRED_QT_VERSION MATCHES 4)
include(${QT_USE_FILE})
qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
else()
qt5_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt5_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt5_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
endif()
qt5_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt5_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT})
qt5_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
# for compiled .ui files
include_directories(${CMAKE_CURRENT_BINARY_DIR})
@ -236,19 +229,7 @@ target_link_libraries(openmw-cs
components
)
if (DESIRED_QT_VERSION MATCHES 4)
target_link_libraries(openmw-cs
${QT_QTGUI_LIBRARY}
${QT_QTCORE_LIBRARY}
${QT_QTNETWORK_LIBRARY}
${QT_QTOPENGL_LIBRARY})
if (WIN32)
target_link_libraries(openmw-cs ${QT_QTMAIN_LIBRARY})
endif()
else()
target_link_libraries(openmw-cs Qt5::Widgets Qt5::Core Qt5::Network Qt5::OpenGL)
endif()
target_link_libraries(openmw-cs Qt5::Widgets Qt5::Core Qt5::Network Qt5::OpenGL)
if (WIN32)
target_link_libraries(openmw-cs ${Boost_LOCALE_LIBRARY})

@ -685,7 +685,6 @@ namespace CSMPrefs
std::make_pair((int)Qt::Key_ContrastAdjust , "ContrastAdjust"),
std::make_pair((int)Qt::Key_LaunchG , "LaunchG"),
std::make_pair((int)Qt::Key_LaunchH , "LaunchH"),
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
std::make_pair((int)Qt::Key_TouchpadToggle , "TouchpadToggle"),
std::make_pair((int)Qt::Key_TouchpadOn , "TouchpadOn"),
std::make_pair((int)Qt::Key_TouchpadOff , "TouchpadOff"),
@ -706,7 +705,6 @@ namespace CSMPrefs
std::make_pair((int)Qt::Key_Find , "Find"),
std::make_pair((int)Qt::Key_Undo , "Undo"),
std::make_pair((int)Qt::Key_Redo , "Redo"),
#endif
std::make_pair((int)Qt::Key_AltGr , "AltGr"),
std::make_pair((int)Qt::Key_Multi_key , "Multi_key"),
std::make_pair((int)Qt::Key_Kanji , "Kanji"),
@ -770,9 +768,7 @@ namespace CSMPrefs
std::make_pair((int)Qt::Key_Sleep , "Sleep"),
std::make_pair((int)Qt::Key_Play , "Play"),
std::make_pair((int)Qt::Key_Zoom , "Zoom"),
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
std::make_pair((int)Qt::Key_Exit , "Exit"),
#endif
std::make_pair((int)Qt::Key_Context1 , "Context1"),
std::make_pair((int)Qt::Key_Context2 , "Context2"),
std::make_pair((int)Qt::Key_Context3 , "Context3"),

@ -116,7 +116,7 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value
Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
{
if (!index.isValid())
return 0;
return Qt::ItemFlags();
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;

@ -116,7 +116,7 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value,
Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const
{
if (!index.isValid())
return 0;
return Qt::ItemFlags();
if (index.internalId() != 0)
{

@ -1143,8 +1143,8 @@ namespace CSMWorld
case 0: return QString(faction.mRanks[subRowIndex].c_str());
case 1: return rankData.mAttribute1;
case 2: return rankData.mAttribute2;
case 3: return rankData.mSkill1;
case 4: return rankData.mSkill2;
case 3: return rankData.mPrimarySkill;
case 4: return rankData.mFavouredSkill;
case 5: return rankData.mFactReaction;
default: throw std::runtime_error("Rank subcolumn index out of range");
}
@ -1165,8 +1165,8 @@ namespace CSMWorld
case 0: faction.mRanks[subRowIndex] = value.toString().toUtf8().constData(); break;
case 1: rankData.mAttribute1 = value.toInt(); break;
case 2: rankData.mAttribute2 = value.toInt(); break;
case 3: rankData.mSkill1 = value.toInt(); break;
case 4: rankData.mSkill2 = value.toInt(); break;
case 3: rankData.mPrimarySkill = value.toInt(); break;
case 4: rankData.mFavouredSkill = value.toInt(); break;
case 5: rankData.mFactReaction = value.toInt(); break;
default: throw std::runtime_error("Rank index out of range");
}

@ -5,10 +5,7 @@
#include <QVBoxLayout>
#include <QDialogButtonBox>
#include <QPushButton>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QScreen>
#endif
#include "filewidget.hpp"
#include "adjusterwidget.hpp"
@ -50,11 +47,7 @@ CSVDoc::NewGameDialogue::NewGameDialogue()
connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)),
mAdjusterWidget, SLOT (setName (const QString&, bool)));
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QRect scr = QGuiApplication::primaryScreen()->geometry();
#else
QRect scr = QApplication::desktop()->screenGeometry();
#endif
QRect rect = geometry();
move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
}

@ -9,10 +9,7 @@
#include <QLabel>
#include <QIcon>
#include <QPushButton>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QScreen>
#endif
QPushButton *CSVDoc::StartupDialogue::addButton (const QString& label, const QIcon& icon)
{
@ -123,12 +120,7 @@ CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2)
setLayout (layout);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QRect scr = QGuiApplication::primaryScreen()->geometry();
#else
QRect scr = QApplication::desktop()->screenGeometry();
#endif
QRect rect = geometry();
move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y());
}

@ -14,10 +14,7 @@
#include <QHBoxLayout>
#include <QDesktopWidget>
#include <QScrollBar>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QScreen>
#endif
#include "../../model/doc/document.hpp"
#include "../../model/prefs/state.hpp"
@ -1071,11 +1068,7 @@ void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth)
if (isGrowLimit)
rect = dw->screenGeometry(this);
else
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
rect = QGuiApplication::screens().at(dw->screenNumber(this))->geometry();
#else
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
#endif
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
{

@ -14,7 +14,7 @@ namespace CSVPrefs
public:
ContextMenuList(QWidget* parent = 0);
ContextMenuList(QWidget* parent = nullptr);
protected:

@ -1,4 +1,3 @@
#include "dialogue.hpp"
#include <QApplication>
@ -7,10 +6,7 @@
#include <QListWidget>
#include <QStackedWidget>
#include <QListWidgetItem>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QScreen>
#endif
#include <components/debug/debuglog.hpp>
@ -39,11 +35,7 @@ void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
{
QString label = QString::fromUtf8 (iter->second.getKey().c_str());
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
maxWidth = std::max (maxWidth, metrics.horizontalAdvance (label));
#else
maxWidth = std::max (maxWidth, metrics.width (label));
#endif
list->addItem (label);
}
@ -116,11 +108,7 @@ void CSVPrefs::Dialogue::show()
}
else
{
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QRect scr = QGuiApplication::primaryScreen()->geometry();
#else
QRect scr = QApplication::desktop()->screenGeometry();
#endif
// otherwise place at the centre of the screen
QPoint screenCenter = scr.center();

@ -21,7 +21,7 @@ namespace CSVRender
public:
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
QWidget* parent = 0);
QWidget* parent = nullptr);
~OrbitCameraMode();
virtual void activate(CSVWidget::SceneToolbar* toolbar);

@ -143,14 +143,9 @@ void RenderWidget::toggleRenderStats()
CompositeViewer::CompositeViewer()
: mSimulationTime(0.0)
{
#if QT_VERSION >= 0x050000
// Qt5 is currently crashing and reporting "Cannot make QOpenGLContext current in a different thread" when the viewer is run multi-threaded, this is regression from Qt4
osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::SingleThreaded;
#else
osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::DrawThreadPerContext;
#endif
setThreadingModel(threadingModel);
// TODO: Upgrade osgQt to support osgViewer::ViewerBase::DrawThreadPerContext
// https://gitlab.com/OpenMW/openmw/-/issues/5481
setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,5)
setUseConfigureAffinity(false);
@ -337,7 +332,7 @@ void SceneWidget::mouseMoveEvent (QMouseEvent *event)
void SceneWidget::wheelEvent(QWheelEvent *event)
{
mCurrentCamControl->handleMouseScrollEvent(event->delta());
mCurrentCamControl->handleMouseScrollEvent(event->angleDelta().y());
}
void SceneWidget::update(double dt)

@ -49,7 +49,7 @@ namespace CSVRender
Q_OBJECT
public:
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
RenderWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~RenderWidget();
/// Initiates a request to redraw the view
@ -78,8 +78,8 @@ namespace CSVRender
{
Q_OBJECT
public:
SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = 0,
Qt::WindowFlags f = 0, bool retrieveInput = true);
SceneWidget(std::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = nullptr,
Qt::WindowFlags f = Qt::WindowFlags(), bool retrieveInput = true);
virtual ~SceneWidget();
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);

@ -33,7 +33,7 @@
#include "cameracontroller.hpp"
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false)
: SceneWidget (document.getData().getResourceSystem(), parent, Qt::WindowFlags(), false)
, mSceneElements(0)
, mRun(0)
, mDocument(document)
@ -646,13 +646,8 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
if (mDragging)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
mDragX = event->localPos().x();
mDragY = height() - event->localPos().y();
#else
mDragX = event->posF().x();
mDragY = height() - event->posF().y();
#endif
}
}
else
@ -682,8 +677,7 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
factor *= mDragShiftFactor;
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
editMode.dragWheel (event->delta(), factor);
editMode.dragWheel (event->angleDelta().y(), factor);
}
else
SceneWidget::wheelEvent(event);

@ -144,11 +144,7 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id)),
mRefreshAction (0), mRefreshState (refreshState)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
#else
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
#endif
horizontalHeader()->setStretchLastSection (true);
verticalHeader()->hide();
setSortingEnabled (true);
@ -277,7 +273,7 @@ void CSVTools::ReportTable::settingChanged (const CSMPrefs::Setting *setting)
if (key.startsWith (base))
{
QString modifierString = key.mid (base.size());
Qt::KeyboardModifiers modifiers = 0;
Qt::KeyboardModifiers modifiers;
if (modifierString=="-s")
modifiers = Qt::ShiftModifier;

@ -5,10 +5,7 @@
#include <QDesktopWidget>
#include <QPainter>
#include <QShowEvent>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QScreen>
#endif
#include "colorpickerpopup.hpp"
@ -99,11 +96,7 @@ QPoint CSVWidget::ColorEditor::calculatePopupPosition()
{
QRect editorGeometry = geometry();
QRect popupGeometry = mColorPicker->geometry();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QRect screenGeometry = QGuiApplication::primaryScreen()->geometry();
#else
QRect screenGeometry = QApplication::desktop()->screenGeometry();
#endif
// Center the popup horizontally relative to the editor
int localPopupX = (editorGeometry.width() - popupGeometry.width()) / 2;

@ -64,13 +64,8 @@ CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& tool
mTable->setShowGrid (false);
mTable->verticalHeader()->hide();
mTable->horizontalHeader()->hide();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents);
#else
mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents);
#endif
mTable->setSelectionMode (QAbstractItemView::NoSelection);
layout->addWidget (mTable);

@ -180,13 +180,8 @@ CSVWidget::SceneToolShapeBrush::SceneToolShapeBrush (SceneToolbar *parent, const
mTable->setShowGrid (true);
mTable->verticalHeader()->hide();
mTable->horizontalHeader()->hide();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::Stretch);
#else
mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setResizeMode (1, QHeaderView::Stretch);
#endif
mTable->setSelectionMode (QAbstractItemView::NoSelection);
layout->addWidget (mTable);

@ -243,13 +243,8 @@ CSVWidget::SceneToolTextureBrush::SceneToolTextureBrush (SceneToolbar *parent, c
mTable->setShowGrid (true);
mTable->verticalHeader()->hide();
mTable->horizontalHeader()->hide();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::Stretch);
#else
mTable->horizontalHeader()->setResizeMode (0, QHeaderView::Stretch);
mTable->horizontalHeader()->setResizeMode (1, QHeaderView::Stretch);
#endif
mTable->setSelectionMode (QAbstractItemView::NoSelection);
layout->addWidget (mTable);

@ -110,11 +110,7 @@ void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewIte
int valueIndex = getValueIndex(index);
if (valueIndex != -1)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
QStyleOptionViewItem itemOption(option);
#else
QStyleOptionViewItemV4 itemOption(option);
#endif
itemOption.text = mValues.at(valueIndex).second;
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &itemOption, painter);
}
@ -134,13 +130,7 @@ QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem &option, const
itemOption.state = option.state;
const QString &valueText = mValues.at(valueIndex).second;
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
QSize valueSize = QSize(itemOption.fontMetrics.horizontalAdvance(valueText), itemOption.fontMetrics.height());
#else
QSize valueSize = QSize(itemOption.fontMetrics.width(valueText), itemOption.fontMetrics.height());
#endif
itemOption.currentText = valueText;
return QApplication::style()->sizeFromContents(QStyle::CT_ComboBox, &itemOption, valueSize);
}

@ -33,11 +33,7 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
#else
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
#endif
verticalHeader()->hide();
int columns = model->columnCount(QModelIndex());

@ -205,12 +205,7 @@ bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
void CSVWorld::ScriptEdit::setTabWidth()
{
// Set tab width to specified number of characters using current font.
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
setTabStopDistance(mTabCharCount * fontMetrics().horizontalAdvance(' '));
#else
setTabStopWidth(mTabCharCount * fontMetrics().width(' '));
#endif
}
void CSVWorld::ScriptEdit::wrapLines(bool wrap)
@ -290,12 +285,7 @@ int CSVWorld::ScriptEdit::lineNumberAreaWidth()
++digits;
}
#if QT_VERSION >= QT_VERSION_CHECK(5,11,0)
int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
#else
int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
#endif
return space;
}

@ -83,13 +83,8 @@ CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document,
QStringList headers;
headers << "Severity" << "Line" << "Description";
setHorizontalHeaderLabels (headers);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (0, QHeaderView::ResizeToContents);
horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents);
#else
horizontalHeader()->setResizeMode (0, QHeaderView::ResizeToContents);
horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents);
#endif
horizontalHeader()->setStretchLastSection (true);
verticalHeader()->hide();
setColumnHidden (3, true);

@ -262,11 +262,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
mDispatcher = new CSMWorld::CommandDispatcher (document, id, this);
setModel (mProxyModel);
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive);
#else
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
#endif
verticalHeader()->hide();
setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection);
@ -675,7 +671,7 @@ void CSVWorld::Table::settingChanged (const CSMPrefs::Setting *setting)
{
std::string modifierString = setting->getKey().substr (6);
Qt::KeyboardModifiers modifiers = 0;
Qt::KeyboardModifiers modifiers;
if (modifierString=="-s")
modifiers = Qt::ShiftModifier;

@ -15,17 +15,13 @@ set(GAME_HEADER
engine.hpp
)
if (BULLET_USE_DOUBLES)
add_definitions(-DBT_USE_DOUBLE_PRECISION)
endif()
source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
renderbin actoranimation landmanager navmesh actorspaths recastmesh
renderbin actoranimation landmanager navmesh actorspaths recastmesh fogmanager objectpaging
)
add_openmw_dir (mwinput
@ -45,7 +41,7 @@ add_openmw_dir (mwgui
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation
draganddrop timeadvancer jailscreen itemchargeview keyboardnavigation textcolours
)
add_openmw_dir (mwdialogue
@ -71,7 +67,7 @@ add_openmw_dir (mwworld
actionequip timestamp actionalchemy cellstore actionapply actioneat
store esmstore recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
contentloader esmloader actiontrap cellreflist cellref physicssystem weather projectilemanager
cellpreloader
cellpreloader datetimemanager
)
add_openmw_dir (mwphysics
@ -90,7 +86,7 @@ add_openmw_dir (mwmechanics
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellcasting spellresistance
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
character actors objects aistate coordinateconverter trading weaponpriority spellpriority weapontype spellutil tickableeffects
character actors objects aistate trading weaponpriority spellpriority weapontype spellutil tickableeffects
spellabsorption linkedeffects
)

@ -1,6 +1,7 @@
#include "engine.hpp"
#include <iomanip>
#include <fstream>
#include <boost/filesystem/fstream.hpp>
@ -186,7 +187,7 @@ bool OMW::Engine::frame(float frametime)
osg::Timer_t afterWorldTick = osg::Timer::instance()->tick();
// update GUI
mEnvironment.getWindowManager()->onFrame(frametime);
mEnvironment.getWindowManager()->update(frametime);
unsigned int frameNumber = mViewer->getFrameStamp()->getFrameNumber();
osg::Stats* stats = mViewer->getViewerStats();
@ -208,12 +209,14 @@ bool OMW::Engine::frame(float frametime)
if (stats->collectStats("resource"))
{
stats->setAttribute(frameNumber, "FrameNumber", frameNumber);
mResourceSystem->reportStats(frameNumber, stats);
stats->setAttribute(frameNumber, "WorkQueue", mWorkQueue->getNumItems());
stats->setAttribute(frameNumber, "WorkThread", mWorkQueue->getNumActiveThreads());
mEnvironment.getWorld()->getNavigator()->reportStats(frameNumber, *stats);
mEnvironment.reportStats(frameNumber, *stats);
}
}
@ -758,6 +761,14 @@ void OMW::Engine::go()
mEnvironment.getWindowManager()->executeInConsole(mStartupScript);
}
std::ofstream stats;
if (const auto path = std::getenv("OPENMW_OSG_STATS_FILE"))
{
stats.open(path, std::ios_base::out);
if (!stats)
Log(Debug::Warning) << "Failed to open file for stats: " << path;
}
// Start the main rendering loop
osg::Timer frameTimer;
double simulationTime = 0.0;
@ -789,6 +800,12 @@ void OMW::Engine::go()
simulationTime += dt;
}
if (stats)
{
const auto frameNumber = mViewer->getFrameStamp()->getFrameNumber();
mViewer->getViewerStats()->report(stats, frameNumber);
}
mEnvironment.limitFrameRate(frameTimer.time_s());
}

@ -53,6 +53,8 @@ namespace MWBase
virtual bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) = 0;
virtual bool inJournal (const std::string& topicId, const std::string& infoId) = 0;
virtual void addTopic (const std::string& topic) = 0;
virtual void addChoice (const std::string& text,int choice) = 0;
@ -68,7 +70,14 @@ namespace MWBase
virtual void goodbyeSelected() = 0;
virtual void questionAnswered (int answer, ResponseCallback* callback) = 0;
enum TopicType
{
Specific = 1,
Exhausted = 2
};
virtual std::list<std::string> getAvailableTopics() = 0;
virtual int getTopicFlag(const std::string&) = 0;
virtual bool checkServiceRefused (ResponseCallback* callback) = 0;

@ -14,7 +14,6 @@
#include "windowmanager.hpp"
#include "statemanager.hpp"
MWBase::Environment *MWBase::Environment::sThis = 0;
MWBase::Environment::Environment()
@ -200,3 +199,8 @@ const MWBase::Environment& MWBase::Environment::get()
return *sThis;
}
void MWBase::Environment::reportStats(unsigned int frameNumber, osg::Stats& stats) const
{
mMechanicsManager->reportStats(frameNumber, stats);
mWorld->reportStats(frameNumber, stats);
}

@ -1,6 +1,11 @@
#ifndef GAME_BASE_ENVIRONMENT_H
#define GAME_BASE_ENVIRONMENT_H
namespace osg
{
class Stats;
}
namespace MWBase
{
class World;
@ -21,85 +26,84 @@ namespace MWBase
/// the set* functions.
class Environment
{
static Environment *sThis;
static Environment *sThis;
World *mWorld;
SoundManager *mSoundManager;
ScriptManager *mScriptManager;
WindowManager *mWindowManager;
MechanicsManager *mMechanicsManager;
DialogueManager *mDialogueManager;
Journal *mJournal;
InputManager *mInputManager;
StateManager *mStateManager;
float mFrameDuration;
float mFrameRateLimit;
Environment (const Environment&);
///< not implemented
World *mWorld;
SoundManager *mSoundManager;
ScriptManager *mScriptManager;
WindowManager *mWindowManager;
MechanicsManager *mMechanicsManager;
DialogueManager *mDialogueManager;
Journal *mJournal;
InputManager *mInputManager;
StateManager *mStateManager;
float mFrameDuration;
float mFrameRateLimit;
Environment& operator= (const Environment&);
///< not implemented
Environment (const Environment&);
///< not implemented
public:
Environment& operator= (const Environment&);
///< not implemented
Environment();
public:
~Environment();
Environment();
void setWorld (World *world);
~Environment();
void setSoundManager (SoundManager *soundManager);
void setWorld (World *world);
void setScriptManager (MWBase::ScriptManager *scriptManager);
void setSoundManager (SoundManager *soundManager);
void setWindowManager (WindowManager *windowManager);
void setScriptManager (MWBase::ScriptManager *scriptManager);
void setMechanicsManager (MechanicsManager *mechanicsManager);
void setWindowManager (WindowManager *windowManager);
void setDialogueManager (DialogueManager *dialogueManager);
void setMechanicsManager (MechanicsManager *mechanicsManager);
void setJournal (Journal *journal);
void setDialogueManager (DialogueManager *dialogueManager);
void setInputManager (InputManager *inputManager);
void setJournal (Journal *journal);
void setStateManager (StateManager *stateManager);
void setInputManager (InputManager *inputManager);
void setFrameDuration (float duration);
///< Set length of current frame in seconds.
void setStateManager (StateManager *stateManager);
void setFrameRateLimit(float frameRateLimit);
float getFrameRateLimit() const;
void limitFrameRate(double dt) const;
void setFrameDuration (float duration);
///< Set length of current frame in seconds.
World *getWorld() const;
void setFrameRateLimit(float frameRateLimit);
float getFrameRateLimit() const;
void limitFrameRate(double dt) const;
SoundManager *getSoundManager() const;
World *getWorld() const;
ScriptManager *getScriptManager() const;
SoundManager *getSoundManager() const;
WindowManager *getWindowManager() const;
ScriptManager *getScriptManager() const;
MechanicsManager *getMechanicsManager() const;
WindowManager *getWindowManager() const;
DialogueManager *getDialogueManager() const;
MechanicsManager *getMechanicsManager() const;
Journal *getJournal() const;
DialogueManager *getDialogueManager() const;
InputManager* getInputManager() const;
Journal *getJournal() const;
InputManager *getInputManager() const;
StateManager *getStateManager() const;
StateManager *getStateManager() const;
float getFrameDuration() const;
float getFrameDuration() const;
void cleanup();
///< Delete all mw*-subsystems.
void cleanup();
///< Delete all mw*-subsystems.
static const Environment& get();
///< Return instance of this class.
static const Environment& get();
///< Return instance of this class.
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
};
}

@ -78,6 +78,8 @@ namespace MWBase
virtual void resetIdleTime() = 0;
virtual void executeAction(int action) = 0;
virtual bool controlsDisabled() = 0;
};
}

@ -7,10 +7,14 @@
#include <set>
#include <stdint.h>
#include "../mwmechanics/actorutil.hpp"
// For MWMechanics::GreetingState
#include "../mwworld/ptr.hpp"
namespace osg
{
class Stats;
class Vec3f;
}
@ -269,6 +273,15 @@ namespace MWBase
virtual bool isAttackPreparing(const MWWorld::Ptr& ptr) = 0;
virtual bool isRunning(const MWWorld::Ptr& ptr) = 0;
virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0;
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;
virtual int getGreetingTimer(const MWWorld::Ptr& ptr) const = 0;
virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const = 0;
virtual MWMechanics::GreetingState getGreetingState(const MWWorld::Ptr& ptr) const = 0;
virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const = 0;
virtual void restoreStatsAfterCorprus(const MWWorld::Ptr& actor, const std::string& sourceId) = 0;
};
}

@ -252,13 +252,7 @@ namespace MWBase
/// returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
virtual int readPressedButton() = 0;
virtual void onFrame (float frameDuration) = 0;
/// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
virtual std::map<int, MWMechanics::SkillValue > getPlayerSkillValues() = 0;
virtual std::map<int, MWMechanics::AttributeValue > getPlayerAttributeValues() = 0;
virtual SkillList getPlayerMinorSkills() = 0;
virtual SkillList getPlayerMajorSkills() = 0;
virtual void update (float duration) = 0;
/**
* Fetches a GMST string from the store, if there is no setting with the given

@ -23,6 +23,7 @@ namespace osg
class Quat;
class Image;
class Node;
class Stats;
class Transform;
}
@ -38,6 +39,7 @@ namespace ESM
struct Position;
struct Cell;
struct Class;
struct Creature;
struct Potion;
struct Spell;
struct NPC;
@ -49,6 +51,7 @@ namespace ESM
struct EffectList;
struct CreatureLevList;
struct ItemLevList;
struct TimeStamp;
}
namespace MWRender
@ -80,11 +83,6 @@ namespace MWWorld
typedef std::vector<std::pair<MWWorld::Ptr,MWMechanics::Movement> > PtrMovementList;
}
namespace MWPhysics
{
class PhysicsSystem;
}
namespace MWBase
{
/// \brief Interface for the World (implemented in MWWorld)
@ -214,24 +212,14 @@ namespace MWBase
virtual void advanceTime (double hours, bool incremental = false) = 0;
///< Advance in-game time.
virtual void setHour (double hour) = 0;
///< Set in-game time hour.
virtual void setMonth (int month) = 0;
///< Set in-game time month.
virtual void setDay (int day) = 0;
///< Set in-game time day.
virtual int getDay() const = 0;
virtual int getMonth() const = 0;
virtual int getYear() const = 0;
virtual std::string getMonthName (int month = -1) const = 0;
///< Return name of month (-1: current month)
virtual MWWorld::TimeStamp getTimeStamp() const = 0;
///< Return current in-game time stamp.
///< Return current in-game time and number of day since new game start.
virtual ESM::EpochTimeStamp getEpochTimeStamp() const = 0;
///< Return current in-game date and time.
virtual bool toggleSky() = 0;
///< \return Resulting mode
@ -389,6 +377,14 @@ namespace MWBase
///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID.
/// \return pointer to created record
virtual const ESM::Creature *createOverrideRecord (const ESM::Creature& record) = 0;
///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID.
/// \return pointer to created record
virtual const ESM::NPC *createOverrideRecord (const ESM::NPC& record) = 0;
///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID.
/// \return pointer to created record
virtual void update (float duration, bool paused) = 0;
virtual void updatePhysics (float duration, bool paused) = 0;
@ -653,10 +649,10 @@ namespace MWBase
/// @Return ESM::Weapon::Type enum describing the type of weapon currently drawn by the player.
virtual int getActiveWeaponType(void) = 0;
virtual MWPhysics::PhysicsSystem* getPhysicsSystem(void) = 0;
virtual bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const = 0;
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;
};
}

@ -276,7 +276,7 @@ namespace MWClass
const MWWorld::LiveCellRef<ESM::Armor> *ref = ptr.get<ESM::Armor>();
int armorSkillType = getEquipmentSkill(ptr);
int armorSkill = actor.getClass().getSkill(actor, armorSkillType);
float armorSkill = actor.getClass().getSkill(actor, armorSkillType);
const MWBase::World *world = MWBase::Environment::get().getWorld();
int iBaseArmorSkill = world->getStore().get<ESM::GameSetting>().find("iBaseArmorSkill")->mValue.getInteger();

@ -521,23 +521,16 @@ namespace MWClass
float Creature::getSpeed(const MWWorld::Ptr &ptr) const
{
MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead())
return 0.f;
const GMST& gmst = getGmst();
float walkSpeed = gmst.fMinWalkSpeedCreature->mValue.getFloat() + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified()
* (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat());
const MWBase::World *world = MWBase::Environment::get().getWorld();
const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects();
bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run);
// The Run speed difference for creatures comes from the animation speed difference (see runStateToWalkState in character.cpp)
float runSpeed = walkSpeed;
float moveSpeed;
if(getEncumbrance(ptr) > getCapacity(ptr))
@ -554,23 +547,14 @@ namespace MWClass
moveSpeed = flySpeed;
}
else if(world->isSwimming(ptr))
{
float swimSpeed = walkSpeed;
if(running)
swimSpeed = runSpeed;
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) *
gmst.fSwimRunAthleticsMult->mValue.getFloat();
moveSpeed = swimSpeed;
}
else if(running)
moveSpeed = runSpeed;
moveSpeed = getSwimSpeed(ptr);
else
moveSpeed = walkSpeed;
if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0)
moveSpeed *= 0.75f;
moveSpeed = getWalkSpeed(ptr);
moveSpeed *= ptr.getClass().getMovementSettings(ptr).mSpeedFactor;
const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr);
if (movementSettings.mIsStrafing)
moveSpeed *= 0.75f;
moveSpeed *= movementSettings.mSpeedFactor;
return moveSpeed;
}
@ -619,7 +603,7 @@ namespace MWClass
float Creature::getCapacity (const MWWorld::Ptr& ptr) const
{
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
return static_cast<float>(stats.getAttribute(ESM::Attribute::Strength).getModified() * 5);
return stats.getAttribute(ESM::Attribute::Strength).getModified() * 5;
}
int Creature::getServices(const MWWorld::ConstPtr &actor) const
@ -759,7 +743,7 @@ namespace MWClass
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
}
int Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const
float Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
@ -823,6 +807,12 @@ namespace MWClass
return;
}
if (ptr.getRefData().getCount() <= 0)
{
state.mHasCustomState = false;
return;
}
const CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData();
ESM::CreatureState& creatureState = state.asCreatureState();
customData.mContainerStore->writeState (creatureState.mInventory);
@ -892,4 +882,36 @@ namespace MWClass
const MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
scale *= ref->mBase->mScale;
}
void Creature::setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const
{
MWMechanics::setBaseAISetting<ESM::Creature>(id, setting, value);
}
float Creature::getWalkSpeed(const MWWorld::Ptr& ptr) const
{
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
const GMST& gmst = getGmst();
return gmst.fMinWalkSpeedCreature->mValue.getFloat()
+ 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified()
* (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat());
}
float Creature::getRunSpeed(const MWWorld::Ptr& ptr) const
{
return getWalkSpeed(ptr);
}
float Creature::getSwimSpeed(const MWWorld::Ptr& ptr) const
{
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
const GMST& gmst = getGmst();
const MWMechanics::MagicEffects& mageffects = stats.getMagicEffects();
return getWalkSpeed(ptr)
* (1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude())
* (gmst.fSwimRunBase->mValue.getFloat()
+ 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat());
}
}

@ -108,7 +108,7 @@ namespace MWClass
virtual bool canSwim (const MWWorld::ConstPtr &ptr) const;
virtual bool canWalk (const MWWorld::ConstPtr &ptr) const;
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
virtual float getSkill(const MWWorld::Ptr &ptr, int skill) const;
/// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const;
@ -129,6 +129,14 @@ namespace MWClass
virtual void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const;
/// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh
virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const;
float getWalkSpeed(const MWWorld::Ptr& ptr) const final;
float getRunSpeed(const MWWorld::Ptr& ptr) const final;
float getSwimSpeed(const MWWorld::Ptr& ptr) const final;
};
}

@ -125,7 +125,7 @@ namespace MWClass
}
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
int alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
float alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
static const float fWortChanceValue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->mValue.getFloat();

@ -128,8 +128,8 @@ namespace
}
// initial health
int strength = creatureStats.getAttribute(ESM::Attribute::Strength).getBase();
int endurance = creatureStats.getAttribute(ESM::Attribute::Endurance).getBase();
float strength = creatureStats.getAttribute(ESM::Attribute::Strength).getBase();
float endurance = creatureStats.getAttribute(ESM::Attribute::Endurance).getBase();
int multiplier = 3;
@ -796,7 +796,22 @@ namespace MWClass
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot);
MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr());
if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name())
bool hasArmor = !armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name();
// If there's no item in the carried left slot or if it is not a shield redistribute the hit.
if (!hasArmor && hitslot == MWWorld::InventoryStore::Slot_CarriedLeft)
{
if (Misc::Rng::rollDice(2) == 0)
hitslot = MWWorld::InventoryStore::Slot_Cuirass;
else
hitslot = MWWorld::InventoryStore::Slot_LeftPauldron;
armorslot = inv.getSlot(hitslot);
if (armorslot != inv.end())
{
armor = *armorslot;
hasArmor = !armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name();
}
}
if (hasArmor)
{
if (!object.isEmpty() || attacker.isEmpty() || attacker.getClass().isNpc()) // Unarmed creature attacks don't affect armor condition
{
@ -976,16 +991,6 @@ namespace MWClass
bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(ptr);
running = running && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr));
float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()*
(gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat());
walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance;
walkSpeed = std::max(0.0f, walkSpeed);
if(sneaking)
walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat();
float runSpeed = walkSpeed*(0.01f * getSkill(ptr, ESM::Skill::Athletics) *
gmst.fAthleticsRunBonus->mValue.getFloat() + gmst.fBaseRunMultiplier->mValue.getFloat());
float moveSpeed;
if(getEncumbrance(ptr) > getCapacity(ptr))
moveSpeed = 0.0f;
@ -1000,26 +1005,19 @@ namespace MWClass
moveSpeed = flySpeed;
}
else if (swimming)
{
float swimSpeed = walkSpeed;
if(running)
swimSpeed = runSpeed;
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics)*
gmst.fSwimRunAthleticsMult->mValue.getFloat();
moveSpeed = swimSpeed;
}
moveSpeed = getSwimSpeed(ptr);
else if (running && !sneaking)
moveSpeed = runSpeed;
moveSpeed = getRunSpeed(ptr);
else
moveSpeed = walkSpeed;
if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0)
moveSpeed *= 0.75f;
moveSpeed = getWalkSpeed(ptr);
if(npcdata->mNpcStats.isWerewolf() && running && npcdata->mNpcStats.getDrawState() == MWMechanics::DrawState_Nothing)
moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat();
moveSpeed *= ptr.getClass().getMovementSettings(ptr).mSpeedFactor;
const MWMechanics::Movement& movementSettings = ptr.getClass().getMovementSettings(ptr);
if (movementSettings.mIsStrafing)
moveSpeed *= 0.75f;
moveSpeed *= movementSettings.mSpeedFactor;
return moveSpeed;
}
@ -1040,7 +1038,7 @@ namespace MWClass
gmst.fJumpEncumbranceMultiplier->mValue.getFloat() *
(1.0f - Npc::getNormalizedEncumbrance(ptr));
float a = static_cast<float>(getSkill(ptr, ESM::Skill::Acrobatics));
float a = getSkill(ptr, ESM::Skill::Acrobatics);
float b = 0.0f;
if(a > 50.0f)
{
@ -1165,7 +1163,7 @@ namespace MWClass
float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat();
float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat();
int unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored);
float unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored);
float ratings[MWWorld::InventoryStore::Slots];
for(int i = 0;i < MWWorld::InventoryStore::Slots;i++)
@ -1312,7 +1310,7 @@ namespace MWClass
return MWWorld::Ptr(cell.insert(ref), &cell);
}
int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
float Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
{
return getNpcStats(ptr).getSkill(skill).getModified();
}
@ -1356,6 +1354,12 @@ namespace MWClass
return;
}
if (ptr.getRefData().getCount() <= 0)
{
state.mHasCustomState = false;
return;
}
const NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData();
ESM::NpcState& npcState = state.asNpcState();
customData.mInventoryStore.writeState (npcState.mInventory);
@ -1466,4 +1470,61 @@ namespace MWClass
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
return ref->mBase->getFactionRank();
}
void Npc::setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const
{
MWMechanics::setBaseAISetting<ESM::NPC>(id, setting, value);
}
float Npc::getWalkSpeed(const MWWorld::Ptr& ptr) const
{
const GMST& gmst = getGmst();
const NpcCustomData* npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
const bool sneaking = MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr);
float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat()
+ 0.01f * npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()
* (gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat());
walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance;
walkSpeed = std::max(0.0f, walkSpeed);
if(sneaking)
walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat();
return walkSpeed;
}
float Npc::getRunSpeed(const MWWorld::Ptr& ptr) const
{
const GMST& gmst = getGmst();
return getWalkSpeed(ptr)
* (0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat()
+ gmst.fBaseRunMultiplier->mValue.getFloat());
}
float Npc::getSwimSpeed(const MWWorld::Ptr& ptr) const
{
const GMST& gmst = getGmst();
const MWBase::World* world = MWBase::Environment::get().getWorld();
const MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
const NpcCustomData* npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
const MWMechanics::MagicEffects& mageffects = npcdata->mNpcStats.getMagicEffects();
const bool swimming = world->isSwimming(ptr);
const bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(ptr);
const bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run)
&& (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr));
float swimSpeed;
if (running)
swimSpeed = getRunSpeed(ptr);
else
swimSpeed = getWalkSpeed(ptr);
swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude();
swimSpeed *= gmst.fSwimRunBase->mValue.getFloat()
+ 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat();
return swimSpeed;
}
}

@ -129,7 +129,7 @@ namespace MWClass
virtual std::string getModel(const MWWorld::ConstPtr &ptr) const;
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const;
/// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const;
@ -164,6 +164,14 @@ namespace MWClass
virtual std::string getPrimaryFaction(const MWWorld::ConstPtr &ptr) const;
virtual int getPrimaryFactionRank(const MWWorld::ConstPtr &ptr) const;
virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const;
float getWalkSpeed(const MWWorld::Ptr& ptr) const final;
float getRunSpeed(const MWWorld::Ptr& ptr) const final;
float getSwimSpeed(const MWWorld::Ptr& ptr) const final;
};
}

@ -228,6 +228,30 @@ namespace MWDialogue
}
}
bool DialogueManager::inJournal (const std::string& topicId, const std::string& infoId)
{
const MWDialogue::Topic *topicHistory = nullptr;
MWBase::Journal *journal = MWBase::Environment::get().getJournal();
for (auto it = journal->topicBegin(); it != journal->topicEnd(); ++it)
{
if (it->first == topicId)
{
topicHistory = &it->second;
break;
}
}
if (!topicHistory)
return false;
for(const auto& topic : *topicHistory)
{
if (topic.mInfoId == infoId)
return true;
}
return false;
}
void DialogueManager::executeTopic (const std::string& topic, ResponseCallback* callback)
{
Filter filter (mActor, mChoice, mTalkedTo);
@ -300,22 +324,34 @@ namespace MWDialogue
mActorKnownTopics.clear();
const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
const auto& dialogs = MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
Filter filter (mActor, -1, mTalkedTo);
for (MWWorld::Store<ESM::Dialogue>::iterator iter = dialogs.begin(); iter != dialogs.end(); ++iter)
for (const auto& dialog : dialogs)
{
if (iter->mType == ESM::Dialogue::Topic)
if (dialog.mType == ESM::Dialogue::Topic)
{
if (filter.responseAvailable (*iter))
const auto* answer = filter.search(dialog, true);
auto topicId = Misc::StringUtils::lowerCase(dialog.mId);
if (answer != nullptr)
{
mActorKnownTopics.insert (iter->mId);
int flag = 0;
if(!inJournal(topicId, answer->mId))
{
// Does this dialogue contains some actor-specific answer?
if (answer->mActor == mActor.getCellRef().getRefId())
flag |= MWBase::DialogueManager::TopicType::Specific;
}
else
flag |= MWBase::DialogueManager::TopicType::Exhausted;
mActorKnownTopics.insert (dialog.mId);
mActorKnownTopicsFlag[dialog.mId] = flag;
}
}
}
}
std::list<std::string> DialogueManager::getAvailableTopics()
@ -336,6 +372,11 @@ namespace MWDialogue
return keywordList;
}
int DialogueManager::getTopicFlag(const std::string& topicId)
{
return mActorKnownTopicsFlag[topicId];
}
void DialogueManager::keywordSelected (const std::string& keyword, ResponseCallback* callback)
{
if(!mIsInChoice)

@ -5,6 +5,7 @@
#include <map>
#include <set>
#include <unordered_map>
#include <components/compiler/streamerrorhandler.hpp>
#include <components/translation/translation.hpp>
@ -30,6 +31,7 @@ namespace MWDialogue
ModFactionReactionMap mChangedFactionReaction;
std::set<std::string, Misc::StringUtils::CiComp> mActorKnownTopics;
std::unordered_map<std::string, int> mActorKnownTopicsFlag;
Translation::Storage& mTranslationDataStorage;
MWScript::CompilerContext mCompilerContext;
@ -71,6 +73,9 @@ namespace MWDialogue
virtual bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback);
std::list<std::string> getAvailableTopics();
int getTopicFlag(const std::string& topicId) final;
bool inJournal (const std::string& topicId, const std::string& infoId) final;
virtual void addTopic (const std::string& topic);

@ -681,15 +681,3 @@ std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue
return infos;
}
bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const
{
for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter)
{
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
return true;
}
return false;
}

@ -66,9 +66,6 @@ namespace MWDialogue
const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
///< Get a matching response for the requested dialogue.
/// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition.
bool responseAvailable (const ESM::Dialogue& dialogue) const;
///< Does a matching response exist? (disposition is ignored for this check)
};
}

@ -105,23 +105,32 @@ namespace MWGui
mGenerateClassSpecializations[0] = 0;
mGenerateClassSpecializations[1] = 0;
mGenerateClassSpecializations[2] = 0;
// Setup player stats
for (int i = 0; i < ESM::Attribute::Length; ++i)
mPlayerAttributes.emplace(ESM::Attribute::sAttributeIds[i], MWMechanics::AttributeValue());
for (int i = 0; i < ESM::Skill::Length; ++i)
mPlayerSkillValues.emplace(ESM::Skill::sSkillIds[i], MWMechanics::SkillValue());
}
void CharacterCreation::setValue (const std::string& id, const MWMechanics::AttributeValue& value)
{
if (mReviewDialog)
static const char *ids[] =
{
static const char *ids[] =
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
"AttribVal6", "AttribVal7", "AttribVal8",
0
};
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4",
"AttribVal5", "AttribVal6", "AttribVal7", "AttribVal8", 0
};
for (int i=0; ids[i]; ++i)
for (int i=0; ids[i]; ++i)
{
if (ids[i]==id)
{
if (ids[i]==id)
mReviewDialog->setAttribute(ESM::Attribute::AttributeID(i), value);
mPlayerAttributes[static_cast<ESM::Attribute::AttributeID>(i)] = value;
if (mReviewDialog)
mReviewDialog->setAttribute(static_cast<ESM::Attribute::AttributeID>(i), value);
break;
}
}
}
@ -147,6 +156,7 @@ namespace MWGui
void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value)
{
mPlayerSkillValues[parSkill] = value;
if (mReviewDialog)
mReviewDialog->setSkillValue(parSkill, value);
}
@ -155,6 +165,9 @@ namespace MWGui
{
if (mReviewDialog)
mReviewDialog->configureSkills(major, minor);
mPlayerMajorSkills = major;
mPlayerMinorSkills = minor;
}
void CharacterCreation::onFrame(float duration)
@ -269,31 +282,21 @@ namespace MWGui
mReviewDialog->setClass(*playerClass);
mReviewDialog->setBirthSign(player.getBirthSign());
{
MWWorld::Ptr playerPtr = MWMechanics::getPlayer();
const MWMechanics::CreatureStats& stats = playerPtr.getClass().getCreatureStats(playerPtr);
mReviewDialog->setHealth ( stats.getHealth() );
mReviewDialog->setMagicka( stats.getMagicka() );
mReviewDialog->setFatigue( stats.getFatigue() );
}
MWWorld::Ptr playerPtr = MWMechanics::getPlayer();
const MWMechanics::CreatureStats& stats = playerPtr.getClass().getCreatureStats(playerPtr);
mReviewDialog->setHealth(stats.getHealth());
mReviewDialog->setMagicka(stats.getMagicka());
mReviewDialog->setFatigue(stats.getFatigue());
for (auto& attributePair : mPlayerAttributes)
{
std::map<int, MWMechanics::AttributeValue > attributes = MWBase::Environment::get().getWindowManager()->getPlayerAttributeValues();
for (auto& attributePair : attributes)
{
mReviewDialog->setAttribute(static_cast<ESM::Attribute::AttributeID> (attributePair.first), attributePair.second);
}
mReviewDialog->setAttribute(static_cast<ESM::Attribute::AttributeID> (attributePair.first), attributePair.second);
}
for (auto& skillPair : mPlayerSkillValues)
{
std::map<int, MWMechanics::SkillValue > skills = MWBase::Environment::get().getWindowManager()->getPlayerSkillValues();
for (auto& skillPair : skills)
{
mReviewDialog->setSkillValue(static_cast<ESM::Skill::SkillEnum> (skillPair.first), skillPair.second);
}
mReviewDialog->configureSkills(MWBase::Environment::get().getWindowManager()->getPlayerMajorSkills(), MWBase::Environment::get().getWindowManager()->getPlayerMinorSkills());
mReviewDialog->setSkillValue(static_cast<ESM::Skill::SkillEnum> (skillPair.first), skillPair.second);
}
mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills);
mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone);
mReviewDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogBack);

@ -4,6 +4,7 @@
#include <components/esm/loadskil.hpp>
#include <components/esm/loadclas.hpp>
#include <map>
#include <vector>
#include "../mwmechanics/stat.hpp"
@ -56,6 +57,10 @@ namespace MWGui
osg::Group* mParent;
Resource::ResourceSystem* mResourceSystem;
SkillList mPlayerMajorSkills, mPlayerMinorSkills;
std::map<int, MWMechanics::AttributeValue> mPlayerAttributes;
std::map<int, MWMechanics::SkillValue> mPlayerSkillValues;
//Dialogs
TextInputDialog* mNameDialog;
RaceDialog* mRaceDialog;

@ -343,6 +343,7 @@ namespace MWGui
mTopicsList->adjustSize();
updateHistory();
updateTopicFormat();
mCurrentWindowSize = _sender->getSize();
}
@ -452,7 +453,6 @@ namespace MWGui
setTitle(mPtr.getClass().getName(mPtr));
updateTopics();
updateTopicsPane(); // force update for new services
updateDisposition();
restock();
@ -495,8 +495,6 @@ namespace MWGui
return;
mIsCompanion = isCompanion();
mKeywords = keyWords;
updateTopicsPane();
}
void DialogueWindow::updateTopicsPane()
@ -546,15 +544,16 @@ namespace MWGui
mTopicsList->addSeparator();
for(std::string& keyword : mKeywords)
for(const auto& keyword : mKeywords)
{
std::string topicId = Misc::StringUtils::lowerCase(keyword);
mTopicsList->addItem(keyword);
Topic* t = new Topic(keyword);
t->eventTopicActivated += MyGUI::newDelegate(this, &DialogueWindow::onTopicActivated);
mTopicLinks[Misc::StringUtils::lowerCase(keyword)] = t;
mTopicLinks[topicId] = t;
mKeywordSearch.seed(Misc::StringUtils::lowerCase(keyword), intptr_t(t));
mKeywordSearch.seed(topicId, intptr_t(t));
}
mTopicsList->adjustSize();
@ -740,9 +739,31 @@ namespace MWGui
updateHistory();
}
void DialogueWindow::updateTopicFormat()
{
if (!Settings::Manager::getBool("color topic enable", "GUI"))
return;
std::string specialColour = Settings::Manager::getString("color topic specific", "GUI");
std::string oldColour = Settings::Manager::getString("color topic exhausted", "GUI");
for (const std::string& keyword : mKeywords)
{
int flag = MWBase::Environment::get().getDialogueManager()->getTopicFlag(keyword);
MyGUI::Button* button = mTopicsList->getItemWidget(keyword);
if (!specialColour.empty() && flag & MWBase::DialogueManager::TopicType::Specific)
button->getSubWidgetText()->setTextColour(MyGUI::Colour::parse(specialColour));
else if (!oldColour.empty() && flag & MWBase::DialogueManager::TopicType::Exhausted)
button->getSubWidgetText()->setTextColour(MyGUI::Colour::parse(oldColour));
}
}
void DialogueWindow::updateTopics()
{
setKeywords(MWBase::Environment::get().getDialogueManager()->getAvailableTopics());
updateTopicsPane();
updateTopicFormat();
}
bool DialogueWindow::isCompanion()

@ -186,6 +186,8 @@ namespace MWGui
std::unique_ptr<ResponseCallback> mCallback;
std::unique_ptr<ResponseCallback> mGreetingCallback;
void updateTopicFormat();
};
}
#endif

@ -166,9 +166,7 @@ namespace MWGui
getWidget(mCrosshair, "Crosshair");
int mapSize = std::max(1, Settings::Manager::getInt("local map hud widget size", "Map"));
int cellDistance = std::max(1, Settings::Manager::getInt("local map cell distance", "Map"));
LocalMapBase::init(mMinimap, mCompass, mapSize, cellDistance);
LocalMapBase::init(mMinimap, mCompass);
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);

@ -81,6 +81,12 @@ namespace MWGui
MWBase::Environment::get().getMechanicsManager()->rest(mDays * 24, true);
MWBase::Environment::get().getWorld()->advanceTime(mDays * 24);
// We should not worsen corprus when in prison
for (auto& spell : player.getClass().getCreatureStats(player).getCorprusSpells())
{
spell.second.mNextWorsening += mDays * 24;
}
std::set<int> skills;
for (int day=0; day<mDays; ++day)
{
@ -89,9 +95,9 @@ namespace MWGui
MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill);
if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak)
value.setBase(std::min(100, value.getBase()+1));
value.setBase(std::min(100.f, value.getBase()+1));
else
value.setBase(std::max(0, value.getBase()-1));
value.setBase(std::max(0.f, value.getBase()-1));
}
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

@ -157,7 +157,7 @@ namespace MWGui
mAttributeValues[i]->setEnabled(true);
availableAttributes++;
int mult = pcStats.getLevelupAttributeMultiplier (i);
float mult = pcStats.getLevelupAttributeMultiplier (i);
mult = std::min(mult, 100-pcStats.getAttribute(i).getBase());
text->setCaption(mult <= 1 ? "" : "x" + MyGUI::utility::toString(mult));
}

@ -16,6 +16,7 @@
#include <components/myguiplatform/myguitexture.hpp>
#include <components/settings/settings.hpp>
#include <components/vfs/manager.hpp>
#include <components/resource/resourcesystem.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/statemanager.hpp"
@ -29,9 +30,9 @@
namespace MWGui
{
LoadingScreen::LoadingScreen(const VFS::Manager* vfs, osgViewer::Viewer* viewer)
LoadingScreen::LoadingScreen(Resource::ResourceSystem* resourceSystem, osgViewer::Viewer* viewer)
: WindowBase("openmw_loading_screen.layout")
, mVFS(vfs)
, mResourceSystem(resourceSystem)
, mViewer(viewer)
, mTargetFrameRate(120.0)
, mLastWallpaperChangeTime(0.0)
@ -39,6 +40,7 @@ namespace MWGui
, mLoadingOnTime(0.0)
, mImportantLabel(false)
, mVisible(false)
, mNestedLoadingCount(0)
, mProgress(0)
, mShowWallpaper(true)
{
@ -64,9 +66,9 @@ namespace MWGui
void LoadingScreen::findSplashScreens()
{
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
const std::map<std::string, VFS::File*>& index = mResourceSystem->getVFS()->getIndex();
std::string pattern = "Splash/";
mVFS->normalizeFilename(pattern);
mResourceSystem->getVFS()->normalizeFilename(pattern);
/* priority given to the left */
const std::array<std::string, 7> supported_extensions {{".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"}};
@ -162,15 +164,21 @@ namespace MWGui
void LoadingScreen::loadingOn(bool visible)
{
mLoadingOnTime = mTimer.time_m();
// Early-out if already on
if (mMainWidget->getVisible())
if (mNestedLoadingCount++ > 0 && mMainWidget->getVisible())
return;
mLoadingOnTime = mTimer.time_m();
// Assign dummy bounding sphere callback to avoid the bounding sphere of the entire scene being recomputed after each frame of loading
// We are already using node masks to avoid the scene from being updated/rendered, but node masks don't work for computeBound()
mViewer->getSceneData()->setComputeBoundingSphereCallback(new DontComputeBoundCallback);
if (const osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) {
mOldIcoMin = ico->getMinimumTimeAvailableForGLCompileAndDeletePerFrame();
mOldIcoMax = ico->getMaximumNumOfObjectsToCompilePerFrame();
}
mVisible = visible;
mLoadingBox->setVisible(mVisible);
setVisible(true);
@ -194,6 +202,8 @@ namespace MWGui
void LoadingScreen::loadingOff()
{
if (--mNestedLoadingCount > 0)
return;
mLoadingBox->setVisible(true); // restore
if (mLastRenderTime < mLoadingOnTime)
@ -215,6 +225,12 @@ namespace MWGui
//std::cout << "loading took " << mTimer.time_m() - mLoadingOnTime << std::endl;
setVisible(false);
if (osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation())
{
ico->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(mOldIcoMin);
ico->setMaximumNumOfObjectsToCompilePerFrame(mOldIcoMax);
}
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_LoadingWallpaper);
}
@ -336,7 +352,13 @@ namespace MWGui
MWBase::Environment::get().getInputManager()->update(0, true, true);
//osg::Timer timer;
mResourceSystem->reportStats(mViewer->getFrameStamp()->getFrameNumber(), mViewer->getViewerStats());
if (osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation())
{
ico->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1.f/getTargetFrameRate());
ico->setMaximumNumOfObjectsToCompilePerFrame(1000);
}
// at the time this function is called we are in the middle of a frame,
// so out of order calls are necessary to get a correct frameNumber for the next frame.
// refer to the advance() and frame() order in Engine::go()
@ -344,10 +366,6 @@ namespace MWGui
mViewer->updateTraversal();
mViewer->renderingTraversals();
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
//std::cout << "frame took " << timer.time_m() << std::endl;
//if (mViewer->getIncrementalCompileOperation())
//std::cout << "num to compile " << mViewer->getIncrementalCompileOperation()->getToCompile().size() << std::endl;
mLastRenderTime = mTimer.time_m();
}

@ -20,9 +20,9 @@ namespace osg
class Texture2D;
}
namespace VFS
namespace Resource
{
class Manager;
class ResourceSystem;
}
namespace MWGui
@ -32,7 +32,7 @@ namespace MWGui
class LoadingScreen : public WindowBase, public Loading::Listener
{
public:
LoadingScreen(const VFS::Manager* vfs, osgViewer::Viewer* viewer);
LoadingScreen(Resource::ResourceSystem* resourceSystem, osgViewer::Viewer* viewer);
virtual ~LoadingScreen();
/// Overridden from Loading::Listener, see the Loading::Listener documentation for usage details
@ -53,7 +53,7 @@ namespace MWGui
void setupCopyFramebufferToTextureCallback();
const VFS::Manager* mVFS;
Resource::ResourceSystem* mResourceSystem;
osg::ref_ptr<osgViewer::Viewer> mViewer;
double mTargetFrameRate;
@ -66,10 +66,13 @@ namespace MWGui
bool mImportantLabel;
bool mVisible;
int mNestedLoadingCount;
size_t mProgress;
bool mShowWallpaper;
float mOldIcoMin = 0.f;
unsigned int mOldIcoMax = 0;
MyGUI::Widget* mLoadingBox;

@ -183,13 +183,13 @@ namespace MWGui
mCustomMarkers.eventMarkersChanged -= MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers);
}
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int mapWidgetSize, int cellDistance)
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass)
{
mLocalMap = widget;
mCompass = compass;
mMapWidgetSize = mapWidgetSize;
mCellDistance = cellDistance;
mNumCells = cellDistance * 2 + 1;
mMapWidgetSize = std::max(1, Settings::Manager::getInt("local map widget size", "Map"));
mCellDistance = Constants::CellGridRadius;
mNumCells = mCellDistance * 2 + 1;
mLocalMap->setCanvasSize(mMapWidgetSize*mNumCells, mMapWidgetSize*mNumCells);
@ -701,9 +701,7 @@ namespace MWGui
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
mEventBoxLocal->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onMapDoubleClicked);
int mapSize = std::max(1, Settings::Manager::getInt("local map widget size", "Map"));
int cellDistance = std::max(1, Settings::Manager::getInt("local map cell distance", "Map"));
LocalMapBase::init(mLocalMap, mPlayerArrowLocal, mapSize, cellDistance);
LocalMapBase::init(mLocalMap, mPlayerArrowLocal);
mGlobalMap->setVisible(mGlobal);
mLocalMap->setVisible(!mGlobal);

@ -72,7 +72,7 @@ namespace MWGui
public:
LocalMapBase(CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled = true);
virtual ~LocalMapBase();
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int mapWidgetSize, int cellDistance);
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass);
void setCellPrefix(const std::string& prefix);
void setActiveCell(const int x, const int y, bool interior=false);

@ -22,7 +22,7 @@ namespace MWGui
{
MWWorld::Ptr player = MWMechanics::getPlayer();
mSourceModel = sourceModel;
int chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
float chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
mSourceModel->update();

@ -132,6 +132,13 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->injectKeyRelease(MyGUI::KeyCode::None);
}
void SaveGameDialog::onClose()
{
mSaveList->setIndexSelected(MyGUI::ITEM_NONE);
WindowModal::onClose();
}
void SaveGameDialog::onOpen()
{
WindowModal::onOpen();

@ -20,6 +20,7 @@ namespace MWGui
SaveGameDialog();
virtual void onOpen();
virtual void onClose();
void setLoadOrSave(bool load);

@ -163,7 +163,7 @@ namespace MWGui
for (int i=0; ids[i]; ++i)
if (ids[i]==id)
{
setText (id, std::to_string(value.getModified()));
setText (id, std::to_string(static_cast<int>(value.getModified())));
MyGUI::TextBox* box;
getWidget(box, id);
@ -624,10 +624,10 @@ namespace MWGui
text += "\n";
if (rankData.mSkill1 > 0)
text += "\n#{sNeedOneSkill} " + MyGUI::utility::toString(rankData.mSkill1);
if (rankData.mSkill2 > 0)
text += " #{sand} #{sNeedTwoSkills} " + MyGUI::utility::toString(rankData.mSkill2);
if (rankData.mPrimarySkill > 0)
text += "\n#{sNeedOneSkill} " + MyGUI::utility::toString(rankData.mPrimarySkill);
if (rankData.mFavouredSkill > 0)
text += " #{sand} #{sNeedTwoSkills} " + MyGUI::utility::toString(rankData.mFavouredSkill);
}
}

@ -0,0 +1,36 @@
#include "textcolours.hpp"
#include <MyGUI_LanguageManager.h>
#include <string>
namespace MWGui
{
MyGUI::Colour getTextColour(const std::string& type)
{
return MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=" + type + "}"));
}
void TextColours::loadColours()
{
header = getTextColour("header");
normal = getTextColour("normal");
notify = getTextColour("notify");
link = getTextColour("link");
linkOver = getTextColour("link_over");
linkPressed = getTextColour("link_pressed");
answer = getTextColour("answer");
answerOver = getTextColour("answer_over");
answerPressed = getTextColour("answer_pressed");
journalLink = getTextColour("journal_link");
journalLinkOver = getTextColour("journal_link_over");
journalLinkPressed = getTextColour("journal_link_pressed");
journalTopic = getTextColour("journal_topic");
journalTopicOver = getTextColour("journal_topic_over");
journalTopicPressed = getTextColour("journal_topic_pressed");
}
}

@ -5,14 +5,12 @@
namespace MWGui
{
struct TextColours
{
MyGUI::Colour header;
MyGUI::Colour normal;
MyGUI::Colour notify;
MyGUI::Colour link;
MyGUI::Colour linkOver;
MyGUI::Colour linkPressed;
@ -28,6 +26,9 @@ namespace MWGui
MyGUI::Colour journalTopic;
MyGUI::Colour journalTopicOver;
MyGUI::Colour journalTopicPressed;
public:
void loadColours();
};
}

@ -74,11 +74,11 @@ namespace MWGui
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold));
// NPC can train you in his best 3 skills
std::vector< std::pair<int, int> > skills;
std::vector< std::pair<int, float> > skills;
for (int i=0; i<ESM::Skill::Length; ++i)
{
int value = actor.getClass().getSkill(actor, i);
float value = actor.getClass().getSkill(actor, i);
skills.push_back(std::make_pair(i, value));
}

@ -150,11 +150,10 @@ namespace MWGui
if (hour >= 13) hour -= 12;
if (hour == 0) hour = 12;
std::string dateTimeText =
MyGUI::utility::toString(MWBase::Environment::get().getWorld ()->getDay ()) + " "
+ month + " (#{sDay} " + MyGUI::utility::toString(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay())
+ ") " + MyGUI::utility::toString(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}");
ESM::EpochTimeStamp currentDate = MWBase::Environment::get().getWorld()->getEpochTimeStamp();
int daysPassed = MWBase::Environment::get().getWorld()->getTimeStamp().getDay();
std::string formattedHour = pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}";
std::string dateTimeText = Misc::StringUtils::format("%i %s (#{sDay} %i) %i %s", currentDate.mDay, month, daysPassed, hour, formattedHour);
mDateTimeText->setCaptionWithReplacing (dateTimeText);
}

@ -443,6 +443,9 @@ namespace MWGui
// constant effects have no duration and no target
if (!mEffectParams.mIsConstant)
{
if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce))
mEffectParams.mDuration = std::max(1, mEffectParams.mDuration);
if (mEffectParams.mDuration > 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
{
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString("sfor", "") + " " + MyGUI::utility::toString(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs);

@ -122,19 +122,8 @@
#include "../mwvr/vrgui.hpp"
#endif
namespace
{
MyGUI::Colour getTextColour(const std::string& type)
{
return MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=" + type + "}"));
}
}
namespace MWGui
{
WindowManager::WindowManager(
SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue,
const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage,
@ -188,12 +177,6 @@ namespace MWGui
, mCursorActive(false)
, mVideoEnabled(false)
, mPlayerBounty(-1)
, mPlayerName()
, mPlayerRaceId()
, mPlayerAttributes()
, mPlayerMajorSkills()
, mPlayerMinorSkills()
, mPlayerSkillValues()
, mGui(nullptr)
, mGuiModes()
, mCursorManager(nullptr)
@ -204,7 +187,6 @@ namespace MWGui
, mRestAllowed(true)
, mShowOwned(0)
, mEncoding(encoding)
, mFontHeight(16)
, mVersionDescription(versionDescription)
, mWindowVisible(true)
{
@ -246,13 +228,6 @@ namespace MWGui
SpellView::registerComponents();
Gui::registerAllWidgets();
int fontSize = Settings::Manager::getInt("font size", "GUI");
fontSize = std::min(std::max(12, fontSize), 20);
mFontHeight = fontSize;
MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("Resource");
MyGUI::ResourceManager::getInstance().registerLoadXmlDelegate("Resource") = newDelegate(this, &WindowManager::loadFontDelegate);
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerFollowMouse>("Controller");
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
@ -269,7 +244,7 @@ namespace MWGui
mKeyboardNavigation->setEnabled(keyboardNav);
Gui::ImageButton::setDefaultNeedKeyFocus(keyboardNav);
mLoadingScreen = new LoadingScreen(mResourceSystem->getVFS(), mViewer);
mLoadingScreen = new LoadingScreen(mResourceSystem, mViewer);
mWindows.push_back(mLoadingScreen);
//set up the hardware cursor manager
@ -313,94 +288,6 @@ namespace MWGui
Settings::Manager::getFloat("contrast", "Video"));
}
void WindowManager::loadFontDelegate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version)
{
MyGUI::xml::ElementEnumerator resourceNode = _node->getElementEnumerator();
bool createCopy = false;
while (resourceNode.next("Resource"))
{
std::string type, name;
resourceNode->findAttribute("type", type);
resourceNode->findAttribute("name", name);
if (name.empty())
continue;
if (Misc::StringUtils::ciEqual(type, "ResourceTrueTypeFont"))
{
createCopy = true;
// For TrueType fonts we should override Size and Resolution properties
// to allow to configure font size via config file, without need to edit XML files.
// Also we should take UI scaling factor in account.
int resolution = Settings::Manager::getInt("ttf resolution", "GUI");
resolution = std::min(960, std::max(48, resolution));
float uiScale = Settings::Manager::getFloat("scaling factor", "GUI");
resolution *= uiScale;
MyGUI::xml::ElementPtr resolutionNode = resourceNode->createChild("Property");
resolutionNode->addAttribute("key", "Resolution");
resolutionNode->addAttribute("value", std::to_string(resolution));
MyGUI::xml::ElementPtr sizeNode = resourceNode->createChild("Property");
sizeNode->addAttribute("key", "Size");
sizeNode->addAttribute("value", std::to_string(mFontHeight));
}
else if (Misc::StringUtils::ciEqual(type, "ResourceSkin") ||
Misc::StringUtils::ciEqual(type, "AutoSizedResourceSkin"))
{
// We should adjust line height for MyGUI widgets depending on font size
MyGUI::xml::ElementPtr heightNode = resourceNode->createChild("Property");
heightNode->addAttribute("key", "HeightLine");
heightNode->addAttribute("value", std::to_string(mFontHeight+2));
}
}
MyGUI::ResourceManager::getInstance().loadFromXmlNode(_node, _file, _version);
if (createCopy)
{
MyGUI::xml::ElementPtr copy = _node->createCopy();
MyGUI::xml::ElementEnumerator copyFont = copy->getElementEnumerator();
while (copyFont.next("Resource"))
{
std::string type, name;
copyFont->findAttribute("type", type);
copyFont->findAttribute("name", name);
if (name.empty())
continue;
if (Misc::StringUtils::ciEqual(type, "ResourceTrueTypeFont"))
{
// Since the journal and books use the custom scaling factor depending on resolution,
// setup separate fonts with different Resolution to fit these windows.
// These fonts have an internal prefix.
int resolution = Settings::Manager::getInt("ttf resolution", "GUI");
resolution = std::min(960, std::max(48, resolution));
float currentX = Settings::Manager::getInt("resolution x", "Video");
float currentY = Settings::Manager::getInt("resolution y", "Video");
// TODO: read size from openmw_layout.xml
float heightScale = (currentY / 520);
float widthScale = (currentX / 600);
float uiScale = std::min(widthScale, heightScale);
resolution *= uiScale;
MyGUI::xml::ElementPtr resolutionNode = copyFont->createChild("Property");
resolutionNode->addAttribute("key", "Resolution");
resolutionNode->addAttribute("value", std::to_string(resolution));
copyFont->setAttribute("name", "Journalbook " + name);
}
}
MyGUI::ResourceManager::getInstance().loadFromXmlNode(copy, _file, _version);
}
}
void WindowManager::loadUserFonts()
{
mFontLoader->loadTrueTypeFonts();
@ -412,26 +299,7 @@ namespace MWGui
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
int h = MyGUI::RenderManager::getInstance().getViewSize().height;
mTextColours.header = getTextColour("header");
mTextColours.normal = getTextColour("normal");
mTextColours.notify = getTextColour("notify");
mTextColours.link = getTextColour("link");
mTextColours.linkOver = getTextColour("link_over");
mTextColours.linkPressed = getTextColour("link_pressed");
mTextColours.answer = getTextColour("answer");
mTextColours.answerOver = getTextColour("answer_over");
mTextColours.answerPressed = getTextColour("answer_pressed");
mTextColours.journalLink = getTextColour("journal_link");
mTextColours.journalLinkOver = getTextColour("journal_link_over");
mTextColours.journalLinkPressed = getTextColour("journal_link_pressed");
mTextColours.journalTopic = getTextColour("journal_topic");
mTextColours.journalTopicOver = getTextColour("journal_topic_over");
mTextColours.journalTopicPressed = getTextColour("journal_topic_pressed");
mTextColours.loadColours();
mDragAndDrop = new DragAndDrop();
@ -608,17 +476,6 @@ namespace MWGui
mCharGen = new CharacterCreation(mViewer->getSceneData()->asGroup(), mResourceSystem);
// Setup player stats
for (int i = 0; i < ESM::Attribute::Length; ++i)
{
mPlayerAttributes.insert(std::make_pair(ESM::Attribute::sAttributeIds[i], MWMechanics::AttributeValue()));
}
for (int i = 0; i < ESM::Skill::Length; ++i)
{
mPlayerSkillValues.insert(std::make_pair(ESM::Skill::sSkillIds[i], MWMechanics::SkillValue()));
}
updatePinnedWindows();
// Set up visibility
@ -627,7 +484,7 @@ namespace MWGui
int WindowManager::getFontHeight() const
{
return mFontHeight;
return mFontLoader->getFontHeight();
}
void WindowManager::setNewGame(bool newgame)
@ -648,7 +505,6 @@ namespace MWGui
{
mKeyboardNavigation.reset();
MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("Resource");
MyGUI::LanguageManager::getInstance().eventRequestTag.clear();
MyGUI::PointerManager::getInstance().eventChangeMousePointer.clear();
MyGUI::InputManager::getInstance().eventChangeKeyFocus.clear();
@ -811,40 +667,14 @@ namespace MWGui
{
mStatsWindow->setValue (id, value);
mCharGen->setValue(id, value);
static const char *ids[] =
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
"AttribVal6", "AttribVal7", "AttribVal8"
};
static ESM::Attribute::AttributeID attributes[] =
{
ESM::Attribute::Strength,
ESM::Attribute::Intelligence,
ESM::Attribute::Willpower,
ESM::Attribute::Agility,
ESM::Attribute::Speed,
ESM::Attribute::Endurance,
ESM::Attribute::Personality,
ESM::Attribute::Luck
};
for (size_t i = 0; i < sizeof(ids)/sizeof(ids[0]); ++i)
{
if (id != ids[i])
continue;
mPlayerAttributes[attributes[i]] = value;
break;
}
}
void WindowManager::setValue (int parSkill, const MWMechanics::SkillValue& value)
{
/// \todo Don't use the skill enum as a parameter type (we will have to drop it anyway, once we
/// allow custom skills.
mStatsWindow->setValue(static_cast<ESM::Skill::SkillEnum> (parSkill), value);
mCharGen->setValue(static_cast<ESM::Skill::SkillEnum> (parSkill), value);
mPlayerSkillValues[parSkill] = value;
}
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
@ -857,10 +687,6 @@ namespace MWGui
void WindowManager::setValue (const std::string& id, const std::string& value)
{
mStatsWindow->setValue (id, value);
if (id=="name")
mPlayerName = value;
else if (id=="race")
mPlayerRaceId = value;
}
void WindowManager::setValue (const std::string& id, int value)
@ -882,8 +708,6 @@ namespace MWGui
{
mStatsWindow->configureSkills (major, minor);
mCharGen->configureSkills(major, minor);
mPlayerMajorSkills = major;
mPlayerMinorSkills = minor;
}
void WindowManager::updateSkillArea()
@ -1021,7 +845,7 @@ namespace MWGui
mHud->setPlayerPos(x, y, u, v);
}
void WindowManager::onFrame (float frameDuration)
void WindowManager::update (float frameDuration)
{
bool gameRunning = MWBase::Environment::get().getStateManager()->getState()!=
MWBase::StateManager::State_NoGame;
@ -1663,26 +1487,6 @@ namespace MWGui
return mGuiModes.back();
}
std::map<int, MWMechanics::SkillValue > WindowManager::getPlayerSkillValues()
{
return mPlayerSkillValues;
}
std::map<int, MWMechanics::AttributeValue > WindowManager::getPlayerAttributeValues()
{
return mPlayerAttributes;
}
WindowManager::SkillList WindowManager::getPlayerMinorSkills()
{
return mPlayerMinorSkills;
}
WindowManager::SkillList WindowManager::getPlayerMajorSkills()
{
return mPlayerMajorSkills;
}
void WindowManager::disallowMouse()
{
mInputBlocker->setVisible (true);

@ -282,13 +282,7 @@ namespace MWGui
virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
virtual void onFrame (float frameDuration);
/// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
virtual std::map<int, MWMechanics::SkillValue > getPlayerSkillValues();
virtual std::map<int, MWMechanics::AttributeValue > getPlayerAttributeValues();
virtual SkillList getPlayerMinorSkills();
virtual SkillList getPlayerMajorSkills();
virtual void update (float duration);
/**
* Fetches a GMST string from the store, if there is no setting with the given
@ -420,8 +414,6 @@ namespace MWGui
MWWorld::Ptr mSelectedEnchantItem;
MWWorld::Ptr mSelectedWeapon;
void loadFontDelegate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version);
std::vector<WindowModal*> mCurrentModals;
// Markers placed manually by the player. Must be shared between both map views (the HUD map and the map window).
@ -478,14 +470,6 @@ namespace MWGui
void setCursorVisible(bool visible);
/// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
// Various stats about player as needed by window manager
std::string mPlayerName;
std::string mPlayerRaceId;
std::map<int, MWMechanics::AttributeValue > mPlayerAttributes;
SkillList mPlayerMajorSkills, mPlayerMinorSkills;
std::map<int, MWMechanics::SkillValue > mPlayerSkillValues;
MyGUI::Gui *mGui; // Gui
struct GuiModeState
@ -535,8 +519,6 @@ namespace MWGui
ToUTF8::FromType mEncoding;
int mFontHeight;
std::string mVersionDescription;
bool mWindowVisible;

@ -36,7 +36,7 @@ namespace MWInput
, mSneakToggleShortcutTimer(0.f)
, mGamepadZoom(0)
, mGamepadGuiCursorEnabled(true)
, mControlsDisabled(false)
, mGuiCursorEnabled(true)
, mJoystickLastUsed(false)
, mSneakGamepadShortcut(false)
, mGamepadPreviewMode(false)
@ -83,9 +83,8 @@ namespace MWInput
}
}
bool ControllerManager::update(float dt, bool disableControls)
bool ControllerManager::update(float dt)
{
mControlsDisabled = disableControls;
mGamepadPreviewMode = mActionManager->getPreviewDelay() == 1.f;
if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled))
@ -232,7 +231,7 @@ namespace MWInput
auto kc = sdlKeyToMyGUI(SDLK_ESCAPE);
mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(kc, 0));
if (!mControlsDisabled)
if (!MWBase::Environment::get().getInputManager()->controlsDisabled())
mBindingsManager->controllerButtonPressed(deviceID, arg);
}
@ -244,7 +243,7 @@ namespace MWInput
return;
}
if (!mJoystickEnabled || mControlsDisabled)
if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled())
return;
mJoystickLastUsed = true;
@ -275,7 +274,7 @@ namespace MWInput
void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg)
{
if (!mJoystickEnabled || mControlsDisabled)
if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled())
return;
mJoystickLastUsed = true;

@ -23,7 +23,7 @@ namespace MWInput
virtual ~ControllerManager() = default;
bool update(float dt, bool disableControls);
bool update(float dt);
virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg);
virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg);
@ -56,9 +56,8 @@ namespace MWInput
float mSneakToggleShortcutTimer;
float mGamepadZoom;
bool mGamepadGuiCursorEnabled;
bool mControlsDisabled;
bool mJoystickLastUsed;
bool mGuiCursorEnabled;
bool mJoystickLastUsed;
bool mSneakGamepadShortcut;
bool mGamepadPreviewMode;
};

@ -30,7 +30,7 @@ namespace MWInput
osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation,
const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile,
const std::string& controllerBindingsFile, bool grab)
: mGrabCursor(Settings::Manager::getBool("grab cursor", "Input"))
: mControlsDisabled(false)
{
mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab);
mInputWrapper->setWindowEventCallback(MWBase::Environment::get().getWindowManager());
@ -80,47 +80,25 @@ namespace MWInput
mActionManager->setAttemptJump(jumping);
}
void InputManager::updateCursorMode()
{
bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
&& !MWBase::Environment::get().getWindowManager()->isConsoleMode();
bool wasRelative = mInputWrapper->getMouseRelative();
bool isRelative = !MWBase::Environment::get().getWindowManager()->isGuiMode();
// don't keep the pointer away from the window edge in gui mode
// stop using raw mouse motions and switch to system cursor movements
mInputWrapper->setMouseRelative(isRelative);
//we let the mouse escape in the main menu
mInputWrapper->setGrabPointer(grab && (mGrabCursor || isRelative));
//we switched to non-relative mode, move our cursor to where the in-game
//cursor is
if (!isRelative && wasRelative != isRelative)
{
mMouseManager->warpMouse();
}
}
void InputManager::update(float dt, bool disableControls, bool disableEvents)
{
mControlsDisabled = disableControls;
mInputWrapper->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
mInputWrapper->capture(disableEvents);
mKeyboardManager->setControlsDisabled(disableControls);
if (disableControls)
{
updateCursorMode();
mMouseManager->updateCursorMode();
return;
}
mBindingsManager->update(dt);
updateCursorMode();
mMouseManager->updateCursorMode();
bool controllerMove = mControllerManager->update(dt, disableControls);
mMouseManager->update(dt, disableControls);
bool controllerMove = mControllerManager->update(dt);
mMouseManager->update(dt);
mSensorManager->update(dt);
mActionManager->update(dt, controllerMove);
}
@ -151,12 +129,6 @@ namespace MWInput
void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed)
{
for (const auto& setting : changed)
{
if (setting.first == "Input" && setting.second == "grab cursor")
mGrabCursor = Settings::Manager::getBool("grab cursor", "Input");
}
mMouseManager->processChangedSettings(changed);
mSensorManager->processChangedSettings(changed);
}

@ -96,14 +96,15 @@ namespace MWInput
void applyHapticsLeftHand(float intensity) override {};
void applyHapticsRightHand(float intensity) override {};
virtual bool controlsDisabled() { return mControlsDisabled; }
protected:
void convertMousePosForMyGUI(int& x, int& y);
void handleGuiArrowKey(int action);
void updateCursorMode();
//void quickKey(int index);
//void showQuickKeysMenu();
@ -112,7 +113,7 @@ namespace MWInput
SDLUtil::InputWrapper* mInputWrapper;
bool mGrabCursor;
bool mControlsDisabled;
ControlSwitch* mControlSwitch;

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

Loading…
Cancel
Save