关于mushclient和lua的一些东西
发现这里有不少人关心mush和lua的机器人,正好在做另外个mud的全自动机器人,说些我的心得讨论讨论。我的机器人的googlecode 地址: http://code.google.com/p/helllua/
首先,是机器人的理念。
机器人其实有两种做法
一种是触发式的
一种是busy+状态式的。
具体来说,以打坐为例。
触发式的机器人是抓取打坐结束的命令
而busy+状态的呢。
就是判断现在是不是在busy,如果不busy,就取得现在的状态,来判断是否完成。
这和mud新手和老手的区别一样
老手一个打坐结束的信息就知道该怎么办
而新手呢,不认识打坐的信息,只能根据是否动作结束,然后看看内力是否加上去来判断是否成功。
对于机器人来说
触发式机器人可以有限的提高效率
而 busy+状态的机器人可以提高机器人的容错率以及降低维护的代价
所以,我选择的还是busy+状态的机器人。
对于busy系统来说,首先要找到各适合的busytest 的命令
我在你们找个mud,招来找去就suicide这个命令比较适合。
suicide -1的话
如果busy
mud显示:
你上一个动作还没完成。
如果不busy,则显示
自杀有两种,您是要永远死掉还是重新投胎
那么很好,让我们定义三个基础函数
busyhook=nil
busytest=function(func)
busyhook=func
Send("suicide -1")
end
busyok=function(name,line,wildcards) -- 自杀有两种,您是要永远死掉还是重新投胎
if busyhook==nil then return end
busyhook()
busyhook=nil
end
busyfail=function(name,line,wildcards)--你上一个动作还没完成。
if busyhook~=nil then
DoAfterSpecial(1,'suicide -1'")
end
end
一个基本的busytest模块就做好了
busyok是执行储存在busyhook里的程序
busyfail是当还在busy的时候,过一秒再发个busytest指令。
busytest函数则表示
当不忙的时候执行func函数 那么如果我们要做打坐到300内里的机器人,怎么做呢?
我来写个范例
dazuo={}
dazuo["ok"]=nil
dazuo["fail"]=nil
dazuo.neili=0
do_dazuo=function(neili,dazuo_ok,dazuo_fail)
dazuo["ok"]=dazuo_ok
dazuo["fail"]=dazuo_fail
dazuo.neili=neili ----打坐到多少内力
busytest(dazuo.check)----不忙后检查内力
end
--打坐函数,打坐成功执行dazuo_ok,否则执行dazuo fail
dazuo["end"]=function(s)
if ((s~="")and(s~=nil)) then
call(dazuo)
end
dazuo["ok"]=nil
dazuo["fail"]=nil
end
--打坐结束函数
dazuo_end_ok=function()
dazuo["end"]("ok")
end
用来表示ok的dazuo结束程序
dazuo_end_fail=function()
dazuo["end"]("fail")
end
用来表示fail的dazuo结束程序
dazuo.check=function()
hp()--这里是对应的取得内力的函数
busytest(dazuo.do)---这里其实不应该用busytest,不过用了也无所谓。
end
dazuo.do=function()
if neili >300 then
dazuo_end_ok() -----------打坐结束了,调用结束函数
return
else
Send("dazuo 50")
busytest(dazuo.check) ----------------当送出dazuo 50之后,不忙就再次取得内力
end
然后,只要
do_dazuo(300,lianskill)
就可以执行打坐到300,然后运行lianskill()的效果了
其中,dazuo.do就是busy,而dazuo.check就是取得status 说好了这个,再说我看到的这个论坛上的另一个问题
怎么去控制处罚开关一次。
比如,要ask sb about sth
那么就要 t+ ask,ask sb about sth,t-ask
可如果真得这么做了,t+t-是在同一个程序里执行的,一开就关了根本无效。
那么正确的写法是什么呢?
就是在命令前后分别加两个命令,利用它的回现来控制触发的开关。
比如,我们send了"set trion ask","ask sb with sth","set trioff ask"
我还是给出三个函数:
on_trion=function(name,line,wildcards) --^设定环境变量:trion = (.*)"
EnableTriggerGroup(wildcards,true)
end
on_trioff=function(name,line,wildcards) --^设定环境变量:trioff = (.*)"
EnableTriggerGroup(wildcards,false)
end
catch=function(trigroup,cmd)
send("set trion"..trigroup)
send (cmd)
send("set trioff"..trigroup)
end
然后
当我需要临时使用任何一个触发组的时候,我只需要这样
catch('ask',"ask sb about sth")
就可以了 ttk_00 楼主提到的“busy+状态式”机器人制作思路让我很受启发。在让游戏角色执行一个命令后,以一定间隔时间(比如一秒)发送buytest命令来获知当前角色是不是处于busy状态。这种方法在做一些大型的机器人时很有用,只有知道了角色当前状态,所处的环境才能更好的进行下一步行动,保证了机器人的稳定性。
楼主提到“t+ ask,ask sb about sth,t-ask”会失效的问题,使用zmud在网络通畅的情况下这是可行的,网络不通畅的话往往会出问题。不过可以把这个命令分成两句话就好了,用“ask sb about sth”得到的提示来触发t-ask。
最后网上搜了一下,发现楼主竟然是那位写出mush下mapper功能的大侠,可否另外开贴详细介绍一下mapper的用法?先谢过了! 我不是写mapper.exe的作者,那个是zsz
我是自己重写了个mapper。也算是还愿
我的mapper的相关内容,在我贴出的机器里我封装在mapper.mod里了
我的mapper.dll的源代码在http://code.google.com/p/mushluamapper/
自学的c,写的比较不正规
有什么问题我会尽量回答的。 触发式的最大麻烦是busy会打乱状态,否则以触发来切换状态启动动作也可以,毕竟加一个比较大的wait浪费时间
我用的方法是在触发后启动判断busy,不busy了再继续
另,lz乃大能啊,呵呵,正在研究你的hell bot,mapper真是个好东东
可惜,俺在zmud时代就没玩透map,哎~~ 话说现在已经是CMUD时代了。
难道LS的还在用ZMUD吗? 也有很多人在用zmud4.62,4.62是哪个年代出来的?只要好用就行了!
cmud也不见得是个好东西
mush挺不错的,要是map功能增强点就完美了。 LS的同学。。。我们公司搞开发还是DOS环境,用TC编的,一年也有几百万的产值。
好用就行...难道让我继续用DOS嘛。。。说实话,用过了CMUD之后,我实在很难在ZMUD环境下写机器了。
另外CMUD的地图功能很强。