一步一步在北侠做机器人 行走限制版
年底较忙,外加更新客户端API,机器人没有什么更新上线倒是发现有个行走限制的Patch,看了下,机器人也受影响,决定修正下。
其实修正的内容很简单,就是行走的时候计算下走了多少步,超过限制就进入和怕汉中失败一样的重试状态就行,说干就干,快马加鞭
本帖最后由 jarlyyn 于 2022-1-11 01:11 PM 编辑
首先,我们明显需要统计最近的行走部数,因此,我们需要先添加一个计时器
[]
ID = "gc"
Name = "gc"
Enabled = true
Hour = 0
Minute = 0
Second = 0.2
Send = ""
Script = "App.OnTimerGC"
AtTime = false
SendTo = 0
ActionWhenDisconnectd = true
Temporary = false
OneShot = false
Group = ""
Variable = ""
OmitFromLog = false
OmitFromOutput = false
用于清理过期的统计数据
入口代码里也要加一个相应的相应代码
App.OnTimerGC=function(name){
App.Raise("gc")
}
触发一个gc事件
本帖最后由 jarlyyn 于 2022-1-11 01:11 PM 编辑
然后,我们在move.js里,需要统计一下最新的移动步数
app.GetMoved=function(){
gc()
return moved.length
}
var moved=[]
var gc=function(){
newmoved=[]
var now=(new Date()).getTime()
moved.forEach(function(ts){
if ((now-ts)<500){
newmoved.push(ts)
}
})
moved=newmoved
}
app.RegisterCallback("core.move.gc", function () {
gc()
})
app.Bind("gc","core.move.gc")
app.RegisterCallback("core.move.onroomobjend", function () {
moved.push((new Date()).getTime())
app.OnStateEvent("move.onRoomObjEnd")
})
很明显,我们创建了一个内部变量moved,用于储存近期行走的房间
在onRoomObjEnd里,负责向moved里推时间戳
把内部函数gc注册到gc事件里
然后增加一个App.Moved函数,用于调用gc,获取移动成功步数,
注意,gc事件在目前的代码里并不必要,只是为了以后可能会主动发送命令做准备
然后,在retry(行走失败)和 ignore(忽略的房间描述)的触发了,弹出最后一个时间戳
app.Core.OnMoveRetry=function(name, output, wildcards){
moved.splice(-1)
app.OnStateEvent("move.retry")
}
app.Core.OnMoveIgnore=function(name, output, wildcards){
moved.splice(-1)
app.OnStateEvent("move.ignore")
}
移动指令就修改完了。
最后,我们修改发送的频率。
很明显,我们修改的是移动发送的模式,按照我们的基础篇里,这明显就是载具负责的事情。
我们添加一个慢悠悠的载具slow
(function (app) {
let Vehicle = Include("core/vehicle/vehicle.js")
let Slow = function () {
Vehicle.call(this)
this.ID="slow"
this.MultiStep=false
this.Fly=true
this.Sender=function(cmd){
if (app.GetMoved()<5){
app.Send(cmd)
}else{
app.OnStateEvent("move.retry")
}
}
}
Slow.prototype = Object.create(Vehicle.prototype)
return Slow
})(App)
和run一样区别是禁止多步,发送时判断一下已经发送的是否大等于5
需要休息的话就触发个move状态的retry时间
否者直接发送
然后在载具的vehicle.js里进行调整
引入slow载具,设置为默认载具,
let slow = Include("core/vehicle/slow.js")
app.Vehicle=null
app.Vehicles={
Run:new run(),
Go:new go(),
Cart:new cart(),
Slow:new slow(),
}
app.DefaultVehicle=app.Vehicles.Slow
app.Vehicle=app.DefaultVehicle
app.Drive=function(id){
if(id){
for (let key in app.Vehicles) {
if (app.Vehicles.ID == id){
app.Vehicle=app.Vehicles
return
}
}
throw "未知的载具 " +id
}else{
app.Vehicle=app.DefaultVehicle
}
}
好了。修改完毕。
最后,测试下机器人
walk.partor,locate都没问题,不需要改代码
明显会走4步停0.5秒
修改完毕
具体的patch 见
https://github.com/hellclient-scripts/pkuxkx.noob/commit/4facae4a6e560fe2aa8d303381c841f5840ac136
很明显,良好的架构对于一个机器的扩展和维护有很重要的价值。 厉害。希望我能有看懂的一天。 虽然程序我不懂,但是喜欢楼主这种分享编程思路的方式
赞一个 厉害,学习了 之前不玩北侠,光这样改还是有点问题的。
首先,移动记录要有个全局的,同时也要有个buff缓冲,就是与其在mud里缓存,不如自己缓存
代码大体如下
var moved=[]
var movebuff=[]
var gc=function(){
newmoved=[]
var now=(new Date()).getTime()
moved.forEach(function(ts){
if ((now-ts)<600){
newmoved.push(ts)
}
})
moved=newmoved
}
App.RegisterCallback("core.move.gc", function () {
gc()
if (moved.length<3&&movebuff.length){
App.Send(movebuff.shift())
moved.push((new Date()).getTime())
}
})
App.SendToMoveBuff=function(cmd){
gc()
if (moved.length<3){
App.Send(cmd)
moved.push((new Date()).getTime())
}else{
movebuff.push(cmd)
}
}
App.Bind("gc","core.move.gc")每0.6秒行走3次就堆入缓冲,这样在不太卡的情况下,任何一个一秒内不会连续发送超过6个移动命令(1.2秒周期,超过一秒)
其次,修改基础载具
(function(App){
let _drivepath=Include("include/drivepath.js")
let Vehicle=function(){
this.TagDrive=false
this.MultiStep=false
this.ID=""
this.RetryInterval=0.5
this.Fly=false
this.Sender=function(cmd){
App.SendToMoveBuff(cmd)
}
}
Vehicle.prototype.Send=function(cmd){
this.Sender(cmd)
}
Vehicle.prototype.ConvertDrivePath=function(cmd,path){
let p=_drivepath
if (!p){
throw "无效的drivepath"+path
}
p=p.replace("%1",cmd)
return p
}
return Vehicle
})(App)
让所有的行走都走这个SendToMoveBuff,收工。
为了以防万一,也就是卡顿的情况下,在移动时出发的[命令加入缓冲],直接发送一个"move.retry"状态事件 到当前状态
当作爬山时需要等一等重走的busy一样处理。
这样尽可能的能解决移动时进入缓冲的问题
另外之后应该还会更新三篇
大体是
武当新人人物篇
迷宫篇
战斗篇。
页:
[1]