@rpgm-tools/neo-angband-core 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (853) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/perceive.d.ts.map +1 -1
  3. package/dist/agent/perceive.js +2 -2
  4. package/dist/agent/perceive.js.map +1 -1
  5. package/dist/combat/blow-vectors.d.ts +78 -0
  6. package/dist/combat/blow-vectors.d.ts.map +1 -0
  7. package/dist/combat/blow-vectors.fixtures.d.ts +19 -0
  8. package/dist/combat/blow-vectors.fixtures.d.ts.map +1 -0
  9. package/dist/combat/blow-vectors.fixtures.js +81 -0
  10. package/dist/combat/blow-vectors.fixtures.js.map +1 -0
  11. package/dist/combat/blow-vectors.js +195 -0
  12. package/dist/combat/blow-vectors.js.map +1 -0
  13. package/dist/combat/brand-slay.d.ts +22 -9
  14. package/dist/combat/brand-slay.d.ts.map +1 -1
  15. package/dist/combat/brand-slay.js +37 -10
  16. package/dist/combat/brand-slay.js.map +1 -1
  17. package/dist/combat/index.d.ts +1 -1
  18. package/dist/combat/index.js +1 -1
  19. package/dist/combat/melee.d.ts +25 -13
  20. package/dist/combat/melee.d.ts.map +1 -1
  21. package/dist/combat/melee.js +23 -19
  22. package/dist/combat/melee.js.map +1 -1
  23. package/dist/combat/mon-melee.d.ts +166 -7
  24. package/dist/combat/mon-melee.d.ts.map +1 -1
  25. package/dist/combat/mon-melee.js +469 -338
  26. package/dist/combat/mon-melee.js.map +1 -1
  27. package/dist/combat/ranged.d.ts +15 -13
  28. package/dist/combat/ranged.d.ts.map +1 -1
  29. package/dist/combat/ranged.js +31 -29
  30. package/dist/combat/ranged.js.map +1 -1
  31. package/dist/constants.d.ts +14 -0
  32. package/dist/constants.d.ts.map +1 -1
  33. package/dist/constants.js +14 -0
  34. package/dist/constants.js.map +1 -1
  35. package/dist/datafile.d.ts +48 -0
  36. package/dist/datafile.d.ts.map +1 -0
  37. package/dist/datafile.js +102 -0
  38. package/dist/datafile.js.map +1 -0
  39. package/dist/effects/effect-info-registry.d.ts +237 -0
  40. package/dist/effects/effect-info-registry.d.ts.map +1 -0
  41. package/dist/effects/effect-info-registry.js +138 -0
  42. package/dist/effects/effect-info-registry.js.map +1 -0
  43. package/dist/effects/effect-info-vectors.d.ts +92 -0
  44. package/dist/effects/effect-info-vectors.d.ts.map +1 -0
  45. package/dist/effects/effect-info-vectors.fixtures.d.ts +18 -0
  46. package/dist/effects/effect-info-vectors.fixtures.d.ts.map +1 -0
  47. package/dist/effects/effect-info-vectors.fixtures.js +51 -0
  48. package/dist/effects/effect-info-vectors.fixtures.js.map +1 -0
  49. package/dist/effects/effect-info-vectors.js +315 -0
  50. package/dist/effects/effect-info-vectors.js.map +1 -0
  51. package/dist/effects/effect-info.d.ts +5 -1
  52. package/dist/effects/effect-info.d.ts.map +1 -1
  53. package/dist/effects/effect-info.js +245 -143
  54. package/dist/effects/effect-info.js.map +1 -1
  55. package/dist/effects/effect.d.ts +4 -3
  56. package/dist/effects/effect.d.ts.map +1 -1
  57. package/dist/effects/effect.js +88 -70
  58. package/dist/effects/effect.js.map +1 -1
  59. package/dist/effects/handlers.d.ts +1 -1
  60. package/dist/effects/handlers.d.ts.map +1 -1
  61. package/dist/effects/handlers.js +5 -2
  62. package/dist/effects/handlers.js.map +1 -1
  63. package/dist/effects/interpreter.d.ts +11 -0
  64. package/dist/effects/interpreter.d.ts.map +1 -1
  65. package/dist/effects/interpreter.js +13 -0
  66. package/dist/effects/interpreter.js.map +1 -1
  67. package/dist/game/cave-cmd.d.ts +9 -5
  68. package/dist/game/cave-cmd.d.ts.map +1 -1
  69. package/dist/game/cave-cmd.js +56 -11
  70. package/dist/game/cave-cmd.js.map +1 -1
  71. package/dist/game/cave-square.d.ts +42 -0
  72. package/dist/game/cave-square.d.ts.map +1 -0
  73. package/dist/game/cave-square.js +73 -0
  74. package/dist/game/cave-square.js.map +1 -0
  75. package/dist/game/char-sheet.d.ts +12 -8
  76. package/dist/game/char-sheet.d.ts.map +1 -1
  77. package/dist/game/char-sheet.js +41 -8
  78. package/dist/game/char-sheet.js.map +1 -1
  79. package/dist/game/chest.d.ts +2 -3
  80. package/dist/game/chest.d.ts.map +1 -1
  81. package/dist/game/chest.js +17 -6
  82. package/dist/game/chest.js.map +1 -1
  83. package/dist/game/context.d.ts +213 -22
  84. package/dist/game/context.d.ts.map +1 -1
  85. package/dist/game/context.js +109 -17
  86. package/dist/game/context.js.map +1 -1
  87. package/dist/game/describe.d.ts +13 -0
  88. package/dist/game/describe.d.ts.map +1 -1
  89. package/dist/game/describe.js +32 -4
  90. package/dist/game/describe.js.map +1 -1
  91. package/dist/game/display.d.ts +97 -8
  92. package/dist/game/display.d.ts.map +1 -1
  93. package/dist/game/display.js +157 -13
  94. package/dist/game/display.js.map +1 -1
  95. package/dist/game/dump-level.d.ts.map +1 -1
  96. package/dist/game/dump-level.js +3 -2
  97. package/dist/game/dump-level.js.map +1 -1
  98. package/dist/game/effect-attack.d.ts.map +1 -1
  99. package/dist/game/effect-attack.js +36 -27
  100. package/dist/game/effect-attack.js.map +1 -1
  101. package/dist/game/effect-detect.d.ts +4 -4
  102. package/dist/game/effect-detect.d.ts.map +1 -1
  103. package/dist/game/effect-detect.js +42 -9
  104. package/dist/game/effect-detect.js.map +1 -1
  105. package/dist/game/effect-env.d.ts +7 -1
  106. package/dist/game/effect-env.d.ts.map +1 -1
  107. package/dist/game/effect-env.js +1 -0
  108. package/dist/game/effect-env.js.map +1 -1
  109. package/dist/game/effect-general.d.ts +5 -3
  110. package/dist/game/effect-general.d.ts.map +1 -1
  111. package/dist/game/effect-general.js +94 -43
  112. package/dist/game/effect-general.js.map +1 -1
  113. package/dist/game/effect-item.d.ts +2 -1
  114. package/dist/game/effect-item.d.ts.map +1 -1
  115. package/dist/game/effect-item.js +136 -82
  116. package/dist/game/effect-item.js.map +1 -1
  117. package/dist/game/effect-melee.d.ts +10 -4
  118. package/dist/game/effect-melee.d.ts.map +1 -1
  119. package/dist/game/effect-melee.js +44 -19
  120. package/dist/game/effect-melee.js.map +1 -1
  121. package/dist/game/effect-monster.d.ts +26 -4
  122. package/dist/game/effect-monster.d.ts.map +1 -1
  123. package/dist/game/effect-monster.js +52 -9
  124. package/dist/game/effect-monster.js.map +1 -1
  125. package/dist/game/effect-teleport.d.ts +58 -19
  126. package/dist/game/effect-teleport.d.ts.map +1 -1
  127. package/dist/game/effect-teleport.js +143 -27
  128. package/dist/game/effect-teleport.js.map +1 -1
  129. package/dist/game/effect-terrain.d.ts +1 -3
  130. package/dist/game/effect-terrain.d.ts.map +1 -1
  131. package/dist/game/effect-terrain.js +38 -22
  132. package/dist/game/effect-terrain.js.map +1 -1
  133. package/dist/game/equip-cmp.d.ts.map +1 -1
  134. package/dist/game/equip-cmp.js +10 -7
  135. package/dist/game/equip-cmp.js.map +1 -1
  136. package/dist/game/floor.d.ts +16 -4
  137. package/dist/game/floor.d.ts.map +1 -1
  138. package/dist/game/floor.js +22 -4
  139. package/dist/game/floor.js.map +1 -1
  140. package/dist/game/gear.d.ts +101 -13
  141. package/dist/game/gear.d.ts.map +1 -1
  142. package/dist/game/gear.js +183 -24
  143. package/dist/game/gear.js.map +1 -1
  144. package/dist/game/harness.d.ts +2 -1
  145. package/dist/game/harness.d.ts.map +1 -1
  146. package/dist/game/harness.js +12 -1
  147. package/dist/game/harness.js.map +1 -1
  148. package/dist/game/ignore-cmd.d.ts +47 -8
  149. package/dist/game/ignore-cmd.d.ts.map +1 -1
  150. package/dist/game/ignore-cmd.js +76 -8
  151. package/dist/game/ignore-cmd.js.map +1 -1
  152. package/dist/game/known.d.ts +223 -34
  153. package/dist/game/known.d.ts.map +1 -1
  154. package/dist/game/known.js +301 -67
  155. package/dist/game/known.js.map +1 -1
  156. package/dist/game/loop.d.ts +4 -3
  157. package/dist/game/loop.d.ts.map +1 -1
  158. package/dist/game/loop.js +49 -29
  159. package/dist/game/loop.js.map +1 -1
  160. package/dist/game/lore-color.d.ts.map +1 -1
  161. package/dist/game/lore-color.js +13 -1
  162. package/dist/game/lore-color.js.map +1 -1
  163. package/dist/game/mon-cast.d.ts +3 -4
  164. package/dist/game/mon-cast.d.ts.map +1 -1
  165. package/dist/game/mon-cast.js +30 -2
  166. package/dist/game/mon-cast.js.map +1 -1
  167. package/dist/game/mon-cmd.d.ts +4 -5
  168. package/dist/game/mon-cmd.d.ts.map +1 -1
  169. package/dist/game/mon-cmd.js +80 -27
  170. package/dist/game/mon-cmd.js.map +1 -1
  171. package/dist/game/mon-death.d.ts +8 -4
  172. package/dist/game/mon-death.d.ts.map +1 -1
  173. package/dist/game/mon-death.js +6 -9
  174. package/dist/game/mon-death.js.map +1 -1
  175. package/dist/game/mon-group.d.ts +9 -5
  176. package/dist/game/mon-group.d.ts.map +1 -1
  177. package/dist/game/mon-group.js +9 -5
  178. package/dist/game/mon-group.js.map +1 -1
  179. package/dist/game/mon-message.d.ts +90 -40
  180. package/dist/game/mon-message.d.ts.map +1 -1
  181. package/dist/game/mon-message.js +267 -59
  182. package/dist/game/mon-message.js.map +1 -1
  183. package/dist/game/mon-place.d.ts +11 -1
  184. package/dist/game/mon-place.d.ts.map +1 -1
  185. package/dist/game/mon-place.js +15 -3
  186. package/dist/game/mon-place.js.map +1 -1
  187. package/dist/game/mon-ranged.d.ts +2 -1
  188. package/dist/game/mon-ranged.d.ts.map +1 -1
  189. package/dist/game/mon-ranged.js +11 -5
  190. package/dist/game/mon-ranged.js.map +1 -1
  191. package/dist/game/mon-side.d.ts +3 -2
  192. package/dist/game/mon-side.d.ts.map +1 -1
  193. package/dist/game/mon-side.js +15 -14
  194. package/dist/game/mon-side.js.map +1 -1
  195. package/dist/game/monster-turn.d.ts +20 -10
  196. package/dist/game/monster-turn.d.ts.map +1 -1
  197. package/dist/game/monster-turn.js +110 -83
  198. package/dist/game/monster-turn.js.map +1 -1
  199. package/dist/game/notice.d.ts +36 -0
  200. package/dist/game/notice.d.ts.map +1 -0
  201. package/dist/game/notice.js +79 -0
  202. package/dist/game/notice.js.map +1 -0
  203. package/dist/game/obj-cmd.d.ts +14 -3
  204. package/dist/game/obj-cmd.d.ts.map +1 -1
  205. package/dist/game/obj-cmd.js +109 -35
  206. package/dist/game/obj-cmd.js.map +1 -1
  207. package/dist/game/obj-list.d.ts +13 -2
  208. package/dist/game/obj-list.d.ts.map +1 -1
  209. package/dist/game/obj-list.js +42 -27
  210. package/dist/game/obj-list.js.map +1 -1
  211. package/dist/game/object-inspect.d.ts +9 -0
  212. package/dist/game/object-inspect.d.ts.map +1 -1
  213. package/dist/game/object-inspect.js +4 -0
  214. package/dist/game/object-inspect.js.map +1 -1
  215. package/dist/game/pickup.d.ts +0 -2
  216. package/dist/game/pickup.d.ts.map +1 -1
  217. package/dist/game/pickup.js +18 -3
  218. package/dist/game/pickup.js.map +1 -1
  219. package/dist/game/player-side-vectors.d.ts +174 -0
  220. package/dist/game/player-side-vectors.d.ts.map +1 -0
  221. package/dist/game/player-side-vectors.fixtures.d.ts +33 -0
  222. package/dist/game/player-side-vectors.fixtures.d.ts.map +1 -0
  223. package/dist/game/player-side-vectors.fixtures.js +191 -0
  224. package/dist/game/player-side-vectors.fixtures.js.map +1 -0
  225. package/dist/game/player-side-vectors.js +292 -0
  226. package/dist/game/player-side-vectors.js.map +1 -0
  227. package/dist/game/player-side.d.ts +129 -1
  228. package/dist/game/player-side.d.ts.map +1 -1
  229. package/dist/game/player-side.js +520 -338
  230. package/dist/game/player-side.js.map +1 -1
  231. package/dist/game/player-turn.d.ts +26 -7
  232. package/dist/game/player-turn.d.ts.map +1 -1
  233. package/dist/game/player-turn.js +180 -33
  234. package/dist/game/player-turn.js.map +1 -1
  235. package/dist/game/poly.d.ts +38 -0
  236. package/dist/game/poly.d.ts.map +1 -0
  237. package/dist/game/poly.js +82 -0
  238. package/dist/game/poly.js.map +1 -0
  239. package/dist/game/project-cast.d.ts +20 -3
  240. package/dist/game/project-cast.d.ts.map +1 -1
  241. package/dist/game/project-cast.js +49 -6
  242. package/dist/game/project-cast.js.map +1 -1
  243. package/dist/game/project-feat-vectors.d.ts +124 -0
  244. package/dist/game/project-feat-vectors.d.ts.map +1 -0
  245. package/dist/game/project-feat-vectors.fixtures.d.ts +13 -0
  246. package/dist/game/project-feat-vectors.fixtures.d.ts.map +1 -0
  247. package/dist/game/project-feat-vectors.fixtures.js +94 -0
  248. package/dist/game/project-feat-vectors.fixtures.js.map +1 -0
  249. package/dist/game/project-feat-vectors.js +229 -0
  250. package/dist/game/project-feat-vectors.js.map +1 -0
  251. package/dist/game/project-feat.d.ts +53 -1
  252. package/dist/game/project-feat.d.ts.map +1 -1
  253. package/dist/game/project-feat.js +374 -247
  254. package/dist/game/project-feat.js.map +1 -1
  255. package/dist/game/project-monster.d.ts +21 -8
  256. package/dist/game/project-monster.d.ts.map +1 -1
  257. package/dist/game/project-monster.js +45 -21
  258. package/dist/game/project-monster.js.map +1 -1
  259. package/dist/game/project-obj.d.ts +62 -0
  260. package/dist/game/project-obj.d.ts.map +1 -1
  261. package/dist/game/project-obj.js +72 -41
  262. package/dist/game/project-obj.js.map +1 -1
  263. package/dist/game/project-player.d.ts +8 -0
  264. package/dist/game/project-player.d.ts.map +1 -1
  265. package/dist/game/project-player.js.map +1 -1
  266. package/dist/game/projection-handlers.d.ts +81 -0
  267. package/dist/game/projection-handlers.d.ts.map +1 -0
  268. package/dist/game/projection-handlers.js +93 -0
  269. package/dist/game/projection-handlers.js.map +1 -0
  270. package/dist/game/quest.d.ts +23 -0
  271. package/dist/game/quest.d.ts.map +1 -1
  272. package/dist/game/quest.js +42 -0
  273. package/dist/game/quest.js.map +1 -1
  274. package/dist/game/ranged-cmd.d.ts +13 -2
  275. package/dist/game/ranged-cmd.d.ts.map +1 -1
  276. package/dist/game/ranged-cmd.js +32 -15
  277. package/dist/game/ranged-cmd.js.map +1 -1
  278. package/dist/game/repeat.d.ts +78 -0
  279. package/dist/game/repeat.d.ts.map +1 -0
  280. package/dist/game/repeat.js +88 -0
  281. package/dist/game/repeat.js.map +1 -0
  282. package/dist/game/shape-inspect.d.ts +74 -0
  283. package/dist/game/shape-inspect.d.ts.map +1 -0
  284. package/dist/game/shape-inspect.js +114 -0
  285. package/dist/game/shape-inspect.js.map +1 -0
  286. package/dist/game/spell-cmd.d.ts +15 -4
  287. package/dist/game/spell-cmd.d.ts.map +1 -1
  288. package/dist/game/spell-cmd.js +35 -6
  289. package/dist/game/spell-cmd.js.map +1 -1
  290. package/dist/game/spoil.d.ts.map +1 -1
  291. package/dist/game/spoil.js +89 -40
  292. package/dist/game/spoil.js.map +1 -1
  293. package/dist/game/steal.d.ts +3 -3
  294. package/dist/game/steal.d.ts.map +1 -1
  295. package/dist/game/steal.js +9 -4
  296. package/dist/game/steal.js.map +1 -1
  297. package/dist/game/target-loop.d.ts +10 -4
  298. package/dist/game/target-loop.d.ts.map +1 -1
  299. package/dist/game/target-loop.js +14 -8
  300. package/dist/game/target-loop.js.map +1 -1
  301. package/dist/game/target.d.ts +4 -4
  302. package/dist/game/target.d.ts.map +1 -1
  303. package/dist/game/target.js +19 -8
  304. package/dist/game/target.js.map +1 -1
  305. package/dist/game/ui-entry.d.ts +63 -4
  306. package/dist/game/ui-entry.d.ts.map +1 -1
  307. package/dist/game/ui-entry.js +151 -23
  308. package/dist/game/ui-entry.js.map +1 -1
  309. package/dist/game/wizard.d.ts +23 -5
  310. package/dist/game/wizard.d.ts.map +1 -1
  311. package/dist/game/wizard.js +93 -11
  312. package/dist/game/wizard.js.map +1 -1
  313. package/dist/game/world.d.ts.map +1 -1
  314. package/dist/game/world.js +6 -0
  315. package/dist/game/world.js.map +1 -1
  316. package/dist/gen/cave.d.ts +49 -8
  317. package/dist/gen/cave.d.ts.map +1 -1
  318. package/dist/gen/cave.js +200 -28
  319. package/dist/gen/cave.js.map +1 -1
  320. package/dist/gen/generate.d.ts +54 -9
  321. package/dist/gen/generate.d.ts.map +1 -1
  322. package/dist/gen/generate.js +55 -8
  323. package/dist/gen/generate.js.map +1 -1
  324. package/dist/gen/glyph-vectors.d.ts +109 -0
  325. package/dist/gen/glyph-vectors.d.ts.map +1 -0
  326. package/dist/gen/glyph-vectors.fixtures.d.ts +18 -0
  327. package/dist/gen/glyph-vectors.fixtures.d.ts.map +1 -0
  328. package/dist/gen/glyph-vectors.fixtures.js +94 -0
  329. package/dist/gen/glyph-vectors.fixtures.js.map +1 -0
  330. package/dist/gen/glyph-vectors.js +218 -0
  331. package/dist/gen/glyph-vectors.js.map +1 -0
  332. package/dist/gen/glyph.d.ts +104 -0
  333. package/dist/gen/glyph.d.ts.map +1 -0
  334. package/dist/gen/glyph.js +72 -0
  335. package/dist/gen/glyph.js.map +1 -0
  336. package/dist/gen/room.d.ts +26 -2
  337. package/dist/gen/room.d.ts.map +1 -1
  338. package/dist/gen/room.js +414 -264
  339. package/dist/gen/room.js.map +1 -1
  340. package/dist/gen/util.d.ts +11 -2
  341. package/dist/gen/util.d.ts.map +1 -1
  342. package/dist/gen/util.js +31 -9
  343. package/dist/gen/util.js.map +1 -1
  344. package/dist/i18n/i18n.d.ts +207 -0
  345. package/dist/i18n/i18n.d.ts.map +1 -0
  346. package/dist/i18n/i18n.js +405 -0
  347. package/dist/i18n/i18n.js.map +1 -0
  348. package/dist/i18n/text.d.ts +62 -0
  349. package/dist/i18n/text.d.ts.map +1 -0
  350. package/dist/i18n/text.js +120 -0
  351. package/dist/i18n/text.js.map +1 -0
  352. package/dist/index.d.ts +25 -0
  353. package/dist/index.d.ts.map +1 -1
  354. package/dist/index.js +38 -0
  355. package/dist/index.js.map +1 -1
  356. package/dist/mod/extension.d.ts +115 -0
  357. package/dist/mod/extension.d.ts.map +1 -0
  358. package/dist/mod/extension.js +85 -0
  359. package/dist/mod/extension.js.map +1 -0
  360. package/dist/mod/hooks.d.ts +27 -1
  361. package/dist/mod/hooks.d.ts.map +1 -1
  362. package/dist/mod/hooks.js +23 -0
  363. package/dist/mod/hooks.js.map +1 -1
  364. package/dist/mod/ids.d.ts +10 -0
  365. package/dist/mod/ids.d.ts.map +1 -1
  366. package/dist/mod/ids.js +90 -21
  367. package/dist/mod/ids.js.map +1 -1
  368. package/dist/mod/record-keys.d.ts +43 -0
  369. package/dist/mod/record-keys.d.ts.map +1 -0
  370. package/dist/mod/record-keys.js +100 -0
  371. package/dist/mod/record-keys.js.map +1 -0
  372. package/dist/mod/registry-host.d.ts +472 -0
  373. package/dist/mod/registry-host.d.ts.map +1 -1
  374. package/dist/mod/registry-host.js +313 -0
  375. package/dist/mod/registry-host.js.map +1 -1
  376. package/dist/mod/save-blocks.d.ts +1 -1
  377. package/dist/mon/bind.d.ts.map +1 -1
  378. package/dist/mon/bind.js +6 -3
  379. package/dist/mon/bind.js.map +1 -1
  380. package/dist/mon/knowledge-groups.d.ts +0 -6
  381. package/dist/mon/knowledge-groups.d.ts.map +1 -1
  382. package/dist/mon/knowledge-groups.js +12 -8
  383. package/dist/mon/knowledge-groups.js.map +1 -1
  384. package/dist/mon/lore-describe.d.ts +46 -10
  385. package/dist/mon/lore-describe.d.ts.map +1 -1
  386. package/dist/mon/lore-describe.js +74 -22
  387. package/dist/mon/lore-describe.js.map +1 -1
  388. package/dist/mon/lore-file.d.ts +126 -0
  389. package/dist/mon/lore-file.d.ts.map +1 -0
  390. package/dist/mon/lore-file.js +291 -0
  391. package/dist/mon/lore-file.js.map +1 -0
  392. package/dist/mon/lore.d.ts +9 -3
  393. package/dist/mon/lore.d.ts.map +1 -1
  394. package/dist/mon/lore.js +9 -3
  395. package/dist/mon/lore.js.map +1 -1
  396. package/dist/mon/make.d.ts +4 -2
  397. package/dist/mon/make.d.ts.map +1 -1
  398. package/dist/mon/make.js +4 -2
  399. package/dist/mon/make.js.map +1 -1
  400. package/dist/mon/monster.d.ts +1 -1
  401. package/dist/mon/monster.js +1 -1
  402. package/dist/mon/predicate.d.ts +14 -9
  403. package/dist/mon/predicate.d.ts.map +1 -1
  404. package/dist/mon/predicate.js +14 -9
  405. package/dist/mon/predicate.js.map +1 -1
  406. package/dist/mon/project-mon.d.ts +16 -3
  407. package/dist/mon/project-mon.d.ts.map +1 -1
  408. package/dist/mon/project-mon.js +14 -5
  409. package/dist/mon/project-mon.js.map +1 -1
  410. package/dist/mon/steal.d.ts +31 -4
  411. package/dist/mon/steal.d.ts.map +1 -1
  412. package/dist/mon/steal.js +20 -7
  413. package/dist/mon/steal.js.map +1 -1
  414. package/dist/mon/take-hit.d.ts +8 -3
  415. package/dist/mon/take-hit.d.ts.map +1 -1
  416. package/dist/mon/take-hit.js +8 -3
  417. package/dist/mon/take-hit.js.map +1 -1
  418. package/dist/mon/timed.d.ts +15 -9
  419. package/dist/mon/timed.d.ts.map +1 -1
  420. package/dist/mon/timed.js +13 -8
  421. package/dist/mon/timed.js.map +1 -1
  422. package/dist/mon/types.d.ts +11 -4
  423. package/dist/mon/types.d.ts.map +1 -1
  424. package/dist/mon/types.js.map +1 -1
  425. package/dist/msg.d.ts +40 -1
  426. package/dist/msg.d.ts.map +1 -1
  427. package/dist/msg.js +42 -1
  428. package/dist/msg.js.map +1 -1
  429. package/dist/obj/artifact-fake.d.ts +46 -14
  430. package/dist/obj/artifact-fake.d.ts.map +1 -1
  431. package/dist/obj/artifact-fake.js +46 -17
  432. package/dist/obj/artifact-fake.js.map +1 -1
  433. package/dist/obj/bind.d.ts +23 -0
  434. package/dist/obj/bind.d.ts.map +1 -1
  435. package/dist/obj/bind.js +49 -9
  436. package/dist/obj/bind.js.map +1 -1
  437. package/dist/obj/desc-vectors.d.ts +68 -0
  438. package/dist/obj/desc-vectors.d.ts.map +1 -0
  439. package/dist/obj/desc-vectors.fixtures.d.ts +12 -0
  440. package/dist/obj/desc-vectors.fixtures.d.ts.map +1 -0
  441. package/dist/obj/desc-vectors.fixtures.js +95 -0
  442. package/dist/obj/desc-vectors.fixtures.js.map +1 -0
  443. package/dist/obj/desc-vectors.js +86 -0
  444. package/dist/obj/desc-vectors.js.map +1 -0
  445. package/dist/obj/desc.d.ts +17 -2
  446. package/dist/obj/desc.d.ts.map +1 -1
  447. package/dist/obj/desc.js +129 -54
  448. package/dist/obj/desc.js.map +1 -1
  449. package/dist/obj/effects-info.d.ts.map +1 -1
  450. package/dist/obj/effects-info.js +87 -58
  451. package/dist/obj/effects-info.js.map +1 -1
  452. package/dist/obj/fake-object.d.ts +70 -0
  453. package/dist/obj/fake-object.d.ts.map +1 -0
  454. package/dist/obj/fake-object.js +104 -0
  455. package/dist/obj/fake-object.js.map +1 -0
  456. package/dist/obj/ignore.d.ts +55 -12
  457. package/dist/obj/ignore.d.ts.map +1 -1
  458. package/dist/obj/ignore.js +68 -31
  459. package/dist/obj/ignore.js.map +1 -1
  460. package/dist/obj/knowledge.d.ts +46 -3
  461. package/dist/obj/knowledge.d.ts.map +1 -1
  462. package/dist/obj/knowledge.js +169 -151
  463. package/dist/obj/knowledge.js.map +1 -1
  464. package/dist/obj/known-object.d.ts +68 -8
  465. package/dist/obj/known-object.d.ts.map +1 -1
  466. package/dist/obj/known-object.js +90 -10
  467. package/dist/obj/known-object.js.map +1 -1
  468. package/dist/obj/make.d.ts +15 -4
  469. package/dist/obj/make.d.ts.map +1 -1
  470. package/dist/obj/make.js +49 -27
  471. package/dist/obj/make.js.map +1 -1
  472. package/dist/obj/object-info.d.ts +10 -0
  473. package/dist/obj/object-info.d.ts.map +1 -1
  474. package/dist/obj/object-info.js +93 -7
  475. package/dist/obj/object-info.js.map +1 -1
  476. package/dist/obj/object.d.ts +42 -4
  477. package/dist/obj/object.d.ts.map +1 -1
  478. package/dist/obj/object.js +362 -147
  479. package/dist/obj/object.js.map +1 -1
  480. package/dist/obj/power.d.ts +23 -4
  481. package/dist/obj/power.d.ts.map +1 -1
  482. package/dist/obj/power.js +231 -65
  483. package/dist/obj/power.js.map +1 -1
  484. package/dist/obj/randart-build.d.ts +27 -22
  485. package/dist/obj/randart-build.d.ts.map +1 -1
  486. package/dist/obj/randart-build.js +435 -357
  487. package/dist/obj/randart-build.js.map +1 -1
  488. package/dist/obj/randart-data.d.ts +62 -24
  489. package/dist/obj/randart-data.d.ts.map +1 -1
  490. package/dist/obj/randart-data.js +333 -189
  491. package/dist/obj/randart-data.js.map +1 -1
  492. package/dist/obj/randart-file.d.ts +21 -0
  493. package/dist/obj/randart-file.d.ts.map +1 -0
  494. package/dist/obj/randart-file.js +119 -0
  495. package/dist/obj/randart-file.js.map +1 -0
  496. package/dist/obj/randart-log.d.ts +63 -0
  497. package/dist/obj/randart-log.d.ts.map +1 -0
  498. package/dist/obj/randart-log.js +72 -0
  499. package/dist/obj/randart-log.js.map +1 -0
  500. package/dist/obj/randart-registry.d.ts +178 -0
  501. package/dist/obj/randart-registry.d.ts.map +1 -0
  502. package/dist/obj/randart-registry.js +140 -0
  503. package/dist/obj/randart-registry.js.map +1 -0
  504. package/dist/obj/randart-vectors.d.ts +97 -0
  505. package/dist/obj/randart-vectors.d.ts.map +1 -0
  506. package/dist/obj/randart-vectors.fixtures.d.ts +18 -0
  507. package/dist/obj/randart-vectors.fixtures.d.ts.map +1 -0
  508. package/dist/obj/randart-vectors.fixtures.js +50 -0
  509. package/dist/obj/randart-vectors.fixtures.js.map +1 -0
  510. package/dist/obj/randart-vectors.js +311 -0
  511. package/dist/obj/randart-vectors.js.map +1 -0
  512. package/dist/obj/randart.d.ts +53 -15
  513. package/dist/obj/randart.d.ts.map +1 -1
  514. package/dist/obj/randart.js +166 -44
  515. package/dist/obj/randart.js.map +1 -1
  516. package/dist/obj/rune-registry.d.ts +180 -0
  517. package/dist/obj/rune-registry.d.ts.map +1 -0
  518. package/dist/obj/rune-registry.js +161 -0
  519. package/dist/obj/rune-registry.js.map +1 -0
  520. package/dist/obj/rune-vectors.d.ts +99 -0
  521. package/dist/obj/rune-vectors.d.ts.map +1 -0
  522. package/dist/obj/rune-vectors.fixtures.d.ts +44 -0
  523. package/dist/obj/rune-vectors.fixtures.d.ts.map +1 -0
  524. package/dist/obj/rune-vectors.fixtures.js +125 -0
  525. package/dist/obj/rune-vectors.fixtures.js.map +1 -0
  526. package/dist/obj/rune-vectors.js +159 -0
  527. package/dist/obj/rune-vectors.js.map +1 -0
  528. package/dist/obj/tval-registry.d.ts +174 -0
  529. package/dist/obj/tval-registry.d.ts.map +1 -0
  530. package/dist/obj/tval-registry.js +151 -0
  531. package/dist/obj/tval-registry.js.map +1 -0
  532. package/dist/obj/tval-vectors.d.ts +85 -0
  533. package/dist/obj/tval-vectors.d.ts.map +1 -0
  534. package/dist/obj/tval-vectors.fixtures.d.ts +24 -0
  535. package/dist/obj/tval-vectors.fixtures.d.ts.map +1 -0
  536. package/dist/obj/tval-vectors.fixtures.js +41 -0
  537. package/dist/obj/tval-vectors.fixtures.js.map +1 -0
  538. package/dist/obj/tval-vectors.js +76 -0
  539. package/dist/obj/tval-vectors.js.map +1 -0
  540. package/dist/obj/types.d.ts +18 -7
  541. package/dist/obj/types.d.ts.map +1 -1
  542. package/dist/obj/types.js.map +1 -1
  543. package/dist/obj/value.d.ts.map +1 -1
  544. package/dist/obj/value.js +23 -20
  545. package/dist/obj/value.js.map +1 -1
  546. package/dist/parser.d.ts +116 -0
  547. package/dist/parser.d.ts.map +1 -0
  548. package/dist/parser.js +205 -0
  549. package/dist/parser.js.map +1 -0
  550. package/dist/player/bind.d.ts.map +1 -1
  551. package/dist/player/bind.js +3 -2
  552. package/dist/player/bind.js.map +1 -1
  553. package/dist/player/birth.d.ts +2 -1
  554. package/dist/player/birth.d.ts.map +1 -1
  555. package/dist/player/birth.js +2 -1
  556. package/dist/player/birth.js.map +1 -1
  557. package/dist/player/calcs.d.ts +58 -23
  558. package/dist/player/calcs.d.ts.map +1 -1
  559. package/dist/player/calcs.js +93 -36
  560. package/dist/player/calcs.js.map +1 -1
  561. package/dist/player/death.d.ts +50 -0
  562. package/dist/player/death.d.ts.map +1 -0
  563. package/dist/player/death.js +46 -0
  564. package/dist/player/death.js.map +1 -0
  565. package/dist/player/options-file.d.ts +129 -0
  566. package/dist/player/options-file.d.ts.map +1 -0
  567. package/dist/player/options-file.js +309 -0
  568. package/dist/player/options-file.js.map +1 -0
  569. package/dist/player/options.d.ts +2 -1
  570. package/dist/player/options.d.ts.map +1 -1
  571. package/dist/player/options.js +2 -1
  572. package/dist/player/options.js.map +1 -1
  573. package/dist/player/player.d.ts +50 -3
  574. package/dist/player/player.d.ts.map +1 -1
  575. package/dist/player/player.js +10 -1
  576. package/dist/player/player.js.map +1 -1
  577. package/dist/player/shape-lore.d.ts +11 -7
  578. package/dist/player/shape-lore.d.ts.map +1 -1
  579. package/dist/player/shape-lore.js +24 -11
  580. package/dist/player/shape-lore.js.map +1 -1
  581. package/dist/player/timed.d.ts +5 -3
  582. package/dist/player/timed.d.ts.map +1 -1
  583. package/dist/player/timed.js +11 -2
  584. package/dist/player/timed.js.map +1 -1
  585. package/dist/player/types.d.ts +29 -4
  586. package/dist/player/types.d.ts.map +1 -1
  587. package/dist/player/types.js +24 -1
  588. package/dist/player/types.js.map +1 -1
  589. package/dist/session/boot.d.ts +26 -2
  590. package/dist/session/boot.d.ts.map +1 -1
  591. package/dist/session/boot.js +21 -2
  592. package/dist/session/boot.js.map +1 -1
  593. package/dist/session/game.d.ts +15 -0
  594. package/dist/session/game.d.ts.map +1 -1
  595. package/dist/session/game.js +616 -140
  596. package/dist/session/game.js.map +1 -1
  597. package/dist/session/save-migrate.d.ts.map +1 -1
  598. package/dist/session/save-migrate.js +76 -1
  599. package/dist/session/save-migrate.js.map +1 -1
  600. package/dist/session/save.d.ts +75 -12
  601. package/dist/session/save.d.ts.map +1 -1
  602. package/dist/session/save.js +177 -18
  603. package/dist/session/save.js.map +1 -1
  604. package/dist/store/bind.d.ts +1 -1
  605. package/dist/store/bind.d.ts.map +1 -1
  606. package/dist/store/bind.js +4 -3
  607. package/dist/store/bind.js.map +1 -1
  608. package/dist/store/mass-produce-vectors.d.ts +40 -0
  609. package/dist/store/mass-produce-vectors.d.ts.map +1 -0
  610. package/dist/store/mass-produce-vectors.fixtures.d.ts +13 -0
  611. package/dist/store/mass-produce-vectors.fixtures.d.ts.map +1 -0
  612. package/dist/store/mass-produce-vectors.fixtures.js +52 -0
  613. package/dist/store/mass-produce-vectors.fixtures.js.map +1 -0
  614. package/dist/store/mass-produce-vectors.js +44 -0
  615. package/dist/store/mass-produce-vectors.js.map +1 -0
  616. package/dist/store/store.d.ts +104 -7
  617. package/dist/store/store.d.ts.map +1 -1
  618. package/dist/store/store.js +199 -77
  619. package/dist/store/store.js.map +1 -1
  620. package/dist/store/transact.d.ts +14 -5
  621. package/dist/store/transact.d.ts.map +1 -1
  622. package/dist/store/transact.js +17 -16
  623. package/dist/store/transact.js.map +1 -1
  624. package/dist/store/types.d.ts +3 -2
  625. package/dist/store/types.d.ts.map +1 -1
  626. package/dist/store/types.js +1 -1
  627. package/dist/version.d.ts +1 -1
  628. package/dist/version.js +1 -1
  629. package/dist/visuals/index.d.ts +1 -0
  630. package/dist/visuals/index.d.ts.map +1 -1
  631. package/dist/visuals/index.js +1 -0
  632. package/dist/visuals/index.js.map +1 -1
  633. package/dist/visuals/map-text.d.ts +8 -0
  634. package/dist/visuals/map-text.d.ts.map +1 -1
  635. package/dist/visuals/map-text.js +1 -1
  636. package/dist/visuals/map-text.js.map +1 -1
  637. package/dist/visuals/object-glyph.d.ts +56 -0
  638. package/dist/visuals/object-glyph.d.ts.map +1 -0
  639. package/dist/visuals/object-glyph.js +52 -0
  640. package/dist/visuals/object-glyph.js.map +1 -0
  641. package/dist/visuals/prefs.d.ts +14 -22
  642. package/dist/visuals/prefs.d.ts.map +1 -1
  643. package/dist/visuals/prefs.js +4 -23
  644. package/dist/visuals/prefs.js.map +1 -1
  645. package/dist/visuals/tile-prefs.d.ts +26 -0
  646. package/dist/visuals/tile-prefs.d.ts.map +1 -1
  647. package/dist/visuals/tile-prefs.js +28 -0
  648. package/dist/visuals/tile-prefs.js.map +1 -1
  649. package/dist/world/feature.d.ts +2 -1
  650. package/dist/world/feature.d.ts.map +1 -1
  651. package/dist/world/feature.js +2 -0
  652. package/dist/world/feature.js.map +1 -1
  653. package/dist/world/project.d.ts +10 -2
  654. package/dist/world/project.d.ts.map +1 -1
  655. package/dist/world/project.js +18 -6
  656. package/dist/world/project.js.map +1 -1
  657. package/dist/world/projection.d.ts +37 -3
  658. package/dist/world/projection.d.ts.map +1 -1
  659. package/dist/world/projection.js +69 -7
  660. package/dist/world/projection.js.map +1 -1
  661. package/dist/world/trap.d.ts +2 -1
  662. package/dist/world/trap.d.ts.map +1 -1
  663. package/dist/world/trap.js +2 -1
  664. package/dist/world/trap.js.map +1 -1
  665. package/dist/world/view.d.ts +1 -1
  666. package/dist/world/view.d.ts.map +1 -1
  667. package/dist/world/view.js +11 -3
  668. package/dist/world/view.js.map +1 -1
  669. package/package.json +1 -1
  670. package/src/agent/perceive.ts +2 -3
  671. package/src/combat/blow-vectors.fixtures.ts +99 -0
  672. package/src/combat/blow-vectors.json +482 -0
  673. package/src/combat/blow-vectors.ts +280 -0
  674. package/src/combat/brand-slay.ts +42 -11
  675. package/src/combat/index.ts +1 -1
  676. package/src/combat/melee.ts +37 -19
  677. package/src/combat/mon-melee.ts +611 -364
  678. package/src/combat/ranged.ts +43 -26
  679. package/src/constants.ts +15 -0
  680. package/src/datafile.ts +148 -0
  681. package/src/effects/effect-info-registry.ts +313 -0
  682. package/src/effects/effect-info-vectors.fixtures.ts +61 -0
  683. package/src/effects/effect-info-vectors.json +11532 -0
  684. package/src/effects/effect-info-vectors.ts +376 -0
  685. package/src/effects/effect-info.ts +1005 -859
  686. package/src/effects/effect.ts +96 -62
  687. package/src/effects/handlers.ts +5 -2
  688. package/src/effects/interpreter.ts +14 -0
  689. package/src/game/cave-cmd.ts +54 -11
  690. package/src/game/cave-square.ts +80 -0
  691. package/src/game/char-sheet.ts +59 -16
  692. package/src/game/chest.ts +25 -8
  693. package/src/game/context.ts +293 -27
  694. package/src/game/describe.ts +34 -4
  695. package/src/game/display.ts +215 -19
  696. package/src/game/dump-level.ts +3 -2
  697. package/src/game/effect-attack.ts +41 -28
  698. package/src/game/effect-detect.ts +45 -8
  699. package/src/game/effect-env.ts +8 -0
  700. package/src/game/effect-general.ts +110 -47
  701. package/src/game/effect-item.ts +1075 -999
  702. package/src/game/effect-melee.ts +51 -18
  703. package/src/game/effect-monster.ts +55 -9
  704. package/src/game/effect-teleport.ts +173 -38
  705. package/src/game/effect-terrain.ts +38 -22
  706. package/src/game/equip-cmp.ts +483 -480
  707. package/src/game/floor.ts +22 -4
  708. package/src/game/gear.ts +210 -21
  709. package/src/game/harness.ts +12 -1
  710. package/src/game/ignore-cmd.ts +96 -8
  711. package/src/game/known.ts +392 -73
  712. package/src/game/loop.ts +52 -27
  713. package/src/game/lore-color.ts +13 -1
  714. package/src/game/mon-cast.ts +31 -6
  715. package/src/game/mon-cmd.ts +95 -30
  716. package/src/game/mon-death.ts +14 -12
  717. package/src/game/mon-group.ts +9 -5
  718. package/src/game/mon-message.ts +363 -65
  719. package/src/game/mon-place.ts +15 -3
  720. package/src/game/mon-ranged.ts +14 -5
  721. package/src/game/mon-side.ts +16 -12
  722. package/src/game/monster-turn.ts +120 -87
  723. package/src/game/notice.ts +85 -0
  724. package/src/game/obj-cmd.ts +126 -37
  725. package/src/game/obj-list.ts +44 -26
  726. package/src/game/object-inspect.ts +13 -0
  727. package/src/game/pickup.ts +29 -5
  728. package/src/game/player-side-vectors.fixtures.ts +215 -0
  729. package/src/game/player-side-vectors.json +6914 -0
  730. package/src/game/player-side-vectors.ts +420 -0
  731. package/src/game/player-side.ts +622 -340
  732. package/src/game/player-turn.ts +228 -31
  733. package/src/game/poly.ts +107 -0
  734. package/src/game/project-cast.ts +63 -6
  735. package/src/game/project-feat-vectors.fixtures.ts +106 -0
  736. package/src/game/project-feat-vectors.json +6554 -0
  737. package/src/game/project-feat-vectors.ts +323 -0
  738. package/src/game/project-feat.ts +417 -248
  739. package/src/game/project-monster.ts +69 -30
  740. package/src/game/project-obj-vectors.json +1 -0
  741. package/src/game/project-obj.ts +115 -47
  742. package/src/game/project-player.ts +8 -0
  743. package/src/game/projection-handlers.ts +110 -0
  744. package/src/game/quest.ts +48 -0
  745. package/src/game/ranged-cmd.ts +45 -11
  746. package/src/game/repeat.ts +92 -0
  747. package/src/game/shape-inspect.ts +166 -0
  748. package/src/game/spell-cmd.ts +39 -6
  749. package/src/game/spoil.ts +92 -39
  750. package/src/game/steal.ts +9 -4
  751. package/src/game/target-loop.ts +14 -7
  752. package/src/game/target.ts +18 -7
  753. package/src/game/ui-entry.ts +172 -22
  754. package/src/game/wizard.ts +97 -10
  755. package/src/game/world.ts +6 -0
  756. package/src/gen/cave.ts +225 -26
  757. package/src/gen/generate.ts +62 -9
  758. package/src/gen/glyph-vectors.fixtures.ts +122 -0
  759. package/src/gen/glyph-vectors.json +5996 -0
  760. package/src/gen/glyph-vectors.ts +280 -0
  761. package/src/gen/glyph.ts +132 -0
  762. package/src/gen/room.ts +446 -265
  763. package/src/gen/util.ts +32 -9
  764. package/src/i18n/i18n.ts +492 -0
  765. package/src/i18n/text.ts +117 -0
  766. package/src/index.ts +307 -254
  767. package/src/mod/extension.ts +136 -0
  768. package/src/mod/hooks.ts +54 -1
  769. package/src/mod/ids.ts +92 -21
  770. package/src/mod/record-keys.ts +102 -0
  771. package/src/mod/registry-host.ts +1063 -234
  772. package/src/mon/bind.ts +14 -8
  773. package/src/mon/knowledge-groups.ts +12 -12
  774. package/src/mon/lore-describe.ts +93 -26
  775. package/src/mon/lore-file.ts +365 -0
  776. package/src/mon/lore.ts +9 -3
  777. package/src/mon/make.ts +4 -2
  778. package/src/mon/monster.ts +1 -1
  779. package/src/mon/predicate.ts +14 -9
  780. package/src/mon/project-mon.ts +23 -5
  781. package/src/mon/steal.ts +39 -7
  782. package/src/mon/take-hit.ts +8 -3
  783. package/src/mon/timed.ts +15 -9
  784. package/src/mon/types.ts +11 -4
  785. package/src/msg.ts +55 -1
  786. package/src/obj/artifact-fake.ts +47 -17
  787. package/src/obj/bind.ts +52 -9
  788. package/src/obj/desc-vectors.fixtures.ts +119 -0
  789. package/src/obj/desc-vectors.json +2360 -0
  790. package/src/obj/desc-vectors.ts +128 -0
  791. package/src/obj/desc.ts +159 -55
  792. package/src/obj/effects-info.ts +90 -59
  793. package/src/obj/fake-object.ts +135 -0
  794. package/src/obj/ignore.ts +95 -28
  795. package/src/obj/knowledge.ts +291 -139
  796. package/src/obj/known-object.ts +126 -11
  797. package/src/obj/make.ts +53 -29
  798. package/src/obj/object-info.ts +103 -6
  799. package/src/obj/object.ts +392 -151
  800. package/src/obj/power.ts +297 -59
  801. package/src/obj/randart-build.ts +1875 -1705
  802. package/src/obj/randart-data.ts +1547 -1344
  803. package/src/obj/randart-file.ts +130 -0
  804. package/src/obj/randart-log.ts +78 -0
  805. package/src/obj/randart-registry.ts +247 -0
  806. package/src/obj/randart-vectors.fixtures.ts +61 -0
  807. package/src/obj/randart-vectors.json +836 -0
  808. package/src/obj/randart-vectors.ts +369 -0
  809. package/src/obj/randart.ts +722 -552
  810. package/src/obj/rune-registry.ts +270 -0
  811. package/src/obj/rune-vectors.fixtures.ts +164 -0
  812. package/src/obj/rune-vectors.json +121 -0
  813. package/src/obj/rune-vectors.ts +229 -0
  814. package/src/obj/tval-kind-vectors.json +391 -0
  815. package/src/obj/tval-registry.ts +243 -0
  816. package/src/obj/tval-vectors.fixtures.ts +50 -0
  817. package/src/obj/tval-vectors.json +38 -0
  818. package/src/obj/tval-vectors.ts +126 -0
  819. package/src/obj/types.ts +18 -7
  820. package/src/obj/value.ts +26 -20
  821. package/src/parser.ts +214 -0
  822. package/src/player/bind.ts +5 -2
  823. package/src/player/birth.ts +2 -1
  824. package/src/player/calcs.ts +123 -42
  825. package/src/player/death.ts +78 -0
  826. package/src/player/options-file.ts +387 -0
  827. package/src/player/options.ts +2 -1
  828. package/src/player/player.ts +60 -4
  829. package/src/player/shape-lore.ts +33 -14
  830. package/src/player/timed.ts +14 -4
  831. package/src/player/types.ts +30 -4
  832. package/src/session/boot.ts +51 -1
  833. package/src/session/game.ts +720 -163
  834. package/src/session/save-migrate.ts +81 -1
  835. package/src/session/save.ts +264 -22
  836. package/src/store/bind.ts +4 -3
  837. package/src/store/mass-produce-vectors.fixtures.ts +64 -0
  838. package/src/store/mass-produce-vectors.json +1169 -0
  839. package/src/store/mass-produce-vectors.ts +67 -0
  840. package/src/store/store.ts +266 -63
  841. package/src/store/transact.ts +39 -16
  842. package/src/store/types.ts +3 -2
  843. package/src/version.ts +1 -1
  844. package/src/visuals/index.ts +1 -0
  845. package/src/visuals/map-text.ts +1 -1
  846. package/src/visuals/object-glyph.ts +76 -0
  847. package/src/visuals/prefs.ts +22 -32
  848. package/src/visuals/tile-prefs.ts +32 -0
  849. package/src/world/feature.ts +4 -1
  850. package/src/world/project.ts +19 -4
  851. package/src/world/projection.ts +79 -8
  852. package/src/world/trap.ts +25 -21
  853. package/src/world/view.ts +11 -1
package/src/mon/bind.ts CHANGED
@@ -60,6 +60,7 @@ import type {
60
60
  } from "./types.js";
61
61
  import { RF, RSF } from "../generated/index.js";
62
62
  import { messageLookupByName } from "../sound/engine.js";
63
+ import { attachExt } from "../mod/extension.js";
63
64
 
64
65
  /* re-export for consumers that reach the domain through bind */
65
66
  export { MFLAG_SIZE, RF_SIZE, RSF_SIZE };
@@ -473,13 +474,16 @@ function bindBases(
473
474
  }
474
475
  const flags = new FlagSet(RF_SIZE);
475
476
  raceFlagsOn(flags, rec.flags);
476
- map.set(rec.name, {
477
- name: rec.name,
478
- text: joinLines(rec.desc),
479
- flags,
480
- glyph: rec.glyph,
481
- pain,
482
- });
477
+ map.set(
478
+ rec.name,
479
+ attachExt<MonsterBase>("monster_base", rec, {
480
+ name: rec.name,
481
+ text: joinLines(rec.desc),
482
+ flags,
483
+ glyph: rec.glyph,
484
+ pain,
485
+ }),
486
+ );
483
487
  }
484
488
  return map;
485
489
  }
@@ -646,7 +650,9 @@ export class MonsterRegistry {
646
650
  this.racesByName = new Map();
647
651
  for (const rec of pack.monsters) {
648
652
  const race = this.bindRace(rec, maxSight, innate, breathOrInnate);
649
- this.races.push(race);
653
+ /* Keys core does not read ride along instead of being dropped - the same
654
+ * seam as ObjectKind.ext, for the same reason. */
655
+ this.races.push(attachExt("monster", rec, race));
650
656
  this.racesByName.set(race.name.toLowerCase(), race);
651
657
  }
652
658
 
@@ -27,10 +27,6 @@ export interface MonsterCategory {
27
27
  readonly incBases: readonly string[];
28
28
  /** mcat-include-flag flag indices (RF_*). */
29
29
  readonly incFlags: readonly number[];
30
- /** mcat-include-other:fully-known */
31
- readonly includeFullyKnown: boolean;
32
- /** mcat-include-other:not-fully-known */
33
- readonly includeNotFullyKnown: boolean;
34
30
  }
35
31
 
36
32
  /** A compiled pack/ui_knowledge.json record. */
@@ -39,8 +35,6 @@ export interface UiKnowledgeRecordJson {
39
35
  "mcat-include-base"?: string[];
40
36
  /** Each entry is a " | "-separated flag list (may hold several flags). */
41
37
  "mcat-include-flag"?: string[];
42
- /** "fully-known" / "not-fully-known". */
43
- "mcat-include-other"?: string[];
44
38
  }
45
39
 
46
40
  /** The reserved catch-all category name (finish_ui_knowledge_parser L3439). */
@@ -60,13 +54,10 @@ export function bindMonsterCategories(
60
54
  if (idx !== undefined) incFlags.push(idx);
61
55
  }
62
56
  }
63
- const other = (r["mcat-include-other"] ?? []).map(String);
64
57
  return {
65
58
  name: r["monster-category"],
66
59
  incBases: (r["mcat-include-base"] ?? []).map(String),
67
60
  incFlags,
68
- includeFullyKnown: other.includes("fully-known"),
69
- includeNotFullyKnown: other.includes("not-fully-known"),
70
61
  };
71
62
  });
72
63
  }
@@ -104,17 +95,26 @@ function compareInGroup(
104
95
  return strcmp(a.name, b.name);
105
96
  }
106
97
 
107
- /** Does a race match a category by flag or by the fully-/not-fully-known other? */
98
+ /**
99
+ * Does a race match a category by flag? (ui-knowledge.c parse_mcat_include_flag.)
100
+ *
101
+ * There is no `mcat-include-other` arm here any more. That directive, and the
102
+ * fully-known / not-fully-known categories it drives, are POST-4.2.6 upstream
103
+ * work; #143 moved reference/ back to the 4.2.6 tag, whose ui-knowledge.c
104
+ * registers only mcat-include-base and mcat-include-flag, and whose
105
+ * ui_knowledge.txt uses neither of the "other" values. Core reproduces a
106
+ * released Angband, so an upstream feature newer than the baseline is an
107
+ * extension and belongs in a mod (#146).
108
+ */
108
109
  function matchesFlagOrOther(
109
110
  category: MonsterCategory,
110
111
  race: MonsterRace,
111
112
  allKnown: boolean,
112
113
  ): boolean {
114
+ void allKnown;
113
115
  for (const flag of category.incFlags) {
114
116
  if (race.flags.has(flag)) return true;
115
117
  }
116
- if (category.includeFullyKnown && allKnown) return true;
117
- if (category.includeNotFullyKnown && !allKnown) return true;
118
118
  return false;
119
119
  }
120
120
 
@@ -18,8 +18,8 @@
18
18
  * spell&blow danger colors that upstream reads off the global player) is not
19
19
  * available in this module, so it is injected through the LoreDeps object.
20
20
  * Colors default to the datum's base lore color when no danger evaluator is
21
- * supplied; the two hit-chance callbacks are the remaining integration seams
22
- * for the combat layer (still default to 0 unwired). The spell damage
21
+ * supplied; the two hit-chance callbacks are integration seams supplied by the
22
+ * combat layer in the live game. The spell damage
23
23
  * callback (`spellLoreDamage`) is a full override only - its default
24
24
  * computes the real mon_spell_lore_damage from the bound spell + race data
25
25
  * (see monSpellLoreDamage below), needing just `breathProjection` from the
@@ -43,6 +43,7 @@ import {
43
43
  colorTextToAttr,
44
44
  } from "../color.js";
45
45
  import { EF, MON_RACE_FLAG_ENTRIES, OF, PROJ, RF } from "../generated/index.js";
46
+ import { ATTR_TILE_BIT } from "../visuals/map-text.js";
46
47
  import { createMonFlagMask, monsterFlagsKnown } from "./lore.js";
47
48
  import type { MonsterLore } from "./lore.js";
48
49
  import { EXTRACT_ENERGY } from "./monster.js";
@@ -114,6 +115,21 @@ export interface LoreDeps {
114
115
  playerSpeed: number;
115
116
  /** OPT(player, effective_speed): multiplier form vs. adjective form. */
116
117
  effectiveSpeed: boolean;
118
+ /**
119
+ * OPT(player, purple_uniques): recolour a unique's title glyph violet
120
+ * (ui-mon-lore.c L56-60). Required rather than optional, and named exactly as
121
+ * `visuals/map-text.ts` names it, because the map layer already honours this
122
+ * option — a lore title that quietly ignored it would disagree with the glyph
123
+ * the player is looking at on the same screen.
124
+ */
125
+ purpleUniques: boolean;
126
+ /**
127
+ * monster_x_attr[race->ridx] / monster_x_char[race->ridx] (ui-mon-lore.c
128
+ * L47/L51): the pref-file / picker override pair for a race. Optional, and
129
+ * absent means "no override table" - a spoiler file and a worldless test have
130
+ * none, and upstream's arrays would hold the default pair there anyway.
131
+ */
132
+ monsterGlyph?: (race: MonsterRace) => { attr: number; char: string } | undefined;
117
133
  /** monster_spell_by_index: the bound spell list, keyed by RSF_ index. */
118
134
  spells: ReadonlyMap<number, MonsterSpell>;
119
135
  /**
@@ -129,13 +145,15 @@ export interface LoreDeps {
129
145
  /**
130
146
  * The player's percent chance to hit this race in melee
131
147
  * (random_chance_scaled of hit_chance(chance_of_melee_hit_base, ac)).
132
- * DEFERRED: defaults to 0 when the combat layer does not supply it.
148
+ * Defaults to 0 only for a caller that omits it. The core spoiler dump has
149
+ * booted player combat state, but deliberately omits this inert callback.
133
150
  */
134
151
  meleeHitPercent?: (race: MonsterRace) => number;
135
152
  /**
136
153
  * The monster's percent chance to land the given blow on the player
137
154
  * (random_chance_scaled of hit_chance(chance_of_monster_hit_base, ac+to_a)).
138
- * DEFERRED: defaults to 0 when the combat layer does not supply it.
155
+ * Defaults to 0 only for a caller that omits it and has no player defence to
156
+ * supply. The core spoiler dump supplies this callback from its booted state.
139
157
  */
140
158
  monsterHitPercent?: (race: MonsterRace, effect: BlowEffect) => number;
141
159
  /**
@@ -151,9 +169,8 @@ export interface LoreDeps {
151
169
  * The breath element's damage divisor/cap (element->divisor /
152
170
  * element->damage_cap, projection.txt), keyed by PROJ_ value - the one
153
171
  * piece of breath damage that lives outside mon/ (world/projection.ts).
154
- * Only consulted for breath-type spells' default damage. DEFERRED: damage
155
- * shows as 0 when the caller does not supply it, like the other
156
- * world-derived callbacks above.
172
+ * Only consulted for breath-type spells' default damage. A worldless caller
173
+ * without projection data renders that component as 0.
157
174
  */
158
175
  breathProjection?: (subtype: number) => BreathProjection | undefined;
159
176
  }
@@ -1342,54 +1359,104 @@ function isFullyKnown(race: MonsterRace, lore: MonsterLore): boolean {
1342
1359
  }
1343
1360
 
1344
1361
  /**
1345
- * lore_title (ui-mon-lore.c L38), reduced to what the headless model can
1346
- * express: "The " for non-uniques, the name, and the primary glyph.
1362
+ * lore_title (ui-mon-lore.c L38): "The " for non-uniques, the name, and the
1363
+ * primary glyph — with OPT(purple_uniques) recolouring a unique's glyph violet
1364
+ * (L56-60). Upstream also recolours the OPTIONAL attr there, but only when it is
1365
+ * not a tile index (`!(optional_attr & 0x80)`).
1347
1366
  *
1348
- * DEFERRED: the optional secondary glyph (monster_x_char / monster_x_attr,
1349
- * ui-mon-lore.c L47/L51), OPT(purple_uniques) recoloring (L56), and tile
1350
- * width/height gating (L69) are all presentation state not modelled here.
1367
+ * The secondary glyph is ported too, through the optional `monsterGlyph` dep.
1368
+ * It used to be filed here as shell-owned along with `purple_uniques` and the
1369
+ * tile-size gate, and all three of those groupings were wrong in different
1370
+ * ways: `purple_uniques` is a live option the map layer already honours;
1371
+ * `monster_x_attr` / `monster_x_char` are a real table in the port
1372
+ * (`visuals/glyph-table.ts`, `GlyphTable.monsterGlyph`); and the
1373
+ * `tile_width == 1 && tile_height == 1` gate (L69) is unconditionally TRUE
1374
+ * here — the port has no multi-cell tiles, a ratified divergence recorded at
1375
+ * `packages/web/src/mapview.ts:70` — so the gate is omitted rather than
1376
+ * deferred. Absent `monsterGlyph` (spoiler files, worldless tests) the pair
1377
+ * equals the race's own and nothing extra is emitted, exactly as upstream's
1378
+ * unmodified array would give.
1351
1379
  */
1352
- function loreTitle(b: LoreTextBuilder, race: MonsterRace): void {
1353
- if (!race.flags.has(RF.UNIQUE)) b.append("The ");
1380
+ function loreTitle(b: LoreTextBuilder, race: MonsterRace, deps: LoreDeps): void {
1381
+ const unique = race.flags.has(RF.UNIQUE);
1382
+ const optional = deps.monsterGlyph?.(race);
1383
+ let standardAttr = race.dAttr;
1384
+ let optionalAttr = optional?.attr ?? race.dAttr;
1385
+ const optionalChar = optional?.char ?? race.dChar;
1386
+
1387
+ if (!unique) {
1388
+ b.append("The ");
1389
+ } else if (deps.purpleUniques) {
1390
+ standardAttr = COLOUR_VIOLET;
1391
+ /* L58-59: a tile code in the slot is left alone. */
1392
+ if (!(optionalAttr & ATTR_TILE_BIT)) optionalAttr = COLOUR_VIOLET;
1393
+ }
1394
+
1354
1395
  b.append(race.name);
1355
1396
  b.append(" ('");
1356
- b.append(race.dChar, race.dAttr);
1397
+ b.append(race.dChar, standardAttr);
1357
1398
  b.append("')");
1399
+
1400
+ if (optionalAttr !== standardAttr || optionalChar !== race.dChar) {
1401
+ b.append(" ('");
1402
+ b.append(optionalChar, optionalAttr);
1403
+ b.append("')");
1404
+ }
1358
1405
  }
1359
1406
 
1360
1407
  /**
1361
- * lore_description (ui-mon-lore.c L89), non-spoiler path: assemble the full
1362
- * recall for what the player knows. Returns the finished flat run list.
1408
+ * lore_description (ui-mon-lore.c L89): assemble the full recall. Returns the
1409
+ * finished flat run list.
1363
1410
  *
1364
1411
  * The order of sections is transcribed from ui-mon-lore.c L110-150:
1365
1412
  * title, kills, flavor, movement, toughness, exp, drop, abilities,
1366
1413
  * awareness, friends, spells, attack, fully-known note, questor note.
1414
+ *
1415
+ * `spoilers` is upstream's fourth argument (L90) and means "full information,
1416
+ * without the subjective parts". It suppresses FOUR sections, not just the
1417
+ * title: the title (L108-112), the kill counts (L114-116), the toughness block
1418
+ * (L124-125) and the experience reward (L128-129). Every one of those is a
1419
+ * statement about a player, and a spoiler file has no player.
1420
+ *
1421
+ * Upstream also calls cheat_monster_lore inside here when the flag is set
1422
+ * (L101-102). The port leaves that to the caller: game/spoil.ts already does it
1423
+ * on the lore copy it owns, and doing it twice is the same work for the same
1424
+ * answer.
1367
1425
  */
1368
1426
  export function loreDescription(
1369
1427
  race: MonsterRace,
1370
1428
  lore: MonsterLore,
1371
1429
  deps: LoreDeps,
1430
+ /**
1431
+ * ui-mon-lore.c's `spoilers` (L90). Defaults false, the player view. There
1432
+ * are exactly two callers and they want different values, so this is a live
1433
+ * branch rather than an option nobody sets.
1434
+ */
1435
+ spoilers = false,
1372
1436
  ): LoreText {
1373
1437
  const b = new LoreTextBuilder();
1374
1438
  const knownFlags = monsterFlagsKnown(race, lore);
1375
1439
 
1376
- /* Title (only in the non-spoiler player view). */
1377
- loreTitle(b, race);
1378
- b.append("\n");
1440
+ /* Title (L108-112). Upstream's own comment: appending it here simplifies the
1441
+ callers, "and it also causes a crash when generating spoilers". */
1442
+ if (!spoilers) {
1443
+ loreTitle(b, race, deps);
1444
+ b.append("\n");
1445
+ }
1379
1446
 
1380
- /* Kills of monster vs. player(s). */
1381
- loreAppendKills(b, race, lore, knownFlags);
1447
+ /* Kills of monster vs. player(s) (L114-116). */
1448
+ if (!spoilers) loreAppendKills(b, race, lore, knownFlags);
1382
1449
 
1383
1450
  loreAppendFlavor(b, race);
1384
1451
 
1385
1452
  /* Type, location, speed. */
1386
1453
  loreAppendMovement(b, race, lore, knownFlags, deps);
1387
1454
 
1388
- /* Life and armor, and player's hit chance. */
1389
- loreAppendToughness(b, race, lore, knownFlags, deps);
1455
+ /* Life and armor, and player's hit chance (L124-125). */
1456
+ if (!spoilers) loreAppendToughness(b, race, lore, knownFlags, deps);
1390
1457
 
1391
- /* Experience reward. */
1392
- loreAppendExp(b, race, lore, knownFlags, deps);
1458
+ /* Experience reward (L128-129). */
1459
+ if (!spoilers) loreAppendExp(b, race, lore, knownFlags, deps);
1393
1460
 
1394
1461
  loreAppendDrop(b, race, lore, knownFlags);
1395
1462
 
@@ -0,0 +1,365 @@
1
+ /**
2
+ * lore.txt: monster memory as a file in ANGBAND_DIR_USER, both halves.
3
+ *
4
+ * WHAT WAS MISSING, AND WHY IT IS NOT JUST A FILE
5
+ *
6
+ * Upstream splits monster memory between two stores, and the split is
7
+ * load-bearing rather than incidental:
8
+ *
9
+ * - the SAVEFILE carries `pkills` and `thefts` - "in this life" counters;
10
+ * - `lore.txt` in the USER directory carries everything else, and the user
11
+ * directory belongs to the PLAYER, not to a character. `lore_save` is
12
+ * called from `save_game_checked` (ui-game.c:1089) and the file is read back
13
+ * by `lore_parser` at startup (mon-init.c:2672), before any savefile is
14
+ * touched.
15
+ *
16
+ * So upstream's monster knowledge SURVIVES DEATH. `tkills` is commented "Count
17
+ * monsters killed in all lives" and mon-lore.c says so out loud: "your ancestors
18
+ * have exterminated at least %d of the creatures." The port kept the whole lore
19
+ * record in the JSON save, which is tidy and is why nothing ever noticed - but it
20
+ * means tkills can only ever count this character's kills, and the ancestor
21
+ * sentence in lore-describe.ts could never be true of an ancestor. A behavioural
22
+ * gap wearing a file's clothes: reading the port, there was no missing function to
23
+ * find, because the knowledge was being persisted - just to the wrong place.
24
+ *
25
+ * THE SPLIT, KEPT EXACTLY. This module is the file. The save keeps carrying the
26
+ * full record (no SAVE_VERSION change: a bump reads as corruption to an existing
27
+ * character), and the front end overlays lore.txt on top of a loaded game for the
28
+ * seven counters plus the flags and blows that the file carries - which is
29
+ * precisely the set `write_lore_entries` writes. pkills and thefts are never in
30
+ * the file and so are never overlaid, exactly as upstream has them.
31
+ *
32
+ * WHAT THIS DELIBERATELY DOES NOT EMIT: `drop:`, `drop-base:`, `friends:`,
33
+ * `friends-base:` and `mimic:`. Upstream writes those from `lore->drops` and
34
+ * friends, and NOTHING in the C populates those lists except the lore PARSER -
35
+ * they are a pure echo of a previously-read file. A player who has never had a
36
+ * lore.txt gets none of those lines from upstream either, and the port models the
37
+ * same knowledge on the race gated on `dropKnown` and the known flags (see
38
+ * lore.ts). The reader below accepts and ignores them, so an upstream lore.txt
39
+ * still loads.
40
+ */
41
+
42
+ import { writeFlags } from "../datafile.js";
43
+ /**
44
+ * writeFlags used to be DEFINED here and is on the pinned ctx.core surface
45
+ * (mod-core-surface.test.ts), so a plugin may be importing it from this
46
+ * module. Moving the definition to ../datafile.js must not move the export.
47
+ */
48
+ export { writeFlags };
49
+ import { FlagSet, flagSetall } from "../bitflag.js";
50
+ import { RF, RSF } from "../generated/index.js";
51
+ import { RF_SIZE, RSF_SIZE } from "./types.js";
52
+ import type { MonsterRace } from "./types.js";
53
+ import { loreUpdate, newMonsterLore } from "./lore.js";
54
+ import type { LoreStore, MonsterLore } from "./lore.js";
55
+
56
+ /**
57
+ * A flag-number -> name table, INVERTED FROM THE ENUM rather than read off the
58
+ * generated entry list.
59
+ *
60
+ * The two entry lists disagree about index 0: MON_SPELL_ENTRIES keeps upstream's
61
+ * RSF_NONE at [0], and MON_RACE_FLAG_ENTRIES drops RF_NONE, so `ENTRIES[flag]`
62
+ * is right for one and off by one for the other. Inverting the enum - which is
63
+ * generated from the same header as the flags themselves - cannot be off by one
64
+ * in either direction, and the test pins both against the reference headers.
65
+ */
66
+ function nameTable(en: Readonly<Record<string, number>>): readonly (string | undefined)[] {
67
+ const out: (string | undefined)[] = [];
68
+ for (const [name, value] of Object.entries(en)) out[value] = name;
69
+ return out;
70
+ }
71
+
72
+ /** r_info_flags (mon-init.c), by flag number. Index 0 is upstream's RF_NONE. */
73
+ export const RF_FLAG_NAMES = nameTable(RF);
74
+ /** r_info_spell_flags (mon-init.c:55-61), by flag number. */
75
+ export const RSF_FLAG_NAMES = nameTable(RSF);
76
+
77
+ const RF_NAMES = RF_FLAG_NAMES;
78
+ const RSF_NAMES = RSF_FLAG_NAMES;
79
+
80
+
81
+ /**
82
+ * write_lore_entries (mon-lore.c:1743-1893): one block per race the player has
83
+ * seen or fully knows, in race index order.
84
+ *
85
+ * `rsf_inter(lore->spell_flags, race->spell_flags)` at L1802 MUTATES the lore
86
+ * record as a side effect of writing the file - a wart, but a wart that changes
87
+ * what the next save contains, so it is reproduced (core keeps the C's warts;
88
+ * fixes go in the bug-fixes mod).
89
+ */
90
+ export function writeLoreEntries(
91
+ races: readonly MonsterRace[],
92
+ store: LoreStore,
93
+ ): string {
94
+ let out = "";
95
+
96
+ for (const race of races) {
97
+ /* "Ignore non-existent or unseen monsters" (L1755-1757). */
98
+ if (!race.name) continue;
99
+ const lore = store.get(race.ridx);
100
+ if (!lore) continue;
101
+ if (!lore.sights && !lore.allKnown) continue;
102
+
103
+ out += `name:${race.name}\n`;
104
+
105
+ /* "Output base if we're remembering everything" (L1760-1762). */
106
+ if (lore.allKnown) out += `base:${race.base.name}\n`;
107
+
108
+ out += `counts:${lore.sights}:${lore.deaths}:${lore.tkills}:${lore.wake}:${lore.ignore}:${lore.castInnate}:${lore.castSpell}\n`;
109
+
110
+ /* Blows, up to mon_blows_max (L1768-1795). */
111
+ for (let n = 0; n < race.blows.length; n++) {
112
+ if (!lore.blowKnown[n] && !lore.allKnown) continue;
113
+ const blow = race.blows[n];
114
+ if (!blow?.method) continue;
115
+ const rv = blow.dice?.randomValue() ?? { base: 0, dice: 0, sides: 0, mBonus: 0 };
116
+ out += `blow:${blow.method.name}`;
117
+ out += `:${blow.effect.name}`;
118
+ out += `:${rv.base}+${rv.dice}d${rv.sides}M${rv.mBonus}`;
119
+ out += `:${lore.blowTimesSeen[n] ?? 0}`;
120
+ out += `:${n}`;
121
+ out += "\n";
122
+ }
123
+
124
+ out += writeFlags("flags:", lore.flags, RF_SIZE, RF_NAMES);
125
+
126
+ /* rsf_inter, in place, then the spell line (L1802-1805). */
127
+ lore.spellFlags.inter(race.spellFlags);
128
+ out += writeFlags("spells:", lore.spellFlags, RSF_SIZE, RSF_NAMES);
129
+
130
+ out += "\n";
131
+ }
132
+
133
+ return out;
134
+ }
135
+
136
+ /** The fields lore.txt carries, for one race. Everything else stays as it was. */
137
+ interface LoreFileEntry {
138
+ readonly sights: number;
139
+ readonly deaths: number;
140
+ readonly tkills: number;
141
+ readonly wake: number;
142
+ readonly ignore: number;
143
+ readonly castInnate: number;
144
+ readonly castSpell: number;
145
+ readonly allKnown: boolean;
146
+ /** index -> times_seen, only for blows the file recorded as seen. */
147
+ readonly blowTimesSeen: ReadonlyMap<number, number>;
148
+ readonly flags: FlagSet;
149
+ readonly spellFlags: FlagSet;
150
+ }
151
+
152
+ /** What one parse produced, plus the lines it could not use. */
153
+ export interface LoreFileParse {
154
+ /** Race name (as written in the file) -> the record it carried. */
155
+ readonly entries: ReadonlyMap<string, LoreFileEntry>;
156
+ /**
157
+ * Directives that were recognised but carry nothing this port models - the
158
+ * drop / friends / mimic echo - counted rather than dropped silently, so a
159
+ * caller can say "this file held more than we read" instead of guessing.
160
+ */
161
+ readonly ignored: number;
162
+ /** Lines that are not a directive at all. Named, because a broken file is a bug. */
163
+ readonly bad: readonly string[];
164
+ }
165
+
166
+ /** grab_flag by name, tolerant exactly as the C's `(void) grab_flag` is. */
167
+ function grabFlags(text: string, set: FlagSet, names: readonly (string | undefined)[]): void {
168
+ for (const token of text.split(/[\s|]+/u)) {
169
+ if (token === "") continue;
170
+ const flag = names.indexOf(token);
171
+ if (flag > 0) set.on(flag);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * lore_parser (mon-init.c:2544-2580), as a pure function over the file text.
177
+ *
178
+ * Upstream resolves `name:` to a race immediately and drops the block when the
179
+ * monster does not exist ("to allow for non-existent monsters"). This keeps the
180
+ * NAME and lets the caller resolve, because in this port a name can be absent for
181
+ * a second reason upstream does not have: a mod that supplied the monster is no
182
+ * longer installed. Losing that block silently would quietly forget a player's
183
+ * memory of it, where keeping it means re-enabling the mod restores the lore.
184
+ */
185
+ export function parseLoreFile(text: string): LoreFileParse {
186
+ const entries = new Map<string, LoreFileEntry>();
187
+ const bad: string[] = [];
188
+ let ignored = 0;
189
+
190
+ let name: string | null = null;
191
+ let cur: {
192
+ sights: number;
193
+ deaths: number;
194
+ tkills: number;
195
+ wake: number;
196
+ ignore: number;
197
+ castInnate: number;
198
+ castSpell: number;
199
+ allKnown: boolean;
200
+ blowTimesSeen: Map<number, number>;
201
+ flags: FlagSet;
202
+ spellFlags: FlagSet;
203
+ } | null = null;
204
+
205
+ const flush = (): void => {
206
+ if (name !== null && cur !== null) entries.set(name, cur);
207
+ name = null;
208
+ cur = null;
209
+ };
210
+
211
+ for (const raw of text.split(/\r?\n/)) {
212
+ const line = raw.trim();
213
+ if (line === "" || line.startsWith("#")) continue;
214
+
215
+ const colon = line.indexOf(":");
216
+ const directive = colon < 0 ? line : line.slice(0, colon);
217
+ const rest = colon < 0 ? "" : line.slice(colon + 1);
218
+
219
+ switch (directive) {
220
+ case "name": {
221
+ flush();
222
+ name = rest;
223
+ cur = {
224
+ sights: 0,
225
+ deaths: 0,
226
+ tkills: 0,
227
+ wake: 0,
228
+ ignore: 0,
229
+ castInnate: 0,
230
+ castSpell: 0,
231
+ allKnown: false,
232
+ blowTimesSeen: new Map<number, number>(),
233
+ flags: new FlagSet(RF_SIZE),
234
+ spellFlags: new FlagSet(RSF_SIZE),
235
+ };
236
+ break;
237
+ }
238
+ case "base": {
239
+ /* parse_lore_base: the base is only validated; what it MEANS is
240
+ * "know everything" plus every racial flag set (mon-init.c:2294-2296). */
241
+ if (cur) {
242
+ cur.allKnown = true;
243
+ flagSetall(cur.flags.bits);
244
+ }
245
+ break;
246
+ }
247
+ case "counts": {
248
+ if (!cur) break;
249
+ const n = rest.split(":").map((v) => Number.parseInt(v, 10));
250
+ if (n.length < 7 || n.some((v) => Number.isNaN(v))) {
251
+ bad.push(line);
252
+ break;
253
+ }
254
+ [cur.sights, cur.deaths, cur.tkills, cur.wake, cur.ignore, cur.castInnate, cur.castSpell] =
255
+ n as [number, number, number, number, number, number, number];
256
+ break;
257
+ }
258
+ case "blow": {
259
+ if (!cur) break;
260
+ /* method:effect:damage:seen:index, every field after the method
261
+ * optional. "Interpret: if (seen)" - a blow seen zero times is not
262
+ * recorded at all (mon-init.c:2345-2351). */
263
+ const f = rest.split(":");
264
+ const seen = Number.parseInt(f[3] ?? "", 10);
265
+ const index = Number.parseInt(f[4] ?? "", 10);
266
+ if (!Number.isNaN(seen) && seen > 0 && !Number.isNaN(index) && index >= 0) {
267
+ cur.blowTimesSeen.set(index, seen);
268
+ }
269
+ break;
270
+ }
271
+ case "flags": {
272
+ if (cur) grabFlags(rest, cur.flags, RF_NAMES);
273
+ break;
274
+ }
275
+ case "spells": {
276
+ if (cur) grabFlags(rest, cur.spellFlags, RSF_NAMES);
277
+ break;
278
+ }
279
+ case "drop":
280
+ case "drop-base":
281
+ case "friends":
282
+ case "friends-base":
283
+ case "mimic": {
284
+ ignored++;
285
+ break;
286
+ }
287
+ default:
288
+ bad.push(line);
289
+ }
290
+ }
291
+ flush();
292
+
293
+ return { entries, ignored, bad };
294
+ }
295
+
296
+ /** What an overlay changed, so a caller can log it instead of assuming. */
297
+ export interface LoreOverlayResult {
298
+ /** Races whose record the file supplied. */
299
+ readonly applied: number;
300
+ /** Entries naming a race this pack does not have (an uninstalled mod). */
301
+ readonly unknownRaces: readonly string[];
302
+ readonly ignored: number;
303
+ readonly bad: readonly string[];
304
+ }
305
+
306
+ /**
307
+ * Put lore.txt's record over a loaded game's store, which is upstream's order:
308
+ * the file is read at startup and the savefile then supplies only pkills and
309
+ * thefts.
310
+ *
311
+ * Overwrites rather than merges, deliberately. The file is written on every save
312
+ * from this same store, so it is never older than the save; inventing a
313
+ * max()-per-counter merge would produce numbers neither store ever held.
314
+ * pkills, thefts, dropGold and dropItem are not in the file and are left alone.
315
+ */
316
+ export function applyLoreFile(
317
+ races: readonly MonsterRace[],
318
+ store: LoreStore,
319
+ parsed: LoreFileParse,
320
+ ): LoreOverlayResult {
321
+ const byName = new Map<string, MonsterRace>();
322
+ for (const race of races) if (race.name) byName.set(race.name, race);
323
+
324
+ const unknownRaces: string[] = [];
325
+ let applied = 0;
326
+
327
+ for (const [name, entry] of parsed.entries) {
328
+ const race = byName.get(name);
329
+ if (!race) {
330
+ unknownRaces.push(name);
331
+ continue;
332
+ }
333
+ let lore: MonsterLore | undefined = store.get(race.ridx);
334
+ if (!lore) {
335
+ lore = newMonsterLore(race);
336
+ store.set(race.ridx, lore);
337
+ }
338
+
339
+ lore.sights = entry.sights;
340
+ lore.deaths = entry.deaths;
341
+ lore.tkills = entry.tkills;
342
+ lore.wake = entry.wake;
343
+ lore.ignore = entry.ignore;
344
+ lore.castInnate = entry.castInnate;
345
+ lore.castSpell = entry.castSpell;
346
+ lore.allKnown = entry.allKnown;
347
+ lore.flags = entry.flags;
348
+ lore.spellFlags = entry.spellFlags;
349
+
350
+ /* Blows the file did not mention were seen zero times, which is what
351
+ * upstream's zeroed l_list means before the parser fills it in. */
352
+ lore.blowTimesSeen = race.blows.map((_, i) => entry.blowTimesSeen.get(i) ?? 0);
353
+ lore.blowKnown = race.blows.map((_, i) => (entry.blowTimesSeen.get(i) ?? 0) > 0);
354
+
355
+ /* lore_update is what derives armourKnown / dropKnown / the RFT_OBV union
356
+ * from the counters, and the parser leaves those unset. */
357
+ loreUpdate(race, lore);
358
+ applied++;
359
+ }
360
+
361
+ return { applied, unknownRaces, ignored: parsed.ignored, bad: parsed.bad };
362
+ }
363
+
364
+ /** The name lore_save is called with (ui-game.c:1090). */
365
+ export const LORE_FILE = "lore.txt";
package/src/mon/lore.ts CHANGED
@@ -13,9 +13,15 @@
13
13
  * gated on dropKnown / the known flags, so they are not modelled.
14
14
  *
15
15
  * The store lives on GameState.lore (a Map keyed by race.ridx), created
16
- * lazily by getLore; the save serializes it whole. Upstream splits
17
- * persistence between the savefile (pkills / thefts) and the user lore
18
- * file (everything else); the JSON save carries the full record.
16
+ * lazily by getLore.
17
+ *
18
+ * PERSISTENCE IS SPLIT, as upstream's is. The savefile owns pkills and thefts
19
+ * ("in this life"); lore.txt in the user directory owns everything else and
20
+ * outlives the character, which is what makes tkills "monsters killed in all
21
+ * lives" and lore-describe's "your ancestors have exterminated at least %d"
22
+ * able to be about an ancestor. lore-file.ts is both halves of that file; the
23
+ * JSON save still carries the whole record (narrowing it would be a
24
+ * SAVE_VERSION change) and the file is laid over it on load.
19
25
  */
20
26
 
21
27
  import { FlagSet } from "../bitflag.js";