From b84e41bd278c7b55755d93ae615f4b6b75f07141 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 22 Aug 2021 15:33:40 +0300 Subject: [PATCH 1/8] Avoid storing ref, dynamic cast worldspacewidget for safety --- apps/opencs/view/render/commands.cpp | 29 ++++++++++++++++--- apps/opencs/view/render/commands.hpp | 8 +++-- apps/opencs/view/render/terrainshapemode.cpp | 13 ++++++--- apps/opencs/view/render/terrainshapemode.hpp | 4 ++- .../opencs/view/render/terraintexturemode.cpp | 5 ++++ .../opencs/view/render/terraintexturemode.hpp | 4 ++- apps/opencs/view/render/worldspacewidget.hpp | 2 ++ 7 files changed, 53 insertions(+), 12 deletions(-) diff --git a/apps/opencs/view/render/commands.cpp b/apps/opencs/view/render/commands.cpp index 7b3760296..7afbd024a 100644 --- a/apps/opencs/view/render/commands.cpp +++ b/apps/opencs/view/render/commands.cpp @@ -1,19 +1,40 @@ #include "commands.hpp" +#include #include +#include "editmode.hpp" #include "terrainselection.hpp" +#include "terrainshapemode.hpp" +#include "terraintexturemode.hpp" +#include "worldspacewidget.hpp" -CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent) - : mTerrainSelection(terrainSelection) +CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent) + : mWorldspaceWidget(worldspaceWidget) { } void CSVRender::DrawTerrainSelectionCommand::redo() { - mTerrainSelection.update(); + if (CSVRender::WorldspaceWidget* worldspaceWidget = dynamic_cast (mWorldspaceWidget)) + { + if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (worldspaceWidget->getEditMode()) ) + { + terrainMode->getTerrainSelection()->update(); + return; + } + } + Log(Debug::Warning) << "Error in redoing terrain selection"; } void CSVRender::DrawTerrainSelectionCommand::undo() { - mTerrainSelection.update(); + if (CSVRender::WorldspaceWidget* worldspaceWidget = dynamic_cast (mWorldspaceWidget)) + { + if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (worldspaceWidget->getEditMode()) ) + { + terrainMode->getTerrainSelection()->update(); + return; + } + } + Log(Debug::Warning) << "Error in undoing terrain selection"; } diff --git a/apps/opencs/view/render/commands.hpp b/apps/opencs/view/render/commands.hpp index cdc389e33..6845785ec 100644 --- a/apps/opencs/view/render/commands.hpp +++ b/apps/opencs/view/render/commands.hpp @@ -3,6 +3,8 @@ #include +#include "worldspacewidget.hpp" + namespace CSVRender { class TerrainSelection; @@ -21,11 +23,13 @@ namespace CSVRender */ class DrawTerrainSelectionCommand : public QUndoCommand { + friend class WorldspaceWidget; + private: - TerrainSelection& mTerrainSelection; + WorldspaceWidget *mWorldspaceWidget; public: - DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent = nullptr); + DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent = nullptr); void redo() override; void undo() override; diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index 866ff69cd..050494495 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -287,7 +287,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() undoStack.beginMacro ("Edit shape and normal records"); // One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes. - undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection)); + undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget())); for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) { @@ -358,7 +358,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId); } // One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes. - undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection)); + undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget())); undoStack.endMacro(); clearTransientEdits(); @@ -1049,7 +1049,7 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob */ if (xIsAtCellBorder && yIsAtCellBorder) { - /* + /* Handle the NW, NE, and SE corner vertices. NW corner: (+1, -1) offset to reach current cell. NE corner: (-1, -1) offset to reach current cell. @@ -1132,7 +1132,7 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& selectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString(); else selectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString(); - + if (selectAction == "Select only") mTerrainShapeSelection->onlySelect(selections); else if (selectAction == "Add to selection") @@ -1444,6 +1444,11 @@ void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event) mBrushDraw->hide(); } +std::shared_ptr CSVRender::TerrainShapeMode::getTerrainSelection() +{ + return mTerrainShapeSelection; +} + void CSVRender::TerrainShapeMode::setBrushSize(int brushSize) { mBrushSize = brushSize; diff --git a/apps/opencs/view/render/terrainshapemode.hpp b/apps/opencs/view/render/terrainshapemode.hpp index a88e60c9c..abc4b8aba 100644 --- a/apps/opencs/view/render/terrainshapemode.hpp +++ b/apps/opencs/view/render/terrainshapemode.hpp @@ -92,6 +92,8 @@ namespace CSVRender void dragMoveEvent (QDragMoveEvent *event) override; void mouseMoveEvent (QMouseEvent *event) override; + std::shared_ptr getTerrainSelection(); + private: /// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse @@ -176,7 +178,7 @@ namespace CSVRender int mDragMode = InteractionType_None; osg::Group* mParentNode; bool mIsEditing = false; - std::unique_ptr mTerrainShapeSelection; + std::shared_ptr mTerrainShapeSelection; int mTotalDiffY = 0; std::vector mAlteredCells; osg::Vec3d mEditingPos; diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index 4e267e942..dfcc29ae0 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -712,6 +712,11 @@ void CSVRender::TerrainTextureMode::mouseMoveEvent (QMouseEvent *event) mBrushDraw->hide(); } +std::shared_ptr CSVRender::TerrainTextureMode::getTerrainSelection() +{ + return mTerrainTextureSelection; +} + void CSVRender::TerrainTextureMode::setBrushSize(int brushSize) { diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index 31932df21..e0c6e4b40 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -85,6 +85,8 @@ namespace CSVRender void mouseMoveEvent (QMouseEvent *event) override; + std::shared_ptr getTerrainSelection(); + private: /// \brief Handle brush mechanics, maths regarding worldspace hit etc. void editTerrainTextureGrid (const WorldspaceHitResult& hit); @@ -115,7 +117,7 @@ namespace CSVRender int mDragMode; osg::Group* mParentNode; bool mIsEditing; - std::unique_ptr mTerrainTextureSelection; + std::shared_ptr mTerrainTextureSelection; const int cellSize {ESM::Land::REAL_SIZE}; const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 5e224b380..d73a6c06e 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -49,6 +49,8 @@ namespace CSVRender { Q_OBJECT + friend class DrawTerrainSelectionCommand; + CSVWidget::SceneToolToggle2 *mSceneElements; CSVWidget::SceneToolRun *mRun; CSMDoc::Document& mDocument; From d62ddc002efd3304a134a9cfefebb4d125da5431 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 22 Aug 2021 19:04:16 +0300 Subject: [PATCH 2/8] Use QPointer to detect object existence, less verbose debug messages --- apps/opencs/view/render/commands.cpp | 42 ++++++++++++++++++---------- apps/opencs/view/render/commands.hpp | 5 ++-- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/apps/opencs/view/render/commands.cpp b/apps/opencs/view/render/commands.cpp index 7afbd024a..b9b7b12f7 100644 --- a/apps/opencs/view/render/commands.cpp +++ b/apps/opencs/view/render/commands.cpp @@ -1,5 +1,7 @@ #include "commands.hpp" +#include + #include #include @@ -15,26 +17,38 @@ CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWi void CSVRender::DrawTerrainSelectionCommand::redo() { - if (CSVRender::WorldspaceWidget* worldspaceWidget = dynamic_cast (mWorldspaceWidget)) + if (mWorldspaceWidget) { - if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (worldspaceWidget->getEditMode()) ) - { - terrainMode->getTerrainSelection()->update(); - return; - } + if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (mWorldspaceWidget->getEditMode()) ) + { + terrainMode->getTerrainSelection()->update(); + return; + } + else + { + Log(Debug::Verbose) << "Can't update terrain selection in current EditMode"; + return; + } } - Log(Debug::Warning) << "Error in redoing terrain selection"; + else + Log(Debug::Verbose) << "Can't update terrain selection, no WorldspaceWidget found!"; } void CSVRender::DrawTerrainSelectionCommand::undo() { - if (CSVRender::WorldspaceWidget* worldspaceWidget = dynamic_cast (mWorldspaceWidget)) + if (mWorldspaceWidget) { - if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (worldspaceWidget->getEditMode()) ) - { - terrainMode->getTerrainSelection()->update(); - return; - } + if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (mWorldspaceWidget->getEditMode()) ) + { + terrainMode->getTerrainSelection()->update(); + return; + } + else + { + Log(Debug::Verbose) << "Can't undo terrain selection in current EditMode"; + return; + } } - Log(Debug::Warning) << "Error in undoing terrain selection"; + else + Log(Debug::Verbose) << "Can't undo terrain selection, no WorldspaceWidget found!"; } diff --git a/apps/opencs/view/render/commands.hpp b/apps/opencs/view/render/commands.hpp index 6845785ec..9698010a9 100644 --- a/apps/opencs/view/render/commands.hpp +++ b/apps/opencs/view/render/commands.hpp @@ -1,6 +1,8 @@ #ifndef CSV_RENDER_COMMANDS_HPP #define CSV_RENDER_COMMANDS_HPP +#include + #include #include "worldspacewidget.hpp" @@ -23,10 +25,9 @@ namespace CSVRender */ class DrawTerrainSelectionCommand : public QUndoCommand { - friend class WorldspaceWidget; private: - WorldspaceWidget *mWorldspaceWidget; + QPointer mWorldspaceWidget; public: DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent = nullptr); From cb42b5287d22d47382fdedbae3e217c53cfecead Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 22 Aug 2021 19:14:51 +0300 Subject: [PATCH 3/8] Remove friend, make getEditMode public to allow editmode testing. --- apps/opencs/view/render/worldspacewidget.cpp | 10 +++++----- apps/opencs/view/render/worldspacewidget.hpp | 6 ++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 723ffcb6a..2ebc083f2 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -452,6 +452,11 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo return hit; } +CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() +{ + return dynamic_cast (mEditMode->getCurrent()); +} + void CSVRender::WorldspaceWidget::abortDrag() { if (mDragging) @@ -697,11 +702,6 @@ void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitRes editMode.primaryOpenPressed (hit); } -CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() -{ - return dynamic_cast (mEditMode->getCurrent()); -} - void CSVRender::WorldspaceWidget::primaryOpen(bool activate) { handleInteraction(InteractionType_PrimaryOpen, activate); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index d73a6c06e..cf244ce71 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -49,8 +49,6 @@ namespace CSVRender { Q_OBJECT - friend class DrawTerrainSelectionCommand; - CSVWidget::SceneToolToggle2 *mSceneElements; CSVWidget::SceneToolRun *mRun; CSMDoc::Document& mDocument; @@ -191,6 +189,8 @@ namespace CSVRender /// Erase all overrides and restore the visual representation to its true state. virtual void reset (unsigned int elementMask) = 0; + EditMode *getEditMode(); + protected: /// Visual elements in a scene @@ -217,8 +217,6 @@ namespace CSVRender void settingChanged (const CSMPrefs::Setting *setting) override; - EditMode *getEditMode(); - bool getSpeedMode(); private: From 4b14818035cef49bd3049d14d53ec6b42e17b56d Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 22 Aug 2021 20:09:21 +0300 Subject: [PATCH 4/8] Restucture code --- apps/opencs/view/render/commands.cpp | 46 +++++++++++----------------- apps/opencs/view/render/commands.hpp | 2 ++ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/apps/opencs/view/render/commands.cpp b/apps/opencs/view/render/commands.cpp index b9b7b12f7..99d8a0da6 100644 --- a/apps/opencs/view/render/commands.cpp +++ b/apps/opencs/view/render/commands.cpp @@ -17,38 +17,28 @@ CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWi void CSVRender::DrawTerrainSelectionCommand::redo() { - if (mWorldspaceWidget) - { - if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (mWorldspaceWidget->getEditMode()) ) - { - terrainMode->getTerrainSelection()->update(); - return; - } - else - { - Log(Debug::Verbose) << "Can't update terrain selection in current EditMode"; - return; - } - } - else - Log(Debug::Verbose) << "Can't update terrain selection, no WorldspaceWidget found!"; + tryUpdate(); } void CSVRender::DrawTerrainSelectionCommand::undo() { - if (mWorldspaceWidget) + tryUpdate(); +} + +void CSVRender::DrawTerrainSelectionCommand::tryUpdate() +{ + if (!mWorldspaceWidget) { - if (CSVRender::TerrainShapeMode* terrainMode = dynamic_cast (mWorldspaceWidget->getEditMode()) ) - { - terrainMode->getTerrainSelection()->update(); - return; - } - else - { - Log(Debug::Verbose) << "Can't undo terrain selection in current EditMode"; - return; - } - } - else Log(Debug::Verbose) << "Can't undo terrain selection, no WorldspaceWidget found!"; + return; + } + + auto terrainMode = dynamic_cast(mWorldspaceWidget->getEditMode()); + if (!terrainMode) + { + Log(Debug::Verbose) << "Can't undo terrain selection in current EditMode"; + return; + } + + terrainMode->getTerrainSelection()->update(); } diff --git a/apps/opencs/view/render/commands.hpp b/apps/opencs/view/render/commands.hpp index 9698010a9..62b7fbfdc 100644 --- a/apps/opencs/view/render/commands.hpp +++ b/apps/opencs/view/render/commands.hpp @@ -34,6 +34,8 @@ namespace CSVRender void redo() override; void undo() override; + + void tryUpdate(); }; } From 08f7c73e02c49850f75cf576d3d432a327ccec71 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 22 Aug 2021 20:11:02 +0300 Subject: [PATCH 5/8] Fix text --- apps/opencs/view/render/commands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/commands.cpp b/apps/opencs/view/render/commands.cpp index 99d8a0da6..699bf5d01 100644 --- a/apps/opencs/view/render/commands.cpp +++ b/apps/opencs/view/render/commands.cpp @@ -29,14 +29,14 @@ void CSVRender::DrawTerrainSelectionCommand::tryUpdate() { if (!mWorldspaceWidget) { - Log(Debug::Verbose) << "Can't undo terrain selection, no WorldspaceWidget found!"; + Log(Debug::Verbose) << "Can't update terrain selection, no WorldspaceWidget found!"; return; } auto terrainMode = dynamic_cast(mWorldspaceWidget->getEditMode()); if (!terrainMode) { - Log(Debug::Verbose) << "Can't undo terrain selection in current EditMode"; + Log(Debug::Verbose) << "Can't update terrain selection in current EditMode"; return; } From ad703d747034465c3f1f959a0bc8366dff09506c Mon Sep 17 00:00:00 2001 From: psi29a Date: Wed, 8 Sep 2021 09:55:42 +0000 Subject: [PATCH 6/8] Merge branch 'fix_pathgrid_path' into 'master' Use pathgrid path when destination is closer to different graph component node See merge request OpenMW/openmw!1155 (cherry picked from commit 4bf22f3ca0e5e5776c09cb8d5ad9793986373975) 9112c65a Use pathgrid path when destination is closer to different graph component node --- apps/openmw/mwmechanics/pathfinding.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 2f8e83043..0e704cd46 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -206,9 +206,6 @@ namespace MWMechanics endPointInLocalCoords, startNode); - if (!endNode.second) - return; - // if it's shorter for actor to travel from start to end, than to travel from either // start or end to nearest pathgrid point, just travel from start to end. float startToEndLength2 = (endPointInLocalCoords - startPointInLocalCoords).length2(); @@ -279,7 +276,8 @@ namespace MWMechanics // unreachable pathgrid point. // // The AI routines will have to deal with such situations. - *out++ = endPoint; + if (endNode.second) + *out++ = endPoint; } float PathFinder::getZAngleToNext(float x, float y) const From 56869ec296b73666aa52af607b664bd358b166f0 Mon Sep 17 00:00:00 2001 From: elsid Date: Wed, 22 Sep 2021 22:12:22 +0000 Subject: [PATCH 7/8] Merge branch 'fix_6296' into 'master' Ignore time to destination when giving way (#6296) See merge request OpenMW/openmw!1234 (cherry picked from commit 14516b9fd603bf603ca2ae366bc0884106fd368c) 5893b884 Ignore time to destination when giving way (#6296) --- apps/openmw/mwmechanics/actors.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 87f462d6f..c9fa3309d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1810,6 +1810,7 @@ namespace MWMechanics // Standing NPCs give way to moving ones if they are not in combat (or pursue) mode and either // follow player or have a AIWander package with non-empty wander area. bool shouldAvoidCollision = isMoving; + bool shouldGiveWay = false; bool shouldTurnToApproachingActor = !isMoving; MWWorld::Ptr currentTarget; // Combat or pursue target (NPCs should not avoid collision with their targets). const auto& aiSequence = ptr.getClass().getCreatureStats(ptr).getAiSequence(); @@ -1820,7 +1821,7 @@ namespace MWMechanics else if (package->getTypeId() == AiPackageTypeId::Wander && giveWayWhenIdle) { if (!static_cast(package.get())->isStationary()) - shouldAvoidCollision = true; + shouldGiveWay = true; } else if (package->getTypeId() == AiPackageTypeId::Combat || package->getTypeId() == AiPackageTypeId::Pursue) { @@ -1830,7 +1831,7 @@ namespace MWMechanics break; } } - if (!shouldAvoidCollision) + if (!shouldAvoidCollision && !shouldGiveWay) continue; osg::Vec2f baseSpeed = origMovement * maxSpeed; @@ -1839,14 +1840,14 @@ namespace MWMechanics osg::Vec3f halfExtents = world->getHalfExtents(ptr); float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding; - float timeToCollision = maxTimeToCheck; + float timeToCheck = maxTimeToCheck; + if (!shouldGiveWay && !aiSequence.isEmpty()) + timeToCheck = std::min(timeToCheck, getTimeToDestination(**aiSequence.begin(), basePos, maxSpeed, duration, halfExtents)); + + float timeToCollision = timeToCheck; osg::Vec2f movementCorrection(0, 0); float angleToApproachingActor = 0; - const float timeToDestination = aiSequence.isEmpty() - ? std::numeric_limits::max() - : getTimeToDestination(**aiSequence.begin(), basePos, maxSpeed, duration, halfExtents); - // Iterate through all other actors and predict collisions. for(PtrActorMap::iterator otherIter(mActors.begin()); otherIter != mActors.end(); ++otherIter) { @@ -1883,7 +1884,7 @@ namespace MWMechanics continue; // No solution; distance is always >= collisionDist. float t = (-vr - std::sqrt(Dh)) / v2; - if (t < 0 || t > timeToCollision || t > timeToDestination) + if (t < 0 || t > timeToCollision) continue; // Check visibility and awareness last as it's expensive. @@ -1903,7 +1904,7 @@ namespace MWMechanics movementCorrection.y() *= 0.5f; } - if (timeToCollision < maxTimeToCheck) + if (timeToCollision < timeToCheck) { // Try to evade the nearest collision. osg::Vec2f newMovement = origMovement + movementCorrection; From f0a77a48df39170545588e9e3b06b3f1680a8e4f Mon Sep 17 00:00:00 2001 From: psi29a Date: Thu, 23 Sep 2021 12:50:08 +0000 Subject: [PATCH 8/8] Merge branch 'check_pathgrid' into 'master' Make sure PathFinder::getClosestPoint is not called with failing precondition (#6294) Closes #6294 See merge request OpenMW/openmw!1236 (cherry picked from commit baa33799de3cb27d9d3805e164b9d7ccea6a3e4d) d36595e0 Make sure PathFinder::getClosestPoint is not called with failing precondition --- apps/openmw/mwmechanics/aicombat.cpp | 2 +- apps/openmw/mwmechanics/aiwander.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index f6123c12c..1adc2531b 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -346,7 +346,7 @@ namespace MWMechanics bool runFallback = true; - if (pathgrid && !actor.getClass().isPureWaterCreature(actor)) + if (pathgrid != nullptr && !pathgrid->mPoints.empty() && !actor.getClass().isPureWaterCreature(actor)) { ESM::Pathgrid::PointList points; Misc::CoordinateConverter coords(storage.mCell->getCell()); diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 0e424b2f8..175836b11 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -754,6 +754,9 @@ namespace MWMechanics const ESM::Pathgrid *pathgrid = MWBase::Environment::get().getWorld()->getStore().get().search(*currentCell->getCell()); + if (pathgrid == nullptr || pathgrid->mPoints.empty()) + return; + int index = PathFinder::getClosestPoint(pathgrid, PathFinder::makeOsgVec3(dest)); getPathGridGraph(currentCell).getNeighbouringPoints(index, points);