主要实现:string.gsub和loadstring解析字符串,运行方法。
主要作用:把条件与事件,以方法的形式告知策划,由策划配置方法名,达到条件判断与事件执行的效果。
条件例子:
"condition1(args) condition2(args) condition3(args)"
condition1、2、3为方法名,返回bool值
事件例子:
"events1(args) events2(args) events3(args)"
event1为方法名,无返回值,执行顺序按字符串顺序执行
注意:当参数为字符串时,需要用单引号
脚本最初是在开发道具等的获取途径跳转时用到的。玩家点击获取途径,需要执行不同的方法,比如:寻路,打开界面等等。然后就想到了这个东西,以事件的方式交给策划配置,程序就不用去控制某个道具的获取途径操作后应该执行什么。
代码:
--[[
说明:
条件与事件解析
备注:
count用于调试
--]]
local count
local result
events = {}
ai_events = {}
conditions = {}
mission_triggers = {}
-- 尝试基本语法错误纠正
local function TrySyntaxFix(input_str)
-- ,)参数错误
result,count = string.gsub(input_str,"(,%))",")")
--
return result
end
local function CheckCondition(player,cond_func)
local params = {}
params.self = player
return cond_func(params)
end
-- 检查函数或条件是否实现
local function CheckFuncImplement(parse_string, pool_name)
if parse_string == nil then parse_string = "" end
local pool = _G[pool_name]
if pool == nil then
print("pool not existed:", pool_name)
return
end
local not_impl_prompt = pool_name .. " not implement function:"
for name,params in string.gmatch(parse_string,"([%a_]+)%(([%w%p%s]-)%)") do
if pool[name] == nil then
print(not_impl_prompt, name)
end
end
end
---------------------------------------------------
-- 条件解析, 默认条件池: conditions
-- 技能条件模式匹配 转换到lua函数的处理,已测试
function GetConditionsString(condition_string)
if condition_string == nil or condition_string == "" then
condition_string = "true"
end
local result,count = "local conditions = _G[\"conditions\"]\nlocal ret=nil\nreturn function(params)\n\tret = (" .. string.gsub(condition_string,"([%a_]+)%(([%w%p%s]-)%)","conditions.%1(params,%2)") .. ")\n\tif ret == nil then\n\t\tprint(\"error\")\n\t\treturn false\n\telse\n\t\treturn ret end\nend"
return TrySyntaxFix(result)
end
----------------------------------------------------------
-- 事件解析, 默认事件池: events
-- 一般情况下技能仅允许执行自已的事件,与普通事件作区别
-- pool_name留作扩展, 对技能事件解析时使用.
function GetEventsString(events_string, pool_name)
if events_string == nil then events_string = "" end
local result,count
if pool_name ~= nil then
result,count = "local pool_name = _G[\"" .. pool_name .. "\"]\nreturn function(params)\n\t" .. string.gsub(events_string,"([%a_]+)%(([%w%p%s]-)%)", "pool_name.%1(params,%2)") .. "\nend"
else
result,count = "local events = _G[\"events\"]\nreturn function(params)\n\t" .. string.gsub(events_string,"([%a_]+)%(([%w%p%s]-)%)", "events.%1(params,%2)") .. "\nend"
end
return TrySyntaxFix(result)
end
-- Ai事件解析,池:ai_events, Node is a table like this: {func = , next = ...}
function GetAiEvents(events_string)
if events_string == nil then events_string = "" end
local ai_str_prefix = "local ai_events = _G[\"ai_events\"]\nreturn function(event_params)\n\treturn ai_events."
local one_func_str
local first_tbl, prev_tbl, events_tbl
for name,params in string.gmatch(events_string,"([%a_]+)%(([%w%p%s]-)%)") do
one_func_str = TrySyntaxFix(ai_str_prefix .. name .. "(event_params," .. params .. ")\n\tend")
events_tbl = {}
events_tbl.func = loadstring(one_func_str)()
events_tbl.dbg_str = name .. "(" .. params .. ")"
if prev_tbl ~= nil then
prev_tbl.next = events_tbl
else
first_tbl = events_tbl
end
prev_tbl = events_tbl
end
return first_tbl
end
function GetTriggersFuncString(triggers_string, pool_name)
if triggers_string == nil then triggers_string = "" end
local result,count
if pool_name ~= nil then
result,count = "local mission_triggers = _G[\"mission_triggers\"]\nlocal pool_name = _G[pool_name]\nreturn function(params)\n\t" .. string.gsub(triggers_string,"([%a_]+)%(([%w%p%s]-)%)","if " .. pool_name .. ".%1~= nil then " .. pool_name .. ".%1(params,%2) else mission_triggers.%1(params,%2) end ") .. "\nend"
else
result,count = "local mission_triggers = _G[\"mission_triggers\"]\nreturn function(params)\n\t" .. string.gsub(triggers_string,"([%a_]+)%(([%w%p%s]-)%)","mission_triggers.%1(params,%2)") .. "\nend"
end
return TrySyntaxFix(result)
end
----------------------------------------------------------
--Interface
function GetEventsFunc(events_string, pool_name)
return loadstring(GetEventsString(events_string, pool_name))()
end
function GetConditionsFunc(condition_string)
return loadstring(GetConditionsString(condition_string))()
end
function GetTriggersFunc(triggers_string)
return loadstring(GetTriggersFuncString(triggers_string))()
end
--执行条件
function DoConditions(run_params, condition_func)
if type(condition_func) ~= "function" or run_params == nil then
return true
end
return condition_func(run_params)
end
--执行事件,3中用法
--1、DoEvents( run_params, 函数)
--2、DoEvents( run_params, 函数名, 参数列表[table])
--3、DoEvents( run_params, 函数名, 参数[number])
function DoEvents( run_params, event_func, parameters )
if type(event_func) == "function" then
event_func(run_params)
elseif type(event_func) == "string" then
event_func = events[event_func]
if event_func == nil or type(event_func) ~= "function" then return end
if parameters ~= nil and type(parameters) == "table" then
event_func(run_params, unpack(parameters))
elseif parameters ~= nil and type(parameters) == "number" then
event_func(run_params, parameters)
end
end
end
events和conditions是全局的变量
当拿到策划配置的条件或事件字符串后:
1.调用GetEventsFunc(events_string, pool_name)或GetConditionsFunc(condition_string)方法
2.然后用第一步的返回值调用DoEvents(run_params, events, parameters)或DoConditions(run_params, condition_func)
DoEvents无返回值DoConditions有返回值,会返回条件的执行结果,类型为bool型
不骗你们,这玩意真的好用,把东西交给策划,解放程序的双手,美滋滋。