area.tin 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #nop vim: set filetype=tt:;
  2. /*
  3. 本文件属于 PaoTin++ 的一部分
  4. ===========
  5. PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
  6. 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
  7. ===========
  8. */
  9. ///=== {
  10. ///// map/area --- 大众版区域信息获取模块
  11. /////
  12. ///// 本模块主要使用 walk 和 localmaps 两个常用命令。
  13. ///// };
  14. VAR {全局区域对照表} {map.area.dict} {};
  15. event.Define {map/GotArea} {无参} {$MODULE} {已经获取到区域信息,并更新到 gMapRoom 全局变量。};
  16. event.Define {map/GotLocalmaps} {无参} {$MODULE} {已经解析 localmaps 命令。};
  17. event.HandleOnce {map/init} {map/area} {map} {pkuxkx.map.area.init};
  18. #alias {pkuxkx.map.area.init} {
  19. set localmap;
  20. storage.Load {map-area} {map.area.dict};
  21. };
  22. ///=== {
  23. // ## map.GetArea
  24. // 弄清楚角色当前位于哪个区域。
  25. // 注意调查过程中可能会向服务器发送必要的命令(尽可能少地)。但如果角色正在移动,则不会发送任何命令。
  26. // 弄清楚之后,发送事件 map/GotArea。
  27. // 注意如果已经弄清楚了,则不会发送事件。因此建议先通过函数 map.GetArea 进行查询。
  28. // };
  29. #alias {map.GetArea} {
  30. #if { @ga.IsUnderway{} } {dbgLog map underway; #return};
  31. #if { "$gMapRoom[direction]" != "here" } {dbgLog map not here; #return};
  32. map.area.check;
  33. };
  34. ///=== {
  35. // #@ map.GetArea
  36. // 返回当前房间信息中的区域信息。无参数。
  37. // };
  38. #func {map.GetArea} {
  39. #return {@map.resolveArea{$gMapRoom[area]}};
  40. };
  41. #alias {map.area.check} {
  42. #local stage {@default{{%1};start}};
  43. #local area {@map.GetArea{}};
  44. #if { "$area" != "" } {
  45. #if { "$gMapRoom[area][RESOLVED]" == "" } {
  46. #var gMapRoom[area][RESOLVED] {$area};
  47. event.DelayEmit map/GotArea;
  48. };
  49. #return;
  50. };
  51. #switch {"$stage"} {
  52. #case {"start"} {
  53. event.HandleOnce {map/GotNodeInfo} {map/area} {map} {map.area.check walk-done};
  54. map.GetNodeInfo gag;
  55. };
  56. #case {"walk-done"} {
  57. event.HandleOnce {map/GotLocalmaps} {map/area} {map} {map.area.check localmaps-done};
  58. map.Localmaps gag;
  59. };
  60. #case {"localmaps-done"} {
  61. #return;
  62. };
  63. };
  64. };
  65. ///=== {
  66. // ## map.Localmaps <是否 gag> [<命令参数>]
  67. // 执行 localmaps,但因为该命令结果过于刷屏,因此允许 gag 其输出。
  68. // };
  69. #alias {map.Localmaps} {
  70. #local gag {%1};
  71. #local args {%2};
  72. #if { "$args" != "" } {
  73. xtt.Send {localmaps $args};
  74. #return;
  75. };
  76. #var gMapRoom[area][LMAP] {};
  77. #class map.Localmaps open;
  78. #line oneshot #action {~^{\e\[0m|}◆%*◆%C{|\(非任务区域\)}%C$} {
  79. #local rawTitle {@raw.EraseInvisible{{%%2};true}};
  80. #if { &rawTitle[fragments][] == 0 } {
  81. errLog 遇到了特殊情况,请报告开发者。;
  82. #return;
  83. };
  84. #local title {$rawTitle[fragments][1]};
  85. #var gMapRoom[area][LMAP] {$title[text]};
  86. #var gMapRoom[area][COLOR] {$title[color]};
  87. #if { "%%4" == "" } {
  88. #var gMapRoom[area][JOB] {true};
  89. };
  90. #else {
  91. #var gMapRoom[area][JOB] {false};
  92. };
  93. } {4};
  94. #line oneshot #action {~^{\e\[0m|}%c◆%*地图%*◆%C{|\(非任务区域\)}%C$} {
  95. #local color {%%2};
  96. #replace color {\e[} {};
  97. #replace color {m$} {};
  98. #replace color {m} {;};
  99. #local area {%%3%%4};
  100. #var gMapRoom[area][LMAP] {$area};
  101. #var gMapRoom[area][COLOR] {$color};
  102. #if { "%%6" == "" } {
  103. #var gMapRoom[area][JOB] {true};
  104. };
  105. #else {
  106. #var gMapRoom[area][JOB] {false};
  107. };
  108. #if { "$area" == "柳秀山庄" } {
  109. #class map.Localmaps.gag kill;
  110. };
  111. } {2};
  112. #line oneshot #action {^%s%S略图%s$} {
  113. #var gMapRoom[terrain] {@default{$gMapRoom[terrain];随机地图}};
  114. #var gMapRoom[village] {%%2};
  115. };
  116. #line oneshot #action {┌─{(─)*}─%*附近详图─{(─)*}─┐$} {
  117. #var gMapRoom[terrain] {随机地图};
  118. };
  119. #if { "$gag" == "gag" } {
  120. #class map.Localmaps.gag open;
  121. #action {^%*{|ID=map/localmaps}$} {#line gag} {6};
  122. #gag {^%*{|ID=map/localmaps}$};
  123. #class map.Localmaps.gag close;
  124. };
  125. option.Push HighlightBlue false;
  126. #class map.Localmaps close;
  127. xtt.Send {localmaps};
  128. sync.Wait {
  129. option.Pop HighlightBlue;
  130. #class map.Localmaps kill;
  131. #class map.Localmaps.gag kill;
  132. event.DelayEmit map/GotLocalmaps;
  133. };
  134. };
  135. #alias {lm} {map.Localmaps nogag {%0}};
  136. #alias {localmaps} {map.Localmaps nogag {%0}};
  137. #alias {localmaps_gag} {map.Localmaps gag {%0}};
  138. #nop 根据数据源确定区域信息。数据源有四种(按使用优先级):link、walk、node、localmaps;
  139. #func {map.resolveArea} {
  140. #local source {%0};
  141. #if { "$source[RESOLVED]" != "" } {
  142. #return {$source[RESOLVED]};
  143. };
  144. #if { "$source[LINK]$source[WALK]$source[NODE]$source[LMAP]" == "" } {
  145. #return {};
  146. };
  147. #local lmap {@default{$source[LMAP];%*}};
  148. #local pattern {%*/$lmap};
  149. #nop 如果有 LMAP 的话,先根据 LMAP 检索,这个基本上可以做到一一对应。;
  150. #if { "$source[LMAP]" != "" } {
  151. #local keys {@table.Keys{map.area.dict;{$pattern}}};
  152. #if { @sset.Size{$keys} == 1 } {
  153. #return {$map.area.dict[$keys][PP]};
  154. };
  155. };
  156. #nop 否则查找与 LINK/WALK/NODE 相匹配的信息。;
  157. #nop TODO: 理论上这部分也可以做优化,但是 KEY 长了之后太丑了没必要。;
  158. #local area {};
  159. #foreach {*map.area.dict[$pattern]} {area} {
  160. #local area {$map.area.dict[$area]};
  161. #if { "$source[LINK]" == "%+/%+" } {
  162. #local link {@str.Replace{{$source[LINK]};%+/%+;{{node}{&1}{links}{&2}}}};
  163. #if { "$area[LINKS][$link[node]]" === "$link[links]" } {
  164. #return {$area[PP]};
  165. };
  166. };
  167. #elseif { "$source[WALK]$source[NODE]" != "" } {
  168. #if { "$source[WALK]$source[NODE]" !== "$area[WALK]$area[NODE]" } {
  169. #continue;
  170. };
  171. #if { "$source[WALK]/$source[NODE]" !== "NOTHING/NOTHING" } {
  172. #return {$area[PP]};
  173. };
  174. };
  175. };
  176. #return {};
  177. };
  178. ///=== {
  179. /// #@ map.AreaColor <区域名称>
  180. // 获取该区域的颜色。
  181. // 区域颜色是一个区域的固有属性,可以通过该区域的平民 title 的颜色来确认。
  182. // };
  183. #func {map.AreaColor} {
  184. #local area {%1};
  185. #local pattern {$area/%*};
  186. #if { &map.area.dict[$pattern][] != 1 } {
  187. #return {};
  188. };
  189. #foreach {*map.area.dict[$pattern]} {pattern} {
  190. #return {$map.area.dict[$pattern][COLOR]};
  191. };
  192. };