jarlyyn 发表于 2021-10-12 18:44:46

本帖最后由 jarlyyn 于 2021-10-12 06:50 PM 编辑

再次提到任务(task)了。

在51楼的任务队列已经使用过task了。再详细解释下


任务(task)是什么。

指当前正在执行的非瞬时动作。比如买东西,移动等等。

任务有以下特点

[*]通过唯一ID注册到全局。这样才能快速Debug
[*]每次只能执行一个任务。执行多个任务的话会报错
[*]任务有3个关键属性,数据(Data),成功回调(OnFihish),失败回调(OnFail)


jarlyyn 发表于 2021-10-13 01:54:36

接下来,就是定义道具文档的格式了。

初步的格式我定为 || 分隔的字符串,每个一行

分别为

道具ID||道具Name||道具Label||道具Type||道具Location||道具Command||道具Interval||道具注释

比如

gan liang||Gan liang||干粮||goods||yz-zxl||buy gan liang ||||
jiudai||Jiudai||牛皮酒袋||goods||yz-zxl||buy jiudai||||
niurou tang||Niurou tang||牛皮酒袋||goods||ly-wxl||buy niurou tang||||

然后我们定义3个接口

App.API.GetItem(id) 通过id获取道具,能找到返回第一个,找不到返回空
App.API.GetItemsByName(name,ignorecase) 根据Name获取道具,返回所有匹配的道具列表。ignorecase为true则忽略大小写
App.API.GetItemsByLabel(label) 根据Label获取获取道具,返回所有匹配的道具列表。

代码见


https://github.com/hellclient-scripts/pkuxkx.noob/blob/8e7542463a1b2a67b354fbded009a4be42fd2e2a/script/info/item.js

再设置一个全局的Produce生产道具的方法,传入道具id,成功回调,失败回调,然后执行一次尝试生产一个道具

代码大概为

    app.Produce=function(id,onFinish,onFail){
      let item=App.API.GetItem(id)
      if (item==null){
            throw "item "+id +" not found"
      }
      let taskid=""
      switch(item.Type){
            case "goods":
                taskid="produce.goods"
                break;
            default:
                throw "unknown item type"+item.Type
      }
      app.ExecuteTask(taskid,id,onFinish,onFail)
    }

https://github.com/hellclient-scripts/pkuxkx.noob/blob/8e7542463a1b2a67b354fbded009a4be42fd2e2a/script/core/produce.js

很明显。我根据取回的道具类型创建不同的任务获取道具。同时定义了一个购买的任务

任务内容为

    app.RegisterCallback("core.produce.goods.arrive",function(){
      if (app.GetTaskID() =="produce.goods"){
            app.Send(app.CurrentTask.Item.Command)
            app.Send("i")
            app.CheckBusy("core.produce.goods.finish")
      }
    })
    app.RegisterCallback("core.produce.goods.finish",function(){
      if (app.GetTaskID() =="produce.goods"){
            app.CurrentTask.Finish(app.CurrentTask.Item)
      }
    })   
    let Goods=function(){
      produce.call(this, "produce.goods")
      this.Execute = function (data, onFinish, onFail) {
            produce.prototype.Execute.call(this, data, onFinish, onFail)
            let move=app.NewMove("walk",this.Item.Location,"core.produce.goods.arrive",{})
            move.onFail=onFail
            move.Start()
      }
    }

就是加了两个回调,一个在到达位置后执行命令,一个执行好命令,忙结束后调用结束回调

https://github.com/hellclient-scripts/pkuxkx.noob/blob/266d068796d59e477339e0c6e4dfcaa0657a5b47/script/core/produce/goods.js

然后再加了一个#item别名,可以通过 #item gan liang ,#item gourou tang的形式自动去补充物品


jarlyyn 发表于 2021-10-13 01:57:41

本帖最后由 jarlyyn 于 2021-10-13 01:59 AM 编辑

好了,老规矩,看看效果

先是#item gan liang

再是#item niurou tang


效果很好,这样就不用担心挨饿了。



ajump 发表于 2021-10-13 15:50:57

两耳嗡嗡,不行了。

jarlyyn 发表于 2021-10-14 13:23:42

按惯例,加入管理界面




jarlyyn 发表于 2021-10-19 22:56:26

加入吃喝部分


(function(app){
    let check=Include("core/check/check.js")
    app.Data.LastEat=0
    app.EatCmd=function(){
      return "eat "+app.GetParam("food")+";drink "+app.GetParam("drink")
    }
    app.Eat=function(){
      app.Data.LastEat=Now()
      app.Send(app.EatCmd())
    }
    app.Bind("Check","core.food.eat")
    let checkFood=(new check("food")).WithLevel(app.CheckLevelBrief).WithIntervalParam("eatinterval").WithLastID("LastEat")
    checkFood.Send=function(){
      app.Eat()
    }
    app.RegisterCallback("core.food.eat",checkFood.Callback())
    })(App)每次检查的时候会先吃喝下

默认有10秒冷却


icer 发表于 2021-10-19 23:27:59

对emoji和ascii特殊字符的显示支持的怎么样?
比如下面两个图:

jarlyyn 发表于 2021-10-20 10:46:38

icer 发表于 2021-10-19 11:27 PM
对emoji和ascii特殊字符的显示支持的怎么样?
比如下面两个图:

客户端不负责显示,显示全靠浏览器,所以一般没什么问题



jarlyyn 发表于 2021-10-20 11:10:43

继续

接下去我们引入 提案proposal的概念

proposal就是一个需要判断是否要去处理的事情,比如检查钱少,是否要去取钱,检查食物是否够,检查饮水是否够,不够去买。

proposal有两个方法,一个是submit,即提交判断是否可以实行,一个是Execute,即去进行相应操作

(function (app) {
    let Proposal=function(id){
      if (!id) {
            throw "Proposal的id不能为空"
      }
      this.ID=id
      this.OnFinish=""
      this.OnExecute=function(){

      }
      this.Execute=function(onFinish){
            this.OnFinish=onFinish
            this.OnExecute()
      }
      this.Submit=function(){
            return false
      }
    }
    return Proposal
})(App)https://github.com/hellclient-scripts/pkuxkx.noob/blob/bbae4ab351568ac9a9df70d2bb249ebc91251c5b/script/core/proposal/proposal.js



proposal的管理代码如下

(function (app) {

    app.Proposals = {}
    app.ProposalGroups = {}
    app.RegisterProposal = function (proposal) {
      if (proposal.ID == "") {
            throw "Proposal id不可为空"
      }
      app.Proposals = proposal
    }
    app.RegisterProposalGroup = function (groupid, proposals) {
      app.ProposalGroups = proposals
    }

    let try_proposals = function (proposals, onfinish) {
      for (var i in proposals) {
            let proposal = app.Proposals]
            if (!proposal) {
                throw "提案 [" + proposals + "] 没找到"
            }
            if (proposal.Submit()) {
                proposal.Execute(onfinish)
                return true
            }
      }
      return false
    }
    let try_proposalgroup = function (groupid, onfinish) {
      let group = app.ProposalGroups
      if (!group) {
            throw "提案组 [" + groupid + "] 没找到"
      }
      return try_proposals(group, onfinish)

    }
    let try_proposalgroups = function (groups, onfinish) {
      for (var i in groups) {
            let group=groups
            if (try_proposalgroup(group,onfinish)){
                return true
            }
      }
      return false
    }
    app.TryProposalGroups = function (groups, onfinish, onrejected) {
      if (try_proposalgroups(groups, onfinish)) {
            return true
      }
      app.ExecuteCallback(onrejected)
      return false

    }
    app.TryProposalGroup = function (groupid, onfinish, onrejected) {
      if (try_proposalgroup(groupid, onfinish)) {
            return true
      }
      app.ExecuteCallback(onrejected)
      return false
    }
    app.TryProposals = function (proposals, onfinish, onrejected) {
      if (try_proposals(proposals, onfinish)) {
            return true
      }
      app.ExecuteCallback(onrejected)
      return false
    }

    Include("core/proposal/cash.js")
    Include("core/proposal/food.js")
    Include("core/proposal/drink.js")
    Include("core/proposal/prepare.js")

})(App)https://github.com/hellclient-scripts/pkuxkx.noob/blob/bbae4ab351568ac9a9df70d2bb249ebc91251c5b/script/core/proposal.js

引入三个全局函数


[*]TryProposals,尝试执行执行多个提案
[*]TryProposalGroup 尝试执行预先定义的提案组
[*]app.TryProposalGroups 尝试执行预先定义的多个提案组



jarlyyn 发表于 2021-10-20 11:16:21

jarlyyn 发表于 2021-10-20 11:10 AM
继续

接下去我们引入 提案proposal的概念


接着引入3个预设的提案和一个提案组

取现金的 Cash提案

(function (app) {
    let proposal=Include("core/proposal/proposal.js")
    let Cash= function(){
      proposal.call(this,"cash")
      this.Submit=function(){
            return app.GetCash()<app.GetNumberParam("gold_min")
      }
      this.OnExecute=function(){
            let move=app.NewMove("walk",app.GetParam("bank_location"),"core.proposal.cash.arrive",{})
            move.Start()
      }
    }
    app.RegisterCallback("core.proposal.cash.arrive",function(){
      app.Send("qu "+app.GetParam("gold_withdraw")+" gold")
      app.Send("i2")
      app.CheckBusy(this.OnFinish)
    })
    app.RegisterProposal(new Cash())
})(App)
买食物的Food提案

(function (app) {
    let proposal=Include("core/proposal/proposal.js")
    let Food= function(){
      proposal.call(this,"food")
      this.Submit=function(){
            
            return app.GetItemNumber(App.API.GetItem(app.GetParam("food")).Name,true)<app.GetNumberParam("food_min")
      }
      this.OnExecute=function(){
            app.Produce(app.GetParam("food"),this.OnFinish)
      }
    }
    app.RegisterProposal(new Food())
})(App)



买饮水的Drink提案

(function (app) {
    let proposal=Include("core/proposal/proposal.js")
    let Drink= function(){
      proposal.call(this,"drink")
      this.Submit=function(){
            
            return app.GetItemNumber(App.API.GetItem(app.GetParam("drink")).Name,true)<app.GetNumberParam("drink_min")
      }
      this.OnExecute=function(){
            app.Produce(app.GetParam("drink"),this.OnFinish)
      }
    }
    app.RegisterProposal(new Drink())
})(App)
然后是准备阶段的prepare提案组

(function (app) {
    app.RegisterProposalGroup("prepare",["cash","food","drink"])
})(App)
再把队列服务加入#check命令

好了,一个简单的自动任务队列机器实现了




页: 1 2 3 4 5 6 7 [8] 9
查看完整版本: 一步一步在北侠做机器人