You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
7.2 KiB
249 lines
7.2 KiB
local mt = {}
|
|
mt.__index = mt
|
|
|
|
local function switch(value)
|
|
return function (mapping)
|
|
if mapping[value] then
|
|
mapping[value]()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function str_trim(str, p)
|
|
return str:gsub('^'..p..'*(.-)$', '%1'):gsub('^(.-)'..p..'*$', '%1')
|
|
end
|
|
|
|
local function str_split(str, p)
|
|
local rt = {}
|
|
local l = 1
|
|
local state = 0
|
|
for i = 1, #str do
|
|
local c = str:sub(i,i)
|
|
if state == 0 then
|
|
if c == '"' then
|
|
state = 1
|
|
elseif c == p then
|
|
table.insert(rt, str:sub(l, i - 1))
|
|
l = i + 1
|
|
end
|
|
elseif state == 1 then
|
|
if c == '"' then
|
|
state = 0
|
|
end
|
|
end
|
|
end
|
|
if l <= #str then
|
|
table.insert(rt, str:sub(l, #str))
|
|
end
|
|
return rt
|
|
end
|
|
|
|
function mt:accept_ui(type, name, key, value)
|
|
if not self.ui[type][name] then
|
|
self.ui[type][name] = { name = name }
|
|
end
|
|
local ui = self.ui[type][name]
|
|
switch(key) {
|
|
args = function ()
|
|
local r = str_split(value, ',')
|
|
if type == 'call' then
|
|
ui.use_in_event = r[2]
|
|
ui.returns = r[3]
|
|
table.remove(r, 1)
|
|
table.remove(r, 1)
|
|
table.remove(r, 1)
|
|
else
|
|
table.remove(r, 1)
|
|
end
|
|
ui.args = {}
|
|
for _, v in ipairs(r) do
|
|
table.insert(ui.args, { type = v })
|
|
end
|
|
end,
|
|
default = function ()
|
|
local r = str_split(value, ',')
|
|
for i, v in ipairs(ui.args) do
|
|
if r[i] and r[i] ~= '_' then
|
|
v.default = r[i]
|
|
end
|
|
end
|
|
end,
|
|
limit = function ()
|
|
local r = str_split(value, ',')
|
|
for i, v in ipairs(ui.args) do
|
|
if r[2*i-1] and r[2*i-1] ~= '_' then
|
|
v.min = r[2*i-1]
|
|
end
|
|
if r[2*i] and r[2*i] ~= '_' then
|
|
v.max = r[2*i]
|
|
end
|
|
end
|
|
end,
|
|
category = function ()
|
|
ui.category = value
|
|
if not self.categories[type][ui.category] then
|
|
self.categories[type][ui.category] = {}
|
|
table.insert(self.categories[type], ui.category)
|
|
end
|
|
table.insert(self.categories[type][ui.category], ui)
|
|
end,
|
|
script_name = function ()
|
|
ui.script_name = value
|
|
end,
|
|
description = function ()
|
|
if not ui.title then
|
|
ui.title = str_trim(value, '"')
|
|
return
|
|
end
|
|
if ui.description then
|
|
return
|
|
end
|
|
local str = ''
|
|
local r = str_split(value, ',')
|
|
for _, s in ipairs(r) do
|
|
s = str_trim(s, '%s')
|
|
if s:sub(1,1) == '~' then
|
|
str = str .. '${' .. s:sub(2) .. '}'
|
|
else
|
|
str = str .. str_trim(s, '"')
|
|
end
|
|
end
|
|
ui.description = str
|
|
end,
|
|
comment = function ()
|
|
ui.comment = str_trim(value, '"')
|
|
end,
|
|
}
|
|
end
|
|
|
|
function mt:parse_ui(type, subtype, key, value)
|
|
if subtype == 'data' then
|
|
if key:sub(1,1) ~= '_' then
|
|
self:accept_ui(type, key, 'args', value)
|
|
elseif key:sub(- #'_Defaults', -1) == '_Defaults' then
|
|
self:accept_ui(type, key:sub(2, -1 - #'_Defaults'), 'default', value)
|
|
elseif key:sub(- #'_Limits', -1) == '_Limits' then
|
|
self:accept_ui(type, key:sub(2, -1 - #'_Limits'), 'limit', value)
|
|
elseif key:sub(- #'_Category', -1) == '_Category' then
|
|
self:accept_ui(type, key:sub(2, -1 - #'_Category'), 'category', value)
|
|
elseif key:sub(- #'_ScriptName', -1) == '_ScriptName' then
|
|
self:accept_ui(type, key:sub(2, -1 - #'_ScriptName'), 'script_name', value)
|
|
elseif key:sub(- #'_UseWithAI', -1) == '_UseWithAI' then
|
|
elseif key:sub(- #'_AIDefaults', -1) == '_AIDefaults' then
|
|
else
|
|
error('无法解析: ' .. key)
|
|
end
|
|
elseif subtype == 'string' then
|
|
if key:sub(- #'Hint', -1) == 'Hint' then
|
|
self:accept_ui(type, key:sub(1, -1 - #'Hint'), 'comment', value)
|
|
else
|
|
self:accept_ui(type, key, 'description', value)
|
|
end
|
|
else
|
|
error('未知类型: ' .. subtype)
|
|
end
|
|
end
|
|
|
|
function mt:parse_define(section, key, value)
|
|
if not self.ui.define[section] then
|
|
self.ui.define[section] = {}
|
|
end
|
|
table.insert(self.ui.define[section], {key, value})
|
|
end
|
|
|
|
function mt:parse(section, key, value)
|
|
switch(section) {
|
|
TriggerEvents = function ()
|
|
self:parse_ui('event', 'data', key, value)
|
|
end,
|
|
TriggerEventStrings = function ()
|
|
self:parse_ui('event', 'string', key, value)
|
|
end,
|
|
TriggerConditions = function ()
|
|
self:parse_ui('condition', 'data', key, value)
|
|
end,
|
|
TriggerConditionStrings = function ()
|
|
self:parse_ui('condition', 'string', key, value)
|
|
end,
|
|
TriggerActions = function ()
|
|
self:parse_ui('action', 'data', key, value)
|
|
end,
|
|
TriggerActionStrings = function ()
|
|
self:parse_ui('action', 'string', key, value)
|
|
end,
|
|
TriggerCalls = function ()
|
|
self:parse_ui('call', 'data', key, value)
|
|
end,
|
|
TriggerCallStrings = function ()
|
|
self:parse_ui('call', 'string', key, value)
|
|
end,
|
|
TriggerCategories = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
TriggerTypes = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
TriggerTypeDefaults = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
TriggerParams = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
DefaultTriggerCategories = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
DefaultTriggers = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
AIFunctionStrings = function ()
|
|
self:parse_define(section, key, value)
|
|
end,
|
|
}
|
|
end
|
|
|
|
function mt:readfile(path)
|
|
local f = assert(io.open(path, "r"))
|
|
local section = nil
|
|
for line in f:lines() do
|
|
if line:sub(1,1) == "[" then
|
|
section = line:sub(2, #line - 1)
|
|
elseif line:sub(1,2) == "//" then
|
|
elseif line ~= "" then
|
|
local first = line:find("=")
|
|
if first then
|
|
local key = line:sub(1, first - 1)
|
|
local value = line:sub(first + 1) or ""
|
|
self:parse(section, key, value)
|
|
end
|
|
end
|
|
end
|
|
f:close()
|
|
end
|
|
|
|
function mt:reset()
|
|
self.ui = {
|
|
define = {},
|
|
event = {},
|
|
condition = {},
|
|
action = {},
|
|
call = {},
|
|
}
|
|
self.categories = {
|
|
event = {},
|
|
condition = {},
|
|
action = {},
|
|
call = {},
|
|
}
|
|
end
|
|
|
|
function mt:read(path)
|
|
self:reset()
|
|
self:readfile(path / [[TriggerData.txt]])
|
|
self:readfile(path / [[TriggerStrings.txt]])
|
|
end
|
|
|
|
return function(path)
|
|
local obj = setmetatable({}, mt)
|
|
obj:read(path)
|
|
return obj
|
|
end
|
|
|