对象(Object)是Mud底层 的Mudos/Fluffos的核心概念。
每个房间/npc/道具都是一个Object,每个Object 内能包含一系列其他Object的列表。
所以,作为一个针对运行在Mudos/Fluffos上的机器人,必然需要面对大量的Object的处理。
我在newhelljs中创建了一个Object类来专门处理这个问题
代码地址
代码中对应了两种概念
Object对象
Object对象中包括了 Label(显示的名字),ID(物品ID),IDLower(小写化的ID),惰性加载的 数量,单位,名字,依据可选的Param
对应的就是Mud中最基本的Object概念。
不论房间中的对象,还是身上的道具,都抽象成这样的一个标准类。
List对象类表
对象列表是一个非常实用的类。
它除了用来放置所有的Object对象外,还提供了一些快速的查找过滤的方法
FindByID 通过ID(大小写敏感)查找
FindByIDLower 通过ID(大小写不敏感)查找
FindByKey 通过特意制定的Key查找
FindByLabel 通过显示的标签(带数量)查找
FindByName 通过解析后的不带数量的名字查找
SearchByName 部分匹配不带数量名字查找
SearchByLabel 部分匹配带数量名字查找
SearchByID 部分匹配id查找
ExcludeID 排除ID查找
FindByFilter 自定义过滤函数查找
以及一些快速方法
First 返回列表中的一个元素
Last 返回列表中的最后一个元素
Sum 统计列表中的数量总和
来覆盖了绝大部分Mud任务的需求。
毕竟本质上,由于Mud底层的实现,除了解密类任务,大部分任务主要就是针对道具,以及房间中的 NPC进行交互。
只要能及时把身上的道具和房间里的NPC抽象为Object和List,做对应的任务可以说易如反掌。
道具处理代码参考
let matcheritem = /^( |□|○)(.+)\(([^\(\)]+)\)$/
let matcherend = /^目前携带了(.+)件物品。$/
//道具统计的计划
let PlanOnItem = new App.Plan(
App.Positions.Connect,
function (task) {
let data = {}
task.AddTrigger(matcheritem, function (task, result, event) {
let item = new objectModule.Object(result[2], result[3], App.History.CurrentOutput)
let index = data[item.IDLower]
if (index == null) {
index = 1
}
switch (result[1]) {
case "□":
item.Mode = 1
break
case "○":
item.Mode = 2
break
default:
item.Mode = 0
}
item.WithKey(item.IDLower + " " + index)
App.Data.Item.List.Append(item)
data[item.IDLower] = index + 1
return true
})
task.AddTrigger(matcherend, function (task, result, event) {
App.Data.Item.Count = objectModule.CNumber.ParseNumber(result[1])
})
},
function (result) {
checkerI.Reset()
},
)
...
房间NPC处理代码参考
let matcherOnHeal = /^ (\S{2,8})正坐在地下(.+)。$/
let matcherOnYanlian = /^ (\S{2,8})正在演练招式。$/
let matcherOnObj = /^ ((\S+) )?(\S*[「\(].+[\)」])?(\S+)\(([^\(\)]+)\)( \[.+\])?(( <.+>)*)$/
//处理得到出口之后的信息(npc和道具列表)的计划
var PlanOnExit = new App.Plan(App.Positions.Connect,
function (task) {
task.AddTrigger(matcherOnObj, function (trigger, result, event) {
let item = new objectModule.Object(result[4], result[5], App.History.CurrentOutput).
WithParam("身份", result[2]).
WithParam("外号", result[3]).
WithParam("描述", result[6] || "").
WithParam("状态", result[7] || "").
WithParam("动作", "")
App.Map.Room.Data.Objects.Append(item)
event.Context.Set("core.room.onobject", true)
return true
})
task.AddTrigger(matcherOnHeal, function (trigger, result, event) {
let item = new objectModule.Object(result[1], "", App.History.CurrentOutput).
WithParam("动作", result[2])
App.Map.Room.Data.Objects.Append(item)
event.Context.Set("core.room.onobject", true)
return true
})
task.AddTrigger(matcherOnYanlian, function (trigger, result, event) {
let item = new objectModule.Object(result[1], "", App.History.CurrentOutput).
WithParam("动作", "演练招式")
App.Map.Room.Data.Objects.Append(item)
event.Context.Set("core.room.onobject", true)
return true
})
task.AddCatcher("line", function (catcher, event) {
let output = event.Data.Output
if (output.length > 4 && output.startsWith(" ") && output[4] != " ") {
return true
}
//未匹配过的行代表npc和道具结束
return event.Context.Get("core.room.onobject")
})
...