skills.tin 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #nop vim: set filetype=tt:;
  2. /*
  3. 本文件属于 PaoTin++ 的一部分
  4. ===========
  5. PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
  6. 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
  7. ===========
  8. */
  9. #var basic_char_skills[META] {
  10. {NAME} {技能列表}
  11. {DESC} {解析 skills 命令的输出结果,并写入到 char[Skills]}
  12. {AUTHOR} {担子炮}
  13. {NOTE} {技能小点和激发关系分别由 skbrief 和 jifa 命令提供,都合并在一起}
  14. {CONFIG} {
  15. }
  16. };
  17. #nop ╭───技能列表(共十六项)─┬─────────────┬──────┬──────┬──────╮
  18. #nop │名称 │ID │描述 │级别 │最大级别 │
  19. #nop ├───一项职业技能────┼─────────────┼──────┼──────┼──────┤
  20. #nop │ 占卜之术 │divination │不足挂齿 │82.0 │387 │
  21. #nop ├───六项基本知识────┼─────────────┼──────┼──────┼──────┤
  22. #nop │ 禅宗心法 │buddhism │半生不熟 │153.0 │- │
  23. #nop │ 鉴定之术 │identification │初窥门径 │54.0 │- │
  24. #nop │ 读书写字 │literate │半生不熟 │152.0 │- │
  25. #nop │ 医术 │medical-skill │新学乍用 │30.0 │- │
  26. #nop │ 妙手空空 │stealing │新学乍用 │10.0 │- │
  27. #nop │ 道家养生术 │taoism │深不可测 │948.23 │- │
  28. #nop ├───六项基本功夫────┼─────────────┼──────┼──────┼──────┤
  29. #nop │ 基本拳法 │cuff │半生不熟 │386.0 │387 │
  30. #nop │ 基本轻功 │dodge │半生不熟 │386.0 │387 │
  31. #nop │ 基本内功 │force │半生不熟 │386.0 │387 │
  32. #nop │ 基本招架 │parry │半生不熟 │386.0 │387 │
  33. #nop │ 基本剑法 │sword │半生不熟 │386.0 │387 │
  34. #nop ├───四项特殊功夫────┼─────────────┼──────┼──────┼──────┤
  35. #nop │□太极剑法 │taiji-jian │半生不熟 │386.0 │387 │
  36. #nop │□太极拳 │taiji-quan │半生不熟 │386.0 │387 │
  37. #nop │□太极神功 │taiji-shengong │第五重楼 │387.0 │387 │
  38. #nop │□梯云纵 │tiyunzong │半生不熟 │386.0 │387 │
  39. #nop ╰─────────────┴─────────────┴──────┴────北大侠客行────╯
  40. #nop;
  41. load-lib event;
  42. event.Define {char/skills} {无参} {$MODULE} {已经获取到 skills 命令输出结果,并更新 char[Skills]。};
  43. event.Define {char/skbrief} {无参} {$MODULE} {已经获取到 skbrief 命令输出结果,并更新 char[Skills]。};
  44. #func {basic_char_skills.Init} {
  45. #class data/basic/char open;
  46. #var char[Skills] {};
  47. #var char-skill-limit {1};
  48. #class data/basic/char close;
  49. #delay char.skills.init {skills;jifa} 1;
  50. #return true;
  51. };
  52. #alias {skills} {char.Skills};
  53. #alias {sk} {char.Skills};
  54. #alias {cha} {char.Skills};
  55. #alias {skbrief} {char.Skbrief {%1} nogag};
  56. #alias {char.Skills} {
  57. #local args {%0};
  58. #if { "$args" == "" } {
  59. #line oneshot #action {^╭───技能列表(共%*项){(─|┬)*}──╮$} {
  60. #var char[Skills][count] {@math.ParseCN{%%1}};
  61. char.skills.parse.output;
  62. };
  63. };
  64. xtt.Send skills %0;
  65. };
  66. #alias {char.skills.parse.output} {
  67. #class {ParseSkills} open;
  68. #var char[Skills][currentType] {};
  69. #var char[Skills][nameList] {};
  70. #gag {^│名称};
  71. #action {^├───%%1项%%2──} {
  72. #var char[Skills][currentType] {%%2};
  73. };
  74. #local RST {\e[0m};
  75. #local RST__ {\e[2;37;0m};
  76. #local __I__ {$RST__│};
  77. #action {~^$RST│%*│%*│%*│%*│%*│{|ID=char.skills}} {
  78. #local line {%%0};
  79. #local code {%%2};
  80. #local level {%%4};
  81. #local limit {%%5};
  82. #replace {code} {\x1b[2;37;0m} {};
  83. #replace {level} {\x1b[2;37;0m} {};
  84. #replace {limit} {\x1b[2;37;0m} {};
  85. #replace level {+} {};
  86. #if { "$limit" == "%s%d%s" } {
  87. #math limit {$limit + 0};
  88. };
  89. #elseif { "$limit" == "%s-%s" } {
  90. #nop 知识类技能没有上限;
  91. #local limit {0};
  92. };
  93. #else {
  94. #return;
  95. };
  96. #nop 给技能加上彩色进度条,用来表示当前级别距离上限的程度;
  97. #local newCode {@__char_skills_colorit__{{$code};$level;$limit}};
  98. #replace code { } {};
  99. #replace line {$code\x1b[2;37;0m%s} {$newCode\e[0m};
  100. #replace line {\x1b[34m} {\x1b[94m};
  101. #echo {%s} {@Beautify{{$line}}};
  102. #local line {Skill/%%1/%%2/%%3/%%4/$limit};
  103. #replace line { } {};
  104. #showme {$line};
  105. #line gag;
  106. };
  107. #action {^Skill/{□|Θ|}%%2/%%3/%%4/%%5/%%6$} {
  108. #local type ${char[Skills][currentType]};
  109. #local enabled {%%1};
  110. #local name {%%2};
  111. #local code {%%3};
  112. #local rank {%%4};
  113. #local level {%%5};
  114. #local limit {%%6};
  115. #replace name { } {};
  116. #if { "$enabled" == "□" } {
  117. #format enabled {true};
  118. };
  119. #else {
  120. #format enabled {false};
  121. };
  122. #list char[Skills][nameList] add {$name};
  123. #var {char[Skills][$name]} {
  124. $char[Skills][$name]
  125. {name}{$name}
  126. {type}{$type}
  127. {enabled}{$enabled}
  128. {code}{$code}
  129. {rank}{$rank}
  130. {level}{$level}
  131. {limit}{$limit}
  132. };
  133. #if { $char-skill-limit < $limit } {
  134. #var char-skill-limit $limit;
  135. };
  136. #line gag;
  137. };
  138. #action {^╰───{(┴|─)*}─%S────╯{|ID=char.skills}$} {
  139. char.skills.parse.done;
  140. };
  141. #action {^你不是查看过吗?{|ID=char/skills}$} {
  142. char.skills.parse.done;
  143. };
  144. #alias {char.skills.parse.done} {
  145. #local __unused {%%0};
  146. event.UnHandle GA {char.skills};
  147. #local nameList {$char[Skills][nameList]};
  148. #local count {$char[Skills][count]};
  149. #unvar char[Skills][currentType];
  150. #unvar char[Skills][nameList];
  151. #unvar char[Skills][count];
  152. #class {ParseSkills} kill;
  153. #if { &nameList[] != $count } {
  154. #line sub var #delay 0 {
  155. errLog skills 命令结果解析不完整,识别到了 &nameList[] 条记录。数据可能有误,请联系开发者。;
  156. };
  157. #return;
  158. };
  159. #list nameList collapse {|};
  160. #local skillName {};
  161. #foreach {*char[Skills][]} {skillName} {
  162. #if { "$skillName" != "{$nameList}" } {
  163. #unvar {char[Skills][$skillName]};
  164. };
  165. };
  166. event.Emit {char/skills};
  167. };
  168. event.HandleOnce GA {char.skills} {char} {char.skills.parse.done};
  169. #class {ParseSkills} close;
  170. };
  171. #func {__char_skills_colorit__} {
  172. #local code {%1};
  173. #local level {%2};
  174. #local limit {%3};
  175. #local p {@math.Int{@math.Eval{$level * 100 / $limit}}};
  176. #local color {@util.Grade{$p;<271>;15;<171>;30;<203>;60;<274>;90;<134>;100;<132>;101;<506>}};
  177. #local spaceLen {@str.Len{$code}};
  178. #local code {@str.Trim{$code}};
  179. #local textLen {@str.Len{$code}};
  180. #math spaceLen {$spaceLen - $textLen};
  181. #cat code {@str.AlignRight{{$p%}; $spaceLen}};
  182. #local {rest} {@math.Eval{100 - $p}};
  183. #return {@util.ColorBar{{$code};$color;$p;<g08>;$rest}};
  184. };
  185. #alias {char.Skbrief} {
  186. #local id {%1};
  187. #if { "$id" == "" } {
  188. errLog 用法: skbrief <技能ID>;
  189. #return;
  190. };
  191. #alias {char.Skbrief.parse} {
  192. #line oneshot #action {^系统回馈:R:skbrief-begin-%%1$} {
  193. #class char-skbrief-parse-output-%%1 open;
  194. #line oneshot #action {^#%d/%d{|ID=char/skbrief-%%1}$} {
  195. #local skill {};
  196. #foreach {*char[Skills][]} {skill} {
  197. #if { "$char[Skills][$skill][code]" == "%%2" } {
  198. #var char[Skills][$skill][lvl] {%%%%1};
  199. #var char[Skills][$skill][point] {%%%%2};
  200. #local level {};
  201. #math level {
  202. $char[Skills][$skill][lvl]*1.00
  203. + $char[Skills][$skill][point]*1.00 / ($char[Skills][$skill][lvl] ** 2)};
  204. #var char[Skills][$skill][level] {$level};
  205. event.Emit {char/skbrief};
  206. #break;
  207. };
  208. };
  209. #local gag {@default{%2;gag}};
  210. #if { "$gag" == "gag" } {
  211. #line gag;
  212. };
  213. };
  214. #line oneshot #action {^系统回馈:R:skbrief-end-%%1$} {
  215. #line gag;
  216. #class char-skbrief-parse-output-%%1 kill;
  217. };
  218. #class char-skbrief-parse-output-%%1 close;
  219. #line gag;
  220. };
  221. };
  222. #local uuid {@uuid{}};
  223. char.Skbrief.parse $uuid $id;
  224. xtt.Send {#response R:skbrief-begin-$uuid;skbrief $id;response R:skbrief-end-$uuid#};
  225. };
  226. ///=== {
  227. // #@ char.SkillLimit [<技能名称>]
  228. // 如果指定了技能名称,则返回该技能所能达到的技能上限。
  229. // 如果没有指定或者技能不存在,则返回本人的武功技能上限。
  230. // 如果技能上限获取失败,默认值为基本内功的上限,如果基本内功上限也没有获取到,则默认为 1。
  231. // };
  232. #func {char.SkillLimit} {
  233. #local skill {%1};
  234. #local limit {@defaultNum{$char-skill-limit;@defaultNum{$char[Skills][基本内功][limit];1}}};
  235. #local limit {@defaultNum{$char[Skills][$skill][limit];$limit}};
  236. #return $limit;
  237. };
  238. ///=== {
  239. // #@ char.SkillType <技能名称>
  240. // 返回该技能的技能类别。
  241. // 常见的技能类别有:
  242. // - 基本功夫
  243. // - 特殊功夫
  244. // - 基本知识
  245. // - 职业技能
  246. // };
  247. #func {char.SkillType} {
  248. #local skill {%1};
  249. #return {$char[Skills][$skill][type]};
  250. };
  251. ///=== {
  252. // #@ char.SkillLevel <技能中文名称>
  253. // 返回该技能的当前等级。没学会的技能等级为 0。
  254. // };
  255. #func {char.SkillLevel} {
  256. #local skill {%1};
  257. #if { "$char[Skills][$skill]" == "" } {
  258. #return 0;
  259. };
  260. #return $char[Skills][$skill][level];
  261. };
  262. ///=== {
  263. // #@ char.IsSkillEnabled <技能中文名称>
  264. // 判断该技能是否被激发。这里的技能名称既可以是基本功夫,也可以是特殊功夫。
  265. // };
  266. #func {char.IsSkillEnabled} {
  267. #local skill {%1};
  268. #if { "$char[Skills][$skill]" == "" } {
  269. #return 0;
  270. };
  271. #if { "$char[Skills][$skill][jifa-to]" == "" } {
  272. #return 0;
  273. };
  274. #return 1;
  275. };
  276. ///=== {
  277. // #@ char.GetJifaSkill 提供技能激发情况查询
  278. // 共分为三种情况:
  279. // 1,输入参数为基本技能,输出对应的特殊技能名称。如果未激发则为空
  280. // 2,输入参数为特殊技能,输出对应的基本技能名称。结果可能为多个。如果未激发则为空
  281. // 3,输入参数为激发类型,则输出对应的基本技能名称。又分为以下两种情形:
  282. // (1),输入参数为常用拳脚或者常用兵器,则输出相应的基本技能名称。
  283. // 由于存在互备的情形,因此结果是一个字符串列表,可能包含多个技能名称
  284. // (2),其它内功、躲闪、招架及武功种类,则输出对应的特殊技能名称
  285. // };
  286. #func {char.GetJifaSkill} {
  287. #local arg {%1};
  288. #local skills {};
  289. #if { "$arg" == "常用{拳脚|兵器}" } {
  290. #local skill {};
  291. #foreach {*char[Skills][]} {skill} {
  292. #local elem {$char[Skills][$skill]};
  293. #if { "$elem[type]" != "基本功夫" } {
  294. #continue;
  295. };
  296. #if { "$elem[jifa-type]" == "$arg" } {
  297. #list skills add {$skill};
  298. };
  299. };
  300. #return {@slist.FromList{$skills}};
  301. };
  302. #if { "$arg" == "躲闪" } {
  303. #local arg {基本轻功};
  304. };
  305. #if { "$char[Skills][$arg][jifa-to]" != "" } {
  306. #return {$char[Skills][$arg][jifa-to]};
  307. };
  308. #local arg {基本$arg};
  309. #if {"$char[Skills][$arg][jifa-to]" != "" } {
  310. #return {$char[Skills][$arg][jifa-to]};
  311. };
  312. #else {
  313. #return;
  314. };
  315. };
  316. ///=== {
  317. // #@ char.SkillJifaLevel <技能中文名称>
  318. // 返回技能激发等级,数据来自 jifa/enable 命令。
  319. // 如果技能未被激发,那么分两种情况:
  320. // 1. 如果输入的技能名称为基本功夫,则取 jifa 数据。
  321. 如果 jifa 数据取不到,则取技能当前等级的一半。
  322. // 2. 如果输入的技能名称为特殊功夫,则取技能的当前等级。
  323. // };
  324. #func {char.SkillJifaLevel} {
  325. #local skill {%1};
  326. #if { "$char[Skills][$skill]" == "" } {
  327. #return 0;
  328. };
  329. #local level {$char[Skills][$skill][level]};
  330. #if { "$skill" == "基本%*" } {
  331. #math level {$char[Skills][$skill][level] / 2};
  332. };
  333. #return {@defaultNum{$char[Skills][$skill][jifa-level];$level}};
  334. };