常言笑的家

          Spring, Hibernate, Struts, Ajax, RoR

          ZMUD機(jī)器人制作(上篇)

          目錄

          第一章 聊聊zmud和機(jī)器人

          基礎(chǔ)篇
          第二章 機(jī)器人的核心靈魂
          第三章 variable和alias的初級(jí)應(yīng)用以及#if
          第四章 實(shí)際例子-打坐吐納機(jī)器人

          中級(jí)篇
          第五章 按鈕﹑系統(tǒng)變量和函數(shù)
          第六章 variable和alias的更多應(yīng)用
          第七章 掌控時(shí)間
          第八章 提高機(jī)器人穩(wěn)定性和適用面
          第九章 豐富你的機(jī)器人
          第十章 實(shí)際例子--朝廷守門機(jī)器人
          補(bǔ)充章 Path的用法

          高級(jí)篇
          第十一章 variable和alias的進(jìn)一步應(yīng)用
          第十二章 遍歷實(shí)現(xiàn)的一種方法
          第十三章 胡一刀和推車全自動(dòng)的可行性分析
          第十四章 實(shí)際例子--解決亂入的2種辦法

           

          第一章 聊聊zmud和機(jī)器人

          本章不涉及機(jī)器人制作的實(shí)際方法,但是卻是最重要的,所以我想放在第一位置來(lái)說(shuō)。

          1.1 Zmud的優(yōu)缺點(diǎn)

          如果你要問(wèn)我?guī)卓钪髁鱩ud工具zmud,cmud,mush哪個(gè)最好?我的回答肯定是mush。

          mush擁有強(qiáng)大的腳本功能,即使不用腳本,也能做出很復(fù)雜的機(jī)器人,從穩(wěn)定性上來(lái)說(shuō),mush也明顯比zmud好。可以說(shuō),凡是zmud能做到的,用mush都能做到。可是mush不適合大多數(shù)人,如果你完全不懂mush,簡(jiǎn)單的正則表達(dá)式都能讓你頭暈,更不用說(shuō)它的腳本語(yǔ)言了。

          而zmud最大的優(yōu)點(diǎn)就是簡(jiǎn)單,簡(jiǎn)單就容易流行。即使你隨便亂寫,它也不會(huì)報(bào)錯(cuò),它總有辦法執(zhí)行下去,實(shí)在執(zhí)行不了,最多也就zmud程序本身崩潰掉。他的語(yǔ)言相當(dāng)靈活,你可能會(huì)有多種辦法來(lái)實(shí)現(xiàn)你的計(jì)劃,這點(diǎn)我會(huì)在后面章節(jié)的實(shí)際例子中盡量涉及到。就目前來(lái)說(shuō),zmud提供的功能已經(jīng)足夠玩mud游戲。

          zmud最讓人頭疼的問(wèn)題就是對(duì)中文的支持不好,某些漢字的截取或者顯示會(huì)變成亂碼,給機(jī)器人的制作帶來(lái)麻煩。出現(xiàn)了亂碼問(wèn)題,只能自己想辦法解決了,絕大多數(shù)還有辦法對(duì)付的。
          另外zmud462和555的tick timer會(huì)在多個(gè)窗口之間發(fā)生干擾,所以設(shè)置tick timer的時(shí)候要統(tǒng)一,等講到tick timer的時(shí)候再詳細(xì)說(shuō)。

          1.2 優(yōu)秀機(jī)器人的充分必要條件

          好的機(jī)器人應(yīng)該具備幾個(gè)條件,從游戲本身來(lái)考慮,非要做個(gè)排名的話,我認(rèn)為應(yīng)該是安全穩(wěn)定效率適用面廣,當(dāng)然如果你還能做到界面豐富生動(dòng)簡(jiǎn)潔易修改等等那更好了。

          從另外一個(gè)方面考慮,好的機(jī)器人應(yīng)該具備一些職業(yè)道德。響應(yīng)冰冰同學(xué)的號(hào)召,不要在chat,rumor等公共頻道發(fā)無(wú)聊的信息,也不要隨意say和emote,不要隨意的get all,不要對(duì)別人做表情,不要刷屏等等。游戲環(huán)境還是要靠大家共同維護(hù)

          1.3 機(jī)器人制作的良好習(xí)慣

          如果你養(yǎng)成了良好的習(xí)慣,將會(huì)節(jié)約你大量的時(shí)間,避免重復(fù)勞動(dòng)。
          使用variable和alias的時(shí)候,為變量取名字一定要含義清楚,否則時(shí)間長(zhǎng)了連你自己都會(huì)忘記,不易于修改。

          盡量為每個(gè)trigger設(shè)置class,相近的trigger歸到一個(gè)class,class取名同樣要含義清楚,以方便其他的機(jī)器人加載。

          對(duì)于用的多的一些trigger,variable和alias,可以點(diǎn)擊菜單Settings->Export專門保存起來(lái),要用的時(shí)候再點(diǎn)擊Settings->Import->Script加載就可以了。

          1.4 尋求幫助
          語(yǔ)法格式忘記了,或者不知道用法,請(qǐng)優(yōu)先使用zmud自帶的help文檔,這才是最全面最權(quán)威的教程。在命令欄輸入#help就能打開(kāi)了。還可以有針對(duì)性地輸入比如#help while,#help exe,#help if來(lái)查找。
          第二章 機(jī)器人的核心靈魂

          2.1 觸發(fā)triggers

          一個(gè)機(jī)器人什么都可以沒(méi)有,就是triggers不能沒(méi)有,所以稱它為機(jī)器人的靈魂一點(diǎn)沒(méi)錯(cuò).機(jī)器人都是靠triggers來(lái)作出反應(yīng)的.

          你可以從菜單里打開(kāi)你的triggers,也可以點(diǎn)擊那個(gè)手槍的圖標(biāo)來(lái)打開(kāi)triggers.然后點(diǎn)擊new來(lái)新建一個(gè)trigger,你會(huì)發(fā)現(xiàn)trigger有四個(gè)要素:Pattern﹑Commands﹑Enable/Disable和Class

          Zmud根據(jù)Pattern的內(nèi)容來(lái)做出反應(yīng),簡(jiǎn)單點(diǎn)說(shuō)只要你的屏幕上出現(xiàn)了跟Pattern一致的內(nèi)容,Commands里的內(nèi)容就作為命令發(fā)送出去了。Enable表示這個(gè)trigger是激活狀態(tài),Disable表示trigger不激活,處于無(wú)效狀態(tài)。Class表示這個(gè)trigger所屬的類,可以通過(guò)操作整個(gè)類來(lái)達(dá)到一次性同時(shí)操作多個(gè)trigger的目的。

          另外trigger還有Options和Test,Zmud721中還有States
          Test是用來(lái)測(cè)試觸發(fā)的,實(shí)際用處不大,trigger制作熟練了很少會(huì)測(cè)試。
          Options里默認(rèn)的勾上的幾個(gè)選項(xiàng)就是平時(shí)用到的。沒(méi)勾上的幾個(gè)除了alarm之外用處都不大,alarm我會(huì)在以后講到;Temporary是用來(lái)建立一個(gè)一次性trigger,用完就扔的那種,命令是#temp,但是我更喜歡用#t+ #t-來(lái)達(dá)到這個(gè)目的;Expression是建立一個(gè)表達(dá)式trigger,沒(méi)什么用;顏色觸發(fā)也不像期待中的那樣強(qiáng)大,有興趣可以自行研究。

          2.2 字符串匹配
          簡(jiǎn)單點(diǎn)說(shuō)就是通過(guò)幾個(gè)特殊的符號(hào)來(lái)代表具有某些共同之處的一類信息。只被用于Pattern。
          zmud提供的字符號(hào)串匹配有:
              *     通配任何數(shù)字、字符或空白
              %d 通配任何數(shù)字(0-9)
              ?  通配任何單個(gè)字符
              %s 通配任何空白(spaces,tabs)
              %w 通配任何字母(a-z)
              %a 通配任何數(shù)字和字母(等于%d+%w)
              %n 通配任何以+或-開(kāi)頭的數(shù)字
              %x 通配任何非空白
              %p 通配一個(gè)方向
              [range] 通配任何在range范圍內(nèi)的字符
              ^ 表示一行的開(kāi)頭,想要你的trigger在一行的開(kāi)頭才有效,就在最前面加上這個(gè)
              $ 表示一行的結(jié)尾。
              (pattern)將括號(hào)里面的內(nèi)容依次存放在參數(shù)%1~%99里
              {val1|val2|val3|……} 通配val1,val2或者val3
              還有一個(gè)特殊字符就是~,用在特殊字符前面。因?yàn)橛行┨厥庾址粃mud理解為其他意思了,所以為了通配這些特殊字符,前面要加~
              比如~{通配{     ~?通配?      ~~通配~
          在命令行輸入#say %def,默認(rèn)顯示為#;@!%.:~>&,再加上括號(hào){}()[],這些都是有特殊含義的特殊字符了,要匹配這些字符,前面都要加上~

          關(guān)于字符串匹配,主要就是這些了,而真正常用的就幾個(gè),上面標(biāo)記為藍(lán)色的是我用過(guò)的,這些就夠了,其余的一次都沒(méi)用過(guò)。所有的這些都可以在zmud幫助文檔里查到。

          實(shí)例一:#tri {□手持一個(gè)圣火令~(Shenghuo ling~)} {#say 明教武士}
          //#tri表示用命令新建一個(gè)trigger,第一個(gè)花括號(hào)里的內(nèi)容作為Pattern,第二個(gè)花括號(hào)里的內(nèi)容作為Commands
          //這里用到~(來(lái)通配(

          實(shí)例二:#tri {【%s氣血%s】%s(%d)%s/%s(%d)%s~[(*)~%~]%s【%s內(nèi)力%s】%s(%d)%s/%s(%d)} {#show %1 %2 %3 %4 %5}
          //依次顯示出你的氣血 氣血最大值 受傷狀況 內(nèi)力 內(nèi)力最大值
          //如上面講過(guò)的,()的作用是把里面的內(nèi)容按順序依次保存在臨時(shí)參數(shù)%1~%99里

          上面2個(gè)例子分別用到了zmud提供的2個(gè)命令#say#show,功能差不多顏色不同,都只是在屏幕上顯示某些內(nèi)容用的,這些內(nèi)容不作為命令發(fā)送給服務(wù)器執(zhí)行,但是zmud會(huì)用這些內(nèi)容來(lái)觸發(fā)trigger,所以做機(jī)器人的時(shí)候可以用這個(gè)來(lái)做觸發(fā),好處可以自行體會(huì)。

          建議:做Pattern的時(shí)候不要手動(dòng)輸入,因?yàn)橹形挠⑽陌虢侨歉鞣N特殊字符還有空格符,你的手動(dòng)輸入很可能不正確,等整個(gè)機(jī)器人做成功了查錯(cuò)又不容易。所以盡量用粘貼的,然后先把里面的空格全部換成%s,把所有的特殊字符前面都加上~,要怎么通配的就換成什么通配,最后看要不要頂行觸發(fā)或者結(jié)尾觸發(fā),這樣一般不會(huì)有錯(cuò)了。

          2.3 Class和#t+ #t-的用途

          Class有好幾個(gè)用途,比如為了方便Import,點(diǎn)擊Settings->Import->settings,然后選擇一個(gè)機(jī)器人,再選擇一個(gè)Class點(diǎn)擊Add-OK就可以把另外一個(gè)機(jī)器人里面所有歸為某個(gè)Class的triggers,variablde,alias等都添加到當(dāng)前機(jī)器人里面。如果刪除某個(gè)Class,那么該Class下的所有元素全部刪除。

          #t+和#t-分別是激活和關(guān)閉某類trigger。#t+和#t-都是針對(duì)Class的名字來(lái)操作,所有的variable,alias,trigger,button都可以取一個(gè)class名字,但是只有trigger才有Enable/Disable狀態(tài),所有#t+/#t-只對(duì)trigger有效。這2個(gè)命令被廣泛的應(yīng)用與機(jī)器人制作中,非常重要。

          實(shí)例三:某些trigger只希望它在特定的時(shí)候激活,其他時(shí)候都處于關(guān)閉狀態(tài),用來(lái)防止誤觸發(fā),這時(shí)候用#t+ #t-是最適合不過(guò)的了。
          #tri {你向林震南打聽(tīng)有關(guān)『*鏢』的消息。} {#t+ job}
          #tri {林震南說(shuō)道:「你上次運(yùn)鏢太辛苦了,下去休息休息吧。」} {#t- job;#wa 5000;ask lin about job} {job}
          //這里第2個(gè)trigger設(shè)置了一個(gè)class:job,平時(shí)都處于disable狀態(tài),只有當(dāng)你向林要任務(wù)的時(shí)候才開(kāi)啟,并且在trigger觸發(fā)之后立刻關(guān)閉。
          如果你不這樣做,當(dāng)別人來(lái)要任務(wù)也要不到的時(shí)候會(huì)出現(xiàn)同樣的觸發(fā)信息從而誤觸發(fā)。游戲里好多機(jī)器人同時(shí)跟林要任務(wù),互相干擾,結(jié)果就變成要任務(wù)比賽了。那么恭喜你,你的機(jī)器人是個(gè)流氓,刷屏!
          第三章 variable和alias的初級(jí)應(yīng)用以及if語(yǔ)句

          3.1 Variable和Alias

          相關(guān)命令 #var,#math,#add,,#alias
          北俠眾應(yīng)該都知道Alias的用法吧,論壇和主頁(yè)下載的zmud包里都有前輩做好的路徑,要去哪里簡(jiǎn)單的輸入地名的拼音就可以了。
          Alias就是別名,用一個(gè)短命令替代一串長(zhǎng)命令

          另外Alias還可以帶參數(shù)使用
          實(shí)例一:#alias {chan} {wield sword;perform sword.chan %1 %2;unwield sword}
          這樣就制作一個(gè)alias,下面分別是4種使用結(jié)果
          A: chan          相當(dāng)于輸入wield sword;perform sword.chan;unwield sword
          B: chan wushi    相當(dāng)于輸入wield sword;perform sword.chan wushi;unwield sword
          C: chan zhang san相當(dāng)于輸入wield sword;perform sword.chan zhang san;unwield sword
          D: chan 1 2 3    相當(dāng)于輸入wield sword;perform sword.chan 1 2;unwield sword 3
          可以看到,無(wú)論你帶不帶參數(shù),帶幾個(gè)參數(shù),zmud都不報(bào)錯(cuò),他都按照他自己固定的理解來(lái)執(zhí)行你的命令,2個(gè)參數(shù)以內(nèi)的依次替換成%1 %2,多余的參數(shù)全部放在最后,沒(méi)有就直接無(wú)視,相當(dāng)?shù)撵`活。

          Variable就是變量,只有用到了變量,才能進(jìn)行各種運(yùn)算,并且根據(jù)運(yùn)算結(jié)果作出不同的反應(yīng)。
          #var為一個(gè)變量賦值,而不管這個(gè)變量存不存在。變量不存在時(shí)新建變量,存在時(shí)改變它的值。
          比如#var abc 100,將100賦值給變量abc,或者說(shuō)abc的值就是100了。另一種賦值方法是abc=100

          變量的值用@加上變量名來(lái)使用和表示。
          例如: #show abc的值是@abc   
                       顯示為 abc的值是100
          #math 用來(lái)計(jì)算,將結(jié)果賦值給變量,zmud只支持+ - * /和()的四則混合運(yùn)算,運(yùn)算優(yōu)先權(quán)是()大于*/大于+ -,并且僅支持整數(shù),如果運(yùn)算結(jié)果不是整數(shù),自動(dòng)進(jìn)行取整運(yùn)算。

          小技巧一:[ ]的運(yùn)用

          [ ]表示運(yùn)算之后結(jié)果,舉例來(lái)說(shuō)
          #var a 100/5;#var b [100/3];#math c 100/3
          #show @a,@b,@c
          顯示結(jié)果為100/3,33,33
          沒(méi)錯(cuò),#var不負(fù)責(zé)運(yùn)算,[]負(fù)責(zé)運(yùn)算,起到了#math的作用。

          小技巧二:&variable和@variable直接用在trigger的Pattern里面

          實(shí)例:如何使用大米a
          #tri {胡一刀說(shuō)道:『我收到消息,聽(tīng)說(shuō)&hydaddress有盜寶人&dbrname~(&dbr~)找到了闖王寶藏的地圖} {}
          #tri {你有種去&hydaddress找我兄弟&dbrname~(&dbr~),他會(huì)給我} {}
          #alias ddd {act hydjob 地點(diǎn)=@hydaddress,name=@dbrname,id=@dbr}
          #tri {盜 寶 人*@dbrname~(@dbr~)} {follow @dbr;hit @dbr}
          可以看到第一個(gè)trigger和第二個(gè)trigger,只有Pattern,沒(méi)有任何Commands
          沒(méi)錯(cuò),&hydaddress,&dbrname,&dbr被用來(lái)做通配了,通配之后被通配的內(nèi)容已經(jīng)自動(dòng)保存到相應(yīng)變量里了,不需要任何賦值操作可以直接使用了。
          命令行輸入ddd就可以在動(dòng)作頻道發(fā)出信息讓大米a去尋找盜寶人了。
          最后一個(gè)trigger,@dbrname,@dbr也被用來(lái)做通配了,只有找到自己的盜寶人才會(huì)觸發(fā)跟隨攻擊命令。
          這種方法又體現(xiàn)了zmud的靈活性,可以省去賦值,也可以省去判斷是否是自己的盜竊人
          另外&和變量名中間可以再加入%d或者%w等特殊字符。比如&{%w}dbr用來(lái)表示僅僅通配字母,并且賦值給變量,不匹配的不會(huì)觸發(fā)并且不會(huì)賦值。

          小技巧三:現(xiàn)在已經(jīng)講了trigger,variable和alias,后面還會(huì)講到button,還有macro,這些都可以互相糅合互相嵌套,任何一個(gè)都可以包含另外一個(gè),也可以自己包含自己,再次體現(xiàn)了zmud的靈活。

          實(shí)例:#Alias jiaxing {do 6 e;se;s;e;e;#var back jiaxingb}
              #Alias jiaxingb {w;w;n;nw;#6 w}
              #ALIAS taohua {#6 e;se;s;e;e;nd;e;e;e;e;n;enter;enter boat;#var back taohuab}
              #ALIAS taohuab {out;s;w;w;w;w;su;w;w;n;nw;#6 w}
              #alias ddd {@back}
          可以看到alias里包含了變量,變量里包含alias,以上4個(gè)alias分別是嘉興和桃花去和回的路徑,但是嫌回來(lái)時(shí)后面加個(gè)b太麻煩了,就用上面這個(gè)方法。不管你是在嘉興還是在桃花,只要去的時(shí)候是用alias去的,回來(lái)的時(shí)候統(tǒng)一用ddd返回。并且不影響jiaxingb,taohuab的使用。

          3.2 if語(yǔ)句 相關(guān)命令#if

          格式:#if 表達(dá)式 {commands1} {commands2}
          當(dāng)表達(dá)式的結(jié)果運(yùn)算為真時(shí),執(zhí)行commands1,否則執(zhí)行commands2

          另2種變化了的格式都可以用
          #if 表達(dá)式 {} {commands2}
          #if 表達(dá)式 {commands1}

          比如:#tri {【%s氣血%s】%s(%d)%s/%s(%d)%s~[(*)~%~]%s【%s內(nèi)力%s】%s(%d)%s/%s(%d)} {#if (%1>500) {dazuo 500} {exert recover;dazuo 500}}
          簡(jiǎn)單的判斷一下氣血值,如果大于500就dazuo 500,否則就先吸氣然后dazuo 500

          #if 可以多重使用,commands1和commands2里面都可以包含一個(gè)或多個(gè)#if
          表達(dá)式也可以是多個(gè)表達(dá)式的組合,多個(gè)表達(dá)式之間用&或者|來(lái)連接。&表示“并且”,|表示“或者”。例如
          ((表達(dá)式1&表達(dá)式2)|表達(dá)式3) 只要表達(dá)式3為真,總表達(dá)式就為真;只要表達(dá)式12同時(shí)為真,總表達(dá)式就為真;其他情況都不真。
          注意事項(xiàng):去掉中間的子括號(hào),(表達(dá)式1&表達(dá)式2|表達(dá)式3)會(huì)造成歧義,zmud不會(huì)報(bào)錯(cuò),具體結(jié)果請(qǐng)自行試驗(yàn)。

          表達(dá)式里通常用到的比較符號(hào)有“>” “<” “=” “!=” “<>” “<=” “>=”,其中!=表示不等于,<>表示大于或者小于
          注意事項(xiàng):表達(dá)式不僅僅是比較數(shù)字,也能比較字符串甚至中文,如有需要可以加上" "
                   比如(@dbr="mengmian shashou"|@dbrname="張三")

          實(shí)例:做一個(gè)機(jī)器人,明教弟子碰到盜寶人先奪兵器直至成功奪掉兵器,然后用陰風(fēng)刀,成功用出1次陰風(fēng)刀之后用tisha來(lái)busy盜寶人,一直到將其殺掉。
          ps.只是舉個(gè)例子,不討論這個(gè)打法的正確性。
          需要解決的困難:自己在busy的時(shí)候,任何perform的結(jié)果都是( 你上一個(gè)動(dòng)作還沒(méi)有完成,不能施用外功。),無(wú)法判斷接下來(lái)的動(dòng)作。
          假設(shè)你已經(jīng)將盜寶人的名字儲(chǔ)存到@dbrname中,將盜寶人的id儲(chǔ)存到@dbr中。
          實(shí)際給出2種制作方案:

          A:#tri {盜 寶 人*@dbrname~(@dbr~)} {follow @dbr;hit @dbr;perform sword.duo @dbr;#var pfm 1}
          //見(jiàn)面奪兵器,注意pfm的值
            #tri {可是@dbrname的看破了你的企圖,立刻采取守勢(shì),使你沒(méi)能奪下兵刃。} {hit @dbr;perform sword.duo @dbr}
          //失敗了繼續(xù)奪
            #tri {你使出圣火神功的奪字訣, @dbrname頓時(shí)覺(jué)得眼前一花,手腕一麻,手中兵刃脫手而出!} {killall @dbr;perform sword.yinfeng @dbr;#var pfm 2}
          //奪掉了武器,陰風(fēng)刀,改變pfm的值
            #tri {你悄悄使出陰風(fēng)刀,運(yùn)起一股無(wú)形無(wú)質(zhì)的陰寒之氣,直插@dbrname胸口玉堂要穴!} {wa 3000;killall @dbr;perform dodge.tisha @dbr;#var pfm 3}
          //繼續(xù)改變pfm的值
          #tri {卻不敢出聲,閉緊雙眼運(yùn)起鐵屁股神功,假裝是一塊石頭一動(dòng)不動(dòng)!} {#wa 3000;perform dodge.tisha}
            #tri {@dbrname雙目難睜,無(wú)法攻擊。} {#wa 3000;perform dodge.tisha @dbr}
            #tri {神目如電來(lái)去悠閑,根本沒(méi)有受到影響.} {#wa 3000;perform dodge.tisha @dbr}
            #tri {~( 你上一個(gè)動(dòng)作還沒(méi)有完成,不能施用外功。~)} {#wa 3000;#if (@pfm=1) {perform sword.duo @dbr};#if (@pfm=2) {perform sword.yinfeng @dbr};#if (@pfm=3) {perform dodge.tisha @dbr}}
          //根據(jù)pfm的值的不同來(lái)發(fā)出不同的perform

          B:#tri {盜 寶 人*@dbrname~(@dbr~)} {follow @dbr;hit @dbr;#var pfm "perform sword.duo";@pfm @dbr}
            #tri {你使出圣火神功的奪字訣, @dbrname頓時(shí)覺(jué)得眼前一花,手腕一麻,手中兵刃脫手而出!} {killall @dbr;#var pfm "perform sword.yinfeng";@pfm @dbr}
            #tri {可是@dbrname的看破了你的企圖,立刻采取守勢(shì),使你沒(méi)能奪下兵刃。} {hit @dbr;@pfm @dbr}
            #tri {你悄悄使出陰風(fēng)刀,運(yùn)起一股無(wú)形無(wú)質(zhì)的陰寒之氣,直插@dbrname胸口玉堂要穴!} {#var pfm "perform dodge.tisha";#wa 3000;killall @dbr;@pfm @dbr}
            #tri {@dbrname雙目難睜,無(wú)法攻擊。} {#wa 3000;@pfm @dbr}
            #tri {神目如電來(lái)去悠閑,根本沒(méi)有受到影響.} {#wa 3000;@pfm @dbr}
            #tri {~( 你上一個(gè)動(dòng)作還沒(méi)有完成,不能施用外功。~)} {#wa 3000;@pfm @dbr}
            
            可以看到方案B明顯優(yōu)于方案A,巧妙的運(yùn)用了一個(gè)變量pfm儲(chǔ)存要發(fā)的perform,而不是簡(jiǎn)單的賦值為一個(gè)數(shù)字,省去了#if語(yǔ)句,更加簡(jiǎn)潔直觀。制作機(jī)器人的時(shí)候能簡(jiǎn)潔堅(jiān)決不要復(fù)雜,會(huì)使你的機(jī)器人更加容易修改。
            #wa 3000表示等待3秒后執(zhí)行后面的命令,有關(guān)#wa命令后面會(huì)講到。
          第四章 機(jī)器人實(shí)例-打坐吐納機(jī)器人

          這個(gè)機(jī)器人的制作非常簡(jiǎn)單,僅僅需要第二章和第三章的知識(shí)就足夠了.但是一個(gè)新手做出來(lái)的機(jī)器人和高手做的比起來(lái)就會(huì)顯得簡(jiǎn)陋.

          實(shí)際制作過(guò)程

          希望機(jī)器人具備的特點(diǎn):穩(wěn)定,效率最大化,適用面最大化,打坐吐納完畢自動(dòng)下線

          A 穩(wěn)定方面:防發(fā)呆,斷線自動(dòng)重連

          B 率最大化方面: (a)1000內(nèi)力或者精力以下充分利用打坐或者吐納雙倍
                                    (b)氣血或精神如果夠,剛好打坐吐納至內(nèi)力精力增加;如果不夠,將氣血精神用完,然后使用恢復(fù)手段
                                    (c)利用休息周30%的提速,并且對(duì)付惡心的噩夢(mèng)周

          C 適用面方面:打坐吐納統(tǒng)一為一個(gè)機(jī)器人,由于內(nèi)力比精力重要,選擇優(yōu)先打坐,內(nèi)力達(dá)到設(shè)定目標(biāo)時(shí)自動(dòng)轉(zhuǎn)化為吐納,同時(shí)可以設(shè)定精力優(yōu)先于內(nèi)力。對(duì)還沒(méi)有脫離發(fā)呆室的未成年人同樣適用。

          步驟一:如果你聽(tīng)從了我的建議,相信你一定制作了4個(gè)專門的trigger來(lái)抓取hp的信息,然后給它們統(tǒng)一取一個(gè)class名并且保存到一個(gè)專門的文件,那么恭喜你,你現(xiàn)在要做的僅僅就是加載這個(gè)文件,去掉經(jīng)驗(yàn)值和潛能抓取的2個(gè)trigger,這一步就完成了。

          #tri {【%s氣血%s】%s(%d)%s/%s(%d)%s~[(*)~%~]%s【%s內(nèi)力%s】%s(%d)%s/%s(%d)}
                   {#var qixue %1
                    #var qixue_max %2
                    #var qixue_health %3
                    #var neili %4
                    #var neili_max %5} {hp}
          #tri {【%s精神%s】%s(%d)%s/%s(%d)%s~[(*)~%~]%s【%s精力%s】%s(%d)%s/%s(%d)}
                   {#var jingshen %1
                    #var jingshen_max %2
                    #var jingshen_health %3
                    #var jingli %4
                    #var jingli_max %5} {hp}


          步驟二:開(kāi)始對(duì)內(nèi)力,精力,氣血,精神進(jìn)行計(jì)算,來(lái)確定dazuo tuna的數(shù)值

          先計(jì)算打坐
          #math need [@neili_max*2+1-@neili]
          //計(jì)算還需要多少內(nèi)力才能使內(nèi)力上限增加
          #if (@neili_max<1000) {#math need (@need+1)/2}
          //內(nèi)力不足1000,需要減半,注意(@need+1)是為了防止/2之后自動(dòng)取整造成結(jié)果不足以使內(nèi)力上限增加
          #var @dazuo [@qixue-(@qixue_max+9)/10]
          //最多能供使用的氣血是@qixue-@qixue_max/10,加9也是為了對(duì)付取整
          #var need [(@need*100+129)/@sudu]
          //通過(guò)一個(gè)變量@sudu來(lái)調(diào)整需要打坐的數(shù)值,+129對(duì)付取整
          #var need %min(@dazuo,@need)
          //%min表示2者之間小的那個(gè)
          #var need %max(@need,10)
          //%max表示2者之間大的那個(gè),最終need的值就是你dazuo的數(shù)值了。注意@dazuo的值可能小于10
          #if (@dazuo<10) {恢復(fù)} {dazuo @need}}
          //氣血不夠恢復(fù),否則dazuo

          再計(jì)算吐納,只需要做少量的修改,用同樣的變量就可以了,盡量減少使用變量的數(shù)目
          #var need [@jingli_max*2-@jingli+1]
          #var need [(@need*100+129)/@sudu]
          #math dazuo @jingshen-(@jingshen_max+9)/10]
          #math need %min(@need,@dazuo)
          #var need %min(@need,10)
          #if (@dazuo<10) {恢復(fù)} {#if ((@neili>500)|(@fadai=0))
                                                     {tuna @need} {dazuo 500}}
          //與打坐的時(shí)候不同,當(dāng)你脫離了發(fā)呆室并且內(nèi)力不夠時(shí),選擇打坐,以確保有足有的內(nèi)力恢復(fù)精神

          步驟三:根據(jù)time的信息來(lái)修改@sudu的值,需要2個(gè)trigger
          #tri {本周為噩夢(mèng)之周*降低*降低(%d)~%} {#var sudu [100-%1]}
          //抓取打坐吐納速度降低的數(shù)值到%1,對(duì)@sudu進(jìn)行修改
          #tri {本周為(*)之周} {#if (%1!="噩夢(mèng)") {#if (%1="休息") {#var sudu 100} {#var sudu 130}}}
          //最前面判斷%1是否=噩夢(mèng),以避免跟第一個(gè)trigger發(fā)生干擾

          步驟四:把步驟二和三合起來(lái)
          #tri {本周為噩夢(mèng)之周*降低*降低(%d)~%}
            {#var sudu [100-%1]
             #if (@neili_max>=@neili_aim) {#var action 0}
          //用@action的值來(lái)控制行為,值為1就打坐,值為0就吐納
             #if @action {#math need [@neili_max*2+1-@neili]
                             #if (@neili_max<1000) {#math need (@need+1)/2}
                             #var @dazuo [@qixue-(@qixue_max+9)/10]
                             #var need [(@need*100+129)/@sudu]
                             #var need %min(@dazuo,@need)
                             #var need %max(@need,10)
                             #if (@dazuo<10) {恢復(fù)} {dazuo @need}
                          }
                         {#var need [@jingli_max*2-@jingli+1]
                          #var need [(@need*100+129)/@sudu]
                          #math dazuo @jingshen-(@jingshen_max+9)/10]
                          #math need %min(@need,@dazuo)
                          #var need %min(@need,10)
                          #if (@dazuo<10)
                            {恢復(fù)} {#if (@jingli_max<@jingli_aim)
                                     {#if ((@neili>500)|(@fadai=0)) {tuna @need} {dazuo 500}}
                                     {#var zhanghao {};#var mima {};quit}
          //再加入一個(gè)if語(yǔ)句,判斷精力最大值如果沒(méi)有達(dá)到目標(biāo),就吐納,否則清空變量zhanghao和mima的值,然后退出,其中zhanghao和mima中保存著你id的帳號(hào)和密碼,這樣做是為了阻止自動(dòng)連線
                                  }
                         }
              }
          #tri {本周為(*)之周}
            { #if (%1!="噩夢(mèng)") {#if (%1="休息") {#var sudu 100} {#var sudu 130}}
              #if (@neili_max>=@neili_aim) {#var action 0}
              #if @action {#math need [@neili_max*2+1-@neili]
                             #if (@neili_max<1000) {#math need (@need+1)/2}
                             #var @dazuo [@qixue-(@qixue_max+9)/10]
                             #var need [(@need*100+129)/@sudu]
                             #var need %min(@dazuo,@need)
                             #var need %max(@need,10)
                             #if (@dazuo<10) {恢復(fù)} {dazuo @need}
                          }
                         {#var need [@jingli_max*2-@jingli+1]
                          #var need [(@need*100+129)/@sudu]
                          #math dazuo @jingshen-(@jingshen_max+9)/10]
                          #math need %min(@need,@dazuo)
                          #var need %min(@need,10)
                          #if (@dazuo<10)
                            {恢復(fù)} {#if (@jingli_max<@jingli_aim)
                                     {#if ((@neili>500)|(@fadai=0)) {tuna @need} {dazuo 500}}
                                     {#var zhanghao {};#var mima {};quit}
             
                                }
                         }
              }


          步驟五:制作恢復(fù)的方法,dazuo和tuna時(shí)恢復(fù)的方法不一樣,需要if語(yǔ)句來(lái)判斷
          #alias 恢復(fù) {#if @action {#if @fadai {out;fadai} {exert recover;hp;time}}
          //打坐時(shí)的恢復(fù)方法,@fadai用來(lái)指示是否脫離發(fā)呆室,分別采用發(fā)呆和吸氣的方法來(lái)恢復(fù)
                          {#if @fadai {out;fadai} {#if (@neili<500)
                                                      {dazuo 500} {exert regenerate;hp;time}
                                                   }
                           }
          //吐納的恢復(fù)方法,exert regenerate之前要判斷內(nèi)力是否夠用
                      }
          #tri {你發(fā)呆了一會(huì)兒,發(fā)現(xiàn)自己居然精神百倍!} {#wa 1500;enter;hp;time}
          #tri {你吐納完畢,睜開(kāi)雙眼,站了起來(lái)。}
                         {#if @fadai {hp;time} {exert regenerate;hp;time}}
          //能發(fā)呆就不用內(nèi)力恢復(fù),由于吐納之前確定內(nèi)力夠用,是可以吸氣的
          #tri {你運(yùn)功完畢,深深吸了口氣,站了起來(lái)。}
                         {#if @fadai {hp;time} {exert recover;hp;time}}


          步驟六:制作數(shù)個(gè)按鈕來(lái)修改zhanghao,mima,fadai,action,jingli_aim,neili_aim按鈕制作下一章再講,制作技巧則在第八章講到。不制作按鈕也可以手動(dòng)修改。
                
          加入斷線自動(dòng)重連,手動(dòng)修改一個(gè)zmud系統(tǒng)自帶alias
          #alias {atconnect} {@zhanghao;@mima;yes} {System}
          #tri {歡迎來(lái)到北大俠客行!} {w;s;d;#if @fadai {out;fadai} {exert recover;exert regenerate;hp;time}}
          由于網(wǎng)絡(luò)速度的原因,用完發(fā)呆室之后的#wa 1500并不能消除busy
          #tri {你的動(dòng)作還沒(méi)有完成,不能移動(dòng)。} {#wa 1500;enter;hp;time}
          另外機(jī)器人會(huì)由于某些原因中斷,需要一個(gè)辦法來(lái)讓它重新運(yùn)轉(zhuǎn)。這是為了對(duì)付地痞以及網(wǎng)絡(luò)速度等不確定因素,具體辦法我會(huì)在第七章講到。

          至此機(jī)器人已經(jīng)基本制作完成了。這個(gè)實(shí)例旨在拋磚引玉,完全面對(duì)新手,注釋得也特別詳細(xì)。
          本例為了讓新手能學(xué)得更多才做得復(fù)雜些,其實(shí)將未成年人和成年人混在一起并不是很好,會(huì)使機(jī)器人制作難度加大很多,看起來(lái)也很復(fù)雜。
          另外在下一章中會(huì)用函數(shù)的方法將本例的計(jì)算大大簡(jiǎn)化。

          基礎(chǔ)篇至此已經(jīng)結(jié)束了,后面將轉(zhuǎn)到中級(jí)篇,更多的應(yīng)用技巧和實(shí)例將奉獻(xiàn)給大家,請(qǐng)繼續(xù)保持關(guān)注,謝謝!
          中級(jí)篇

          第五章 buttons﹑系統(tǒng)變量﹑function

          5.1 button

          按鈕(buttons)是很實(shí)用的一個(gè)功能,不光應(yīng)用于半自動(dòng)的機(jī)器人讓游戲過(guò)程更加便捷,也用于全自動(dòng)機(jī)器人,讓人為修改某些變量更加簡(jiǎn)單.

          按鈕有3個(gè)要素:Caption,Commands(zmud721中這個(gè)要素被稱為Value)和Class.其中Caption是按鈕的名字,顯示在按鈕中間;Commands保存有一系列命令,當(dāng)你點(diǎn)擊按鈕的時(shí)候,Commands中的內(nèi)容就作為指令發(fā)送出去;Class是按鈕所屬的類,只是為了加載的時(shí)候方便。

          Caption后面的顏色圖標(biāo)可以更改按鈕的顏色,主選項(xiàng)卡Button States里可以選擇按鈕的種類;Postion/Size選項(xiàng)卡里的內(nèi)容可以更改按鈕的大小和位置;Advanced選項(xiàng)卡里Bitmap File可以選擇一個(gè)自定義圖標(biāo)顯示在按鈕上,并且zmud721還有自帶圖標(biāo)供選擇。

          按鈕的種類:一共四種Push﹑Toggle﹑Separator和Multistate
          Push:點(diǎn)擊一下執(zhí)行一次Commands中的命令
          Toggle:分為button up和button down2種狀態(tài),分別儲(chǔ)存有2個(gè)命令串;每次點(diǎn)擊都會(huì)執(zhí)行對(duì)應(yīng)狀態(tài)中儲(chǔ)存的命令串并且從一種狀態(tài)改變?yōu)榱硪环N狀態(tài)。簡(jiǎn)單點(diǎn)說(shuō)就相當(dāng)于2個(gè)按鈕。
          Separator:僅僅作為分隔其他按鈕的工具來(lái)使用,不包含任何命令。
          Multistate:一個(gè)下拉式按鈕,點(diǎn)擊之后會(huì)出現(xiàn)下拉列表,然后選擇,不同的選擇執(zhí)行不同的命令。

          在Buttons列表里有button的序號(hào),#button 序號(hào) 這個(gè)命令等同于鼠標(biāo)點(diǎn)擊一次按鈕,這個(gè)命令可以用于alias,variable,marco和trigger中。其他與button有關(guān)的命令有#yesno,#pr和#pick,這3個(gè)命令將在第八章中介紹。另外#button也可用于新建按鈕,鑒于語(yǔ)法格式過(guò)于復(fù)雜,這里略過(guò)了。

          按鈕的功能可以說(shuō)非常豐富,可以做出很漂亮的界面。
          這里要推薦inspector同學(xué)的一篇文章http://telweb.pkuxkx.net/forum/thread-6501-1-3.html 小蜜蜂機(jī)器人(新手專用)

          5.2 系統(tǒng)變量
          主要介紹最實(shí)用的%ctime,%i和%random

          %ctime表示你的連線時(shí)間,單位是秒

          實(shí)例一:我需要機(jī)器人計(jì)算吐納時(shí)每小時(shí)增加精力的速度。
          #tri {你的精力上限增加了!!} {#add jingli_add 1;#var tuna_speed [@jingli_add*3600/%ctime];#show 每小時(shí)獲得@tuna_speed點(diǎn)精力!}

          %ctime還可用于蕭峰,萬(wàn)安塔,胡一刀,護(hù)鏢,護(hù)送和朝廷守門等任務(wù),能接任務(wù)時(shí)由機(jī)器人自動(dòng)提醒,具體在第七章中專門介紹

          %i主要用于各種命令中,配合#number和#loop來(lái)使用,也用于專門針對(duì)數(shù)據(jù)庫(kù)變量、record類型變量和list類型變量的命令中,這些命令主要有#loopdb,#forall等等
          比如 #5 kill menggu bing %i等價(jià)于kill menggu bing 1;kill menggu bing 2;kill minggu bing 3;kill menggu bing 4;kill menggu bing 5

          #number和#loop都是一次性發(fā)送數(shù)個(gè)相同的命令,區(qū)別在于變量可以用于#loop中來(lái)控制發(fā)送命令的次數(shù),而#number中的number一定要是一個(gè)實(shí)際的阿拉伯?dāng)?shù)字

          錯(cuò)誤用法:#var number 5;#@number kill menggu bing %i
          正確用法:#var number 5;#loop @number {kill menggu bing %i}
          注意事項(xiàng):#var number 0;#loop @number {kill menggu bing %i}實(shí)際效果是kill menggu bing 1,也就是說(shuō)#loop至少會(huì)執(zhí)行一次,@number中的值為0或者負(fù)值或者干脆是字符串乃至漢字,都是執(zhí)行1次命令,zmud不會(huì)抱錯(cuò),可以自行試驗(yàn)。

          #loop命令在我發(fā)的領(lǐng)悟機(jī)器人中被用到,用來(lái)改變領(lǐng)悟或者練習(xí)的次數(shù),以適用不同exp層次的id。

          %random產(chǎn)生一個(gè)0-99的隨即數(shù)字,%random(1,5)產(chǎn)生一個(gè)1-5的隨機(jī)數(shù),結(jié)合#case命令來(lái)發(fā)送隨機(jī)命令

          #case @variable {cmd1} {cmd2} {cmd3} {cmd4} {cmd5}...可以根據(jù)@variable值的不同來(lái)發(fā)送不同的命令,比如@variable值為3,第3個(gè)括號(hào)中的命令cmd3會(huì)被執(zhí)行,其他命令都不執(zhí)行。

          另外%time和%dice有興趣也可以看一下,舉幾個(gè)例子簡(jiǎn)單說(shuō)下
          #say %time()顯示為星期三 七月 22, 2009 2:14:14 am
          #say %time(c)顯示為2009/7/22 2:16:12
          #say %time("aaaa tttt")顯示為星期三 2:26:03
          %time()的括號(hào)中可以使用參數(shù)來(lái)改變顯示內(nèi)容,這些參數(shù)有a(星期)、d(日期)、m(月份)、y(年)、e(年)、t(時(shí)分秒)、h(小時(shí))、n(分)和s(秒),下面給個(gè)復(fù)雜點(diǎn)的例子,有興趣可以自行試驗(yàn)看下顯示結(jié)果。
          #FORALL {a|d|m|y|e|g|t|h|n|s} {#SH %i: %time(%i) | %time(%i%i) | %time(%i%i%i) | %time(%i%i%i%i)}
          這個(gè)例子基本包含了所有的格式,%i依次等于a、d、m、y、e、g、t、h、n、s,%time()的括號(hào)中分別用1-4個(gè)%i來(lái)顯示不同詳細(xì)程度的內(nèi)容。

          %dice(2d6+2)顯示為擲2個(gè)6面色子的和再加上2,是一個(gè)隨機(jī)結(jié)果,()中用到的格式為xdy+n,表示"x個(gè)y面色子+n",相關(guān)變量有%dicemin()、%dicemax()、%diceavg()、%dicedev()。

          其他系統(tǒng)變量還有很多,作用都不大,不感興趣的可以跳過(guò)。下面只列舉一些,太多了不可能全面的,具體可以#help 自行查找。
          %action 最后一次觸發(fā)所執(zhí)行的命令。   
          %cr 換行。  
          %def 當(dāng)前使用的特殊字符。  
          %host 當(dāng)前連線MUD的IP地址。   
          %lastcom 最后被執(zhí)行的命令。   
          %lastcom2 倒數(shù)第二個(gè)被執(zhí)行的命令。  
          %lastcom3 倒數(shù)第三個(gè)被執(zhí)行的命令。  
          %line 從MUD中得到的最后一行文本。  
          %line2 從MUD中得到的倒數(shù)第二行文本。   
          %line3 從MUD中得到的倒數(shù)第三行文本。   
          %port 當(dāng)前連線的端口號(hào)。
          %selected 當(dāng)前選中的文本。可用于speed menu的制作,通過(guò)鼠標(biāo)點(diǎn)擊來(lái)發(fā)出包含選中文本的命令
          %selline 當(dāng)前選中的行。可用于speed menu的制作
          %selword 當(dāng)前選中的單詞。可用于speed menu的制作
          %title 當(dāng)前MUD的標(biāo)題。   
          %trigger 最近一次被觸發(fā)的行。   
          %window 當(dāng)前窗口的標(biāo)題。

          5.3 fuction(函數(shù))

          zmud允許自定義函數(shù),命令為#function,#fu為命令的縮寫形式.可以簡(jiǎn)單的把函數(shù)理解為帶參數(shù)的變量.還是用實(shí)際的小例子來(lái)說(shuō)明函數(shù)的用法.

          實(shí)例1:#fu sum %eval(%1+%2)
          這里%eval是系統(tǒng)自帶函數(shù),作用等于[ ],負(fù)責(zé)運(yùn)算并且返回運(yùn)算結(jié)果
          #say @sum(100,40)顯示為140
          sum在這里為一個(gè)自定義函數(shù),包含2個(gè)參數(shù),用法相當(dāng)于帶參數(shù)的變量,@sum()為函數(shù)的值

          實(shí)例2:#fu min %if(%1<%2,%1,%2)
          這里定義了一個(gè)函數(shù)min,作用是選擇2個(gè)數(shù)中較小的數(shù)
          %if為系統(tǒng)自帶的條件函數(shù),語(yǔ)法為%if(表達(dá)式,true-value,false-value),如果表達(dá)式為真,返回true-value,否則返回false-value
          #say @min(5,7)顯示為5
          #say @min(20,11)顯示為11

          實(shí)例3:#fu fact {%if(%1<=1,1,%1*@fact(%eval(%1-1)))}
          這個(gè)例子要復(fù)雜些,用到了函數(shù)的自身嵌套,如果參數(shù)<=1,返回1,否則返回"參數(shù)*@face(參數(shù)-1)",然后再對(duì)@fact(參數(shù)-1)重復(fù)上面的條件運(yùn)算,最終的結(jié)果就是"參數(shù)*(參數(shù)-1)*(參數(shù)-2)*...*1",其實(shí)就是一個(gè)階乘運(yùn)算.
          #say [@fact(5)]顯示為120

          函數(shù)很多時(shí)候用起來(lái)很方便,使你的機(jī)器人更容易看懂,修改起來(lái)當(dāng)然就更容易
          比如在上一章打坐吐納機(jī)器人中,可以定義一個(gè)函數(shù)對(duì)氣血,內(nèi)力,精神,精力進(jìn)行計(jì)算,確定dazuo,tuna的數(shù)值
          #fu need %max(%min([(%if(%eval(%4*2-%3)<1000,[(%4*2-%3)/2],[%4*2-%3])*100+129)/@sudu],[%1-(%2+9)/10]),10)
          這個(gè)函數(shù)擁有4個(gè)參數(shù),并且包含一個(gè)變量@sudu
          打坐的命令是dazuo @need(@qixue,@qixue_max,@neili,@neili_max)
          吐納的命令是tuna @need(@jingshen,@jingshen_max,@jingli,@jingli_max)
          可以看到比第4章更簡(jiǎn)潔明了,省去了一大堆#var,#math,#if

          另外值得一提的是,zmud的命令,系統(tǒng)自帶變量,系統(tǒng)自帶函數(shù)相當(dāng)?shù)亩?從而使得機(jī)器人的寫法多種多樣,相當(dāng)靈活.基本上任意一個(gè)#xxx的命令都對(duì)應(yīng)有一個(gè)系統(tǒng)已定義好了的函數(shù)或變量%xxx()
          比如#if,%if;#case,%case;#eval,%eval;#null,%null;#walk,%walk;#alias,%alias;#color,%color;#additem,%additem
          太多了,實(shí)在無(wú)法一一舉例,如此多的命令使zmud語(yǔ)言變得相當(dāng)豐富靈活,我也無(wú)法做到全部了解并且熟練運(yùn)用每一個(gè)命令。但是毫無(wú)疑問(wèn),知道的越多,做機(jī)器人就越容易。你知道多少對(duì)這樣的命令,他們的用法你都知道嗎?平時(shí)做機(jī)器人的時(shí)候有用過(guò)嗎?
          第六章 Variable和Alias的更多應(yīng)用

          本章主要介紹record類型變量和list類型變量以及變量別名的自身嵌套和相互嵌套

          6.1 record類型變量

          實(shí)例一:
          #var skill.name "玄鐵劍法"
          #var skill.id "xuantie-jia"
          #var skill.level 310

          上面3個(gè)命令將一個(gè)技能的中文名字、英文名字和等級(jí)全部保存到了一個(gè)變量@skill中
          #say @skill///@skill.name///@skill.id///@skill.level
          顯示結(jié)果為:name玄鐵劍法idxuantie-jialevel310///玄鐵劍法///xuantie-jia///310

          也有專門針對(duì)record類型變量的顯示命令#showdb,注意沒(méi)有#saydb這個(gè)命令
          #showdb @skill,顯示結(jié)果一共3行如下:
          name: 玄鐵劍法
          id: xuantie-jia
          level: 310

          我們把@skill稱為一個(gè)database record,把name、id、level稱為key,而"玄鐵劍法"、"xuantie-jian"、"310"分別為對(duì)應(yīng)key的值

          record類型的變量的優(yōu)點(diǎn)在于變量的含義更加清楚,并且相關(guān)的信息都保存在一個(gè)變量中,對(duì)這些信息的使用更加方便.

          對(duì)record類型的變量進(jìn)行操作的相關(guān)命令非常多,下面通過(guò)一些例子來(lái)簡(jiǎn)單說(shuō)明下

          (1)#say %db(@skill,level) 完全等同于#say @skill.level

          (2)#say %iskey(@skill,id)//%iskey(@skill,shuliandu)
          %iskey(record,key)返回record中key的序號(hào),如果不存在返回0
          上面例子中id是第二個(gè)key,shuliandu不是@skill的key,所以顯示為2//0

          (3)#say %addkey(@skill,shuliandu,10002)//%iskey(@skill,shuliandu)
          顯示為:name玄鐵劍法idxuantie-jialevel310shuliandu10002//0
          %addkey可以在record中添加key和key對(duì)應(yīng)的值,但是并不會(huì)改變r(jià)ecord的內(nèi)容,所以%iskey(@skill,shuliandu)的顯示結(jié)果仍然為0
          如果需要改變r(jià)ecord的內(nèi)容,可以用下面的3個(gè)命令中的任意一個(gè)
          #addkey skill shuliandu 10002
          #var skill.shuliandu 10002
          #var skill %addkey(@skill,shuliandu,10002)


          跟添加key類似,刪除key的命令有#delkey,%delkey,用法類似,這里就不做介紹了

          (4)#say %numkeys(@skill) 顯示@skill中key的個(gè)數(shù)

          這里介紹的一些命令已經(jīng)跟DataBase有點(diǎn)沾邊了。在zmud555和721版本中提供DB和Map,并且有非常多的命令配合DB和Map來(lái)使用。考慮到DB和Map的制作及使用講起來(lái)需要大量篇幅,同時(shí)還要配合大量圖片,并且在機(jī)器人制作過(guò)程中并非不可缺少,所以此文暫時(shí)不涉及這2方面內(nèi)容。以后如有需要,可能會(huì)專門開(kāi)貼來(lái)介紹DB和Map。

          6.2 list類型變量

          將一列信息保存在一個(gè)變量中,每個(gè)單獨(dú)的信息用"|"間隔開(kāi)來(lái),每項(xiàng)信息稱為list類型變量的item

          實(shí)例一:做一個(gè)trigger來(lái)拾取游戲中掉落的隨機(jī)裝備

          #var baobei "劍|刀|杖|鞭|斧|槍|錘|戟|匕|鎧甲|盔|腰帶|靴|項(xiàng)鏈|戒指|披風(fēng)|袍|護(hù)腕|手套|盾"
          #var baobei2 "sword|blade|staff|whip|axe|spear|hammer|halberd|dagger|armor|head|waist|boots|necklace|ring|surcoat|cloth|wrists|hands|shield"
          #tri {從@dbrname身上掉了出來(lái)一*之(*)$} {get %item(@baobei2,%ismember(%1,@baobei))}
          在這個(gè)例子中@baobei中保存了所有隨機(jī)裝備的種類,@baobei2中保存所有隨機(jī)裝備的id,并且注意到@baobei和@baobei2中種類和id是一一對(duì)應(yīng)的
          %ismember(%1,@baobei)返回%1在@baobei中的位置。比如如果掉落刀返回值為2,掉落鞭返回值為4
          如果%1不在@baobei中,返回為0
          %item(@baobei2,%ismember(%1,@baobei)),通過(guò)%ismember(%1,@baobei)的返回值得到掉落的隨機(jī)裝備的id
          注:現(xiàn)在這個(gè)例子已經(jīng)沒(méi)有意義了,應(yīng)該寫一些觸發(fā)來(lái)drop垃圾,不過(guò)這個(gè)例子中的方法還是很好的.

          實(shí)例二:輸入sk命令,抓取所有技能的中文名字英文名字技能等級(jí)保存到變量中

          #tri {你目前所學(xué)過(guò)的技能:} {#var skname {};#var sklevel {};#var skills {}}
          //將@skname,@sklevel,@skills清空
          #tri {│%s(*)%s~((*)~)%s-*%s(%d)~/} {#if (%numitems(@skname)=0) {#var skname %1} {#var skname %additem(%1,@skname)};#if (%numitems(@skils)=0) {#var skills %2} {#var skills %additem(%2,@skills)};#if (%numitems(@sklevel)=0) {#var sklevel %3} {#var sklevel %additem(%3,@sklevel)}}
          //%numitems()返回list類型變量中item的個(gè)數(shù)
          //抓取中文名字英文名字和技能等級(jí)進(jìn)行賦值,如果變量為空就直接賦值,否則作為變量的一個(gè)item添加進(jìn)去
          //%additem和#additem類似于前面講過(guò)的%addkey和#addkey
          //對(duì)每個(gè)技能都觸發(fā),并且抓取到的中文名字英文名字和技能等級(jí)在變量中的位置都是對(duì)應(yīng)的

          再定義幾個(gè)函數(shù)就可以了
          #fu name {%item(@skname,%ismember(%1,@skills))}
          #fu level {%item(@sklevel,%ismember(%1,@skills))}
          #say @name("xuantie-jian")//@level("xuantie-jian")級(jí)
          顯示為:玄鐵劍法//310級(jí)

          實(shí)例三:輸入semote,抓取所有的表情命令保存到變量中

          輸入semote,每一行有5個(gè)表情命令,每個(gè)命令由字母和數(shù)字組成,需要用%a通配

          #tri {^(%a)%s(%a)%s(%a)%s(%a)%s(%a)$} {#additem emotes %1;#additem emotes %2;#additem emotes %3;#additem emotes %4;#additem emotes %5}
          //list類型變量中item的個(gè)數(shù)是沒(méi)有限制的,把所有的表情都保存到@emotes中
          然后你可以通過(guò)%random %disc等函數(shù)來(lái)選取隨機(jī)表情使用

          #say %numitems(@emotes) 顯示出表情的個(gè)數(shù)

          注意:舉個(gè)例子來(lái)說(shuō)明%additem和#additem的另一個(gè)區(qū)別
          #var path {n|e|sw|se|e|u|enter boat|out|w}
          #say %additem("sw",@path) 顯示為n|e|sw|se|e|u|enter boat|out|w|sw
          #say %additem(@path,"sw") 顯示為sw|n|e|sw|se|e|u|enter boat|out|w
          #say @path 顯示為n|e|sw|se|e|u|enter boat|out|w
          #additem path "sw";#say @path 顯示為n|e|sw|se|e|u|enter boat|out|w
          //如果要添加的item已經(jīng)存在于list變量中,則添加無(wú)效

          #additem path "enter";#say @path 顯示為n|e|sw|se|e|u|enter boat|out|w|enter
          簡(jiǎn)而言之,#additem不允許item重復(fù),如果有重復(fù)則命令無(wú)效.需要添加重復(fù)的item,請(qǐng)用%additem

          對(duì)list類型變量進(jìn)行操作的命令除了上面提到的%item、%numitems、%ismember、%additem、#additem,還有#delitem、#delnitem、%delitem、%dups、%sort
          #delitem list item 刪除指定item,如果變量中有多個(gè)重復(fù)的item,則刪除所有重復(fù)的item
          %delitem(item,@list) 刪除指定item,如果變量中有多個(gè)重復(fù)的item,只刪除第一個(gè)的item
          #delnitem list n 從@list中刪除第n個(gè)item
          %dups 去掉變量中重復(fù)的item,只保留第一個(gè)item
          #SHOW %dups(Athos|Bertrand|Caesar|Bertrand|Caesar|Bertrand)
          顯示為Athos|Bertrand|Caesar
          %sort 對(duì)變量中的item按照字母和數(shù)字進(jìn)行排序

          6.3 嵌套

          zmud允許variable,alias和function互相嵌套,來(lái)完成更復(fù)雜的事情

          上一章中已經(jīng)介紹了一個(gè)function的嵌套
          #fu fact {%if(%1<=1,1,%1*@fact(%eval(%1-1)))}
          其實(shí)就是定義了一個(gè)階乘函數(shù),不用嵌套很難計(jì)算階乘

          實(shí)例一:定義一個(gè)函數(shù),計(jì)算exp支持的技能等級(jí)上限

          #fu maxlevel %if((%1*%1*%1/10)<%2,@maxlevel(%eval(%1+1),%2),%1)
          #say @maxlevel(1,100000)//@maxlevel(100,3000000)//@maxlevel(700,50000000)
          顯示為100/311/794,分別為100k,3m,50m exp對(duì)應(yīng)的技能等級(jí)上限

          這里第一個(gè)參數(shù)的作用是保守的預(yù)估一個(gè)等級(jí),一定要比最大技能等級(jí)低,可以減少計(jì)算次數(shù),提高計(jì)算速度,第二個(gè)參數(shù)就是要計(jì)算的經(jīng)驗(yàn)值

          實(shí)例二:用alias來(lái)計(jì)算exp支持的技能等級(jí)上限
          #alias maxlevel {#var n 1;#while ((@n*@n*@n/10)<%1) {#add n 1};#say 技能最高為@n級(jí)}
          maxlevel 3000000
          顯示為:技能最高為312級(jí)
          不使用嵌套,但是用到了#while循環(huán)語(yǔ)句.#while功能也很強(qiáng)大,但同時(shí)也有我不喜歡的缺點(diǎn),所以我一般避免使用#while,后面章節(jié)中會(huì)講到#while的缺點(diǎn)

          #alias maxlevel {#if ((%1*%1*%1/10)<%2) {maxlevel %eval(%1+1) %2} {#say 技能最高為%1級(jí)}}
          使用嵌套同樣可以達(dá)到目的,你可以隨意預(yù)估一個(gè)值作為%1,要計(jì)算的經(jīng)驗(yàn)值作為%2

          這幾個(gè)例子中,用定義函數(shù)的方法來(lái)計(jì)算速度最快,比另外2種方法要快幾倍,推薦使用

          總結(jié):個(gè)人認(rèn)為,本章和下一章將要講到的內(nèi)容是所有章節(jié)中最重要的2章,可以算是從中級(jí)水平到高級(jí)水平的一個(gè)轉(zhuǎn)折。機(jī)器人編寫中用到record,list以及嵌套,能完成很多復(fù)雜的事情.后面的章節(jié)中將會(huì)大量的出現(xiàn)record,list以及嵌套.
          第七章 掌控時(shí)間

          7.1 #wa命令

          #wa是#wait的縮寫,用來(lái)延遲一個(gè)命令的執(zhí)行.

          用法一:延遲的具體時(shí)間以毫秒為單位指定.

          比如{#wa 2000;hp}作用是2秒后發(fā)送hp這個(gè)命令

          #wa后面可以指定具體數(shù)字,也可以指定一個(gè)變量用變量來(lái)控制等待的時(shí)間

          前面章節(jié)中多次使用這種用法.#wa命令太重要了,如果沒(méi)有#wa,任何命令都是立即發(fā)送,容易造成機(jī)器人發(fā)狂.另外有些命令執(zhí)行完畢之后人物處于busy狀態(tài),用#wa命令來(lái)度過(guò)busy時(shí)間,#wa的時(shí)間設(shè)置應(yīng)該保守一些,一般大于busy時(shí)間.

          用法二:不指定時(shí)間,#wa單獨(dú)使用

          實(shí)例一:{study book for 1;hp;#wa;exert regenerate}
          在zmud 462和555兩個(gè)版本中,運(yùn)行結(jié)果為
          > study book for 1
          hp
          你的「基本劍法」進(jìn)步了!
          exert regenerate
          你從身上拿出一本華山劍譜準(zhǔn)備好好研讀。
          你研讀了一次有關(guān)基本劍法的技巧,似乎有點(diǎn)心得。
          > ≡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━≡
          【 精神 】 110   / 130    [100%]  【 精力 】 0     / 0     (+   0)
          【 氣血 】 48    / 97     [ 80%]  【 內(nèi)力 】 0     / 0     (+   0)
          【 食物 】 0     / 300    [饑餓]  【 潛能 】 234901               
          【 飲水 】 0     / 300    [饑渴]  【 經(jīng)驗(yàn) 】 75643                 
          ≡━━━━━━━━━━━━━━━━━━━━━━━◎北大俠客行◎━━≡
          > 你略一凝神,精神看起來(lái)好多了。
          study book for 1;hp;#wa3個(gè)命令同時(shí)發(fā)送執(zhí)行,然后等待命令執(zhí)行的結(jié)果,但是只等待一行信息,接著發(fā)送exert regenerate這個(gè)命令。#wa后面的命令得不到hp的信息,如果想讓#wa后面的命令對(duì)內(nèi)力氣血進(jìn)行判斷,數(shù)一下上面的行數(shù),至少需要連續(xù)6次#wa,而且會(huì)被中途輸出的其他信息干擾,實(shí)用性為0。使用462和555版本的可以忘記這個(gè)用法。需要用其他方法來(lái)替代這個(gè)用法,最簡(jiǎn)單的就是tell自己的id,然后用tell的信息做觸發(fā)。
          在zmud721中運(yùn)行結(jié)果為
          > study book for 1
          hp
          你的「基本劍法」進(jìn)步了!
          你從身上拿出一本華山劍譜準(zhǔn)備好好研讀。
          你研讀了一次有關(guān)基本劍法的技巧,似乎有點(diǎn)心得。
          > ≡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━≡
          【 精神 】 110   / 130    [100%]  【 精力 】 0     / 0     (+   0)
          【 氣血 】 48    / 97     [ 80%]  【 內(nèi)力 】 0     / 0     (+   0)
          【 食物 】 0     / 300    [饑餓]  【 潛能 】 234901               
          【 飲水 】 0     / 300    [饑渴]  【 經(jīng)驗(yàn) 】 75643                 
          ≡━━━━━━━━━━━━━━━━━━━━━━━◎北大俠客行◎━━≡
          exert regenerate
          > 你略一凝神,精神看起來(lái)好多了。
          具有比較高的實(shí)用性了。不同版本的差異請(qǐng)多多體會(huì)。

          注意事項(xiàng):#wa為單線流程,多個(gè)#wa同時(shí)執(zhí)行時(shí),后面的會(huì)替代前面。
          試驗(yàn)A:在命令行里輸入#wa 10000;hp,然后輸入#wa 1,會(huì)發(fā)現(xiàn)hp被立刻執(zhí)行了
          試驗(yàn)B:在命令行反復(fù)輸入{#wa 3000;hp}6次,每次輸入的間隔小于3秒,會(huì)發(fā)現(xiàn)hp遲遲沒(méi)有執(zhí)行,當(dāng)你停止輸入時(shí),3秒后會(huì)同時(shí)執(zhí)行6次hp
          請(qǐng)大家自行體會(huì),做機(jī)器人時(shí)應(yīng)該盡量避免多個(gè)#wa同時(shí)執(zhí)行,另外可以重新輸入#wa xxx來(lái)延長(zhǎng)或者縮短前面已經(jīng)輸入的#wa命令。這個(gè)雖然是#wa命令的不足之處,但是仍然可以被我們利用。

          因?yàn)?wa單線流程的特點(diǎn),決定了#wa只用于簡(jiǎn)單的控制時(shí)間。

          7.2 tick timer
          點(diǎn)擊菜單Actions->Tick Timer來(lái)設(shè)置tick timer,有3個(gè)要素組成:Timer IntervalTimeout MarginTimeout Command

          舉例來(lái)說(shuō),設(shè)置Timer Interval為10,Timeout Margin為2,Timeout Command為hp,點(diǎn)擊Start之后,zmud開(kāi)始循環(huán)倒計(jì)時(shí)10秒,當(dāng)計(jì)時(shí)至2秒時(shí),執(zhí)行hp這個(gè)命令。

          這是另外一個(gè)控制時(shí)間的工具,最大的優(yōu)點(diǎn)是穩(wěn)定,我喜歡稱它為計(jì)時(shí)器。準(zhǔn)確地倒計(jì)時(shí),準(zhǔn)確地執(zhí)行命令,不受到機(jī)器人的影響。缺點(diǎn)在于一個(gè)窗口只能設(shè)置一個(gè)tick timer,一般只用在最關(guān)鍵的地方。

          相關(guān)命令#timer on,#timer off,#ts和#tz等。
          #timer on :打開(kāi)tick timer
          #timer off:關(guān)閉tick timer
          #ts 數(shù)字:  設(shè)置Timer Interval中的值
          #tz:        重置計(jì)時(shí)器的時(shí)間,讓他重新開(kāi)始計(jì)時(shí)
          以上4個(gè)命令被用于trigger,alias中用來(lái)對(duì)tick timer進(jìn)行操作.

          注意:zmud 555在加載其他機(jī)器人時(shí),不同的時(shí)間器之間會(huì)發(fā)生干擾,tick timer的3要素都會(huì)發(fā)生改變,所以建議Timeout Command中的值統(tǒng)一填為timer,并且新建一個(gè)alias timer來(lái)保存計(jì)時(shí)結(jié)束需要執(zhí)行的命令串。

          實(shí)例二:胡一刀接任務(wù)的時(shí)間間隔為10分鐘,10分鐘到了的時(shí)候由機(jī)器人提醒
          tick timer中Timer Interval設(shè)置為600秒,Timeout Margin設(shè)置為5秒,Timeout Command設(shè)置為{#say 可以接任務(wù)了!}
          #tri {胡一刀說(shuō)道:『我收到消息,聽(tīng)說(shuō)&hydaddress有盜寶人&dbrname~(&dbr~)找到了闖王寶藏的地圖} {#tz}

          實(shí)例三:用#wa來(lái)實(shí)現(xiàn)計(jì)時(shí)器的功能,這樣你就擁有相當(dāng)于2個(gè)計(jì)時(shí)器了。
          #alias ticktimer {#wa 10000;hp;ticktimer}
          如果你在命令行輸入ticktimer,恭喜你,你有了另外一個(gè)計(jì)時(shí)器,每隔10秒就執(zhí)行一次hp命令。如果你不修改ticktimer這個(gè)alias,它將永遠(yuǎn)不會(huì)停止,請(qǐng)用#alias ticktimer {}來(lái)停止這個(gè)時(shí)間器。

          實(shí)例四:達(dá)摩院領(lǐng)悟,內(nèi)力不足時(shí)回去睡覺(jué)
          #alias lw {#if @sleep {d;sd;w;n;sleep} {#wa 500;lingwu sword 100;exert regenerate;lw}}
          #tri {你的內(nèi)力不夠。} {#var sleep 1}
          這個(gè)例子也可以用tick timer來(lái)實(shí)現(xiàn);zmud721中也可以直接用#wa來(lái)實(shí)現(xiàn);或者用下面要講到的#alarm來(lái)實(shí)現(xiàn)。zmud的靈活性使得同樣的事情,可以有很多種方法完成。

          zmud本身提供#while命令,但是#wa和#while混合使用時(shí)會(huì)出問(wèn)題,所以我一般不用#while,而是用這種自身嵌套來(lái)實(shí)現(xiàn)#while的功能。

          上面的2個(gè)例子都用到了alias的自身嵌套,更多的用法大家可以自己創(chuàng)造,在高級(jí)篇中我會(huì)大量的使用自身嵌套,使用時(shí)需要注意不要造成死循環(huán),一定要設(shè)置一個(gè)辦法讓它停止;否則,唉,你的zmud已經(jīng)崩潰了,重啟吧!

          7.3 #alarm命令(重要)

          實(shí)際上#alarm是創(chuàng)造一個(gè)alarm類型的trigger,以時(shí)間作為觸發(fā),相關(guān)命令為#untr

          命令格式為#alarm hh:mm:ss {cmds}
          其中hh:mm:ss為時(shí):分:秒,時(shí)間前面可以加上"+"或者"-",hh、mm、ss前面也可以加上*或者直接用*代替,"+" "-" "*"這3個(gè)特殊字符的含義舉例說(shuō)明

          #alarm 2:50:00 {#say 保衛(wèi)時(shí)間到了}
          時(shí)間前面沒(méi)有+和-,以你計(jì)算機(jī)上的時(shí)間作為觸發(fā),凌晨2點(diǎn)50分提示保衛(wèi)時(shí)間到了

          #alarm -00:00 {save}
          前面加了-,以你的連線時(shí)間作為觸發(fā).時(shí)間上沒(méi)有指定小時(shí),默認(rèn)為任意小時(shí),連線時(shí)間達(dá)到整點(diǎn)時(shí)自動(dòng)save

          #alarm +01:05 {cmd}
          前面加個(gè)+,則建立一個(gè)一次性trigger,觸發(fā)之后自動(dòng)刪除.并且既不以連線時(shí)間為觸發(fā),也不以計(jì)算機(jī)時(shí)間為觸發(fā),而是從建立trigger時(shí)算起,65秒之后觸發(fā)

          #alarm +65 {cmd}
          跟上面的#alarm +01:05 {cmd}完全相同

          #alarm (2|6|10|14|18|22):50:00 {#say %eval(%i+1)點(diǎn)保衛(wèi)時(shí)間到了}
          以計(jì)算機(jī)時(shí)間作為觸發(fā),并且用"|"指定了多個(gè)小時(shí),同時(shí)用到了(),小時(shí)被保存到了臨時(shí)變量%i中。
          不光能在保衛(wèi)時(shí)提醒,還指出了是哪個(gè)時(shí)間點(diǎn)的保衛(wèi)。

          #alarm *10:00 {save}
          沒(méi)有"+""-",以計(jì)算機(jī)時(shí)間作為觸發(fā)。小時(shí)未指定默認(rèn)為任意,分鐘指定為*10意思是10的倍數(shù),這個(gè)trigger會(huì)在計(jì)算機(jī)時(shí)間的分鐘為00、10、20、30、40、50時(shí)自動(dòng)save

          #alarm -2:30:* {hp}
          小時(shí)和分都有具體指定,秒為任意。這是一個(gè)每秒鐘觸發(fā)一次的trigger,但是僅在你連線時(shí)間為2個(gè)半小時(shí)的觸發(fā)。事實(shí)上小時(shí)分和秒都可以設(shè)定為任意,看下面的例子

          #alarm -* {hp}
          每秒鐘觸發(fā)一次,永遠(yuǎn)不會(huì)停止,用#untr -*刪除這個(gè)trigger

          建議:使用這個(gè)命令太頻繁,機(jī)器人里會(huì)有很多已經(jīng)觸發(fā)過(guò)的alarm類型的trigger,但是這些trigger并沒(méi)有刪除掉,建議創(chuàng)建這個(gè)trigger的時(shí)候,統(tǒng)一取一個(gè)alarm的類名,這樣就可以隨時(shí)用#delclass alarm來(lái)刪除所有的alarm類型的trigger.

          實(shí)例五:胡一刀接任務(wù)的時(shí)間間隔為10分鐘,10分鐘到了的時(shí)候由機(jī)器人提醒
          #tri {胡一刀說(shuō)道:『我收到消息,聽(tīng)說(shuō)&hydaddress有盜寶人&dbrname~(&dbr~)找到了闖王寶藏的地圖} {#alarm +600 {#say 可以接任務(wù)了!}}

          實(shí)例六:保衛(wèi)時(shí)間自動(dòng)上線
          #alarm {2|6|10|14|18|22}:50:00 {#connect;@account.zhanghao;@account.mima}
          #tri {【公告天下】保衛(wèi)襄陽(yáng)任務(wù)全部結(jié)束} {quit;#disconnect}
          其中record類型變量@account中保存有帳號(hào)密碼信息
          #connect連接服務(wù)器,#disconnect從服務(wù)器斷開(kāi)

          實(shí)例七:守門結(jié)束后退出,天亮前上線
          #tri {你的經(jīng)驗(yàn)增加了*!} {#var time [1440-%ctime];#alarm
          +@time {#connect;@account.zhanghao;@account.mima};quit;#disconnect}
          //經(jīng)過(guò)大米用天色做觸發(fā)統(tǒng)計(jì)游戲中1天的時(shí)間為24分鐘,因此[1440-%ctime]就是晚上的時(shí)間
          //在#alarm的時(shí)間中用到了變量,這也是zmud允許的一個(gè)用法;用變量來(lái)控制時(shí)間使得#alarm這個(gè)命令的作用大大增加,對(duì)時(shí)間的控制也更加靈活

          實(shí)例八:多個(gè)tick timer并存
          #alias tick1 {#alarm +40 {cmd1;tick1}}
          #alias tick2 {#alarm +20 {cmd2;tick2}}
          命令行輸入tick1;tick2就建立了2個(gè)tick timer,分別是20秒計(jì)時(shí)和40秒計(jì)時(shí)
          計(jì)時(shí)存在時(shí)輸入tick1或者tick2可以重置計(jì)時(shí),相當(dāng)于#tz命令
          #untr +40或者#untr +20可以刪除這2個(gè)alarm類型的trigger,相當(dāng)于#timer off

          實(shí)例九:#tri {林震南說(shuō)道:「你上次運(yùn)鏢太辛苦了,下去休息休息吧。」} {#alarm +5 {ask lin about job}}
          這個(gè)例子曾在第二章中出現(xiàn)過(guò),用的是#wa 5000,需要打開(kāi)關(guān)閉觸發(fā)來(lái)防止誤觸發(fā)
          這里用#alarm,就不需要那么麻煩,無(wú)論如何也不會(huì)出現(xiàn)同時(shí)輸入多個(gè)"ask lin about job"的情況
          但是新的問(wèn)題是:如果有人一直在林這里制造干擾,命令就發(fā)不出去了。所以還是有必須要打開(kāi)關(guān)閉觸發(fā)。

          注一:#alarm是一個(gè)功能更為強(qiáng)大的命令,和#wa,tick timer一起構(gòu)成了zmud控制時(shí)間的3柄利器。
          注二:在wiki里誠(chéng)三的一篇文章中也講過(guò)#alarm這個(gè)命令,不過(guò)我認(rèn)為他講的"-"的作用不準(zhǔn)確,而且時(shí)間中應(yīng)該不允許出現(xiàn)小數(shù),所以#alarm -0.5是永遠(yuǎn)也不會(huì)觸發(fā)的。
          注三(新增):在721中去測(cè)試#alarm發(fā)現(xiàn)wiki里誠(chéng)三的文章講的是正確的。由于alarm命令在721中與另2個(gè)版本差異較大,下面專門舉幾個(gè)例子說(shuō)明下。

          不管什么版本中,#alarm都是trigger,時(shí)間就是它的Pattern。

          在721中,Pattern相同的#alarm +@time,后建立的不會(huì)替代先建立的。

          #alarm -0.5 {};#alarm -10;#alarm -30{}
          時(shí)間中用到了-號(hào),并且小時(shí)和分都未指定,分別是每0.5秒,每10秒,每30秒觸發(fā)一次,不以連線時(shí)間觸發(fā),跟#alarm +類似,但是觸發(fā)之后不會(huì)刪除。后建立的會(huì)替代更新掉先建立的。意味著不停的輸入#alarm -5 {commands},commands永遠(yuǎn)不會(huì)執(zhí)行。

          #alarm -1:05 {};#alarm -2:30 {}
          這2個(gè)命令跟zmud555中一樣,以連線時(shí)間為觸發(fā),只觸發(fā)一次。

          最后的總結(jié)就是721中alarm命令很矛盾很復(fù)雜,使用時(shí)請(qǐng)尤其小心。更多的差異請(qǐng)自行試驗(yàn)。

           

          第八章 提高機(jī)器人穩(wěn)定性和適用面

          8.1 防止發(fā)呆

          實(shí)例一:跳樓機(jī)器人做起來(lái)很簡(jiǎn)單,但是從塔上跳下來(lái)之后會(huì)busy 1.5秒左右.大部分時(shí)候1.5秒以后就可以繼續(xù)跳樓了,但是由于網(wǎng)絡(luò)的原因,有時(shí)候2秒都不能保證busy結(jié)束.
          如果#wa 2500;enter;do 6 up;out固然比較保險(xiǎn),效率卻很低.
          2.5秒跳一次和1.5秒跳一次從效率上來(lái)說(shuō)差別太大.
          #tri {你已穩(wěn)穩(wěn)地站在地上。} {#t+ busy;#alarm +6 {enter;do 6 up;out};#wa 1500;enter;do 6 up;out}
          #tri {你的動(dòng)作還沒(méi)有完成,不能移動(dòng)。} {#t- busy;#wa 2000;enter;do 6 u;out} {busy}

          這個(gè)trigger不僅能解決busy問(wèn)題,同時(shí)還能解決up的時(shí)候被系統(tǒng)跘住的問(wèn)題,機(jī)器人最多發(fā)呆6秒就能繼續(xù)工作
          在#alarm +6 {enter;do 6 up;out}未觸發(fā)之前,再一次建立#alarm +6 {enter;do 6 up;out},這個(gè)時(shí)間觸發(fā)器會(huì)被重置,觸發(fā)器中的命令暫時(shí)不會(huì)執(zhí)行,所以不用擔(dān)心會(huì)出現(xiàn)多次跳樓的情況。

          在俠客島讀石壁也可以用類似辦法來(lái)防止機(jī)器人中斷,同時(shí)設(shè)置好自動(dòng)連線,除非服務(wù)器掉線超過(guò)10分鐘才可能會(huì)從俠客島上掉下來(lái).
          類似辦法同樣也可以用于打坐吐納,釣魚,讀書,領(lǐng)悟等各種機(jī)器人中

          防止發(fā)呆的一般做法:

          步驟一: 一般一個(gè)機(jī)器人正常運(yùn)轉(zhuǎn)時(shí),都會(huì)循環(huán)出現(xiàn)各種信息,可以將這些信息做成trigger,觸發(fā)命令中加入#add idle 1
          步驟二: #alias Testidle {#alarm +@time {#if (@idle>0) {#say 運(yùn)行情況良好;#var idle 0} {#say 機(jī)器人已經(jīng)中斷;let it run};testidle}}
          對(duì)@idle進(jìn)行定時(shí)判斷,如果@idle大于1,表示運(yùn)行情況良好,變量歸0;否則表示機(jī)器人中斷,重新運(yùn)轉(zhuǎn)它

          8.2 自動(dòng)連線

          非常簡(jiǎn)單但是實(shí)用的一個(gè)辦法。

          zmud555和721的alias列表里都有atconnect這個(gè)alias,atconnect中的命令是空的。你可以修改這個(gè)alias里面的命令,在連接到服務(wù)器時(shí)自動(dòng)執(zhí)行,用這個(gè)alias來(lái)輸入帳號(hào)密碼非常方便。
          zmud462中雖然沒(méi)有atconnect這個(gè)alias,但是你可以自己新建一個(gè)atconnect,功能和555 721版一樣。

          注:每當(dāng)連接到服務(wù)器時(shí),atconnect里面的命令都自動(dòng)執(zhí)行,不需要另外的trigger或者命令來(lái)執(zhí)行它。所以它不是常規(guī)的alias,你在新建常規(guī)alias的時(shí)候,也不要取名為atconnect。

          盡量為你的每個(gè)機(jī)器人都添加自動(dòng)連線和防止發(fā)呆功能,在雙保險(xiǎn)的情況,你的機(jī)器人連續(xù)掛幾天不是什么難事。

          8.3 提高適用面

          一個(gè)機(jī)器人可能只適用于某個(gè)id或者某個(gè)門派,需要更改很多變量才能適用于另外的id和門派。可是從大量的variables中尋找要改的變量不僅浪費(fèi)時(shí)間,而且容易漏掉一些變量。如果你不是機(jī)器人的制作者,可能都不知道要怎么改。這個(gè)時(shí)候機(jī)器人的適用面就非常窄了,而且別人用起來(lái)也不容易,不能算是一個(gè)好用的機(jī)器人。

          有3個(gè)命令可以用于解決這個(gè)問(wèn)題,分別是#pick,#pr,#yesno

          實(shí)例二:在我發(fā)布的555版領(lǐng)悟機(jī)器人中第一個(gè)按鈕中的命令
          n=1
          #pr level "你要領(lǐng)悟或者練習(xí)到多少級(jí)"
          //彈出一個(gè)對(duì)話框,提示你輸入一個(gè)數(shù)字,這個(gè)數(shù)字被賦值給level,達(dá)到了修改領(lǐng)悟等級(jí)的目的,并且別人可以通過(guò)“你要領(lǐng)悟或者練習(xí)到多少級(jí)”這句話很清楚的知道要輸入什么內(nèi)容
          #wh @n {#pick {p:添加要領(lǐng)悟或者練習(xí)的武功} {o:1} {添加基本功夫:#exe @action1
          #exe @action2} {添加特殊功夫:#exe @action1
          #exe @action6
          #if %ismember(@skill,@tsskills)=0 {#exe @action3
          #exe @action4
          #exe @action5}} {*添加完畢:#var n 0}}
          //這個(gè)命令要復(fù)雜一些了。#pick彈出一個(gè)選項(xiàng)框,可以提供很多選項(xiàng)來(lái)選擇
          //{p:添加要領(lǐng)悟或者練習(xí)的武功}為這個(gè)選項(xiàng)框設(shè)定一個(gè)名字或者稱為"title"
          //{o:1}表示這個(gè)選項(xiàng)框?yàn)?font color="blue">單選框,去掉這個(gè)則默認(rèn)為復(fù)選框
          //{提示信息:命令}設(shè)置這個(gè)選項(xiàng)框的選項(xiàng),當(dāng)鼠標(biāo)點(diǎn)擊選擇這個(gè)選項(xiàng)時(shí),命令被執(zhí)行
          //{*添加完畢:#var n 0}}提示信息前面加入了*,表示這個(gè)選項(xiàng)為默認(rèn)選項(xiàng)
          //上面#pick總共設(shè)置了3個(gè)選項(xiàng),只有當(dāng)選擇最后一個(gè)選項(xiàng)時(shí),#while的循環(huán)中止,整個(gè)命令結(jié)束,否則反復(fù)彈出選項(xiàng)框,用來(lái)反復(fù)添加基本功夫和特殊功夫

          實(shí)例三:如果你的機(jī)器人有自動(dòng)連線功能,那么制作一個(gè)按鈕來(lái)修改帳號(hào)密碼等信息就很必要了
          #button 0 {修改帳號(hào)} {#pr account.zhanghao "你的帳號(hào)";#pr account.mima "你的密碼" "*"}
          這里#pr account.mima的時(shí)候,多用了一個(gè)可選設(shè)置"*",當(dāng)你在對(duì)話框中輸入密碼時(shí)顯示****,也算是一個(gè)有趣的功能吧.

          實(shí)例四:萬(wàn)安塔簡(jiǎn)化識(shí)別碼的輸入
          #tri {你向鹿杖客打聽(tīng)有關(guān)『進(jìn)塔』的消息。} {#pr answer "識(shí)別碼";exert powerup;answer %upper(@answer);perform busy wushi}
          #alias jinta {ask ke about 進(jìn)塔}
          在萬(wàn)安塔門口輸入jinta,就自動(dòng)彈出一個(gè)對(duì)話框詢問(wèn)你識(shí)別碼,對(duì)照?qǐng)D片在對(duì)話框中輸入小寫的識(shí)別碼,自動(dòng)回答大寫的識(shí)別碼,同時(shí)powerup和busy武士

          #yesno "question" {yes-command} {no-command}
          這個(gè)命令用來(lái)彈出一個(gè)對(duì)話框詢問(wèn)你一個(gè)問(wèn)題,如果你點(diǎn)yes,那么yes-command被執(zhí)行,否則no-command被執(zhí)行

          做機(jī)器人的時(shí)候盡量考慮到門派的差異以及帳號(hào)密碼的不同,然后制作一些按鈕來(lái)修改這些信息,不光自己在用不同id掛機(jī)時(shí)更加方便,別人也更容易使用你的機(jī)器人.

          第九章 豐富你的機(jī)器人

          本章主要介紹各種實(shí)用的小命令,讓你的機(jī)器人變得更有意思

          9.1 #beep #play

          #beep 讓zmud播放音樂(lè),可以在菜單中找到sound進(jìn)行設(shè)置,只支持wav格式
          你可以下載一些wav格式的音樂(lè)或者干脆自己錄制一個(gè)
          任務(wù)完成之后播放一段輕松的音樂(lè),或者遇到危險(xiǎn)播放一個(gè)警告的音樂(lè)都是不錯(cuò)的選擇

          #play 支持wav、mid、avi格式,把你想要播放的音樂(lè)放到zmud目錄下或者放到zmud的子文件夾中,然后在命令行或者trigger中用#play filename.wav命令就可以播放了.如果#play命令沒(méi)有效果,可能是zmud沒(méi)有找到該音樂(lè)文件,請(qǐng)參照下圖修改

          9.2 status bar

          窗口最下面得一段空白的地方就是status bar,你可以在這里顯示你最關(guān)心的內(nèi)容,
          這里給出1張截圖,分別是我的胡一刀機(jī)器人和護(hù)鏢機(jī)器人中狀態(tài)條顯示的內(nèi)容


          圖中顯示了任務(wù)計(jì)時(shí),這個(gè)時(shí)間用#alarm每秒更新一次,完全同步顯示出任務(wù)花費(fèi)的時(shí)間

          #st命令用來(lái)定義狀態(tài)條

          比如我的護(hù)鏢機(jī)器人中是這樣定義的:
          #st {【任務(wù):@address  伙計(jì)@huoji】【伙計(jì)位置編號(hào)@huojinum】【第@round輪:用時(shí)@time秒】【本次連線成功推車@success/@total次】}

          9.3 #cap

          實(shí)例:#tri {【閑聊】} {#cap chat}
          把所有的聊天信息抓到另外一個(gè)窗口單獨(dú)顯示出來(lái),不用擔(dān)心刷屏太快看不到聊天信息
          當(dāng)然你也可以把你感興趣的任何信息都抓到另一個(gè)窗口顯示出來(lái)。

          9.4 #co #cw #hi

          #co 改變最后一行顯示信息的顏色
          #cw 創(chuàng)造一個(gè)觸發(fā),只改變指定信息的顏色,該行中其他內(nèi)容的顏色不變
          #hi 如果最后一行的顏色為暗色,則改變?yōu)榱辽蝗绻麨榱辽瑒t改變?yōu)榘瞪?/font>

          顏色的代碼如下:
          black   0
          blue   1
          green   2
          cyan   3
          red   4
          magenta  5
          brown   6
          grey   7
          yellow   14
          white   15
          bold   128

          你可以直接用red,blue,yellow來(lái)指定顏色,也可以用代碼來(lái)指定顏色
          比如:#co red或者#co 4是一個(gè)意思

          #cw 唐果 red,highlight,blink
          //創(chuàng)造一個(gè)觸發(fā),將屏幕上唐果2個(gè)字全部用亮紅顯示,并且閃爍,這里使用了復(fù)合顏色

          #show %ansi(green)歡迎使用%ansi("red,highlight,blink")糖果機(jī)器人!
          //用到了%ansi(顏色代碼),在一行中可以顯示多種顏色

          #LOOP 20 {#SHOWP %ansi(%if(%i\2=0,green,"blue,bold")).oOo};#SHOW
          //#showp和#show類似,區(qū)別在于#showp不另起一行。最后用#show結(jié)尾,表示顯示完畢,另起一行;命令中的"\"表示模運(yùn)算,等同于%mod()
          //這條命令顯示的內(nèi)容很有趣,有興趣的不妨把它復(fù)制到你的命令行里看看,你可以用#showp和%ansi()來(lái)顯示更多有趣的內(nèi)容.

          9.5 #mess

          當(dāng)我正在看網(wǎng)頁(yè)的時(shí)候,我的遍歷機(jī)器人沒(méi)有找到盜寶人,可以用這個(gè)命令提醒我。我可以選擇關(guān)閉機(jī)器人手動(dòng)去迷宮殺盜寶人,也可以不管它,讓機(jī)器人放棄這個(gè)任務(wù)。
          你可以將#mess用在更多的地方,無(wú)論是提醒還是危險(xiǎn)警告都不錯(cuò)。

          9.6 #gag

          當(dāng)你在領(lǐng)悟或者讀書的時(shí)候,刷屏太快,可以用#gag來(lái)屏蔽某些信息。需要注意的是,被屏蔽了的信息雖然看不到了,但是它還是存在的,并且機(jī)器人會(huì)通過(guò)這些信息來(lái)觸發(fā)trigger,所以這個(gè)命令僅僅的作用就是讓你看不到。

          #tri {屏息凝神,一神守內(nèi),一神游外,意圖雙手各成方圓,卻總是很難成功。} {#gag}
          //在學(xué)左右互博時(shí),這行字出現(xiàn)的太多,沒(méi)有任何意思的刷屏,屏蔽掉!

          9.7 #sc

          當(dāng)張三跑出來(lái)時(shí),由于你的屏幕跳動(dòng)太快,看不清張三找誰(shuí)比武了,你可以用#cap,也可以用這個(gè)命令

          #sc "張 三" 10
          //顯示最后10行包含張三的信息;如果去掉10,則顯示所有包含張三的信息
          //省去了你用滾動(dòng)條到上面手動(dòng)尋找的麻煩

          9.8 #log

          把你需要的某些信息保存到一個(gè)文本文件中,日后研究或者統(tǒng)計(jì)都可以

          #log filename.txt
          //開(kāi)啟log,接下來(lái)所有信息都會(huì)保存在filename.txt中
          #log
          //如果log已經(jīng)開(kāi)啟,用這個(gè)命令關(guān)閉log
          你可以通過(guò)反復(fù)的開(kāi)啟關(guān)閉來(lái)保存你感興趣的內(nèi)容。

          9.9 #ig

          你是否覺(jué)得同時(shí)關(guān)閉所有的trigger太麻煩,需要用#t-來(lái)關(guān)閉每個(gè)類.這時(shí)你可以用這個(gè)命令,當(dāng)你需要打開(kāi)時(shí),再次輸入#ig命令就可以了.

          注意:用#ig來(lái)關(guān)閉觸發(fā),相當(dāng)于你用鼠標(biāo)點(diǎn)擊zmud窗口右下角的手槍圖標(biāo),并不會(huì)改變triggers的enable和disable狀態(tài).看下面的幾個(gè)例子

          #ig;#alarm +5 {#ig}
          //這條命令的初衷是短暫的關(guān)閉5秒再打開(kāi),可惜#alarm +5是trigger,而所有的triggers都是關(guān)閉的,所以5秒后不會(huì)打開(kāi)triggers
          #ig;#wa 5000;#ig
          //#wa好比潑出去的水,收不回來(lái)的.關(guān)閉5秒后能自動(dòng)打開(kāi).同樣你也可以用tick timer來(lái)打開(kāi).

          9.10 #stw

          這個(gè)的用途跟定義status bar類似,當(dāng)你覺(jué)得status bar太短不夠用的時(shí)候你可以用這個(gè).當(dāng)然也有其他用途.

          #stw {hp;@qixue/@maxqixue  內(nèi)力:@neili/@maxneli %cr 精神: @jingshen/@maxjingshen 食物:@food 飲水:@drink %cr 潛能:@pot  經(jīng)驗(yàn): @exp}
          //如果你已經(jīng)用trigger把相關(guān)信息保存到了上述變量中,這條命令會(huì)打開(kāi)一個(gè)小窗口來(lái)顯示你的hp有關(guān)信息
          //%cr的作用是換行.

          你也可以用%ansi()來(lái)選擇你喜歡的顏色,例如
          #stw {本次推車獲得%ansi(red,high)@expgrain}
          //你獲得的經(jīng)驗(yàn)需要用trigger保存到@expgrain中

          #stw on#stw off分別是打開(kāi)status window窗口關(guān)閉status window窗口

          9.11 #tab

          此命令用來(lái)定義一些快捷命令,比如
          #tab "ask lin about job"
          //不論什么時(shí)候,在命令行簡(jiǎn)單的輸入一個(gè)a,然后按一下鍵盤上的tab鍵,ask lin about job就完整的出現(xiàn)在命令行中了

          9.12 #menu

          這個(gè)命令讓你可以用鼠標(biāo)發(fā)送命令,請(qǐng)看下面幾個(gè)有趣的用法

          #menu admire {chat* admire %lower(%selword)}
          #menu praise {chat* praise %lower(%selword)}
          #menu goodman {chat* goodman %lower(%selword)}
          //當(dāng)你把上述3條命令輸入到你的zmud中之后,右鍵點(diǎn)擊屏幕,你會(huì)看到彈出一個(gè)菜單,比平時(shí)多了3個(gè)選項(xiàng),任意選擇一個(gè),括號(hào)里面的命令就發(fā)送出去了
          //當(dāng)你右鍵點(diǎn)擊某個(gè)玩家的id,然后任意選擇一個(gè),你就會(huì)在閑聊頻道對(duì)該玩家發(fā)出表情動(dòng)作了.
          //如果你點(diǎn)擊的是空白地方,執(zhí)行的命令等同于chat* admire/praise/goodman
          //%selword意思是你選中的單詞

          這個(gè)用法也可以幫助你撿東西或者賣東西,但是請(qǐng)不要用這個(gè)命令來(lái)kill sb,不小心點(diǎn)錯(cuò)了概不負(fù)責(zé).

          9.13 #all

          當(dāng)你在一個(gè)窗口中輸入#all {vote unchblk sb.},你的所有窗口都會(huì)發(fā)出vote unchblk sb.命令.

          9.14 窗口名:{命令}

          sghjjj:tell tangguo [@qixue]
          //如果你的大米的窗口名是sghjjj,那么這個(gè)命令能讓你的大米把他的氣血值告訴你
          //值得注意的,大米tell過(guò)來(lái)的信息中,@qixue的值是sghjjj窗口中變量qixue的值,這條命令可以讓你和你的大米配合的更完美.
          //相當(dāng)于直接在sghjjj這個(gè)窗口中輸入了冒號(hào)后面的命令

          你可以用#name xxx 來(lái)更改窗口名字

          9.15 #gauge(新增)

          命令格式#gauge number "Title" @variable @maxvariable (表達(dá)式)

          用途:將2個(gè)變量以圖形對(duì)比的形式表現(xiàn)在一個(gè)浮動(dòng)的條形框內(nèi)

          number:定義浮動(dòng)條形框的序號(hào)
          "Title":定義浮動(dòng)條形框的標(biāo)題
          @variable和@maxvariable分別為你關(guān)心的2個(gè)變量,比如氣血/氣血最大值,任務(wù)已花費(fèi)時(shí)間/任務(wù)總時(shí)間等等
          (表達(dá)式)可以設(shè)定一個(gè)危險(xiǎn)警告,比如 (@maxvariable/5),那么當(dāng)@variable<(@maxvariable/5)時(shí),用紅色顯示@variable所占百分比,否則用藍(lán)色顯示。

          實(shí)例:護(hù)送任務(wù)總時(shí)間10分鐘
          接到任務(wù)時(shí){#var time_left 600;#alarm -* {#add time_left -1};#gauge 1 剩余時(shí)間 @time_left 600 (60)}
          //time_left初始化600秒,用一個(gè)每秒觸發(fā)一次的trigger同步更新@time_left的值,創(chuàng)建一個(gè)浮動(dòng)條形框顯示任務(wù)剩余時(shí)間,當(dāng)剩余時(shí)間小于1分鐘時(shí),浮動(dòng)條形框的顏色變?yōu)榧t色
          任務(wù)完成時(shí){#untr -*;#gauge 1 off}
          //任務(wù)完成后刪除alarm類型的trigger并且關(guān)閉剩余時(shí)間顯示


          通過(guò)序號(hào),你可以定義很多個(gè)這樣的浮動(dòng)條形框。你可以用下面的命令隨時(shí)關(guān)閉打開(kāi)某一個(gè)或者所有的浮動(dòng)條形框。
          #gauge 1 off    #gauge 1 on
          關(guān)閉或者打開(kāi)第一個(gè)浮動(dòng)條形框
          #gauge off      #gauge on
          關(guān)閉或者打開(kāi)所有的浮動(dòng)條形框

          這個(gè)有趣的命令也可以用來(lái)顯示你的血量或者你正在領(lǐng)悟的技能,Have Fun!

          注:類似以上一些實(shí)用小命令可能還有很多暫時(shí)想不起來(lái),我會(huì)隨時(shí)添加

          到本章為止,zmud的大部分內(nèi)容已經(jīng)基本介紹完畢,如果你看到了這里,相信絕大多數(shù)機(jī)器人已經(jīng)難不倒你了.

          posted on 2011-08-17 17:15 常言笑 閱讀(28367) 評(píng)論(1)  編輯  收藏

          Feedback

          # re: ZMUD機(jī)器人制作(上篇) 2015-11-16 16:46 老吳

          很仔細(xì)啊 謝謝樓主 受教了  回復(fù)  更多評(píng)論   



          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          My Links

          Blog Stats

          • 隨筆 - 142
          • 文章 - 2
          • 評(píng)論 - 39
          • Trackbacks - 0

          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          搜索

          •  

          積分與排名

          • 積分 - 218274
          • 排名 - 260

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 台北县| 江华| 冷水江市| 湖口县| 罗城| 洪江市| 密山市| 绿春县| 昆山市| 松滋市| 阆中市| 玉溪市| 手游| 肥东县| 汉寿县| 郴州市| 临高县| 长武县| 嵩明县| 潼南县| 新郑市| 金乡县| 镇江市| 丹东市| 临夏县| 荔波县| 海宁市| 喀喇沁旗| 长白| 修武县| 临西县| 汨罗市| 普陀区| 鲁山县| 通海县| 海兴县| 广昌县| 鄂州市| 昌宁县| 买车| 建瓯市|