mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 08:29:56 +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.
|
// 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;
|
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/scriptmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/luamanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
|
@ -334,4 +334,30 @@ namespace MWLua
|
||||||
scripts->setSerializer(mLocalSerializer.get());
|
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 loadLocalScripts(const MWWorld::Ptr& ptr, const ESM::LuaScripts& data) override;
|
||||||
void setContentFileMapping(const std::map<int, int>& mapping) override { mContentFileMapping = mapping; }
|
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:
|
private:
|
||||||
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr);
|
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace MWLua
|
||||||
friend class Object;
|
friend class Object;
|
||||||
friend class GObject;
|
friend class GObject;
|
||||||
friend class LObject;
|
friend class LObject;
|
||||||
|
friend class LuaManager;
|
||||||
|
|
||||||
bool mChanged = false;
|
bool mChanged = false;
|
||||||
int64_t mUpdateCounter = 0;
|
int64_t mUpdateCounter = 0;
|
||||||
|
|
|
@ -480,5 +480,6 @@ op 0x200031d: StartScript, explicit
|
||||||
op 0x200031e: GetDistance
|
op 0x200031e: GetDistance
|
||||||
op 0x200031f: GetDistance, explicit
|
op 0x200031f: GetDistance, explicit
|
||||||
op 0x2000320: Help
|
op 0x2000320: Help
|
||||||
|
op 0x2000321: ReloadLua
|
||||||
|
|
||||||
opcodes 0x2000321-0x3ffffff unused
|
opcodes 0x2000322-0x3ffffff unused
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "../mwbase/scriptmanager.hpp"
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/luamanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
|
@ -169,8 +170,6 @@ namespace MWScript
|
||||||
void execute (Interpreter::Runtime& runtime) override
|
void execute (Interpreter::Runtime& runtime) override
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
if(!ptr.isEmpty() && !ptr.mRef->mData.isEnabled())
|
|
||||||
ptr.mRef->mData.mPhysicsPostponed = false;
|
|
||||||
MWBase::Environment::get().getWorld()->enable (ptr);
|
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)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
{
|
{
|
||||||
interpreter.installSegment5 (Compiler::Misc::opcodeMenuMode, new OpMenuMode);
|
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::opcodeRepairedOnMeExplicit, new OpRepairedOnMe<ExplicitRef>);
|
||||||
interpreter.installSegment5 (Compiler::Misc::opcodeToggleRecastMesh, new OpToggleRecastMesh);
|
interpreter.installSegment5 (Compiler::Misc::opcodeToggleRecastMesh, new OpToggleRecastMesh);
|
||||||
interpreter.installSegment5 (Compiler::Misc::opcodeHelp, new OpHelp);
|
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.registerFunction ("repairedonme", 'l', "S", opcodeRepairedOnMe, opcodeRepairedOnMeExplicit);
|
||||||
extensions.registerInstruction ("togglerecastmesh", "", opcodeToggleRecastMesh);
|
extensions.registerInstruction ("togglerecastmesh", "", opcodeToggleRecastMesh);
|
||||||
extensions.registerInstruction ("help", "", opcodeHelp);
|
extensions.registerInstruction ("help", "", opcodeHelp);
|
||||||
|
extensions.registerInstruction ("reloadlua", "", opcodeReloadLua);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,7 @@ namespace Compiler
|
||||||
const int opcodeGetDisabledExplicit = 0x200031c;
|
const int opcodeGetDisabledExplicit = 0x200031c;
|
||||||
const int opcodeStartScriptExplicit = 0x200031d;
|
const int opcodeStartScriptExplicit = 0x200031d;
|
||||||
const int opcodeHelp = 0x2000320;
|
const int opcodeHelp = 0x2000320;
|
||||||
|
const int opcodeReloadLua = 0x2000321;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Sky
|
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.
|
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
|
Script structure
|
||||||
================
|
================
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue