path.tin 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. #nop vim: set filetype=tt:;
  2. /*
  3. 本文件属于 PaoTin++ 的一部分
  4. ===========
  5. PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
  6. 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
  7. ===========
  8. */
  9. #pathdir {n} {s} {1};
  10. #pathdir {e} {w} {2};
  11. #pathdir {s} {n} {4};
  12. #pathdir {w} {e} {8};
  13. #pathdir {u} {d} {16};
  14. #pathdir {d} {u} {32};
  15. #pathdir {ne} {sw} {3};
  16. #pathdir {nw} {se} {9};
  17. #pathdir {se} {nw} {6};
  18. #pathdir {sw} {ne} {12};
  19. #pathdir {nu} {sd} {17};
  20. #pathdir {eu} {wd} {18};
  21. #pathdir {su} {nd} {20};
  22. #pathdir {wu} {ed} {24};
  23. #pathdir {nd} {su} {33};
  24. #pathdir {ed} {wu} {34};
  25. #pathdir {sd} {nu} {36};
  26. #pathdir {wd} {eu} {40};
  27. #pathdir {out} {enter} {19};
  28. #pathdir {enter} {out} {44};
  29. VAR {当前路径} path-current {};
  30. event.HandleOnce {map/init} {map/path} {map} {map.path.Init};
  31. #alias {map.path.Init} {
  32. event.Handle {map/GotRoomInfo} {path.Hint} {map/path} {path.Hint};
  33. storage.Load path path-list;
  34. };
  35. ///=== {
  36. // ## path.Trace
  37. // 开始为本房间录制路径。
  38. // };
  39. #alias {path.Trace} {
  40. #local area {@map.GetArea{}};
  41. #if { "$area" == "" } {
  42. event.HandleOnce {map/GotArea} {path.Trace} {map/path} {path.Trace};
  43. #delay map.Trace.retry {map.GetArea} 1;
  44. #return;
  45. };
  46. #if { @path.isTracing{} } {
  47. errLog 录制路径工作正在进行中。;
  48. #return;
  49. };
  50. #var path-current {
  51. {from} {@map.Room.CID{}}
  52. {to} {}
  53. };
  54. event.Handle {GMCP.Move} {path.Trace} {map/path} {path.response};
  55. #path create;
  56. path.message 开始录制路径。;
  57. option.Enable KeypadWalk;
  58. ui.walk.SetCmd path.ui.move;
  59. };
  60. #alias {path.ui.move} {
  61. #local dir {%1};
  62. #local short {@dir.Short{%1}};
  63. #path insert {$short};
  64. go $dir;
  65. };
  66. #alias {path.response} {
  67. #local cmd {@ga.ThisCmd{}};
  68. #if { @isFalse{$gGMCP[Move][成功]} } {
  69. #if { "$cmd" == "go %+" } {
  70. #path delete;
  71. };
  72. #return;
  73. };
  74. #if { @dir.IsDir{$cmd} } {
  75. #local short {@dir.Short{$cmd}};
  76. #if { "$cmd" !== "$short" } {
  77. #path insert {$cmd};
  78. };
  79. };
  80. #elseif { "$cmd" != "go %*" } {
  81. warnLog 未知的移动方式,无法识别,请手动维护路径。;
  82. path.Mark {$gMapRoom[name]/$cmd};
  83. #return;
  84. };
  85. #local length {};
  86. #path get length length;
  87. path.message 路径录制中,{<139>$cmd<159>} 已添加,目前长度: $length;
  88. };
  89. ///=== {
  90. // ## path.BotStep <机器人名称> [<机器人参数> ...]
  91. // 插入一个机器人行走步骤。
  92. // 接到本指令时,PaoTin++ 会进行如下处理:
  93. // - 1: 暂停路径录制;
  94. // - 2: 在路径中插入一个机器人步骤;
  95. // - 3: 自动调用机器人行走;
  96. // - 4: 机器人行走完成后,自动恢复录制。
  97. // 按照约定,符合本规范的机器人必须发射以下事件之一:
  98. // - map/walk/continue: 代表机器人成功结束运行,通过该区域
  99. // - map/walk/failed: 代表机器人遇到了无法逾越的障碍,放弃行走
  100. // 本命令会监听以上事件并做相应处理。
  101. // };
  102. #alias {path.BotStep} {
  103. #local bot {%0};
  104. #local name {%1};
  105. #if { ! @path.isTracing{} } {
  106. errLog 路径录制尚未开始。;
  107. #return;
  108. };
  109. #if { !@existsAlias{map.$name} } {
  110. errLog 不存在机器人 $name,请检查是否拼写错误。;
  111. #return;
  112. };
  113. #local cancel {@mslp.Exec{path.Cancel;path.Cacnel}};
  114. #local finish {@mslp.Exec{path.Finish;path.Finish}};
  115. #class path.BotStep open;
  116. #alias {path.BotStep.done} {
  117. path.BotStep.end;
  118. path.message 机器人运行完成,继续录制路径。;
  119. };
  120. #line sub var #alias {path.BotStep.failed} {
  121. path.BotStep.end;
  122. errLog 机器人运行出错,姑且继续录制。如果想要取消录制请使用 $cancel;
  123. };
  124. #line sub var #alias {path.BotStep.end} {
  125. #class path.BotStep kill;
  126. event.UnHandle {map/walk/continue} {path.BotStep};
  127. event.UnHandle {map/walk/failed} {path.BotStep};
  128. #path start;
  129. event.Handle {GMCP.Move} {path.Trace} {pathdir} {path.response};
  130. path.message <129>录制路径中…… <299>取消录制请点击【<119>$cancel<299>】结束录制请点击【<129>$finish<299>】;
  131. };
  132. #class path.BotStep close;
  133. event.HandleOnce {map/walk/continue} {path.BotStep} {pathdir} {path.BotStep.done};
  134. event.HandleOnce {map/walk/failed} {path.BotStep} {pathdir} {path.BotStep.failed};
  135. event.UnHandle {GMCP.Move} {path.Trace} {pathdir};
  136. path.message <139>录制路径已暂停<299>取消录制请点击【<119>$cancel<299>】结束录制请点击【<129>$finish<299>】;
  137. #path stop;
  138. #path insert {$bot} {$bot};
  139. path.message 已经暂停路径录制,将会在机器人运行结束后自动继续。;
  140. map.$bot;
  141. };
  142. ///=== {
  143. // ## path.Mark [<记号>]
  144. // 在录制路径的过程中,插入一个记号,方便将来手动编辑路径。
  145. // 如果省略记号,默认为当前房间名。
  146. // };
  147. #alias {path.Mark} {
  148. #local mark {@default{%1;$gMapRoom[name]}};
  149. #if { ! @path.isTracing{} } {
  150. errLog 路径录制尚未开始。;
  151. #return;
  152. };
  153. #path insert {Mark/$mark} {Mark/$mark};
  154. };
  155. #alias {map.Mark} {
  156. #local mark {%1};
  157. okLog 这里有一个记号:「$mark」。;
  158. map.BotReturn map.Mark;
  159. };
  160. ///=== {
  161. // ## path.Cancel
  162. // 取消当前正在进行的录制路径工作。
  163. // };
  164. #alias {path.Cancel} {
  165. #if { ! @path.isTracing{} } {
  166. errLog 路径录制尚未开始。;
  167. #return;
  168. };
  169. #var path-current {};
  170. #path destroy;
  171. event.UnHandle {GMCP.Move} {path.Trace};
  172. path.message 放弃了本次路径录制工作。;
  173. };
  174. ///=== {
  175. // ## path.Finish
  176. // 完成录制。
  177. // };
  178. #alias {path.Finish} {
  179. #local area {@map.GetArea{}};
  180. #if { "$area" == "" } {
  181. event.HandleOnce {map/GotArea} {path.Finish} {map/path} {path.Finish};
  182. #delay map.Finish.retry {map.GetArea} 1;
  183. #return;
  184. };
  185. #local here {@map.Room.CID{}};
  186. #var path-current[to] {$here};
  187. #path stop;
  188. event.UnHandle {GMCP.Move} {path.Trace};
  189. #local fpath {};
  190. #path save forward fpath;
  191. #local bpath {};
  192. #path save backward bpath;
  193. #if { "$path-current[from]" == "$path-current[to]" } {
  194. okLog 检测到遍历路径。;
  195. #local length {};
  196. #path get length length;
  197. #local pathName {${here}-遍历${area}-$length};
  198. #var path-list[$pathName] {$fpath};
  199. };
  200. #else {
  201. #local fpath {@path.Simplify{$fpath}};
  202. okLog 正向路径: {#$fpath#};
  203. #local pathName {${path-current[from]}-${path-current[to]}};
  204. #var path-list[$pathName] {$fpath};
  205. #local bpath {@path.Simplify{$bpath}};
  206. okLog 反向路径: {#$bpath#};
  207. #local pathName {${path-current[to]}-${path-current[from]}};
  208. #var path-list[$pathName] {$bpath};
  209. };
  210. #var path-current {};
  211. #path destroy;
  212. path.message 路径录制结束。你可以使用 {@mslp.Exec{path.List;path.List}} 命令查看本房间的关联路径。;
  213. storage.Save path path-list;
  214. };
  215. ///=== {
  216. // ## path.Hint
  217. // 如果此处有路径,则提醒玩家。
  218. // };
  219. #alias {path.Hint} {
  220. #nop 录制路径的过程中,提示以录制为主。;
  221. #if { @path.isTracing{} } {
  222. #return;
  223. };
  224. #local area {@map.GetArea{}};
  225. #if { "$area" == "" } {
  226. #local here {@xiaoyao.Locate{}};
  227. #if { "$here" == "" } {
  228. path.hint;
  229. #return;
  230. };
  231. };
  232. #local here {@map.Room.CID{}};
  233. #local path {@table.Keys{path-list; {${here}-%*}}};
  234. #local count {@slist.Size{$path}};
  235. #if { $count > 0 } {
  236. #local path {@fp.Transform{{$path};\@str.Replace{VALUE;{%*-%*};{&2}}}};
  237. #local path {@fp.Transform{{$path};\@mslp.Exec{{path.Walk ${here}-VALUE};<139>VALUE<299>}} };
  238. path.hint $path;
  239. };
  240. #else {
  241. path.hint;
  242. };
  243. };
  244. ///=== {
  245. // ## path.List
  246. // 查看本房间都有哪些关联路径,类似于北侠 node 或者 walk 命令。
  247. // };
  248. #alias {path.List} {
  249. #local area {@map.GetArea{}};
  250. #if { "$area" == "" } {
  251. event.HandleOnce {map/GotArea} {path.List} {map/path} {path.List};
  252. #delay map.List.retry {map.GetArea} 1;
  253. #return;
  254. };
  255. #local here {@map.Room.CID{}};
  256. #local count {0};
  257. #local name {};
  258. #foreach {*path-list[]} {name} {
  259. #if { "$name" == "${here}-%*" } {
  260. #local path {$path-list[$name]};
  261. #local size {@slist.Size{$path}};
  262. #echo {%s(<129>$size<299>): %s} {@mslp.Exec{{path.Walk $name};<139>$name<299>}} {<169>$path<099>};
  263. #math count {$count + 1};
  264. };
  265. };
  266. #if { $count > 0 } {
  267. okLog 共列出 $count 条关联路径。;
  268. };
  269. #else {
  270. warnLog 尚未找到本房间的关联路径。;
  271. };
  272. path.message 为本房间录制更多路径请使用 {@mslp.Exec{path.Trace;path.Trace}}。;
  273. };
  274. ///=== {
  275. // #@ path.Get <路径名称>
  276. // 查询并返回路径。
  277. // };
  278. #func {path.Get} {
  279. #local name {%0};
  280. #if { "$name" == "" } {
  281. #return {};
  282. };
  283. #return {$path-list[$name]};
  284. };
  285. ///=== {
  286. // ## path.Walk <路径名称> [<回调代码>]
  287. // 沿着指定的路径名称执行行走任务。行走完成后,执行回调代码。
  288. // };
  289. #alias {path.Walk} {
  290. #local name {%1};
  291. #local callback {%2};
  292. #local path {$path-list[$name]};
  293. path.WalkSteps {$path} {$callback};
  294. };
  295. ///=== {
  296. // ## path.WalkSteps <路径> [<回调代码>]
  297. // 走一个自定义路径。行走完成后,执行回调代码。
  298. // };
  299. #alias {path.WalkSteps} {
  300. #local path {%1};
  301. #local callback {%2};
  302. #local len {@slist.Size{$path}};
  303. #local path {@fp.Transform{{$path};path.step {VALUE}}};
  304. #if { $len > 1 } {
  305. env.Set brief 3;
  306. #local path {@slist.Insert{{$path};$len;path.last-step}};
  307. };
  308. #if { "$callback" == "" } {
  309. #path load {$path;path.end};
  310. };
  311. #else {
  312. #path load {$path;path.end;$callback};
  313. };
  314. sync.Wait {#path walk};
  315. };
  316. #alias {path.step} {
  317. #class path.step open;
  318. #local cmd {@dir.Long{%1}};
  319. event.HandleOnce {map/walk/continue} {map/step} {map/path} {path.step.next};
  320. event.HandleOnce {map/walk/failed} {map/step} {map/path} {#path destroy; path.last-step};
  321. map.step.Try {} {$cmd} {};
  322. };
  323. VAR {停止走路标志} path.walk.stop {0};
  324. #alias {path.Walk.Stop} {
  325. #var path.walk.stop 1;
  326. };
  327. #alias {path.Walk.Resume} {
  328. #var path.walk.stop 0;
  329. };
  330. #alias {path.Walk.Reset} {
  331. #var path.walk.stop 0;
  332. #path destroy;
  333. };
  334. #alias {path.step.next} {
  335. #if { ! $path.walk.stop } {
  336. #path walk;
  337. };
  338. };
  339. #alias {path.last-step} {
  340. env.UnSet brief;
  341. #path walk;
  342. };
  343. #alias {path.end} {
  344. okLog 行走完成。;
  345. #local path {};
  346. #path get info {path};
  347. #if { $path[position] <= $path[length] } {
  348. sync.Wait {
  349. #path run;
  350. };
  351. };
  352. event.HandleOnce {map/GotArea} {path/end} {map/path} {path.Hint};
  353. map.GetArea;
  354. };
  355. #func {path.isTracing} {
  356. #if { &path-current[] > 0 } {
  357. #return 1;
  358. };
  359. #else {
  360. #return 0;
  361. };
  362. };
  363. #alias {path.message} {
  364. #local msg {%0};
  365. infoLog <159>$msg<299>;
  366. path.hint %0;
  367. };
  368. VAR {map/path 模块提醒内容} {path-hint} {NOTHING};
  369. #alias {path.hint} {
  370. #local hint {%0};
  371. #if { "$path-hint" == "$hint" } {
  372. #return;
  373. };
  374. #var path-hint {$hint};
  375. #local trace {【@mslp.Exec{path.Trace;<159>开始录制<299>}】};
  376. #local cancel {【@mslp.Exec{path.Cancel;<119>取消录制<299>}】};
  377. #local finish {【@mslp.Exec{path.Finish;<129>完成录制<299>}】};
  378. #if { @path.isTracing{} } {
  379. #local hint {$finish $cancel <159>$hint<299>};
  380. };
  381. #else {
  382. #local hint {$trace <159>$hint<299>};
  383. };
  384. prompt.Set {{path}{$hint}};
  385. };