From dee72e94302f1a0fec2be48ba807240b46fb48df Mon Sep 17 00:00:00 2001 From: Phillip Andrews Date: Tue, 21 May 2019 17:58:10 -0500 Subject: [PATCH 01/30] Make script literal lookup functions safer Assert isn't really the right way to range check these, since in theory we could have a malformed compiled script. This should make it safer with zero performance overhead. --- components/interpreter/runtime.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index 6599882f1..a90bda94b 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -15,7 +15,8 @@ namespace Interpreter int Runtime::getIntegerLiteral (int index) const { - assert (index>=0 && index (mCode[1])); + if (index < 0 || index >= static_cast (mCode[1])) + throw std::out_of_range("out of range"); const Type_Code *literalBlock = mCode + 4 + mCode[0]; @@ -24,7 +25,8 @@ namespace Interpreter float Runtime::getFloatLiteral (int index) const { - assert (index>=0 && index (mCode[2])); + if (index < 0 || index >= static_cast (mCode[2])) + throw std::out_of_range("out of range"); const Type_Code *literalBlock = mCode + 4 + mCode[0] + mCode[1]; @@ -33,7 +35,8 @@ namespace Interpreter std::string Runtime::getStringLiteral (int index) const { - assert (index>=0 && static_cast (mCode[3])>0); + if (index < 0 || static_cast (mCode[3]) <= 0) + throw std::out_of_range("out of range"); const char *literalBlock = reinterpret_cast (mCode + 4 + mCode[0] + mCode[1] + mCode[2]); @@ -43,7 +46,8 @@ namespace Interpreter for (; index; --index) { offset += std::strlen (literalBlock+offset) + 1; - assert (offset/4 (mCode[3])); + if (offset / 4 >= static_cast (mCode[3])) + throw std::out_of_range("out of range"); } return literalBlock+offset; From bd149b909feb037a09f9c23c0c55f4f8df61e74c Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 16:37:38 +0100 Subject: [PATCH 02/30] Remove unused virtual modifiers in ShadowManager /home/elsid/dev/openmw/components/sceneutil/shadow.cpp:100:9: warning: Call to virtual function during construction [clang-analyzer-optin.cplusplus.VirtualCall] setupShadowSettings(); ^ /home/elsid/dev/openmw/components/sceneutil/shadow.cpp:100:9: note: This constructor of an object of type 'ShadowManager' has not returned when the virtual method was called /home/elsid/dev/openmw/components/sceneutil/shadow.cpp:100:9: note: Call to virtual function during construction /home/elsid/dev/openmw/components/sceneutil/shadow.cpp:104:9: warning: Call to virtual function during construction [clang-analyzer-optin.cplusplus.VirtualCall] enableOutdoorMode(); ^ /home/elsid/dev/openmw/components/sceneutil/shadow.cpp:104:9: note: This constructor of an object of type 'ShadowManager' has not returned when the virtual method was called /home/elsid/dev/openmw/components/sceneutil/shadow.cpp:104:9: note: Call to virtual function during construction --- components/sceneutil/shadow.hpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/components/sceneutil/shadow.hpp b/components/sceneutil/shadow.hpp index 928de4543..c823ecf86 100644 --- a/components/sceneutil/shadow.hpp +++ b/components/sceneutil/shadow.hpp @@ -19,15 +19,13 @@ namespace SceneUtil ShadowManager(osg::ref_ptr sceneRoot, osg::ref_ptr rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager); - virtual ~ShadowManager() = default; + void setupShadowSettings(); - virtual void setupShadowSettings(); + Shader::ShaderManager::DefineMap getShadowDefines(); - virtual Shader::ShaderManager::DefineMap getShadowDefines(); + void enableIndoorMode(); - virtual void enableIndoorMode(); - - virtual void enableOutdoorMode(); + void enableOutdoorMode(); protected: bool mEnableShadows; From 2e1d8a5e5593b5174b0ccf7959f4397a708990e3 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 16:49:03 +0100 Subject: [PATCH 03/30] Remove unused virtual modifiers in DebugHUD /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3127:9: warning: Call to virtual function during construction [clang-analyzer-optin.cplusplus.VirtualCall] addAnotherShadowMap(); ^ /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3094:5: note: Loop condition is true. Entering loop body for (int i = 0; i < 2; ++i) ^ /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3094:5: note: Loop condition is true. Entering loop body /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3094:5: note: Loop condition is false. Execution continues on line 3102 /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3126:21: note: Assuming 'i' is < 'numberOfShadowMapsPerLight' for (int i = 0; i < numberOfShadowMapsPerLight; ++i) ^ /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3126:5: note: Loop condition is true. Entering loop body for (int i = 0; i < numberOfShadowMapsPerLight; ++i) ^ /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3127:9: note: This constructor of an object of type 'DebugHUD' has not returned when the virtual method was called addAnotherShadowMap(); ^ /home/elsid/dev/openmw/components/sceneutil/mwshadowtechnique.cpp:3127:9: note: Call to virtual function during construction --- components/sceneutil/mwshadowtechnique.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/sceneutil/mwshadowtechnique.hpp b/components/sceneutil/mwshadowtechnique.hpp index 1aa25585f..165613f3c 100644 --- a/components/sceneutil/mwshadowtechnique.hpp +++ b/components/sceneutil/mwshadowtechnique.hpp @@ -261,18 +261,18 @@ namespace SceneUtil { float _shadowFadeStart = 0.0; - class DebugHUD : public osg::Referenced + class DebugHUD final : public osg::Referenced { public: DebugHUD(int numberOfShadowMapsPerLight); - virtual void draw(osg::ref_ptr texture, unsigned int shadowMapNumber, const osg::Matrixd &matrix, osgUtil::CullVisitor& cv); + void draw(osg::ref_ptr texture, unsigned int shadowMapNumber, const osg::Matrixd &matrix, osgUtil::CullVisitor& cv); - virtual void releaseGLObjects(osg::State* state = 0) const; + void releaseGLObjects(osg::State* state = 0) const; - virtual void setFrustumVertices(osg::ref_ptr vertices, unsigned int traversalNumber); + void setFrustumVertices(osg::ref_ptr vertices, unsigned int traversalNumber); protected: - virtual void addAnotherShadowMap(); + void addAnotherShadowMap(); static const int sDebugTextureUnit = 0; From 4cd2ff9a3da1a02d4a159dd185a930f1bf7330c0 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 16:53:29 +0100 Subject: [PATCH 04/30] Avoid virtual call in TerrainGrid dtor /home/elsid/dev/openmw/components/terrain/terraingrid.cpp:31:9: warning: Call to virtual function during destruction [clang-analyzer-optin.cplusplus.VirtualCall] unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second); ^ /home/elsid/dev/openmw/components/terrain/terraingrid.cpp:29:12: note: Assuming the condition is true while (!mGrid.empty()) ^ /home/elsid/dev/openmw/components/terrain/terraingrid.cpp:29:5: note: Loop condition is true. Entering loop body while (!mGrid.empty()) ^ /home/elsid/dev/openmw/components/terrain/terraingrid.cpp:31:9: note: This destructor of an object of type '~TerrainGrid' has not returned when the virtual method was called unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second); ^ /home/elsid/dev/openmw/components/terrain/terraingrid.cpp:31:9: note: Call to virtual function during destruction --- components/terrain/terraingrid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index c91240334..7310846c2 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -28,7 +28,7 @@ TerrainGrid::~TerrainGrid() { while (!mGrid.empty()) { - unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second); + TerrainGrid::unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second); } } From b07a6afa91ecf85dcaca86bb62d4383b6a06916a Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 17:01:30 +0100 Subject: [PATCH 05/30] Avoid virtual call in GraphicsWindowSDL2 ctor /home/elsid/dev/openmw/components/sdlutil/sdlgraphicswindow.cpp:23:8: warning: Call to virtual function during construction [clang-analyzer-optin.cplusplus.VirtualCall] if(valid()) ^ /home/elsid/dev/openmw/components/sdlutil/sdlgraphicswindow.cpp:23:8: note: This constructor of an object of type 'GraphicsWindowSDL2' has not returned when the virtual method was called /home/elsid/dev/openmw/components/sdlutil/sdlgraphicswindow.cpp:23:8: note: Call to virtual function during construction --- components/sdlutil/sdlgraphicswindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/sdlutil/sdlgraphicswindow.cpp b/components/sdlutil/sdlgraphicswindow.cpp index ad8454b25..cd5e80c31 100644 --- a/components/sdlutil/sdlgraphicswindow.cpp +++ b/components/sdlutil/sdlgraphicswindow.cpp @@ -20,7 +20,7 @@ GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits *traits) _traits = traits; init(); - if(valid()) + if(GraphicsWindowSDL2::valid()) { setState(new osg::State); getState()->setGraphicsContext(this); From cf01df31be22354f98370bd0e5a3b85d333000c7 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 17:02:35 +0100 Subject: [PATCH 06/30] Remove unused variable initialization /home/elsid/dev/openmw/apps/openmw/mwrender/animation.cpp:518:28: warning: Value stored to 'material' during its initialization is never read [clang-analyzer-deadcode.DeadStores] osg::Material* material = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); ^ /home/elsid/dev/openmw/apps/openmw/mwrender/animation.cpp:518:28: note: Value stored to 'material' during its initialization is never read --- apps/openmw/mwrender/animation.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 56c3846af..37a39cdc4 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -515,13 +515,11 @@ namespace MWRender protected: virtual void setDefaults(osg::StateSet* stateset) { - osg::Material* material = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); - osg::BlendFunc* blendfunc (new osg::BlendFunc); stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); // FIXME: overriding diffuse/ambient/emissive colors - material = new osg::Material; + osg::Material* material = new osg::Material; material->setColorMode(osg::Material::OFF); material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,mAlpha)); material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); From b55f5ab64840a3317e0da4aca4549a9ce2f91806 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 17:10:09 +0100 Subject: [PATCH 07/30] Avoid virtual call in WindowManager ctor /home/elsid/dev/openmw/apps/openmw/mwgui/windowmanagerimp.cpp:244:9: warning: Call to virtual function during construction [clang-analyzer-optin.cplusplus.VirtualCall] loadUserFonts(); ^ /home/elsid/dev/openmw/apps/openmw/mwgui/windowmanagerimp.cpp:244:9: note: This constructor of an object of type 'WindowManager' has not returned when the virtual method was called /home/elsid/dev/openmw/apps/openmw/mwgui/windowmanagerimp.cpp:244:9: note: Call to virtual function during construction --- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 02bedee86..0524945fd 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -241,7 +241,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); MyGUI::FactoryManager::getInstance().registerFactory("Resource", "AutoSizedResourceSkin"); MyGUI::ResourceManager::getInstance().load("core.xml"); - loadUserFonts(); + WindowManager::loadUserFonts(); bool keyboardNav = Settings::Manager::getBool("keyboard navigation", "GUI"); mKeyboardNavigation.reset(new KeyboardNavigation()); From b4794e8ca593de22d9588bef159347df88ef1264 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 17:26:08 +0100 Subject: [PATCH 08/30] Avoid virtual call in OpenAL_Output dtor /home/elsid/dev/openmw/apps/openmw/mwsound/openal_output.cpp:1492:5: warning: Call to virtual function during destruction [clang-analyzer-optin.cplusplus.VirtualCall] deinit(); ^ /home/elsid/dev/openmw/apps/openmw/mwsound/openal_output.cpp:1492:5: note: This destructor of an object of type '~OpenAL_Output' has not returned when the virtual method was called /home/elsid/dev/openmw/apps/openmw/mwsound/openal_output.cpp:1492:5: note: Call to virtual function during destruction --- apps/openmw/mwsound/openal_output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 4c41a5b40..9c87cac19 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -1489,7 +1489,7 @@ OpenAL_Output::OpenAL_Output(SoundManager &mgr) OpenAL_Output::~OpenAL_Output() { - deinit(); + OpenAL_Output::deinit(); } } From 8083df4567ae75d05afb65e848936a572fe8bf66 Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 18:46:58 +0100 Subject: [PATCH 09/30] Avoid virtual call in Animation dtor --- apps/openmw/mwrender/animation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 37a39cdc4..3505ea261 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -633,7 +633,7 @@ namespace MWRender Animation::~Animation() { - setLightEffect(0.f); + Animation::setLightEffect(0.f); if (mObjectRoot) mInsert->removeChild(mObjectRoot); From f156c9522e03b1bffed5194a0a59674da92570ab Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 18:49:13 +0100 Subject: [PATCH 10/30] Avoid virtual call in SoundManager dtor --- apps/openmw/mwsound/soundmanagerimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index e01df7aa9..5c277d09e 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -1362,7 +1362,7 @@ namespace MWSound void SoundManager::clear() { - stopMusic(); + SoundManager::stopMusic(); for(SoundMap::value_type &snd : mActiveSounds) { From 8d358eeb7d34ccf5b2deaf1ce9e680db4d0e1d1b Mon Sep 17 00:00:00 2001 From: elsid Date: Sun, 17 Nov 2019 18:50:42 +0100 Subject: [PATCH 11/30] Avoid virtual call in ParticleSystem ctor --- components/nifosg/particle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index eeb6777ce..16bef0a80 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -27,7 +27,7 @@ ParticleSystem::ParticleSystem(const ParticleSystem ©, const osg::CopyOp &co { // For some reason the osgParticle constructor doesn't copy the particles for (int i=0;i Date: Wed, 20 Nov 2019 13:37:00 +0000 Subject: [PATCH 12/30] perf regression fix --- apps/opencs/view/render/terrainstorage.hpp | 2 ++ components/esmterrain/storage.cpp | 11 +++++++---- components/esmterrain/storage.hpp | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/render/terrainstorage.hpp b/apps/opencs/view/render/terrainstorage.hpp index 032261ad4..74c30ce5c 100644 --- a/apps/opencs/view/render/terrainstorage.hpp +++ b/apps/opencs/view/render/terrainstorage.hpp @@ -18,6 +18,8 @@ namespace CSVRender TerrainStorage(const CSMWorld::Data& data); void setAlteredHeight(int inCellX, int inCellY, float heightMap); void resetHeights(); + + virtual bool useAlteration() const { return true; } float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY); float* getAlteredHeight(int inCellX, int inCellY); diff --git a/components/esmterrain/storage.cpp b/components/esmterrain/storage.cpp index 52af530f5..021ae32e9 100644 --- a/components/esmterrain/storage.cpp +++ b/components/esmterrain/storage.cpp @@ -201,6 +201,8 @@ namespace ESMTerrain LandCache cache; + bool alteration = useAlteration(); + float vertY_ = 0; // of current cell corner for (int cellY = startCellY; cellY < startCellY + std::ceil(size); ++cellY) { @@ -251,11 +253,12 @@ namespace ESMTerrain float height = defaultHeight; if (heightData) height = heightData->mHeights[col*ESM::Land::LAND_SIZE + row]; - + if (alteration) + height += getAlteredHeight(col, row); (*positions)[static_cast(vertX*numVerts + vertY)] = osg::Vec3f((vertX / float(numVerts - 1) - 0.5f) * size * Constants::CellSizeInUnits, (vertY / float(numVerts - 1) - 0.5f) * size * Constants::CellSizeInUnits, - height + getAlteredHeight(col, row)); + height); if (normalData) { @@ -290,8 +293,8 @@ namespace ESMTerrain color.g() = 255; color.b() = 255; } - - adjustColor(col, row, heightData, color); //Does nothing by default, override in OpenMW-CS + if (alteration) + adjustColor(col, row, heightData, color); //Does nothing by default, override in OpenMW-CS // Unlike normals, colors mostly connect seamlessly between cells, but not always... if (col == ESM::Land::LAND_SIZE-1 || row == ESM::Land::LAND_SIZE-1) diff --git a/components/esmterrain/storage.hpp b/components/esmterrain/storage.hpp index 65e531e5c..a5f62ba48 100644 --- a/components/esmterrain/storage.hpp +++ b/components/esmterrain/storage.hpp @@ -125,6 +125,7 @@ namespace ESMTerrain inline const LandObject* getLand(int cellX, int cellY, LandCache& cache); + virtual bool useAlteration() const { return false; } virtual void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const; virtual float getAlteredHeight(int col, int row) const; From 4b38bab0d90b51eca4b21e98fdb3056b1d891d3c Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 3 Dec 2019 18:46:42 +0300 Subject: [PATCH 13/30] Make sure empty cell name subrecords are saved (bug #5222) --- CHANGELOG.md | 1 + components/esm/loadcell.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b8284f1..4680f0e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -179,6 +179,7 @@ Bug #5213: SameFaction script function is broken Bug #5218: Crash when disabling ToggleBorders Bug #5220: GetLOS crashes when actor isn't loaded + Bug #5222: Empty cell name subrecords are not saved Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index 657d92d6e..ec4155f59 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -160,7 +160,7 @@ namespace ESM void Cell::save(ESMWriter &esm, bool isDeleted) const { - esm.writeHNOCString("NAME", mName); + esm.writeHNCString("NAME", mName); esm.writeHNT("DATA", mData, 12); if (isDeleted) From 86c8fe386bdf541b05299597cb8b870600be8f86 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Tue, 3 Dec 2019 20:50:57 +0300 Subject: [PATCH 14/30] Fix idle state reset --- apps/openmw/mwmechanics/character.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 96f2a19ac..fa3fe4bd2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -576,6 +576,13 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup mCurrentMovement = movementAnimName; if(!mCurrentMovement.empty()) { + if (resetIdle) + { + mAnimation->disable(mCurrentIdle); + mIdleState = CharState_None; + idle = CharState_None; + } + // For non-flying creatures, MW uses the Walk animation to calculate the animation velocity // even if we are running. This must be replicated, otherwise the observed speed would differ drastically. std::string anim = mCurrentMovement; @@ -615,9 +622,6 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup mAnimation->play(mCurrentMovement, Priority_Movement, movemask, false, 1.f, "start", "stop", startpoint, ~0ul, true); - - if (resetIdle) - mAnimation->disable(mCurrentIdle); } else mMovementState = CharState_None; @@ -1656,6 +1660,7 @@ bool CharacterController::updateWeaponState(CharacterState& idle) mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim) { mAnimation->disable(mCurrentIdle); + mIdleState = CharState_None; } animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); From d66b81d7f71a6fe4fdcfe91341c199e0aa29bb6e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 5 Dec 2019 17:35:32 +0400 Subject: [PATCH 15/30] Reset holstered shield before rebuilding an NPC animation --- apps/openmw/mwrender/npcanimation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index abc2583d5..063c1a60f 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -409,6 +409,7 @@ void NpcAnimation::setRenderBin() void NpcAnimation::rebuild() { mScabbard.reset(); + mHolsteredShield.reset(); updateNpcBase(); MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr); From 0bc13b47fac6f25e7be190fd3c2be4c6d1c414c5 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 5 Dec 2019 23:42:12 +0300 Subject: [PATCH 16/30] Fix essimporter script header and inventory item conversion --- apps/essimporter/convertscpt.cpp | 2 +- apps/essimporter/importinventory.cpp | 4 ++-- apps/essimporter/importinventory.hpp | 8 ++++++++ apps/essimporter/importscpt.hpp | 8 +++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/essimporter/convertscpt.cpp b/apps/essimporter/convertscpt.cpp index 484a2782a..ca81ebbbf 100644 --- a/apps/essimporter/convertscpt.cpp +++ b/apps/essimporter/convertscpt.cpp @@ -9,7 +9,7 @@ namespace ESSImport void convertSCPT(const SCPT &scpt, ESM::GlobalScript &out) { - out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName); + out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName.toString()); out.mRunning = scpt.mRunning; convertSCRI(scpt.mSCRI, out.mLocals); } diff --git a/apps/essimporter/importinventory.cpp b/apps/essimporter/importinventory.cpp index 177213a13..cff114acb 100644 --- a/apps/essimporter/importinventory.cpp +++ b/apps/essimporter/importinventory.cpp @@ -13,11 +13,11 @@ namespace ESSImport { while (esm.isNextSub("NPCO")) { - ESM::ContItem contItem; + ContItem contItem; esm.getHT(contItem); InventoryItem item; - item.mId = contItem.mItem; + item.mId = contItem.mItem.toString(); item.mCount = contItem.mCount; item.mRelativeEquipmentSlot = -1; item.mLockLevel = 0; diff --git a/apps/essimporter/importinventory.hpp b/apps/essimporter/importinventory.hpp index 0b5405d96..a1324a696 100644 --- a/apps/essimporter/importinventory.hpp +++ b/apps/essimporter/importinventory.hpp @@ -5,6 +5,8 @@ #include #include +#include + #include "importscri.hpp" namespace ESM @@ -15,6 +17,12 @@ namespace ESM namespace ESSImport { + struct ContItem + { + int mCount; + ESM::NAME32 mItem; + }; + struct Inventory { struct InventoryItem : public ESM::CellRef diff --git a/apps/essimporter/importscpt.hpp b/apps/essimporter/importscpt.hpp index ce54c3a73..6bfd2603a 100644 --- a/apps/essimporter/importscpt.hpp +++ b/apps/essimporter/importscpt.hpp @@ -13,10 +13,16 @@ namespace ESM namespace ESSImport { + struct SCHD + { + ESM::NAME32 mName; + ESM::Script::SCHDstruct mData; + }; + // A running global script struct SCPT { - ESM::Script::SCHD mSCHD; + SCHD mSCHD; // values of local variables SCRI mSCRI; From 0a96f065d7006eeb843e33e2ccfc26fe6f9129b7 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sun, 8 Dec 2019 17:03:27 +0300 Subject: [PATCH 17/30] Launcher: improve first run and missing game data dialogues (bug #4009) --- CHANGELOG.md | 1 + apps/launcher/maindialog.cpp | 31 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4680f0e11..f390cb72a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Bug #3812: Wrong multiline tooltips width when word-wrapping is enabled Bug #3894: Hostile spell effects not detected/present on first frame of OnPCHitMe Bug #3977: Non-ASCII characters in object ID's are not supported + Bug #4009: Launcher does not show data files on the first run after installing Bug #4077: Enchanted items are not recharged if they are not in the player's inventory Bug #4202: Open .omwaddon files without needing toopen openmw-cs first Bug #4240: Ash storm origin coordinates and hand shielding animation behavior are incorrect diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 4ec7f34a7..f69213c4a 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -116,6 +116,10 @@ void Launcher::MainDialog::createIcons() void Launcher::MainDialog::createPages() { + // Avoid creating the widgets twice + if (pagesWidget->count() != 0) + return; + mPlayPage = new PlayPage(this); mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); mGraphicsPage = new GraphicsPage(mCfgMgr, mEngineSettings, this); @@ -166,18 +170,20 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() QAbstractButton *skipButton = msgBox.addButton(tr("Skip"), QMessageBox::RejectRole); - Q_UNUSED(skipButton); // Surpress compiler unused warning - msgBox.exec(); if (msgBox.clickedButton() == wizardButton) { - if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) { - return FirstRunDialogResultFailure; - } else { + if (mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) return FirstRunDialogResultWizard; - } } + else if (msgBox.clickedButton() == skipButton) + { + // Don't bother setting up absent game data. + if (setup()) + return FirstRunDialogResultContinue; + } + return FirstRunDialogResultFailure; } if (!setup() || !setupGameData()) { @@ -384,22 +390,23 @@ bool Launcher::MainDialog::setupGameData() QMessageBox msgBox; msgBox.setWindowTitle(tr("Error detecting Morrowind installation")); msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setStandardButtons(QMessageBox::NoButton); msgBox.setText(tr("
Could not find the Data Files location

\ The directory containing the data files was not found.")); QAbstractButton *wizardButton = msgBox.addButton(tr("Run &Installation Wizard..."), QMessageBox::ActionRole); + QAbstractButton *skipButton = + msgBox.addButton(tr("Skip"), QMessageBox::RejectRole); + + Q_UNUSED(skipButton); // Supress compiler unused warning msgBox.exec(); if (msgBox.clickedButton() == wizardButton) { - if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) { + if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) return false; - } else { - return true; - } } } @@ -582,7 +589,7 @@ void Launcher::MainDialog::wizardFinished(int exitCode, QProcess::ExitStatus exi // HACK: Ensure the pages are created, else segfault setup(); - if (reloadSettings()) + if (setupGameData() && reloadSettings()) show(); } From 5b5c52d92e49c062688cd68ad26252809e2900b2 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 10 Dec 2019 10:53:17 +0400 Subject: [PATCH 18/30] Handle NiKeyframeController for NiTriShape (feature #5224) --- CHANGELOG.md | 1 + components/nifosg/nifloader.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f390cb72a..a492f8616 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -231,6 +231,7 @@ Feature #5147: Show spell magicka cost in spell buying window Feature #5170: Editor: Land shape editing, land selection Feature #5193: Weapon sheathing + Feature #5224: Handle NiKeyframeController for NiTriShape Task #4686: Upgrade media decoder to a more current FFmpeg API Task #4695: Optimize Distant Terrain memory consumption Task #4789: Optimize cell transitions diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 901dccc51..509877381 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -614,8 +614,6 @@ namespace NifOsg if (composite->getNumControllers() > 0) node->addUpdateCallback(composite); - // Note: NiTriShapes are not allowed to have KeyframeControllers (the vanilla engine just crashes when there is one). - // We can take advantage of this constraint for optimizations later. if (nifNode->recType != Nif::RC_NiTriShape && nifNode->recType != Nif::RC_NiTriStrips && !nifNode->controller.empty() && node->getDataVariance() == osg::Object::DYNAMIC) handleNodeControllers(nifNode, static_cast(node.get()), animflags); @@ -676,6 +674,17 @@ namespace NifOsg setupController(niuvctrl, uvctrl, animflags); composite->addController(uvctrl); } + else if (ctrl->recType == Nif::RC_NiKeyframeController) + { + const Nif::NiKeyframeController *key = static_cast(ctrl.getPtr()); + if(!key->data.empty()) + { + osg::ref_ptr callback(new KeyframeController(key->data.getPtr())); + + setupController(key, callback, animflags); + node->addUpdateCallback(callback); + } + } else if (ctrl->recType == Nif::RC_NiVisController) { handleVisController(static_cast(ctrl.getPtr()), node, animflags); From 3d9c42e8ee750c1efca84741707152689f94e0ed Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 11 Dec 2019 08:47:46 +0400 Subject: [PATCH 19/30] Cap reputation values (bug #5226) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/npcstats.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a492f8616..5acc8b4f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -181,6 +181,7 @@ Bug #5218: Crash when disabling ToggleBorders Bug #5220: GetLOS crashes when actor isn't loaded Bug #5222: Empty cell name subrecords are not saved + Bug #5226: Reputation should be capped Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 7dca082b6..aa6cd142b 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -370,7 +370,8 @@ int MWMechanics::NpcStats::getReputation() const void MWMechanics::NpcStats::setReputation(int reputation) { - mReputation = reputation; + // Reputation is capped in original engine + mReputation = std::min(255, std::max(0, reputation)); } int MWMechanics::NpcStats::getCrimeId() const From 483b37bb3f960a367222bd9b9c9425a6ed4bdc19 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 12 Dec 2019 15:20:23 +0300 Subject: [PATCH 20/30] Disallow resting if the fall height hasn't been reset (bug #4802) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/creaturestats.cpp | 5 +++++ apps/openmw/mwmechanics/creaturestats.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 4 +++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5acc8b4f5..d55452e42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ Bug #4787: Sneaking makes 1st person walking/bobbing animation super-slow Bug #4797: Player sneaking and running stances are not accounted for when in air Bug #4800: Standing collisions are not updated immediately when an object is teleported without a cell change + Bug #4802: You can rest before taking falling damage from landing from a jump Bug #4803: Stray special characters before begin statement break script compilation Bug #4804: Particle system with the "Has Sizes = false" causes an exception Bug #4805: NPC movement speed calculations do not take race Weight into account diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 236587669..1c377540a 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -426,6 +426,11 @@ namespace MWMechanics mFallHeight += height; } + float CreatureStats::getFallHeight() const + { + return mFallHeight; + } + float CreatureStats::land(bool isPlayer) { if (isPlayer) diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 6ec4cc3a1..7c4a83db1 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -115,6 +115,7 @@ namespace MWMechanics bool needToRecalcDynamicStats(); void setNeedRecalcDynamicStats(bool val); + float getFallHeight() const; void addToFallHeight(float height); /// Reset the fall height diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 704ffe6f9..2ac27f0b7 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2513,7 +2513,9 @@ namespace MWWorld if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player)) return Rest_PlayerIsUnderwater; - if ((actor->getCollisionMode() && !mPhysics->isOnSolidGround(player)) || isFlying(player)) + float fallHeight = player.getClass().getCreatureStats(player).getFallHeight(); + float epsilon = 1e-4; + if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon)) || isFlying(player)) return Rest_PlayerIsInAir; if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) || player.getClass().getNpcStats(player).isWerewolf()) From 909c8ef0ea50cd0ae898796111ce762d3063efed Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Sat, 14 Dec 2019 20:35:23 +0300 Subject: [PATCH 21/30] Avoid working with empty controller data (bug #5229) --- CHANGELOG.md | 1 + components/nifosg/nifloader.cpp | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d55452e42..deb7abd44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -183,6 +183,7 @@ Bug #5220: GetLOS crashes when actor isn't loaded Bug #5222: Empty cell name subrecords are not saved Bug #5226: Reputation should be capped + Bug #5229: Crash if mesh controller node has no data node Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI Feature #3025: Analogue gamepad movement controls diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 509877381..f1dd63def 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -661,6 +661,8 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiUVController) { const Nif::NiUVController *niuvctrl = static_cast(ctrl.getPtr()); + if (niuvctrl->data.empty()) + continue; const unsigned int uvSet = niuvctrl->uvSet; std::set texUnits; // UVController should work only for textures which use a given UV Set, usually 0. @@ -728,6 +730,8 @@ namespace NifOsg void handleVisController(const Nif::NiVisController* visctrl, osg::Node* node, int animflags) { + if (visctrl->data.empty()) + return; osg::ref_ptr callback(new VisController(visctrl->data.getPtr())); setupController(visctrl, callback, animflags); node->addUpdateCallback(callback); @@ -735,6 +739,8 @@ namespace NifOsg void handleRollController(const Nif::NiRollController* rollctrl, osg::Node* node, int animflags) { + if (rollctrl->data.empty()) + return; osg::ref_ptr callback(new RollController(rollctrl->data.getPtr())); setupController(rollctrl, callback, animflags); node->addUpdateCallback(callback); @@ -749,6 +755,8 @@ namespace NifOsg if (ctrl->recType == Nif::RC_NiAlphaController) { const Nif::NiAlphaController* alphactrl = static_cast(ctrl.getPtr()); + if (alphactrl->data.empty()) + continue; osg::ref_ptr osgctrl(new AlphaController(alphactrl->data.getPtr())); setupController(alphactrl, osgctrl, animflags); composite->addController(osgctrl); @@ -756,6 +764,8 @@ namespace NifOsg else if (ctrl->recType == Nif::RC_NiMaterialColorController) { const Nif::NiMaterialColorController* matctrl = static_cast(ctrl.getPtr()); + if (matctrl->data.empty()) + continue; // Two bits that correspond to the controlled material color. // 00: Ambient // 01: Diffuse @@ -1142,10 +1152,12 @@ namespace NifOsg continue; if(ctrl->recType == Nif::RC_NiGeomMorpherController) { - drawable = handleMorphGeometry(static_cast(ctrl.getPtr()), geom, parentNode, composite, boundTextures, animflags); + const Nif::NiGeomMorpherController* nimorphctrl = static_cast(ctrl.getPtr()); + if (nimorphctrl->data.empty()) + continue; + drawable = handleMorphGeometry(nimorphctrl, geom, parentNode, composite, boundTextures, animflags); - osg::ref_ptr morphctrl = new GeomMorpherController( - static_cast(ctrl.getPtr())->data.getPtr()); + osg::ref_ptr morphctrl = new GeomMorpherController(nimorphctrl->data.getPtr()); setupController(ctrl.getPtr(), morphctrl, animflags); drawable->setUpdateCallback(morphctrl); break; From 97ee4bc3496d104e5c4e49458ef9e4d4851e112c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 14 Dec 2019 21:30:46 +0400 Subject: [PATCH 22/30] Improve equipment logic (bug #5223) --- CHANGELOG.md | 1 + apps/openmw/mwmechanics/actors.cpp | 26 ++++++++++++++------------ apps/openmw/mwrender/npcanimation.cpp | 2 +- apps/openmw/mwworld/actionequip.cpp | 2 +- apps/openmw/mwworld/inventorystore.cpp | 6 ++++-- apps/openmw/mwworld/inventorystore.hpp | 2 +- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d55452e42..a8ee80f31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -182,6 +182,7 @@ Bug #5218: Crash when disabling ToggleBorders Bug #5220: GetLOS crashes when actor isn't loaded Bug #5222: Empty cell name subrecords are not saved + Bug #5223: Bow replacement during attack animation removes attached arrow Bug #5226: Reputation should be capped Feature #1774: Handle AvoidNode Feature #2229: Improve pathfinding AI diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 7cd17d13e..35a48710d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -299,10 +299,10 @@ namespace MWMechanics bool wasEquipped = currentItem != store.end() && Misc::StringUtils::ciEqual(currentItem->getCellRef().getRefId(), itemId); - store.remove(itemId, 1, actor); - if (actor != MWMechanics::getPlayer()) { + store.remove(itemId, 1, actor); + // Equip a replacement if (!wasEquipped) return; @@ -329,17 +329,19 @@ namespace MWMechanics std::string prevItemId = player.getPreviousItem(itemId); player.erasePreviousItem(itemId); - if (prevItemId.empty()) - return; + if (!prevItemId.empty()) + { + // Find previous item (or its replacement) by id. + // we should equip previous item only if expired bound item was equipped. + MWWorld::Ptr item = store.findReplacement(prevItemId); + if (!item.isEmpty() && wasEquipped) + { + MWWorld::ActionEquip action(item); + action.execute(actor); + } + } - // Find previous item (or its replacement) by id. - // we should equip previous item only if expired bound item was equipped. - MWWorld::Ptr item = store.findReplacement(prevItemId); - if (item.isEmpty() || !wasEquipped) - return; - - MWWorld::ActionEquip action(item); - action.execute(actor); + store.remove(itemId, 1, actor); } void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 063c1a60f..e9f62e25c 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -598,7 +598,7 @@ void NpcAnimation::updateParts() }; static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]); - bool wasArrowAttached = (mAmmunition.get() != nullptr); + bool wasArrowAttached = isArrowAttached(); mAmmunition.reset(); const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index 30f969193..4cb0dbe51 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -93,7 +93,7 @@ namespace MWWorld { for (slot=slots_.first.begin();slot!=slots_.first.end(); ++slot) { - invStore.unequipSlot(*slot, actor); + invStore.unequipSlot(*slot, actor, false); if (slot+1 != slots_.first.end()) invStore.equip(*slot, invStore.getSlot(*(slot+1)), actor); else diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 04947335f..094d1c8ec 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -779,7 +779,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor return retCount; } -MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, const MWWorld::Ptr& actor) +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, const MWWorld::Ptr& actor, bool fireEvent) { if (slot<0 || slot>=static_cast (mSlots.size())) throw std::runtime_error ("slot number out of range"); @@ -811,7 +811,9 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, c } } - fireEquipmentChangedEvent(actor); + if (fireEvent) + fireEquipmentChangedEvent(actor); + updateMagicEffects(actor); return retval; diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 2293f96af..663e7a2d3 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -173,7 +173,7 @@ namespace MWWorld /// /// @return the number of items actually removed - ContainerStoreIterator unequipSlot(int slot, const Ptr& actor); + ContainerStoreIterator unequipSlot(int slot, const Ptr& actor, bool fireEvent=true); ///< Unequip \a slot. /// /// @return an iterator to the item that was previously in the slot From c41562fa2787afcbc584edccc5dc2a0c5e5f4bfe Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 15 Dec 2019 13:56:20 +0400 Subject: [PATCH 23/30] Make TextureProperty warnings more informative --- components/nifosg/nifloader.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index f1dd63def..2fd42e77a 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1410,7 +1410,7 @@ namespace NifOsg return image; } - void handleTextureProperty(const Nif::NiTexturingProperty* texprop, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector& boundTextures, int animflags) + void handleTextureProperty(const Nif::NiTexturingProperty* texprop, const std::string& nodeName, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector& boundTextures, int animflags) { if (!boundTextures.empty()) { @@ -1444,7 +1444,7 @@ namespace NifOsg } default: { - Log(Debug::Info) << "Unhandled texture stage " << i << " in " << mFilename; + Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename; continue; } } @@ -1452,7 +1452,8 @@ namespace NifOsg const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i]; if(tex.texture.empty() && texprop->controller.empty()) { - Log(Debug::Verbose) << "Texture layer " << i << " is in use but empty in " << mFilename; + if (i == 0) + Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName << "\" in " << mFilename; continue; } @@ -1640,7 +1641,7 @@ namespace NifOsg { const Nif::NiTexturingProperty* texprop = static_cast(property); osg::StateSet* stateset = node->getOrCreateStateSet(); - handleTextureProperty(texprop, stateset, composite, imageManager, boundTextures, animflags); + handleTextureProperty(texprop, node->getName(), stateset, composite, imageManager, boundTextures, animflags); break; } // unused by mw From dfbe0021a5ab4717058ed86721e45a13f5d13a88 Mon Sep 17 00:00:00 2001 From: Assumeru Date: Wed, 18 Dec 2019 17:37:45 +0100 Subject: [PATCH 24/30] Change rescaling to be more inline with vanilla (fixes #5214) (#2635) * move rescaling to loadData * clamp on save --- apps/openmw/mwworld/scene.cpp | 22 ++++++---------------- apps/openmw/mwworld/scene.hpp | 2 +- components/esm/cellref.cpp | 11 ++++++++++- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index c558dd4d2..0d1b98ebb 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -204,12 +204,11 @@ namespace struct InsertVisitor { MWWorld::CellStore& mCell; - bool mRescale; Loading::Listener& mLoadingListener; std::vector mToInsert; - InsertVisitor (MWWorld::CellStore& cell, bool rescale, Loading::Listener& loadingListener); + InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener); bool operator() (const MWWorld::Ptr& ptr); @@ -217,8 +216,8 @@ namespace void insert(AddObject&& addObject); }; - InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, bool rescale, Loading::Listener& loadingListener) - : mCell (cell), mRescale (rescale), mLoadingListener (loadingListener) + InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener) + : mCell (cell), mLoadingListener (loadingListener) {} bool InsertVisitor::operator() (const MWWorld::Ptr& ptr) @@ -234,14 +233,6 @@ namespace { for (MWWorld::Ptr& ptr : mToInsert) { - if (mRescale) - { - if (ptr.getCellRef().getScale()<0.5) - ptr.getCellRef().setScale(0.5); - else if (ptr.getCellRef().getScale()>2) - ptr.getCellRef().setScale(2); - } - if (!ptr.getRefData().isDeleted() && ptr.getRefData().isEnabled()) { try @@ -427,8 +418,7 @@ namespace MWWorld cell->respawn(); // ... then references. This is important for adjustPosition to work correctly. - /// \todo rescale depending on the state of a new GMST - insertCell (*cell, true, loadingListener); + insertCell (*cell, loadingListener); mRendering.addCell(cell); MWBase::Environment::get().getWindowManager()->addCell(cell); @@ -769,9 +759,9 @@ namespace MWWorld mCellChanged = false; } - void Scene::insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener) + void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener) { - InsertVisitor insertVisitor (cell, rescale, *loadingListener); + InsertVisitor insertVisitor (cell, *loadingListener); cell.forEach (insertVisitor); insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering); }); insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); }); diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 056c3acb2..57f994fab 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -85,7 +85,7 @@ namespace MWWorld osg::Vec3f mLastPlayerPos; - void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener); + void insertCell (CellStore &cell, Loading::Listener* loadingListener); // Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center void changeCellGrid (int playerCellX, int playerCellY, bool changeEvent = true); diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index 4b9c6b073..c6adfbd4d 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -67,6 +67,10 @@ void ESM::CellRef::loadData(ESMReader &esm, bool &isDeleted) break; case ESM::FourCC<'X','S','C','L'>::value: esm.getHT(mScale); + if (mScale < 0.5) + mScale = 0.5; + else if (mScale > 2) + mScale = 2; break; case ESM::FourCC<'A','N','A','M'>::value: mOwner = esm.getHString(); @@ -141,7 +145,12 @@ void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory, bool } if (mScale != 1.0) { - esm.writeHNT("XSCL", mScale); + float scale = mScale; + if (scale < 0.5) + scale = 0.5; + else if (scale > 2) + scale = 2; + esm.writeHNT("XSCL", scale); } esm.writeHNOCString("ANAM", mOwner); From 737aa1e4e8886e5def0664888398e61a40a257fd Mon Sep 17 00:00:00 2001 From: Assumeru Date: Wed, 18 Dec 2019 18:42:54 +0100 Subject: [PATCH 25/30] Remove FactionID editing from OpenCS (#2636) * Remove FactionID editing * remove useless comments * rename FactionID to Unknown --- apps/esmtool/record.cpp | 9 ---- apps/opencs/model/world/columns.cpp | 4 -- apps/opencs/model/world/columns.hpp | 3 -- apps/opencs/model/world/refidadapterimp.cpp | 58 ++++++++++----------- apps/opencs/model/world/refidcollection.cpp | 2 - components/esm/loadnpc.cpp | 4 +- components/esm/loadnpc.hpp | 4 +- 7 files changed, 31 insertions(+), 53 deletions(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index e8f444489..5ffe76c4a 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1032,14 +1032,6 @@ void Record::print() std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl; std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl; std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; - //Why do we want to print these fields? They are padding in the struct and contain - // nothing of real value. Now we don't deal with NPDTstruct12 in runtime either... - //std::cout << " Unknown1: " - // << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; - //std::cout << " Unknown2: " - // << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; - //std::cout << " Unknown3: " - // << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; } else { @@ -1047,7 +1039,6 @@ void Record::print() std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl; std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl; std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; - std::cout << " FactionID: " << (int)mData.mNpdt.mFactionID << std::endl; std::cout << " Attributes:" << std::endl; std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl; diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 5dda78919..e2c3be789 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -236,7 +236,6 @@ namespace CSMWorld { ColumnId_FactionReactions, "Reactions" }, { ColumnId_FactionRanks, "Ranks" }, - //{ ColumnId_FactionID, "Faction ID" }, { ColumnId_FactionReaction, "Reaction" }, { ColumnId_FactionAttrib1, "Attrib 1" }, @@ -248,7 +247,6 @@ namespace CSMWorld { ColumnId_EffectList, "Effects" }, { ColumnId_EffectId, "Effect" }, - //{ ColumnId_EffectAttribute, "Attrib" }, { ColumnId_EffectRange, "Range" }, { ColumnId_EffectArea, "Area" }, @@ -257,7 +255,6 @@ namespace CSMWorld { ColumnId_AiWanderDist, "Wander Dist" }, { ColumnId_AiDuration, "Ai Duration" }, { ColumnId_AiWanderToD, "Wander ToD" }, - //{ ColumnId_AiWanderIdle, "Wander Idle" }, { ColumnId_AiWanderRepeat, "Wander Repeat" }, { ColumnId_AiActivateName, "Activate" }, { ColumnId_AiTargetId, "Target ID" }, @@ -291,7 +288,6 @@ namespace CSMWorld { ColumnId_UChar, "Value [0..255]" }, { ColumnId_NpcMisc, "NPC Misc" }, { ColumnId_Level, "Level" }, - { ColumnId_NpcFactionID, "Faction ID" }, { ColumnId_GenderNpc, "Gender"}, { ColumnId_Mana, "Mana" }, { ColumnId_Fatigue, "Fatigue" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 3430a4837..085e6e178 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -225,12 +225,10 @@ namespace CSMWorld ColumnId_SoundChance = 210, ColumnId_FactionReactions = 211, - //ColumnId_FactionID = 212, ColumnId_FactionReaction = 213, ColumnId_EffectList = 214, ColumnId_EffectId = 215, - //ColumnId_EffectAttribute = 216, ColumnId_EffectRange = 217, ColumnId_EffectArea = 218, @@ -275,7 +273,6 @@ namespace CSMWorld ColumnId_UChar = 250, ColumnId_NpcMisc = 251, ColumnId_Level = 252, - ColumnId_NpcFactionID = 253, ColumnId_GenderNpc = 254, ColumnId_Mana = 255, ColumnId_Fatigue = 256, diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 3c9faa211..d85fcc068 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1096,27 +1096,25 @@ QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column case 1: return QVariant(QVariant::UserType); case 2: return QVariant(QVariant::UserType); case 3: return QVariant(QVariant::UserType); - case 4: return QVariant(QVariant::UserType); - case 5: return static_cast(record.get().mNpdt.mDisposition); - case 6: return static_cast(record.get().mNpdt.mReputation); - case 7: return static_cast(record.get().mNpdt.mRank); - case 8: return record.get().mNpdt.mGold; - case 9: return record.get().mPersistent == true; + case 4: return static_cast(record.get().mNpdt.mDisposition); + case 5: return static_cast(record.get().mNpdt.mReputation); + case 6: return static_cast(record.get().mNpdt.mRank); + case 7: return record.get().mNpdt.mGold; + case 8: return record.get().mPersistent == true; default: return QVariant(); // throw an exception here? } else switch (subColIndex) { case 0: return static_cast(record.get().mNpdt.mLevel); - case 1: return static_cast(record.get().mNpdt.mFactionID); - case 2: return static_cast(record.get().mNpdt.mHealth); - case 3: return static_cast(record.get().mNpdt.mMana); - case 4: return static_cast(record.get().mNpdt.mFatigue); - case 5: return static_cast(record.get().mNpdt.mDisposition); - case 6: return static_cast(record.get().mNpdt.mReputation); - case 7: return static_cast(record.get().mNpdt.mRank); - case 8: return record.get().mNpdt.mGold; - case 9: return record.get().mPersistent == true; + case 1: return static_cast(record.get().mNpdt.mHealth); + case 2: return static_cast(record.get().mNpdt.mMana); + case 3: return static_cast(record.get().mNpdt.mFatigue); + case 4: return static_cast(record.get().mNpdt.mDisposition); + case 5: return static_cast(record.get().mNpdt.mReputation); + case 6: return static_cast(record.get().mNpdt.mRank); + case 7: return record.get().mNpdt.mGold; + case 8: return record.get().mPersistent == true; default: return QVariant(); // throw an exception here? } } @@ -1137,27 +1135,25 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column, case 1: return; case 2: return; case 3: return; - case 4: return; - case 5: npc.mNpdt.mDisposition = static_cast(value.toInt()); break; - case 6: npc.mNpdt.mReputation = static_cast(value.toInt()); break; - case 7: npc.mNpdt.mRank = static_cast(value.toInt()); break; - case 8: npc.mNpdt.mGold = value.toInt(); break; - case 9: npc.mPersistent = value.toBool(); break; + case 4: npc.mNpdt.mDisposition = static_cast(value.toInt()); break; + case 5: npc.mNpdt.mReputation = static_cast(value.toInt()); break; + case 6: npc.mNpdt.mRank = static_cast(value.toInt()); break; + case 7: npc.mNpdt.mGold = value.toInt(); break; + case 8: npc.mPersistent = value.toBool(); break; default: return; // throw an exception here? } else switch(subColIndex) { case 0: npc.mNpdt.mLevel = static_cast(value.toInt()); break; - case 1: npc.mNpdt.mFactionID = static_cast(value.toInt()); break; - case 2: npc.mNpdt.mHealth = static_cast(value.toInt()); break; - case 3: npc.mNpdt.mMana = static_cast(value.toInt()); break; - case 4: npc.mNpdt.mFatigue = static_cast(value.toInt()); break; - case 5: npc.mNpdt.mDisposition = static_cast(value.toInt()); break; - case 6: npc.mNpdt.mReputation = static_cast(value.toInt()); break; - case 7: npc.mNpdt.mRank = static_cast(value.toInt()); break; - case 8: npc.mNpdt.mGold = value.toInt(); break; - case 9: npc.mPersistent = value.toBool(); break; + case 1: npc.mNpdt.mHealth = static_cast(value.toInt()); break; + case 2: npc.mNpdt.mMana = static_cast(value.toInt()); break; + case 3: npc.mNpdt.mFatigue = static_cast(value.toInt()); break; + case 4: npc.mNpdt.mDisposition = static_cast(value.toInt()); break; + case 5: npc.mNpdt.mReputation = static_cast(value.toInt()); break; + case 6: npc.mNpdt.mRank = static_cast(value.toInt()); break; + case 7: npc.mNpdt.mGold = value.toInt(); break; + case 8: npc.mPersistent = value.toBool(); break; default: return; // throw an exception here? } @@ -1166,7 +1162,7 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column, int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { - return 10; // Level, FactionID, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist + return 9; // Level, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist } int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 19d2900da..ff146bb91 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -535,8 +535,6 @@ CSMWorld::RefIdCollection::RefIdCollection() mNestedAdapters.push_back (std::make_pair(&mColumns.back(), miscMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_NpcFactionID, CSMWorld::ColumnBase::Display_SignedInteger8)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_UnsignedInteger16)); mColumns.back().addColumn( diff --git a/components/esm/loadnpc.cpp b/components/esm/loadnpc.cpp index b68aa6375..2bb0811ac 100644 --- a/components/esm/loadnpc.cpp +++ b/components/esm/loadnpc.cpp @@ -216,9 +216,9 @@ namespace ESM mNpdt.mReputation = 0; mNpdt.mHealth = mNpdt.mMana = mNpdt.mFatigue = 0; mNpdt.mDisposition = 0; - mNpdt.mFactionID = 0; + mNpdt.mUnknown1 = 0; mNpdt.mRank = 0; - mNpdt.mUnknown = 0; + mNpdt.mUnknown2 = 0; mNpdt.mGold = 0; } diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index ac3f1a343..687afeaf6 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -87,10 +87,10 @@ struct NPC // mSkill can grow up to 200, it must be unsigned unsigned char mSkills[Skill::Length]; - char mFactionID; + char mUnknown1; unsigned short mHealth, mMana, mFatigue; unsigned char mDisposition, mReputation, mRank; - char mUnknown; + char mUnknown2; int mGold; }; // 52 bytes From 5220177ebca03cb7d90c9b95d6f477010b8bbf1f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 19 Dec 2019 15:21:49 +0400 Subject: [PATCH 26/30] Fix ESMTool build --- apps/esmtool/record.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 5ffe76c4a..b7cbd8f65 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -1058,7 +1058,6 @@ void Record::print() std::cout << " Health: " << mData.mNpdt.mHealth << std::endl; std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl; std::cout << " Fatigue: " << mData.mNpdt.mFatigue << std::endl; - std::cout << " Unknown: " << (int)mData.mNpdt.mUnknown << std::endl; std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; } From e44021b369fd868c5a5461155a43de89b07d2e78 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 28 Nov 2019 08:34:18 +0400 Subject: [PATCH 27/30] Fix most of deprecated API usage in the editor --- apps/opencs/view/doc/newgame.cpp | 8 ++++++++ apps/opencs/view/doc/startup.cpp | 9 +++++++++ apps/opencs/view/prefs/dialogue.cpp | 18 +++++++++++++++++- apps/opencs/view/widget/coloreditor.cpp | 8 ++++++++ apps/opencs/view/world/enumdelegate.cpp | 5 +++++ apps/opencs/view/world/scriptedit.cpp | 9 +++++++++ 6 files changed, 56 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp index b3e2a4f63..8e976c68f 100644 --- a/apps/opencs/view/doc/newgame.cpp +++ b/apps/opencs/view/doc/newgame.cpp @@ -6,6 +6,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#endif + #include "filewidget.hpp" #include "adjusterwidget.hpp" @@ -46,7 +50,11 @@ CSVDoc::NewGameDialogue::NewGameDialogue() connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), mAdjusterWidget, SLOT (setName (const QString&, bool))); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + QRect scr = QGuiApplication::primaryScreen()->geometry(); +#else QRect scr = QApplication::desktop()->screenGeometry(); +#endif QRect rect = geometry(); move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); } diff --git a/apps/opencs/view/doc/startup.cpp b/apps/opencs/view/doc/startup.cpp index 78f18b3a1..beb2cf7d8 100644 --- a/apps/opencs/view/doc/startup.cpp +++ b/apps/opencs/view/doc/startup.cpp @@ -10,6 +10,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#endif + QPushButton *CSVDoc::StartupDialogue::addButton (const QString& label, const QIcon& icon) { int column = mColumn--; @@ -119,7 +123,12 @@ CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2) setLayout (layout); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + QRect scr = QGuiApplication::primaryScreen()->geometry(); +#else QRect scr = QApplication::desktop()->screenGeometry(); +#endif + QRect rect = geometry(); move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); } diff --git a/apps/opencs/view/prefs/dialogue.cpp b/apps/opencs/view/prefs/dialogue.cpp index 0d32ebd0a..853031ccd 100644 --- a/apps/opencs/view/prefs/dialogue.cpp +++ b/apps/opencs/view/prefs/dialogue.cpp @@ -8,6 +8,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#endif + #include #include "../../model/prefs/state.hpp" @@ -34,7 +38,12 @@ void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main) ++iter) { QString label = QString::fromUtf8 (iter->second.getKey().c_str()); + +#if QT_VERSION >= QT_VERSION_CHECK(5,11,0) + maxWidth = std::max (maxWidth, metrics.horizontalAdvance (label)); +#else maxWidth = std::max (maxWidth, metrics.width (label)); +#endif list->addItem (label); } @@ -107,8 +116,15 @@ void CSVPrefs::Dialogue::show() } else { +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + QRect scr = QGuiApplication::primaryScreen()->geometry(); +#else + QRect scr = QApplication::desktop()->screenGeometry(); +#endif + // otherwise place at the centre of the screen - QPoint screenCenter = QApplication::desktop()->screenGeometry().center(); + QPoint screenCenter = scr.center(); + move (screenCenter - QPoint(frameGeometry().width()/2, frameGeometry().height()/2)); } diff --git a/apps/opencs/view/widget/coloreditor.cpp b/apps/opencs/view/widget/coloreditor.cpp index e30696458..cd19e54a3 100644 --- a/apps/opencs/view/widget/coloreditor.cpp +++ b/apps/opencs/view/widget/coloreditor.cpp @@ -6,6 +6,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#endif + #include "colorpickerpopup.hpp" CSVWidget::ColorEditor::ColorEditor(const QColor &color, QWidget *parent, const bool popupOnStart) @@ -95,7 +99,11 @@ QPoint CSVWidget::ColorEditor::calculatePopupPosition() { QRect editorGeometry = geometry(); QRect popupGeometry = mColorPicker->geometry(); +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + QRect screenGeometry = QGuiApplication::primaryScreen()->geometry(); +#else QRect screenGeometry = QApplication::desktop()->screenGeometry(); +#endif // Center the popup horizontally relative to the editor int localPopupX = (editorGeometry.width() - popupGeometry.width()) / 2; diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index dd4405a92..0f920db94 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -134,7 +134,12 @@ QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem &option, const itemOption.state = option.state; const QString &valueText = mValues.at(valueIndex).second; + +#if QT_VERSION >= QT_VERSION_CHECK(5,11,0) + QSize valueSize = QSize(itemOption.fontMetrics.horizontalAdvance(valueText), itemOption.fontMetrics.height()); +#else QSize valueSize = QSize(itemOption.fontMetrics.width(valueText), itemOption.fontMetrics.height()); +#endif itemOption.currentText = valueText; return QApplication::style()->sizeFromContents(QStyle::CT_ComboBox, &itemOption, valueSize); diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 1105404b3..996e80da4 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -205,7 +205,12 @@ bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const void CSVWorld::ScriptEdit::setTabWidth() { // Set tab width to specified number of characters using current font. +#if QT_VERSION >= QT_VERSION_CHECK(5,11,0) + setTabStopDistance(mTabCharCount * fontMetrics().horizontalAdvance(' ')); +#else setTabStopWidth(mTabCharCount * fontMetrics().width(' ')); +#endif + } void CSVWorld::ScriptEdit::wrapLines(bool wrap) @@ -285,7 +290,11 @@ int CSVWorld::ScriptEdit::lineNumberAreaWidth() ++digits; } +#if QT_VERSION >= QT_VERSION_CHECK(5,11,0) + int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits; +#else int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; +#endif return space; } From 47a13f1ed2d97d4bb2bc8082ffb64e5daa0c7f8a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 28 Nov 2019 09:48:59 +0400 Subject: [PATCH 28/30] Do not use deprecated Qt API in the launcher --- apps/launcher/graphicspage.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 4ba164698..6bc22bad6 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -5,6 +5,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#endif + #ifdef MAC_OS_X_VERSION_MIN_REQUIRED #undef MAC_OS_X_VERSION_MIN_REQUIRED // We need to do this because of Qt: https://bugreports.qt-project.org/browse/QTBUG-22154 @@ -311,6 +315,17 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen) QRect Launcher::GraphicsPage::getMaximumResolution() { QRect max; + +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + for (QScreen* screen : QGuiApplication::screens()) + { + QRect res = screen->geometry(); + if (res.width() > max.width()) + max.setWidth(res.width()); + if (res.height() > max.height()) + max.setHeight(res.height()); + } +#else int screens = QApplication::desktop()->screenCount(); for (int i = 0; i < screens; ++i) { @@ -320,6 +335,7 @@ QRect Launcher::GraphicsPage::getMaximumResolution() if (res.height() > max.height()) max.setHeight(res.height()); } +#endif return max; } From 78450312bfe0ae2f94ea3bc69b355c9023a056a1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 20 Dec 2019 13:36:32 +0400 Subject: [PATCH 29/30] Fix the last warning about deprecated Qt functions --- apps/opencs/view/doc/view.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 529f21165..9c0e33080 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -15,6 +15,10 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include +#endif + #include "../../model/doc/document.hpp" #include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcut.hpp" @@ -1050,7 +1054,7 @@ void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth) if (isGrowLimit) rect = dw->screenGeometry(this); else - rect = dw->screenGeometry(dw->screen(dw->screenNumber(this))); + rect = QGuiApplication::screens().at(dw->screenNumber(this))->geometry(); if (!mScrollbarOnly && mScroll && mSubViews.size() > 1) { From e1958b671ec3af70cec3d3f74bc976cfe3046bfb Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 20 Dec 2019 14:16:39 +0400 Subject: [PATCH 30/30] Make dtMeshTile POD --- extern/recastnavigation/Detour/Include/DetourNavMesh.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/extern/recastnavigation/Detour/Include/DetourNavMesh.h b/extern/recastnavigation/Detour/Include/DetourNavMesh.h index 98293c49d..0bf59ab06 100644 --- a/extern/recastnavigation/Detour/Include/DetourNavMesh.h +++ b/extern/recastnavigation/Detour/Include/DetourNavMesh.h @@ -306,9 +306,6 @@ struct dtMeshTile int dataSize; ///< Size of the tile data. int flags; ///< Tile flags. (See: #dtTileFlags) dtMeshTile* next; ///< The next free tile, or the next tile in the spatial grid. -private: - dtMeshTile(const dtMeshTile&); - dtMeshTile& operator=(const dtMeshTile&); }; /// Get flags for edge in detail triangle.