From 7fe39c6a3a8c7f4d2e9337566c40d2153d2e9333 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Fri, 22 Jan 2021 19:42:24 +0000 Subject: [PATCH 001/396] sdlcursormanager: Clarify ANDROID check This check will not be needed in the upcoming versions of OSG. This was originally needed due to a bug in OSG that was fixed in https://github.com/openscenegraph/OpenSceneGraph/pull/1027 --- components/sdlutil/sdlcursormanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sdlutil/sdlcursormanager.cpp b/components/sdlutil/sdlcursormanager.cpp index 56225868e3..626930291d 100644 --- a/components/sdlutil/sdlcursormanager.cpp +++ b/components/sdlutil/sdlcursormanager.cpp @@ -20,7 +20,7 @@ #include "imagetosurface.hpp" -#if defined(OSG_LIBRARY_STATIC) && !defined(ANDROID) +#if defined(OSG_LIBRARY_STATIC) && (!defined(ANDROID) || OSG_VERSION_GREATER_THAN(3, 6, 5)) // Sets the default windowing system interface according to the OS. // Necessary for OpenSceneGraph to do some things, like decompression. USE_GRAPHICSWINDOW() From 56fe1a8c12f49065fb9c339da996b9a403b4f84c Mon Sep 17 00:00:00 2001 From: wareya Date: Fri, 19 Mar 2021 21:49:17 -0400 Subject: [PATCH 002/396] wobbly water --- files/shaders/water_fragment.glsl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index d9b9463ad9..fc0167d84e 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -231,6 +231,7 @@ void main(void) #if REFRACTION // refraction vec3 refraction = texture2D(refractionMap, screenCoords - screenCoordsOffset).rgb; + vec3 rawRefraction = refraction; // brighten up the refraction underwater if (cameraPos.z < 0.0) @@ -249,6 +250,12 @@ void main(void) float lightScatter = clamp(dot(lVec,lNormal)*0.7+0.3, 0.0, 1.0) * clamp(dot(lR, vVec)*2.0-1.2, 0.0, 1.0) * SCATTER_AMOUNT * sunFade * clamp(1.0-exp(-sunHeight), 0.0, 1.0); gl_FragData[0].xyz = mix( mix(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * gl_LightSource[0].specular.xyz + vec3(rainRipple.w) * 0.2; gl_FragData[0].w = 1.0; + + // wobbly water: hard-fade into refraction texture at extremely low depth, with a wobble based on normal mapping + vec3 normalShoreRippleRain = texture2D(normalMap,normalCoords(UV, 2.0, 2.7, -1.0*waterTimer, 0.05, 0.1, normal3)).rgb - 0.5 + + texture2D(normalMap,normalCoords(UV, 2.0, 2.7, waterTimer, 0.04, -0.13, normal4)).rgb - 0.5; + float shoreOffset = clamp((realWaterDepth - (normal2.r + mix(0, normalShoreRippleRain.r, rainIntensity) + 0.35)*8), 0, 1); + gl_FragData[0].xyz = mix(rawRefraction, gl_FragData[0].xyz, shoreOffset); #else gl_FragData[0].xyz = mix(reflection, waterColor, (1.0-fresnel)*0.5) + specular * gl_LightSource[0].specular.xyz + vec3(rainRipple.w) * 0.7; gl_FragData[0].w = clamp(fresnel*6.0 + specular * gl_LightSource[0].specular.w, 0.0, 1.0); //clamp(fresnel*2.0 + specular * gl_LightSource[0].specular.w, 0.0, 1.0); From 2ea0bf91e684b17aa1f63bc24224aa1d2db83da6 Mon Sep 17 00:00:00 2001 From: wareya Date: Sat, 20 Mar 2021 13:11:19 -0400 Subject: [PATCH 003/396] try to estimate vertical water depth, not screen-direction water depth --- files/shaders/water_fragment.glsl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/files/shaders/water_fragment.glsl b/files/shaders/water_fragment.glsl index fc0167d84e..e829e1a869 100644 --- a/files/shaders/water_fragment.glsl +++ b/files/shaders/water_fragment.glsl @@ -254,7 +254,11 @@ void main(void) // wobbly water: hard-fade into refraction texture at extremely low depth, with a wobble based on normal mapping vec3 normalShoreRippleRain = texture2D(normalMap,normalCoords(UV, 2.0, 2.7, -1.0*waterTimer, 0.05, 0.1, normal3)).rgb - 0.5 + texture2D(normalMap,normalCoords(UV, 2.0, 2.7, waterTimer, 0.04, -0.13, normal4)).rgb - 0.5; - float shoreOffset = clamp((realWaterDepth - (normal2.r + mix(0, normalShoreRippleRain.r, rainIntensity) + 0.35)*8), 0, 1); + float verticalWaterDepth = realWaterDepth * mix(abs(vVec.z), 1.0, 0.2); // an estimate + float shoreOffset = verticalWaterDepth - (normal2.r + mix(0, normalShoreRippleRain.r, rainIntensity) + 0.15)*8; + float fuzzFactor = min(1.0, 1000.0/surfaceDepth) * mix(abs(vVec.z), 1, 0.2); + shoreOffset *= fuzzFactor; + shoreOffset = clamp(shoreOffset, 0, 1); gl_FragData[0].xyz = mix(rawRefraction, gl_FragData[0].xyz, shoreOffset); #else gl_FragData[0].xyz = mix(reflection, waterColor, (1.0-fresnel)*0.5) + specular * gl_LightSource[0].specular.xyz + vec3(rainRipple.w) * 0.7; From f81be5b4639b6b17d7c8874addd8a7fdb9206663 Mon Sep 17 00:00:00 2001 From: CedricMocquillon Date: Thu, 13 May 2021 19:59:28 +0200 Subject: [PATCH 004/396] Replace land static container from vector to flat_set I use a ordered container to fix the "is there any other way to speed this up?". The flat_set allow to have the same locality when searching an element. I use the is_transparent C++14 feature to avoid to create a dummy Land when searching I use a unique_ptr to avoid to manualy manage the memory --- apps/openmw/mwworld/store.cpp | 48 +++-------------------------------- apps/openmw/mwworld/store.hpp | 34 ++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index fb66b0a1d7..d2c4725117 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -11,25 +11,6 @@ #include #include -namespace -{ - struct Compare - { - bool operator()(const ESM::Land *x, const ESM::Land *y) { - if (x->mX == y->mX) { - return x->mY < y->mY; - } - return x->mX < y->mX; - } - bool operator()(const ESM::Land *x, const std::pair& y) { - if (x->mX == y.first) { - return x->mY < y.second; - } - return x->mX < y.first; - } - }; -} - namespace MWWorld { RecordId::RecordId(const std::string &id, bool isDeleted) @@ -425,11 +406,6 @@ namespace MWWorld //========================================================================= Store::~Store() { - for (const ESM::Land* staticLand : mStatic) - { - delete staticLand; - } - } size_t Store::getSize() const { @@ -446,12 +422,8 @@ namespace MWWorld const ESM::Land *Store::search(int x, int y) const { std::pair comp(x,y); - - std::vector::const_iterator it = - std::lower_bound(mStatic.begin(), mStatic.end(), comp, Compare()); - - if (it != mStatic.end() && (*it)->mX == x && (*it)->mY == y) { - return *it; + if (auto it = mStatic.find(comp); it != mStatic.end() && (*it)->mX == x && (*it)->mY == y) { + return it->get(); } return nullptr; } @@ -467,24 +439,13 @@ namespace MWWorld } RecordId Store::load(ESM::ESMReader &esm) { - ESM::Land *ptr = new ESM::Land(); + auto ptr = std::make_unique(); bool isDeleted = false; ptr->load(esm, isDeleted); // Same area defined in multiple plugins? -> last plugin wins - // Can't use search() because we aren't sorted yet - is there any other way to speed this up? - for (std::vector::iterator it = mStatic.begin(); it != mStatic.end(); ++it) - { - if ((*it)->mX == ptr->mX && (*it)->mY == ptr->mY) - { - delete *it; - mStatic.erase(it); - break; - } - } - - mStatic.push_back(ptr); + mStatic.insert(std::move(ptr)); return RecordId("", isDeleted); } @@ -494,7 +455,6 @@ namespace MWWorld if (mBuilt) return; - std::sort(mStatic.begin(), mStatic.end(), Compare()); mBuilt = true; } diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index e37152431e..d65422516a 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include "recordcmp.hpp" @@ -74,10 +76,10 @@ namespace MWWorld const T *find(int index) const; }; - template + template > class SharedIterator { - typedef typename std::vector::const_iterator Iter; + typedef typename Container::const_iterator Iter; Iter mIter; @@ -233,10 +235,34 @@ namespace MWWorld template <> class Store : public StoreBase { - std::vector mStatic; + struct SpatialComparator + { + using is_transparent = void; + + bool operator()(const std::unique_ptr& x, const std::unique_ptr& y) const { + if (x->mX == y->mX) { + return x->mY < y->mY; + } + return x->mX < y->mX; + } + bool operator()(const std::unique_ptr& x, const std::pair& y) const { + if (x->mX == y.first) { + return x->mY < y.second; + } + return x->mX < y.first; + } + bool operator()(const std::pair& x, const std::unique_ptr& y) const { + if (x.first == y->mX) { + return x.second < y->mY; + } + return x.first < y->mX; + } + }; + using Statics = boost::container::flat_set, SpatialComparator>; + Statics mStatic; public: - typedef SharedIterator iterator; + typedef SharedIterator iterator; virtual ~Store(); From 6ba23a028c6e7b6652c5c73af3aacc73bbf70dfb Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Tue, 18 May 2021 18:23:16 -0500 Subject: [PATCH 005/396] Removing unused imports in the Launcher --- apps/launcher/datafilespage.cpp | 1 - apps/launcher/graphicspage.cpp | 2 -- apps/launcher/maindialog.cpp | 1 - apps/launcher/settingspage.cpp | 5 ----- apps/launcher/utils/openalutil.cpp | 1 - 5 files changed, 10 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 956483a3f2..24729d5096 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -17,7 +17,6 @@ #include #include -#include #include "utils/textinputdialog.hpp" #include "utils/profilescombobox.hpp" diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 3bfd90fdeb..bb906085be 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -15,8 +15,6 @@ #include -#include - QString getAspect(int x, int y) { int gcd = std::gcd (x, y); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d41cd529d3..de3070f463 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index ca7fd028a7..9c750a7c25 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -4,11 +4,6 @@ #include #include -#include - -#include -#include - #include "utils/textinputdialog.hpp" #include "datafilespage.hpp" diff --git a/apps/launcher/utils/openalutil.cpp b/apps/launcher/utils/openalutil.cpp index 52ad20894d..53fd704203 100644 --- a/apps/launcher/utils/openalutil.cpp +++ b/apps/launcher/utils/openalutil.cpp @@ -1,6 +1,5 @@ #include #include -#include #include From ded7bd92e64028902a0c1ffa23f157577cebf468 Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Tue, 18 May 2021 19:20:59 -0500 Subject: [PATCH 006/396] Using auto keyword in most apps Detected by clang-tidy's modernize-use-auto --- apps/essimporter/converter.cpp | 6 +++--- apps/essimporter/converter.hpp | 8 ++++---- apps/essimporter/importer.cpp | 6 +++--- apps/launcher/maindialog.cpp | 14 +++++++------- apps/launcher/utils/profilescombobox.cpp | 2 +- apps/launcher/utils/textinputdialog.cpp | 4 ++-- apps/mwiniimporter/importer.cpp | 10 +++++----- apps/niftest/niftest.cpp | 4 ++-- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index e0756602dd..320f7224bc 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -357,7 +357,7 @@ namespace ESSImport std::string idLower = Misc::StringUtils::lowerCase(out.mRefID); - std::map, NPCC>::const_iterator npccIt = mContext->mNpcChanges.find( + auto npccIt = mContext->mNpcChanges.find( std::make_pair(refIndex, out.mRefID)); if (npccIt != mContext->mNpcChanges.end()) { @@ -383,7 +383,7 @@ namespace ESSImport continue; } - std::map, CNTC>::const_iterator cntcIt = mContext->mContainerChanges.find( + auto cntcIt = mContext->mContainerChanges.find( std::make_pair(refIndex, out.mRefID)); if (cntcIt != mContext->mContainerChanges.end()) { @@ -398,7 +398,7 @@ namespace ESSImport continue; } - std::map, CREC>::const_iterator crecIt = mContext->mCreatureChanges.find( + auto crecIt = mContext->mCreatureChanges.find( std::make_pair(refIndex, out.mRefID)); if (crecIt != mContext->mCreatureChanges.end()) { diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 9a1923c2b6..46e4426dc5 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -374,7 +374,7 @@ public: void write(ESM::ESMWriter &esm) override { esm.startRecord(ESM::REC_DCOU); - for (std::map::const_iterator it = mKillCounter.begin(); it != mKillCounter.end(); ++it) + for (auto it = mKillCounter.begin(); it != mKillCounter.end(); ++it) { esm.writeHNString("ID__", it->first); esm.writeHNT ("COUN", it->second); @@ -397,7 +397,7 @@ public: faction.load(esm, isDeleted); std::string id = Misc::StringUtils::lowerCase(faction.mId); - for (std::map::const_iterator it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it) + for (auto it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it) { std::string faction2 = Misc::StringUtils::lowerCase(it->first); mContext->mDialogueState.mChangedFactionReaction[id].insert(std::make_pair(faction2, it->second)); @@ -431,7 +431,7 @@ public: void write(ESM::ESMWriter &esm) override { ESM::StolenItems items; - for (std::map >::const_iterator it = mStolenItems.begin(); it != mStolenItems.end(); ++it) + for (auto it = mStolenItems.begin(); it != mStolenItems.end(); ++it) { std::map, int> owners; for (const auto & ownerIt : it->second) @@ -487,7 +487,7 @@ public: } void write(ESM::ESMWriter &esm) override { - for (std::map::const_iterator it = mDials.begin(); it != mDials.end(); ++it) + for (auto it = mDials.begin(); it != mDials.end(); ++it) { esm.startRecord(ESM::REC_QUES); ESM::QuestState state; diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index 706512263e..27f77e40d1 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -385,7 +385,7 @@ namespace ESSImport // Writing order should be Dynamic Store -> Cells -> Player, // so that references to dynamic records can be recognized when loading - for (std::map >::const_iterator it = converters.begin(); + for (auto it = converters.begin(); it != converters.end(); ++it) { if (it->second->getStage() != 0) @@ -398,7 +398,7 @@ namespace ESSImport context.mPlayerBase.save(writer); writer.endRecord(ESM::REC_NPC_); - for (std::map >::const_iterator it = converters.begin(); + for (auto it = converters.begin(); it != converters.end(); ++it) { if (it->second->getStage() != 1) @@ -423,7 +423,7 @@ namespace ESSImport writer.endRecord(ESM::REC_ACTC); // Stage 2 requires cell references to be written / actors IDs assigned - for (std::map >::const_iterator it = converters.begin(); + for (auto it = converters.begin(); it != converters.end(); ++it) { if (it->second->getStage() != 2) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d41cd529d3..d77d765227 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -52,8 +52,8 @@ Launcher::MainDialog::MainDialog(QWidget *parent) iconWidget->setCurrentRow(0); iconWidget->setFlow(QListView::LeftToRight); - QPushButton *helpButton = new QPushButton(tr("Help")); - QPushButton *playButton = new QPushButton(tr("Play")); + auto *helpButton = new QPushButton(tr("Help")); + auto *playButton = new QPushButton(tr("Play")); buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close")); buttonBox->addButton(helpButton, QDialogButtonBox::HelpRole); buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole); @@ -79,31 +79,31 @@ void Launcher::MainDialog::createIcons() if (!QIcon::hasThemeIcon("document-new")) QIcon::setThemeName("tango"); - QListWidgetItem *playButton = new QListWidgetItem(iconWidget); + auto *playButton = new QListWidgetItem(iconWidget); playButton->setIcon(QIcon(":/images/openmw.png")); playButton->setText(tr("Play")); playButton->setTextAlignment(Qt::AlignCenter); playButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - QListWidgetItem *dataFilesButton = new QListWidgetItem(iconWidget); + auto *dataFilesButton = new QListWidgetItem(iconWidget); dataFilesButton->setIcon(QIcon(":/images/openmw-plugin.png")); dataFilesButton->setText(tr("Data Files")); dataFilesButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); dataFilesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - QListWidgetItem *graphicsButton = new QListWidgetItem(iconWidget); + auto *graphicsButton = new QListWidgetItem(iconWidget); graphicsButton->setIcon(QIcon(":/images/preferences-video.png")); graphicsButton->setText(tr("Graphics")); graphicsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute); graphicsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - QListWidgetItem *settingsButton = new QListWidgetItem(iconWidget); + auto *settingsButton = new QListWidgetItem(iconWidget); settingsButton->setIcon(QIcon(":/images/preferences.png")); settingsButton->setText(tr("Settings")); settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); settingsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - QListWidgetItem *advancedButton = new QListWidgetItem(iconWidget); + auto *advancedButton = new QListWidgetItem(iconWidget); advancedButton->setIcon(QIcon(":/images/preferences-advanced.png")); advancedButton->setText(tr("Advanced")); advancedButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); diff --git a/apps/launcher/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp index af349ddfff..d06cfacff6 100644 --- a/apps/launcher/utils/profilescombobox.cpp +++ b/apps/launcher/utils/profilescombobox.cpp @@ -29,7 +29,7 @@ void ProfilesComboBox::setEditEnabled(bool editable) setEditable(true); setValidator(mValidator); - ComboBoxLineEdit *edit = new ComboBoxLineEdit(this); + auto *edit = new ComboBoxLineEdit(this); setLineEdit(edit); setCompleter(nullptr); diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index 70b827596e..5bbcf4c198 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -16,7 +16,7 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString & mButtonBox->addButton(QDialogButtonBox::Cancel); mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); - QLabel *label = new QLabel(this); + auto *label = new QLabel(this); label->setText(text); // Line edit @@ -25,7 +25,7 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString & mLineEdit->setValidator(validator); mLineEdit->setCompleter(nullptr); - QVBoxLayout *dialogLayout = new QVBoxLayout(this); + auto *dialogLayout = new QVBoxLayout(this); dialogLayout->addWidget(label); dialogLayout->addWidget(mLineEdit); dialogLayout->addWidget(mButtonBox); diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 2763d8ad95..35a1c4ec8b 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -778,7 +778,7 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, const multistrmap &ini) cons } void MwIniImporter::insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value) { - const multistrmap::const_iterator it = cfg.find(key); + const auto it = cfg.find(key); if(it == cfg.end()) { cfg.insert(std::make_pair (key, std::vector() )); } @@ -791,7 +791,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) con std::string archive; // Search archives listed in ini file - multistrmap::const_iterator it = ini.begin(); + auto it = ini.begin(); for(int i=0; it != ini.end(); i++) { archive = baseArchive; archive.append(std::to_string(i)); @@ -813,7 +813,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) con // does not appears in the ini file cfg["fallback-archive"].push_back("Morrowind.bsa"); - for(std::vector::const_iterator iter=archives.begin(); iter!=archives.end(); ++iter) { + for(auto iter=archives.begin(); iter!=archives.end(); ++iter) { cfg["fallback-archive"].push_back(*iter); } } @@ -886,7 +886,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co dataPaths.push_back(iniFilename.parent_path() /= "Data Files"); - multistrmap::const_iterator it = ini.begin(); + auto it = ini.begin(); for (int i=0; it != ini.end(); i++) { std::string gameFile = baseGameFile; @@ -969,7 +969,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co void MwIniImporter::writeToFile(std::ostream &out, const multistrmap &cfg) { for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) { - for(std::vector::const_iterator entry=it->second.begin(); entry != it->second.end(); ++entry) { + for(auto entry=it->second.begin(); entry != it->second.end(); ++entry) { out << (it->first) << "=" << (*entry) << std::endl; } } diff --git a/apps/niftest/niftest.cpp b/apps/niftest/niftest.cpp index e403562d32..2e81885c75 100644 --- a/apps/niftest/niftest.cpp +++ b/apps/niftest/niftest.cpp @@ -53,7 +53,7 @@ void readVFS(VFS::Archive* anArchive,std::string archivePath = "") myManager.buildIndex(); std::map files=myManager.getIndex(); - for(std::map::const_iterator it=files.begin(); it!=files.end(); ++it) + for(auto it=files.begin(); it!=files.end(); ++it) { std::string name = it->first; @@ -134,7 +134,7 @@ int main(int argc, char **argv) Nif::NIFFile::setLoadUnsupportedFiles(true); // std::cout << "Reading Files" << std::endl; - for(std::vector::const_iterator it=files.begin(); it!=files.end(); ++it) + for(auto it=files.begin(); it!=files.end(); ++it) { std::string name = *it; From 1196e0cfe6c073869b27ea190f3718d2e5892199 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 24 Jun 2021 22:02:52 +0200 Subject: [PATCH 007/396] Change disposition to work like vanilla --- CHANGELOG.md | 2 + apps/openmw/mwbase/dialoguemanager.hpp | 1 - apps/openmw/mwbase/mechanicsmanager.hpp | 4 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 76 +++++++++++-------- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 8 +- .../mwmechanics/mechanicsmanagerimp.cpp | 31 ++++---- .../mwmechanics/mechanicsmanagerimp.hpp | 4 +- 7 files changed, 72 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00d576eec..32dd61c190 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,12 @@ Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions) Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes Bug #3905: Great House Dagoth issues + Bug #5100: Persuasion doesn't always clamp the resulting disposition Bug #5120: Scripted object spawning updates physics system Bug #5379: Wandering NPCs falling through cantons Bug #5453: Magic effect VFX are offset for creatures Bug #5483: AutoCalc flag is not used to calculate spells cost + Bug #5842: GetDisposition adds temporary disposition change from different actors Bug #6037: Morrowind Content Language Cannot be Set to English in OpenMW Launcher Bug #6066: addtopic "return" does not work from within script. No errors thrown Bug #6067: esp loader fails in for certain subrecord orders diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index 6103921e02..dc1f6f9667 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -94,7 +94,6 @@ namespace MWBase virtual bool checkServiceRefused (ResponseCallback* callback, ServiceType service = ServiceType::Any) = 0; virtual void persuade (int type, ResponseCallback* callback) = 0; - virtual int getTemporaryDispositionChange () const = 0; /// @note Controlled by an option, gets discarded when dialogue ends by default virtual void applyBarterDispositionChange (int delta) = 0; diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index d6e948d685..b638ecade9 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -100,7 +100,7 @@ namespace MWBase virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. - virtual int getDerivedDisposition(const MWWorld::Ptr& ptr, bool addTemporaryDispositionChange = true) = 0; + virtual int getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp = true) = 0; ///< Calculate the diposition of an NPC toward the player. virtual int countDeaths (const std::string& id) const = 0; @@ -156,7 +156,7 @@ namespace MWBase PT_Bribe100, PT_Bribe1000 }; - virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, float& tempChange, float& permChange) = 0; + virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) = 0; ///< Perform a persuasion action on NPC virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 3c6349ad85..8aa6acd8ed 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -52,8 +52,9 @@ namespace MWDialogue , mCompilerContext (MWScript::CompilerContext::Type_Dialogue) , mErrorHandler() , mTalkedTo(false) - , mTemporaryDispositionChange(0.f) - , mPermanentDispositionChange(0.f) + , mOriginalDisposition(0) + , mCurrentDisposition(0) + , mPermanentDispositionChange(0) { mChoice = -1; mIsInChoice = false; @@ -65,7 +66,8 @@ namespace MWDialogue { mKnownTopics.clear(); mTalkedTo = false; - mTemporaryDispositionChange = 0; + mOriginalDisposition = 0; + mCurrentDisposition = 0; mPermanentDispositionChange = 0; } @@ -98,6 +100,20 @@ namespace MWDialogue } } + void DialogueManager::updateOriginalDisposition() + { + if(mActor.getClass().isNpc()) + { + const auto& stats = mActor.getClass().getNpcStats(mActor); + // Disposition changed by script; discard our preconceived notions + if(stats.getBaseDisposition() != mCurrentDisposition) + { + mCurrentDisposition = stats.getBaseDisposition(); + mOriginalDisposition = mCurrentDisposition; + } + } + } + bool DialogueManager::startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) { updateGlobals(); @@ -107,8 +123,7 @@ namespace MWDialogue return false; mLastTopic = ""; - mPermanentDispositionChange = 0; - mTemporaryDispositionChange = 0; + // Note that we intentionally don't reset mPermanentDispositionChange mChoice = -1; mIsInChoice = false; @@ -398,19 +413,21 @@ namespace MWDialogue void DialogueManager::goodbyeSelected() { - // Apply disposition change to NPC's base disposition - if (mActor.getClass().isNpc()) + // Apply disposition change to NPC's base disposition if we **think** we need to change something + if ((mPermanentDispositionChange || mOriginalDisposition != mCurrentDisposition) && mActor.getClass().isNpc()) { - // Clamp permanent disposition change so that final disposition doesn't go below 0 (could happen with intimidate) - float curDisp = static_cast(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false)); - if (curDisp + mPermanentDispositionChange < 0) - mPermanentDispositionChange = -curDisp; - + updateOriginalDisposition(); MWMechanics::NpcStats& npcStats = mActor.getClass().getNpcStats(mActor); - npcStats.setBaseDisposition(static_cast(npcStats.getBaseDisposition() + mPermanentDispositionChange)); + // Clamp permanent disposition change so that final disposition doesn't go below 0 (could happen with intimidate) + npcStats.setBaseDisposition(0); + int zero = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false); + int disposition = std::min(100 - zero, std::max(mOriginalDisposition + mPermanentDispositionChange, -zero)); + + npcStats.setBaseDisposition(disposition); } mPermanentDispositionChange = 0; - mTemporaryDispositionChange = 0; + mOriginalDisposition = 0; + mCurrentDisposition = 0; } void DialogueManager::questionAnswered (int answer, ResponseCallback* callback) @@ -490,20 +507,17 @@ namespace MWDialogue void DialogueManager::persuade(int type, ResponseCallback* callback) { bool success; - float temp, perm; + int temp, perm; MWBase::Environment::get().getMechanicsManager()->getPersuasionDispositionChange( mActor, MWBase::MechanicsManager::PersuasionType(type), success, temp, perm); - mTemporaryDispositionChange += temp; + updateOriginalDisposition(); + if(temp > 0 && perm > 0 && mOriginalDisposition + perm + mPermanentDispositionChange < 0) + perm = -(mOriginalDisposition + mPermanentDispositionChange); + mCurrentDisposition += temp; + mActor.getClass().getNpcStats(mActor).setBaseDisposition(mCurrentDisposition); mPermanentDispositionChange += perm; - // change temp disposition so that final disposition is between 0...100 - float curDisp = static_cast(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false)); - if (curDisp + mTemporaryDispositionChange < 0) - mTemporaryDispositionChange = -curDisp; - else if (curDisp + mTemporaryDispositionChange > 100) - mTemporaryDispositionChange = 100 - curDisp; - MWWorld::Ptr player = MWMechanics::getPlayer(); player.getClass().skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1); @@ -539,16 +553,16 @@ namespace MWDialogue executeTopic (text + (success ? " Success" : " Fail"), callback); } - int DialogueManager::getTemporaryDispositionChange() const - { - return static_cast(mTemporaryDispositionChange); - } - void DialogueManager::applyBarterDispositionChange(int delta) { - mTemporaryDispositionChange += delta; - if (Settings::Manager::getBool("barter disposition change is permanent", "Game")) - mPermanentDispositionChange += delta; + if(mActor.getClass().isNpc()) + { + updateOriginalDisposition(); + mCurrentDisposition += delta; + mActor.getClass().getNpcStats(mActor).setBaseDisposition(mCurrentDisposition); + if (Settings::Manager::getBool("barter disposition change is permanent", "Game")) + mPermanentDispositionChange += delta; + } } bool DialogueManager::checkServiceRefused(ResponseCallback* callback, ServiceType service) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index b35bee6d43..ab2625ff5a 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -47,8 +47,9 @@ namespace MWDialogue std::vector > mChoices; - float mTemporaryDispositionChange; - float mPermanentDispositionChange; + int mOriginalDisposition; + int mCurrentDisposition; + int mPermanentDispositionChange; void parseText (const std::string& text); @@ -62,6 +63,8 @@ namespace MWDialogue const ESM::Dialogue* searchDialogue(const std::string& id); + void updateOriginalDisposition(); + public: DialogueManager (const Compiler::Extensions& extensions, Translation::Storage& translationDataStorage); @@ -96,7 +99,6 @@ namespace MWDialogue void questionAnswered (int answer, ResponseCallback* callback) override; void persuade (int type, ResponseCallback* callback) override; - int getTemporaryDispositionChange () const override; /// @note Controlled by an option, gets discarded when dialogue ends by default void applyBarterDispositionChange (int delta) override; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index e790f21413..24601d79c8 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -483,7 +483,7 @@ namespace MWMechanics mUpdatePlayer = true; } - int MechanicsManager::getDerivedDisposition(const MWWorld::Ptr& ptr, bool addTemporaryDispositionChange) + int MechanicsManager::getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp) { const MWMechanics::NpcStats& npcSkill = ptr.getClass().getNpcStats(ptr); float x = static_cast(npcSkill.getBaseDisposition()); @@ -562,11 +562,9 @@ namespace MWMechanics x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude(); - if(addTemporaryDispositionChange) - x += MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange(); - - int effective_disposition = std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used - return effective_disposition; + if(clamp) + return std::max(0,std::min(int(x),100));//, normally clamped to [0..100] when used + return int(x); } int MechanicsManager::getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) @@ -603,7 +601,7 @@ namespace MWMechanics return mActors.countDeaths (id); } - void MechanicsManager::getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, float& tempChange, float& permChange) + void MechanicsManager::getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) { const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); @@ -727,19 +725,22 @@ namespace MWMechanics x = success ? std::max(iPerMinChange, c) : c; } - tempChange = type == PT_Intimidate ? x : int(x * fPerTempMult); + tempChange = type == PT_Intimidate ? int(x) : int(x * fPerTempMult); - float cappedDispositionChange = tempChange; - if (currentDisposition + tempChange > 100.f) - cappedDispositionChange = static_cast(100 - currentDisposition); - if (currentDisposition + tempChange < 0.f) - cappedDispositionChange = static_cast(-currentDisposition); + int cappedDispositionChange = tempChange; + if (currentDisposition + tempChange > 100) + cappedDispositionChange = 100 - currentDisposition; + if (currentDisposition + tempChange < 0) + { + cappedDispositionChange = -currentDisposition; + tempChange = 0; + } permChange = floor(cappedDispositionChange / fPerTempMult); if (type == PT_Intimidate) { - permChange = success ? -int(cappedDispositionChange/ fPerTempMult) : y; + permChange = success ? -int(cappedDispositionChange/ fPerTempMult) : int(y); } } @@ -1722,7 +1723,7 @@ namespace MWMechanics int disposition = 50; if (ptr.getClass().isNpc()) - disposition = getDerivedDisposition(ptr, true); + disposition = getDerivedDisposition(ptr); int fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(CreatureStats::AI_Fight).getModified() + static_cast(getFightDistanceBias(ptr, target) + getFightDispositionBias(static_cast(disposition))); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index ed28c0a463..0aaeb23435 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -87,13 +87,13 @@ namespace MWMechanics int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) override; ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. - int getDerivedDisposition(const MWWorld::Ptr& ptr, bool addTemporaryDispositionChange = true) override; + int getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp = true) override; ///< Calculate the diposition of an NPC toward the player. int countDeaths (const std::string& id) const override; ///< Return the number of deaths for actors with the given ID. - void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, float& tempChange, float& permChange) override; + void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) override; ///< Perform a persuasion action on NPC /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! From 269cd31059451f277a65008caeb721d3ed7ee824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mocquillon?= Date: Sat, 10 Jul 2021 19:04:46 +0200 Subject: [PATCH 008/396] Use same world coordinates to compute distances --- apps/openmw/mwrender/objectpaging.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 6b5f9a6e34..ba0891da83 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -485,8 +485,7 @@ namespace MWRender constexpr auto copyMask = ~Mask_UpdateVisitor; AnalyzeVisitor analyzeVisitor(copyMask); - osg::Vec3f center3 = { center.x(), center.y(), 0.f }; - analyzeVisitor.mCurrentDistance = (viewPoint - center3).length2(); + analyzeVisitor.mCurrentDistance = (viewPoint - worldCenter).length2(); float minSize = mMinSize; if (mMinSizeMergeFactor) minSize *= mMinSizeMergeFactor; From 84721fb58a2691d6e557bee38527e5a8a304acbf Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 10 Jul 2021 23:43:55 +0200 Subject: [PATCH 009/396] Disable special processing of Lua errors in debug builds. Fixes #6151. --- extern/sol_config/sol/config.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extern/sol_config/sol/config.hpp b/extern/sol_config/sol/config.hpp index fc8c93e64c..3b0625c2e9 100644 --- a/extern/sol_config/sol/config.hpp +++ b/extern/sol_config/sol/config.hpp @@ -6,10 +6,13 @@ #define SOL_SAFE_FUNCTION_CALLS 1 #define SOL_SAFE_FUNCTION 1 #define SOL_NO_NIL 0 +#define SOL_IN_DEBUG_DETECTED 0 #ifndef NO_LUAJIT #define SOL_LUAJIT 1 #define SOL_EXCEPTIONS_SAFE_PROPAGATION 0 #endif +#include // missing in sol/sol.hpp + #endif // SOL_SINGLE_CONFIG_HPP From e1c525914c1f91470256ab715079c31049e81dfd Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 10 Jul 2021 18:57:20 +0200 Subject: [PATCH 010/396] Add CI jobs to build tests in debug mode --- .gitlab-ci.yml | 18 ++++++++++++++++++ CI/before_script.linux.sh | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ceba2841fe..47c3426913 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -76,6 +76,15 @@ Debian_GCC_tests: CCACHE_SIZE: 1G BUILD_TESTS_ONLY: 1 +Debian_GCC_tests_Debug: + extends: Debian_GCC + cache: + key: Debian_GCC_tests_Debug.v1 + variables: + CCACHE_SIZE: 1G + BUILD_TESTS_ONLY: 1 + CMAKE_BUILD_TYPE: Debug + Debian_GCC_Static_Deps: extends: Debian_GCC cache: @@ -118,6 +127,15 @@ Debian_Clang_tests: CCACHE_SIZE: 1G BUILD_TESTS_ONLY: 1 +Debian_Clang_tests_Debug: + extends: Debian_Clang + cache: + key: Debian_Clang_tests_Debug.v1 + variables: + CCACHE_SIZE: 1G + BUILD_TESTS_ONLY: 1 + CMAKE_BUILD_TYPE: Debug + .MacOS: image: macos-11-xcode-12 tags: diff --git a/CI/before_script.linux.sh b/CI/before_script.linux.sh index 17292e4e98..4344b5212f 100755 --- a/CI/before_script.linux.sh +++ b/CI/before_script.linux.sh @@ -34,6 +34,12 @@ if [[ $CI_OPENMW_USE_STATIC_DEPS ]]; then ) fi +if [[ "${CMAKE_BUILD_TYPE}" ]]; then + CMAKE_CONF_OPTS+=( + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + ) +fi + mkdir -p build cd build From 73639a93b64041102c43c8f9e0068bac655b4164 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 11 Jul 2021 13:22:26 +0200 Subject: [PATCH 011/396] Avoid CTAD to fix macOS build ../../../apps/openmw/engine.cpp:706:23: error: no viable constructor or deduction guide for deduction of template arguments of 'function' ? std::function(ScheduleNonDialogMessageBox {}) ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1430:48: note: candidate template ignored: could not match 'function<_Fp>' against '(anonymous namespace)::ScheduleNonDialogMessageBox' template class _LIBCPP_TEMPLATE_VIS function; // undefined ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1430:48: note: candidate function template not viable: requires 0 arguments, but 1 was provided ../../../apps/openmw/engine.cpp:707:23: error: no viable constructor or deduction guide for deduction of template arguments of 'function' : std::function(IgnoreString {}) ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:1430:48: note: candidate template ignored: could not match 'function<_Fp>' against '(anonymous namespace)::IgnoreString' template class _LIBCPP_TEMPLATE_VIS function; // undefined ^ --- apps/openmw/engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 1bd79cdd02..f554821b3d 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -703,8 +703,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mCfgMgr.getScreenshotPath().string(), Settings::Manager::getString("screenshot format", "General"), Settings::Manager::getBool("notify on saved screenshot", "General") - ? std::function(ScheduleNonDialogMessageBox {}) - : std::function(IgnoreString {}) + ? std::function(ScheduleNonDialogMessageBox {}) + : std::function(IgnoreString {}) ) ); From 6ad2cf8e4f063f3be3b5f5e652f903f1dff5a3e7 Mon Sep 17 00:00:00 2001 From: fredzio Date: Sun, 11 Jul 2021 16:42:45 +0200 Subject: [PATCH 012/396] Skip simulation result after calling Actor::updatePosition(). Otherwise when going out of tcl the player would go back to previous position for one frame. --- apps/openmw/mwphysics/actor.cpp | 4 +++- apps/openmw/mwphysics/actor.hpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 21736543ab..4df5646516 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -124,11 +124,13 @@ void Actor::updatePosition() mPositionOffset = osg::Vec3f(); mStandingOnPtr = nullptr; mSkipCollisions = true; + mSkipSimulation = true; } void Actor::setSimulationPosition(const osg::Vec3f& position) { - mSimulationPosition = position; + if (!std::exchange(mSkipSimulation, false)) + mSimulationPosition = position; } osg::Vec3f Actor::getSimulationPosition() const diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index dd4ea45714..8bbb90dbed 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -204,6 +204,7 @@ namespace MWPhysics osg::Vec3f mVelocity; bool mWorldPositionChanged; bool mSkipCollisions; + bool mSkipSimulation; btTransform mLocalTransform; mutable std::mutex mPositionMutex; From 643a64cb2f2b5fe24b113ba343e7ef69788390cf Mon Sep 17 00:00:00 2001 From: fredzio Date: Sat, 24 Apr 2021 12:40:47 +0200 Subject: [PATCH 013/396] Change some settings for async physics: - default to 1 thread - default to always use defered aabb update, remove option - always keep a cache of LOS request for at least the current frame. This decreases number of raycast, especially when a lot of actors are involved and "NPCs avoid collisions" is on --- apps/openmw/mwphysics/mtphysics.cpp | 16 +++++--------- apps/openmw/mwphysics/mtphysics.hpp | 1 - .../reference/modding/settings/physics.rst | 22 +++++-------------- files/settings-default.cfg | 6 +---- 4 files changed, 12 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 9b98e7e8f7..0d57cc2f23 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -137,7 +137,6 @@ namespace MWPhysics , mNumJobs(0) , mRemainingSteps(0) , mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics")) - , mDeferAabbUpdate(Settings::Manager::getBool("defer aabb update", "Physics")) , mNewFrame(false) , mAdvanceSimulation(false) , mQuit(false) @@ -163,8 +162,7 @@ namespace MWPhysics } else { - mLOSCacheExpiry = -1; - mDeferAabbUpdate = false; + mLOSCacheExpiry = 0; } mPreStepBarrier = std::make_unique(mNumThreads); @@ -392,7 +390,7 @@ namespace MWPhysics void PhysicsTaskScheduler::updateSingleAabb(std::weak_ptr ptr, bool immediate) { - if (!mDeferAabbUpdate || immediate) + if (immediate) { updatePtrAabb(ptr); } @@ -417,8 +415,7 @@ namespace MWPhysics if (result == mLOSCache.end()) { req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get()); - if (mLOSCacheExpiry >= 0) - mLOSCache.push_back(req); + mLOSCache.push_back(req); return req.mResult; } result->mAge = 0; @@ -508,8 +505,7 @@ namespace MWPhysics } } - if (mLOSCacheExpiry >= 0) - refreshLOSCache(); + refreshLOSCache(); mPostSimBarrier->wait([this] { afterPostSim(); }); } } @@ -594,8 +590,7 @@ namespace MWPhysics void PhysicsTaskScheduler::afterPreStep() { - if (mDeferAabbUpdate) - updateAabbs(); + updateAabbs(); if (!mRemainingSteps) return; for (auto& data : mActorsFrameData) @@ -619,7 +614,6 @@ namespace MWPhysics void PhysicsTaskScheduler::afterPostSim() { mNewFrame = false; - if (mLOSCacheExpiry >= 0) { std::unique_lock lock(mLOSCacheMutex); mLOSCache.erase( diff --git a/apps/openmw/mwphysics/mtphysics.hpp b/apps/openmw/mwphysics/mtphysics.hpp index 3fd4d5a693..ae82727c56 100644 --- a/apps/openmw/mwphysics/mtphysics.hpp +++ b/apps/openmw/mwphysics/mtphysics.hpp @@ -90,7 +90,6 @@ namespace MWPhysics int mNumJobs; int mRemainingSteps; int mLOSCacheExpiry; - bool mDeferAabbUpdate; bool mNewFrame; bool mAdvanceSimulation; bool mThreadSafeBullet; diff --git a/docs/source/reference/modding/settings/physics.rst b/docs/source/reference/modding/settings/physics.rst index 59aba91aa9..c6d27f58f8 100644 --- a/docs/source/reference/modding/settings/physics.rst +++ b/docs/source/reference/modding/settings/physics.rst @@ -6,7 +6,7 @@ async num threads :Type: integer :Range: >= 0 -:Default: 0 +:Default: 1 Determines how many threads will be spawned to compute physics update in the background (that is, process actors movement). A value of 0 means that the update will be performed in the main thread. A value greater than 1 requires the Bullet library be compiled with multithreading support. If that's not the case, a warning will be written in ``openmw.log`` and a value of 1 will be used. @@ -19,19 +19,9 @@ lineofsight keep inactive cache :Default: 0 The line of sight determines if 2 actors can see each other (without taking into account game mechanics such as invisibility or sneaking). It is used by some scripts (the getLOS function), by the AI (to determine if an actor should start combat or chase an opponent) and for functionnalities such as greetings or turning NPC head toward an object. -This parameters determine for how long a cache of request should be kept warm. It depends on :ref:`async num threads` being > 0, otherwise a value of -1 will be used. If a request is not found in the cache, it is always fulfilled immediately. In case Bullet is compiled without multithreading support, non-cached requests involve blocking the async thread(s), which might hurt performance. -A value of -1 means no caching. -A value of 0 means that for as long as a request is made (after the first one), it will be preemptively "refreshed" in the async thread, without blocking neither the main thread nor the async thread. +This parameters determine for how long a cache of request should be kept warm. +A value of 0 means that the cache is kept only for the current frame, that is if a request is done 2 times in the same frame, the second request will be in cache. Any value > 0 is the number of frames for which the values are kept in cache even if the results was not requested again. -If Bullet is compiled with multithreading support, requests are non blocking, it is better to set this parameter to -1. - -defer aabb update ------------------ - -:Type: boolean -:Range: True/False -:Default: True - -Axis-aligned bounding box (aabb for short) are used by Bullet for collision detection. They should be updated anytime a physical object is modified (for instance moved) for collision detection to be correct. -This parameter control wether the update should be done as soon as the object is modified (the default), which involves blocking the async thread(s), or queue the modifications to update them as a batch before the collision detections. It depends on :ref:`async num threads` being > 0, otherwise it will be disabled. -Disabling this parameter is intended as an aid for debugging collisions detection issues. +If :ref:`async num threads` is 0, a value of 0 will be used. +If a request is not found in the cache, it is always fulfilled immediately. In case Bullet is compiled without multithreading support, non-cached requests involve blocking the async thread, which might hurt performance. +If Bullet is compiled with multithreading support, requests are non blocking, it is better to set this parameter to 0. diff --git a/files/settings-default.cfg b/files/settings-default.cfg index d539ba34da..e7439fb5ae 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -985,16 +985,12 @@ enable indoor shadows = true # Set the number of background threads used for physics. # If no background threads are used, physics calculations are processed in the main thread # and the settings below have no effect. -async num threads = 0 +async num threads = 1 # Set the number of frames an inactive line-of-sight request will be kept # refreshed in the background physics thread cache. -# If this is set to -1, line-of-sight requests are never cached. lineofsight keep inactive cache = 0 -# Defer bounding boxes update until collision detection. -defer aabb update = true - [Models] # Attempt to load any valid NIF file regardless of its version and track the progress. From 1650dabed86fff39df673985d36e7b217ab7880e Mon Sep 17 00:00:00 2001 From: fredzio Date: Sun, 11 Jul 2021 18:01:20 +0200 Subject: [PATCH 014/396] Assign the return value of weak_ptr::lock() to a variable, so that the shared object lifetime is properly extended. Otherwise there is a possibility that the Actor gets destroyed during call to unstuck(). --- apps/openmw/mwphysics/mtphysics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 9b98e7e8f7..29d1e0b7c1 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -599,7 +599,7 @@ namespace MWPhysics if (!mRemainingSteps) return; for (auto& data : mActorsFrameData) - if (data.mActor.lock()) + if (const auto actor = data.mActor.lock()) { std::unique_lock lock(mCollisionWorldMutex); MovementSolver::unstuck(data, mCollisionWorld); From 5aaac8e47e90891c3868e88978becf4ff991fe14 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Wed, 30 Jun 2021 18:29:00 +0200 Subject: [PATCH 015/396] Reduce a bit the size of getHT Factoring common code parts outside of a template is apparently a good practise to reduce code duplication (and the size of openmw by around 0.5%), and should improve a bit the performances, since the whole `std::to_string` * 2 + string concatenation dance results in quite a lot of code, preventing inlining on my machine. --- components/esm/esmreader.cpp | 2 +- components/esm/esmreader.hpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index a30ad2c069..0cf7c3f81f 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -198,7 +198,7 @@ void ESMReader::skipHSubSize(int size) { skipHSub(); if (static_cast (mCtx.leftSub) != size) - fail("skipHSubSize() mismatch"); + reportSubSizeMismatch(mCtx.leftSub, size); } void ESMReader::skipHSubUntil(const char *name) diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index 6129147d33..608222a1bb 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -134,11 +134,7 @@ public: { getSubHeader(); if (mCtx.leftSub != sizeof(X)) - { - fail("getHT(): subrecord size mismatch,requested " - + std::to_string(sizeof(X)) + ", got" - + std::to_string(mCtx.leftSub)); - } + reportSubSizeMismatch(sizeof(X), mCtx.leftSub); getT(x); } @@ -261,6 +257,13 @@ public: size_t getFileSize() const { return mFileSize; } private: + [[noreturn]] void reportSubSizeMismatch(size_t want, size_t got) { + fail("subrecord size mismatch, requested " + + std::to_string(want) + + ", got" + + std::to_string(got)); + } + void clearCtx(); Files::IStreamPtr mEsm; From 389b830046deefa4d7fe13178a6cd2e5b30ab590 Mon Sep 17 00:00:00 2001 From: "glassmancody.info" Date: Sun, 11 Jul 2021 23:03:55 -0700 Subject: [PATCH 016/396] fix black objects with OP batch debug due to unitialized uniform --- apps/openmw/mwrender/objectpaging.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index ba0891da83..d91f4efaaa 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -364,6 +364,7 @@ namespace MWRender osg::ref_ptr stateset = node.getStateSet() ? osg::clone(node.getStateSet(), osg::CopyOp::SHALLOW_COPY) : new osg::StateSet; stateset->setAttribute(m); stateset->addUniform(new osg::Uniform("colorMode", 0)); + stateset->addUniform(new osg::Uniform("emissiveMult", 1.f)); node.setStateSet(stateset); } }; From b8fcd6d3ba0a3a91879ae7a98b22f75c852433c1 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 11 Jul 2021 14:43:52 +0200 Subject: [PATCH 017/396] Manage work item lifetime on the client side Instead of explicit work queue stop before any possibly used engine manager is destructed. Based on an assumption that any engine manager can be destructed independently from the work queue destruction. This model is already used in CellPreloader that conflicts with explicit work queue stop. After the work queue is requested to be stopped, any client waiting for a not started work item to be done will wait forever because the work item is dropped from the queue. Therefore either clients should not wait for own work items to be completed in destructor or the work queue should not drop items before clients are destructed. Other approaches are possible but are not considered due to increasing complexity. CellPreloader already tries to wait for all created work items to be done so keep it that way and extend the model to AsyncScreenCaptureOperation and Scene. Additionally abort all scheduled work items when owner is destructed. This prevents a long exit when multiple screenshots are scheduled right before exiting the game. --- apps/openmw/engine.cpp | 3 ++- apps/openmw/engine.hpp | 3 ++- apps/openmw/mwworld/scene.cpp | 24 +++++++++++++++++++- apps/openmw/mwworld/scene.hpp | 9 ++++++++ components/sceneutil/screencapture.cpp | 31 +++++++++++++++++++++++++- components/sceneutil/screencapture.hpp | 9 ++++++++ 6 files changed, 75 insertions(+), 4 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f554821b3d..b0047fd1df 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -427,7 +427,8 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) OMW::Engine::~Engine() { - mWorkQueue->stop(); + if (mScreenCaptureOperation != nullptr) + mScreenCaptureOperation->stop(); mEnvironment.cleanup(); diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 180e06bcbc..290fd890a6 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -21,6 +21,7 @@ namespace Resource namespace SceneUtil { class WorkQueue; + class AsyncScreenCaptureOperation; } namespace VFS @@ -67,7 +68,7 @@ namespace OMW boost::filesystem::path mResDir; osg::ref_ptr mViewer; osg::ref_ptr mScreenCaptureHandler; - osg::ref_ptr mScreenCaptureOperation; + osg::ref_ptr mScreenCaptureOperation; std::string mCellName; std::vector mContentFiles; std::vector mGroundcoverFiles; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 7d3a6c7893..c43ee76d1b 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -867,6 +868,11 @@ namespace MWWorld Scene::~Scene() { + for (const osg::ref_ptr& v : mWorkItems) + v->abort(); + + for (const osg::ref_ptr& v : mWorkItems) + v->waitTillDone(); } bool Scene::hasCellChanged() const @@ -1061,6 +1067,9 @@ namespace MWWorld void doWork() override { + if (mAborted) + return; + try { mSceneManager->getTemplate(mMesh); @@ -1069,9 +1078,16 @@ namespace MWWorld { } } + + void abort() override + { + mAborted = true; + } + private: std::string mMesh; Resource::SceneManager* mSceneManager; + std::atomic_bool mAborted {false}; }; void Scene::preload(const std::string &mesh, bool useAnim) @@ -1081,7 +1097,13 @@ namespace MWWorld mesh_ = Misc::ResourceHelpers::correctActorModelPath(mesh_, mRendering.getResourceSystem()->getVFS()); if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(mesh_, mRendering.getReferenceTime())) - mRendering.getWorkQueue()->addWorkItem(new PreloadMeshItem(mesh_, mRendering.getResourceSystem()->getSceneManager())); + { + osg::ref_ptr item(new PreloadMeshItem(mesh_, mRendering.getResourceSystem()->getSceneManager())); + mRendering.getWorkQueue()->addWorkItem(item); + const auto isDone = [] (const osg::ref_ptr& v) { return v->isDone(); }; + mWorkItems.erase(std::remove_if(mWorkItems.begin(), mWorkItems.end(), isDone), mWorkItems.end()); + mWorkItems.emplace_back(std::move(item)); + } } void Scene::preloadCells(float dt) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index bc9c2386bb..75c070dd1e 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "ptr.hpp" #include "globals.hpp" @@ -10,6 +11,7 @@ #include #include #include +#include #include @@ -49,6 +51,11 @@ namespace MWPhysics class PhysicsSystem; } +namespace SceneUtil +{ + class WorkItem; +} + namespace MWWorld { class Player; @@ -91,6 +98,8 @@ namespace MWWorld std::set mPagedRefs; + std::vector> mWorkItems; + void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool onlyObjects, bool test = false); osg::Vec2i mCurrentGridCenter; diff --git a/components/sceneutil/screencapture.cpp b/components/sceneutil/screencapture.cpp index 47119f3644..99cb535326 100644 --- a/components/sceneutil/screencapture.cpp +++ b/components/sceneutil/screencapture.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace { @@ -32,6 +33,9 @@ namespace void doWork() override { + if (mAborted) + return; + try { (*mImpl)(*mImage, mContextId); @@ -42,10 +46,16 @@ namespace } } + void abort() override + { + mAborted = true; + } + private: const osg::ref_ptr mImpl; const osg::ref_ptr mImage; const unsigned int mContextId; + std::atomic_bool mAborted {false}; }; } @@ -130,8 +140,27 @@ namespace SceneUtil assert(mImpl != nullptr); } + AsyncScreenCaptureOperation::~AsyncScreenCaptureOperation() + { + stop(); + } + + void AsyncScreenCaptureOperation::stop() + { + for (const osg::ref_ptr& item : *mWorkItems.lockConst()) + item->abort(); + + for (const osg::ref_ptr& item : *mWorkItems.lockConst()) + item->waitTillDone(); + } + void AsyncScreenCaptureOperation::operator()(const osg::Image& image, const unsigned int context_id) { - mQueue->addWorkItem(new ScreenCaptureWorkItem(mImpl, image, context_id)); + osg::ref_ptr item(new ScreenCaptureWorkItem(mImpl, image, context_id)); + mQueue->addWorkItem(item); + const auto isDone = [] (const osg::ref_ptr& v) { return v->isDone(); }; + const auto workItems = mWorkItems.lock(); + workItems->erase(std::remove_if(workItems->begin(), workItems->end(), isDone), workItems->end()); + workItems->emplace_back(std::move(item)); } } diff --git a/components/sceneutil/screencapture.hpp b/components/sceneutil/screencapture.hpp index 6395d989d8..87e396b020 100644 --- a/components/sceneutil/screencapture.hpp +++ b/components/sceneutil/screencapture.hpp @@ -1,10 +1,13 @@ #ifndef OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H #define OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H +#include + #include #include #include +#include namespace osg { @@ -14,6 +17,7 @@ namespace osg namespace SceneUtil { class WorkQueue; + class WorkItem; std::string writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat, const osg::Image& image); @@ -38,11 +42,16 @@ namespace SceneUtil AsyncScreenCaptureOperation(osg::ref_ptr queue, osg::ref_ptr impl); + ~AsyncScreenCaptureOperation(); + + void stop(); + void operator()(const osg::Image& image, const unsigned int context_id) override; private: const osg::ref_ptr mQueue; const osg::ref_ptr mImpl; + Misc::ScopeGuarded>> mWorkItems; }; } From eece47f70e1f65891d101d42f1f445e71ad22a50 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 10 Jul 2021 12:11:48 +0200 Subject: [PATCH 018/396] Avoid copying osg::ref_ptr when adding or removing item from work queue Copy constructor does refcounting, and move constructor doesn't. --- apps/openmw/mwrender/renderingmanager.cpp | 2 +- components/sceneutil/workqueue.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e497fdecd2..016149ed90 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -492,7 +492,7 @@ namespace MWRender workItem->mTextures.emplace_back("textures/_land_default.dds"); - mWorkQueue->addWorkItem(workItem); + mWorkQueue->addWorkItem(std::move(workItem)); } double RenderingManager::getReferenceTime() const diff --git a/components/sceneutil/workqueue.cpp b/components/sceneutil/workqueue.cpp index 3c1df80ac4..81c9bee29c 100644 --- a/components/sceneutil/workqueue.cpp +++ b/components/sceneutil/workqueue.cpp @@ -74,9 +74,9 @@ void WorkQueue::addWorkItem(osg::ref_ptr item, bool front) std::unique_lock lock(mMutex); if (front) - mQueue.push_front(item); + mQueue.push_front(std::move(item)); else - mQueue.push_back(item); + mQueue.push_back(std::move(item)); mCondition.notify_one(); } @@ -89,7 +89,7 @@ osg::ref_ptr WorkQueue::removeWorkItem() } if (!mQueue.empty()) { - osg::ref_ptr item = mQueue.front(); + osg::ref_ptr item = std::move(mQueue.front()); mQueue.pop_front(); return item; } From d4a2dab9d93b5b9903112abca6888c68dda06079 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 10 Jul 2021 12:19:59 +0200 Subject: [PATCH 019/396] Remove redundant else --- components/sceneutil/workqueue.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/sceneutil/workqueue.cpp b/components/sceneutil/workqueue.cpp index 81c9bee29c..0c68c61921 100644 --- a/components/sceneutil/workqueue.cpp +++ b/components/sceneutil/workqueue.cpp @@ -93,8 +93,7 @@ osg::ref_ptr WorkQueue::removeWorkItem() mQueue.pop_front(); return item; } - else - return nullptr; + return nullptr; } unsigned int WorkQueue::getNumItems() const From 153cd9a20cf1891f9a953870d1b04d591740a5f3 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 10 Jul 2021 13:02:28 +0200 Subject: [PATCH 020/396] Avoid redundant search for existing element --- apps/openmw/mwworld/cellpreloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 44afde22ae..a2167c562f 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -317,7 +317,7 @@ namespace MWWorld if (found->second.mWorkItem) { found->second.mWorkItem->abort(); - mUnrefQueue->push(mPreloadCells[cell].mWorkItem); + mUnrefQueue->push(std::move(found->second.mWorkItem)); } mPreloadCells.erase(found); From 4db5fa351d4120d6141f98afa14a06e8840d0d92 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Mon, 12 Jul 2021 11:46:32 +0200 Subject: [PATCH 021/396] Add sol3.2.2/sol/sol.hpp to extern instead of downloading during building --- CMakeLists.txt | 7 +- extern/sol3.2.2/README.md | 3 + extern/sol3.2.2/sol/sol.hpp | 26674 ++++++++++++++++++++++++++++++++++ 3 files changed, 26679 insertions(+), 5 deletions(-) create mode 100644 extern/sol3.2.2/README.md create mode 100644 extern/sol3.2.2/sol/sol.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d20e451676..f81af9e38b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -404,11 +404,8 @@ else(USE_LUAJIT) add_compile_definitions(NO_LUAJIT) endif(USE_LUAJIT) -# Download sol - C++ library binding to Lua -file(DOWNLOAD - "https://github.com/ThePhD/sol2/releases/download/v3.2.2/sol.hpp" "${OpenMW_BINARY_DIR}/extern/sol3.2.2/sol/sol.hpp" - EXPECTED_MD5 ba113cf458f60672917108e69bb4d958) -set(SOL_INCLUDE_DIRS ${OpenMW_BINARY_DIR}/extern/sol3.2.2 ${OpenMW_SOURCE_DIR}/extern/sol_config) +# C++ library binding to Lua +set(SOL_INCLUDE_DIRS ${OpenMW_SOURCE_DIR}/extern/sol3.2.2 ${OpenMW_SOURCE_DIR}/extern/sol_config) include_directories( BEFORE SYSTEM diff --git a/extern/sol3.2.2/README.md b/extern/sol3.2.2/README.md new file mode 100644 index 0000000000..c831941822 --- /dev/null +++ b/extern/sol3.2.2/README.md @@ -0,0 +1,3 @@ +sol/sol.hpp is downloaded from https://github.com/ThePhD/sol2/releases/download/v3.2.2/sol.hpp + +License: MIT diff --git a/extern/sol3.2.2/sol/sol.hpp b/extern/sol3.2.2/sol/sol.hpp new file mode 100644 index 0000000000..c25fd549e7 --- /dev/null +++ b/extern/sol3.2.2/sol/sol.hpp @@ -0,0 +1,26674 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This file was generated with a script. +// Generated 2020-10-03 21:34:24.496436 UTC +// This header was generated with sol v3.2.1 (revision 48eea7b5) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_INCLUDE_HPP +#define SOL_SINGLE_INCLUDE_HPP + +// beginning of sol/sol.hpp + +#ifndef SOL_HPP +#define SOL_HPP + +// beginning of sol/version.hpp + +#include + +#include + +#define SOL_VERSION_MAJOR 3 +#define SOL_VERSION_MINOR 5 +#define SOL_VERSION_PATCH 0 +#define SOL_VERSION_STRING "3.5.0" +#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH)) + +#define SOL_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0) +#define SOL_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0) +#define SOL_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3) +#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0) + +#define SOL_ON | +#define SOL_OFF ^ +#define SOL_DEFAULT_ON + +#define SOL_DEFAULT_OFF - + +#if defined(_MSC_VER) + #define SOL_COMPILER_CLANG_I_ SOL_OFF + #define SOL_COMPILER_GCC_I_ SOL_OFF + #define SOL_COMPILER_EDG_I_ SOL_OFF + #define SOL_COMPILER_VCXX_I_ SOL_ON +#elif defined(__clang__) + #define SOL_COMPILER_CLANG_I_ SOL_ON + #define SOL_COMPILER_GCC_I_ SOL_OFF + #define SOL_COMPILER_EDG_I_ SOL_OFF + #define SOL_COMPILER_VCXX_I_ SOL_OFF +#elif defined(__GNUC__) + #define SOL_COMPILER_CLANG_I_ SOL_OFF + #define SOL_COMPILER_GCC_I_ SOL_ON + #define SOL_COMPILER_EDG_I_ SOL_OFF + #define SOL_COMPILER_VCXX_I_ SOL_OFF +#else + #define SOL_COMPILER_CLANG_I_ SOL_OFF + #define SOL_COMPILER_GCC_I_ SOL_OFF + #define SOL_COMPILER_EDG_I_ SOL_OFF + #define SOL_COMPILER_VCXX_I_ SOL_OFF +#endif + +#if defined(__MINGW32__) + #define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_ON +#else + #define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_OFF +#endif + +#if SIZE_MAX <= 0xFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_ON + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_OFF +#elif SIZE_MAX <= 0xFFFFFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_ON + #define SOL_PLATFORM_X64_I_ SOL_OFF +#else + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_ON +#endif + +#define SOL_PLATFORM_ARM32_I_ SOL_OFF +#define SOL_PLATFORM_ARM64_I_ SOL_OFF + +#if defined(_WIN32) + #define SOL_PLATFORM_WINDOWS_I_ SOL_ON +#else + #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF +#endif +#if defined(__APPLE__) + #define SOL_PLATFORM_APPLE_I_ SOL_ON +#else + #define SOL_PLATFORM_APPLE_I_ SOL_OFF +#endif +#if defined(__unix__) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON +#else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF +#endif +#if defined(__linux__) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON +#else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF +#endif + +#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF +#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF + +#if defined(SOL_IN_DEBUG_DETECTED) + #if SOL_IN_DEBUG_DETECTED != 0 + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#elif !defined(NDEBUG) + #if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && defined(_DEBUG) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #elif (SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)) && !defined(__OPTIMIZE__) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF +#endif // We are in a debug mode of some sort + +#if defined(SOL_NO_EXCEPTIONS) + #if (SOL_NO_EXCEPTIONS != 0) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) + #if !defined(_CPPUNWIND) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_) + #if !defined(__EXCEPTIONS) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#else + #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_RTTI) + #if (SOL_NO_RTTI != 0) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) + #if !defined(_CPPRTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_) + #if !defined(__GXX_RTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#else + #define SOL_RTTI_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_THREAD_LOCAL) && (SOL_NO_THREAD_LOCAL != 0) + #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF +#else + #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON +#endif // thread_local keyword is bjorked on some platforms + +#if defined(SOL_ALL_SAFETIES_ON) && (SOL_ALL_SAFETIES_ON != 0) + #define SOL_ALL_SAFETIES_ON_I_ SOL_ON +#else + #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_GETTER) && (SOL_SAFE_GETTER != 0) + #define SOL_SAFE_GETTER_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_GETTER_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_USERTYPE) && (SOL_SAFE_USERTYPE != 0) + #define SOL_SAFE_USERTYPE_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_REFERENCES) && (SOL_SAFE_REFERENCES != 0) + #define SOL_SAFE_REFERENCES_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if (defined(SOL_SAFE_FUNCTIONS) && (SOL_SAFE_FUNCTIONS != 0)) \ + || (defined(SOL_SAFE_FUNCTION_OBJECTS) && (SOL_SAFE_FUNCTION_OBJECTS != 0)) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTION_CALLS) && (SOL_SAFE_FUNCTION_CALLS != 0) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_PROXIES) && (SOL_SAFE_PROXIES != 0) + #define SOL_SAFE_PROXIES_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_PROXIES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_NUMERICS) && (SOL_SAFE_NUMERICS != 0) + #define SOL_SAFE_NUMERICS_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_STACK_CHECK) && (SOL_SAFE_STACK_CHECK != 0) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if (defined(SOL_NO_CHECK_NUMBER_PRECISION) && (SOL_NO_CHECK_NUMBER_PRECISION != 0)) \ + || (defined(SOL_NO_CHECKING_NUMBER_PRECISION) && (SOL_NO_CHECKING_NUMBER_PRECISION != 0)) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_SAFE_NUMERICS_I_) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_STRINGS_ARE_NUMBERS) + #if (SOL_STRINGS_ARE_NUMBERS != 0) + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON + #else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF + #endif +#else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ENABLE_INTEROP) && (SOL_ENABLE_INTEROP != 0) \ + || defined(SOL_USE_INTEROP) && (SOL_USE_INTEROP != 0) + #define SOL_USE_INTEROP_I_ SOL_ON +#else + #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_NIL) + #if (SOL_NO_NIL != 0) + #define SOL_NIL_I_ SOL_OFF + #else + #define SOL_NIL_I_ SOL_ON + #endif +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil) + #define SOL_NIL_I_ SOL_DEFAULT_OFF +#else + #define SOL_NIL_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USERTYPE_TYPE_BINDING_INFO) + #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0) + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON + #else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF + #endif +#else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON +#endif // We should generate a my_type.__type table with lots of class information for usertypes + +#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT) + #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES) + #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON +#endif // make is_automagical on/off by default + +#if defined(SOL_STD_VARIANT) + #if (SOL_STD_VARIANT != 0) + #define SOL_STD_VARIANT_I_ SOL_ON + #else + #define SOL_STD_VARIANT_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_COMPILER_CLANG_I_) && SOL_IS_ON(SOL_PLATFORM_APPLE_I_) + #if defined(__has_include) + #if __has_include() + #define SOL_STD_VARIANT_I_ SOL_ON + #else + #define SOL_STD_VARIANT_I_ SOL_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #endif +#endif // make is_automagical on/off by default + +#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) + #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #endif +#else + #if defined(__cpp_noexcept_function_type) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L)) + // There is a bug in the VC++ compiler?? + // on /std:c++latest under x86 conditions (VS 15.5.2), + // compiler errors are tossed for noexcept markings being on function types + // that are identical in every other way to their non-noexcept marked types function types... + // VS 2019: There is absolutely a bug. + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON + #endif +#endif // noexcept is part of a function's type + +#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0 + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE +#else + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024 +#endif + +#if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 + #define SOL_ID_SIZE_I_ SOL_ID_SIZE +#else + #define SOL_ID_SIZE_I_ 512 +#endif + +#if defined(LUA_IDSIZE) && LUA_IDSIZE > 0 + #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE +#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 + #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE +#else + #define SOL_FILE_ID_SIZE_I_ 2048 +#endif + +#if defined(SOL_PRINT_ERRORS) + #if (SOL_PRINT_ERRORS != 0) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#endif + +#if defined(SOL_DEFAULT_PASS_ON_ERROR) && (SOL_DEFAULT_PASS_ON_ERROR != 0) + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_ON + #else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF + #endif +#endif + +#if defined(SOL_USING_CXX_LUA) + #if (SOL_USING_CXX_LUA != 0) + #define SOL_USE_CXX_LUA_I_ SOL_ON + #else + #define SOL_USE_CXX_LUA_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUA) + #if (SOL_USE_CXX_LUA != 0) + #define SOL_USE_CXX_LUA_I_ SOL_ON + #else + #define SOL_USE_CXX_LUA_I_ SOL_OFF + #endif +#else + #define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif + +#if defined(SOL_USING_CXX_LUAJIT) + #if (SOL_USING_CXX_LUA != 0) + #define SOL_USE_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUAJIT) + #if (SOL_USE_CXX_LUA != 0) + #define SOL_USE_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF + #endif +#else + #define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif + +#if defined(SOL_NO_LUA_HPP) + #if (SOL_NO_LUA_HPP != 0) + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #else + #define SOL_USE_LUA_HPP_I_ SOL_ON + #endif +#elif defined(SOL_USING_CXX_LUA) + #define SOL_USE_LUA_HPP_I_ SOL_OFF +#elif defined(__has_include) + #if __has_include() + #define SOL_USE_LUA_HPP_I_ SOL_ON + #else + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #endif +#else + #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_CONTAINERS_START) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START +#elif defined(SOL_CONTAINERS_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX +#elif defined(SOL_CONTAINER_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX +#else + #define SOL_CONTAINER_START_INDEX_I_ 1 +#endif + +#if defined (SOL_NO_MEMORY_ALIGNMENT) + #if (SOL_NO_MEMORY_ALIGNMENT != 0) + #define SOL_ALIGN_MEMORY_I_ SOL_OFF + #else + #define SOL_ALIGN_MEMORY_I_ SOL_ON + #endif +#else + #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USE_BOOST) + #if (SOL_USE_BOOST != 0) + #define SOL_USE_BOOST_I_ SOL_ON + #else + #define SOL_USE_BOOST_I_ SOL_OFF + #endif +#else + #define SOL_USE_BOOST_I_ SOL_OFF +#endif + +#if defined(SOL_USE_UNSAFE_BASE_LOOKUP) + #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0) + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON + #else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF + #endif +#else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF +#endif + +#if defined(SOL_INSIDE_UNREAL) + #if (SOL_INSIDE_UNREAL != 0) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF + #endif +#else + #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_COMPAT) + #if (SOL_NO_COMPAT != 0) + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF + #else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON + #endif +#else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE) + #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0) + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON + #else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF + #endif +#else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF +#endif + +#if SOL_IS_ON(SOL_COMPILER_FRONTEND_MINGW_I_) && defined(__GNUC__) && (__GNUC__ < 6) + // MinGW is off its rocker in some places... + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON +#else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF +#endif + +// end of sol/version.hpp + +#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_) +#ifdef check +#pragma push_macro("check") +#undef check +#endif +#endif // Unreal Engine 4 Bullshit + +#if SOL_IS_ON(SOL_COMPILER_GCC_I_) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#if __GNUC__ > 6 +#pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS +#endif // clang++ vs. g++ vs. VC++ + +// beginning of sol/forward.hpp + +#ifndef SOL_FORWARD_HPP +#define SOL_FORWARD_HPP + +#include +#include +#include + +#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) +struct lua_State; +#else +extern "C" { +struct lua_State; +} +#endif // C++ Mangling for Lua vs. Not + +namespace sol { + + enum class type; + + class stateless_reference; + template + class basic_reference; + using reference = basic_reference; + using main_reference = basic_reference; + class stateless_stack_reference; + class stack_reference; + + template + class basic_bytecode; + + struct lua_value; + + struct proxy_base_tag; + template + struct proxy_base; + template + struct table_proxy; + + template + class basic_table_core; + template + using table_core = basic_table_core; + template + using main_table_core = basic_table_core; + template + using stack_table_core = basic_table_core; + template + using basic_table = basic_table_core; + using table = table_core; + using global_table = table_core; + using main_table = main_table_core; + using main_global_table = main_table_core; + using stack_table = stack_table_core; + using stack_global_table = stack_table_core; + + template + struct basic_lua_table; + using lua_table = basic_lua_table; + using stack_lua_table = basic_lua_table; + + template + class basic_usertype; + template + using usertype = basic_usertype; + template + using stack_usertype = basic_usertype; + + template + class basic_metatable; + using metatable = basic_metatable; + using stack_metatable = basic_metatable; + + template + struct basic_environment; + using environment = basic_environment; + using main_environment = basic_environment; + using stack_environment = basic_environment; + + template + class basic_function; + template + class basic_protected_function; + using unsafe_function = basic_function; + using safe_function = basic_protected_function; + using main_unsafe_function = basic_function; + using main_safe_function = basic_protected_function; + using stack_unsafe_function = basic_function; + using stack_safe_function = basic_protected_function; + using stack_aligned_unsafe_function = basic_function; + using stack_aligned_safe_function = basic_protected_function; + using protected_function = safe_function; + using main_protected_function = main_safe_function; + using stack_protected_function = stack_safe_function; + using stack_aligned_protected_function = stack_aligned_safe_function; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) + using function = protected_function; + using main_function = main_protected_function; + using stack_function = stack_protected_function; + using stack_aligned_function = stack_aligned_safe_function; +#else + using function = unsafe_function; + using main_function = main_unsafe_function; + using stack_function = stack_unsafe_function; + using stack_aligned_function = stack_aligned_unsafe_function; +#endif + using stack_aligned_stack_handler_function = basic_protected_function; + + struct unsafe_function_result; + struct protected_function_result; + using safe_function_result = protected_function_result; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) + using function_result = safe_function_result; +#else + using function_result = unsafe_function_result; +#endif + + template + class basic_object_base; + template + class basic_object; + template + class basic_userdata; + template + class basic_lightuserdata; + template + class basic_coroutine; + template + class basic_thread; + + using object = basic_object; + using userdata = basic_userdata; + using lightuserdata = basic_lightuserdata; + using thread = basic_thread; + using coroutine = basic_coroutine; + using main_object = basic_object; + using main_userdata = basic_userdata; + using main_lightuserdata = basic_lightuserdata; + using main_coroutine = basic_coroutine; + using stack_object = basic_object; + using stack_userdata = basic_userdata; + using stack_lightuserdata = basic_lightuserdata; + using stack_thread = basic_thread; + using stack_coroutine = basic_coroutine; + + struct stack_proxy_base; + struct stack_proxy; + struct variadic_args; + struct variadic_results; + struct stack_count; + struct this_state; + struct this_main_state; + struct this_environment; + + class state_view; + class state; + + template + struct as_table_t; + template + struct as_container_t; + template + struct nested; + template + struct light; + template + struct user; + template + struct as_args_t; + template + struct protect_t; + template + struct policy_wrapper; + + template + struct usertype_traits; + template + struct unique_usertype_traits; + + template + struct types { + typedef std::make_index_sequence indices; + static constexpr std::size_t size() { + return sizeof...(Args); + } + }; + + template + struct derive : std::false_type { + typedef types<> type; + }; + + template + struct base : std::false_type { + typedef types<> type; + }; + + template + struct weak_derive { + static bool value; + }; + + template + bool weak_derive::value = false; + + namespace stack { + struct record; + } + +#if SOL_IS_OFF(SOL_USE_BOOST_I_) + template + class optional; + + template + class optional; +#endif + + using check_handler_type = int(lua_State*, int, type, type, const char*); + +} // namespace sol + +#define SOL_BASE_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct base : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() +#define SOL_DERIVED_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct derive : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() + +#endif // SOL_FORWARD_HPP +// end of sol/forward.hpp + +// beginning of sol/forward_detail.hpp + +#ifndef SOL_FORWARD_DETAIL_HPP +#define SOL_FORWARD_DETAIL_HPP + +// beginning of sol/traits.hpp + +// beginning of sol/tuple.hpp + +// beginning of sol/base_traits.hpp + +#include + +namespace sol { + namespace detail { + struct unchecked_t {}; + const unchecked_t unchecked = unchecked_t{}; + } // namespace detail + + namespace meta { + using sfinae_yes_t = std::true_type; + using sfinae_no_t = std::false_type; + + template + using void_t = void; + + template + using unqualified = std::remove_cv>; + + template + using unqualified_t = typename unqualified::type; + + namespace meta_detail { + template + struct unqualified_non_alias : unqualified {}; + + template