Lua console

pull/3226/head
Petr Mikheev 3 years ago
parent 1363292fc9
commit 88d09c336c

@ -92,6 +92,8 @@ namespace MWBase
// Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script.
virtual void reloadAllScripts() = 0;
virtual void handleConsoleCommand(const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) = 0;
};
}

@ -154,6 +154,13 @@ namespace MWBase
virtual void updateSpellWindow() = 0;
virtual void setConsoleSelectedObject(const MWWorld::Ptr& object) = 0;
virtual void setConsoleMode(const std::string& mode) = 0;
static constexpr std::string_view sConsoleColor_Default = "#FFFFFF";
static constexpr std::string_view sConsoleColor_Error = "#FF2222";
static constexpr std::string_view sConsoleColor_Success = "#FF00FF";
static constexpr std::string_view sConsoleColor_Info = "#AAAAAA";
virtual void printToConsole(const std::string& msg, std::string_view color) = 0;
/// Set time left for the player to start drowning (update the drowning bar)
/// @param time time left to start drowning

@ -162,25 +162,34 @@ namespace MWGui
MyGUI::LayerManager::getInstance().upLayerItem(mMainWidget);
}
void Console::print(const std::string &msg, const std::string& color)
void Console::print(const std::string &msg, std::string_view color)
{
mHistory->addText(color + MyGUI::TextIterator::toTagsString(msg));
mHistory->addText(std::string(color) + MyGUI::TextIterator::toTagsString(msg));
}
void Console::printOK(const std::string &msg)
{
print(msg + "\n", "#FF00FF");
print(msg + "\n", MWBase::WindowManager::sConsoleColor_Success);
}
void Console::printError(const std::string &msg)
{
print(msg + "\n", "#FF2222");
print(msg + "\n", MWBase::WindowManager::sConsoleColor_Error);
}
void Console::execute (const std::string& command)
{
// Log the command
print("> " + command + "\n");
if (mConsoleMode.empty())
print("> " + command + "\n");
else
print(mConsoleMode + " " + command + "\n");
if (!mConsoleMode.empty() || (command.size() >= 3 && std::string_view(command).substr(0, 3) == "lua"))
{
MWBase::Environment::get().getLuaManager()->handleConsoleCommand(mConsoleMode, command, mPtr);
return;
}
Compiler::Locals locals;
if (!mPtr.isEmpty())
@ -271,7 +280,7 @@ namespace MWGui
}
}
}
else if(key == MyGUI::KeyCode::Tab)
else if(key == MyGUI::KeyCode::Tab && mConsoleMode.empty())
{
std::vector<std::string> matches;
listNames();
@ -475,7 +484,7 @@ namespace MWGui
void Console::onResChange(int width, int height)
{
setCoord(10,10, width-10, height/2);
setCoord(10, 10, width-10, height/2);
}
void Console::updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr)
@ -489,23 +498,31 @@ namespace MWGui
if (!object.isEmpty())
{
if (object == mPtr)
{
setTitle("#{sConsoleTitle}");
mPtr=MWWorld::Ptr();
}
mPtr = MWWorld::Ptr();
else
{
setTitle("#{sConsoleTitle} (" + object.getCellRef().getRefId() + ")");
mPtr = object;
}
// User clicked on an object. Restore focus to the console command line.
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCommandLine);
}
else
{
setTitle("#{sConsoleTitle}");
mPtr = MWWorld::Ptr();
}
updateConsoleTitle();
}
void Console::updateConsoleTitle()
{
std::string title = "#{sConsoleTitle}";
if (!mConsoleMode.empty())
title = mConsoleMode + " " + title;
if (!mPtr.isEmpty())
title.append(" (" + mPtr.getCellRef().getRefId() + ")");
setTitle(title);
}
void Console::setConsoleMode(std::string_view mode)
{
mConsoleMode = std::string(mode);
updateConsoleTitle();
}
void Console::onReferenceUnavailable()

@ -9,6 +9,8 @@
#include <components/compiler/output.hpp>
#include <components/compiler/extensions.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
@ -40,7 +42,7 @@ namespace MWGui
void onResChange(int width, int height) override;
// Print a message to the console, in specified color.
void print(const std::string &msg, const std::string& color = "#FFFFFF");
void print(const std::string &msg, std::string_view color = MWBase::WindowManager::sConsoleColor_Default);
// These are pre-colored versions that you should use.
@ -60,12 +62,19 @@ namespace MWGui
void resetReference () override;
const std::string& getConsoleMode() const { return mConsoleMode; }
void setConsoleMode(std::string_view mode);
protected:
void onReferenceUnavailable() override;
private:
std::string mConsoleMode;
void updateConsoleTitle();
void keyPress(MyGUI::Widget* _sender,
MyGUI::KeyCode key,
MyGUI::Char _char);

@ -2069,6 +2069,16 @@ namespace MWGui
mConsole->setSelectedObject(object);
}
void WindowManager::printToConsole(const std::string& msg, std::string_view color)
{
mConsole->print(msg, color);
}
void WindowManager::setConsoleMode(const std::string& mode)
{
mConsole->setConsoleMode(mode);
}
std::string WindowManager::correctIconPath(const std::string& path)
{
return Misc::ResourceHelpers::correctIconPath(path, mResourceSystem->getVFS());

@ -195,6 +195,8 @@ namespace MWGui
void updateSpellWindow() override;
void setConsoleSelectedObject(const MWWorld::Ptr& object) override;
void printToConsole(const std::string& msg, std::string_view color) override;
void setConsoleMode(const std::string& mode) override;
/// Set time left for the player to start drowning (update the drowning bar)
/// @param time time left to start drowning

@ -242,6 +242,9 @@ namespace MWLua
for (const std::string& message : mUIMessages)
windowManager->messageBox(message);
mUIMessages.clear();
for (auto& [msg, color] : mInGameConsoleMessages)
windowManager->printToConsole(msg, "#" + color.toHex());
mInGameConsoleMessages.clear();
for (std::unique_ptr<Action>& action : mActionQueue)
action->safeApply(mWorldView);
@ -256,6 +259,7 @@ namespace MWLua
{
LuaUi::clearUserInterface();
mUiResourceManager.clear();
MWBase::Environment::get().getWindowManager()->setConsoleMode("");
mActiveLocalScripts.clear();
mLocalEvents.clear();
mGlobalEvents.clear();
@ -480,6 +484,7 @@ namespace MWLua
Log(Debug::Info) << "Reload Lua";
LuaUi::clearUserInterface();
MWBase::Environment::get().getWindowManager()->setConsoleMode("");
mUiResourceManager.clear();
mLua.dropScriptCache();
initConfiguration();
@ -503,6 +508,25 @@ namespace MWLua
scripts->receiveEngineEvent(LocalScripts::OnActive());
}
void LuaManager::handleConsoleCommand(const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr)
{
PlayerScripts* playerScripts = nullptr;
if (!mPlayer.isEmpty())
playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
if (!playerScripts)
{
MWBase::Environment::get().getWindowManager()->printToConsole("You must enter a game session to run Lua commands\n",
MWBase::WindowManager::sConsoleColor_Error);
return;
}
sol::object selected = sol::nil;
if (!selectedPtr.isEmpty())
selected = sol::make_object(mLua.sol(), LObject(getId(selectedPtr), mWorldView.getObjectRegistry()));
if (!playerScripts->consoleCommand(consoleMode, command, selected))
MWBase::Environment::get().getWindowManager()->printToConsole("No Lua handlers for console\n",
MWBase::WindowManager::sConsoleColor_Error);
}
LuaManager::Action::Action(LuaUtil::LuaState* state)
{
static const bool luaDebug = Settings::Manager::getBool("lua debug", "Lua");

@ -10,6 +10,8 @@
#include <components/lua_ui/resources.hpp>
#include <components/misc/color.hpp>
#include "../mwbase/luamanager.hpp"
#include "object.hpp"
@ -60,6 +62,10 @@ namespace MWLua
// Used only in Lua bindings
void addCustomLocalScript(const MWWorld::Ptr&, int scriptId);
void addUIMessage(std::string_view message) { mUIMessages.emplace_back(message); }
void addInGameConsoleMessage(const std::string& msg, const Misc::Color& color)
{
mInGameConsoleMessages.push_back({msg, color});
}
// Some changes to the game world can not be done from the scripting thread (because it runs in parallel with OSG Cull),
// so we need to queue it and apply from the main thread. All such changes should be implemented as classes inherited
@ -94,6 +100,8 @@ namespace MWLua
// Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script.
void reloadAllScripts() override;
void handleConsoleCommand(const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) override;
// Used to call Lua callbacks from C++
void queueCallback(LuaUtil::Callback callback, sol::object arg)
{
@ -172,6 +180,7 @@ namespace MWLua
std::vector<std::unique_ptr<Action>> mActionQueue;
std::unique_ptr<Action> mTeleportPlayerAction;
std::vector<std::string> mUIMessages;
std::vector<std::pair<std::string, Misc::Color>> mInGameConsoleMessages;
LuaUtil::LuaStorage mGlobalStorage{mLua.sol()};
LuaUtil::LuaStorage mPlayerStorage{mLua.sol()};

@ -18,7 +18,7 @@ namespace MWLua
PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj) : LocalScripts(lua, obj, ESM::LuaScriptCfg::sPlayer)
{
registerEngineHandlers({
&mKeyPressHandlers, &mKeyReleaseHandlers,
&mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers,
&mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers,
&mActionHandlers, &mInputUpdateHandlers,
&mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved
@ -59,7 +59,14 @@ namespace MWLua
void inputUpdate(float dt) { callEngineHandlers(mInputUpdateHandlers, dt); }
bool consoleCommand(const std::string& consoleMode, const std::string& command, const sol::object& selectedObject)
{
callEngineHandlers(mConsoleCommandHandlers, consoleMode, command, selectedObject);
return !mConsoleCommandHandlers.mList.empty();
}
private:
EngineHandlerList mConsoleCommandHandlers{"onConsoleCommand"};
EngineHandlerList mKeyPressHandlers{"onKeyPress"};
EngineHandlerList mKeyReleaseHandlers{"onKeyRelease"};
EngineHandlerList mControllerButtonPressHandlers{"onControllerButtonPress"};

@ -12,6 +12,8 @@
#include "context.hpp"
#include "luamanagerimp.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWLua
{
namespace
@ -213,6 +215,33 @@ namespace MWLua
{
luaManager->addUIMessage(message);
};
api["CONSOLE_COLOR"] = LuaUtil::makeReadOnly(context.mLua->tableFromPairs<std::string, Misc::Color>({
{"Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1))},
{"Error", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Error.substr(1))},
{"Success", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Success.substr(1))},
{"Info", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Info.substr(1))},
}));
api["printToConsole"] = [luaManager=context.mLuaManager](const std::string& message, const Misc::Color& color)
{
luaManager->addInGameConsoleMessage(message + "\n", color);
};
api["setConsoleMode"] = [luaManager=context.mLuaManager](std::string_view mode)
{
luaManager->addAction(
[mode = std::string(mode)]{ MWBase::Environment::get().getWindowManager()->setConsoleMode(mode); });
};
api["setConsoleSelectedObject"] = [luaManager=context.mLuaManager](const sol::object& obj)
{
auto* wm = MWBase::Environment::get().getWindowManager();
if (obj == sol::nil)
luaManager->addAction([wm]{ wm->setConsoleSelectedObject(MWWorld::Ptr()); });
else
{
if (!obj.is<LObject>())
throw std::runtime_error("Game object expected");
luaManager->addAction([wm, obj=obj.as<LObject>()]{ wm->setConsoleSelectedObject(obj.ptr()); });
}
};
api["content"] = [](const sol::table& table)
{
return LuaUi::Content(table);

@ -70,23 +70,28 @@ Engine handler is a function defined by a script, that can be called by the engi
:widths: 20 80
* - onInputUpdate(dt)
- | Called every frame (if the game is not paused) right after processing
| user input. Use it only for latency-critical stuff.
- | Called every frame (if the game is not paused) right after
| processing user input. Use it only for latency-critical stuff.
* - onKeyPress(key)
- | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed.
| Usage example: ``if key.symbol == 'z' and key.withShift then ...``
| Usage example:
| ``if key.symbol == 'z' and key.withShift then ...``
* - onKeyRelease(key)
- | `Key <openmw_input.html##(KeyboardEvent)>`_ is released.
| Usage example: ``if key.symbol == 'z' and key.withShift then ...``
| Usage example:
| ``if key.symbol == 'z' and key.withShift then ...``
* - onControllerButtonPress(id)
- | A `button <openmw_input.html##(CONTROLLER_BUTTON)>`_ on a game controller is pressed.
| Usage example: ``if id == input.CONTROLLER_BUTTON.LeftStick then ...``
| Usage example:
| ``if id == input.CONTROLLER_BUTTON.LeftStick then ...``
* - onControllerButtonRelease(id)
- | A `button <openmw_input.html##(CONTROLLER_BUTTON)>`_ on a game controller is released.
| Usage example: ``if id == input.CONTROLLER_BUTTON.LeftStick then ...``
| Usage example:
| ``if id == input.CONTROLLER_BUTTON.LeftStick then ...``
* - onInputAction(id)
- | `Game control <openmw_input.html##(ACTION)>`_ is pressed.
| Usage example: ``if id == input.ACTION.ToggleWeapon then ...``
| Usage example:
| ``if id == input.ACTION.ToggleWeapon then ...``
* - onTouchPress(touchEvent)
- | A finger pressed on a touch device.
| `Touch event <openmw_input.html##(TouchEvent)>`_.
@ -95,4 +100,9 @@ Engine handler is a function defined by a script, that can be called by the engi
| `Touch event <openmw_input.html##(TouchEvent)>`_.
* - onTouchMove(touchEvent)
- | A finger moved on a touch device.
| `Touch event <openmw_input.html##(TouchEvent)>`_.
| `Touch event <openmw_input.html##(TouchEvent)>`_.
* - | onConsoleCommand(
| mode, command, selectedObject)
- | User entered `command` in in-game console. Called if either
| `mode` is not default or `command` starts with prefix `lua`.

@ -13,6 +13,9 @@ set(LUA_BUILTIN_FILES
scripts/omw/camera.lua
scripts/omw/head_bobbing.lua
scripts/omw/third_person.lua
scripts/omw/console/player.lua
scripts/omw/console/global.lua
scripts/omw/console/local.lua
l10n/Calendar/en.yaml
)

@ -1,2 +1,5 @@
PLAYER: scripts/omw/camera.lua
NPC,CREATURE: scripts/omw/ai.lua
PLAYER: scripts/omw/console/player.lua
GLOBAL: scripts/omw/console/global.lua
CUSTOM: scripts/omw/console/local.lua

@ -1,4 +1,4 @@
-------------------------------------------------------------------------------
---
-- `openmw_aux.util` defines utility functions that are implemented in Lua rather than in C++.
-- Implementation can be found in `resources/vfs/openmw_aux/util.lua`.
-- @module util
@ -6,6 +6,27 @@
local aux_util = {}
---
-- Works like `tostring` but shows also content of tables.
-- @function [parent=#util] deepToString
-- @param #any value The value to conver to string
-- @param #number maxDepth Max depth of tables unpacking (optional, 2 by default)
function aux_util.deepToString(val, level, prefix)
level = (level or 1) - 1
local ok, iter, t = pcall(function() return pairs(val) end)
if level < 0 or not ok then
return tostring(val)
end
local prefix = prefix or ''
local newPrefix = prefix .. ' '
local strs = {tostring(val) .. ' {\n'}
for k, v in iter, t do
strs[#strs + 1] = newPrefix .. tostring(k) .. ' = ' .. aux_util.deepToString(v, level, newPrefix) .. ',\n'
end
strs[#strs + 1] = prefix .. '}'
return table.concat(strs)
end
-------------------------------------------------------------------------------
-- Finds the nearest object to the given point in the given list.
-- Ignores cells, uses only coordinates. Returns the nearest object,

@ -0,0 +1,81 @@
local util = require('openmw.util')
local player = nil
local function printToConsole(...)
local strs = {}
for i = 1, select('#', ...) do
strs[i] = tostring(select(i, ...))
end
player:sendEvent('OMWConsolePrint', table.concat(strs, '\t'))
end
local function printRes(...)
if select('#', ...) >= 0 then
printToConsole(...)
end
end
local env = {
I = require('openmw.interfaces'),
util = require('openmw.util'),
storage = require('openmw.storage'),
core = require('openmw.core'),
types = require('openmw.types'),
async = require('openmw.async'),
world = require('openmw.world'),
aux_util = require('openmw_aux.util'),
view = require('openmw_aux.util').deepToString,
print = printToConsole,
exit = function() player:sendEvent('OMWConsoleExit') end,
help = function() player:sendEvent('OMWConsoleHelp') end,
}
env._G = env
setmetatable(env, {__index = _G, __metatable = false})
_G = nil
local function executeLuaCode(code)
local fn
local ok, err = pcall(function() fn = util.loadCode('return ' .. code, env) end)
if ok then
ok, err = pcall(function() printRes(fn()) end)
else
ok, err = pcall(function() util.loadCode(code, env)() end)
end
if not ok then
player:sendEvent('OMWConsoleError', err)
end
end
return {
eventHandlers = {
OMWConsoleEval = function(data)
player = data.player
env.selected = data.selected
executeLuaCode(data.code)
if env.selected ~= data.selected then
local ok, err = pcall(function() player:sendEvent('OMWConsoleSetSelected', env.selected) end)
if not ok then player:sendEvent('OMWConsoleError', err) end
end
end,
OMWConsoleStartLocal = function(data)
player = data.player
ok, err = pcall(function()
if not data.selected:hasScript('scripts/omw/console/local.lua') then
data.selected:addScript('scripts/omw/console/local.lua')
end
end)
if ok then
player:sendEvent('OMWConsoleSetContext', data.selected)
else
player:sendEvent('OMWConsoleError', err)
end
end,
OMWConsoleStopLocal = function(obj)
if obj:hasScript('scripts/omw/console/local.lua') then
obj:removeScript('scripts/omw/console/local.lua')
end
end,
},
}

@ -0,0 +1,71 @@
local util = require('openmw.util')
local core = require('openmw.core')
local self = require('openmw.self')
local player = nil
local function printToConsole(...)
local strs = {}
for i = 1, select('#', ...) do
strs[i] = tostring(select(i, ...))
end
player:sendEvent('OMWConsolePrint', table.concat(strs, '\t'))
end
local function printRes(...)
if select('#', ...) >= 0 then
printToConsole(...)
end
end
local env = {
I = require('openmw.interfaces'),
util = require('openmw.util'),
storage = require('openmw.storage'),
core = require('openmw.core'),
types = require('openmw.types'),
async = require('openmw.async'),
nearby = require('openmw.nearby'),
self = require('openmw.self'),
aux_util = require('openmw_aux.util'),
view = require('openmw_aux.util').deepToString,
print = printToConsole,
exit = function() player:sendEvent('OMWConsoleExit') end,
help = function() player:sendEvent('OMWConsoleHelp') end,
}
env._G = env
setmetatable(env, {__index = _G, __metatable = false})
_G = nil
local function executeLuaCode(code)
local fn
local ok, err = pcall(function() fn = util.loadCode('return ' .. code, env) end)
if ok then
ok, err = pcall(function() printRes(fn()) end)
else
ok, err = pcall(function() util.loadCode(code, env)() end)
end
if not ok then
player:sendEvent('OMWConsoleError', err)
end
end
return {
eventHandlers = {
OMWConsoleEval = function(data)
player = data.player
env.selected = data.selected
executeLuaCode(data.code)
if env.selected ~= data.selected then
local ok, err = pcall(function() player:sendEvent('OMWConsoleSetSelected', env.selected) end)
if not ok then player:sendEvent('OMWConsoleError', err) end
end
end,
},
engineHandlers = {
onLoad = function()
core.sendGlobalEvent('OMWConsoleStopLocal', self.object)
end,
}
}

@ -0,0 +1,158 @@
local ui = require('openmw.ui')
local util = require('openmw.util')
local self = require('openmw.self')
local core = require('openmw.core')
local function printHelp()
local msg = [[
This is the built-in Lua interpreter.
help() - print this message
exit() - exit Lua mode
selected - currently selected object (click on any object to change)
view(_G) - print content of the table `_G` (current environment)
standard libraries (math, string, etc.) are loaded by default but not visible in `_G`
view(types, 2) - print table `types` (i.e. `openmw.types`) and its subtables (2 - traversal depth)]]
ui.printToConsole(msg, ui.CONSOLE_COLOR.Info)
end
local function printToConsole(...)
local strs = {}
for i = 1, select('#', ...) do
strs[i] = tostring(select(i, ...))
end
return ui.printToConsole(table.concat(strs, '\t'), ui.CONSOLE_COLOR.Info)
end
local function printRes(...)
if select('#', ...) >= 0 then
printToConsole(...)
end
end
local currentSelf = nil
local currentMode = ''
local function exitLuaMode()
currentSelf = nil
currentMode = ''
ui.setConsoleMode('')
ui.printToConsole('Lua mode OFF', ui.CONSOLE_COLOR.Success)
end
local function setContext(obj)
ui.printToConsole('Lua mode ON, use exit() to return, help() for more info', ui.CONSOLE_COLOR.Success)
if obj == self then
currentMode = 'Lua[Player]'
ui.printToConsole('Context: Player', ui.CONSOLE_COLOR.Success)
elseif obj then
if not obj:isValid() then error('Object not available') end
currentMode = 'Lua['..obj.recordId..']'
ui.printToConsole('Context: Local['..tostring(obj)..']', ui.CONSOLE_COLOR.Success)
else
currentMode = 'Lua[Global]'
ui.printToConsole('Context: Global', ui.CONSOLE_COLOR.Success)
end
currentSelf = obj
ui.setConsoleMode(currentMode)
end
local function setSelected(obj)
local ok, err = pcall(function() ui.setConsoleSelectedObject(obj) end)
if ok then
ui.printToConsole('Selected object changed', ui.CONSOLE_COLOR.Success)
else
ui.printToConsole(err, ui.CONSOLE_COLOR.Error)
end
end
local env = {
I = require('openmw.interfaces'),
util = require('openmw.util'),
storage = require('openmw.storage'),
core = require('openmw.core'),
types = require('openmw.types'),
async = require('openmw.async'),
nearby = require('openmw.nearby'),
self = require('openmw.self'),
input = require('openmw.input'),
ui = require('openmw.ui'),
camera = require('openmw.camera'),
aux_util = require('openmw_aux.util'),
view = require('openmw_aux.util').deepToString,
print = printToConsole,
exit = exitLuaMode,
help = printHelp,
}
env._G = env
setmetatable(env, {__index = _G, __metatable = false})
_G = nil
local function executeLuaCode(code)
local fn
local ok, err = pcall(function() fn = util.loadCode('return ' .. code, env) end)
if ok then
ok, err = pcall(function() printRes(fn()) end)
else
ok, err = pcall(function() util.loadCode(code, env)() end)
end
if not ok then
ui.printToConsole(err, ui.CONSOLE_COLOR.Error)
end
end
local function onConsoleCommand(mode, cmd, selectedObject)
env.selected = selectedObject
if mode == '' then
cmd, arg = cmd:lower():match('(%w+) *(%w*)')
if cmd == 'lua' then
if arg == 'player' then
cmd = 'luap'
elseif arg == 'global' then
cmd = 'luag'
elseif arg == 'selected' then
cmd = 'luas'
else
local msg = [[
Usage: 'lua player' or 'luap' - enter player context
'lua global' or 'luag' - enter global context
'lua selected' or 'luas' - enter local context on the selected object]]
ui.printToConsole(msg, ui.CONSOLE_COLOR.Info)
end
end
if cmd == 'luap' or (cmd == 'luas' and selectedObject == self.object) then
setContext(self)
elseif cmd == 'luag' then
setContext()
elseif cmd == 'luas' then
if selectedObject then
core.sendGlobalEvent('OMWConsoleStartLocal', {player=self.object, selected=selectedObject})
else
ui.printToConsole('No selected object', ui.CONSOLE_COLOR.Error)
end
end
elseif mode == currentMode then
if cmd == 'exit()' then
exitLuaMode()
elseif currentSelf == self then
executeLuaCode(cmd)
if env.selected ~= selectedObject then setSelected(env.selected) end
elseif currentSelf then
currentSelf:sendEvent('OMWConsoleEval', {player=self.object, code=cmd, selected=selectedObject})
else
core.sendGlobalEvent('OMWConsoleEval', {player=self.object, code=cmd, selected=selectedObject})
end
end
end
return {
engineHandlers = {onConsoleCommand = onConsoleCommand},
eventHandlers = {
OMWConsolePrint = function(msg) ui.printToConsole(tostring(msg), ui.CONSOLE_COLOR.Info) end,
OMWConsoleError = function(msg) ui.printToConsole(tostring(msg), ui.CONSOLE_COLOR.Error) end,
OMWConsoleSetContext = setContext,
OMWConsoleSetSelected = setSelected,
OMWConsoleExit = exitLuaMode,
OMWConsoleHelp = printHelp,
}
}

@ -38,6 +38,37 @@
-- @function [parent=#ui] showMessage
-- @param #string msg
---
-- Predefined colors for console output
-- @field [parent=#ui] #CONSOLE_COLOR CONSOLE_COLOR
---
-- Predefined colors for console output
-- @type CONSOLE_COLOR
-- @field openmw.util#Color Default
-- @field openmw.util#Color Error
-- @field openmw.util#Color Success
-- @field openmw.util#Color Info
---
-- Print to the in-game console.
-- @function [parent=#ui] printToConsole
-- @param #string msg
-- @param openmw.util#Color color
---
-- Set mode of the in-game console.
-- The mode can be any string, by default is empty.
-- If not empty, then the console doesn't handle mwscript commands and
-- instead passes user input to Lua scripts via `onConsoleCommand` engine handler.
-- @function [parent=#ui] setConsoleMode
-- @param #string mode
---
-- Set selected object for console.
-- @function [parent=#ui] setConsoleSelectedObject
-- @param openmw.core#GameObject obj
---
-- Returns the size of the OpenMW window in pixels as a 2D vector.
-- @function [parent=#ui] screenSize

Loading…
Cancel
Save