本帖最后由 jcl 于 2013-5-1 14:06 编辑  
 
工欲善其事,必先利其器! 
 
上回我帖了一个自动吃大红的机器,目的只是展示MUSH机器的代码长什么样,本帖将从代码复用的角度,以实际的例子来向大家展示复杂的MUSH机器的制作。 
 
首先看一段代码: 
 
Me.check_state = function(f) 
        Execute("hp;set keep_idle hp"); 
        local l, w = wait.regexp("^【 精 气 】\\s*(\\d+)\\/\\s*(\\d*)\\s*\\(\\s*(\\d*)\\%\\)\\s*【 精 力 】\\s*(\\d*)\\s*\\/\\s*(\\d*) \\(\\+(\\d*)\\)$") 
        Me.mp, Me.maxmp, Me.pmp, Me.mana, Me.maxmana = tonumber(w[1]), tonumber(w[2]), tonumber(w[3]), tonumber(w[4]), tonumber(w[5]) 
        l, w = wait.regexp("^【 气 血 】\\s*(\\d+)\\/\\s*(\\d*)\\s*\\(\\s*(\\d*)\\%\\)\\s*【 内 力 】\\s*(\\d*)\\s*\\/\\s*(\\d*) \\(\\+(\\d*)\\)$") 
        Me.hp, Me.maxhp, Me.php, Me.force, Me.maxforce, Me.enforce = tonumber(w[1]), tonumber(w[2]), tonumber(w[3]), tonumber(w[4]), tonumber(w[5]), tonumber(w[6]) 
        l, w = wait.regexp("^【 食 物 】\\s*(\\d*)\\/\\s*(\\d*)\\s*【 潜 能 】\\s*(\\d*)\\s*$") 
        Me.food, Me.maxfood, Me.pot = tonumber(w[1]), tonumber(w[2]), tonumber(w[3]) 
        l, w = wait.regexp("^【 饮 水 】\\s*(\\d*)\\/\\s*(\\d*)\\s*【 体 会 】\\s*(\\d*)\\s*$") 
        Me.water, Me.maxwater, Me.tihui = tonumber(w[1]), tonumber(w[2]), tonumber(w[3]) 
        l, w = wait.regexp("^【 等 级 】\\s*(\\d*)\\s*【 经 验 】\\s*(\\d*)\\s*$") 
        Me.level, Me.exp = tonumber(w[1]), tonumber(w[2]) 
        wait.regexp ("^(> )*设定环境变数:keep_idle = \"hp\"$") 
        if f then f() end 
end 
 
以上代码看起来密密麻麻的,但实际上稍微有点悟性的同学都能一眼看出,这个函数其实就是获取hp命令输出的人物各种状态,然后回调 f 这个函数,如果有的话。也就是说,你在机器的任意一个地方,如果调用了 Me.check_state() 的话,那么得到了人物的各种状态。 这个函数其实没什么要说明的,无法就是一行行获取信息罢了。 
 
再来看一段代码: 
 
Me.heal = function(f) 
        if Me.pmp < 95 then 
                Execute("yun inspire") 
                wait.regexp ("^[> ]*(你现在精神饱满,有什么好激励的?|.*缓缓睁开双目,精光四射,神清意爽。)$") 
        end 
        if Me.php < 90 then 
                repeat 
                        Execute("halt;yun heal") 
                        local l, w = wait.regexp("^[> ]*你现在气血充盈,不需要疗伤。$", 1) 
                until l 
        end 
        if Me.mp < Me.maxmp - 1000 then Execute("yun regenerate") end 
        if Me.hp < Me.maxhp - 1000 then Execute("yun recover") end 
        if Me.mana < Me.maxmana - 1000 then Execute("yun refresh") end 
        if f then f() end 
end 
 
以上代码比check_state要清爽多了,相信大家都看出来了,就是在人物受伤之后自动疗伤。 
 
以上代码保存在 Me.lua 文件里面,然后在各机器里面引用进来 
<include name="Me.lua"/> 
这样,,我们就可以在机器的任意地方做如下调用了: 
 
        Me.check_state(function() 
                Me.heal() 
        end) 
 
这段代码更简单了吧,就是先检查状态,然后有精伤的疗精,有血伤的疗伤!在任意机器,任意地方都可以调用!简直是一劳永逸啊!也就是说只要像Me.lua这样的共通函数足够的,新建一个完成新功能的机器也就是分分钟的事儿! 
 
继续帖Me.lua里面的函数 
 
Me.eat = function(feat, buy) 
        if feat or Me.food < Me.maxfood then 
                Execute("eat gan liang") 
                Me.noFood = mywait({"你身上没有.*?这样东西.*"}, {"你摸出一块干粮啃了几口。", "你已经吃太饱了,再也塞不下任何东西了。"}, {"没有"}) 
        end 
        if feat or Me.water < Me.maxwater then 
                Execute("drink shui dai") 
                Me.noWater = mywait({"你身上没有.*?这样东西.*"}, {"你拿起牛皮水袋咕噜噜地喝了几口清水。", "你已经喝太多了,再也灌不下一滴水了。"}, {"没有"}) 
        end 
        if Me.noFood or Me.noWater then 
                if buy then 
                        Execute("r gc;n;n;e") 
                        if Me.noFood then Me.buy("20 gan liang", "xiao er") end 
                        if Me.noWater then Me.buy("shui dai", "xiao er") end 
                        Execute("w;s;s") 
                        wait.time(0.5) 
                end 
        end 
end 
 
这段代码,相信我不解释,大家都看出来了,功能即使吃饭喝水,根据所传参数,可以去自动买食物和水,当然也可以不买(如果人物在副本里) 
 
在各机器机器里面的用法: 
 
        Me.check_state(function() 
                Me.eat(false, false)    -- 检查状态,该吃喝就吃喝,没有东西就先饿着,例如在副本等不方便买东西的地方 
        end) 
        Me.check_state(function() 
                Me.eat(false, true)    --  检查状态,该吃喝就吃喝,没有东西就去买 
        end) 
        Me.check_state(function() 
                Me.eat(true, true)  --  检查状态,强制吃喝强制买,适用于机器开始,确保开始后身上带着食物和水 
        end) 
 
 
看到这里,聪明的同学应该已经想到了,更加完善的调用方式应该是酱紫的: 
 
        Me.check_state(function() 
                Me.heal()   -- 检查状态之后先疗伤 
                Me.eat(false, false)  -- 然后吃喝 
        end) 
 
有了共通的Me.lua之后,只需要加入这么一点点代码,你就能在自己的机器里面拥有自动疗伤自动吃喝的功能了! 
 
细心的同学应该发现了,买东西调用的是Me.buy这个函数,下面就来看看买东西的代码: 
 
Me.buy = function(b, s) 
        Execute("give " .. b .. " to " .. s) 
        if mywait({"你身上没有.+?这样东西。", "你没有那么多的.+?。"}, {"你拿出.*给.*。"}, {"没有"}, {"你拿出"}) then 
                myrepeat("buy " .. b .. " from " .. s, {".+?不耐烦道:“没看见我这儿正忙着么?”"}, {"你从.+?那里买下了.+?。"}, {"不耐烦道:“没看见我这儿正忙着么?”"}, {"买下了"}, 1) 
        end 
end 
 
买东西也很简单,先把东西给seller(防止重复买),如果身上有就不买了,身上没有就反复买,直到买成功为止! 
强烈BS巫师雇佣的店小二体力太弱!买个东西要忙半天! 
 
有了这个Me.buy函数,之前自动买食物和水的功能就能实现了。不仅仅是这样,其它类型的机器里面,例如帮派机器,独孤机器,task机器等都要买东西,这个函数就都可以代劳了! 
注:如果卖家是容易被杀的npc,那么buy前要判断该npc是否存在,这个以后再说。 
 
到这里为止,机器的辅助都差不多了,初期买食物和水,在核心节点检查状态并疗伤+吃喝,这些功能任意一个全自动机器都是必须的!有了Me.lua这个共通的代码库,在自己任意一个机器里面都能通过简单地添加几行代码就能拥有这个功能! 
 
本帖先告一个段落,后续在帖关于战斗的部分。 
 
 
 |