area.tin 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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$} {
  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. } {4};
  88. #line oneshot #action {~^{\e\[0m|}%c◆%*地图%*◆%C{|\(非任务区域\)}%C$} {
  89. #local color {%%2};
  90. #replace color {\e[} {};
  91. #replace color {m$} {};
  92. #replace color {m} {;};
  93. #local area {%%3%%4};
  94. #var gMapRoom[area][LMAP] {$area};
  95. #var gMapRoom[area][COLOR] {$color};
  96. #if { "%%6" == "" } {
  97. #var gMapRoom[area][JOB] {true};
  98. };
  99. #else {
  100. #var gMapRoom[area][JOB] {false};
  101. };
  102. #if { "$area" == "柳秀山庄" } {
  103. #class map.Localmaps.gag kill;
  104. };
  105. } {2};
  106. #line oneshot #action {^%s%S略图%s$} {
  107. #var gMapRoom[terrain] {@default{$gMapRoom[terrain];随机地图}};
  108. #var gMapRoom[village] {%%2};
  109. };
  110. #line oneshot #action {┌─{(─)*}─%*附近详图─{(─)*}─┐$} {
  111. #var gMapRoom[terrain] {随机地图};
  112. };
  113. #if { "$gag" == "gag" } {
  114. #class map.Localmaps.gag open;
  115. #action {^%*{|ID=map/localmaps}$} {#line gag} {6};
  116. #gag {^%*{|ID=map/localmaps}$};
  117. #class map.Localmaps.gag close;
  118. };
  119. #class map.Localmaps close;
  120. xtt.Send {localmaps};
  121. sync.Wait {
  122. #class map.Localmaps kill;
  123. #class map.Localmaps.gag kill;
  124. event.DelayEmit map/GotLocalmaps;
  125. };
  126. };
  127. #alias {lm} {map.Localmaps nogag {%0}};
  128. #alias {localmaps} {map.Localmaps nogag {%0}};
  129. #alias {localmaps_gag} {map.Localmaps gag {%0}};
  130. #nop 根据数据源确定区域信息。数据源有四种(按使用优先级):link、walk、node、localmaps;
  131. #func {map.resolveArea} {
  132. #local source {%0};
  133. #if { "$source[RESOLVED]" != "" } {
  134. #return {$source[RESOLVED]};
  135. };
  136. #if { "$source[LINK]$source[WALK]$source[NODE]$source[LMAP]" == "" } {
  137. #return {};
  138. };
  139. #local lmap {@default{$source[LMAP];%*}};
  140. #local pattern {%*/$lmap};
  141. #nop 如果有 LMAP 的话,先根据 LMAP 检索,这个基本上可以做到一一对应。;
  142. #if { "$source[LMAP]" != "" } {
  143. #local keys {@table.Keys{map.area.dict;{$pattern}}};
  144. #if { @sset.Size{$keys} == 1 } {
  145. #return {$map.area.dict[$keys][PP]};
  146. };
  147. };
  148. #nop 否则查找与 LINK/WALK/NODE 相匹配的信息。;
  149. #nop TODO: 理论上这部分也可以做优化,但是 KEY 长了之后太丑了没必要。;
  150. #local area {};
  151. #foreach {*map.area.dict[$pattern]} {area} {
  152. #local area {$map.area.dict[$area]};
  153. #if { "$source[LINK]" == "%+/%+" } {
  154. #local link {@str.Replace{{$source[LINK]};%+/%+;{{node}{&1}{links}{&2}}}};
  155. #if { "$area[LINKS][$link[node]]" === "$link[links]" } {
  156. #return {$area[PP]};
  157. };
  158. };
  159. #elseif { "$source[WALK]$source[NODE]" != "" } {
  160. #if { "$source[WALK]$source[NODE]" !== "$area[WALK]$area[NODE]" } {
  161. #continue;
  162. };
  163. #if { "$source[WALK]/$source[NODE]" !== "NOTHING/NOTHING" } {
  164. #return {$area[PP]};
  165. };
  166. };
  167. };
  168. #return {};
  169. };
  170. ///=== {
  171. /// #@ map.AreaColor <区域名称>
  172. // 获取该区域的颜色。
  173. // 区域颜色是一个区域的固有属性,可以通过该区域的平民 title 的颜色来确认。
  174. // };
  175. #func {map.AreaColor} {
  176. #local area {%1};
  177. #local pattern {$area/%*};
  178. #if { &map.area.dict[$pattern][] != 1 } {
  179. #return {};
  180. };
  181. #foreach {*map.area.dict[$pattern]} {pattern} {
  182. #return {$map.area.dict[$pattern][COLOR]};
  183. };
  184. };