You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/files/data/scripts/omw/console/player.lua

166 lines
5.6 KiB
Lua

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'),
vfs = require('openmw.vfs'),
markup = require('openmw.markup'),
ambient = require('openmw.ambient'),
async = require('openmw.async'),
nearby = require('openmw.nearby'),
self = require('openmw.self'),
input = require('openmw.input'),
postprocessing = require('openmw.postprocessing'),
ui = require('openmw.ui'),
camera = require('openmw.camera'),
aux_util = require('openmw_aux.util'),
debug = require('openmw.debug'),
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'
elseif arg == 'menu' then
-- handled in menu.lua
else
local msg = [[
Usage: 'lua menu' or 'luam' - enter menu context
'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,
}
}