996引擎 - 【任务系统】和【cfg_newtask.xls】
- 总结
- 测试NPC界面
- cfg_newtask.xls 表
- 坑1:【新建任务接口】 对应 【接取任务触发】
- 坑2:增加系统任务计时 `dsfuncall` 除了角色对象,不支持任何其他参数
- 抢救一下
- 坑3: 修改 cfg_newtask.xls 必须重启引擎才能生效
- 参考资料
总结
- 996这个任务系统是一个
仅用于控制主界面左上角的【任务列表】UI刷新,交互状态通知,不含具体业务逻辑。,不持久化任何数据 - 任务列表有多个任务时支持上下滑动,可以调用接口将指定任务【置顶】
- 任务列表中,每个任务一行,分标题和(当前状态对应的)内容两部分,点击能触发
clicknewtask事件 - 具体的任务系统业务逻辑,需要自己写代码实现。(配合996提供的任务接口和触发,实现更新任务列表)
任务系统提供的接口,仅为会话内任务UI与轻量状态控制工具,不涉及任何自动持久化机制。
真实任务进度、完成状态、条件判断等,必须通过开发者在触发器或接口调用中,显式读写引擎变量,才能实现跨会话持续存在。
cfg_newtask.xls 是配置源头,actor 是运行时载体,引擎变量是持久化桥梁——三者缺一不可。
测试NPC界面
对应【任务系统】的 5 个接口,每行对应一个任务。
localnpc={}npc.title="任务系统";npc.paramsAndFuncs={};fori=1,18dotable.insert(npc.paramsAndFuncs,{"领取任务"..i,function(player)newpicktask(player,i,"领取参数A");end});table.insert(npc.paramsAndFuncs,{"刷新任务"..i,function(player)newchangetask(player,i,"刷新参数A","刷新参数B");end});table.insert(npc.paramsAndFuncs,{"完成任务"..i,function(player)newcompletetask(player,i);end});table.insert(npc.paramsAndFuncs,{"删除任务"..i,function(player)newdeletetask(player,i);end});table.insert(npc.paramsAndFuncs,{"任务置顶"..i,function(player)tasktopshow(player,i);end});endreturnnpc;cfg_newtask.xls 表
为了测试简单填了下。
- 支持富文本。支持
<u>、<br> - 支持给(接取任务前、任务进行中、完成任务时)分别置不同的特效。
- 支持设置排序字段
坑1:【新建任务接口】 对应 【接取任务触发】
也不知什么脑回路能想出这种命名风格。
调用新建任务接口newpicktask,服务端触发接取任务触发picktask,任务列表中当前内容显示newtask表的接取任务前内容。
其他的接口和触发都还好见名知意。
坑2:增加系统任务计时dsfuncall除了角色对象,不支持任何其他参数
--QFunction-0.luafunctiondingshicf_1(actor)enddsfuncall(actor,"dingshicf_1",10*1000,1,1)直接放弃,996所有的定时、延迟类的接口,都坑的一B。
抢救一下
如果一定想用系统任务计时要又不想声明 dingshicf_1,dingshicf_2,dingshicf_3… 一堆回调
可以考虑封装一下 dsfuncall 搞个支持直接传回调函数的版本。
--QFunction-0.lua--- 系统任务计时扩展版 (支持匿名函数)--- @param actor object 玩家对象--- @param func function 回调函数 (匿名函数或局部函数)--- @param time number 倒计时时间 (毫秒) 默认1000--- @param model number|nil 0=上线需重新开启, 1=上线直接执行 (默认0)--- @param isClear number|nil 0=开启新的, 1=上线刷新当前时间 (默认0)functiondsfuncallEx(actor,func,time,model,isClear)iftype(func)~="function"thenrelease_print("[Error] dsfuncallEx: func must be a function!")returnendtime=timeor1000-- 生成唯一的全局调度函数名-- 使用 os.clock() 配合随机数,防止在同一毫秒内生成重复 KeylocaldispatcherName=string.format("dingshicf_EX_%d_%d",gettcount64(),math.random(1000,9999))-- 注册到全局 _G_G[dispatcherName]=function()-- 使用 pcall 保护,确保即使业务代码报错,也能清理掉全局变量localok,err=pcall(func,actor)ifnotokthenrelease_print("[Timer Error] "..tostring(err))end-- 执行完毕后立即销毁,释放内存_G[dispatcherName]=nilend-- 调用 64_23.10.24 引擎原生接口dsfuncall(actor,dispatcherName,time,modelor0,isClearor0)end可以直接传匿名方法,匿名方法中可以访问闭包上下文的变量。坑爹的限制解除啦
locala=1;localb=2;-- 比如玩家触发某个机关,3秒后检查状态dsfuncallEx(actor,function(p)release_print("系统任务计时完成,访问闭包变量: a = "..a.." b = "..b)end,3000)坑3: 修改 cfg_newtask.xls 必须重启引擎才能生效
修改cfg_newtask.xls表后,必须关闭 M2 并重启引擎才能生效
参考资料
996引擎 - 任务系统