| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- #nop vim: set filetype=tt:;
- /*
- 本文件属于 PaoTin++ 的一部分
- ===========
- PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
- 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
- ===========
- */
- #pathdir {n} {s} {1};
- #pathdir {e} {w} {2};
- #pathdir {s} {n} {4};
- #pathdir {w} {e} {8};
- #pathdir {u} {d} {16};
- #pathdir {d} {u} {32};
- #pathdir {ne} {sw} {3};
- #pathdir {nw} {se} {9};
- #pathdir {se} {nw} {6};
- #pathdir {sw} {ne} {12};
- #pathdir {nu} {sd} {17};
- #pathdir {eu} {wd} {18};
- #pathdir {su} {nd} {20};
- #pathdir {wu} {ed} {24};
- #pathdir {nd} {su} {33};
- #pathdir {ed} {wu} {34};
- #pathdir {sd} {nu} {36};
- #pathdir {wd} {eu} {40};
- #pathdir {neu} {swd} {19};
- #pathdir {nwu} {sed} {25};
- #pathdir {seu} {nwd} {22};
- #pathdir {swu} {ned} {28};
- #pathdir {ned} {swu} {35};
- #pathdir {nwd} {seu} {42};
- #pathdir {sed} {nwu} {38};
- #pathdir {swd} {neu} {44};
- #pathdir {out} {enter} {19};
- #pathdir {enter} {out} {44};
- VAR {当前路径} map.path.current {};
- event.HandleOnce {map/init} {map/path} {map} {map.path.Init};
- #alias {map.path.Init} {
- event.Handle {map/GotRoomInfo} {path.Hint} {map/path} {path.Hint};
- storage.Load map-path map.path.list;
- };
- ///=== {
- // ## path.Trace [<是否可翻转>] [<是否可压缩>]
- // 开始为本房间录制路径。
- // 两个参数指定了本次即将录制的路径特点,并会在录制完成时真正运用。
- // 如果省略参数,则默认为可翻转、可压缩。
- // 在录制完成之前,你仍然可以随时用 path.SetType 来重新设置。
- // };
- #alias {path.Trace} {
- #local reversible {@default{%1;true}};
- #local compact {@default{%2;true}};
- #if { @path.isTracing{} } {
- errLog 录制路径工作正在进行中。;
- #return;
- };
- #local area {@map.GetArea{}};
- #if { "$area" == "" } {
- event.HandleOnce {map/GotArea} {path.Trace} {map/path} {path.Trace};
- #delay map.Trace.retry {map.GetArea} 1;
- #return;
- };
- #var map.path.current {
- {from} {@map.Room.CID{}}
- {to} {}
- {reversible} {$reversible}
- {compact} {$compact}
- };
- event.Handle {GMCP.Move} {path.Trace} {map/path} {path.response};
- #path create;
- path.message 开始录制路径。;
- option.Enable KeypadWalk;
- ui.walk.SetCmd path.ui.move;
- };
- ///=== {
- // ## path.SetType [<是否可翻转>] [<是否可压缩>]
- // 重新设置当前正在录制的路径特点。
- // 两个参数指定了此时正在录制的路径特点,并会在录制完成时真正运用。
- // 如果省略参数,则默认为前值,不予改变。
- // 在录制完成之前,你仍然可以随时用 path.SetType 来重新设置。
- // };
- #alias {path.SetType} {
- #if { "%0" == "" } {
- xtt.Usage %90;
- #return;
- };
- #if { ! @path.isTracing{} } {
- errLog 尚未开始录制。;
- #return;
- };
- #local reversible {@default{%1;$map.path.current[reversible]}};
- #local compact {@default{%2;$map.path.current[compact]}};
- #var map.path.current[reversible] {$reversible};
- #var map.path.current[compact] {$compact};
- };
- #alias {path.ui.move} {
- #local dir {%1};
- #local short {@dir.Short{%1}};
- #path insert {$short};
- go $dir;
- };
- #alias {path.response} {
- #local cmd {@ga.ThisCmd{}};
- #if { @isFalse{$gGMCP[Move][成功]} } {
- #if { "$cmd" == "go %+" } {
- #path delete;
- };
- #return;
- };
- #if { @dir.IsDir{$cmd} } {
- #local short {@dir.Short{$cmd}};
- #if { "$cmd" !== "$short" } {
- #path insert {$cmd};
- };
- };
- #elseif { "$cmd" != "go %*" } {
- warnLog 未知的移动方式,无法识别,请手动维护路径。;
- path.Mark {$gMapRoom[name]/$cmd};
- #return;
- };
- #local length {};
- #path get length length;
- path.message 路径录制中,{<139>$cmd<159>} 已添加,目前长度: $length;
- };
- ///=== {
- // ## path.BotStep <机器人名称> [<机器人参数> ...]
- // 插入一个机器人行走步骤。
- // 接到本指令时,PaoTin++ 会进行如下处理:
- // - 1: 暂停路径录制;
- // - 2: 在路径中插入一个机器人步骤;
- // - 3: 自动调用机器人行走;
- // - 4: 机器人行走完成后,自动恢复录制。
- // 按照约定,符合本规范的机器人必须发射以下事件之一:
- // - map/walk/continue: 代表机器人成功结束运行,通过该区域
- // - map/walk/failed: 代表机器人遇到了无法逾越的障碍,放弃行走
- // 本命令会监听以上事件并做相应处理。
- // };
- #alias {path.BotStep} {
- #local bot {%1};
- #info arguments save;
- #local args {$info[ARGUMENTS]};
- #unvar info[ARGUMENTS];
- #unlocal args[0];
- #if { "$bot" == "" } {
- xtt.Usage %90;
- #return;
- };
- #if { ! @path.isTracing{} } {
- errLog 路径录制尚未开始。;
- #return;
- };
- #if { !@existsAlias{map.$bot} } {
- errLog 不存在机器人 $bot,请检查是否拼写错误。;
- #return;
- };
- #class path.BotStep open;
- #alias {path.BotStep.done} {
- path.BotStep.end;
- path.message 机器人运行完成,继续录制路径。;
- };
- #line sub var #alias {path.BotStep.failed} {
- path.BotStep.end;
- path.message 机器人运行出错,姑且继续录制,如有不脱请取消录制。;
- };
- #line sub var #alias {path.BotStep.end} {
- #class path.BotStep kill;
- #path start;
- event.Handle {GMCP.Move} {path.Trace} {pathdir} {path.response};
- path.message <129>录制路径中…… <299>;
- };
- event.ClassHandleOnce {map/walk/continue} {map.$bot} {pathdir} {path.BotStep.done};
- event.ClassHandleOnce {map/walk/failed} {map.$bot} {pathdir} {path.BotStep.failed};
- #class path.BotStep close;
- event.UnHandle {GMCP.Move} {path.Trace} {pathdir};
- #local step {$bot};
- #local count {&args[]};
- #if { $count > 1 } {
- #local idx {};
- #loop 2 {$count} {idx} {
- #local arg {$args[$idx]};
- #if { "$arg" == "%*;%*" } {
- #cat {step} {/{$arg}};
- };
- #else {
- #cat {step} {/$arg};
- };
- };
- };
- #path stop;
- #path insert {$step} {$step};
- path.message 已经暂停路径录制,将会在机器人运行结束后自动继续。;
- map.%0;
- };
- ///=== {
- // ## path.Mark [<记号>]
- // 在录制路径的过程中,插入一个记号,方便将来手动编辑路径。
- // 如果省略记号,默认为当前房间名。
- // };
- #alias {path.Mark} {
- #local mark {@default{%1;$gMapRoom[name]}};
- #if { ! @path.isTracing{} } {
- errLog 路径录制尚未开始。;
- #return;
- };
- #path insert {Mark/$mark} {Mark/$mark};
- };
- #alias {map.Mark} {
- #local mark {%1};
- okLog 这里有一个记号:「$mark」。;
- map.BotReturn map.Mark;
- };
- ///=== {
- // ## path.Cancel
- // 取消当前正在进行的录制路径工作。
- // };
- #alias {path.Cancel} {
- #if { ! @path.isTracing{} } {
- errLog 路径录制尚未开始。;
- #return;
- };
- #var map.path.current {};
- #path destroy;
- event.UnHandle {GMCP.Move} {path.Trace};
- path.message 放弃了本次路径录制工作。;
- };
- ///=== {
- // ## path.Finish
- // 完成录制。
- // };
- #alias {path.Finish} {
- #local area {@map.GetArea{}};
- #if { "$area" == "" } {
- event.HandleOnce {map/GotArea} {path.Finish} {map/path} {path.Finish};
- #delay map.Finish.retry {map.GetArea} 1;
- #return;
- };
- #local here {@map.Room.CID{}};
- #var map.path.current[to] {$here};
- #path stop;
- event.UnHandle {GMCP.Move} {path.Trace};
- #local fpath {};
- #path save forward fpath;
- #local bpath {};
- #path save backward bpath;
- #if { "$map.path.current[from]" == "$map.path.current[to]" } {
- okLog 检测到遍历路径。;
- #local length {};
- #path get length length;
- #local pathName {${here}-遍历${area}-$length};
- #var map.path.list[$pathName] {$fpath};
- };
- #else {
- #if { @isTrue{$map.path.current[compact]} } {
- #local fpath {@path.Simplify{$fpath}};
- };
- okLog 正向路径: {#$fpath#};
- #local pathName {${map.path.current[from]}-${map.path.current[to]}};
- #var map.path.list[$pathName] {$fpath};
- #if { @isTrue{$map.path.current[reversible]} } {
- #if { @isTrue{$map.path.current[compact]} } {
- #local bpath {@path.Simplify{$bpath}};
- };
- okLog 反向路径: {#$bpath#};
- #local pathName {${map.path.current[to]}-${map.path.current[from]}};
- #var map.path.list[$pathName] {$bpath};
- };
- };
- #var map.path.current {};
- #path destroy;
- path.message 路径录制结束。你可以使用 {@mslp.Exec{path.List;path.List}} 命令查看本房间的关联路径。;
- path.Hint;
- storage.Save map-path map.path.list;
- };
- ///=== {
- // ## path.Hint
- // 如果此处有路径,则提醒玩家。
- // };
- #alias {path.Hint} {
- #nop 录制路径的过程中,提示以录制为主。;
- #if { @path.isTracing{} } {
- #return;
- };
- #local area {@map.GetArea{}};
- #if { "$area" == "" } {
- #local here {@xiaoyao.Locate{}};
- #if { "$here" == "" } {
- path.hint;
- #return;
- };
- };
- #local here {@map.Room.CID{}};
- #local path {@table.Keys{map.path.list; {${here}-%*}}};
- #local count {@slist.Size{$path}};
- #if { $count > 0 } {
- #local path {@fp.Transform{{$path};\@str.Replace{VALUE;{%*-%*};{&2}}}};
- #local path {@fp.Transform{{$path};\@mslp.Exec{{path.Walk ${here}-VALUE};<139>\@str.Replace{VALUE;{$area的};{}}<299>}} };
- path.hint $path;
- };
- #else {
- path.hint;
- };
- };
- ///=== {
- // ## path.List
- // 查看本房间都有哪些关联路径,类似于北侠 node 或者 walk 命令。
- // };
- #alias {path.List} {
- #local area {@map.GetArea{}};
- #if { "$area" == "" } {
- event.HandleOnce {map/GotArea} {path.List} {map/path} {path.List};
- #delay map.List.retry {map.GetArea} 1;
- #return;
- };
- #local here {@map.Room.CID{}};
- #local count {0};
- #local name {};
- #foreach {*map.path.list[]} {name} {
- #if { "$name" == "${here}-%*" } {
- #local path {$map.path.list[$name]};
- #local size {@slist.Size{$path}};
- #echo {%s(<129>$size<299>): %s} {@mslp.Exec{{path.Walk $name};<139>$name<299>}} {<169>$path<099>};
- #math count {$count + 1};
- };
- };
- #if { $count > 0 } {
- okLog 共列出 $count 条关联路径。;
- };
- #else {
- warnLog 尚未找到本房间的关联路径。;
- };
- path.message 为本房间录制更多路径请使用 {@mslp.Exec{path.Trace;path.Trace}}。;
- };
- ///=== {
- // #@ path.Get <路径名称>
- // 查询并返回路径。
- // };
- #func {path.Get} {
- #local name {%0};
- #if { "$name" == "" } {
- #return {};
- };
- #return {$map.path.list[$name]};
- };
- VAR {千里通步进推进器} {path.Walk.Stepper} {};
- ///=== {
- // ## path.Walk.SetStepper <步进推进器>
- // 设置路径行走的步进推进器。如果设置了步进推进器,则千里通将进入步进推进模式。
- // 你推一步,它就走一步,不推就不走。
- // 你可以用 path.Walk.Resume 来推动千里通继续前进,一次一步。
- // 注意,步进推进器仅在下一次行走任务中生效。一旦行走结束,无论成功失败,步进推进器设置将被清空。
- // };
- #alias {path.Walk.SetStepper} {
- #local stepper {%21};
- #if { "$stepper" == "" } {
- xtt.Usage %90;
- #return;
- };
- #var path.Walk.Stepper {$stepper};
- };
- ///=== {
- // ## path.Walk <路径名称> [<回调代码>]
- // 沿着指定的路径名称执行行走任务。行走完成后,执行回调代码。
- // 如果省略回调代码,用户仍可通过订阅 map/walk/continue 事件获得回调机会。
- // 注意约定的回调钩子名称为 map/path/end。
- // };
- #alias {path.Walk} {
- #local name {%1};
- #local callback {%22};
- #local path {$map.path.list[$name]};
- #if { "$name" == "" } {
- xtt.Usage %90;
- #return;
- };
- #if { "$callback" != "" } {
- #line sub {escapes;var} event.HandleOnce map/walk/continue {map/path/end} {map/path} {$callback};
- };
- path.WalkSteps {$path};
- };
- ///=== {
- // ## path.WalkSteps <路径> [<回调代码>]
- // 走一个自定义路径。行走完成后,执行回调代码。
- // };
- #alias {path.WalkSteps} {
- #local path {%1};
- #local callback {%22};
- #local len {@slist.Size{$path}};
- #if { $len == 0 } {
- xtt.Usage %90;
- #return;
- };
- #local path {@fp.Transform{{$path};path.step {VALUE}}};
- #if { $len > 1 } {
- env.Set brief 3;
- #local path {@slist.Insert{{$path};$len;path.last-step}};
- };
- #if { "$callback" != "" } {
- #line sub {escapes;var} event.HandleOnce map/walk/continue {map/path/end} {map/path} {$callback};
- };
- #path load {$path;path.end};
- sync.Wait {#path walk};
- };
- #alias {path.step} {
- #class path.step open;
- #local cmd {@dir.Long{%1}};
- #if { "$path.Walk.Stepper" === "" } {
- event.HandleOnce {map/walk/continue} {map/step} {map/path} {path.step.next};
- };
- #else {
- #line sub {escapes;var} event.HandleOnce {map/walk/continue} {map/step} {map/path} {$path.Walk.Stepper};
- };
- event.HandleOnce {map/walk/failed} {map/step} {map/path} {#path destroy; path.last-step; path.end};
- map.step.Try {} {$cmd} {};
- };
- VAR {停止走路标志} path.walk.stop {0};
- #alias {path.Walk.Stop} {
- #var path.walk.stop 1;
- };
- #alias {path.Walk.Resume} {
- #var path.walk.stop 0;
- path.step.next;
- };
- #alias {path.Walk.Reset} {
- #var path.walk.stop 0;
- #path destroy;
- };
- #alias {path.step.next} {
- #if { ! $path.walk.stop } {
- #path walk;
- };
- };
- #alias {path.last-step} {
- env.UnSet brief;
- #path walk;
- };
- #alias {path.end} {
- okLog 行走完成。;
- #local path {};
- #path get info {path};
- #if { $path[position] <= $path[length] } {
- sync.Wait {
- #path run;
- };
- };
- #var path.Walk.Stepper {};
- event.Emit {map/walk/continue} {map/path/end};
- event.HandleOnce {map/GotArea} {path/end} {map/path} {path.Hint};
- map.GetArea;
- };
- #func {path.isTracing} {
- #if { &map.path.current[] > 0 } {
- #return 1;
- };
- #else {
- #return 0;
- };
- };
- #alias {path.message} {
- #local msg {%0};
- #local trace {@mslp.Exec{path.Trace;<159>path.Trace<299>}};
- #local cancel {@mslp.Exec{path.Cancel;<119>path.Cancel<299>}};
- #local finish {@mslp.Exec{path.Finish;<129>path.Finish<299>}};
- #if { @path.isTracing{} } {
- infoLog <159>$msg<299> 取消录制请使用 {$cancel},完成录制请使用 {$finish}。<299>;
- };
- #else {
- infoLog <159>$msg<299> 要想录制新路径,请使用 {$trace}。<299>;
- };
- path.hint %0;
- };
- VAR {map/path 模块提醒内容} {path-hint} {NOTHING};
- #alias {path.hint} {
- #local hint {%0};
- #if { "$path-hint" == "$hint" } {
- #return;
- };
- #var path-hint {$hint};
- #local trace {【@mslp.Exec{path.Trace;<159>开始录制<299>}】};
- #local cancel {【@mslp.Exec{path.Cancel;<119>取消录制<299>}】};
- #local finish {【@mslp.Exec{path.Finish;<129>完成录制<299>}】};
- #if { @path.isTracing{} } {
- #local hint {$finish $cancel <159>$hint<299>};
- };
- #else {
- #local hint {$trace <159>$hint<299>};
- };
- prompt.Set {{path}{$hint}};
- };
|