jarlyyn 发表于 2024-10-12 21:14:32

闲来无事,开了个新坑

最近做了一个新机器(非北侠),拿我的pkuxkx.noob和hclua已经之前的一些新的想法,抽象了一个框架出来,准备用来做跨MUD机器的框架。

当然,做新框架,除了蛋疼,还是为了解决问题。

pkuxkx.noob作为一个我刚做完不久的完整机器,功能上是完备的,也很好的体现了我可维护性高的需求。

但是,作为一个开荒机器,必然是边写边用,很多功能等到发现有更好的实现方式时已经作为地基打入底下几十米了,而且还可能为了做 基本/扩展的分离,有很大的坑(主要是行走搜索模块)。整好乘这次好好的整一下。

因此这个框架主要是解决了pkuxkx.noob的这几个问题

1.基础构架
后期我已经完全脱离了对客户端触发器和Timer的使用了。但初期还是有些有所依赖。然后我整体的用了很多单独的状态机来处理触发,有点过于麻烦。同时触发的失效还是比较麻烦,没有一个真正的“临时触发”,也就是任务中用的触发都是临时的概念。这次正好将我够死的不同层的不同生命周期融入进去。

2.行走模块
固定路径,点对点,动态路径,行走,遍历,定位,本质是一回事。就是路径提供者(导航)和路径确认者(乘客)的关系。由于我pkuxkx.noob的底子考虑分享问题是不包含点对点的,点对点是作为MOD进行扩展的,可以说非常坑……
这也算重构的重点

3.驱动机制
pkuxkx.noob的主要驱动我是先使用了状态机,状态机对列,然后写着太麻烦,实际任务时又引入指令和指令对列,使得整个机器十分复杂,双线操作。
这次我要把两条线并成一条线。

4.全局条件
作为复杂配置的必需品吗,我的条件模块分为了任务条件,战斗条件,各种配置的条件,过于零散,必须整合起来。

5.统一的事故和挑战机制
我的机器本身有一个死亡处理模块,就是假死/真死后能继续做任务的。但是这个应该时应对我正向的命令流机制的侧路机制,而不是一个特殊的模块。
同样还有挑战机制,就是任务做了一半时,张三或者亲戚找你时,判断是否能停下当前任务去处理,然后继续完成任务的机制。
顺序流(正常流程)+事故(意外流程)+挑战(随机分支)才能构建成一个比较完整的流程系统。


这5点,我在新机器里开始陆陆续续的实现了,新机器已经能完成部分简单的任务,我会逐渐把已经完善定型的模块发在这里,和有兴趣的人分享一下。

jarlyyn 发表于 2024-10-12 21:18:02



新机器战斗模块还没做,但已经能完成非战斗任务了。

jarlyyn 发表于 2024-10-12 21:23:02

(function (App) {
    App.Quest.Beiqi = {}
    App.Quest.Beiqi.Data = {}
    App.Quest.Beiqi.Delay = 5 * 60 * 1000
    App.Quest.Beiqi.Tasks = {}
    ReadLines("src/quests/beiqi/task.txt").forEach(line => {
      line = line.trim()
      if (line == "" || line.startsWith("//")) {
            return
      }
      let data = line.split("|")
      App.Quest.Beiqi.Tasks] = {
            Key: data,
            Name: data,
            InfoLoc: data,
            InfoID: data,
            Last: 0,
      }
    })
    App.Quest.Beiqi.Receivers = {}
    ReadLines("src/quests/beiqi/receiver.txt").forEach(line => {
      line = line.trim()
      if (line == "" || line.startsWith("//")) {
            return
      }
      let data = line.split("|")
      App.Quest.Beiqi.Receivers] = {
            Loc: data,
            ID: data,
      }
    })
    let readyCommand = App.Commands.NewFunctionCommand(function () {
      let now = (new Date()).getTime()
      let min = null
      let list = []
      for (var key in App.Quest.Beiqi.Tasks) {
            let task = App.Quest.Beiqi.Tasks
            let cd = now - task.Last
            if (min == null || min > cd) {
                min = cd
            }
            if (cd > App.Quest.Beiqi.Delay) {
                list.push(task)
            }
      }
      if (!App.Quests.Stopped && list.length) {
            App.Quest.Beiqi.Data.Current = App.Random(list)
            App.Quest.Beiqi.Go()
            return
      }
      let cd = App.Quest.Beiqi.Delay - min
      if (!App.Quests.Stopped) {
            Note("所有的备齐已做完,等待 " + ((cd/1000).toFixed(2)) + " 秒")
            Quest.Cooldown(cd)
      }
      App.Quest.Beiqi.Finish()
    })
    App.Quest.Beiqi.Finish = function () {
      App.Pop()
    }
    App.Quest.Beiqi.Go = function () {
      let task = App.Quest.Beiqi.Data.Current
      App.Commands.PushCommands(
            App.NewPrepareCommand(),
            App.Move.NewToCommand(task.InfoLoc),
            App.NewNobusyCommand(),
            App.NewAskCommand(task.InfoID, task.Name + "的事", 1),
            App.Commands.NewFunctionCommand(App.Quest.Beiqi.Check),
      ).
            WithFailCommand(nextCommand).
            WithFinishCommand(nextCommand)
      App.Next()
    }
    App.Quest.Beiqi.Next = function () {
      if (App.Quest.Beiqi.Data.Current) {
            App.Quest.Beiqi.Data.Current.Last = (new Date()).getTime()
      }
      App.Next()
    }
    let nextCommand = App.Commands.NewFunctionCommand(App.Quest.Beiqi.Next)

    let re = /.+说道:据说(.+)急需一批(.+)。嘿!你说他想干什么?$/
    App.Quest.Beiqi.Check = function () {
      if (App.Quests.Stopped){
            App.Next()
            return
      }
      if (App.Data.Ask.Answers.length == 0) {
            App.Fail()
            return
      }
      let answer = App.Data.Ask.Answers
      let result = answer.Line.match(re)
      if (result) {
            let key = App.Quest.Beiqi.Data.Current.Key + "-" + result
            let receiver = App.Quest.Beiqi.Receivers
            if (receiver == null) {
                App.Fatal("beiqi","未知的收货人" + key)
                return
            }
            App.Quest.Beiqi.Data.Quest = {
                Receiver: receiver,
                Item: result,
            }
            App.Quest.Beiqi.Give()
            return
      }
      App.Fatal("beiqi","未知的回答:" + answer)
    }
    App.Quest.Beiqi.Give = function () {
      let item = App.Data.Item.List.FindByName(App.Quest.Beiqi.Data.Quest.Item).First()
      if (item) {
            App.PushCommands(
                App.Move.NewToCommand(App.Quest.Beiqi.Data.Quest.Receiver.Loc),
                App.NewNobusyCommand(),
                App.Commands.NewDoCommand("give " + item.GetData().IDLower + " to " + App.Quest.Beiqi.Data.Quest.Receiver.ID),
                App.Commands.NewDoCommand("i"),
                App.Commands.NewWaitCommand(1000),
                App.Commands.NewFunctionCommand(App.Quest.Beiqi.Go)
            )
            App.Next()
            return
      }
      let goods = App.Goods.GetGoodsByName(App.Quest.Beiqi.Data.Quest.Item)
      if (!goods.length) {
            Note("无法购买的物品:" + App.Quest.Beiqi.Data.Quest.Item)
            App.Fail()
            return
      }
      App.PushCommands(
            App.Goods.NewBuyCommand(goods.Key),
            App.Commands.NewFunctionCommand(App.Quest.Beiqi.Give),
      )
      App.Next()
    }
    let Quest = App.Quests.NewQuest("beiqi")
    Quest.Name = "备齐"
    Quest.Desc = "做备齐任务,积累阅历"
    Quest.Intro = ""
    Quest.Help = ""
    Quest.Start = function (data) {
      App.Commands.Push().
            WithReadyCommand(readyCommand)
      App.Next()
    }
    App.Quests.Register(Quest)
})(App)

任务代码。总体和pkuxkx.noob差不多。

devilkate 发表于 2024-10-12 21:48:44

太高端了不懂
页: [1]
查看完整版本: 闲来无事,开了个新坑