mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 03:29:55 +00:00
Console command "reload lua"
This commit is contained in:
parent
9d09ecf8ca
commit
d5cda61855
10 changed files with 58 additions and 3 deletions
|
@ -59,6 +59,9 @@ namespace MWBase
|
|||
|
||||
// Should be called before loading. The map is used to fix refnums if the order of content files was changed.
|
||||
virtual void setContentFileMapping(const std::map<int, int>&) = 0;
|
||||
|
||||
// Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script.
|
||||
virtual void reloadAllScripts() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "../mwbase/scriptmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/luamanager.hpp"
|
||||
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
|
|
@ -334,4 +334,30 @@ namespace MWLua
|
|||
scripts->setSerializer(mLocalSerializer.get());
|
||||
}
|
||||
|
||||
void LuaManager::reloadAllScripts()
|
||||
{
|
||||
Log(Debug::Info) << "Reload Lua";
|
||||
mLua.dropScriptCache();
|
||||
|
||||
{ // Reload global scripts
|
||||
ESM::LuaScripts data;
|
||||
mGlobalScripts.save(data);
|
||||
mGlobalScripts.removeAllScripts();
|
||||
for (const std::string& path : mGlobalScriptList)
|
||||
if (mGlobalScripts.addNewScript(path))
|
||||
Log(Debug::Info) << "Global script restarted: " << path;
|
||||
mGlobalScripts.load(data, false);
|
||||
}
|
||||
|
||||
for (const auto& [id, ptr] : mWorldView.getObjectRegistry()->mObjectMapping)
|
||||
{ // Reload local scripts
|
||||
LocalScripts* scripts = ptr.getRefData().getLuaScripts();
|
||||
if (scripts == nullptr)
|
||||
continue;
|
||||
ESM::LuaScripts data;
|
||||
scripts->save(data);
|
||||
scripts->load(data, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ namespace MWLua
|
|||
void loadLocalScripts(const MWWorld::Ptr& ptr, const ESM::LuaScripts& data) override;
|
||||
void setContentFileMapping(const std::map<int, int>& mapping) override { mContentFileMapping = mapping; }
|
||||
|
||||
// Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script.
|
||||
void reloadAllScripts() override;
|
||||
|
||||
private:
|
||||
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr);
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace MWLua
|
|||
friend class Object;
|
||||
friend class GObject;
|
||||
friend class LObject;
|
||||
friend class LuaManager;
|
||||
|
||||
bool mChanged = false;
|
||||
int64_t mUpdateCounter = 0;
|
||||
|
|
|
@ -480,5 +480,6 @@ op 0x200031d: StartScript, explicit
|
|||
op 0x200031e: GetDistance
|
||||
op 0x200031f: GetDistance, explicit
|
||||
op 0x2000320: Help
|
||||
op 0x2000321: ReloadLua
|
||||
|
||||
opcodes 0x2000321-0x3ffffff unused
|
||||
opcodes 0x2000322-0x3ffffff unused
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "../mwbase/scriptmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/luamanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
@ -169,8 +170,6 @@ namespace MWScript
|
|||
void execute (Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
if(!ptr.isEmpty() && !ptr.mRef->mData.isEnabled())
|
||||
ptr.mRef->mData.mPhysicsPostponed = false;
|
||||
MWBase::Environment::get().getWorld()->enable (ptr);
|
||||
}
|
||||
};
|
||||
|
@ -1599,6 +1598,17 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
class OpReloadLua : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
void execute (Interpreter::Runtime& runtime) override
|
||||
{
|
||||
MWBase::Environment::get().getLuaManager()->reloadAllScripts();
|
||||
runtime.getContext().report("All Lua scripts are reloaded");
|
||||
}
|
||||
};
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
{
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeMenuMode, new OpMenuMode);
|
||||
|
@ -1719,6 +1729,7 @@ namespace MWScript
|
|||
interpreter.installSegment5 (Compiler::Misc::opcodeRepairedOnMeExplicit, new OpRepairedOnMe<ExplicitRef>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeToggleRecastMesh, new OpToggleRecastMesh);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeHelp, new OpHelp);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeReloadLua, new OpReloadLua);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -338,6 +338,7 @@ namespace Compiler
|
|||
extensions.registerFunction ("repairedonme", 'l', "S", opcodeRepairedOnMe, opcodeRepairedOnMeExplicit);
|
||||
extensions.registerInstruction ("togglerecastmesh", "", opcodeToggleRecastMesh);
|
||||
extensions.registerInstruction ("help", "", opcodeHelp);
|
||||
extensions.registerInstruction ("reloadlua", "", opcodeReloadLua);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -319,6 +319,7 @@ namespace Compiler
|
|||
const int opcodeGetDisabledExplicit = 0x200031c;
|
||||
const int opcodeStartScriptExplicit = 0x200031d;
|
||||
const int opcodeHelp = 0x2000320;
|
||||
const int opcodeReloadLua = 0x2000321;
|
||||
}
|
||||
|
||||
namespace Sky
|
||||
|
|
|
@ -114,6 +114,13 @@ Finally :ref:`register <Lua scripting>` it in ``openmw.cfg``:
|
|||
|
||||
Now every time the player presses "X" on a keyboard, a message is shown.
|
||||
|
||||
Hot reloading
|
||||
=============
|
||||
|
||||
It is possible to modify a script without restarting OpenMW. To apply changes open in-game console and run the command ``reloadlua``.
|
||||
It will restart all Lua scripts using `onSave and onLoad`_ handlers the same way as if the game was saved and loaded.
|
||||
It works only with existing ``*.lua`` files that are not packed to any archives. Adding new scripts or modifying ``*.omwscripts`` files always requires restarting the game.
|
||||
|
||||
Script structure
|
||||
================
|
||||
|
||||
|
|
Loading…
Reference in a new issue