mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-06 17:45:33 +00:00
Merge remote-tracking branch 'remotes/origin/master' into openxr_vr
This commit is contained in:
commit
49e76fa077
267 changed files with 2785 additions and 1671 deletions
|
@ -37,6 +37,8 @@ Debian_GCC:
|
|||
CC: gcc
|
||||
CXX: g++
|
||||
CCACHE_SIZE: 3G
|
||||
# When CCache doesn't exist (e.g. first build on a fork), build takes more than 1h, which is the default for forks.
|
||||
timeout: 2h
|
||||
|
||||
Debian_GCC_tests:
|
||||
extends: .Debian
|
||||
|
@ -96,7 +98,7 @@ variables: &cs-targets
|
|||
- windows
|
||||
before_script:
|
||||
- Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
|
||||
- choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolately/" --priority=1
|
||||
- choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolatey/" --priority=1
|
||||
- choco install git --force --params "/GitAndUnixToolsOnPath" -y
|
||||
- choco install 7zip -y
|
||||
- choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y
|
||||
|
@ -120,6 +122,8 @@ variables: &cs-targets
|
|||
Get-ChildItem -Recurse *.pdb | Remove-Item
|
||||
}
|
||||
- 7z a -tzip ..\..\OpenMW_MSVC2019_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.zip '*'
|
||||
after_script:
|
||||
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
||||
cache:
|
||||
key: ninja-v2
|
||||
paths:
|
||||
|
@ -186,7 +190,7 @@ Windows_Ninja_CS_RelWithDebInfo:
|
|||
- windows
|
||||
before_script:
|
||||
- Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
|
||||
- choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolately/" --priority=1
|
||||
- choco source add -n=openmw-proxy -s="https://repo.openmw.org/repository/Chocolatey/" --priority=1
|
||||
- choco install git --force --params "/GitAndUnixToolsOnPath" -y
|
||||
- choco install 7zip -y
|
||||
- choco install cmake.install --installargs 'ADD_CMAKE_TO_PATH=System' -y
|
||||
|
@ -208,6 +212,8 @@ Windows_Ninja_CS_RelWithDebInfo:
|
|||
Get-ChildItem -Recurse *.pdb | Remove-Item
|
||||
}
|
||||
- 7z a -tzip ..\..\OpenMW_MSVC2019_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}.zip '*'
|
||||
after_script:
|
||||
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
||||
cache:
|
||||
key: msbuild-v2
|
||||
paths:
|
||||
|
@ -299,4 +305,4 @@ Debian_AndroidNDK_arm64-v8a:
|
|||
- ccache -s
|
||||
artifacts:
|
||||
paths:
|
||||
- build/install/
|
||||
- build/install/
|
||||
|
|
43
.travis.yml
43
.travis.yml
|
@ -2,19 +2,12 @@ language: cpp
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- coverity_scan
|
||||
- /openmw-.*$/
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "jybGzAdUbqt9vWR/GEnRd96BgAi/7Zd1+2HK68j/i/8+/1YH2XxLOy4Jv/DUBhBlJIkxs/Xv8dRcUlFOclZDHX1d/9Qnsqd3oUVkD7k1y7cTOWy9TBQaE/v/kZo3LpzA3xPwwthrb0BvqIbOfIELi5fS5s8ba85WFRg3AX70wWE="
|
||||
cache: ccache
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'ppa:openmw/openmw'
|
||||
# - ubuntu-toolchain-r-test # for GCC-10
|
||||
packages: [
|
||||
# Dev
|
||||
build-essential, cmake, clang-tools, ccache,
|
||||
|
@ -23,32 +16,21 @@ addons:
|
|||
# FFmpeg
|
||||
libavcodec-dev, libavformat-dev, libavutil-dev, libswresample-dev, libswscale-dev,
|
||||
# Audio, Video and Misc. deps
|
||||
libsdl2-dev, libqt5opengl5-dev, libopenal-dev, libunshield-dev, libtinyxml-dev, liblz4-dev
|
||||
libsdl2-dev, libqt5opengl5-dev, libopenal-dev, libunshield-dev, libtinyxml-dev, liblz4-dev,
|
||||
# The other ones from OpenMW ppa
|
||||
libbullet-dev, libopenscenegraph-dev, libmygui-dev
|
||||
]
|
||||
coverity_scan: # TODO: currently takes too long, disabled openmw/openmw-cs for now.
|
||||
project:
|
||||
name: "OpenMW/openmw"
|
||||
description: "<Your project description here>"
|
||||
branch_pattern: coverity_scan
|
||||
notification_email: 1122069+psi29a@users.noreply.github.com
|
||||
build_command_prepend: "cov-configure --comptype gcc --compiler gcc-5 --template; cmake . -DBUILD_OPENMW=FALSE -DBUILD_OPENCS=FALSE"
|
||||
build_command: "make VERBOSE=1 -j3"
|
||||
matrix:
|
||||
include:
|
||||
- name: OpenMW (all) on MacOS 10.15 with Xcode 11.6
|
||||
os: osx
|
||||
osx_image: xcode11.6
|
||||
if: branch != coverity_scan
|
||||
- name: OpenMW (all) on Ubuntu Focal with GCC
|
||||
os: linux
|
||||
dist: focal
|
||||
if: branch != coverity_scan
|
||||
- name: OpenMW (tests only) on Ubuntu Focal with GCC
|
||||
os: linux
|
||||
dist: focal
|
||||
if: branch != coverity_scan
|
||||
env:
|
||||
- BUILD_TESTS_ONLY: 1
|
||||
- name: OpenMW (openmw) on Ubuntu Focal with Clang's Static Analysis
|
||||
|
@ -57,30 +39,21 @@ matrix:
|
|||
env:
|
||||
- MATRIX_EVAL="CC=clang && CXX=clang++"
|
||||
- ANALYZE="scan-build --force-analyze-debug-code --use-cc clang --use-c++ clang++"
|
||||
if: branch != coverity_scan
|
||||
compiler: clang
|
||||
- name: OpenMW Components Coverity Scan
|
||||
os: linux
|
||||
dist: focal
|
||||
if: branch = coverity_scan
|
||||
# allow_failures:
|
||||
# - name: OpenMW (openmw) on Ubuntu Focal with GCC-10
|
||||
# env:
|
||||
# - MATRIX_EVAL="CC=gcc-10 && CXX=g++-10"
|
||||
|
||||
before_install:
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then eval "${MATRIX_EVAL}"; fi
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./CI/before_install.${TRAVIS_OS_NAME}.sh; fi
|
||||
- ./CI/before_install.${TRAVIS_OS_NAME}.sh
|
||||
before_script:
|
||||
- ccache -z
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./CI/before_script.${TRAVIS_OS_NAME}.sh; fi
|
||||
- ./CI/before_script.${TRAVIS_OS_NAME}.sh
|
||||
script:
|
||||
- cd ./build
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ${ANALYZE} make -j3; fi
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ] && [ "${BUILD_TESTS_ONLY}" ]; then ./openmw_test_suite; fi
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ] && [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi
|
||||
- ${ANALYZE} make -j3;
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then make package; fi
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ../CI/check_package.osx.sh; fi
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ] && [ "${BUILD_TESTS_ONLY}" ]; then ./openmw_test_suite; fi
|
||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then cd .. && ./CI/check_tabs.sh; fi
|
||||
- cd "${TRAVIS_BUILD_DIR}"
|
||||
- ccache -s
|
||||
deploy:
|
||||
|
|
|
@ -96,6 +96,7 @@ Programmers
|
|||
Jan Borsodi (am0s)
|
||||
Jason Hooks (jhooks)
|
||||
jeaye
|
||||
jefetienne
|
||||
Jeffrey Haines (Jyby)
|
||||
Jengerer
|
||||
Jiří Kuneš (kunesj)
|
||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -7,12 +7,15 @@
|
|||
Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs
|
||||
Bug #2473: Unable to overstock merchants
|
||||
Bug #2798: Mutable ESM records
|
||||
Bug #2976 [reopened]: Issues combining settings from the command line and both config files
|
||||
Bug #3676: NiParticleColorModifier isn't applied properly
|
||||
Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects
|
||||
Bug #3789: Crash in visitEffectSources while in battle
|
||||
Bug #3862: Random container contents behave differently than vanilla
|
||||
Bug #3929: Leveled list merchant containers respawn on barter
|
||||
Bug #4021: Attributes and skills are not stored as floats
|
||||
Bug #4055: Local scripts don't inherit variables from their base record
|
||||
Bug #4083: Door animation freezes when colliding with actors
|
||||
Bug #4623: Corprus implementation is incorrect
|
||||
Bug #4631: Setting MSAA level too high doesn't fall back to highest supported level
|
||||
Bug #4764: Data race in osg ParticleSystem
|
||||
|
@ -33,6 +36,7 @@
|
|||
Bug #5403: Enchantment effect doesn't show on an enemy during death animation
|
||||
Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work
|
||||
Bug #5416: Junk non-node records before the root node are not handled gracefully
|
||||
Bug #5422: The player loses all spells when resurrected
|
||||
Bug #5424: Creatures do not headtrack player
|
||||
Bug #5425: Poison effect only appears for one frame
|
||||
Bug #5427: GetDistance unknown ID error is misleading
|
||||
|
@ -56,8 +60,12 @@
|
|||
Bug #5603: Setting constant effect cast style doesn't correct effects view
|
||||
Bug #5611: Usable items with "0 Uses" should be used only once
|
||||
Bug #5622: Can't properly interact with the console when in pause menu
|
||||
Bug #5633: Damage Spells in effect before god mode is enabled continue to hurt the player character and can kill them
|
||||
Bug #5639: Tooltips cover Messageboxes
|
||||
Bug #5644: Summon effects running on the player during game initialization cause crashes
|
||||
Bug #5656: Sneaking characters block hits while standing
|
||||
Bug #5661: Region sounds don't play at the right interval
|
||||
Bug #5688: Water shader broken indoors with enable indoor shadows = false
|
||||
Feature #390: 3rd person look "over the shoulder"
|
||||
Feature #2386: Distant Statics in the form of Object Paging
|
||||
Feature #2404: Levelled List can not be placed into a container
|
||||
|
@ -78,6 +86,8 @@
|
|||
Feature #5610: Actors movement should be smoother
|
||||
Feature #5642: Ability to attach arrows to actor skeleton instead of bow mesh
|
||||
Feature #5649: Skyrim SE compressed BSA format support
|
||||
Feature #5672: Make stretch menu background configuration more accessible
|
||||
Feature #5692: Improve spell/magic item search to factor in magic effect names
|
||||
Task #5480: Drop Qt4 support
|
||||
Task #5520: Improve cell name autocompleter implementation
|
||||
|
||||
|
|
|
@ -5,8 +5,5 @@ command -v ccache >/dev/null 2>&1 || brew install ccache
|
|||
command -v cmake >/dev/null 2>&1 || brew install cmake
|
||||
command -v qmake >/dev/null 2>&1 || brew install qt
|
||||
|
||||
brew link --overwrite lz4 # overwrite system lz4; use brew
|
||||
brew reinstall lz4
|
||||
|
||||
curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-ef2462c.zip -o ~/openmw-deps.zip
|
||||
curl -fSL -R -J https://downloads.openmw.org/osx/dependencies/openmw-deps-f8918dd.zip -o ~/openmw-deps.zip
|
||||
unzip -o ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null
|
||||
|
|
|
@ -917,7 +917,7 @@ printf "LZ4 1.9.2... "
|
|||
printf "Exists. "
|
||||
elif [ -z $SKIP_EXTRACT ]; then
|
||||
rm -rf LZ4_1.9.2
|
||||
eval 7z x -y lz4_win${BITS}_v1_9_2.7z -o./LZ4_1.9.2 $STRIP
|
||||
eval 7z x -y lz4_win${BITS}_v1_9_2.7z -o$(real_pwd)/LZ4_1.9.2 $STRIP
|
||||
fi
|
||||
export LZ4DIR="$(real_pwd)/LZ4_1.9.2"
|
||||
add_cmake_opts -DLZ4_INCLUDE_DIR="${LZ4DIR}/include" \
|
||||
|
|
|
@ -25,5 +25,6 @@ cmake \
|
|||
-D BUILD_BSATOOL=TRUE \
|
||||
-D BUILD_ESSIMPORTER=TRUE \
|
||||
-D BUILD_NIFTEST=TRUE \
|
||||
-D BULLET_USE_DOUBLES=TRUE \
|
||||
-G"Unix Makefiles" \
|
||||
..
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
project(OpenMW)
|
||||
cmake_minimum_required(VERSION 3.1.0)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# for link time optimization, remove if cmake version is >= 3.9
|
||||
if(POLICY CMP0069)
|
||||
|
@ -307,7 +309,7 @@ endif()
|
|||
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
find_package(Boost 1.6.2 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
find_package(MyGUI 3.2.2 REQUIRED)
|
||||
find_package(SDL2 2.0.9 REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
|
@ -394,9 +396,6 @@ if (NOT WIN32 AND NOT APPLE)
|
|||
"${OpenMW_BINARY_DIR}/org.openmw.cs.desktop")
|
||||
endif()
|
||||
|
||||
# CXX Compiler settings
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if(OPENMW_LTO_BUILD)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.9)
|
||||
include(CheckIPOSupported)
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <components/bsa/bsa_file.hpp>
|
||||
#include <components/bsa/compressedbsafile.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#define BSATOOL_VERSION 1.1
|
||||
|
||||
|
@ -25,16 +26,6 @@ struct Arguments
|
|||
bool fullpath;
|
||||
};
|
||||
|
||||
void replaceAll(std::string& str, const std::string& needle, const std::string& substitute)
|
||||
{
|
||||
size_t pos = str.find(needle);
|
||||
while(pos != std::string::npos)
|
||||
{
|
||||
str.replace(pos, needle.size(), substitute);
|
||||
pos = str.find(needle);
|
||||
}
|
||||
}
|
||||
|
||||
bool parseOptions (int argc, char** argv, Arguments &info)
|
||||
{
|
||||
bpo::options_description desc("Inspect and extract files from Bethesda BSA archives\n\n"
|
||||
|
@ -144,9 +135,9 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
|||
return true;
|
||||
}
|
||||
|
||||
int list(Bsa::BSAFile& bsa, Arguments& info);
|
||||
int extract(Bsa::BSAFile& bsa, Arguments& info);
|
||||
int extractAll(Bsa::BSAFile& bsa, Arguments& info);
|
||||
int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
|
||||
int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
|
||||
int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
@ -157,8 +148,16 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
|
||||
// Open file
|
||||
Bsa::BSAFile bsa;
|
||||
bsa.open(info.filename);
|
||||
std::unique_ptr<Bsa::BSAFile> bsa;
|
||||
|
||||
Bsa::BsaVersion bsaVersion = Bsa::CompressedBSAFile::detectVersion(info.filename);
|
||||
|
||||
if (bsaVersion == Bsa::BSAVER_COMPRESSED)
|
||||
bsa = std::make_unique<Bsa::CompressedBSAFile>(Bsa::CompressedBSAFile());
|
||||
else
|
||||
bsa = std::make_unique<Bsa::BSAFile>(Bsa::BSAFile());
|
||||
|
||||
bsa->open(info.filename);
|
||||
|
||||
if (info.mode == "list")
|
||||
return list(bsa, info);
|
||||
|
@ -179,10 +178,10 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
int list(Bsa::BSAFile& bsa, Arguments& info)
|
||||
int list(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
|
||||
{
|
||||
// List all files
|
||||
const Bsa::BSAFile::FileList &files = bsa.getList();
|
||||
const Bsa::BSAFile::FileList &files = bsa->getList();
|
||||
for (const auto& file : files)
|
||||
{
|
||||
if(info.longformat)
|
||||
|
@ -201,15 +200,15 @@ int list(Bsa::BSAFile& bsa, Arguments& info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int extract(Bsa::BSAFile& bsa, Arguments& info)
|
||||
int extract(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
|
||||
{
|
||||
std::string archivePath = info.extractfile;
|
||||
replaceAll(archivePath, "/", "\\");
|
||||
Misc::StringUtils::replaceAll(archivePath, "/", "\\");
|
||||
|
||||
std::string extractPath = info.extractfile;
|
||||
replaceAll(extractPath, "\\", "/");
|
||||
Misc::StringUtils::replaceAll(extractPath, "\\", "/");
|
||||
|
||||
if (!bsa.exists(archivePath.c_str()))
|
||||
if (!bsa->exists(archivePath.c_str()))
|
||||
{
|
||||
std::cout << "ERROR: file '" << archivePath << "' not found\n";
|
||||
std::cout << "In archive: " << info.filename << std::endl;
|
||||
|
@ -237,7 +236,7 @@ int extract(Bsa::BSAFile& bsa, Arguments& info)
|
|||
}
|
||||
|
||||
// Get a stream for the file to extract
|
||||
Files::IStreamPtr stream = bsa.getFile(archivePath.c_str());
|
||||
Files::IStreamPtr stream = bsa->getFile(archivePath.c_str());
|
||||
|
||||
bfs::ofstream out(target, std::ios::binary);
|
||||
|
||||
|
@ -250,12 +249,12 @@ int extract(Bsa::BSAFile& bsa, Arguments& info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int extractAll(Bsa::BSAFile& bsa, Arguments& info)
|
||||
int extractAll(std::unique_ptr<Bsa::BSAFile>& bsa, Arguments& info)
|
||||
{
|
||||
for (const auto &file : bsa.getList())
|
||||
for (const auto &file : bsa->getList())
|
||||
{
|
||||
std::string extractPath(file.name);
|
||||
replaceAll(extractPath, "\\", "/");
|
||||
Misc::StringUtils::replaceAll(extractPath, "\\", "/");
|
||||
|
||||
// Get the target path (the path the file will be extracted to)
|
||||
bfs::path target (info.outdir);
|
||||
|
@ -273,7 +272,7 @@ int extractAll(Bsa::BSAFile& bsa, Arguments& info)
|
|||
|
||||
// Get a stream for the file to extract
|
||||
// (inefficient because getFile iter on the list again)
|
||||
Files::IStreamPtr data = bsa.getFile(file.name);
|
||||
Files::IStreamPtr data = bsa->getFile(file.name);
|
||||
bfs::ofstream out(target, std::ios::binary);
|
||||
|
||||
// Write the file to disk
|
||||
|
|
|
@ -152,6 +152,7 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
// Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid.
|
||||
if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
|
||||
showOwnedComboBox->setCurrentIndex(showOwnedIndex);
|
||||
loadSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI");
|
||||
}
|
||||
|
||||
// Bug fixes
|
||||
|
@ -277,6 +278,7 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
|
||||
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game"))
|
||||
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex);
|
||||
saveSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI");
|
||||
}
|
||||
|
||||
// Bug fixes
|
||||
|
|
|
@ -211,10 +211,10 @@ void Launcher::MainDialog::setVersionLabel()
|
|||
versionLabel->setText(tr("OpenMW development (%1)").arg(revision.left(10)));
|
||||
|
||||
// Add the compile date and time
|
||||
versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale(QLocale::C).toDate(QString(__DATE__).simplified(),
|
||||
QLatin1String("MMM d yyyy")).toString(Qt::SystemLocaleLongDate),
|
||||
QLocale(QLocale::C).toTime(QString(__TIME__).simplified(),
|
||||
QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate)));
|
||||
auto compileDate = QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), QLatin1String("MMM d yyyy"));
|
||||
auto compileTime = QLocale(QLocale::C).toTime(QString(__TIME__).simplified(), QLatin1String("hh:mm:ss"));
|
||||
versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale::system().toString(compileDate, QLocale::LongFormat),
|
||||
QLocale::system().toString(compileTime, QLocale::ShortFormat)));
|
||||
}
|
||||
|
||||
bool Launcher::MainDialog::setup()
|
||||
|
|
|
@ -645,7 +645,7 @@ MwIniImporter::MwIniImporter()
|
|||
}
|
||||
|
||||
for(int i=0; fallback[i]; i++) {
|
||||
mMergeFallback.push_back(fallback[i]);
|
||||
mMergeFallback.emplace_back(fallback[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -910,7 +910,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co
|
|||
std::time_t time = lastWriteTime(path, defaultTime);
|
||||
if (time != defaultTime)
|
||||
{
|
||||
contentFiles.push_back({time, path});
|
||||
contentFiles.emplace_back(time, std::move(path));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -985,14 +985,7 @@ std::time_t MwIniImporter::lastWriteTime(const boost::filesystem::path& filename
|
|||
std::time_t writeTime(defaultTime);
|
||||
if (boost::filesystem::exists(filename))
|
||||
{
|
||||
// FixMe: remove #if when Boost dependency for Linux builds updated
|
||||
// This allows Linux to build until then
|
||||
#if (BOOST_VERSION >= 104800)
|
||||
// need to resolve any symlinks so that we get time of file, not symlink
|
||||
boost::filesystem::path resolved = boost::filesystem::canonical(filename);
|
||||
#else
|
||||
boost::filesystem::path resolved = filename;
|
||||
#endif
|
||||
writeTime = boost::filesystem::last_write_time(resolved);
|
||||
|
||||
// print timestamp
|
||||
|
|
|
@ -132,6 +132,7 @@ int main(int argc, char **argv)
|
|||
if(!parseOptions (argc, argv, files))
|
||||
return 1;
|
||||
|
||||
Nif::NIFFile::setLoadUnsupportedFiles(true);
|
||||
// std::cout << "Reading Files" << std::endl;
|
||||
for(std::vector<std::string>::const_iterator it=files.begin(); it!=files.end(); ++it)
|
||||
{
|
||||
|
|
|
@ -89,10 +89,10 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
|||
|
||||
desc.add_options()
|
||||
("data", boost::program_options::value<Files::EscapePathContainer>()->default_value(Files::EscapePathContainer(), "data")->multitoken()->composing())
|
||||
("data-local", boost::program_options::value<Files::EscapeHashString>()->default_value(""))
|
||||
("data-local", boost::program_options::value<Files::EscapePath>()->default_value(Files::EscapePath(), ""))
|
||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||
("encoding", boost::program_options::value<Files::EscapeHashString>()->default_value("win1252"))
|
||||
("resources", boost::program_options::value<Files::EscapeHashString>()->default_value("resources"))
|
||||
("resources", boost::program_options::value<Files::EscapePath>()->default_value(Files::EscapePath(), "resources"))
|
||||
("fallback-archive", boost::program_options::value<Files::EscapeStringVector>()->
|
||||
default_value(Files::EscapeStringVector(), "fallback-archive")->multitoken())
|
||||
("fallback", boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "")
|
||||
|
@ -112,7 +112,7 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
|||
mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName));
|
||||
mFileDialog.setEncoding (QString::fromUtf8(mEncodingName.c_str()));
|
||||
|
||||
mDocumentManager.setResourceDir (mResources = variables["resources"].as<Files::EscapeHashString>().toStdString());
|
||||
mDocumentManager.setResourceDir (mResources = variables["resources"].as<Files::EscapePath>().mPath);
|
||||
|
||||
if (variables["script-blacklist-use"].as<bool>())
|
||||
mDocumentManager.setBlacklistedScripts (
|
||||
|
@ -125,14 +125,9 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
|||
dataDirs = Files::PathContainer(Files::EscapePath::toPathContainer(variables["data"].as<Files::EscapePathContainer>()));
|
||||
}
|
||||
|
||||
std::string local = variables["data-local"].as<Files::EscapeHashString>().toStdString();
|
||||
Files::PathContainer::value_type local(variables["data-local"].as<Files::EscapePath>().mPath);
|
||||
if (!local.empty())
|
||||
{
|
||||
if (local.front() == '\"')
|
||||
local = local.substr(1, local.length() - 2);
|
||||
|
||||
dataLocal.push_back(Files::PathContainer::value_type(local));
|
||||
}
|
||||
dataLocal.push_back(local);
|
||||
|
||||
mCfgMgr.processPaths (dataDirs);
|
||||
mCfgMgr.processPaths (dataLocal, true);
|
||||
|
@ -229,7 +224,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath, const std::
|
|||
if(discoveredFiles.empty())
|
||||
{
|
||||
for (const QString &path : mFileDialog.selectedFilePaths())
|
||||
files.push_back(path.toUtf8().constData());
|
||||
files.emplace_back(path.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -246,7 +241,7 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
|
|||
std::vector<boost::filesystem::path> files;
|
||||
|
||||
for (const QString &path : mFileDialog.selectedFilePaths()) {
|
||||
files.push_back(path.toUtf8().constData());
|
||||
files.emplace_back(path.toUtf8().constData());
|
||||
}
|
||||
|
||||
files.push_back (savePath);
|
||||
|
|
|
@ -47,9 +47,6 @@ int runApplication(int argc, char *argv[])
|
|||
setenv("OSG_GL_TEXTURE_STORAGE", "OFF", 0);
|
||||
#endif
|
||||
|
||||
// To allow background thread drawing in OSG
|
||||
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
|
||||
|
||||
Q_INIT_RESOURCE (resources);
|
||||
|
||||
qRegisterMetaType<std::string> ("std::string");
|
||||
|
|
|
@ -127,7 +127,7 @@ void CSMDoc::Loader::load()
|
|||
|
||||
void CSMDoc::Loader::loadDocument (CSMDoc::Document *document)
|
||||
{
|
||||
mDocuments.push_back (std::make_pair (document, Stage()));
|
||||
mDocuments.emplace_back (document, Stage());
|
||||
}
|
||||
|
||||
void CSMDoc::Loader::abortLoading (CSMDoc::Document *document)
|
||||
|
|
|
@ -57,7 +57,7 @@ void CSMDoc::Operation::run()
|
|||
|
||||
void CSMDoc::Operation::appendStage (Stage *stage)
|
||||
{
|
||||
mStages.push_back (std::make_pair (stage, 0));
|
||||
mStages.emplace_back (stage, 0);
|
||||
}
|
||||
|
||||
void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity)
|
||||
|
|
|
@ -35,7 +35,7 @@ CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValue& value)
|
|||
|
||||
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const std::string& tooltip)
|
||||
{
|
||||
mValues.push_back (EnumValue (value, tooltip));
|
||||
mValues.emplace_back(value, tooltip);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ namespace CSMPrefs
|
|||
}
|
||||
else if (pos == lastPos)
|
||||
{
|
||||
potentials.push_back(std::make_pair(result, shortcut));
|
||||
potentials.emplace_back(result, shortcut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ std::vector<CSMWorld::UniversalId> CSMWorld::CommandDispatcher::getExtendedTypes
|
|||
if (mId==UniversalId::Type_Cells)
|
||||
{
|
||||
tables.push_back (mId);
|
||||
tables.push_back (UniversalId::Type_References);
|
||||
tables.emplace_back(UniversalId::Type_References);
|
||||
/// \todo add other cell-specific types
|
||||
}
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
|
|||
// If it does not exist or it is in the current plugin, it can be skipped.
|
||||
if (oldRow < 0 || plugin == 0)
|
||||
{
|
||||
results.recordMapping.push_back(std::make_pair(id, id));
|
||||
results.recordMapping.emplace_back(id, id);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
|
|||
auto searchIt = reverseLookupMap.find(texture);
|
||||
if (searchIt != reverseLookupMap.end())
|
||||
{
|
||||
results.recordMapping.push_back(std::make_pair(id, searchIt->second));
|
||||
results.recordMapping.emplace_back(id, searchIt->second);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -381,7 +381,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
|
|||
// Id not taken, clone it
|
||||
cloneRecord(id, newId, UniversalId::Type_LandTexture);
|
||||
results.createdRecords.push_back(newId);
|
||||
results.recordMapping.push_back(std::make_pair(id, newId));
|
||||
results.recordMapping.emplace_back(id, newId);
|
||||
reverseLookupMap.emplace(texture, newId);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
|||
|
||||
// ignore content file number
|
||||
std::map<ESM::RefNum, std::string>::iterator iter = cache.begin();
|
||||
ref.mRefNum.mIndex = ref.mRefNum.mIndex & 0x00ffffff;
|
||||
for (; iter != cache.end(); ++iter)
|
||||
{
|
||||
if (ref.mRefNum.mIndex == iter->first.mIndex)
|
||||
|
|
|
@ -40,45 +40,45 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
{
|
||||
BaseColumns baseColumns;
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Id, ColumnBase::Display_Id,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
mColumns.emplace_back(Columns::ColumnId_Id, ColumnBase::Display_Id,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false);
|
||||
baseColumns.mId = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Modification, ColumnBase::Display_RecordState,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false));
|
||||
mColumns.emplace_back(Columns::ColumnId_Modification, ColumnBase::Display_RecordState,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false);
|
||||
baseColumns.mModified = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
mColumns.emplace_back(Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false);
|
||||
baseColumns.mType = &mColumns.back();
|
||||
|
||||
ModelColumns modelColumns (baseColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Model, ColumnBase::Display_Mesh));
|
||||
mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh);
|
||||
modelColumns.mModel = &mColumns.back();
|
||||
|
||||
NameColumns nameColumns (modelColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Name, ColumnBase::Display_String));
|
||||
mColumns.emplace_back(Columns::ColumnId_Name, ColumnBase::Display_String);
|
||||
nameColumns.mName = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Script, ColumnBase::Display_Script));
|
||||
mColumns.emplace_back(Columns::ColumnId_Script, ColumnBase::Display_Script);
|
||||
nameColumns.mScript = &mColumns.back();
|
||||
|
||||
InventoryColumns inventoryColumns (nameColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Icon, ColumnBase::Display_Icon));
|
||||
mColumns.emplace_back(Columns::ColumnId_Icon, ColumnBase::Display_Icon);
|
||||
inventoryColumns.mIcon = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Weight, ColumnBase::Display_Float));
|
||||
mColumns.emplace_back(Columns::ColumnId_Weight, ColumnBase::Display_Float);
|
||||
inventoryColumns.mWeight = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_CoinValue, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_CoinValue, ColumnBase::Display_Integer);
|
||||
inventoryColumns.mValue = &mColumns.back();
|
||||
|
||||
IngredientColumns ingredientColumns (inventoryColumns);
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_EffectList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
ingredientColumns.mEffects = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> ingredientEffectsMap;
|
||||
ingredientEffectsMap.insert(std::make_pair(UniversalId::Type_Ingredient,
|
||||
new IngredEffectRefIdAdapter ()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), ingredientEffectsMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), ingredientEffectsMap);
|
||||
mColumns.back().addColumn(
|
||||
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_IngredEffectId));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -88,13 +88,13 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
// nested table
|
||||
PotionColumns potionColumns (inventoryColumns);
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_EffectList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> effectsMap;
|
||||
effectsMap.insert(std::make_pair(UniversalId::Type_Potion,
|
||||
new EffectsRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), effectsMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), effectsMap);
|
||||
mColumns.back().addColumn(
|
||||
new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -114,67 +114,67 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
EnchantableColumns enchantableColumns (inventoryColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment));
|
||||
mColumns.emplace_back(Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment);
|
||||
enchantableColumns.mEnchantment = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer);
|
||||
enchantableColumns.mEnchantmentPoints = &mColumns.back();
|
||||
|
||||
ToolColumns toolsColumns (inventoryColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Quality, ColumnBase::Display_Float));
|
||||
mColumns.emplace_back(Columns::ColumnId_Quality, ColumnBase::Display_Float);
|
||||
toolsColumns.mQuality = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Charges, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_Charges, ColumnBase::Display_Integer);
|
||||
toolsColumns.mUses = &mColumns.back();
|
||||
|
||||
ActorColumns actorsColumns (nameColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger16));
|
||||
mColumns.emplace_back(Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger16);
|
||||
actorsColumns.mHello = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFlee, ColumnBase::Display_UnsignedInteger8));
|
||||
mColumns.emplace_back(Columns::ColumnId_AiFlee, ColumnBase::Display_UnsignedInteger8);
|
||||
actorsColumns.mFlee = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_AiFight, ColumnBase::Display_UnsignedInteger8));
|
||||
mColumns.emplace_back(Columns::ColumnId_AiFight, ColumnBase::Display_UnsignedInteger8);
|
||||
actorsColumns.mFight = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_UnsignedInteger8));
|
||||
mColumns.emplace_back(Columns::ColumnId_AiAlarm, ColumnBase::Display_UnsignedInteger8);
|
||||
actorsColumns.mAlarm = &mColumns.back();
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_ActorInventory,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
actorsColumns.mInventory = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> inventoryMap;
|
||||
inventoryMap.insert(std::make_pair(UniversalId::Type_Npc,
|
||||
new NestedInventoryRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
|
||||
inventoryMap.insert(std::make_pair(UniversalId::Type_Creature,
|
||||
new NestedInventoryRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), inventoryMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_SpellList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
actorsColumns.mSpells = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> spellsMap;
|
||||
spellsMap.insert(std::make_pair(UniversalId::Type_Npc,
|
||||
new NestedSpellRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
|
||||
spellsMap.insert(std::make_pair(UniversalId::Type_Creature,
|
||||
new NestedSpellRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), spellsMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell));
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_NpcDestinations,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
actorsColumns.mDestinations = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> destMap;
|
||||
destMap.insert(std::make_pair(UniversalId::Type_Npc,
|
||||
new NestedTravelRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
|
||||
destMap.insert(std::make_pair(UniversalId::Type_Creature,
|
||||
new NestedTravelRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), destMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -191,15 +191,15 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Double));
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_AiPackageList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_AiPackageList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
actorsColumns.mAiPackages = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> aiMap;
|
||||
aiMap.insert(std::make_pair(UniversalId::Type_Npc,
|
||||
new ActorAiRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc)));
|
||||
aiMap.insert(std::make_pair(UniversalId::Type_Creature,
|
||||
new ActorAiRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), aiMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), aiMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_AiPackageType, CSMWorld::ColumnBase::Display_AiPackageType));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -270,56 +270,56 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
for (int i=0; sServiceTable[i].mName!=-1; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sServiceTable[i].mName, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(sServiceTable[i].mName, ColumnBase::Display_Boolean);
|
||||
actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag));
|
||||
}
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
||||
mColumns.emplace_back(Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh);
|
||||
const RefIdColumn *autoCalc = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_ApparatusType,
|
||||
ColumnBase::Display_ApparatusType));
|
||||
mColumns.emplace_back(Columns::ColumnId_ApparatusType,
|
||||
ColumnBase::Display_ApparatusType);
|
||||
const RefIdColumn *apparatusType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_ArmorType, ColumnBase::Display_ArmorType));
|
||||
mColumns.emplace_back(Columns::ColumnId_ArmorType, ColumnBase::Display_ArmorType);
|
||||
const RefIdColumn *armorType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Health, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_Health, ColumnBase::Display_Integer);
|
||||
const RefIdColumn *health = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer);
|
||||
const RefIdColumn *armor = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_BookType, ColumnBase::Display_BookType));
|
||||
mColumns.emplace_back(Columns::ColumnId_BookType, ColumnBase::Display_BookType);
|
||||
const RefIdColumn *bookType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Skill, ColumnBase::Display_SkillId));
|
||||
mColumns.emplace_back(Columns::ColumnId_Skill, ColumnBase::Display_SkillId);
|
||||
const RefIdColumn *skill = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Text, ColumnBase::Display_LongString));
|
||||
mColumns.emplace_back(Columns::ColumnId_Text, ColumnBase::Display_LongString);
|
||||
const RefIdColumn *text = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType));
|
||||
mColumns.emplace_back(Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType);
|
||||
const RefIdColumn *clothingType = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeightCapacity, ColumnBase::Display_Float));
|
||||
mColumns.emplace_back(Columns::ColumnId_WeightCapacity, ColumnBase::Display_Float);
|
||||
const RefIdColumn *weightCapacity = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_OrganicContainer, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(Columns::ColumnId_OrganicContainer, ColumnBase::Display_Boolean);
|
||||
const RefIdColumn *organic = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(Columns::ColumnId_Respawn, ColumnBase::Display_Boolean);
|
||||
const RefIdColumn *respawn = &mColumns.back();
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_ContainerContent,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
const RefIdColumn *content = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> contMap;
|
||||
contMap.insert(std::make_pair(UniversalId::Type_Container,
|
||||
new NestedInventoryRefIdAdapter<ESM::Container> (UniversalId::Type_Container)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), contMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -327,11 +327,11 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
CreatureColumns creatureColumns (actorsColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType));
|
||||
mColumns.emplace_back(Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType);
|
||||
creatureColumns.mType = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Scale, ColumnBase::Display_Float));
|
||||
mColumns.emplace_back(Columns::ColumnId_Scale, ColumnBase::Display_Float);
|
||||
creatureColumns.mScale = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_ParentCreature, ColumnBase::Display_Creature));
|
||||
mColumns.emplace_back(Columns::ColumnId_ParentCreature, ColumnBase::Display_Creature);
|
||||
creatureColumns.mOriginal = &mColumns.back();
|
||||
|
||||
static const struct
|
||||
|
@ -354,7 +354,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
for (int i=0; sCreatureFlagTable[i].mName!=-1; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean);
|
||||
creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag));
|
||||
|
||||
switch (sCreatureFlagTable[i].mFlag)
|
||||
|
@ -363,7 +363,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
}
|
||||
}
|
||||
|
||||
mColumns.push_back(RefIdColumn(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType));
|
||||
mColumns.emplace_back(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType);
|
||||
// For re-use in NPC records.
|
||||
const RefIdColumn *bloodType = &mColumns.back();
|
||||
creatureColumns.mBloodType = bloodType;
|
||||
|
@ -371,24 +371,24 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn));
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_CreatureAttributes,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_CreatureAttributes,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
creatureColumns.mAttributes = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> creaAttrMap;
|
||||
creaAttrMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttributesRefIdAdapter()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), creaAttrMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), creaAttrMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_AttributeValue, CSMWorld::ColumnBase::Display_Integer));
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_CreatureAttack,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_CreatureAttack,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
creatureColumns.mAttacks = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> attackMap;
|
||||
attackMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttackRefIdAdapter()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), attackMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), attackMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_CreatureAttack, CSMWorld::ColumnBase::Display_Integer, false, false));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -397,12 +397,12 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
new RefIdColumn (Columns::ColumnId_MaxAttack, CSMWorld::ColumnBase::Display_Integer));
|
||||
|
||||
// Nested list
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_CreatureMisc,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
|
||||
mColumns.emplace_back(Columns::ColumnId_CreatureMisc,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List);
|
||||
creatureColumns.mMisc = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> creaMiscMap;
|
||||
creaMiscMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureMiscRefIdAdapter()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), creaMiscMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), creaMiscMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_Integer,
|
||||
ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));
|
||||
|
@ -423,27 +423,27 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer));
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_OpenSound, ColumnBase::Display_Sound));
|
||||
mColumns.emplace_back(Columns::ColumnId_OpenSound, ColumnBase::Display_Sound);
|
||||
const RefIdColumn *openSound = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_CloseSound, ColumnBase::Display_Sound));
|
||||
mColumns.emplace_back(Columns::ColumnId_CloseSound, ColumnBase::Display_Sound);
|
||||
const RefIdColumn *closeSound = &mColumns.back();
|
||||
|
||||
LightColumns lightColumns (inventoryColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_Duration, ColumnBase::Display_Integer);
|
||||
lightColumns.mTime = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Radius, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_Radius, ColumnBase::Display_Integer);
|
||||
lightColumns.mRadius = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Colour, ColumnBase::Display_Colour));
|
||||
mColumns.emplace_back(Columns::ColumnId_Colour, ColumnBase::Display_Colour);
|
||||
lightColumns.mColor = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Sound, ColumnBase::Display_Sound));
|
||||
mColumns.emplace_back(Columns::ColumnId_Sound, ColumnBase::Display_Sound);
|
||||
lightColumns.mSound = &mColumns.back();
|
||||
|
||||
mColumns.push_back(RefIdColumn(Columns::ColumnId_EmitterType, ColumnBase::Display_EmitterType));
|
||||
mColumns.emplace_back(Columns::ColumnId_EmitterType, ColumnBase::Display_EmitterType);
|
||||
lightColumns.mEmitterType = &mColumns.back();
|
||||
|
||||
static const struct
|
||||
|
@ -462,31 +462,31 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
for (int i=0; sLightFlagTable[i].mName!=-1; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sLightFlagTable[i].mName, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(sLightFlagTable[i].mName, ColumnBase::Display_Boolean);
|
||||
lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag));
|
||||
}
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_IsKey, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(Columns::ColumnId_IsKey, ColumnBase::Display_Boolean);
|
||||
const RefIdColumn *key = &mColumns.back();
|
||||
|
||||
NpcColumns npcColumns (actorsColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Race, ColumnBase::Display_Race));
|
||||
mColumns.emplace_back(Columns::ColumnId_Race, ColumnBase::Display_Race);
|
||||
npcColumns.mRace = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Class, ColumnBase::Display_Class));
|
||||
mColumns.emplace_back(Columns::ColumnId_Class, ColumnBase::Display_Class);
|
||||
npcColumns.mClass = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction));
|
||||
mColumns.emplace_back(Columns::ColumnId_Faction, ColumnBase::Display_Faction);
|
||||
npcColumns.mFaction = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::Columnid_Hair, ColumnBase::Display_BodyPart));
|
||||
mColumns.emplace_back(Columns::Columnid_Hair, ColumnBase::Display_BodyPart);
|
||||
npcColumns.mHair = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Head, ColumnBase::Display_BodyPart));
|
||||
mColumns.emplace_back(Columns::ColumnId_Head, ColumnBase::Display_BodyPart);
|
||||
npcColumns.mHead = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc));
|
||||
mColumns.emplace_back(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc);
|
||||
npcColumns.mGender = &mColumns.back();
|
||||
|
||||
npcColumns.mFlags.insert (std::make_pair (essential, ESM::NPC::Essential));
|
||||
|
@ -503,36 +503,36 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
// These needs to be driven from the autocalculated setting.
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcAttributes,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_NpcAttributes,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
npcColumns.mAttributes = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> attrMap;
|
||||
attrMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcAttributesRefIdAdapter()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), attrMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), attrMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8));
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcSkills,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_NpcSkills,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
npcColumns.mSkills = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> skillsMap;
|
||||
skillsMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcSkillsRefIdAdapter()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), skillsMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), skillsMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Skill, CSMWorld::ColumnBase::Display_SkillId, false, false));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8));
|
||||
|
||||
// Nested list
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcMisc,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
|
||||
mColumns.emplace_back(Columns::ColumnId_NpcMisc,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List);
|
||||
npcColumns.mMisc = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> miscMap;
|
||||
miscMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcMiscRefIdAdapter()));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), miscMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), miscMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -554,15 +554,15 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
WeaponColumns weaponColumns (enchantableColumns);
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType));
|
||||
mColumns.emplace_back(Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType);
|
||||
weaponColumns.mType = &mColumns.back();
|
||||
|
||||
weaponColumns.mHealth = health;
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponSpeed, ColumnBase::Display_Float));
|
||||
mColumns.emplace_back(Columns::ColumnId_WeaponSpeed, ColumnBase::Display_Float);
|
||||
weaponColumns.mSpeed = &mColumns.back();
|
||||
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponReach, ColumnBase::Display_Float));
|
||||
mColumns.emplace_back(Columns::ColumnId_WeaponReach, ColumnBase::Display_Float);
|
||||
weaponColumns.mReach = &mColumns.back();
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
|
@ -572,8 +572,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
for (int j=0; j<2; ++j)
|
||||
{
|
||||
mColumns.push_back (
|
||||
RefIdColumn (Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer));
|
||||
mColumns.emplace_back(Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer);
|
||||
column[j] = &mColumns.back();
|
||||
}
|
||||
}
|
||||
|
@ -591,19 +590,19 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
|
||||
for (int i=0; sWeaponFlagTable[i].mName!=-1; ++i)
|
||||
{
|
||||
mColumns.push_back (RefIdColumn (sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean));
|
||||
mColumns.emplace_back(sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean);
|
||||
weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag));
|
||||
}
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
const RefIdColumn *partRef = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> partMap;
|
||||
partMap.insert(std::make_pair(UniversalId::Type_Armor,
|
||||
new BodyPartRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor)));
|
||||
partMap.insert(std::make_pair(UniversalId::Type_Clothing,
|
||||
new BodyPartRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), partMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), partMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType));
|
||||
mColumns.back().addColumn(
|
||||
|
@ -614,30 +613,30 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
|||
LevListColumns levListColumns (baseColumns);
|
||||
|
||||
// Nested table
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue));
|
||||
mColumns.emplace_back(Columns::ColumnId_LevelledList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue);
|
||||
levListColumns.mLevList = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> levListMap;
|
||||
levListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList,
|
||||
new NestedLevListRefIdAdapter<ESM::CreatureLevList> (UniversalId::Type_CreatureLevelledList)));
|
||||
levListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList,
|
||||
new NestedLevListRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), levListMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), levListMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer));
|
||||
|
||||
// Nested list
|
||||
mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List));
|
||||
mColumns.emplace_back(Columns::ColumnId_LevelledList,
|
||||
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List);
|
||||
levListColumns.mNestedListLevList = &mColumns.back();
|
||||
std::map<UniversalId::Type, NestedRefIdAdapterBase*> nestedListLevListMap;
|
||||
nestedListLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList,
|
||||
new NestedListLevListRefIdAdapter<ESM::CreatureLevList> (UniversalId::Type_CreatureLevelledList)));
|
||||
nestedListLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList,
|
||||
new NestedListLevListRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList)));
|
||||
mNestedAdapters.push_back (std::make_pair(&mColumns.back(), nestedListLevListMap));
|
||||
mNestedAdapters.emplace_back(&mColumns.back(), nestedListLevListMap);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_LevelledItemTypeEach, CSMWorld::ColumnBase::Display_Boolean));
|
||||
mColumns.back().addColumn(
|
||||
|
|
|
@ -553,7 +553,7 @@ std::vector<osg::ref_ptr<CSVRender::TagBase> > CSVRender::Cell::getSelection (un
|
|||
result.push_back (iter->second->getTag());
|
||||
if (mPathgrid && elementMask & Mask_Pathgrid)
|
||||
if (mPathgrid->isSelected())
|
||||
result.push_back(mPathgrid->getTag());
|
||||
result.emplace_back(mPathgrid->getTag());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -59,38 +59,38 @@ namespace CSVRender
|
|||
/// Editmode for terrain shape grid
|
||||
TerrainShapeMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr);
|
||||
|
||||
void primaryOpenPressed (const WorldspaceHitResult& hit) final;
|
||||
void primaryOpenPressed (const WorldspaceHitResult& hit) override;
|
||||
|
||||
/// Create single command for one-click shape editing
|
||||
void primaryEditPressed (const WorldspaceHitResult& hit) final;
|
||||
void primaryEditPressed (const WorldspaceHitResult& hit) override;
|
||||
|
||||
/// Open brush settings window
|
||||
void primarySelectPressed(const WorldspaceHitResult&) final;
|
||||
void primarySelectPressed(const WorldspaceHitResult&) override;
|
||||
|
||||
void secondarySelectPressed(const WorldspaceHitResult&) final;
|
||||
void secondarySelectPressed(const WorldspaceHitResult&) override;
|
||||
|
||||
void activate(CSVWidget::SceneToolbar*) final;
|
||||
void deactivate(CSVWidget::SceneToolbar*) final;
|
||||
void activate(CSVWidget::SceneToolbar*) override;
|
||||
void deactivate(CSVWidget::SceneToolbar*) override;
|
||||
|
||||
/// Start shape editing command macro
|
||||
bool primaryEditStartDrag (const QPoint& pos) final;
|
||||
bool primaryEditStartDrag (const QPoint& pos) override;
|
||||
|
||||
bool secondaryEditStartDrag (const QPoint& pos) final;
|
||||
bool primarySelectStartDrag (const QPoint& pos) final;
|
||||
bool secondarySelectStartDrag (const QPoint& pos) final;
|
||||
bool secondaryEditStartDrag (const QPoint& pos) override;
|
||||
bool primarySelectStartDrag (const QPoint& pos) override;
|
||||
bool secondarySelectStartDrag (const QPoint& pos) override;
|
||||
|
||||
/// Handle shape edit behavior during dragging
|
||||
void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) final;
|
||||
void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override;
|
||||
|
||||
/// End shape editing command macro
|
||||
void dragCompleted(const QPoint& pos) final;
|
||||
void dragCompleted(const QPoint& pos) override;
|
||||
|
||||
/// Cancel shape editing, and reset all pending changes
|
||||
void dragAborted() final;
|
||||
void dragAborted() override;
|
||||
|
||||
void dragWheel (int diff, double speedFactor) final;
|
||||
void dragMoveEvent (QDragMoveEvent *event) final;
|
||||
void mouseMoveEvent (QMouseEvent *event) final;
|
||||
void dragWheel (int diff, double speedFactor) override;
|
||||
void dragMoveEvent (QDragMoveEvent *event) override;
|
||||
void mouseMoveEvent (QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ namespace CSVRender
|
|||
const CSMWorld::Data& mData;
|
||||
std::array<float, ESM::Land::LAND_SIZE * ESM::Land::LAND_SIZE> mAlteredHeight;
|
||||
|
||||
osg::ref_ptr<const ESMTerrain::LandObject> getLand (int cellX, int cellY) final;
|
||||
const ESM::LandTexture* getLandTexture(int index, short plugin) final;
|
||||
osg::ref_ptr<const ESMTerrain::LandObject> getLand (int cellX, int cellY) override;
|
||||
const ESM::LandTexture* getLandTexture(int index, short plugin) override;
|
||||
|
||||
void getBounds(float& minX, float& maxX, float& minY, float& maxY) final;
|
||||
void getBounds(float& minX, float& maxX, float& minY, float& maxY) override;
|
||||
|
||||
int getThisHeight(int col, int row, const ESM::Land::LandData *heightData) const;
|
||||
int getLeftHeight(int col, int row, const ESM::Land::LandData *heightData) const;
|
||||
|
@ -44,8 +44,8 @@ namespace CSVRender
|
|||
bool leftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const;
|
||||
bool rightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const;
|
||||
|
||||
void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const final;
|
||||
float getAlteredHeight(int col, int row) const final;
|
||||
void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const override;
|
||||
float getAlteredHeight(int col, int row) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -53,37 +53,37 @@ namespace CSVRender
|
|||
/// \brief Editmode for terrain texture grid
|
||||
TerrainTextureMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr);
|
||||
|
||||
void primaryOpenPressed (const WorldspaceHitResult& hit) final;
|
||||
void primaryOpenPressed (const WorldspaceHitResult& hit) override;
|
||||
|
||||
/// \brief Create single command for one-click texture editing
|
||||
void primaryEditPressed (const WorldspaceHitResult& hit) final;
|
||||
void primaryEditPressed (const WorldspaceHitResult& hit) override;
|
||||
|
||||
/// \brief Open brush settings window
|
||||
void primarySelectPressed(const WorldspaceHitResult&) final;
|
||||
void primarySelectPressed(const WorldspaceHitResult&) override;
|
||||
|
||||
void secondarySelectPressed(const WorldspaceHitResult&) final;
|
||||
void secondarySelectPressed(const WorldspaceHitResult&) override;
|
||||
|
||||
void activate(CSVWidget::SceneToolbar*) final;
|
||||
void deactivate(CSVWidget::SceneToolbar*) final;
|
||||
void activate(CSVWidget::SceneToolbar*) override;
|
||||
void deactivate(CSVWidget::SceneToolbar*) override;
|
||||
|
||||
/// \brief Start texture editing command macro
|
||||
bool primaryEditStartDrag (const QPoint& pos) final;
|
||||
bool primaryEditStartDrag (const QPoint& pos) override;
|
||||
|
||||
bool secondaryEditStartDrag (const QPoint& pos) final;
|
||||
bool primarySelectStartDrag (const QPoint& pos) final;
|
||||
bool secondarySelectStartDrag (const QPoint& pos) final;
|
||||
bool secondaryEditStartDrag (const QPoint& pos) override;
|
||||
bool primarySelectStartDrag (const QPoint& pos) override;
|
||||
bool secondarySelectStartDrag (const QPoint& pos) override;
|
||||
|
||||
/// \brief Handle texture edit behavior during dragging
|
||||
void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) final;
|
||||
void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override;
|
||||
|
||||
/// \brief End texture editing command macro
|
||||
void dragCompleted(const QPoint& pos) final;
|
||||
void dragCompleted(const QPoint& pos) override;
|
||||
|
||||
void dragAborted() final;
|
||||
void dragWheel (int diff, double speedFactor) final;
|
||||
void dragMoveEvent (QDragMoveEvent *event) final;
|
||||
void dragAborted() override;
|
||||
void dragWheel (int diff, double speedFactor) override;
|
||||
void dragMoveEvent (QDragMoveEvent *event) override;
|
||||
|
||||
void mouseMoveEvent (QMouseEvent *event) final;
|
||||
void mouseMoveEvent (QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
/// \brief Handle brush mechanics, maths regarding worldspace hit etc.
|
||||
|
|
|
@ -255,8 +255,7 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool (
|
|||
bool default_ = debugProfiles.data (debugProfiles.index (i, defaultColumn)).toInt();
|
||||
|
||||
if (state!=CSMWorld::RecordBase::State_Deleted && default_)
|
||||
profiles.push_back (
|
||||
debugProfiles.data (debugProfiles.index (i, idColumn)).
|
||||
profiles.emplace_back(debugProfiles.data (debugProfiles.index (i, idColumn)).
|
||||
toString().toUtf8().constData());
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ void CSVWorld::DataDisplayDelegate::buildPixmaps ()
|
|||
|
||||
while (it != mIcons.end())
|
||||
{
|
||||
mPixmaps.push_back (std::make_pair (it->mValue, it->mIcon.pixmap (mIconSize) ) );
|
||||
mPixmaps.emplace_back (it->mValue, it->mIcon.pixmap (mIconSize) );
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,5 +181,5 @@ void CSVWorld::EnumDelegateFactory::add (int value, const QString& name)
|
|||
}
|
||||
}
|
||||
|
||||
mValues.push_back(std::make_pair (value, name));
|
||||
mValues.emplace_back (value, name);
|
||||
}
|
||||
|
|
|
@ -345,18 +345,16 @@ std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDraggedRecords() co
|
|||
std::vector<CSMWorld::UniversalId> ids;
|
||||
for (const QModelIndex& it : selected)
|
||||
{
|
||||
ids.push_back(
|
||||
CSMWorld::UniversalId(
|
||||
ids.emplace_back(
|
||||
CSMWorld::UniversalId::Type_Cell,
|
||||
model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()));
|
||||
model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData());
|
||||
}
|
||||
selected = getSelectedCells(false, true);
|
||||
for (const QModelIndex& it : selected)
|
||||
{
|
||||
ids.push_back(
|
||||
CSMWorld::UniversalId(
|
||||
ids.emplace_back(
|
||||
CSMWorld::UniversalId::Type_Cell_Missing,
|
||||
model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()));
|
||||
model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
|
|
@ -452,7 +452,7 @@ std::vector<std::string> CSVWorld::Table::getSelectedIds() const
|
|||
++iter)
|
||||
{
|
||||
int row = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)).row();
|
||||
ids.push_back (mModel->data (mModel->index (row, columnIndex)).toString().toUtf8().constData());
|
||||
ids.emplace_back(mModel->data (mModel->index (row, columnIndex)).toString().toUtf8().constData());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
@ -784,7 +784,7 @@ std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column
|
|||
|
||||
if (display == columndisplay)
|
||||
{
|
||||
titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData());
|
||||
titles.emplace_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
return titles;
|
||||
|
|
|
@ -133,12 +133,12 @@ void CSVWorld::TableSubView::createFilterRequest (std::vector< CSMWorld::Univers
|
|||
std::vector<std::string> col = mTable->getColumnsWithDisplay(CSMWorld::TableMimeData::convertEnums(type));
|
||||
if(!col.empty())
|
||||
{
|
||||
filterSource.push_back(std::make_pair(it->getId(), col));
|
||||
filterSource.emplace_back(it->getId(), col);
|
||||
}
|
||||
|
||||
if(hasRefIdDisplay && CSMWorld::TableMimeData::isReferencable(type))
|
||||
{
|
||||
filterSource.push_back(std::make_pair(it->getId(), refIdColumns));
|
||||
filterSource.emplace_back(it->getId(), refIdColumns);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ namespace
|
|||
Script,
|
||||
Mechanics,
|
||||
Physics,
|
||||
PhysicsWorker,
|
||||
World,
|
||||
Gui,
|
||||
|
||||
|
@ -130,6 +131,9 @@ namespace
|
|||
template <>
|
||||
const UserStats UserStatsValue<UserStatsType::Physics>::sValue {"Phys", "physics"};
|
||||
|
||||
template <>
|
||||
const UserStats UserStatsValue<UserStatsType::PhysicsWorker>::sValue {" -Async", "physicsworker"};
|
||||
|
||||
template <>
|
||||
const UserStats UserStatsValue<UserStatsType::World>::sValue {"World", "world"};
|
||||
|
||||
|
@ -209,6 +213,10 @@ namespace
|
|||
profiler.addUserStatsLine(v.mLabel, textColor, barColor, v.mTaken, multiplier,
|
||||
average, averageInInverseSpace, v.mBegin, v.mEnd, maxValue);
|
||||
});
|
||||
// the forEachUserStatsValue loop is "run" at compile time, hence the settings manager is not available.
|
||||
// Unconditionnally add the async physics stats, and then remove it at runtime if necessary
|
||||
if (Settings::Manager::getInt("async num threads", "Physics") == 0)
|
||||
profiler.removeUserStatsLine(" -Async");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +332,7 @@ bool OMW::Engine::frame(float frametime)
|
|||
|
||||
if (mEnvironment.getStateManager()->getState() != MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
mEnvironment.getWorld()->updatePhysics(frametime, guiActive);
|
||||
mEnvironment.getWorld()->updatePhysics(frametime, guiActive, frameStart, frameNumber, *stats);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,22 +21,6 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
*/
|
||||
#if (BOOST_VERSION <= 104600)
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<>
|
||||
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
||||
{
|
||||
return boost::filesystem::path(arg);
|
||||
}
|
||||
|
||||
} /* namespace boost */
|
||||
#endif /* (BOOST_VERSION <= 104600) */
|
||||
|
||||
|
||||
using namespace Fallback;
|
||||
|
||||
|
@ -63,20 +47,20 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
("data", bpo::value<Files::EscapePathContainer>()->default_value(Files::EscapePathContainer(), "data")
|
||||
->multitoken()->composing(), "set data directories (later directories have higher priority)")
|
||||
|
||||
("data-local", bpo::value<Files::EscapeHashString>()->default_value(""),
|
||||
("data-local", bpo::value<Files::EscapePath>()->default_value(Files::EscapePath(), ""),
|
||||
"set local data directory (highest priority)")
|
||||
|
||||
("fallback-archive", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "fallback-archive")
|
||||
->multitoken(), "set fallback BSA archives (later archives have higher priority)")
|
||||
->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)")
|
||||
|
||||
("resources", bpo::value<Files::EscapeHashString>()->default_value("resources"),
|
||||
("resources", bpo::value<Files::EscapePath>()->default_value(Files::EscapePath(), "resources"),
|
||||
"set resources directory")
|
||||
|
||||
("start", bpo::value<Files::EscapeHashString>()->default_value(""),
|
||||
("start", bpo::value<Files::EscapeHashString>()->default_value(""),
|
||||
"set initial cell")
|
||||
|
||||
("content", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "")
|
||||
->multitoken(), "content file(s): esm/esp, or omwgame/omwaddon")
|
||||
->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon")
|
||||
|
||||
("no-sound", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "disable all sounds")
|
||||
|
@ -90,7 +74,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
("script-console", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "enable console-only script functionality")
|
||||
|
||||
("script-run", bpo::value<Files::EscapeHashString>()->default_value(""),
|
||||
("script-run", bpo::value<Files::EscapeHashString>()->default_value(""),
|
||||
"select a file containing a list of console commands that is executed on startup")
|
||||
|
||||
("script-warn", bpo::value<int>()->implicit_value (1)
|
||||
|
@ -101,12 +85,12 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
"\t2 - treat warnings as errors")
|
||||
|
||||
("script-blacklist", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "")
|
||||
->multitoken(), "ignore the specified script (if the use of the blacklist is enabled)")
|
||||
->multitoken()->composing(), "ignore the specified script (if the use of the blacklist is enabled)")
|
||||
|
||||
("script-blacklist-use", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(true), "enable script blacklisting")
|
||||
|
||||
("load-savegame", bpo::value<Files::EscapeHashString>()->default_value(""),
|
||||
("load-savegame", bpo::value<Files::EscapePath>()->default_value(Files::EscapePath(), ""),
|
||||
"load a save game file on game startup (specify an absolute filename or a filename relative to the current working directory)")
|
||||
|
||||
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
||||
|
@ -118,14 +102,14 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
("fs-strict", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "strict file system handling (no case folding)")
|
||||
|
||||
("encoding", bpo::value<Files::EscapeHashString>()->
|
||||
("encoding", bpo::value<Files::EscapeHashString>()->
|
||||
default_value("win1252"),
|
||||
"Character encoding used in OpenMW game messages:\n"
|
||||
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
|
||||
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
||||
"\n\twin1252 - Western European (Latin) alphabet, used by default")
|
||||
|
||||
("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")
|
||||
("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")
|
||||
->multitoken()->composing(), "fallback values")
|
||||
|
||||
("no-grab", bpo::value<bool>()->implicit_value(true)->default_value(false), "Don't grab mouse cursor")
|
||||
|
@ -159,14 +143,16 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
{
|
||||
cfgMgr.readConfiguration(variables, desc, true);
|
||||
|
||||
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::EscapeHashString>().toStdString());
|
||||
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::EscapePath>().mPath.string());
|
||||
std::cout << v.describe() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bpo::variables_map composingVariables = cfgMgr.separateComposingVariables(variables, desc);
|
||||
cfgMgr.readConfiguration(variables, desc);
|
||||
cfgMgr.mergeComposingVariables(variables, composingVariables, desc);
|
||||
|
||||
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::EscapeHashString>().toStdString());
|
||||
Version::Version v = Version::getOpenmwVersion(variables["resources"].as<Files::EscapePath>().mPath.string());
|
||||
std::cout << v.describe() << std::endl;
|
||||
|
||||
engine.setGrabMouse(!variables["no-grab"].as<bool>());
|
||||
|
@ -181,18 +167,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
|
||||
Files::PathContainer dataDirs(Files::EscapePath::toPathContainer(variables["data"].as<Files::EscapePathContainer>()));
|
||||
|
||||
std::string local(variables["data-local"].as<Files::EscapeHashString>().toStdString());
|
||||
Files::PathContainer::value_type local(variables["data-local"].as<Files::EscapePath>().mPath);
|
||||
if (!local.empty())
|
||||
{
|
||||
if (local.front() == '\"')
|
||||
local = local.substr(1, local.length() - 2);
|
||||
|
||||
dataDirs.push_back(Files::PathContainer::value_type(local));
|
||||
}
|
||||
dataDirs.push_back(local);
|
||||
|
||||
cfgMgr.processPaths(dataDirs);
|
||||
|
||||
engine.setResourceDir(variables["resources"].as<Files::EscapeHashString>().toStdString());
|
||||
engine.setResourceDir(variables["resources"].as<Files::EscapePath>().mPath);
|
||||
engine.setDataDirs(dataDirs);
|
||||
|
||||
// fallback archives
|
||||
|
@ -230,7 +211,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
engine.setWarningsMode (variables["script-warn"].as<int>());
|
||||
engine.setScriptBlacklist (variables["script-blacklist"].as<Files::EscapeStringVector>().toStdStringVector());
|
||||
engine.setScriptBlacklistUse (variables["script-blacklist-use"].as<bool>());
|
||||
engine.setSaveGameFile (variables["load-savegame"].as<Files::EscapeHashString>().toStdString());
|
||||
engine.setSaveGameFile (variables["load-savegame"].as<Files::EscapePath>().mPath.string());
|
||||
|
||||
// other settings
|
||||
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap);
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <components/esm/cellid.hpp>
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/doorstate.hpp"
|
||||
|
||||
|
@ -398,7 +400,7 @@ namespace MWBase
|
|||
/// \return pointer to created record
|
||||
|
||||
virtual void update (float duration, bool paused) = 0;
|
||||
virtual void updatePhysics (float duration, bool paused) = 0;
|
||||
virtual void updatePhysics (float duration, bool paused, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) = 0;
|
||||
|
||||
virtual void updateWindowManager () = 0;
|
||||
|
||||
|
|
|
@ -132,11 +132,11 @@ namespace MWClass
|
|||
|
||||
void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const override;
|
||||
|
||||
float getWalkSpeed(const MWWorld::Ptr& ptr) const final;
|
||||
float getWalkSpeed(const MWWorld::Ptr& ptr) const override;
|
||||
|
||||
float getRunSpeed(const MWWorld::Ptr& ptr) const final;
|
||||
float getRunSpeed(const MWWorld::Ptr& ptr) const override;
|
||||
|
||||
float getSwimSpeed(const MWWorld::Ptr& ptr) const final;
|
||||
float getSwimSpeed(const MWWorld::Ptr& ptr) const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -432,12 +432,12 @@ namespace MWClass
|
|||
const MWWorld::LiveCellRef<ESM::NPC> *npc = ptr.get<ESM::NPC>();
|
||||
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(npc->mBase->mRace);
|
||||
if(race && race->mData.mFlags & ESM::Race::Beast)
|
||||
models.push_back("meshes\\base_animkna.nif");
|
||||
models.emplace_back("meshes\\base_animkna.nif");
|
||||
|
||||
// keep these always loaded just in case
|
||||
models.push_back("meshes/xargonian_swimkna.nif");
|
||||
models.push_back("meshes/xbase_anim_female.nif");
|
||||
models.push_back("meshes/xbase_anim.nif");
|
||||
models.emplace_back("meshes/xargonian_swimkna.nif");
|
||||
models.emplace_back("meshes/xbase_anim_female.nif");
|
||||
models.emplace_back("meshes/xbase_anim.nif");
|
||||
|
||||
if (!npc->mBase->mModel.empty())
|
||||
models.push_back("meshes/"+npc->mBase->mModel);
|
||||
|
|
|
@ -166,11 +166,11 @@ namespace MWClass
|
|||
|
||||
void modifyBaseInventory(const std::string& actorId, const std::string& itemId, int amount) const override;
|
||||
|
||||
float getWalkSpeed(const MWWorld::Ptr& ptr) const final;
|
||||
float getWalkSpeed(const MWWorld::Ptr& ptr) const override;
|
||||
|
||||
float getRunSpeed(const MWWorld::Ptr& ptr) const final;
|
||||
float getRunSpeed(const MWWorld::Ptr& ptr) const override;
|
||||
|
||||
float getSwimSpeed(const MWWorld::Ptr& ptr) const final;
|
||||
float getSwimSpeed(const MWWorld::Ptr& ptr) const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -468,7 +468,7 @@ namespace MWDialogue
|
|||
void DialogueManager::addChoice (const std::string& text, int choice)
|
||||
{
|
||||
mIsInChoice = true;
|
||||
mChoices.push_back(std::make_pair(text, choice));
|
||||
mChoices.emplace_back(text, choice);
|
||||
}
|
||||
|
||||
const std::vector<std::pair<std::string, int> >& DialogueManager::getChoices()
|
||||
|
|
|
@ -73,9 +73,9 @@ namespace MWDialogue
|
|||
bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) override;
|
||||
|
||||
std::list<std::string> getAvailableTopics() override;
|
||||
int getTopicFlag(const std::string& topicId) final;
|
||||
int getTopicFlag(const std::string& topicId) override;
|
||||
|
||||
bool inJournal (const std::string& topicId, const std::string& infoId) final;
|
||||
bool inJournal (const std::string& topicId, const std::string& infoId) override;
|
||||
|
||||
void addTopic (const std::string& topic) override;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace MWDialogue
|
|||
tokenizeKeywords(text.substr(iteration_pos, pos_begin - iteration_pos), result);
|
||||
|
||||
std::string link = text.substr(pos_begin + 1, pos_end - pos_begin - 1);
|
||||
result.push_back(Token(link, Token::ExplicitLink));
|
||||
result.emplace_back(link, Token::ExplicitLink);
|
||||
|
||||
iteration_pos = pos_end + 1;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace MWDialogue
|
|||
|
||||
for (std::vector<KeywordSearch<std::string, int /*unused*/>::Match>::const_iterator it = matches.begin(); it != matches.end(); ++it)
|
||||
{
|
||||
tokens.push_back(Token(std::string(it->mBeg, it->mEnd), Token::ImplicitKeyword));
|
||||
tokens.emplace_back(std::string(it->mBeg, it->mEnd), Token::ImplicitKeyword);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ namespace MWGui
|
|||
*/
|
||||
void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool stretch=true);
|
||||
|
||||
void setSize (const MyGUI::IntSize &_value) final;
|
||||
void setCoord (const MyGUI::IntCoord &_value) final;
|
||||
void setSize (const MyGUI::IntSize &_value) override;
|
||||
void setCoord (const MyGUI::IntCoord &_value) override;
|
||||
|
||||
private:
|
||||
MyGUI::ImageBox* mChild;
|
||||
|
|
|
@ -147,7 +147,7 @@ namespace MWGui
|
|||
|
||||
for (const ESM::BirthSign& sign : signs)
|
||||
{
|
||||
birthSigns.push_back(std::make_pair(sign.mId, &sign));
|
||||
birthSigns.emplace_back(sign.mId, &sign);
|
||||
}
|
||||
std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns);
|
||||
|
||||
|
|
|
@ -524,9 +524,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
|||
break;
|
||||
|
||||
if ( lead != origin )
|
||||
mPartialWhitespace.push_back (PartialText (style, lead, origin, space_width));
|
||||
mPartialWhitespace.emplace_back(style, lead, origin, space_width);
|
||||
if ( origin != extent )
|
||||
mPartialWord.push_back (PartialText (style, origin, extent, word_width));
|
||||
mPartialWord.emplace_back(style, origin, extent, word_width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1152,7 @@ public:
|
|||
i->second->createDrawItem (mNode);
|
||||
}
|
||||
|
||||
void setVisible (bool newVisible) final
|
||||
void setVisible (bool newVisible) override
|
||||
{
|
||||
if (mVisible == newVisible)
|
||||
return;
|
||||
|
@ -1174,7 +1174,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) final
|
||||
void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) override
|
||||
{
|
||||
mNode = node;
|
||||
|
||||
|
@ -1242,9 +1242,9 @@ public:
|
|||
|
||||
// ISubWidget should not necessarily be a drawitem
|
||||
// in this case, it is not...
|
||||
void doRender() final { }
|
||||
void doRender() override { }
|
||||
|
||||
void _updateView () final
|
||||
void _updateView () override
|
||||
{
|
||||
_checkMargin();
|
||||
|
||||
|
@ -1253,7 +1253,7 @@ public:
|
|||
mNode->outOfDate (i->second->mRenderItem);
|
||||
}
|
||||
|
||||
void _correctView() final
|
||||
void _correctView() override
|
||||
{
|
||||
_checkMargin ();
|
||||
|
||||
|
@ -1263,7 +1263,7 @@ public:
|
|||
|
||||
}
|
||||
|
||||
void destroyDrawItem() final
|
||||
void destroyDrawItem() override
|
||||
{
|
||||
for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i)
|
||||
i->second->destroyDrawItem (mNode);
|
||||
|
@ -1283,24 +1283,24 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void showPage (TypesetBook::Ptr book, size_t page) final
|
||||
void showPage (TypesetBook::Ptr book, size_t page) override
|
||||
{
|
||||
mPageDisplay->showPage (book, page);
|
||||
}
|
||||
|
||||
void adviseLinkClicked (std::function <void (InteractiveId)> linkClicked) final
|
||||
void adviseLinkClicked (std::function <void (InteractiveId)> linkClicked) override
|
||||
{
|
||||
mPageDisplay->mLinkClicked = linkClicked;
|
||||
}
|
||||
|
||||
void unadviseLinkClicked () final
|
||||
void unadviseLinkClicked () override
|
||||
{
|
||||
mPageDisplay->mLinkClicked = std::function <void (InteractiveId)> ();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void initialiseOverride() final
|
||||
void initialiseOverride() override
|
||||
{
|
||||
Base::initialiseOverride();
|
||||
|
||||
|
@ -1314,24 +1314,24 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void onMouseLostFocus(Widget* _new) final
|
||||
void onMouseLostFocus(Widget* _new) override
|
||||
{
|
||||
// NOTE: MyGUI also fires eventMouseLostFocus for widgets that are about to be destroyed (if they had focus).
|
||||
// Child widgets may already be destroyed! So be careful.
|
||||
mPageDisplay->onMouseLostFocus ();
|
||||
}
|
||||
|
||||
void onMouseMove(int left, int top) final
|
||||
void onMouseMove(int left, int top) override
|
||||
{
|
||||
mPageDisplay->onMouseMove (left, top);
|
||||
}
|
||||
|
||||
void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) final
|
||||
void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) override
|
||||
{
|
||||
mPageDisplay->onMouseButtonPressed (left, top, id);
|
||||
}
|
||||
|
||||
void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) final
|
||||
void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) override
|
||||
{
|
||||
mPageDisplay->onMouseButtonReleased (left, top, id);
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ namespace MWGui
|
|||
if (store.get<ESM::Class>().isDynamic(classInfo.mId))
|
||||
continue; // custom-made class not relevant for this dialog
|
||||
|
||||
items.push_back(std::make_pair(classInfo.mId, classInfo.mName));
|
||||
items.emplace_back(classInfo.mId, classInfo.mName);
|
||||
}
|
||||
std::sort(items.begin(), items.end(), sortClasses);
|
||||
|
||||
|
|
|
@ -163,8 +163,8 @@ bool CompanionWindow::exit()
|
|||
if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0)
|
||||
{
|
||||
std::vector<std::string> buttons;
|
||||
buttons.push_back("#{sCompanionWarningButtonOne}");
|
||||
buttons.push_back("#{sCompanionWarningButtonTwo}");
|
||||
buttons.emplace_back("#{sCompanionWarningButtonOne}");
|
||||
buttons.emplace_back("#{sCompanionWarningButtonTwo}");
|
||||
mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons);
|
||||
mMessageBoxManager->eventButtonPressed += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked);
|
||||
return false;
|
||||
|
|
|
@ -167,6 +167,10 @@ namespace MWGui
|
|||
{
|
||||
WindowBase::onClose();
|
||||
|
||||
// Make sure the window was actually closed and not temporarily hidden.
|
||||
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container))
|
||||
return;
|
||||
|
||||
if (mModel)
|
||||
mModel->onClose();
|
||||
|
||||
|
@ -189,6 +193,7 @@ namespace MWGui
|
|||
|
||||
// transfer everything into the player's inventory
|
||||
ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel();
|
||||
assert(mModel);
|
||||
mModel->update();
|
||||
|
||||
// unequip all items to avoid unequipping/reequipping
|
||||
|
|
|
@ -49,14 +49,14 @@ ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSour
|
|||
for(const MWWorld::Ptr& source : itemSources)
|
||||
{
|
||||
MWWorld::ContainerStore& store = source.getClass().getContainerStore(source);
|
||||
mItemSources.push_back(std::make_pair(source, store.resolveTemporarily()));
|
||||
mItemSources.emplace_back(source, store.resolveTemporarily());
|
||||
}
|
||||
}
|
||||
|
||||
ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source) : mTrading(false)
|
||||
{
|
||||
MWWorld::ContainerStore& store = source.getClass().getContainerStore(source);
|
||||
mItemSources.push_back(std::make_pair(source, store.resolveTemporarily()));
|
||||
mItemSources.emplace_back(source, store.resolveTemporarily());
|
||||
}
|
||||
|
||||
bool ContainerItemModel::allowedToUseItems() const
|
||||
|
|
|
@ -9,21 +9,17 @@ namespace MyGUI
|
|||
class Widget;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
namespace Controllers
|
||||
namespace MWGui::Controllers
|
||||
{
|
||||
/// Automatically positions a widget below the mouse cursor.
|
||||
class ControllerFollowMouse final :
|
||||
public MyGUI::ControllerItem
|
||||
class ControllerFollowMouse final : public MyGUI::ControllerItem
|
||||
{
|
||||
MYGUI_RTTI_DERIVED( ControllerFollowMouse )
|
||||
|
||||
private:
|
||||
bool addTime(MyGUI::Widget* _widget, float _time) final;
|
||||
void prepareItem(MyGUI::Widget* _widget) final;
|
||||
bool addTime(MyGUI::Widget* _widget, float _time) override;
|
||||
void prepareItem(MyGUI::Widget* _widget) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,10 +20,10 @@ namespace MWGui
|
|||
ResourceImageSetPointerFix();
|
||||
virtual ~ResourceImageSetPointerFix();
|
||||
|
||||
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final;
|
||||
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) override;
|
||||
|
||||
void setImage(MyGUI::ImageBox* _image) final;
|
||||
void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point) final;
|
||||
void setImage(MyGUI::ImageBox* _image) override;
|
||||
void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point) override;
|
||||
|
||||
//and now for the whole point of this class, allow us to get
|
||||
//the hot spot, the image and the size of the cursor.
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace MWGui
|
|||
/// Register needed components with MyGUI's factory manager
|
||||
static void registerComponents();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
/// Takes ownership of \a model
|
||||
void setModel(ItemModel* model);
|
||||
|
@ -47,8 +47,8 @@ namespace MWGui
|
|||
void layoutWidgets();
|
||||
void resetScrollbars();
|
||||
|
||||
void setSize(const MyGUI::IntSize& value) final;
|
||||
void setCoord(const MyGUI::IntCoord& value) final;
|
||||
void setSize(const MyGUI::IntSize& value) override;
|
||||
void setCoord(const MyGUI::IntCoord& value) override;
|
||||
|
||||
MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, const MWWorld::Ptr&> eventItemClicked;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace MWGui
|
|||
MYGUI_RTTI_DERIVED(ItemView)
|
||||
public:
|
||||
ItemView();
|
||||
virtual ~ItemView();
|
||||
~ItemView() override;
|
||||
|
||||
/// Register needed components with MyGUI's factory manager
|
||||
static void registerComponents ();
|
||||
|
@ -33,12 +33,12 @@ namespace MWGui
|
|||
void resetScrollBars();
|
||||
|
||||
private:
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
void layoutWidgets();
|
||||
|
||||
void setSize(const MyGUI::IntSize& _value) final;
|
||||
void setCoord(const MyGUI::IntCoord& _value) final;
|
||||
void setSize(const MyGUI::IntSize& _value) override;
|
||||
void setCoord(const MyGUI::IntCoord& _value) override;
|
||||
|
||||
void onSelectedItem (MyGUI::Widget* sender);
|
||||
void onSelectedBackground (MyGUI::Widget* sender);
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace MWGui
|
|||
void setFrame (const std::string& frame, const MyGUI::IntCoord& coord);
|
||||
|
||||
protected:
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
MyGUI::ImageBox* mItem;
|
||||
MyGUI::ImageBox* mItemShadow;
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
std::vector<std::string> buttons;
|
||||
buttons.push_back("#{sOk}");
|
||||
buttons.emplace_back("#{sOk}");
|
||||
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,25 +231,25 @@ namespace MWGui
|
|||
std::vector<std::string> buttons;
|
||||
|
||||
if (state==MWBase::StateManager::State_Running)
|
||||
buttons.push_back("return");
|
||||
buttons.emplace_back("return");
|
||||
|
||||
buttons.push_back("newgame");
|
||||
buttons.emplace_back("newgame");
|
||||
|
||||
if (state==MWBase::StateManager::State_Running &&
|
||||
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 &&
|
||||
MWBase::Environment::get().getWindowManager()->isSavingAllowed())
|
||||
buttons.push_back("savegame");
|
||||
buttons.emplace_back("savegame");
|
||||
|
||||
if (MWBase::Environment::get().getStateManager()->characterBegin()!=
|
||||
MWBase::Environment::get().getStateManager()->characterEnd())
|
||||
buttons.push_back("loadgame");
|
||||
buttons.emplace_back("loadgame");
|
||||
|
||||
buttons.push_back("options");
|
||||
buttons.emplace_back("options");
|
||||
|
||||
if (state==MWBase::StateManager::State_NoGame)
|
||||
buttons.push_back("credits");
|
||||
buttons.emplace_back("credits");
|
||||
|
||||
buttons.push_back("exitgame");
|
||||
buttons.emplace_back("exitgame");
|
||||
|
||||
// Create new buttons if needed
|
||||
std::vector<std::string> allButtons { "return", "newgame", "savegame", "loadgame", "options", "credits", "exitgame"};
|
||||
|
|
|
@ -74,12 +74,12 @@ namespace
|
|||
MyGUI::Colour mNormalColour;
|
||||
MyGUI::Colour mHoverColour;
|
||||
|
||||
void onMouseLostFocus(MyGUI::Widget* _new) final
|
||||
void onMouseLostFocus(MyGUI::Widget* _new) override
|
||||
{
|
||||
setColour(mNormalColour);
|
||||
}
|
||||
|
||||
void onMouseSetFocus(MyGUI::Widget* _old) final
|
||||
void onMouseSetFocus(MyGUI::Widget* _old) override
|
||||
{
|
||||
setColour(mHoverColour);
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ namespace MWGui
|
|||
if (!playable) // Only display playable races
|
||||
continue;
|
||||
|
||||
items.push_back(std::make_pair(race.mId, race.mName));
|
||||
items.emplace_back(race.mId, race.mName);
|
||||
}
|
||||
std::sort(items.begin(), items.end(), sortRaces);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace MWGui
|
|||
MYGUI_RTTI_DERIVED( AutoSizedResourceSkin )
|
||||
|
||||
public:
|
||||
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) final;
|
||||
void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ namespace MWGui
|
|||
{
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetDisplayMode(screen, i, &mode);
|
||||
resolutions.push_back(std::make_pair(mode.w, mode.h));
|
||||
resolutions.emplace_back(mode.w, mode.h);
|
||||
}
|
||||
std::sort(resolutions.begin(), resolutions.end(), sortResolutions);
|
||||
for (std::pair<int, int>& resolution : resolutions)
|
||||
|
|
|
@ -31,18 +31,18 @@ namespace
|
|||
{
|
||||
// this defines the sorting order of types. types that are first in the vector appear before other types.
|
||||
std::vector<std::string> mapping;
|
||||
mapping.push_back( typeid(ESM::Weapon).name() );
|
||||
mapping.push_back( typeid(ESM::Armor).name() );
|
||||
mapping.push_back( typeid(ESM::Clothing).name() );
|
||||
mapping.push_back( typeid(ESM::Potion).name() );
|
||||
mapping.push_back( typeid(ESM::Ingredient).name() );
|
||||
mapping.push_back( typeid(ESM::Apparatus).name() );
|
||||
mapping.push_back( typeid(ESM::Book).name() );
|
||||
mapping.push_back( typeid(ESM::Light).name() );
|
||||
mapping.push_back( typeid(ESM::Miscellaneous).name() );
|
||||
mapping.push_back( typeid(ESM::Lockpick).name() );
|
||||
mapping.push_back( typeid(ESM::Repair).name() );
|
||||
mapping.push_back( typeid(ESM::Probe).name() );
|
||||
mapping.emplace_back(typeid(ESM::Weapon).name() );
|
||||
mapping.emplace_back(typeid(ESM::Armor).name() );
|
||||
mapping.emplace_back(typeid(ESM::Clothing).name() );
|
||||
mapping.emplace_back(typeid(ESM::Potion).name() );
|
||||
mapping.emplace_back(typeid(ESM::Ingredient).name() );
|
||||
mapping.emplace_back(typeid(ESM::Apparatus).name() );
|
||||
mapping.emplace_back(typeid(ESM::Book).name() );
|
||||
mapping.emplace_back(typeid(ESM::Light).name() );
|
||||
mapping.emplace_back(typeid(ESM::Miscellaneous).name() );
|
||||
mapping.emplace_back(typeid(ESM::Lockpick).name() );
|
||||
mapping.emplace_back(typeid(ESM::Repair).name() );
|
||||
mapping.emplace_back(typeid(ESM::Probe).name() );
|
||||
|
||||
assert( std::find(mapping.begin(), mapping.end(), type1) != mapping.end() );
|
||||
assert( std::find(mapping.begin(), mapping.end(), type2) != mapping.end() );
|
||||
|
@ -166,7 +166,7 @@ namespace MWGui
|
|||
|
||||
void SortFilterItemModel::addDragItem (const MWWorld::Ptr& dragItem, size_t count)
|
||||
{
|
||||
mDragItems.push_back(std::make_pair(dragItem, count));
|
||||
mDragItems.emplace_back(dragItem, count);
|
||||
}
|
||||
|
||||
void SortFilterItemModel::clearDragItems()
|
||||
|
|
|
@ -12,8 +12,8 @@ namespace MWGui
|
|||
{
|
||||
mSoulgem = soulgem;
|
||||
std::vector<std::string> buttons;
|
||||
buttons.push_back("#{sRechargeEnchantment}");
|
||||
buttons.push_back("#{sMake Enchantment}");
|
||||
buttons.emplace_back("#{sRechargeEnchantment}");
|
||||
buttons.emplace_back("#{sMake Enchantment}");
|
||||
mManager->createInteractiveMessageBox("#{sDoYouWantTo}", buttons);
|
||||
mManager->eventButtonPressed += MyGUI::newDelegate(this, &SoulgemDialog::onButtonPressed);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,44 @@ namespace MWGui
|
|||
{
|
||||
}
|
||||
|
||||
bool SpellModel::matchingEffectExists(std::string filter, const ESM::EffectList &effects)
|
||||
{
|
||||
auto wm = MWBase::Environment::get().getWindowManager();
|
||||
const MWWorld::ESMStore &store =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
for (unsigned int i = 0; i < effects.mList.size(); ++i)
|
||||
{
|
||||
short effectId = effects.mList[i].mEffectID;
|
||||
|
||||
if (effectId != -1)
|
||||
{
|
||||
const ESM::MagicEffect *magicEffect =
|
||||
store.get<ESM::MagicEffect>().search(effectId);
|
||||
std::string effectIDStr = ESM::MagicEffect::effectIdToString(effectId);
|
||||
std::string fullEffectName = wm->getGameSettingString(effectIDStr, "");
|
||||
|
||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill && effects.mList[i].mSkill != -1)
|
||||
{
|
||||
fullEffectName += " " + wm->getGameSettingString(ESM::Skill::sSkillNameIds[effects.mList[i].mSkill], "");
|
||||
}
|
||||
|
||||
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute && effects.mList[i].mAttribute != -1)
|
||||
{
|
||||
fullEffectName += " " + wm->getGameSettingString(ESM::Attribute::sGmstAttributeIds[effects.mList[i].mAttribute], "");
|
||||
}
|
||||
|
||||
std::string convert = Misc::StringUtils::lowerCaseUtf8(fullEffectName);
|
||||
if (convert.find(filter) != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SpellModel::update()
|
||||
{
|
||||
mSpells.clear();
|
||||
|
@ -61,8 +99,9 @@ namespace MWGui
|
|||
continue;
|
||||
|
||||
std::string name = Misc::StringUtils::lowerCaseUtf8(spell->mName);
|
||||
|
||||
if (name.find(filter) == std::string::npos)
|
||||
|
||||
if (name.find(filter) == std::string::npos
|
||||
&& !matchingEffectExists(filter, spell->mEffects))
|
||||
continue;
|
||||
|
||||
Spell newSpell;
|
||||
|
@ -103,7 +142,8 @@ namespace MWGui
|
|||
|
||||
std::string name = Misc::StringUtils::lowerCaseUtf8(item.getClass().getName(item));
|
||||
|
||||
if (name.find(filter) == std::string::npos)
|
||||
if (name.find(filter) == std::string::npos
|
||||
&& !matchingEffectExists(filter, enchant->mEffects))
|
||||
continue;
|
||||
|
||||
Spell newSpell;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define OPENMW_GUI_SPELLMODEL_H
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include <components/esm/effectlist.hpp>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -57,6 +58,8 @@ namespace MWGui
|
|||
std::vector<Spell> mSpells;
|
||||
|
||||
std::string mFilter;
|
||||
|
||||
bool matchingEffectExists(std::string filter, const ESM::EffectList &effects);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -128,10 +128,10 @@ namespace MWGui
|
|||
group.push_back(costChance);
|
||||
Gui::SharedStateButton::createButtonGroup(group);
|
||||
|
||||
mLines.push_back(LineInfo(t, costChance, i));
|
||||
mLines.emplace_back(t, costChance, i);
|
||||
}
|
||||
else
|
||||
mLines.push_back(LineInfo(t, (MyGUI::Widget*)nullptr, i));
|
||||
mLines.emplace_back(t, (MyGUI::Widget*)nullptr, i);
|
||||
|
||||
t->setStateSelected(spell.mSelected);
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ namespace MWGui
|
|||
MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 18),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
separator->setNeedMouseFocus(false);
|
||||
mLines.push_back(LineInfo(separator, (MyGUI::Widget*)nullptr, NoSpellIndex));
|
||||
mLines.emplace_back(separator, (MyGUI::Widget*)nullptr, NoSpellIndex);
|
||||
}
|
||||
|
||||
MyGUI::TextBox* groupWidget = mScrollView->createWidget<Gui::TextBox>("SandBrightText",
|
||||
|
@ -255,10 +255,10 @@ namespace MWGui
|
|||
groupWidget2->setTextAlign(MyGUI::Align::Right);
|
||||
groupWidget2->setNeedMouseFocus(false);
|
||||
|
||||
mLines.push_back(LineInfo(groupWidget, groupWidget2, NoSpellIndex));
|
||||
mLines.emplace_back(groupWidget, groupWidget2, NoSpellIndex);
|
||||
}
|
||||
else
|
||||
mLines.push_back(LineInfo(groupWidget, (MyGUI::Widget*)nullptr, NoSpellIndex));
|
||||
mLines.emplace_back(groupWidget, (MyGUI::Widget*)nullptr, NoSpellIndex);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,10 +47,10 @@ namespace MWGui
|
|||
/// Fired when a spell was clicked
|
||||
EventHandle_ModelIndex eventSpellClicked;
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
void setSize(const MyGUI::IntSize& _value) final;
|
||||
void setCoord(const MyGUI::IntCoord& _value) final;
|
||||
void setSize(const MyGUI::IntSize& _value) override;
|
||||
void setCoord(const MyGUI::IntCoord& _value) override;
|
||||
|
||||
void resetScrollbars();
|
||||
|
||||
|
|
|
@ -523,6 +523,9 @@ namespace MWGui
|
|||
|
||||
void TradeWindow::onClose()
|
||||
{
|
||||
// Make sure the window was actually closed and not temporarily hidden.
|
||||
if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Barter))
|
||||
return;
|
||||
resetReference();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace MWGui
|
|||
{
|
||||
float value = getSkillForTraining(actorStats, i);
|
||||
|
||||
skills.push_back(std::make_pair(i, value));
|
||||
skills.emplace_back(i, value);
|
||||
}
|
||||
|
||||
std::sort(skills.begin(), skills.end(), sortSkills);
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace MWGui
|
|||
protected:
|
||||
virtual ~MWSkill();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
void onClicked(MyGUI::Widget* _sender);
|
||||
|
||||
|
@ -156,7 +156,7 @@ namespace MWGui
|
|||
protected:
|
||||
virtual ~MWAttribute();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
void onClicked(MyGUI::Widget* _sender);
|
||||
|
||||
|
@ -199,7 +199,7 @@ namespace MWGui
|
|||
protected:
|
||||
virtual ~MWSpell();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
private:
|
||||
void updateWidgets();
|
||||
|
@ -241,7 +241,7 @@ namespace MWGui
|
|||
protected:
|
||||
virtual ~MWEffectList();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
private:
|
||||
void updateWidgets();
|
||||
|
@ -265,7 +265,7 @@ namespace MWGui
|
|||
protected:
|
||||
virtual ~MWSpellEffect();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
private:
|
||||
static const int sIconOffset = 24;
|
||||
|
@ -294,7 +294,7 @@ namespace MWGui
|
|||
protected:
|
||||
virtual ~MWDynamicStat();
|
||||
|
||||
void initialiseOverride() final;
|
||||
void initialiseOverride() override;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace MWMechanics
|
|||
if (sourceId != mSpellId)
|
||||
return;
|
||||
|
||||
mMagnitudes.push_back(std::make_pair(key, magnitude));
|
||||
mMagnitudes.emplace_back(key, magnitude);
|
||||
}
|
||||
|
||||
std::vector<std::pair<MWMechanics::EffectKey, float>> mMagnitudes;
|
||||
|
@ -590,7 +590,9 @@ namespace MWMechanics
|
|||
|
||||
if (!actorState.isTurningToPlayer())
|
||||
{
|
||||
float angle = std::atan2(dir.x(), dir.y());
|
||||
float from = dir.x();
|
||||
float to = dir.y();
|
||||
float angle = std::atan2(from, to);
|
||||
actorState.setAngleToPlayer(angle);
|
||||
float deltaAngle = Misc::normalizeAngle(angle - actor.getRefData().getPosition().rot[2]);
|
||||
if (!mSmoothMovement || std::abs(deltaAngle) > osg::DegreesToRadians(60.f))
|
||||
|
@ -914,12 +916,54 @@ namespace MWMechanics
|
|||
}
|
||||
};
|
||||
|
||||
void Actors::applyCureEffects(const MWWorld::Ptr& actor)
|
||||
{
|
||||
CreatureStats &creatureStats = actor.getClass().getCreatureStats(actor);
|
||||
const MagicEffects &effects = creatureStats.getMagicEffects();
|
||||
|
||||
if (effects.get(ESM::MagicEffect::CurePoison).getModifier() > 0)
|
||||
{
|
||||
creatureStats.getActiveSpells().purgeEffect(ESM::MagicEffect::Poison);
|
||||
creatureStats.getSpells().purgeEffect(ESM::MagicEffect::Poison);
|
||||
if (actor.getClass().hasInventoryStore(actor))
|
||||
actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Poison);
|
||||
}
|
||||
else if (effects.get(ESM::MagicEffect::CureParalyzation).getModifier() > 0)
|
||||
{
|
||||
creatureStats.getActiveSpells().purgeEffect(ESM::MagicEffect::Paralyze);
|
||||
creatureStats.getSpells().purgeEffect(ESM::MagicEffect::Paralyze);
|
||||
if (actor.getClass().hasInventoryStore(actor))
|
||||
actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Paralyze);
|
||||
}
|
||||
else if (effects.get(ESM::MagicEffect::CureCommonDisease).getModifier() > 0)
|
||||
{
|
||||
creatureStats.getSpells().purgeCommonDisease();
|
||||
}
|
||||
else if (effects.get(ESM::MagicEffect::CureBlightDisease).getModifier() > 0)
|
||||
{
|
||||
creatureStats.getSpells().purgeBlightDisease();
|
||||
}
|
||||
else if (effects.get(ESM::MagicEffect::CureCorprusDisease).getModifier() > 0)
|
||||
{
|
||||
creatureStats.getActiveSpells().purgeCorprusDisease();
|
||||
creatureStats.getSpells().purgeCorprusDisease();
|
||||
if (actor.getClass().hasInventoryStore(actor))
|
||||
actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Corprus, true);
|
||||
}
|
||||
else if (effects.get(ESM::MagicEffect::RemoveCurse).getModifier() > 0)
|
||||
{
|
||||
creatureStats.getSpells().purgeCurses();
|
||||
}
|
||||
}
|
||||
|
||||
void Actors::calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
CreatureStats &creatureStats = ptr.getClass().getCreatureStats(ptr);
|
||||
const MagicEffects &effects = creatureStats.getMagicEffects();
|
||||
bool godmode = ptr == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState();
|
||||
|
||||
applyCureEffects(ptr);
|
||||
|
||||
bool wasDead = creatureStats.isDead();
|
||||
|
||||
if (duration > 0)
|
||||
|
@ -1687,6 +1731,9 @@ namespace MWMechanics
|
|||
|
||||
void Actors::predictAndAvoidCollisions()
|
||||
{
|
||||
if (!MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
||||
return;
|
||||
|
||||
const float minGap = 10.f;
|
||||
const float maxDistForPartialAvoiding = 200.f;
|
||||
const float maxDistForStrictAvoiding = 100.f;
|
||||
|
@ -1723,7 +1770,7 @@ namespace MWMechanics
|
|||
shouldAvoidCollision = true;
|
||||
else if (package->getTypeId() == AiPackageTypeId::Wander && giveWayWhenIdle)
|
||||
{
|
||||
if (!dynamic_cast<const AiWander*>(package.get())->isStationary())
|
||||
if (!static_cast<const AiWander*>(package.get())->isStationary())
|
||||
shouldAvoidCollision = true;
|
||||
}
|
||||
else if (package->getTypeId() == AiPackageTypeId::Combat || package->getTypeId() == AiPackageTypeId::Pursue)
|
||||
|
|
|
@ -206,6 +206,7 @@ namespace MWMechanics
|
|||
|
||||
private:
|
||||
void updateVisibility (const MWWorld::Ptr& ptr, CharacterController* ctrl);
|
||||
void applyCureEffects (const MWWorld::Ptr& actor);
|
||||
|
||||
PtrActorMap mActors;
|
||||
float mTimerDisposeSummonsCorpses;
|
||||
|
|
|
@ -24,15 +24,15 @@ namespace MWMechanics
|
|||
public:
|
||||
/// Constructor
|
||||
/** \param objectId Reference to object to activate **/
|
||||
AiActivate(const std::string &objectId);
|
||||
explicit AiActivate(const std::string &objectId);
|
||||
|
||||
AiActivate(const ESM::AiSequence::AiActivate* activate);
|
||||
explicit AiActivate(const ESM::AiSequence::AiActivate* activate);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; }
|
||||
|
||||
void writeState(ESM::AiSequence::AiSequence& sequence) const final;
|
||||
void writeState(ESM::AiSequence::AiSequence& sequence) const override;
|
||||
|
||||
private:
|
||||
const std::string mObjectId;
|
||||
|
|
|
@ -20,9 +20,9 @@ namespace MWMechanics
|
|||
{
|
||||
public:
|
||||
/// Avoid door until the door is fully open
|
||||
AiAvoidDoor(const MWWorld::ConstPtr& doorPtr);
|
||||
explicit AiAvoidDoor(const MWWorld::ConstPtr& doorPtr);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::AvoidDoor; }
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace MWMechanics
|
|||
class AiBreathe final : public TypedAiPackage<AiBreathe>
|
||||
{
|
||||
public:
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Breathe; }
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@ namespace MWMechanics
|
|||
public:
|
||||
AiCast(const std::string& targetId, const std::string& spellId, bool manualSpell=false);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Cast; }
|
||||
|
||||
MWWorld::Ptr getTarget() const final;
|
||||
MWWorld::Ptr getTarget() const override;
|
||||
|
||||
static constexpr Options makeDefaultOptions()
|
||||
{
|
||||
|
|
|
@ -96,13 +96,13 @@ namespace MWMechanics
|
|||
public:
|
||||
///Constructor
|
||||
/** \param actor Actor to fight **/
|
||||
AiCombat(const MWWorld::Ptr& actor);
|
||||
explicit AiCombat(const MWWorld::Ptr& actor);
|
||||
|
||||
AiCombat (const ESM::AiSequence::AiCombat* combat);
|
||||
explicit AiCombat (const ESM::AiSequence::AiCombat* combat);
|
||||
|
||||
void init();
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Combat; }
|
||||
|
||||
|
@ -116,9 +116,9 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
///Returns target ID
|
||||
MWWorld::Ptr getTarget() const final;
|
||||
MWWorld::Ptr getTarget() const override;
|
||||
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const final;
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const override;
|
||||
|
||||
private:
|
||||
/// Returns true if combat should end
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace MWMechanics
|
|||
|
||||
AiEscort(const ESM::AiSequence::AiEscort* escort);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Escort; }
|
||||
|
||||
|
@ -42,11 +42,11 @@ namespace MWMechanics
|
|||
return options;
|
||||
}
|
||||
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const final;
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const override;
|
||||
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) final;
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) override;
|
||||
|
||||
osg::Vec3f getDestination() const final { return osg::Vec3f(mX, mY, mZ); }
|
||||
osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); }
|
||||
|
||||
private:
|
||||
const std::string mCellId;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace MWMechanics
|
|||
public:
|
||||
AiFace(float targetX, float targetY);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Face; }
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace MWMechanics
|
|||
|
||||
AiFollow(const ESM::AiSequence::AiFollow* follow);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Follow; }
|
||||
|
||||
|
@ -69,15 +69,15 @@ namespace MWMechanics
|
|||
/// Returns the actor being followed
|
||||
std::string getFollowedActor();
|
||||
|
||||
void writeState (ESM::AiSequence::AiSequence& sequence) const final;
|
||||
void writeState (ESM::AiSequence::AiSequence& sequence) const override;
|
||||
|
||||
bool isCommanded() const;
|
||||
|
||||
int getFollowIndex() const;
|
||||
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) final;
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) override;
|
||||
|
||||
osg::Vec3f getDestination() const final
|
||||
osg::Vec3f getDestination() const override
|
||||
{
|
||||
MWWorld::Ptr target = getTarget();
|
||||
if (target.isEmpty())
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace MWMechanics
|
|||
|
||||
AiPursue(const ESM::AiSequence::AiPursue* pursue);
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Pursue; }
|
||||
|
||||
|
@ -38,9 +38,9 @@ namespace MWMechanics
|
|||
return options;
|
||||
}
|
||||
|
||||
MWWorld::Ptr getTarget() const final;
|
||||
MWWorld::Ptr getTarget() const override;
|
||||
|
||||
void writeState (ESM::AiSequence::AiSequence& sequence) const final;
|
||||
void writeState (ESM::AiSequence::AiSequence& sequence) const override;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,14 +25,14 @@ namespace MWMechanics
|
|||
|
||||
AiTravel(float x, float y, float z);
|
||||
|
||||
AiTravel(const ESM::AiSequence::AiTravel* travel);
|
||||
explicit AiTravel(const ESM::AiSequence::AiTravel* travel);
|
||||
|
||||
/// Simulates the passing of time
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) final;
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) override;
|
||||
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const final;
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const override;
|
||||
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; }
|
||||
|
||||
|
@ -44,7 +44,7 @@ namespace MWMechanics
|
|||
return options;
|
||||
}
|
||||
|
||||
osg::Vec3f getDestination() const final { return osg::Vec3f(mX, mY, mZ); }
|
||||
osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); }
|
||||
|
||||
private:
|
||||
const float mX;
|
||||
|
@ -62,7 +62,7 @@ namespace MWMechanics
|
|||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::InternalTravel; }
|
||||
|
||||
std::unique_ptr<AiPackage> clone() const final;
|
||||
std::unique_ptr<AiPackage> clone() const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -89,9 +89,9 @@ namespace MWMechanics
|
|||
\param repeat Repeat wander or not **/
|
||||
AiWander(int distance, int duration, int timeOfDay, const std::vector<unsigned char>& idle, bool repeat);
|
||||
|
||||
AiWander (const ESM::AiSequence::AiWander* wander);
|
||||
explicit AiWander (const ESM::AiSequence::AiWander* wander);
|
||||
|
||||
bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) final;
|
||||
bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override;
|
||||
|
||||
static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Wander; }
|
||||
|
||||
|
@ -103,13 +103,13 @@ namespace MWMechanics
|
|||
return options;
|
||||
}
|
||||
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const final;
|
||||
void writeState(ESM::AiSequence::AiSequence &sequence) const override;
|
||||
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) final;
|
||||
void fastForward(const MWWorld::Ptr& actor, AiState& state) override;
|
||||
|
||||
osg::Vec3f getDestination(const MWWorld::Ptr& actor) const final;
|
||||
osg::Vec3f getDestination(const MWWorld::Ptr& actor) const override;
|
||||
|
||||
osg::Vec3f getDestination() const final
|
||||
osg::Vec3f getDestination() const override
|
||||
{
|
||||
if (!mHasDestination)
|
||||
return osg::Vec3f(0, 0, 0);
|
||||
|
|
|
@ -276,6 +276,7 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle)
|
|||
mCurrentHit = "shield";
|
||||
MWRender::Animation::AnimPriority priorityBlock (Priority_Hit);
|
||||
priorityBlock[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block;
|
||||
priorityBlock[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody;
|
||||
mAnimation->play(mCurrentHit, priorityBlock, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0);
|
||||
}
|
||||
|
||||
|
@ -295,6 +296,8 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle)
|
|||
mUpperBodyState = UpperCharState_Nothing;
|
||||
}
|
||||
}
|
||||
if (mHitState != CharState_None)
|
||||
idle = CharState_None;
|
||||
}
|
||||
else if(!mAnimation->isPlaying(mCurrentHit))
|
||||
{
|
||||
|
@ -314,8 +317,6 @@ void CharacterController::refreshHitRecoilAnims(CharacterState& idle)
|
|||
mAnimation->disable(mCurrentHit);
|
||||
mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "loop stop", "stop", 0.0f, 0);
|
||||
}
|
||||
if (mHitState != CharState_None)
|
||||
idle = CharState_None;
|
||||
}
|
||||
|
||||
void CharacterController::refreshJumpAnims(const std::string& weapShortGroup, JumpingState jump, CharacterState& idle, bool force)
|
||||
|
|
|
@ -971,7 +971,7 @@ namespace MWMechanics
|
|||
{
|
||||
const OwnerMap& owners = it->second;
|
||||
for (OwnerMap::const_iterator ownerIt = owners.begin(); ownerIt != owners.end(); ++ownerIt)
|
||||
result.push_back(std::make_pair(ownerIt->first.first, ownerIt->second));
|
||||
result.emplace_back(ownerIt->first.first, ownerIt->second);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,24 +205,6 @@ namespace MWMechanics
|
|||
break;
|
||||
}
|
||||
|
||||
case ESM::MagicEffect::CurePoison:
|
||||
actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Poison);
|
||||
break;
|
||||
case ESM::MagicEffect::CureParalyzation:
|
||||
actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Paralyze);
|
||||
break;
|
||||
case ESM::MagicEffect::CureCommonDisease:
|
||||
actor.getClass().getCreatureStats(actor).getSpells().purgeCommonDisease();
|
||||
break;
|
||||
case ESM::MagicEffect::CureBlightDisease:
|
||||
actor.getClass().getCreatureStats(actor).getSpells().purgeBlightDisease();
|
||||
break;
|
||||
case ESM::MagicEffect::CureCorprusDisease:
|
||||
actor.getClass().getCreatureStats(actor).getSpells().purgeCorprusDisease();
|
||||
break;
|
||||
case ESM::MagicEffect::RemoveCurse:
|
||||
actor.getClass().getCreatureStats(actor).getSpells().purgeCurses();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace MWMechanics
|
|||
struct EffectKey;
|
||||
|
||||
/// Apply a magic effect that is applied in tick intervals until its remaining time ends or it is removed
|
||||
/// Note: this function works in loop, so magic effects should not be removed here to avoid iterator invalidation.
|
||||
/// @return Was the effect a tickable effect with a magnitude?
|
||||
bool effectTick(CreatureStats& creatureStats, const MWWorld::Ptr& actor, const EffectKey& effectKey, float magnitude);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace MWPhysics
|
|||
|
||||
|
||||
Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler)
|
||||
: mCanWaterWalk(false), mWalkingOnWater(false)
|
||||
: mStandingOnPtr(nullptr), mCanWaterWalk(false), mWalkingOnWater(false)
|
||||
, mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents)
|
||||
, mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false)
|
||||
, mInternalCollisionMode(true)
|
||||
|
@ -74,10 +74,8 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
|
|||
|
||||
updateRotation();
|
||||
updateScale();
|
||||
updatePosition();
|
||||
|
||||
resetPosition();
|
||||
addCollisionMask(getCollisionMask());
|
||||
commitPositionChange();
|
||||
}
|
||||
|
||||
Actor::~Actor()
|
||||
|
@ -122,88 +120,80 @@ int Actor::getCollisionMask() const
|
|||
|
||||
void Actor::updatePosition()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
osg::Vec3f position = mPtr.getRefData().getPosition().asVec3();
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
|
||||
}
|
||||
|
||||
mPosition = position;
|
||||
mPreviousPosition = position;
|
||||
osg::Vec3f Actor::getWorldPosition() const
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
return mWorldPosition;
|
||||
}
|
||||
|
||||
mTransformUpdatePending = true;
|
||||
updateCollisionObjectPosition();
|
||||
void Actor::setNextPosition(const osg::Vec3f& position)
|
||||
{
|
||||
mNextPosition = position;
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getNextPosition() const
|
||||
{
|
||||
return mNextPosition;
|
||||
}
|
||||
|
||||
void Actor::updateCollisionObjectPosition()
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
|
||||
osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale);
|
||||
osg::Vec3f newPosition = scaledTranslation + mPosition;
|
||||
mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition));
|
||||
mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation));
|
||||
|
||||
}
|
||||
|
||||
void Actor::commitPositionChange()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
if (mScaleUpdatePending)
|
||||
{
|
||||
mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
|
||||
mScaleUpdatePending = false;
|
||||
}
|
||||
if (mTransformUpdatePending)
|
||||
{
|
||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||
mTransformUpdatePending = false;
|
||||
}
|
||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getCollisionObjectPosition() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
return Misc::Convert::toOsg(mLocalTransform.getOrigin());
|
||||
}
|
||||
|
||||
void Actor::setPosition(const osg::Vec3f &position, bool updateCollisionObject)
|
||||
void Actor::setPosition(const osg::Vec3f& position)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
if (mTransformUpdatePending)
|
||||
{
|
||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||
mTransformUpdatePending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPreviousPosition = mPosition;
|
||||
mPreviousPosition = mPosition;
|
||||
mPosition = position;
|
||||
}
|
||||
|
||||
mPosition = position;
|
||||
if (updateCollisionObject)
|
||||
{
|
||||
updateCollisionObjectPosition();
|
||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||
}
|
||||
}
|
||||
void Actor::adjustPosition(const osg::Vec3f& offset)
|
||||
{
|
||||
mPosition += offset;
|
||||
mPreviousPosition += offset;
|
||||
}
|
||||
|
||||
void Actor::resetPosition()
|
||||
{
|
||||
updatePosition();
|
||||
mPreviousPosition = mWorldPosition;
|
||||
mPosition = mWorldPosition;
|
||||
mNextPosition = mWorldPosition;
|
||||
updateCollisionObjectPosition();
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getPosition() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getPreviousPosition() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
return mPreviousPosition;
|
||||
}
|
||||
|
||||
void Actor::updateRotation ()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude())
|
||||
return;
|
||||
mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
|
||||
|
||||
mTransformUpdatePending = true;
|
||||
updateCollisionObjectPosition();
|
||||
}
|
||||
|
||||
bool Actor::isRotationallyInvariant() const
|
||||
|
@ -213,37 +203,33 @@ bool Actor::isRotationallyInvariant() const
|
|||
|
||||
void Actor::updateScale()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
float scale = mPtr.getCellRef().getScale();
|
||||
osg::Vec3f scaleVec(scale,scale,scale);
|
||||
|
||||
mPtr.getClass().adjustScale(mPtr, scaleVec, false);
|
||||
mScale = scaleVec;
|
||||
mScaleUpdatePending = true;
|
||||
|
||||
scaleVec = osg::Vec3f(scale,scale,scale);
|
||||
mPtr.getClass().adjustScale(mPtr, scaleVec, true);
|
||||
mRenderingScale = scaleVec;
|
||||
|
||||
mTransformUpdatePending = true;
|
||||
updateCollisionObjectPosition();
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getHalfExtents() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
return osg::componentMultiply(mHalfExtents, mScale);
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getOriginalHalfExtents() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
return mHalfExtents;
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getRenderingHalfExtents() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
return osg::componentMultiply(mHalfExtents, mRenderingScale);
|
||||
}
|
||||
|
||||
|
@ -274,7 +260,7 @@ void Actor::setWalkingOnWater(bool walkingOnWater)
|
|||
|
||||
void Actor::setCanWaterWalk(bool waterWalk)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
if (waterWalk != mCanWaterWalk)
|
||||
{
|
||||
mCanWaterWalk = waterWalk;
|
||||
|
@ -282,4 +268,16 @@ void Actor::setCanWaterWalk(bool waterWalk)
|
|||
}
|
||||
}
|
||||
|
||||
MWWorld::Ptr Actor::getStandingOnPtr() const
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
return mStandingOnPtr;
|
||||
}
|
||||
|
||||
void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
mStandingOnPtr = ptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,13 +57,20 @@ namespace MWPhysics
|
|||
bool isRotationallyInvariant() const;
|
||||
|
||||
/**
|
||||
* Set mPosition and mPreviousPosition to the position in the Ptr's RefData. This should be used
|
||||
* Set mWorldPosition to the position in the Ptr's RefData. This is used by the physics simulation to account for
|
||||
* when an object is "instantly" moved/teleported as opposed to being moved by the physics simulation.
|
||||
*/
|
||||
void updatePosition();
|
||||
osg::Vec3f getWorldPosition() const;
|
||||
|
||||
/**
|
||||
* Used by the physics simulation to store the simulation result. Used in conjunction with mWorldPosition
|
||||
* to account for e.g. scripted movements
|
||||
*/
|
||||
void setNextPosition(const osg::Vec3f& position);
|
||||
osg::Vec3f getNextPosition() const;
|
||||
|
||||
void updateCollisionObjectPosition();
|
||||
void commitPositionChange();
|
||||
|
||||
/**
|
||||
* Returns the half extents of the collision body (scaled according to collision scale)
|
||||
|
@ -83,9 +90,10 @@ namespace MWPhysics
|
|||
|
||||
/**
|
||||
* Store the current position into mPreviousPosition, then move to this position.
|
||||
* Optionally, inform the physics engine about the change of position.
|
||||
*/
|
||||
void setPosition(const osg::Vec3f& position, bool updateCollisionObject=true);
|
||||
void setPosition(const osg::Vec3f& position);
|
||||
void resetPosition();
|
||||
void adjustPosition(const osg::Vec3f& offset);
|
||||
|
||||
osg::Vec3f getPosition() const;
|
||||
|
||||
|
@ -137,7 +145,11 @@ namespace MWPhysics
|
|||
void setWalkingOnWater(bool walkingOnWater);
|
||||
bool isWalkingOnWater() const;
|
||||
|
||||
MWWorld::Ptr getStandingOnPtr() const;
|
||||
void setStandingOnPtr(const MWWorld::Ptr& ptr);
|
||||
|
||||
private:
|
||||
MWWorld::Ptr mStandingOnPtr;
|
||||
/// Removes then re-adds the collision object to the dynamics world
|
||||
void updateCollisionMask();
|
||||
void addCollisionMask(int collisionMask);
|
||||
|
@ -159,11 +171,11 @@ namespace MWPhysics
|
|||
|
||||
osg::Vec3f mScale;
|
||||
osg::Vec3f mRenderingScale;
|
||||
osg::Vec3f mWorldPosition;
|
||||
osg::Vec3f mNextPosition;
|
||||
osg::Vec3f mPosition;
|
||||
osg::Vec3f mPreviousPosition;
|
||||
btTransform mLocalTransform;
|
||||
bool mScaleUpdatePending;
|
||||
bool mTransformUpdatePending;
|
||||
mutable std::mutex mPositionMutex;
|
||||
|
||||
osg::Vec3f mForce;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
|
||||
#include "components/misc/convert.hpp"
|
||||
|
||||
#include "ptrholder.hpp"
|
||||
|
||||
namespace MWPhysics
|
||||
|
@ -20,7 +22,7 @@ namespace MWPhysics
|
|||
collisionObject = col1Wrap->m_collisionObject;
|
||||
PtrHolder* holder = static_cast<PtrHolder*>(collisionObject->getUserPointer());
|
||||
if (holder)
|
||||
mResult.push_back(holder->getPtr());
|
||||
mResult.emplace_back(ContactPoint{holder->getPtr(), Misc::Convert::toOsg(cp.m_positionWorldOnB), Misc::Convert::toOsg(cp.m_normalWorldOnB)});
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "physicssystem.hpp"
|
||||
|
||||
class btCollisionObject;
|
||||
struct btCollisionObjectWrapper;
|
||||
|
||||
|
@ -23,7 +25,7 @@ namespace MWPhysics
|
|||
const btCollisionObjectWrapper* col0Wrap,int partId0,int index0,
|
||||
const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) override;
|
||||
|
||||
std::vector<MWWorld::Ptr> mResult;
|
||||
std::vector<ContactPoint> mResult;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace MWPhysics
|
|||
mObject = collisionObject;
|
||||
mLeastDistSqr = distsqr;
|
||||
mContactPoint = cp.getPositionWorldOnA();
|
||||
mContactNormal = cp.m_normalWorldOnB;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace MWPhysics
|
|||
public:
|
||||
const btCollisionObject *mObject{nullptr};
|
||||
btVector3 mContactPoint{0,0,0};
|
||||
btVector3 mContactNormal{0,0,0};
|
||||
btScalar mLeastDistSqr;
|
||||
|
||||
DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector<const btCollisionObject*>& targets, const btVector3 &origin);
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace MWPhysics
|
|||
{
|
||||
}
|
||||
|
||||
bool process(const btBroadphaseProxy* proxy) final
|
||||
bool process(const btBroadphaseProxy* proxy) override
|
||||
{
|
||||
if (mResult)
|
||||
return false;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
|
||||
#include <osg/Stats>
|
||||
|
||||
#include "components/debug/debuglog.hpp"
|
||||
#include <components/misc/barrier.hpp>
|
||||
#include "components/misc/convert.hpp"
|
||||
|
@ -82,14 +84,6 @@ namespace
|
|||
ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;
|
||||
}
|
||||
|
||||
void updateStandingCollision(MWPhysics::ActorFrameData& actorData, MWPhysics::CollisionMap& standingCollisions)
|
||||
{
|
||||
if (!actorData.mStandingOn.isEmpty())
|
||||
standingCollisions[actorData.mPtr] = actorData.mStandingOn;
|
||||
else
|
||||
standingCollisions.erase(actorData.mPtr);
|
||||
}
|
||||
|
||||
void updateMechanics(MWPhysics::ActorFrameData& actorData)
|
||||
{
|
||||
if (actorData.mDidJump)
|
||||
|
@ -102,9 +96,18 @@ namespace
|
|||
stats.addToFallHeight(-actorData.mFallHeight);
|
||||
}
|
||||
|
||||
osg::Vec3f interpolateMovements(const MWPhysics::ActorFrameData& actorData, float timeAccum, float physicsDt)
|
||||
osg::Vec3f interpolateMovements(MWPhysics::ActorFrameData& actorData, float timeAccum, float physicsDt)
|
||||
{
|
||||
const float interpolationFactor = timeAccum / physicsDt;
|
||||
|
||||
// account for force change of actor's position in the main thread
|
||||
const auto correction = actorData.mActorRaw->getWorldPosition() - actorData.mOrigin;
|
||||
if (correction.length() != 0)
|
||||
{
|
||||
actorData.mActorRaw->adjustPosition(correction);
|
||||
actorData.mPosition = actorData.mActorRaw->getPosition();
|
||||
}
|
||||
|
||||
return actorData.mPosition * interpolationFactor + actorData.mActorRaw->getPreviousPosition() * (1.f - interpolationFactor);
|
||||
}
|
||||
|
||||
|
@ -142,6 +145,7 @@ namespace MWPhysics
|
|||
{
|
||||
PhysicsTaskScheduler::PhysicsTaskScheduler(float physicsDt, std::shared_ptr<btCollisionWorld> collisionWorld)
|
||||
: mPhysicsDt(physicsDt)
|
||||
, mTimeAccum(0.f)
|
||||
, mCollisionWorld(std::move(collisionWorld))
|
||||
, mNumJobs(0)
|
||||
, mRemainingSteps(0)
|
||||
|
@ -152,6 +156,8 @@ namespace MWPhysics
|
|||
, mQuit(false)
|
||||
, mNextJob(0)
|
||||
, mNextLOS(0)
|
||||
, mFrameNumber(0)
|
||||
, mTimer(osg::Timer::instance())
|
||||
{
|
||||
mNumThreads = Config::computeNumThreads(mThreadSafeBullet);
|
||||
|
||||
|
@ -181,22 +187,22 @@ namespace MWPhysics
|
|||
|
||||
mPostSimBarrier = std::make_unique<Misc::Barrier>(mNumThreads, [&]()
|
||||
{
|
||||
udpateActorsAabbs();
|
||||
mNewFrame = false;
|
||||
if (mLOSCacheExpiry >= 0)
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mLOSCacheMutex);
|
||||
std::unique_lock lock(mLOSCacheMutex);
|
||||
mLOSCache.erase(
|
||||
std::remove_if(mLOSCache.begin(), mLOSCache.end(),
|
||||
[](const LOSRequest& req) { return req.mStale; }),
|
||||
mLOSCache.end());
|
||||
}
|
||||
mTimeEnd = mTimer->tick();
|
||||
});
|
||||
}
|
||||
|
||||
PhysicsTaskScheduler::~PhysicsTaskScheduler()
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mSimulationMutex);
|
||||
std::unique_lock lock(mSimulationMutex);
|
||||
mQuit = true;
|
||||
mNumJobs = 0;
|
||||
mRemainingSteps = 0;
|
||||
|
@ -206,19 +212,16 @@ namespace MWPhysics
|
|||
thread.join();
|
||||
}
|
||||
|
||||
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, CollisionMap& standingCollisions, bool skipSimulation)
|
||||
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||
{
|
||||
// This function run in the main thread.
|
||||
// While the mSimulationMutex is held, background physics threads can't run.
|
||||
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mSimulationMutex);
|
||||
std::unique_lock lock(mSimulationMutex);
|
||||
|
||||
// start by finishing previous background computation
|
||||
if (mNumThreads != 0)
|
||||
{
|
||||
if (mAdvanceSimulation)
|
||||
standingCollisions.clear();
|
||||
|
||||
for (auto& data : mActorsFrameData)
|
||||
{
|
||||
// Ignore actors that were deleted while the background thread was running
|
||||
|
@ -227,8 +230,21 @@ namespace MWPhysics
|
|||
|
||||
updateMechanics(data);
|
||||
if (mAdvanceSimulation)
|
||||
updateStandingCollision(data, standingCollisions);
|
||||
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||
|
||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||
}
|
||||
|
||||
if (mFrameNumber == frameNumber - 1)
|
||||
{
|
||||
stats.setAttribute(mFrameNumber, "physicsworker_time_begin", mTimer->delta_s(mFrameStart, mTimeBegin));
|
||||
stats.setAttribute(mFrameNumber, "physicsworker_time_taken", mTimer->delta_s(mTimeBegin, mTimeEnd));
|
||||
stats.setAttribute(mFrameNumber, "physicsworker_time_end", mTimer->delta_s(mFrameStart, mTimeEnd));
|
||||
}
|
||||
mFrameStart = frameStart;
|
||||
mTimeBegin = mTimer->tick();
|
||||
mFrameNumber = frameNumber;
|
||||
}
|
||||
|
||||
// init
|
||||
|
@ -244,18 +260,17 @@ namespace MWPhysics
|
|||
if (mAdvanceSimulation)
|
||||
mWorldFrameData = std::make_unique<WorldFrameData>();
|
||||
|
||||
// update each actor position based on latest data
|
||||
for (auto& data : mActorsFrameData)
|
||||
data.updatePosition();
|
||||
|
||||
// we are asked to skip the simulation (load a savegame for instance)
|
||||
// just return the actors' reference position without applying the movements
|
||||
if (skipSimulation)
|
||||
{
|
||||
standingCollisions.clear();
|
||||
mMovementResults.clear();
|
||||
for (const auto& m : mActorsFrameData)
|
||||
mMovementResults[m.mPtr] = m.mPosition;
|
||||
{
|
||||
m.mActorRaw->setStandingOnPtr(nullptr);
|
||||
m.mActorRaw->resetPosition();
|
||||
mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition();
|
||||
}
|
||||
return mMovementResults;
|
||||
}
|
||||
|
||||
|
@ -264,11 +279,12 @@ namespace MWPhysics
|
|||
mMovementResults.clear();
|
||||
syncComputation();
|
||||
|
||||
if (mAdvanceSimulation)
|
||||
for (auto& data : mActorsFrameData)
|
||||
{
|
||||
standingCollisions.clear();
|
||||
for (auto& data : mActorsFrameData)
|
||||
updateStandingCollision(data, standingCollisions);
|
||||
if (mAdvanceSimulation)
|
||||
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||
}
|
||||
return mMovementResults;
|
||||
}
|
||||
|
@ -294,25 +310,25 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
|
||||
{
|
||||
MaybeSharedLock<std::shared_timed_mutex> lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
mCollisionWorld->rayTest(rayFromWorld, rayToWorld, resultCallback);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const
|
||||
{
|
||||
MaybeSharedLock<std::shared_timed_mutex> lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
mCollisionWorld->convexSweepTest(castShape, from, to, resultCallback);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::shared_lock lock(mCollisionWorldMutex);
|
||||
mCollisionWorld->contactTest(colObj, resultCallback);
|
||||
}
|
||||
|
||||
boost::optional<btVector3> PhysicsTaskScheduler::getHitPoint(const btTransform& from, btCollisionObject* target)
|
||||
std::optional<btVector3> PhysicsTaskScheduler::getHitPoint(const btTransform& from, btCollisionObject* target)
|
||||
{
|
||||
MaybeSharedLock<std::shared_timed_mutex> lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
// target the collision object's world origin, this should be the center of the collision object
|
||||
btTransform rayTo;
|
||||
rayTo.setIdentity();
|
||||
|
@ -323,37 +339,37 @@ namespace MWPhysics
|
|||
mCollisionWorld->rayTestSingle(from, rayTo, target, target->getCollisionShape(), target->getWorldTransform(), cb);
|
||||
if (!cb.hasHit())
|
||||
// didn't hit the target. this could happen if point is already inside the collision box
|
||||
return boost::none;
|
||||
return std::nullopt;
|
||||
return {cb.m_hitPointWorld};
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::shared_lock lock(mCollisionWorldMutex);
|
||||
mCollisionWorld->getBroadphase()->aabbTest(aabbMin, aabbMax, callback);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::shared_lock lock(mCollisionWorldMutex);
|
||||
obj->getCollisionShape()->getAabb(obj->getWorldTransform(), min, max);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask)
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
collisionObject->getBroadphaseHandle()->m_collisionFilterMask = collisionFilterMask;
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
mCollisionWorld->addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::removeCollisionObject(btCollisionObject* collisionObject)
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
mCollisionWorld->removeCollisionObject(collisionObject);
|
||||
}
|
||||
|
||||
|
@ -361,19 +377,19 @@ namespace MWPhysics
|
|||
{
|
||||
if (mDeferAabbUpdate)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mUpdateAabbMutex);
|
||||
std::unique_lock lock(mUpdateAabbMutex);
|
||||
mUpdateAabb.insert(std::move(ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
updatePtrAabb(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsTaskScheduler::getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2)
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mLOSCacheMutex);
|
||||
std::unique_lock lock(mLOSCacheMutex);
|
||||
|
||||
auto actorPtr1 = actor1.lock();
|
||||
auto actorPtr2 = actor2.lock();
|
||||
|
@ -395,7 +411,7 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::refreshLOSCache()
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> lock(mLOSCacheMutex);
|
||||
std::shared_lock lock(mLOSCacheMutex);
|
||||
int job = 0;
|
||||
int numLOS = mLOSCache.size();
|
||||
while ((job = mNextLOS.fetch_add(1, std::memory_order_relaxed)) < numLOS)
|
||||
|
@ -414,9 +430,7 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::updateAabbs()
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock1(mCollisionWorldMutex, std::defer_lock);
|
||||
std::unique_lock<std::mutex> lock2(mUpdateAabbMutex, std::defer_lock);
|
||||
std::lock(lock1, lock2);
|
||||
std::scoped_lock lock(mCollisionWorldMutex, mUpdateAabbMutex);
|
||||
std::for_each(mUpdateAabb.begin(), mUpdateAabb.end(),
|
||||
[this](const std::weak_ptr<PtrHolder>& ptr) { updatePtrAabb(ptr); });
|
||||
mUpdateAabb.clear();
|
||||
|
@ -428,7 +442,7 @@ namespace MWPhysics
|
|||
{
|
||||
if (const auto actor = std::dynamic_pointer_cast<Actor>(p))
|
||||
{
|
||||
actor->commitPositionChange();
|
||||
actor->updateCollisionObjectPosition();
|
||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||
}
|
||||
else if (const auto object = std::dynamic_pointer_cast<Object>(p))
|
||||
|
@ -441,7 +455,7 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::worker()
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> lock(mSimulationMutex);
|
||||
std::shared_lock lock(mSimulationMutex);
|
||||
while (!mQuit)
|
||||
{
|
||||
if (!mNewFrame)
|
||||
|
@ -453,7 +467,7 @@ namespace MWPhysics
|
|||
int job = 0;
|
||||
while (mRemainingSteps && (job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
||||
{
|
||||
MaybeSharedLock<std::shared_timed_mutex> lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
if(const auto actor = mActorsFrameData[job].mActor.lock())
|
||||
MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData);
|
||||
}
|
||||
|
@ -481,33 +495,22 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::updateActorsPositions()
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
for (auto& actorData : mActorsFrameData)
|
||||
{
|
||||
if(const auto actor = actorData.mActor.lock())
|
||||
{
|
||||
if (actorData.mPosition == actor->getPosition())
|
||||
actor->setPosition(actorData.mPosition, false); // update previous position to make sure interpolation is correct
|
||||
else
|
||||
bool positionChanged = actorData.mPosition != actorData.mActorRaw->getPosition();
|
||||
actorData.mActorRaw->setPosition(actorData.mPosition);
|
||||
if (positionChanged)
|
||||
{
|
||||
actorData.mPositionChanged = true;
|
||||
actor->setPosition(actorData.mPosition);
|
||||
actor->updateCollisionObjectPosition();
|
||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::udpateActorsAabbs()
|
||||
{
|
||||
std::unique_lock<std::shared_timed_mutex> lock(mCollisionWorldMutex);
|
||||
for (const auto& actorData : mActorsFrameData)
|
||||
if (actorData.mPositionChanged)
|
||||
{
|
||||
if(const auto actor = actorData.mActor.lock())
|
||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2)
|
||||
{
|
||||
btVector3 pos1 = Misc::Convert::toBullet(actor1->getCollisionObjectPosition() + osg::Vec3f(0,0,actor1->getHalfExtents().z() * 0.9)); // eye level
|
||||
|
@ -517,7 +520,7 @@ namespace MWPhysics
|
|||
resultCallback.m_collisionFilterGroup = 0xFF;
|
||||
resultCallback.m_collisionFilterMask = CollisionType_World|CollisionType_HeightMap|CollisionType_Door;
|
||||
|
||||
MaybeSharedLock<std::shared_timed_mutex> lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
mCollisionWorld->rayTest(pos1, pos2, resultCallback);
|
||||
|
||||
return !resultCallback.hasHit();
|
||||
|
@ -539,6 +542,5 @@ namespace MWPhysics
|
|||
mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt);
|
||||
updateMechanics(actorData);
|
||||
}
|
||||
udpateActorsAabbs();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
#include "physicssystem.hpp"
|
||||
#include "ptrholder.hpp"
|
||||
|
||||
|
@ -30,13 +32,13 @@ namespace MWPhysics
|
|||
/// @param timeAccum accumulated time from previous run to interpolate movements
|
||||
/// @param actorsData per actor data needed to compute new positions
|
||||
/// @return new position of each actor
|
||||
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, CollisionMap& standingCollisions, bool skip);
|
||||
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skip, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||
|
||||
// Thread safe wrappers
|
||||
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
||||
void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const;
|
||||
void contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback);
|
||||
boost::optional<btVector3> getHitPoint(const btTransform& from, btCollisionObject* target);
|
||||
std::optional<btVector3> getHitPoint(const btTransform& from, btCollisionObject* target);
|
||||
void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
|
||||
void getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max);
|
||||
void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask);
|
||||
|
@ -49,7 +51,6 @@ namespace MWPhysics
|
|||
void syncComputation();
|
||||
void worker();
|
||||
void updateActorsPositions();
|
||||
void udpateActorsAabbs();
|
||||
bool hasLineOfSight(const Actor* actor1, const Actor* actor2);
|
||||
void refreshLOSCache();
|
||||
void updateAabbs();
|
||||
|
@ -83,11 +84,17 @@ namespace MWPhysics
|
|||
std::atomic<int> mNextLOS;
|
||||
std::vector<std::thread> mThreads;
|
||||
|
||||
mutable std::shared_timed_mutex mSimulationMutex;
|
||||
mutable std::shared_timed_mutex mCollisionWorldMutex;
|
||||
mutable std::shared_timed_mutex mLOSCacheMutex;
|
||||
mutable std::shared_mutex mSimulationMutex;
|
||||
mutable std::shared_mutex mCollisionWorldMutex;
|
||||
mutable std::shared_mutex mLOSCacheMutex;
|
||||
mutable std::mutex mUpdateAabbMutex;
|
||||
std::condition_variable_any mHasJob;
|
||||
|
||||
unsigned int mFrameNumber;
|
||||
const osg::Timer* mTimer;
|
||||
osg::Timer_t mTimeBegin;
|
||||
osg::Timer_t mTimeEnd;
|
||||
osg::Timer_t mFrameStart;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#include "physicssystem.hpp"
|
||||
|
||||
#include <LinearMath/btIDebugDraw.h>
|
||||
#include <LinearMath/btVector3.h>
|
||||
#include <memory>
|
||||
#include <osg/Group>
|
||||
#include <osg/Stats>
|
||||
#include <osg/Timer>
|
||||
|
||||
#include <BulletCollision/CollisionShapes/btConeShape.h>
|
||||
#include <BulletCollision/CollisionShapes/btSphereShape.h>
|
||||
|
@ -90,6 +94,7 @@ namespace MWPhysics
|
|||
}
|
||||
|
||||
mTaskScheduler = std::make_unique<PhysicsTaskScheduler>(mPhysicsDt, mCollisionWorld);
|
||||
mDebugDrawer = std::make_unique<MWRender::DebugDrawer>(mParentNode, mCollisionWorld.get(), mDebugDrawEnabled);
|
||||
}
|
||||
|
||||
PhysicsSystem::~PhysicsSystem()
|
||||
|
@ -124,14 +129,8 @@ namespace MWPhysics
|
|||
{
|
||||
mDebugDrawEnabled = !mDebugDrawEnabled;
|
||||
|
||||
if (mDebugDrawEnabled && !mDebugDrawer)
|
||||
{
|
||||
mDebugDrawer.reset(new MWRender::DebugDrawer(mParentNode, mCollisionWorld.get()));
|
||||
mCollisionWorld->setDebugDrawer(mDebugDrawer.get());
|
||||
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
|
||||
}
|
||||
else if (mDebugDrawer)
|
||||
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
|
||||
mCollisionWorld->setDebugDrawer(mDebugDrawEnabled ? mDebugDrawer.get() : nullptr);
|
||||
mDebugDrawer->setDebugMode(mDebugDrawEnabled);
|
||||
return mDebugDrawEnabled;
|
||||
}
|
||||
|
||||
|
@ -150,11 +149,11 @@ namespace MWPhysics
|
|||
if (!physactor || !physactor->getOnGround())
|
||||
return false;
|
||||
|
||||
CollisionMap::const_iterator found = mStandingCollisions.find(actor);
|
||||
if (found == mStandingCollisions.end())
|
||||
const auto obj = physactor->getStandingOnPtr();
|
||||
if (obj.isEmpty())
|
||||
return true; // assume standing on terrain (which is a non-object, so not collision tracked)
|
||||
|
||||
ObjectMap::const_iterator foundObj = mObjects.find(found->second);
|
||||
ObjectMap::const_iterator foundObj = mObjects.find(obj);
|
||||
if (foundObj == mObjects.end())
|
||||
return false;
|
||||
|
||||
|
@ -175,6 +174,7 @@ namespace MWPhysics
|
|||
|
||||
if (result.mHit)
|
||||
{
|
||||
reportCollision(Misc::Convert::toBullet(result.mHitPos), Misc::Convert::toBullet(result.mHitNormal));
|
||||
return std::make_pair(result.mHitObject, result.mHitPos);
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,10 @@ namespace MWPhysics
|
|||
{
|
||||
PtrHolder* holder = static_cast<PtrHolder*>(resultCallback.mObject->getUserPointer());
|
||||
if (holder)
|
||||
{
|
||||
reportCollision(resultCallback.mContactPoint, resultCallback.mContactNormal);
|
||||
return std::make_pair(holder->getPtr(), Misc::Convert::toOsg(resultCallback.mContactPoint));
|
||||
}
|
||||
}
|
||||
return std::make_pair(MWWorld::Ptr(), osg::Vec3f());
|
||||
}
|
||||
|
@ -239,7 +242,7 @@ namespace MWPhysics
|
|||
|
||||
auto hitpoint = mTaskScheduler->getHitPoint(rayFrom, targetCollisionObj);
|
||||
if (hitpoint)
|
||||
return (point - Misc::Convert::toOsg(hitpoint.get())).length();
|
||||
return (point - Misc::Convert::toOsg(*hitpoint)).length();
|
||||
|
||||
// didn't hit the target. this could happen if point is already inside the collision box
|
||||
return 0.f;
|
||||
|
@ -401,15 +404,15 @@ namespace MWPhysics
|
|||
return osg::Vec3f();
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> PhysicsSystem::getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const
|
||||
std::vector<ContactPoint> PhysicsSystem::getCollisionsPoints(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const
|
||||
{
|
||||
btCollisionObject* me = nullptr;
|
||||
|
||||
ObjectMap::const_iterator found = mObjects.find(ptr);
|
||||
auto found = mObjects.find(ptr);
|
||||
if (found != mObjects.end())
|
||||
me = found->second->getCollisionObject();
|
||||
else
|
||||
return std::vector<MWWorld::Ptr>();
|
||||
return {};
|
||||
|
||||
ContactTestResultCallback resultCallback (me);
|
||||
resultCallback.m_collisionFilterGroup = collisionGroup;
|
||||
|
@ -418,13 +421,21 @@ namespace MWPhysics
|
|||
return resultCallback.mResult;
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> PhysicsSystem::getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const
|
||||
{
|
||||
std::vector<MWWorld::Ptr> actors;
|
||||
for (auto& [actor, point, normal] : getCollisionsPoints(ptr, collisionGroup, collisionMask))
|
||||
actors.emplace_back(actor);
|
||||
return actors;
|
||||
}
|
||||
|
||||
osg::Vec3f PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight)
|
||||
{
|
||||
ActorMap::iterator found = mActors.find(ptr);
|
||||
if (found == mActors.end())
|
||||
return ptr.getRefData().getPosition().asVec3();
|
||||
else
|
||||
return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight);
|
||||
found->second->resetPosition();
|
||||
return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight);
|
||||
}
|
||||
|
||||
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
||||
|
@ -491,22 +502,6 @@ namespace MWPhysics
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
|
||||
{
|
||||
CollisionMap::iterator found = map.find(old);
|
||||
if (found != map.end())
|
||||
{
|
||||
map[updated] = found->second;
|
||||
map.erase(found);
|
||||
}
|
||||
|
||||
for (auto& collision : map)
|
||||
{
|
||||
if (collision.second == old)
|
||||
collision.second = updated;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
|
||||
{
|
||||
ObjectMap::iterator found = mObjects.find(old);
|
||||
|
@ -527,7 +522,11 @@ namespace MWPhysics
|
|||
mActors.emplace(updated, std::move(actor));
|
||||
}
|
||||
|
||||
updateCollisionMapPtr(mStandingCollisions, old, updated);
|
||||
for (auto& [_, actor] : mActors)
|
||||
{
|
||||
if (actor->getStandingOnPtr() == old)
|
||||
actor->setStandingOnPtr(updated);
|
||||
}
|
||||
}
|
||||
|
||||
Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr)
|
||||
|
@ -648,27 +647,26 @@ namespace MWPhysics
|
|||
return false;
|
||||
}
|
||||
|
||||
void PhysicsSystem::queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &movement)
|
||||
void PhysicsSystem::queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity)
|
||||
{
|
||||
for(auto& movementItem : mMovementQueue)
|
||||
{
|
||||
if (movementItem.first == ptr)
|
||||
{
|
||||
movementItem.second = movement;
|
||||
movementItem.second = velocity;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mMovementQueue.emplace_back(ptr, movement);
|
||||
mMovementQueue.emplace_back(ptr, velocity);
|
||||
}
|
||||
|
||||
void PhysicsSystem::clearQueuedMovement()
|
||||
{
|
||||
mMovementQueue.clear();
|
||||
mStandingCollisions.clear();
|
||||
}
|
||||
|
||||
const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation)
|
||||
const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||
{
|
||||
mTimeAccum += dt;
|
||||
|
||||
|
@ -678,24 +676,20 @@ namespace MWPhysics
|
|||
|
||||
mTimeAccum -= numSteps * mPhysicsDt;
|
||||
|
||||
return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(), mStandingCollisions, skipSimulation);
|
||||
return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), skipSimulation, frameStart, frameNumber, stats);
|
||||
}
|
||||
|
||||
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData()
|
||||
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps)
|
||||
{
|
||||
std::vector<ActorFrameData> actorsFrameData;
|
||||
actorsFrameData.reserve(mMovementQueue.size());
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
for (const auto& m : mMovementQueue)
|
||||
for (const auto& [character, movement] : mMovementQueue)
|
||||
{
|
||||
const auto& character = m.first;
|
||||
const auto& movement = m.second;
|
||||
const auto foundActor = mActors.find(character);
|
||||
if (foundActor == mActors.end()) // actor was already removed from the scene
|
||||
{
|
||||
mStandingCollisions.erase(character);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto physicActor = foundActor->second;
|
||||
|
||||
float waterlevel = -std::numeric_limits<float>::max();
|
||||
|
@ -723,7 +717,12 @@ namespace MWPhysics
|
|||
// Slow fall reduces fall speed by a factor of (effect magnitude / 200)
|
||||
const float slowFall = 1.f - std::max(0.f, std::min(1.f, effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f));
|
||||
|
||||
actorsFrameData.emplace_back(std::move(physicActor), character, mStandingCollisions[character], moveToWaterSurface, movement, slowFall, waterlevel);
|
||||
// Ue current value only if we don't advance the simulation. Otherwise we might get a stale value.
|
||||
MWWorld::Ptr standingOn;
|
||||
if (numSteps == 0)
|
||||
standingOn = physicActor->getStandingOnPtr();
|
||||
|
||||
actorsFrameData.emplace_back(std::move(physicActor), character, standingOn, moveToWaterSurface, movement, slowFall, waterlevel);
|
||||
}
|
||||
mMovementQueue.clear();
|
||||
return actorsFrameData;
|
||||
|
@ -755,26 +754,24 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsSystem::debugDraw()
|
||||
{
|
||||
if (mDebugDrawer)
|
||||
if (mDebugDrawEnabled)
|
||||
mDebugDrawer->step();
|
||||
}
|
||||
|
||||
bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const
|
||||
{
|
||||
for (const auto& standingActor : mStandingCollisions)
|
||||
{
|
||||
if (standingActor.first == actor && standingActor.second == object)
|
||||
return true;
|
||||
}
|
||||
const auto physActor = mActors.find(actor);
|
||||
if (physActor != mActors.end())
|
||||
return physActor->second->getStandingOnPtr() == object;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr &object, std::vector<MWWorld::Ptr> &out) const
|
||||
{
|
||||
for (const auto& standingActor : mStandingCollisions)
|
||||
for (const auto& [_, actor] : mActors)
|
||||
{
|
||||
if (standingActor.second == object)
|
||||
out.push_back(standingActor.first);
|
||||
if (actor->getStandingOnPtr() == object)
|
||||
out.emplace_back(actor->getPtr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -861,10 +858,16 @@ namespace MWPhysics
|
|||
stats.setAttribute(frameNumber, "Physics HeightFields", mHeightFields.size());
|
||||
}
|
||||
|
||||
void PhysicsSystem::reportCollision(const btVector3& position, const btVector3& normal)
|
||||
{
|
||||
if (mDebugDrawEnabled)
|
||||
mDebugDrawer->addCollision(position, normal);
|
||||
}
|
||||
|
||||
ActorFrameData::ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn,
|
||||
bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel)
|
||||
: mActor(actor), mActorRaw(actor.get()), mStandingOn(standingOn),
|
||||
mPositionChanged(false), mDidJump(false), mNeedLand(false), mMoveToWaterSurface(moveToWaterSurface),
|
||||
mDidJump(false), mNeedLand(false), mMoveToWaterSurface(moveToWaterSurface),
|
||||
mWaterlevel(waterlevel), mSlowFall(slowFall), mOldHeight(0), mFallHeight(0), mMovement(movement), mPosition(), mRefpos()
|
||||
{
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
|
@ -874,10 +877,9 @@ namespace MWPhysics
|
|||
mWantJump = mPtr.getClass().getMovementSettings(mPtr).mPosition[2] != 0;
|
||||
mIsDead = mPtr.getClass().getCreatureStats(mPtr).isDead();
|
||||
mWasOnGround = actor->getOnGround();
|
||||
}
|
||||
|
||||
void ActorFrameData::updatePosition()
|
||||
{
|
||||
mActorRaw->updatePosition();
|
||||
mOrigin = mActorRaw->getNextPosition();
|
||||
mPosition = mActorRaw->getPosition();
|
||||
if (mMoveToWaterSurface)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <osg/Quat>
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Timer>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
|
@ -45,17 +46,24 @@ class btDefaultCollisionConfiguration;
|
|||
class btCollisionDispatcher;
|
||||
class btCollisionObject;
|
||||
class btCollisionShape;
|
||||
class btVector3;
|
||||
|
||||
namespace MWPhysics
|
||||
{
|
||||
using PtrPositionList = std::map<MWWorld::Ptr, osg::Vec3f>;
|
||||
using CollisionMap = std::map<MWWorld::Ptr, MWWorld::Ptr>;
|
||||
|
||||
class HeightField;
|
||||
class Object;
|
||||
class Actor;
|
||||
class PhysicsTaskScheduler;
|
||||
|
||||
struct ContactPoint
|
||||
{
|
||||
MWWorld::Ptr mObject;
|
||||
osg::Vec3f mPoint;
|
||||
osg::Vec3f mNormal;
|
||||
};
|
||||
|
||||
struct LOSRequest
|
||||
{
|
||||
LOSRequest(const std::weak_ptr<Actor>& a1, const std::weak_ptr<Actor>& a2);
|
||||
|
@ -70,14 +78,12 @@ namespace MWPhysics
|
|||
struct ActorFrameData
|
||||
{
|
||||
ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel);
|
||||
void updatePosition();
|
||||
std::weak_ptr<Actor> mActor;
|
||||
Actor* mActorRaw;
|
||||
MWWorld::Ptr mPtr;
|
||||
MWWorld::Ptr mStandingOn;
|
||||
bool mFlying;
|
||||
bool mSwimming;
|
||||
bool mPositionChanged;
|
||||
bool mWasOnGround;
|
||||
bool mWantJump;
|
||||
bool mDidJump;
|
||||
|
@ -89,6 +95,7 @@ namespace MWPhysics
|
|||
float mOldHeight;
|
||||
float mFallHeight;
|
||||
osg::Vec3f mMovement;
|
||||
osg::Vec3f mOrigin;
|
||||
osg::Vec3f mPosition;
|
||||
ESM::Position mRefpos;
|
||||
};
|
||||
|
@ -144,6 +151,7 @@ namespace MWPhysics
|
|||
void debugDraw();
|
||||
|
||||
std::vector<MWWorld::Ptr> getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; ///< get handles this object collides with
|
||||
std::vector<ContactPoint> getCollisionsPoints(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const;
|
||||
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight);
|
||||
|
||||
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::ConstPtr& actor,
|
||||
|
@ -156,17 +164,17 @@ namespace MWPhysics
|
|||
/// target vector hits the collision shape and then calculates distance from the intersection point.
|
||||
/// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful.
|
||||
/// \note Only Actor targets are supported at the moment.
|
||||
float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const final;
|
||||
float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const override;
|
||||
|
||||
/// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors.
|
||||
RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(),
|
||||
std::vector<MWWorld::Ptr> targets = std::vector<MWWorld::Ptr>(),
|
||||
int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const final;
|
||||
int mask = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const override;
|
||||
|
||||
RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const final;
|
||||
RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius) const override;
|
||||
|
||||
/// Return true if actor1 can see actor2.
|
||||
bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const final;
|
||||
bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const override;
|
||||
|
||||
bool isOnGround (const MWWorld::Ptr& actor);
|
||||
|
||||
|
@ -193,7 +201,7 @@ namespace MWPhysics
|
|||
void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity);
|
||||
|
||||
/// Apply all queued movements, then clear the list.
|
||||
const PtrPositionList& applyQueuedMovement(float dt, bool skipSimulation);
|
||||
const PtrPositionList& applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||
|
||||
/// Clear the queued movements list without applying.
|
||||
void clearQueuedMovement();
|
||||
|
@ -232,12 +240,13 @@ namespace MWPhysics
|
|||
bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, const MWWorld::ConstPtr& ignore) const;
|
||||
|
||||
void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
|
||||
void reportCollision(const btVector3& position, const btVector3& normal);
|
||||
|
||||
private:
|
||||
|
||||
void updateWater();
|
||||
|
||||
std::vector<ActorFrameData> prepareFrameData();
|
||||
std::vector<ActorFrameData> prepareFrameData(int numSteps);
|
||||
|
||||
osg::ref_ptr<SceneUtil::UnrefQueue> mUnrefQueue;
|
||||
|
||||
|
@ -263,13 +272,6 @@ namespace MWPhysics
|
|||
|
||||
bool mDebugDrawEnabled;
|
||||
|
||||
// Tracks standing collisions happening during a single frame. <actor handle, collided handle>
|
||||
// This will detect standing on an object, but won't detect running e.g. against a wall.
|
||||
CollisionMap mStandingCollisions;
|
||||
|
||||
// replaces all occurrences of 'old' in the map by 'updated', no matter if it's a key or value
|
||||
void updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated);
|
||||
|
||||
using PtrVelocityList = std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>>;
|
||||
PtrVelocityList mMovementQueue;
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/resource/keyframemanager.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
#include <components/misc/constants.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
|
@ -37,8 +36,6 @@
|
|||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
@ -66,7 +63,7 @@ namespace
|
|||
void apply(osg::Node &node) override
|
||||
{
|
||||
if (dynamic_cast<osgParticle::ParticleProcessor*>(&node))
|
||||
mToRemove.push_back(&node);
|
||||
mToRemove.emplace_back(&node);
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
@ -74,7 +71,7 @@ namespace
|
|||
void apply(osg::Drawable& drw) override
|
||||
{
|
||||
if (osgParticle::ParticleSystem* partsys = dynamic_cast<osgParticle::ParticleSystem*>(&drw))
|
||||
mToRemove.push_back(partsys);
|
||||
mToRemove.emplace_back(partsys);
|
||||
}
|
||||
|
||||
void remove()
|
||||
|
@ -278,7 +275,7 @@ namespace
|
|||
if (vfxCallback)
|
||||
{
|
||||
if (vfxCallback->mFinished)
|
||||
mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0)));
|
||||
mToRemove.emplace_back(group.asNode(), group.getParent(0));
|
||||
else
|
||||
mHasMagicEffects = true;
|
||||
}
|
||||
|
@ -331,7 +328,7 @@ namespace
|
|||
{
|
||||
bool toRemove = mEffectId < 0 || vfxCallback->mParams.mEffectId == mEffectId;
|
||||
if (toRemove)
|
||||
mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0)));
|
||||
mToRemove.emplace_back(group.asNode(), group.getParent(0));
|
||||
else
|
||||
mHasMagicEffects = true;
|
||||
}
|
||||
|
@ -432,7 +429,7 @@ namespace
|
|||
node.setStateSet(nullptr);
|
||||
|
||||
if (node.getNodeMask() == 0x1 && node.getNumParents() == 1)
|
||||
mToRemove.push_back(std::make_pair(&node, node.getParent(0)));
|
||||
mToRemove.emplace_back(&node, node.getParent(0));
|
||||
else
|
||||
traverse(node);
|
||||
}
|
||||
|
@ -450,12 +447,12 @@ namespace
|
|||
osg::Group* parentParent = static_cast<osg::Group*>(*(parent - 1));
|
||||
if (parentGroup->getNumChildren() == 1 && parentGroup->getDataVariance() == osg::Object::STATIC)
|
||||
{
|
||||
mToRemove.push_back(std::make_pair(parentGroup, parentParent));
|
||||
mToRemove.emplace_back(parentGroup, parentParent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mToRemove.push_back(std::make_pair(&node, parentGroup));
|
||||
mToRemove.emplace_back(&node, parentGroup);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -483,7 +480,7 @@ namespace
|
|||
{
|
||||
osg::Group* parent = static_cast<osg::Group*>(*(getNodePath().end()-2));
|
||||
// Not safe to remove in apply(), since the visitor is still iterating the child list
|
||||
mToRemove.push_back(std::make_pair(&node, parent));
|
||||
mToRemove.emplace_back(&node, parent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -494,9 +491,8 @@ namespace MWRender
|
|||
class TransparencyUpdater : public SceneUtil::StateSetUpdater
|
||||
{
|
||||
public:
|
||||
TransparencyUpdater(const float alpha, osg::ref_ptr<osg::Uniform> shadowUniform)
|
||||
TransparencyUpdater(const float alpha)
|
||||
: mAlpha(alpha)
|
||||
, mShadowUniform(shadowUniform)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -510,9 +506,6 @@ namespace MWRender
|
|||
{
|
||||
osg::BlendFunc* blendfunc (new osg::BlendFunc);
|
||||
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
||||
// TODO: don't do this anymore once custom shadow renderbin is handling it
|
||||
if (mShadowUniform)
|
||||
stateset->addUniform(mShadowUniform);
|
||||
|
||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
|
||||
|
@ -534,7 +527,6 @@ namespace MWRender
|
|||
|
||||
private:
|
||||
float mAlpha;
|
||||
osg::ref_ptr<osg::Uniform> mShadowUniform;
|
||||
};
|
||||
|
||||
struct Animation::AnimSource
|
||||
|
@ -1827,7 +1819,7 @@ namespace MWRender
|
|||
{
|
||||
if (mTransparencyUpdater == nullptr)
|
||||
{
|
||||
mTransparencyUpdater = new TransparencyUpdater(alpha, mResourceSystem->getSceneManager()->getShaderManager().getShadowMapAlphaTestEnableUniform());
|
||||
mTransparencyUpdater = new TransparencyUpdater(alpha);
|
||||
mObjectRoot->addCullCallback(mTransparencyUpdater);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "bulletdebugdraw.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||
|
||||
|
@ -6,27 +6,19 @@
|
|||
#include <osg/Group>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/misc/convert.hpp>
|
||||
|
||||
#include "bulletdebugdraw.hpp"
|
||||
#include "vismask.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
osg::Vec3f toOsg(const btVector3& vec)
|
||||
{
|
||||
return osg::Vec3f(vec.x(), vec.y(), vec.z());
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
DebugDrawer::DebugDrawer(osg::ref_ptr<osg::Group> parentNode, btCollisionWorld *world)
|
||||
DebugDrawer::DebugDrawer(osg::ref_ptr<osg::Group> parentNode, btCollisionWorld *world, int debugMode)
|
||||
: mParentNode(parentNode),
|
||||
mWorld(world),
|
||||
mDebugOn(true)
|
||||
mWorld(world)
|
||||
{
|
||||
|
||||
createGeometry();
|
||||
setDebugMode(debugMode);
|
||||
}
|
||||
|
||||
void DebugDrawer::createGeometry()
|
||||
|
@ -37,11 +29,14 @@ void DebugDrawer::createGeometry()
|
|||
mGeometry->setNodeMask(Mask_Debug);
|
||||
|
||||
mVertices = new osg::Vec3Array;
|
||||
mColors = new osg::Vec4Array;
|
||||
|
||||
mDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES);
|
||||
|
||||
mGeometry->setUseDisplayList(false);
|
||||
mGeometry->setVertexArray(mVertices);
|
||||
mGeometry->setColorArray(mColors);
|
||||
mGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
mGeometry->setDataVariance(osg::Object::DYNAMIC);
|
||||
mGeometry->addPrimitiveSet(mDrawArrays);
|
||||
|
||||
|
@ -70,23 +65,53 @@ void DebugDrawer::step()
|
|||
if (mDebugOn)
|
||||
{
|
||||
mVertices->clear();
|
||||
mColors->clear();
|
||||
mWorld->debugDrawWorld();
|
||||
showCollisions();
|
||||
mDrawArrays->setCount(mVertices->size());
|
||||
mVertices->dirty();
|
||||
mColors->dirty();
|
||||
mGeometry->dirtyBound();
|
||||
}
|
||||
}
|
||||
|
||||
void DebugDrawer::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)
|
||||
{
|
||||
mVertices->push_back(toOsg(from));
|
||||
mVertices->push_back(toOsg(to));
|
||||
mVertices->push_back(Misc::Convert::toOsg(from));
|
||||
mVertices->push_back(Misc::Convert::toOsg(to));
|
||||
mColors->push_back({1,1,1,1});
|
||||
mColors->push_back({1,1,1,1});
|
||||
}
|
||||
|
||||
void DebugDrawer::addCollision(const btVector3& orig, const btVector3& normal)
|
||||
{
|
||||
mCollisionViews.emplace_back(orig, normal);
|
||||
}
|
||||
|
||||
void DebugDrawer::showCollisions()
|
||||
{
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
for (auto& [from, to , created] : mCollisionViews)
|
||||
{
|
||||
if (now - created < std::chrono::seconds(2))
|
||||
{
|
||||
mVertices->push_back(Misc::Convert::toOsg(from));
|
||||
mVertices->push_back(Misc::Convert::toOsg(to));
|
||||
mColors->push_back({1,0,0,1});
|
||||
mColors->push_back({1,0,0,1});
|
||||
}
|
||||
}
|
||||
mCollisionViews.erase(std::remove_if(mCollisionViews.begin(), mCollisionViews.end(),
|
||||
[&now](const CollisionView& view) { return now - view.mCreated >= std::chrono::seconds(2); }),
|
||||
mCollisionViews.end());
|
||||
}
|
||||
|
||||
void DebugDrawer::drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)
|
||||
{
|
||||
mVertices->push_back(toOsg(PointOnB));
|
||||
mVertices->push_back(toOsg(PointOnB) + (toOsg(normalOnB) * distance * 20));
|
||||
mVertices->push_back(Misc::Convert::toOsg(PointOnB));
|
||||
mVertices->push_back(Misc::Convert::toOsg(PointOnB) + (Misc::Convert::toOsg(normalOnB) * distance * 20));
|
||||
mColors->push_back({1,1,1,1});
|
||||
mColors->push_back({1,1,1,1});
|
||||
}
|
||||
|
||||
void DebugDrawer::reportErrorWarning(const char *warningString)
|
||||
|
@ -96,7 +121,7 @@ void DebugDrawer::reportErrorWarning(const char *warningString)
|
|||
|
||||
void DebugDrawer::setDebugMode(int isOn)
|
||||
{
|
||||
mDebugOn = (isOn == 0) ? false : true;
|
||||
mDebugOn = (isOn != 0);
|
||||
|
||||
if (!mDebugOn)
|
||||
destroyGeometry();
|
||||
|
@ -109,6 +134,4 @@ int DebugDrawer::getDebugMode() const
|
|||
return mDebugOn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef OPENMW_MWRENDER_BULLETDEBUGDRAW_H
|
||||
#define OPENMW_MWRENDER_BULLETDEBUGDRAW_H
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Array>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
@ -20,11 +23,22 @@ namespace MWRender
|
|||
|
||||
class DebugDrawer : public btIDebugDraw
|
||||
{
|
||||
private:
|
||||
struct CollisionView
|
||||
{
|
||||
btVector3 mOrig;
|
||||
btVector3 mEnd;
|
||||
std::chrono::time_point<std::chrono::steady_clock> mCreated;
|
||||
CollisionView(btVector3 orig, btVector3 normal) : mOrig(orig), mEnd(orig + normal * 20), mCreated(std::chrono::steady_clock::now()) {};
|
||||
};
|
||||
std::vector<CollisionView> mCollisionViews;
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<osg::Group> mParentNode;
|
||||
btCollisionWorld *mWorld;
|
||||
osg::ref_ptr<osg::Geometry> mGeometry;
|
||||
osg::ref_ptr<osg::Vec3Array> mVertices;
|
||||
osg::ref_ptr<osg::Vec4Array> mColors;
|
||||
osg::ref_ptr<osg::DrawArrays> mDrawArrays;
|
||||
|
||||
bool mDebugOn;
|
||||
|
@ -34,13 +48,17 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
DebugDrawer(osg::ref_ptr<osg::Group> parentNode, btCollisionWorld *world);
|
||||
DebugDrawer(osg::ref_ptr<osg::Group> parentNode, btCollisionWorld *world, int debugMode = 1);
|
||||
~DebugDrawer();
|
||||
|
||||
void step();
|
||||
|
||||
void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) override;
|
||||
|
||||
void addCollision(const btVector3& orig, const btVector3& normal);
|
||||
|
||||
void showCollisions();
|
||||
|
||||
void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) override;
|
||||
|
||||
void reportErrorWarning(const char* warningString) override;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue