本帖最后由 381676420 于 2016-2-10 19:26 编辑
作为整个教程的最后一层,在这里放上一个完整的武林师门机器人。提供大家使用跟研究。先来看整个机器人的运行结果--------------------------------------------------------------------------------------------
以上图片的运行结果,是没有加入hp判断的,下面给出的机器人实际是加了判断的,所以你们如果运行,可能结果会跟图片不一样哈。
-------------------------------------------------------------------------------------------------------
下面我们直接放出整个代码部分
————————————————————————————————————————
首先我们需要建立一个任务地点,以及抵达地点的数组,代码如下
path_sm = { -- 坑爹的路径数组,如要修改注意格式。
["洛阳城南城根"] = {
"r luoyang;s;s;s;s;s;s;s;s;w;w;w;w;nw;n;n;n;n;s;s;s;s;se;e;e;e;e;e;e;e;n;n;n;n;e;n;s;w;s;s;s;s;e;ne;n;n;n;n;n;n;s;s;e;e;w;w;w;w;w;w;w"
},
["洛阳城内城南门"] = {
""
},
["洛阳城内城西门"] = {
""
},
["洛阳城内城北门"] = {
""
},
["洛阳城内城东门"] = {
""
},
["洛阳城兰薪寺"] = {
""
},
["洛阳城茅草屋"] = {
""
},
["洛阳城牢房"] = {
""
},
["洛阳城洛阳中心广场"] = {
""
},
["华山附近平心石"] = {
""
},
["华山附近广场"] = {
""
},
["华山附近西村口"] = {
""
},
["华山附近打谷场"] = {
""
},
["开封城朱雀门"] = {
""
},
["开封城州桥"] = {
""
},
["开封城延庆观"] = {
""
},
["开封城山陕甘会馆"] = {
""
},
["开封城南盈门"] = {
""
},
["开封城放生池"] = {
""
},
["中州城市中心"] = {
“"
},
["中州城中州南门"] = {
""
},
["中州城中州北门"] = {
""
},
["中州城延陵东路"] = {
""
},
["中州城延陵东路"] = {
""
},
["中州城西城楼"] = {
""
},-
["昆明城南大街"] = {
""
},
["昆明城红土路"] = {
""
},
["昆明城小西门"] = {
""
},
["昆明城小路"] = {
""
},
["荆州城荆州中心"] = {
""
},
["荆州城荆州南门"] = {
""
},
["荆州城温泉井"] = {
""
},
["荆州城紫竹林"] = {
""
},
["南海一带南海渔村"] = {
""
},
["扬州城南门"] = {
""
},
["扬州城西门"] = {
""
},
["扬州城北门"] = {
""
},
["扬州城东门"] = {
""
},
["兰州城中央广场"] = {
""
},
["兰州城兰州南门"] = {
""
},
["兰州城兰州西门"] = {
""
},
["长安城长安东城门"] = {
""
},
["长安城长安南城门"] = {
""
},
["长安城长安西城门"] = {
""
},
["长安城长安北城门"] = {
""
},
["长安城青龙街"] = {
""
},
["长安城白虎街"] = {
""
},
["武功镇西街"] = {
""
},
["武功镇南街"] = {
""
},
["佛山一带西镇街"] = {
""
},
["佛山一带南门"] = {
""
},
["汝州一带汝州城"] = {
""
},
["嵩山一带天中阁"] = {
""
},
["嵩山一带太室阙"] = {
""
},
["嵩山一带少林寺山门"] = {
""
},
["终南山翠屏谷"] = {
""
},
["终南山柏树林"] = {
""
},
["终南山太乙池"] = {
""
},
["终南山神禾原"] = {
""
},
["终南山半山亭"] = {
""
},
["成都城南大街"] = {
""
},
["成都城青羊宫"] = {
""
},
["成都城北大街"] = {
""
},
["星宿海天山山路"] = {
""
},
[""] = {
""
},
}
由于地点太多,我就不放出全部的来,这个格式大家复制粘贴就可以用,然后自己可以添加,我没有直接给出路径,这个希望大家可以自己去录,毕竟机器人的效率很大一部分原因取决于路径的好坏。我录的不一定最好。
在教大家一个 mush下录制路径的办法,很方便。
如上图这样创建一个Alias 图片主要看选项,具体的我都会用可复制的形式写出来
别名(A) 的内容为 ^(.*)$
发送(S) 的内容为
Send("%1")
for i, v in pairs(direction) do --direction是一个数组
if "%1" == v then
utils.appendtonotepad("遍历记录", "%1" .. ";")
break
end
end
在给出direction数组代码 这代码是在脚本中的哦
direction = {
"n",
"s",
"w",
"e",
"ne",
"se",
"sw",
"nw",
"nu",
"nd",
"su",
"sd",
"wu",
"wd",
"eu",
"ed",
"u",
"d",
"enter",
"out",
}
-------------这样使用起来的好处是,在游戏里只有输入数组中存在的元素时,才会被记录下来存入一个记事本中。大家复制下来,去使用下就知道了。
有了路径,我们就可以让机器人按我们的意愿跑起来了。特别声明:由于这个机器人,我本人还想日后继续添加更多的功能进去,所以没有封装成插件,你们复制粘贴的使用没有问题,但是记住 需要手动改变量。
我先给出变量的图片截图,在一一说明
大家在使用的时候,复制这些代码之前,我建议就先在mush中创建好这些变量。missB是定位用的10B请自己填写自己的,pfm1为使用的绝招自己填写, masteEN是师门NPC的ID根据自己情况填写。bianli_i这个变量,在第一次创建的时候另其值为1,以后就不用再管了。其他没有写到的变量,都是会自己抓取的,只需要创建出来,不用赋值。放在那里就可以。
---------------------------------------------------------------------------------------------
下面我在给出所有在mush下的触发器内的内容:
这就是全部用到的触发,其实3个触发配合脚本就可以完美的运行了,只是考虑到要发送出来给大家用,所以添加了判断气血的部分,我个人做师门是不需要判断气血的。下面我写出每条触发的内容,请注意每个触发的选项,组名,名称部分
---------------------------
匹配行 @npcCN\(@npcEN\)
发送 行
EnableTrigger("sm_go", false)
Execute("follow " .. GetVariable("npcEN"))
kill()
--------------------------------------------------------
匹配行 \"go\_next\"$
发送行
SetVariable("bianli_i", GetVariable("bianli_i") + 1)
wait.make(function()
wait.time(0.1)
bianli()
end)
-----------------------------------------------------------------
匹配行 ^[> ]*\S+对你道:(.*)\((.*)\).*听说他最近在(.*)附近.*$
发送行
SetVariable("npcCN", "%1")
SetVariable("npcEN", "%2")
SetVariable("city_place", "%3")
print("【任务NPC名:】" .. "%1" .. " 【任务NPCID: 】" .. "%2" .. " 【NPC所在地点:】" .. "%3")
Goto_Find_NpcSM()
----------------------------------------------------------------------------------------------------------------
匹配行 【 精 气 】\s+\d+\/\s+\d+\s+\((.*)\%\)\s+【 精 力 】\s+\d+\s+\/\s+\d+\s+\(\+.*\)\n【 气 血 】\s+\d+\/\s+\d+\s+\((.*)\%\)\s+【 内 力 】\s+\d+\s+\/\s+\d+\s+\(\+.*\)\Z
发送行
print("%1", "%2")
SetVariable("jingqi", "%1")
SetVariable("qixue", "%2")
HP()
这里注意下哦,这个是个多行匹配,我只抓取了百分比的数字作为判断健康度。
-------------------------------------------------------------------------------------
匹配行 [> ]*你缓缓睁开双目,精光四射,神清意爽。
发送行
if tonumber(GetVariable("jingqi")) < 60 then
Execute("yun heal")
else
EnableTrigger("hp_1", false)
EnableTrigger("hp_2", false)
EnableTrigger("hp_3", false)
Execute("hp")
end
------------------------------------------------------------------------------------------
匹配行 [> ]*你运功完毕,吐出一口瘀血,自觉经脉顺畅,内伤尽去,神元气足地站了起来。
发送行
if tonumber(GetVariable("qixue")) < 60 then
Execute("yun heal")
else
EnableTrigger("hp_1", false)
EnableTrigger("hp_2", false)
EnableTrigger("hp_3", false)
Execute("hp")
end
-------------------------------------------------------------------
匹配行 ^[> ]*.*对你说道:你今天的任务份额已经领完了,你还是自己锻炼一段时间吧。$
发送行
EnableGroup("师门", false)
print("今日可领任务完成")
还有一个计时器
发送行
Execute("yong " .. GetVariable("pfm1") .. " " .. GetVariable("npcEN"))
还有个Alias
发送行
EnableGroup("师门", true)
EnableTrigger("sm_go", true)
Execute("miss " .. GetVariable("missB") .. ";r family;" .. "quest " .. GetVariable("masteEN"))
--------------------------------------------以上就是全部的触发器内容-------------------------------
下面给出所有配合使用的代码,复制粘贴在你的新建脚本中 外加路径齐全,你就可以跑起来了,效率还是不错的
脚本头需要调用wait
require "wait"
--如果需要打印数组,还需要调用tprint
require "tprint"
function Split(szFullString, szSeparator) --把字符串形式的路径(n;e;s),转换成数组。
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
function Goto_Find_NpcSM() --接到任务后,给lj变量赋值,这个值是已转换成数组形式的路径
lj = {} --每次进入函数,初始化数组。
for i, v in pairs(path_sm) do --遍历path_sm数组。
if i == GetVariable("city_place") then --判断任务地点是否存在于数组中
lj = Split(path_sm[GetVariable("city_place")][1], ";") --给lj赋值已转换的路径数组。注意:此时lj是一个数组
break --跳出循环,减少计算量(不跳出也无所谓)
end
end
if next(lj) == nil then
print("没有任务地点,或者任务地点没有路径,请补充")
else
SetVariable("bianli_i", 1) -- 走路计数器变量赋值1,行走的关键,如果不是1会造成错误。
EnableTrigger("sm_go", true) --打开sm_go的触发器,行走前准备
print("六秒后出发前往:★ " .. GetVariable("city_place") .. " ★》》《《击杀:【 " .. GetVariable("npcCN") .. "(" .. GetVariable("npcEN") .. ") 】")
wait.make(function() -- 携程
wait.time(6) -- 等待六秒秒后出发。
Execute("miss " .. GetVariable("missB")) -- 游戏中的定位10B请在mush变量下,手动修改missB变量。
bianli() --在函数中调用另外一个函数,开始行走。
end)
end
end
等待6秒出发的原因是,防止一过去,碰见npc就刚准备杀,npc离开了,然后就不停的pfm,可是没人,而且就算follow了,一旦准备打,npc跑了, follow了也没什么用,我测试了好多次,不知道为什么。所以干脆等时间长点,让npc不在走动以后,在前进,这个数字自己可以调整。----------------------------------------------------------------------------------------------------
function kill() --看函数名字就知道什么意思咯。^_^
EnableTrigger("find_npc", false) --关闭find_npc触发器
Execute("kill " .. GetVariable("npcEN"))
EnableTimer("pfm", true) --打开pfm计时器
wait.make(function() --携程
local l, w = wait.regexp("[> ]*" .. GetVariable("npcCN").."扑在地上挣扎了几下,腿一伸,口中喷出几口鲜血,死了!") -- 用这句话来做为触发
EnableTimer("pfm", false)
wait.time(3) -- 等待3秒,可以按照个人不同需求进行修改。
--print("开始砍头") --检测是否触发成功,多养成打印的好习惯。
Execute("cut " .. "head " .. "from " .. "corpse")
local l, w = wait.regexp("[> ]*.*一下子(把|就把)" .. GetVariable("npcCN") .. "的尸体的头给砍下来。")
wait.time(5) -- 等待5秒,可以按照个人不同需求进行修改。
--print("砍头结束") --检测是否触发成功,多养成打印的好习惯
Execute("apply yanwu dan;" .. "miss " .. GetVariable("missB") .. ";r family;" .. "give " .. GetVariable("masteEN") .. " head")
local l, w = wait.regexp("[> ]*你拿出" .. GetVariable("npcCN") .. "的人头.*$")
EnableTrigger("hp_1", true)
EnableTrigger("hp_2", true)
EnableTrigger("hp_3", true)
wait.time(2)
EnableTrigger("find_npc", true)
Execute("hp")
--Execute("hp;" .. "quest " .. GetVariable("masteEN"))
end)
end
最后一个等待5秒是为了防止,有时候战斗时候有3个npc,砍头以后,还在战斗,会造成你现在很忙这样的提示,我这里是偷懒,不愿意更精细的处理,所以等待时间长点算了,有能力的可以自己写个触发,来解决这个问题。
--------------------------------------------------------------------------
function HP() --判断气血的函数,没什么好说的
local jingqi, qixue = tonumber(GetVariable("jingqi")), tonumber(GetVariable("qixue"))
--print(jingqi, qixue)
if jingqi < 60 then
Execute("yun inspire")
elseif qixue < 50 then
Execute("yun heal")
else
EnableTrigger("hp_1", false)
EnableTrigger("hp_2", false)
EnableTrigger("hp_3", false)
Execute("quest " .. GetVariable("masteEN"))
end
end
- function bianli() --走路用的家伙
- --print("lj变量的值:" .. table.concat(lj, ";")) ----检测lj的值是否被传了进来
- local i=tonumber(GetVariable("bianli_i"))-------bianli_i是个计数器,表明现在走到数组的哪一个元素了。
- if lj[tonumber(GetVariable("bianli_i"))] == nil then
- Note("----遍历【" .. GetVariable("city_place") .. "】完成。未找到目标,请检查或补充路径----")
- return
- end -------数组遍历完成之后就不要遍历了再
- local s1="当前行走段一共"..tostring(table.getn(lj)).."步,现在为 第"..GetVariable("bianli_i").."步"..",当前命令:"..lj[i]
- Note(s1)---------以上两行是用来提醒自己的。
- Execute(lj[i] .. ";set auto_drinkout go_next")------这才是行走的命令。
- end
复制代码
重要代码部分我都做了十分详细的注释,应该是可以看懂吧。
另外如果你们复制上面的代码。在游戏中运行的时候,跟我一开始的图片会有点小小的出入,图片上可以看到有”当前行走段一共41步,现在为 第26步,当前命令:east“这样的东西,你们用的时候就会变成”当前行走段一共41步,现在为 第26步,当前命令:e“这样,不影响使用的,我自己有两个转换路径的函数,所以显示后的结果不一样,那两个函数都没什么大用,所以我就不放出来,不用纠结。
机器人整体思路没有什么出彩的地方,更好的思路有,但是代码写起来太麻烦了,我容易晕,所以选择简单粗暴的。男人么,你们懂的!!哇哈哈
整个机器人这样就算是彻底的完成了,不知道武林的世界里,有多少小伙伴会去尝试上面这些东西。。
---------------------------------------------------------------------------------------------------------------------------------
这篇教程就到这里结束吧,我自己都没想到能写这么多东西。由于懒癌晚期的关系,这样一个完整的mush机器人,或者说一个完整的可以面向广大玩家使用的mush机器人,肯定不会再写了哈。
希望大家都赶紧使用mush吧
PS:重要的事说三遍是惯例,坐等mush大神机器人,我是伸手党
PS:重要的事说三遍是惯例,坐等mush大神机器人,我是伸手党
|