diff --git a/apps/openmw/mwbase/luamanager.hpp b/apps/openmw/mwbase/luamanager.hpp index fcbb6289f9..5aef1763f0 100644 --- a/apps/openmw/mwbase/luamanager.hpp +++ b/apps/openmw/mwbase/luamanager.hpp @@ -98,6 +98,9 @@ namespace MWBase virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void saveLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScripts& data) = 0; + // Must be called before save, otherwise the world can be saved in an inconsistent state. + virtual void applyDelayedActions() = 0; + // Loading from a save virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; virtual void loadLocalScripts(const MWWorld::Ptr& ptr, const ESM::LuaScripts& data) = 0; diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index f7386ca61d..22e1014034 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -237,6 +237,11 @@ namespace MWLua windowManager->printToConsole(msg, "#" + color.toHex()); mInGameConsoleMessages.clear(); + applyDelayedActions(); + } + + void LuaManager::applyDelayedActions() + { for (DelayedAction& action : mActionQueue) action.apply(); mActionQueue.clear(); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 01315bb9df..e9311fc854 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -56,6 +56,11 @@ namespace MWLua // Can use the scene graph and applies the actions queued during update() void synchronizedUpdate(); + // Normally it is called by `synchronizedUpdate` every frame. + // Additionally must be called before making a save to ensure that there are no pending delayed + // actions and the world is in a consistent state. + void applyDelayedActions() override; + // Available everywhere through the MWBase::LuaManager interface. // LuaManager queues these events and propagates to scripts on the next `update` call. void newGameStarted() override; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index f5db8b26ba..b6d701fe88 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -190,6 +190,8 @@ void MWState::StateManager::resumeGame() void MWState::StateManager::saveGame(std::string_view description, const Slot* slot) { + MWBase::Environment::get().getLuaManager()->applyDelayedActions(); + MWState::Character* character = getCurrentCharacter(); try